diff --git a/BUILD.bazel b/BUILD.bazel index e246217503abd868585d80d2f8e1c6ee6cd3f679..653c52689352f843526425218efe42ec306d5503 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,3 +1,4 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") load("@bazel_gazelle//:def.bzl", "gazelle") # gazelle:prefix github.com/bio-routing/bio-rd @@ -6,3 +7,29 @@ gazelle( external = "vendored", prefix = "github.com/bio-routing/bio-rd", ) + +go_library( + name = "go_default_library", + srcs = [ + "main.go", + "main_ipv4.go", + ], + importpath = "github.com/bio-routing/bio-rd", + visibility = ["//visibility:private"], + deps = [ + "//config:go_default_library", + "//net:go_default_library", + "//protocols/bgp/server:go_default_library", + "//protocols/netlink:go_default_library", + "//routingtable:go_default_library", + "//routingtable/filter:go_default_library", + "//routingtable/locRIB:go_default_library", + "//vendor/github.com/sirupsen/logrus:go_default_library", + ], +) + +go_binary( + name = "bio-rd", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) diff --git a/Gopkg.lock b/Gopkg.lock index 93a2bb9c5d130034a39ae14faa94cea4229e09a5..9e5fde7a5be79a0929d31d64e0f1f1500a8902f6 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -52,7 +52,7 @@ "gps/paths", "gps/pkgtree", "gps/verify", - "internal/fs" + "internal/fs", ] revision = "224a564abe296670b692fe08bb63a3e4c4ad7978" version = "v0.5.0" @@ -129,6 +129,21 @@ packages = ["convert"] revision = "c05b18bd57ea723faad165126ec38ae661bc1df6" +[[projects]] + name = "github.com/vishvananda/netlink" + packages = [ + ".", + "nl", + ] + revision = "a2ad57a690f3caf3015351d2d6e1c0b95c349752" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/vishvananda/netns" + packages = ["."] + revision = "13995c7128ccc8e51e9a6bd2b551020a27180abd" + [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -152,7 +167,7 @@ name = "golang.org/x/sys" packages = [ "unix", - "windows" + "windows", ] revision = "4497e2df6f9e69048a54498c7affbbec3294ad47" @@ -165,6 +180,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "ec525bd690a1530d850c09d334bc4cb35b167cd5f308ad5d30be88974d3242d7" + inputs-digest = "b06675ba943a08e455d38c9e661639629eca92a2747f433e91e8c772edb644c1" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..13538600e715a8aecd406ba97465e4a767c058bf --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +NAME=bio-rd + +all: test + +$(NAME): gazelle + bazel build //:bio-rd + +gazelle: + bazel run //:gazelle -- update + +test: $(NAME) + bazel test //... + +vendor: + bazel build //vendor/github.com/golang/dep/cmd/dep + bazel-bin/vendor/github.com/golang/dep/cmd/dep/linux_amd64_stripped/dep use + # hack: dep of dep gives us these, and it breaks gazelle + rm -rf vendor/github.com/golang/dep/cmd/dep/testdata + rm -rf vendor/github.com/golang/dep/internal/fs/testdata/symlinks/dir-symlink + +clean: + bazel clean + rm $(NAME) + +.PHONY: $(NAME) gazelle clean diff --git a/config/BUILD.bazel b/config/BUILD.bazel index 59561fc18788143092394d865b43cd731773674e..b12ff81e8b96d9295ebddc981628e8596eed9c95 100644 --- a/config/BUILD.bazel +++ b/config/BUILD.bazel @@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ + "netlink.go", "peer.go", "server.go", ], diff --git a/config/netlink.go b/config/netlink.go new file mode 100644 index 0000000000000000000000000000000000000000..22077f70afb0f3382c3f7624c526c584138ece5a --- /dev/null +++ b/config/netlink.go @@ -0,0 +1,22 @@ +package config + +import ( + "time" + + "github.com/bio-routing/bio-rd/routingtable/filter" +) + +const ( + RtLocal int = 255 + RtMain int = 254 + RtDefault int = 253 + RtUnspec int = 0 +) + +type Netlink struct { + HoldTime time.Duration + UpdateInterval time.Duration + RoutingTable int + ImportFilter *filter.Filter // Which routes are imported from the Kernel + ExportFilter *filter.Filter // Which routes are exportet to the Kernel +} diff --git a/main.go b/main.go new file mode 100644 index 0000000000000000000000000000000000000000..c6a0576dd6e524ae0cb1490a664f909189e76096 --- /dev/null +++ b/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "net" + "os" + "time" + + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/protocols/bgp/server" + "github.com/bio-routing/bio-rd/protocols/netlink" + "github.com/bio-routing/bio-rd/routingtable/locRIB" + log "github.com/sirupsen/logrus" + + bnet "github.com/bio-routing/bio-rd/net" +) + +func strAddr(s string) uint32 { + ret, _ := bnet.StrToAddr(s) + return ret +} + +func main() { + log.SetLevel(log.DebugLevel) + + f, err := os.OpenFile("/var/log/bio-rd.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + defer f.Close() + + log.SetOutput(f) + + log.Info("bio-routing started...\n") + + cfg := &config.Global{ + Listen: true, + LocalAddressList: []net.IP{ + net.IPv4(169, 254, 0, 2), + }, + } + + rib := locRIB.New() + b := server.NewBgpServer() + startBGPServer(b, rib, cfg) + + // Netlink communication + n := proto_netlink.NewNetlinkServer(&config.Netlink{ + HoldTime: time.Second * 15, + UpdateInterval: time.Second * 15, + RoutingTable: config.RtMain, + }, rib) + n.Start() + + go func() { + for { + log.Debugf("LocRIB count: %d", rib.Count()) + log.Debugf(rib.Print()) + time.Sleep(time.Second * 10) + } + }() + + select {} +} diff --git a/main_ipv4.go b/main_ipv4.go new file mode 100644 index 0000000000000000000000000000000000000000..12bb67ae2305208035c00d46ed634c72a2dee454 --- /dev/null +++ b/main_ipv4.go @@ -0,0 +1,49 @@ +package main + +import ( + "time" + + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/locRIB" + + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/protocols/bgp/server" + "github.com/bio-routing/bio-rd/routingtable/filter" + log "github.com/sirupsen/logrus" + + bnet "github.com/bio-routing/bio-rd/net" +) + +func startBGPServer(b server.BGPServer, rib *locRIB.LocRIB, cfg *config.Global) { + err := b.Start(cfg) + if err != nil { + log.Fatalf("Unable to start BGP server: %v", err) + } + + b.AddPeer(config.Peer{ + AdminEnabled: true, + LocalAS: 65200, + PeerAS: 65100, + PeerAddress: bnet.IPv4FromOctets(169, 254, 0, 1), + LocalAddress: bnet.IPv4FromOctets(169, 254, 0, 2), + ReconnectInterval: time.Second * 20, + HoldTime: time.Second * 20, + KeepAlive: time.Second * 20, + Passive: false, + RouterID: b.RouterID(), + + //AddPathSend: routingtable.ClientOptions{ + // MaxPaths: 10, + //}, + //RouteServerClient: true, + IPv4: &config.AddressFamilyConfig{ + RIB: rib, + ImportFilter: filter.NewAcceptAllFilter(), + ExportFilter: filter.NewAcceptAllFilter(), + AddPathSend: routingtable.ClientOptions{ + MaxPaths: 10, + }, + AddPathRecv: true, + }, + }) +} diff --git a/main_ipv6.go b/main_ipv6.go new file mode 100644 index 0000000000000000000000000000000000000000..cc26484b2e7f855eca6eeb75c6d51df436167f47 --- /dev/null +++ b/main_ipv6.go @@ -0,0 +1,72 @@ +// +build ipv6 + +package main + +import ( + "net" + "time" + + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/protocols/bgp/server" + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/filter" + "github.com/bio-routing/bio-rd/routingtable/locRIB" + "github.com/sirupsen/logrus" + + bnet "github.com/bio-routing/bio-rd/net" +) + +func startServer(b server.BGPServer, rib *locRIB.LocRIB) { + + err := b.Start(&config.Global{ + Listen: true, + LocalAddressList: []net.IP{ + net.IP{0x20, 0x01, 0x6, 0x78, 0x1, 0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0xca, 0xfe}, + }, + }) + if err != nil { + logrus.Fatalf("Unable to start BGP server: %v", err) + } + + b.AddPeer(config.Peer{ + AdminEnabled: true, + LocalAS: 65200, + PeerAS: 202739, + PeerAddress: bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 1), + LocalAddress: bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 0xcafe), + ReconnectInterval: time.Second * 15, + HoldTime: time.Second * 90, + KeepAlive: time.Second * 30, + Passive: true, + RouterID: b.RouterID(), + IPv6: &config.AddressFamilyConfig{ + RIB: rib, + ImportFilter: filter.NewAcceptAllFilter(), + ExportFilter: filter.NewDrainFilter(), + AddPathSend: routingtable.ClientOptions{ + BestOnly: true, + }, + }, + }) + + b.AddPeer(config.Peer{ + AdminEnabled: true, + LocalAS: 65200, + PeerAS: 65400, + PeerAddress: bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0xcafe, 0, 0, 0, 5), + LocalAddress: bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 0xcafe), + ReconnectInterval: time.Second * 15, + HoldTime: time.Second * 90, + KeepAlive: time.Second * 30, + Passive: true, + RouterID: b.RouterID(), + IPv6: &config.AddressFamilyConfig{ + RIB: rib, + ImportFilter: filter.NewDrainFilter(), + ExportFilter: filter.NewAcceptAllFilter(), + AddPathSend: routingtable.ClientOptions{ + BestOnly: true, + }, + }, + }) +} diff --git a/net/ip.go b/net/ip.go index 4392fd1941729cdb98c8cf73f73ac4dd10c8eba9..59d09201d8e3b25694064c4d4c46107b1e5aca43 100644 --- a/net/ip.go +++ b/net/ip.go @@ -79,11 +79,13 @@ func IPFromString(str string) (IP, error) { // Equal returns true if ip is equal to other func (ip IP) Equal(other IP) bool { - return ip == other + return ip.higher == other.higher && + ip.lower == other.lower && + ip.ipVersion == other.ipVersion } // Compare compares two IP addresses (returns 0 if equal, -1 if `ip` is smaller than `other`, 1 if `ip` is greater than `other`) -func (ip IP) Compare(other IP) int { +func (ip IP) Compare(other IP) int8 { if ip.Equal(other) { return 0 } diff --git a/net/ip_test.go b/net/ip_test.go index 961730c01844a3c13c569de97eb7caed0be0567e..33ba4bce4cf373f6192e8416fa6245de6502c561 100644 --- a/net/ip_test.go +++ b/net/ip_test.go @@ -13,7 +13,7 @@ func TestCompare(t *testing.T) { name string ip IP other IP - expected int + expected int8 }{ { name: "equal", diff --git a/net/prefix.go b/net/prefix.go index 5abd32f141f8ae5cfb9c107d2bc5a7ce98bddf4e..064c28692913057ee69f5d36bed53587d2c374b9 100644 --- a/net/prefix.go +++ b/net/prefix.go @@ -3,6 +3,7 @@ package net import ( "fmt" "math" + "net" "strconv" "strings" ) @@ -21,6 +22,16 @@ func NewPfx(addr IP, pfxlen uint8) Prefix { } } +func NewPfxFromIPNet(ipNet *net.IPNet) Prefix { + ones, _ := ipNet.Mask.Size() + ip, _ := IPFromBytes(ipNet.IP) + + return Prefix{ + addr: ip, + pfxlen: uint8(ones), + } +} + // StrToAddr converts an IP address string to it's uint32 representation func StrToAddr(x string) (uint32, error) { parts := strings.Split(x, ".") @@ -60,6 +71,20 @@ func (pfx Prefix) String() string { return fmt.Sprintf("%s/%d", pfx.addr, pfx.pfxlen) } +func (pfx Prefix) GetIPNet() *net.IPNet { + var dstNetwork net.IPNet + dstNetwork.IP = pfx.Addr().Bytes() + + pfxLen := int(pfx.Pfxlen()) + if pfx.Addr().IsIPv4() { + dstNetwork.Mask = net.CIDRMask(pfxLen, 32) + } else { + dstNetwork.Mask = net.CIDRMask(pfxLen, 128) + } + + return &dstNetwork +} + // Contains checks if x is a subnet of or equal to pfx func (pfx Prefix) Contains(x Prefix) bool { if x.pfxlen <= pfx.pfxlen { @@ -94,7 +119,7 @@ func (pfx Prefix) containsIPv6(x Prefix) bool { // Equal checks if pfx and x are equal func (pfx Prefix) Equal(x Prefix) bool { - return pfx == x + return pfx.addr.Equal(x.addr) && pfx.pfxlen == x.pfxlen } // GetSupernet gets the next common supernet of pfx and x diff --git a/protocols/netlink/BUILD.bazel b/protocols/netlink/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..d179347aa63671b72d907bf79622d215d02eca44 --- /dev/null +++ b/protocols/netlink/BUILD.bazel @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "netlink.go", + "netlink_reader.go", + "netlink_writer.go", + ], + importpath = "github.com/bio-routing/bio-rd/protocols/netlink", + visibility = ["//visibility:public"], + deps = [ + "//config:go_default_library", + "//net:go_default_library", + "//route:go_default_library", + "//routingtable:go_default_library", + "//routingtable/filter:go_default_library", + "//routingtable/locRIB:go_default_library", + "//vendor/github.com/sirupsen/logrus:go_default_library", + "//vendor/github.com/vishvananda/netlink:go_default_library", + ], +) diff --git a/protocols/netlink/netlink.go b/protocols/netlink/netlink.go new file mode 100644 index 0000000000000000000000000000000000000000..46d40223fd1d602460494606d2e700946ff09b80 --- /dev/null +++ b/protocols/netlink/netlink.go @@ -0,0 +1,42 @@ +package proto_netlink + +import ( + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/locRIB" +) + +type NetlinkServer struct { + locRib *locRIB.LocRIB + + writer *NetlinkWriter + reader *NetlinkReader +} + +func NewNetlinkServer(options *config.Netlink, locRib *locRIB.LocRIB) *NetlinkServer { + + n := &NetlinkServer{ + locRib: locRib, + writer: NewNetlinkWriter(options), + reader: NewNetlinkReader(options), + } + return n +} + +func (n *NetlinkServer) Start() { + // connect all RIBs + options := routingtable.ClientOptions{ + BestOnly: false, + EcmpOnly: false, + MaxPaths: ^uint(0), // max int + } + + // 1. from locRib to Kernel + n.locRib.ClientManager.RegisterWithOptions(n.writer, options) + + // 2. vom Kernel to locRib + n.reader.ClientManager.RegisterWithOptions(n.locRib, options) + + // Listn for new routes from kernel + go n.reader.Read() +} diff --git a/protocols/netlink/netlink_reader.go b/protocols/netlink/netlink_reader.go new file mode 100644 index 0000000000000000000000000000000000000000..0671d220109af0174d186de84100b5bf8d0c2530 --- /dev/null +++ b/protocols/netlink/netlink_reader.go @@ -0,0 +1,226 @@ +package proto_netlink + +import ( + "fmt" + "sync" + "time" + + "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/route" + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/filter" + log "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" +) + +type NetlinkReader struct { + options *config.Netlink + routingtable.ClientManager + filter *filter.Filter + + mu sync.RWMutex + routes []netlink.Route +} + +func NewNetlinkReader(options *config.Netlink) *NetlinkReader { + nr := &NetlinkReader{ + options: options, + filter: options.ImportFilter, + } + + nr.ClientManager = routingtable.NewClientManager(nr) + + return nr +} + +// Read routes from kernel +func (nr *NetlinkReader) Read() { + log.WithField("rt_table", nr.options.RoutingTable).Info("Started netlink server") + + // Start fetching the kernel routes after the hold time + time.Sleep(nr.options.HoldTime) + + for { + // Family doesn't matter. I only filter by the rt_table here + routes, err := netlink.RouteListFiltered(4, &netlink.Route{Table: nr.options.RoutingTable}, netlink.RT_FILTER_TABLE) + if err != nil { + log.WithError(err).Panic("Failed to read routes from kernel") + } + + nr.propagateChanges(routes) + + nr.mu.Lock() + nr.routes = routes + + log.Debugf("NetlinkRouteDiff: %d", len(route.NetlinkRouteDiff(nr.routes, routes))) + nr.mu.Unlock() + + time.Sleep(nr.options.UpdateInterval) + } +} + +// create a path from a route +func createPathFromRoute(r *netlink.Route) (*route.Path, error) { + nlPath, err := route.NewNlPathFromRoute(r, true) + + if err != nil { + return nil, fmt.Errorf("Error while creating path object from route object", err) + } + + return &route.Path{ + Type: route.NetlinkPathType, + NetlinkPath: nlPath, + }, nil +} + +// propagate changes to all subscribed clients +func (nr *NetlinkReader) propagateChanges(routes []netlink.Route) { + nr.removePathsFromClients(routes) + nr.addPathsToClients(routes) +} + +// Add given paths to clients +func (nr *NetlinkReader) addPathsToClients(routes []netlink.Route) { + for _, client := range nr.ClientManager.Clients() { + // only advertise changed routes + + nr.mu.RLock() + advertise := route.NetlinkRouteDiff(routes, nr.routes) + nr.mu.RUnlock() + + for _, r := range advertise { + // Is it a BIO-Written route? if so, skip it, dont advertise it + if r.Protocol == route.ProtoBio { + log.WithFields(routeLogFields(r)).Debug("Skipping bio route") + continue + } + + // create pfx and path from route + pfx := bnet.NewPfxFromIPNet(r.Dst) + path, err := createPathFromRoute(&r) + if err != nil { + log.WithError(err).Error("Unable to create path") + continue + } + + // Apply filter (if existing) + if nr.filter != nil { + var reject bool + // TODO: Implement filter that cann handle netlinkRoute objects + path, reject = nr.filter.ProcessTerms(pfx, path) + if reject { + log.Debug("Skipping route due to filter") + continue + } + } + + log.WithFields(log.Fields{ + "pfx": pfx, + "path": path, + }).Debug("NetlinkReader - client.AddPath") + client.AddPath(pfx, path) + } + } +} + +// Remove given paths from clients +func (nr *NetlinkReader) removePathsFromClients(routes []netlink.Route) { + for _, client := range nr.ClientManager.Clients() { + // If there where no routes yet, just skip this funktion. There's nothing to delete + nr.mu.RLock() + if len(nr.routes) == 0 { + nr.mu.RUnlock() + break + } + + // only withdraw changed routes + withdraw := route.NetlinkRouteDiff(nr.routes, routes) + nr.mu.RUnlock() + + for _, r := range withdraw { + // Is it a BIO-Written route? if so, skip it, dont advertise it + if r.Protocol == route.ProtoBio { + continue + } + + // create pfx and path from route + pfx := bnet.NewPfxFromIPNet(r.Dst) + path, err := createPathFromRoute(&r) + if err != nil { + log.WithError(err).Error("Unable to create path") + continue + } + + // Apply filter (if existing) + if nr.filter != nil { + var reject bool + // TODO: Implement filter that cann handle netlinkRoute objects + path, reject = nr.filter.ProcessTerms(pfx, path) + if reject { + continue + } + } + + log.WithFields(log.Fields{ + "pfx": pfx, + "path": path, + }).Debug("NetlinkReader - client.RemovePath") + client.RemovePath(pfx, path) + } + } +} + +func routeLogFields(route netlink.Route) log.Fields { + return log.Fields{ + "LinkIndex": route.LinkIndex, + "ILinkIndex": route.ILinkIndex, + "Scope": route.Scope, + "Dst": route.Dst, + "Src": route.Src, + "Gw": route.Gw, + "MultiPath": route.MultiPath, + "Protocol": route.Protocol, + "Priority": route.Priority, + "Table": route.Table, + "Type": route.Type, + "Tos": route.Tos, + "Flags": route.Flags, + "MPLSDst": route.MPLSDst, + "NewDst": route.NewDst, + "Encap": route.Encap, + "MTU": route.MTU, + "AdvMSS": route.AdvMSS, + } +} + +// Not supported +func (nr *NetlinkReader) AddPath(bnet.Prefix, *route.Path) error { + return fmt.Errorf("Not supported") +} + +// Not supported +func (nr *NetlinkReader) RemovePath(bnet.Prefix, *route.Path) bool { + return false +} + +// Not supported +func (nr *NetlinkReader) UpdateNewClient(routingtable.RouteTableClient) error { + return fmt.Errorf("Not supported") +} + +func (nr *NetlinkReader) Register(routingtable.RouteTableClient) { +} + +func (nr *NetlinkReader) RegisterWithOptions(routingtable.RouteTableClient, routingtable.ClientOptions) { +} + +func (nr *NetlinkReader) Unregister(routingtable.RouteTableClient) { +} + +func (nr *NetlinkReader) RouteCount() int64 { + nr.mu.RLock() + defer nr.mu.RUnlock() + + return int64(len(nr.routes)) +} diff --git a/protocols/netlink/netlink_writer.go b/protocols/netlink/netlink_writer.go new file mode 100644 index 0000000000000000000000000000000000000000..c644ec45910472fe7bab199671d83f051f963b85 --- /dev/null +++ b/protocols/netlink/netlink_writer.go @@ -0,0 +1,229 @@ +package proto_netlink + +import ( + "fmt" + "sync" + + "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/route" + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/filter" + log "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" +) + +type NetlinkWriter struct { + options *config.Netlink + filter *filter.Filter + + // Routingtable for buffering, to ensure no double writes (a.k.a rtnetlink: file exists) + mu sync.RWMutex + pt map[bnet.Prefix][]*route.Path +} + +func NewNetlinkWriter(options *config.Netlink) *NetlinkWriter { + return &NetlinkWriter{ + options: options, + filter: options.ExportFilter, + pt: make(map[bnet.Prefix][]*route.Path), + } +} + +// Not supported +func (nw *NetlinkWriter) UpdateNewClient(routingtable.RouteTableClient) error { + return fmt.Errorf("Not supported") +} + +// Not supported +func (nw *NetlinkWriter) Register(routingtable.RouteTableClient) { + log.Error("Not supported") +} + +// Not supported +func (nw *NetlinkWriter) RegisterWithOptions(routingtable.RouteTableClient, routingtable.ClientOptions) { + log.Error("Not supported") +} + +// Not supported +func (nw *NetlinkWriter) Unregister(routingtable.RouteTableClient) { + log.Error("Not supported") +} + +// RouteCount returns the number of stored routes +func (nw *NetlinkWriter) RouteCount() int64 { + nw.mu.RLock() + defer nw.mu.RUnlock() + return int64(len(nw.pt)) +} + +// Add a path to the Kernel using netlink +// This function is triggered by the loc_rib, cause we are subscribed as +// client in the loc_rib +func (nw *NetlinkWriter) AddPath(pfx bnet.Prefix, path *route.Path) error { + // check if for this prefix already a route is existing + existingPaths, ok := nw.pt[pfx] + + // if no route exists, add that route + if existingPaths == nil || !ok { + paths := make([]*route.Path, 1) + paths = append(paths, path) + nw.pt[pfx] = paths + + // add the route to kernel + return nw.addKernel(pfx, path) + } + + // if the new path is already in, don't do anything + for _, ePath := range existingPaths { + if ePath.Equal(path) { + return nil + } + } + + existingPaths = append(existingPaths, path) + nw.pt[pfx] = existingPaths + + // now add to netlink + return nw.addKernel(pfx, path) +} + +// Remove a path from the Kernel using netlink +// This function is triggered by the loc_rib, cause we are subscribed as +// client in the loc_rib +func (nw *NetlinkWriter) RemovePath(pfx bnet.Prefix, path *route.Path) bool { + // check if for this prefix already a route is existing + existingPaths, ok := nw.pt[pfx] + + // if no route exists, nothing to do + if existingPaths == nil || !ok { + return true + } + + // if the new path is already in: remove + removeIdx := 0 + remove := false + for idx, ePath := range existingPaths { + if ePath.Equal(path) { + removeIdx = idx + + remove = true + err := nw.removeKernel(pfx, path) + if err != nil { + log.WithError(err).Errorf("Error while removing path %s for prefix %s", path.String(), pfx.String()) + remove = false + } + + break + } + } + + if remove { + existingPaths = append(existingPaths[:removeIdx], existingPaths[removeIdx+1:]...) + nw.pt[pfx] = existingPaths + } + + return true +} + +// Add pfx/path to kernel +func (nw *NetlinkWriter) addKernel(pfx bnet.Prefix, path *route.Path) error { + route, err := nw.createRoute(pfx, path) + if err != nil { + log.Errorf("Error while creating route: %v", err) + return fmt.Errorf("Error while creating route: %v", err) + } + + log.WithFields(log.Fields{ + "Prefix": pfx.String(), + "Table": route.Table, + }).Debug("AddPath to netlink") + + err = netlink.RouteAdd(route) + if err != nil { + log.Errorf("Error while adding route: %v", err) + return fmt.Errorf("Error while adding route: %v", err) + } + + return nil +} + +// remove pfx/path from kernel +func (nw *NetlinkWriter) removeKernel(pfx bnet.Prefix, path *route.Path) error { + log.WithFields(log.Fields{ + "Prefix": pfx.String(), + }).Debug("Remove from netlink") + + route, err := nw.createRoute(pfx, path) + if err != nil { + return fmt.Errorf("Error while creating route: %v", err) + } + + err = netlink.RouteDel(route) + if err != nil { + return fmt.Errorf("Error while removing route: %v", err) + } + + return nil +} + +// create a route from a prefix and a path +func (nw *NetlinkWriter) createRoute(pfx bnet.Prefix, path *route.Path) (*netlink.Route, error) { + if path.Type != route.NetlinkPathType { + } + + switch path.Type { + case route.NetlinkPathType: + return nw.createRouteFromNetlink(pfx, path) + + case route.BGPPathType: + return nw.createRouteFromBGPPath(pfx, path) + + default: + return nil, fmt.Errorf("PathType %d is not supported for adding to netlink", path.Type) + } +} + +func (nw *NetlinkWriter) createRouteFromNetlink(pfx bnet.Prefix, path *route.Path) (*netlink.Route, error) { + nlPath := path.NetlinkPath + + log.WithFields(log.Fields{ + "Dst": nlPath.Dst, + "Src": nlPath.Src, + "NextHop": nlPath.NextHop, + "Priority": nlPath.Priority, + "Protocol": nlPath.Protocol, + "Type": nlPath.Type, + "Table": nw.options.RoutingTable, + }).Debug("created route") + + return &netlink.Route{ + Dst: nlPath.Dst.GetIPNet(), + Src: nlPath.Src.Bytes(), + Gw: nlPath.NextHop.Bytes(), + Priority: nlPath.Priority, + Type: nlPath.Type, + Table: nw.options.RoutingTable, // config dependent + Protocol: route.ProtoBio, // fix + }, nil +} + +func (nw *NetlinkWriter) createRouteFromBGPPath(pfx bnet.Prefix, path *route.Path) (*netlink.Route, error) { + bgpPath := path.BGPPath + + log.WithFields(log.Fields{ + "Dst": pfx, + "NextHop": bgpPath.NextHop, + "Protocol": "BGP", + "BGPIdentifier": bgpPath.BGPIdentifier, + "Table": nw.options.RoutingTable, + }).Debug("created route") + + return &netlink.Route{ + Dst: pfx.GetIPNet(), + Gw: bgpPath.NextHop.Bytes(), + Table: nw.options.RoutingTable, // config dependent + Protocol: route.ProtoBio, // fix + }, nil + +} diff --git a/route/BUILD.bazel b/route/BUILD.bazel index 3673d29995e0ef11a14bbd7043135457f7ea1d7e..c249b10f33d990279a7fa5cdbc2578cbdd8c639b 100644 --- a/route/BUILD.bazel +++ b/route/BUILD.bazel @@ -5,6 +5,7 @@ go_library( srcs = [ "bgp_path.go", "bgp_path_manager.go", + "netlink_path.go", "path.go", "route.go", "static.go", @@ -14,7 +15,9 @@ go_library( deps = [ "//net:go_default_library", "//protocols/bgp/types:go_default_library", + "//vendor/github.com/sirupsen/logrus:go_default_library", "//vendor/github.com/taktv6/tflow2/convert:go_default_library", + "//vendor/github.com/vishvananda/netlink:go_default_library", ], ) @@ -31,5 +34,6 @@ go_test( "//net:go_default_library", "//protocols/bgp/types:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", + "//vendor/github.com/vishvananda/netlink:go_default_library", ], ) diff --git a/route/bgp_path.go b/route/bgp_path.go index 78c6d2a327bebd62eb5ed1cc4145b56ad0d50398..e2ec089d2c17efde7b1ebf832d9068cbbb4eb774 100644 --- a/route/bgp_path.go +++ b/route/bgp_path.go @@ -235,6 +235,45 @@ func (b *BGPPath) better(c *BGPPath) bool { } // Print all known information about a route in human readable form +func (b *BGPPath) String() string { + origin := "" + switch b.Origin { + case 0: + origin = "Incomplete" + case 1: + origin = "EGP" + case 2: + origin = "IGP" + } + + bgpType := "internal" + if b.EBGP { + bgpType = "external" + } + + ret := fmt.Sprintf("Local Pref: %d, ", b.LocalPref) + ret += fmt.Sprintf("Origin: %s, ", origin) + ret += fmt.Sprintf("AS Path: %v, ", b.ASPath) + ret += fmt.Sprintf("BGP type: %s, ", bgpType) + ret += fmt.Sprintf("NEXT HOP: %s, ", b.NextHop) + ret += fmt.Sprintf("MED: %d, ", b.MED) + ret += fmt.Sprintf("Path ID: %d, ", b.PathIdentifier) + ret += fmt.Sprintf("Source: %s, ", b.Source) + ret += fmt.Sprintf("Communities: %v, ", b.Communities) + ret += fmt.Sprintf("LargeCommunities: %v, ", b.LargeCommunities) + + if b.OriginatorID != 0 { + oid := convert.Uint32Byte(b.OriginatorID) + ret += fmt.Sprintf("OriginatorID: %d.%d.%d.%d, ", oid[0], oid[1], oid[2], oid[3]) + } + if b.ClusterList != nil { + ret += fmt.Sprintf("ClusterList %s", b.ClusterListString()) + } + + return ret +} + +// Pretty Print all known information about a route in human readable form func (b *BGPPath) Print() string { origin := "" switch b.Origin { diff --git a/route/netlink_path.go b/route/netlink_path.go new file mode 100644 index 0000000000000000000000000000000000000000..ccdebbdb91e94c3ea102b04aaa3b559b55838faa --- /dev/null +++ b/route/netlink_path.go @@ -0,0 +1,169 @@ +package route + +import ( + "fmt" + + bnet "github.com/bio-routing/bio-rd/net" + log "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" +) + +const ( + ProtoBio = 45 +) + +// NetlinkPath represents a path learned via Netlink of a route +type NetlinkPath struct { + Dst bnet.Prefix + Src bnet.IP + NextHop bnet.IP // GW + Priority int + Protocol int + Type int + Table int + Kernel bool // True if the route is already installed in the kernel +} + +func NewNlPathFromBgpPath(p *BGPPath) *NetlinkPath { + return &NetlinkPath{ + Src: p.Source, + NextHop: p.NextHop, + Protocol: ProtoBio, + Kernel: false, + } +} + +func NewNlPathFromRoute(r *netlink.Route, kernel bool) (*NetlinkPath, error) { + var src bnet.IP + var dst bnet.Prefix + + if r.Src == nil && r.Dst == nil { + return nil, fmt.Errorf("Cannot create NlPath, since source and destination are both nil") + } + + if r.Src == nil && r.Dst != nil { + dst = bnet.NewPfxFromIPNet(r.Dst) + if dst.Addr().IsIPv4() { + src = bnet.IPv4FromOctets(0, 0, 0, 0) + } else { + src = bnet.IPv6FromBlocks(0, 0, 0, 0, 0, 0, 0, 0) + } + } + + if r.Src != nil && r.Dst == nil { + src, _ = bnet.IPFromBytes(r.Src) + if src.IsIPv4() { + dst = bnet.NewPfx(bnet.IPv4FromOctets(0, 0, 0, 0), 0) + } else { + dst = bnet.NewPfx(bnet.IPv6FromBlocks(0, 0, 0, 0, 0, 0, 0, 0), 0) + } + } + + if r.Src != nil && r.Dst != nil { + src, _ = bnet.IPFromBytes(r.Src) + dst = bnet.NewPfxFromIPNet(r.Dst) + } + + log.Warnf("IPFromBytes: %v goes to %v", r.Src, src) + log.Warnf("IPFromBytes: %v goes to %v", r.Dst, dst) + + nextHop, _ := bnet.IPFromBytes(r.Gw) + + return &NetlinkPath{ + Dst: dst, + Src: src, + NextHop: nextHop, + Priority: r.Priority, + Protocol: r.Protocol, + Type: r.Type, + Table: r.Table, + Kernel: kernel, + }, nil +} + +// Compare returns negative if s < t, 0 if paths are equal, positive if s > t +func (s *NetlinkPath) Select(t *NetlinkPath) int8 { + if !s.Dst.Equal(t.Dst) { + return 1 + } + + if s.NextHop.Compare(t.NextHop) > 0 { + return -1 + } + + if s.NextHop.Compare(t.NextHop) < 0 { + return 1 + } + + if s.Src.Compare(t.Src) > 0 { + return -1 + } + + if s.Src.Compare(t.Src) < 0 { + return 1 + } + + if s.Priority < t.Priority { + return -1 + } + + if s.Priority > t.Priority { + return 1 + } + + if s.Protocol < t.Protocol { + return -1 + } + + if s.Protocol > t.Protocol { + return 1 + } + + if s.Table < t.Table { + return -1 + } + + if s.Table > t.Table { + return 1 + } + + return 0 +} + +// ECMP determines if path s and t are equal in terms of ECMP +func (s *NetlinkPath) ECMP(t *NetlinkPath) bool { + return true +} + +func (s *NetlinkPath) Copy() *NetlinkPath { + if s == nil { + return nil + } + + cp := *s + return &cp +} + +// get all known information about a route in a machine readable form +func (s *NetlinkPath) String() string { + ret := fmt.Sprintf("Destination: %s, ", s.Dst.String()) + ret += fmt.Sprintf("Source: %s, ", s.Src.String()) + ret += fmt.Sprintf("NextHop: %s, ", s.NextHop.String()) + ret += fmt.Sprintf("Priority: %d, ", s.Priority) + ret += fmt.Sprintf("Type: %d, ", s.Type) + ret += fmt.Sprintf("Table: %d", s.Table) + + return ret +} + +// Pretty Print all known information about a route in human readable form +func (s *NetlinkPath) Print() string { + ret := fmt.Sprintf("\t\tDestination: %s\n", s.Dst.String()) + ret += fmt.Sprintf("\t\tSource: %s\n", s.Src.String()) + ret += fmt.Sprintf("\t\tNextHop: %s\n", s.NextHop.String()) + ret += fmt.Sprintf("\t\tPriority: %d\n", s.Priority) + ret += fmt.Sprintf("\t\tType: %d\n", s.Type) + ret += fmt.Sprintf("\t\tTable: %d\n", s.Table) + + return ret +} diff --git a/route/path.go b/route/path.go index 0f7d8372a9f04e93eed1ec24b9f14407f36fb6fd..ab587ba8afa8ee96a032befd650bb23419880249 100644 --- a/route/path.go +++ b/route/path.go @@ -2,12 +2,16 @@ package route import ( "fmt" + "log" + + bnet "github.com/bio-routing/bio-rd/net" ) type Path struct { - Type uint8 - StaticPath *StaticPath - BGPPath *BGPPath + Type uint8 + StaticPath *StaticPath + BGPPath *BGPPath + NetlinkPath *NetlinkPath } // Select returns negative if p < q, 0 if paths are equal, positive if p > q @@ -35,6 +39,8 @@ func (p *Path) Select(q *Path) int8 { return p.BGPPath.Select(q.BGPPath) case StaticPathType: return p.StaticPath.Select(q.StaticPath) + case NetlinkPathType: + return p.NetlinkPath.Select(q.NetlinkPath) } panic("Unknown path type") @@ -46,6 +52,8 @@ func (p *Path) ECMP(q *Path) bool { return p.BGPPath.ECMP(q.BGPPath) case StaticPathType: return p.StaticPath.ECMP(q.StaticPath) + case NetlinkPathType: + return p.NetlinkPath.ECMP(q.NetlinkPath) } panic("Unknown path type") @@ -93,6 +101,19 @@ func pathsContains(needle *Path, haystack []*Path) bool { return false } +func (p *Path) String() string { + switch p.Type { + case StaticPathType: + return "not implemented yet" + case BGPPathType: + return p.BGPPath.String() + case NetlinkPathType: + return p.NetlinkPath.String() + default: + return "Unknown paty type. Probably not implemented yet" + } +} + func (p *Path) Print() string { protocol := "" switch p.Type { @@ -100,6 +121,8 @@ func (p *Path) Print() string { protocol = "static" case BGPPathType: protocol = "BGP" + case NetlinkPathType: + protocol = "Netlink" } ret := fmt.Sprintf("\tProtocol: %s\n", protocol) @@ -108,6 +131,8 @@ func (p *Path) Print() string { ret += "Not implemented yet" case BGPPathType: ret += p.BGPPath.Print() + case NetlinkPathType: + ret += p.NetlinkPath.Print() } return ret @@ -124,3 +149,18 @@ func (p *Path) Copy() *Path { return &cp } + +func (p *Path) NextHop() bnet.IP { + switch p.Type { + case BGPPathType: + return p.BGPPath.NextHop + case StaticPathType: + return p.StaticPath.NextHop + case NetlinkPathType: + return p.NetlinkPath.NextHop + default: + log.Panic("Type %d not implemented (yet)", p.Type) + } + + return bnet.IP{} +} diff --git a/route/route.go b/route/route.go index f263f70bcd7573b381299759d4ca24ba5440f5fe..ae26d58d8135692cece39c8dcf382d602fad51d2 100644 --- a/route/route.go +++ b/route/route.go @@ -6,19 +6,27 @@ import ( "sync" "github.com/bio-routing/bio-rd/net" + "github.com/vishvananda/netlink" ) -// StaticPathType indicats a path is a static path -const StaticPathType = 1 +const ( + _ = iota // 0 -// BGPPathType indicates a path is a BGP path -const BGPPathType = 2 + // StaticPathType indicats a path is a static path + StaticPathType -// OSPFPathType indicates a path is an OSPF path -const OSPFPathType = 3 + // BGPPathType indicates a path is a BGP path + BGPPathType -// ISISPathType indicates a path is an ISIS path -const ISISPathType = 4 + // OSPFPathType indicates a path is an OSPF path + OSPFPathType + + // ISISPathType indicates a path is an ISIS path + ISISPathType + + // NetlinkPathType indicates a path is an Netlink/Kernel path + NetlinkPathType +) // Route links a prefix to paths type Route struct { @@ -191,6 +199,44 @@ func (r *Route) PathSelection() { r.updateEqualPathCount() } +func (r *Route) Equal(other *Route) bool { + r.mu.Lock() + defer r.mu.Unlock() + + a := r.pfx.Equal(other.pfx) + b := r.ecmpPaths == other.ecmpPaths + c := true + + if r.paths == nil && other.paths == nil { + c = true + return a && b && c + } + + if len(r.paths) != len(other.paths) { + c = false + return a && b && c + } + + for _, myP := range r.paths { + if !r.compareItemExists(myP, other.paths) { + c = false + return a && b && c + } + } + + return a && b && c +} + +func (r *Route) compareItemExists(needle *Path, haystack []*Path) bool { + for _, compare := range haystack { + if needle.Equal(compare) { + return true + } + } + + return false +} + func (r *Route) updateEqualPathCount() { count := uint(1) for i := 0; i < len(r.paths)-1; i++ { @@ -229,3 +275,49 @@ func (r *Route) Print() string { return ret } + +// NetlinkRouteDiff gets the list of elements contained by a but not b +func NetlinkRouteDiff(a, b []netlink.Route) []netlink.Route { + ret := make([]netlink.Route, 0) + + for _, pa := range a { + if !netlinkRoutesContains(pa, b) { + ret = append(ret, pa) + } + } + + return ret +} + +func netlinkRoutesContains(needle netlink.Route, haystack []netlink.Route) bool { + for _, p := range haystack { + + probeMaskSize, probeMaskBits := p.Dst.Mask.Size() + needleMaskSize, needleMaskBits := needle.Dst.Mask.Size() + + if p.LinkIndex == needle.LinkIndex && + p.ILinkIndex == needle.ILinkIndex && + p.Scope == needle.Scope && + + p.Dst.IP.Equal(needle.Dst.IP) && + probeMaskSize == needleMaskSize && + probeMaskBits == needleMaskBits && + + p.Src.Equal(needle.Src) && + p.Gw.Equal(needle.Gw) && + + p.Protocol == needle.Protocol && + p.Priority == needle.Priority && + p.Table == needle.Table && + p.Type == needle.Type && + p.Tos == needle.Tos && + p.Flags == needle.Flags && + p.MTU == needle.MTU && + p.AdvMSS == needle.AdvMSS { + + return true + } + } + + return false +} diff --git a/route/route_test.go b/route/route_test.go index 4aaeb92804618918f8306364448c47521fa19cea..354612c5081b6aa78febe71a48b031dc9a4e649a 100644 --- a/route/route_test.go +++ b/route/route_test.go @@ -1,13 +1,158 @@ package route import ( + "net" "testing" "github.com/stretchr/testify/assert" + "github.com/vishvananda/netlink" bnet "github.com/bio-routing/bio-rd/net" ) +func TestNetlinkRouteDiff(t *testing.T) { + tests := []struct { + name string + left []netlink.Route + right []netlink.Route + expected []netlink.Route + }{ + { + name: "Equal", + left: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + right: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + expected: []netlink.Route{}, + }, { + name: "Left empty", + left: []netlink.Route{}, + right: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + expected: []netlink.Route{}, + }, { + name: "Right empty", + left: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + right: []netlink.Route{}, + expected: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + }, { + name: "Diff", + left: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + right: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(10, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 1, + }, + }, + expected: []netlink.Route{ + { + Dst: &net.IPNet{ + IP: net.IPv4(20, 0, 0, 1), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + Table: 2, + }, + }, + }, + } + + for _, test := range tests { + res := NetlinkRouteDiff(test.left, test.right) + assert.Equal(t, test.expected, res) + } + +} + func TestNewRoute(t *testing.T) { tests := []struct { name string @@ -397,3 +542,121 @@ func TestECMPPaths(t *testing.T) { assert.Equal(t, tc.expected, tc.route.ECMPPaths()) } } + +func TestCompare(t *testing.T) { + tests := []struct { + a *Route + b *Route + equal bool + }{ + { + a: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 0, 1), + }, + }, + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + }, + }, + b: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 0, 1), + }, + }, + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + }, + }, + equal: true, + }, { + a: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 0, 1), + }, + }, + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + }, + }, + b: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 2, 1), + }, + }, + }, + }, + equal: false, + }, + { + a: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 0, 1), + }, + }, + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + }, + }, + b: &Route{ + ecmpPaths: 2, + paths: []*Path{ + { + Type: StaticPathType, + StaticPath: &StaticPath{ + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), + }, + }, + }, + }, + equal: false, + }, + } + + for _, tc := range tests { + res := tc.a.Equal(tc.b) + assert.Equal(t, tc.equal, res) + } +} diff --git a/route/static.go b/route/static.go index df282d2217eca7a4457a65f995cc2427cd9789e9..33f39bd418ef330647928d74d6997a0b3220e858 100644 --- a/route/static.go +++ b/route/static.go @@ -18,12 +18,12 @@ func (r *Route) staticPathSelection() { // Select returns negative if s < t, 0 if paths are equal, positive if s > t func (s *StaticPath) Select(t *StaticPath) int8 { - return 0 + return s.NextHop.Compare(t.NextHop) } // Equal returns true if s and t are euqal func (s *StaticPath) Equal(t *StaticPath) bool { - return s.NextHop == t.NextHop + return s.NextHop.Compare(t.NextHop) == 0 } // ECMP determines if path s and t are equal in terms of ECMP diff --git a/vendor/github.com/golang/dep/.codeclimate.yml b/vendor/github.com/golang/dep/.codeclimate.yml deleted file mode 100644 index a1c11c89924b1e37dd7a933832a45fbbc2e01347..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.codeclimate.yml +++ /dev/null @@ -1,35 +0,0 @@ -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 - identical-code: - enabled: false -plugins: - gofmt: - enabled: true - govet: - enabled: true - golint: - enabled: true -exclude_paths: - - vendor/ - - gps/_testdata - - cmd/dep/testdata - - testdata - - gps/internal/pb diff --git a/vendor/github.com/golang/dep/.gitattributes b/vendor/github.com/golang/dep/.gitattributes deleted file mode 100644 index d8df4ca60a61d207e8f0315d33a0be53ded1ee22..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Prevent problems comparing golden files on Windows -**/testdata/** text eol=lf diff --git a/vendor/github.com/golang/dep/.github/CODEOWNERS b/vendor/github.com/golang/dep/.github/CODEOWNERS deleted file mode 100644 index 6bc15ea97d33b07c3903306cd810beb26e23f4fb..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.github/CODEOWNERS +++ /dev/null @@ -1,25 +0,0 @@ -# general -* @sdboyer - -# init -/cmd/dep/init* @carolynvs -/cmd/dep/gopath_scanner* @carolynvs -/cmd/dep/root_analyzer* @carolynvs -/cmd/dep/testdata/init @carolynvs -/cmd/dep/testdata/harness_tests/init @carolynvs -/internal/importers @carolynvs -/analyzer* @carolynvs -/testdata/analyzer @carolynvs -/internal/feedback @carolynvs - -# ensure -/cmd/dep/ensure* @ibrasho -/cmd/dep/testdata/harness_tests/ensure** @ibrasho - -# status -/cmd/dep/status* @darkowlzz -/cmd/dep/testdata/harness_tests/status** @darkowlzz -/cmd/dep/graphviz* @darkowlzz - -# gps caching -/gps/source_cache* @jmank88 diff --git a/vendor/github.com/golang/dep/.github/ISSUE_TEMPLATE.md b/vendor/github.com/golang/dep/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 3e612d9b2a163c0bef6c08b34baf5e790213e87f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - -Thanks for filing an issue! If this is a question or feature request, just delete -everything here and write out the request, providing as much context as you can. - ---> - -### What version of `dep` are you using (`dep version`)? -<!-- - If you installed `dep` via `go get`, report the version instead with - `cd $GOPATH/src/github.com/golang/dep && git describe --tags` ---> - -### What `dep` command did you run? - -<!-- - -Paste the output of the commands you ran in here, making sure to pass -v for maximum context. - -The output of `dep hash-inputs` may also be helpful to include. - ---> - -### What did you expect to see? - -### What did you see instead? diff --git a/vendor/github.com/golang/dep/.github/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/golang/dep/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index c0668911ffb9ace05c6dfac409aecbb3d3b747b4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,23 +0,0 @@ -<!-- -Work-in-progress PRs are welcome as a way to get early feedback - just prefix -the title with [WIP]. - -Add the change in the changelog (except for test changes and docs updates). -Please edit CHANGELOG.md and add the change under the appropriate category (NEW -FEATURES, IMPROVEMENTS & BUG FIXES) along with the PR number. ---> - -### What does this do / why do we need it? - -### What should your reviewer look out for in this PR? - -### Do you need help or clarification on anything? - -### Which issue(s) does this PR fix? - -<!-- - -fixes # -fixes # - ---> diff --git a/vendor/github.com/golang/dep/.gitignore b/vendor/github.com/golang/dep/.gitignore deleted file mode 100644 index a7c3f4116e6df6c79123c9ccb0e5fa5e5e22f0f0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# dep project generated files to ignore -# if you want to ignore files created by your editor/tools, -# please consider a global .gitignore https://help.github.com/articles/ignoring-files -# please do not open a pull request to add something created by your editor or tools -/dep -/testdep -/dep.exe -/licenseok -/profile.out -/coverage.txt diff --git a/vendor/github.com/golang/dep/.travis.yml b/vendor/github.com/golang/dep/.travis.yml deleted file mode 100644 index 88d434b822a10d48068ebaf2fb6c6f327b34638f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/.travis.yml +++ /dev/null @@ -1,87 +0,0 @@ -language: go -sudo: false -notifications: - email: false -jobs: - include: - - stage: test - go_import_path: github.com/golang/dep - install: - - go get -u github.com/golang/lint/golint honnef.co/go/tools/cmd/megacheck - - npm install -g codeclimate-test-reporter - env: - - DEPTESTBYPASS501=1 - os: linux - go: 1.9.x - script: - - go test -i ./... - - ./hack/lint.bash - - ./hack/validate-vendor.bash - - ./hack/validate-licence.bash - - ./hack/coverage.bash - after_success: - - codeclimate-test-reporter < coverage.txt - # YAML alias, for settings shared across the simpler builds - - &simple-test - go: 1.8.x - stage: test - go_import_path: github.com/golang/dep - install: skip - env: - - DEPTESTBYPASS501=1 - script: go test -race $(go list ./... | grep -v vendor) - - <<: *simple-test - go: tip - - <<: *simple-test - os: osx - go: 1.9.x - install: - # brew takes horribly long to update itself despite the above caching - # attempt; only bzr install if it's not on the $PATH - - test $(which bzr) || brew install bzr - env: - - HOMEBREW_NO_AUTO_UPDATE=1 - - DEPTESTBYPASS501=1 - script: - # OSX as of El Capitan sets an exit trap that interacts poorly with how - # travis seems to spawn these shells; if set -e is set, then it can cause - # build failures. We're not doing that here, but retain the trap statement - # for future safety. - # Related: https://superuser.com/questions/1044130/why-am-i-having-how-can-i-fix-this-error-shell-session-update-command-not-f - - trap EXIT - - go test -race ./... - - go: 1.9.x - stage: deploy - go_import_path: github.com/golang/dep - install: skip - script: skip - before_deploy: - - ./hack/build-all.bash - deploy: - - provider: releases - api_key: - secure: fL9GX11J3JLizEBTPZHN32wuAT91eAJsGl0kjlAdIc6Lb/9UCe1XZGgFnpQFN4qo/S+omhHBDbM6Ty1xhNy7xmjDecpQGDU8Rmap9Oll0TuxqMigG+njOuPp5VUYPofPP0PGKdxAcYg+KaFM7x0o2rK+qA046NHwo2gH1BbE+bn55TZglEajEfc8j9iX4jt96KC7zlu+WiKArLmfUtlrI8m8ZYgbYcvFmlYjeCiEqlNhvNL59ejug9Rl0PLtPbamqVXkGLafYtekgPCb4WSxBiCt8pq5Rb5svk9YcdXpiaWQhZjMPAuKN6BrmN2lw1PiXzADUG5fjvNc8eo2HY70GD2utU9cAsY8VIafhoH5n6uM1WI8MHwDfd7P1PiQA3ZGQ8CPwk4q/8HSfQU9ap7vZgSF63pTIbtlviyIG67orOJE9PWWncl9olYM946UylZu6m3hWI/rmJxOeJ1UJjym/3GNPMRfKubaGhV/TyRdM0bKX4M0cXHU6k/ESVFupGXdKRt4RpvkD4/1Km6b2OShW6PNI+ifFspnJr7obkI7dm7ubySdnNz4lMv9WWymxRpMVc8hUAhuoDvXeZJq7pSnkjBEWDxIRoTkA93CU3/Rf7MFYCJMnGSqjcxWUpIfCAk2/r4BqL9NQnqBvvVt+MYi64QaD5n7ZF3dVbr6HZ2zjSU= - file: - - release/dep-linux-amd64 - - release/dep-linux-amd64.sha256 - - release/dep-darwin-amd64 - - release/dep-darwin-amd64.sha256 - - release/dep-freebsd-amd64 - - release/dep-freebsd-amd64.sha256 - - release/dep-windows-amd64.exe - - release/dep-windows-amd64.exe.sha256 - - release/dep-linux-386 - - release/dep-linux-386.sha256 - - release/dep-darwin-386 - - release/dep-darwin-386.sha256 - - release/dep-freebsd-386 - - release/dep-freebsd-386.sha256 - - release/dep-windows-386.exe - - release/dep-windows-386.exe.sha256 - skip_cleanup: true - on: - repo: golang/dep - branch: master - tags: true -addons: - ssh_known_hosts: github.com diff --git a/vendor/github.com/golang/dep/AUTHORS b/vendor/github.com/golang/dep/AUTHORS deleted file mode 100644 index 15167cd746c560e5b3d3b233a169aa64d3e9101e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/github.com/golang/dep/BUILD.bazel b/vendor/github.com/golang/dep/BUILD.bazel deleted file mode 100644 index e5fa67015561b614abde2a9c800c3c5acb116bf6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/BUILD.bazel +++ /dev/null @@ -1,25 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "analyzer.go", - "context.go", - "doc.go", - "lock.go", - "manifest.go", - "project.go", - "txn_writer.go", - ], - importmap = "vendor/github.com/golang/dep", - importpath = "github.com/golang/dep", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/gps/paths:go_default_library", - "//vendor/github.com/golang/dep/gps/pkgtree:go_default_library", - "//vendor/github.com/golang/dep/internal/fs:go_default_library", - "//vendor/github.com/pelletier/go-toml:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/CHANGELOG.md b/vendor/github.com/golang/dep/CHANGELOG.md deleted file mode 100644 index f169391069ecc64f3ba8ea662238f43022a6b604..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/CHANGELOG.md +++ /dev/null @@ -1,122 +0,0 @@ -# (next version) - -NEW FEATURES: - -BUG FIXES: - -IMPROVEMENTS: - -# v0.4.1 - -BUG FIXES: - -* Fix per-project prune option handling ([#1570](https://github.com/golang/dep/pull/1570)) - -# v0.4.0 - -NEW FEATURES: -* Add support for importing from [glock](https://github.com/robfig/glock) based projects. ([#1422](https://github.com/golang/dep/pull/1422) -* Add support for importing from [govendor](https://github.com/kardianos/govendor) based projects. ([#815](https://github.com/golang/dep/pull/815) -* Allow override of cache directory location using environment variable `DEPCACHEDIR`. ([#1234](https://github.com/golang/dep/pull/1234)) -* Add support for template output in `dep status`. ([#1389](https://github.com/golang/dep/pull/1389) -* Each element in a multi-item TOML array is output on its own line. ([#1461](https://github.com/golang/dep/pull/1461) - -BUG FIXES: - -* Releases targeting Windows now have a `.exe` suffix. ([#1291](https://github.com/golang/dep/pull/1291) -* Adaptively recover from dirty and corrupted git repositories in cache. ([#1279](https://github.com/golang/dep/pull/1279) -* Suppress git password prompts in more places. ([#1357](https://github.com/golang/dep/pull/1357) -* Fix `-no-vendor` flag for `ensure -update`. ([#1361](https://github.com/golang/dep/pull/1361) -* Validate `git ls-remote` output and ignore all malformed lines. ([#1379](https://github.com/golang/dep/pull/1379) -* Support [gopkg.in version zero](http://labix.org/gopkg.in#VersionZero). ([#1243](https://github.com/golang/dep/pull/1243) -* Fix how dep status print revision constraints. ([#1421](https://github.com/golang/dep/pull/1421) -* Add optional `-v` flag to ensure sub command's syntax. ([#1458](https://github.com/golang/dep/pull/1458) -* Allow URLs containing ports in `Gopkg.toml` `source` fields. ([#1509](https://github.com/golang/dep/pull/1509) - -IMPROVEMENTS: - -* Log as dependencies are pre-fetched during dep init. ([#1176](https://github.com/golang/dep/pull/1176)) -* Make the gps package importable. ([#1349](https://github.com/golang/dep/pull/1349)) -* Improve file copy performance by not forcing a file sync. ([#1408](https://github.com/golang/dep/pull/1408) -* Skip empty constraints during import. ([#1414](https://github.com/golang/dep/pull/1349)) -* Handle errors when writing status output. ([#1420](https://github.com/golang/dep/pull/1420)) -* Add constraint for locked projects in `dep status`. ([#962](https://github.com/golang/dep/pull/962) -* Make external config importers error tolerant. ([#1315](https://github.com/golang/dep/pull/1315)) -* Show LATEST and VERSION as the same type in status. ([#1515](https://github.com/golang/dep/pull/1515) -* Warn when [[constraint]] rules that will have no effect. ([#1534](https://github.com/golang/dep/pull/1534)) - -# v0.3.2 - -NEW FEATURES: - -* Add support for importing from [gvt](https://github.com/FiloSottile/gvt) -and [gb](https://godoc.org/github.com/constabulary/gb/cmd/gb-vendor). -(#1149) -* Wildcard ignore support. (#1156) -* Disable SourceManager lock by setting `DEPNOLOCK` environment variable. -(#1206) -* `dep ensure -no-vendor -dry-run` now exits with an error when changes would -have to be made to `Gopkg.lock`. This is useful for CI. (#1256) - -BUG FIXES: - -* gps: Fix case mismatch error with multiple dependers. (#1233) -* Skip broken `vendor` symlink rather than returning an error. (#1191) -* Fix `status` shows incorrect reason for lock mismatch when ignoring packages. -(#1216) - -IMPROVEMENTS: - -* Allow `dep ensure -add` and `-update` when lock is out-of-sync. (#1225) -* gps: vcs: Dedupe git version list (#1212) -* gps: Add prune functions to gps. (#1020) -* gps: Skip broken vendor symlinks. (#1191) -* `dep ensure -add` now concurrently fetches the source and adds the projects. -(#1218) -* File name case check is now performed on `Gopkg.toml` and `Gopkg.lock`. -(#1114) -* gps: gps now supports pruning. (#1020) -* `dep ensure -update` now concurrently validates the passed project arguments. -Improving performance when updating dependencies with `-update`. (#1175) -* `dep status` now concurrently fetches repo info. Improving status performance. -(#1135) -* gps: Add SourceURLsForPath() to SourceManager. (#1166) -* gps: Include output in error. (#1180) - -WIP: - -* gps: Process canonical import paths. (#1017) -* gps: Persistent cache. (#1127, #1215) - - -# v0.3.1 - -* gps: Add satisfiability check for case variants (#1079) -* Validate Project Roots in manifest (#1116) -* gps: Properly separate sources for different gopkg.in versions & github -(#1132) -* gps: Add persistent BoltDB cache (#1098) -* gps: Increase default subcommand timeout to 30s (#1087) -* Fix importer [issue](https://github.com/golang/dep/issues/939) where the -importer would drop the imported version of a project (#1100) -* Import analyzer now always uses the same name, fixing the lock mismatch -immediately after dep init issue (#1099) -* Add support for importing from [govend](https://github.com/govend/govend) -(#1040) and [LK4D4/vndr](https://github.com/LK4D4/vndr) (#978) based projects -* gps: gps no longer assumes that every git repo has a HEAD (#1053) -* `os.Chmod` failures on Windows due to long path length has been fixed (#925) -* Add `version` command (#996) -* Drop support for building with go1.7 (#714) -* gps: Parse abbreviated git revisions (#1027) -* gps: Parallelize writing dep tree (#1021) -* `status` now shows the progress in verbose mode (#1009, #1037) -* Fix empty `Constraint` and `Version` in `status` json output (#976) -* `status` table output now shows override constraints (#918) -* gps: Display warning message every 15 seconds when lockfile is busy (#958) -* gps: Hashing directory tree and tree verification (#959) -* `ensure` now has `-vendor-only` mode to populate vendor/ without updating -Gopkg.lock (#954) -* Use fork of Masterminds/semver until -Masterminds/semver [issue#59](https://github.com/Masterminds/semver/issues/59) -is fixed upstream (#938) -* gps: Ensure packages are deducible before attempting to solve (#697) diff --git a/vendor/github.com/golang/dep/CODE_OF_CONDUCT.md b/vendor/github.com/golang/dep/CODE_OF_CONDUCT.md deleted file mode 100644 index 660ee848e25fb13d9815ee03a5bb721b3cc3eb6f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of -experience, nationality, personal appearance, race, religion, or sexual identity -and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, or to ban temporarily or permanently any -contributor for other behaviors that they deem inappropriate, threatening, -offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at sam (at) samboyer.org. All complaints -will be reviewed and investigated and will result in a response that is deemed -necessary and appropriate to the circumstances. The project team is obligated to -maintain confidentiality with regard to the reporter of an incident. Further -details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/golang/dep/CONTRIBUTING.md b/vendor/github.com/golang/dep/CONTRIBUTING.md deleted file mode 100644 index 2a0e7b2855b837f653e64a966d34d4ff3800d34f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/CONTRIBUTING.md +++ /dev/null @@ -1,109 +0,0 @@ -# Contributing to `dep` - -`dep` is an open source project. - -It is the work of hundreds of contributors. We appreciate your help! - -Keep an eye on the [Roadmap](https://github.com/golang/dep/wiki/Roadmap) for a summary of where the project is, and where we're headed. - -## Filing issues - -Please check the existing issues and [FAQ](docs/FAQ.md) to see if your feedback has already been reported. - -When [filing an issue](https://github.com/golang/dep/issues/new), make sure to answer these five questions: - -1. What version of Go (`go version`) and `dep` (`git describe --tags`) are you using?? -3. What `dep` command did you run? -4. What did you expect to see? -5. What did you see instead? - -General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. -The gophers there will answer or ask you to file an issue if you've tripped over a bug. - -## Contributing code - -Let us know if you are interested in working on an issue by leaving a comment -on the issue in GitHub. This helps avoid multiple people unknowingly -working on the same issue. - -Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) -before sending patches. - -The -[help wanted](https://github.com/golang/dep/issues?q=is%3Aissue+is%3Aopen+label%3A%22help%20wanted%22) -label highlights issues that are well-suited for folks to jump in on. The -[good first issue](https://github.com/golang/dep/issues?q=is%3Aissue+is%3Aopen+label%3A%22good%20first%20issue%22) -label further identifies issues that are particularly well-sized for newcomers. - -Unless otherwise noted, the `dep` source files are distributed under -the BSD-style license found in the LICENSE file. - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult [GitHub Help] for more -information on using pull requests. - -We check `dep`'s own `vendor` directory into git. For any PR to `dep` where you're -updating `Gopkg.toml`, make sure to run `dep ensure` and -([for now](https://github.com/golang/dep/issues/944)) `dep prune` and commit all -changes to `vendor`. - -[GitHub Help]: https://help.github.com/articles/about-pull-requests/ - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution, -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to <https://cla.developers.google.com/> to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Maintainer's Guide - -`dep` has subsystem maintainers; this guide is intended for them in performing their work as a maintainer. - -### General guidelines - -* _Be kind, respectful, and inclusive_. Really live [that CoC](https://github.com/golang/dep/blob/master/CODE_OF_CONDUCT.md). We've developed a reputation as one of the most welcoming and supportive project environments in the Go community, and we want to keep that up! -* The lines of responsibility between maintainership areas can be fuzzy. Get to know your fellow maintainers - it's important to work _with_ them when an issue falls in this grey area. -* Remember, the long-term goal of `dep` is to disappear into the `go` toolchain. That's going to be a challenging process, no matter what. Minimizing that eventual difficulty should be a guiding light for all your decisions today. - * Try to match the toolchain's assumptions as closely as possible ([example](https://github.com/golang/dep/issues/564#issuecomment-300994599)), and avoid introducing new rules the toolchain would later have to incorporate. - * Every new flag or option in the metadata files is more exposed surface area that demands conversion later. Only add these with a clear design plan. - * `dep` is experimental, but increasingly only on a larger scale. Experiments need clear hypotheses and parameters for testing - nothing off-the-cuff. -* Being a maintainer doesn't mean you're always right. Admitting when you've made a mistake keeps the code flowing, the environment health, and the respect level up. -* It's fine if you need to step back from maintainership responsibilities - just, please, don't fade away! Let other maintainers know what's going on. - -### Issue management - -* We use [Zenhub](https://www.zenhub.com) to manage the queue, in addition to what we do with labels. - * You will need to install [ZenHub extension](https://www.zenhub.com/extension) to your browser to show the board. - * Pipelines, and [the board](https://github.com/golang/dep#boards) are one thing we try to utilize: - * **New Issues Pipeline**: When someone creates a new issue, it goes here first. Keep an eye out for issues that fall into your area. Add labels to them, and if it's something we should do, put it in the `Backlog` pipeline. If you aren't sure, throw it in the `Icebox`. It helps to sort this pipeline by date. - * **Icebox Pipeline**: Issues that we aren't immediately closing but aren't really ready to be prioritized and started on. It's not a wontfix bucket, but a "not sure if we should/can fix right now" bucket. - * **Backlog Pipeline**: Issues that we know we want to tackle. You can drag/drop up and down to prioritize issues. - * Marking dependencies/blockers is also quite useful where appropriate; please do that. - * We use epics and milestones in roughly the same way (because OSS projects don't have real sprints). Epics should be duplicated as milestones; if there's a main epic issue, it should contain a checklist of the relevant issues to complete it. -* The `area:` labels correspond to maintainership areas. Apply yours to any issues or PRs that fall under your purview. It's to be expected that multiple `area:` labels may be applied to a single issue. -* The [`help wanted`](https://github.com/golang/dep/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [`good first issue`](https://github.com/golang/dep/labels/good%20first%20issue) labels are two of our most important tools for making the project accessible to newcomers - a key goal for our community. Here's how to use them well. - * `good-first-pr` should be applied when there's a very straightforward, self-contained task that is very unlikely to have any hidden complexity. The real purpose of these is to provide a "chink in the armor", providing newcomers a lens through which to start understanding the project. - * `help-wanted` should be applied to issues where there's a clear, stated goal, there is at most one significant question that needs answering, and it looks like the implementation won't be inordinately difficult, or disruptive to other parts of the system. - * `help-wanted` should also be applied to all `good-first-pr` issues - it's duplicative, but not doing so seems unfriendly. - - -### Pull Requests - -* Try to make, and encourage, smaller pull requests. -* [No is temporary. Yes is forever.](https://blog.jessfraz.com/post/the-art-of-closing/) -* Long-running feature branches should generally be avoided. Discuss it with other maintainers first. -* Unless it's trivial, don't merge your own PRs - ask another maintainer. -* Commit messages should follow [Tim Pope's rules](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -* Checklist for merging PRs: - * Does the PR pass [the code review comments](https://github.com/golang/go/wiki/CodeReviewComments)? (internalize these rules!) - * Are there tests to cover new or changed behavior? Prefer reliable tests > no tests > flaky tests. - * Does the first post in the PR contain "Fixes #..." text for any issues it resolves? - * Are any necessary follow-up issues _already_ posted, prior to merging? - * Does this change entail the updating of any docs? - * For docs kept in the repo, e.g. FAQ.md, docs changes _must_ be submitted as part of the same PR. diff --git a/vendor/github.com/golang/dep/CONTRIBUTORS b/vendor/github.com/golang/dep/CONTRIBUTORS deleted file mode 100644 index 1c4577e9680611383f46044d17fa343a96997c3c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# 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. diff --git a/vendor/github.com/golang/dep/Gopkg.lock b/vendor/github.com/golang/dep/Gopkg.lock deleted file mode 100644 index 1779ee42072dcdb018f85ec43f6050b014e1652c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/Gopkg.lock +++ /dev/null @@ -1,94 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "parse-constraints-with-dash-in-pre" - name = "github.com/Masterminds/semver" - packages = ["."] - revision = "a93e51b5a57ef416dac8bb02d11407b6f55d8929" - source = "https://github.com/carolynvs/semver.git" - -[[projects]] - name = "github.com/Masterminds/vcs" - packages = ["."] - revision = "3084677c2c188840777bff30054f2b553729d329" - version = "v1.11.1" - -[[projects]] - branch = "master" - name = "github.com/armon/go-radix" - packages = ["."] - revision = "4239b77079c7b5d1243b7b4736304ce8ddb6f0f2" - -[[projects]] - name = "github.com/boltdb/bolt" - packages = ["."] - revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8" - version = "v1.3.1" - -[[projects]] - branch = "v2" - name = "github.com/go-yaml/yaml" - packages = ["."] - revision = "cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b" - -[[projects]] - branch = "master" - name = "github.com/golang/protobuf" - packages = ["proto"] - revision = "5afd06f9d81a86d6e3bb7dc702d6bd148ea3ff23" - -[[projects]] - name = "github.com/jmank88/nuts" - packages = ["."] - revision = "8b28145dffc87104e66d074f62ea8080edfad7c8" - version = "v0.3.0" - -[[projects]] - branch = "master" - name = "github.com/nightlyone/lockfile" - packages = ["."] - revision = "e83dc5e7bba095e8d32fb2124714bf41f2a30cb5" - -[[projects]] - branch = "master" - name = "github.com/pelletier/go-toml" - packages = ["."] - revision = "b8b5e7696574464b2f9bf303a7b37781bb52889f" - -[[projects]] - name = "github.com/pkg/errors" - packages = ["."] - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - branch = "master" - name = "github.com/sdboyer/constext" - packages = ["."] - revision = "836a144573533ea4da4e6929c235fd348aed1c80" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = ["context"] - revision = "66aacef3dd8a676686c7ae3716979581e8b03c47" - -[[projects]] - branch = "master" - name = "golang.org/x/sync" - packages = ["errgroup"] - revision = "f52d1811a62927559de87708c8913c1650ce4f26" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "bb24a47a89eac6c1227fbcb2ae37a8b9ed323366" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "e70d26b359aed7af66f3393fc9d4985bbcf499c0b5ed3b5661a5912b4c71a32e" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/golang/dep/Gopkg.toml b/vendor/github.com/golang/dep/Gopkg.toml deleted file mode 100644 index 1bec06d061a34328981d161d73d24bd3ff972c88..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/Gopkg.toml +++ /dev/null @@ -1,37 +0,0 @@ -[[constraint]] - branch = "parse-constraints-with-dash-in-pre" - name = "github.com/Masterminds/semver" - source = "https://github.com/carolynvs/semver.git" - -[[constraint]] - name = "github.com/Masterminds/vcs" - version = "1.11.0" - -[[constraint]] - branch = "v2" - name = "github.com/go-yaml/yaml" - -[[constraint]] - branch = "master" - name = "github.com/pelletier/go-toml" - -[[constraint]] - name = "github.com/pkg/errors" - version = "0.8.0" - -[[constraint]] - name = "github.com/boltdb/bolt" - version = "1.0.0" - -[[constraint]] - name = "github.com/jmank88/nuts" - version = "0.3.0" - -[[constraint]] - name = "github.com/golang/protobuf" - branch = "master" - -[prune] - non-go = true - go-tests = true - unused-packages = true diff --git a/vendor/github.com/golang/dep/LICENSE b/vendor/github.com/golang/dep/LICENSE deleted file mode 100644 index a2dd15faf469eeca454eb7a47341568f0ac3e504..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2014 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/golang/dep/MAINTAINERS.md b/vendor/github.com/golang/dep/MAINTAINERS.md deleted file mode 100644 index 9b985c389e8df9f1d2538e274112f7f36b20bb45..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/MAINTAINERS.md +++ /dev/null @@ -1,17 +0,0 @@ - -General maintainers: - sam boyer (@sdboyer) - -* dep - * `init` command: Carolyn Van Slyck (@carolynvs) - * `ensure` command: Ibrahim AshShohail (@ibrasho) - * `status` command: Sunny (@darkowlzz) - * testing harness: (vacant) -* gps - * solver: (vacant) - * source manager: (vacant) - * root deduction: (vacant) - * source/vcs interaction: (vacant) - * caching: Jordan Krage (@jmank88) - * pkgtree: (vacant) - * versions and constraints: (vacant) diff --git a/vendor/github.com/golang/dep/PATENTS b/vendor/github.com/golang/dep/PATENTS deleted file mode 100644 index 733099041f84fa1e58611ab2e11af51c1f26d1d2..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google 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, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/github.com/golang/dep/README.md b/vendor/github.com/golang/dep/README.md deleted file mode 100644 index 49e407dfdac9fe25d22070e8e23234d3f38799a3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/README.md +++ /dev/null @@ -1,47 +0,0 @@ -<p align="center"><img src="docs/assets/DigbyShadows.png" width="360"></p> -<p align="center"> - <a href="https://travis-ci.org/golang/dep"><img src="https://travis-ci.org/golang/dep.svg?branch=master" alt="Build Status"></img></a> - <a href="https://ci.appveyor.com/project/golang/dep"><img src="https://ci.appveyor.com/api/projects/status/github/golang/dep?svg=true&branch=master&passingText=Windows%20-%20OK&failingText=Windows%20-%20failed&pendingText=Windows%20-%20pending" alt="Windows Build Status"></a> - <a href="https://goreportcard.com/report/github.com/golang/dep"><img src="https://goreportcard.com/badge/github.com/golang/dep" /></a> -</p> - -## Dep - -`dep` is a prototype dependency management tool for Go. It requires Go 1.8 or newer to compile. **`dep` is safe for production use.** - -`dep` is the official _experiment_, but not yet the official tool. Check out the [Roadmap](https://github.com/golang/dep/wiki/Roadmap) for more on what this means! - -For guides and reference materials about `dep`, see [the documentation](https://golang.github.io/dep). - -## Installation - -It is strongly recommended that you use a released version. Release binaries are available on the [releases](https://github.com/golang/dep/releases) page. - -On MacOS you can install or upgrade to the latest released version with Homebrew: - -```sh -$ brew install dep -$ brew upgrade dep -``` - -If you're interested in hacking on `dep`, you can install via `go get`: - -```sh -go get -u github.com/golang/dep/cmd/dep -``` - -## Feedback - -Feedback is greatly appreciated. -At this stage, the maintainers are most interested in feedback centered on the user experience (UX) of the tool. -Do you have workflows that the tool supports well, or doesn't support at all? -Do any of the commands have surprising effects, output, or results? -If not, please file an issue, describing what you did or wanted to do, what you expected to happen, and what actually happened. - -## Contributing - -Contributions are greatly appreciated. -The maintainers actively manage the issues list, and try to highlight issues suitable for newcomers. -The project follows the typical GitHub pull request model. -See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. -Before starting any work, please either comment on an existing issue, or file a new one. diff --git a/vendor/github.com/golang/dep/analyzer.go b/vendor/github.com/golang/dep/analyzer.go deleted file mode 100644 index 1d0b920ec51796be0308d48eac6228a2cc4e9591..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/analyzer.go +++ /dev/null @@ -1,53 +0,0 @@ -// 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 dep - -import ( - "os" - "path/filepath" - - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/fs" -) - -// Analyzer implements gps.ProjectAnalyzer. -type Analyzer struct{} - -// HasDepMetadata determines if a dep manifest exists at the specified path. -func (a Analyzer) HasDepMetadata(path string) bool { - mf := filepath.Join(path, ManifestName) - fileOK, err := fs.IsRegular(mf) - return err == nil && fileOK -} - -// DeriveManifestAndLock reads and returns the manifest at path/ManifestName or nil if one is not found. -// The Lock is always nil for now. -func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) { - if !a.HasDepMetadata(path) { - return nil, nil, nil - } - - f, err := os.Open(filepath.Join(path, ManifestName)) - if err != nil { - return nil, nil, err - } - defer f.Close() - - // Ignore warnings irrelevant to user. - m, _, err := readManifest(f) - if err != nil { - return nil, nil, err - } - - return m, nil, nil -} - -// Info returns Analyzer's name and version info. -func (a Analyzer) Info() gps.ProjectAnalyzerInfo { - return gps.ProjectAnalyzerInfo{ - Name: "dep", - Version: 1, - } -} diff --git a/vendor/github.com/golang/dep/appveyor.yml b/vendor/github.com/golang/dep/appveyor.yml deleted file mode 100644 index fb07653a742a8d858bfccb5bbb638a441710edbd..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/appveyor.yml +++ /dev/null @@ -1,34 +0,0 @@ -version: "{build}" - -# Source Config - -clone_folder: c:\gopath\src\github.com\golang\dep - -# Build host - -environment: - GOPATH: c:\gopath - DEPTESTBYPASS501: 1 - GOVERSION: 1.8 - -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 build github.com/golang/dep/cmd/dep - - for /f "" %%G in ('go list github.com/golang/dep/... ^| find /i /v "/vendor/"') do ( go test %%G & IF ERRORLEVEL == 1 EXIT 1) diff --git a/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel b/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel deleted file mode 100644 index 69276c90879818b0f1c81b25ce3b032c3413579c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel +++ /dev/null @@ -1,39 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "doc.go", - "ensure.go", - "failures.go", - "gopath_scanner.go", - "graphviz.go", - "hash_in.go", - "init.go", - "main.go", - "prune.go", - "root_analyzer.go", - "status.go", - "version.go", - ], - importmap = "vendor/github.com/golang/dep/cmd/dep", - importpath = "github.com/golang/dep/cmd/dep", - visibility = ["//visibility:private"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/gps/paths:go_default_library", - "//vendor/github.com/golang/dep/gps/pkgtree:go_default_library", - "//vendor/github.com/golang/dep/internal/feedback:go_default_library", - "//vendor/github.com/golang/dep/internal/fs:go_default_library", - "//vendor/github.com/golang/dep/internal/importers:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - "//vendor/golang.org/x/sync/errgroup:go_default_library", - ], -) - -go_binary( - name = "dep", - embed = [":go_default_library"], - visibility = ["//visibility:public"], -) diff --git a/vendor/github.com/golang/dep/cmd/dep/doc.go b/vendor/github.com/golang/dep/cmd/dep/doc.go deleted file mode 100644 index 7d5afdcea1eeb2c74f6e8dc7c3cbf14a9d50c580..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/doc.go +++ /dev/null @@ -1,143 +0,0 @@ -// 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. - -// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh. -// Edit the documentation in other files and rerun mkdoc.sh to generate this one. - -// Dep is a tool for managing dependencies for Go projects -// -// Usage: "dep [command]" -// -// Commands: -// -// init Initialize a new project with manifest and lock files -// status Report the status of the project's dependencies -// ensure Ensure a dependency is safely vendored in the project -// prune Prune the vendor tree of unused packages -// version Show the dep version information -// -// Examples: -// dep init set up a new project -// dep ensure install the project's dependencies -// dep ensure -update update the locked versions of all dependencies -// dep ensure -add github.com/pkg/errors add a dependency to the project -// -// Use "dep help [command]" for more information about a command. -// -// Initialize a new project with manifest and lock files -// -// Usage: -// -// init [root] -// -// Initialize the project at filepath root by parsing its dependencies, writing -// manifest and lock files, and vendoring the dependencies. If root isn't -// specified, use the current directory. -// -// When configuration for another dependency management tool is detected, it is -// imported into the initial manifest and lock. Use the -skip-tools flag to -// disable this behavior. The following external tools are supported: -// glide, godep, vndr, govend, gb, gvt, glock. -// -// Any dependencies that are not constrained by external configuration use the -// GOPATH analysis below. -// -// By default, the dependencies are resolved over the network. A version will be -// selected from the versions available from the upstream source per the following -// algorithm: -// -// - Tags conforming to semver (sorted by semver rules) -// - Default branch(es) (sorted lexicographically) -// - Non-semver tags (sorted lexicographically) -// -// An alternate mode can be activated by passing -gopath. In this mode, the version -// of each dependency will reflect the current state of the GOPATH. If a dependency -// doesn't exist in the GOPATH, a version will be selected based on the above -// network version selection algorithm. -// -// A Gopkg.toml file will be written with inferred version constraints for all -// direct dependencies. Gopkg.lock will be written with precise versions, and -// vendor/ will be populated with the precise versions written to Gopkg.lock. -// -// -// Report the status of the project's dependencies -// -// Usage: -// -// status [package...] -// -// With no arguments, print the status of each dependency of the project. -// -// PROJECT Import path -// CONSTRAINT Version constraint, from the manifest -// VERSION Version chosen, from the lock -// REVISION VCS revision of the chosen version -// LATEST Latest VCS revision available -// PKGS USED Number of packages from this project that are actually used -// -// With one or more explicitly specified packages, or with the -detailed flag, -// print an extended status output for each dependency of the project. -// -// TODO Another column description -// FOOBAR Another column description -// -// Status returns exit code zero if all dependencies are in a "good state". -// -// -// Ensure a dependency is safely vendored in the project -// -// Usage: -// -// ensure [-update | -add] [-no-vendor | -vendor-only] [-dry-run] [<spec>...] -// -// Project spec: -// -// <import path>[:alt source URL][@<constraint>] -// -// -// Ensure gets a project into a complete, reproducible, and likely compilable state: -// -// * All non-stdlib imports are fulfilled -// * All rules in Gopkg.toml are respected -// * Gopkg.lock records precise versions for all dependencies -// * vendor/ is populated according to Gopkg.lock -// -// Ensure has fast techniques to determine that some of these steps may be -// unnecessary. If that determination is made, ensure may skip some steps. Flags -// may be passed to bypass these checks; -vendor-only will allow an out-of-date -// Gopkg.lock to populate vendor/, and -no-vendor will update Gopkg.lock (if -// needed), but never touch vendor/. -// -// The effect of passing project spec arguments varies slightly depending on the -// combination of flags that are passed. -// -// -// Examples: -// -// dep ensure Populate vendor from existing Gopkg.toml and Gopkg.lock -// dep ensure -add github.com/pkg/foo Introduce a named dependency at its newest version -// dep ensure -add github.com/pkg/foo@^1.0.1 Introduce a named dependency with a particular constraint -// -// For more detailed usage examples, see dep ensure -examples. -// -// -// Prune the vendor tree of unused packages -// -// Usage: -// -// prune -// -// Prune is used to remove unused packages from your vendor tree. -// -// STABILITY NOTICE: this command creates problems for vendor/ verification. As -// such, it may be removed and/or moved out into a separate project later on. -// -// -// Show the dep version information -// -// Usage: -// -// version -// -package main diff --git a/vendor/github.com/golang/dep/cmd/dep/ensure.go b/vendor/github.com/golang/dep/cmd/dep/ensure.go deleted file mode 100644 index f2cd7081558f7f1f7afaf27f139bdb41d2036889..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/ensure.go +++ /dev/null @@ -1,917 +0,0 @@ -// 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 main - -import ( - "bytes" - "context" - "flag" - "fmt" - "go/build" - "io/ioutil" - "log" - "os" - "path/filepath" - "sort" - "strings" - "sync" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/paths" - "github.com/golang/dep/gps/pkgtree" - "github.com/pkg/errors" -) - -const ensureShortHelp = `Ensure a dependency is safely vendored in the project` -const ensureLongHelp = ` -Project spec: - - <import path>[:alt source URL][@<constraint>] - - -Ensure gets a project into a complete, reproducible, and likely compilable state: - - * All non-stdlib imports are fulfilled - * All rules in Gopkg.toml are respected - * Gopkg.lock records precise versions for all dependencies - * vendor/ is populated according to Gopkg.lock - -Ensure has fast techniques to determine that some of these steps may be -unnecessary. If that determination is made, ensure may skip some steps. Flags -may be passed to bypass these checks; -vendor-only will allow an out-of-date -Gopkg.lock to populate vendor/, and -no-vendor will update Gopkg.lock (if -needed), but never touch vendor/. - -The effect of passing project spec arguments varies slightly depending on the -combination of flags that are passed. - - -Examples: - - dep ensure Populate vendor from existing Gopkg.toml and Gopkg.lock - dep ensure -add github.com/pkg/foo Introduce a named dependency at its newest version - dep ensure -add github.com/pkg/foo@^1.0.1 Introduce a named dependency with a particular constraint - -For more detailed usage examples, see dep ensure -examples. -` -const ensureExamples = ` -dep ensure - - Solve the project's dependency graph, and place all dependencies in the - vendor folder. If a dependency is in the lock file, use the version - specified there. Otherwise, use the most recent version that can satisfy the - constraints in the manifest file. - -dep ensure -vendor-only - - Write vendor/ from an existing Gopkg.lock file, without first verifying that - the lock is in sync with imports and Gopkg.toml. (This may be useful for - e.g. strategically layering a Docker images) - -dep ensure -add github.com/pkg/foo github.com/pkg/foo/bar - - Introduce one or more dependencies, at their newest version, ensuring that - specific packages are present in Gopkg.lock and vendor/. Also, append a - corresponding constraint to Gopkg.toml. - - Note: packages introduced in this way will disappear on the next "dep - ensure" if an import statement is not added first. - -dep ensure -add github.com/pkg/foo/subpkg@1.0.0 bitbucket.org/pkg/bar/baz@master - - Append version constraints to Gopkg.toml for one or more packages, if no - such rules already exist. - - If the named packages are not already imported, also ensure they are present - in Gopkg.lock and vendor/. As in the preceding example, packages introduced - in this way will disappear on the next "dep ensure" if an import statement - is not added first. - -dep ensure -add github.com/pkg/foo:git.internal.com/alt/foo - - Specify an alternate location to treat as the upstream source for a dependency. - -dep ensure -update github.com/pkg/foo github.com/pkg/bar - - Update a list of dependencies to the latest versions allowed by Gopkg.toml, - ignoring any versions recorded in Gopkg.lock. Write the results to - Gopkg.lock and vendor/. - -dep ensure -update - - Update all dependencies to the latest versions allowed by Gopkg.toml, - ignoring any versions recorded in Gopkg.lock. Update the lock file with any - changes. (NOTE: Not recommended. Updating one/some dependencies at a time is - preferred.) - -dep ensure -update -no-vendor - - As above, but only modify Gopkg.lock; leave vendor/ unchanged. - -dep ensure -no-vendor -dry-run - - This fails with a non zero exit code if Gopkg.lock is not up to date with - the Gopkg.toml or the project imports. It can be useful to run this during - CI to check if Gopkg.lock is up to date. - -` - -var ( - errUpdateArgsValidation = errors.New("update arguments validation failed") - errAddDepsFailed = errors.New("adding dependencies failed") -) - -func (cmd *ensureCommand) Name() string { return "ensure" } -func (cmd *ensureCommand) Args() string { - return "[-update | -add] [-no-vendor | -vendor-only] [-dry-run] [-v] [<spec>...]" -} -func (cmd *ensureCommand) ShortHelp() string { return ensureShortHelp } -func (cmd *ensureCommand) LongHelp() string { return ensureLongHelp } -func (cmd *ensureCommand) Hidden() bool { return false } - -func (cmd *ensureCommand) Register(fs *flag.FlagSet) { - fs.BoolVar(&cmd.examples, "examples", false, "print detailed usage examples") - fs.BoolVar(&cmd.update, "update", false, "update the named dependencies (or all, if none are named) in Gopkg.lock to the latest allowed by Gopkg.toml") - fs.BoolVar(&cmd.add, "add", false, "add new dependencies, or populate Gopkg.toml with constraints for existing dependencies") - fs.BoolVar(&cmd.vendorOnly, "vendor-only", false, "populate vendor/ from Gopkg.lock without updating it first") - fs.BoolVar(&cmd.noVendor, "no-vendor", false, "update Gopkg.lock (if needed), but do not update vendor/") - fs.BoolVar(&cmd.dryRun, "dry-run", false, "only report the changes that would be made") -} - -type ensureCommand struct { - examples bool - update bool - add bool - noVendor bool - vendorOnly bool - dryRun bool -} - -func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error { - if cmd.examples { - ctx.Err.Println(strings.TrimSpace(ensureExamples)) - return nil - } - - if err := cmd.validateFlags(); err != nil { - return err - } - - p, err := ctx.LoadProject() - if err != nil { - return err - } - - sm, err := ctx.SourceManager() - if err != nil { - return err - } - sm.UseDefaultSignalHandling() - defer sm.Release() - - if err := dep.ValidateProjectRoots(ctx, p.Manifest, sm); err != nil { - return err - } - - params := p.MakeParams() - if ctx.Verbose { - params.TraceLogger = ctx.Err - } - - if cmd.vendorOnly { - return cmd.runVendorOnly(ctx, args, p, sm, params) - } - - params.RootPackageTree, err = p.ParseRootPackageTree() - if err != nil { - return err - } - - if fatal, err := checkErrors(params.RootPackageTree.Packages, p.Manifest.IgnoredPackages()); err != nil { - if fatal { - return err - } else if ctx.Verbose { - ctx.Out.Println(err) - } - } - if ineffs := p.FindIneffectualConstraints(sm); len(ineffs) > 0 { - ctx.Err.Printf("Warning: the following project(s) have [[constraint]] stanzas in %s:\n\n", dep.ManifestName) - for _, ineff := range ineffs { - ctx.Err.Println(" ✗ ", ineff) - } - // TODO(sdboyer) lazy wording, it does not mention ignores at all - ctx.Err.Printf("\nHowever, these projects are not direct dependencies of the current project:\n") - ctx.Err.Printf("they are not imported in any .go files, nor are they in the 'required' list in\n") - ctx.Err.Printf("%s. Dep only applies [[constraint]] rules to direct dependencies, so\n", dep.ManifestName) - ctx.Err.Printf("these rules will have no effect.\n\n") - ctx.Err.Printf("Either import/require packages from these projects so that they become direct\n") - ctx.Err.Printf("dependencies, or convert each [[constraint]] to an [[override]] to enforce rules\n") - ctx.Err.Printf("on these projects, if they happen to be transitive dependencies,\n\n") - } - - if cmd.add { - return cmd.runAdd(ctx, args, p, sm, params) - } else if cmd.update { - return cmd.runUpdate(ctx, args, p, sm, params) - } - return cmd.runDefault(ctx, args, p, sm, params) -} - -func (cmd *ensureCommand) validateFlags() error { - if cmd.add && cmd.update { - return errors.New("cannot pass both -add and -update") - } - - if cmd.vendorOnly { - if cmd.update { - return errors.New("-vendor-only makes -update a no-op; cannot pass them together") - } - if cmd.add { - return errors.New("-vendor-only makes -add a no-op; cannot pass them together") - } - if cmd.noVendor { - // TODO(sdboyer) can't think of anything not snarky right now - return errors.New("really?") - } - } - return nil -} - -func (cmd *ensureCommand) vendorBehavior() dep.VendorBehavior { - if cmd.noVendor { - return dep.VendorNever - } - return dep.VendorOnChanged -} - -func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { - // Bare ensure doesn't take any args. - if len(args) != 0 { - return errors.New("dep ensure only takes spec arguments with -add or -update") - } - - if err := ctx.ValidateParams(sm, params); err != nil { - return err - } - - solver, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "prepare solver") - } - - if p.Lock != nil && bytes.Equal(p.Lock.InputsDigest(), solver.HashInputs()) { - // Memo matches, so there's probably nothing to do. - if ctx.Verbose { - ctx.Out.Printf("%s was already in sync with imports and %s\n", dep.LockName, dep.ManifestName) - } - - if cmd.noVendor { - // The user said not to touch vendor/, so definitely nothing to do. - return nil - } - - // TODO(sdboyer) The desired behavior at this point is to determine - // whether it's necessary to write out vendor, or if it's already - // consistent with the lock. However, we haven't yet determined what - // that "verification" is supposed to look like (#121); in the meantime, - // we unconditionally write out vendor/ so that `dep ensure`'s behavior - // is maximally compatible with what it will eventually become. - sw, err := dep.NewSafeWriter(nil, p.Lock, p.Lock, dep.VendorAlways, p.Manifest.PruneOptions) - if err != nil { - return err - } - - if cmd.dryRun { - return sw.PrintPreparedActions(ctx.Out, ctx.Verbose) - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - return errors.WithMessage(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor") - } - - if cmd.noVendor && cmd.dryRun { - return errors.New("Gopkg.lock was not up to date") - } - - solution, err := solver.Solve(context.TODO()) - if err != nil { - return handleAllTheFailuresOfTheWorld(err) - } - - sw, err := dep.NewSafeWriter(nil, p.Lock, dep.LockFromSolution(solution), cmd.vendorBehavior(), p.Manifest.PruneOptions) - if err != nil { - return err - } - if cmd.dryRun { - return sw.PrintPreparedActions(ctx.Out, ctx.Verbose) - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - return errors.Wrap(sw.Write(p.AbsRoot, sm, false, logger), "grouped write of manifest, lock and vendor") -} - -func (cmd *ensureCommand) runVendorOnly(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { - if len(args) != 0 { - return errors.Errorf("dep ensure -vendor-only only populates vendor/ from %s; it takes no spec arguments", dep.LockName) - } - - if p.Lock == nil { - return errors.Errorf("no %s exists from which to populate vendor/", dep.LockName) - } - // Pass the same lock as old and new so that the writer will observe no - // difference and choose not to write it out. - sw, err := dep.NewSafeWriter(nil, p.Lock, p.Lock, dep.VendorAlways, p.Manifest.PruneOptions) - if err != nil { - return err - } - - if cmd.dryRun { - return sw.PrintPreparedActions(ctx.Out, ctx.Verbose) - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - return errors.WithMessage(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor") -} - -func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { - if p.Lock == nil { - return errors.Errorf("-update works by updating the versions recorded in %s, but %s does not exist", dep.LockName, dep.LockName) - } - - if err := ctx.ValidateParams(sm, params); err != nil { - return err - } - - // We'll need to discard this prepared solver as later work changes params, - // but solver preparation is cheap and worth doing up front in order to - // perform the fastpath check of hash comparison. - solver, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "fastpath solver prepare") - } - - // Compare the hashes. If they're not equal, bail out and ask the user to - // run a straight `dep ensure` before updating. This is handholding the - // user a bit, but the extra effort required is minimal, and it ensures the - // user is isolating variables in the event of solve problems (was it the - // "pending" changes, or the -update that caused the problem?). - if !bytes.Equal(p.Lock.InputsDigest(), solver.HashInputs()) { - ctx.Out.Printf("Warning: %s is out of sync with %s or the project's imports.", dep.LockName, dep.ManifestName) - } - - // When -update is specified without args, allow every dependency to change - // versions, regardless of the lock file. - if len(args) == 0 { - params.ChangeAll = true - } - - if err := validateUpdateArgs(ctx, args, p, sm, ¶ms); err != nil { - return err - } - - // Re-prepare a solver now that our params are complete. - solver, err = gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "fastpath solver prepare") - } - solution, err := solver.Solve(context.TODO()) - if err != nil { - // TODO(sdboyer) special handling for warning cases as described in spec - // - e.g., named projects did not upgrade even though newer versions - // were available. - return handleAllTheFailuresOfTheWorld(err) - } - - sw, err := dep.NewSafeWriter(nil, p.Lock, dep.LockFromSolution(solution), cmd.vendorBehavior(), p.Manifest.PruneOptions) - if err != nil { - return err - } - if cmd.dryRun { - return sw.PrintPreparedActions(ctx.Out, ctx.Verbose) - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - return errors.Wrap(sw.Write(p.AbsRoot, sm, false, logger), "grouped write of manifest, lock and vendor") -} - -func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { - if len(args) == 0 { - return errors.New("must specify at least one project or package to -add") - } - - if err := ctx.ValidateParams(sm, params); err != nil { - return err - } - - // We'll need to discard this prepared solver as later work changes params, - // but solver preparation is cheap and worth doing up front in order to - // perform the fastpath check of hash comparison. - solver, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "fastpath solver prepare") - } - - // Compare the hashes. If they're not equal, bail out and ask the user to - // run a straight `dep ensure` before updating. This is handholding the - // user a bit, but the extra effort required is minimal, and it ensures the - // user is isolating variables in the event of solve problems (was it the - // "pending" changes, or the -add that caused the problem?). - if p.Lock != nil && !bytes.Equal(p.Lock.InputsDigest(), solver.HashInputs()) { - ctx.Out.Printf("Warning: %s is out of sync with %s or the project's imports.", dep.LockName, dep.ManifestName) - } - - rm, _ := params.RootPackageTree.ToReachMap(true, true, false, p.Manifest.IgnoredPackages()) - - // TODO(sdboyer) re-enable this once we ToReachMap() intelligently filters out normally-excluded (_*, .*), dirs from errmap - //rm, errmap := params.RootPackageTree.ToReachMap(true, true, false, p.Manifest.IgnoredPackages()) - // Having some problematic internal packages isn't cause for termination, - // but the user needs to be warned. - //for fail, err := range errmap { - //if _, is := err.Err.(*build.NoGoError); !is { - //ctx.Err.Printf("Warning: %s, %s", fail, err) - //} - //} - - // Compile unique sets of 1) all external packages imported or required, and - // 2) the project roots under which they fall. - exmap := make(map[string]bool) - exrmap := make(map[gps.ProjectRoot]bool) - - for _, ex := range append(rm.FlattenFn(paths.IsStandardImportPath), p.Manifest.Required...) { - exmap[ex] = true - root, err := sm.DeduceProjectRoot(ex) - if err != nil { - // This should be very uncommon to hit, as it entails that we - // couldn't deduce the root for an import, but that some previous - // solve run WAS able to deduce the root. It's most likely to occur - // if the user has e.g. not connected to their organization's VPN, - // and thus cannot access an internal go-get metadata service. - return errors.Wrapf(err, "could not deduce project root for %s", ex) - } - exrmap[root] = true - } - - // Note: these flags are only partially used by the latter parts of the - // algorithm; rather, it relies on inference. However, they remain in their - // entirety as future needs may make further use of them, being a handy, - // terse way of expressing the original context of the arg inputs. - type addType uint8 - const ( - // Straightforward case - this induces a temporary require, and thus - // a warning message about it being ephemeral. - isInManifest addType = 1 << iota - // If solving works, we'll pull this constraint from the in-memory - // manifest (where we recorded it earlier) and then append it to the - // manifest on disk. - isInImportsWithConstraint - // If solving works, we'll extract a constraint from the lock and - // append it into the manifest on disk, similar to init's behavior. - isInImportsNoConstraint - // This gets a message AND a hoist from the solution up into the - // manifest on disk. - isInNeither - ) - - type addInstruction struct { - id gps.ProjectIdentifier - ephReq map[string]bool - constraint gps.Constraint - typ addType - } - addInstructions := make(map[gps.ProjectRoot]addInstruction) - - // A mutex for limited access to addInstructions by goroutines. - var mutex sync.Mutex - - // Channel for receiving all the errors. - errCh := make(chan error, len(args)) - - var wg sync.WaitGroup - - ctx.Out.Println("Fetching sources...") - - for i, arg := range args { - wg.Add(1) - - if ctx.Verbose { - ctx.Err.Printf("(%d/%d) %s\n", i+1, len(args), arg) - } - - go func(arg string) { - defer wg.Done() - - pc, path, err := getProjectConstraint(arg, sm) - if err != nil { - // TODO(sdboyer) ensure these errors are contextualized in a sensible way for -add - errCh <- err - return - } - - // check if the the parsed path is the current root path - if strings.EqualFold(string(p.ImportRoot), string(pc.Ident.ProjectRoot)) { - errCh <- errors.New("cannot add current project to itself") - return - } - - inManifest := p.Manifest.HasConstraintsOn(pc.Ident.ProjectRoot) - inImports := exmap[string(pc.Ident.ProjectRoot)] - if inManifest && inImports { - errCh <- errors.Errorf("nothing to -add, %s is already in %s and the project's direct imports or required list", pc.Ident.ProjectRoot, dep.ManifestName) - return - } - - err = sm.SyncSourceFor(pc.Ident) - if err != nil { - errCh <- errors.Wrapf(err, "failed to fetch source for %s", pc.Ident.ProjectRoot) - return - } - - someConstraint := !gps.IsAny(pc.Constraint) || pc.Ident.Source != "" - - // Obtain a lock for addInstructions - mutex.Lock() - defer mutex.Unlock() - instr, has := addInstructions[pc.Ident.ProjectRoot] - if has { - // Multiple packages from the same project were specified as - // arguments; make sure they agree on declared constraints. - // TODO(sdboyer) until we have a general method for checking constraint equality, only allow one to declare - if someConstraint { - if !gps.IsAny(instr.constraint) || instr.id.Source != "" { - errCh <- errors.Errorf("can only specify rules once per project being added; rules were given at least twice for %s", pc.Ident.ProjectRoot) - return - } - instr.constraint = pc.Constraint - instr.id = pc.Ident - } - } else { - instr.ephReq = make(map[string]bool) - instr.constraint = pc.Constraint - instr.id = pc.Ident - } - - if inManifest { - if someConstraint { - errCh <- errors.Errorf("%s already contains rules for %s, cannot specify a version constraint or alternate source", dep.ManifestName, path) - return - } - - instr.ephReq[path] = true - instr.typ |= isInManifest - } else if inImports { - if !someConstraint { - if exmap[path] { - errCh <- errors.Errorf("%s is already imported or required, so -add is only valid with a constraint", path) - return - } - - // No constraints, but the package isn't imported; require it. - // TODO(sdboyer) this case seems like it's getting overly specific and risks muddying the water more than it helps - instr.ephReq[path] = true - instr.typ |= isInImportsNoConstraint - } else { - // Don't require on this branch if the path was a ProjectRoot; - // most common here will be the user adding constraints to - // something they already imported, and if they specify the - // root, there's a good chance they don't actually want to - // require the project's root package, but are just trying to - // indicate which project should receive the constraints. - if !exmap[path] && string(pc.Ident.ProjectRoot) != path { - instr.ephReq[path] = true - } - instr.typ |= isInImportsWithConstraint - } - } else { - instr.typ |= isInNeither - instr.ephReq[path] = true - } - - addInstructions[pc.Ident.ProjectRoot] = instr - }(arg) - } - - wg.Wait() - close(errCh) - - // Newline after printing the fetching source output. - ctx.Err.Println() - - // Log all the errors. - if len(errCh) > 0 { - ctx.Err.Printf("Failed to add the dependencies:\n\n") - for err := range errCh { - ctx.Err.Println(" ✗", err.Error()) - } - ctx.Err.Println() - return errAddDepsFailed - } - - // We're now sure all of our add instructions are individually and mutually - // valid, so it's safe to begin modifying the input parameters. - for pr, instr := range addInstructions { - // The arg processing logic above only adds to the ephReq list if - // that package definitely needs to be on that list, so we don't - // need to check instr.typ here - if it's in instr.ephReq, it - // definitely needs to be added to the manifest's required list. - for path := range instr.ephReq { - p.Manifest.Required = append(p.Manifest.Required, path) - } - - // Only two branches can possibly be adding rules, though the - // isInNeither case may or may not have an empty constraint. - if instr.typ&(isInNeither|isInImportsWithConstraint) != 0 { - p.Manifest.Constraints[pr] = gps.ProjectProperties{ - Source: instr.id.Source, - Constraint: instr.constraint, - } - } - } - - // Re-prepare a solver now that our params are complete. - solver, err = gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "fastpath solver prepare") - } - solution, err := solver.Solve(context.TODO()) - if err != nil { - // TODO(sdboyer) detect if the failure was specifically about some of the -add arguments - return handleAllTheFailuresOfTheWorld(err) - } - - // Prep post-actions and feedback from adds. - var reqlist []string - appender := dep.NewManifest() - - for pr, instr := range addInstructions { - for path := range instr.ephReq { - reqlist = append(reqlist, path) - } - - if instr.typ&isInManifest == 0 { - var pp gps.ProjectProperties - var found bool - for _, proj := range solution.Projects() { - // We compare just ProjectRoot instead of the whole - // ProjectIdentifier here because an empty source on the input side - // could have been converted into a source by the solver. - if proj.Ident().ProjectRoot == pr { - found = true - pp = getProjectPropertiesFromVersion(proj.Version()) - break - } - } - if !found { - panic(fmt.Sprintf("unreachable: solution did not contain -add argument %s, but solver did not fail", pr)) - } - pp.Source = instr.id.Source - - if !gps.IsAny(instr.constraint) { - pp.Constraint = instr.constraint - } - appender.Constraints[pr] = pp - } - } - - extra, err := appender.MarshalTOML() - if err != nil { - return errors.Wrap(err, "could not marshal manifest into TOML") - } - sort.Strings(reqlist) - - sw, err := dep.NewSafeWriter(nil, p.Lock, dep.LockFromSolution(solution), dep.VendorOnChanged, p.Manifest.PruneOptions) - if err != nil { - return err - } - - if cmd.dryRun { - return sw.PrintPreparedActions(ctx.Out, ctx.Verbose) - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - if err := errors.Wrap(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor"); err != nil { - return err - } - - // FIXME(sdboyer) manifest writes ABSOLUTELY need verification - follow up! - f, err := os.OpenFile(filepath.Join(p.AbsRoot, dep.ManifestName), os.O_APPEND|os.O_WRONLY, 0666) - if err != nil { - return errors.Wrapf(err, "opening %s failed", dep.ManifestName) - } - - if _, err := f.Write(extra); err != nil { - f.Close() - return errors.Wrapf(err, "writing to %s failed", dep.ManifestName) - } - - switch len(reqlist) { - case 0: - // nothing to tell the user - case 1: - if cmd.noVendor { - ctx.Out.Printf("%q is not imported by your project, and has been temporarily added to %s.\n", reqlist[0], dep.LockName) - ctx.Out.Printf("If you run \"dep ensure\" again before actually importing it, it will disappear from %s. Running \"dep ensure -vendor-only\" is safe, and will guarantee it is present in vendor/.", dep.LockName) - } else { - ctx.Out.Printf("%q is not imported by your project, and has been temporarily added to %s and vendor/.\n", reqlist[0], dep.LockName) - ctx.Out.Printf("If you run \"dep ensure\" again before actually importing it, it will disappear from %s and vendor/.", dep.LockName) - } - default: - if cmd.noVendor { - ctx.Out.Printf("The following packages are not imported by your project, and have been temporarily added to %s:\n", dep.LockName) - ctx.Out.Printf("\t%s\n", strings.Join(reqlist, "\n\t")) - ctx.Out.Printf("If you run \"dep ensure\" again before actually importing them, they will disappear from %s. Running \"dep ensure -vendor-only\" is safe, and will guarantee they are present in vendor/.", dep.LockName) - } else { - ctx.Out.Printf("The following packages are not imported by your project, and have been temporarily added to %s and vendor/:\n", dep.LockName) - ctx.Out.Printf("\t%s\n", strings.Join(reqlist, "\n\t")) - ctx.Out.Printf("If you run \"dep ensure\" again before actually importing them, they will disappear from %s and vendor/.", dep.LockName) - } - } - - return errors.Wrapf(f.Close(), "closing %s", dep.ManifestName) -} - -func getProjectConstraint(arg string, sm gps.SourceManager) (gps.ProjectConstraint, string, error) { - emptyPC := gps.ProjectConstraint{ - Constraint: gps.Any(), // default to any; avoids panics later - } - - // try to split on '@' - // When there is no `@`, use any version - var versionStr string - atIndex := strings.Index(arg, "@") - if atIndex > 0 { - parts := strings.SplitN(arg, "@", 2) - arg = parts[0] - versionStr = parts[1] - } - - // TODO: if we decide to keep equals..... - - // split on colon if there is a network location - var source string - colonIndex := strings.Index(arg, ":") - if colonIndex > 0 { - parts := strings.SplitN(arg, ":", 2) - arg = parts[0] - source = parts[1] - } - - pr, err := sm.DeduceProjectRoot(arg) - if err != nil { - return emptyPC, "", errors.Wrapf(err, "could not infer project root from dependency path: %s", arg) // this should go through to the user - } - - pi := gps.ProjectIdentifier{ProjectRoot: pr, Source: source} - c, err := sm.InferConstraint(versionStr, pi) - if err != nil { - return emptyPC, "", err - } - return gps.ProjectConstraint{Ident: pi, Constraint: c}, arg, nil -} - -func checkErrors(m map[string]pkgtree.PackageOrErr, ignore *pkgtree.IgnoredRuleset) (fatal bool, err error) { - var ( - noGoErrors int - pkgtreeErrors = make(pkgtreeErrs, 0, len(m)) - ) - - for ip, poe := range m { - if ignore.IsIgnored(ip) { - continue - } - - if poe.Err != nil { - switch poe.Err.(type) { - case *build.NoGoError: - noGoErrors++ - default: - pkgtreeErrors = append(pkgtreeErrors, poe.Err) - } - } - } - - // If pkgtree was empty or all dirs lacked any Go code, return an error. - if len(m) == 0 || len(m) == noGoErrors { - return true, errors.New("no dirs contained any Go code") - } - - // If all dirs contained build errors, return an error. - if len(m) == len(pkgtreeErrors) { - return true, errors.New("all dirs contained build errors") - } - - // If all directories either had no Go files or caused a build error, return an error. - if len(m) == len(pkgtreeErrors)+noGoErrors { - return true, pkgtreeErrors - } - - // If m contained some errors, return a warning with those errors. - if len(pkgtreeErrors) > 0 { - return false, pkgtreeErrors - } - - return false, nil -} - -type pkgtreeErrs []error - -func (e pkgtreeErrs) Error() string { - errs := make([]string, 0, len(e)) - - for _, err := range e { - errs = append(errs, err.Error()) - } - - return fmt.Sprintf("found %d errors in the package tree:\n%s", len(e), strings.Join(errs, "\n")) -} - -func validateUpdateArgs(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params *gps.SolveParameters) error { - // Channel for receiving all the valid arguments. - argsCh := make(chan string, len(args)) - - // Channel for receiving all the validation errors. - errCh := make(chan error, len(args)) - - var wg sync.WaitGroup - - // Allow any of specified project versions to change, regardless of the lock - // file. - for _, arg := range args { - wg.Add(1) - - go func(arg string) { - defer wg.Done() - - // Ensure the provided path has a deducible project root. - pc, path, err := getProjectConstraint(arg, sm) - if err != nil { - // TODO(sdboyer) ensure these errors are contextualized in a sensible way for -update - errCh <- err - return - } - if path != string(pc.Ident.ProjectRoot) { - // TODO(sdboyer): does this really merit an abortive error? - errCh <- errors.Errorf("%s is not a project root, try %s instead", path, pc.Ident.ProjectRoot) - return - } - - if !p.Lock.HasProjectWithRoot(pc.Ident.ProjectRoot) { - errCh <- errors.Errorf("%s is not present in %s, cannot -update it", pc.Ident.ProjectRoot, dep.LockName) - return - } - - if pc.Ident.Source != "" { - errCh <- errors.Errorf("cannot specify alternate sources on -update (%s)", pc.Ident.Source) - return - } - - if !gps.IsAny(pc.Constraint) { - // TODO(sdboyer) constraints should be allowed to allow solves that - // target particular versions while remaining within declared constraints. - errCh <- errors.Errorf("version constraint %s passed for %s, but -update follows constraints declared in %s, not CLI arguments", pc.Constraint, pc.Ident.ProjectRoot, dep.ManifestName) - return - } - - // Valid argument. - argsCh <- arg - }(arg) - } - - wg.Wait() - close(errCh) - close(argsCh) - - // Log all the errors. - if len(errCh) > 0 { - ctx.Err.Printf("Invalid arguments passed to ensure -update:\n\n") - for err := range errCh { - ctx.Err.Println(" ✗", err.Error()) - } - ctx.Err.Println() - return errUpdateArgsValidation - } - - // Add all the valid arguments to solve params. - for arg := range argsCh { - params.ToChange = append(params.ToChange, gps.ProjectRoot(arg)) - } - - return nil -} diff --git a/vendor/github.com/golang/dep/cmd/dep/failures.go b/vendor/github.com/golang/dep/cmd/dep/failures.go deleted file mode 100644 index c40ac8c78595b8abeecc0eee4c1daae2674af04a..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/failures.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 main - -import ( - "context" - - "github.com/golang/dep/gps" - "github.com/pkg/errors" -) - -// TODO solve failures can be really creative - we need to be similarly creative -// in handling them and informing the user appropriately -func handleAllTheFailuresOfTheWorld(err error) error { - switch errors.Cause(err) { - case context.Canceled, context.DeadlineExceeded, gps.ErrSourceManagerIsReleased: - return nil - } - - return errors.Wrap(err, "Solving failure") -} diff --git a/vendor/github.com/golang/dep/cmd/dep/gopath_scanner.go b/vendor/github.com/golang/dep/cmd/dep/gopath_scanner.go deleted file mode 100644 index ed94d8d49ff13fcc8e161aea0e19c2d8d5fe9fca..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/gopath_scanner.go +++ /dev/null @@ -1,408 +0,0 @@ -// 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 main - -import ( - "fmt" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/paths" - "github.com/golang/dep/gps/pkgtree" - fb "github.com/golang/dep/internal/feedback" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -// gopathScanner supplies manifest/lock data by scanning the contents of GOPATH -// It uses its results to fill-in any missing details left by the rootAnalyzer. -type gopathScanner struct { - ctx *dep.Ctx - directDeps map[gps.ProjectRoot]bool - sm gps.SourceManager - - pd projectData - origM *dep.Manifest - origL *dep.Lock -} - -func newGopathScanner(ctx *dep.Ctx, directDeps map[gps.ProjectRoot]bool, sm gps.SourceManager) *gopathScanner { - return &gopathScanner{ - ctx: ctx, - directDeps: directDeps, - sm: sm, - } -} - -// InitializeRootManifestAndLock performs analysis of the filesystem tree rooted -// at path, with the root import path importRoot, to determine the project's -// constraints. Respect any initial constraints defined in the root manifest and -// lock. -func (g *gopathScanner) InitializeRootManifestAndLock(rootM *dep.Manifest, rootL *dep.Lock) error { - var err error - - g.ctx.Err.Println("Searching GOPATH for projects...") - g.pd, err = g.scanGopathForDependencies() - if err != nil { - return err - } - - g.origM = dep.NewManifest() - g.origM.Constraints = g.pd.constraints - - g.origL = &dep.Lock{ - P: make([]gps.LockedProject, 0, len(g.pd.ondisk)), - } - - for pr, v := range g.pd.ondisk { - // That we have to chop off these path prefixes is a symptom of - // a problem in gps itself - pkgs := make([]string, 0, len(g.pd.dependencies[pr])) - prslash := string(pr) + "/" - for _, pkg := range g.pd.dependencies[pr] { - if pkg == string(pr) { - pkgs = append(pkgs, ".") - } else { - pkgs = append(pkgs, trimPathPrefix(pkg, prslash)) - } - } - - g.origL.P = append(g.origL.P, gps.NewLockedProject( - gps.ProjectIdentifier{ProjectRoot: pr}, v, pkgs), - ) - } - - g.overlay(rootM, rootL) - - return nil -} - -// Fill in gaps in the root manifest/lock with data found from the GOPATH. -func (g *gopathScanner) overlay(rootM *dep.Manifest, rootL *dep.Lock) { - for pkg, prj := range g.origM.Constraints { - if _, has := rootM.Constraints[pkg]; has { - continue - } - rootM.Constraints[pkg] = prj - v := g.pd.ondisk[pkg] - - pi := gps.ProjectIdentifier{ProjectRoot: pkg, Source: prj.Source} - f := fb.NewConstraintFeedback(gps.ProjectConstraint{Ident: pi, Constraint: v}, fb.DepTypeDirect) - f.LogFeedback(g.ctx.Err) - f = fb.NewLockedProjectFeedback(gps.NewLockedProject(pi, v, nil), fb.DepTypeDirect) - f.LogFeedback(g.ctx.Err) - } - - // Keep track of which projects have been locked - lockedProjects := map[gps.ProjectRoot]bool{} - for _, lp := range rootL.P { - lockedProjects[lp.Ident().ProjectRoot] = true - } - - for _, lp := range g.origL.P { - pkg := lp.Ident().ProjectRoot - if _, isLocked := lockedProjects[pkg]; isLocked { - continue - } - rootL.P = append(rootL.P, lp) - lockedProjects[pkg] = true - - if _, isDirect := g.directDeps[pkg]; !isDirect { - f := fb.NewLockedProjectFeedback(lp, fb.DepTypeTransitive) - f.LogFeedback(g.ctx.Err) - } - } - - // Identify projects whose version is unknown and will have to be solved for - var missing []string // all project roots missing from GOPATH - var missingVCS []string // all project roots missing VCS information - for pr := range g.pd.notondisk { - if _, isLocked := lockedProjects[pr]; isLocked { - continue - } - if g.pd.invalidSVC[pr] { - missingVCS = append(missingVCS, string(pr)) - } else { - missing = append(missing, string(pr)) - } - } - - missingStr := "" - missingVCSStr := "" - if len(missing) > 0 { - missingStr = fmt.Sprintf("The following dependencies were not found in GOPATH:\n %s\n\n", - strings.Join(missing, "\n ")) - } - if len(missingVCS) > 0 { - missingVCSStr = fmt.Sprintf("The following dependencies found in GOPATH were missing VCS information (a remote source is required):\n %s\n\n", - strings.Join(missingVCS, "\n ")) - } - if len(missingVCS)+len(missing) > 0 { - g.ctx.Err.Printf("\n%s%sThe most recent version of these projects will be used.\n\n", missingStr, missingVCSStr) - } -} - -func trimPathPrefix(p1, p2 string) string { - if isPrefix, _ := fs.HasFilepathPrefix(p1, p2); isPrefix { - return p1[len(p2):] - } - return p1 -} - -// contains checks if a array of strings contains a value -func contains(a []string, b string) bool { - for _, v := range a { - if b == v { - return true - } - } - return false -} - -// getProjectPropertiesFromVersion takes a Version and returns a proper -// ProjectProperties with Constraint value based on the provided version. -func getProjectPropertiesFromVersion(v gps.Version) gps.ProjectProperties { - pp := gps.ProjectProperties{} - - // extract version and ignore if it's revision only - switch tv := v.(type) { - case gps.PairedVersion: - v = tv.Unpair() - case gps.Revision: - return pp - } - - switch v.Type() { - case gps.IsBranch, gps.IsVersion: - pp.Constraint = v - case gps.IsSemver: - c, err := gps.NewSemverConstraintIC(v.String()) - if err != nil { - panic(err) - } - pp.Constraint = c - } - - return pp -} - -type projectData struct { - constraints gps.ProjectConstraints // constraints that could be found - dependencies map[gps.ProjectRoot][]string // all dependencies (imports) found by project root - notondisk map[gps.ProjectRoot]bool // projects that were not found on disk - invalidSVC map[gps.ProjectRoot]bool // projects that were found on disk but SVC data could not be read - ondisk map[gps.ProjectRoot]gps.Version // projects that were found on disk -} - -func (g *gopathScanner) scanGopathForDependencies() (projectData, error) { - constraints := make(gps.ProjectConstraints) - dependencies := make(map[gps.ProjectRoot][]string) - packages := make(map[string]bool) - notondisk := make(map[gps.ProjectRoot]bool) - invalidSVC := make(map[gps.ProjectRoot]bool) - ondisk := make(map[gps.ProjectRoot]gps.Version) - - var syncDepGroup sync.WaitGroup - syncDep := func(pr gps.ProjectRoot, sm gps.SourceManager) { - if err := sm.SyncSourceFor(gps.ProjectIdentifier{ProjectRoot: pr}); err != nil { - g.ctx.Err.Printf("%+v", errors.Wrapf(err, "Unable to cache %s", pr)) - } - syncDepGroup.Done() - } - - if len(g.directDeps) == 0 { - return projectData{}, nil - } - - for ippr := range g.directDeps { - // TODO(sdboyer) these are not import paths by this point, they've - // already been worked down to project roots. - ip := string(ippr) - pr, err := g.sm.DeduceProjectRoot(ip) - if err != nil { - return projectData{}, errors.Wrap(err, "sm.DeduceProjectRoot") - } - - packages[ip] = true - if _, has := dependencies[pr]; has { - dependencies[pr] = append(dependencies[pr], ip) - continue - } - syncDepGroup.Add(1) - go syncDep(pr, g.sm) - - dependencies[pr] = []string{ip} - abs, err := g.ctx.AbsForImport(string(pr)) - if err != nil { - notondisk[pr] = true - continue - } - v, err := gps.VCSVersion(abs) - if err != nil { - invalidSVC[pr] = true - notondisk[pr] = true - continue - } - - ondisk[pr] = v - pp := getProjectPropertiesFromVersion(v) - if pp.Constraint != nil || pp.Source != "" { - constraints[pr] = pp - } - } - - // Explore the packages we've found for transitive deps, either - // completing the lock or identifying (more) missing projects that we'll - // need to ask gps to solve for us. - colors := make(map[string]uint8) - const ( - white uint8 = iota - grey - black - ) - - // cache of PackageTrees, so we don't parse projects more than once - ptrees := make(map[gps.ProjectRoot]pkgtree.PackageTree) - - // depth-first traverser - var dft func(string) error - dft = func(pkg string) error { - switch colors[pkg] { - case white: - colors[pkg] = grey - - pr, err := g.sm.DeduceProjectRoot(pkg) - if err != nil { - return errors.Wrap(err, "could not deduce project root for "+pkg) - } - - // We already visited this project root earlier via some other - // pkg within it, and made the decision that it's not on disk. - // Respect that decision, and pop the stack. - if notondisk[pr] { - colors[pkg] = black - return nil - } - - ptree, has := ptrees[pr] - if !has { - // It's fine if the root does not exist - it indicates that this - // project is not present in the workspace, and so we need to - // solve to deal with this dep. - r := filepath.Join(g.ctx.GOPATH, "src", string(pr)) - fi, err := os.Stat(r) - if os.IsNotExist(err) || !fi.IsDir() { - colors[pkg] = black - notondisk[pr] = true - return nil - } - - // We know the project is on disk; the question is whether we're - // first seeing it here, in the transitive exploration, or if it - // was found in the initial pass on direct imports. We know it's - // the former if there's no entry for it in the ondisk map. - if _, in := ondisk[pr]; !in { - abs, err := g.ctx.AbsForImport(string(pr)) - if err != nil { - colors[pkg] = black - notondisk[pr] = true - return nil - } - v, err := gps.VCSVersion(abs) - if err != nil { - // Even if we know it's on disk, errors are still - // possible when trying to deduce version. If we - // encounter such an error, just treat the project as - // not being on disk; the solver will work it out. - colors[pkg] = black - notondisk[pr] = true - return nil - } - ondisk[pr] = v - } - - ptree, err = pkgtree.ListPackages(r, string(pr)) - if err != nil { - // Any error here other than an a nonexistent dir (which - // can't happen because we covered that case above) is - // probably critical, so bail out. - return errors.Wrap(err, "gps.ListPackages") - } - ptrees[pr] = ptree - } - - // Get a reachmap that includes main pkgs (even though importing - // them is an error, what we're checking right now is simply whether - // there's a package with go code present on disk), and does not - // backpropagate errors (again, because our only concern right now - // is package existence). - rm, errmap := ptree.ToReachMap(true, false, false, nil) - reached, ok := rm[pkg] - if !ok { - colors[pkg] = black - // not on disk... - notondisk[pr] = true - return nil - } - if _, ok := errmap[pkg]; ok { - // The package is on disk, but contains some errors. - colors[pkg] = black - return nil - } - - if deps, has := dependencies[pr]; has { - if !contains(deps, pkg) { - dependencies[pr] = append(deps, pkg) - } - } else { - dependencies[pr] = []string{pkg} - syncDepGroup.Add(1) - go syncDep(pr, g.sm) - } - - // recurse - for _, rpkg := range reached.External { - if paths.IsStandardImportPath(rpkg) { - continue - } - - err := dft(rpkg) - if err != nil { - // Bubble up any errors we encounter - return err - } - } - - colors[pkg] = black - case grey: - return errors.Errorf("Import cycle detected on %s", pkg) - } - return nil - } - - // run the depth-first traversal from the set of immediate external - // package imports we found in the current project - for pkg := range packages { - err := dft(pkg) - if err != nil { - return projectData{}, err // already errors.Wrap()'d internally - } - } - - syncDepGroup.Wait() - - pd := projectData{ - constraints: constraints, - dependencies: dependencies, - invalidSVC: invalidSVC, - notondisk: notondisk, - ondisk: ondisk, - } - return pd, nil -} diff --git a/vendor/github.com/golang/dep/cmd/dep/graphviz.go b/vendor/github.com/golang/dep/cmd/dep/graphviz.go deleted file mode 100644 index b422ddde7e474cff2a39f7ca338c8548a116ed50..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/graphviz.go +++ /dev/null @@ -1,110 +0,0 @@ -// 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 main - -import ( - "bytes" - "fmt" - "hash/fnv" - "strings" -) - -type graphviz struct { - ps []*gvnode - b bytes.Buffer - h map[string]uint32 -} - -type gvnode struct { - project string - version string - children []string -} - -func (g graphviz) New() *graphviz { - ga := &graphviz{ - ps: []*gvnode{}, - h: make(map[string]uint32), - } - return ga -} - -func (g graphviz) output() bytes.Buffer { - g.b.WriteString("digraph {\n\tnode [shape=box];") - - for _, gvp := range g.ps { - // Create node string - g.b.WriteString(fmt.Sprintf("\n\t%d [label=\"%s\"];", gvp.hash(), gvp.label())) - } - - // Store relations to avoid duplication - rels := make(map[string]bool) - - // Create relations - for _, dp := range g.ps { - for _, bsc := range dp.children { - for pr, hsh := range g.h { - if isPathPrefix(bsc, pr) { - r := fmt.Sprintf("\n\t%d -> %d", g.h[dp.project], hsh) - - if _, ex := rels[r]; !ex { - g.b.WriteString(r + ";") - rels[r] = true - } - - } - } - } - } - - g.b.WriteString("\n}") - return g.b -} - -func (g *graphviz) createNode(project, version string, children []string) { - pr := &gvnode{ - project: project, - version: version, - children: children, - } - - g.h[pr.project] = pr.hash() - g.ps = append(g.ps, pr) -} - -func (dp gvnode) hash() uint32 { - h := fnv.New32a() - h.Write([]byte(dp.project)) - return h.Sum32() -} - -func (dp gvnode) label() string { - label := []string{dp.project} - - if dp.version != "" { - label = append(label, dp.version) - } - - return strings.Join(label, "\\n") -} - -// isPathPrefix ensures that the literal string prefix is a path tree match and -// guards against possibilities like this: -// -// github.com/sdboyer/foo -// github.com/sdboyer/foobar/baz -// -// Verify that prefix is path match and either the input is the same length as -// the match (in which case we know they're equal), or that the next character -// is a "/". (Import paths are defined to always use "/", not the OS-specific -// path separator.) -func isPathPrefix(path, pre string) bool { - pathlen, prflen := len(path), len(pre) - if pathlen < prflen || path[0:prflen] != pre { - return false - } - - return prflen == pathlen || strings.Index(path[prflen:], "/") == 0 -} diff --git a/vendor/github.com/golang/dep/cmd/dep/hash_in.go b/vendor/github.com/golang/dep/cmd/dep/hash_in.go deleted file mode 100644 index ed7f356934baa82062759d6f8e34a275cabc2f99..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/hash_in.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 main - -import ( - "flag" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/pkgtree" - "github.com/pkg/errors" -) - -func (cmd *hashinCommand) Name() string { return "hash-inputs" } -func (cmd *hashinCommand) Args() string { return "" } -func (cmd *hashinCommand) ShortHelp() string { return "" } -func (cmd *hashinCommand) LongHelp() string { return "" } -func (cmd *hashinCommand) Hidden() bool { return true } - -func (cmd *hashinCommand) Register(fs *flag.FlagSet) {} - -type hashinCommand struct{} - -func (hashinCommand) Run(ctx *dep.Ctx, args []string) error { - p, err := ctx.LoadProject() - if err != nil { - return err - } - - sm, err := ctx.SourceManager() - if err != nil { - return err - } - sm.UseDefaultSignalHandling() - defer sm.Release() - - params := p.MakeParams() - params.RootPackageTree, err = pkgtree.ListPackages(p.ResolvedAbsRoot, string(p.ImportRoot)) - if err != nil { - return errors.Wrap(err, "gps.ListPackages") - } - - s, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "prepare solver") - } - ctx.Out.Println(gps.HashingInputsAsString(s)) - return nil -} diff --git a/vendor/github.com/golang/dep/cmd/dep/init.go b/vendor/github.com/golang/dep/cmd/dep/init.go deleted file mode 100644 index fe90b8671b932bba89fa954caf1594846d3f4e1b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/init.go +++ /dev/null @@ -1,245 +0,0 @@ -// 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 main - -import ( - "context" - "flag" - "io/ioutil" - "log" - "os" - "path/filepath" - "time" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -const initShortHelp = `Set up a new Go project, or migrate an existing one` -const initLongHelp = ` -Initialize the project at filepath root by parsing its dependencies, writing -manifest and lock files, and vendoring the dependencies. If root isn't -specified, use the current directory. - -When configuration for another dependency management tool is detected, it is -imported into the initial manifest and lock. Use the -skip-tools flag to -disable this behavior. The following external tools are supported: -glide, godep, vndr, govend, gb, gvt, govendor, glock. - -Any dependencies that are not constrained by external configuration use the -GOPATH analysis below. - -By default, the dependencies are resolved over the network. A version will be -selected from the versions available from the upstream source per the following -algorithm: - - - Tags conforming to semver (sorted by semver rules) - - Default branch(es) (sorted lexicographically) - - Non-semver tags (sorted lexicographically) - -An alternate mode can be activated by passing -gopath. In this mode, the version -of each dependency will reflect the current state of the GOPATH. If a dependency -doesn't exist in the GOPATH, a version will be selected based on the above -network version selection algorithm. - -A Gopkg.toml file will be written with inferred version constraints for all -direct dependencies. Gopkg.lock will be written with precise versions, and -vendor/ will be populated with the precise versions written to Gopkg.lock. -` - -func (cmd *initCommand) Name() string { return "init" } -func (cmd *initCommand) Args() string { return "[root]" } -func (cmd *initCommand) ShortHelp() string { return initShortHelp } -func (cmd *initCommand) LongHelp() string { return initLongHelp } -func (cmd *initCommand) Hidden() bool { return false } - -func (cmd *initCommand) Register(fs *flag.FlagSet) { - fs.BoolVar(&cmd.noExamples, "no-examples", false, "don't include example in Gopkg.toml") - fs.BoolVar(&cmd.skipTools, "skip-tools", false, "skip importing configuration from other dependency managers") - fs.BoolVar(&cmd.gopath, "gopath", false, "search in GOPATH for dependencies") -} - -type initCommand struct { - noExamples bool - skipTools bool - gopath bool -} - -func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error { - if len(args) > 1 { - return errors.Errorf("too many args (%d)", len(args)) - } - - var root string - if len(args) <= 0 { - root = ctx.WorkingDir - } else { - root = args[0] - if !filepath.IsAbs(args[0]) { - root = filepath.Join(ctx.WorkingDir, args[0]) - } - if err := os.MkdirAll(root, os.FileMode(0777)); err != nil { - return errors.Wrapf(err, "init failed: unable to create a directory at %s", root) - } - } - - p, err := cmd.establishProjectAt(root, ctx) - if err != nil { - return err - } - - sm, err := ctx.SourceManager() - if err != nil { - return errors.Wrap(err, "init failed: unable to create a source manager") - } - sm.UseDefaultSignalHandling() - defer sm.Release() - - if ctx.Verbose { - ctx.Out.Println("Getting direct dependencies...") - } - - ptree, directDeps, err := p.GetDirectDependencyNames(sm) - if err != nil { - return errors.Wrap(err, "init failed: unable to determine direct dependencies") - } - if ctx.Verbose { - ctx.Out.Printf("Checked %d directories for packages.\nFound %d direct dependencies.\n", len(ptree.Packages), len(directDeps)) - } - - // Initialize with imported data, then fill in the gaps using the GOPATH - rootAnalyzer := newRootAnalyzer(cmd.skipTools, ctx, directDeps, sm) - p.Manifest, p.Lock, err = rootAnalyzer.InitializeRootManifestAndLock(root, p.ImportRoot) - if err != nil { - return errors.Wrap(err, "init failed: unable to prepare an initial manifest and lock for the solver") - } - - // Set default prune options for go-tests and unused-packages - p.Manifest.PruneOptions.DefaultOptions = gps.PruneNestedVendorDirs | gps.PruneGoTestFiles | gps.PruneUnusedPackages - - if cmd.gopath { - gs := newGopathScanner(ctx, directDeps, sm) - err = gs.InitializeRootManifestAndLock(p.Manifest, p.Lock) - if err != nil { - return errors.Wrap(err, "init failed: unable to scan the GOPATH for dependencies") - } - } - - rootAnalyzer.skipTools = true // Don't import external config during solve for now - copyLock := *p.Lock // Copy lock before solving. Use this to separate new lock projects from solved lock - - params := gps.SolveParameters{ - RootDir: root, - RootPackageTree: ptree, - Manifest: p.Manifest, - Lock: p.Lock, - ProjectAnalyzer: rootAnalyzer, - } - - if ctx.Verbose { - params.TraceLogger = ctx.Err - } - - if err := ctx.ValidateParams(sm, params); err != nil { - return errors.Wrapf(err, "init failed: validation of solve parameters failed") - } - - s, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "init failed: unable to prepare the solver") - } - - soln, err := s.Solve(context.TODO()) - if err != nil { - err = handleAllTheFailuresOfTheWorld(err) - return errors.Wrap(err, "init failed: unable to solve the dependency graph") - } - p.Lock = dep.LockFromSolution(soln) - - rootAnalyzer.FinalizeRootManifestAndLock(p.Manifest, p.Lock, copyLock) - - // Run gps.Prepare with appropriate constraint solutions from solve run - // to generate the final lock memo. - s, err = gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "init failed: unable to recalculate the lock digest") - } - - p.Lock.SolveMeta.InputsDigest = s.HashInputs() - - // Pass timestamp (yyyyMMddHHmmss format) as suffix to backup name. - vendorbak, err := dep.BackupVendor(filepath.Join(root, "vendor"), time.Now().Format("20060102150405")) - if err != nil { - return errors.Wrap(err, "init failed: first backup vendor/, delete it, and then retry the previous command: failed to backup existing vendor directory") - } - if vendorbak != "" { - ctx.Err.Printf("Old vendor backed up to %v", vendorbak) - } - - sw, err := dep.NewSafeWriter(p.Manifest, nil, p.Lock, dep.VendorAlways, p.Manifest.PruneOptions) - if err != nil { - return errors.Wrap(err, "init failed: unable to create a SafeWriter") - } - - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - if err := sw.Write(root, sm, !cmd.noExamples, logger); err != nil { - return errors.Wrap(err, "init failed: unable to write the manifest, lock and vendor directory to disk") - } - - return nil -} - -// establishProjectAt attempts to set up the provided path as the root for the -// project to be created. -// -// It checks for being within a GOPATH, that there is no pre-existing manifest -// and lock, and that we can successfully infer the root import path from -// GOPATH. -// -// If successful, it returns a dep.Project, ready for further use. -func (cmd *initCommand) establishProjectAt(root string, ctx *dep.Ctx) (*dep.Project, error) { - var err error - p := new(dep.Project) - if err = p.SetRoot(root); err != nil { - return nil, errors.Wrapf(err, "init failed: unable to set the root project to %s", root) - } - - ctx.GOPATH, err = ctx.DetectProjectGOPATH(p) - if err != nil { - return nil, errors.Wrapf(err, "init failed: unable to detect the containing GOPATH") - } - - mf := filepath.Join(root, dep.ManifestName) - lf := filepath.Join(root, dep.LockName) - - mok, err := fs.IsRegular(mf) - if err != nil { - return nil, errors.Wrapf(err, "init failed: unable to check for an existing manifest at %s", mf) - } - if mok { - return nil, errors.Errorf("init aborted: manifest already exists at %s", mf) - } - - lok, err := fs.IsRegular(lf) - if err != nil { - return nil, errors.Wrapf(err, "init failed: unable to check for an existing lock at %s", lf) - } - if lok { - return nil, errors.Errorf("invalid aborted: lock already exists at %s", lf) - } - - ip, err := ctx.ImportForAbs(root) - if err != nil { - return nil, errors.Wrapf(err, "init failed: unable to determine the import path for the root project %s", root) - } - p.ImportRoot = gps.ProjectRoot(ip) - - return p, nil -} diff --git a/vendor/github.com/golang/dep/cmd/dep/main.go b/vendor/github.com/golang/dep/cmd/dep/main.go deleted file mode 100644 index 969d8b8d7070516d146db9ba1c416522f0c5914e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/main.go +++ /dev/null @@ -1,329 +0,0 @@ -// 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. - -//go:generate ./mkdoc.sh - -package main - -import ( - "bytes" - "flag" - "fmt" - "io" - "log" - "os" - "path/filepath" - "strings" - "text/tabwriter" - - "github.com/golang/dep" - "github.com/golang/dep/internal/fs" -) - -var ( - successExitCode = 0 - errorExitCode = 1 -) - -type command interface { - Name() string // "foobar" - Args() string // "<baz> [quux...]" - ShortHelp() string // "Foo the first bar" - LongHelp() string // "Foo the first bar meeting the following conditions..." - Register(*flag.FlagSet) // command-specific flags - Hidden() bool // indicates whether the command should be hidden from help output - Run(*dep.Ctx, []string) error -} - -func main() { - wd, err := os.Getwd() - if err != nil { - fmt.Fprintln(os.Stderr, "failed to get working directory", err) - os.Exit(1) - } - c := &Config{ - Args: os.Args, - Stdout: os.Stdout, - Stderr: os.Stderr, - WorkingDir: wd, - Env: os.Environ(), - } - os.Exit(c.Run()) -} - -// A Config specifies a full configuration for a dep execution. -type Config struct { - WorkingDir string // Where to execute - Args []string // Command-line arguments, starting with the program name. - Env []string // Environment variables - Stdout, Stderr io.Writer // Log output -} - -// Run executes a configuration and returns an exit code. -func (c *Config) Run() int { - // Build the list of available commands. - commands := [...]command{ - &initCommand{}, - &statusCommand{}, - &ensureCommand{}, - &pruneCommand{}, - &hashinCommand{}, - &versionCommand{}, - } - - examples := [...][2]string{ - { - "dep init", - "set up a new project", - }, - { - "dep ensure", - "install the project's dependencies", - }, - { - "dep ensure -update", - "update the locked versions of all dependencies", - }, - { - "dep ensure -add github.com/pkg/errors", - "add a dependency to the project", - }, - } - - usage := func(w io.Writer) { - fmt.Fprintln(w, "Dep is a tool for managing dependencies for Go projects") - fmt.Fprintln(w) - fmt.Fprintln(w, "Usage: \"dep [command]\"") - fmt.Fprintln(w) - fmt.Fprintln(w, "Commands:") - fmt.Fprintln(w) - tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0) - for _, cmd := range commands { - if !cmd.Hidden() { - fmt.Fprintf(tw, "\t%s\t%s\n", cmd.Name(), cmd.ShortHelp()) - } - } - tw.Flush() - fmt.Fprintln(w) - fmt.Fprintln(w, "Examples:") - for _, example := range examples { - fmt.Fprintf(tw, "\t%s\t%s\n", example[0], example[1]) - } - tw.Flush() - fmt.Fprintln(w) - fmt.Fprintln(w, "Use \"dep help [command]\" for more information about a command.") - } - - cmdName, printCommandHelp, exit := parseArgs(c.Args) - if exit { - usage(c.Stderr) - return errorExitCode - } - - // 'dep help documentation' generates doc.go. - if printCommandHelp && cmdName == "documentation" { - fmt.Println("// Copyright 2017 The Go Authors. All rights reserved.") - fmt.Println("// Use of this source code is governed by a BSD-style") - fmt.Println("// license that can be found in the LICENSE file.") - fmt.Println() - fmt.Println("// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.") - fmt.Println("// Edit the documentation in other files and rerun mkdoc.sh to generate this one.") - fmt.Println() - - var cw io.Writer = &commentWriter{W: c.Stdout} - usage(cw) - for _, cmd := range commands { - if !cmd.Hidden() { - fmt.Fprintln(cw) - short := cmd.ShortHelp() - fmt.Fprintln(cw, short) - fmt.Fprintln(cw) - fmt.Fprintln(cw, "Usage:") - fmt.Fprintln(cw) - fmt.Fprintln(cw, "", cmd.Name(), cmd.Args()) - if long := cmd.LongHelp(); long != short { - fmt.Fprintln(cw, long) - } - } - } - - fmt.Println("//") - fmt.Println("package main") - return successExitCode - } - - outLogger := log.New(c.Stdout, "", 0) - errLogger := log.New(c.Stderr, "", 0) - - for _, cmd := range commands { - if cmd.Name() == cmdName { - // Build flag set with global flags in there. - flags := flag.NewFlagSet(cmdName, flag.ContinueOnError) - flags.SetOutput(c.Stderr) - verbose := flags.Bool("v", false, "enable verbose logging") - - // Register the subcommand flags in there, too. - cmd.Register(flags) - - // Override the usage text to something nicer. - resetUsage(errLogger, flags, cmdName, cmd.Args(), cmd.LongHelp()) - - if printCommandHelp { - flags.Usage() - return errorExitCode - } - - // Parse the flags the user gave us. - // flag package automatically prints usage and error message in err != nil - // or if '-h' flag provided - if err := flags.Parse(c.Args[2:]); err != nil { - return errorExitCode - } - - // Cachedir is loaded from env if present. `$GOPATH/pkg/dep` is used as the - // default cache location. - cachedir := getEnv(c.Env, "DEPCACHEDIR") - if cachedir != "" { - if err := fs.EnsureDir(cachedir, 0777); err != nil { - errLogger.Printf( - "dep: $DEPCACHEDIR set to an invalid or inaccessible path: %q\n", cachedir, - ) - errLogger.Printf("dep: failed to ensure cache directory: %v\n", err) - return errorExitCode - } - } - - // Set up dep context. - ctx := &dep.Ctx{ - Out: outLogger, - Err: errLogger, - Verbose: *verbose, - DisableLocking: getEnv(c.Env, "DEPNOLOCK") != "", - Cachedir: cachedir, - } - - GOPATHS := filepath.SplitList(getEnv(c.Env, "GOPATH")) - ctx.SetPaths(c.WorkingDir, GOPATHS...) - - // Run the command with the post-flag-processing args. - if err := cmd.Run(ctx, flags.Args()); err != nil { - errLogger.Printf("%v\n", err) - return errorExitCode - } - - // Easy peasy livin' breezy. - return successExitCode - } - } - - errLogger.Printf("dep: %s: no such command\n", cmdName) - usage(c.Stderr) - return errorExitCode -} - -func resetUsage(logger *log.Logger, fs *flag.FlagSet, name, args, longHelp string) { - var ( - hasFlags bool - flagBlock bytes.Buffer - flagWriter = tabwriter.NewWriter(&flagBlock, 0, 4, 2, ' ', 0) - ) - fs.VisitAll(func(f *flag.Flag) { - hasFlags = true - // Default-empty string vars should read "(default: <none>)" - // rather than the comparatively ugly "(default: )". - defValue := f.DefValue - if defValue == "" { - defValue = "<none>" - } - fmt.Fprintf(flagWriter, "\t-%s\t%s (default: %s)\n", f.Name, f.Usage, defValue) - }) - flagWriter.Flush() - fs.Usage = func() { - logger.Printf("Usage: dep %s %s\n", name, args) - logger.Println() - logger.Println(strings.TrimSpace(longHelp)) - logger.Println() - if hasFlags { - logger.Println("Flags:") - logger.Println() - logger.Println(flagBlock.String()) - } - } -} - -// parseArgs determines the name of the dep command and whether the user asked for -// help to be printed. -func parseArgs(args []string) (cmdName string, printCmdUsage bool, exit bool) { - isHelpArg := func() bool { - return strings.Contains(strings.ToLower(args[1]), "help") || strings.ToLower(args[1]) == "-h" - } - - switch len(args) { - case 0, 1: - exit = true - case 2: - if isHelpArg() { - exit = true - } else { - cmdName = args[1] - } - default: - if isHelpArg() { - cmdName = args[2] - printCmdUsage = true - } else { - cmdName = args[1] - } - } - return cmdName, printCmdUsage, exit -} - -// getEnv returns the last instance of an environment variable. -func getEnv(env []string, key string) string { - for i := len(env) - 1; i >= 0; i-- { - v := env[i] - kv := strings.SplitN(v, "=", 2) - if kv[0] == key { - if len(kv) > 1 { - return kv[1] - } - return "" - } - } - return "" -} - -// commentWriter writes a Go comment to the underlying io.Writer, -// using line comment form (//). -// -// Copied from cmd/go/internal/help/help.go. -type commentWriter struct { - W io.Writer - wroteSlashes bool // Wrote "//" at the beginning of the current line. -} - -func (c *commentWriter) Write(p []byte) (int, error) { - var n int - for i, b := range p { - if !c.wroteSlashes { - s := "//" - if b != '\n' { - s = "// " - } - if _, err := io.WriteString(c.W, s); err != nil { - return n, err - } - c.wroteSlashes = true - } - n0, err := c.W.Write(p[i : i+1]) - n += n0 - if err != nil { - return n, err - } - if b == '\n' { - c.wroteSlashes = false - } - } - return len(p), nil -} diff --git a/vendor/github.com/golang/dep/cmd/dep/mkdoc.sh b/vendor/github.com/golang/dep/cmd/dep/mkdoc.sh deleted file mode 100755 index c2e6941ff47d71c230cc9d4843f546e7dd7a71b4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/mkdoc.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# 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. - -set -e - -go build -o dep.latest -./dep.latest help documentation >doc.go -gofmt -w doc.go -rm dep.latest diff --git a/vendor/github.com/golang/dep/cmd/dep/prune.go b/vendor/github.com/golang/dep/cmd/dep/prune.go deleted file mode 100644 index 41e5e80e055cb71e03822619705e257f1c092088..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/prune.go +++ /dev/null @@ -1,211 +0,0 @@ -// 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 main - -import ( - "bytes" - "flag" - "io/ioutil" - "log" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -const pruneShortHelp = `Pruning is now performed automatically by dep ensure.` -const pruneLongHelp = ` -Prune was merged into the ensure command. -Set prune options in the manifest and it will be applied after every ensure. -dep prune will be removed in a future version of dep, causing this command to exit non-0. -` - -type pruneCommand struct { -} - -func (cmd *pruneCommand) Name() string { return "prune" } -func (cmd *pruneCommand) Args() string { return "" } -func (cmd *pruneCommand) ShortHelp() string { return pruneShortHelp } -func (cmd *pruneCommand) LongHelp() string { return pruneLongHelp } -func (cmd *pruneCommand) Hidden() bool { return false } - -func (cmd *pruneCommand) Register(fs *flag.FlagSet) { -} - -func (cmd *pruneCommand) Run(ctx *dep.Ctx, args []string) error { - ctx.Err.Printf("Pruning is now performed automatically by dep ensure.\n") - ctx.Err.Printf("Set prune settings in %s and it it will be applied when running ensure.\n", dep.ManifestName) - ctx.Err.Printf("\nThis command currently still prunes as it always has, to ease the transition.\n") - ctx.Err.Printf("However, it will be removed in a future version of dep.\n") - ctx.Err.Printf("\nNow is the time to update your Gopkg.toml and remove `dep prune` from any scripts.\n") - - p, err := ctx.LoadProject() - if err != nil { - return err - } - - sm, err := ctx.SourceManager() - if err != nil { - return err - } - sm.UseDefaultSignalHandling() - defer sm.Release() - - // While the network churns on ListVersions() requests, statically analyze - // code from the current project. - ptree, err := pkgtree.ListPackages(p.ResolvedAbsRoot, string(p.ImportRoot)) - if err != nil { - return errors.Wrap(err, "analysis of local packages failed: %v") - } - - // Set up a solver in order to check the InputHash. - params := p.MakeParams() - params.RootPackageTree = ptree - - if ctx.Verbose { - params.TraceLogger = ctx.Err - } - - s, err := gps.Prepare(params, sm) - if err != nil { - return errors.Wrap(err, "could not set up solver for input hashing") - } - - if p.Lock == nil { - return errors.Errorf("Gopkg.lock must exist for prune to know what files are safe to remove.") - } - - if !bytes.Equal(s.HashInputs(), p.Lock.SolveMeta.InputsDigest) { - return errors.Errorf("Gopkg.lock is out of sync; run dep ensure before pruning.") - } - - pruneLogger := ctx.Err - if !ctx.Verbose { - pruneLogger = log.New(ioutil.Discard, "", 0) - } - return pruneProject(p, sm, pruneLogger) -} - -// pruneProject removes unused packages from a project. -func pruneProject(p *dep.Project, sm gps.SourceManager, logger *log.Logger) error { - td, err := ioutil.TempDir(os.TempDir(), "dep") - if err != nil { - return errors.Wrap(err, "error while creating temp dir for writing manifest/lock/vendor") - } - defer os.RemoveAll(td) - - if err := gps.WriteDepTree(td, p.Lock, sm, gps.CascadingPruneOptions{DefaultOptions: gps.PruneNestedVendorDirs}, logger); err != nil { - return err - } - - var toKeep []string - for _, project := range p.Lock.Projects() { - projectRoot := string(project.Ident().ProjectRoot) - for _, pkg := range project.Packages() { - toKeep = append(toKeep, filepath.Join(projectRoot, pkg)) - } - } - - toDelete, err := calculatePrune(td, toKeep, logger) - if err != nil { - return err - } - - if len(toDelete) > 0 { - logger.Println("Calculated the following directories to prune:") - for _, d := range toDelete { - logger.Printf(" %s\n", d) - } - } else { - logger.Println("No directories found to prune") - } - - if err := deleteDirs(toDelete); err != nil { - return err - } - - vpath := filepath.Join(p.AbsRoot, "vendor") - vendorbak := vpath + ".orig" - var failerr error - if _, err := os.Stat(vpath); err == nil { - // Move out the old vendor dir. just do it into an adjacent dir, to - // try to mitigate the possibility of a pointless cross-filesystem - // move with a temp directory. - if _, err := os.Stat(vendorbak); err == nil { - // If the adjacent dir already exists, bite the bullet and move - // to a proper tempdir. - vendorbak = filepath.Join(td, "vendor.orig") - } - failerr = fs.RenameWithFallback(vpath, vendorbak) - if failerr != nil { - goto fail - } - } - - // Move in the new one. - failerr = fs.RenameWithFallback(td, vpath) - if failerr != nil { - goto fail - } - - os.RemoveAll(vendorbak) - - return nil - -fail: - fs.RenameWithFallback(vendorbak, vpath) - return failerr -} - -func calculatePrune(vendorDir string, keep []string, logger *log.Logger) ([]string, error) { - logger.Println("Calculating prune. Checking the following packages:") - sort.Strings(keep) - toDelete := []string{} - err := filepath.Walk(vendorDir, func(path string, info os.FileInfo, err error) error { - if _, err := os.Lstat(path); err != nil { - return nil - } - if !info.IsDir() { - return nil - } - if path == vendorDir { - return nil - } - - name := strings.TrimPrefix(path, vendorDir+string(filepath.Separator)) - logger.Printf(" %s", name) - i := sort.Search(len(keep), func(i int) bool { - return name <= keep[i] - }) - if i >= len(keep) || !strings.HasPrefix(keep[i], name) { - toDelete = append(toDelete, path) - } - return nil - }) - return toDelete, err -} - -func deleteDirs(toDelete []string) error { - // sort by length so we delete sub dirs first - sort.Sort(byLen(toDelete)) - for _, path := range toDelete { - if err := os.RemoveAll(path); err != nil { - return err - } - } - return nil -} - -type byLen []string - -func (a byLen) Len() int { return len(a) } -func (a byLen) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byLen) Less(i, j int) bool { return len(a[i]) > len(a[j]) } diff --git a/vendor/github.com/golang/dep/cmd/dep/root_analyzer.go b/vendor/github.com/golang/dep/cmd/dep/root_analyzer.go deleted file mode 100644 index 76d410fe6e0240c3ea57d37e747cbee3b50f91f5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/root_analyzer.go +++ /dev/null @@ -1,209 +0,0 @@ -// 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 main - -import ( - "context" - "io/ioutil" - "log" - - "golang.org/x/sync/errgroup" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - fb "github.com/golang/dep/internal/feedback" - "github.com/golang/dep/internal/importers" -) - -// rootAnalyzer supplies manifest/lock data from both dep and external tool's -// configuration files. -// * When used on the root project, it imports only from external tools. -// * When used by the solver for dependencies, it first looks for dep config, -// then external tools. -type rootAnalyzer struct { - skipTools bool - ctx *dep.Ctx - sm gps.SourceManager - directDeps map[gps.ProjectRoot]bool -} - -func newRootAnalyzer(skipTools bool, ctx *dep.Ctx, directDeps map[gps.ProjectRoot]bool, sm gps.SourceManager) *rootAnalyzer { - return &rootAnalyzer{ - skipTools: skipTools, - ctx: ctx, - sm: sm, - directDeps: directDeps, - } -} - -func (a *rootAnalyzer) InitializeRootManifestAndLock(dir string, pr gps.ProjectRoot) (rootM *dep.Manifest, rootL *dep.Lock, err error) { - if !a.skipTools { - rootM, rootL = a.importManifestAndLock(dir, pr, false) - } - - if rootM == nil { - rootM = dep.NewManifest() - - // Since we didn't find anything to import, dep's cache is empty. - // We are prefetching dependencies and logging so that the subsequent solve step - // doesn't spend a long time retrieving dependencies without feedback for the user. - if err := a.cacheDeps(pr); err != nil { - return nil, nil, err - } - } - if rootL == nil { - rootL = &dep.Lock{} - } - - return -} - -func (a *rootAnalyzer) cacheDeps(pr gps.ProjectRoot) error { - logger := a.ctx.Err - g, _ := errgroup.WithContext(context.TODO()) - concurrency := 4 - - syncDep := func(pr gps.ProjectRoot, sm gps.SourceManager) error { - if err := sm.SyncSourceFor(gps.ProjectIdentifier{ProjectRoot: pr}); err != nil { - logger.Printf("Unable to cache %s - %s", pr, err) - return err - } - return nil - } - - deps := make(chan gps.ProjectRoot) - - for i := 0; i < concurrency; i++ { - g.Go(func() error { - for d := range deps { - err := syncDep(gps.ProjectRoot(d), a.sm) - if err != nil { - return err - } - } - return nil - }) - } - - g.Go(func() error { - defer close(deps) - for pr := range a.directDeps { - logger.Printf("Caching package %q", pr) - deps <- pr - } - return nil - }) - - if err := g.Wait(); err != nil { - return err - } - logger.Printf("Successfully cached all deps.") - return nil -} - -func (a *rootAnalyzer) importManifestAndLock(dir string, pr gps.ProjectRoot, suppressLogs bool) (*dep.Manifest, *dep.Lock) { - logger := a.ctx.Err - if suppressLogs { - logger = log.New(ioutil.Discard, "", 0) - } - - for _, i := range importers.BuildAll(logger, a.ctx.Verbose, a.sm) { - if i.HasDepMetadata(dir) { - a.ctx.Err.Printf("Importing configuration from %s. These are only initial constraints, and are further refined during the solve process.", i.Name()) - m, l, err := i.Import(dir, pr) - if err != nil { - a.ctx.Err.Printf( - "Warning: Encountered an unrecoverable error while trying to import %s config from %q: %s", - i.Name(), dir, err, - ) - break - } - a.removeTransitiveDependencies(m) - return m, l - } - } - - var emptyManifest = dep.NewManifest() - - return emptyManifest, nil -} - -func (a *rootAnalyzer) removeTransitiveDependencies(m *dep.Manifest) { - for pr := range m.Constraints { - if _, isDirect := a.directDeps[pr]; !isDirect { - delete(m.Constraints, pr) - } - } -} - -// DeriveManifestAndLock evaluates a dependency for existing dependency manager -// configuration (ours or external) and passes any configuration found back -// to the solver. -func (a *rootAnalyzer) DeriveManifestAndLock(dir string, pr gps.ProjectRoot) (gps.Manifest, gps.Lock, error) { - // Ignore other tools if we find dep configuration - var depAnalyzer dep.Analyzer - if depAnalyzer.HasDepMetadata(dir) { - return depAnalyzer.DeriveManifestAndLock(dir, pr) - } - - if !a.skipTools { - // The assignment back to an interface prevents interface-based nil checks from failing later - var manifest gps.Manifest = gps.SimpleManifest{} - var lock gps.Lock - im, il := a.importManifestAndLock(dir, pr, true) - if im != nil { - manifest = im - } - if il != nil { - lock = il - } - return manifest, lock, nil - } - - return gps.SimpleManifest{}, nil, nil -} - -func (a *rootAnalyzer) FinalizeRootManifestAndLock(m *dep.Manifest, l *dep.Lock, ol dep.Lock) { - // Iterate through the new projects in solved lock and add them to manifest - // if they are direct deps and log feedback for all the new projects. - for _, y := range l.Projects() { - var f *fb.ConstraintFeedback - pr := y.Ident().ProjectRoot - // New constraints: in new lock and dir dep but not in manifest - if _, ok := a.directDeps[pr]; ok { - if _, ok := m.Constraints[pr]; !ok { - pp := getProjectPropertiesFromVersion(y.Version()) - if pp.Constraint != nil { - m.Constraints[pr] = pp - pc := gps.ProjectConstraint{Ident: y.Ident(), Constraint: pp.Constraint} - f = fb.NewConstraintFeedback(pc, fb.DepTypeDirect) - f.LogFeedback(a.ctx.Err) - } - f = fb.NewLockedProjectFeedback(y, fb.DepTypeDirect) - f.LogFeedback(a.ctx.Err) - } - } else { - // New locked projects: in new lock but not in old lock - newProject := true - for _, opl := range ol.Projects() { - if pr == opl.Ident().ProjectRoot { - newProject = false - } - } - if newProject { - f = fb.NewLockedProjectFeedback(y, fb.DepTypeTransitive) - f.LogFeedback(a.ctx.Err) - } - } - } -} - -// Info provides metadata on the analyzer algorithm used during solve. -func (a *rootAnalyzer) Info() gps.ProjectAnalyzerInfo { - return gps.ProjectAnalyzerInfo{ - Name: "dep", - Version: 1, - } -} diff --git a/vendor/github.com/golang/dep/cmd/dep/status.go b/vendor/github.com/golang/dep/cmd/dep/status.go deleted file mode 100644 index c342b20f29e9cdbc788699706ac0194580da7608..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/status.go +++ /dev/null @@ -1,844 +0,0 @@ -// 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 main - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "html/template" - "io" - "io/ioutil" - "log" - "sort" - "sync" - "text/tabwriter" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/paths" - "github.com/pkg/errors" -) - -const statusShortHelp = `Report the status of the project's dependencies` -const statusLongHelp = ` -With no arguments, print the status of each dependency of the project. - - PROJECT Import path - CONSTRAINT Version constraint, from the manifest - VERSION Version chosen, from the lock - REVISION VCS revision of the chosen version - LATEST Latest VCS revision available - PKGS USED Number of packages from this project that are actually used - -With one or more explicitly specified packages, or with the -detailed flag, -print an extended status output for each dependency of the project. - - TODO Another column description - FOOBAR Another column description - -Status returns exit code zero if all dependencies are in a "good state". -` - -const ( - shortRev uint8 = iota - longRev -) - -var ( - errFailedUpdate = errors.New("failed to fetch updates") - errFailedListPkg = errors.New("failed to list packages") - errMultipleFailures = errors.New("multiple sources of failure") - errInputDigestMismatch = errors.New("input-digest mismatch") -) - -func (cmd *statusCommand) Name() string { return "status" } -func (cmd *statusCommand) Args() string { return "[package...]" } -func (cmd *statusCommand) ShortHelp() string { return statusShortHelp } -func (cmd *statusCommand) LongHelp() string { return statusLongHelp } -func (cmd *statusCommand) Hidden() bool { return false } - -func (cmd *statusCommand) Register(fs *flag.FlagSet) { - fs.BoolVar(&cmd.json, "json", false, "output in JSON format") - fs.StringVar(&cmd.template, "f", "", "output in text/template format") - fs.BoolVar(&cmd.dot, "dot", false, "output the dependency graph in GraphViz format") - fs.BoolVar(&cmd.old, "old", false, "only show out-of-date dependencies") - fs.BoolVar(&cmd.missing, "missing", false, "only show missing dependencies") -} - -type statusCommand struct { - json bool - template string - output string - dot bool - old bool - missing bool -} - -type outputter interface { - BasicHeader() error - BasicLine(*BasicStatus) error - BasicFooter() error - MissingHeader() error - MissingLine(*MissingStatus) error - MissingFooter() error -} - -type tableOutput struct{ w *tabwriter.Writer } - -func (out *tableOutput) BasicHeader() error { - _, err := fmt.Fprintf(out.w, "PROJECT\tCONSTRAINT\tVERSION\tREVISION\tLATEST\tPKGS USED\n") - return err -} - -func (out *tableOutput) BasicFooter() error { - return out.w.Flush() -} - -func (out *tableOutput) BasicLine(bs *BasicStatus) error { - _, err := fmt.Fprintf(out.w, - "%s\t%s\t%s\t%s\t%s\t%d\t\n", - bs.ProjectRoot, - bs.getConsolidatedConstraint(), - formatVersion(bs.Version), - formatVersion(bs.Revision), - bs.getConsolidatedLatest(shortRev), - bs.PackageCount, - ) - return err -} - -func (out *tableOutput) MissingHeader() error { - _, err := fmt.Fprintln(out.w, "PROJECT\tMISSING PACKAGES") - return err -} - -func (out *tableOutput) MissingLine(ms *MissingStatus) error { - _, err := fmt.Fprintf(out.w, - "%s\t%s\t\n", - ms.ProjectRoot, - ms.MissingPackages, - ) - return err -} - -func (out *tableOutput) MissingFooter() error { - return out.w.Flush() -} - -type jsonOutput struct { - w io.Writer - basic []*rawStatus - missing []*MissingStatus -} - -func (out *jsonOutput) BasicHeader() error { - out.basic = []*rawStatus{} - return nil -} - -func (out *jsonOutput) BasicFooter() error { - return json.NewEncoder(out.w).Encode(out.basic) -} - -func (out *jsonOutput) BasicLine(bs *BasicStatus) error { - out.basic = append(out.basic, bs.marshalJSON()) - return nil -} - -func (out *jsonOutput) MissingHeader() error { - out.missing = []*MissingStatus{} - return nil -} - -func (out *jsonOutput) MissingLine(ms *MissingStatus) error { - out.missing = append(out.missing, ms) - return nil -} - -func (out *jsonOutput) MissingFooter() error { - return json.NewEncoder(out.w).Encode(out.missing) -} - -type dotOutput struct { - w io.Writer - o string - g *graphviz - p *dep.Project -} - -func (out *dotOutput) BasicHeader() error { - out.g = new(graphviz).New() - - ptree, err := out.p.ParseRootPackageTree() - // TODO(sdboyer) should be true, true, false, out.p.Manifest.IgnoredPackages() - prm, _ := ptree.ToReachMap(true, false, false, nil) - - out.g.createNode(string(out.p.ImportRoot), "", prm.FlattenFn(paths.IsStandardImportPath)) - - return err -} - -func (out *dotOutput) BasicFooter() error { - gvo := out.g.output() - _, err := fmt.Fprintf(out.w, gvo.String()) - return err -} - -func (out *dotOutput) BasicLine(bs *BasicStatus) error { - out.g.createNode(bs.ProjectRoot, bs.getConsolidatedVersion(), bs.Children) - return nil -} - -func (out *dotOutput) MissingHeader() error { return nil } -func (out *dotOutput) MissingLine(ms *MissingStatus) error { return nil } -func (out *dotOutput) MissingFooter() error { return nil } - -type templateOutput struct { - w io.Writer - tmpl *template.Template -} - -func (out *templateOutput) BasicHeader() error { return nil } -func (out *templateOutput) BasicFooter() error { return nil } - -func (out *templateOutput) BasicLine(bs *BasicStatus) error { - return out.tmpl.Execute(out.w, bs) -} - -func (out *templateOutput) MissingHeader() error { return nil } -func (out *templateOutput) MissingFooter() error { return nil } - -func (out *templateOutput) MissingLine(ms *MissingStatus) error { - return out.tmpl.Execute(out.w, ms) -} - -func (cmd *statusCommand) Run(ctx *dep.Ctx, args []string) error { - if err := cmd.validateFlags(); err != nil { - return err - } - - p, err := ctx.LoadProject() - if err != nil { - return err - } - - sm, err := ctx.SourceManager() - if err != nil { - return err - } - sm.UseDefaultSignalHandling() - defer sm.Release() - - if err := dep.ValidateProjectRoots(ctx, p.Manifest, sm); err != nil { - return err - } - - var buf bytes.Buffer - var out outputter - switch { - case cmd.missing: - return errors.Errorf("not implemented") - case cmd.old: - return errors.Errorf("not implemented") - case cmd.json: - out = &jsonOutput{ - w: &buf, - } - case cmd.dot: - out = &dotOutput{ - p: p, - o: cmd.output, - w: &buf, - } - case cmd.template != "": - tmpl, err := template.New("status").Parse(cmd.template) - if err != nil { - return err - } - out = &templateOutput{ - w: &buf, - tmpl: tmpl, - } - default: - out = &tableOutput{ - w: tabwriter.NewWriter(&buf, 0, 4, 2, ' ', 0), - } - } - - // Check if the lock file exists. - if p.Lock == nil { - return errors.Errorf("no Gopkg.lock found. Run `dep ensure` to generate lock file") - } - - hasMissingPkgs, errCount, err := runStatusAll(ctx, out, p, sm) - if err != nil { - switch err { - case errFailedUpdate: - // Print the results with unknown data - ctx.Out.Println(buf.String()) - // Print the help when in non-verbose mode - if !ctx.Verbose { - ctx.Out.Printf("The status of %d projects are unknown due to errors. Rerun with `-v` flag to see details.\n", errCount) - } - case errInputDigestMismatch: - // Tell the user why mismatch happened and how to resolve it. - if hasMissingPkgs { - ctx.Err.Printf("Lock inputs-digest mismatch due to the following packages missing from the lock:\n\n") - ctx.Out.Print(buf.String()) - ctx.Err.Printf("\nThis happens when a new import is added. Run `dep ensure` to install the missing packages.\n") - } else { - ctx.Err.Printf("Lock inputs-digest mismatch. This happens when Gopkg.toml is modified.\n" + - "Run `dep ensure` to regenerate the inputs-digest.") - } - } - - return err - } - - // Print the status output - ctx.Out.Print(buf.String()) - - return nil -} - -func (cmd *statusCommand) validateFlags() error { - // Operating mode flags. - opModes := []string{} - - if cmd.old { - opModes = append(opModes, "-old") - } - - if cmd.missing { - opModes = append(opModes, "-missing") - } - - // Check if any other flags are passed with -dot. - if cmd.dot { - if cmd.template != "" { - return errors.New("cannot pass template string with -dot") - } - - if cmd.json { - return errors.New("cannot pass multiple output format flags") - } - - if len(opModes) > 0 { - return errors.New("-dot generates dependency graph; cannot pass other flags") - } - } - - if len(opModes) > 1 { - // List the flags because which flags are for operation mode might not - // be apparent to the users. - return errors.Wrapf(errors.New("cannot pass multiple operating mode flags"), "%v", opModes) - } - - return nil -} - -type rawStatus struct { - ProjectRoot string - Constraint string - Version string - Revision string - Latest string - PackageCount int -} - -// BasicStatus contains all the information reported about a single dependency -// in the summary/list status output mode. -type BasicStatus struct { - ProjectRoot string - Children []string - Constraint gps.Constraint - Version gps.UnpairedVersion - Revision gps.Revision - Latest gps.Version - PackageCount int - hasOverride bool - hasError bool -} - -func (bs *BasicStatus) getConsolidatedConstraint() string { - var constraint string - if bs.Constraint != nil { - if v, ok := bs.Constraint.(gps.Version); ok { - constraint = formatVersion(v) - } else { - constraint = bs.Constraint.String() - } - } - - if bs.hasOverride { - constraint += " (override)" - } - - return constraint -} - -func (bs *BasicStatus) getConsolidatedVersion() string { - version := formatVersion(bs.Revision) - if bs.Version != nil { - version = formatVersion(bs.Version) - } - return version -} - -func (bs *BasicStatus) getConsolidatedLatest(revSize uint8) string { - latest := "" - if bs.Latest != nil { - switch revSize { - case shortRev: - latest = formatVersion(bs.Latest) - case longRev: - latest = bs.Latest.String() - } - } - - if bs.hasError { - latest += "unknown" - } - - return latest -} - -func (bs *BasicStatus) marshalJSON() *rawStatus { - return &rawStatus{ - ProjectRoot: bs.ProjectRoot, - Constraint: bs.getConsolidatedConstraint(), - Version: formatVersion(bs.Version), - Revision: string(bs.Revision), - Latest: bs.getConsolidatedLatest(longRev), - PackageCount: bs.PackageCount, - } -} - -// MissingStatus contains information about all the missing packages in a project. -type MissingStatus struct { - ProjectRoot string - MissingPackages []string -} - -func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceManager) (hasMissingPkgs bool, errCount int, err error) { - // While the network churns on ListVersions() requests, statically analyze - // code from the current project. - ptree, err := p.ParseRootPackageTree() - if err != nil { - return false, 0, err - } - - // Set up a solver in order to check the InputHash. - params := gps.SolveParameters{ - ProjectAnalyzer: dep.Analyzer{}, - RootDir: p.AbsRoot, - RootPackageTree: ptree, - Manifest: p.Manifest, - // Locks aren't a part of the input hash check, so we can omit it. - } - - logger := ctx.Err - if ctx.Verbose { - params.TraceLogger = ctx.Err - } else { - logger = log.New(ioutil.Discard, "", 0) - } - - if err := ctx.ValidateParams(sm, params); err != nil { - return false, 0, err - } - - s, err := gps.Prepare(params, sm) - if err != nil { - return false, 0, errors.Wrapf(err, "could not set up solver for input hashing") - } - - // Errors while collecting constraints should not fail the whole status run. - // It should count the error and tell the user about incomplete results. - cm, ccerrs := collectConstraints(ctx, p, sm) - if len(ccerrs) > 0 { - errCount += len(ccerrs) - } - - // Get the project list and sort it so that the printed output users see is - // deterministically ordered. (This may be superfluous if the lock is always - // written in alpha order, but it doesn't hurt to double down.) - slp := p.Lock.Projects() - sort.Slice(slp, func(i, j int) bool { - return slp[i].Ident().Less(slp[j].Ident()) - }) - - if bytes.Equal(s.HashInputs(), p.Lock.SolveMeta.InputsDigest) { - // If these are equal, we're guaranteed that the lock is a transitively - // complete picture of all deps. That eliminates the need for at least - // some checks. - - if err := out.BasicHeader(); err != nil { - return false, 0, err - } - - logger.Println("Checking upstream projects:") - - // BasicStatus channel to collect all the BasicStatus. - bsCh := make(chan *BasicStatus, len(slp)) - - // Error channels to collect different errors. - errListPkgCh := make(chan error, len(slp)) - errListVerCh := make(chan error, len(slp)) - - var wg sync.WaitGroup - - for i, proj := range slp { - wg.Add(1) - logger.Printf("(%d/%d) %s\n", i+1, len(slp), proj.Ident().ProjectRoot) - - go func(proj gps.LockedProject) { - bs := BasicStatus{ - ProjectRoot: string(proj.Ident().ProjectRoot), - PackageCount: len(proj.Packages()), - } - - // Get children only for specific outputers - // in order to avoid slower status process. - switch out.(type) { - case *dotOutput: - ptr, err := sm.ListPackages(proj.Ident(), proj.Version()) - - if err != nil { - bs.hasError = true - errListPkgCh <- err - } - - prm, _ := ptr.ToReachMap(true, true, false, p.Manifest.IgnoredPackages()) - bs.Children = prm.FlattenFn(paths.IsStandardImportPath) - } - - // Split apart the version from the lock into its constituent parts. - switch tv := proj.Version().(type) { - case gps.UnpairedVersion: - bs.Version = tv - case gps.Revision: - bs.Revision = tv - case gps.PairedVersion: - bs.Version = tv.Unpair() - bs.Revision = tv.Revision() - } - - // Check if the manifest has an override for this project. If so, - // set that as the constraint. - if pp, has := p.Manifest.Ovr[proj.Ident().ProjectRoot]; has && pp.Constraint != nil { - bs.hasOverride = true - bs.Constraint = pp.Constraint - } else if pp, has := p.Manifest.Constraints[proj.Ident().ProjectRoot]; has && pp.Constraint != nil { - // If the manifest has a constraint then set that as the constraint. - bs.Constraint = pp.Constraint - } else { - bs.Constraint = gps.Any() - for _, c := range cm[bs.ProjectRoot] { - bs.Constraint = c.Constraint.Intersect(bs.Constraint) - } - } - - // Only if we have a non-rev and non-plain version do/can we display - // anything wrt the version's updateability. - if bs.Version != nil && bs.Version.Type() != gps.IsVersion { - c, has := p.Manifest.Constraints[proj.Ident().ProjectRoot] - if !has { - // Get constraint for locked project - for _, lockedP := range p.Lock.P { - if lockedP.Ident().ProjectRoot == proj.Ident().ProjectRoot { - // Use the unpaired version as the constraint for checking updates. - c.Constraint = bs.Version - } - } - } - // TODO: This constraint is only the constraint imposed by the - // current project, not by any transitive deps. As a result, - // transitive project deps will always show "any" here. - bs.Constraint = c.Constraint - - vl, err := sm.ListVersions(proj.Ident()) - if err == nil { - gps.SortPairedForUpgrade(vl) - - for _, v := range vl { - // Because we've sorted the version list for - // upgrade, the first version we encounter that - // matches our constraint will be what we want. - if c.Constraint.Matches(v) { - // Latest should be of the same type as the Version. - if bs.Version.Type() == gps.IsSemver { - bs.Latest = v - } else { - bs.Latest = v.Revision() - } - break - } - } - } else { - // Failed to fetch version list (could happen due to - // network issue). - bs.hasError = true - errListVerCh <- err - } - } - - bsCh <- &bs - - wg.Done() - }(proj) - } - - wg.Wait() - close(bsCh) - close(errListPkgCh) - close(errListVerCh) - - // Newline after printing the status progress output. - logger.Println() - - // List Packages errors. This would happen only for dot output. - if len(errListPkgCh) > 0 { - err = errFailedListPkg - if ctx.Verbose { - for err := range errListPkgCh { - ctx.Err.Println(err.Error()) - } - ctx.Err.Println() - } - } - - // List Version errors. - if len(errListVerCh) > 0 { - if err == nil { - err = errFailedUpdate - } else { - err = errMultipleFailures - } - - // Count ListVersions error because we get partial results when - // this happens. - errCount += len(errListVerCh) - if ctx.Verbose { - for err := range errListVerCh { - ctx.Err.Println(err.Error()) - } - ctx.Err.Println() - } - } - - // A map of ProjectRoot and *BasicStatus. This is used in maintain the - // order of BasicStatus in output by collecting all the BasicStatus and - // then using them in order. - bsMap := make(map[string]*BasicStatus) - for bs := range bsCh { - bsMap[bs.ProjectRoot] = bs - } - - // Use the collected BasicStatus in outputter. - for _, proj := range slp { - if err := out.BasicLine(bsMap[string(proj.Ident().ProjectRoot)]); err != nil { - return false, 0, err - } - } - - if footerErr := out.BasicFooter(); footerErr != nil { - return false, 0, footerErr - } - - return false, errCount, err - } - - // Hash digest mismatch may indicate that some deps are no longer - // needed, some are missing, or that some constraints or source - // locations have changed. - // - // It's possible for digests to not match, but still have a correct - // lock. - rm, _ := ptree.ToReachMap(true, true, false, p.Manifest.IgnoredPackages()) - - external := rm.FlattenFn(paths.IsStandardImportPath) - roots := make(map[gps.ProjectRoot][]string, len(external)) - - type fail struct { - ex string - err error - } - var errs []fail - for _, e := range external { - root, err := sm.DeduceProjectRoot(e) - if err != nil { - errs = append(errs, fail{ - ex: e, - err: err, - }) - continue - } - - roots[root] = append(roots[root], e) - } - - if len(errs) != 0 { - // TODO this is just a fix quick so staticcheck doesn't complain. - // Visually reconciling failure to deduce project roots with the rest of - // the mismatch output is a larger problem. - ctx.Err.Printf("Failed to deduce project roots for import paths:\n") - for _, fail := range errs { - ctx.Err.Printf("\t%s: %s\n", fail.ex, fail.err.Error()) - } - - return false, 0, errors.New("address issues with undeducible import paths to get more status information") - } - - if err = out.MissingHeader(); err != nil { - return false, 0, err - } - -outer: - for root, pkgs := range roots { - // TODO also handle the case where the project is present, but there - // are items missing from just the package list - for _, lp := range slp { - if lp.Ident().ProjectRoot == root { - continue outer - } - } - - hasMissingPkgs = true - err := out.MissingLine(&MissingStatus{ProjectRoot: string(root), MissingPackages: pkgs}) - if err != nil { - return false, 0, err - } - } - if err = out.MissingFooter(); err != nil { - return false, 0, err - } - - // We are here because of an input-digest mismatch. Return error. - return hasMissingPkgs, 0, errInputDigestMismatch -} - -func formatVersion(v gps.Version) string { - if v == nil { - return "" - } - switch v.Type() { - case gps.IsBranch: - return "branch " + v.String() - case gps.IsRevision: - r := v.String() - if len(r) > 7 { - r = r[:7] - } - return r - } - return v.String() -} - -// projectConstraint stores ProjectRoot and Constraint for that project. -type projectConstraint struct { - Project gps.ProjectRoot - Constraint gps.Constraint -} - -// constraintsCollection is a map of ProjectRoot(dependency) and a collection of -// projectConstraint for the dependencies. This can be used to find constraints -// on a dependency and the projects that apply those constraints. -type constraintsCollection map[string][]projectConstraint - -// collectConstraints collects constraints declared by all the dependencies. -// It returns constraintsCollection and a slice of errors encountered while -// collecting the constraints, if any. -func collectConstraints(ctx *dep.Ctx, p *dep.Project, sm gps.SourceManager) (constraintsCollection, []error) { - logger := ctx.Err - if !ctx.Verbose { - logger = log.New(ioutil.Discard, "", 0) - } - - logger.Println("Collecting project constraints:") - - var mutex sync.Mutex - constraintCollection := make(constraintsCollection) - - // Collect the complete set of direct project dependencies, incorporating - // requireds and ignores appropriately. - _, directDeps, err := p.GetDirectDependencyNames(sm) - if err != nil { - // Return empty collection, not nil, if we fail here. - return constraintCollection, []error{errors.Wrap(err, "failed to get direct dependencies")} - } - - // Create a root analyzer. - rootAnalyzer := newRootAnalyzer(true, ctx, directDeps, sm) - - lp := p.Lock.Projects() - - // Channel for receiving all the errors. - errCh := make(chan error, len(lp)) - - var wg sync.WaitGroup - - // Iterate through the locked projects and collect constraints of all the projects. - for i, proj := range lp { - wg.Add(1) - logger.Printf("(%d/%d) %s\n", i+1, len(lp), proj.Ident().ProjectRoot) - - go func(proj gps.LockedProject) { - defer wg.Done() - - manifest, _, err := sm.GetManifestAndLock(proj.Ident(), proj.Version(), rootAnalyzer) - if err != nil { - errCh <- errors.Wrap(err, "error getting manifest and lock") - return - } - - // Get project constraints. - pc := manifest.DependencyConstraints() - - // Obtain a lock for constraintCollection. - mutex.Lock() - defer mutex.Unlock() - // Iterate through the project constraints to get individual dependency - // project and constraint values. - for pr, pp := range pc { - // Check if the project constraint is imported in the root project - if _, ok := directDeps[pr]; !ok { - continue - } - - tempCC := append( - constraintCollection[string(pr)], - projectConstraint{proj.Ident().ProjectRoot, pp.Constraint}, - ) - - // Sort the inner projectConstraint slice by Project string. - // Required for consistent returned value. - sort.Sort(byProject(tempCC)) - constraintCollection[string(pr)] = tempCC - } - }(proj) - } - - wg.Wait() - close(errCh) - - var errs []error - if len(errCh) > 0 { - for e := range errCh { - errs = append(errs, e) - logger.Println(e.Error()) - } - } - - return constraintCollection, errs -} - -type byProject []projectConstraint - -func (p byProject) Len() int { return len(p) } -func (p byProject) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p byProject) Less(i, j int) bool { return p[i].Project < p[j].Project } diff --git a/vendor/github.com/golang/dep/cmd/dep/version.go b/vendor/github.com/golang/dep/cmd/dep/version.go deleted file mode 100644 index d7a3d33059749d2de708d29ee3d093f94194a158..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/cmd/dep/version.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 main - -import ( - "flag" - "runtime" - - "github.com/golang/dep" -) - -var ( - version = "devel" - buildDate string - commitHash string -) - -const versionHelp = `Show the dep version information` - -func (cmd *versionCommand) Name() string { return "version" } -func (cmd *versionCommand) Args() string { - return "" -} -func (cmd *versionCommand) ShortHelp() string { return versionHelp } -func (cmd *versionCommand) LongHelp() string { return versionHelp } -func (cmd *versionCommand) Hidden() bool { return false } - -func (cmd *versionCommand) Register(fs *flag.FlagSet) {} - -type versionCommand struct{} - -func (cmd *versionCommand) Run(ctx *dep.Ctx, args []string) error { - ctx.Out.Printf(`dep: - version : %s - build date : %s - git hash : %s - go version : %s - go compiler : %s - platform : %s/%s -`, version, buildDate, commitHash, - runtime.Version(), runtime.Compiler, runtime.GOOS, runtime.GOARCH) - return nil -} diff --git a/vendor/github.com/golang/dep/context.go b/vendor/github.com/golang/dep/context.go deleted file mode 100644 index 475efb377652bfd40950fe870957a3bdb2c057e3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/context.go +++ /dev/null @@ -1,297 +0,0 @@ -// 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 dep - -import ( - "log" - "os" - "path/filepath" - "runtime" - - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -// Ctx defines the supporting context of dep. -// -// A properly initialized Ctx has a GOPATH containing the project root and non-nil Loggers. -// -// ctx := &dep.Ctx{ -// WorkingDir: GOPATH + "/src/project/root", -// GOPATH: GOPATH, -// Out: log.New(os.Stdout, "", 0), -// Err: log.New(os.Stderr, "", 0), -// } -// -// Ctx.DetectProjectGOPATH() helps with setting the containing GOPATH. -// -// ctx.GOPATH, err := Ctx.DetectProjectGOPATH(project) -// if err != nil { -// // Could not determine which GOPATH to use for the project. -// } -// -type Ctx struct { - WorkingDir string // Where to execute. - GOPATH string // Selected Go path, containing WorkingDir. - GOPATHs []string // Other Go paths. - Out, Err *log.Logger // Required loggers. - Verbose bool // Enables more verbose logging. - DisableLocking bool // When set, no lock file will be created to protect against simultaneous dep processes. - Cachedir string // Cache directory loaded from environment. -} - -// SetPaths sets the WorkingDir and GOPATHs fields. If GOPATHs is empty, then -// the GOPATH environment variable (or the default GOPATH) is used instead. -func (c *Ctx) SetPaths(wd string, GOPATHs ...string) error { - if wd == "" { - return errors.New("cannot set Ctx.WorkingDir to an empty path") - } - c.WorkingDir = wd - - if len(GOPATHs) == 0 { - GOPATH := os.Getenv("GOPATH") - if GOPATH == "" { - GOPATH = defaultGOPATH() - } - GOPATHs = filepath.SplitList(GOPATH) - } - - c.GOPATHs = append(c.GOPATHs, GOPATHs...) - - return nil -} - -// defaultGOPATH gets the default GOPATH that was added in 1.8 -// copied from go/build/build.go -func defaultGOPATH() string { - env := "HOME" - if runtime.GOOS == "windows" { - env = "USERPROFILE" - } else if runtime.GOOS == "plan9" { - env = "home" - } - if home := os.Getenv(env); home != "" { - def := filepath.Join(home, "go") - if def == runtime.GOROOT() { - // Don't set the default GOPATH to GOROOT, - // as that will trigger warnings from the go tool. - return "" - } - return def - } - return "" -} - -// SourceManager produces an instance of gps's built-in SourceManager -// initialized to log to the receiver's logger. -func (c *Ctx) SourceManager() (*gps.SourceMgr, error) { - cachedir := c.Cachedir - if cachedir == "" { - // When `DEPCACHEDIR` isn't set in the env, use the default - `$GOPATH/pkg/dep`. - cachedir = filepath.Join(c.GOPATH, "pkg", "dep") - // Create the default cachedir if it does not exist. - if err := os.MkdirAll(cachedir, 0777); err != nil { - return nil, errors.Wrap(err, "failed to create default cache directory") - } - } - - return gps.NewSourceManager(gps.SourceManagerConfig{ - Cachedir: cachedir, - Logger: c.Out, - DisableLocking: c.DisableLocking, - }) -} - -// LoadProject starts from the current working directory and searches up the -// directory tree for a project root. The search stops when a file with the name -// ManifestName (Gopkg.toml, by default) is located. -// -// The Project contains the parsed manifest as well as a parsed lock file, if -// present. The import path is calculated as the remaining path segment -// below Ctx.GOPATH/src. -func (c *Ctx) LoadProject() (*Project, error) { - root, err := findProjectRoot(c.WorkingDir) - if err != nil { - return nil, err - } - - err = checkGopkgFilenames(root) - if err != nil { - return nil, err - } - - p := new(Project) - - if err = p.SetRoot(root); err != nil { - return nil, err - } - - c.GOPATH, err = c.DetectProjectGOPATH(p) - if err != nil { - return nil, err - } - - ip, err := c.ImportForAbs(p.AbsRoot) - if err != nil { - return nil, errors.Wrap(err, "root project import") - } - p.ImportRoot = gps.ProjectRoot(ip) - - mp := filepath.Join(p.AbsRoot, ManifestName) - mf, err := os.Open(mp) - if err != nil { - if os.IsNotExist(err) { - // TODO: list possible solutions? (dep init, cd $project) - return nil, errors.Errorf("no %v found in project root %v", ManifestName, p.AbsRoot) - } - // Unable to read the manifest file - return nil, err - } - defer mf.Close() - - var warns []error - p.Manifest, warns, err = readManifest(mf) - for _, warn := range warns { - c.Err.Printf("dep: WARNING: %v\n", warn) - } - if err != nil { - return nil, errors.Wrapf(err, "error while parsing %s", mp) - } - - lp := filepath.Join(p.AbsRoot, LockName) - lf, err := os.Open(lp) - if err != nil { - if os.IsNotExist(err) { - // It's fine for the lock not to exist - return p, nil - } - // But if a lock does exist and we can't open it, that's a problem - return nil, errors.Wrapf(err, "could not open %s", lp) - } - defer lf.Close() - - p.Lock, err = readLock(lf) - if err != nil { - return nil, errors.Wrapf(err, "error while parsing %s", lp) - } - - return p, nil -} - -// DetectProjectGOPATH attempt to find the GOPATH containing the project. -// -// If p.AbsRoot is not a symlink and is within a GOPATH, the GOPATH containing p.AbsRoot is returned. -// If p.AbsRoot is a symlink and is not within any known GOPATH, the GOPATH containing p.ResolvedAbsRoot is returned. -// -// p.AbsRoot is assumed to be a symlink if it is not the same as p.ResolvedAbsRoot. -// -// DetectProjectGOPATH will return an error in the following cases: -// -// If p.AbsRoot is not a symlink and is not within any known GOPATH. -// If neither p.AbsRoot nor p.ResolvedAbsRoot are within a known GOPATH. -// If both p.AbsRoot and p.ResolvedAbsRoot are within the same GOPATH. -// If p.AbsRoot and p.ResolvedAbsRoot are each within a different GOPATH. -func (c *Ctx) DetectProjectGOPATH(p *Project) (string, error) { - if p.AbsRoot == "" || p.ResolvedAbsRoot == "" { - return "", errors.New("project AbsRoot and ResolvedAbsRoot must be set to detect GOPATH") - } - - pGOPATH, perr := c.detectGOPATH(p.AbsRoot) - - // If p.AbsRoot is a not symlink, attempt to detect GOPATH for p.AbsRoot only. - if equal, _ := fs.EquivalentPaths(p.AbsRoot, p.ResolvedAbsRoot); equal { - return pGOPATH, perr - } - - rGOPATH, rerr := c.detectGOPATH(p.ResolvedAbsRoot) - - // If detectGOPATH() failed for both p.AbsRoot and p.ResolvedAbsRoot, then both are not within any known GOPATHs. - if perr != nil && rerr != nil { - return "", errors.Errorf("both %s and %s are not within any known GOPATH", p.AbsRoot, p.ResolvedAbsRoot) - } - - // If pGOPATH equals rGOPATH, then both are within the same GOPATH. - if equal, _ := fs.EquivalentPaths(pGOPATH, rGOPATH); equal { - return "", errors.Errorf("both %s and %s are in the same GOPATH %s", p.AbsRoot, p.ResolvedAbsRoot, pGOPATH) - } - - if pGOPATH != "" && rGOPATH != "" { - return "", errors.Errorf("%s and %s are both in different GOPATHs", p.AbsRoot, p.ResolvedAbsRoot) - } - - // Otherwise, either the p.AbsRoot or p.ResolvedAbsRoot is within a GOPATH. - if pGOPATH == "" { - return rGOPATH, nil - } - - return pGOPATH, nil -} - -// detectGOPATH detects the GOPATH for a given path from ctx.GOPATHs. -func (c *Ctx) detectGOPATH(path string) (string, error) { - for _, gp := range c.GOPATHs { - isPrefix, err := fs.HasFilepathPrefix(path, gp) - if err != nil { - return "", errors.Wrap(err, "failed to detect GOPATH") - } - if isPrefix { - return gp, nil - } - } - return "", errors.Errorf("%s is not within a known GOPATH/src", path) -} - -// ImportForAbs returns the import path for an absolute project path by trimming the -// `$GOPATH/src/` prefix. Returns an error for paths equal to, or without this prefix. -func (c *Ctx) ImportForAbs(path string) (string, error) { - srcprefix := filepath.Join(c.GOPATH, "src") + string(filepath.Separator) - isPrefix, err := fs.HasFilepathPrefix(path, srcprefix) - if err != nil { - return "", errors.Wrap(err, "failed to find import path") - } - if isPrefix { - if len(path) <= len(srcprefix) { - return "", errors.New("dep does not currently support using GOPATH/src as the project root") - } - - // filepath.ToSlash because we're dealing with an import path now, - // not an fs path - return filepath.ToSlash(path[len(srcprefix):]), nil - } - - return "", errors.Errorf("%s is not within any GOPATH/src", path) -} - -// AbsForImport returns the absolute path for the project root -// including the $GOPATH. This will not work with stdlib packages and the -// package directory needs to exist. -func (c *Ctx) AbsForImport(path string) (string, error) { - posspath := filepath.Join(c.GOPATH, "src", path) - dirOK, err := fs.IsDir(posspath) - if err != nil { - return "", errors.Wrapf(err, "checking if %s is a directory", posspath) - } - if !dirOK { - return "", errors.Errorf("%s does not exist", posspath) - } - return posspath, nil -} - -// ValidateParams ensure that solving can be completed with the specified params. -func (c *Ctx) ValidateParams(sm gps.SourceManager, params gps.SolveParameters) error { - err := gps.ValidateParams(params, sm) - if err != nil { - if deduceErrs, ok := err.(gps.DeductionErrs); ok { - c.Err.Println("The following errors occurred while deducing packages:") - for ip, dErr := range deduceErrs { - c.Err.Printf(" * \"%s\": %s", ip, dErr) - } - c.Err.Println() - } - } - - return errors.Wrap(err, "validateParams") -} diff --git a/vendor/github.com/golang/dep/doc.go b/vendor/github.com/golang/dep/doc.go deleted file mode 100644 index 63226ce4c22fffd5f1907424a592d2a2c2c4df93..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// 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 dep is a prototype dependency management library. -package dep diff --git a/vendor/github.com/golang/dep/docs/FAQ.md b/vendor/github.com/golang/dep/docs/FAQ.md deleted file mode 100644 index ffa47c8cc6d7e846d4a8582bc1d835ae3b2f7647..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/FAQ.md +++ /dev/null @@ -1,491 +0,0 @@ ---- -title: FAQ ---- - -The FAQ predated the introduction of the rest of the documentation. If something in here conflicts with other guides or reference documents, it's probably here that it's wrong - please file a PR! - -## Concepts -* [Does `dep` replace `go get`?](#does-dep-replace-go-get) -* [Why is it `dep ensure` instead of `dep install`?](#why-is-it-dep-ensure-instead-of-dep-install) -* [What is a direct or transitive dependency?](#what-is-a-direct-or-transitive-dependency) - -## Configuration -* [What is the difference between Gopkg.toml (the "manifest") and Gopkg.lock (the "lock")?](#what-is-the-difference-between-gopkgtoml-the-manifest-and-gopkglock-the-lock) -* [How do I constrain a transitive dependency's version?](#how-do-i-constrain-a-transitive-dependencys-version) -* [Can I put the manifest and lock in the vendor directory?](#can-i-put-the-manifest-and-lock-in-the-vendor-directory) -* [How do I get `dep` to authenticate to a `git` repo?](#how-do-i-get-dep-to-authenticate-to-a-git-repo) -* [How do I get `dep` to consume private `git` repos using a Github Token?](#how-do-i-get-dep-to-consume-private-git-repos-using-a-github-token) - -## Behavior -* [How does `dep` decide what version of a dependency to use?](#how-does-dep-decide-what-version-of-a-dependency-to-use) -* [What external tools are supported?](#what-external-tools-are-supported) -* [Why is `dep` ignoring a version constraint in the manifest?](#why-is-dep-ignoring-a-version-constraint-in-the-manifest) -* [Why did `dep` use a different revision for package X instead of the revision in the lock file?](#why-did-dep-use-a-different-revision-for-package-x-instead-of-the-revision-in-the-lock-file) -* [Why is `dep` slow?](#why-is-dep-slow) -* [How does `dep` handle symbolic links?](#how-does-dep-handle-symbolic-links) -* [Does `dep` support relative imports?](#does-dep-support-relative-imports) -* [How do I make `dep` resolve dependencies from my `GOPATH`?](#how-do-i-make-dep-resolve-dependencies-from-my-gopath) -* [Will `dep` let me use git submodules to store dependencies in `vendor`?](#will-dep-let-me-use-git-submodules-to-store-dependencies-in-vendor) - -## Best Practices -* [Should I commit my vendor directory?](#should-i-commit-my-vendor-directory) -* [How do I roll releases that `dep` will be able to use?](#how-do-i-roll-releases-that-dep-will-be-able-to-use) -* [What semver version should I use?](#what-semver-version-should-i-use) -* [Is it OK to make backwards-incompatible changes now?](#is-it-ok-to-make-backwards-incompatible-changes-now) -* [My dependers don't use `dep` yet. What should I do?](#my-dependers-dont-use-dep-yet-what-should-i-do) -* [How do I configure a dependency that doesn't tag its releases?](#how-do-i-configure-a-dependency-that-doesnt-tag-its-releases) -* [How do I use `dep` with Docker?](#how-do-i-use-dep-with-docker) -* [How do I use `dep` in CI?](#how-do-i-use-dep-in-ci) - -## Concepts -### Does `dep` replace `go get`? - -No. `dep` and `go get` serve mostly different purposes. - -Here are some suggestions for when you could use `dep` or `go get`: -> I would say that dep doesn't replace go get, but they both can do similar things. Here's how I use them: -> -> `go get`: I want to download the source code for a go project so that I can work on it myself, or to install a tool. This clones the repo under GOPATH for all to use. -> -> `dep ensure`: I have imported a new dependency in my code and want to download the dependency so I can start using it. My workflow is "add the import to the code, and then run dep ensure so that the manifest/lock/vendor are updated". This clones the repo under my project's vendor directory, and remembers the revision used so that everyone who works on my project is guaranteed to be using the same version of dependencies. -> -> [@carolynvs in #376](https://github.com/golang/dep/issues/376#issuecomment-293964655) - -> The long term vision is a sane, overall-consistent go tool. My general take is that `go get` -> is for people consuming Go code, and dep-family commands are for people developing it. -> -> [@sdboyer in #376](https://github.com/golang/dep/issues/376#issuecomment-294045873) - -### Why is it `dep ensure` instead of `dep install`? - -> Yeah, we went round and round on names. [A lot](https://gist.github.com/jessfraz/315db91b272441f510e81e449f675a8b). -> -> The idea of "ensure" is roughly, "ensure that all my local states - code tree, manifest, lock, and vendor - are in sync with each other." When arguments are passed, it becomes "ensure this argument is satisfied, along with synchronization between all my local states." -> -> We opted for this approach because we came to the conclusion that allowing the tool to perform partial work/exit in intermediate states ended up creating a tool that had more commands, had far more possible valid exit and input states, and was generally full of footguns. In this approach, the user has most of the same ultimate control, but exercises it differently (by modifying the code/manifest and re-running dep ensure). -> -> [@sdboyer in #371](https://github.com/golang/dep/issues/371#issuecomment-293246832) - -### What is a direct or transitive dependency? -* Direct dependencies are dependencies that are imported directly by your project: they appear in at least one import statement from your project. -* Transitive dependencies are the dependencies of your dependencies. Necessary to compile but are not directly used by your code. - -## Configuration -### What is the difference between `Gopkg.toml` (the "manifest") and `Gopkg.lock` (the "lock")? - -> The manifest describes user intent, and the lock describes computed outputs. There's flexibility in manifests that isn't present in locks..., as the "branch": "master" constraint will match whatever revision master HAPPENS to be at right now, whereas the lock is nailed down to a specific revision. -> -> This flexibility is important because it allows us to provide easy commands (e.g. `dep ensure -update`) that can manage an update process for you, within the constraints you specify, AND because it allows your project, when imported by someone else, to collaboratively specify the constraints for your own dependencies. -> -> [@sdboyer in #281](https://github.com/golang/dep/issues/281#issuecomment-284118314) - -## How do I constrain a transitive dependency's version? -First, if you're wondering about this because you're trying to keep the version -of the transitive dependency from changing, then you're working against `dep`'s -design. The lock file, `Gopkg.lock`, will keep the selected version of the -transitive dependency stable, unless you explicitly request an upgrade or it's -impossible to find a solution without changing that version. - -If that isn't your use case and you still need to constrain a transitive -dependency, you have a couple of options: - -1. Make the transitive dependency a direct one, either with a dummy import or an entry in the `required` list in `Gopkg.toml`. -2. Use an override. - -Overrides are a sledgehammer, and should only be used as a last resort. While -constraints and overrides are declared in the same way in `Gopkg.toml`, they -behave differently: - -* Constraints: - 1. Can be declared by any project's manifest, yours or a dependency - 2. Apply only to direct dependencies of the project declaring the constraint - 3. Must not conflict with the `constraint` entries declared in any other project's manifest -* Overrides: - 1. Are only utilized from the current/your project's manifest - 2. Apply globally, to direct and transitive dependencies - 3. Supersede constraints declared in all manifests, yours or a dependency's - -Overrides are also discussed with some visuals in [the gps docs](https://github.com/sdboyer/gps/wiki/gps-for-Implementors#overrides). - -## Can I put the manifest and lock in the vendor directory? -No. - -> Placing these files inside `vendor/` would concretely bind us to `vendor/` in the long term. -> We prefer to treat the `vendor/` as an implementation detail. -> -> [@sdboyer on go package management list](https://groups.google.com/d/msg/go-package-management/et1qFUjrkP4/LQFCHP4WBQAJ) - -## How do I get dep to authenticate to a git repo? - -`dep` currently uses the `git` command under the hood, so configuring the credentials -for each repository you wish to authenticate to will allow `dep` to use an -authenticated repository. - -First, configure `git` to use the credentials option for the specific repository. - -For example, if you use gitlab, and you wish to access `https://gitlab.example.com/example/package.git`, -then you would want to use the following configuration: - -``` -$ git config --global credential.https://gitlab.example.com.example yourusername -``` - -In the example the hostname `gitlab.example.com.example` string seems incorrect, but -it's actually the hostname plus the name of the repo you are accessing which is `username`. -The trailing 'yourusername' is the username you would use for the actual authentication. - -You also need to configure `git` with the authentication provider you wish to use. You can get -a list of providers, with the command: - -``` -$ git help -a | grep credential- - credential-cache remote-fd - credential-cache--daemon remote-ftp - credential-osxkeychain remote-ftps - credential-store remote-http -``` - -You would then choose an appropriate provider. For example, to use the osxkeychain, you -would use the following: - -``` -git config --global credential.helper osxkeychain -``` - -If you need to do this for a CI system, then you may want to use the "store" provider. -Please see the documentation on how to configure that: https://git-scm.com/docs/git-credential-store - -After configuring `git`, you may need to use `git` manually once to have it store the -credentials. Once you've checked out the repo manually, it will then use the stored -credentials. This at least appears to be the behavior for the osxkeychain provider. - -### How do I get dep to consume private git repos using a Github Token? - -Another alternative to make `dep` work with private repos is to use a [Personal Github -Token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) -and configure it inside the [`.netrc` file](https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html) -as the following example: -``` -machine github.com -   login [YOUR_GITHUB_USERNAME] - password [YOUR_GITHUB_TOKEN] -``` - -Once you have set that up, dep will automatically use that Token to authenticate to the repositories. - -## Behavior -### How does `dep` decide what version of a dependency to use? - -The full algorithm is complex, but the most important thing to understand is -that `dep` tries versions in a [certain -order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade), -checking to see a version is acceptable according to specified constraints. - -- All semver versions come first, and sort mostly according to the semver 2.0 - spec, with one exception: - - Semver versions with a prerelease are sorted after *all* non-prerelease - semver. Within this subset they are sorted first by their numerical - component, then lexicographically by their prerelease version. -- The default branch(es) are next; the semantics of what "default branch" means - are specific to the underlying source type, but this is generally what you'd - get from a `go get`. -- All other branches come next, sorted lexicographically. -- All non-semver versions (tags) are next, sorted lexicographically. -- Revisions, if any, are last, sorted lexicographically. Revisions do not - typically appear in version lists, so the only invariant we maintain is - determinism - deeper semantics, like chronology or topology, do not matter. - -So, given a slice of the following versions: - -- Branch: `master` `devel` -- Semver tags: `v1.0.0` `v1.1.0` `v1.1.0-alpha1` -- Non-semver tags: `footag` -- Revision: `f6e74e8d` - -Sorting for upgrade will result in the following slice. - -`[v1.1.0 v1.0.0 v1.1.0-alpha1 master devel footag f6e74e8d]` - -There are a number of factors that can eliminate a version from consideration, -the simplest of which is that it doesn't match a constraint. But if you're -trying to figure out why `dep` is doing what it does, understanding that its -basic action is to attempt versions in this order should help you to reason -about what's going on. - -## What external tools are supported? -During `dep init` configuration from other dependency managers is detected -and imported, unless `-skip-tools` is specified. - -The following tools are supported: `glide`, `godep`, `vndr`, `govend`, `gb`, `gvt`, `govendor` and `glock`. - -See [#186](https://github.com/golang/dep/issues/186#issuecomment-306363441) for -how to add support for another tool. - -## Why is `dep` ignoring a version constraint in the manifest? -Only your project's directly imported dependencies are affected by a `constraint` entry -in the manifest. Transitive dependencies are unaffected. See [How do I constrain a transitive dependency's version](#how-do-i-constrain-a-transitive-dependencys-version)? - -## Why did `dep` use a different revision for package X instead of the revision in the lock file? -Sometimes the revision specified in the lock file is no longer valid. There are a few -ways this can occur: - -* When you generated the lock file, you had an unpushed commit in your local copy of package X's repository in your `GOPATH`. (This case will be going away soon) -* After generating the lock file, new commits were force pushed to package X's repository, causing the commit revision in your lock file to no longer exist. - -To troubleshoot, you can revert dep's changes to your lock, and then run `dep ensure -v -n`. -This retries the command in dry-run mode with verbose logs enabled. Check the output -for a warning like the one below, indicating that a commit in the lock is no longer valid. - -``` -Unable to update checked out version: fatal: reference is not a tree: 4dfc6a8a7e15229398c0a018b6d7a078cccae9c8 -``` - -> The lock file represents a set of precise, typically immutable versions for the entire transitive closure of dependencies for a project. But "the project" can be, and is, decomposed into just a bunch of arguments to an algorithm. When those inputs change, the lock may need to change as well. -> -> Under most circumstances, if those arguments don't change, then the lock remains fine and correct. You've hit one of the few cases where that guarantee doesn't apply. The fact that you ran dep ensure and it DID a solve is a product of some arguments changing; that solving failed because this particular commit had become stale is a separate problem. -> -> [@sdboyer in #405](https://github.com/golang/dep/issues/405#issuecomment-295998489) - -## Why is `dep` slow? - -There are two things that really slow `dep` down. One is unavoidable; for the other, we have a plan. - -The unavoidable part is the initial clone. `dep` relies on a cache of local -repositories (stored under `$GOPATH/pkg/dep`), which is populated on demand. -Unfortunately, the first `dep` run, especially for a large project, may take a -while, as all dependencies are cloned into the cache. - -Fortunately, this is just an _initial_ clone - pay it once, and you're done. -The problem repeats itself a bit when you're running `dep` for the first time -in a while and there's new changesets to fetch, but even then, these costs are -only paid once per changeset. - -The other part is the work of retrieving information about dependencies. There are three parts to this: - -1. Getting an up-to-date list of versions from the upstream source -2. Reading the `Gopkg.toml` for a particular version out of the local cache -3. Parsing the tree of packages for import statements at a particular version - -The first requires one or more network calls; the second two usually mean -something like a `git checkout`, and the third is a filesystem walk, plus -loading and parsing `.go` files. All of these are expensive operations. - -Fortunately, we can cache the second and third. And that cache can be permanent -when keyed on an immutable identifier for the version - like a git commit SHA1 -hash. The first is a bit trickier, but there are reasonable staleness tradeoffs -we can consider to avoid the network entirely. There's an issue to [implement -persistent caching](https://github.com/golang/dep/issues/431) that's the -gateway to all of these improvements. - -There's another major performance issue that's much harder - the process of picking versions itself is an NP-complete problem in `dep`'s current design. This is a much trickier problem 😜 - -## How does `dep` handle symbolic links? - -> because we're not crazy people who delight in inviting chaos into our lives, we need to work within one `GOPATH` at a time. -> -[@sdboyer in #247](https://github.com/golang/dep/pull/247#issuecomment-284181879) - -Out of convenience, one might create a symlink to a directory within their `GOPATH/src`, e.g. `ln -s ~/go/src/github.com/user/awesome-project ~/Code/awesome-project`. - -When `dep` is invoked with a project root that is a symlink, it will be resolved according to the following rules: - -- If the symlink is outside `GOPATH` and links to a directory within a `GOPATH`, or vice versa, then `dep` will choose whichever path is within `GOPATH`. -- If the symlink is within a `GOPATH` and the resolved path is within a *different* `GOPATH`, then an error is thrown. -- If both the symlink and the resolved path are in the same `GOPATH`, then an error is thrown. -- If neither the symlink nor the resolved path are in a `GOPATH`, then an error is thrown. - -This is the only symbolic link support that `dep` really intends to provide. In keeping with the general practices of the `go` tool, `dep` tends to either ignore symlinks (when walking) or copy the symlink itself, depending on the filesystem operation being performed. - -## Does `dep` support relative imports? - -No. -> dep simply doesn't allow relative imports. this is one of the few places where we restrict a case that the toolchain itself allows. we disallow them only because: -> -> * the toolchain already frowns heavily on them<br> -> * it's worse for our case, as we start venturing into [dot dot hell](http://doc.cat-v.org/plan_9/4th_edition/papers/lexnames) territory when trying to prove that the import does not escape the tree of the project -> -> [@sdboyer in #899](https://github.com/golang/dep/issues/899#issuecomment-317904001) - -For a refresher on Go's recommended workspace organization, see the ["How To Write Go Code"](https://golang.org/doc/code.html) article in the Go docs. Organizing your code this way gives you a unique import path for every package. - -## How do I make `dep` resolve dependencies from my `GOPATH`? - -`dep init` provides an option to scan the `GOPATH` for dependencies by doing -`dep init -gopath`, which falls back to network mode when the packages are not -found in `GOPATH`. `dep ensure` doesn't work with projects in `GOPATH`. - -## Will `dep` let me use git submodules to store dependencies in `vendor`? - -No, with just one tiny exception: `dep` preserves `/vendor/.git`, if it exists. This was added at [cockroachdb](https://github.com/cockroachdb/cockroach)'s request, who rely on it to keep `vendor` from bloating their primary repository. - -The reasons why git submodules will not be a part of dep are best expressed as a pro/con list: - -**Pros** - -* git submodules provide a well-structured way of nesting repositories within repositories. - -**Cons** - -* The nesting that git submodules perform is no more powerful or expressive than what dep already does, but dep does it both more generally (for bzr and hg) and more domain-specifically (e.g. elimination of nested vendor directories). -* Incorporating git submodules in any way would new fork new paths in the logic to handle the submodule cases, meaning nontrivial complexity increases. -* dep does not currently know or care if the project it operates on is under version control. Relying on submodules would entail that dep start paying attention to that. That it would only be conditionally does not make it better - again, more forking paths in the logic, more complexity. -* Incorporating submodules in a way that is at all visible to the user (and why else would you do it?) makes dep's workflows both more complicated and less predictable: _sometimes_ submodule-related actions are expected; _sometimes_ submodule-derived workflows are sufficient. -* Nesting one repository within another implies that changes could, potentially, be made directly in that subrepository. This is directly contrary to dep's foundational principle that `vendor` is dead code, and directly modifying anything in there is an error. - -## Best Practices -### Should I commit my vendor directory? - -It's up to you: - -**Pros** - -- It's the only way to get truly reproducible builds, as it guards against upstream renames, - deletes and commit history overwrites. -- You don't need an extra `dep ensure` step to sync `vendor/` with Gopkg.lock after most operations, - such as `go get`, cloning, getting latest, merging, etc. - -**Cons** - -- Your repo will be bigger, potentially a lot bigger, - though [`prune`](Gopkg.toml.md#prune) can help minimize this problem. -- PR diffs will include changes for files under `vendor/` when Gopkg.lock is modified, - however files in `vendor/` are [hidden by default](https://github.com/github/linguist/blob/v5.2.0/lib/linguist/generated.rb#L328) on Github. - -## How do I roll releases that `dep` will be able to use? - -In short: make sure you've committed your `Gopkg.toml` and `Gopkg.lock`, then -just create a tag in your version control system and push it to the canonical -location. `dep` is designed to work automatically with this sort of metadata -from `git`, `bzr`, and `hg`. - -It's strongly preferred that you use [semver](http://semver.org)-compliant tag -names. We hope to develop documentation soon that describes this more precisely, -but in the meantime, the [npm](https://docs.npmjs.com/misc/semver) docs match -our patterns pretty well. - -## What semver version should I use? - -This can be a nuanced question, and the community is going to have to work out -some accepted standards for how semver should be applied to Go projects. At the -highest level, though, these are the rules: - -* Below `v1.0.0`, anything goes. Use these releases to figure out what you want - your API to be. -* Above `v1.0.0`, the general Go best practices continue to apply - don't make - backwards-incompatible changes - exported identifiers can be added to, but - not changed or removed. -* If you must make a backwards-incompatible change, then bump the major version. - -It's important to note that having a `v1.0.0` does not preclude you from having -alpha/beta/etc releases. The semver spec allows for [prerelease -versions](http://semver.org/#spec-item-9), and `dep` is careful to _not_ allow -such versions unless `Gopkg.toml` contains a range constraint that explicitly -includes prereleases: if there exists a version `v1.0.1-alpha4`, then the -constraint `>=1.0.0` will not match it, but `>=1.0.1-alpha1` will. - -Some work has been done towards [a tool -to](https://github.com/bradleyfalzon/apicompat) that will analyze and compare -your code with the last release, and suggest the next version you should use. - -## Is it OK to make backwards-incompatible changes now? - -Yes. But. - -`dep` will make it possible for the Go ecosystem to handle -backwards-incompatible changes more gracefully. However, `dep` is not some -magical panacea. Version and dependency management is hard, and dependency hell -is real. The longstanding community wisdom about avoiding breaking changes -remains important. Any `v1.0.0` release should be accompanied by a plan for how -to avoid future breaking API changes. - -One good strategy may be to add to your API instead of changing it, deprecating -old versions as you progress. Then, when the time is right, you can roll a new -major version and clean out a bunch of deprecated symbols all at once. - -Note that providing an incremental migration path across breaking changes (i.e., -shims) is tricky, and something we [don't have a good answer for -yet](https://groups.google.com/forum/#!topic/go-package-management/fp2uBMf6kq4). - -## My dependers don't use `dep` yet. What should I do? - -For the most part, you needn't do anything differently. - -The only possible issue is if your project is ever consumed as a library. If -so, then you may want to be wary about committing your `vendor/` directory, as -it can [cause -problems](https://groups.google.com/d/msg/golang-nuts/AnMr9NL6dtc/UnyUUKcMCAAJ). -If your dependers are using `dep`, this is not a concern, as `dep` takes care of -stripping out nested `vendor` directories. - -## How do I configure a dependency that doesn't tag its releases? - -Add a constraint to `Gopkg.toml` that specifies `branch: "master"` (or whichever branch you need) in the `[[constraint]]` for that dependency. `dep ensure` will determine the current revision of your dependency's master branch, and place it in `Gopkg.lock` for you. See also: [What is the difference between Gopkg.toml and Gopkg.lock?](#what-is-the-difference-between-gopkgtoml-the-manifest-and-gopkglock-the-lock) - -## How do I use `dep` with Docker? - -`dep ensure -vendor-only` creates the vendor folder from a valid `Gopkg.toml` and `Gopkg.lock` without checking for Go code. -This is especially useful for builds inside docker utilizing cache layers. - -Sample dockerfile: - -```Dockerfile -FROM golang:1.9 AS builder - -RUN curl -fsSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/vX.X.X/dep-linux-amd64 && chmod +x /usr/local/bin/dep - -RUN mkdir -p /go/src/github.com/*** -WORKDIR /go/src/github.com/*** - -COPY Gopkg.toml Gopkg.lock ./ -# copies the Gopkg.toml and Gopkg.lock to WORKDIR - -RUN dep ensure -vendor-only -# install the dependencies without checking for go code - -... -``` - -## How do I use `dep` in CI? - -Since `dep` is expected to change until `v1.0.0` is released, it is recommended to rely on a released version. -You can find the latest binary from the [releases](https://github.com/golang/dep/releases) page. - -Sample configuration for Travis CI: - -```yml -# ... - -env: - - DEP_VERSION="X.X.X" - -before_install: - # Download the binary to bin folder in $GOPATH - - curl -L -s https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 -o $GOPATH/bin/dep - # Make the binary executable - - chmod +x $GOPATH/bin/dep - -install: - - dep ensure -``` - -Caching can also be enabled but there are a couple of caveats you should be aware of: - -> Until recently, we have had intermittent cache corruption that would have been super annoying if it was breaking Travis build too. -> -> Also according to https://docs.travis-ci.com/user/caching/#Things-not-to-cache, they don't recommend it for larger caches. -> -> https://docs.travis-ci.com/user/caching/#How-does-the-caching-work%3F -> -> > Note that this makes our cache not network-local, it's still bound to network bandwidth and DNS resolutions for S3. -> > That impacts what you can and should store in the cache. If you store archives larger than a few hundred megabytes in the cache, it's unlikely that you'll see a big speed improvement. -> -> [@carolynvs in #1293](https://github.com/golang/dep/pull/1293#issuecomment-342969292) - -If you are sure you want to enable caching on travis, it can be done by adding `$GOPATH/pkg/dep`, the default location for `dep` cache, to the cached directories: - -```yml -# ... - -cache: - directories: - - $GOPATH/pkg/dep -``` diff --git a/vendor/github.com/golang/dep/docs/Gopkg.lock.md b/vendor/github.com/golang/dep/docs/Gopkg.lock.md deleted file mode 100644 index c68fdc0128cd9109ffa47f96ee8997e3f3b945f9..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/Gopkg.lock.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Gopkg.lock ---- - -The `Gopkg.lock` file is generated by `dep ensure` and `dep init`. It is the output of [the solving function](ensure-mechanics.md#functional-flow): a transitively complete snapshot of a project's dependency graph, expressed as a series of `[[project]]` stanzas. That means: - -* Every package a project needs to compile -* Plus any [`required`](Gopkg.toml.md#required) packages -* Less any [`ignored`](Gopkg.toml.md#ignored) packages - -`Gopkg.lock` also contains some metadata about the algorithm used to arrive at the final graph, under `[solve-meta]`. - -`Gopkg.lock` always includes a `revision` for all listed dependencies, as the semantics of `revision` guarantee them to be immutable. Thus, the `Gopkg.lock` acts as a reproducible build list - as long as the upstream remains available, all dependencies can be precisely reproduced. - -`Gopkg.lock` is autogenerated; editing it manually is generally an antipattern. If there is a goal you can only achieve by hand-editing `Gopkg.lock`, it is at least a feature request, and likely a bug. - -## `[[project]]` - -The dependency graph is expressed as a series of `[[project]]` stanzas, each representing a single dependency project. A given project can only appear once in the list, and the version information expressed about them encompasses all contained packages - it is not possible to have multiple packages from a single project at different versions. - -These are all the properties that can appear in a `[[project]]` stanza, and whether or not they are guaranteed to be present/must be present for a stanza to be valid. - -| **Property** | **Always present?** | -| ------------ | ------------------- | -| `name` | Y | -| `packages` | Y | -| `source` | N | -| `revision` | Y | -| `version` | N | -| `branch` | N | - -### `name` - -The project to which the stanza applies, as identified by its [project root](glossary.md#project-root). - -### `source` - -If present, it indicates the upstream source from which the project should be retrieved. It has the same properties as [`source` in `Gopkg.toml`](Gopkg.toml.md#source). - -### `packages` - -A complete list of directories from within the source that dep determined to be necessary for the build. - -In general, this is the set of packages that were found to be participants in the package import graph, through at least one but as many as all of the following mechanisms: - -* Being in the current project's [`required`](Gopkg.toml.md#required) list -* Being imported by a package from either the current project or a different dependency -* Being imported by a package from within this project that, directly or transitively, is imported by a package from a different project - -### Version information: `revision`, `version`, and `branch` - -In order to provide reproducible builds, it is an absolute requirement that every project stanza contain a `revision`, no matter what kinds of constraints were encountered in `Gopkg.toml` files. It is further possible that exactly one of either `version` or `branch` will _additionally_ be present. - -When one of the other two are present, the `revision` is understood to be the underlying, immutable identifier that corresponded to that `version` or `branch` _at the time when the `Gopkg.lock` was written_. - -## `[solve-meta]` - -Metadata contained in this section tells us about the algorithm that was used to generate the `Gopkg.lock` file. These are very coarse indicators, primarily used to trigger a re-evaluation of the lock when it might have become invalid, as well as warn a team when its members are using algorithms with potentially subtly different effects. - -More details on "analyzer" and "solver" follow, but the versioning principle is the same: algorithmic changes that result in a decrease to the set of acceptable solutions for at least one input set generally require a version bump, while changes that increase the size of that set do not. However, this is not a formal definition; we leave room for judgment calls on small changes and bug fixes, and we bump at most once per release. - -By bumping versions only on solution set contractions, but not expansions, it allows us to avoid having to bump constantly (which could make using dep across teams awkward), while still making it likely that when the solver and version numbers match between `Gopkg.lock` and a running version of dep, what's recorded in the file is acceptable by the running version's rules. - -### `analyzer-name` and `analyzer-version` - -The analyzer is an internal dep component responsible for interpreting the contents of `Gopkg.toml` files, as well as metadata files from any tools dep knows about: `glide.yaml`, `vendor.json`, etc. - -The analyzer is named because the dep needs to identify itself to its engine, gps (`github.com/golang/dep/gps`); gps knows nothing about dep. The analyzer version is bumped when something in the analyzer's logic begins treating data that it already accepted in a significantly different way, or stops accepting a particular class of data. It is _not_ changed when support for entirely new types of data are added. - -For example, if dep's analyzer stopped supporting automated conversions from glide, then that would not require bumping the analyzer version, as doing so makes _more_ solutions possible. Adding support for converting from a new tool, or changing the interpretation of `version` fields in `Gopkg.toml` so that it was only allowed to specify minimum versions, would entail a version bump. - -### `solver-name` and `solver-version` - -The solver is the algorithm behind [the solving function](ensure-mechanics.md#functional-flow). It selects all the versions that ultimately appear in `Gopkg.lock` by finding a combination that satisfies all the rules, including those from `Gopkg.toml` (fed to the solver by the analyzer). - -The solver is named because, like the analyzer, it is pluggable; an alternative algorithm could be written that applies different rules to achieve the same goal. The one dep uses, "gps-cdcl", is named after [the general class of SAT solving algorithm it most resembles](https://en.wikipedia.org/wiki/Conflict-Driven_Clause_Learning), though the algorithm is actually a specialized, domain-specific [SMT solver](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories). - -The same general principles of version-bumping apply to the solver version: if the solver starts enforcing [Go 1.4 import path comments](https://golang.org/cmd/go/#hdr-Import_path_checking), that entails a bump, because it can only narrow the solution set. If it were to later relax that requirement, it would not require a bump, as that can only expand the solution set. - -### `inputs-digest` - -A SHA256 hash digest of all the [inputs to the solving function](ensure-mechanics.md#functional-flow). Those inputs can be shown directly with the hidden command `dep hash-inputs`, allowing this value to be generated directly: - -``` -dep hash-inputs | tr -d “\n†| shasum -a256 -``` \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/Gopkg.toml.md b/vendor/github.com/golang/dep/docs/Gopkg.toml.md deleted file mode 100644 index 84ff9d3f1a96aea0b9872f7334dcfcb4228c57d8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/Gopkg.toml.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: Gopkg.toml ---- - -The `Gopkg.toml` file is initially generated by `dep init`, and is primarily hand-edited. It contains several types of rule declarations that govern dep's behavior: - -* _Dependency rules:_ [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. -* _Package graph rules:_ [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively. -* [`metadata`](#metadata) are a user-defined maps of key-value pairs that dep will ignore. They provide a data sidecar for tools building on top of dep. -* [`prune`](#prune) settings determine what files and directories can be deemed unnecessary, and thus automatically removed from `vendor/`. - -Note that because TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`. - -There is a full [example](#example) `Gopkg.toml` file at the bottom of this document. `dep init` will also, by default, generate a `Gopkg.toml` containing some example values, for guidance. - -## Dependency rules: `[[constraint]]` and `[[override]]` - -Most of the rule declarations in a `Gopkg.toml` will be either `[[constraint]]` or `[[override]]` stanzas. Both of these types of stanzas allow exactly the same types of values, but dep interprets them differently. Each allows the following values: - -* `name` - the import path corresponding to the [source root](glossary.md#source-root) of a dependency (generally: where the VCS root is) -* At most one [version rule](#version-rules) -* An optional [`source` rule](#source) -* [`metadata`](#metadata) that is specific to the `name`'d project - -A full example (invalid, actually, as it has more than one version rule, for illustrative purposes) of either one of these stanzas looks like this: - -```toml -[[constraint]] - # Required: the root import path of the project being constrained. - name = "github.com/user/project" - # Recommended: the version constraint to enforce for the project. - # Note that only one of "branch", "version" or "revision" can be specified. - version = "1.0.0" - branch = "master" - revision = "abc123" - - # Optional: an alternate location (URL or import path) for the project's source. - source = "https://github.com/myfork/package.git" - - # Optional: metadata about the constraint or override that could be used by other independent systems - [metadata] - key1 = "value that convey data to other systems" - system1-data = "value that is used by a system" - system2-data = "value that is used by another system" -``` - -### `[[constraint]]` - -A `[[constraint]]` stanza defines rules for how a [direct dependency](glossary.md#direct-dependency) must be incorporated into the dependency graph. Dep respects these declarations from the current project's `Gopkg.toml`, as well as the `Gopkg.toml` files found in any dependencies. - -**Use this for:** having a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) use a specific branch, version range, revision, or alternate source (such as a fork). - -### `[[override]]` - -An `[[override]]` stanza differs from a `[[constraint]]` in that it applies to all dependencies, [direct](glossary.md#direct-dependency) and [transitive](glossary.md#transitive-dependency), and supersedes all other `[[constraint]]` declarations for that project. However, only overrides from the current project's `Gopkg.toml` are incorporated. - -**Use this for:** Overrides are primarily intended as a way of eliminating disagreements between multiple irreconcilable `[[constraint]]` declarations on a single dependency. However, they will also be your primary recourse if you need to [constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version) - -Overrides should be used cautiously and temporarily, when possible. - -### `source` - -A `source` rule can specify an alternate location from which the `name`'d project should be retrieved. It is primarily useful for temporarily specifying a fork for a repository. - -`source` rules are generally brittle and should only be used when there is no other recourse. Using them to try to circumvent network reachability issues is typically an antipattern. - -### Version rules - -Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. - -#### `version` - -`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. It can be used to target an arbitrary VCS tag, or a semantic version, or a range of semantic versions. - -Specifying semantic version ranges can be done using the following operators: - -* `=`: equal -* `!=`: not equal -* `>`: greater than -* `<`: less than -* `>=`: greater than or equal to -* `<=`: less than or equal to -* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5 -* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0 -* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0 -* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0 - -You might, for example, include a rule that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "~2.1.0"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info. - -**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example: - -* `1.2.3` becomes the range `>=1.2.3, <2.0.0` -* `0.2.3` becomes the range `>=0.2.3, <0.3.0` -* `0.0.3` becomes the range `>=0.0.3, <0.1.0` - -`~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example: -``` -^1.2.3 means 1.2.3 <= X < 2.0.0 -^0.2.3 means 0.2.3 <= X < 0.3.0 -^0.0.3 means 0.0.3 <= X < 0.1.0 -``` - -To pin a version of direct dependency in manifest, prefix the version with `=`. For example: -```toml -[[constraint]] - name = "github.com/pkg/errors" - version = "=0.8.0" -``` - -#### `branch` - -Using a `branch` constraint will cause dep to use the named branch (e.g., `branch = "master"`) for a particular dependency. The revision at the tip of the branch will be recorded into `Gopkg.lock`, and almost always remain the same until a change is requested, via `dep ensure -update`. - -In general, you should prefer semantic versions to branches, when a project has made them available. - -#### `revision` - -A `revision` is the underlying immutable identifier - like a git commit SHA1. While it is allowed to constrain to a `revision`, doing so is almost always an antipattern. - -Usually, folks are inclined to pin to a revision because they feel it will somehow improve their project's reproducibility. That is not a good reason. `Gopkg.lock` provides reproducibility. Only use `revision` if you have a good reason to believe that _no_ other version of that dependency _could_ work. - -## Package graph rules: `required` and `ignored` - -As part of normal operation, dep analyzes import statements in Go code. These import statements connect packages together, ultimately forming a graph. The `required` and `ignored` rules manipulate that graph, in ways that are roughly dual to each other: `required` adds import paths to the graph, and `ignored` removes them. - -### `required` - -`required` lists a set of packages (not projects) that must be included in Gopkg.lock. This list is merged with the set of packages imported by the current project. -```toml -required = ["github.com/user/thing/cmd/thing"] -``` - -**Use this for:** linters, generators, and other development tools that - -* Are needed by your project -* Aren't `import`ed by your project, [directly or transitively](FAQ.md#what-is-a-direct-or-transitive-dependency) -* You don't want to put them in your `GOPATH`, and/or you want to lock the version - -Please note that this only pulls in the sources of these dependencies. It does not install or compile them. So, if you need the tool to be installed you should still run the following (manually or from a `Makefile`) after each `dep ensure`: - -```bash -cd vendor/pkg/to/install -go install . -``` - -This only works reliably if this is the only project to install these executables. This is not enough if you want to be able to run a different version of the same executable depending on the project you're working. In that case you have to use a different `GOBIN` for each project, by doing something like this before running the above commands: - -```bash -export GOBIN=$PWD/bin -export PATH=$GOBIN:$PATH -``` - -You might also try [virtualgo](https://github.com/GetStream/vg), which installs dependencies in the `required` list automatically in a project specific `GOBIN`. - - -### `ignored` -`ignored` lists a set of packages (not projects) that are ignored when dep statically analyzes source code. Ignored packages can be in this project, or in a dependency. - -```toml -ignored = ["github.com/user/project/badpkg"] -``` - -Use `*` to define a package prefix to be ignored. This will cause any lexical wildcard match to be ignored, including the literal string prior to the `*`. - -```toml -ignored = ["github.com/user/project/badpkg*"] -``` - -**Use this for:** preventing a package, and any of that package's unique dependencies, from being incorporated in `Gopkg.lock`. - -## `metadata` -`metadata` can exist at the root as well as under `constraint` and `override` declarations. - -`metadata` declarations are ignored by dep and are meant for usage by other independent systems. - -The root `metadata` declaration defines information about the project itself, while a `metadata` declaration under a `[[constraint]]` or an `[[override]]` defines metadata about that rule, for the `name`d project. -```toml -[metadata] -key1 = "value that convey data to other systems" -system1-data = "value that is used by a system" -system2-data = "value that is used by another system" -``` - -## `prune` - -`prune` defines the global and per-project prune options for dependencies. The options determine which files are discarded when writing the `vendor/` tree. - -The following are the current available options: -* `unused-packages` indicates that files from directories that do not appear in the package import graph should be pruned. -* `non-go` prunes files that are not used by Go. -* `go-tests` prunes Go test files. - -Out of an abundance of caution, dep non-optionally preserves files that may have legal significance. - -Pruning is disabled by default. It can be enabled by setting them to `true` at the root level. -```toml -[prune] - non-go = true -``` - -The same prune options can be defined per-project. An addtional `name` field is required and, as with should represent a project and not a package. - - -```toml -[prune] - non-go = true - - [[prune.project]] - name = "github.com/project/name" - go-tests = true - non-go = false -``` -# Example - -A sample `Gopkg.toml` with most elements present: - -```toml -required = ["github.com/user/thing/cmd/thing"] - -ignored = [ - "github.com/user/project/pkgX", - "bitbucket.org/user/project/pkgA/pkgY" -] - -[metadata] -codename = "foo" - -[prune] - non-go = true - - [[prune.project]] - name = "github.com/project/name" - go-tests = true - non-go = false - -[[constraint]] - name = "github.com/user/project" - version = "1.0.0" - - [metadata] - property1 = "value1" - property2 = 10 - -[[constraint]] - name = "github.com/user/project2" - branch = "dev" - source = "github.com/myfork/project2" - -[[override]] - name = "github.com/x/y" - version = "2.4.0" - - [metadata] - propertyX = "valueX" -``` diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyFlat.png b/vendor/github.com/golang/dep/docs/assets/DigbyFlat.png deleted file mode 100644 index e05dcf38f0c792a8b4078898278b117992076e98..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyFlat.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyFlat.svg b/vendor/github.com/golang/dep/docs/assets/DigbyFlat.svg deleted file mode 100644 index 84b63eca5e8fc062beb9fe65cda5ab113368e6ff..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyFlat.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720.07 762.53"><defs><style>.cls-1{fill:#ced8d2;}.cls-2{fill:#1d1d1b;}.cls-3{fill:#ccbca8;}.cls-4{fill:#b7a38d;}.cls-5{fill:#b79765;}.cls-6{fill:#fff;}.cls-7{fill:#d7b89b;}.cls-8{opacity:0.27;}.cls-9{opacity:0.51;}.cls-10{fill:#e3fbfc;}.cls-11{opacity:0.39;}.cls-12{fill:none;stroke:#1d1d1b;stroke-linecap:round;stroke-linejoin:round;stroke-width:5px;}</style></defs><title>BoyeFlat</title><g id="BACKGROUND_OCLOR" data-name="BACKGROUND OCLOR"><path class="cls-1" d="M604,97c102.41,62,170.85,174.54,170.85,303,0,195.53-158.51,354-354,354s-354-158.51-354-354A352.48,352.48,0,0,1,139,185.68l6.95-8.83A356,356,0,0,1,220.64,108Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M774.33,418.17H743a2.5,2.5,0,0,1,0-5h31.33a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/></g><g id="COLOR"><path class="cls-3" d="M379.67,631.39l50.88-10.2,110.17-24.29,74.73-16.24-13.42-60L594.42,482H680l66-17.43V289l-50.12-6.6V177.1l-23.14-25.84-5.41-2.66L604,148V12.67L539,0,400,5V32H290L222,46V174.2l-83,2.89V312.74L80,314l-3.72,4.24,1,154.1,1.75,2,57.45,11.84,57.15-.53L343,454.5c-.07,0,4.24,22.37,4.47,23.62l4.68,24.73c1.64,8.67,3.73,18.35,2.53,27.22-.51,3.75-.49,7.66-.68,11.44-.17,3.33-.59,6.81,3.25,7.49,1.29.23,2.84-.51,3.7.5s.4,3.3.62,4.55c.37,2.13,1.11,4.34,1.52,6.52l2.81,14.86,5,26.61,5.49,29s.05.34.06.34Z" transform="translate(-60.79 2.5)"/><polygon class="cls-4" points="134.41 488.2 78.21 488.68 13.87 477.07 16.52 316.5 280.95 315.24 352.71 324.5 352.71 390.84 343.71 391 134.41 488.2"/><polygon class="cls-4" points="355.21 150.5 355.21 297.5 635.1 295.83 635.1 179.59 624.21 167 611.96 153.75 591.85 151.83 355.21 150.5"/><polygon class="cls-4" points="161.71 172.5 161.21 48.46 229.21 34.5 366.21 34.5 366.21 148.95 355.21 150.5 354.38 177.49 227.43 179.46 161.71 172.5"/><path class="cls-5" d="M345.88,628.62a19.34,19.34,0,0,0-3.63,1.85c-2.64,1.58-5.9,2.39-8.78,3.45-3.7,1.36-7.63,3.4-11.49,4.23L304,642l-23,.65-32.85-9.12-7.9,6.43-9.5,4.29-10.13,2L217.74,642l4.69-12.72,8.29-7.88-10.09-12.88-6.8-21.21c-.15-4.54-.28-9.09-.46-13.63-.3-7.38-4.83-1.22-7.93-5.12-2.19-2.75,1.31-8.37,2.14-11.07,1.07-3.46,3.65-6.93,4.39-10.37.4-1.85-.79-3.32-.72-5.08,0-1.19.59-1.75.76-2.79.45-2.78-.62-5.74-.77-8.51a117.36,117.36,0,0,0-1.67-11.85c-.45-2.87-.2-6.63-2.31-8.89-1.73-1.86-4.94-2-6.25-4.25-1.1-1.9.2-3.86,0-6-.46-5.23-3.43-9.56-5.81-14.05l-6.84-12.87-8.25-15.52-7.75-20.06,1.3-22.67L182,391.63l3.62-6.63-6.09-2.31-4.76-8.25-.58-11,2.6-4.53,6.43-3.44,5.21,1.25,9.51,9L222.55,355l38.54-8.5,1-7.65,2.74-5.2,5.88-1,3.44,2.58,4.14,9.6,24,.7,32,5.52L350,363.07l8.4-3.82L373.94,355l11.35.35,4.29,3.65L365.95,378.2l6.22,22,14.59,20.54,7.77,6.22-.82,12.28-.82,3.44L343,454.5c-.52.12,6.72,41.69,7.34,45.53.84,5.22,1.15,10.56,2.18,15.72a45.42,45.42,0,0,1,.49,8.61V535.8c0,3.16-.7,9.73,1.75,12.08,1.49,1.43,2.23-.07,3.76.62,2.49,1.13,3,8.54,3.63,11.14L365,572.22c1.27,5.54,3,11.17,3.86,16.79l6.24,40.78,3.37,3.93,3.22-.31.51,6.09-8.08,3.15c-7.9-3.34-15.36-6.95-21.87-12.71a6,6,0,0,0-1.84-1.28A6.58,6.58,0,0,0,345.88,628.62Z" transform="translate(-60.79 2.5)"/><path class="cls-6" d="M367.71,375s25.05-15.79,25.17-15.79,4.73,6.38,4.73,6.38l6.18,19.06-3.15,14-5.14,6.35-5.92,2.45-5.69-4.41-4.45-2.88.39-7.3L371,391.63Z" transform="translate(-60.79 2.5)"/><polygon class="cls-6" points="268 386.47 240.1 389.87 209.14 394.5 194.94 395.41 192.21 407.55 197.47 425.94 207.9 439.05 220.17 446.08 230.11 448.31 240.1 448.06 252.46 444.82 262.21 437.75 268.24 430.09 273.17 419.72 275.01 407.55 273.81 397.65 268 386.47"/><path class="cls-2" d="M362.47,402.31a4.84,4.84,0,0,0,1.79,1l3.11,1.18a10.32,10.32,0,0,0,3.91.92c2.44-.07,4.46-1.82,6.24-3.49a6,6,0,0,0,2.17-3.23A4.82,4.82,0,0,0,378,394.8c-2.45-2.47-7.94-4.68-11.46-3.35C363.61,392.55,359.91,399.72,362.47,402.31Z" transform="translate(-60.79 2.5)"/><path class="cls-7" d="M355,414.41c.84,3.95,4.6,7.43,8.59,6.85,2.93-.42,5.19-2.74,7.93-3.87,4.64-1.92,9.9-.21,14.92-.33a5,5,0,0,0,2-.35,3.89,3.89,0,0,0,1.84-4.23,10.3,10.3,0,0,0-2.31-4.34q-2.11-2.7-4.46-5.2c-1.22-1.3-3-2.65-4.61-1.88a6.15,6.15,0,0,0-1.74,1.69,7.77,7.77,0,0,1-7,2.48c-3.49-.58-7.21-4.17-10.76-2.09S354.24,410.71,355,414.41Z" transform="translate(-60.79 2.5)"/><g class="cls-8"><path class="cls-6" d="M368.81,388.34l-1.1-23.69s8.48-17.33,8.09-18,6.68-6.06,6.68-6.06l13-1,8.29,1.85,9.82,12.28,7.21,15.07L424.21,386l-4.71,21.73-6.39,11.59-8.61,4.11L390.36,422l-5.08-3.31,3.67-3.79v-5.42l-4-6.79-5.56-2.47-1.51-7.57Z" transform="translate(-60.79 2.5)"/></g><g class="cls-8"><polygon class="cls-6" points="226.66 366.6 237.24 361.46 250.18 361.46 265.7 366.6 279.96 384.01 285.01 395.42 287.35 407.55 286.4 422.15 279.23 440.12 268 452.2 253.91 456.94 235.27 454.47 220.17 446.08 208.28 425.94 205.61 398.57 213.7 378.9 226.66 366.6"/></g><g class="cls-9"><path class="cls-6" d="M409,439.75c2.36,4.34,2.22,12.12,2.69,17.5.09,1.06-.14,3.22.56,4,1.48,1.65,1-.36,2.56-.69.63-.14,1.51.46,1.75.39.58-.16,1.31-1.06,1.76-1.16,1.15-.24,3,.52,4.19,0,.76-.35,1-1.35,1.69-1.59.86-.31,1.44.2,2.31.08,1.47-.21,4-2,4.8-.05,1.43.12,1.21-1.24,2.15-1.49.72-.19,1.17.59,1.7.51.9-.12,3.54-.38,4.45-1,2.39-1.52,1-8.77.9-11.83A110.37,110.37,0,0,0,439,431.52c-2.13,0-4.39,1.84-6.54,2.33-5.92,1.36-12,1.57-17.91,3.15" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M536.5,417c-1.36,2.71.54,8.93,1.31,12,.62,2.48,1.22,5,1.73,7.46,1.31-.76,1.41-1.43,3-1.49a14.4,14.4,0,0,0,1.74.77c1.14.13,1.75-.4,2.77-.56,1.84-.29,4.55-.88,6.77-.28-2.06-4.24-3-8.94-3.79-13.6-.18-1,.13-3.81-.67-4.58C547.82,415.29,542.06,417.06,536.5,417Z" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M547.25,294.25c0,9.83-1.48,19.55-1.25,29.38,0,1-.43,3.13,0,4,1.14,2.17,1,.14,2.53.12s2.27,1.32,4.2,1.26c1.21,0,2.66-.62,4-.76,3.52-.36,8.43.88,11.46,2.23.67-11.62-.15-23.39-.24-34.95-.89,0-1.82,0-2.72,0" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M374.75,251c-.19,4,.75,8,.75,12,0,3.31-.18,6.68,0,10,.21,3.74.35,7.47.54,11.21,1.38.2,3.73-1.36,4.73-1,1.66.62.39,3.52,2.47,3.79,1.05.14,1.18-1.19,2-1.3s1.31.73,2,.73,1.89-.48,2.52-.4,1.11.91,1.41.91c4.59,0,3.49-6.39,3.58-10.1.13-5.21,1.23-10.28,1.25-15.49,0-1.39.84-6.83-.05-7.82-.59-.65-1.81-.24-2.59-.25-4.44,0-8.91.19-13.36.19" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M106.25,316.25c-1.22.56-1,9.29-1,11.36,0,3.62.17,7.29,0,10.9-.18,4,.39,8.06.28,12,1.35-.75,2.9-3.06,4.67-2.25.54.25.24,1.64,1,1.93.91.36,1.25-.45,2.07-.48,1.63-.05,2.85.13,4.37-.9,2.49-1.67,1.66-4,1.38-7a76.43,76.43,0,0,1,.5-16.47c.16-1.27,1.52-4.07.75-5.3-1.56-2.48-7.92.65-10.25-1.75" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M164.25,177.75c-1.19,3.13-.24,7.9-.49,11.31a68.35,68.35,0,0,0,.46,11.07c.29,3.43-.16,7.73,1.25,10.84,1-.46,1.46-1.42,2.82-1.47.78,0,2,.77,2.82,1,2.6.78,4.87,1.11,5.37-1.72,1.86-10.4-1.63-22.08,1-32.28" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M314.75,177.5c0,7.1,1,13.7,1.73,20.63.29,2.92-.35,7.68,1,10.32,1.16,2.23.77.49,2.85-.06,2.62-.7,1.29.93,3.27,1.47.61.17,2.79-.54,3.55-.66a40.06,40.06,0,0,0,4.08-.44c.39-.1,2-.76,2.13-.74.87.11,1.12.85,1.65,1,1.47.41,3.44.31,4.72,1.27,2.09-1.86,1.25-6.75,1.25-9.29a111.45,111.45,0,0,1,.28-11.35c.43-4.23,2.08-8.41,2-12.67,0,.13-.45.23-.75.54" transform="translate(-60.79 2.5)"/></g><path class="cls-6" d="M638.75,149.5c0,7.67-.1,15.3-.27,22.94.64-1.54,2.45-3.17,4.22-2.9.54,3.11,1,3.66,3.49,1.74,1.22,3.69,3.36-.27,4.8-1s3.29.33,4.75,0c2-.47,2.21-2.73,2.48-4.73.72-5.42,1.62-10.88,2.52-16.27" transform="translate(-60.79 2.5)"/><g class="cls-9"><path class="cls-6" d="M565.25,4.5c-1.2,3.83-.25,9.22-.25,13.24s-.2,8.22.13,12.26c.34,4.2,1,8.33,1.41,12.49.65-.46,1.79-2.75,2.71-2.77.62,0,1.28,1.34,2,1.55-.51-.15,2.6-.36,2.12-.27.58-.11,1.29.45,2.08-.47,0,.81.59,1.27.81,1.76a1.44,1.44,0,0,1,1.94-.08c1.62-2.72,1.09-7.6,1.24-10.71s.35-6.07.57-9.07c.26-3.51-1.82-10.46-.26-13.18" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M344,32c-.48,1,.06,2.92,0,4.3-.19,2.38-1.19,4.66-1.53,7-.46,3.24-.18,6.66-.18,9.93,0,4-.57,8.72.5,12.48,1.9-1.32,4.18-5.76,6.51-6,.23.57.47,2.78,1.23,3,1.51.34,1.67-2.51,2.77-2.78,1.7-.43,1.94,2.07,3.94.33,1,2.63,1.73,0,3-.48s2.08.81,3.71-.52c.4,1.15,1.06,2.27,2.23,2.45,1.38-2.07,1.35-4.43,1.62-6.86.37-3.41,1.16-6.53,1.19-10,0-4.25-.05-8.71,1.25-12.62" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M247.5,41.25c-.35,3.5,1.76,7.33,2.25,10.81.25,1.81.14,4,1.25,5.48,1.82-3,4.84,1.18,5.79-1,6.84,1.07,2.63-13.17,5-16.54" transform="translate(-60.79 2.5)"/></g><g class="cls-9"><path class="cls-6" d="M709.67,295.33c2.33,3.49,2,11.62,2,16a48.19,48.19,0,0,1-1.63,14c1.82-1.77,2.28-.66,4.27-.64,1.46,0,2.63.09,4.2,0,4.21-.25,4.85.8,4.83-4.4,0-9,1.83-19.42,1.67-27.6" transform="translate(-60.79 2.5)"/></g><path class="cls-5" d="M372.5,517.5c-1,0-4.6-.61-5.25-.27-1.44.77-.83,5.27-1.06,7.08a86.53,86.53,0,0,0-.65,15.65c3.48.21,7.31-1.35,10.34-2.82,2.46-1.19,7-2.37,8.37-5,1.23-2.26-.15-5.42-1.3-7.43C380.22,520,375.95,520.66,372.5,517.5Z" transform="translate(-60.79 2.5)"/><path class="cls-6" d="M364,513.75c-1.64,0-3.47.25-5-.4-1-.43-1.89-2-2.87-2.21-2.63-.57-3.64,4.44-3.93,6.55-.65,4.7,0,9.78-.21,14.56-.18,3.54-.83,7.5-.49,11,.27,2.77,5.17,7.86,7,3.79,2.07,0,2.24,1.42,4.13-.47,2.36-2.36,2.43-8.28,2.58-11.46A89.06,89.06,0,0,0,364,513.75Z" transform="translate(-60.79 2.5)"/><path class="cls-6" d="M346.75,488.75c-4.43-.36-9,1.44-13.25,2.5s-8.35,2.19-12.6,2.12a119.23,119.23,0,0,0-14.92.71c-9.72,1-19.31,3-29,4.43-8,1.18-16.07.42-24.15.8a160.73,160.73,0,0,1-21.67-.3c-3.36-.3-6.5-1.24-9.81-1.71s-7.16.62-10.52,0c-2.57-.5-10.5-4.42-12.24-.89-1.1,2.24,1.65,9,3.37,10.62,1.91,1.8,3.77,2.19,5.08,4.74s1.34,5.38,2.05,8a61.06,61.06,0,0,1,2,12c.21,3.07-.48,6-.26,9,.41,5.51-1.6,10.3-2.13,15.74-.27,2.81-1.92,4.91-2.43,7.58-.45,2.35-1.55,4.24.74,5.47,1.78,1,4.4.33,6.33.6,4.14.59,8.24,1.38,12.37,2.18,10.84,2.11,23,2.42,34,1.95a173.24,173.24,0,0,1,25.22.5c7.15.72,14.39,1.51,21.56,1.87s13.5.73,20.7-.13c4.43-.53,8.73-1,13.2-1.3,3.77-.21,7.17-.5,10.6-2,2.85-1.28,10.28-3.3,11-6.25.81-3.33-1.57-7.8-2-11.1-.3-2.5-.36-4.25-1.34-6.51-5.43.15-6.21-5.74-6.47-10.28-.19-3.35,1.7-6.78,2.08-10.14a70.7,70.7,0,0,0,.18-8.57c-.06-4.81-1.46-9.9-2.56-14.55-.51-2.15-4.41-14.24-4.69-14.24" transform="translate(-60.79 2.5)"/><path class="cls-6" d="M367.67,422.33c-.24-.33.24-.54-.26-.66-.48,7.73,6.38,11.62,12.85,8.57,5.41-2.54,7.2-11,.74-12.92A11.57,11.57,0,0,0,367.67,422.33Z" transform="translate(-60.79 2.5)"/><path class="cls-10" d="M231,391.5c-3,2.57-14.36,15.14-8,18.65C227.9,412.85,231.23,401.12,231,391.5Z" transform="translate(-60.79 2.5)"/><path class="cls-10" d="M230.5,419c-3.25,2.7-10.29,24.24-2.73,21.27C233.1,438.17,229.89,425.67,230.5,419Z" transform="translate(-60.79 2.5)"/></g><g id="DETAILS"><path class="cls-2" d="M391.56,572.73a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,0,1,.5,1.94l-33.32,8.69A1,1,0,0,1,391.56,572.73Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M398.8,603.88a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.1,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M398.8,603.88a1,1,0,0,1-.24-2c11.3-2.76,24.26-5.85,34.69-7.87a1,1,0,1,1,.38,2c-10.39,2-23.32,5.09-34.6,7.85A1,1,0,0,1,398.8,603.88Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M433.44,596a1,1,0,0,1-.92-.61c-2.65-6.23-4.23-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,0,1,1.92-.57c1.08,3.65,2,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M430.55,564.05a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,0,1,.5,1.94L430.8,564A1,1,0,0,1,430.55,564.05Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M437.79,595.21a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.11,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M437.79,595.21a1,1,0,0,1-.24-2c11.3-2.76,24.26-5.85,34.69-7.87a1,1,0,1,1,.38,2c-10.39,2-23.32,5.09-34.6,7.85A1,1,0,0,1,437.79,595.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M472.43,587.35a1,1,0,0,1-.92-.61c-2.65-6.23-4.24-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,0,1,1.92-.57c1.08,3.65,1.95,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M469.54,555.13a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,1,1,.5,1.94l-33.32,8.69A1,1,0,0,1,469.54,555.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M476.78,586.28a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.11,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M476.78,586.28a1,1,0,0,1-.24-2c11.31-2.76,24.27-5.86,34.69-7.87a1,1,0,0,1,.38,2c-10.38,2-23.31,5.09-34.6,7.85A1,1,0,0,1,476.78,586.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M511.42,578.43a1,1,0,0,1-.92-.61c-2.65-6.23-4.23-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,1,1,1.92-.57c1.08,3.65,1.95,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M411,594.15a1,1,0,0,1-1-.75,147.58,147.58,0,0,1-3-14.59,1,1,0,0,1,2-.3,146,146,0,0,0,2.94,14.39,1,1,0,0,1-1,1.25Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M404.8,579.33a.31.31,0,0,0,0,.19c0,.18.32.13.49,0a15.4,15.4,0,0,1,5.9-1.86,13.93,13.93,0,0,1-2.23-2.31c-.38-.46-1.53-2.3-2.17-2.28-.82,0-.82,2.22-.95,2.8A23.77,23.77,0,0,1,404.8,579.33Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M417.37,592.77a1,1,0,0,1-1-.75,147.58,147.58,0,0,1-3-14.59,1,1,0,0,1,2-.3,146,146,0,0,0,2.94,14.39,1,1,0,0,1-1,1.25Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M411.2,578a.31.31,0,0,0,0,.19c0,.18.32.13.49,0a15.4,15.4,0,0,1,5.9-1.86,13.93,13.93,0,0,1-2.23-2.31c-.38-.46-1.53-2.3-2.17-2.28-.82,0-.82,2.22-.95,2.8A23.77,23.77,0,0,1,411.2,578Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M408.18,597.66a1,1,0,0,1-.14-2,113.17,113.17,0,0,0,12.62-2.59,1,1,0,0,1,.51,1.93,115.38,115.38,0,0,1-12.84,2.63Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M455.14,587.53l-.29,0a3,3,0,0,1-2.33-2.1,16.6,16.6,0,0,1-.68-2l-2.24-7.76a1,1,0,1,1,1.92-.55l2.24,7.76a14.83,14.83,0,0,0,.59,1.77c.22.52.52.88.75.91a.8.8,0,0,0,.62-.44,4.3,4.3,0,0,0,.38-1.52,1,1,0,0,1,2,.26,6,6,0,0,1-.64,2.26A2.74,2.74,0,0,1,455.14,587.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M443.83,577.65a1.81,1.81,0,0,1-1.5-.64c-.86-1.07,0-2.7.28-3.23a9.06,9.06,0,0,1,5.24-4.79,13.43,13.43,0,0,1,5.21-.59,7.57,7.57,0,0,1,4.56,1.92c.75.55,2.14,1.58,2.24,3.18a1,1,0,0,1-.77,1c-3.13.75-6.31,1.44-9.45,2.06-.59.12-1.19.21-1.79.31a28,28,0,0,0-2.87.56A4.39,4.39,0,0,1,443.83,577.65Zm8.13-7.28a10.64,10.64,0,0,0-3.46.52,7.11,7.11,0,0,0-4.12,3.83,4.21,4.21,0,0,0-.38.92,3.18,3.18,0,0,0,.45-.09,29.36,29.36,0,0,1,3.08-.61c.58-.09,1.15-.18,1.72-.3,2.74-.54,5.51-1.14,8.25-1.78a6.36,6.36,0,0,0-1.07-.93,5.68,5.68,0,0,0-3.49-1.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M449.68,569.86a1,1,0,0,1-.95-.68l-.65-1.95a1,1,0,1,1,1.89-.64l.66,2a1,1,0,0,1-.95,1.32Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M487.63,569.34a7.54,7.54,0,0,1-2.89-.62,4.08,4.08,0,0,1-1.66-1.15,4.62,4.62,0,0,1-.81-2l-1.89-9.07a1,1,0,0,1,2-.41l1.89,9.07a3,3,0,0,0,.41,1.2,2.27,2.27,0,0,0,.87.55,5.12,5.12,0,0,0,2.67.42,2.93,2.93,0,0,0,2-1.2c.79-1.21.35-3-.12-4.65L488.21,555a1,1,0,0,1,1.92-.56l1.89,6.42c.6,2,1.14,4.39-.12,6.31a4.88,4.88,0,0,1-3.42,2.08A5.85,5.85,0,0,1,487.63,569.34Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M481.41,557a1,1,0,0,1-.38-1.93,10,10,0,0,1,2.29-.55l5.71-.89a1,1,0,1,1,.31,2l-5.71.89a8.28,8.28,0,0,0-1.84.43A1,1,0,0,1,481.41,557Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.11,579a1,1,0,0,1-1-.73c-.84-3-1.53-6.16-2.07-9.27a1,1,0,0,1,2-.34c.53,3,1.21,6.1,2,9.07a1,1,0,0,1-1,1.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M486.73,580.72a1,1,0,0,1-.4-1.92,11.07,11.07,0,0,1,2.91-.69l.95-.14a13.12,13.12,0,0,0,2.83-.84,1,1,0,1,1,.78,1.84,15.09,15.09,0,0,1-3.26,1l-1,.16a9.4,9.4,0,0,0-2.39.54A1,1,0,0,1,486.73,580.72Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M539.23,438.62h-.05a1,1,0,0,1-.92-.76,100.06,100.06,0,0,1-2.75-19.47,1,1,0,1,1,2-.08,98.07,98.07,0,0,0,2.08,16.38q.29-.45.62-.87a1,1,0,0,1,1.55,0,3,3,0,0,0,1.45,1.13.67.67,0,0,0,.6-.23,1,1,0,0,1,1.91-.48.66.66,0,0,0,.78.29,2.38,2.38,0,0,0,.25-.15,2.75,2.75,0,0,1,1-.43,2.79,2.79,0,0,1,1.72.3l.35.14h.05a1,1,0,0,1,1.57-.38,4,4,0,0,0,1.15.68c-1.13-6.06-2.51-12.14-4.09-18.09a1,1,0,1,1,1.93-.51c1.72,6.47,3.2,13.1,4.39,19.69a1,1,0,0,1-.23.83.94.94,0,0,1-.79.34,6.06,6.06,0,0,1-2.82-.83,2.28,2.28,0,0,1-1.79.15c-.17-.06-.34-.13-.52-.2a2,2,0,0,0-.52-.18,1.72,1.72,0,0,0-.28.16,4.4,4.4,0,0,1-.47.27,2.6,2.6,0,0,1-2,.06l-.29-.12,0,0a2.66,2.66,0,0,1-2.24.61,3.67,3.67,0,0,1-1.69-.87,10.64,10.64,0,0,0-.95,2A1,1,0,0,1,539.23,438.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M413.45,463.26a1,1,0,0,1-.8-.4c-1.36-1.8-1.36-4.11-1.36-6.14v-.54a34.58,34.58,0,0,0-3.39-14.73,1,1,0,1,1,1.8-.87,36.62,36.62,0,0,1,3.59,15.59v.55a13.41,13.41,0,0,0,.31,3.6l.66-.92a1,1,0,0,1,1.67.06.37.37,0,0,0,.31.11.38.38,0,0,0,.31-.12l.07-.15a2.15,2.15,0,0,1,.55-.8c1.06-.91,2.17-.05,2.7.36a3.14,3.14,0,0,0,.62.41.21.21,0,0,0,.19,0,3,3,0,0,0,1-1.69,1,1,0,0,1,1.81-.24,2,2,0,0,0,3.34-.39,1,1,0,0,1,1.69-.34,3.62,3.62,0,0,0,2.06,1.31.43.43,0,0,0,.31-.13,2.09,2.09,0,0,0,.27-.51,4.56,4.56,0,0,1,.43-.81,2.72,2.72,0,0,1,2.6-1.06,3,3,0,0,1,1.39.55l.45-.45a1,1,0,0,1,1.59.25.43.43,0,0,0,.78-.35,1,1,0,0,1,1.77-.91,2.4,2.4,0,0,0,.38.45l-1.72-21.17a1,1,0,0,1,2-.16l1.86,22.86a1,1,0,0,1-1.15,1.07A4.46,4.46,0,0,1,440,457a2.36,2.36,0,0,1-.95.8,2.48,2.48,0,0,1-2.26-.15l-.54.54a1,1,0,0,1-1.64-.35.78.78,0,0,0-.64-.4.79.79,0,0,0-.72.23,3,3,0,0,0-.23.46,3.62,3.62,0,0,1-.64,1.07,2.39,2.39,0,0,1-1.79.77,4.43,4.43,0,0,1-2.59-1.09,4,4,0,0,1-2.48,1.18,4.09,4.09,0,0,1-2.49-.47,3.7,3.7,0,0,1-1.47,1.51,2.18,2.18,0,0,1-1.77.1,4.43,4.43,0,0,1-1.15-.7l-.26-.2-.09.18a2.34,2.34,0,0,1-2,1.14,2.22,2.22,0,0,1-1-.18l-1,1.45a1,1,0,0,1-.8.42Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M568,334.05a2,2,0,0,1-1.63-.84q-.62-.86-1.14-1.78a2.62,2.62,0,0,1-1.57.53,3.26,3.26,0,0,1-2.43-1.15l-.8-.81a3.77,3.77,0,0,1-4.27.95,4,4,0,0,1-1.4-1.09l-.28.46a2.83,2.83,0,0,1-4.34.92l-1.78-1.15a13.94,13.94,0,0,1-1.61,1.75,2,2,0,0,1-3.34-1.73,114.37,114.37,0,0,0,.86-19.86c0-.71-.07-1.42-.11-2.13a46.28,46.28,0,0,1,.41-11.9,2,2,0,0,1,3.92.81,42.57,42.57,0,0,0-.33,10.87c0,.72.08,1.45.11,2.17a118.36,118.36,0,0,1-.32,15.26,2,2,0,0,1,.92.31l2.7,1.75,1.05-1.76a2,2,0,0,1,1.89-1,4,4,0,0,1,3,2.11l.21.31a4.35,4.35,0,0,0,.77-1.08,2,2,0,0,1,3.2-.48l1.59,1.62a2.92,2.92,0,0,1,2.11-1.48,2,2,0,0,1,1.14.17c.08-3.24-.09-6.52-.25-9.73-.35-7-.71-14.15,1.29-21.07a2,2,0,1,1,3.84,1.11c-1.81,6.28-1.48,12.83-1.13,19.77.27,5.39.55,11-.26,16.43a2,2,0,0,1-2,1.71Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M723.53,328.85a2,2,0,0,1-1.7-.94h0a3.37,3.37,0,0,1-1.62.17,3.55,3.55,0,0,1-1.3-.46,2,2,0,0,1-1.19.4,2,2,0,0,1-1.59-.77,4.51,4.51,0,0,0-1.65-1.3,8.46,8.46,0,0,1-2.29,2.39,2,2,0,0,1-3.14-1.52,48.11,48.11,0,0,1,.34-7.82c.06-.61.12-1.22.17-1.83a90.75,90.75,0,0,0-.81-22.43,2,2,0,0,1,3.95-.64,94.8,94.8,0,0,1,.84,23.42c-.06.62-.12,1.25-.18,1.87s-.15,1.48-.21,2.21a2,2,0,0,1,.52,0,8.49,8.49,0,0,1,3.76,1.46,3.43,3.43,0,0,0,4.1-.29h0c.07-9.84.45-19.76,1.14-29.55a2,2,0,0,1,4,.28c-.78,11.06-1.17,22.29-1.15,33.37a2,2,0,0,1-2,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M637.16,177a2,2,0,0,1-2-2.4,143.33,143.33,0,0,0,2.81-24,2,2,0,0,1,4,.13,147.05,147.05,0,0,1-1.22,14.67,2.79,2.79,0,0,1,2.14,1.26l1.59,2.13a3.5,3.5,0,0,1,.5-.66,3.06,3.06,0,0,1,4.17-.17l.15-.26a2,2,0,0,1,1.79-1,2,2,0,0,1,1.73,1.1q.29.58.56,1.17l1.26-1.74a2.6,2.6,0,0,1,2.63-1.2,63.58,63.58,0,0,0,2.49-16.74,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,67.58,67.58,0,0,1-4,22,2,2,0,0,1-2,1.32,2,2,0,0,1-1.54-.82l-1.84,2.54a3.31,3.31,0,0,0-4.89.84,2,2,0,0,1-1.91-.57l-.1-.11a3.58,3.58,0,0,1-.21.34,2,2,0,0,1-1.61.85,2.09,2.09,0,0,1-1.63-.81l-3-4.05L639,175.74A2,2,0,0,1,637.16,177Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M578.34,48.08a2,2,0,0,1-1-.25,5.11,5.11,0,0,1-2.11-2.27,3,3,0,0,1-1.94-.21,3.58,3.58,0,0,1-1.52-1.43,2,2,0,0,1-3.17-.08L568,43a18.65,18.65,0,0,0-.65,2.92,2,2,0,0,1-4-.28q0-18.63,0-37.26a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2q0,14.29,0,28.57h0a2,2,0,0,1,1.76.82l.71,1q.19-.25.41-.48a2,2,0,0,1,3.22.4l1,1.85a2,2,0,0,1,1.76-1.37c-.05-9.67.38-19.39,1.28-29a2,2,0,1,1,4,.38A288.91,288.91,0,0,0,580.34,46a2,2,0,0,1-2,2.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M341.35,72.24a2,2,0,0,1-2-2.07c.46-12.23,1.44-24.6,2.91-36.75a2,2,0,1,1,4,.48c-1,8.09-1.74,16.27-2.27,24.44a2,2,0,0,1,2.25-.33,11,11,0,0,1,2.36,1.58l.3-.64a2,2,0,0,1,3.7.19l.48,1.37a3.47,3.47,0,0,1,2.3-1.8,2,2,0,0,1,1.66.4l.16.15.08-.15a2,2,0,0,1,2.43-.89q.18-.64.32-1.28a2,2,0,0,1,3.93.11q0,.25.09.51a2,2,0,0,1,2-1.12l2.38-24.32a2,2,0,0,1,4,.39l-3.12,31.83a2,2,0,0,1-3.57,1,8.93,8.93,0,0,1-.56-.81,2,2,0,0,1-3-.59l-.26-.48q-.31.63-.65,1.25a9.33,9.33,0,0,0-4.17,1,2,2,0,0,1-1.71-.68l-.2-.24a3.67,3.67,0,0,1-1.7,1.06,2.83,2.83,0,0,1-2.46-.47,2.94,2.94,0,0,1-.64-.68,2,2,0,0,1-3.08-.44,6.92,6.92,0,0,0-.75-1,31,31,0,0,1-3.55,8A2,2,0,0,1,341.35,72.24Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M250.94,60a2,2,0,0,1-2-1.71L246.6,42.31a2,2,0,1,1,4-.58L252,51.65a2,2,0,0,1,1.31.75l.35.44a2,2,0,0,1,2.52.09,3.33,3.33,0,0,1,.47.5,2.46,2.46,0,0,1,.74-.33,2,2,0,0,1,1,0,2,2,0,0,1,1.21-.66c.05-4.25.07-8.52,0-12.75a2,2,0,0,1,2-2,2,2,0,0,1,2,2c0,5.9,0,11.88-.12,17.78a2,2,0,0,1-3,1.67,5.14,5.14,0,0,1-.61-.43,2,2,0,0,1-2.39-.14,2.66,2.66,0,0,1-1.36.08A3.1,3.1,0,0,1,255,58.1a2,2,0,0,1-1.1.3,2,2,0,0,1-1-.27,2,2,0,0,1-1.82,1.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.36,215.29h-.1a2,2,0,0,1-1.83-1.51c0-.09-.06-.22-.1-.37a2,2,0,0,1-2.54-.55,5.77,5.77,0,0,1-.38-.57,1.5,1.5,0,0,0-2,.7,2.42,2.42,0,0,1-2.31-1.24,3.3,3.3,0,0,1-.73.66,3.23,3.23,0,0,1-2.57.42,3.9,3.9,0,0,1-1.72-.94L326,212a7.25,7.25,0,0,0-3.9.33,2,2,0,0,1-1.52-.63q-.69-.73-1.3-1.52l-.78,1.1a2,2,0,0,1-3.63-1,286.61,286.61,0,0,1-.45-32.05,2,2,0,0,1,2.08-1.91,2,2,0,0,1,1.91,2.08c-.37,8.76-.33,17.62.13,26.4a2,2,0,0,1,2.54.87q.33.6.71,1.16a13.67,13.67,0,0,0,5.52-1.38,2,2,0,0,1,1.48,2v.13a3.09,3.09,0,0,1,3.68-1.4,2.81,2.81,0,0,1,.86.51l.5-1a2,2,0,0,1,3.78.82l0,.35a2,2,0,0,1,1,2,3.47,3.47,0,0,1,.74.11,50.87,50.87,0,0,0,.36-7.37v-.84a208.41,208.41,0,0,1,1.46-24.08,2,2,0,1,1,4,.47,204.43,204.43,0,0,0-1.43,23.61v.84c0,4.07,0,8.28-1.47,12.29A2,2,0,0,1,340.36,215.29Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.18,290.76a2.88,2.88,0,0,1-2.64-1.93,2,2,0,0,1-2.78-.7l-.18.21a2,2,0,0,1-3.18-.19q-.27-.4-.56-.78a16.48,16.48,0,0,0-.57,1.72,2,2,0,0,1-3.93-.47l-1-34.89a2,2,0,1,1,4-.12l.84,28.28a2,2,0,0,1,1.56.52q.68.62,1.29,1.31.2-.34.38-.69A2,2,0,0,1,383.1,282a2,2,0,0,1,1.77,1l.06.11a2,2,0,0,1,3.53.81l.19.87.92-1.57a2,2,0,0,1,3.72.89q0,.2,0,.39l.06,0c1.1-7.19,2-14.54,1.41-21.78,0-.57-.1-1.13-.16-1.7a28.16,28.16,0,0,1,0-7.76,2,2,0,1,1,3.94.7,24.78,24.78,0,0,0,.07,6.67c.06.59.12,1.18.16,1.76.73,8.92-.66,17.76-2,26.32a4,4,0,0,1-6.32.89,2.86,2.86,0,0,1-1.82,1.19A2.66,2.66,0,0,1,388.18,290.76Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M176,215.44a2,2,0,0,1-1.12-.34,8,8,0,0,1-1.65-1.5l-.06.07a2,2,0,0,1-3,.23q-.18-.17-.35-.36a2,2,0,0,1-2.12-.32q-.42-.37-.82-.77l0,.15a2,2,0,0,1-3.94-.14,198.32,198.32,0,0,1-1.3-35.58,2,2,0,1,1,4,.21,194.37,194.37,0,0,0,.65,29.33h.13a2,2,0,0,1,1.72,1,10,10,0,0,0,.56.9l.19-.32a2,2,0,0,1,3.55.21,2,2,0,0,1,2.92.93,2,2,0,0,1,.22-.25,104.51,104.51,0,0,0-.31-12.64c-.42-6.48-.85-13.19.58-19.75a2,2,0,1,1,3.91.85c-1.31,6-.92,12.15-.5,18.64a89.68,89.68,0,0,1,.08,15.77,2,2,0,0,1-1.27,1.64l-.2.61a2,2,0,0,1-1.9,1.38Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M105.57,354.11a2,2,0,0,1-2-2.32,82.63,82.63,0,0,0,.84-19.26c-.09-1.22-.21-2.43-.32-3.65a61.71,61.71,0,0,1-.39-10.8,2,2,0,1,1,4,.32,57.8,57.8,0,0,0,.39,10.1c.12,1.25.24,2.49.33,3.74a86.64,86.64,0,0,1,0,13.21l.17.05a2,2,0,0,1,1.25,1.26,2,2,0,0,1,3.41-.55,2,2,0,0,1,2.72-.39c-.92-8.6.7-17.35,2.13-25.16a2,2,0,0,1,3.93.72c-1.59,8.64-3.24,17.58-1.78,26.27.41,2.42-.13,4.09-1.6,4.95a2,2,0,0,1-2.71-.67,2,2,0,0,1-1.35-.21,2,2,0,0,1-2.37-.24l-.42-.4a3.82,3.82,0,0,1-2.09.58,3.71,3.71,0,0,1-1.5-.36l-.84,1.69A2,2,0,0,1,105.57,354.11Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M312.16,134.92a.81.81,0,0,1,0-1.62L340,133a.83.83,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M311.72,160.82a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.81.81,0,0,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.48,161.46h0c-8.56-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.48,161.46a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,1.62-.07c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M344.5,135.77a.81.81,0,0,1,0-1.62l27.89-.27a.81.81,0,1,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M344.06,161.67a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.81.81,0,0,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372.82,162.31h0c-8.55-.47-19.32-.58-28.72-.64a.81.81,0,0,1-.81-.81.8.8,0,0,1,.81-.81c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372.82,162.31a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.8.8,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.88,136.43a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.44,162.33a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.81.81,0,1,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M405.21,163h0c-8.57-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.41.05,20.2.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M405.21,163a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.84.84,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M323.19,155.57a.81.81,0,0,1-.81-.8,119.45,119.45,0,0,1,.53-12,.81.81,0,1,1,1.61.15,117.78,117.78,0,0,0-.52,11.88.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M321.06,142.69a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,321.06,142.69Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M328.49,155.74a.81.81,0,0,1-.81-.8,119.74,119.74,0,0,1,.53-12,.81.81,0,1,1,1.61.15,118.08,118.08,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M326.36,142.86a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,326.36,142.86Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M359.46,159.08a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.4,13.4,0,0,1-.14-1.71L357,148.6a.81.81,0,1,1,1.62-.06l.24,6.54a12,12,0,0,0,.12,1.51c.07.45.23.79.41.86a.65.65,0,0,0,.57-.23,3.52,3.52,0,0,0,.6-1.12.81.81,0,1,1,1.5.6,4.84,4.84,0,0,1-.94,1.65A2.32,2.32,0,0,1,359.46,159.08Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M364.67,149.6h0c-2.6,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a22.82,22.82,0,0,0-2.37-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.84,10.84,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,364.67,149.6Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.56.19,6.83.22a5.18,5.18,0,0,0-.66-.94,4.6,4.6,0,0,0-2.44-1.89,9.3,9.3,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.41,3.41,0,0,0-.48.65,2.61,2.61,0,0,0,.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M358.38,144.1a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.61-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M389.22,151.27l-.45,0a5.75,5.75,0,0,1-2.82-1.17,3.27,3.27,0,0,1-1.08-1.23,3.75,3.75,0,0,1-.23-1.76l.3-7.5a.82.82,0,0,1,.84-.78.81.81,0,0,1,.78.84l-.3,7.49a2.47,2.47,0,0,0,.09,1,1.72,1.72,0,0,0,.57.6,4.14,4.14,0,0,0,2,.86,2.37,2.37,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,1,1,1.62-.07l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,389.22,151.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M392.22,140.66h-.07l-4.66-.42a6.73,6.73,0,0,0-1.53,0,.81.81,0,0,1-.23-1.6,8.12,8.12,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.35,159.23a.81.81,0,0,1-.81-.79c-.06-2.56,0-5.14.2-7.69a.81.81,0,0,1,1.62.12c-.19,2.49-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M389.16,160.06q-.43,0-.86,0l-.83-.08a7.63,7.63,0,0,0-2,0,.81.81,0,0,1-.26-1.6,8.9,8.9,0,0,1,2.41,0l.78.07a10.65,10.65,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.24,12.24,0,0,1,389.16,160.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M436.16,110.93a.81.81,0,0,1,0-1.62L464,109a.85.85,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M435.72,136.83a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M464.49,137.47h0c-8.55-.47-19.32-.58-28.73-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M464.48,137.47a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75A.81.81,0,0,1,464,109a.84.84,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M468.5,111.78a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M468.06,137.69a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M496.82,138.33h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M496.82,138.33a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M500.89,112.44a.81.81,0,0,1,0-1.62l27.89-.27a.84.84,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M500.45,138.34a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M529.21,139h0c-8.55-.47-19.32-.59-28.73-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.22.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M529.21,139a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M447.2,131.58a.81.81,0,0,1-.81-.8,119.88,119.88,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.36,118.36,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M445.07,118.7a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,445.07,118.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M452.5,131.76a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M450.37,118.88a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,450.37,118.88Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M483.46,135.1a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.51,13.51,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78l.24,6.54a12.11,12.11,0,0,0,.12,1.51c.08.45.24.79.41.86a.64.64,0,0,0,.57-.23,3.54,3.54,0,0,0,.6-1.12.81.81,0,1,1,1.5.6,4.78,4.78,0,0,1-.94,1.65A2.32,2.32,0,0,1,483.46,135.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M488.68,125.61h0c-2.61,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a21.9,21.9,0,0,0-2.37-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.85,10.85,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,488.68,125.61Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.55.19,6.83.22a5.15,5.15,0,0,0-.66-.94,4.59,4.59,0,0,0-2.44-1.89,9.34,9.34,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.38,3.38,0,0,0-.48.65l.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M482.39,120.11a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.62-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M513.23,127.28l-.45,0a5.74,5.74,0,0,1-2.82-1.17,3.27,3.27,0,0,1-1.08-1.23,3.76,3.76,0,0,1-.23-1.76l.3-7.5a.85.85,0,0,1,.84-.78.81.81,0,0,1,.78.84l-.3,7.49a2.48,2.48,0,0,0,.09,1,1.84,1.84,0,0,0,.57.6,4.14,4.14,0,0,0,2,.86,2.39,2.39,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,.78-.84.8.8,0,0,1,.84.78l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,513.23,127.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M516.23,116.68h-.07l-4.66-.42a6.78,6.78,0,0,0-1.53,0,.81.81,0,1,1-.23-1.6,8.16,8.16,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M512.36,135.24a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.14.2-7.69a.82.82,0,0,1,.87-.75.81.81,0,0,1,.75.87c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M513.16,136.07q-.43,0-.86,0l-.83-.08a7.66,7.66,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.62,10.62,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.27,12.27,0,0,1,513.16,136.07Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.5,258.07a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.06,284a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M518.83,284.61h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M518.83,284.61a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M522.84,258.92a.81.81,0,0,1,0-1.62l27.89-.27a.79.79,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M522.4,284.82a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M551.17,285.46h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M551.17,285.46a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M555.23,259.58a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M554.79,285.48a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M583.56,286.12h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M583.55,286.12a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M501.54,278.72a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M499.41,265.84a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,499.41,265.84Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M506.84,278.89a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M504.71,266a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,504.71,266Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M537.81,282.23a1.86,1.86,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.51,13.51,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78l.24,6.54a12.11,12.11,0,0,0,.12,1.51c.08.45.24.79.41.86a.65.65,0,0,0,.57-.23,3.49,3.49,0,0,0,.6-1.12.81.81,0,1,1,1.51.6,4.85,4.85,0,0,1-.94,1.65A2.32,2.32,0,0,1,537.81,282.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M543,272.75h0c-2.6,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a23.26,23.26,0,0,0-2.38-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.88,10.88,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.76,3.76,0,0,1,1.13,2.94A.81.81,0,0,1,543,272.75Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.55.19,6.83.22a5.25,5.25,0,0,0-.66-.94,4.6,4.6,0,0,0-2.44-1.89,9.31,9.31,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.47,3.47,0,0,0-.48.65,2.52,2.52,0,0,0,.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M536.73,267.24a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.62-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567.57,274.42l-.45,0a5.76,5.76,0,0,1-2.82-1.17,3.26,3.26,0,0,1-1.08-1.23,3.8,3.8,0,0,1-.23-1.76l.3-7.49a.81.81,0,0,1,.81-.78h0a.81.81,0,0,1,.78.84l-.3,7.49a2.49,2.49,0,0,0,.09,1,1.85,1.85,0,0,0,.57.6,4.15,4.15,0,0,0,2,.86,2.37,2.37,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,1.62-.07l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,567.57,274.42Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M570.57,263.81h-.07l-4.66-.42a6.7,6.7,0,0,0-1.53,0,.81.81,0,1,1-.23-1.6,8.16,8.16,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M566.7,282.37a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.13.2-7.69a.82.82,0,0,1,.87-.75.81.81,0,0,1,.75.87c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567.51,283.21q-.43,0-.86,0l-.83-.08a7.59,7.59,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.58,10.58,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.27,12.27,0,0,1,567.51,283.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M587.27,441.82a.81.81,0,0,1,0-1.62l23.12-.22a.81.81,0,1,1,0,1.62l-23.12.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M610.83,468.41h0c-5.06-.28-11.42-.46-19.44-.56a.81.81,0,0,1,0-1.62h0c8,.1,14.43.28,19.51.56a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M610.82,468.41a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M614.84,442.72a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M614.4,468.62a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M643.17,469.26h0c-8.55-.47-19.32-.58-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M643.16,469.26a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.86.86,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M647.23,443.38a.81.81,0,0,1,0-1.62l27.89-.27a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.79,469.28a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.81.81,0,1,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M675.55,469.92h0c-8.57-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.41.05,20.2.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M675.55,469.92a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M593.54,462.51a.81.81,0,0,1-.81-.8,119.92,119.92,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.4,118.4,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M591.41,449.64a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,591.41,449.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M598.84,462.69a.81.81,0,0,1-.81-.8,119.87,119.87,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.37,118.37,0,0,0-.52,11.88.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M596.71,449.81a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,596.71,449.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M629.8,466a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.55,13.55,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.84.84,0,0,1,.84.78l.24,6.54a11.94,11.94,0,0,0,.12,1.51c.07.45.24.79.41.86a.64.64,0,0,0,.57-.23,3.49,3.49,0,0,0,.6-1.12.81.81,0,0,1,1.51.6,4.82,4.82,0,0,1-.94,1.65A2.32,2.32,0,0,1,629.8,466Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M635,456.54h0c-2.59,0-5.23-.11-7.83-.24-.48,0-1-.07-1.47-.11-.79-.07-1.6-.13-2.37-.12-1,0-1.71-.28-2-.89-.46-1,.53-2.12.86-2.48a7.32,7.32,0,0,1,5.06-2.73,10.87,10.87,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,635,456.54Zm-11.45-2.09c.76,0,1.53.07,2.28.13.47,0,.94.08,1.41.1,2.27.11,4.56.19,6.83.22a5.12,5.12,0,0,0-.66-.94,4.59,4.59,0,0,0-2.44-1.89,9.45,9.45,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.43,3.43,0,0,0-.48.65l.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M628.73,451a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,.74-.87.8.8,0,0,1,.87.74l.13,1.66a.81.81,0,0,1-.75.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M659.57,458.22l-.45,0A5.76,5.76,0,0,1,656.3,457a3.27,3.27,0,0,1-1.08-1.23A3.76,3.76,0,0,1,655,454l.3-7.49a.81.81,0,0,1,.81-.78h0a.81.81,0,0,1,.78.84l-.3,7.49a2.51,2.51,0,0,0,.09,1,1.72,1.72,0,0,0,.57.6,4.16,4.16,0,0,0,2,.86,2.39,2.39,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,659.57,458.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M662.57,447.61h-.07l-4.66-.42a6.67,6.67,0,0,0-1.53,0,.81.81,0,0,1-.23-1.6,8,8,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M658.7,466.17a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.14.2-7.69a.81.81,0,1,1,1.62.12c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M659.5,467c-.29,0-.57,0-.86,0l-.83-.08a7.66,7.66,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.54,10.54,0,0,0,2.38-.1.81.81,0,1,1,.25,1.6A12.16,12.16,0,0,1,659.5,467Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M649.15,174.82a1.5,1.5,0,0,1-1.06-2.56l1.28-1.28a1.5,1.5,0,0,1,2.12,2.12l-1.29,1.28A1.5,1.5,0,0,1,649.15,174.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.76,297.47a1.91,1.91,0,0,1-.54-.08c-.46-.14-2-.78-1.73-3.32a821.6,821.6,0,0,0,2-121.16,1.5,1.5,0,1,1,3-.17,824.54,824.54,0,0,1-1.89,120.89,1.64,1.64,0,0,1,.42.25,2.14,2.14,0,0,1,.42,2.58A1.82,1.82,0,0,1,646.76,297.47Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M720.11,472.24h0a1.5,1.5,0,0,1-1.49-1.51c.17-47.52-.5-95.68-2-143.15a1.5,1.5,0,0,1,1.45-1.55,1.48,1.48,0,0,1,1.55,1.45c1.5,47.5,2.17,95.7,2,143.26A1.5,1.5,0,0,1,720.11,472.24Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M580,590.51c-.85,0-2.61-.4-3.33-3.53l-34.2-149.63a1.5,1.5,0,0,1,2.92-.67L579.55,586a1.76,1.76,0,0,1,1.05,0,2.53,2.53,0,0,1,1.49,2.71,2,2,0,0,1-1.94,1.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M509.61,417.68a1.5,1.5,0,0,1-1.49-1.35c-.91-9-1.45-18.11-1.61-27.13a1.5,1.5,0,0,1,1.47-1.53h0a1.5,1.5,0,0,1,1.5,1.47c.16,8.93.69,18,1.59,26.88a1.5,1.5,0,0,1-1.34,1.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M172.54,314.24a1.5,1.5,0,0,1-1.5-1.4c-2.16-33.64-3.43-67.8-3.77-101.51a1.5,1.5,0,0,1,1.48-1.52h0a1.5,1.5,0,0,1,1.5,1.48c.34,33.66,1.61,67.76,3.77,101.35a1.5,1.5,0,0,1-1.4,1.59Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M102.22,479.3a1.5,1.5,0,0,1-1.5-1.5,976.48,976.48,0,0,1,8.15-126.63,1.5,1.5,0,0,1,3,.39,973.51,973.51,0,0,0-8.13,126.24,1.5,1.5,0,0,1-1.5,1.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M382.09,318.12a1.5,1.5,0,0,1-1.5-1.46,137.6,137.6,0,0,1,2.19-27.88,1.5,1.5,0,0,1,3,.54,134.6,134.6,0,0,0-2.15,27.27,1.5,1.5,0,0,1-1.46,1.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567,147.95h-.11a1.5,1.5,0,0,1-1.39-1.61c2.5-34.22,3.92-69,4.21-103.28a1.5,1.5,0,0,1,1.5-1.49h0a1.5,1.5,0,0,1,1.49,1.51c-.29,34.38-1.71,69.19-4.22,103.47A1.5,1.5,0,0,1,567,147.95Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M254.41,176.21a1.5,1.5,0,0,1-1.5-1.49l-.43-115.58A1.5,1.5,0,0,1,254,57.63h0a1.5,1.5,0,0,1,1.5,1.49l.43,115.58a1.5,1.5,0,0,1-1.49,1.51Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M323.06,194a.88.88,0,0,1-.34-1.68,20.41,20.41,0,0,0,8.61-6.82.88.88,0,1,1,1.42,1A21.88,21.88,0,0,1,323.4,194,.88.88,0,0,1,323.06,194Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M329.51,195.91a.88.88,0,0,1-.31-1.69,7.32,7.32,0,0,0,3.11-2.27.87.87,0,0,1,1.37,1.09,9.07,9.07,0,0,1-3.85,2.81A.88.88,0,0,1,329.51,195.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M383.94,269.31a.88.88,0,0,1-.59-1.52,18.54,18.54,0,0,0,4.38-6.13.87.87,0,1,1,1.6.7,20.31,20.31,0,0,1-4.8,6.71A.88.88,0,0,1,383.94,269.31Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M387,272.83a.87.87,0,0,1-.61-1.5l3-3a.87.87,0,0,1,1.22,1.25l-3,3A.87.87,0,0,1,387,272.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M550.94,316.28a.87.87,0,0,1-.46-1.62,10.51,10.51,0,0,0,4.81-7.27.88.88,0,0,1,1.73.26,12.29,12.29,0,0,1-5.62,8.49A.87.87,0,0,1,550.94,316.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M555.08,319.94a.88.88,0,0,1-.68-1.43l4.05-5a.88.88,0,0,1,1.36,1.11l-4.05,5A.87.87,0,0,1,555.08,319.94Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.36,158.78a.87.87,0,0,1-.72-1.36l6.27-9.32a.87.87,0,1,1,1.45,1l-6.27,9.32A.87.87,0,0,1,646.36,158.78Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M647.38,163.19a.88.88,0,0,1-.49-1.6,22.85,22.85,0,0,0,6.44-6.52.88.88,0,0,1,1.47,1,24.63,24.63,0,0,1-6.94,7A.87.87,0,0,1,647.38,163.19Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M715.47,312.87a.88.88,0,0,1-.23,0,.87.87,0,0,1-.61-1.08,45.45,45.45,0,0,0,1.57-9.31.87.87,0,0,1,1.75.11,47.17,47.17,0,0,1-1.63,9.67A.87.87,0,0,1,715.47,312.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M717.5,317.38a.87.87,0,0,1-.87-.87V314a.88.88,0,0,1,1.75,0v2.5A.87.87,0,0,1,717.5,317.38Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M569.57,20.39h-.13a.88.88,0,0,1-.74-1l.52-3.5a.87.87,0,1,1,1.73.26l-.52,3.5A.88.88,0,0,1,569.57,20.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M572.25,30a.86.86,0,0,1-.28,0,.88.88,0,0,1-.55-1.11A43.82,43.82,0,0,0,573.68,17a.91.91,0,0,1,.92-.83.87.87,0,0,1,.83.92,45.63,45.63,0,0,1-2.35,12.32A.88.88,0,0,1,572.25,30Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M351.81,47.69a.88.88,0,0,1-.63-1.48,27.74,27.74,0,0,0,5.53-8.54.87.87,0,1,1,1.62.66,29.07,29.07,0,0,1-5.89,9.08A.87.87,0,0,1,351.81,47.69Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M356.83,51.68a.88.88,0,0,1-.58-1.53A45.23,45.23,0,0,0,362,44.08a.87.87,0,1,1,1.38,1.08,47,47,0,0,1-5.94,6.3A.87.87,0,0,1,356.83,51.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M255.46,48.4a.87.87,0,0,1-.77-.46L253.09,45a.87.87,0,1,1,1.54-.83l1.59,2.95a.87.87,0,0,1-.77,1.29Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M173.55,192.77a.87.87,0,0,1-.4-.1,12.56,12.56,0,0,1-6.25-7.89.88.88,0,0,1,1.7-.43,10.78,10.78,0,0,0,5.36,6.77.88.88,0,0,1-.41,1.65Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M171.49,204.89a.87.87,0,0,1-.48-.15,10,10,0,0,1-4.38-8.8.88.88,0,1,1,1.75.11,8.22,8.22,0,0,0,3.6,7.23.87.87,0,0,1-.48,1.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M114,331.87a.88.88,0,0,1-.81-.53l-1.49-3.5a.88.88,0,0,1,1.61-.69l1.49,3.5a.87.87,0,0,1-.8,1.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M112.89,344.45a.88.88,0,0,1-.72-.38,24.28,24.28,0,0,1-3.57-7.84.87.87,0,0,1,1.7-.43,22.53,22.53,0,0,0,3.32,7.28.87.87,0,0,1-.72,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M190.82,374.17a.88.88,0,0,1-.82-.58,9.05,9.05,0,0,0-7.67-5.79.88.88,0,0,1,.12-1.75,10.85,10.85,0,0,1,9.19,6.94.87.87,0,0,1-.82,1.17Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M189.51,373.73a.87.87,0,0,1-.62-.25,4.18,4.18,0,0,0-5.15-.45.87.87,0,0,1-1-1.43,5.92,5.92,0,0,1,7.39.64.88.88,0,0,1-.62,1.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M269.07,343.71a.87.87,0,0,1-.86-.72,17.45,17.45,0,0,1-.2-4.76.88.88,0,0,1,1.74.17,15.71,15.71,0,0,0,.18,4.28.87.87,0,0,1-.71,1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M268.36,343.16a.87.87,0,0,1-.57-1.54l3.13-2.7a.87.87,0,1,1,1.14,1.33l-3.13,2.7A.87.87,0,0,1,268.36,343.16Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M377.93,433.36h-.11a.88.88,0,0,1-.76-1,26.76,26.76,0,0,0-1.74-14.15.88.88,0,1,1,1.63-.63,28.38,28.38,0,0,1,1.85,15A.88.88,0,0,1,377.93,433.36Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M420.89,450.7a1,1,0,0,1-.53-1.85l9.92-6.12a1,1,0,0,1,1,1.7l-9.92,6.12A1,1,0,0,1,420.89,450.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M424.36,453.7a1,1,0,0,1-.45-1.89l2.94-1.46a1,1,0,1,1,.89,1.79l-2.93,1.46A1,1,0,0,1,424.36,453.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M544.14,426.87a1,1,0,0,1-.45-1.89l2-1a1,1,0,1,1,.89,1.79l-2,1A1,1,0,0,1,544.14,426.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M545.1,431.23h-.49a1,1,0,0,1,0-2h.49a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M475.12,219.77a1,1,0,0,1,0-2A235.3,235.3,0,0,0,547,203.46a1,1,0,0,1,.69,1.88,237.28,237.28,0,0,1-72.48,14.43Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M510.53,226.27a1,1,0,0,1-.25-2l9.8-2.54a1,1,0,0,1,.5,1.94l-9.8,2.54A1,1,0,0,1,510.53,226.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M544.37,369.75a1,1,0,0,1-.07-2c16.71-1.22,32.23-8.25,47.24-15.05a1,1,0,0,1,.83,1.82c-14.46,6.55-30.85,14-47.92,15.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M580.71,394.05a1,1,0,0,1-.45-1.89l5.5-2.76a1,1,0,0,1,.9,1.79l-5.5,2.76A1,1,0,0,1,580.71,394.05Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M454.49,60.42a1,1,0,0,1,0-2,214.71,214.71,0,0,0,53.3-9.11,1,1,0,1,1,.58,1.91,216.68,216.68,0,0,1-53.8,9.19Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M327.29,102.14a1,1,0,0,1-.06-2,192.46,192.46,0,0,0,70.27-18,1,1,0,1,1,.86,1.81,194.47,194.47,0,0,1-71,18.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M432.07,510.83c-10.54,0-21-1.47-31.26-2.9a1,1,0,1,1,.28-2c12.26,1.72,24.94,3.49,37.49,2.68,13.92-.91,25.89-5.09,34.6-12.1a1,1,0,1,1,1.25,1.56c-9,7.27-21.39,11.6-35.73,12.54C436.49,510.76,434.28,510.83,432.07,510.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M450.56,528.21h-.06c-9.42-.56-19-.73-28.4-.49h0a1,1,0,0,1,0-2c9.48-.23,19.09-.06,28.57.5a1,1,0,0,1-.06,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M359,529.5a1,1,0,0,1-1-1,55.34,55.34,0,0,1,.78-8.08c.31-2.13.63-4.32.73-6.47a1,1,0,0,1,1-1,1,1,0,0,1,1,1,66.87,66.87,0,0,1-.74,6.67,53.91,53.91,0,0,0-.75,7.79,1,1,0,0,1-1,1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M357.5,544.5a1,1,0,0,1-1-1v-6a1,1,0,0,1,2,0v6A1,1,0,0,1,357.5,544.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M227.31,549.06c-4.17,0-11.51-.6-15.38-4.5a1.5,1.5,0,1,1,2.13-2.11c3.07,3.09,9.95,3.87,15.35,3.56a1.5,1.5,0,0,1,.17,3C229,549,228.26,549.06,227.31,549.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M227.5,541a1.46,1.46,0,0,1-.31,0,20.42,20.42,0,0,0-5.58-.47,1.5,1.5,0,0,1-.22-3,23.41,23.41,0,0,1,6.42.53,1.5,1.5,0,0,1-.31,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M328.5,560a1.5,1.5,0,0,1-.7-2.83c1.12-.59,2.3-1.27,3.42-2a1.5,1.5,0,1,1,1.57,2.56c-1.17.72-2.41,1.43-3.58,2A1.48,1.48,0,0,1,328.5,560Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340,561a1.5,1.5,0,0,1-.55-2.9,4.24,4.24,0,0,0,1.83-1.48,1.5,1.5,0,1,1,2.44,1.74,7.21,7.21,0,0,1-3.17,2.52A1.5,1.5,0,0,1,340,561Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M230.5,604a1.5,1.5,0,0,1-1.07-.45,8.85,8.85,0,0,1-2.42-4.84,1.5,1.5,0,0,1,3-.43,5.86,5.86,0,0,0,1.58,3.16A1.5,1.5,0,0,1,230.5,604Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M236.5,613a1.49,1.49,0,0,1-.89-.29,5.41,5.41,0,0,1-2.11-4.15,1.5,1.5,0,0,1,1.44-1.55,1.47,1.47,0,0,1,1.55,1.44,2.46,2.46,0,0,0,.89,1.85,1.5,1.5,0,0,1-.89,2.71Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M239.5,604.5a1.5,1.5,0,0,1-1.16-.55,3.88,3.88,0,0,1-.81-3.23,1.5,1.5,0,0,1,2.95.56.86.86,0,0,0,.19.77,1.5,1.5,0,0,1-1.16,2.45Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M184.5,419a1.5,1.5,0,0,1-1.48-1.25,8,8,0,0,1,.7-5,1.5,1.5,0,0,1,2.57,1.55,5.2,5.2,0,0,0-.3,3,1.5,1.5,0,0,1-1.23,1.73Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M186,431.5a1.5,1.5,0,0,1-1.22-.63,7.49,7.49,0,0,1-1.28-4.41,1.5,1.5,0,1,1,3,.07,4.53,4.53,0,0,0,.72,2.59A1.5,1.5,0,0,1,186,431.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M192,424.5a1.5,1.5,0,0,1-1.37-.9,14.86,14.86,0,0,1-1.11-3.89,1.5,1.5,0,1,1,3-.42,11.86,11.86,0,0,0,.89,3.11,1.5,1.5,0,0,1-1.37,2.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204.5,533h-36a1.5,1.5,0,0,1,0-3h36a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204,549.5H185.5a1.5,1.5,0,0,1,0-3H204a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M189.5,578.5c-6,0-12.13-.13-18-.25s-12-.25-18-.25a1.5,1.5,0,0,1,0-3c6,0,12.13.13,18,.25s12,.25,18,.25a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M194.74,597.1c-1.16,0-2.31,0-3.45-.05s-2.2,0-3.29,0a1.5,1.5,0,0,1,0-3h0c1.11,0,2.23,0,3.36,0a47.35,47.35,0,0,0,10.34-.52,1.5,1.5,0,0,1,.6,2.94A37.75,37.75,0,0,1,194.74,597.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204.57,643.61c-1.36,0-2.93-.29-3.46-1.53a1.5,1.5,0,0,1,2.52-1.56,6.25,6.25,0,0,0,2.15,0,1.5,1.5,0,0,1,.43,3A11.65,11.65,0,0,1,204.57,643.61Zm-.69-2.69h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M224.41,412a4.41,4.41,0,0,1-2.14-.58,4.94,4.94,0,0,1-2.65-4c-.63-6.22,8.66-15.66,10.4-17.13a1.5,1.5,0,0,1,2.47,1.11c.19,7.81-1.82,17.46-5.91,19.94A4.16,4.16,0,0,1,224.41,412Zm5-16.86c-3.19,3.51-7.12,8.94-6.81,12a2,2,0,0,0,1.11,1.64,1.14,1.14,0,0,0,1.3,0C227.15,407.56,229,401.53,229.42,395.18Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M226.47,442.05a3.21,3.21,0,0,1-2.82-1.63c-2.75-4.65,2.88-20.07,5.89-22.57a1.5,1.5,0,0,1,2.45,1.29,49.5,49.5,0,0,0,.16,7c.44,6.71.89,13.65-3.83,15.5A5.05,5.05,0,0,1,226.47,442.05ZM229,424.37c-2.07,4.91-4,12.42-2.8,14.52.07.11.18.3,1,0,2.69-1.05,2.27-7.41,1.94-12.52C229.11,425.68,229.07,425,229,424.37Z" transform="translate(-60.79 2.5)"/><g class="cls-11"><path class="cls-2" d="M659,528.67a1,1,0,0,1-.06-2l1.29-.08c4.56-.29,8.88-.57,13.44-.59h0a1,1,0,0,1,0,2c-4.5,0-8.79.29-13.32.58l-1.29.08Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M680.33,545.33H669.67a1,1,0,0,1,0-2h10.67a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M638.33,570H633a1,1,0,0,1,0-2h5.33a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M421,664.7c-.45,0-.91,0-1.36,0a1,1,0,0,1,.1-2,43.87,43.87,0,0,0,6.81-.34c1.22-.12,2.49-.25,3.75-.32a1,1,0,0,1,1.06.94,1,1,0,0,1-.94,1.06c-1.22.07-2.46.2-3.66.32A57,57,0,0,1,421,664.7Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M457.67,654a1,1,0,0,1-.36-1.93c3.28-1.27,7.31-1.07,11.22-.87,1.35.07,2.62.13,3.81.13a1,1,0,0,1,0,2c-1.25,0-2.54-.07-3.91-.14-3.69-.19-7.51-.38-10.39.74A1,1,0,0,1,457.67,654Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M503,674H490.33a1,1,0,1,1,0-2H503a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M340.77,690.77a22.36,22.36,0,0,1-6-.81,1,1,0,1,1,.54-1.93,21.35,21.35,0,0,0,7.64.63,1,1,0,0,1,.19,2Q341.92,690.77,340.77,690.77Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M393,700h-8a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M645,630.67h-7.33a1,1,0,0,1,0-2H645a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M731,508.67h-2.67a1,1,0,0,1,0-2H731a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M630.33,513.33a1,1,0,0,1-.35-1.94,11.21,11.21,0,0,1,4.38-.73,1,1,0,0,1,1,1,1,1,0,0,1-1,1,9.37,9.37,0,0,0-3.62.6A1,1,0,0,1,630.33,513.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M753,472h-2.67a1,1,0,1,1,0-2H753a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M765.67,446H763a1,1,0,0,1,0-2h2.67a1,1,0,1,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M111,505.33h-5.33a1,1,0,1,1,0-2H111a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M144.33,500.67h-4a1,1,0,1,1,0-2h4a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-2" d="M120.56,518.83a7.62,7.62,0,0,1-4.12-1,1,1,0,0,1,1.14-1.65,7.18,7.18,0,0,0,4.58.51,1,1,0,1,1,.38,2A10.47,10.47,0,0,1,120.56,518.83Z" transform="translate(-60.79 2.5)"/></g></g><g id="LINEART"><path class="cls-12" d="M145.95,176.85" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M255.72,395.42a2.5,2.5,0,0,1-.07-5c14.6-.4,26.34-2.39,38.77-4.49a316.57,316.57,0,0,1,34.2-4.45,2.5,2.5,0,0,1,.32,5,312.48,312.48,0,0,0-33.68,4.38c-12,2-24.51,4.16-39.46,4.56Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M365,378.9a2.5,2.5,0,0,1-1.06-4.76c5.28-2.48,9.35-5.59,13.65-8.88a95.33,95.33,0,0,1,12-8.2,2.5,2.5,0,0,1,2.42,4.38,91.32,91.32,0,0,0-11.39,7.8c-4.33,3.31-8.8,6.72-14.56,9.43A2.49,2.49,0,0,1,365,378.9Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M371.49,408.63a13.15,13.15,0,0,1-1.43-.08,12.82,12.82,0,0,1-8.47-4.94,9.18,9.18,0,0,1-1.83-7.18c1.23-6.66,9.76-7.66,14.6-7.21h0a9.63,9.63,0,0,1,4.79,1.55,8.4,8.4,0,0,1,3.17,7.19,11.07,11.07,0,0,1-6.4,9.79A11.23,11.23,0,0,1,371.49,408.63Zm.79-14.5c-3.31,0-7.17.89-7.6,3.21a4.26,4.26,0,0,0,.92,3.28,7.71,7.71,0,0,0,5,3,6.7,6.7,0,0,0,3.36-.42,6.08,6.08,0,0,0,3.38-5.35,3.59,3.59,0,0,0-1.08-3,5.2,5.2,0,0,0-2.35-.64h0C373.39,394.15,372.85,394.13,372.29,394.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M363.66,424.5a11.22,11.22,0,0,1-7.68-3,12.76,12.76,0,0,1-3.34-12.21,15.39,15.39,0,0,1,7.71-9.63,2.5,2.5,0,0,1,2.39,4.39,10.53,10.53,0,0,0-5.24,6.45,7.79,7.79,0,0,0,1.94,7.37,6.05,6.05,0,0,0,6.84,1,13.26,13.26,0,0,0,1.65-1.22,18.82,18.82,0,0,1,2.06-1.53c3.61-2.23,8-2,11.37-1.58,1.91.24,4,.51,5-.3s.89-3.23,0-5c-1.06-2.1-5.27-5.48-8-6.77a2.5,2.5,0,0,1,2.15-4.51c3.08,1.47,8.52,5.54,10.28,9s2,8.39-1.34,11.12c-2.66,2.14-6.14,1.7-8.68,1.37s-5.91-.53-8.19.87a14.67,14.67,0,0,0-1.52,1.14,17.46,17.46,0,0,1-2.31,1.68A10.19,10.19,0,0,1,363.66,424.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.27,435a8.13,8.13,0,0,1-4-1,13,13,0,0,1-3.16-2.74,12,12,0,0,1-1.82-2.39c-1.18-2.18-2.32-5.7-2-8.26a2.5,2.5,0,1,1,5,.56,11.53,11.53,0,0,0,1.46,5.31,8.1,8.1,0,0,0,1.12,1.4,8.88,8.88,0,0,0,1.92,1.75,4,4,0,0,0,4-.44,6.94,6.94,0,0,0,2.53-4.42,20.49,20.49,0,0,0-.59-7,2.5,2.5,0,1,1,4.89-1,24.37,24.37,0,0,1,.62,8.94,11.8,11.8,0,0,1-4.51,7.58A9.3,9.3,0,0,1,376.27,435Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.38,410.24a2.5,2.5,0,0,1-.38-5c5.57-.87,10.41-5.64,12.34-12.16,2.08-7,.34-14.44-1.48-19.41a28.74,28.74,0,0,0-3.29-6.64c-4.09-5.88-11.69-9.55-19.85-9.6h-.15c-9,0-17,4.08-22.08,7.51a2.5,2.5,0,0,1-2.79-4.15c8.19-5.51,16.84-8.38,25-8.36,9.76,0,18.92,4.55,23.93,11.74a33.58,33.58,0,0,1,3.88,7.78c3,8.15,3.54,16,1.58,22.56-2.48,8.36-8.9,14.52-16.37,15.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M291.58,645.16a94,94,0,0,1-26.67-3.83,95.29,95.29,0,0,1-38-21.85c-11.07-10.39-14.37-23.33-16.28-35.77a40.63,40.63,0,0,1,0-12.24,2.5,2.5,0,0,1,5,.53,35.69,35.69,0,0,0,0,11c2.05,13.35,5.35,24,14.76,32.88a89.3,89.3,0,0,0,82.71,21.78c2-.48,4-.93,6-1.37,10.24-2.28,19.91-4.44,28.15-10.85a2.5,2.5,0,0,1,3.07,3.95c-9.13,7.1-19.33,9.38-30.14,11.79-2,.44-3.95.88-5.94,1.36A97.5,97.5,0,0,1,291.58,645.16Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M200.22,497.51a2.5,2.5,0,0,1-2.21-1.33c-2.34-4.4-4.81-8.85-7.19-13.15-2.67-4.82-5.43-9.81-8-14.76-6.07-11.51-11.81-24-12.76-37.34-1-13.78,3-28.47,12.17-44.91,4.35-7.8,8.33-13.25,12.9-17.67a67.46,67.46,0,0,1,17.65-11.86c27.92-13.6,60.15-14.28,88-13.15,28.91,1.17,48.72,11.29,66.24,33.85a2.5,2.5,0,1,1-3.95,3.07c-16.52-21.27-35.21-30.82-62.49-31.92s-58.7-.46-85.61,12.65a62.58,62.58,0,0,0-16.36,11c-4.2,4.06-7.9,9.15-12,16.51C177.87,404,174.09,417.8,175,430.58c.88,12.41,6.39,24.33,12.2,35.36,2.59,4.91,5.34,9.87,8,14.67,2.39,4.32,4.87,8.79,7.23,13.22a2.5,2.5,0,0,1-2.21,3.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M261.89,349a2.49,2.49,0,0,1-1.67-.64,4.61,4.61,0,0,1-1.32-3.69,34.16,34.16,0,0,1,.75-6.35,12.71,12.71,0,0,1,2-5,8.89,8.89,0,0,1,9.85-3.06c3,1.06,5.42,3.7,7.23,8.08a43.72,43.72,0,0,1,2,5.84,2.5,2.5,0,0,1-4.84,1.25,38.8,38.8,0,0,0-1.73-5.17c-1.24-3-2.63-4.71-4.25-5.28a3.88,3.88,0,0,0-4.19,1.3,8.26,8.26,0,0,0-1.17,3.09,29.18,29.18,0,0,0-.64,5.42c0,.09,0,.16,0,.21a2.5,2.5,0,0,1-2,4Zm1.67-4.36h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M183.89,387.5a2.52,2.52,0,0,1-.41,0c-3.94-.65-7.3-3.73-9.72-8.89-2.67-5.71-3.34-11.18-1.95-15.82,1.62-5.36,7.07-10.44,13.41-9.67,5,.61,8.67,4.6,11.1,7.24l4.87,5.3a2.5,2.5,0,1,1-3.68,3.38l-4.87-5.3c-2.55-2.78-5.08-5.3-8-5.66-3.68-.45-7,2.84-8,6.15-1.31,4.35.2,9.06,1.69,12.25,1.17,2.51,3.17,5.61,6,6.08a2.5,2.5,0,0,1-.41,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M294.85,448.5A43.45,43.45,0,1,1,338.3,405,43.5,43.5,0,0,1,294.85,448.5Zm0-81.9A38.45,38.45,0,1,0,333.3,405,38.49,38.49,0,0,0,294.85,366.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M394.52,444.82a2.5,2.5,0,0,1-2.5-2.41c-.18-4.94-.79-11.63-1.59-17.47a4.05,4.05,0,0,1,0-1.16A2.53,2.53,0,0,1,392.5,421a2.46,2.46,0,0,1,2.86,2,4.07,4.07,0,0,1,0,1.28c.82,6,1.44,12.85,1.63,17.9a2.5,2.5,0,0,1-2.41,2.59Zm-4.09-20.91h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M375.87,636.22a2.5,2.5,0,0,1-2.46-2l-16-84.58a2.5,2.5,0,0,1,4.91-.93l15.56,82L537.75,595,500.12,420.84,344.73,456.22l10,56.84a2.5,2.5,0,0,1-4.92.87l-10.45-59.18a2.5,2.5,0,0,1,1.91-2.87l160.17-36.47a2.5,2.5,0,0,1,3,1.91l38.69,179a2.5,2.5,0,0,1-1.9,3L376.42,636.16A2.45,2.45,0,0,1,375.87,636.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M542.38,599.64a2.5,2.5,0,0,1-.49-5c23.54-4.76,47.28-10.1,70.61-15.88L578,417l-53.49,1.44c-6.61.18-13.44.36-20.07,1a2.5,2.5,0,0,1-.51-5c6.82-.7,13.74-.89,20.44-1.07L580,411.91a2.46,2.46,0,0,1,2.51,2l35.43,166.24a2.5,2.5,0,0,1-1.84,2.95c-24.16,6-48.78,11.58-73.18,16.51A2.48,2.48,0,0,1,542.38,599.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M339.58,545.66a2.5,2.5,0,0,1-.67-4.91A92.52,92.52,0,0,1,350.66,539l1.36-.16a2.5,2.5,0,0,1,.57,5l-1.36.15a94.18,94.18,0,0,0-11,1.58A2.5,2.5,0,0,1,339.58,545.66Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M365,542.15a2.5,2.5,0,0,1-.41-5c10.27-1.72,16.43-4,18.3-6.92a3.28,3.28,0,0,0,.4-2.81c-1-4-7.08-6.94-18-8.69a2.5,2.5,0,0,1,.79-4.94c8.44,1.36,19.9,4.12,22,12.38a8.33,8.33,0,0,1-1.05,6.79c-2.78,4.27-9.46,7.09-21.67,9.13A2.49,2.49,0,0,1,365,542.15Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M353,517.24l-.28,0A200,200,0,0,0,330.45,516a2.5,2.5,0,0,1,0-5,205,205,0,0,1,22.86,1.26,2.5,2.5,0,0,1-.27,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M374.91,644.09a19.3,19.3,0,0,1-7.71-1.6,35.5,35.5,0,0,1-5.75-3.38l-23.4-15.86a2.5,2.5,0,0,1,2.8-4.14L364.26,635a31.89,31.89,0,0,0,4.94,2.93,14.31,14.31,0,0,0,7.26,1.1,4.63,4.63,0,0,0,2.48-.81c1-.83,1-2.61.47-3.86a2.5,2.5,0,0,1,4.65-1.85c1.39,3.49.62,7.4-1.87,9.52a9.29,9.29,0,0,1-5.17,2A19.23,19.23,0,0,1,374.91,644.09Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M224.4,649.13a19.38,19.38,0,0,1-5.42-.75,5.09,5.09,0,0,1-3-2,5.2,5.2,0,0,1-.74-3c.17-10,7.38-17.73,14.76-24.76a2.5,2.5,0,1,1,3.45,3.62c-6.61,6.3-13.07,13.13-13.21,21.23v.08l.14,0c4.2,1.22,9.32.4,14-2.26,4.56-2.56,8.4-6.47,11.86-10.31a2.5,2.5,0,0,1,3.71,3.35c-3.75,4.16-7.94,8.4-13.13,11.32A25.75,25.75,0,0,1,224.4,649.13Zm-4.15-5.26h0Zm-.31-.44Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M559.82,416.91a2.5,2.5,0,0,1-2.5-2.5V390.84H404.5a2.5,2.5,0,0,1,0-5H559.82a2.5,2.5,0,0,1,2.5,2.5v26.08A2.5,2.5,0,0,1,559.82,416.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M447.94,433.1a2.5,2.5,0,0,1-2.5-2.5V388.34a2.5,2.5,0,0,1,5,0V430.6A2.5,2.5,0,0,1,447.94,433.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M682,484.5H594.42a2.5,2.5,0,1,1,0-5H679.5v-182h-243v90.84a2.5,2.5,0,0,1-5,0V295a2.5,2.5,0,0,1,2.5-2.5H682a2.5,2.5,0,0,1,2.5,2.5V482A2.5,2.5,0,0,1,682,484.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M682,484.5a2.5,2.5,0,0,1-.66-4.91l62.16-16.93V291.75l-61.27,5.74a2.5,2.5,0,1,1-.47-5l64-6A2.5,2.5,0,0,1,748.5,289V464.57a2.5,2.5,0,0,1-1.84,2.41l-64,17.43A2.52,2.52,0,0,1,682,484.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M598,297.5a2.5,2.5,0,0,1-2.5-2.5V150.5H417.66v142H434a2.5,2.5,0,0,1,0,5H415.16a2.5,2.5,0,0,1-2.5-2.5V148a2.5,2.5,0,0,1,2.5-2.5H598a2.5,2.5,0,0,1,2.5,2.5V295A2.5,2.5,0,0,1,598,297.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M670.74,151.74h0L598,150.5a2.5,2.5,0,1,1,.09-5l72.74,1.24a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M695.88,296.2a2.5,2.5,0,0,1-2.5-2.5V177.1a2.5,2.5,0,0,1,5,0V293.7A2.5,2.5,0,0,1,695.88,296.2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M604,150.5a2.5,2.5,0,0,1-2.5-2.5V16L541.5,3.1V148a2.5,2.5,0,0,1-5,0V0a2.5,2.5,0,0,1,.93-1.94,2.5,2.5,0,0,1,2.1-.5l65,14a2.5,2.5,0,0,1,2,2.44V148A2.5,2.5,0,0,1,604,150.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M400,30.5a2.5,2.5,0,0,1-2.5-2.5V5a2.5,2.5,0,0,1,2.41-2.5l139-5A2.51,2.51,0,0,1,541.5-.09a2.5,2.5,0,0,1-2.41,2.59L402.5,7.41V28A2.5,2.5,0,0,1,400,30.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,179.6H289.78l-68-5.1A2.5,2.5,0,0,1,219.5,172V46a2.5,2.5,0,0,1,2-2.45l68-14a2.49,2.49,0,0,1,.5-.05H427a2.5,2.5,0,0,1,2.5,2.5V148a2.5,2.5,0,0,1-5,0V34.5H290.25L224.5,48V169.68l65.56,4.92h125.1a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M290,179.6h0a2.5,2.5,0,0,1-2.5-2.5l0-145.1a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5l0,145.1A2.5,2.5,0,0,1,290,179.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M290,316.5H139a2.5,2.5,0,0,1-2.5-2.5V177.1a2.5,2.5,0,0,1,2.41-2.5L242,171a2.5,2.5,0,1,1,.17,5L141.5,179.51v132h146l0-59.5a2.5,2.5,0,0,1,.74-1.77,2.38,2.38,0,0,1,1.78-.72l125.16,1a2.5,2.5,0,1,1,0,5l-122.64-1,0,59.48A2.5,2.5,0,0,1,290,316.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M199.36,316.5a2.5,2.5,0,0,1-2.5-2.5V175a2.5,2.5,0,0,1,5,0V314A2.5,2.5,0,0,1,199.36,316.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,324.62H144l-.3,0L77,316.48a2.5,2.5,0,0,1,.3-5H139a2.5,2.5,0,0,1,0,5H118.54l25.61,3.12H369.87l-28.15-3.12H290a2.5,2.5,0,0,1,0-5h51.88l.27,0,73.31,8.12a2.5,2.5,0,0,1-.28,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M195.71,489.21H139a2.51,2.51,0,0,1-.5-.05L76.81,476.45a2.5,2.5,0,0,1-2-2.45V314a2.5,2.5,0,0,1,5,0V472l59.44,12.25h56.46a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M144,489.21a2.5,2.5,0,0,1-2.5-2.5V322.12a2.5,2.5,0,0,1,5,0v164.6A2.5,2.5,0,0,1,144,489.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,391a2.5,2.5,0,0,1-2.5-2.5V322.12a2.5,2.5,0,0,1,5,0V388.5A2.5,2.5,0,0,1,415.16,391Z" transform="translate(-60.79 2.5)"/><circle class="cls-2" cx="268" cy="397.88" r="4.97"/><circle class="cls-2" cx="332.92" cy="374.31" r="4.97"/><path class="cls-2" d="M746,291.5l-.33,0-50.12-6.6a2.5,2.5,0,1,1,.65-5l50.12,6.6a2.5,2.5,0,0,1-.32,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M260.2,516c-11.18,0-22.1-.85-32.78-1.67-5.72-.44-11.25-1.28-17.79-2.41-.42-.07-1.15-.13-1.93-.2-3.83-.31-6.88-.7-8.48-2.55-2.33-2.7-2.49-14.1-2.49-14.21a2.5,2.5,0,0,1,.76-1.78,2.43,2.43,0,0,1,1.81-.7,86.45,86.45,0,0,1,11.45,1.34c2.72.44,5.53.9,8.3,1.14,2.19.19,4.39.43,6.52.67,2.37.27,4.82.54,7.24.73,11.37.88,23.05.62,37.87-.85,4.78-.47,9.53-.91,14.27-1.34,8.69-.79,17.68-1.62,26.58-2.67,6.31-.75,12-1.48,17.45-2.22,4.9-.67,9.64-1.59,14.23-2.48l3-.57a2.5,2.5,0,0,1,.94,4.91l-3,.57c-4.65.9-9.46,1.83-14.5,2.52-5.46.75-11.2,1.48-17.54,2.23-9,1.06-18,1.89-26.71,2.69-4.73.43-9.47.87-14.23,1.34-15.12,1.5-27.08,1.76-38.75.86-2.5-.19-5-.47-7.41-.74-2.1-.23-4.26-.48-6.39-.66-3-.25-5.88-.73-8.69-1.18s-5.43-.89-8.12-1.12c.21,3.07.69,7.15,1.22,8.31.74.45,3.75.69,5.05.8.93.08,1.73.14,2.37.25,6.4,1.1,11.79,1.92,17.33,2.35,16.15,1.25,32.85,2.55,49.94.84,3.43-.34,7-.56,10.36-.78,4.63-.29,9.41-.59,14-1.2,3.91-.53,7.81-1.15,11.58-1.76a221.82,221.82,0,0,1,23.71-2.93c2.85-.15,5.73-.1,8.52-.05,1.38,0,2.75,0,4.11,0a2.5,2.5,0,0,1,0,5c-1.39,0-2.8,0-4.2,0-2.7,0-5.49-.1-8.17,0a215,215,0,0,0-23.18,2.88c-3.81.61-7.74,1.25-11.71,1.78-4.73.63-9.6.94-14.31,1.23-3.36.21-6.84.43-10.18.76C272.16,515.75,266.14,516,260.2,516Zm-57.09-10Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M312.32,579.89q-1.43,0-2.86,0c-15-.5-31.12-1.47-50.81-3.05-3.23-.26-6.56-.34-9.77-.42-3.72-.09-7.57-.19-11.4-.55a74,74,0,0,1-8.77-1.55c-2-.44-4.12-.9-6.18-1.21a55.21,55.21,0,0,0-9.94-.29c-2.27.07-4.62.13-7,0a2.5,2.5,0,0,1-2.38-2.36c-.21-3.82-.29-8.26,1.5-12.54a66.07,66.07,0,0,0,3.9-11.72,3.41,3.41,0,0,0-.06-2.55l-.09-.07a4.08,4.08,0,0,1-1.68-3.3,3.78,3.78,0,0,1,1.78-2.78l.12-.09c1.49-5.19-.17-11.18-1.78-17a76.62,76.62,0,0,1-2.05-8.66,2.5,2.5,0,0,1,4.94-.76,71.94,71.94,0,0,0,1.93,8.08c1.86,6.69,3.78,13.6,1.57,20.34a3.23,3.23,0,0,1-.73,1.2,3.74,3.74,0,0,1,.63,1.13,7.77,7.77,0,0,1,.32,5.48,70.61,70.61,0,0,1-4.19,12.63,19.26,19.26,0,0,0-1.21,8c1.44,0,2.85,0,4.33-.08a59.92,59.92,0,0,1,10.83.34c2.22.33,4.4.81,6.51,1.27a69.34,69.34,0,0,0,8.18,1.46c3.64.35,7.4.44,11,.53,3.29.08,6.68.16,10.05.43,19.61,1.58,35.68,2.55,50.57,3,12.67.43,25.17-2.26,37.24-4.86,7.23-1.55,12.09-2.88,14.44-3.93a2.5,2.5,0,0,1,2,4.56c-2.71,1.21-7.75,2.6-15.43,4.25C336.44,577.34,324.6,579.89,312.32,579.89Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372,620.83a2.49,2.49,0,0,1-1.73-.69c-1.32-1.27-2.55-2.67-3.74-4a39,39,0,0,0-5.07-5.14,2.5,2.5,0,0,1,3.07-3.94,43.31,43.31,0,0,1,5.76,5.79c1.17,1.33,2.27,2.59,3.43,3.71a2.5,2.5,0,0,1-1.73,4.31Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M357,551.65a5.21,5.21,0,0,1-2.67-1c-5.24-3.3-4.58-11.16-4.14-16.36.07-.8.13-1.54.16-2.18.06-1.23.14-2.47.22-3.7.17-2.67.34-5.43.34-8.11,0-.37-.07-1-.15-1.64-.32-2.75-.76-6.51,1.74-8.64a5,5,0,0,1,2.09-1,4.05,4.05,0,0,1,3.34.57,3.84,3.84,0,0,1,.47-.26,2.5,2.5,0,0,1,3.11.82l.07.09a3.77,3.77,0,0,1,5.15,1c1.64,2.09,1.54,5.24,1.47,7.55,0,.38,0,.72,0,1,0,4.07,0,8.45-.34,12.9,0,.57-.06,1.32-.08,2.17-.17,6.18-.56,11.92-3.51,14.29-.94.76-1.91,1.54-3.26,1.25a2.59,2.59,0,0,1-1.34-.75,2.73,2.73,0,0,1-2.64,2Zm-1.41-37.47a16,16,0,0,0,.13,3.87,20.36,20.36,0,0,1,.18,2.21c0,2.84-.18,5.68-.35,8.43-.08,1.21-.15,2.42-.21,3.64,0,.69-.1,1.49-.17,2.34-.28,3.34-.73,8.69,1.06,11l.18-.14a3.3,3.3,0,0,1,3.06-2,2.86,2.86,0,0,1,2.16.91c.92-2.23,1.07-7.73,1.13-9.73,0-.93,0-1.74.09-2.36.28-4.31.32-8.59.33-12.58,0-.35,0-.75,0-1.18a22.32,22.32,0,0,0-.07-3.18,2.63,2.63,0,0,1-3.27.36,2.5,2.5,0,0,1-3.7-.65l-.09-.14C355.94,514.73,355.76,514.44,355.59,514.19Zm4.89,30.51h0Zm-4.74-30.9h0Zm-1.62-1.9h0Z" transform="translate(-60.79 2.5)"/></g><g id="circle"><path class="cls-2" d="M153.52,177.1A349.71,349.71,0,0,1,222,114.31L221,102a6,6,0,0,0-3.76,1,361.7,361.7,0,0,0-75.95,70.06,6,6,0,0,0-1.31,4.4" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M139.38,195.21A344.77,344.77,0,0,0,72.79,400c0,191.91,156.13,348,348,348s348-156.13,348-348c0-121.6-61.55-232-164.86-296l.87-13a6,6,0,0,1,2.24.81A359.84,359.84,0,0,1,780.86,400,360.13,360.13,0,0,1,89.08,540.14,360.53,360.53,0,0,1,134.23,182a6,6,0,0,1,3.74-2.26Z" transform="translate(-60.79 2.5)"/></g><g id="layers"><g class="cls-8"><path class="cls-6" d="M368.81,388.34l-1.1-23.69s8.48-17.33,8.09-18,6.68-6.06,6.68-6.06l13-1,8.29,1.85,9.82,12.28,7.21,15.07L424.21,386l-4.71,21.73-6.39,11.59-8.61,4.11L390.36,422l-5.08-3.31,3.67-3.79v-5.42l-4-6.79-5.56-2.47-1.51-7.57Z" transform="translate(-60.79 2.5)"/></g><g class="cls-8"><polygon class="cls-6" points="226.66 366.6 237.24 361.46 250.18 361.46 265.7 366.6 279.96 384.01 285.01 395.42 287.35 407.55 286.4 422.15 279.23 440.12 268 452.2 253.91 456.94 235.27 454.47 220.17 446.08 208.28 425.94 205.61 398.57 213.7 378.9 226.66 366.6"/></g><path class="cls-2" d="M426,376.14c-2.08-12-7.08-22.86-14.06-30.5-7.32-8-16-11.61-24.38-10.16s-15.34,7.76-19.54,17.76c-3.34,7.95-4.62,17.52-3.76,27.46a26.09,26.09,0,0,0-17.18,6.73c-8.49-20.91-28.27-34.1-48.45-30.6-23.83,4.13-39.32,30-34.53,57.59,4.35,25.11,24,43.19,45.38,43.19a38.08,38.08,0,0,0,6.5-.56c11.63-2,21.63-9.18,28.14-20.17a55,55,0,0,0,6.39-37.42c-.32-1.87-.74-3.7-1.23-5.49a19.71,19.71,0,0,1,15.78-7.13c.22,1.27.63,3.21.91,4.42a3.06,3.06,0,0,0,6-1.36c-.26-1.15-.67-3.1-.87-4.24-1.89-10.9-1-21.56,2.6-30,3.37-8,8.67-13,14.95-14.1s13,1.85,18.82,8.26c6.2,6.78,10.66,16.52,12.54,27.41,3.81,22-4.06,41.81-17.54,44.14a13,13,0,0,1-3.13.12,23.62,23.62,0,0,1-10.67-3.64,11.5,11.5,0,0,0-1.58-1.14c-.49-.19-1.28.36-1.83.46a9.58,9.58,0,0,0-1.67.32,1.45,1.45,0,0,0-1,1.23,2.66,2.66,0,0,0,.7,1.39,13,13,0,0,1,.83,1.85c.22.45.71.67,1.13.94a28.53,28.53,0,0,0,15.33,4.73,17.49,17.49,0,0,0,3-.24C420.27,424.45,430.38,401.47,426,376.14Zm-87.14,57.62c-5.59,9.43-14.08,15.56-23.92,17.26-20.5,3.55-40.6-13.34-44.81-37.64s9-47,29.55-50.52a32.07,32.07,0,0,1,5.48-.47c18.49,0,35.5,16,39.33,38.11A48.84,48.84,0,0,1,338.85,433.76Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M309.47,458.61c-22.09,0-42-18.92-46.37-44-4.88-28.17,11-54.53,35.35-58.75,19.89-3.45,39.86,8.82,49,29.93a27.19,27.19,0,0,1,15.71-6,58.73,58.73,0,0,1,3.92-26.87c4.34-10.33,11.55-16.85,20.3-18.36s17.73,2.2,25.29,10.47c7.11,7.77,12.19,18.78,14.3,31h0c4.48,25.87-6,49.37-23.34,52.37a18.5,18.5,0,0,1-3.14.25,29.35,29.35,0,0,1-15.87-4.89l-.23-.14a3,3,0,0,1-1.25-1.2c-.13-.27-.23-.54-.33-.81a4.14,4.14,0,0,0-.42-.92l-.16-.22a2.91,2.91,0,0,1-.72-1.74,2.4,2.4,0,0,1,1.67-2.16,5.81,5.81,0,0,1,1.34-.29l.5-.07a3.31,3.31,0,0,0,.46-.17,2.52,2.52,0,0,1,1.92-.24,4.9,4.9,0,0,1,1.26.85,5.44,5.44,0,0,0,.5.39,21.77,21.77,0,0,0,3.33,1.76,21.47,21.47,0,0,0,6.86,1.72,12,12,0,0,0,2.89-.11c12.94-2.24,20.45-21.52,16.73-43-1.85-10.71-6.22-20.27-12.3-26.91-5.63-6.15-12-9-17.91-7.95s-11,5.82-14.2,13.51c-3.49,8.3-4.39,18.77-2.53,29.48.2,1.14.6,3.06.86,4.19a4.06,4.06,0,1,1-7.91,1.81c-.22-1-.53-2.43-.77-3.66a18.76,18.76,0,0,0-13.84,6.39c.45,1.71.82,3.41,1.11,5.07a56,56,0,0,1-6.51,38.1C338.31,448.64,328.07,456,316.15,458A39.24,39.24,0,0,1,309.47,458.61Zm-4.33-101.34a37.16,37.16,0,0,0-6.35.55c-23.28,4-38.41,29.35-33.72,56.44,4.18,24.15,23.27,42.36,44.4,42.36a37.25,37.25,0,0,0,6.33-.54c11.34-2,21.09-9,27.45-19.69a54,54,0,0,0,6.26-36.74c-.31-1.77-.71-3.58-1.21-5.4l-.14-.5.32-.4a20.76,20.76,0,0,1,16.59-7.5l.81,0,.14.79c.23,1.3.63,3.22.9,4.37a2.06,2.06,0,0,0,2.47,1.55,2.06,2.06,0,0,0,1.55-2.47c-.27-1.16-.68-3.13-.88-4.3-1.92-11.08-1-21.95,2.66-30.59,3.5-8.33,9.08-13.56,15.7-14.7s13.62,1.89,19.73,8.57C414.49,356,419,365.93,420.95,377c3.9,22.55-4.33,42.87-18.36,45.3a14,14,0,0,1-3.37.13,23.47,23.47,0,0,1-7.5-1.87,23.81,23.81,0,0,1-3.64-1.93,7.5,7.5,0,0,1-.69-.53,5.15,5.15,0,0,0-.63-.48,4.85,4.85,0,0,0-.5.19,4.3,4.3,0,0,1-.86.29l-.6.09a4.18,4.18,0,0,0-.89.18.65.65,0,0,0-.38.3,1.91,1.91,0,0,0,.33.55l.19.27a5.89,5.89,0,0,1,.65,1.35c.08.21.16.42.26.63a1.78,1.78,0,0,0,.49.36l.29.18a27.71,27.71,0,0,0,14.78,4.57,16.5,16.5,0,0,0,2.8-.22c16.26-2.82,26-25.27,21.71-50.06h0c-2.05-11.85-7-22.5-13.81-30-7.08-7.75-15.42-11.24-23.47-9.85S373,344,368.94,353.64c-3.27,7.78-4.54,17.11-3.68,27l.09,1.08h-1.09a25.09,25.09,0,0,0-16.52,6.47l-1.06,1-.54-1.33C338.55,369.1,322.28,357.27,305.14,357.27Zm4.32,95.22c-19,0-36.41-16.32-40.32-38.94-4.3-24.85,9.32-48,30.36-51.67a33.19,33.19,0,0,1,5.65-.49c19.14,0,36.48,16.74,40.32,38.94a49.84,49.84,0,0,1-5.75,33.94C334,444,325.23,450.25,315.1,452A33,33,0,0,1,309.46,452.49Zm-4.31-89.1a31.2,31.2,0,0,0-5.31.46c-20,3.46-32.85,25.6-28.73,49.36S294.8,453.49,314.76,450c9.55-1.65,17.8-7.61,23.23-16.79h0a47.84,47.84,0,0,0,5.5-32.58C339.81,379.42,323.32,363.39,305.14,363.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M371.49,408.63a13.15,13.15,0,0,1-1.43-.08,12.82,12.82,0,0,1-8.47-4.94,9.18,9.18,0,0,1-1.83-7.18c1.23-6.66,9.76-7.66,14.6-7.21h0a9.63,9.63,0,0,1,4.79,1.55,8.4,8.4,0,0,1,3.17,7.19,11.07,11.07,0,0,1-6.4,9.79A11.23,11.23,0,0,1,371.49,408.63Zm.79-14.5c-3.31,0-7.17.89-7.6,3.21a4.26,4.26,0,0,0,.92,3.28,7.71,7.71,0,0,0,5,3,6.7,6.7,0,0,0,3.36-.42,6.08,6.08,0,0,0,3.38-5.35,3.59,3.59,0,0,0-1.08-3,5.2,5.2,0,0,0-2.35-.64h0C373.39,394.15,372.85,394.13,372.29,394.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M363.66,424.5a11.22,11.22,0,0,1-7.68-3,12.76,12.76,0,0,1-3.34-12.21,15.39,15.39,0,0,1,7.71-9.63,2.5,2.5,0,0,1,2.39,4.39,10.53,10.53,0,0,0-5.24,6.45,7.79,7.79,0,0,0,1.94,7.37,6.05,6.05,0,0,0,6.84,1,13.26,13.26,0,0,0,1.65-1.22,18.82,18.82,0,0,1,2.06-1.53c3.61-2.23,8-2,11.37-1.58,1.91.24,4,.51,5-.3s.89-3.23,0-5c-1.06-2.1-5.27-5.48-8-6.77a2.5,2.5,0,0,1,2.15-4.51c3.08,1.47,8.52,5.54,10.28,9s2,8.39-1.34,11.12c-2.66,2.14-6.14,1.7-8.68,1.37s-5.91-.53-8.19.87a14.67,14.67,0,0,0-1.52,1.14,17.46,17.46,0,0,1-2.31,1.68A10.19,10.19,0,0,1,363.66,424.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.27,435a8.13,8.13,0,0,1-4-1,13,13,0,0,1-3.16-2.74,12,12,0,0,1-1.82-2.39c-1.18-2.18-2.32-5.7-2-8.26a2.5,2.5,0,1,1,5,.56,11.53,11.53,0,0,0,1.46,5.31,8.1,8.1,0,0,0,1.12,1.4,8.88,8.88,0,0,0,1.92,1.75,4,4,0,0,0,4-.44,6.94,6.94,0,0,0,2.53-4.42,20.49,20.49,0,0,0-.59-7,2.5,2.5,0,1,1,4.89-1,24.37,24.37,0,0,1,.62,8.94,11.8,11.8,0,0,1-4.51,7.58A9.3,9.3,0,0,1,376.27,435Z" transform="translate(-60.79 2.5)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.png b/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.png deleted file mode 100644 index 62e2af686a6ad9ac1f48c4fab3cb92460ee9cddf..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.svg b/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.svg deleted file mode 100644 index 06a7fedc4d5fc13addd93190f88928162cd3c4ce..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyFlatScene2.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 725.13 841.56"><defs><style>.cls-1{fill:#1c1c1b;}.cls-2{fill:#ced8d2;}.cls-3{opacity:0.2;}.cls-4{opacity:0.45;}.cls-5{fill:#ccbca8;}.cls-6{fill:#b79765;}.cls-7{fill:#fff;}.cls-8{opacity:0.38;}.cls-9{fill:#f6d2a2;}.cls-10{fill:#b7a38d;}.cls-11{fill:#1d1d1b;}.cls-12{opacity:0.19;}</style></defs><title>BoyerFlatScene2</title><g id="Capa_10" data-name="Capa 10"><path class="cls-1" d="M764.83,322.58A357.59,357.59,0,0,0,608.13,193.31l.36-11,36.64-58.43a2.5,2.5,0,0,0-2.34-3.82l-24.27,2.17,11.87-36.4a2.5,2.5,0,0,0-1.76-3.2l-134.5-34a2.5,2.5,0,0,0-3.05,1.89l-21.16,96.39L429.15,79.7a2.51,2.51,0,0,0-2.31-1.2L276.83,89a2.5,2.5,0,0,0-2.15,3.41l3.72,9.52-17.26-4.35a2.5,2.5,0,0,0-2.5,4.06l53.29,61.29V202.7a3.52,3.52,0,0,0-3.42-.16,357.58,357.58,0,1,0,456.3,120Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M468.33,885.06a362.61,362.61,0,0,1-162-687q.32-.16.65-.29v-33l-52.07-59.88a7.5,7.5,0,0,1,7.49-12.19l7.84,2-.18-.47A7.5,7.5,0,0,1,276.48,84l150-10.5a7.49,7.49,0,0,1,6.93,3.59l34.28,56.48,18.48-84.19a7.5,7.5,0,0,1,9.15-5.67l134.51,34a7.5,7.5,0,0,1,5.29,9.6l-9.52,29.2L642.34,115a7.5,7.5,0,0,1,7,11.45l-35.92,57.28-.2,6.29a362.56,362.56,0,0,1-144.91,695ZM310,207.39a352.51,352.51,0,1,0,296.15-9.48L603,196.57l.51-15.82,34.68-55.31-26.8,2.39L624.8,86.77,495.4,54.06,472.12,160.13,425.66,83.6,280.58,93.76l6,15.39-18.95-4.78,49.29,56.69v50.56Z" transform="translate(-105.77 -43.5)"/></g><g id="background_color" data-name="background color"><path class="cls-2" d="M606.14,196.29C733.21,250,822.37,375.85,822.37,522.5c0,195.53-158.51,354-354,354s-354-158.51-354-354c0-138.66,79.71-258.7,195.81-316.8" transform="translate(-105.77 -43.5)"/></g><g id="background_shadows" data-name="background shadows"><g class="cls-3"><polygon points="655.41 575.12 531.59 650.5 494.43 631.06 496.06 597.66 556.54 578.75 655.41 575.12"/></g><g class="cls-3"><path d="M168.51,577.42l-52.39,5.17s20.59,65.66,26.2,78.18S178.74,727,185.62,737.5s37.45,40.32,37.45,40.32L383.61,705Z" transform="translate(-105.77 -43.5)"/></g></g><g id="Capa_9" data-name="Capa 9"><path class="cls-1" d="M770.15,537.19c-5.12,0-9.59-.48-13-1.76a2.5,2.5,0,0,1,1.78-4.67c7.58,2.88,23.89.83,38.27-1,8.92-1.12,17.34-2.18,23.83-2.18a2.5,2.5,0,0,1,0,5c-6.19,0-14.46,1-23.21,2.14C788.21,535.95,778.35,537.19,770.15,537.19Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M116.11,585.09a2.5,2.5,0,0,1-.58-4.93c12-2.85,23.67-3.07,36.58-3.07a2.5,2.5,0,0,1,0,5h0c-12.64,0-24,.21-35.42,2.93A2.48,2.48,0,0,1,116.11,585.09Z" transform="translate(-105.77 -43.5)"/><g class="cls-4"><path class="cls-1" d="M307.84,758.67h-4.67a2.5,2.5,0,0,1,0-5h4.67a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M348.51,782.67h-6a2.5,2.5,0,1,1,0-5h6a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M491.18,824.67h-2.67a2.5,2.5,0,1,1,0-5h2.67a2.5,2.5,0,1,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M546.51,806h-2.67a2.5,2.5,0,0,1,0-5h2.67a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M693.18,678.67a2.5,2.5,0,0,1-1-4.78,9.8,9.8,0,0,1,4.46-.89,2.5,2.5,0,0,1,2.41,2.59,2.53,2.53,0,0,1-2.59,2.41,4.85,4.85,0,0,0-2.2.44A2.49,2.49,0,0,1,693.18,678.67Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M671.17,663.33a2.5,2.5,0,0,1-.21-5l3.06-.29c1.43-.14,2.86-.28,4.3-.38a2.5,2.5,0,0,1,.36,5c-1.4.1-2.79.24-4.18.37l-3.13.29Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M743.84,654h-6a2.5,2.5,0,0,1,0-5h6a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M787.18,579.33h-8a2.5,2.5,0,0,1,0-5h8a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M628.13,800.15a18.45,18.45,0,0,1-6.49-1,2.5,2.5,0,1,1,1.73-4.69c2.16.8,4.77.7,7.54.59,1,0,2-.07,2.94-.07a2.5,2.5,0,0,1,0,5h-.09c-.87,0-1.75,0-2.65.07S629.13,800.15,628.13,800.15Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M302.11,802.76a25.61,25.61,0,0,1-6.21-.84,2.5,2.5,0,0,1,1.22-4.85,18.38,18.38,0,0,0,6.44.61,2.5,2.5,0,1,1,.57,5A17.58,17.58,0,0,1,302.11,802.76Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M354.79,816.06a18.53,18.53,0,0,1-8-1.64,2.5,2.5,0,0,1,2.15-4.51,14.84,14.84,0,0,0,7.42,1.1,2.5,2.5,0,0,1,.35,5Q355.72,816.06,354.79,816.06Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M239.84,748.67h-5.33a2.5,2.5,0,1,1,0-5h5.33a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g></g><g id="COLOR"><path class="cls-5" d="M636.94,672.51l.8-29.52,123.44-24.37V376.75L670.5,347.84,601.4,325l3.79-143.43L643,122.5,615,125,627.37,87,493.51,51,468.33,152.25,427,81,277,91.5l5.55,14.05L262,101.71,313.76,162l.69,106.83L247.51,274l-11.2-.75,8.12,48.44-1.59,103.56v2.92l-42.58,5.43V470.5l-50.82,8v45l-4.36,2,12.4,36-2,100.22,95.38,63.2c.75.5,131-19.64,131-19.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M488,791.08c1.73.41,3.46.83,5.22,1.13,6.25,1.07,11.6,2.26,18.06,1.63,15.87-1.55,33.24-1.7,48.46-6.84,9.3-3.14,17.6-8.61,25.79-14l21.6-14.3c7.14-4.73,14.35-9.51,20.21-15.76,3.07-3.27,6-7.1,10.28-8.44,3.42-1.07,6.91,0,10.21-1s6.54-3.75,8.88-6.16a28.13,28.13,0,0,0,8.11-19.64c-.06-4.51-1.64-9.52-5.69-11.52-5.15-2.55-8.9,1.34-12.27,4.65-2.85,2.8-5.23,7.7-7.65,2-1.27-3-1-5.72-1.82-8.82-2-7.49-2.87-17.1-6.28-24.09s-13.47-5.69-19.9-5c-3.27.35-6.28,2.14-9.35,2.57-5.08.73-10.24-.11-15.36.77-10,1.71-20.73,3.63-30.14,7.61-10.29,4.35-19,11.78-28.48,17.55-6.62,4-8.49,8.54-12.51,14.63-2.18,3.29-2.85,4.21-7.09,4.81a13.21,13.21,0,0,0-7.4,3,133.18,133.18,0,0,0-20,17.45A147.06,147.06,0,0,0,464.33,755c-2.47,4-4.95,7.94-7.57,11.93-2.18,3.31-7.21,7.6-8.2,11.21,4.48.44,9.38,4.8,13.63,6.63,4,1.74,8.69,4.48,13,5.08,2.75.39,5.59-.06,8.33.34C485,790.4,486.49,790.73,488,791.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M577.72,629.6q1.12-1.14,2.21-2.32c2.31-2.5,6.69-5.41,7.4-8.85a12.6,12.6,0,0,0-.2-4.62c-.49-2.9-4-13.59-1.07-15.25a6.65,6.65,0,0,1,2.48-.54c4.88-.6,8.84-4.32,11.51-8.45,7.67-11.89,6.78-30.25-1.48-41.48l-5.77-7.85a42.81,42.81,0,0,0-6.15-7.19,24.19,24.19,0,0,0-19.1-5.79c-5.24.6-10.62,1.84-15.71.44-6.12-1.68-10.55-6.81-15.62-10.61-11.44-8.57-26.51-10.51-40.81-10.52a6.36,6.36,0,0,1-3.58-.7,7.41,7.41,0,0,1-2-2.67,19.85,19.85,0,0,0-6.55-6.83,7,7,0,0,0-4.88-1.36,8.49,8.49,0,0,0-3.73,2.19c-2.45,2.07-5.11,4.3-6.63,7.19-1.34,2.55-.75,6.11-3.41,7.46-2.07,1.05-6.25,1-8.69,1.86q-6,2.11-11.86,4.63c-11.08,4.77-21.65,10.62-32.2,16.46-9.48,5.25-19.69,11.33-23.34,21.53-.76,2.13-2.21,3-3.16,5a22.16,22.16,0,0,0-23.17,2.28,10.31,10.31,0,0,0-4.1,5.86,10.86,10.86,0,0,0,1.44,6.8,28,28,0,0,0,16.12,13.78,4.73,4.73,0,0,1,2.38,1.28c1.42,1.8-.31,4.55-1,6.29a16.18,16.18,0,0,0-1.49,6.8v50.12c0,5.83.09,12,3.07,17,24.4.82,49.14-5.34,73.43-7.85,10.86-1.13,21.79-1.25,32.68-2,13.67-1,27.24-2.89,40.81-4.83,6.15-.88,12.4-1.86,18.23-4.11a93,93,0,0,0,25.29-15.26A110.36,110.36,0,0,0,577.72,629.6Z" transform="translate(-105.77 -43.5)"/><path class="cls-7" d="M551.14,648.24a67.44,67.44,0,0,1-9.66,4.38,66.76,66.76,0,0,1-13.13,2.49q-36.59,4.39-73.27,7.93c-22.21,2.14-43.57,6.23-65.86,7.06a40.19,40.19,0,0,0-15.61,3.34c-.16,3.1-.3,6.31.75,9.23s3.64,5.53,6.75,5.62a31.17,31.17,0,0,0,1.32,12.18,62.17,62.17,0,0,0,3.63,8.47c2.84,5.82,5.29,12.19,8.67,17.71,2.63,4.3,5.48,8.34,6.8,13.35,1.23,4.67,3.06,6.19,6.32,9.51,3.59,3.65,7.3,7.54,11,11.31,5.46,5.63,10.9,9.18,18,12.77,1.93,1,3.89,1.83,5.74,2.84,3.09,1.68,3.64,2.29,6.11-.71,3.95-4.81,7.13-10.25,11.23-14.92,3.41-3.88,6.75-7.86,9.78-12,4.73-6.42,9.78-12.61,14.9-18.73,4.32-5.16,10.41-8.76,15-13.52,2.82-2.94.35-3.06-.08-7.15-.74-7,2.48-24.26,12.5-18.55,3.65,2.08,4.47,6.22,7.77,7.92,1-2.83,4.22-5.08,6.75-6.63,4.12-2.52,7.95-5.48,12.35-7.42,6.86-3,13.52-6.36,20.46-9.1,7.16-2.83,14.43-6.14,22-7.72,8.37-1.74,16.44-1.92,25-2.34,6.53-.32,13.08-.12,19.43-1.12,0-1.92-3.18-4.81-4.48-6.45a70.75,70.75,0,0,0-5.79-6.52c-4.4-4.28-8.58-.64-12.84,2.51s-15.29,11-19.27,3.36c-4.43-8.46,2.81-15.4,10.76-15.85,4.41-.25,7.76.45,11.09,3.34,2.94,2.54,5,6.21,8.85,7.3,3.25-5.74-.65-13.37-5.28-16.92-5-3.86-11-3.82-15.33-8.71-1.53-1.75-3-6-5-7-2.57-1.27-4.3,2.26-6,4.44-4,5.2-7.54,10.85-13.37,14.23S557.26,645.07,551.14,648.24Z" transform="translate(-105.77 -43.5)"/><g class="cls-8"><path class="cls-7" d="M548.55,520.1a25.14,25.14,0,0,1,6.58-6.75,23.42,23.42,0,0,1,7.31-2.95,40.69,40.69,0,0,1,35.7,8.76c11.42,10,15.88,25.19,17.67,39.75.86,7,2.84,12.83,1.86,20a46.19,46.19,0,0,1-9.29,22.14,24.82,24.82,0,0,1-7.23,6.57c-4.26,2.37-9.29,2.79-14.15,3.17l-12.41,1c-3,.23-6.28.43-9-1-2.14-1.16-3.63-3.21-5-5.2C543.23,581.15,529,547.74,548.55,520.1Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-8"><path class="cls-7" d="M423.16,562.28a25.14,25.14,0,0,1,6.58-6.75c17.24-11.2,40.27-11.29,59.15-4.76,7.48,2.59,15,6.48,19.15,13.23,2.19,3.57,3.27,7.7,5.06,11.48,2.78,5.88,5.22,8.87,5.62,15.37.35,5.59,1.06,11.13,1.07,16.75,0,10.38-1.67,22-10.26,29-9.82,7.93-21.24,14.51-33.77,16-11.55,1.37-23.07-1.78-33.34-6.94-4.59-2.31-11.26-5.26-14.7-9.17-2.83-3.22-4.69-8.71-6.44-12.64C412.37,603.93,410,580.92,423.16,562.28Z" transform="translate(-105.77 -43.5)"/></g><path class="cls-9" d="M521.44,619.75a4.06,4.06,0,0,0,.1,2.17,3.59,3.59,0,0,0,1.47,1.52,10.39,10.39,0,0,0,11.8-.66c2.25-1.82,3.66-4.55,6-6.22,4.47-3.15,10.66-1.55,15.94-3a8.15,8.15,0,0,0,5.21-3.66c1.57-2.92.15-6.82-2.56-8.74s-6.3-2.16-9.56-1.52a7.14,7.14,0,0,0-2.58.94c-.5.33-.92.76-1.44,1.07a7.24,7.24,0,0,1-2.14.74,91,91,0,0,1-9.6,2.15c-1.8.21-4-.33-5.66.51C524.25,607.22,522.06,615.55,521.44,619.75Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M539.69,595.19a16.74,16.74,0,0,0-5.23,2.53,7.4,7.4,0,0,0-2.66,3.05,2.77,2.77,0,0,0-.21,1.58,3,3,0,0,0,1.52,1.83,8.09,8.09,0,0,0,4.66.9,34.56,34.56,0,0,0,4.74-.86,12.39,12.39,0,0,0,4.27-1.41,3.67,3.67,0,0,0,1.78-3.83,4.43,4.43,0,0,0-2.74-2.55,12.88,12.88,0,0,0-7.51-.78" transform="translate(-105.77 -43.5)"/><path class="cls-7" d="M538.59,620.55a4.57,4.57,0,0,0,.24,1.64c.34,1.06,2.86,5.74,4,6.17,3.37,1.25,12-3.91,12-7.67-.11-7-5.46-6-10.54-4.6C541.69,616.81,538.73,617.93,538.59,620.55Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M511.18,690.5c-9.54-4.09-12.13,7.26-11.68,14.67.27,4.56,1.43,7.6,6.67,7.33,4.82-.25,10.48-4.16,12.43-8.64S516.34,693.51,511.18,690.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M601.84,640.83c-4.64-2.27-18.77,2-20.76,7.33-5.05,13.47,13.34,13.65,20.77,9.07C608.25,653.3,614.29,646.82,601.84,640.83Z" transform="translate(-105.77 -43.5)"/><polygon class="cls-10" points="261.69 395.02 182.17 404.84 135.41 383.03 140.61 281.16 130.54 229.75 142.41 232.33 236.08 222.66 247.41 240.66 251.49 239.66 264.08 210.62 310.13 222.66 306.47 236.45 312.74 236 302.08 275.33 302.33 355.11 274.9 357.33 280.37 390.09 254.85 381.34 261.69 395.02"/></g><g id="DETAILS"><path class="cls-11" d="M652,604.19a1.5,1.5,0,0,1-.3-3l27.16-5.51a1.5,1.5,0,0,1,.6,2.94l-27.15,5.51A1.5,1.5,0,0,1,652,604.19Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M656.45,629.7a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,1.37-1.62,1.52,1.52,0,0,1,1.62,1.37c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M656.44,629.7a1.5,1.5,0,0,1-.27-3c9.22-1.72,19.79-3.64,28.25-4.79a1.5,1.5,0,0,1,.41,3c-8.4,1.15-18.92,3.05-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M684.63,624.91a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.81-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,0,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.37,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M683.75,598.95a1.5,1.5,0,0,1-.3-3l27.16-5.51a1.5,1.5,0,1,1,.6,2.94l-27.15,5.51A1.5,1.5,0,0,1,683.75,598.95Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M688.15,624.45a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,1.37-1.62,1.52,1.52,0,0,1,1.62,1.37c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M688.15,624.45a1.5,1.5,0,0,1-.27-3c9.21-1.72,19.77-3.64,28.25-4.79a1.5,1.5,0,0,1,.41,3c-8.42,1.15-18.93,3.06-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M716.33,619.67a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.81-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,1,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.37,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M715.47,593.5a1.5,1.5,0,0,1-.3-3L742.33,585a1.5,1.5,0,0,1,.6,2.94l-27.16,5.51A1.49,1.49,0,0,1,715.47,593.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M719.87,619a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,3-.25c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M719.87,619a1.5,1.5,0,0,1-.27-3c9.21-1.72,19.76-3.64,28.25-4.79a1.5,1.5,0,1,1,.4,3c-8.43,1.15-18.94,3.06-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M748.05,614.22a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.82-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,0,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.38,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M666.66,622.38a1.5,1.5,0,0,1-1.47-1.21,120.78,120.78,0,0,1-1.74-12,1.5,1.5,0,1,1,3-.28,118,118,0,0,0,1.7,11.69,1.5,1.5,0,0,1-1.47,1.79Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M662.34,609.44a.26.26,0,0,0,0,.15c0,.15.25.12.39.05a12.33,12.33,0,0,1,4.83-1.24,11.24,11.24,0,0,1-1.68-2c-.28-.39-1.12-1.92-1.64-1.94s-.76,1.76-.89,2.22A19.33,19.33,0,0,1,662.34,609.44Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M671.86,621.56a1.5,1.5,0,0,1-1.47-1.21,120.75,120.75,0,0,1-1.74-12,1.5,1.5,0,1,1,3-.28,117.9,117.9,0,0,0,1.7,11.69,1.5,1.5,0,0,1-1.18,1.76Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M667.54,608.61a.26.26,0,0,0,0,.15c0,.15.25.12.39.05a12.33,12.33,0,0,1,4.83-1.24,11.24,11.24,0,0,1-1.68-2c-.28-.39-1.12-1.92-1.64-1.94s-.76,1.76-.89,2.22A19.33,19.33,0,0,1,667.54,608.61Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M702.49,619a2.52,2.52,0,0,1-.46,0,3.11,3.11,0,0,1-2.3-2.24,14.26,14.26,0,0,1-.48-1.74l-1.45-6.37a1.5,1.5,0,1,1,2.93-.67l1.45,6.37a12.26,12.26,0,0,0,.35,1.31,5.84,5.84,0,0,0,.14-.61,1.5,1.5,0,0,1,2.95.56,5.49,5.49,0,0,1-.71,2A2.91,2.91,0,0,1,702.49,619Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M693.91,610.54a2.17,2.17,0,0,1-1.89-.87c-.61-.85-.49-2,.34-3.36a8.16,8.16,0,0,1,4.83-3.94,11.49,11.49,0,0,1,4.48-.26,6.73,6.73,0,0,1,3.94,1.92,4.41,4.41,0,0,1,1.9,3.2,1.5,1.5,0,0,1-1.23,1.49c-2.55.46-5.14.88-7.71,1.25-.48.07-1,.12-1.47.17a21.5,21.5,0,0,0-2.27.32A4.39,4.39,0,0,1,693.91,610.54ZM700,605a7.29,7.29,0,0,0-2,.25,4.76,4.76,0,0,0-2.72,2.06c.51-.07,1-.12,1.51-.18s.91-.09,1.36-.16c1.77-.25,3.56-.53,5.33-.83a3.56,3.56,0,0,0-2.16-1.06A11.39,11.39,0,0,0,700,605Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M698.86,604.5a1.5,1.5,0,0,1-1.45-1.11l-.44-1.6a1.5,1.5,0,1,1,2.89-.79l.44,1.6a1.5,1.5,0,0,1-1.45,1.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M729.58,605.81a6.59,6.59,0,0,1-2.87-.71,4,4,0,0,1-1.54-1.23,4.38,4.38,0,0,1-.67-2l-1.1-7.41a1.5,1.5,0,1,1,3-.44l1.1,7.41a2.64,2.64,0,0,0,.16.7,1.16,1.16,0,0,0,.41.26,3.42,3.42,0,0,0,1.76.39,1.67,1.67,0,0,0,1.19-.6c.52-.71.27-2,0-3.21l-1.22-5.27a1.5,1.5,0,1,1,2.92-.68l1.22,5.27c.31,1.32.88,3.77-.5,5.66a4.62,4.62,0,0,1-3.34,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M724.92,595.53a1.5,1.5,0,0,1-.49-2.92,8.6,8.6,0,0,1,2-.38l4.62-.46a1.5,1.5,0,0,1,.3,3l-4.62.46a6.16,6.16,0,0,0-1.34.23A1.5,1.5,0,0,1,724.92,595.53Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M730.91,613.71a1.5,1.5,0,0,1-1.46-1.19c-.54-2.52-1-5.09-1.25-7.65a1.5,1.5,0,1,1,3-.34c.28,2.46.68,4.93,1.2,7.36a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M728.12,615a1.5,1.5,0,0,1-.52-2.91,9.5,9.5,0,0,1,2.54-.46l.75-.07A9.73,9.73,0,0,0,733,611a1.5,1.5,0,1,1,1,2.82,12.73,12.73,0,0,1-2.81.67l-.85.08a7.07,7.07,0,0,0-1.76.29A1.49,1.49,0,0,1,728.12,615Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M500.65,218.38a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3l-27.59,2.52Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M502.24,244.21a1.5,1.5,0,0,1-1.47-1.19c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M502.24,244.21a1.5,1.5,0,0,1-.11-3c9.34-.71,20.05-1.46,28.61-1.69h0a1.5,1.5,0,0,1,0,3c-8.49.22-19.15,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M530.77,242.53a1.5,1.5,0,0,1-1.46-1.15C528,236,527.73,230,527.44,224.2c-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M532.74,216.62a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3l-27.59,2.52Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M534.33,242.45a1.5,1.5,0,0,1-1.47-1.19c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M534.33,242.45a1.5,1.5,0,0,1-.11-3c9.34-.71,20.05-1.46,28.61-1.69a1.5,1.5,0,0,1,.08,3c-8.49.22-19.15,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M562.86,240.77a1.5,1.5,0,0,1-1.46-1.15c-1.29-5.39-1.58-11.38-1.87-17.17-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M564.86,214.67a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3L565,214.66Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M566.45,240.5A1.5,1.5,0,0,1,565,239.3c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M566.45,240.5a1.5,1.5,0,0,1-.11-3c9.33-.71,20-1.46,28.61-1.69a1.5,1.5,0,0,1,.08,3c-8.51.22-19.16,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M595,238.81a1.5,1.5,0,0,1-1.46-1.15c-1.29-5.39-1.58-11.38-1.87-17.18-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M513.19,238.06a1.5,1.5,0,0,1-1.49-1.37,120.8,120.8,0,0,1-.42-12.11,1.52,1.52,0,0,1,1.52-1.48,1.5,1.5,0,0,1,1.48,1.52,118,118,0,0,0,.41,11.81,1.5,1.5,0,0,1-1.37,1.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M510.14,224.71a.26.26,0,0,0,0,.15c0,.15.24.14.38.09a12.33,12.33,0,0,1,4.93-.71,11.24,11.24,0,0,1-1.46-2.14c-.24-.42-.91-2-1.42-2.11s-.95,1.66-1.12,2.11A19.33,19.33,0,0,1,510.14,224.71Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M518.45,237.8a1.5,1.5,0,0,1-1.49-1.37,120.79,120.79,0,0,1-.42-12.11,1.5,1.5,0,0,1,1.5-1.48h0a1.5,1.5,0,0,1,1.48,1.52,118,118,0,0,0,.41,11.81,1.5,1.5,0,0,1-1.37,1.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M515.4,224.46a.26.26,0,0,0,0,.15c0,.15.24.14.38.09a12.33,12.33,0,0,1,4.93-.71,11.24,11.24,0,0,1-1.46-2.14c-.24-.42-.91-2-1.42-2.11s-.95,1.66-1.12,2.11A19.33,19.33,0,0,1,515.4,224.46Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M549.29,238.63a2.53,2.53,0,0,1-.73-.11,3.11,3.11,0,0,1-2-2.48,14,14,0,0,1-.28-1.78l-.75-6.5a1.5,1.5,0,1,1,3-.34l.74,6.49a12.42,12.42,0,0,0,.2,1.34,5.71,5.71,0,0,0,.21-.59,1.5,1.5,0,1,1,2.87.88,5.48,5.48,0,0,1-.93,2A3,3,0,0,1,549.29,238.63Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M541.83,229.26a2.3,2.3,0,0,1-2.2-1.1c-.51-.91-.27-2,.7-3.3a8.16,8.16,0,0,1,5.24-3.39,11.43,11.43,0,0,1,4.48.23,6.71,6.71,0,0,1,3.71,2.33,4.4,4.4,0,0,1,1.54,3.39,1.5,1.5,0,0,1-1.39,1.34c-2.58.18-5.21.32-7.8.4-.49,0-1,0-1.48,0a22.18,22.18,0,0,0-2.28.07Zm12-2h0Zm-6.65-2.92a6.64,6.64,0,0,0-1.09.09,4.76,4.76,0,0,0-2.93,1.75c.51,0,1,0,1.51,0s.92,0,1.37,0c1.79-.06,3.59-.14,5.39-.24a3.56,3.56,0,0,0-2-1.29A10,10,0,0,0,547.15,224.35Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M547.14,223.79a1.5,1.5,0,0,1-1.48-1.27l-.26-1.64a1.5,1.5,0,1,1,3-.47l.26,1.64a1.5,1.5,0,0,1-1.25,1.72Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M578,228.46h-.11a6.37,6.37,0,0,1-3.25-1,4,4,0,0,1-1.4-1.39,4.39,4.39,0,0,1-.46-2l-.29-7.49a1.5,1.5,0,0,1,3-.12l.29,7.49a2.64,2.64,0,0,0,.08.71,1.17,1.17,0,0,0,.38.3,3.4,3.4,0,0,0,1.7.58,1.69,1.69,0,0,0,1.25-.46c.6-.65.49-2,.35-3.19l-.64-5.37a1.5,1.5,0,0,1,3-.35l.64,5.37c.16,1.34.46,3.85-1.12,5.57A4.6,4.6,0,0,1,578,228.46Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M574,217.71a1.5,1.5,0,0,1-.33-3,8.77,8.77,0,0,1,2.05-.15l4.65,0a1.5,1.5,0,0,1,0,3h0l-4.64,0a6.15,6.15,0,0,0-1.35.08A1.53,1.53,0,0,1,574,217.71Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M578,236.44a1.5,1.5,0,0,1-1.49-1.35c-.26-2.55-.4-5.16-.41-7.74a1.5,1.5,0,0,1,1.49-1.51h0a1.5,1.5,0,0,1,1.5,1.49c0,2.48.14,5,.39,7.45a1.5,1.5,0,0,1-1.34,1.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M575.09,237.37a1.5,1.5,0,0,1-.36-3,9.55,9.55,0,0,1,2.58-.18h.75a9.75,9.75,0,0,0,2.19-.27,1.5,1.5,0,1,1,.71,2.92,12.81,12.81,0,0,1-2.87.36h-.85a7.06,7.06,0,0,0-1.79.1A1.52,1.52,0,0,1,575.09,237.37Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M266.5,686.83a1.5,1.5,0,0,1-.31-3l27.11-5.73a1.5,1.5,0,1,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,266.5,686.83Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M271.1,712.29a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.21-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.13a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,271.1,712.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M271.1,712.29a1.5,1.5,0,0,1-.29-3c9.18-1.79,19.71-3.79,28.21-5a1.5,1.5,0,0,1,.43,3c-8.43,1.22-18.92,3.21-28.07,5A1.46,1.46,0,0,1,271.1,712.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M299.24,707.28a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.84-.57-3.39-1.11-6.6-1.81-9.51a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.27,1.86,9.72.94,5.59,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M298.16,681.32a1.5,1.5,0,0,1-.31-3L325,672.62a1.5,1.5,0,0,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,298.16,681.32Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M302.77,706.79a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.22-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.13a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,302.77,706.79Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M302.77,706.79a1.5,1.5,0,0,1-.29-3c9.2-1.8,19.75-3.8,28.21-5a1.5,1.5,0,1,1,.43,3c-8.4,1.21-18.9,3.21-28.07,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M330.91,701.78a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.84-.57-3.39-1.11-6.6-1.81-9.51a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.27,1.86,9.72.94,5.58,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M329.83,675.62a1.5,1.5,0,0,1-.31-3l27.11-5.73a1.5,1.5,0,1,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,329.83,675.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M334.44,701.08a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.21-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.12a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,334.44,701.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M334.44,701.08a1.5,1.5,0,0,1-.29-3c9.19-1.79,19.74-3.8,28.21-5a1.5,1.5,0,0,1,.43,3c-8.41,1.22-18.91,3.21-28.07,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M362.58,696.07a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.83-.57-3.39-1.11-6.6-1.82-9.52a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.28,1.86,9.72.94,5.58,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M281.26,704.9a1.5,1.5,0,0,1-1.47-1.2c-.81-3.95-1.43-8-1.84-12a1.5,1.5,0,1,1,3-.3c.4,3.9,1,7.83,1.79,11.68a1.5,1.5,0,0,1-1.17,1.77A1.54,1.54,0,0,1,281.26,704.9Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M276.84,692a.26.26,0,0,0,0,.15c0,.15.25.12.39,0a12.33,12.33,0,0,1,4.82-1.28,11.24,11.24,0,0,1-1.7-2c-.29-.39-1.14-1.92-1.66-1.93s-.75,1.76-.87,2.23A19.33,19.33,0,0,1,276.84,692Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M286.45,704a1.5,1.5,0,0,1-1.47-1.2,120.91,120.91,0,0,1-1.84-12,1.5,1.5,0,1,1,3-.3,118,118,0,0,0,1.79,11.68,1.5,1.5,0,0,1-1.17,1.77A1.53,1.53,0,0,1,286.45,704Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M282,691.12a.26.26,0,0,0,0,.15c0,.15.25.12.39,0a12.33,12.33,0,0,1,4.82-1.28,11.24,11.24,0,0,1-1.7-2c-.29-.39-1.14-1.92-1.66-1.93s-.75,1.76-.87,2.23A19.33,19.33,0,0,1,282,691.12Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M317.05,701.25a2.49,2.49,0,0,1-.44,0,3.11,3.11,0,0,1-2.32-2.23,14.09,14.09,0,0,1-.49-1.73l-1.5-6.36a1.5,1.5,0,0,1,2.92-.69l1.5,6.36a12.44,12.44,0,0,0,.36,1.31,5.79,5.79,0,0,0,.13-.61,1.5,1.5,0,1,1,3,.54,5.42,5.42,0,0,1-.7,2.05A2.91,2.91,0,0,1,317.05,701.25Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M308.39,692.83a2.17,2.17,0,0,1-1.87-.86c-.61-.84-.51-2,.31-3.36a8.15,8.15,0,0,1,4.8-4,11.42,11.42,0,0,1,4.48-.3,6.72,6.72,0,0,1,4,1.88,4.4,4.4,0,0,1,1.93,3.18,1.5,1.5,0,0,1-1.22,1.49c-2.56.49-5.15.93-7.7,1.31-.48.07-1,.13-1.46.18a21.61,21.61,0,0,0-2.27.33A4.39,4.39,0,0,1,308.39,692.83Zm6.15-5.59a7.42,7.42,0,0,0-2.07.27,4.76,4.76,0,0,0-2.71,2.08c.51-.08,1-.13,1.51-.19s.91-.1,1.36-.17c1.76-.26,3.54-.56,5.32-.87a3.57,3.57,0,0,0-2.17-1A11.49,11.49,0,0,0,314.55,687.24Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M313.31,686.76a1.5,1.5,0,0,1-1.44-1.09l-.45-1.6a1.5,1.5,0,1,1,2.89-.81l.45,1.6a1.5,1.5,0,0,1-1.44,1.91Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M344,687.81a6.59,6.59,0,0,1-2.83-.68,3.93,3.93,0,0,1-1.55-1.22,4.38,4.38,0,0,1-.69-2l-1.16-7.4a1.5,1.5,0,0,1,3-.47l1.16,7.4a2.62,2.62,0,0,0,.17.69,1.14,1.14,0,0,0,.41.26,3.37,3.37,0,0,0,1.76.38,1.67,1.67,0,0,0,1.18-.61c.52-.72.26-2,0-3.21l-1.27-5.26A1.5,1.5,0,0,1,347,675l1.27,5.26c.32,1.32.91,3.77-.46,5.66a4.62,4.62,0,0,1-3.33,1.84Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M339.3,677.57a1.5,1.5,0,0,1-.5-2.91,8.62,8.62,0,0,1,2-.39l4.62-.5a1.5,1.5,0,1,1,.32,3l-4.62.5a6.21,6.21,0,0,0-1.34.24A1.49,1.49,0,0,1,339.3,677.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M345.44,695.71a1.5,1.5,0,0,1-1.46-1.17c-.56-2.51-1-5.08-1.31-7.64a1.5,1.5,0,1,1,3-.36c.3,2.46.73,4.93,1.26,7.35a1.5,1.5,0,0,1-1.47,1.83Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M342.65,697a1.5,1.5,0,0,1-.53-2.9,9.58,9.58,0,0,1,2.54-.48l.74-.08a9.78,9.78,0,0,0,2.15-.53,1.5,1.5,0,0,1,1,2.81,12.85,12.85,0,0,1-2.81.69l-.84.09a7.08,7.08,0,0,0-1.77.31A1.5,1.5,0,0,1,342.65,697Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M698.06,387.11a3.52,3.52,0,0,1-1.07-.17c-19.51-6.22-39-13.58-57.77-20.69-27.37-10.35-55.66-21.06-84.39-28.32a3.53,3.53,0,1,1,1.73-6.84c29.12,7.36,57.61,18.14,85.16,28.56,18.72,7.08,38.09,14.41,57.42,20.57a3.53,3.53,0,0,1-1.07,6.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M233.85,453.13a3.53,3.53,0,0,1-.9-6.94c12.29-3.27,24.88-6.06,37.4-8.29a3.53,3.53,0,0,1,1.24,6.95c-12.33,2.19-24.72,4.94-36.82,8.16A3.55,3.55,0,0,1,233.85,453.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M557.18,676.67a1.5,1.5,0,0,1-1.35-.85,43.4,43.4,0,0,1-1.72-4.29c-1-2.89-1.94-5.39-4.29-7.6a1.5,1.5,0,1,1,2.05-2.19c2.88,2.7,4,5.79,5.06,8.78a41,41,0,0,0,1.6,4,1.5,1.5,0,0,1-1.35,2.15Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M564.18,672.33a1.5,1.5,0,0,1-1.22-.62,9.23,9.23,0,0,1-1.36-4.23,12.75,12.75,0,0,0-.42-2.11,8.8,8.8,0,0,0-1.28-2.19,8.19,8.19,0,0,1-1.89-4.25,1.5,1.5,0,0,1,3-.18,5.7,5.7,0,0,0,1.34,2.7,11.35,11.35,0,0,1,1.68,3,15.14,15.14,0,0,1,.54,2.62,6.87,6.87,0,0,0,.83,2.91,1.5,1.5,0,0,1-1.22,2.38Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M411.84,735.33a1.5,1.5,0,0,1-.95-2.66c4.89-4,15-6.91,21.52-7.33a1.5,1.5,0,1,1,.19,3c-6.1.39-15.52,3.16-19.81,6.67A1.49,1.49,0,0,1,411.84,735.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M425.84,743a1.5,1.5,0,0,1-.73-2.81c.79-.43,1.54-.93,2.35-1.46a21.68,21.68,0,0,1,4.89-2.64,1.5,1.5,0,0,1,1,2.84,19.12,19.12,0,0,0-4.21,2.31c-.81.54-1.66,1.09-2.55,1.58A1.49,1.49,0,0,1,425.84,743Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,698.67h-.07a1.5,1.5,0,0,1-1.43-1.57c.16-3.24,3.28-9.69,5.4-12a1.5,1.5,0,1,1,2.19,2.05c-1.71,1.82-4.47,7.53-4.6,10A1.5,1.5,0,0,1,492.18,698.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,708.33a1.5,1.5,0,0,1-1.37-2.12,14.94,14.94,0,0,0,1.2-4.79,1.5,1.5,0,0,1,3,.14,17.83,17.83,0,0,1-1.46,5.88A1.5,1.5,0,0,1,492.18,708.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M488.84,783.33a1.5,1.5,0,0,1-.57-.11c-.86-.35-1.75-.69-2.57-1a1.5,1.5,0,1,1,1-2.84c.89.3,1.84.66,2.76,1a1.5,1.5,0,0,1-.57,2.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,776.67H492a9.22,9.22,0,0,1-3.59-1.2,1.5,1.5,0,1,1,1.51-2.59,6.19,6.19,0,0,0,2.41.8,1.5,1.5,0,0,1-.17,3Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M498.45,782.38a6.56,6.56,0,0,1-2.51-.49,1.5,1.5,0,0,1,1.14-2.78,3.67,3.67,0,0,0,1.9.23,1.5,1.5,0,1,1,.39,3A7.09,7.09,0,0,1,498.45,782.38Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M631.18,690.67a1.5,1.5,0,0,1-1.5-1.5v-3a1.5,1.5,0,0,1,3,0v3A1.5,1.5,0,0,1,631.18,690.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M632.51,700.67h-.21A1.5,1.5,0,0,1,631,699a2.59,2.59,0,0,0-.21-1.5,1.5,1.5,0,0,1,2.72-1.26,5.58,5.58,0,0,1,.46,3.17A1.5,1.5,0,0,1,632.51,700.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M627.18,696.33a1.5,1.5,0,0,1-1.5-1.5v-1.67a1.5,1.5,0,0,1,3,0v1.67A1.5,1.5,0,0,1,627.18,696.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M372.18,581.33a1.5,1.5,0,0,1-.72-2.82c3.81-2.08,14.85-4.39,18.79-.4a1.5,1.5,0,1,1-2.13,2.11c-2.49-2.52-11.85-.91-15.21.93A1.49,1.49,0,0,1,372.18,581.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M388.51,580.33a1.5,1.5,0,0,1-1.14-.52,24.8,24.8,0,0,0-5.8-4.47c-3.37-2.12-6.86-4.32-8.77-8.56a1.5,1.5,0,1,1,2.74-1.23c1.54,3.42,4.5,5.28,7.63,7.25a27.44,27.44,0,0,1,6.47,5.05,1.5,1.5,0,0,1-1.14,2.48Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M510.58,669.36l-1.18,0h-1.23a1.5,1.5,0,0,1,0-3h1.29a13.85,13.85,0,0,0,4-.29,1.5,1.5,0,1,1,.81,2.89A13.35,13.35,0,0,1,510.58,669.36Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M521.51,671.33h-2a1.5,1.5,0,0,1,0-3h2a1.5,1.5,0,0,1,0,3Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M549.17,628a1.5,1.5,0,0,1-1.47-1.21A30,30,0,0,0,543,616.46a1.5,1.5,0,1,1,2.31-1.92c2.25,2.71,4.66,8.39,5.32,11.67a1.5,1.5,0,0,1-1.18,1.76A1.46,1.46,0,0,1,549.17,628Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M268.51,659a1.5,1.5,0,0,1-1.5-1.5v-4.67a1.5,1.5,0,0,1,3,0v4.67A1.5,1.5,0,0,1,268.51,659Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M267.84,666.67a1.5,1.5,0,0,1-1.49-1.33,8.15,8.15,0,0,1,.41-3.67,1.5,1.5,0,0,1,2.83,1,5.18,5.18,0,0,0-.26,2.33,1.5,1.5,0,0,1-1.32,1.66Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M273.17,659.33a1.5,1.5,0,0,1-1.48-1.3,4.89,4.89,0,0,1,.48-2.88,1.5,1.5,0,1,1,2.68,1.35,1.89,1.89,0,0,0-.19,1.12,1.5,1.5,0,0,1-1.28,1.69Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M165.51,652.67a1.5,1.5,0,0,1-1.4-.95,33.38,33.38,0,0,1-2.1-13,1.5,1.5,0,0,1,3,.16,30.59,30.59,0,0,0,1.9,11.7,1.5,1.5,0,0,1-1.39,2.05Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M170.51,646.67a1.5,1.5,0,0,1-1.2-.59,17.13,17.13,0,0,1-1.55-2.73c-.19-.39-.38-.77-.57-1.13a1.5,1.5,0,0,1,2.65-1.42c.21.39.41.81.62,1.22a15.28,15.28,0,0,0,1.25,2.25,1.5,1.5,0,0,1-1.19,2.41Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M270.84,441.67h0a1.5,1.5,0,0,1-1.5-1.5,15.5,15.5,0,0,0-.58-3.65,27.65,27.65,0,0,1-.57-2.81,30,30,0,0,1-.21-3.51c0-.44,0-.87,0-1.29a1.5,1.5,0,0,1-1.85-.73,8.88,8.88,0,0,1-.72-2.27,3.93,3.93,0,0,1-.73.54,1.5,1.5,0,0,1-2.2-.92l-.08-.3-.06-.22c-.17.32-.34.63-.53.93a1.5,1.5,0,0,1-2.17.42,6.21,6.21,0,0,1-.52-.43,28.48,28.48,0,0,1,.58,7.39,1.5,1.5,0,1,1-3-.26,27.61,27.61,0,0,0-.63-7.12,35.76,35.76,0,0,1-.73-6.67,1.5,1.5,0,0,1,2.74-.82,18.52,18.52,0,0,1,1.35,2.49c.26.54.51,1.07.78,1.55.22-.52.42-1.09.62-1.72a1.5,1.5,0,0,1,2.46-.64,5.09,5.09,0,0,1,1.07,1.51c.07-.19.13-.37.2-.55a1.5,1.5,0,0,1,2.78,0,12.55,12.55,0,0,1,.71,2.64,1.41,1.41,0,0,1,.86-.25,1.5,1.5,0,0,1,1.4,1,19,19,0,0,1,.69,5.67,27.31,27.31,0,0,0,.18,3.17,24.77,24.77,0,0,0,.52,2.51,18,18,0,0,1,.67,4.36A1.5,1.5,0,0,1,270.84,441.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M206.51,695.33a1.5,1.5,0,0,1-1.41-1c-1.2-3.37-.75-7-.32-10.57a34.32,34.32,0,0,0,.4-6.41,2.38,2.38,0,0,1-1.44.28c-1.77-.24-2.37-2.24-3-4.35l0-.13a4.77,4.77,0,0,1-1.67,2.22,1.5,1.5,0,0,1-2.18-.57,15.46,15.46,0,0,1-1.05-3.23l-.14-.57-.12.56a21.28,21.28,0,0,1-.67,2.66,1.5,1.5,0,0,1-1.35,1,1.49,1.49,0,0,1-1.43-.89,38.93,38.93,0,0,1-2-6.27c-.21-.8-.41-1.59-.62-2.35-.15.79-.28,1.6-.42,2.43s-.23,1.4-.35,2.12-.29,1.44-.47,2.28c-.65,3-1.64,7.55-.66,9.66a1.5,1.5,0,0,1-2.72,1.26c-1.41-3-.38-7.76.45-11.56.17-.8.33-1.54.45-2.17s.24-1.38.35-2.06a31.06,31.06,0,0,1,1.81-7.32,1.5,1.5,0,0,1,2.72-.09,34.45,34.45,0,0,1,2.38,7.07l.26,1a7.69,7.69,0,0,1,1.07-2.13,1.5,1.5,0,0,1,1.13-.61,1.53,1.53,0,0,1,1.19.49,9.35,9.35,0,0,1,1.9,4.11,9.09,9.09,0,0,1,.77-1.8,1.5,1.5,0,0,1,2.42-.22,11.77,11.77,0,0,1,1.88,4.24c.17.57.4,1.33.61,1.85a8.94,8.94,0,0,0,.62-.88,1.5,1.5,0,0,1,2.69.34c1.09,3.36.65,6.94.23,10.41s-.8,6.49.17,9.19a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M455.51,328.33a1.5,1.5,0,0,1-1.5-1.43c0-.59-.09-1.18-.15-1.76a24.68,24.68,0,0,1-.18-2.65,1.5,1.5,0,0,1,3,0,21.91,21.91,0,0,0,.17,2.33c.07.64.13,1.28.17,1.93a1.5,1.5,0,0,1-1.43,1.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M455.51,339.67a1.5,1.5,0,0,1-1.5-1.5v-2a1.5,1.5,0,0,1,3,0v2A1.5,1.5,0,0,1,455.51,339.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M462.18,330.33a1.5,1.5,0,0,1-1.45-1.13c-.24-.93-.51-2.33-.69-3.47a1.5,1.5,0,1,1,3-.47c.17,1,.43,2.36.64,3.2a1.5,1.5,0,0,1-1.46,1.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M496.84,441h-.06a1.5,1.5,0,0,1-1.44-1.56v-.35a26,26,0,0,1,.71-6,1.5,1.5,0,0,1,2.88.83,23.86,23.86,0,0,0-.6,5.29v.36A1.5,1.5,0,0,1,496.84,441Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M497.18,450.33a1.5,1.5,0,0,1-1.27-2.3,1.23,1.23,0,0,0,.13-.9,1.5,1.5,0,1,1,2.94-.6,4.22,4.22,0,0,1-.53,3.1A1.5,1.5,0,0,1,497.18,450.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M636.84,488.33a1.5,1.5,0,0,1-1.31-2.22,10.57,10.57,0,0,1,2.73-3.13,1.5,1.5,0,1,1,1.83,2.38,7.6,7.6,0,0,0-1.94,2.2A1.5,1.5,0,0,1,636.84,488.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M743.18,547a1.5,1.5,0,0,1-1.28-2.28,17.16,17.16,0,0,0,1.4-3.36c.16-.46.31-.93.48-1.38a1.5,1.5,0,0,1,2.81,1c-.16.43-.3.86-.45,1.3a19.66,19.66,0,0,1-1.67,4A1.5,1.5,0,0,1,743.18,547Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M747.18,559a1.5,1.5,0,0,1-1-2.61.53.53,0,0,0,.18-.47,1.5,1.5,0,0,1,3-.18,3.52,3.52,0,0,1-1.15,2.87A1.49,1.49,0,0,1,747.18,559Z" transform="translate(-105.77 -43.5)"/></g><g id="LINEART"><path class="cls-1" d="M389.53,594.58a2.5,2.5,0,0,1-.54-.06l-.89-.19c-12.57-2.76-33.6-7.38-31.41-25.13.7-5.64,2.85-9.58,6.39-11.73,7-4.23,17.46-.3,25.87,2.86,2.22.83,4.31,1.62,6.1,2.16a2.5,2.5,0,1,1-1.46,4.78c-1.94-.59-4.1-1.4-6.4-2.26-7.4-2.78-16.62-6.24-21.52-3.26-2.2,1.33-3.51,4-4,8.06-1.51,12.21,12.77,16.39,27.52,19.63l.89.2a2.5,2.5,0,0,1-.54,4.94Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M586.6,621.13h-.12a2.5,2.5,0,0,1-2.37-2.62c.31-6.34.06-8.26-.76-14.61-.25-1.94-.6-4-1-6a2.5,2.5,0,0,1,4.9-1c.45,2.18.81,4.33,1.08,6.39a67.68,67.68,0,0,1,.8,15.5A2.5,2.5,0,0,1,586.6,621.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M384.51,562.5a2.5,2.5,0,0,1-2.11-3.83,92.9,92.9,0,0,1,26.15-27.28,106.28,106.28,0,0,1,34-15.26c4.37-1.1,8.81-2.41,13.1-3.68,8.43-2.49,17.14-5.07,26.13-6.25,1.59-.21,3.17-.44,4.75-.66,6.18-.88,12.57-1.8,19-1.59,8.11.27,13.78,2.23,20.9,5a72,72,0,0,1,29.78,21.5,2.5,2.5,0,0,1-3.83,3.22,67.07,67.07,0,0,0-27.75-20.05c-6.87-2.65-11.92-4.4-19.27-4.65-6-.2-11.92.65-18.16,1.54-1.6.23-3.2.46-4.8.67-8.59,1.13-17.12,3.65-25.36,6.09-4.34,1.28-8.82,2.61-13.3,3.73a101.32,101.32,0,0,0-32.41,14.54,87.87,87.87,0,0,0-24.72,25.8A2.5,2.5,0,0,1,384.51,562.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M378.15,676a2.5,2.5,0,0,1-2.48-2.17c-3.25-24.48-5.7-53.7.79-84.83a2.5,2.5,0,0,1,4.89,1c-6.33,30.4-3.92,59.1-.73,83.16a2.5,2.5,0,0,1-2.15,2.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.25,702.13a2.5,2.5,0,0,1-1.5-4.5A210.35,210.35,0,0,1,546.49,679a136.83,136.83,0,0,1,39.61-13.51c3.2-.56,6.43-.83,9.57-1.09a92.3,92.3,0,0,0,9.49-1.1,104.21,104.21,0,0,1,15.61-1.72l-.75-.81c-3.51-3.81-7.88-8.55-11.65-8.77a2.5,2.5,0,0,1,.29-5c5.79.33,10.71,5.66,15,10.37a49.59,49.59,0,0,0,4.7,4.71,2.5,2.5,0,0,1-1.56,4.45h-.06a98.51,98.51,0,0,0-20.7,1.67,97,97,0,0,1-10,1.17c-3,.25-6.14.5-9.1,1a131.83,131.83,0,0,0-38.16,13,205.28,205.28,0,0,0-28.06,18.21A2.49,2.49,0,0,1,519.25,702.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M445.87,782.45a2.5,2.5,0,0,1-1.79-.76c-2.5-2.57-6-4.44-9.79-6.42a61.91,61.91,0,0,1-8-4.77c-1.3-1-2.69-1.91-4.17-2.91a59.53,59.53,0,0,1-9.12-7.07,16.94,16.94,0,0,1-3.32-5.47,13.19,13.19,0,0,0-2-3.59,10.17,10.17,0,0,0-1.83-1.43,10.61,10.61,0,0,1-4.93-6.24,12.12,12.12,0,0,0-.93-2,61.62,61.62,0,0,1-3-5.52c-.79-1.56-1.53-3-2.4-4.48-.58-1-1.24-1.9-1.93-2.89-.57-.81-1.16-1.65-1.71-2.52-1.32-2.08-2.37-4.14-3.38-6.14-.52-1-1-2.06-1.61-3.1C381,708,379.4,699.4,378,689.9a2.5,2.5,0,1,1,4.95-.74c1.35,9,2.83,17.18,7.38,25.56.59,1.08,1.13,2.16,1.67,3.22,1,2,1.95,3.84,3.14,5.71.49.78,1,1.53,1.59,2.33.71,1,1.45,2.07,2.13,3.19,1,1.61,1.79,3.24,2.58,4.81a57.23,57.23,0,0,0,2.78,5.08,16.18,16.18,0,0,1,1.37,2.9,5.94,5.94,0,0,0,3.08,3.91,14.23,14.23,0,0,1,2.74,2.23,17.39,17.39,0,0,1,2.87,4.94,12.66,12.66,0,0,0,2.3,4,55.94,55.94,0,0,0,8.36,6.44c1.46,1,3,2,4.35,3a57.43,57.43,0,0,0,7.38,4.36,57,57,0,0,1,8.81,5.36c3-4.17,6.22-8.18,9.37-12.08a177.59,177.59,0,0,0,12.68-17c7.6-12.15,18.9-24.48,32.7-35.65a2.5,2.5,0,0,1,3.15,3.88C490,726.16,479,738.06,471.72,749.75a181.62,181.62,0,0,1-13,17.53c-3.67,4.54-7.46,9.23-10.75,14.08a2.5,2.5,0,0,1-1.85,1.09Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M518.09,796a170.73,170.73,0,0,1-28.22-2.37c-5.62.34-10.17-1.06-15-2.54-1.41-.43-2.87-.88-4.37-1.29a104,104,0,0,1-23.77-9.44,2.5,2.5,0,1,1,2.44-4.37,99,99,0,0,0,22.64,9c1.59.43,3.09.89,4.54,1.34,4.63,1.43,8.63,2.66,13.46,2.31a2.51,2.51,0,0,1,.6,0,162.56,162.56,0,0,0,38.24,2c12.47-.88,24.46-5.86,34.53-10.61a2.5,2.5,0,0,1,2.13,4.52c-10.49,5-23,10.14-36.31,11.08C525.44,795.85,521.79,796,518.09,796Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M579.89,776.93a2.5,2.5,0,0,1-1.2-4.7,168.65,168.65,0,0,0,16.36-10.06c3.14-2.2,6.54-4.29,9.82-6.3,7.82-4.8,15.91-9.76,21.57-16.9,18.62-23.46,11.39-59.13-7-77.71-1.25-1.26-2.29-2.46-3.21-3.52-2.36-2.71-4.06-4.66-7.51-5.89a2.5,2.5,0,0,1,1.68-4.71c4.69,1.67,7.08,4.41,9.61,7.32.92,1.05,1.86,2.14,3,3.28,10.43,10.51,17.37,25.4,19,40.85,1.78,16.35-2.36,31.79-11.64,43.49-6.22,7.83-14.68,13-22.87,18.05-3.37,2.07-6.55,4-9.56,6.13a173.37,173.37,0,0,1-16.84,10.35A2.49,2.49,0,0,1,579.89,776.93Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.17,513.92l-.39,0a2.5,2.5,0,0,1-2.09-2.85c1.1-7.09,5.21-16,13.17-17.81,7.2-1.64,14,4.06,16.22,13.56a2.5,2.5,0,0,1-4.87,1.12c-1.32-5.73-5.27-10.94-10.24-9.81-5.13,1.16-8.43,7.92-9.33,13.7A2.5,2.5,0,0,1,467.17,513.92Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M537.44,607.22h-.74c-4-.16-6.74-1.62-7.5-4s.57-5,4-7.56c2.92-2.24,11.31-4.41,15.13-1.5,1,.74,3,2.91,1.3,7.16S542.27,607.22,537.44,607.22Zm-3.33-5.55a10.86,10.86,0,0,0,6,.29c2.43-.46,4.36-1.49,4.79-2.56h0a2.43,2.43,0,0,0,.29-1.33c-1-1-7.07,0-9,1.52A8.16,8.16,0,0,0,534.12,601.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M461.94,640.88c-1.43,0-2.8,0-4.09-.05-14.46-.36-26.11-9.2-32.81-24.88a71.6,71.6,0,0,1-3.63-12.73,55.67,55.67,0,0,1-1.47-13c.18-9.12,3.38-16.86,10.38-25.08,4.1-4.82,12-9.22,18.08-11.46,20.17-7.44,48.23-1.52,57.84,19.15A94.12,94.12,0,0,1,511,586.68c3.92,13.69,2.82,25.54-3.26,35.23-4.81,7.67-14,13.74-25.16,16.67A82.12,82.12,0,0,1,461.94,640.88ZM466,555.62a46.28,46.28,0,0,0-15.89,2.71c-5.42,2-12.66,6.08-16,10-6.2,7.28-9,14-9.18,21.94h0a50.76,50.76,0,0,0,1.36,11.86A67.88,67.88,0,0,0,429.64,614c3.41,8,11.62,21.43,28.33,21.85,6.55.16,15.12.07,23.35-2.08,9.81-2.57,18.1-8,22.19-14.49,5.3-8.44,6.2-18.94,2.69-31.2a90.18,90.18,0,0,0-4.51-13.16C495.66,561.92,480.59,555.62,466,555.62Zm-43.57,34.61h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.07,655.25a61.92,61.92,0,0,1-23.16-4.39,51.53,51.53,0,0,1-28.79-28c-2.13-5-3.34-10.51-4.51-15.82a69.67,69.67,0,0,1-1.84-16.21h0c.2-11.39,4.16-21,12.81-31.27,5.09-6,14.91-11.5,22.39-14.27,19.5-7.21,44.36-3.48,60.45,9.07,12.67,9.89,16,25.19,18.73,37.49,6.14,28-10.29,53.73-39.07,61.25A67.41,67.41,0,0,1,467.07,655.25Zm-2-106.55a54.06,54.06,0,0,0-18.65,3.16c-6.6,2.45-15.41,7.42-19.45,12.21-7.54,8.91-11,17.19-11.15,26.84h0a62.8,62.8,0,0,0,1.68,14.57c1.1,5,2.23,10.16,4.11,14.57,10.56,24.83,38.53,32,60.69,26.17,25.38-6.63,39.34-28.39,34-52.91-3.12-14.23-6.3-25.72-16.18-33.44C490.8,552.63,477.77,548.7,465.08,548.7ZM412.3,590.85h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M578.15,615.43c-5.87,0-12-1.19-17.83-6.13-8-6.76-13.43-15.13-18.08-28a126.1,126.1,0,0,1-4.16-15.7,97.31,97.31,0,0,1-2.3-15.87A51.14,51.14,0,0,1,543,519.87c3.39-5.84,10.34-10.84,15.73-13.2,14.07-6.15,32.68-.86,45.25,12.87,9.54,10.41,12.86,25.54,15.52,37.7,3.71,16.92,2.33,31.23-4.12,42.55-7.37,12.93-19.3,14.13-28.88,15.1A82.79,82.79,0,0,1,578.15,615.43Zm-7-104.21a24,24,0,0,0-9.66,1.92c-4.33,1.9-10,6-12.45,10.27a44.47,44.47,0,0,0-6.25,26h0A90.27,90.27,0,0,0,545,564.08a121,121,0,0,0,3.9,14.81c4.26,11.78,8.89,19,16,25,6.42,5.41,13.41,4.71,20.81,4,10.88-1.09,18.35-2.49,23.53-11.58,5.56-9.75,6.69-22.39,3.36-37.54-3.16-14.41-6.19-26.09-13.84-34.44S580.64,511.22,571.19,511.22Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M583.65,599.89c-12.91,0-24.11-8.93-30.41-24.49-6.2-15.29-11.87-34.24-.67-45.15h0c.33-.32.68-.64,1-.95,9.59-8.13,26.29-5.09,35.28,2.74,12.16,10.58,16.24,24.2,18.63,36.13a28.15,28.15,0,0,1-4.45,22,23,23,0,0,1-16,9.47A28.62,28.62,0,0,1,583.65,599.89ZM556,533.84c-9.16,8.93-3.35,26.93,1.82,39.69,2.86,7.05,11.35,23.23,28.56,21.2A18,18,0,0,0,599,587.28a23.14,23.14,0,0,0,3.59-18.12c-3.15-15.74-8.23-25.71-17-33.34-7.45-6.48-21.33-9-28.78-2.69-.28.24-.54.47-.79.72Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M502.34,715.06a12.41,12.41,0,0,1-1.45-.08,2.5,2.5,0,1,1,.59-5c3.81.45,12.26-2.27,14.54-5.22,1.69-2.17.74-5.17.25-6.36a12.76,12.76,0,0,0-10.33-7.21l-2.56-.05a2.5,2.5,0,0,1,0-5h0l2.66.06a17.75,17.75,0,0,1,14.8,10.31c1.72,4.21,1.38,8.33-.93,11.31C516.83,711.92,508,715.06,502.34,715.06Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M567.78,785.4a11.33,11.33,0,0,1-5.54-1.29,6.36,6.36,0,0,1-2.08-1.92h0c-1.34-2-1.28-4.29-1.24-6.16a54.15,54.15,0,0,1,.73-7.32,57.41,57.41,0,0,1,3.61-13.28c1.85-4.36,7.79-13.46,14.3-13.77,2.15-.11,5.22.7,7.6,5.1a20.48,20.48,0,0,1,2.14,10c0,8.79-3.16,17.45-8.36,23.17-3,3.28-6.47,5.15-10.1,5.42C568.57,785.38,568.21,785.4,567.78,785.4Zm10.15-38.76h-.14c-3.3.16-8.17,6.56-9.94,10.73a52.57,52.57,0,0,0-3.27,12.13,49.13,49.13,0,0,0-.66,6.58c0,1.34-.07,2.65.36,3.28h0a1.35,1.35,0,0,0,.47.41,7.22,7.22,0,0,0,3.72.59c2.94-.22,5.3-2.18,6.77-3.79,4.32-4.76,7-12.36,7.06-19.83a15.72,15.72,0,0,0-1.53-7.62C579.51,746.83,578.42,746.65,577.93,746.65Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M638.39,738.56a8.38,8.38,0,0,1-2.86-.48,7.6,7.6,0,0,1-4.72-5.53,2.5,2.5,0,1,1,4.82-1.34c.49,1.77,1.3,2.06,1.6,2.17,3.61,1.3,12-4.53,14.77-6.45l.64-.44c4.49-3.09,7.55-11.34,8.59-18.14.57-3.7.06-8.38-2-10.17-.35-.3-1.41-1.21-4-.4-5.1,1.57-10.45,7.24-12.17,12.9a2.5,2.5,0,1,1-4.78-1.46C640.4,702,647.05,695,653.69,693c4.37-1.34,7.19,0,8.78,1.39,3.87,3.34,4.41,10,3.69,14.71-.4,2.64-2.81,16.08-10.69,21.5l-.63.43C649.12,735,643.25,738.56,638.39,738.56Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M447.81,618.41c-8.8,0-17.45-1.38-23.25-7.2a2.5,2.5,0,0,1,3.54-3.53c6.33,6.33,18,6.1,28.43,5.37,16.86-1.17,34.34-8.73,52-22.5a2.5,2.5,0,0,1,3.08,3.94c-18.43,14.39-36.84,22.31-54.71,23.54C453.9,618.24,450.84,618.41,447.81,618.41Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M566.29,578.89a30.83,30.83,0,0,1-11.69-2.11,2.5,2.5,0,0,1,1.9-4.62c13.85,5.69,37.34-3,43.33-16.07a2.5,2.5,0,0,1,4.54,2.09C598.86,570.2,581.39,578.89,566.29,578.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M556.63,603.14a2.49,2.49,0,0,1-1.14-.28,30.21,30.21,0,0,0-8.12-2.49,2.5,2.5,0,0,1,.78-4.94,34.78,34.78,0,0,1,9.62,3,2.5,2.5,0,0,1-1.14,4.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M529.43,626.73a8,8,0,0,1-6-2.45c-2.56-2.71-2.92-7-1-12,2.31-6.09,4.85-10,7.76-12A2.5,2.5,0,1,1,533,604.5c-2,1.35-4,4.58-5.88,9.6-.55,1.45-1.66,5,0,6.75s5,.78,7.32-.94c1-.71,1.89-1.55,2.86-2.43a17.66,17.66,0,0,1,14-6c1.06-.05,2.07-.1,3-.23,2.09-.27,4.7-1.25,5.3-3.11,0-.29,0-.8.06-1.22s0-.87.05-1a2.5,2.5,0,1,1,5,.57c0,.05,0,.3,0,.6a10.56,10.56,0,0,1-.18,2.17c-1.16,4.34-5.68,6.42-9.53,6.92-1.17.15-2.32.21-3.43.27a13,13,0,0,0-10.91,4.69c-1,.92-2.08,1.88-3.24,2.74A13.82,13.82,0,0,1,529.43,626.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.85,593.87a3.53,3.53,0,0,1-2.47-6,44.74,44.74,0,0,1,26.81-12.52,3.53,3.53,0,0,1,.7,7,37.66,37.66,0,0,0-22.57,10.54A3.52,3.52,0,0,1,519.85,593.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M491.51,718.37a2.5,2.5,0,0,1-1.68-.65,6.89,6.89,0,0,1-.56-.57,3.4,3.4,0,0,1-2,.17c-3.42-.68-4.15-5.85-4.29-7.42-.39-4.33,1.18-20.68,7.72-27h0a8.46,8.46,0,0,1,7.46-2.49,2.5,2.5,0,0,1,1.95,1.64,4.71,4.71,0,0,1,1.85,0,2.5,2.5,0,0,1,1.12.58,4.43,4.43,0,0,1,3.88,1.52c1.49,2.13.1,4.4-.56,5.5a5.42,5.42,0,0,0-.3.51,66.63,66.63,0,0,0-2.4,9.82l0,.23c-1.5,7.72-1.78,11.54-1.71,12.87a2.5,2.5,0,0,1-1.77,4.15c-1.32.06-2.6.05-3.84,0-1,0-1.92,0-2.87,0a2.5,2.5,0,0,1-1.74,1Zm-2.59-5.64h0Zm1-2.27a2.43,2.43,0,0,1,.38,0,2.5,2.5,0,0,1,2.06,1.9c1.4-.07,2.75-.06,4-.05H497a81.17,81.17,0,0,1,1.79-13l0-.22a71.26,71.26,0,0,1,2.62-10.6,5,5,0,0,1,.23-.54,2.51,2.51,0,0,1-1.52-.41l0,0c-.31.25-.62.48-.92.67a2.5,2.5,0,0,1-3.83-2.3c0-.09,0-.19,0-.29a4.89,4.89,0,0,0-1.19.87h0c-4.59,4.42-6.62,18.44-6.21,22.93a10.75,10.75,0,0,0,.28,1.64A2.5,2.5,0,0,1,489.94,710.45ZM500,712.29h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M374,676.5a2.5,2.5,0,0,1-.3-5c52.83-6.38,114.94-14,175.09-21.86a2.5,2.5,0,1,1,.65,5c-60.17,7.9-122.3,15.49-175.14,21.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M550.07,654.18a2.5,2.5,0,0,1-1.68-4.35c4.28-3.89,9.64-7.94,14.83-11.86,9.22-7,18.75-14.15,22.48-20.59a2.5,2.5,0,1,1,4.33,2.51c-4.24,7.32-14.18,14.82-23.79,22.08-5.1,3.85-10.37,7.83-14.48,11.57A2.49,2.49,0,0,1,550.07,654.18Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M378.4,692q-2,0-3.93,0a2.5,2.5,0,0,1-2.42-2.2,88.85,88.85,0,0,1-.51-15.92,2.5,2.5,0,1,1,5,.29,83.89,83.89,0,0,0,.24,12.87c12.87.14,25.88-1.39,38.49-2.87,16.89-2,38.15-4.31,58.71-6.56s41.89-4.58,58.8-6.57a2.5,2.5,0,1,1,.58,5c-16.93,2-38.23,4.32-58.83,6.57s-41.8,4.58-58.67,6.55C403.63,690.55,391,692,378.4,692Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,676a2.5,2.5,0,0,1-2.5-2.5V517.87l-33.42,6.51a2.5,2.5,0,1,1-1-4.91l36.4-7.09a2.5,2.5,0,0,1,3,2.45V673.51A2.5,2.5,0,0,1,637.74,676Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,645.49a2.5,2.5,0,0,1-.48-5l121.42-24V378.4L641.23,396a2.51,2.51,0,0,1-1.25-.13l-140.5-52.67a2.5,2.5,0,0,1,.53-4.82l101-14.1a2.52,2.52,0,0,1,1.08.08l159.83,48.76h0a2.49,2.49,0,0,1,1.42,1.16h0l0,0h0a2.49,2.49,0,0,1,.26,1.17V618.63a2.5,2.5,0,0,1-2,2.45L638.22,645.45A2.52,2.52,0,0,1,637.74,645.49ZM510.46,341.95l130.67,49,108.74-16.27L601.14,329.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M640.86,433a2.5,2.5,0,0,1-2.5-2.5v-37a2.5,2.5,0,0,1,5,0v37A2.5,2.5,0,0,1,640.86,433Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M500.36,393.33a2.5,2.5,0,0,1-2.5-2.5V344a2.5,2.5,0,0,1,5,0v46.83A2.5,2.5,0,0,1,500.36,393.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,517.35a2.51,2.51,0,0,1-2.41-3.21c.7-2.41,15.84-32.87,22.19-45.59l-113,13.94-16.81,30a2.5,2.5,0,1,1-4.36-2.44l17.42-31.1a2.5,2.5,0,0,1,1.88-1.26L661.54,463a2.5,2.5,0,0,1,2.54,3.6c-9.21,18.41-23.18,46.64-23.95,48.94A2.48,2.48,0,0,1,637.74,517.35Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.63,512.6a2.49,2.49,0,0,1-.93-.18L398.53,485.2a2.5,2.5,0,0,1-1.13-.9L357,425.58a2.5,2.5,0,0,1,3.05-3.71l120.36,52a2.49,2.49,0,0,1,1.07.87l19.66,28.47a2.5,2.5,0,1,1-4.11,2.84l-19.26-27.88L366,429.91l35.05,50.93,67.48,26.95a2.5,2.5,0,0,1-.93,4.82Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M396.21,500.85a2.5,2.5,0,0,1-2.5-2.5V480.93a2.5,2.5,0,0,1,5,0v17.42A2.5,2.5,0,0,1,396.21,500.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M287.51,543a2.47,2.47,0,0,1-.38,0,2.5,2.5,0,0,1-2.11-2.19l-8.71-77L151.94,480.69V522.5a2.5,2.5,0,0,1-5,0v-44a2.5,2.5,0,0,1,2.16-2.48l129.07-17.5a2.5,2.5,0,0,1,2.82,2.2l8,70.3,29.27-66.52a2.5,2.5,0,0,1,3.34-1.26l106.5,49.33a2.5,2.5,0,0,1,1.32,3.06l-3.65,10.88a2.5,2.5,0,1,1-4.74-1.59l2.94-8.76L321.77,468.84l-32,72.67A2.5,2.5,0,0,1,287.51,543Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M256.51,614.13a2.5,2.5,0,0,1-2.47-2.87l10-66.48a2.5,2.5,0,0,1,2.15-2.11L404.9,524.54a2.5,2.5,0,0,1,2.82,2.48v9.9a2.5,2.5,0,0,1-5,0v-7.06l-134,17.53-9.22,61.32,118-16a2.5,2.5,0,0,1,.67,5L256.84,614.11Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M256.51,614.13a2.5,2.5,0,0,1-1.15-.28l-99-51.63a2.5,2.5,0,0,1-1.2-1.37l-13.5-37.5A2.5,2.5,0,0,1,145,520.2l79.5,33.5a2.5,2.5,0,0,1,1.18,1l33,55.63a2.5,2.5,0,0,1-2.15,3.78Zm-97-55.89,90.35,47.12L221.78,558l-73.49-31Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M207.35,551.69a2.5,2.5,0,0,1-.17-5l59.16-4a2.5,2.5,0,0,1,.34,5l-59.16,4Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M252.51,728.5a2.5,2.5,0,0,1-1.38-.42l-97-64.28a2.5,2.5,0,0,1-1.12-2.13L155,560a2.5,2.5,0,0,1,2.5-2.45h.05A2.5,2.5,0,0,1,160,560L158,660.4l95,63,130.14-20.83a2.5,2.5,0,1,1,.79,4.94l-131.1,21A2.56,2.56,0,0,1,252.51,728.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M252.51,728.5h-.09a2.5,2.5,0,0,1-2.41-2.58l4-114.37a2.5,2.5,0,0,1,5,.17l-4,114.37A2.5,2.5,0,0,1,252.51,728.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M454.71,468a2.5,2.5,0,0,1-.2-5l52.56-4.31-1.75-65.17L383.58,403l5.43,32.6a2.5,2.5,0,0,1-4.93.82l-5.88-35.29a2.5,2.5,0,0,1,2.27-2.9l127.09-9.92a2.5,2.5,0,0,1,2.69,2.43l1.88,70.17a2.5,2.5,0,0,1-2.29,2.56L454.92,468Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M560.41,480.52a2.49,2.49,0,0,1-.79-.13l-50.78-17a2.5,2.5,0,0,1,1.59-4.74l50.78,17a2.5,2.5,0,0,1-.79,4.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M645.36,469.64a2.5,2.5,0,0,1-2.17-3.73l15-26.56L538,396.62l-26.32,57.8a2.5,2.5,0,0,1-4.55-2.07l27.28-59.88a2.5,2.5,0,0,1,3.11-1.32l125.14,44.48a2.5,2.5,0,0,1,1.34,3.59l-16.48,29.15A2.5,2.5,0,0,1,645.36,469.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M279,468a2.5,2.5,0,0,1-.28-5l95.89-11a2.5,2.5,0,1,1,.57,5L279.3,468Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M200.26,474.11a2.5,2.5,0,0,1-2.5-2.5v-38a2.5,2.5,0,0,1,5,0v38A2.5,2.5,0,0,1,200.26,474.11Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M259,466.15a2.49,2.49,0,0,1-1.14-.27l-58.72-30.05a2.5,2.5,0,0,1,.82-4.71l42.58-5.43a2.53,2.53,0,0,1,1.33.2l44.76,19.9L369,436.54a2.5,2.5,0,1,1,.57,5l-81,9.31a2.5,2.5,0,0,1-1.3-.2l-44.74-19.89-33.87,4.32,51.52,26.37a2.5,2.5,0,0,1-1.14,4.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M288.23,450.84a2.5,2.5,0,0,1-2.5-2.43l-3.4-116.85-35.44-6.85L245.34,428.2a2.5,2.5,0,0,1-2.5,2.46h0a2.5,2.5,0,0,1-2.46-2.54l1.59-106.47a2.5,2.5,0,0,1,3-2.42L285.24,327a2.5,2.5,0,0,1,2,2.38l3.46,118.85a2.5,2.5,0,0,1-2.43,2.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M408.1,401.12a2.5,2.5,0,0,1-2.5-2.5V320c-12.94.83-77.13,7.39-120.57,12a2.5,2.5,0,0,1-2.61-3.33l14.87-41.24a2.5,2.5,0,0,1,2.17-1.65L418.63,277a2.5,2.5,0,0,1,2.59,3.17L410.6,317.82v80.8A2.5,2.5,0,0,1,408.1,401.12ZM301.44,290.62l-13,36c9.27-1,33.4-3.49,57.35-5.92,17.84-1.81,32.09-3.21,42.37-4.18s15.31-1.42,18-1.52l9.23-32.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M357.46,286.49a2.5,2.5,0,0,1-2.35-3.34l11.34-31.79a2.5,2.5,0,0,1,3-1.56l47.09,13.64a2.5,2.5,0,0,1,1.72,3.06l-3.88,14.14a2.5,2.5,0,1,1-4.82-1.32l3.23-11.76-42.46-12.3-10.55,29.58A2.5,2.5,0,0,1,357.46,286.49Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M351.79,286.91a2.5,2.5,0,0,1-2.23-1.37L341,268.81l-94.43,9a2.5,2.5,0,1,1-.47-5l96.12-9.12a2.49,2.49,0,0,1,2.46,1.35L354,283.27a2.5,2.5,0,0,1-2.23,3.63Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M284.76,332a2.5,2.5,0,0,1-2.47-2.12l-6.65-43.51-36.22-10.81,7.47,45.74a2.5,2.5,0,0,1-4.93.81l-8.12-49.69a2.5,2.5,0,0,1,3.18-2.8L278.59,282a2.5,2.5,0,0,1,1.76,2l6.89,45.08a2.5,2.5,0,0,1-2.09,2.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M601.34,329.24h-.08a2.5,2.5,0,0,1-2.42-2.58l4.57-142.37-163.65,17.2a2.5,2.5,0,0,1-.52-5L605.75,179a2.5,2.5,0,0,1,2.76,2.57l-4.67,145.24A2.5,2.5,0,0,1,601.34,329.24Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M436.5,398.9h0a2.5,2.5,0,0,1-2.46-2.54l3-195.5-120-35.51V268.83a2.5,2.5,0,0,1-5,0V162a2.5,2.5,0,0,1,3.21-2.4l125.06,37A2.5,2.5,0,0,1,442,199l-3,197.4A2.5,2.5,0,0,1,436.5,398.9Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M439.51,201.5a2.5,2.5,0,0,1-2.08-3.88l41-62a2.5,2.5,0,0,1,1.86-1.11L642.79,120a2.5,2.5,0,0,1,2.34,3.82l-37,59a2.5,2.5,0,0,1-4.24-2.66l34.33-54.73L481.93,139.38l-40.34,61A2.5,2.5,0,0,1,439.51,201.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M403.51,157.5a2.5,2.5,0,0,1-.17-5l66.33-4.57,21.4-97.47a2.5,2.5,0,0,1,3.05-1.89l134.5,34a2.5,2.5,0,0,1,1.76,3.2l-13,40a2.5,2.5,0,1,1-4.75-1.55L624.8,86.77,495.4,54.06l-21.25,96.78a2.5,2.5,0,0,1-2.27,2l-68.2,4.7Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M436.62,200.64a2.5,2.5,0,0,1-1.94-.92l-54.58-67L267.65,104.37l48.68,56a2.5,2.5,0,1,1-3.77,3.28l-53.91-62a2.5,2.5,0,0,1,2.5-4.06l121,30.5a2.51,2.51,0,0,1,1.33.85l55.11,67.64a2.5,2.5,0,0,1-1.94,4.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M468.33,151.57a2.5,2.5,0,0,1-2.14-1.2L425.66,83.6,280.58,93.76l3.26,8.33a2.5,2.5,0,1,1-4.66,1.82l-4.5-11.5A2.5,2.5,0,0,1,276.83,89l150-10.5a2.51,2.51,0,0,1,2.31,1.2l41.32,68.07a2.5,2.5,0,0,1-2.13,3.8Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M522.51,687.33a2.5,2.5,0,0,1-2-4,77.06,77.06,0,0,1,20-18.5c2.69-1.64,26.72-16.06,40.51-16.42h.07a2.5,2.5,0,0,1,.07,5c-10.15.27-28.69,10-38,15.69a71.62,71.62,0,0,0-18.59,17.2A2.5,2.5,0,0,1,522.51,687.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M540.51,669.67a2.5,2.5,0,0,1-2-4,33.69,33.69,0,0,0,2.67-5.27c1.9-4.25,3.69-8.26,6.47-9.77A2.5,2.5,0,0,1,550,655c-1.29.7-3.09,4.74-4.29,7.41a35.3,35.3,0,0,1-3.23,6.22A2.5,2.5,0,0,1,540.51,669.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M558.51,659.67a2.49,2.49,0,0,1-1.23-.33c-.71-.4-1.68-.83-2.71-1.29-2.24-1-4.78-2.11-6.47-3.76a2.5,2.5,0,1,1,3.49-3.58,19.25,19.25,0,0,0,5,2.77c1.14.5,2.22,1,3.15,1.51a2.5,2.5,0,0,1-1.23,4.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M484.51,715c-.87,0-1.8,0-2.85-.08-5.32-.27-26.21-3.31-31.25-13.33-1.28-2.54-2.08-6.67,1.4-11.88,6-8.94,19.6-7.5,30.55-6.35,3.06.32,5.94.63,8.15.63a2.5,2.5,0,0,1,0,5c-2.47,0-5.48-.32-8.67-.65-9.62-1-21.58-2.28-25.87,4.15-1.74,2.61-2.1,4.85-1.09,6.85,3.33,6.61,19.51,10.2,27,10.58,1,0,1.82.07,2.6.07a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M593,628a2.5,2.5,0,0,1-2.32-1.57,19.54,19.54,0,0,0-4-5.67,2.5,2.5,0,0,1,3.54-3.53,24.33,24.33,0,0,1,5,7.33A2.5,2.5,0,0,1,593,628Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M572.5,655a2.61,2.61,0,0,1-.7-.1,2.54,2.54,0,0,1-1.71-3.13c.92-3.26,15-19.9,15.16-20.06a25.2,25.2,0,0,0,2.06-3,22,22,0,0,1,3.52-4.63,2.5,2.5,0,0,1,3.38,3.69,18.24,18.24,0,0,0-2.66,3.61A29.11,29.11,0,0,1,589,635c-3.08,3.56-13.32,16.19-14.16,18.23A2.44,2.44,0,0,1,572.5,655Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M614.19,654a2.49,2.49,0,0,1-.67-.09c-3.05-.85-4.95-3.27-6.78-5.6-1.67-2.13-3.25-4.14-5.5-4.68a32.78,32.78,0,0,0-4.7.14c-6.27.42-10.21.53-12.15-1.51a3.61,3.61,0,0,1-1-3,2.49,2.49,0,0,1,.64-1.4,2.39,2.39,0,0,1,.14-.65c1.66-4.44,6-7.31,12-7.88h0a23.37,23.37,0,0,1,9.1.94,18.94,18.94,0,0,1,11.2,10.37,14.19,14.19,0,0,1,0,11.89A2.5,2.5,0,0,1,614.19,654Zm-13.86-15.42a9.08,9.08,0,0,1,2.07.19c3.95.94,6.25,3.87,8.27,6.46a29.17,29.17,0,0,0,2,2.43,10.16,10.16,0,0,0-.84-5,14,14,0,0,0-8.15-7.58,18.26,18.26,0,0,0-7.08-.72h0a11,11,0,0,0-6.19,2.33,2.58,2.58,0,0,1,.36.61,2.45,2.45,0,0,1,.05,1.71h0c1.82,0,4-.14,5.32-.23C597.94,638.62,599.27,638.54,600.33,638.54Zm-3.91-6.71h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M590.08,663.44a11.54,11.54,0,0,1-8.33-3.41,8.64,8.64,0,0,1-2.31-6.88c.26-4.44,2.92-9.72,6.2-12.28a2.5,2.5,0,0,1,3.08,3.94,13.56,13.56,0,0,0-4.29,8.63,4,4,0,0,0,.84,3c4.68,4.63,11.85,0,14.71-2.27,1.12-.87,2.2-1.82,3.34-2.84a53.86,53.86,0,0,1,4.76-3.91,2.5,2.5,0,1,1,2.87,4.1,49.44,49.44,0,0,0-4.31,3.56c-1.15,1-2.34,2.08-3.59,3C598.52,661.66,594.05,663.44,590.08,663.44Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M608.54,636a2.49,2.49,0,0,1-1.28-.35c-3.93-2.35-12.45-5.87-15.18-5.62a2.5,2.5,0,0,1-.48-5c5-.49,15.66,4.78,18.23,6.31a2.5,2.5,0,0,1-1.29,4.65Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M545.57,631.36h-.23c-3.13-.2-4.86-3.22-6.24-5.64a11.71,11.71,0,0,0-1.85-2.72,2.5,2.5,0,0,1,2.52-4.32c1.6.94,2.65,2.77,3.67,4.55a13.1,13.1,0,0,0,2.12,3.07,20.3,20.3,0,0,0,2-1.2,15.74,15.74,0,0,1,1.92-1.13,34.39,34.39,0,0,1,3.19-1.28c-.36-.67-.75-1.35-1.17-2a24.07,24.07,0,0,1-2.75-5.82,2.5,2.5,0,0,1,4.82-1.31,20.12,20.12,0,0,0,2.23,4.59,25.17,25.17,0,0,1,2.71,5.64,2.5,2.5,0,0,1-2.16,3.19,17.73,17.73,0,0,0-4.84,1.59c-.21.1-.81.48-1.25.76C548.38,630.53,547,631.36,545.57,631.36Z" transform="translate(-105.77 -43.5)"/></g><g id="circle"><g class="cls-12"><path class="cls-7" d="M412.3,590.85c.19-10.39,3.77-19.35,12-29.06C429,556.25,438.5,551,445.2,548.55c18-6.67,41.77-3.38,57.05,8.54,11.26,8.79,14.51,22.08,17.45,35.46,5.89,26.81-10.08,50.17-36.51,57.08-25.62,6.69-54-2.76-64.83-28.2-2-4.68-3.14-9.87-4.31-15.2A66.21,66.21,0,0,1,412.3,590.85Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-12"><path class="cls-7" d="M539.3,549.54a47.78,47.78,0,0,1,6.72-27.9c3-5.17,9.47-9.71,14.09-11.74,12.44-5.44,29.58-.7,41.23,12,8.59,9.38,11.74,22.69,14.68,36.07,3.29,15,2.67,28.79-3.74,40-6.27,11-15.81,12.29-26.17,13.33-7.79.78-15.93,1.62-23.52-4.77-8-6.75-12.87-15-17-26.51a122.75,122.75,0,0,1-4-15.26A93.72,93.72,0,0,1,539.3,549.54Z" transform="translate(-105.77 -43.5)"/></g><path class="cls-1" d="M467.07,655.25a61.92,61.92,0,0,1-23.16-4.39,51.53,51.53,0,0,1-28.79-28c-2.13-5-3.34-10.51-4.51-15.82a69.67,69.67,0,0,1-1.84-16.21h0c.2-11.39,4.16-21,12.81-31.27,5.09-6,14.91-11.5,22.39-14.27,19.5-7.21,44.36-3.48,60.45,9.07,12.67,9.89,16,25.19,18.73,37.49,6.14,28-10.29,53.73-39.07,61.25A67.41,67.41,0,0,1,467.07,655.25Zm-2-106.55a54.06,54.06,0,0,0-18.65,3.16c-6.6,2.45-15.41,7.42-19.45,12.21-7.54,8.91-11,17.19-11.15,26.84h0a62.8,62.8,0,0,0,1.68,14.57c1.1,5,2.23,10.16,4.11,14.57,10.56,24.83,38.53,32,60.69,26.17,25.38-6.63,39.34-28.39,34-52.91-3.12-14.23-6.3-25.72-16.18-33.44C490.8,552.63,477.77,548.7,465.08,548.7ZM412.3,590.85h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M578.15,615.43c-5.87,0-12-1.19-17.83-6.13-8-6.76-13.43-15.13-18.08-28a126.1,126.1,0,0,1-4.16-15.7,97.31,97.31,0,0,1-2.3-15.87A51.14,51.14,0,0,1,543,519.87c3.39-5.84,10.34-10.84,15.73-13.2,14.07-6.15,32.68-.86,45.25,12.87,9.54,10.41,12.86,25.54,15.52,37.7,3.71,16.92,2.33,31.23-4.12,42.55-7.37,12.93-19.3,14.13-28.88,15.1A82.79,82.79,0,0,1,578.15,615.43Zm-7-104.21a24,24,0,0,0-9.66,1.92c-4.33,1.9-10,6-12.45,10.27a44.47,44.47,0,0,0-6.25,26h0A90.27,90.27,0,0,0,545,564.08a121,121,0,0,0,3.9,14.81c4.26,11.78,8.89,19,16,25,6.42,5.41,13.41,4.71,20.81,4,10.88-1.09,18.35-2.49,23.53-11.58,5.56-9.75,6.69-22.39,3.36-37.54-3.16-14.41-6.19-26.09-13.84-34.44S580.64,511.22,571.19,511.22Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.85,593.87a3.53,3.53,0,0,1-2.47-6,44.74,44.74,0,0,1,26.81-12.52,3.53,3.53,0,0,1,.7,7,37.66,37.66,0,0,0-22.57,10.54A3.52,3.52,0,0,1,519.85,593.87Z" transform="translate(-105.77 -43.5)"/><g class="cls-12"><path class="cls-7" d="M594.18,528.83c-2.91-2.27-6.89-1-6.33,3,.48,3.5,3.92,7.78,5.33,11.35,1.52,3.85,1.69,9.59,4.15,12.83,6.11,8,5.64-6.3,4.59-9.76C600,539.94,598.74,534.06,594.18,528.83Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-12"><path class="cls-7" d="M496.84,563.83c-1-3.57-9.51-2.83-8.77,1.67.41,2.44,3.62,5.41,4.9,7.54a40.24,40.24,0,0,1,4.21,9.12c1.7,5.77-.86,14.73,3.3,19.67,3.29,3.9,6.35,1.12,6.68-2.86.42-5.1-.18-10.25-.7-15.28C505.86,577.61,503,567.14,496.84,563.83Z" transform="translate(-105.77 -43.5)"/></g></g><g id="layers"><path class="cls-1" d="M468.33,880.06a357.61,357.61,0,0,1-159.8-677.52,3.53,3.53,0,1,1,3.16,6.31c-119.58,59.84-193.86,180-193.86,313.64C117.82,715.77,275.06,873,468.33,873S818.84,715.77,818.84,522.5a350,350,0,0,0-214.08-323,3.53,3.53,0,0,1,2.75-6.5,357.56,357.56,0,0,1-139.18,687Z" transform="translate(-105.77 -43.5)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.png b/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.png deleted file mode 100644 index 1b13ab4243ec46bcb15c9a8b36b9dff556265044..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.svg b/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.svg deleted file mode 100644 index f579c37a7b8b479ca8f2d775b7adb2f4f5985522..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Flat.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 688.25 700.83"><defs><style>.cls-1{fill:none;}.cls-2{fill:#474747;}.cls-3{opacity:0.2;}.cls-4{fill:#edc0e3;}.cls-5{fill:#e8e5e3;}.cls-6{fill:#aaa39f;}.cls-7{fill:#fff;}.cls-8{fill:#c4d8ba;}.cls-9{fill:#807e6e;}.cls-10{fill:#d7b89b;}.cls-11{fill:#efe6da;}.cls-12{opacity:0.44;}.cls-13{fill:#995967;}.cls-14{opacity:0.72;}.cls-15{fill:#829e93;}.cls-16{opacity:0.61;}.cls-17{fill:#a7d8bf;}.cls-18{opacity:0.59;}.cls-19{fill:#d1b288;}.cls-20{fill:#606282;}.cls-21{opacity:0.46;}.cls-22{fill:#51483e;}.cls-23{fill:#6e607f;}.cls-24{fill:#1d1d1b;}.cls-25{clip-path:url(#clip-path);}.cls-26{clip-path:url(#clip-path-2);}.cls-27{clip-path:url(#clip-path-3);}.cls-28{clip-path:url(#clip-path-4);}.cls-29{clip-path:url(#clip-path-5);}.cls-30{clip-path:url(#clip-path-6);}.cls-31{clip-path:url(#clip-path-7);}.cls-32{fill:#b79765;}.cls-33{fill:#e9e9f2;}.cls-34{fill:#3d3d3d;}.cls-35{opacity:0.68;}.cls-36{opacity:0.17;}.cls-37{opacity:0.36;}</style><clipPath id="clip-path" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M64.1,446.5,68,327c0-.74,110.68.57,120.76.64q30.51.22,61,.33c6.75,0,15.67-2.86,18.19,5,1.69,5.22-.25,11.23,0,16.58a66.07,66.07,0,0,0,2,13.25c1.3,5,2,6.21,0,10.75-3.71,8.44-8.65,15.92-13.38,24.23a58.76,58.76,0,0,0-4.67,11c-1.6,4.92-1.3,10.78-3.33,15.37s-6.67,8.57-9.26,12.9c-2.48,4.16-4.41,10-9.47,11.12-5.52,1.28-15.14-.81-21.12-.85q-24.31-.15-48.62-.34C152.13,446.9,64.12,445.91,64.1,446.5Z"/></clipPath><clipPath id="clip-path-2" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M547.52,426.07A19.5,19.5,0,0,1,543,417c-1.22-5.73-3.79-10.48-5.95-16-6.29-16.22-11.85-27-11.27-44.83.32-9.71.48-19.43,1-29.13,0-.74,110.68.57,120.76.64q30.51.22,61,.33c6.38,0,12.68-.67,19.06-.19,4,11.39,4.55,23,6.27,35.07,1.86,13.09,4.55,25.42,3.85,39-.63,12.08-.29,26.9-4,38.38-1.72,5.29-1.34,5.51-7.3,6.15-4.38.47-8.93-.24-13.33,0-15.44.84-30.18,1.06-45.52,1q-24.31-.15-48.63-.34c-11.71-.09-23.42-.23-35.13-.34-6.18-.06-16.86,2.13-22.47-.37-5.11-2.28-5.82-8.72-8.39-13.08A51.57,51.57,0,0,0,547.52,426.07Z"/></clipPath><clipPath id="clip-path-3" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M132.33,613.67c3-.92,8.1.34,11.5.67a101.15,101.15,0,0,0,14.08,0c8.09-.4,16.39-.28,24.51-.67a108.86,108.86,0,0,1,11.88-.28,17.65,17.65,0,0,0-1.35,4.55c-5.19-.07-3.06,3.59-1.4,6.15-3.62,1.72-3.81,5.09.74,5,0,2.42,0,5.84,1.7,7.78,1,1.1,2.72,1.61,3.56,2.78,1,1.36,1.07,3.37,1.7,4.94a22.28,22.28,0,0,0,6.36,8.73c5.62,4.73,13.19,6.71,20.4,7.06,3.64.18,7.32-.15,10.95,0,.35,7,1,14.28.22,21.25-.66,6.16-2.13,12.08-2.57,18.27-1.4-2.33-5.52-4.06-7.76-5.57-3.65-2.46-7.27-3.34-11.15-5.16-7.75-3.64-13.38-9.11-20.36-13.93-7.53-5.2-15.21-9-22.15-15.08a173,173,0,0,1-22.18-24c-2.75-3.56-6-6.48-8.67-10.07-2.39-3.16-6.59-7.57-8-11.09"/></clipPath><clipPath id="clip-path-4" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M661.33,612.33c-11.53,0-23.3,1.39-34.74,2.33-7.67.63-15.22-.38-22.87.06a6.61,6.61,0,0,0-.34,3.56c3.57.37,3.12,4.64.31,5.63,1.48.49,2.61,1.47,2.59,3-4.54.55-2.26,4.19-3.27,7.39-.52,1.64-1.08,1.92-2.16,3-.36.36-1.26-.21-1.77.39s-.45,1.93-.81,2.67c-2.6,5.29-5.11,10.83-10.45,13.92-4.11,2.37-9.38,3.66-13.82,5.25a32.68,32.68,0,0,1-12.27,2.13c-.65,4.82.62,10.54.62,15.51,0,6.61-.91,14,.34,20.42,4,.09,8.51-3.94,11.64-6.28,5.48-4.09,11.25-7.68,16.78-11.7,5.72-4.15,10.69-9,16.23-13.34s11.78-8.28,17-13.27c4.31-4.15,8.76-8.19,13.34-12,4.43-3.73,7.79-7.72,11.83-11.78C652.16,626.52,662.91,616.69,661.33,612.33Z"/></clipPath><clipPath id="clip-path-5" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M579.07,484.41c-.8,4.09-1.75,8.25-2.81,12.34-2.06,7.88-6.13,15.35-9.25,22.91-1.85,4.48-3.71,6.52-8.28,8.4.2-.08.35,8.66.44,9.64.36,3.72,1.64,7.27,2.7,10.83,2.2,7.37,3.58,13.61-1.5,20.06.48-.61,9.82,2.94,10.61,3.5,2.42,1.71,4.69,3.82,7.21,5.6a47.82,47.82,0,0,1,5.91,5.44c2.74,2.71,4.32,5.41,8.4,5.21,5.13-.25,10.46-1.11,15.65-.58,8,.83,16,.73,24,1.07s16.17-.83,24.31-.83c6.07,0,12.15,0,18.19-.26,5.07-.24,6.21.26,8.85-4.21,2.51-4.26,6.39-7.32,9.59-11,3.9-4.51,5.95-9.54,8.61-14.76,3.82-7.47,5.77-15.67,8-23.71,2.16-7.84,6.43-14.87,9.36-22.45,2.19-5.66,4.22-11.21,4.93-17.26a124.32,124.32,0,0,1,2.34-13.68c.62-2.7,1.77-6.43,1.27-9.27-38.84-2.08-78.82-1.69-117.78,0q-10.63.45-21.24,1.36c-2.39.21-8-.29-9.27,1.76C578.16,476.28,579.53,482,579.07,484.41Z"/></clipPath><clipPath id="clip-path-6" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M141.17,586c8.14.29,16,1.67,24.41,1.67,9.44,0,18.67.29,28-.17,3.4-.17,6.65-.41,10.06-.5,4.37-.12,4.93-2.93,8-6,6-5.95,13.79-9.37,20.88-13.73-1.29-5.55-4.27-8.69-4.28-14.83,0-7.27,4.87-15.19,3.32-22.24-.32-1.47-2.51-3-2.26-4.78s2.46-3.63,2.94-5.42c1-3.89.57-9.75-.41-13.59-1.61-6.29-7-10.59-8.18-17-.63-3.39-.23-6.81-.74-10.19-.35-2.34-1.66-4.32-1.71-6.81-7.93-.44-16-.07-24-.05-10.2,0-20.36-1.34-30.64-1.33-17.24,0-34.65,0-51.82-.67a289.65,289.65,0,0,0-39.92,1c-2,.2-6.86-.45-7.95,1.35-1.41,2.34,3.64,10,4.3,12.3,1.76,6,3.44,12,5.3,17.93,5.63,18.05,11.86,35.93,17.48,54,3,9.49,7.26,19.28,14.09,26.65,4.48,4.84,7.5,4.35,13.9,3.82S134.75,585.77,141.17,586Z"/></clipPath><clipPath id="clip-path-7" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M260.38,162.7c55.06.06,110.12.66,165.17.93s110,.24,164.94-1q11.49-.25,23-.58c6.76-.19,14.57.48,21.18-.81-2.12-2.56-2.84-5.8-5.31-8.27a49.21,49.21,0,0,0-8.75-6.93c-3.43-2.17-6.39-5.18-9.92-7.17s-7.45-3.18-10.4-6.06c-2.57-2.52-3.58-5.46-6.65-7.58-3.92-2.7-8.47-4.14-12.53-6.6-8.77-5.33-15.26-12.33-24.56-16.66-5.63-2.62-9.94-7.32-15.43-10-5.2-2.54-11.11-3.46-16.43-5.68C519,84,513.78,80.24,508,78.17c-11.9-4.27-24.91-5.63-37-9.42-6-1.89-11.6-2.33-17.86-2.73-6.58-.43-13.28-2.26-19.83-3.1a194.85,194.85,0,0,0-31.88-1.22c-4.19.15-7.08-1.83-11.21-1.81s-8.06,1.46-12.12,1.87c-10.28,1-20.62,1.18-30.91,2.28-16.38,1.76-32.39,8-48.07,12.63-10.5,3.1-21.41,6.09-31.32,10.75-9.51,4.47-18.42,10-27.82,14.64-9,4.48-18.56,8.06-26.82,13.94-3.55,2.52-6.66,5.4-10.63,7.35-4.14,2-8.49,3.57-12.18,6.41-7.21,5.55-14.07,12.07-21,17.93-2.51,2.12-15.05,10-10.75,14,2.39,2.2,12.65.55,15.86.57l17.34.12Q226.08,162.62,260.38,162.7Z"/></clipPath></defs><title>BoyerScene2Flat</title><g id="COLOR"><path class="cls-2" d="M411.55,62.33C592.55,69.76,737,218.85,737,401.67c0,187.57-152.06,339.62-339.62,339.62S57.75,589.24,57.75,401.67,209.81,62,397.38,62h3Z" transform="translate(-53.25 -44.96)"/><g class="cls-3"><path d="M411.55,62.33C592.55,69.76,737,218.85,737,401.67c0,187.57-152.06,339.62-339.62,339.62S57.75,589.24,57.75,401.67,209.81,62,397.38,62h3Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-4" d="M89.49,418.2c.15-3,.16-6,.34-9.05.16-2.72.88-5.49.78-8.19s-.8-5.19,2.15-6.53a49.56,49.56,0,0,1,10.52-3.06c5.41-1.11,11.86-.2,17.44-.35,6.67-.18,13.51,0,20.13-.73,5.79-.66,11.57,2.28,17.41.66,4.71-1.3,1.34-16.9.49-20.44-.92-3.87-2.37-5.83-4.24-9.25-1.77-3.25-2.63-4.83-5.59-7.05-3.61-2.71-6.83-5.59-11.24-7-4-1.23-9.3-.66-13.37-.25a149.55,149.55,0,0,0-15.43,2.48c-7.23,1.5-13.51-4.77-15.24-11.31a15.92,15.92,0,0,1-.43-6.7c.71-3.35,2.92-4.58,6.15-4.63,2,0,3.83-.42,5.79-.51s5.19-.69,6.93-.16c2.42.73,3.93,4.59,5.11,6.67.4.69.56,2.46,1.48,2.68s4.9-2.71,5.85-3.19c5.28-2.67,10.15-4.48,16.08-4.7,8.39-.31,16.79-.16,25.19,0,7.38.17,14.71.78,22.06.17,5-.41,9.91-.5,14.91-.5,5.15,0,10.31-.07,15.45.17,2.67.12,5.91.73,8.14,2.3,2,1.4,5.57,5,8.15,4.47,2.23-.5,3.46-3.4,5.18-4.67,3-2.22,7.08-2.77,10.8-2.43,3.53.32,6.58.76,8.5,3.85s.88,5.93-.23,9.07a54.25,54.25,0,0,1-6.23,12.12,3.82,3.82,0,0,0-2.87-1,13.92,13.92,0,0,1-5.53-1.33c-4.15-2.12-7.94-3.68-12.69-3.83a37.3,37.3,0,0,0-16,3.29c-4.25,1.8-9.81,4.19-13.05,7.58-6,6.26-6.8,14.53-7.53,22.8-.29,3.31-.68,6.73,0,10,.42,2,.9,2.61,3,2.63a68.9,68.9,0,0,0,10.13-.75c8.26-1.17,16.85-3.06,25.24-2.38,4.65.38,9.17.43,13.79,1.32,2.23.43,4.37,1.06,6.63,1.38a14.25,14.25,0,0,1,4,.83c.16,2.13-1.9,5-2.87,6.84-2.06,3.94-3.08,8.38-4.95,12.42a43.33,43.33,0,0,0-2.5,6.58c-.66,2.33-.74,5.27-1.67,7.46-1,2.4-3.9,4.89-5.55,7.09a105.22,105.22,0,0,1-7,8.37c-1.79,1.93-3.67,4.55-5.59,6.25-2.14,1.89-6.41.88-9.08.79-7.44-.26-14.64-1.68-22.17-1.13-6.64.49-13.72-.28-20.44-.32-7.34,0-14.67,0-22,.3-18.33.83-36.7-3.1-54.85-.54a26,26,0,0,1-6.08.2c-1.8-.16-4.23.14-4.82-1.77-.72-2.33.22-6.49.33-9C88.72,430.24,89.19,424.23,89.49,418.2Z" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M727.5,327.5c0-.64,0-1.28-.09-1.91-.34-5.38-.65-22.82-6.92-23.84-4.21-.69-9.54.16-13.88.16h-41c-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-126.07-1.17-191.59-1.17L68,327c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0H728" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M637.53,161.53c-3.9,0-7.8,0-11.68.17-120.91,3.89-243.85,1.14-365.47,1-34.45,0-68.81-.31-103.17-.56l-23.62,24.93c42.24.28,84.46.68,126.79.73,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M64.1,446.5c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0,20.81,0,51.3,2.07,72.11,2.07L730,470.8c-20.81,0-47.47.79-68.28.79-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-130.77-1-196.28-1" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M681,588.06c-6.91-.23-13.49-.4-19.3-.4-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-48.95-.05-97.73-.59-146.58-.85L131.17,613c43,.28,86.06.7,129.21.75,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M727.5,327.5c0-.64,0-1.28-.09-1.91-.34-5.38-.65-22.82-6.92-23.84-4.21-.69-9.54.16-13.88.16h-41c-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-126.07-1.17-191.59-1.17L68,327c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0H728" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M637.53,161.53c-3.9,0-7.8,0-11.68.17-120.91,3.89-243.85,1.14-365.47,1-34.45,0-68.81-.31-103.17-.56l-23.62,24.93c42.24.28,84.46.68,126.79.73,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M64.1,446.5c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0,20.81,0,51.3,2.07,72.11,2.07L730,470.8c-20.81,0-47.47.79-68.28.79-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-130.77-1-196.28-1" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M681,588.06c-6.91-.23-13.49-.4-19.3-.4-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-48.95-.05-97.73-.59-146.58-.85L131.17,613c43,.28,86.06.7,129.21.75,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M689.33,345.33c-15.88.07-27.4,7.39-33.93,21.91-3.35,7.46-4.21,16-1.49,23.75.63,1.79,2.24,7.45,4.14,8.28s7.59-1.84,9.76-1.94c4.4-.21,8.78-.44,13.16-.67,9.14-.47,19-2.15,28-.83,5.14.75,10.82,4.1,15.95,3.49,0-6.61,2.86-12.73,2.39-19.62-.37-5.43-3.36-10.23-6.19-14.69s-6.29-10.2-10.14-13.95C706.06,346.23,699.6,346.58,689.33,345.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M577.33,345.67c-8.13,2.74-16.2,6.05-22.67,12-7.18,6.59-8,16.39-8,25.65,0,5,.58,12.8,4,16.73,9.37-6.75,25.31-5.33,36.26-4.37,6,.52,11.95.82,17.84,1.91,3.54.65,7.58,1.86,11.19,1.37,1.49-6.31,5.31-10,5.06-17a39.76,39.76,0,0,0-5.5-18.32C607.56,350.39,597,346.33,577.33,345.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-8" d="M584.47,330.32c-2.69,1.39-5.71,4.62-8.4,5.3-3.34-7-9.64-7-16.73-6.62-4,.22-7-.06-6.67,4.58.38,5.94,3.06,14.31,9.5,16,5.45,1.42,10.87-1.23,16.15-2.22,6.6-1.23,12.53-1.2,18.85,1,14.85,5.24,21.87,18,21.17,33.56-.16,3.48,0,16.13-4.19,18.05-1.58.72-7.86-1.67-9.82-2-8-1.24-16-2.9-24.13-3.7s-14.79.94-22.37,3.32c-2.75.86-6.43,1.58-8.2,3.86s-2.1,6.88-2.3,9.51c-.45,5.79-2,12.06.31,17.62,1.53,3.63,4.42,6.53,7.44,8.93,3.53,2.82,4.78,5.89,6.65,10.07,14.65.9,29-2.15,43.76-2.28,9-.08,18-.93,26.84-1,9.1-.07,17.51,1.92,26.5,2.68,10.45.88,21,.63,31.53.81,9.78.17,19.79.78,29.48.75,4.8,0,2.74-3,2.71-7.43,0-5.1.57-10.23-.2-15.3-.52-3.43-1.15-6.67-1.35-10.15-.15-2.71-1.27-6.44-.67-9,.75-3.19,3.76-4.87,3.28-8.62-11.35-.63-22.56-1.38-33.94-1.38s-22.47,3.56-33.34,1.83c.18-4-1.47-7.84-1.67-11.83s-.33-8-.33-12c0-8.39,4.09-14.09,10.68-19.41,9.93-8,21.7-11.6,34.67-9.23,3.63.66,7.27,3.77,10.65,4.14,4.87.54,7.91-8.54,8.51-12.84,1.2-8.69-1.45-10.79-9.68-11.17-3.57-.16-6.87-.6-9.85,1.68s-5,5.72-8.22,7.79c-5.52-9.81-22.7-9.3-32.08-9.3-17.09,0-34.29.82-51.35,1.67-3.94.2-8-.88-11.91-1C590.64,326.75,588.76,328.11,584.47,330.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M638,393.67c-3.35,0-15.51-.26-14.36,5.67.5,2.58,6,4.42,8.19,4.83,3,.56,5.94.31,8.16-1.82C641.55,400.86,645.87,392.58,638,393.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M626,400.67c-8.15-1.58-12.48,17.44-3.33,18.33,3.87.38,6.87-2.06,10.41-2.92,4.88-1.19,10.23.45,15.19,0,5.93-.57,6.78-6.25,4-11.05-1.75-3-4.79-3.2-7.18-5.3-2,5.4-13.39,5.35-16.08,1" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M628,418.33c-.19,2.28-1.39,7.7-.18,9.85,1.32,2.33,6,2.67,8.35,2.49,2.92-.23,5.64-1.43,6.58-4.33.44-1.35,1.15-8,.59-9.17C641.86,414.17,631,415,628,418.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M183.67,393c-3.93,0-20.42-1.1-18.35,6,1.15,3.93,8.21,4.93,11.58,5C182.73,404.09,186.51,400.8,183.67,393Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M161.75,404.35c-1.93,2.57-4.11,7.18-2.35,10.26s6.5,4.14,9.6,3.32A43,43,0,0,1,179.5,416c3.4-.11,8.91,1.1,12-.37,7.94-3.79.72-11.47-3.41-14.71-3.25-2.55-3.86.42-6.92,2.25-2.62,1.56-5.68,2.94-8.67,1.7C168.19,403.07,166,398.74,161.75,404.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M168.33,417.33c0,7,.59,11.56,8.33,12.34,3.34.33,6.66.05,8.26-3.17,1-2.07,1.55-7.61.22-9.49C182.34,413.05,174.9,415.3,168.33,417.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M88.5,394.33a48.2,48.2,0,0,1-.21-22.53A27.33,27.33,0,0,1,96,358.64c2-2,3.92-4.38,6.43-5.77a53.9,53.9,0,0,1,8-3.24c6.09-2.19,12.16-3.64,18.69-3.3a36.48,36.48,0,0,1,10.33,2.26c2.89,1.05,4.92,3.18,7.24,5.1,2.08,1.72,4.25,2.94,5.92,5a29.06,29.06,0,0,1,3.73,6.56c2.84,6.42,3.69,12.08,3.68,19.05,0,1.77.92,6.87-.68,8.23-1.13,1-4.26-.81-5.46-1.24-3.84-1.37-8-1.5-12-1.5-9.57,0-19.67.27-29.12,1.88C104.76,393.07,96,393.51,88.5,394.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M196,392c-1.79-1.75-1.89-6.26-2-8.63a33.15,33.15,0,0,1,.46-8c.9-4.59,3.49-9.41,5.67-13.5,7.79-14.61,29.4-17.66,44-13.87,4.77,1.24,9.79,2.87,12.87,6.92,2.27,3,5.88,7.5,6.46,11.25" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M248.67,351.33c.78,1.44,2.61,2.29,3.84,3.33a44,44,0,0,1,4.62,4.63,40.35,40.35,0,0,1,5.83,8.8,52,52,0,0,1,3.62,7.83c.95,3.06-2.19,6-3.86,8.48-2.07,3.07-4.34,6.07-6.27,9.26-2.39-2.19-6.42-2.57-9.56-3.09a103.84,103.84,0,0,0-17.2-1.23c-10.86,0-21.52,2.53-32.37,2.67" transform="translate(-53.25 -44.96)"/><path class="cls-11" d="M180.17,162.33c-4.89,0-5.59-1.1-7.57-5.41-.55-1.2-2.47-4.28-2.28-5.58.35-2.33,3.06-3.08,5-4.35,6.52-4.23,12.36-9.33,18.49-14.16,7.48-5.9,15.18-10.77,23.17-15.93,5.58-3.61,11.35-6.67,17.1-10,11.44-6.63,24.34-10.63,36.4-16.08A352.56,352.56,0,0,1,347.35,66a242.15,242.15,0,0,1,28.52-3.37c3-.23,17.34-2.79,18.83,1,.22.58-.92,3.37-1,4.17-.23,1.6-.25,3.32-.33,4.91-.22,4.5-2.48,16.8.83,20.26,1.57,1.65,2.82.45,5.18,0,3.1-.59,6.36-.33,9.51-.33,6.7,0,13.33,0,20,.67,1.42.14,4.8-.14,5.55,1,.59.87-.24,4.17-.34,5.19-.67,6.65-.65,13.76-.68,20.51,0,10-.34,19.9-.28,29.86,0,2.6-1.23,9.56.09,11.76,1.22,2,4.81,1.58,6.81,2-.32-.07.52-32.62.49-35.66-.1-10.61-.77-21.25-.77-32,0-5-2-14.61.39-18.94,5-.32,9.91-.19,14.89-.44.14-2.75-1-7.18,1.38-8.28,3.14-1.44,9.33,1.6,12.88,1.38-.32,0,.45,22.21.45,24.2,0,5.69-.34,11.33-.59,17-.54,12.46.59,24.71.59,37.15,0,5.16-.47,10.06-.72,15.2-4.26.57-9.19-.62-13.58-.62-5.59,0-11.39-.35-16.94.24-15.7,1.69-32.27.91-48.16.09-10.62-.55-21.43.27-32.14.1-12.09-.19-24.18-.44-36.27-.44-29.6,0-59,1-88.57,1-8.16,0-16.68.73-24.62-.76-2.89-.54-5.9-1-8.74-1.49C193.6,160.38,186.58,162.33,180.17,162.33Z" transform="translate(-53.25 -44.96)"/><g class="cls-3"><path d="M440.17,158.78c-.13-10.26.36-20.52.26-30.82-.1-10.61-.77-21.25-.77-32,0-5-2-14.61.39-18.94,5-.32,9.91-.19,14.89-.44.14-2.75-1-7.18,1.38-8.28,3.14-1.44,9.33,1.6,12.88,1.38-.32,0,.45,22.21.45,24.2,0,5.69-.34,11.33-.59,17-.54,12.46.59,24.71.59,37.15,0,5.16-.47,10.06-.72,15.2,0,.76-19.65-.13-21.13-.32a10.14,10.14,0,0,0-4.14,0c-1.13.34-2.28,1.1-3.39.72Q440.2,161.24,440.17,158.78Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M303.55,161.86c-.81-12.51,1.83-24.9,2.8-37.33a114.16,114.16,0,0,0-.45-18.9c-.5-5.93.14-12.09.09-18.06q0-4.55-.21-9.1c8.46-5.27,18.63-7.23,28.31-9.56,7.08-1.7,14.13-3.37,21.41-1.81-3.48,13.14-.1,27-.06,40.58,0,3.35-.18,6.7-.33,10a355.09,355.09,0,0,0,.93,45.51c-.07-.88-31.13-.58-34.17-.58-1.33,0-18.28-.34-18.21.53Q303.59,162.53,303.55,161.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-14"><path class="cls-15" d="M239.27,163.84a64.66,64.66,0,0,0,2.63-13.77l4.88-41.94a19,19,0,0,1,1.28-5.73c1.72-3.78,6.3-4.89,9.83-6.3,4.23-1.69,8.45-3.38,12.6-5.26a188.12,188.12,0,0,1,24.76-9.16L294,102.77c-.4,6.47-1.61,13.54-.9,19.93a203.82,203.82,0,0,1,1.36,23.14c0,3.86-.17,7.72-.48,11.57s0,5.17-3.94,5.26c-8.35.18-16.71.58-25.05.71q-7,.11-14.07.19C247.54,163.6,242.35,165,239.27,163.84Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M180.17,162.33c-4.89,0-5.59-1.1-7.57-5.41-.55-1.2-2.47-4.28-2.28-5.58.35-2.33,3.06-3.08,5-4.35,6.52-4.23,12.36-9.33,18.49-14.16,7.48-5.9,15.18-10.77,23.17-15.93,5.58-3.61,11.35-6.67,17.1-10,4.47-2.59,9.16-5.63,14.1-7.05a1.67,1.67,0,0,1,1-.08c.77.26.74,1.35.55,2.14a479.38,479.38,0,0,0-8.47,47.41c-.42,3.28.1,9.24-1.38,12.13-1.2,2.34-5,2.19-7.76,2.21-7.81.06-15.73.68-23.45-.76-2.89-.54-5.9-1-8.74-1.49C193.6,160.38,186.58,162.33,180.17,162.33Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/><g class="cls-16"><path class="cls-17" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M92.25,301.5c0-6-.5-12-.5-18.06,0-5.5-1-10.71-.75-16.21s-.53-10.74,1.4-16c3.53-9.57,9.82-18.41,15.56-26.75,3.87-5.62,7.07-11.13,14-12.82q.13-.15,0,0a3.67,3.67,0,0,1-.62.54c3.43-.59,7-2.53,10.66-1.41,5.14,1.6,6.51,6.61,7.46,11.3,3.59,17.89,6,36.34,7.92,54.46.51,4.84.5,13.41,4.64,16.72,1.58-5.82,1-12.05.73-18-.09-2.2,1-6.55-1-8,0,0,1.38-62,1.31-63s9.69-2,9.69-2l8.44,1.41,1.06,4.33L174,195.93h20.67v14.55l12.33.13V195.93l19-.65s12.92,3.72,12.84,4.22.17,76.75.17,76.75l.47,16.25,16.16-28.11,31.47-48.05L297.25,201l11.54,8L310.67,188l13.09-.23L323.18,219l17.32.25L338.75,304l-28.66-1V213l-1.84-1L274,271l-11.25,20L253,302l-12-8.67-2,1.09,1.33,6.85Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-19" d="M92.25,301.5c0-6-.5-12-.5-18.06,0-5.5-1-10.71-.75-16.21s-.53-10.74,1.4-16c3.53-9.57,9.82-18.41,15.56-26.75,3.87-5.62,7.07-11.13,14-12.82q.13-.15,0,0a3.67,3.67,0,0,1-.62.54c3.43-.59,7-2.53,10.66-1.41,5.14,1.6,6.51,6.61,7.46,11.3,3.59,17.89,6,36.34,7.92,54.46.36,3.41.41,6.88,1.22,10.23s3,6.57,2.57,10.21c-.92,7-12.72,4.42-17.57,4.43l-21.11,0Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-14"><path class="cls-15" d="M310.09,301.5V253.82c0-17.45.39-34.95-.69-52.32-.06-1,1.2-13.52,1.27-13.52l13.09-.23L323.18,219l17.32.25L338.75,304l-28.66-1Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M253,302c-2.25-1.63-4.71-2.95-7-4.5-1.06-.72-5.47-2.36-5.74-3.5a2.51,2.51,0,0,1,.14-1.25c2.85-9.95,10.06-19.35,15.24-28.36l31.47-48.05L297.25,201c4.1,2.86,9.46,5.37,12.37,9.43a3.46,3.46,0,0,1-1.25,3.18c-3.48,2.74-5.36,7.38-7.58,11.2l-8.67,14.93-15.74,27.11L274,271l-11.25,20Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M153,295.9c-.63-6.8,0-13.85-.26-20.65-.09-2.2,1-6.55-1-8,0,0,1.38-62,1.31-63s9.69-2,9.69-2l8.44,1.41,1.06,4.33L174,195.93h20.67v14.55l12.33.13V195.93l19-.65s12.92,3.72,12.84,4.22.17,76.74.17,76.75c0,2.8.16,5.61.24,8.41.11,4-.6,8.55.14,12.4.4,2.11,2.31,3.77,2.05,6.09-10.6.4-21.52-1-32.17-1.15s-21.12,0-31.67.34c-7.47.26-15.09.63-22.26-1.48a3,3,0,0,1-1.46-.77,3,3,0,0,1-.55-1.55C153.19,297.68,153.08,296.79,153,295.9Z" transform="translate(-53.25 -44.96)"/></g><polygon class="cls-11" points="292.81 257.04 292.37 188.62 331.25 188.69 332.25 161.42 375.58 161.42 377.25 158.59 388.74 157.38 392.75 158.09 396.14 159.65 397.6 150.81 419.52 150.97 418.91 163.79 431.27 164.54 431.3 151.68 445.66 150.81 454.25 150.63 462.5 152.7 463.08 178.06 474.5 177.82 477.54 175.78 476.5 171.22 496 164.54 500.75 165.29 513 237.04 518.25 258.54 486.5 258.79 479.75 205.44 476.5 185.51 474.5 188.04 474.5 259.72 388.74 258.79 372.42 251.62 363.92 248.75 359.76 249.29 360.52 252.7 346.42 254.29 327.96 255.7 320.75 255.7 292.81 257.04"/><g class="cls-16"><path class="cls-17" d="M536.48,277.9,533,250.4c-1.67-10.25-2.32-20.24-3.6-30.5a7,7,0,0,1-.06-2c.57-3.44,8.49-4.49,11.35-5.47l8.57-2.94,4.75.75L566.25,282l5.25,21.5-31.75.25Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M473.47,293.73c-1.74-26.81.49-53.82-1.55-80.62a4.35,4.35,0,0,1,.27-2.4c1-1.92,12.33-1.69,12.33-1.21l0-12.86,14.36-.87,8.59-.19,8.25,2.08.58,25.36c2.8-.06,10.63-1.71,11.76,1.59a7.14,7.14,0,0,1,.21,2.63c-.69,16-.55,32.12-.55,48.19v29.24s-17.26-.19-18.27-.2l-18.3-.2-9.55-.1c-1.55,0-5.71,1.2-6.72,0a4.87,4.87,0,0,1-.81-2.69Q473.72,297.6,473.47,293.73Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M425.5,293.74a206.26,206.26,0,0,1-.69-22.25l.26-51.15a30.31,30.31,0,0,0-.76-8.51,7.25,7.25,0,0,1-.48-2.53c.14-1.71,1.71-2.93,3.28-3.62,5-2.2,9.39-2.75,14.88-3.33l4,.71,3.39,1.56,1.45-8.84,21.92.16c-.27,5.63.18,11.07-.14,16.67-.46,8.18-.88,16.36-1.09,24.55-.41,16.12,0,32.31,2.46,48.27.91,5.88,2.09,11.73,2.51,17.66.16,2.26-.67,1.84-2,1.84-.19,0-1.31-.76-1.64-.85-1.21-.34-3,0-4.25,0L455,303.89l-13-.14c-2,0-5.17-2.27-7-3.05-2.68-1.18-9-2.58-9.43-6Q425.55,294.23,425.5,293.74Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-19" d="M346.06,302l-.45-68.42,38.88.07,1-27.27h16.62c8.39,0,18.24-1.41,26.4.12a68.46,68.46,0,0,1-.41,12.13l-2.78,29.79c-.43,4.65-.87,9.3-.88,14,0,3.8.25,7.6.52,11.39.52,7.46,4,19.43,3.88,26.89-3.05.17-7.48-.41-10.33,0l-4.62-.25h0L400,300.5l-18.79.17H374Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M433.26,162.79c-.09-1.68-.12-3.36-.15-5l-.53-29.61a72.4,72.4,0,0,0-.4-7.61c-.31-2.49-.88-5-1-7.47-.28-6.72,2.75-13.46,1.35-20a1.53,1.53,0,0,0-.45-.93,1.6,1.6,0,0,0-1-.22c-7.26,0-14.53.07-21.78.32-2.6.09-4.76,1-7.28,1.19-2.21.18-6.4-.33-6.61,3-.06.92.31,2.07-.45,2.59-2.09-11,1.69-22.46-.31-33.48a3,3,0,0,0-.73-1.72,3.17,3.17,0,0,0-2.4-.51c-11.48.7-23,1.4-34.34,3.2a4.31,4.31,0,0,0-2.25.82c-1.21,1.08-1.59,5.31-2,6.89-.75,3.31.08,7.37.39,10.71,1.19,12.69.41,25.42.46,38.17q.08,19.88,1,39.74,20.06,1.58,40.21,1.38C398.23,164.17,433.25,162.64,433.26,162.79Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M714.75,284.75c1.42,1.82,1.16,5.24,1.75,7.45s2,3.71,2.85,5.67c2.21,5.24-8.77,4.26-11.58,4.29l-18.26.18-52,.51L635.34,210l-2.86-3.52S622.35,250.08,616.92,266s-12.28,36-12.28,36l-14.84-6.92-2.55,7.29L571.5,303.5l-2.5-97,.75-2.25,11.8-1.16H587l1.5,3.28-.12,6.5-1.13,54.83.25,23.8,26.19-77,5.56-13.75L620,194l13,3.25,2.34,2.5-1.1,4.5,18.27-1.2,2.69,3.45,1.1,2.25V195l8-.33s31,44.17,38.25,58.88" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-19" d="M714.75,284.75c1.42,1.82,1.16,5.24,1.75,7.45s2,3.71,2.85,5.67c2.21,5.24-8.77,4.26-11.58,4.29l-18.26.18-52,.51-1-42.75-.73-31.8-.27-11.63c0-1.28-.74-11.06-1.42-10.63,5.27-3.33,12.27-2.59,18.43-3l2.69,3.45,1.1,2.25V195l8-.33s31,44.17,38.25,58.88" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M635.34,199.75c-1.38,5.62-3.78,10.93-5.29,16.55-1.63,6.07-2.86,12.23-4.4,18.32-2.66,10.52-5.23,21.14-8.72,31.42-5.42,16-12.28,36-12.28,36l-14.84-6.92-2.55,7.29L571.5,303.5l-2.5-97,.75-2.25,11.8-1.16H587l1.5,3.28-.12,6.5-1.13,54.83.25,23.8,26.19-77,5.56-13.75L620,194l13,3.25Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M82,522.25l5.82-27.41,20.8,5.82,5.19,3.67L111.33,509l8.5-.68,4,.74,1.66-3V484.25l12.81-2.65h8l6.21.9,3.5.32.5,14.42L168,495.5l1.14-.66.11-13.09,16.5.75h5.91v9.65l1,2.69,5.11-5.88,4.59-.52,4.57.52,5.1.67.6,5.21,4.79-2.88,4.73-.25,3.63-1s7,15.41,8.11,18.2-.1,4.09-.1,4.09l-2,8.21L229.5,544.5l-2.88,12.27v5.56l2.63,3.86,2.76,1.43-13.26,8.62L206,587.76l-92.21.05Z" transform="translate(-53.25 -44.96)"/><g class="cls-21"><path class="cls-22" d="M82,522.25l5.82-27.41,20.8,5.82,5.19,3.67L111.33,509l8.5-.68,4,.74,1.66-3V484.25l12.81-2.65h8l6.21.9,3.5.32.5,14.42L168,495.5l1.14-.66.11-13.09,16.5.75h5.91v9.65l1,2.69,5.11-5.88,4.59-.52,4.57.52,5.1.67.6,5.21,4.79-2.88,4.73-.25,3.63-1s7,15.41,8.11,18.2-.1,4.09-.1,4.09l-2,8.21L229.5,544.5l-2.88,12.27v5.56l2.63,3.86,2.76,1.43-13.26,8.62L206,587.76l-92.21.05Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M592.09,588l14.61-9.7-.15,9.23,31.78.81,44.33-.81s8.87-18.31,18-38c9-19.49,18.24-40.34,19.36-46.2,2.25-11.78,0-5.95,0-5.95a36.4,36.4,0,0,1-5.55-.79c-1.25-.39-2.24-2.22-3.75-.67-.92.95-1,2.4-1.12,3.72-.61,7.11-3.47,13.81-5,20.78a67.44,67.44,0,0,0-1.42,17.29c.17,4.31.64,8.82-1.1,12.76s-5.5,6.72-7.62,10.51a101.78,101.78,0,0,1-.84-11.9q.65-29.68,1.3-59.37c-3.89.63-7.49-1.87-11.53-1.89a9.74,9.74,0,0,0-4.33.8,4.84,4.84,0,0,0-2.73,3.3,16.64,16.64,0,0,1-.3,2.3c-.25.74-1,1.39-1.76,1.09-1.23-.52-1.5-11.2-1.48-13-1.88-.13-20.08-1.41-20.08-1.38l-1.12,14.8-13.22,1s.25-13.54.33-14.21-31.5,1.57-31.5,1.57l-1.5,90.54-2-1.6-35.11-56.86-7.33,10.78-3,3,21.07,38.54" transform="translate(-53.25 -44.96)"/><path class="cls-11" d="M175.14,629.45a13.91,13.91,0,0,1,6.19,6.09l-.49-13.79a26.83,26.83,0,0,1,8.37,1.08,8.38,8.38,0,0,1-.92,4.7c1.39-.45,2.83.81,3.26,2.21a17.53,17.53,0,0,1,.27,4.36c.07,1.46.59,3.08,1.91,3.71.45.21,1,.29,1.42.49a5.55,5.55,0,0,1,2.35,2.88c2.91,5.91,6.45,12,12.24,15.11a28.83,28.83,0,0,0,8.88,2.75,78.46,78.46,0,0,0,10.7,1.11,9.41,9.41,0,0,1,4.68.93c1.89,1.17,2.62,3.54,3,5.73a62.61,62.61,0,0,1,.5,9.74v15.57c0,2.63-.39,5.87-2.83,6.85s-5.12-1.25-7.11-3.15a92.58,92.58,0,0,0-11-8.45c-7.57-5.3-15-10.82-22.31-16.47-8.51-6.58-16.64-13.72-25.3-20.1-6.14-4.53-9.18-8.39-8.43-16.6.31-3.47,1.82-3.48,5-3.79Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-23" d="M175.14,629.45a13.91,13.91,0,0,1,6.19,6.09l-.49-13.79a26.83,26.83,0,0,1,8.37,1.08,8.38,8.38,0,0,1-.92,4.7c1.39-.45,2.83.81,3.26,2.21a17.53,17.53,0,0,1,.27,4.36c.07,1.46.59,3.08,1.91,3.71.45.21,1,.29,1.42.49a5.55,5.55,0,0,1,2.35,2.88c2.91,5.91,6.45,12,12.24,15.11a28.83,28.83,0,0,0,8.88,2.75,78.46,78.46,0,0,0,10.7,1.11,9.41,9.41,0,0,1,4.68.93c1.89,1.17,2.62,3.54,3,5.73a62.61,62.61,0,0,1,.5,9.74v15.57c0,2.63-.39,5.87-2.83,6.85s-5.12-1.25-7.11-3.15a92.58,92.58,0,0,0-11-8.45c-7.57-5.3-15-10.82-22.31-16.47-8.51-6.58-16.64-13.72-25.3-20.1-6.14-4.53-9.18-8.39-8.43-16.6.31-3.47,1.82-3.48,5-3.79Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M560.6,661.45a34,34,0,0,0,27-8c4-3.55,7.13-8,10.2-12.41a101.21,101.21,0,0,0-3,33c5-2.15,10.08-4.38,13.87-8.25a42,42,0,0,0,5.77-8.14,71.54,71.54,0,0,0,6.35-12.44c.93-2.62,1.55-5.34,2.28-8a104.45,104.45,0,0,1,4.87-14,1.57,1.57,0,0,1,.44-.67,1.54,1.54,0,0,1,1-.19,25,25,0,0,1,13.82,5.09c-5.61,4.68-5.11,13.61-9.43,19.5a27.5,27.5,0,0,1-6.13,5.57q-18.32,13.5-37.27,26.11-9.35,6.22-18.84,12.22c-1.75,1.1-6.93,5.66-9,5.23-2.86-.6-1.62-6.71-1.62-8.86S561.4,661.57,560.6,661.45Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-23" d="M560.6,661.45a34,34,0,0,0,27-8c4-3.55,7.13-8,10.2-12.41a101.21,101.21,0,0,0-3,33c5-2.15,10.08-4.38,13.87-8.25a42,42,0,0,0,5.77-8.14,71.54,71.54,0,0,0,6.35-12.44c.93-2.62,1.55-5.34,2.28-8a104.45,104.45,0,0,1,4.87-14,1.57,1.57,0,0,1,.44-.67,1.54,1.54,0,0,1,1-.19,25,25,0,0,1,13.82,5.09c-5.61,4.68-5.11,13.61-9.43,19.5a27.5,27.5,0,0,1-6.13,5.57q-18.32,13.5-37.27,26.11-9.35,6.22-18.84,12.22c-1.75,1.1-6.93,5.66-9,5.23-2.86-.6-1.62-6.71-1.62-8.86S561.4,661.57,560.6,661.45Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M618.76,481.46c-3.58,0-7.92.36-9.5,3.58a9.59,9.59,0,0,0-.68,4.06l-2.13,98.17a180.81,180.81,0,0,0,34.45-.75c-2.21-6.75-2.28-14-2.32-21.09l-.17-28.76a101.28,101.28,0,0,1,.41-12c.47-4.13,1.45-8.2,1.66-12.35.25-4.95-.6-9.85-.78-14.79-.12-3.56,1.07-7.89-.42-11.27C636.27,479.39,624.51,481.52,618.76,481.46Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-23" d="M652.25,544q.42-27.32-.87-54.62c-.13-2.8,0-6.14,2.34-7.64a8,8,0,0,1,4.52-.82l11.28.18a2.46,2.46,0,0,1,3,2.44l1.86,9.92c1.53-.69,1.42-3.21,2.93-3.93a3.4,3.4,0,0,1,1.64-.2A117.76,117.76,0,0,1,694.3,491a1.45,1.45,0,0,1,1.53,1.88l-3.67,40.48a59.81,59.81,0,0,0-.35,9.87c.26,3.51,1.15,6.95,1.53,10.45a48.07,48.07,0,0,1-.17,10.79,10.67,10.67,0,0,1-.59,2.76,12.66,12.66,0,0,1-2.09,3.11,67.57,67.57,0,0,0-10.11,17.14,147.26,147.26,0,0,0-16.07-.7c-3.72,0-9.24,1.46-12.55-.81-2.9-2-2.75-5.51-2.27-8.6.83-5.29,1.67-10.51,2.07-15.86C652,555.68,652.16,549.82,652.25,544Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-21"><path class="cls-22" d="M590.16,587.71c-1.45-5.44-5.88-9.46-9.16-14-5.17-7.2-7.61-16.07-12.71-23.33a50.69,50.69,0,0,1-3.54-5.18c-.9-1.69-1.47-3.54-2.34-5.24-1-2-2.55-4-2.77-6.23a11.73,11.73,0,0,1,1.12-5.19c1.69-4.42,3.58-9.11,7.45-11.83,5.85,6.16,8.57,14.61,13.45,21.56,1.1,1.56,2.3,3,3.44,4.56A135.37,135.37,0,0,1,593.95,557q2.83,5,5.65,10,1.41,2.5,2.8,5c.74,1.34,2.23,3.11,2.42,4.65.31,2.54-3.39,4-5.15,5.19Q595.06,585,590.16,587.71Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-21"><path class="cls-22" d="M639.06,496.73c-1.32,8.89-1.12,17.92-.91,26.91l.18,7.91c.31,13.59.63,27.17.85,40.76a79.15,79.15,0,0,1-.68,14.6l11.23-1.48q1.41-23.59,1.67-47.24c.07-6.84.07-13.68.08-20.52v-8.08c0-2.4,0-4.79-.09-7.19-.06-1.61.23-4.24-.84-5.61S639.17,496,639.06,496.73Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M709.39,497.13a.65.65,0,0,0-.78.67l-3.88,25.33c-1,6.83-2.1,13.74-1.52,20.62,4.23-4.28,5.51-10.58,8.36-15.89,1.36-2.54,3.1-4.87,4.28-7.5a39.23,39.23,0,0,0,2.33-8.3c.85-4.17,2.49-9.42,1.85-13.69-.32-2.18-1.46-1.82-3.46-1.69Z" transform="translate(-53.25 -44.96)"/></g></g><g id="DETAILS"><path class="cls-24" d="M636.33,431.17a1.5,1.5,0,0,1-1.46-1.14c-.77-3.17-.62-6.77-.48-10.25.05-1.32.11-2.57.11-3.77a1.5,1.5,0,0,1,3,0c0,1.26-.05,2.6-.11,3.89-.13,3.28-.27,6.67.4,9.42a1.5,1.5,0,0,1-1.46,1.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M177.34,430.83h-.21a1.5,1.5,0,0,1-1.28-1.69,37.15,37.15,0,0,0-.09-7.5c-.13-1.65-.26-3.35-.26-5a1.5,1.5,0,0,1,3,0c0,1.5.12,3.07.25,4.73a39.23,39.23,0,0,1,.07,8.14A1.5,1.5,0,0,1,177.34,430.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M569,342.17a1.5,1.5,0,0,1-.73-.19c-.63-.35-1.23-.71-1.83-1.07-2.38-1.43-4.43-2.67-7.31-2.41a1.5,1.5,0,1,1-.27-3c3.84-.34,6.53,1.27,9.12,2.83.57.34,1.14.69,1.74,1a1.5,1.5,0,0,1-.73,2.81Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M569,341.5a1.5,1.5,0,0,1-1.42-1,17.5,17.5,0,0,1-.48-6.45c0-.7.07-1.39.07-2a1.5,1.5,0,0,1,3,0c0,.7,0,1.44-.07,2.19a15.14,15.14,0,0,0,.32,5.32,1.5,1.5,0,0,1-1.42,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M700.66,342.78a1.44,1.44,0,0,1-.71-.18,1.46,1.46,0,0,1-.59-2l0-.08c1.39-2.46,3.29-5.84,3.43-8.59a1.5,1.5,0,0,1,3,.15c-.18,3.46-2.28,7.19-3.81,9.91A1.58,1.58,0,0,1,700.66,342.78Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M701,343.83a1.5,1.5,0,0,1-.85-2.74,24.7,24.7,0,0,1,9.93-3.58,1.5,1.5,0,0,1,.5,3,21.84,21.84,0,0,0-8.74,3.09A1.49,1.49,0,0,1,701,343.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M242.33,343.5a1.5,1.5,0,0,1-1.32-2.21l.54-1c1.08-1.95,2.57-4.61,3-6.9a1.5,1.5,0,1,1,3,.52c-.49,2.79-2.11,5.71-3.3,7.84l-.52.95A1.5,1.5,0,0,1,242.33,343.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M243.26,342.84l-.4,0a1.5,1.5,0,1,1,.28-3,28.1,28.1,0,0,0,6.41-1.27,1.5,1.5,0,0,1,.9,2.86A32.77,32.77,0,0,1,243.26,342.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.33,344.17a1.5,1.5,0,0,1-1.41-1c-.71-1.92-4.84-5.23-6.7-5.36a1.5,1.5,0,0,1,.21-3c3.27.23,8.26,4.49,9.3,7.31a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M109.67,343.5a1.5,1.5,0,0,1-1.38-.9c-1-2.2-1.91-9.32.22-11.89a1.5,1.5,0,1,1,2.31,1.91c-1,1.17-.69,6.68.22,8.78a1.5,1.5,0,0,1-1.37,2.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.83,217.59c-3.24,0-6.29-.39-8.5-1.78a1.25,1.25,0,0,1,1.33-2.11c3,1.87,8.76,1.43,13.43,1.07,1.78-.14,3.47-.26,4.9-.26,3.17,0,6.77-.09,9.56-1.17a1.25,1.25,0,0,1,.9,2.33C234.27,216.9,230.38,217,227,217c-1.33,0-3,.12-4.71.26C220.18,217.42,218,217.59,215.83,217.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.7,222.35c-3.13,0-6.2-.35-8.59-1.77a1.25,1.25,0,1,1,1.28-2.15c3,1.77,7.8,1.49,12,1.24,1.43-.08,2.77-.16,4-.16.82,0,1.7,0,2.59.06,2.9.1,5.89.21,8-.71a1.25,1.25,0,1,1,1,2.29c-2.61,1.14-6,1-9.06.92-.86,0-1.71-.06-2.5-.06-1.15,0-2.47.08-3.86.16C219,222.25,217.34,222.35,215.7,222.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M220.25,211.33c-1.06,0-2.08-.74-3-2.2-1.12-1.69-1.28-6.22.52-7.53.38-.27,1.73-1,3.25.87A1.25,1.25,0,0,1,219,204a7.39,7.39,0,0,0,0,3,1.25,1.25,0,0,1,.73-.95,4.58,4.58,0,0,1,2.71-.3,1.25,1.25,0,0,1,1,1.47c-.59,3-1.82,3.82-2.75,4A2.33,2.33,0,0,1,220.25,211.33Zm-.47-2.92a1.84,1.84,0,0,0,.45.39,1.47,1.47,0,0,0,.22-.32A1.26,1.26,0,0,1,219.78,208.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M226.3,210.34a3.82,3.82,0,0,1-1-.15,2.84,2.84,0,0,1-2-2,8.61,8.61,0,0,1,1.22-6.48,3.12,3.12,0,0,0,1.05-.76,1.25,1.25,0,0,1,1.72.41c.31.5,2.64,5.81,1,8A2.38,2.38,0,0,1,226.3,210.34Zm-.38-5.79a5.77,5.77,0,0,0-.2,2.89c.09.31.19.33.23.34a1,1,0,0,0,.4.05C226.61,207.44,226.32,205.89,225.92,204.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M218.77,281.3c-4.57,0-9.06-.65-11-3.31a1.25,1.25,0,1,1,2-1.48c2.21,3,11.17,2.31,16,1.94,1.14-.09,2.15-.17,3-.2,3.06-.12,7.16-1.07,8.9-2.87a1.25,1.25,0,0,1,1.79,1.74c-2.39,2.46-7.2,3.49-10.6,3.63-.79,0-1.77.11-2.87.19C223.8,281.11,221.27,281.3,218.77,281.3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.15,285c-4.72,0-9.85-.19-14.16-2.12a1.25,1.25,0,1,1,1-2.28c4.34,1.95,9.67,1.92,14.82,1.9h1.82c2.67,0,8.25,0,10.18-2.09a1.25,1.25,0,1,1,1.84,1.69c-2.67,2.92-8.75,2.91-12,2.91h-3.49Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M260.15,291.5c-5.17,0-12.44-6.59-14.82-9.15a1.25,1.25,0,1,1,1.83-1.7c3.24,3.49,9.38,8.35,13,8.35h.11a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.75,289a1.24,1.24,0,0,1-.31,0c-5.06-1.3-11.1-5.88-14.85-9.85a1.25,1.25,0,0,1,1.82-1.72c3.38,3.59,9.1,8,13.65,9.15a1.25,1.25,0,0,1-.31,2.46Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M297.25,229.5l-.23,0c-4.42-.83-9.93-2.35-13.26-6.72a1.25,1.25,0,0,1,2-1.52c2.82,3.69,7.75,5,11.74,5.78a1.25,1.25,0,0,1-.23,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M299.5,227.5h0c-3.75,0-7.37-2.34-10.56-4.39a43.46,43.46,0,0,0-3.75-2.25,1.25,1.25,0,1,1,1.12-2.23,44.92,44.92,0,0,1,4,2.38c3,2,6.19,4,9.21,4a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M302.75,224.25h-.07c-4.22-.24-7.69-3.18-10.75-5.78-1.18-1-2.3-1.94-3.39-2.69a1.25,1.25,0,0,1,1.41-2.06,45.3,45.3,0,0,1,3.59,2.85c2.9,2.45,5.89,5,9.27,5.19a1.25,1.25,0,0,1-.07,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M225.2,288.58a84.79,84.79,0,0,1-18-1.61,1.25,1.25,0,0,1,.53-2.44c9,1.94,18.55,1.63,27.82,1.33l3.38-.11a1.25,1.25,0,0,1,.07,2.5l-3.37.11C232.21,288.47,228.71,288.58,225.2,288.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M203.42,226.89a23.26,23.26,0,0,1-6.81-1.45,1.25,1.25,0,0,1,.78-2.37c1.72.57,5.76,1.9,7.58,1.05a1.25,1.25,0,1,1,1.05,2.27A6.16,6.16,0,0,1,203.42,226.89Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M203.75,230.5h0a24.26,24.26,0,0,1-4.32-.53,19.58,19.58,0,0,0-3.91-.47h0a1.25,1.25,0,0,1,0-2.5,22.23,22.23,0,0,1,4.4.51,22.07,22.07,0,0,0,3.88.49,1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M204.21,291.25a17,17,0,0,1-3.78-.54,17.39,17.39,0,0,0-2.75-.47,1.25,1.25,0,0,1-1.17-1.32,1.24,1.24,0,0,1,1.32-1.17,19.55,19.55,0,0,1,3.15.52,13.65,13.65,0,0,0,3.48.48,1.25,1.25,0,0,1,.08,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.25,211.87c-.81,0-1.63,0-2.42-.06s-1.28-.05-1.83-.05a1.25,1.25,0,0,1,0-2.5h0c.58,0,1.23,0,1.93.05,2,.08,4.55.18,5.76-.42a1.25,1.25,0,0,1,1.11,2.24A10.66,10.66,0,0,1,183.25,211.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M182.34,216.06a6,6,0,0,1-3-.5,1.25,1.25,0,0,1,1.28-2.15,15.14,15.14,0,0,0,3.34.11l1.28,0a1.25,1.25,0,0,1,0,2.5l-1.2,0C183.43,216,182.86,216.06,182.34,216.06Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M184.5,286.5h-.25a1.25,1.25,0,0,1,0-2.5h.25a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M162.75,220.25a30,30,0,0,1-6.77-.53,1.25,1.25,0,1,1,.55-2.44,27.88,27.88,0,0,0,6.17.47l.05,1.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M160,229a1.25,1.25,0,0,1-.42-.07c-.27-.09-.63-.26-1-.45s-.71-.33-1.06-.47a1.25,1.25,0,0,1-2-.8,1.55,1.55,0,0,1,.56-1.52c.91-.7,2.12-.13,3.53.53.32.15.61.29.82.36A1.25,1.25,0,0,1,160,229Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M159,295.25a1.25,1.25,0,0,1-.73-2.26,7,7,0,0,1,2.65-1l.75-.18a1.25,1.25,0,1,1,.67,2.41l-.86.21a5.26,5.26,0,0,0-1.74.6A1.24,1.24,0,0,1,159,295.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M121.9,229.57a22.28,22.28,0,0,1-5.46-.61,1.25,1.25,0,0,1,.61-2.42,25,25,0,0,0,8.56.33l1-.09c2.75-.25,7.34-.67,9.07-2.21a1.25,1.25,0,1,1,1.66,1.87c-2.35,2.09-7.26,2.54-10.51,2.84l-1,.09C124.43,229.5,123.12,229.57,121.9,229.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M119,234.75a1.25,1.25,0,0,1,0-2.5c1.84,0,3.7-.15,5.49-.28,1.06-.08,2.13-.16,3.2-.22a1.25,1.25,0,0,1,.13,2.5c-1.05.05-2.1.13-3.14.21-1.84.14-3.74.28-5.67.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M130.92,292.79c-.6,0-1.2,0-1.75-.06l-.4,0a1.25,1.25,0,0,1-1-.66,1.87,1.87,0,0,1-.22-1.13,1.27,1.27,0,0,1,1.11-1.4,1.24,1.24,0,0,1,1.29.74c1.71.08,3.4.05,4.51-.94a1.25,1.25,0,1,1,1.67,1.86A7.39,7.39,0,0,1,130.92,292.79Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M100.65,293a16.77,16.77,0,0,1-6.1-1.1,1.25,1.25,0,0,1,.91-2.33,14.75,14.75,0,0,0,6,.92,1.25,1.25,0,1,1,.12,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M103,253.75H96.75a1.25,1.25,0,0,1,0-2.5H103a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M316.38,201.63a28.3,28.3,0,0,1-4.06-.39,1.25,1.25,0,1,1,.35-2.47h0c2.75.4,4.92.71,7.29-.4a1.25,1.25,0,1,1,1.06,2.26A10.62,10.62,0,0,1,316.38,201.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M315.5,206h0a4,4,0,0,1-2.92-1.45,1.25,1.25,0,1,1,1.92-1.6,1.47,1.47,0,0,0,1.08.55,1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.84,298.77a10.29,10.29,0,0,1-3-.57,8,8,0,0,0-2.3-.45,1.25,1.25,0,0,1-.06-2.5,9.52,9.52,0,0,1,3.08.55,7.1,7.1,0,0,0,2.6.45,1.25,1.25,0,1,1,.21,2.49Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M315.81,294a2,2,0,0,1-1.5-.7A1.25,1.25,0,0,1,316,291.5h0a1.25,1.25,0,0,1,.26,2.47A2.16,2.16,0,0,1,315.81,294Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M331.74,237.75a12.81,12.81,0,0,1-4.15-.82,1.25,1.25,0,1,1,.81-2.37,10.12,10.12,0,0,0,3.55.68,1.25,1.25,0,1,1,.09,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M367.76,250.38c-1,0-2,0-3-.07-1.61-.06-3.14-.07-4.72,0-2.81.1-5.73.2-8.4-1.19a1.25,1.25,0,1,1,1.15-2.22c2.1,1.09,4.56,1,7.17.91,1.64-.06,3.23,0,4.9,0,3,.1,6.07.21,8.68-.74a1.25,1.25,0,1,1,.85,2.35A19.37,19.37,0,0,1,367.76,250.38Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M366.25,253.75c-4,0-7.73-.17-11.37-.51a1.25,1.25,0,0,1,.23-2.49c3.56.33,7.2.49,11.13.49a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M404.37,234.9a10.12,10.12,0,0,1-2.15-.23,10.85,10.85,0,0,1-7.26-5,10.7,10.7,0,0,1-.75-8.67c1.15-3.67,5.93-7.72,10.18-7.23,7.43.77,10.94,7.22,10.61,11.58a10.23,10.23,0,0,1-4.18,7.39A10.8,10.8,0,0,1,404.37,234.9Zm-.69-18.68c-2.82,0-6.29,3-7.09,5.52a8.24,8.24,0,0,0,.53,6.67,8.39,8.39,0,0,0,5.63,3.82,8.13,8.13,0,0,0,6.57-1.51,7.74,7.74,0,0,0,3.18-5.57c.24-3.26-2.6-8.31-8.38-8.91h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M416.68,242.27c-2.57,0-5.17,0-7.74-.14-1.52-.07-3-.16-4.58-.25-3.16-.19-6.45-.35-9.62-.37-.59,0-1.3,0-2.08.07-2.88.14-6.14.3-7.83-.77a1.25,1.25,0,0,1,1.33-2.12c1,.64,4.24.49,6.38.39.89,0,1.67-.08,2.34-.08,3.22,0,6.48.19,9.63.38,1.52.09,3,.18,4.54.25,3.52.16,7.14.15,10.64.13h3.05a1.25,1.25,0,0,1,0,2.5h-6.07Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M432.44,215.28c-.42,0-.84,0-1.25,0a1.25,1.25,0,1,1,.12-2.5,57.87,57.87,0,0,0,8.39-.51c2.29-.25,4.45-.48,6.3-.49h0a1.25,1.25,0,0,1,0,2.5c-1.72,0-3.82.23-6,.47A72.52,72.52,0,0,1,432.44,215.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M430.5,219.5a1.25,1.25,0,0,1-.23-2.48,76.8,76.8,0,0,1,14.48-1,1.25,1.25,0,0,1,0,2.5,74.64,74.64,0,0,0-14,1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M456.75,222c-.43,0-.87,0-1.3,0a1.25,1.25,0,0,1-1.1-1.68c.67-1.81,1.26-3.74,1.83-5.61.72-2.38,1.47-4.84,2.42-7.15a1.25,1.25,0,0,1,2.27-.08,32.87,32.87,0,0,0,2.57,4c2.06,2.9,4.19,5.89,4,8.87a1.25,1.25,0,0,1-1.25,1.18h0a39.69,39.69,0,0,0-4.91.25C459.8,221.86,458.29,222,456.75,222ZM460,210.86c-.52,1.49-1,3-1.44,4.53-.41,1.35-.83,2.74-1.29,4.1,1.23,0,2.48-.14,3.77-.26s2.52-.23,3.81-.27c-.44-1.86-2-4-3.45-6.1C460.93,212.21,460.45,211.53,460,210.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M460.45,247.43a5.05,5.05,0,0,1-4.72-2.68c-1.77-3.28-.51-8.47,1.76-10.75a3.53,3.53,0,0,1,4.22-.91c3.38,1.05,5.33,5.14,5.2,8.38a5.74,5.74,0,0,1-4.7,5.77A8.85,8.85,0,0,1,460.45,247.43Zm-.21-12.19a1.42,1.42,0,0,0-1,.53c-1.57,1.58-2.5,5.64-1.33,7.8.24.45,1,1.8,3.79,1.23a3.28,3.28,0,0,0,2.7-3.41c.1-2.59-1.54-5.35-3.52-5.92a1.25,1.25,0,0,1-.24-.1A.86.86,0,0,0,460.24,235.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M461.06,273.63a15,15,0,0,1-3.85-.46,1.25,1.25,0,0,1-.92-1.17c0-.92-.15-1.86-.27-2.85a23.47,23.47,0,0,1-.27-4.48,1.27,1.27,0,0,1,.1-.42,12.49,12.49,0,0,1,7.33-6.77,3.17,3.17,0,0,1,2.82.29c1.53,1.12,1.8,4.45,1.75,9.83,0,.5,0,.9,0,1.15V269c.08,2.88-.22,3.68-3.23,4.32A16.94,16.94,0,0,1,461.06,273.63Zm-2.33-2.69a15.17,15.17,0,0,0,5.28-.11,8.3,8.3,0,0,0,1.24-.33,10.35,10.35,0,0,0,0-1.47v-.22c0-.28,0-.71,0-1.24.05-5.74-.38-7.41-.75-7.8-.79-.27-4.62,1.71-6.27,5.28a22.69,22.69,0,0,0,.27,3.79C458.59,269.53,458.67,270.23,458.73,270.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M499.19,228.22a9.21,9.21,0,0,1-1.77-.17c-4.48-.87-6.68-3.57-6.92-8.47-.19-3.88,1.83-10.92,6-13.49a6.41,6.41,0,0,1,6.88.07,1.25,1.25,0,0,1-1.23,2.18,4,4,0,0,0-4.34-.12c-3.12,1.93-5,8-4.8,11.24.19,3.77,1.56,5.49,4.9,6.14,2.67.52,5.84-.58,6.76-3.7.62-2.12-.39-6.15-2.41-7.65a2.53,2.53,0,0,0-3.18.08c-.92.6-2.12,3.18-2.24,5.5-.06,1.18.19,1.82.45,2a1,1,0,0,0,1.2.09,1.88,1.88,0,0,0,.89-1.13,1.29,1.29,0,0,1-.42-1.63,1.21,1.21,0,0,1,1.61-.56,2.32,2.32,0,0,1,1.32,2.15,4.19,4.19,0,0,1-2.43,3.49,3.43,3.43,0,0,1-3.74-.46c-1-.8-1.47-2.22-1.37-4.1.14-2.62,1.46-6.22,3.37-7.46a5,5,0,0,1,6,0c2.94,2.19,4.2,7.37,3.32,10.36A8,8,0,0,1,499.19,228.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M496.25,258.25A1.25,1.25,0,0,1,495,257a38,38,0,0,1,.89-8.09c.27-1.5.53-2.92.68-4.3.06-.55.09-1.32.12-2.21.12-3.34.26-7.49,2.26-9.16a1.25,1.25,0,0,1,1.93.44c.62,1.34,1.31,2.72,2,4.05.49,1,1,1.95,1.45,2.92.17.36.41.8.67,1.29,1.5,2.84,2.72,5.34,2.52,7.25-.26,2.38-2.82,3.8-5.29,5.17a15.92,15.92,0,0,0-3.27,2.14,1.25,1.25,0,0,1-1.36.28l-.07,0s0,.1,0,.15a1.25,1.25,0,0,1-1.2,1.3Zm3.59-10.6a39.39,39.39,0,0,0-.52,5.53c.54-.33,1.1-.64,1.66-.95l1-.58a1.24,1.24,0,0,1-.52-.4A12.68,12.68,0,0,1,499.84,247.65Zm-.17-4.88a1.25,1.25,0,0,1,1.06.59,16,16,0,0,1,1.44,3.39,11.14,11.14,0,0,0,1.32,3,1.24,1.24,0,0,1,.25.8A2.77,2.77,0,0,0,505,249c.14-1.3-1.35-4.12-2.24-5.81-.28-.52-.52-1-.71-1.37-.46-1-.95-1.93-1.43-2.89l-.93-1.86a32.17,32.17,0,0,0-.52,5.49v.33a1.24,1.24,0,0,1,.47-.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M493.31,296.12a1.23,1.23,0,0,1-1-.54c-.24-.34-.51-1,.32-1.93a1.25,1.25,0,0,1,1.77-.07,1.17,1.17,0,0,1,.15.17,1.25,1.25,0,0,1-.25,2.14A2.35,2.35,0,0,1,493.31,296.12Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M501.16,296a1.21,1.21,0,0,1-.92-.39c-.37-.42-.61-1.1.33-2a1.29,1.29,0,0,1,1.8,0,1.21,1.21,0,0,1,0,1.73l-.14.13a1.2,1.2,0,0,1-.17.17A1.4,1.4,0,0,1,501.16,296Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M507.58,295.18h-.17a1.33,1.33,0,0,1-1.16-1.3,1.37,1.37,0,1,1,2.67,0l0,.08C508.63,294.79,508.19,295.18,507.58,295.18Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M494.91,292.32c-1.58,0-3.16,0-4.72,0s-3.13,0-4.69,0a1.25,1.25,0,0,1,0-2.5c1.57,0,3.14,0,4.72,0a135.16,135.16,0,0,0,14.23-.34c.88-.08,1.9-.13,3-.18,2.7-.12,6.06-.26,7.75-1.14a1.25,1.25,0,1,1,1.14,2.22c-2.18,1.12-5.69,1.28-8.78,1.41-1,0-2,.09-2.86.17C501.45,292.25,498.17,292.32,494.91,292.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476.59,238.29l-2.13,0-2,0a1.25,1.25,0,1,1,0-2.5h0l2,0a37.3,37.3,0,0,0,8.23-.49,1.25,1.25,0,1,1,.54,2.44A31.24,31.24,0,0,1,476.59,238.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M482,243c-1.25,0-2.52-.07-3.74-.15a42.49,42.49,0,0,0-4.93-.11,1.25,1.25,0,0,1-.14-2.5,45.62,45.62,0,0,1,5.22.11c1.19.07,2.43.14,3.6.14a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M472.5,233a1.25,1.25,0,0,1,0-2.5c1.46,0,2.95-.13,4.39-.25a48.2,48.2,0,0,1,5.41-.25,1.25,1.25,0,0,1,1.21,1.29,1.27,1.27,0,0,1-1.29,1.21,45.31,45.31,0,0,0-5.12.24c-1.49.13-3,.26-4.59.26Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M473,227.25a1.25,1.25,0,0,1-.31-2.46,40.15,40.15,0,0,1,11.14-1,1.25,1.25,0,1,1-.15,2.5,37.41,37.41,0,0,0-10.36,1A1.25,1.25,0,0,1,473,227.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M518.75,239.75a1.25,1.25,0,0,1,0-2.5c2.07,0,5.69-.13,9-.25a1.25,1.25,0,1,1,.09,2.5C524.51,239.62,520.86,239.75,518.75,239.75Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M517.75,235.5a1.25,1.25,0,0,1-.19-2.49,39.94,39.94,0,0,1,6.62-.28l1.82,0a1.25,1.25,0,0,1,0,2.5l-1.85,0a38.16,38.16,0,0,0-6.21.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M542.16,236.15a7.76,7.76,0,0,1-.82,0,5.72,5.72,0,0,1-4.17-2.31,6.49,6.49,0,0,1-.72-5.35,3.89,3.89,0,0,1,2.29-2.58c3-1.57,8.68-3.08,11.54-1.37a3.39,3.39,0,0,1,1.72,2.66c.25,2.56-2.09,5.4-3.36,6.54A10.13,10.13,0,0,1,542.16,236.15Zm4.82-9.92a17.25,17.25,0,0,0-7.15,1.88l-.18.08a1.42,1.42,0,0,0-.82,1,4,4,0,0,0,.36,3.13,3.24,3.24,0,0,0,2.41,1.29,7.54,7.54,0,0,0,5.36-1.8c1.32-1.19,2.66-3.26,2.54-4.44a.91.91,0,0,0-.51-.75A4.07,4.07,0,0,0,547,226.23Zm-7.73.77h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M538.5,227.75a1.25,1.25,0,0,1-1-.45,4.76,4.76,0,0,1-.92-2,1.25,1.25,0,0,1,1.09-1.48,3.57,3.57,0,0,1,2.5.67,2.31,2.31,0,0,1-1.7,3.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M549.25,226a1.72,1.72,0,0,0-2.39-.31,1.25,1.25,0,0,1-.79-1.58,3.66,3.66,0,0,1,1.82-2.2,1.25,1.25,0,0,1,1.72.66,5.17,5.17,0,0,0,.29.57,5.47,5.47,0,0,1,.57,1.31,1.25,1.25,0,0,1-1.21,1.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M533,244a1.25,1.25,0,0,1-.51-2.39c4.39-1.94,9.74-3,14.45-4,1.23-.25,2.43-.5,3.59-.76l1.25-.28a41.06,41.06,0,0,1,5.87-1,1.25,1.25,0,1,1,.19,2.49,39.3,39.3,0,0,0-5.51,1l-1.26.29c-1.17.26-2.38.51-3.62.76-4.82,1-9.8,2-13.95,3.85A1.25,1.25,0,0,1,533,244Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M538.5,293.5a1.25,1.25,0,0,1,0-2.5,79.17,79.17,0,0,0,18.59-2.62c.84-.21,1.75-.38,2.72-.56a20.92,20.92,0,0,0,5.82-1.65,1.25,1.25,0,0,1,1.25,2.17,22,22,0,0,1-6.6,1.94c-.93.18-1.81.34-2.59.53a81.57,81.57,0,0,1-19.18,2.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M541.59,299.51h-.87a1.25,1.25,0,0,1,0-2.5h0c7.63.21,15.26-2.72,22.6-5.55l2.92-1.12a1.25,1.25,0,0,1,.88,2.34l-2.91,1.11C557,296.6,549.45,299.51,541.59,299.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M572.38,217.43a8,8,0,0,1-3.12-.53,1.25,1.25,0,0,1,1-2.3c1.75.74,4.88.13,7.64-.41a32.09,32.09,0,0,1,4.32-.66c.54,0,1.08-.08,1.63-.13a19.47,19.47,0,0,1,3.27-.14,1.25,1.25,0,0,1,1.16,1.33,1.23,1.23,0,0,1-1.33,1.16,17.49,17.49,0,0,0-2.85.13c-.58.06-1.17.11-1.75.14a30.63,30.63,0,0,0-4,.62A32.48,32.48,0,0,1,572.38,217.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M584.5,221H571a1.25,1.25,0,0,1,0-2.5h13.5a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.25,283.25c-2.46,0-4.94-.13-7.34-.26-2.84-.15-5.78-.31-8.63-.24h0a1.25,1.25,0,0,1,0-2.5c2.94-.07,5.93.09,8.82.24,2.37.13,4.82.26,7.21.26a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M588.5,286.75H572.75a1.25,1.25,0,0,1,0-2.5H588.5a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M632,210h-.12a37.79,37.79,0,0,1-14-4.64,1.25,1.25,0,1,1,1.18-2.2,35.33,35.33,0,0,0,13,4.36A1.25,1.25,0,0,1,632,210Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M631.25,215.75a1.25,1.25,0,0,1-.42-.07c-1.36-.49-2.75-1.08-4.22-1.71-3.66-1.56-7.44-3.17-10.88-3.22a1.25,1.25,0,1,1,0-2.5c3.93.05,7.94,1.76,11.82,3.42,1.44.61,2.79,1.19,4.08,1.66a1.25,1.25,0,0,1-.42,2.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.66,291.29a4.59,4.59,0,0,1-4.13-2.24,6.26,6.26,0,0,1,.39-6.52,4.15,4.15,0,0,1,4.34-1.75,1.25,1.25,0,0,1,.84.62,5,5,0,0,1-.73,9.86A6.58,6.58,0,0,1,599.66,291.29Zm-1.06-7.92a2,2,0,0,0-.66.61,3.81,3.81,0,0,0-.26,3.8,2.25,2.25,0,0,0,2.42,1,2.52,2.52,0,0,0-.52-5A1.25,1.25,0,0,1,598.6,283.37Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M639.25,294a1.25,1.25,0,0,1-.7-2.28c2.92-2,11-1.56,14.28-.67a1.25,1.25,0,1,1-.65,2.41c-3.16-.86-10.25-1-12.22.33A1.25,1.25,0,0,1,639.25,294Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M636,217.5a1.25,1.25,0,0,1-.61-2.34c3.3-1.83,11.37-3.43,15.33-1.81a1.25,1.25,0,1,1-.95,2.31c-3.11-1.27-10.41.15-13.17,1.69A1.25,1.25,0,0,1,636,217.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M643.45,235.79a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.64-5.27,5.59-4.85h0a5.23,5.23,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M645.13,254.09a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.65-5.27,5.59-4.85h0a5.22,5.22,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M644.82,272.38a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.65-5.26,5.59-4.85h0a5.22,5.22,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M675.75,217a1.25,1.25,0,0,1-.53-.12c-.87-.41-2.74-.3-4.24-.21-.65,0-1.26.07-1.79.07-1.54,0-3.14-.06-4.66-.13s-2.86-.12-4.29-.12a1.25,1.25,0,0,1,0-2.5h0c1.48,0,3,.07,4.39.13s2.95.12,4.42.12h.12c.49,0,1.05,0,1.65-.07,1.87-.11,4-.24,5.44.44a1.25,1.25,0,0,1-.53,2.38Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.5,228.25a1.26,1.26,0,0,1-.47-.09,13.36,13.36,0,0,0-3.59-.54l-1.28-.1a67.49,67.49,0,0,1-12.24-2.62,1.25,1.25,0,0,1-.44-2.18c2.77-2.21,6.45-3.5,10-4.74a49.15,49.15,0,0,0,6.44-2.59,1.25,1.25,0,0,1,1.16,2.21,51.72,51.72,0,0,1-6.78,2.73,47.88,47.88,0,0,0-7.06,2.89,53.81,53.81,0,0,0,9.15,1.8l1.22.09a14.9,14.9,0,0,1,4.35.72,1.25,1.25,0,0,1-.47,2.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M666.44,283.13c-4.71,0-5.74-.45-6.11-1.44a1.25,1.25,0,0,1,2.06-1.32c1.56.5,9.36.15,12.74,0,1.5-.07,2.72-.12,3.38-.13h0a1.25,1.25,0,0,1,.44.08,1.31,1.31,0,0,1,.91,1.26,1.29,1.29,0,0,1-.95,1.21,1.25,1.25,0,0,1-1.4,0l-2.28.1C671.4,283,668.55,283.13,666.44,283.13Zm12.8-.63h0Zm-16.58-1.7h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M239,158.58l-.21,0a73.4,73.4,0,0,1-10.64-2.37,57.77,57.77,0,0,1-5.62-2.28c-3.74-1.67-7.61-3.36-10.84-3.33a1.23,1.23,0,0,1-1.27-1.22,1.25,1.25,0,0,1,1.23-1.27c3.8-.07,7.92,1.76,11.91,3.54a56.19,56.19,0,0,0,5.36,2.19,71.43,71.43,0,0,0,10.3,2.29,1.25,1.25,0,0,1-.21,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M240.33,154.58h-.07a23.16,23.16,0,0,1-7.07-1.93c-.85-.33-1.73-.68-2.59-1-1.62-.55-3.37-1-5.22-1.47-4.74-1.21-9.64-2.47-13.21-5.61a1.25,1.25,0,1,1,1.65-1.87c3.12,2.75,7.72,3.93,12.17,5.06,1.81.46,3.69.94,5.4,1.52.92.31,1.83.67,2.71,1a21,21,0,0,0,6.3,1.76,1.25,1.25,0,0,1-.07,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M200,158.92c-2.45,0-4.2-1.83-4.39-4.59s1.22-5.62,3.88-5.9h0a1.25,1.25,0,0,1,1.6-.57,7,7,0,0,1,3.75,7.29,4.58,4.58,0,0,1-4.71,3.77Zm.62-8.5a1.25,1.25,0,0,1-.87.49c-1.09.12-1.75,1.8-1.65,3.25,0,.7.35,2.32,2,2.26a2.12,2.12,0,0,0,2.33-1.74A4.57,4.57,0,0,0,200.66,150.42Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M252.67,154.58a1.25,1.25,0,0,1,0-2.5,39,39,0,0,0,7.44-.64,1.25,1.25,0,1,1,.47,2.46,41.36,41.36,0,0,1-7.9.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M252.33,149.92a1.25,1.25,0,0,1-.21-2.48,18.9,18.9,0,0,1,2.8-.19,9.51,9.51,0,0,0,3.21-.37,1.25,1.25,0,1,1,1.07,2.26,10.79,10.79,0,0,1-4.24.62,16.86,16.86,0,0,0-2.41.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M295.33,148.92a1.25,1.25,0,0,1-.1-2.5c1.15-.09,2.34-.12,3.5-.16a37.78,37.78,0,0,0,6-.49,1.25,1.25,0,0,1,.48,2.45,39.59,39.59,0,0,1-6.44.54c-1.17,0-2.28.07-3.37.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M295.38,154.58h-.05a1.25,1.25,0,0,1-1.25-1.25,1.27,1.27,0,0,1,1.25-1.25,28.42,28.42,0,0,0,4.5-.5,25.18,25.18,0,0,1,5.92-.5,1.25,1.25,0,1,1-.17,2.49,22.63,22.63,0,0,0-5.33.47A29.61,29.61,0,0,1,295.38,154.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M301.32,98.77a5.18,5.18,0,0,1-1.74-.33c-2.41-.86-3.2-3.61-2.71-5.75a3.86,3.86,0,0,1,4.26-3.26,1.25,1.25,0,0,1,.87,2,4.61,4.61,0,0,1,2.24,5.4A3,3,0,0,1,301.32,98.77Zm-1.57-6.47a2.06,2.06,0,0,0-.44.94c-.25,1.09.11,2.49,1.12,2.85.47.17,1.28.37,1.48-.15a2.16,2.16,0,0,0-1.37-2.44A1.25,1.25,0,0,1,299.75,92.3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M327,87.25H308.67a1.25,1.25,0,0,1,0-2.5H327a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M310,92.25h-2a1.25,1.25,0,0,1,0-2.5h1c3.62,0,7.36,0,11-.17.69,0,1.48,0,2.31,0,1.7,0,3.82.07,4.86-.39a1.25,1.25,0,0,1,1,2.29c-1.54.68-3.76.64-5.92.6-.79,0-1.53,0-2.15,0C316.74,92.24,313.31,92.25,310,92.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.48,117.31c-1.41,0-2.81,0-4.16-.11a1.25,1.25,0,0,1-1.18-1.11,9.07,9.07,0,0,1,1.23-5,7.35,7.35,0,0,0,1.05-3.93,6.4,6.4,0,0,0,2.2-1.49,1.25,1.25,0,0,1,1.74.32l.5.72c1.76,2.5,4.42,6.29,4,9.44a1.25,1.25,0,0,1-1.17,1.08C320.3,117.27,318.89,117.31,317.48,117.31Zm-2.82-2.55c1.87.07,3.8.07,5.69,0-.34-2.07-2.2-4.75-3.43-6.51a11.59,11.59,0,0,1-1.28,3.88A10.13,10.13,0,0,0,314.65,114.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.93,132.87a1.25,1.25,0,0,1-.87-.35c-1.54-1.49-2.12-3.64-2.68-5.72-.47-1.75-.91-3.4-1.85-4.18a1.25,1.25,0,0,1,.57-2.19,1.25,1.25,0,0,1,1.75-.91,10.12,10.12,0,0,0,3.66.28c.74,0,1.5,0,2.19,0a1.25,1.25,0,0,1,1.1,1.68,28.14,28.14,0,0,0-1.06,4.49,24.54,24.54,0,0,1-1.69,6.19,1.25,1.25,0,0,1-.91.69Zm-2.54-10.64a16.54,16.54,0,0,1,1.41,3.92,24.47,24.47,0,0,0,.81,2.63c.27-1,.48-2.16.67-3.26s.4-2.17.66-3.23h-.36A19.72,19.72,0,0,1,315.38,122.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M323,153.58a1.25,1.25,0,0,1-.28,0c-3.24-.73-7-.58-10.64-.43-1.47.06-3,.12-4.42.12a1.25,1.25,0,0,1,0-2.5c1.39,0,2.81-.06,4.32-.12,3.8-.16,7.72-.32,11.29.49a1.25,1.25,0,0,1-.27,2.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M340.6,87.54a5.83,5.83,0,0,1-5.79-4.18A7.23,7.23,0,0,1,338,74.92a2.56,2.56,0,0,0,2.84-.48c3.51.62,5.56,4.49,5.43,7.71a5.26,5.26,0,0,1-4.94,5.36A7.74,7.74,0,0,1,340.6,87.54Zm-.82-11a1.24,1.24,0,0,1-.5.53,4.72,4.72,0,0,0-2.1,5.51A3.44,3.44,0,0,0,341.13,85a2.79,2.79,0,0,0,2.7-3c.08-2.14-1.28-4.78-3.37-5.15A1.24,1.24,0,0,1,339.79,76.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M347,101.58H332.33a1.25,1.25,0,0,1,0-2.5H347a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M347.33,118.25a1.24,1.24,0,0,1-.45-.09c-2.59-1-6.67-.84-10.28-.69-1.28.05-2.49.1-3.6.1a1.25,1.25,0,0,1,0-2.5c1.06,0,2.24,0,3.5-.1,3.85-.16,8.22-.35,11.29.86a1.25,1.25,0,0,1-.46,2.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M356.33,79.58a1.25,1.25,0,0,1,0-2.5c7.22,0,14.81-.33,22.56-1,1-.09,2.15-.15,3.28-.2a35.06,35.06,0,0,0,8.44-1.08,1.25,1.25,0,1,1,.76,2.38,36.78,36.78,0,0,1-9.07,1.2c-1.1.06-2.18.11-3.2.2C371.28,79.25,363.62,79.58,356.33,79.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M358,87.58a1.25,1.25,0,0,1,0-2.5c5.58,0,11.25-.61,16.73-1.17s11.28-1.15,16.94-1.17h0a1.25,1.25,0,0,1,0,2.5c-5.54,0-11.21.6-16.69,1.16s-11.27,1.15-17,1.18Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M373.19,127.89c-4.6,0-9.16-1.46-11.59-5.48a18.94,18.94,0,0,1,0-19.05,13.71,13.71,0,0,1,12.76-6.94h0c9.7.78,14.87,4.9,15.81,12.61.66,5.4.64,13-7.13,16.69A24.1,24.1,0,0,1,373.19,127.89Zm.43-29a11.12,11.12,0,0,0-9.83,5.74,16.6,16.6,0,0,0,0,16.48c3.35,5.52,12.95,4.89,18.3,2.35,4.94-2.34,6.65-6.57,5.72-14.13-.8-6.52-5-9.73-13.51-10.42Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M367.44,123.21H367a1.25,1.25,0,0,1-1.2-1.15c-.32-3.86.8-7.22,1.88-10.47a28.1,28.1,0,0,1,1.69-3.72c1-1.87,1.94-3.8,2-5.27a1.25,1.25,0,0,1,2.15-.79,21.29,21.29,0,0,1,3.1,4.13,15.17,15.17,0,0,0,1.41,2.06,22.93,22.93,0,0,0,2.73,2.5c2.12,1.75,4.3,3.57,5,6.11a1.25,1.25,0,0,1-1.08,1.58,28.36,28.36,0,0,0-7.69,2.39C373.93,121.87,370.7,123.21,367.44,123.21Zm5.86-17.86a34.89,34.89,0,0,1-1.7,3.65,28.41,28.41,0,0,0-3.35,11.68,27.38,27.38,0,0,0,7.85-2.41A39.11,39.11,0,0,1,382.8,116a18.07,18.07,0,0,0-3.59-3.55,25.06,25.06,0,0,1-3-2.8,17.36,17.36,0,0,1-1.65-2.38C374.16,106.63,373.78,106,373.3,105.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M392.33,145.58h-35a1.25,1.25,0,0,1,0-2.5h35a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M363.79,154.26h-6.46a1.25,1.25,0,0,1,0-2.5h3.23c7.16,0,14.57,0,21.67-.66a38.38,38.38,0,0,1,4.64,0c2.65.08,5.65.17,7.31-.54a1.25,1.25,0,1,1,1,2.3c-2.16.93-5.32.83-8.37.74a36.82,36.82,0,0,0-4.32,0C376.32,154.18,370,154.26,363.79,154.26Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M426.47,108.22c-1.47,0-3-.1-4.37-.19-.73,0-1.4-.09-2-.11-3.38-.13-6.82-.48-10.15-.82-3.74-.38-7.61-.78-11.33-.85a1.25,1.25,0,0,1-1.23-1.27,1.24,1.24,0,0,1,1.27-1.23c3.82.07,7.74.47,11.54.86,3.29.34,6.69.69,10,.81.6,0,1.29.07,2,.12,2.74.18,6.5.43,8.23-.35a1.25,1.25,0,1,1,1,2.28A13.1,13.1,0,0,1,426.47,108.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M446.35,89.6c-.93,0-1.85,0-2.77,0-1.69,0-3.44-.08-5.17,0a1.25,1.25,0,1,1-.15-2.5c1.83-.11,3.64-.07,5.38,0a33,33,0,0,0,9.05-.61,1.25,1.25,0,1,1,.61,2.42A28.08,28.08,0,0,1,446.35,89.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M453.67,95.58H439.33a1.25,1.25,0,0,1,0-2.5h14.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M463.67,82.58h-6a1.25,1.25,0,0,1,0-2.5h6a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M462.26,153.33a8.62,8.62,0,0,1-3.07-.51,1.25,1.25,0,0,1,1-2.31c1.1.45,3.63.44,4.44-.17a1.25,1.25,0,1,1,1.51,2A6.56,6.56,0,0,1,462.26,153.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M520,149.25a1.25,1.25,0,0,1-1-2,50,50,0,0,1,8.81-8.32c.92-.74,1.83-1.47,2.71-2.21a1.25,1.25,0,1,1,1.61,1.92c-.9.75-1.82,1.5-2.76,2.24a48.07,48.07,0,0,0-8.38,7.89A1.25,1.25,0,0,1,520,149.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M522.33,153.58a1.25,1.25,0,0,1-1.13-1.78,17,17,0,0,1,3.55-4.58,13.25,13.25,0,0,0,3.08-4,1.25,1.25,0,1,1,2.32.93,15.26,15.26,0,0,1-3.62,4.84,15,15,0,0,0-3.08,3.89A1.25,1.25,0,0,1,522.33,153.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M481.93,87.59h-.31a1.25,1.25,0,1,1,.09-2.5c2.23.08,5-1.11,7.63-2.27a40.11,40.11,0,0,1,4.3-1.68,1.25,1.25,0,0,1,.71,2.4,38.48,38.48,0,0,0-4,1.58C487.53,86.33,484.63,87.59,481.93,87.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M484,92.92a1.25,1.25,0,0,1-.7-2.29c2.45-1.66,5.83-2.61,9.09-3.53,1.52-.43,3-.83,4.18-1.28a1.25,1.25,0,0,1,.86,2.35c-1.31.48-2.79.9-4.36,1.34-3.07.86-6.25,1.76-8.37,3.19A1.24,1.24,0,0,1,484,92.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M555.52,157.85a6.45,6.45,0,0,1-5.64-3.1,8.58,8.58,0,0,1,1.6-10.51c3.37-3.32,6.34-2.72,7.82-2.07,2.79,1.24,4.72,4.63,4.58,8.07a7.61,7.61,0,0,1-5.44,7.08h0A8.89,8.89,0,0,1,555.52,157.85Zm2.5-1.7h0Zm-1.11-12a5.43,5.43,0,0,0-3.68,1.85,6.06,6.06,0,0,0-1.24,7.41c1.13,1.82,3.18,2.38,5.61,1.54h0a5.14,5.14,0,0,0,3.76-4.83,6.07,6.07,0,0,0-3.09-5.68A3.35,3.35,0,0,0,556.92,144.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M570.67,149.58h-4.33a1.25,1.25,0,0,1,0-2.5h4.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M542.6,151.64a9.44,9.44,0,0,1-1.08-.06,1.25,1.25,0,1,1,.29-2.48,8.67,8.67,0,0,0,3.19-.3,1.25,1.25,0,1,1,.67,2.41A11.65,11.65,0,0,1,542.6,151.64Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M549.58,132.21h-.91a1.25,1.25,0,0,1-1.16-1.61,52.47,52.47,0,0,1,3.39-8,42.37,42.37,0,0,0,3.88-9.88,1.25,1.25,0,0,1,2.42-.12,56.07,56.07,0,0,0,2.43,6.07c1.63,3.67,3.32,7.46,3.24,10.94a1.25,1.25,0,0,1-1.06,1.21l-1.26.2A73.36,73.36,0,0,1,549.58,132.21ZM556.15,117a67.5,67.5,0,0,1-3,6.74,65.08,65.08,0,0,0-2.7,6,79.31,79.31,0,0,0,9.71-1.12l.17,0c-.25-2.67-1.58-5.67-3-8.83C556.94,118.82,556.53,117.91,556.15,117Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603,150.25c-2.34,0-5.13-.15-8.08-.32-3.61-.2-7.34-.41-10.56-.35a1.28,1.28,0,0,1-1.27-1.23,1.25,1.25,0,0,1,1.23-1.27c3.33-.06,7.1.15,10.75.35,2.91.16,5.67.31,7.94.31a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M585.67,144.58a1.25,1.25,0,0,1-.4-2.43c4.81-1.65,10.6-1.54,15.7-1.44,1.27,0,2.52,0,3.7,0h0a1.25,1.25,0,0,1,0,2.5c-1.22,0-2.47,0-3.75,0-5.14-.1-10.45-.19-14.85,1.31A1.25,1.25,0,0,1,585.67,144.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M610.35,152.6H609a1.25,1.25,0,0,1,0-2.5h0c3.29.07,7.09-.14,10.76-.35,2.76-.16,5.37-.3,7.54-.31h0a1.25,1.25,0,0,1,0,2.5c-2.11,0-4.68.16-7.41.31C616.71,152.41,613.39,152.6,610.35,152.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M147.76,501.88c-3.43,0-6.88-.24-10.26-.48s-6.79-.48-10.13-.48h0a1.25,1.25,0,0,1-1.25-1.25,1.29,1.29,0,0,1,1.28-1.25c3.43,0,6.92.25,10.31.49,6.05.43,12.31.87,18.12-.13a1.25,1.25,0,1,1,.42,2.46A49.74,49.74,0,0,1,147.76,501.88Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M138.33,525.58h-.1c-.51,0-1-.1-1.53-.15a18.61,18.61,0,0,0-3-.18,1.23,1.23,0,0,1-1.31-1.19,1.25,1.25,0,0,1,1.19-1.31,21.27,21.27,0,0,1,3.38.19c.48.05,1,.11,1.44.14a1.25,1.25,0,0,1-.09,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M146.58,580.92a90.71,90.71,0,0,1-12-1c-.57-.07-1.27-.11-2-.15-2.76-.14-6.19-.31-7.88-2.71a1.25,1.25,0,1,1,2-1.44c1,1.4,3.74,1.54,6,1.65.79,0,1.54.08,2.2.17a95.08,95.08,0,0,0,11.83,1H147c3.33,0,5.73,0,8.49-1.23a1.25,1.25,0,1,1,1,2.29c-3.24,1.43-6,1.43-9.5,1.44h-.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M189.67,506.92h0c-4.84,0-13.33-.8-17.81-1.34a1.25,1.25,0,1,1,.3-2.48c4.42.53,12.79,1.29,17.53,1.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M182.45,514.29c-4.67,0-9.59-.2-13.8-1.43a1.25,1.25,0,0,1,.7-2.4c4.87,1.42,11,1.36,16.42,1.3l3.57,0a1.25,1.25,0,0,1,0,2.5,3.43,3.43,0,0,1-.44,0l-3.1,0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M202.33,564.63c-1.34,0-2.86-.1-4.5-.23-1-.08-1.9-.15-2.5-.15a1.25,1.25,0,0,1,0-2.5c.69,0,1.62.07,2.69.16,1.9.15,6.94.55,7.66-.35a1.25,1.25,0,0,1,2,1.56C206.71,564.28,204.82,564.63,202.33,564.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208.67,570.58h-13a1.25,1.25,0,0,1,0-2.5h13a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M201,581.92h-.23c-2.67-.14-3.68-1.28-4.05-2.21-.54-1.35-.05-3,1.31-4.48s3.48-2.61,5.7-1.88c2.5.83,3.09,2.69,2.82,4.15A5.94,5.94,0,0,1,201,581.92Zm1.39-6.29a3.88,3.88,0,0,0-2.54,1.3c-.71.75-.95,1.51-.81,1.84s.66.59,1.86.65h0a3.45,3.45,0,0,0,3.18-2.39c0-.26.17-.88-1.15-1.31A1.71,1.71,0,0,0,202.38,575.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.35,517.29a22.47,22.47,0,0,1-8.32-1.93,75.86,75.86,0,0,1-7.71-3.87L93,510.76a23.18,23.18,0,0,0-2.32-1c-1.85-.75-3.94-1.6-5.3-3.27a1.25,1.25,0,1,1,1.94-1.58c1,1.17,2.66,1.86,4.3,2.53a25.54,25.54,0,0,1,2.58,1.16l1.34.74a74.18,74.18,0,0,0,7.45,3.74,18.35,18.35,0,0,0,8.25,1.7,1.25,1.25,0,0,1,.22,2.49Q110.91,517.29,110.35,517.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110,522.92a1.25,1.25,0,0,1-.33,0c-3.36-.9-6.88-2.06-10.49-3.27-.66-.22-1.43-.46-2.26-.72-4.57-1.43-10.83-3.38-13.24-6.44a1.25,1.25,0,0,1,2-1.54c1.93,2.45,8,4.35,12,5.6.85.27,1.64.51,2.31.74,3.57,1.2,7,2.34,10.34,3.23a1.25,1.25,0,0,1-.32,2.46Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M114.33,529.92a1.25,1.25,0,0,1-.47-2.41c2.22-.91,5.17-.72,7.78-.55,1,.06,1.89.12,2.7.12a1.25,1.25,0,1,1,0,2.5c-.89,0-1.84-.06-2.86-.13-2.34-.15-5-.32-6.67.37A1.24,1.24,0,0,1,114.33,529.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M121.32,533c-2.07,0-4.35-.2-6-1.25a1.25,1.25,0,0,1,1.35-2.1c1.53,1,4.41.89,6.51.82h.44a1.22,1.22,0,0,1,1.29,1.21,1.25,1.25,0,0,1-1.21,1.29h-.43C122.67,533,122,533,121.32,533Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M204.06,502.94c-1.59,0-3.19-.1-4.71-.19s-2.79-.17-4-.17a1.25,1.25,0,1,1,0-2.5c1.31,0,2.7.08,4.17.17,3.66.22,7.8.47,10.68-.74a1.25,1.25,0,0,1,1,2.31A18.59,18.59,0,0,1,204.06,502.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.65,507.25c-3.38,0-6.75-.28-10-.54-2.19-.18-4.46-.36-6.69-.46a1.25,1.25,0,1,1,.11-2.5c2.28.1,4.57.29,6.79.47,3.21.26,6.52.53,9.8.53h0a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M626.88,500.82c-2.73,0-5.52-.16-8.27-.32-3.4-.19-6.62-.38-9.55-.25a1.25,1.25,0,1,1-.1-2.5c3.05-.12,6.33.06,9.8.26,6.67.38,13.56.77,18.82-1.18a1.25,1.25,0,0,1,.87,2.34A33.57,33.57,0,0,1,626.88,500.82Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M638.67,506.25c-4.2,0-8.52-.31-12.7-.6a122.36,122.36,0,0,0-17.87-.4,1.25,1.25,0,0,1-.2-2.49,124.15,124.15,0,0,1,18.24.4c4.14.29,8.42.6,12.53.6a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M634.9,576.77c-1.72,0-3.45-.16-5.06-.3-1-.09-2-.18-2.9-.23-1.46-.07-2.93-.09-4.49-.11-4.54-.06-9.24-.12-13.52-1.62a1.25,1.25,0,1,1,.83-2.36c3.9,1.37,8.38,1.43,12.73,1.48,1.52,0,3.08,0,4.59.12,1,0,2,.14,3,.23,3.09.28,6.3.57,8.93-.19a1.25,1.25,0,1,1,.69,2.4A17.52,17.52,0,0,1,634.9,576.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M622.24,579.36a123.7,123.7,0,0,1-13.37-.78,1.25,1.25,0,0,1,.27-2.49,111.6,111.6,0,0,0,17.55.66c.93,0,2-.06,3-.06,2.82,0,6,0,8.2-.86a1.25,1.25,0,0,1,.87,2.34c-2.59,1-6,1-9,1-1,0-2,0-2.91.06Q624.58,579.36,622.24,579.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M662.25,493.36a39.46,39.46,0,0,1-6.09-.66,32.89,32.89,0,0,0-3.53-.45,1.25,1.25,0,1,1,.09-2.5,34,34,0,0,1,3.84.48,26,26,0,0,0,7.42.5,31.79,31.79,0,0,0,4.85-1.31c1-.34,2.11-.69,3.19-1a1.25,1.25,0,1,1,.63,2.42c-1,.26-2,.58-3,.93a34.23,34.23,0,0,1-5.24,1.4A13.65,13.65,0,0,1,662.25,493.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M663.41,498.84a35.43,35.43,0,0,1-10.82-1.66,1.25,1.25,0,1,1,.81-2.36c4.77,1.64,14,2.52,18.25-.2a1.25,1.25,0,0,1,1.35,2.1C670.63,498.25,667.07,498.84,663.41,498.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M620.51,540.9a5.16,5.16,0,0,1-4.57-2.22c-2-3-.88-8.07,1.28-11.54,1.94-3.12,4.47-4.72,6.94-4.38h0c4.22.63,6.67,3.05,6.71,6.65.06,4.85-4.34,10.57-8.72,11.33A9.76,9.76,0,0,1,620.51,540.9Zm3-15.68c-1.36,0-2.9,1.19-4.18,3.24-1.92,3.09-2.52,7.05-1.33,8.82.66,1,1.92,1.31,3.73,1,3.15-.55,6.69-5.25,6.65-8.83,0-2.34-1.57-3.76-4.57-4.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M661.55,536.59a4.66,4.66,0,0,1-4.27-2.25c-1.38-2.4-.59-6,.9-8.31,1.32-2,3.12-3.11,4.94-2.93h0a1.25,1.25,0,0,1,.83.18,8.54,8.54,0,0,1,3.58,9,5.74,5.74,0,0,1-5.69,4.35Zm1.18-11a3.33,3.33,0,0,0-2.45,1.81c-1.22,1.89-1.59,4.4-.83,5.71.15.27.62,1.08,2.32,1a3.28,3.28,0,0,0,3.38-2.49,6,6,0,0,0-2.21-6h-.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M685,507.44a75.46,75.46,0,0,1-8.17-.54,1.25,1.25,0,1,1,.27-2.48c5.78.64,12.24,1,16.33-.89a1.25,1.25,0,0,1,1.06,2.26A22.82,22.82,0,0,1,685,507.44Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.67,512.58a1.25,1.25,0,0,1,0-2.5c2.87,0,5.77-.25,8.58-.5,2.64-.23,5.38-.47,8.07-.5h0a1.25,1.25,0,0,1,0,2.5c-2.6,0-5.17.25-7.88.49S679.64,512.58,676.67,512.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M663.94,579.51c-2.27,0-4.67-.17-6.95-.33-2-.14-3.82-.27-5.33-.27a1.25,1.25,0,0,1,0-2.5c1.6,0,3.5.13,5.5.27,4.81.34,10.79.76,13.55-.78a1.25,1.25,0,1,1,1.21,2.19C670,579.19,667.07,579.51,663.94,579.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M662.37,583.61c-2,0-4.06-.11-5.92-.21-1.42-.08-2.76-.15-3.79-.15a1.25,1.25,0,0,1,0-2.5c1.09,0,2.47.07,3.92.15,4.14.22,9.8.53,12.94-.73a1.25,1.25,0,0,1,.93,2.32A22.89,22.89,0,0,1,662.37,583.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M678.95,578c-.41,0-.77,0-1.07,0a1.25,1.25,0,1,1,.25-2.49c1.78.19,6.62-.33,8.56-1.49a1.25,1.25,0,1,1,1.29,2.14C685.8,577.38,681.47,578,678.95,578Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M707,514.25a1.27,1.27,0,0,1-.28,0,1.25,1.25,0,0,1-.95-1.49c.41-1.81,3-1.88,6.57-2a21,21,0,0,0,3.64-.28,1.25,1.25,0,0,1,.68,2.41,20.75,20.75,0,0,1-4.25.37,20.78,20.78,0,0,0-4.34.38A1.25,1.25,0,0,1,707,514.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.67,582.58a1.25,1.25,0,0,1-1-2c3.71-5.15,8.35-9.53,12.43-11.71a1.25,1.25,0,0,1,1.18,2.21c-3.75,2-8.08,6.1-11.57,11A1.25,1.25,0,0,1,587.67,582.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M583.67,576.58a1.25,1.25,0,0,1-1.07-1.9c2.1-3.48,10.42-10.32,14.9-10.93a1.25,1.25,0,0,1,.33,2.48c-3.31.45-11.2,6.6-13.1,9.74A1.25,1.25,0,0,1,583.67,576.58Z" transform="translate(-53.25 -44.96)"/></g><g id="BACKGROUND"><path class="cls-24" d="M479.9,331.07c-37.71,0-75.29-.27-112.34-.54-33.89-.24-68.94-.49-103.29-.53-31.44,0-63.33-.27-94.18-.5-33.44-.25-68-.5-102.1-.5a2,2,0,0,1,0-4c34.1,0,68.68.26,102.13.5,30.83.23,62.72.46,94.15.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08H728a2,2,0,0,1,0,4H665.58c-4,0-8,0-12-.08-7.82-.08-15.9-.17-23.81.08C580.3,330.59,530,331.07,479.9,331.07Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M479.9,306c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.7,0-62.72-.31-92.72-.58-32-.29-65-.59-98.87-.59a2,2,0,1,1,0-4c33.84,0,66.92.3,98.91.59,30,.27,61,.55,92.69.58,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08h56.53a2,2,0,0,1,0,4H665.58c-4,0-8,0-12-.09-7.82-.08-15.9-.17-23.81.08C580.3,305.5,530,306,479.9,306Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,190.86c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.42,0-63.29-.27-94.12-.5l-32.69-.23a2,2,0,0,1-2-2,2,2,0,0,1,2-2l32.69.23c30.82.23,62.68.46,94.09.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08a2,2,0,0,1,0,4c-4,0-8,0-12-.09-7.82-.08-15.9-.17-23.81.08C576.4,190.38,526.09,190.86,476,190.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,165.77c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.52,0-63.48-.27-94.4-.5l-8.79-.06a2,2,0,0,1,0-4h0l8.79.06c30.91.23,62.87.46,94.38.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,3.52-.11,7.36-.17,11.75-.17h0a2,2,0,0,1,0,4c-4.34,0-8.14.06-11.62.17C576.4,165.29,526.09,165.77,476,165.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,475.66c-37.71,0-75.29-.27-112.35-.54-33.89-.24-68.93-.5-103.27-.53-31.45,0-63.35-.27-94.2-.5-33.43-.25-68-.5-102.07-.5a2,2,0,1,1,0-4c34.09,0,68.66.25,102.1.5,30.84.23,62.74.46,94.18.5,34.35,0,69.4.29,103.29.53,86.23.62,175.39,1.26,262.11-1.53,8-.25,16.12-.17,24-.09,4,0,7.95.08,11.91.08,10.39,0,22.44-.2,34.11-.4s23.75-.4,34.17-.4a2,2,0,0,1,0,4c-10.39,0-22.45.2-34.11.4s-23.75.4-34.17.4c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08C576.39,475.19,526.08,475.66,476,475.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M733.78,450.57c-10.44,0-23.51-.53-36.14-1s-25.61-1-36-1c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08-86.79,2.79-176,2.15-262.23,1.53-33.9-.24-69-.5-103.31-.53-31.43,0-63.31-.27-94.14-.5-33.45-.25-68-.5-102.13-.5a2,2,0,1,1,0-4c34.11,0,68.7.25,102.16.5,30.83.23,62.7.46,94.12.5,34.37,0,69.43.29,103.33.53,86.21.62,175.36,1.26,262.07-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08,10.44,0,23.5.53,36.13,1s25.61,1,36,1a2,2,0,0,1,0,4Z" transform="translate(-53.25 -44.96)"/><g class="cls-25"><path class="cls-24" d="M167.18,469.74a2.91,2.91,0,0,1-1.53-.42,4.18,4.18,0,0,1-1.65-3.38h0c-.07-.82-.11-1.66-.15-2.5s-.07-1.56-.13-2.32c-.19-2.42-.29-5.09-.29-8.41a4.24,4.24,0,0,1,1.48-3.58c1.55-1.09,3.5-.4,4.66,0a21.31,21.31,0,0,1,9.27,5.93l.19.21c1.06,1.17,2.65,2.94,2,4.76-.35,1-1.32,1.71-2.88,2.76-.28.19-.52.34-.65.45-.95.78-1.93,1.46-2.89,2.13-.56.39-1.13.78-1.68,1.19-.29.22-.58.45-.88.68a14.2,14.2,0,0,1-3.3,2.15A4.14,4.14,0,0,1,167.18,469.74Zm.91-3.46h0Zm-.66-13.63v.05c0,3.21.09,5.78.28,8.09.06.81.1,1.64.14,2.46s.06,1.38.11,2.06a18.62,18.62,0,0,0,1.61-1.2c.33-.27.66-.53,1-.77.59-.43,1.19-.85,1.79-1.27.93-.65,1.81-1.25,2.63-1.93.19-.16.54-.4,1-.68l.9-.62c-.28-.35-.62-.73-.77-.9l-.22-.25a17.5,17.5,0,0,0-7.61-4.8C167.89,452.79,167.63,452.71,167.43,452.65Zm10,5.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M190.73,469.74a4.13,4.13,0,0,1-1.59-.35,14.22,14.22,0,0,1-3.3-2.15c-.3-.24-.59-.47-.88-.68-.55-.41-1.12-.8-1.69-1.19-1-.66-1.94-1.35-2.89-2.13-.13-.11-.37-.26-.65-.45-1.56-1.05-2.54-1.77-2.88-2.76-.63-1.81,1-3.58,2-4.76l.19-.21a21.32,21.32,0,0,1,9.27-5.93c1.16-.42,3.11-1.11,4.66,0a4.24,4.24,0,0,1,1.48,3.58c0,3.32-.09,6-.29,8.41-.06.76-.1,1.54-.13,2.32s-.08,1.69-.15,2.51a4.18,4.18,0,0,1-1.65,3.38A2.91,2.91,0,0,1,190.73,469.74Zm-9.65-10.88.9.62c.41.28.76.52,1,.68.82.67,1.7,1.28,2.62,1.93.6.42,1.2.83,1.79,1.27.33.24.66.5,1,.77a18.47,18.47,0,0,0,1.61,1.2c0-.68.08-1.37.11-2.07s.08-1.64.14-2.45c.19-2.31.27-4.88.28-8.1v-.05c-.2.05-.46.14-.8.26a17.5,17.5,0,0,0-7.61,4.8l-.22.24C181.71,458.13,181.37,458.5,181.09,458.86Zm-.65-.52" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M102.47,354.23a2,2,0,0,1-1.68-3.08,79.22,79.22,0,0,1,7.43-9.73c6.39-7.21,15.4-12.58,27.57-16.43,11.57-3.66,22.64-7.53,30.94-14.54a2,2,0,0,1,3.25,1.91,18.25,18.25,0,0,1-2,5.36c6.95-2,16.48-6.56,19.26-10a2,2,0,0,1,3.55,1.36,16.94,16.94,0,0,1-3,8.82,65.35,65.35,0,0,0,12.58-2.63c1.46-.41,2.94-.82,4.46-1.21a2,2,0,0,1,2.44,2.41,12.34,12.34,0,0,1-1.78,4c17.25,3.33,36.68,15.6,47.45,30.28a2,2,0,1,1-3.23,2.37c-11-15-31.37-27.27-48.49-29.27a2,2,0,0,1-1-3.57,9.19,9.19,0,0,0,1.26-1.18l-.05,0c-5.93,1.65-11.53,3.21-18.5,2.83a2,2,0,0,1-1.09-3.6,12.31,12.31,0,0,0,3.36-3.87c-6.56,4.13-16.49,7.75-21.54,8.2a2,2,0,0,1-1.7-3.3c.35-.4.71-.85,1.08-1.35-7.71,4.74-16.71,7.82-26,10.77-11.46,3.62-19.89,8.62-25.78,15.27a75.18,75.18,0,0,0-7.06,9.24A2,2,0,0,1,102.47,354.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M119.46,422.75c-6.6,0-13.4-1.41-18.19-5.32-12.68-10.37-18.57-28.31-14.66-44.65,3.5-14.6,13.77-24.79,28.19-27.94a50.34,50.34,0,0,1,13.11-1.2h0c21.69,1,33,17.78,34.56,33.91,1.71,17.53-7.28,37.86-31.21,43.77A50.23,50.23,0,0,1,119.46,422.75Zm6.37-75.16a47.77,47.77,0,0,0-10.17,1.15c-12.86,2.81-22,11.91-25.15,25-3.56,14.88,1.78,31.21,13.3,40.62,6.27,5.12,17.82,5.25,26.5,3.11,21.61-5.34,29.73-23.69,28.19-39.5-1.41-14.42-11.46-29.38-30.77-30.3Q126.79,347.59,125.83,347.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M136.19,391.22c6.18-1.2,8.88-12,3.72-16s-15.21,1.36-14.1,8.27C126.6,388.33,131.25,392.18,136.19,391.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M88.65,512.72a2,2,0,0,1-2-2c0-8.37-.06-16.77-.11-24.89-.19-29.54-.38-57.44,1.85-87a2,2,0,1,1,4,.3c-2.22,29.38-2,57.2-1.84,86.66.05,8.13.11,16.53.11,24.91A2,2,0,0,1,88.65,512.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M263.59,512.72h-.2a2,2,0,0,1-1.79-2.19c1.33-13.41.87-37.17.34-58.37-.17-6.66-.6-13.32-1-19.77-.58-8.87-1.18-18-1.07-27.25a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.1,9.06.49,18.15,1.06,26.95.42,6.49.86,13.2,1,19.93.53,21.33,1,45.23-.36,58.87A2,2,0,0,1,263.59,512.72Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="84.62" cy="334.45" r="2.31"/><path class="cls-24" d="M235.5,423.2a50.2,50.2,0,0,1-11.8-1.43c-23.93-5.91-32.92-26.24-31.21-43.77,1.57-16.13,12.87-32.87,34.56-33.91a50.36,50.36,0,0,1,13.11,1.2c14.42,3.15,24.69,13.33,28.19,27.94,3.91,16.34-2,34.29-14.66,44.65C248.9,421.79,242.1,423.2,235.5,423.2ZM229.13,348q-1,0-1.9,0h0c-19.31.92-29.37,15.89-30.77,30.3-1.54,15.81,6.58,34.16,28.19,39.5,8.68,2.14,20.23,2,26.5-3.11,11.52-9.42,16.87-25.74,13.3-40.62-3.13-13.05-12.29-22.15-25.15-25A47.79,47.79,0,0,0,229.13,348Zm-2-2h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M240.76,389.67c-6.18-1.2-8.88-12-3.72-16s15.21,1.36,14.1,8.27C250.36,386.77,245.71,390.62,240.76,389.67Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="191.83" cy="332.89" r="2.31"/><path class="cls-24" d="M176.13,407.12a13.92,13.92,0,0,1-8.83-3.22h0c-3.83-3.15-3.79-5.86-3.09-7.58,1.81-4.42,9.6-5.72,13.19-5.4s8.38,1.36,10,4.47c.61,1.18,1,3.14-.55,5.76a12,12,0,0,1-8.4,5.76A13.24,13.24,0,0,1,176.13,407.12Zm-6.29-6.31a9.78,9.78,0,0,0,7.89,2.17,8.07,8.07,0,0,0,5.65-3.86c.34-.58.7-1.38.43-1.89-.46-.89-2.73-2-6.77-2.31-3.51-.31-8.45,1.28-9.13,2.93-.27.65.46,1.76,1.93,3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M165.22,420.86a8.93,8.93,0,0,1-5.31-1.66,8,8,0,0,1-3.17-7c.2-4.74,3.51-11.08,9.24-13.51a2,2,0,0,1,1.56,3.68c-4,1.7-6.65,6.51-6.8,10a4,4,0,0,0,1.53,3.62,5.83,5.83,0,0,0,5.35.45l1.06-.39c4.27-1.57,7.64-2.81,13.06-2.09a28.21,28.21,0,0,1,3.13.66c3.48.87,5.69,1.27,7.19-.59s.86-4.43.32-5.75c-1.36-3.33-4.58-6.19-7.32-6.52a2,2,0,0,1,.47-4c4.19.5,8.62,4.27,10.55,9,1.49,3.64,1.16,7.2-.9,9.77-3.21,4-7.87,2.83-11.28,2a25.36,25.36,0,0,0-2.68-.58c-4.44-.58-7.12.4-11.16,1.88l-1.08.39A11.06,11.06,0,0,1,165.22,420.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M176.32,432.68c-2.92,0-5.13-.74-6.72-2.25-2.9-2.77-3-7.44-2.79-12.38a2,2,0,1,1,4,.15c-.14,3.84-.14,7.72,1.55,9.34,1,1,2.74,1.31,5.32,1.09l.2,0c3.29-.28,4-.34,4.67-2.76a36.9,36.9,0,0,0,.84-9.07,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,39.11,39.11,0,0,1-1,10.13c-1.45,5.07-4.72,5.35-8.17,5.65l-.2,0Q177.14,432.68,176.32,432.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M104,352.05a2,2,0,0,1-.74-.14C98,349.85,93.29,344,91.72,337.8c-1.24-4.94-.36-9.51,2.47-12.85,3.35-4,10.47-4.29,15-2.12,4.91,2.34,7.35,5.93,9.93,9.73l1.09,1.6a2,2,0,0,1-3.28,2.28l-1.12-1.63c-2.46-3.63-4.41-6.49-8.34-8.37-3.07-1.46-8.22-1.31-10.25,1.09-2.53,3-2.29,6.71-1.64,9.3,1.25,5,5.08,9.77,9.11,11.37a2,2,0,0,1-.74,3.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M251.49,354a2,2,0,0,1-1.5-3.32c3.8-4.33,11.95-15.11,5.66-21.62-2.51-2.6-7.3-2.47-10.55-1-3.57,1.58-5.83,4.67-8,7.65l-.92,1.25a2,2,0,0,1-3.2-2.4l.9-1.21c2.38-3.25,5.08-6.93,9.62-8.94s11.23-2,15,1.91c6.05,6.27,4,16.12-5.53,27A2,2,0,0,1,251.49,354Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-26"><path class="cls-24" d="M625.88,469.74a2.91,2.91,0,0,1-1.54-.42,4.19,4.19,0,0,1-1.65-3.38c-.07-.82-.11-1.67-.15-2.52s-.07-1.55-.13-2.31c-.19-2.42-.29-5.09-.29-8.41a4.24,4.24,0,0,1,1.48-3.58c1.55-1.09,3.5-.4,4.66,0a21.33,21.33,0,0,1,9.27,5.93l.19.21c1.06,1.17,2.65,2.94,2,4.76-.35,1-1.32,1.71-2.88,2.76-.28.19-.52.34-.65.45-.95.78-1.93,1.46-2.89,2.13-.57.39-1.13.79-1.69,1.2-.29.21-.58.45-.88.68a14.24,14.24,0,0,1-3.3,2.15A4.13,4.13,0,0,1,625.88,469.74Zm.91-3.46h0Zm-.66-13.63v.05c0,3.21.09,5.78.28,8.09.06.81.1,1.63.14,2.44s.07,1.4.12,2.08a18.23,18.23,0,0,0,1.61-1.2c.33-.27.66-.53,1-.77.59-.44,1.19-.85,1.79-1.27.93-.64,1.81-1.25,2.62-1.93.19-.16.54-.4,1-.68l.9-.62c-.28-.35-.62-.73-.77-.9l-.22-.25a17.51,17.51,0,0,0-7.61-4.8C626.59,452.79,626.33,452.71,626.13,452.65Zm10,5.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M649.44,469.74a4.13,4.13,0,0,1-1.59-.35,14.23,14.23,0,0,1-3.3-2.15c-.3-.24-.59-.47-.88-.68-.55-.41-1.12-.8-1.68-1.19-1-.66-1.94-1.35-2.89-2.13-.13-.11-.37-.26-.65-.45-1.56-1.05-2.54-1.77-2.88-2.76-.63-1.81,1-3.58,2-4.75l.19-.21a21.33,21.33,0,0,1,9.27-5.93c1.16-.42,3.11-1.11,4.66,0a4.24,4.24,0,0,1,1.48,3.58c0,3.32-.1,6-.29,8.41-.06.77-.1,1.54-.13,2.32s-.08,1.69-.15,2.51h0a4.19,4.19,0,0,1-1.65,3.38A2.91,2.91,0,0,1,649.44,469.74Zm-9.65-10.88c.32.23.67.47.9.62.41.28.76.52,1,.68.82.67,1.7,1.28,2.63,1.93.6.42,1.2.83,1.79,1.27.33.24.66.5,1,.77a18.42,18.42,0,0,0,1.61,1.2c0-.68.08-1.37.11-2.07s.08-1.64.14-2.45c.18-2.31.27-4.88.28-8.1v-.05c-.2.05-.46.14-.8.26a17.51,17.51,0,0,0-7.61,4.8l-.22.24C640.41,458.13,640.07,458.5,639.79,458.86Zm-.65-.52" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M561.17,354.23a2,2,0,0,1-1.68-3.08,79.07,79.07,0,0,1,7.43-9.73c6.39-7.21,15.4-12.58,27.57-16.43,11.57-3.66,22.64-7.53,30.95-14.54a2,2,0,0,1,3.25,1.91,18.24,18.24,0,0,1-2,5.36c6.95-2,16.48-6.56,19.26-10a2,2,0,0,1,3.55,1.36,16.94,16.94,0,0,1-3,8.82A65.37,65.37,0,0,0,659,315.26c1.46-.41,2.94-.82,4.46-1.21a2,2,0,0,1,2.44,2.42,12.35,12.35,0,0,1-1.78,4c17.25,3.33,36.67,15.59,47.45,30.28a2,2,0,1,1-3.22,2.37c-11-15-31.37-27.27-48.49-29.27a2,2,0,0,1-1-3.57,9.15,9.15,0,0,0,1.26-1.18h-.05c-5.93,1.65-11.54,3.21-18.5,2.83a2,2,0,0,1-1.09-3.6,12.32,12.32,0,0,0,3.36-3.87c-6.57,4.13-16.49,7.75-21.54,8.2a2,2,0,0,1-1.7-3.29c.35-.4.71-.86,1.08-1.35-7.71,4.74-16.72,7.82-26,10.77-11.46,3.62-19.89,8.62-25.78,15.27a75.13,75.13,0,0,0-7.06,9.24A2,2,0,0,1,561.17,354.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M578.17,422.75c-6.6,0-13.4-1.41-18.19-5.32-12.68-10.37-18.57-28.31-14.66-44.65,3.5-14.6,13.77-24.79,28.19-27.94a50.35,50.35,0,0,1,13.11-1.2h0c21.69,1,33,17.78,34.56,33.91,1.71,17.53-7.28,37.86-31.21,43.77A50.23,50.23,0,0,1,578.17,422.75Zm6.37-75.16a47.79,47.79,0,0,0-10.18,1.15c-12.86,2.81-22,11.91-25.15,25-3.56,14.88,1.78,31.21,13.3,40.62,6.27,5.12,17.82,5.25,26.5,3.11,21.61-5.34,29.73-23.69,28.19-39.5-1.41-14.42-11.47-29.38-30.77-30.3Q585.49,347.59,584.53,347.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M571.9,391.22c6.18-1.2,8.88-12,3.72-16s-15.21,1.36-14.1,8.27C562.3,388.33,567,392.18,571.9,391.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M547.36,512.72a2,2,0,0,1-2-2c0-8.37-.06-16.77-.11-24.88-.2-29.54-.38-57.44,1.85-87a2,2,0,0,1,4,.3c-2.22,29.38-2,57.21-1.84,86.66.05,8.12.11,16.52.11,24.91A2,2,0,0,1,547.36,512.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M722.29,512.72h-.2a2,2,0,0,1-1.79-2.19c1.33-13.41.87-37.16.34-58.37-.17-6.66-.6-13.32-1-19.77-.58-8.87-1.17-18-1.07-27.26a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.1,9.06.49,18.16,1.07,27,.42,6.49.86,13.19,1,19.93.53,21.33,1,45.23-.36,58.87A2,2,0,0,1,722.29,512.72Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="520.33" cy="334.45" r="2.31"/><path class="cls-24" d="M694.2,423.2a50.2,50.2,0,0,1-11.8-1.43c-23.93-5.91-32.92-26.24-31.21-43.77,1.57-16.13,12.87-32.87,34.56-33.91a50.16,50.16,0,0,1,13.11,1.2c14.42,3.15,24.69,13.33,28.19,27.94,3.91,16.34-2,34.29-14.66,44.65C707.6,421.79,700.8,423.2,694.2,423.2ZM687.83,348q-1,0-1.9,0h0c-19.31.92-29.37,15.89-30.77,30.3-1.54,15.81,6.58,34.16,28.19,39.5,8.68,2.14,20.23,2,26.5-3.11,11.52-9.42,16.86-25.74,13.3-40.62C720,361.1,710.86,352,698,349.19A47.79,47.79,0,0,0,687.83,348Zm-2-2h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.47,389.67c-6.18-1.2-8.88-12-3.72-16s15.21,1.36,14.1,8.27C686.07,386.77,681.41,390.62,676.47,389.67Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="627.54" cy="332.89" r="2.31"/><path class="cls-24" d="M634.83,407.12A13.92,13.92,0,0,1,626,403.9h0c-3.83-3.15-3.79-5.86-3.09-7.58,1.81-4.42,9.61-5.71,13.19-5.4s8.38,1.36,10,4.47c.61,1.18,1,3.14-.55,5.76a12,12,0,0,1-8.4,5.76A13.24,13.24,0,0,1,634.83,407.12Zm-6.29-6.31a9.78,9.78,0,0,0,7.88,2.17,8.08,8.08,0,0,0,5.65-3.86c.34-.58.7-1.38.43-1.89-.46-.89-2.73-2-6.77-2.31-3.51-.31-8.46,1.28-9.13,2.93-.26.65.46,1.76,1.93,3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M623.92,420.86a8.93,8.93,0,0,1-5.31-1.66,8,8,0,0,1-3.17-7c.2-4.74,3.51-11.08,9.23-13.51a2,2,0,0,1,1.56,3.68c-4,1.7-6.65,6.51-6.8,10A4,4,0,0,0,621,416a5.83,5.83,0,0,0,5.35.45l1.06-.39c4.27-1.57,7.64-2.82,13.06-2.09a28.19,28.19,0,0,1,3.13.66c3.48.87,5.7,1.27,7.19-.59s.86-4.43.32-5.75c-1.36-3.33-4.58-6.19-7.32-6.52a2,2,0,1,1,.47-4c4.19.5,8.62,4.27,10.55,9,1.49,3.64,1.16,7.2-.9,9.77-3.21,4-7.87,2.83-11.28,2a25.6,25.6,0,0,0-2.68-.58c-4.44-.58-7.12.4-11.16,1.88l-1.08.39A11.05,11.05,0,0,1,623.92,420.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M635,432.68c-2.92,0-5.13-.74-6.72-2.25-2.9-2.76-3-7.44-2.79-12.38a2,2,0,0,1,4,.15c-.14,3.84-.14,7.72,1.55,9.34,1,1,2.74,1.31,5.32,1.09l.2,0c3.29-.28,4-.34,4.67-2.76a36.89,36.89,0,0,0,.84-9.07,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,39.06,39.06,0,0,1-1,10.13c-1.45,5.07-4.71,5.35-8.17,5.65l-.2,0Q635.84,432.68,635,432.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M562.68,352.05a2,2,0,0,1-.74-.14c-5.21-2.06-9.95-7.87-11.52-14.11-1.24-4.94-.37-9.51,2.46-12.85,3.35-4,10.47-4.29,15-2.12,4.91,2.34,7.35,5.93,9.93,9.74l1.09,1.59a2,2,0,1,1-3.29,2.28l-1.12-1.63c-2.46-3.63-4.41-6.5-8.34-8.37-3.07-1.47-8.23-1.31-10.25,1.09-2.53,3-2.29,6.71-1.64,9.3,1.25,5,5.08,9.77,9.11,11.37a2,2,0,0,1-.74,3.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M710.2,354a2,2,0,0,1-1.5-3.32c3.8-4.33,11.95-15.11,5.66-21.62-2.51-2.6-7.3-2.47-10.54-1-3.57,1.58-5.83,4.67-8,7.65l-.92,1.25a2,2,0,0,1-3.2-2.4l.89-1.21c2.38-3.25,5.08-6.93,9.62-8.94s11.23-2,15,1.91c6.05,6.26,4,16.12-5.53,27A2,2,0,0,1,710.2,354Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M658,401.5a2,2,0,0,1-1.75-3c1.28-2.33,6-3.06,16.21-3.8,1.16-.08,2.16-.16,2.84-.23a186.1,186.1,0,0,1,25.3-.51l3.1.08c6.61.14,14.83.32,19.92,3.76a2,2,0,1,1-2.24,3.31c-4.12-2.78-11.69-2.94-17.77-3.08l-3.16-.08a182.21,182.21,0,0,0-24.75.49c-.72.07-1.75.15-3,.24-3.18.23-11.54.84-13.11,1.92A2,2,0,0,1,658,401.5Zm1.75-1h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M550.5,403a2,2,0,0,1-.85-3.81c22.12-10.34,50.14-5.14,64.87-1.12a2,2,0,1,1-1.05,3.86c-14.2-3.88-41.16-8.92-62.13.88A2,2,0,0,1,550.5,403Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-24" d="M476,616.83c-37.71,0-75.29-.27-112.35-.54-33.89-.24-68.93-.5-103.27-.53-31.46,0-63.37-.27-94.23-.5l-35-.25a2,2,0,0,1,0-4h0l35,.25c30.85.23,62.75.46,94.2.5,34.35,0,69.4.29,103.29.53,86.22.62,175.38,1.26,262.11-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08a2,2,0,0,1,0,4c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08C576.39,616.35,526.08,616.83,476,616.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,591.73c-37.71,0-75.28-.27-112.32-.54-33.9-.24-69-.5-103.31-.53-31.4,0-63.25-.27-94.05-.5q-26.27-.19-52.54-.35a2,2,0,0,1,0-4h0q26.28.14,52.55.35c30.8.23,62.64.46,94,.5,34.37,0,69.43.29,103.33.53,86.21.62,175.36,1.26,262.07-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08,5.21,0,11.36.13,19.37.4a2,2,0,0,1,1.93,2.07,2,2,0,0,1-2.07,1.93c-8-.27-14.08-.39-19.24-.39-4,0-8,0-12-.08-7.82-.08-15.9-.17-23.81.08C576.4,591.25,526.09,591.73,476,591.73Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M89,396a2,2,0,0,1-.1-4,88.43,88.43,0,0,0,11.52-1.63c3-.56,6.18-1.15,9.26-1.47a131.34,131.34,0,0,1,15.92-.45c1.88,0,3.77.05,5.71,0,1.54,0,3.15,0,4.81-.07,7.7-.16,16.42-.33,23.09,2.2a2,2,0,0,1-1.42,3.74c-5.94-2.26-14.25-2.09-21.59-1.94-1.69,0-3.33.07-4.88.07-2,0-3.87,0-5.77,0a128,128,0,0,0-15.45.42c-2.92.31-6,.88-8.95,1.43A91.36,91.36,0,0,1,89.1,396Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M256,394.5a2,2,0,0,1-.63-.1c-13.31-4.45-28.4-3-43-1.64-5.39.51-11,1-16.28,1.24a2,2,0,1,1-.15-4c5.21-.2,10.48-.7,16.06-1.23,15-1.42,30.54-2.89,44.65,1.83a2,2,0,0,1-.63,3.9Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M91.67,303.33a2,2,0,0,1-2-2V282.07c0-4.12.11-8.41.34-12.75.09-1.79.1-4.22.11-6.8,0-3.27,0-6.64.22-8.83a2,2,0,1,1,4,.35c-.18,2-.19,5.31-.21,8.49,0,2.62,0,5.1-.12,7-.22,4.33-.33,8.44-.33,12.55v19.26A2,2,0,0,1,91.67,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.33,303.33a2,2,0,0,1-2-2V222.5a2,2,0,0,1,4,0v78.83A2,2,0,0,1,110.33,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M122.33,303.74a2,2,0,0,1-.93-.23c-1.39-.73-1.91-2.27-2.88-11.69-.08-.74-.14-1.34-.19-1.73-.64-5.16-1.33-10.52-2-16-2.33-18.08-4.73-36.78-6-53.83a2,2,0,1,1,4-.29c1.23,16.93,3.63,35.58,5.95,53.61.7,5.47,1.39,10.83,2,16,.05.41.12,1,.2,1.81.2,1.92.78,7.61,1.31,9a2,2,0,0,1-1.48,3.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M151.33,298.33a2,2,0,0,1-2-1.91,53.62,53.62,0,0,0-1.07-6.68c-.3-1.53-.62-3.1-.83-4.51-.49-3.15-1-6.3-1.55-9.46-.38-2.26-.75-4.52-1.12-6.79-.75-4.62-1.46-9.25-2.18-13.88-2.2-14.2-4.47-28.86-7.59-43.13-5.25-.24-12.81-.26-17,3.52a2,2,0,1,1-2.67-3c5.43-4.85,13.91-4.84,21.43-4.46a2,2,0,0,1,1.85,1.56c3.33,14.87,5.69,30.12,8,44.88.72,4.62,1.43,9.24,2.17,13.86q.55,3.38,1.12,6.76c.53,3.17,1.06,6.34,1.55,9.51.21,1.33.51,2.86.81,4.35a55.52,55.52,0,0,1,1.14,7.28,2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M138.56,304a2,2,0,0,1-.14-4,17.88,17.88,0,0,0,5.7-1.36c.58-.22,1.13-.44,1.7-.59a11.3,11.3,0,0,0,2.52-1.24c.58-.34,1.18-.7,1.81-1a2,2,0,0,1,1.71,3.61c-.46.22-1,.51-1.49.83a14.58,14.58,0,0,1-3.48,1.65c-.38.1-.82.27-1.33.47a21.89,21.89,0,0,1-6.85,1.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M153.33,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.06-3.86.13-7.85,0-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.1-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.44.33,26.71,1,38.39.41,7.12.49,14.44.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,153.33,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M170.33,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.2s-.17-4.93-.17-7.48v-7.94c0-22,0-44.68,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.37-.27-5-1.78-2.09-8.12-1.15-12.31-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.77,38.77,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.86-1,66.78v7.95c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,170.33,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M527.75,303.33a2,2,0,0,1-2-2V222.5a2,2,0,0,1,4,0v78.83A2,2,0,0,1,527.75,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M539.75,303.74a2,2,0,0,1-.93-.23c-1.39-.73-1.91-2.27-2.88-11.68-.08-.74-.14-1.35-.19-1.75l-.58-4.7c-2.64-21.32-5.92-47.86-7.42-68.57a2,2,0,0,1,4-.29c1.49,20.6,4.76,47.09,7.4,68.37l.58,4.7c.05.41.12,1.05.2,1.83.2,1.91.78,7.59,1.31,9a2,2,0,0,1-1.48,3.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M568.75,298.33a2,2,0,0,1-2-1.91,53.52,53.52,0,0,0-1.07-6.67c-.3-1.53-.62-3.11-.84-4.52-.49-3.15-1-6.3-1.54-9.46-.38-2.26-.75-4.52-1.12-6.79-.75-4.62-1.46-9.25-2.18-13.88-2.19-14.18-4.46-28.83-7.58-43.08-6.43.09-17.21,2.45-21.34,6.14a2,2,0,0,1-2.67-3c5.46-4.88,18.89-7.47,25.72-7.12a2,2,0,0,1,1.85,1.56c3.33,14.87,5.69,30.13,8,44.88.72,4.62,1.43,9.24,2.17,13.85.36,2.25.74,4.51,1.12,6.76.53,3.17,1.06,6.34,1.55,9.51.21,1.33.51,2.87.81,4.35a55.44,55.44,0,0,1,1.14,7.27,2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M556,304a2,2,0,0,1-.14-4,17.89,17.89,0,0,0,5.7-1.36c.58-.22,1.13-.44,1.7-.59a11.29,11.29,0,0,0,2.52-1.24c.58-.34,1.18-.7,1.81-1a2,2,0,1,1,1.71,3.61c-.46.22-1,.51-1.49.82a14.58,14.58,0,0,1-3.48,1.65c-.38.1-.82.27-1.33.47a21.89,21.89,0,0,1-6.85,1.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M570.75,302.67a2,2,0,0,1-2-2c0-2,0-4.06.07-6.1.06-3.86.13-7.85-.05-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,570.75,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.75,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.84-.16-7.2s-.17-4.93-.17-7.48v-7.93c0-22,0-44.69,1-67,0-.33,0-.69.06-1.08.08-1.2.29-4.37-.27-5-1.78-2.09-8.12-1.15-12.31-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.68-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.87-1,66.8v7.93c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,587.75,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M175.66,301.33a2,2,0,0,1-2-1.66,70.59,70.59,0,0,1-.53-13.69,87.77,87.77,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.77,90.77,0,0,1,.15,10.86,66.62,66.62,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M180.34,197.94a62.68,62.68,0,0,1-7-.33,2,2,0,1,1,.46-4,105.46,105.46,0,0,0,14.11.14c2.39-.08,4.65-.15,6.72-.15a2,2,0,0,1,2,2,2,2,0,0,1-2,2h0c-2,0-4.24.07-6.6.15C185.46,197.85,182.85,197.94,180.34,197.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M197.66,303.33a2,2,0,0,1-2-1.65,139.45,139.45,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59v-4.22a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4A135.63,135.63,0,0,0,199.64,301,2,2,0,0,1,198,303.3,2.05,2.05,0,0,1,197.66,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M207,212.49a2,2,0,0,1-.5-.06c-2.37-.61-8.13-.82-11.23-.84a2,2,0,1,1,0-4c2.94,0,9.26.2,12.22,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21A2,2,0,0,1,208,303Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M239.67,304h0a2,2,0,0,1-2-2c0-2.18-.07-5-.16-8s-.18-5.94-.18-8.58c0-15.56-.34-31.45-.67-46.8-.29-13.42-.59-27.3-.66-40.92a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c.07,13.58.37,27.45.66,40.85.33,15.38.68,31.28.68,46.89,0,2.59.09,5.57.18,8.46s.18,5.89.16,8.15A2,2,0,0,1,239.67,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M238,199.67a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.73,0c-1.77,0-3.59,0-5.36,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,1,1-1.69-3.63c2.26-1,5-1.11,7.28-1.15l1.16,0c1.87-.07,3.74,0,5.56,0l2.68,0c4.73,0,11.73.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M430.83,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.71,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,430.83,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M447.83,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.21s-.17-4.93-.17-7.47v-8c0-22,0-44.66,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,4.94.17,7.33s.17,4.87.17,7.35A2,2,0,0,1,447.83,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M453.16,301.33a2,2,0,0,1-2-1.66,70.61,70.61,0,0,1-.53-13.69,87.64,87.64,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.75,90.75,0,0,1,.15,10.86,66.58,66.58,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M457.84,197.94a62.68,62.68,0,0,1-7-.33,2,2,0,1,1,.46-4,105.2,105.2,0,0,0,14.11.14c2.41-.08,4.65-.13,6.77-.15a2,2,0,0,1,0,4h0c-2,0-4.24.07-6.6.15C463,197.85,460.35,197.94,457.84,197.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M475.16,303.33a2,2,0,0,1-2-1.65,139.55,139.55,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59v-4.22a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4A135.64,135.64,0,0,0,477.13,301a2,2,0,0,1-1.62,2.32A2,2,0,0,1,475.16,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M484.5,212.49a2,2,0,0,1-.5-.06c-2.37-.61-8.13-.84-11.22-.84h0a2,2,0,1,1,0-4h0c2.94,0,9.26.2,12.22,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M485.5,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21a2,2,0,0,1-1.83,2.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M517.17,304h0a2,2,0,0,1-2-2c0-2.18-.07-5-.16-8s-.18-5.94-.18-8.59c0-15.56-.34-31.44-.67-46.79-.29-13.43-.59-27.31-.66-40.93a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c.07,13.58.37,27.45.66,40.86.33,15.38.67,31.28.67,46.88,0,2.59.09,5.58.18,8.47s.18,5.89.16,8.15A2,2,0,0,1,517.17,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M515.5,199.67a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.73,0c-1.77,0-3.59,0-5.36,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,0,1-1.69-3.63c2.26-1,5-1.11,7.28-1.15l1.16,0c1.87-.07,3.74,0,5.56,0l2.68,0c4.73,0,11.73.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M637.34,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.71,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,637.34,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M654.34,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.2s-.17-4.93-.17-7.48v-8c0-22,0-44.66,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,654.34,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M659.67,301.33a2,2,0,0,1-2-1.66,70.61,70.61,0,0,1-.53-13.69,87.64,87.64,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,1,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.75,90.75,0,0,1,.15,10.86,66.58,66.58,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M681.67,303.33a2,2,0,0,1-2-1.65,139.55,139.55,0,0,1-1.7-17.26c-1.2-25.62-1.32-50.17-1.33-73.13a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,22.91.13,47.4,1.33,72.94A135.64,135.64,0,0,0,683.64,301a2,2,0,0,1-2,2.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M692,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.2-.08-30.69-.17-45.66l-.06-11.11a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2l.06,11.11c.08,15,.17,30.47.17,45.68,0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21A2,2,0,0,1,692,303Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M253,303.33a2,2,0,0,1-1.19-.4c-.74-.55-1.6-1.25-2.51-2-2.68-2.19-6.36-5.2-8.67-5.64a2,2,0,1,1,.75-3.93c3.31.63,7.27,3.87,10.46,6.47.87.72,1.7,1.39,2.37,1.89a2,2,0,0,1-1.2,3.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M241.33,293a2,2,0,0,1-1.94-2.48c2.64-10.63,9.2-19.77,15.55-28.61,2-2.82,3.94-5.48,5.73-8.19,3.93-5.95,7.81-12.09,11.57-18,4.56-7.21,9.27-14.66,14.11-21.83.44-.66.89-1.29,1.33-1.91a29.33,29.33,0,0,0,3.24-5.33c.53-1.23,2.4-5.38,4.32-7.35a2,2,0,1,1,2.86,2.79,25,25,0,0,0-3.51,6.14,32.85,32.85,0,0,1-3.65,6.06c-.42.6-.85,1.2-1.28,1.84-4.81,7.13-9.5,14.55-14,21.74-3.77,6-7.66,12.11-11.61,18.09-1.83,2.77-3.86,5.59-5.81,8.32-6.13,8.53-12.46,17.35-14.91,27.24A2,2,0,0,1,241.33,293Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M309.67,212a2,2,0,0,1-1.49-.67c-2.4-2.68-5.79-4.76-9.06-6.77-1.18-.72-2.39-1.47-3.55-2.23a2,2,0,0,1,2.21-3.34c1.1.73,2.23,1.42,3.43,2.16,3.52,2.16,7.16,4.39,10,7.51a2,2,0,0,1-1.49,3.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M254,304.33a2,2,0,0,1-1.92-2.58c.78-2.6,2.65-4.64,4.45-6.62a32.78,32.78,0,0,0,2.18-2.56c2.36-3.22,4.48-6.69,6.54-10.05l3.33-5.44c3.09-5.06,6.29-10.29,9.55-15.45a408.31,408.31,0,0,0,21.48-38.44c.38-.79.77-1.6,1.16-2.42,2-4.17,4.2-8.89,7.47-12.18a2,2,0,1,1,2.84,2.82c-2.78,2.8-4.77,7-6.69,11.07-.4.84-.79,1.67-1.18,2.47a412.46,412.46,0,0,1-21.69,38.82c-3.25,5.13-6.44,10.35-9.52,15.39l-3.33,5.44c-2.1,3.43-4.27,7-6.73,10.33a35.92,35.92,0,0,1-2.45,2.89c-1.5,1.65-3.06,3.36-3.58,5.09A2,2,0,0,1,254,304.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603.43,303.32a2,2,0,0,1-.75-.15c-.85-.35-1.86-.81-2.93-1.3-3.15-1.45-7.48-3.43-9.81-3.28a2,2,0,1,1-.26-4c3.38-.23,8,1.92,11.75,3.64,1,.47,2,.92,2.77,1.23a2,2,0,0,1-.76,3.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M589.54,296.25a2,2,0,0,1-2-2c-.12-11,3.94-21.45,7.86-31.6,1.25-3.24,2.43-6.29,3.49-9.36,2.31-6.75,4.53-13.67,6.67-20.36,2.6-8.12,5.29-16.51,8.17-24.67.26-.75.54-1.47.81-2.18a29.41,29.41,0,0,0,1.8-6c.2-1.32,1-5.82,2.34-8.2a2,2,0,1,1,3.47,2,25.08,25.08,0,0,0-1.86,6.83,32.91,32.91,0,0,1-2,6.78c-.26.68-.52,1.38-.78,2.1-2.86,8.1-5.54,16.47-8.13,24.56-2.15,6.71-4.37,13.65-6.7,20.44-1.08,3.14-2.33,6.38-3.54,9.51-3.79,9.8-7.7,19.92-7.59,30.11a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M635.33,200.68a2,2,0,0,1-1.11-.33c-3-2-6.8-3.15-10.47-4.27-1.32-.4-2.68-.82-4-1.27a2,2,0,1,1,1.3-3.78c1.25.43,2.52.82,3.87,1.23,3.95,1.21,8,2.45,11.52,4.77a2,2,0,0,1-1.11,3.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.65,304h-.08a2,2,0,0,1-1.92-2.08c.11-2.71,1.4-5.16,2.65-7.53a32.79,32.79,0,0,0,1.47-3c1.47-3.71,2.66-7.6,3.81-11.37l1.86-6.13c1.72-5.67,3.49-11.52,5.36-17.33A408.38,408.38,0,0,0,628.92,214c.17-.86.34-1.74.51-2.64.86-4.53,1.84-9.66,4.17-13.66a2,2,0,1,1,3.46,2c-2,3.41-2.86,8-3.7,12.39-.17.92-.35,1.82-.52,2.69a412.59,412.59,0,0,1-11.24,43c-1.85,5.77-3.63,11.61-5.34,17.26l-1.86,6.13c-1.17,3.85-2.38,7.83-3.92,11.69a35.72,35.72,0,0,1-1.65,3.41c-1,2-2.12,4-2.19,5.82A2,2,0,0,1,604.65,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M310,304.86a2,2,0,0,1-2-1.91c-.52-11.52-.63-20-.34-26,.76-16,.71-32.73.67-48.9,0-13.26-.08-27,.33-40.1a2,2,0,0,1,4,.13c-.41,13.07-.37,26.74-.33,40,0,16.22.1,33-.67,49.1-.28,5.88-.17,14.28.34,25.67a2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M323.33,305.14a2,2,0,0,1-2-2V278.83c0-5.5-.21-11.11-.41-16.53-.3-8.08-.62-16.43-.25-24.7.34-7.62.33-15.47.33-23.06v-2.2c0-2.18.07-4.55.14-7.06a126.8,126.8,0,0,0-.26-17,2,2,0,1,1,4-.46,129.52,129.52,0,0,1,.29,17.58c-.07,2.48-.14,4.82-.14,6.94v2.2c0,7.64,0,15.53-.34,23.24-.36,8.1,0,16.37.25,24.37.21,5.46.42,11.11.42,16.68v24.31A2,2,0,0,1,323.33,305.14Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M340.5,221a2,2,0,0,1-.78-.16c-2.63-1.12-8.49-.91-12.77-.75-1.38.05-2.69.1-3.76.1a2,2,0,0,1,0-4c1,0,2.27,0,3.61-.1,4.92-.18,11-.4,14.49,1.07a2,2,0,0,1-.79,3.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M338.75,305.14a2,2,0,0,1-2-2V289.69c0-11.85.45-23.83.88-35.41s.88-23.52.87-35.28a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,11.84-.44,23.83-.87,35.43s-.87,23.48-.87,35.26v13.45A2,2,0,0,1,338.75,305.14Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M346.25,305.29a2,2,0,0,1-2-2V293c0-9.65-.1-19.65-.19-29.32s-.19-19.77-.19-29.53a2,2,0,1,1,4,0c0,9.74.1,19.78.19,29.49s.19,19.68.19,29.35v10.31A2,2,0,0,1,346.25,305.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M380.14,236.27h-.33c-16.41-.09-27.82-.13-33.94-.13a2,2,0,0,1,0-4c6.12,0,17.54,0,34,.13h1.38v2l2,0C383.19,236.15,381.69,236.27,380.14,236.27Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M380,303.28a2,2,0,0,1-2-2c0-9.68.36-21.38,1-32.94.48-8.65.38-17.78.28-26.61,0-2.51-.06-5-.07-7.44a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,2.44,0,4.92.07,7.42.1,8.9.21,18.09-.28,26.88-.64,11.49-1,23.11-1,32.71A2,2,0,0,1,380,303.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M384.18,302.4a2,2,0,0,1-2-2c-.05-4.06-.14-11.62-.4-16.81-.38-7.67,0-15.44.28-22.95.22-5.06.45-10.3.45-15.42,0-6.33.06-13.14.13-19.74s.13-13.42.13-19.76a2,2,0,0,1,4,0c0,6.35-.06,13.19-.12,19.79s-.12,13.39-.12,19.7c0,5.2-.23,10.49-.45,15.59-.32,7.42-.65,15.09-.28,22.58.26,5.27.36,12.88.41,17a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M425,208c-2.64,0-5.15-.2-7.58-.39-2-.16-3.87-.31-5.84-.36-4.83-.13-9.6.07-13.22.26-2.63.14-10.62.24-13.62.24a2,2,0,0,1,0-4c3,0,10.84-.1,13.41-.23,3.69-.19,8.56-.39,13.53-.26,2.08.05,4.1.21,6.05.37,2.35.19,4.78.38,7.26.38a2,2,0,0,1,0,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M424.5,296a2,2,0,0,1-2-2V279.51c0-12.4.19-24.88.38-37s.37-24.48.37-36.81a2,2,0,0,1,4,0c0,12.36-.19,24.82-.37,36.87s-.37,24.52-.37,36.89V294A2,2,0,0,1,424.5,296Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M657.67,197.33a2,2,0,0,1,0-4c1.61,0,3.14-.17,4.77-.34,1.35-.14,2.75-.28,4.18-.33a2,2,0,0,1,.14,4c-1.29,0-2.56.17-3.91.31-1.65.17-3.35.34-5.15.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M516.67,225.33a2,2,0,0,1-.88-3.8c2.92-1.42,9.36-1.86,12.44-.32a2,2,0,0,1-1.79,3.58c-1.87-.94-7-.59-8.9.34A2,2,0,0,1,516.67,225.33Z" transform="translate(-53.25 -44.96)"/><g class="cls-27"><path class="cls-24" d="M161.5,730.09a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.38.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,161.5,730.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M178.5,730.76h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.21s-.17-4.93-.17-7.47v-7.94c0-22,0-44.67,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a39.88,39.88,0,0,1-5.15.57h0a2,2,0,0,1,0-4,39,39,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.86-1,66.78v7.95c0,2.48.08,4.95.17,7.34s.17,4.87.17,7.35A2,2,0,0,1,178.5,730.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.83,728.76a2,2,0,0,1-2-1.66,70.59,70.59,0,0,1-.53-13.69,87.87,87.87,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.77,90.77,0,0,1,.15,10.86,66.65,66.65,0,0,0,.47,12.91,2,2,0,0,1-1.63,2.31Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M188.51,625.36a62.93,62.93,0,0,1-7-.33,2,2,0,0,1,.46-4,105.22,105.22,0,0,0,14.11.14c2.39-.08,4.65-.15,6.72-.15a2,2,0,1,1,0,4s0,0,0,0c-2,0-4.24.07-6.6.15C193.63,625.28,191,625.36,188.51,625.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M205.83,730.76a2,2,0,0,1-2-1.65,139.57,139.57,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59V623a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4a135.64,135.64,0,0,0,1.64,16.74,2,2,0,0,1-2,2.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.17,639.92a2,2,0,0,1-.5-.06c-2.37-.61-8.12-.84-11.21-.84h0a2,2,0,0,1,0-4h0c2.94,0,9.25.2,12.21,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.17,730.43a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21a2,2,0,0,1-1.83,2.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M246.16,627.1a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.72,0c-1.77,0-3.6,0-5.37,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,1,1-1.69-3.63c2.26-1,5-1.11,7.27-1.15l1.16,0c1.87-.07,3.75,0,5.58,0l2.67,0c4.73,0,11.72.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-28"><path class="cls-24" d="M578.92,730.09a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.39-.38-12.92-.45-19.23-.08-7-.17-14.32-.57-21.34-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.38.41,7.12.49,14.44.57,21.52.07,6.28.15,12.77.45,19.09.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,578.92,730.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M595.92,730.76h0a2,2,0,0,1-2-2c0-2.41-.08-4.84-.16-7.2s-.17-4.93-.17-7.48v-8c0-22,0-44.66,1-66.95,0-.32,0-.68.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.31-.53a39.9,39.9,0,0,1-5.15.57h0a2,2,0,0,1,0-4,39,39,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.22,1.21,7.89,0,.36,0,.69-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,595.92,730.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M611.59,730.75a2,2,0,0,1-.75-.15c-.85-.35-1.86-.81-2.93-1.3-3.15-1.45-7.45-3.44-9.81-3.28a2,2,0,1,1-.26-4c3.38-.21,8,1.92,11.75,3.64,1,.47,2,.92,2.76,1.23a2,2,0,0,1-.76,3.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M597.71,723.68a2,2,0,0,1-2-2c-.12-11,3.94-21.45,7.86-31.6,1.25-3.24,2.43-6.29,3.48-9.36,2.31-6.75,4.53-13.67,6.67-20.36,2.6-8.12,5.29-16.51,8.17-24.67.26-.75.54-1.47.81-2.18a29.33,29.33,0,0,0,1.8-6c.2-1.32,1-5.82,2.34-8.21a2,2,0,0,1,3.47,2,25.08,25.08,0,0,0-1.86,6.83,32.84,32.84,0,0,1-2,6.78c-.26.68-.52,1.38-.78,2.1-2.86,8.1-5.54,16.47-8.13,24.55-2.15,6.71-4.37,13.65-6.7,20.44-1.08,3.14-2.33,6.38-3.54,9.51-3.79,9.8-7.7,19.93-7.59,30.11a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M643.5,628.11a2,2,0,0,1-1.11-.33c-3-2-6.8-3.15-10.47-4.27-1.32-.4-2.68-.82-4-1.27a2,2,0,1,1,1.3-3.78c1.25.43,2.52.82,3.86,1.23,4,1.21,8,2.45,11.52,4.77a2,2,0,0,1-1.11,3.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M612.81,731.47h-.08a2,2,0,0,1-1.92-2.08c.11-2.71,1.4-5.16,2.65-7.53a32.54,32.54,0,0,0,1.47-3c1.47-3.71,2.66-7.61,3.81-11.38l1.86-6.12c1.72-5.67,3.49-11.53,5.36-17.33a408,408,0,0,0,11.13-42.6c.17-.86.34-1.74.51-2.64.86-4.53,1.84-9.66,4.17-13.67a2,2,0,0,1,3.46,2c-2,3.41-2.86,8-3.7,12.4-.17.92-.35,1.82-.52,2.69a412.27,412.27,0,0,1-11.24,43c-1.86,5.77-3.63,11.61-5.34,17.27l-1.86,6.12c-1.17,3.85-2.38,7.83-3.92,11.69a35.94,35.94,0,0,1-1.65,3.41c-1,2-2.12,4-2.19,5.83A2,2,0,0,1,612.81,731.47Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-29"><path class="cls-24" d="M694.89,584.32h-.09a2,2,0,0,1-1.91-2.09,55.68,55.68,0,0,1,1.14-7.28c.29-1.48.6-3,.8-4.34.49-3.16,1-6.33,1.55-9.5q.57-3.38,1.12-6.77c.75-4.62,1.46-9.24,2.18-13.86,2.28-14.75,4.64-30,8-44.87A2,2,0,0,1,709.5,494c7.52-.39,16-.39,21.43,4.46a2,2,0,1,1-2.67,3c-4.23-3.78-11.79-3.76-17-3.52-3.13,14.27-5.4,28.93-7.59,43.13-.72,4.63-1.43,9.26-2.18,13.89q-.55,3.4-1.12,6.79c-.53,3.16-1.05,6.31-1.54,9.46-.22,1.41-.53,3-.83,4.51a53.58,53.58,0,0,0-1.07,6.68A2,2,0,0,1,694.89,584.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M707.66,590h-.15a21.87,21.87,0,0,1-6.85-1.62c-.51-.2-1-.37-1.33-.47a14.59,14.59,0,0,1-3.49-1.65c-.53-.31-1-.6-1.49-.82a2,2,0,1,1,1.71-3.61c.63.3,1.23.65,1.81,1a11.31,11.31,0,0,0,2.52,1.24c.57.16,1.11.37,1.7.59a17.86,17.86,0,0,0,5.7,1.36,2,2,0,0,1-.14,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M692.88,588.65a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.81.45-19.09.08-7.08.17-14.41.57-21.52.67-11.68,1-25,1-38.39a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.5-.33,26.86-1,38.62-.4,7-.49,14.3-.57,21.34-.07,6.32-.15,12.84-.45,19.23-.18,3.85-.12,7.84,0,11.7,0,2,.07,4.08.07,6.11A2,2,0,0,1,692.88,588.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M675.88,589.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-8c0-21.91,0-44.57-1-66.76,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.22-3.79,10.28-2.74,16-1.9a38.94,38.94,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.38,0,.75.06,1.07,1,22.29,1,45,1,66.95v8c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.21A2,2,0,0,1,675.88,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M670.55,587.32l-.34,0a2,2,0,0,1-1.63-2.31,66.62,66.62,0,0,0,.47-12.9,90.82,90.82,0,0,1,.16-10.87c1.92-20.09,1.73-41.2,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,1,1,4,0c0,5.92.05,12,.11,18,.18,20.52.37,41.73-1.57,62a87.71,87.71,0,0,0-.14,10.38,70.56,70.56,0,0,1-.53,13.69A2,2,0,0,1,670.55,587.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M665.88,483.92c-2.51,0-5.12-.08-7.68-.17-2.36-.08-4.59-.15-6.59-.15h-.05a2,2,0,1,1,.05-4c2.07,0,4.33.07,6.72.15a105.2,105.2,0,0,0,14.1-.14,2,2,0,0,1,.46,4A62.84,62.84,0,0,1,665.88,483.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M648.55,589.32a2,2,0,0,1-2-2.35,135.59,135.59,0,0,0,1.64-16.74c1.34-28.56,1.34-55.68,1.33-84.4V481.6a2,2,0,1,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59a139.52,139.52,0,0,1-1.7,17.26A2,2,0,0,1,648.55,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M639.22,498.47a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,639.22,498.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M638.22,589a2,2,0,0,1-1.83-2.8c.8-1.84.67-5.92.57-9.21,0-1.12-.07-2.19-.07-3.15,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,1,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.92,0,1.95.07,3,.12,3.87.25,8.26-.9,10.92A2,2,0,0,1,638.22,589Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M606.55,590a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.67-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M608.22,485.65a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.88-2.13l2.69,0c1.81,0,3.69,0,5.55,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.5-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.58,0-5.34,0l-2.75,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,608.22,485.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M593.22,589.32a2,2,0,0,1-1.2-3.6c.67-.5,1.49-1.17,2.37-1.89,3.18-2.6,7.14-5.84,10.45-6.47a2,2,0,1,1,.75,3.93c-2.31.44-6,3.45-8.67,5.64-.91.75-1.77,1.45-2.51,2A2,2,0,0,1,593.22,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.88,579a2,2,0,0,1-1.94-1.52c-2.45-9.89-8.79-18.71-14.92-27.24-2-2.72-4-5.54-5.81-8.31-4-6-7.85-12.14-11.61-18.09-4.54-7.18-9.24-14.61-14-21.73-.43-.63-.86-1.24-1.28-1.84a32.89,32.89,0,0,1-3.65-6.05,25,25,0,0,0-3.51-6.14,2,2,0,1,1,2.86-2.79c1.92,2,3.79,6.13,4.32,7.35a29.38,29.38,0,0,0,3.24,5.33c.44.62.89,1.25,1.33,1.92,4.84,7.17,9.55,14.62,14.11,21.83,3.76,5.94,7.64,12.08,11.57,18,1.79,2.71,3.7,5.37,5.72,8.19,6.35,8.84,12.91,18,15.55,28.61a2,2,0,0,1-1.94,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M592.22,590.32a2,2,0,0,1-1.91-1.42c-.52-1.73-2.08-3.44-3.58-5.09a36.17,36.17,0,0,1-2.45-2.89c-2.45-3.34-4.62-6.89-6.72-10.31l-3.35-5.49c-3.08-5-6.26-10.25-9.5-15.37A412.7,412.7,0,0,1,543,510.94c-.39-.8-.78-1.63-1.18-2.47-1.92-4.07-3.91-8.27-6.69-11.07a2,2,0,1,1,2.84-2.82c3.26,3.29,5.5,8,7.47,12.18.39.83.78,1.64,1.16,2.43a408.3,408.3,0,0,0,21.47,38.44c3.26,5.15,6.45,10.37,9.54,15.42l3.35,5.48c2.06,3.35,4.18,6.82,6.53,10a32.83,32.83,0,0,0,2.18,2.56c1.8,2,3.67,4,4.45,6.62a2,2,0,0,1-1.92,2.58Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-30"><path class="cls-24" d="M113.55,589.32a2,2,0,0,1-2-2V508.48a2,2,0,0,1,4,0v78.83A2,2,0,0,1,113.55,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M101.55,589.72a2,2,0,0,1-1.48-3.35c.52-1.38,1.11-7.07,1.31-9,.08-.77.15-1.41.2-1.81l.58-4.72c2.63-21.27,5.9-47.75,7.39-68.35a2,2,0,1,1,4,.29c-1.5,20.7-4.78,47.23-7.41,68.55l-.58,4.72c0,.39-.11,1-.19,1.73-1,9.42-1.49,11-2.88,11.69A2,2,0,0,1,101.55,589.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M72.55,584.32h-.09a2,2,0,0,1-1.91-2.09,55.58,55.58,0,0,1,1.14-7.28c.29-1.49.6-3,.81-4.35.49-3.16,1-6.33,1.55-9.5.38-2.25.75-4.51,1.12-6.77.74-4.62,1.46-9.24,2.17-13.86,2.28-14.75,4.64-30,8-44.88A2,2,0,0,1,87.17,494c6.85-.36,20.26,2.25,25.72,7.12a2,2,0,1,1-2.67,3c-4.13-3.69-14.91-6-21.34-6.14-3.12,14.25-5.39,28.9-7.58,43.08-.72,4.63-1.43,9.26-2.18,13.88-.37,2.26-.74,4.53-1.12,6.79-.53,3.16-1.05,6.31-1.54,9.46-.22,1.41-.53,3-.83,4.51a53.65,53.65,0,0,0-1.07,6.68A2,2,0,0,1,72.55,584.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.47,588.65a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.39a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.23-.18,3.86-.11,7.85,0,11.71,0,2,.07,4.08.07,6.11A2,2,0,0,1,210.47,588.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193.47,589.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a39,39,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.95c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.21A2,2,0,0,1,193.47,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M188.14,587.32l-.34,0a2,2,0,0,1-1.63-2.31,66.63,66.63,0,0,0,.47-12.91,90.75,90.75,0,0,1,.15-10.86c1.92-20.09,1.73-41.21,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.95.18,20.52.37,41.74-1.57,62a87.75,87.75,0,0,0-.14,10.38,70.6,70.6,0,0,1-.53,13.69A2,2,0,0,1,188.14,587.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.47,483.92c-2.51,0-5.12-.08-7.68-.17-2.38-.08-4.63-.15-6.64-.15h0a2,2,0,0,1,0-4h.05c2.07,0,4.33.07,6.72.15a105.06,105.06,0,0,0,14.1-.14,2,2,0,0,1,.46,4A62.84,62.84,0,0,1,183.47,483.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M166.14,589.32a2,2,0,0,1-2-2.35,135.67,135.67,0,0,0,1.64-16.74c1.34-28.56,1.34-55.68,1.33-84.4V481.6a2,2,0,0,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59a139.43,139.43,0,0,1-1.7,17.26A2,2,0,0,1,166.14,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M156.8,498.47a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,156.8,498.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M155.81,589a2,2,0,0,1-1.83-2.8c.8-1.84.67-5.92.57-9.21,0-1.12-.07-2.19-.07-3.15,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,1,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.92,0,1.95.07,3,.12,3.87.25,8.26-.9,10.92A2,2,0,0,1,155.81,589Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M124.14,590a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.68-46.88.29-13.41.59-27.28.66-40.87a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M125.81,485.65a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.87-2.13l2.69,0c1.81,0,3.69,0,5.55,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.5-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.58,0-5.35,0l-2.74,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,125.81,485.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.31,494a2,2,0,1,1,0-4c2.48,0,4.91-.19,7.26-.38,2-.16,4-.32,6.06-.37,5-.13,9.84.07,13.53.26,2.43.13,10.08.23,13.41.23a2,2,0,0,1,0,4c-3,0-11-.1-13.61-.24-3.62-.19-8.39-.39-13.22-.26-2,.05-3.85.2-5.85.36C221.45,493.78,218.95,494,216.31,494Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.81,582a2,2,0,0,1-2-2V565.5c0-12.37-.19-24.84-.37-36.89s-.37-24.51-.37-36.87a2,2,0,0,1,4,0c0,12.33.19,24.77.37,36.81s.38,24.55.38,37V580A2,2,0,0,1,216.81,582Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M124.64,511.32a2,2,0,0,1-.87-.2c-1.92-.93-7-1.28-8.9-.34a2,2,0,1,1-1.79-3.58c3.07-1.54,9.51-1.1,12.44.32a2,2,0,0,1-.88,3.8Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-31"><path class="cls-24" d="M625.89,161.66a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.81.45-19.09.08-7.08.17-14.41.57-21.52.67-11.68,1-25,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.5-.33,26.86-1,38.62-.4,7-.49,14.3-.57,21.34-.07,6.31-.15,12.84-.45,19.23-.18,3.85-.12,7.84,0,11.7,0,2,.07,4.08.07,6.11A2,2,0,0,1,625.89,161.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M608.89,162.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-8c0-21.91,0-44.57-1-66.76,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a38.75,38.75,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,66.95v8c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,608.89,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M251.47,162.32a2,2,0,0,1-2-2V81.49a2,2,0,1,1,4,0v78.83A2,2,0,0,1,251.47,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M238.84,164.65a2,2,0,0,1-1.49-3.34c.21-.53.95-3,2.15-12.73l.58-4.72c2.63-21.27,5.9-47.75,7.39-68.34a2,2,0,0,1,4,.29c-1.5,20.7-4.78,47.23-7.41,68.54l-.58,4.72c-1.77,14.33-2.66,14.8-3.7,15.35A2,2,0,0,1,238.84,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.47,157.32h-.09a2,2,0,0,1-1.91-2.09,55.62,55.62,0,0,1,1.14-7.28c.29-1.49.6-3,.81-4.35.49-3.16,1-6.33,1.55-9.51.38-2.25.75-4.51,1.12-6.76.74-4.61,1.46-9.24,2.17-13.86,2.28-14.75,4.64-30,8-44.88A2,2,0,0,1,225.08,67c6.84-.35,20.26,2.25,25.72,7.12a2,2,0,1,1-2.67,3c-4.13-3.69-14.91-6-21.34-6.14-3.12,14.26-5.39,28.9-7.58,43.08-.72,4.63-1.43,9.26-2.18,13.88q-.55,3.39-1.12,6.78c-.53,3.16-1.05,6.32-1.55,9.47-.22,1.41-.53,3-.83,4.51a53.54,53.54,0,0,0-1.07,6.68A2,2,0,0,1,210.47,157.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M224.5,164.58h-.15a18.39,18.39,0,0,1-7.71-2.77,11.93,11.93,0,0,0-1.73-.87,14.6,14.6,0,0,1-3.48-1.65c-.53-.31-1-.6-1.49-.82a2,2,0,1,1,1.71-3.61c.63.3,1.23.65,1.81,1a11.28,11.28,0,0,0,2.52,1.24,12.72,12.72,0,0,1,2.62,1.24,14.89,14.89,0,0,0,6,2.27,2,2,0,0,1-.14,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208.47,161.66a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.22-.18,3.86-.11,7.85,0,11.71,0,2,.07,4.08.07,6.11A2,2,0,0,1,208.47,161.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M191.47,162.32a2,2,0,0,1-2-2c0-2.48.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.17-2.67-.39-6,1.21-7.88,3.21-3.79,10.28-2.74,16-1.9a38.76,38.76,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.57-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.94c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,191.47,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603.56,163.53a2,2,0,0,1-2-2.34c.7-4.07.59-9.54.47-14.84a109.87,109.87,0,0,1,.16-12.13c1.92-20.09,1.74-41.21,1.55-61.63-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.94.18,20.52.37,41.74-1.57,62a107,107,0,0,0-.14,11.66c.12,5.49.24,11.16-.53,15.61A2,2,0,0,1,603.56,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M598.88,56.92c-2.51,0-5.12-.08-7.69-.17-2.36-.08-4.59-.15-6.59-.15h0a2,2,0,0,1-2-2,2,2,0,0,1,2-2c2.07,0,4.33.07,6.72.15a105.14,105.14,0,0,0,14.11-.14,2,2,0,1,1,.46,4A62.66,62.66,0,0,1,598.88,56.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M581.56,162.32a2,2,0,0,1-2-2.35,135.61,135.61,0,0,0,1.64-16.74c1.34-28.54,1.34-55.65,1.33-84.35V54.61a2,2,0,0,1,4,0v4.27c0,28.75,0,55.9-1.34,84.54a139.52,139.52,0,0,1-1.7,17.26A2,2,0,0,1,581.56,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M572.22,71.48a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,572.22,71.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M571.72,163.53a2,2,0,0,1-1.83-2.8c.7-1.62.42-6.14.21-9.44-.1-1.64-.2-3.19-.2-4.45,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,0,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,1.13.09,2.62.2,4.19.27,4.32.56,8.78-.53,11.29A2,2,0,0,1,571.72,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M539.56,163a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.67-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,2-2,2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M541.22,58.66a2,2,0,0,1-.71-3.87c4.15-1.57,11.15-2.13,15.88-2.13l2.68,0c1.82,0,3.7,0,5.56,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.49-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.59,0-5.36,0l-2.73,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,541.22,58.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M349.32,164.65a2,2,0,0,1-2-2c0-2.53-.23-5.64-.47-8.93a109,109,0,0,1-.47-12.06c.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.22a106.6,106.6,0,0,0,.47,11.58c.25,3.37.48,6.55.48,9.23A2,2,0,0,1,349.32,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M331.39,162.32a2,2,0,0,1-2-2c0-2.48.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a38.76,38.76,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.57-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.95c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,331.39,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M326.06,163a2,2,0,0,1-2-2.34c.7-4.06.59-9.38.47-14.52a107.94,107.94,0,0,1,.16-11.92c1.92-20.09,1.73-41.21,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.95.18,20.52.37,41.74-1.57,62a103.64,103.64,0,0,0-.14,11.45c.12,5.33.24,10.84-.53,15.29A2,2,0,0,1,326.06,163Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M321.39,56.92c-2.51,0-5.12-.08-7.69-.17-2.36-.08-4.59-.15-6.59-.15h0a2,2,0,1,1,0-4c2.07,0,4.33.07,6.72.15a105.3,105.3,0,0,0,14.1-.14,2,2,0,1,1,.46,4A62.65,62.65,0,0,1,321.39,56.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M304.06,164.65a2,2,0,0,1-2-2.35,169,169,0,0,0,1.64-19.07c1.34-28.56,1.34-55.68,1.33-84.4V54.61a2,2,0,0,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59A172.17,172.17,0,0,1,306,163,2,2,0,0,1,304.06,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M294.72,71.48a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1a2,2,0,0,1,2,2,2,2,0,0,1-2,2h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,294.72,71.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M293.72,164.65a2,2,0,0,1-1.83-2.8c.82-1.89.66-8.07.56-11.76,0-1.24-.06-2.36-.06-3.25,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,0,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.86,0,1.95.06,3.15.16,6.1.19,11-.89,13.45A2,2,0,0,1,293.72,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.06,163a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.68-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,4,0c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M263.72,58.66a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.87-2.13l2.68,0c1.82,0,3.7,0,5.56,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,1,1-1.69,3.63c-1.49-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.59,0-5.36,0l-2.73,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,263.72,58.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M526.22,162.32a2,2,0,0,1-1.2-3.6c.67-.5,1.5-1.17,2.37-1.89,3.18-2.6,7.14-5.84,10.45-6.47a2,2,0,1,1,.75,3.93c-2.32.44-6,3.45-8.67,5.64-.91.75-1.77,1.45-2.51,2A2,2,0,0,1,526.22,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M537.89,152a2,2,0,0,1-1.94-1.52c-2.45-9.89-8.79-18.71-14.92-27.24-2-2.72-4-5.54-5.81-8.31-4-6-7.85-12.14-11.61-18.09-4.54-7.18-9.24-14.61-14-21.73-.43-.63-.86-1.24-1.28-1.84a32.83,32.83,0,0,1-3.65-6.06,25,25,0,0,0-3.51-6.14A2,2,0,1,1,484,58.26c1.92,2,3.8,6.13,4.32,7.35a29.37,29.37,0,0,0,3.24,5.33c.44.62.89,1.25,1.33,1.91C497.72,80,502.43,87.48,507,94.68c3.76,5.94,7.64,12.08,11.57,18,1.79,2.71,3.7,5.37,5.72,8.19,6.35,8.84,12.91,18,15.55,28.61a2,2,0,0,1-1.46,2.42A2,2,0,0,1,537.89,152Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M469.56,71a2,2,0,0,1-1.49-3.33c2.79-3.12,6.43-5.35,10-7.51,1.2-.74,2.33-1.43,3.43-2.16a2,2,0,0,1,2.21,3.34c-1.16.77-2.37,1.51-3.55,2.23-3.28,2-6.66,4.08-9.06,6.77A2,2,0,0,1,469.56,71Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M525.22,163.32a2,2,0,0,1-1.91-1.42c-.52-1.73-2.08-3.44-3.58-5.09a35.82,35.82,0,0,1-2.45-2.89c-2.46-3.36-4.63-6.91-6.74-10.34l-3.35-5.48c-3.07-5-6.25-10.23-9.49-15.35A412.58,412.58,0,0,1,476,83.94c-.39-.8-.78-1.63-1.18-2.47-1.92-4.07-3.91-8.27-6.69-11.07A2,2,0,1,1,471,67.58c3.26,3.29,5.5,8,7.47,12.18.39.83.78,1.64,1.16,2.42a408.43,408.43,0,0,0,21.47,38.44c3.26,5.14,6.44,10.36,9.53,15.4L514,141.5c2.06,3.37,4.19,6.85,6.55,10.07a32.68,32.68,0,0,0,2.18,2.56c1.8,2,3.67,4,4.45,6.62a2,2,0,0,1-1.92,2.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M175.8,162.31a2,2,0,0,1-.76-3.85c.77-.31,1.74-.76,2.77-1.23,3.73-1.72,8.37-3.86,11.74-3.64a2,2,0,1,1-.26,4c-2.35-.14-6.66,1.83-9.81,3.28-1.07.49-2.08,1-2.93,1.31A2,2,0,0,1,175.8,162.31Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M189.68,155.24h0a2,2,0,0,1-2-2c.11-10.19-3.81-20.32-7.59-30.11-1.21-3.13-2.46-6.36-3.54-9.51-2.32-6.79-4.55-13.73-6.7-20.44-2.59-8.09-5.27-16.45-8.13-24.55-.25-.72-.52-1.41-.78-2.1a32.89,32.89,0,0,1-2-6.78,25,25,0,0,0-1.86-6.83,2,2,0,1,1,3.47-2c1.37,2.39,2.13,6.89,2.34,8.2a29.35,29.35,0,0,0,1.8,6c.27.71.54,1.43.81,2.18,2.88,8.16,5.57,16.55,8.17,24.67,2.14,6.69,4.36,13.62,6.67,20.36,1.05,3.07,2.23,6.13,3.48,9.36,3.92,10.15,8,20.64,7.86,31.6A2,2,0,0,1,189.68,155.24Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M143.89,59.67A2,2,0,0,1,142.78,56c3.49-2.32,7.57-3.56,11.52-4.77,1.35-.41,2.62-.8,3.86-1.23a2,2,0,0,1,1.3,3.78c-1.31.45-2.67.87-4,1.27-3.68,1.12-7.48,2.28-10.48,4.27A2,2,0,0,1,143.89,59.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M174.57,163a2,2,0,0,1-2-1.92c-.07-1.8-1.15-3.85-2.19-5.82a35.88,35.88,0,0,1-1.65-3.41C167.21,148,166,144,164.83,140.2L163,134.1c-1.72-5.67-3.49-11.52-5.35-17.31a412.5,412.5,0,0,1-11.24-43c-.18-.87-.35-1.78-.52-2.69-.84-4.42-1.71-9-3.7-12.4a2,2,0,1,1,3.46-2c2.33,4,3.31,9.14,4.17,13.66.17.9.34,1.78.51,2.64a408.42,408.42,0,0,0,11.13,42.6c1.87,5.82,3.65,11.69,5.37,17.37l1.85,6.09c1.15,3.77,2.33,7.66,3.81,11.36a32.7,32.7,0,0,0,1.47,3c1.25,2.37,2.54,4.82,2.65,7.53a2,2,0,0,1-1.92,2.08Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M469.22,163.85h-.09a2,2,0,0,1-1.91-2.09c.51-11.39.62-19.78.34-25.67-.77-16.11-.72-32.88-.67-49.1,0-13.22.08-26.89-.33-40a2,2,0,0,1,4-.13c.41,13.13.37,26.84.33,40.09,0,16.17-.1,32.9.67,48.9.29,6,.17,14.53-.34,26A2,2,0,0,1,469.22,163.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M455.89,164.13a2,2,0,0,1-2-2V137.82c0-5.58.21-11.22.42-16.68.3-8,.61-16.27.25-24.37-.34-7.72-.34-15.63-.34-23.28V71.32c0-2.12-.07-4.46-.14-6.94a129.62,129.62,0,0,1,.29-17.58,2,2,0,1,1,4,.46,127,127,0,0,0-.26,17c.07,2.51.14,4.87.14,7.05v2.16c0,7.61,0,15.47.33,23.1.37,8.26.05,16.62-.25,24.7-.2,5.42-.41,11-.41,16.53v24.31A2,2,0,0,1,455.89,164.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M438.72,80a2,2,0,0,1-.79-3.84c3.45-1.47,9.57-1.25,14.49-1.07,1.35,0,2.62.1,3.61.1a2,2,0,0,1,0,4c-1.07,0-2.38,0-3.76-.1-4.28-.16-10.15-.37-12.77.75A2,2,0,0,1,438.72,80Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M440.47,164.13a2,2,0,0,1-2-2V148.68c0-11.78-.44-23.72-.87-35.26s-.88-23.59-.87-35.43a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,11.76.44,23.71.87,35.28s.88,23.56.88,35.41v13.45A2,2,0,0,1,440.47,164.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M433,164.28a2,2,0,0,1-2-2V152c0-9.67.09-19.68.19-29.35s.19-19.75.19-29.49a2,2,0,0,1,4,0c0,9.76-.1,19.81-.19,29.53S435,142.32,435,152v10.31A2,2,0,0,1,433,164.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M399.1,95.25c-1.5,0-3.07-.11-3.08-2l2,0v-2h1.37c16.41-.09,27.84-.13,34-.13a2,2,0,1,1,0,4c-6.11,0-17.53,0-33.94.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M399.22,164.65a2,2,0,0,1-2-2c0-10.34-.4-24.44-1-35.1-.49-8.79-.39-18-.28-26.87,0-2.5.06-5,.07-7.43a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,2.45,0,4.94-.07,7.45-.1,8.82-.21,18,.28,26.6.6,10.72,1,24.92,1,35.32A2,2,0,0,1,399.22,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395,163.53h0a2,2,0,0,1-2-2l0-1.28c.06-4.91.16-13.14.39-17.83.37-7.49,0-15.16-.28-22.58-.22-5.11-.45-10.39-.45-15.59,0-6.31-.06-13.12-.12-19.7s-.12-13.44-.12-19.79a2,2,0,1,1,4,0c0,6.33.06,13.16.13,19.76s.13,13.41.13,19.74c0,5.12.23,10.35.45,15.42.33,7.51.66,15.28.28,22.95-.23,4.61-.33,12.79-.39,17.68l0,1.28A2,2,0,0,1,395,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M354.22,67a2,2,0,0,1,0-4c2.48,0,4.91-.19,7.26-.38,2-.16,4-.32,6.06-.37,5-.13,9.83.07,13.53.26,2.42.13,10.07.23,13.41.23a2,2,0,0,1,0,4c-3,0-11-.1-13.62-.24-3.62-.19-8.39-.39-13.22-.26-2,.05-3.85.2-5.84.36C359.37,66.79,356.87,67,354.22,67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M355.5,164.65a2,2,0,0,1-2-2c0-2.37-.2-7.26-.39-12s-.39-9.7-.39-12.15c0-12.37-.19-24.84-.37-36.89S352,77.1,352,64.74a2,2,0,1,1,4,0c0,12.33.19,24.77.37,36.81s.38,24.55.38,37c0,2.37.2,7.26.39,12s.39,9.7.39,12.15A2,2,0,0,1,355.5,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.56,84.32a2,2,0,0,1-.87-.2c-1.92-.93-7-1.28-8.9-.34A2,2,0,1,1,251,80.2c3.07-1.54,9.51-1.1,12.44.32a2,2,0,0,1-.88,3.8Z" transform="translate(-53.25 -44.96)"/></g></g><g id="COLOR-2" data-name="COLOR"><path class="cls-7" d="M348.43,470c-2.63-1-6-1-8.83-1.21-4.22-.38-8.44-.52-12.67-.62-8.68-.21-17.29.23-25.92-.82a58.42,58.42,0,0,0-15.84.35c-4.32.6-8.71,1.09-13,1.84-6.7,1.17-13.45,1.86-20.12,3.25-5.91,1.24-11.79,2.64-17.71,3.83-2.56.52-5.13,1-7.69,1.49-.88.18-3.73.26-4.27,1.08-.74,1.11.42,4.52.63,5.75.67,3.87,1.55,8,3.4,11.51A140.8,140.8,0,0,0,234,508.57c2.85,4.25,4.81,8.24,8.61,11.85a50.38,50.38,0,0,0,12.91,9.06c6.17,2.86,13.11,5.65,19.89,6.31a85.31,85.31,0,0,0,14-.13c2.73-.16,5.46-.65,8.16-1a122,122,0,0,0,14.46-3.5,36.34,36.34,0,0,0,12.24-5.8c7-5.16,12.12-12.82,17.1-19.83a60,60,0,0,0,3.33-5.67,39.58,39.58,0,0,0,2.58-6.66c1.62-4.58,1.84-9.14,2.88-13.77C350.78,476.48,352.27,471.49,348.43,470Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M272.5,468.5c-.55,7,4.53,14,11.81,14,7.66,0,11.95-7.38,12.41-14-3.09-.42-7.19,1.21-10.45,1.23A57.65,57.65,0,0,1,272.5,468.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M290.26,472c-3.34-.13-4.94,3.06-.58,2.67,2.51-.23,5.53-3,1.25-2.83" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M566,470c-2.63-1-6-1-8.83-1.21-4.22-.38-8.44-.52-12.67-.62-8.68-.21-17.29.23-25.92-.82-18.38-2.22-37,.43-55,4.19C455.38,473.24,447,474.6,439,477a22.34,22.34,0,0,0,.84,6.53c.75,3.28,1.14,6.75,2.57,9.82a112.66,112.66,0,0,0,9.11,15.2c2.85,4.25,4.81,8.24,8.61,11.85a50.38,50.38,0,0,0,12.91,9.06c6.17,2.86,13.11,5.65,19.89,6.31a64.13,64.13,0,0,0,22.71-1.38c6.84-1.83,14-4,19.51-8.59,4.69-4,10.07-7.07,14.29-11.55,2.36-2.51,5.09-4.83,7-7.72,2.46-3.72,4-8,5.56-12.17s3.3-8,4.88-12C567.68,480.36,570.64,471.62,566,470Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M492.5,468.5c.12,7,6.16,13.3,13.38,12.25A15.38,15.38,0,0,0,516,474.18a10,10,0,0,0,1.8-4.45c.18-2.63-.45-2.46-2.81-2.49-3.94,0-7.84-.25-11.77-.25C500.19,467,495.9,466.38,492.5,468.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M315,336.21c-3.66-2.95-5.67-7.23-9.3-10.61a61.08,61.08,0,0,0-13.44-9.16c-13.63-7.12-22.83,11.34-15.79,22.31,1.81,2.82,3.9,6.21,5.88,8.72,2.17,2.76,5.2,4.37,6.55,7.9-5.6,3.14-9.54,8.71-14,13.22-4.26,4.27-9.21,8.45-12.54,13.52-6,9.16-8.62,20.26-12.72,30.3-1.67,4.08-3.53,7.71-4.1,11.93.88-.56,2.17-.79,3-1.35-.69,6.27-5.62,4.49-9.37,9.14A81.54,81.54,0,0,0,230,445.5c-2.49,4.82-4,10.2-5.38,15.5a42.67,42.67,0,0,0-1.63,8c-.08,1.43.32,3.13,0,4.52-.24,1.12-2,1.94-2,3,0,5,1.76,2.87,5,2.16,4.82-1.05,9.7-2.48,14.66-3.53,11.74-2.48,23.52-5.57,35.38-7.38,13-2,26.14-1.74,39.38-1.74a121.68,121.68,0,0,1,18.1,1.38c4,.58,8.63-.25,12.5.62,13.48,3.05-4.54,36.54-8,41.74-3.59,5.43-8.81,10.7-13.66,15.14-17.42,16-52.62,19.6-71.13,3.4-3.87-3.39-8.18-6.07-11.48-10-2.56-3.09-4.87-7.49-8.66-8.7-.2,5.41-2.39,12.29-1.1,17.24,1.24,4.78,4.77,10.72,8.52,13.7,10.08,8,23.71,10.68,36.14,12.46,6.95,1,13.36,3.11,19.89,5.3,6.29,2.11,12.84,2.16,19.22,3.75a129.87,129.87,0,0,0,18.63,3.61c19.63,2,38.31,8.92,58.11,10.9,8.06.81,17.29-3,25-5,9.67-2.49,19.64-3.34,29.46-5s19.43-3,29-5c26.08-5.38,52.67-10.58,77.5-20.36,5.66-2.23,6-3,6-9.14,0-4.5.11-9,0-13.5s-.23-9.77-2.39-13.45c-6.66,16.31-24.6,27.61-42.11,29-16.18,1.25-40.74-.14-53-12.53C454.77,514.15,449.39,505,444.5,496c-2.2-4.06-7.86-16-5-20.76,1.8-3,11.67-2,15.14-2.34,7.56-.73,15.16-1.67,22.75-2.42,14.61-1.43,29.36-3.19,44-3.86a166.26,166.26,0,0,1,29.35.78c5.67.76,11.27,2,17,1.57-1.84-6.64-3.32-13.49-5.52-20.14-1.83-5.55-6.93-10.4-10.44-14.94-2.31-3-5.15-5.56-6.5-9.25-1.09-3-.88-6.4-1.87-9.51a106,106,0,0,0-8.23-18.77c-6.24-11.45-12-22.6-21.15-32-2.26-2.33-4.65-4.29-6.76-6.75a20.87,20.87,0,0,0-6.1-5.09c-.54-.29-2.94-1.07-3.1-1.77-.65-3,6.25-6.28,8.11-7.71a21,21,0,0,0,7.09-11.23c1.46-5.57.17-8.86-3.45-13.25s-8.49-6-14.18-6c-6.75,0-10.71,3.57-15.28,8.09a24.4,24.4,0,0,0-5.5,7.9c-1.46,3.52-2.07,7.25-3.21,10.66-1.59-.87-2.6-2.55-4.12-3.59a27,27,0,0,0-8.5-3.24c-4.63-1.12-9.44-1.34-14.09-2.34-4.33-.94-8.63-2.49-12.93-3.73-5.4-1.57-10.35-1.59-16-1.59-12.77,0-25.3.87-38,2-12.39,1.1-25.51,1.3-37.58,4.33a122.83,122.83,0,0,0-13.36,3.92c-2.8,1.05-7.43,1.34-9.43,3A14.6,14.6,0,0,1,315,336.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M229.13,623.25c.89,1.17,1.92,3.92,2.74,4.87,1.3,1.5,2.83,2.79,4.21,4.21a82.17,82.17,0,0,1,6.68,7.93c3.71,4.95,4.32,10.93-.5,15.32-5.63,5.12-13.27,6-20.58,4.77-5.58-.92-8.09-4.39-12-8-2.89-2.68-6.07-4.7-8.76-7.58-3.41-3.66-6.39-7.37-2.9-11.67,3.77-4.65,10.31-6.32,15.92-7.45,3.29-.66,11.72-4.79,14.75-2.82A1.88,1.88,0,0,1,229.13,623.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M566,624.33c-4.5,5.82-7.4,11.21-12.83,16.15s-4.81,10.93-.67,16.68c4.66,6.47,17.4,5.51,23.58,2.74,9-4,18.16-10.94,22.66-20,1.53-3.07,1.13-2.81-1.62-4.79a69.33,69.33,0,0,0-9.77-5.8C581.45,626.37,576.32,625,566,624.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M383.12,470.36c-4.4,2-11.06,9.12-12.45,14-2.15,7.44,4.66,10.07,10.72,8.56,4.63-1.15,8.94-3.74,13.79-4,2.3-.1,4.26.7,6.41,1.39,2.45.79,4.77,1.95,7.27,2.57,6.06,1.51,12.87-1.12,10.72-8.56-1.39-4.83-8.05-12-12.45-14" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M393.83,462.79a18.23,18.23,0,0,0-7.35,2.06c-2.93,1.7-5.13,5.48-1.36,7.86,4.51,2.85,16.6,2.72,20.71-.84,2.88-2.49,2.1-6.25-1.3-7.7A23.59,23.59,0,0,0,393.83,462.79Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M401,490.33c-2.85-1.27-7.34-1.63-10.46-1.34-3.28.31-3.21,2.87-3.58,5.87-.26,2.07-.66,8.48,1.53,9.5,1.47.69,4.55-.06,6.26.11a15.56,15.56,0,0,0,4.83,0C405,503.31,401.23,493.16,401,490.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M510.83,472c-3.34-.13-4.94,3.06-.58,2.67,2.51-.23,5.53-3,1.25-2.83" transform="translate(-53.25 -44.96)"/><path class="cls-33" d="M560.91,668.12c0-1.84.56-4.94-.4-6.62-.74-1.31-2.44-1.5-3.69-2.11a11.57,11.57,0,0,1-5.08-4.89c-3.75-7-.4-12.58,4.49-17.77,2.1-2.22,3.94-4.35,4.32-7.5s-.31-6-.36-9.07c0-1.58.14-3.18.11-4.74,0-.78.26-3.69,0-4.24,1.45,2.88,3.64,5.18,4.62,8.42,1.32,4.38,4,4.19,8,4.76a92.15,92.15,0,0,1,10.5,2c6.07,1.61,14.06,4.53,15.75,11.39.41,1.66,3.47-2.07,3.74-2.9.66-2,.46-4.22.45-6.28,1.23-.16,2.15-1.09,3.38-1.17-.9-1-1.73-2.52-2.91-3.44,1.84-2.05,1.58-3.31-.38-4.65-2.17-1.48-1.34-2.76-1.65-5.3a39.1,39.1,0,0,0-1.89-7.92,58.56,58.56,0,0,0-7.94-14.85c-3.7-5.19-8.79-9.52-13.92-13.24a68.21,68.21,0,0,0-8.86-5.52c-2.45-1.26-6.23-2-8-4.15,1.08-2.54,1.48-5.31,2.46-7.89a13,13,0,0,0,.91-6.71,37.36,37.36,0,0,0-2.8-9c-.76-1.89-1.17-4.3-3.42-4.9-3.36-.9-7.19,2.16-10.17,3.27q-6.93,2.58-14,4.84c-9.38,3-18.89,5.63-28.46,8-25,6.06-50.38,10.09-75.76,14q-11,1.71-22,3.82a57.18,57.18,0,0,0-8.85,2.39c-2.64,1-5.4-.68-8-1.22q-4.67-1-9.35-1.84-9.24-1.73-18.54-3.16c-24.86-3.85-49.68-8.14-74.12-14.14-10.36-2.54-20.65-5.39-30.81-8.66q-7.54-2.43-15-5.18c-2.45-.91-4.91-1.84-7.33-2.83-1.74-.7-3.09-2.28-4.29-.4s-1.61,5.42-2.17,7.66c-1.09,4.37-2.51,9.25-1.29,13.74.72,2.67,3.45,6.2,2.49,9.08-.55,1.66-2.06,1.46-3.53,2.05a37.62,37.62,0,0,0-5.61,2.95,64.39,64.39,0,0,0-18.26,17,58.28,58.28,0,0,0-8,15.09,43.9,43.9,0,0,0-1.84,7.89c-.32,2.28-.07,3.79-1.86,5.29-.72.61-1.35.41-1.48,1.66a4.11,4.11,0,0,0,1.34,2.8c-1.18.92-2,2.49-2.91,3.44,1.24.08,2.16,1,3.38,1.17,0,2.42-.47,5.93,1.21,7.94,1,1.19,2.81,2.33,4,.82s.55-3.19,1.91-4.66c2.44-2.64,6.15-4.18,9.48-5.31a79.51,79.51,0,0,1,14.05-3c3.79-.56,6.63-.61,8.16-4.4.54-1.34,1.66-4.24,2.9-5,1.16,2.17,1.1,4.83,1.3,7.21.32,3.8-.19,8.6,1.75,12,1.64,2.89,4.65,4.7,6.43,7.48a12,12,0,0,1,.35,12.77,10,10,0,0,1-4.13,4.33c-1.71.78-3.68,1.13-3.61,3.32,0,.91.52,1.9.56,2.88.07,1.64,0,3.29.05,4.93.1,8.11.25,15.62-1,23.45-1.39,8.62,2.78,7.83,9.13,11.09,7.41,3.81,14.76,8.81,22.48,11.89,9.71,3.87,21.29,5.47,31.42,8,7.78,1.95,15.39,4.44,23.07,6.74,20.13,6,39.23,12.91,60.46,9.87,29.79-4.26,60-3.23,89.34-10.76,19.65-5,39.24-8.93,58.6-15.13A117.05,117.05,0,0,0,546.43,708c4-2,12.41-4,14.5-8.19,1.47-2.92.11-8.2.07-11.39C560.92,681.63,561,674.88,560.91,668.12Z" transform="translate(-53.25 -44.96)"/><path class="cls-34" d="M399.75,580.86a69.12,69.12,0,0,1,4.48,10.28c.68,1.78,2.41,4.44,2.53,6.3s.46.9-.88,2c-1.09.92-2.07.55-2.95,2a9.39,9.39,0,0,0-.79,3.94,31.94,31.94,0,0,0,.66,8.16c2.37,12.11,1.73,25.25,2.94,37.65.76,7.85,2.22,15,2.26,23.06,0,5.48,3.54,12.13,1.26,17.11-3.09,6.74-8.66,12-13.07,17.81-2.64-1.83-4-6.26-6.06-8.84-2.42-3-5.46-10.59-9.34-11.43-.36-3.59.56-7.58.71-11.2.51-12.06,2.79-23.94,4.6-35.84,1.73-11.41,2.17-22.8,3.15-34.23.11-1.34.63-3.71.2-4.94-1.13-3.26-3.19-4.05-2.63-7.94.47-3.31,2.83-6.07,4.74-8.68C393.71,583.2,396.57,575.41,399.75,580.86Z" transform="translate(-53.25 -44.96)"/></g><g id="LIGHTS"><g class="cls-35"><path class="cls-7" d="M552.25,251c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C552.94,253.89,553,252.63,552.25,251Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M543.3,134.37c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C544,137.27,544,136,543.3,134.37Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M467.29,196.29c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C468,199.18,468,197.91,467.29,196.29Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M664,239.37c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C664.73,242.26,664.78,241,664,239.37Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M395.2,206.7c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C395.9,209.6,396,208.33,395.2,206.7Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M490.21,264.49c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C490.91,267.38,491,266.11,490.21,264.49Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M503.78,95.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C504.48,98.75,504.53,97.48,503.78,95.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M681.87,531.06c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C682.56,534,682.62,532.68,681.87,531.06Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M149,482.09c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C149.72,485,149.78,483.72,149,482.09Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M633.27,482.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C634,485.75,634,484.48,633.27,482.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M179.43,517.52c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C180.13,520.42,180.18,519.15,179.43,517.52Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M165.19,633c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C165.88,635.94,165.93,634.67,165.19,633Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M187.74,639.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C188.44,642.75,188.49,641.48,187.74,639.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M145.49,539.88c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C146.19,542.78,146.24,541.51,145.49,539.88Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M657.92,563.36c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C658.61,566.25,658.67,565,657.92,563.36Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M587.59,553c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36A5.15,5.15,0,0,1,589.4,557C588.28,555.89,588.34,554.63,587.59,553Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M335.84,215.69c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C336.53,218.59,336.58,217.32,335.84,215.69Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M427.19,90.19c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36A5.15,5.15,0,0,1,429,94.19C427.89,93.09,427.94,91.82,427.19,90.19Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M225.82,231.69c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C226.52,234.59,226.57,233.32,225.82,231.69Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M359.42,266.65c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C359.65,267.64,359.67,267.21,359.42,266.65Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M339.39,141c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C339.63,142,339.65,141.57,339.39,141Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M363.07,260.66c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C363.48,262.38,363.51,261.62,363.07,260.66Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M345.15,131.25c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C345.56,133,345.59,132.21,345.15,131.25Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M662.2,258.7c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C662.61,260.41,662.64,259.66,662.2,258.7Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M182.29,542.66c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C182.71,544.37,182.74,543.62,182.29,542.66Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M220.61,677.2c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C221,678.91,221.05,678.16,220.61,677.2Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M116.86,539.75c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C117.27,541.47,117.3,540.71,116.86,539.75Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M669.88,245.85c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C670.29,247.56,670.32,246.81,669.88,245.85Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M592.3,133.64c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C592.71,135.35,592.74,134.6,592.3,133.64Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M99.4,519.52c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C99.81,521.23,99.85,520.48,99.4,519.52Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M629.94,495.14c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C630.35,496.85,630.38,496.1,629.94,495.14Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M578.78,209.48c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C579.19,211.2,579.22,210.45,578.78,209.48Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M498.53,87.64c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95A3,3,0,0,1,499.6,90C498.94,89.35,499,88.6,498.53,87.64Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M621.17,210.72c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C621.58,212.43,621.61,211.68,621.17,210.72Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M129.34,220.08c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C129.57,221.07,129.59,220.63,129.34,220.08Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M133,214.09c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C133.4,215.8,133.43,215.05,133,214.09Z" transform="translate(-53.25 -44.96)"/></g></g><g id="DETAILS-2" data-name="DETAILS"><path class="cls-24" d="M479.33,333.67a1,1,0,0,1-.92-1.38c.22-.54.45-1.1.66-1.64a1,1,0,1,1,1.87.72c-.22.56-.45,1.13-.68,1.69A1,1,0,0,1,479.33,333.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M480.33,337a1,1,0,0,1-.38-1.93.65.65,0,0,0,.39-.55,1,1,0,1,1,2,.29,2.62,2.62,0,0,1-1.61,2.11A1,1,0,0,1,480.33,337Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M483.67,332l-.2,0a1,1,0,0,1-.79-1.18,5.48,5.48,0,0,1,1.22-2.46,1,1,0,0,1,1.52,1.31,3.46,3.46,0,0,0-.78,1.54A1,1,0,0,1,483.67,332Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M483,327.67h-.08a1,1,0,0,1-.91-1.08,2.65,2.65,0,0,1,1.54-2.14,1,1,0,1,1,.92,1.78c-.44.23-.46.45-.46.53A1,1,0,0,1,483,327.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M307,335a1,1,0,0,1-.48-.12,4.52,4.52,0,0,1-1.72-1.72,1,1,0,0,1,1.74-1,2.54,2.54,0,0,0,.94,1A1,1,0,0,1,307,335Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M308.67,340.67a1,1,0,0,1-.7-.29,4.44,4.44,0,0,1-1.27-2.15,1,1,0,0,1,1.95-.46,2.52,2.52,0,0,0,.73,1.18,1,1,0,0,1-.7,1.71Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M304,338.67a1,1,0,0,1-.72-.31,5.2,5.2,0,0,1-1.23-2.05,1,1,0,1,1,1.9-.62,3.2,3.2,0,0,0,.77,1.28,1,1,0,0,1-.72,1.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M302,330.33a1,1,0,0,1-.69-.28,17,17,0,0,1-2.12-2.48,1,1,0,1,1,1.64-1.15,15,15,0,0,0,1.88,2.19,1,1,0,0,1-.69,1.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M261.67,463.67a1,1,0,0,1-.19-2,210.85,210.85,0,0,1,41.19-4,1,1,0,1,1,0,2,208.87,208.87,0,0,0-40.81,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M491.33,461.33a1,1,0,0,1-.46-1.89c3.49-1.78,8.65-1.75,13.18-1.72,1.59,0,3.08,0,4.39-.05l.44,0c4.21-.22,9-.48,13,.38a1,1,0,0,1-.42,2c-3.75-.8-8.37-.55-12.46-.34l-.45,0c-1.36.07-2.89.06-4.5.05-4.32,0-9.21-.05-12.27,1.5A1,1,0,0,1,491.33,461.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M394,506.5a1.5,1.5,0,0,1-1.5-1.5V489.67a1.5,1.5,0,0,1,3,0V505A1.5,1.5,0,0,1,394,506.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M397,686.67h-.14a1,1,0,0,1-.85-1.13,6,6,0,0,1,1.2-2.81,1,1,0,1,1,1.58,1.23,4.05,4.05,0,0,0-.8,1.86A1,1,0,0,1,397,686.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M398.67,689a1,1,0,0,1-1-.89,1.25,1.25,0,0,1,1.43-1.43,1.25,1.25,0,0,1-.33,2.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M372,601a1,1,0,0,1-.35-.06,1.67,1.67,0,0,1-.94-2.23A1.39,1.39,0,1,1,372,601Zm.6-1.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M374.67,599.33a1,1,0,0,1-.65-.24,4,4,0,0,1-1.33-2.22,1,1,0,0,1,2-.42,2,2,0,0,0,.67,1.11,1,1,0,0,1-.65,1.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M420.67,598a1,1,0,0,1-1-1v-3a1,1,0,0,1,2,0v3A1,1,0,0,1,420.67,598Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M192,626.33a1,1,0,0,1-.71-1.7c3.28-3.33,12-4.81,15.58-5.29a1,1,0,0,1,.27,2c-5.45.73-12.1,2.35-14.42,4.71A1,1,0,0,1,192,626.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193,630a1,1,0,0,1-.43-1.9,27.69,27.69,0,0,1,3.3-.75,1,1,0,1,1,.24,2c-.68.08-2.55.55-2.81.63A1,1,0,0,1,193,630Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.33,629.33l-.21,0a21,21,0,0,1-5-2,21.42,21.42,0,0,0-4.71-2,47.68,47.68,0,0,0-12-1.64h0a1,1,0,0,1,0-2,49.77,49.77,0,0,1,12.52,1.69,22.92,22.92,0,0,1,5.16,2.12,19.2,19.2,0,0,0,4.55,1.87,1,1,0,0,1-.21,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M605.67,625.67h0a18.9,18.9,0,0,1-5-1.06,14,14,0,0,0-5.2-.94,1,1,0,0,1-1.08-.91,1,1,0,0,1,.91-1.08,15.42,15.42,0,0,1,6,1,17.07,17.07,0,0,0,4.49,1,1,1,0,0,1,0,2Z" transform="translate(-53.25 -44.96)"/></g><g id="LINEART"><path class="cls-24" d="M561,701a2.5,2.5,0,0,1-2.5-2.5V684.63c0-7-.05-14.7-.17-23.48a2.5,2.5,0,1,1,5-.06c.11,8.8.17,16.5.17,23.54V698.5A2.5,2.5,0,0,1,561,701Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M560.38,634.64a2.5,2.5,0,0,1-2.5-2.46c-.25-14.88-.48-30.71-.42-46.42,0-7.15,0-13.43,0-19.2a2.5,2.5,0,0,1,2.49-2.51h0a2.5,2.5,0,0,1,2.5,2.49c0,5.78,0,12.08,0,19.24-.07,15.65.17,31.46.42,46.31a2.5,2.5,0,0,1-2.46,2.54Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M559.63,541.5a2.5,2.5,0,0,1-2.5-2.44c-.29-12.49-.76-23.82-1.45-34.65a2.5,2.5,0,0,1,5-.31c.68,10.89,1.16,22.29,1.45,34.84a2.5,2.5,0,0,1-2.44,2.56Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M547.24,430.29a2.5,2.5,0,0,1-2.4-1.8q-.26-.9-.53-1.8c-5.82-19.3-15-43.91-34.51-63.11-13.58-13.36-32.91-23.48-57.45-30.09-6.15-1.65-11.36-2.85-16-3.66-17.78-3.15-36.76-2.18-55.12-1.24-4,.21-8.05.41-12,.57-35.32,1.43-66.4,13.65-87.49,34.41-19.51,19.2-28.69,43.81-34.51,63.11a2.5,2.5,0,1,1-4.79-1.44c6-19.87,15.47-45.24,35.79-65.23,22-21.63,54.23-34.36,90.8-35.84,4-.16,8-.37,12-.57,18.64-1,37.91-1.94,56.25,1.31,4.74.84,10.1,2.07,16.38,3.76C479,335.49,499.11,346,513.31,360c20.32,20,29.8,45.36,35.79,65.23q.28.92.55,1.85a2.5,2.5,0,0,1-2.4,3.2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M232,540h0a2.5,2.5,0,0,1-2.46-2.54c.17-9.84.55-19.7,1.1-29.31a2.5,2.5,0,1,1,5,.29c-.55,9.54-.92,19.33-1.1,29.11A2.5,2.5,0,0,1,232,540Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M235.67,635.7a2.5,2.5,0,0,1-2.5-2.38c-.18-3.87-.41-7.43-.7-10.88-1.6-19.07-2.59-38-2.94-56.19a2.5,2.5,0,1,1,5-.1c.35,18.11,1.33,36.91,2.92,55.87.3,3.51.53,7.13.72,11.06a2.5,2.5,0,0,1-2.38,2.62Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M236.44,704.72a2.5,2.5,0,0,1-2.47-2.16c-.71-5.17-.46-6.39,0-7.95.24-.79.55-1.77.36-5.79-.41-9-.49-18.31-.57-27.28v-1.29a2.5,2.5,0,0,1,5,0v1.29c.08,8.93.16,18.16.56,27.1.2,4.52-.14,6.06-.58,7.49-.24.78-.45,1.45.15,5.79a2.5,2.5,0,0,1-2.13,2.82Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M291,354.83a2.49,2.49,0,0,1-1-.23c-7-3.19-17.19-13.06-18.28-23.27-.61-5.75,1.75-10.8,6.83-14.6a16.09,16.09,0,0,1,13.71-3.12c13.11,3,23,20.91,24.85,24.47a2.5,2.5,0,1,1-4.44,2.31c-4.62-8.89-13-20-21.53-21.9a11.15,11.15,0,0,0-9.6,2.25c-3.69,2.76-5.28,6.05-4.85,10.07.85,7.94,9.54,16.56,15.39,19.25a2.5,2.5,0,0,1-1,4.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M497.67,352.83a2.5,2.5,0,0,1-1.55-4.46l1.68-1.32c3.62-2.82,7.72-6,10.47-9.17a14.43,14.43,0,0,0,2.58-15.12c-2-4.73-6.39-7.56-11.94-7.77-11-.44-21.13,11.1-24.17,22a2.5,2.5,0,1,1-4.82-1.34c3.63-13,15.5-26.18,29.17-25.66,7.45.28,13.56,4.31,16.34,10.79A19.45,19.45,0,0,1,512,341.18c-3.06,3.5-7.36,6.85-11.15,9.81l-1.66,1.3A2.49,2.49,0,0,1,497.67,352.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.17,481.17a2.49,2.49,0,0,1-1.79-.76c-2.65-2.72-3.46-6.28-2-9.07a13.19,13.19,0,0,0,.68-3.53c.08-.73.16-1.42.28-2.06a67.86,67.86,0,0,1,7-20.67A68.93,68.93,0,0,1,247.25,421a66,66,0,0,1,97.16,20.76c3,5.36,4.85,11.47,6.64,17.78a3.24,3.24,0,0,0,1.57,2.36c2.67,2.24,3,4.42,2.81,5.86s-1.12,3.55-4.45,5.1a2.5,2.5,0,0,1-2.12-4.53c1.26-.59,1.59-1.12,1.6-1.22s-.14-.6-1.07-1.37a7.5,7.5,0,0,1-3.16-4.82c-1.71-6-3.47-11.82-6.2-16.71A60.88,60.88,0,0,0,250.23,425a64,64,0,0,0-18.46,22.4,63.26,63.26,0,0,0-6.56,19.27c-.09.51-.16,1.11-.23,1.73a15.77,15.77,0,0,1-1.19,5.22c-.34.67-.12,2,1.17,3.33a2.5,2.5,0,0,1-1.79,4.24Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.66,540c-.89,0-1.78,0-2.68-.05a66.06,66.06,0,0,1-63.3-61.13,2.5,2.5,0,0,1,5-.37,61.13,61.13,0,0,0,122-2.13c.08-2,.06-3.93,0-5.88a2.5,2.5,0,1,1,5-.27c.12,2.1.13,4.24,0,6.35A66.22,66.22,0,0,1,286.66,540Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M284.37,485.33a15.13,15.13,0,0,1-15-13.82,2.5,2.5,0,0,1,5-.43,10.13,10.13,0,1,0,20.19-1.76,2.5,2.5,0,0,1,5-.43,15.15,15.15,0,0,1-13.76,16.39C285.26,485.31,284.81,485.33,284.37,485.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.17,481.17a2.5,2.5,0,0,1-.53-4.94l2.9-.63c7.58-1.64,14.74-3.2,22.69-4.56,3.42-.59,6.9-1.29,10.26-2a171.15,171.15,0,0,1,22-3.46c17.18-1.17,34.56-.63,49.51,0,1.58.06,3.28.05,5.09,0,5.17,0,10.51-.05,14.94,1.54a2.5,2.5,0,0,1-1.69,4.71c-3.6-1.29-8.49-1.27-13.22-1.25-1.86,0-3.62,0-5.31,0-14.82-.59-32-1.13-49,0a167.45,167.45,0,0,0-21.4,3.37c-3.4.69-6.92,1.4-10.41,2-7.85,1.35-15,2.89-22.48,4.52l-2.9.63A2.47,2.47,0,0,1,223.17,481.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M439.67,478.95a2.49,2.49,0,0,1-.8-.13c-3.48-1.17-4.63-3.13-5-4.57s-.26-3.61,2.14-6.14a3.25,3.25,0,0,0,1.29-2.52c1.07-6.47,2.23-12.75,4.6-18.41a65.89,65.89,0,0,1,94.21-31.56,68.94,68.94,0,0,1,22.51,21.73,67.86,67.86,0,0,1,9.31,19.75c.19.63.34,1.3.51,2a13.18,13.18,0,0,0,1.08,3.42c1.71,2.61,1.32,6.24-1,9.24a2.5,2.5,0,0,1-4-3.06c1.13-1.46,1.2-2.8.79-3.43a15.75,15.75,0,0,1-1.77-5.05c-.14-.61-.27-1.2-.42-1.7a63.24,63.24,0,0,0-8.68-18.41,64,64,0,0,0-20.86-20.18,61,61,0,0,0-87.09,29.16c-2.16,5.17-3.26,11.13-4.28,17.3a7.5,7.5,0,0,1-2.6,5.15c-.83.88-.93,1.4-.91,1.49s.41.59,1.73,1a2.5,2.5,0,0,1-.8,4.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M502.91,538.8a66.23,66.23,0,0,1-65.32-56.08c-.32-2.1-.55-4.22-.67-6.32a2.5,2.5,0,1,1,5-.29c.11,1.94.32,3.91.62,5.85A61.13,61.13,0,0,0,564,470.36a2.5,2.5,0,0,1,5-.2,66.18,66.18,0,0,1-66.13,68.64Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M504.75,483.85a15.13,15.13,0,0,1-15.12-14.74,2.5,2.5,0,0,1,2.43-2.56h.07a2.5,2.5,0,0,1,2.5,2.44,10.13,10.13,0,1,0,20.26-.52,2.5,2.5,0,0,1,2.43-2.56,2.46,2.46,0,0,1,2.56,2.43,15.15,15.15,0,0,1-14.74,15.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M440.26,477.84a2.5,2.5,0,0,1-1.11-4.74c4.22-2.08,9.53-2.66,14.67-3.21,1.79-.19,3.48-.38,5-.62,14.79-2.28,32-4.77,49.2-5.53a170.23,170.23,0,0,1,22.29,1c3.42.3,7,.6,10.42.8,8.08.46,15.38,1.2,23.12,2l2.89.29a2.5,2.5,0,0,1-.5,5l-2.89-.29c-7.68-.78-14.93-1.51-22.9-2-3.54-.2-7.11-.51-10.57-.81a168.33,168.33,0,0,0-21.64-.94c-16.95.75-34,3.23-48.66,5.48-1.67.26-3.42.45-5.27.65-4.71.51-9.57,1-13,2.72A2.48,2.48,0,0,1,440.26,477.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M393.72,477.54c-4.22,0-8.34-.81-10.74-2.32a6,6,0,0,1-3.13-5.28c0-2.5,1.83-5.12,4.53-6.69a20.53,20.53,0,0,1,8.22-2.34h0a25.62,25.62,0,0,1,11.67,1.54,7.17,7.17,0,0,1,4.44,5.39,6.91,6.91,0,0,1-2.52,6.33C403.56,476.47,398.57,477.54,393.72,477.54Zm-.67-11.65a15.45,15.45,0,0,0-6.16,1.69,3.86,3.86,0,0,0-2,2.46c0,.3.26.62.79,1,3.77,2.38,14.27,2,17.29-.6a2,2,0,0,0,.85-1.78,2.22,2.22,0,0,0-1.46-1.56,20.71,20.71,0,0,0-9.27-1.16Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M377.41,495.74a10.85,10.85,0,0,1-7.91-3c-2.15-2.23-2.76-5.43-1.73-9,1.63-5.66,8.82-13.11,13.56-15.24a2.5,2.5,0,0,1,2,4.56c-3.85,1.73-9.71,8.27-10.8,12.06-.53,1.84-.35,3.23.53,4.15,1.3,1.35,4.16,1.8,7,1.11a43.8,43.8,0,0,0,4.76-1.59,29.73,29.73,0,0,1,9.23-2.35,16.92,16.92,0,0,1,6.25,1.18l.88.29c1.06.34,2.08.74,3.07,1.13a31.94,31.94,0,0,0,3.89,1.34c2.8.69,5.66.24,7-1.11.88-.92,1.06-2.31.53-4.15-1.09-3.79-7-10.33-10.8-12.06a2.5,2.5,0,1,1,2-4.56c4.74,2.13,11.93,9.58,13.56,15.24,1,3.57.42,6.77-1.73,9-2.6,2.69-7.1,3.65-11.76,2.49a36.21,36.21,0,0,1-4.51-1.54c-1-.37-1.85-.73-2.76-1l-.94-.31a12.24,12.24,0,0,0-4.46-.93,25.55,25.55,0,0,0-7.69,2,48.2,48.2,0,0,1-5.31,1.76A16,16,0,0,1,377.41,495.74Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M394.25,507.75a17.94,17.94,0,0,1-5.4-.66c-3.8-1.3-3.85-4.93-3.88-7.34,0-.32,0-.65,0-1-.08-2.48-.06-5.07,0-7.36v-.91a2.5,2.5,0,0,1,2.5-2.48h0a2.5,2.5,0,0,1,2.48,2.52v.91c0,2.24,0,4.78,0,7.16,0,.36,0,.72,0,1.08,0,2.28.17,2.56.5,2.67,1.55.53,5.59.49,7.9.11a6.24,6.24,0,0,0,.89-.2c0-.3,0-.75,0-1.13,0-.63-.09-1.42-.08-2.32,0-1.83,0-3-.08-4.32,0-1.11-.09-2.26-.09-3.82a2.5,2.5,0,0,1,5,0c0,1.47,0,2.57.08,3.63.05,1.29.1,2.63.08,4.58,0,.71,0,1.34.07,1.94.14,2.26.36,5.69-5,6.58A33.27,33.27,0,0,1,394.25,507.75Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.42,555.33A80.37,80.37,0,1,1,366.79,475,80.46,80.46,0,0,1,286.42,555.33Zm0-150.74A70.37,70.37,0,1,0,356.79,475,70.45,70.45,0,0,0,286.42,404.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M503,554.33A80.37,80.37,0,1,1,583.34,474,80.46,80.46,0,0,1,503,554.33Zm0-150.74A70.37,70.37,0,1,0,573.34,474,70.45,70.45,0,0,0,503,403.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M426,465a5,5,0,0,1-4.26-2.37c-1.47-2.38-11.35-7.06-25.79-7.89-13.45-.77-24.29,2.35-29,8.36a5,5,0,0,1-7.85-6.19c6.85-8.69,20.51-13.12,37.45-12.15,12.95.74,29,5,33.73,12.62A5,5,0,0,1,426,465Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210,462h-.27c-5.85-.31-10.27-2.79-12.11-6.8a8.69,8.69,0,0,1,1-9.07c2.79-3.64,8-5.12,14.2-4.06a5,5,0,0,1-1.68,9.86,11.76,11.76,0,0,0-2.75-.18,10.12,10.12,0,0,0,1.86.26,5,5,0,0,1-.26,10Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M579,462a5,5,0,0,1-.26-10,10.1,10.1,0,0,0,1.86-.26,11.7,11.7,0,0,0-2.75.18,5,5,0,0,1-1.68-9.86c6.23-1.07,11.41.42,14.2,4.06a8.69,8.69,0,0,1,1,9.07c-1.85,4-6.26,6.49-12.11,6.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M382.36,612.58a2.56,2.56,0,0,1-.46,0c-10.2-1.9-18.76-4.71-27.82-7.67-3.3-1.08-6.7-2.2-10.31-3.31-21.85-6.75-44.73-12.41-66.85-17.89-8.13-2-16.54-4.1-24.7-6.19l-1.4-.36c-8.17-2.07-19.37-4.9-24-13.77-3.18-6.08,0-16.94,2.14-24.13.25-.86.49-1.65.68-2.35a2.5,2.5,0,0,1,4.82,1.35c-.2.71-.44,1.53-.7,2.41-1.66,5.63-4.74,16.12-2.5,20.4,3.62,6.9,13.15,9.31,20.82,11.25l1.41.36c8.14,2.08,16.54,4.16,24.66,6.18,22.19,5.5,45.14,11.18,67.13,18,3.65,1.13,7.08,2.25,10.39,3.33,8.9,2.92,17.31,5.67,27.18,7.51a2.5,2.5,0,0,1-.46,5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M396.13,578.5a2.54,2.54,0,0,1-.52-.06c-11.08-2.36-21.5-4.28-32.79-6-44.24-6.84-90.83-15.53-131.76-32.57a2.5,2.5,0,1,1,1.92-4.62c40.44,16.84,86.67,25.45,130.6,32.25,11.39,1.76,21.9,3.69,33.07,6.08a2.5,2.5,0,0,1-.52,4.95Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M382.36,612.58h-.18a2.5,2.5,0,0,1-2.32-2.67c.53-7.58,4.21-14.32,7.78-20.84,2.44-4.47,4.75-8.69,6.09-13.12a2.5,2.5,0,1,1,4.79,1.45c-1.49,4.92-4,9.58-6.49,14.07-3.46,6.33-6.73,12.3-7.18,18.79A2.5,2.5,0,0,1,382.36,612.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M411,612.58a2.5,2.5,0,0,1-.46-5c9.73-1.82,17.93-4.52,26.61-7.38,3.41-1.13,6.94-2.29,10.73-3.46,22-6.79,44.92-12.47,67.11-18,8.13-2,16.53-4.1,24.68-6.18l.33-.08c7.38-1.89,15.74-4,19.9-10.15,3.84-5.67,2.12-10-.26-15.95a65.76,65.76,0,0,1-2.41-6.77,2.5,2.5,0,1,1,4.81-1.35,61.79,61.79,0,0,0,2.24,6.27c2.5,6.27,5.09,12.75-.25,20.61-5.22,7.69-15,10.18-22.79,12.19l-.33.08c-8.16,2.09-16.58,4.17-24.71,6.19-22.12,5.48-45,11.14-66.83,17.89-3.74,1.16-7.25,2.31-10.64,3.43-8.85,2.92-17.2,5.67-27.26,7.55A2.57,2.57,0,0,1,411,612.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M397,578.5a2.5,2.5,0,0,1-.52-4.95c11.18-2.38,21.68-4.32,33.07-6.08,40.41-6.25,86.22-13.34,128.13-30.79a2.5,2.5,0,1,1,1.92,4.62C517.14,559,471,566.12,430.32,572.42c-11.29,1.75-21.71,3.66-32.79,6A2.54,2.54,0,0,1,397,578.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M411,612.58a2.5,2.5,0,0,1-2.49-2.33c-.45-6.45-3.76-12.4-7.27-18.7-2.52-4.53-5.13-9.21-6.63-14.17a2.5,2.5,0,1,1,4.79-1.45c1.34,4.44,3.71,8.69,6.21,13.18,3.62,6.5,7.36,13.22,7.89,20.78a2.5,2.5,0,0,1-2.32,2.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M229.87,663.57a41.28,41.28,0,0,1-16.34-3.66,39.84,39.84,0,0,1-19.73-21.19,2.5,2.5,0,0,1,4.63-1.89,34.79,34.79,0,0,0,17.19,18.54c6.44,3,21.18,6.34,25.68-2,3.47-6.46.36-10.22-5-15.81a36.79,36.79,0,0,1-6.18-7.72,6.23,6.23,0,0,1-2.7-3.22,5.9,5.9,0,0,0-.87-1.53,2.5,2.5,0,0,1,3.93-3.09A10.75,10.75,0,0,1,232,624.6c.29.67.32.74,1.16,1.19a2.5,2.5,0,0,1,1.09,1.14c1.18,2.47,3.34,4.73,5.64,7.13,5,5.18,11.16,11.64,5.8,21.63C242.57,661.53,236.38,663.57,229.87,663.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193.09,620.7H193a2.5,2.5,0,0,1-2.38-2.61c.45-9.82,3.75-18.54,10.68-28.29,5.72-8,18.92-20.32,30.37-22.5a2.5,2.5,0,1,1,.93,4.91c-9,1.72-21.17,12-27.23,20.49-6.34,8.92-9.36,16.82-9.76,25.62A2.5,2.5,0,0,1,193.09,620.7Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M228.33,626.08a2.5,2.5,0,0,1-2-4.06l0,0a2.5,2.5,0,0,1,.44-2,3.43,3.43,0,0,1,.48-1.3,2.52,2.52,0,0,1,.31-.85,71,71,0,0,0,4.08-8.66,2.5,2.5,0,0,1,4.63,1.89,84,84,0,0,1-3.7,8,2.5,2.5,0,0,1-.55,1.84l-.24.27a2.83,2.83,0,0,1-.18.82,4.76,4.76,0,0,1-1.27,3l-.11.13A2.5,2.5,0,0,1,228.33,626.08Zm-1.22-2.85h0Zm4.08-6.18h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M196.12,640.27a2.51,2.51,0,0,1-2.43-3.1c2.94-11.89,21.33-14.36,31.21-15.68,1.25-.17,2.34-.31,3.19-.45a2.5,2.5,0,1,1,.82,4.93c-.89.15-2,.3-3.34.48-8.08,1.08-24.9,3.34-27,11.93A2.5,2.5,0,0,1,196.12,640.27Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M195.84,640.28a5.69,5.69,0,0,1-4.05-1.56c-2.2-2.12-2.4-5.65-2.39-8.37l-.2-.1a3.72,3.72,0,0,0-.83-.34,2.5,2.5,0,0,1-1.65-4.21,12.38,12.38,0,0,0,.84-1.07c.21-.29.44-.6.68-.9a4.87,4.87,0,0,1-.28-4.23c1.74-4.17,9.13-5.1,16.86-5.49,10.49-.53,22.23,1.82,25.58,2.55a2.5,2.5,0,1,1-1.07,4.88c-6.58-1.44-16.4-2.83-24.2-2.44-9.92.5-12,1.88-12.48,2.35a3.58,3.58,0,0,0,.67,1,2.5,2.5,0,0,1-.33,3.64,3.19,3.19,0,0,0-.29.26,2.5,2.5,0,0,1,1.73,2.39v.79c0,1.45-.09,4.83.84,5.72.06.06.2.2.72.16a2.5,2.5,0,0,1,.29,5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M565.37,663.57c-6.51,0-12.69-2-15.83-7.89-5.36-10,.83-16.45,5.8-21.63,2.3-2.39,4.47-4.66,5.64-7.12a2.49,2.49,0,0,1,1.09-1.14c.85-.45.88-.52,1.16-1.19a10.73,10.73,0,0,1,1.54-2.65,2.5,2.5,0,0,1,3.93,3.09,5.91,5.91,0,0,0-.87,1.53,6.23,6.23,0,0,1-2.7,3.22,36.77,36.77,0,0,1-6.18,7.72c-5.36,5.59-8.47,9.34-5,15.81,4.5,8.39,19.24,5,25.68,2a34.79,34.79,0,0,0,17.19-18.54,2.5,2.5,0,1,1,4.63,1.89,39.84,39.84,0,0,1-19.73,21.19A41.28,41.28,0,0,1,565.37,663.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M602.15,620.7a2.5,2.5,0,0,1-2.5-2.38c-.41-8.8-3.42-16.7-9.76-25.62-5.67-8-20.58-19.22-29.88-21a2.5,2.5,0,1,1,.93-4.91c10.84,2.06,26.66,14.06,33,23,6.94,9.74,10.23,18.47,10.68,28.29a2.5,2.5,0,0,1-2.38,2.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M566.91,626.08a2.49,2.49,0,0,1-2-.94l-.11-.14a4.77,4.77,0,0,1-1.27-3,2.8,2.8,0,0,1-.18-.83l-.24-.27a2.5,2.5,0,0,1-.55-1.84,84,84,0,0,1-3.7-8,2.5,2.5,0,1,1,4.63-1.89,71.12,71.12,0,0,0,4.08,8.66,2.5,2.5,0,0,1,.31.85,3.43,3.43,0,0,1,.48,1.31,2.48,2.48,0,0,1,.44,1,2.53,2.53,0,0,1,0,1l0,0a2.5,2.5,0,0,1-2,4.06Zm1.22-2.85h0Zm-4.08-6.18h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.12,640.27a2.5,2.5,0,0,1-2.42-1.9c-2.12-8.59-18.94-10.84-27-11.93-1.31-.18-2.45-.33-3.34-.48a2.5,2.5,0,1,1,.82-4.93c.85.14,1.93.29,3.19.45,9.88,1.33,28.28,3.79,31.21,15.68a2.5,2.5,0,0,1-2.43,3.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.4,640.28H599a2.5,2.5,0,1,1,.29-5c.51,0,.66-.11.72-.16.92-.89.86-4.27.84-5.72v-.79a2.5,2.5,0,0,1,1.73-2.39,3.12,3.12,0,0,0-.29-.26,2.5,2.5,0,0,1-.33-3.64,3.58,3.58,0,0,0,.67-1c-.44-.47-2.56-1.85-12.43-2.34-7.86-.39-17.68,1-24.26,2.44a2.5,2.5,0,1,1-1.07-4.88c3.35-.73,15.08-3.08,25.52-2.55,7.79.39,15.18,1.32,16.92,5.49a4.87,4.87,0,0,1-.28,4.23c.24.31.46.61.68.9a12.45,12.45,0,0,0,.84,1.07,2.5,2.5,0,0,1-1.65,4.21,3.73,3.73,0,0,0-.83.34l-.2.1c0,2.72-.18,6.25-2.39,8.37A5.69,5.69,0,0,1,599.4,640.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.89,605.19a13.23,13.23,0,0,1-2.15-.17,13.89,13.89,0,0,1-9.52-6.77,2.5,2.5,0,1,1,4.23-2.66,8.94,8.94,0,0,0,6.1,4.49c3.11.51,6.78-.8,10.32-3.69a2.5,2.5,0,1,1,3.16,3.88C404.08,603.49,399.85,605.19,395.89,605.19Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M381.45,690.17h-.18A2.5,2.5,0,0,1,379,687.5c.55-7.7,1.54-17.78,2.59-28.45,2-20.32,4.27-43.35,4.29-57.89a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5c0,14.78-2.3,37.94-4.31,58.37-1,10.64-2,20.68-2.58,28.32A2.5,2.5,0,0,1,381.45,690.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M409.89,690.37A2.5,2.5,0,0,1,407.4,688c-.55-7.75-1.55-18-2.62-28.77-2-20.33-4.27-43.38-4.29-58.11a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5c0,14.49,2.27,37.41,4.27,57.63,1.07,10.85,2.08,21.1,2.63,28.91a2.5,2.5,0,0,1-2.32,2.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.67,712.41a2.5,2.5,0,0,1-2-.94A128.91,128.91,0,0,1,379.22,689a2.5,2.5,0,1,1,4.5-2.19,123.3,123.3,0,0,0,13.91,21.57,2.5,2.5,0,0,1-2,4.06Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.67,712.41a2.5,2.5,0,0,1-2-4.06,124.1,124.1,0,0,0,13.94-21.57,2.5,2.5,0,0,1,4.5,2.19,129.3,129.3,0,0,1-14.52,22.5A2.5,2.5,0,0,1,395.67,712.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M222,539.15a40.07,40.07,0,0,1-11.74-1.43c-25.41-7.8-19.39-36.26-14.54-59.13,1.89-8.93,3.68-17.36,3.44-23.49a2.5,2.5,0,1,1,5-.19c.26,6.75-1.59,15.48-3.55,24.72-4.65,22-9.93,46.86,11.12,53.32,4.87,1.5,10.81,1.27,16.55,1,2-.08,4.08-.16,6.05-.16a2.5,2.5,0,0,1,0,5c-1.87,0-3.81.07-5.86.15S224.16,539.15,222,539.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M559,542.83a2.5,2.5,0,0,1-2.1-3.85c2.37-3.68,7.95-4.14,13.34-4.59,3.45-.29,7-.59,8.82-1.67,11.8-7.07,17.55-20.9,14.67-35.23-1.06-5.25-2.55-10.19-4-15C587.16,474,584.5,465.2,584.5,455a2.5,2.5,0,0,1,5,0c0,9.46,2.44,17.53,5,26.07,1.48,4.9,3,10,4.11,15.44,3.31,16.43-3.36,32.33-17,40.51-2.79,1.68-7,2-11,2.36-3.8.32-8.52.71-9.55,2.32A2.5,2.5,0,0,1,559,542.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M486,344.5a2.5,2.5,0,0,1-1.32-4.62c2.93-1.83,5.25-6.67,6.36-13.29a2.5,2.5,0,1,1,4.93.82c-1,5.77-3.24,13.35-8.64,16.71A2.49,2.49,0,0,1,486,344.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M487,345.5a2.5,2.5,0,0,1-2.07-3.9c2.69-4,7.07-5.2,10.93-6.28.81-.23,1.61-.45,2.37-.7a2.5,2.5,0,1,1,1.53,4.76c-.83.27-1.68.51-2.56.75-3.33.93-6.48,1.82-8.14,4.27A2.5,2.5,0,0,1,487,345.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M300,347.5a2.49,2.49,0,0,1-1.68-.65L297,345.61c-2.17-2-7.92-7.44-10.14-7.13a2.5,2.5,0,1,1-.68-5c4.23-.58,9.15,3.66,14.24,8.44l1.28,1.19A2.5,2.5,0,0,1,300,347.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M300.5,347.5a2.5,2.5,0,0,1-2.07-1.1c-2.93-4.33-2.93-10.32-2.93-15.13v-.77A2.5,2.5,0,0,1,298,328h0a2.5,2.5,0,0,1,2.5,2.5v.77c0,4.34,0,9.26,2.07,12.33a2.5,2.5,0,0,1-2.07,3.9Z" transform="translate(-53.25 -44.96)"/></g><g id="HAIR_DETAILS" data-name="HAIR DETAILS"><path class="cls-24" d="M400.45,398h0Z" transform="translate(-53.25 -44.96)"/></g><g id="layers"><g class="cls-36"><circle class="cls-7" cx="233.17" cy="430" r="75.37"/></g><g class="cls-36"><circle class="cls-7" cx="449.72" cy="429" r="75.37"/></g><path class="cls-24" d="M426,465a5,5,0,0,1-4.26-2.37c-1.47-2.38-11.35-7.06-25.79-7.89-13.45-.77-24.29,2.35-29,8.36a5,5,0,0,1-7.85-6.19c6.85-8.69,20.51-13.12,37.45-12.15,12.95.74,29,5,33.73,12.62A5,5,0,0,1,426,465Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.42,555.33A80.37,80.37,0,1,1,366.79,475,80.46,80.46,0,0,1,286.42,555.33Zm0-150.74A70.37,70.37,0,1,0,356.79,475,70.45,70.45,0,0,0,286.42,404.59Z" transform="translate(-53.25 -44.96)"/><g class="cls-37"><path class="cls-7" d="M532.48,427.22c1.29,3.14,3.66,6,5.79,8.72a96.55,96.55,0,0,1,18.14,38.2c1,4.5,7.56,4.49,9.69.91a10.2,10.2,0,0,0,1.13-4.2,51.8,51.8,0,0,0-3.32-24.26c-1.32-3.37-3.17-5.84-5.09-8.79-2.11-3.25-3-6.77-6-9.49-3.77-3.43-7.3-7.66-11.88-10.14-2.12-1.15-4.77-2-6.87-.84a5.82,5.82,0,0,0-2.52,4.86A11.66,11.66,0,0,0,532.48,427.22Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-37"><path class="cls-7" d="M316.29,432.4c1.29,3.14,3.66,6,5.79,8.72a96.55,96.55,0,0,1,18.14,38.2c1,4.5,7.56,4.49,9.69.91a10.2,10.2,0,0,0,1.13-4.2,51.8,51.8,0,0,0-3.32-24.26c-1.32-3.37-3.17-5.84-5.09-8.79-2.11-3.25-3-6.77-6-9.49-3.77-3.43-7.3-7.66-11.88-10.14-2.12-1.15-4.77-2-6.87-.84a5.82,5.82,0,0,0-2.52,4.86A11.66,11.66,0,0,0,316.29,432.4Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-24" d="M503,554.33A80.37,80.37,0,1,1,583.34,474,80.46,80.46,0,0,1,503,554.33Zm0-150.74A70.37,70.37,0,1,0,573.34,474,70.45,70.45,0,0,0,503,403.59Z" transform="translate(-53.25 -44.96)"/></g><g id="CIRCLE"><path class="cls-24" d="M397.38,745.79A344.13,344.13,0,0,1,154,158.33,341.87,341.87,0,0,1,397.38,57.54h3l11.29.28h.07a344.13,344.13,0,0,1-14.36,688Zm0-679.25c-184.79,0-335.12,150.34-335.12,335.13S212.59,736.79,397.38,736.79,732.5,586.46,732.5,401.67A334.16,334.16,0,0,0,411.4,66.83l-11.17-.28Z" transform="translate(-53.25 -44.96)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.png b/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.png deleted file mode 100644 index f15ad9a4cc88310b73c79bcd5f3b75c0f9a9efa9..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.svg b/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.svg deleted file mode 100644 index 4122d3d1f5c25bb22c584df4ae8620b3ef87eb89..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyScene2Shadows.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 688.25 700.83"><defs><style>.cls-1{fill:none;}.cls-2{fill:#474747;}.cls-3{opacity:0.2;}.cls-4{fill:#edc0e3;}.cls-5{fill:#e8e5e3;}.cls-6{fill:#aaa39f;}.cls-7{fill:#fff;}.cls-8{fill:#c4d8ba;}.cls-9{fill:#807e6e;}.cls-10{fill:#d7b89b;}.cls-11{fill:#efe6da;}.cls-12{opacity:0.44;}.cls-13{fill:#995967;}.cls-14{opacity:0.72;}.cls-15{fill:#829e93;}.cls-16{opacity:0.61;}.cls-17{fill:#a7d8bf;}.cls-18{opacity:0.59;}.cls-19{fill:#d1b288;}.cls-20{fill:#606282;}.cls-21{opacity:0.46;}.cls-22{fill:#51483e;}.cls-23{fill:#6e607f;}.cls-24{fill:#1d1d1b;}.cls-25{clip-path:url(#clip-path);}.cls-26{clip-path:url(#clip-path-2);}.cls-27{clip-path:url(#clip-path-3);}.cls-28{clip-path:url(#clip-path-4);}.cls-29{clip-path:url(#clip-path-5);}.cls-30{clip-path:url(#clip-path-6);}.cls-31{clip-path:url(#clip-path-7);}.cls-32{fill:#b79765;}.cls-33{fill:#e9e9f2;}.cls-34{fill:#3d3d3d;}.cls-35{opacity:0.68;}.cls-36{opacity:0.17;}.cls-37{opacity:0.36;}</style><clipPath id="clip-path" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M64.1,446.5,68,327c0-.74,110.68.57,120.76.64q30.51.22,61,.33c6.75,0,15.67-2.86,18.19,5,1.69,5.22-.25,11.23,0,16.58a66.07,66.07,0,0,0,2,13.25c1.3,5,2,6.21,0,10.75-3.71,8.44-8.65,15.92-13.38,24.23a58.76,58.76,0,0,0-4.67,11c-1.6,4.92-1.3,10.78-3.33,15.37s-6.67,8.57-9.26,12.9c-2.48,4.16-4.41,10-9.47,11.12-5.52,1.28-15.14-.81-21.12-.85q-24.31-.15-48.62-.34C152.13,446.9,64.12,445.91,64.1,446.5Z"/></clipPath><clipPath id="clip-path-2" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M547.52,426.07A19.5,19.5,0,0,1,543,417c-1.22-5.73-3.79-10.48-5.95-16-6.29-16.22-11.85-27-11.27-44.83.32-9.71.48-19.43,1-29.13,0-.74,110.68.57,120.76.64q30.51.22,61,.33c6.38,0,12.68-.67,19.06-.19,4,11.39,4.55,23,6.27,35.07,1.86,13.09,4.55,25.42,3.85,39-.63,12.08-.29,26.9-4,38.38-1.72,5.29-1.34,5.51-7.3,6.15-4.38.47-8.93-.24-13.33,0-15.44.84-30.18,1.06-45.52,1q-24.31-.15-48.63-.34c-11.71-.09-23.42-.23-35.13-.34-6.18-.06-16.86,2.13-22.47-.37-5.11-2.28-5.82-8.72-8.39-13.08A51.57,51.57,0,0,0,547.52,426.07Z"/></clipPath><clipPath id="clip-path-3" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M132.33,613.67c3-.92,8.1.34,11.5.67a101.15,101.15,0,0,0,14.08,0c8.09-.4,16.39-.28,24.51-.67a108.86,108.86,0,0,1,11.88-.28,17.65,17.65,0,0,0-1.35,4.55c-5.19-.07-3.06,3.59-1.4,6.15-3.62,1.72-3.81,5.09.74,5,0,2.42,0,5.84,1.7,7.78,1,1.1,2.72,1.61,3.56,2.78,1,1.36,1.07,3.37,1.7,4.94a22.28,22.28,0,0,0,6.36,8.73c5.62,4.73,13.19,6.71,20.4,7.06,3.64.18,7.32-.15,10.95,0,.35,7,1,14.28.22,21.25-.66,6.16-2.13,12.08-2.57,18.27-1.4-2.33-5.52-4.06-7.76-5.57-3.65-2.46-7.27-3.34-11.15-5.16-7.75-3.64-13.38-9.11-20.36-13.93-7.53-5.2-15.21-9-22.15-15.08a173,173,0,0,1-22.18-24c-2.75-3.56-6-6.48-8.67-10.07-2.39-3.16-6.59-7.57-8-11.09"/></clipPath><clipPath id="clip-path-4" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M661.33,612.33c-11.53,0-23.3,1.39-34.74,2.33-7.67.63-15.22-.38-22.87.06a6.61,6.61,0,0,0-.34,3.56c3.57.37,3.12,4.64.31,5.63,1.48.49,2.61,1.47,2.59,3-4.54.55-2.26,4.19-3.27,7.39-.52,1.64-1.08,1.92-2.16,3-.36.36-1.26-.21-1.77.39s-.45,1.93-.81,2.67c-2.6,5.29-5.11,10.83-10.45,13.92-4.11,2.37-9.38,3.66-13.82,5.25a32.68,32.68,0,0,1-12.27,2.13c-.65,4.82.62,10.54.62,15.51,0,6.61-.91,14,.34,20.42,4,.09,8.51-3.94,11.64-6.28,5.48-4.09,11.25-7.68,16.78-11.7,5.72-4.15,10.69-9,16.23-13.34s11.78-8.28,17-13.27c4.31-4.15,8.76-8.19,13.34-12,4.43-3.73,7.79-7.72,11.83-11.78C652.16,626.52,662.91,616.69,661.33,612.33Z"/></clipPath><clipPath id="clip-path-5" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M579.07,484.41c-.8,4.09-1.75,8.25-2.81,12.34-2.06,7.88-6.13,15.35-9.25,22.91-1.85,4.48-3.71,6.52-8.28,8.4.2-.08.35,8.66.44,9.64.36,3.72,1.64,7.27,2.7,10.83,2.2,7.37,3.58,13.61-1.5,20.06.48-.61,9.82,2.94,10.61,3.5,2.42,1.71,4.69,3.82,7.21,5.6a47.82,47.82,0,0,1,5.91,5.44c2.74,2.71,4.32,5.41,8.4,5.21,5.13-.25,10.46-1.11,15.65-.58,8,.83,16,.73,24,1.07s16.17-.83,24.31-.83c6.07,0,12.15,0,18.19-.26,5.07-.24,6.21.26,8.85-4.21,2.51-4.26,6.39-7.32,9.59-11,3.9-4.51,5.95-9.54,8.61-14.76,3.82-7.47,5.77-15.67,8-23.71,2.16-7.84,6.43-14.87,9.36-22.45,2.19-5.66,4.22-11.21,4.93-17.26a124.32,124.32,0,0,1,2.34-13.68c.62-2.7,1.77-6.43,1.27-9.27-38.84-2.08-78.82-1.69-117.78,0q-10.63.45-21.24,1.36c-2.39.21-8-.29-9.27,1.76C578.16,476.28,579.53,482,579.07,484.41Z"/></clipPath><clipPath id="clip-path-6" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M141.17,586c8.14.29,16,1.67,24.41,1.67,9.44,0,18.67.29,28-.17,3.4-.17,6.65-.41,10.06-.5,4.37-.12,4.93-2.93,8-6,6-5.95,13.79-9.37,20.88-13.73-1.29-5.55-4.27-8.69-4.28-14.83,0-7.27,4.87-15.19,3.32-22.24-.32-1.47-2.51-3-2.26-4.78s2.46-3.63,2.94-5.42c1-3.89.57-9.75-.41-13.59-1.61-6.29-7-10.59-8.18-17-.63-3.39-.23-6.81-.74-10.19-.35-2.34-1.66-4.32-1.71-6.81-7.93-.44-16-.07-24-.05-10.2,0-20.36-1.34-30.64-1.33-17.24,0-34.65,0-51.82-.67a289.65,289.65,0,0,0-39.92,1c-2,.2-6.86-.45-7.95,1.35-1.41,2.34,3.64,10,4.3,12.3,1.76,6,3.44,12,5.3,17.93,5.63,18.05,11.86,35.93,17.48,54,3,9.49,7.26,19.28,14.09,26.65,4.48,4.84,7.5,4.35,13.9,3.82S134.75,585.77,141.17,586Z"/></clipPath><clipPath id="clip-path-7" transform="translate(-53.25 -44.96)"><path class="cls-1" d="M260.38,162.7c55.06.06,110.12.66,165.17.93s110,.24,164.94-1q11.49-.25,23-.58c6.76-.19,14.57.48,21.18-.81-2.12-2.56-2.84-5.8-5.31-8.27a49.21,49.21,0,0,0-8.75-6.93c-3.43-2.17-6.39-5.18-9.92-7.17s-7.45-3.18-10.4-6.06c-2.57-2.52-3.58-5.46-6.65-7.58-3.92-2.7-8.47-4.14-12.53-6.6-8.77-5.33-15.26-12.33-24.56-16.66-5.63-2.62-9.94-7.32-15.43-10-5.2-2.54-11.11-3.46-16.43-5.68C519,84,513.78,80.24,508,78.17c-11.9-4.27-24.91-5.63-37-9.42-6-1.89-11.6-2.33-17.86-2.73-6.58-.43-13.28-2.26-19.83-3.1a194.85,194.85,0,0,0-31.88-1.22c-4.19.15-7.08-1.83-11.21-1.81s-8.06,1.46-12.12,1.87c-10.28,1-20.62,1.18-30.91,2.28-16.38,1.76-32.39,8-48.07,12.63-10.5,3.1-21.41,6.09-31.32,10.75-9.51,4.47-18.42,10-27.82,14.64-9,4.48-18.56,8.06-26.82,13.94-3.55,2.52-6.66,5.4-10.63,7.35-4.14,2-8.49,3.57-12.18,6.41-7.21,5.55-14.07,12.07-21,17.93-2.51,2.12-15.05,10-10.75,14,2.39,2.2,12.65.55,15.86.57l17.34.12Q226.08,162.62,260.38,162.7Z"/></clipPath></defs><title>BoyerScene2Shadows</title><g id="COLOR"><path class="cls-2" d="M411.55,62.33C592.55,69.76,737,218.85,737,401.67c0,187.57-152.06,339.62-339.62,339.62S57.75,589.24,57.75,401.67,209.81,62,397.38,62h3Z" transform="translate(-53.25 -44.96)"/><g class="cls-3"><path d="M411.55,62.33C592.55,69.76,737,218.85,737,401.67c0,187.57-152.06,339.62-339.62,339.62S57.75,589.24,57.75,401.67,209.81,62,397.38,62h3Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-4" d="M89.49,418.2c.15-3,.16-6,.34-9.05.16-2.72.88-5.49.78-8.19s-.8-5.19,2.15-6.53a49.56,49.56,0,0,1,10.52-3.06c5.41-1.11,11.86-.2,17.44-.35,6.67-.18,13.51,0,20.13-.73,5.79-.66,11.57,2.28,17.41.66,4.71-1.3,1.34-16.9.49-20.44-.92-3.87-2.37-5.83-4.24-9.25-1.77-3.25-2.63-4.83-5.59-7.05-3.61-2.71-6.83-5.59-11.24-7-4-1.23-9.3-.66-13.37-.25a149.55,149.55,0,0,0-15.43,2.48c-7.23,1.5-13.51-4.77-15.24-11.31a15.92,15.92,0,0,1-.43-6.7c.71-3.35,2.92-4.58,6.15-4.63,2,0,3.83-.42,5.79-.51s5.19-.69,6.93-.16c2.42.73,3.93,4.59,5.11,6.67.4.69.56,2.46,1.48,2.68s4.9-2.71,5.85-3.19c5.28-2.67,10.15-4.48,16.08-4.7,8.39-.31,16.79-.16,25.19,0,7.38.17,14.71.78,22.06.17,5-.41,9.91-.5,14.91-.5,5.15,0,10.31-.07,15.45.17,2.67.12,5.91.73,8.14,2.3,2,1.4,5.57,5,8.15,4.47,2.23-.5,3.46-3.4,5.18-4.67,3-2.22,7.08-2.77,10.8-2.43,3.53.32,6.58.76,8.5,3.85s.88,5.93-.23,9.07a54.25,54.25,0,0,1-6.23,12.12,3.82,3.82,0,0,0-2.87-1,13.92,13.92,0,0,1-5.53-1.33c-4.15-2.12-7.94-3.68-12.69-3.83a37.3,37.3,0,0,0-16,3.29c-4.25,1.8-9.81,4.19-13.05,7.58-6,6.26-6.8,14.53-7.53,22.8-.29,3.31-.68,6.73,0,10,.42,2,.9,2.61,3,2.63a68.9,68.9,0,0,0,10.13-.75c8.26-1.17,16.85-3.06,25.24-2.38,4.65.38,9.17.43,13.79,1.32,2.23.43,4.37,1.06,6.63,1.38a14.25,14.25,0,0,1,4,.83c.16,2.13-1.9,5-2.87,6.84-2.06,3.94-3.08,8.38-4.95,12.42a43.33,43.33,0,0,0-2.5,6.58c-.66,2.33-.74,5.27-1.67,7.46-1,2.4-3.9,4.89-5.55,7.09a105.22,105.22,0,0,1-7,8.37c-1.79,1.93-3.67,4.55-5.59,6.25-2.14,1.89-6.41.88-9.08.79-7.44-.26-14.64-1.68-22.17-1.13-6.64.49-13.72-.28-20.44-.32-7.34,0-14.67,0-22,.3-18.33.83-36.7-3.1-54.85-.54a26,26,0,0,1-6.08.2c-1.8-.16-4.23.14-4.82-1.77-.72-2.33.22-6.49.33-9C88.72,430.24,89.19,424.23,89.49,418.2Z" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M727.5,327.5c0-.64,0-1.28-.09-1.91-.34-5.38-.65-22.82-6.92-23.84-4.21-.69-9.54.16-13.88.16h-41c-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-126.07-1.17-191.59-1.17L68,327c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0H728" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M637.53,161.53c-3.9,0-7.8,0-11.68.17-120.91,3.89-243.85,1.14-365.47,1-34.45,0-68.81-.31-103.17-.56l-23.62,24.93c42.24.28,84.46.68,126.79.73,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M64.1,446.5c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0,20.81,0,51.3,2.07,72.11,2.07L730,470.8c-20.81,0-47.47.79-68.28.79-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-130.77-1-196.28-1" transform="translate(-53.25 -44.96)"/><path class="cls-5" d="M681,588.06c-6.91-.23-13.49-.4-19.3-.4-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-48.95-.05-97.73-.59-146.58-.85L131.17,613c43,.28,86.06.7,129.21.75,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M727.5,327.5c0-.64,0-1.28-.09-1.91-.34-5.38-.65-22.82-6.92-23.84-4.21-.69-9.54.16-13.88.16h-41c-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-126.07-1.17-191.59-1.17L68,327c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0H728" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M637.53,161.53c-3.9,0-7.8,0-11.68.17-120.91,3.89-243.85,1.14-365.47,1-34.45,0-68.81-.31-103.17-.56l-23.62,24.93c42.24.28,84.46.68,126.79.73,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M64.1,446.5c65.51,0,130.74.93,196.28,1,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0,20.81,0,51.3,2.07,72.11,2.07L730,470.8c-20.81,0-47.47.79-68.28.79-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-65.54-.07-130.77-1-196.28-1" transform="translate(-53.25 -44.96)"/><path class="cls-6" d="M681,588.06c-6.91-.23-13.49-.4-19.3-.4-11.92,0-23.91-.38-35.82,0-120.91,3.89-243.85,1.14-365.47,1-48.95-.05-97.73-.59-146.58-.85L131.17,613c43,.28,86.06.7,129.21.75,121.62.14,244.56,2.89,365.47-1,11.91-.38,23.9,0,35.82,0" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M689.33,345.33c-15.88.07-27.4,7.39-33.93,21.91-3.35,7.46-4.21,16-1.49,23.75.63,1.79,2.24,7.45,4.14,8.28s7.59-1.84,9.76-1.94c4.4-.21,8.78-.44,13.16-.67,9.14-.47,19-2.15,28-.83,5.14.75,10.82,4.1,15.95,3.49,0-6.61,2.86-12.73,2.39-19.62-.37-5.43-3.36-10.23-6.19-14.69s-6.29-10.2-10.14-13.95C706.06,346.23,699.6,346.58,689.33,345.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M577.33,345.67c-8.13,2.74-16.2,6.05-22.67,12-7.18,6.59-8,16.39-8,25.65,0,5,.58,12.8,4,16.73,9.37-6.75,25.31-5.33,36.26-4.37,6,.52,11.95.82,17.84,1.91,3.54.65,7.58,1.86,11.19,1.37,1.49-6.31,5.31-10,5.06-17a39.76,39.76,0,0,0-5.5-18.32C607.56,350.39,597,346.33,577.33,345.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-8" d="M584.47,330.32c-2.69,1.39-5.71,4.62-8.4,5.3-3.34-7-9.64-7-16.73-6.62-4,.22-7-.06-6.67,4.58.38,5.94,3.06,14.31,9.5,16,5.45,1.42,10.87-1.23,16.15-2.22,6.6-1.23,12.53-1.2,18.85,1,14.85,5.24,21.87,18,21.17,33.56-.16,3.48,0,16.13-4.19,18.05-1.58.72-7.86-1.67-9.82-2-8-1.24-16-2.9-24.13-3.7s-14.79.94-22.37,3.32c-2.75.86-6.43,1.58-8.2,3.86s-2.1,6.88-2.3,9.51c-.45,5.79-2,12.06.31,17.62,1.53,3.63,4.42,6.53,7.44,8.93,3.53,2.82,4.78,5.89,6.65,10.07,14.65.9,29-2.15,43.76-2.28,9-.08,18-.93,26.84-1,9.1-.07,17.51,1.92,26.5,2.68,10.45.88,21,.63,31.53.81,9.78.17,19.79.78,29.48.75,4.8,0,2.74-3,2.71-7.43,0-5.1.57-10.23-.2-15.3-.52-3.43-1.15-6.67-1.35-10.15-.15-2.71-1.27-6.44-.67-9,.75-3.19,3.76-4.87,3.28-8.62-11.35-.63-22.56-1.38-33.94-1.38s-22.47,3.56-33.34,1.83c.18-4-1.47-7.84-1.67-11.83s-.33-8-.33-12c0-8.39,4.09-14.09,10.68-19.41,9.93-8,21.7-11.6,34.67-9.23,3.63.66,7.27,3.77,10.65,4.14,4.87.54,7.91-8.54,8.51-12.84,1.2-8.69-1.45-10.79-9.68-11.17-3.57-.16-6.87-.6-9.85,1.68s-5,5.72-8.22,7.79c-5.52-9.81-22.7-9.3-32.08-9.3-17.09,0-34.29.82-51.35,1.67-3.94.2-8-.88-11.91-1C590.64,326.75,588.76,328.11,584.47,330.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M638,393.67c-3.35,0-15.51-.26-14.36,5.67.5,2.58,6,4.42,8.19,4.83,3,.56,5.94.31,8.16-1.82C641.55,400.86,645.87,392.58,638,393.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M626,400.67c-8.15-1.58-12.48,17.44-3.33,18.33,3.87.38,6.87-2.06,10.41-2.92,4.88-1.19,10.23.45,15.19,0,5.93-.57,6.78-6.25,4-11.05-1.75-3-4.79-3.2-7.18-5.3-2,5.4-13.39,5.35-16.08,1" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M628,418.33c-.19,2.28-1.39,7.7-.18,9.85,1.32,2.33,6,2.67,8.35,2.49,2.92-.23,5.64-1.43,6.58-4.33.44-1.35,1.15-8,.59-9.17C641.86,414.17,631,415,628,418.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M183.67,393c-3.93,0-20.42-1.1-18.35,6,1.15,3.93,8.21,4.93,11.58,5C182.73,404.09,186.51,400.8,183.67,393Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M161.75,404.35c-1.93,2.57-4.11,7.18-2.35,10.26s6.5,4.14,9.6,3.32A43,43,0,0,1,179.5,416c3.4-.11,8.91,1.1,12-.37,7.94-3.79.72-11.47-3.41-14.71-3.25-2.55-3.86.42-6.92,2.25-2.62,1.56-5.68,2.94-8.67,1.7C168.19,403.07,166,398.74,161.75,404.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M168.33,417.33c0,7,.59,11.56,8.33,12.34,3.34.33,6.66.05,8.26-3.17,1-2.07,1.55-7.61.22-9.49C182.34,413.05,174.9,415.3,168.33,417.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M88.5,394.33a48.2,48.2,0,0,1-.21-22.53A27.33,27.33,0,0,1,96,358.64c2-2,3.92-4.38,6.43-5.77a53.9,53.9,0,0,1,8-3.24c6.09-2.19,12.16-3.64,18.69-3.3a36.48,36.48,0,0,1,10.33,2.26c2.89,1.05,4.92,3.18,7.24,5.1,2.08,1.72,4.25,2.94,5.92,5a29.06,29.06,0,0,1,3.73,6.56c2.84,6.42,3.69,12.08,3.68,19.05,0,1.77.92,6.87-.68,8.23-1.13,1-4.26-.81-5.46-1.24-3.84-1.37-8-1.5-12-1.5-9.57,0-19.67.27-29.12,1.88C104.76,393.07,96,393.51,88.5,394.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M196,392c-1.79-1.75-1.89-6.26-2-8.63a33.15,33.15,0,0,1,.46-8c.9-4.59,3.49-9.41,5.67-13.5,7.79-14.61,29.4-17.66,44-13.87,4.77,1.24,9.79,2.87,12.87,6.92,2.27,3,5.88,7.5,6.46,11.25" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M248.67,351.33c.78,1.44,2.61,2.29,3.84,3.33a44,44,0,0,1,4.62,4.63,40.35,40.35,0,0,1,5.83,8.8,52,52,0,0,1,3.62,7.83c.95,3.06-2.19,6-3.86,8.48-2.07,3.07-4.34,6.07-6.27,9.26-2.39-2.19-6.42-2.57-9.56-3.09a103.84,103.84,0,0,0-17.2-1.23c-10.86,0-21.52,2.53-32.37,2.67" transform="translate(-53.25 -44.96)"/><path class="cls-11" d="M180.17,162.33c-4.89,0-5.59-1.1-7.57-5.41-.55-1.2-2.47-4.28-2.28-5.58.35-2.33,3.06-3.08,5-4.35,6.52-4.23,12.36-9.33,18.49-14.16,7.48-5.9,15.18-10.77,23.17-15.93,5.58-3.61,11.35-6.67,17.1-10,11.44-6.63,24.34-10.63,36.4-16.08A352.56,352.56,0,0,1,347.35,66a242.15,242.15,0,0,1,28.52-3.37c3-.23,17.34-2.79,18.83,1,.22.58-.92,3.37-1,4.17-.23,1.6-.25,3.32-.33,4.91-.22,4.5-2.48,16.8.83,20.26,1.57,1.65,2.82.45,5.18,0,3.1-.59,6.36-.33,9.51-.33,6.7,0,13.33,0,20,.67,1.42.14,4.8-.14,5.55,1,.59.87-.24,4.17-.34,5.19-.67,6.65-.65,13.76-.68,20.51,0,10-.34,19.9-.28,29.86,0,2.6-1.23,9.56.09,11.76,1.22,2,4.81,1.58,6.81,2-.32-.07.52-32.62.49-35.66-.1-10.61-.77-21.25-.77-32,0-5-2-14.61.39-18.94,5-.32,9.91-.19,14.89-.44.14-2.75-1-7.18,1.38-8.28,3.14-1.44,9.33,1.6,12.88,1.38-.32,0,.45,22.21.45,24.2,0,5.69-.34,11.33-.59,17-.54,12.46.59,24.71.59,37.15,0,5.16-.47,10.06-.72,15.2-4.26.57-9.19-.62-13.58-.62-5.59,0-11.39-.35-16.94.24-15.7,1.69-32.27.91-48.16.09-10.62-.55-21.43.27-32.14.1-12.09-.19-24.18-.44-36.27-.44-29.6,0-59,1-88.57,1-8.16,0-16.68.73-24.62-.76-2.89-.54-5.9-1-8.74-1.49C193.6,160.38,186.58,162.33,180.17,162.33Z" transform="translate(-53.25 -44.96)"/><g class="cls-3"><path d="M440.17,158.78c-.13-10.26.36-20.52.26-30.82-.1-10.61-.77-21.25-.77-32,0-5-2-14.61.39-18.94,5-.32,9.91-.19,14.89-.44.14-2.75-1-7.18,1.38-8.28,3.14-1.44,9.33,1.6,12.88,1.38-.32,0,.45,22.21.45,24.2,0,5.69-.34,11.33-.59,17-.54,12.46.59,24.71.59,37.15,0,5.16-.47,10.06-.72,15.2,0,.76-19.65-.13-21.13-.32a10.14,10.14,0,0,0-4.14,0c-1.13.34-2.28,1.1-3.39.72Q440.2,161.24,440.17,158.78Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M303.55,161.86c-.81-12.51,1.83-24.9,2.8-37.33a114.16,114.16,0,0,0-.45-18.9c-.5-5.93.14-12.09.09-18.06q0-4.55-.21-9.1c8.46-5.27,18.63-7.23,28.31-9.56,7.08-1.7,14.13-3.37,21.41-1.81-3.48,13.14-.1,27-.06,40.58,0,3.35-.18,6.7-.33,10a355.09,355.09,0,0,0,.93,45.51c-.07-.88-31.13-.58-34.17-.58-1.33,0-18.28-.34-18.21.53Q303.59,162.53,303.55,161.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-14"><path class="cls-15" d="M239.27,163.84a64.66,64.66,0,0,0,2.63-13.77l4.88-41.94a19,19,0,0,1,1.28-5.73c1.72-3.78,6.3-4.89,9.83-6.3,4.23-1.69,8.45-3.38,12.6-5.26a188.12,188.12,0,0,1,24.76-9.16L294,102.77c-.4,6.47-1.61,13.54-.9,19.93a203.82,203.82,0,0,1,1.36,23.14c0,3.86-.17,7.72-.48,11.57s0,5.17-3.94,5.26c-8.35.18-16.71.58-25.05.71q-7,.11-14.07.19C247.54,163.6,242.35,165,239.27,163.84Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M180.17,162.33c-4.89,0-5.59-1.1-7.57-5.41-.55-1.2-2.47-4.28-2.28-5.58.35-2.33,3.06-3.08,5-4.35,6.52-4.23,12.36-9.33,18.49-14.16,7.48-5.9,15.18-10.77,23.17-15.93,5.58-3.61,11.35-6.67,17.1-10,4.47-2.59,9.16-5.63,14.1-7.05a1.67,1.67,0,0,1,1-.08c.77.26.74,1.35.55,2.14a479.38,479.38,0,0,0-8.47,47.41c-.42,3.28.1,9.24-1.38,12.13-1.2,2.34-5,2.19-7.76,2.21-7.81.06-15.73.68-23.45-.76-2.89-.54-5.9-1-8.74-1.49C193.6,160.38,186.58,162.33,180.17,162.33Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/><g class="cls-16"><path class="cls-17" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M499.64,86.89c-.77-1.42-1.53-2.84-2.27-4.28-3-5.84-6.46-6.27-12.5-8.39-4.32-1.51-8.84-3.06-13.48-2.84-.63,4,6.39,10.9,8.54,14.28,3.41,5.36,5,11,7.49,16.75,2.83,6.54,8,11.93,11.25,18.33,3.69,7.21,8.86,13.26,12.93,20.29,4,6.84,9.36,13.51,14.4,19.55,5.21-1.43,7.56-8.46,13.61-9.2,1.34,3.76-.71,7.55-.23,11.23a520.91,520.91,0,0,0,78.88-1.94c4.88-.48,9.81-.13,14.71-.39-2.19-3-3.55-6.49-6.15-9.47-3.41-3.91-7.1-6.63-11.26-9.64-6.7-4.85-14.37-8.71-20.69-14-3.87-3.24-7.56-6.62-11.76-9.5a196.87,196.87,0,0,0-30.18-16.75c-2.57-1.15-10.73-6.6-13.35-3.61-1.39,1.58-.13,8.08-.23,10.18-.44,9.22,1.55,18,1.65,27.17.05,4.4,1.27,12.09-1,15.71-4.13-2.63-4.54-9.06-6.61-13.08-2.44-4.74-6.06-8.74-8.82-13.29-3.25-5.35-7-9.85-10.51-15-1.79-2.64-3-5.7-4.81-8.32C506,96,502.37,91.94,499.64,86.89Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M92.25,301.5c0-6-.5-12-.5-18.06,0-5.5-1-10.71-.75-16.21s-.53-10.74,1.4-16c3.53-9.57,9.82-18.41,15.56-26.75,3.87-5.62,7.07-11.13,14-12.82q.13-.15,0,0a3.67,3.67,0,0,1-.62.54c3.43-.59,7-2.53,10.66-1.41,5.14,1.6,6.51,6.61,7.46,11.3,3.59,17.89,6,36.34,7.92,54.46.51,4.84.5,13.41,4.64,16.72,1.58-5.82,1-12.05.73-18-.09-2.2,1-6.55-1-8,0,0,1.38-62,1.31-63s9.69-2,9.69-2l8.44,1.41,1.06,4.33L174,195.93h20.67v14.55l12.33.13V195.93l19-.65s12.92,3.72,12.84,4.22.17,76.75.17,76.75l.47,16.25,16.16-28.11,31.47-48.05L297.25,201l11.54,8L310.67,188l13.09-.23L323.18,219l17.32.25L338.75,304l-28.66-1V213l-1.84-1L274,271l-11.25,20L253,302l-12-8.67-2,1.09,1.33,6.85Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-19" d="M92.25,301.5c0-6-.5-12-.5-18.06,0-5.5-1-10.71-.75-16.21s-.53-10.74,1.4-16c3.53-9.57,9.82-18.41,15.56-26.75,3.87-5.62,7.07-11.13,14-12.82q.13-.15,0,0a3.67,3.67,0,0,1-.62.54c3.43-.59,7-2.53,10.66-1.41,5.14,1.6,6.51,6.61,7.46,11.3,3.59,17.89,6,36.34,7.92,54.46.36,3.41.41,6.88,1.22,10.23s3,6.57,2.57,10.21c-.92,7-12.72,4.42-17.57,4.43l-21.11,0Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-14"><path class="cls-15" d="M310.09,301.5V253.82c0-17.45.39-34.95-.69-52.32-.06-1,1.2-13.52,1.27-13.52l13.09-.23L323.18,219l17.32.25L338.75,304l-28.66-1Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M253,302c-2.25-1.63-4.71-2.95-7-4.5-1.06-.72-5.47-2.36-5.74-3.5a2.51,2.51,0,0,1,.14-1.25c2.85-9.95,10.06-19.35,15.24-28.36l31.47-48.05L297.25,201c4.1,2.86,9.46,5.37,12.37,9.43a3.46,3.46,0,0,1-1.25,3.18c-3.48,2.74-5.36,7.38-7.58,11.2l-8.67,14.93-15.74,27.11L274,271l-11.25,20Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M153,295.9c-.63-6.8,0-13.85-.26-20.65-.09-2.2,1-6.55-1-8,0,0,1.38-62,1.31-63s9.69-2,9.69-2l8.44,1.41,1.06,4.33L174,195.93h20.67v14.55l12.33.13V195.93l19-.65s12.92,3.72,12.84,4.22.17,76.74.17,76.75c0,2.8.16,5.61.24,8.41.11,4-.6,8.55.14,12.4.4,2.11,2.31,3.77,2.05,6.09-10.6.4-21.52-1-32.17-1.15s-21.12,0-31.67.34c-7.47.26-15.09.63-22.26-1.48a3,3,0,0,1-1.46-.77,3,3,0,0,1-.55-1.55C153.19,297.68,153.08,296.79,153,295.9Z" transform="translate(-53.25 -44.96)"/></g><polygon class="cls-11" points="292.81 257.04 292.37 188.62 331.25 188.69 332.25 161.42 375.58 161.42 377.25 158.59 388.74 157.38 392.75 158.09 396.14 159.65 397.6 150.81 419.52 150.97 418.91 163.79 431.27 164.54 431.3 151.68 445.66 150.81 454.25 150.63 462.5 152.7 463.08 178.06 474.5 177.82 477.54 175.78 476.5 171.22 496 164.54 500.75 165.29 513 237.04 518.25 258.54 486.5 258.79 479.75 205.44 476.5 185.51 474.5 188.04 474.5 259.72 388.74 258.79 372.42 251.62 363.92 248.75 359.76 249.29 360.52 252.7 346.42 254.29 327.96 255.7 320.75 255.7 292.81 257.04"/><g class="cls-16"><path class="cls-17" d="M536.48,277.9,533,250.4c-1.67-10.25-2.32-20.24-3.6-30.5a7,7,0,0,1-.06-2c.57-3.44,8.49-4.49,11.35-5.47l8.57-2.94,4.75.75L566.25,282l5.25,21.5-31.75.25Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M473.47,293.73c-1.74-26.81.49-53.82-1.55-80.62a4.35,4.35,0,0,1,.27-2.4c1-1.92,12.33-1.69,12.33-1.21l0-12.86,14.36-.87,8.59-.19,8.25,2.08.58,25.36c2.8-.06,10.63-1.71,11.76,1.59a7.14,7.14,0,0,1,.21,2.63c-.69,16-.55,32.12-.55,48.19v29.24s-17.26-.19-18.27-.2l-18.3-.2-9.55-.1c-1.55,0-5.71,1.2-6.72,0a4.87,4.87,0,0,1-.81-2.69Q473.72,297.6,473.47,293.73Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M425.5,293.74a206.26,206.26,0,0,1-.69-22.25l.26-51.15a30.31,30.31,0,0,0-.76-8.51,7.25,7.25,0,0,1-.48-2.53c.14-1.71,1.71-2.93,3.28-3.62,5-2.2,9.39-2.75,14.88-3.33l4,.71,3.39,1.56,1.45-8.84,21.92.16c-.27,5.63.18,11.07-.14,16.67-.46,8.18-.88,16.36-1.09,24.55-.41,16.12,0,32.31,2.46,48.27.91,5.88,2.09,11.73,2.51,17.66.16,2.26-.67,1.84-2,1.84-.19,0-1.31-.76-1.64-.85-1.21-.34-3,0-4.25,0L455,303.89l-13-.14c-2,0-5.17-2.27-7-3.05-2.68-1.18-9-2.58-9.43-6Q425.55,294.23,425.5,293.74Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-19" d="M346.06,302l-.45-68.42,38.88.07,1-27.27h16.62c8.39,0,18.24-1.41,26.4.12a68.46,68.46,0,0,1-.41,12.13l-2.78,29.79c-.43,4.65-.87,9.3-.88,14,0,3.8.25,7.6.52,11.39.52,7.46,4,19.43,3.88,26.89-3.05.17-7.48-.41-10.33,0l-4.62-.25h0L400,300.5l-18.79.17H374Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M433.26,162.79c-.09-1.68-.12-3.36-.15-5l-.53-29.61a72.4,72.4,0,0,0-.4-7.61c-.31-2.49-.88-5-1-7.47-.28-6.72,2.75-13.46,1.35-20a1.53,1.53,0,0,0-.45-.93,1.6,1.6,0,0,0-1-.22c-7.26,0-14.53.07-21.78.32-2.6.09-4.76,1-7.28,1.19-2.21.18-6.4-.33-6.61,3-.06.92.31,2.07-.45,2.59-2.09-11,1.69-22.46-.31-33.48a3,3,0,0,0-.73-1.72,3.17,3.17,0,0,0-2.4-.51c-11.48.7-23,1.4-34.34,3.2a4.31,4.31,0,0,0-2.25.82c-1.21,1.08-1.59,5.31-2,6.89-.75,3.31.08,7.37.39,10.71,1.19,12.69.41,25.42.46,38.17q.08,19.88,1,39.74,20.06,1.58,40.21,1.38C398.23,164.17,433.25,162.64,433.26,162.79Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M714.75,284.75c1.42,1.82,1.16,5.24,1.75,7.45s2,3.71,2.85,5.67c2.21,5.24-8.77,4.26-11.58,4.29l-18.26.18-52,.51L635.34,210l-2.86-3.52S622.35,250.08,616.92,266s-12.28,36-12.28,36l-14.84-6.92-2.55,7.29L571.5,303.5l-2.5-97,.75-2.25,11.8-1.16H587l1.5,3.28-.12,6.5-1.13,54.83.25,23.8,26.19-77,5.56-13.75L620,194l13,3.25,2.34,2.5-1.1,4.5,18.27-1.2,2.69,3.45,1.1,2.25V195l8-.33s31,44.17,38.25,58.88" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-19" d="M714.75,284.75c1.42,1.82,1.16,5.24,1.75,7.45s2,3.71,2.85,5.67c2.21,5.24-8.77,4.26-11.58,4.29l-18.26.18-52,.51-1-42.75-.73-31.8-.27-11.63c0-1.28-.74-11.06-1.42-10.63,5.27-3.33,12.27-2.59,18.43-3l2.69,3.45,1.1,2.25V195l8-.33s31,44.17,38.25,58.88" transform="translate(-53.25 -44.96)"/></g><g class="cls-12"><path class="cls-13" d="M635.34,199.75c-1.38,5.62-3.78,10.93-5.29,16.55-1.63,6.07-2.86,12.23-4.4,18.32-2.66,10.52-5.23,21.14-8.72,31.42-5.42,16-12.28,36-12.28,36l-14.84-6.92-2.55,7.29L571.5,303.5l-2.5-97,.75-2.25,11.8-1.16H587l1.5,3.28-.12,6.5-1.13,54.83.25,23.8,26.19-77,5.56-13.75L620,194l13,3.25Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M82,522.25l5.82-27.41,20.8,5.82,5.19,3.67L111.33,509l8.5-.68,4,.74,1.66-3V484.25l12.81-2.65h8l6.21.9,3.5.32.5,14.42L168,495.5l1.14-.66.11-13.09,16.5.75h5.91v9.65l1,2.69,5.11-5.88,4.59-.52,4.57.52,5.1.67.6,5.21,4.79-2.88,4.73-.25,3.63-1s7,15.41,8.11,18.2-.1,4.09-.1,4.09l-2,8.21L229.5,544.5l-2.88,12.27v5.56l2.63,3.86,2.76,1.43-13.26,8.62L206,587.76l-92.21.05Z" transform="translate(-53.25 -44.96)"/><g class="cls-21"><path class="cls-22" d="M82,522.25l5.82-27.41,20.8,5.82,5.19,3.67L111.33,509l8.5-.68,4,.74,1.66-3V484.25l12.81-2.65h8l6.21.9,3.5.32.5,14.42L168,495.5l1.14-.66.11-13.09,16.5.75h5.91v9.65l1,2.69,5.11-5.88,4.59-.52,4.57.52,5.1.67.6,5.21,4.79-2.88,4.73-.25,3.63-1s7,15.41,8.11,18.2-.1,4.09-.1,4.09l-2,8.21L229.5,544.5l-2.88,12.27v5.56l2.63,3.86,2.76,1.43-13.26,8.62L206,587.76l-92.21.05Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M592.09,588l14.61-9.7-.15,9.23,31.78.81,44.33-.81s8.87-18.31,18-38c9-19.49,18.24-40.34,19.36-46.2,2.25-11.78,0-5.95,0-5.95a36.4,36.4,0,0,1-5.55-.79c-1.25-.39-2.24-2.22-3.75-.67-.92.95-1,2.4-1.12,3.72-.61,7.11-3.47,13.81-5,20.78a67.44,67.44,0,0,0-1.42,17.29c.17,4.31.64,8.82-1.1,12.76s-5.5,6.72-7.62,10.51a101.78,101.78,0,0,1-.84-11.9q.65-29.68,1.3-59.37c-3.89.63-7.49-1.87-11.53-1.89a9.74,9.74,0,0,0-4.33.8,4.84,4.84,0,0,0-2.73,3.3,16.64,16.64,0,0,1-.3,2.3c-.25.74-1,1.39-1.76,1.09-1.23-.52-1.5-11.2-1.48-13-1.88-.13-20.08-1.41-20.08-1.38l-1.12,14.8-13.22,1s.25-13.54.33-14.21-31.5,1.57-31.5,1.57l-1.5,90.54-2-1.6-35.11-56.86-7.33,10.78-3,3,21.07,38.54" transform="translate(-53.25 -44.96)"/><path class="cls-11" d="M175.14,629.45a13.91,13.91,0,0,1,6.19,6.09l-.49-13.79a26.83,26.83,0,0,1,8.37,1.08,8.38,8.38,0,0,1-.92,4.7c1.39-.45,2.83.81,3.26,2.21a17.53,17.53,0,0,1,.27,4.36c.07,1.46.59,3.08,1.91,3.71.45.21,1,.29,1.42.49a5.55,5.55,0,0,1,2.35,2.88c2.91,5.91,6.45,12,12.24,15.11a28.83,28.83,0,0,0,8.88,2.75,78.46,78.46,0,0,0,10.7,1.11,9.41,9.41,0,0,1,4.68.93c1.89,1.17,2.62,3.54,3,5.73a62.61,62.61,0,0,1,.5,9.74v15.57c0,2.63-.39,5.87-2.83,6.85s-5.12-1.25-7.11-3.15a92.58,92.58,0,0,0-11-8.45c-7.57-5.3-15-10.82-22.31-16.47-8.51-6.58-16.64-13.72-25.3-20.1-6.14-4.53-9.18-8.39-8.43-16.6.31-3.47,1.82-3.48,5-3.79Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-23" d="M175.14,629.45a13.91,13.91,0,0,1,6.19,6.09l-.49-13.79a26.83,26.83,0,0,1,8.37,1.08,8.38,8.38,0,0,1-.92,4.7c1.39-.45,2.83.81,3.26,2.21a17.53,17.53,0,0,1,.27,4.36c.07,1.46.59,3.08,1.91,3.71.45.21,1,.29,1.42.49a5.55,5.55,0,0,1,2.35,2.88c2.91,5.91,6.45,12,12.24,15.11a28.83,28.83,0,0,0,8.88,2.75,78.46,78.46,0,0,0,10.7,1.11,9.41,9.41,0,0,1,4.68.93c1.89,1.17,2.62,3.54,3,5.73a62.61,62.61,0,0,1,.5,9.74v15.57c0,2.63-.39,5.87-2.83,6.85s-5.12-1.25-7.11-3.15a92.58,92.58,0,0,0-11-8.45c-7.57-5.3-15-10.82-22.31-16.47-8.51-6.58-16.64-13.72-25.3-20.1-6.14-4.53-9.18-8.39-8.43-16.6.31-3.47,1.82-3.48,5-3.79Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-11" d="M560.6,661.45a34,34,0,0,0,27-8c4-3.55,7.13-8,10.2-12.41a101.21,101.21,0,0,0-3,33c5-2.15,10.08-4.38,13.87-8.25a42,42,0,0,0,5.77-8.14,71.54,71.54,0,0,0,6.35-12.44c.93-2.62,1.55-5.34,2.28-8a104.45,104.45,0,0,1,4.87-14,1.57,1.57,0,0,1,.44-.67,1.54,1.54,0,0,1,1-.19,25,25,0,0,1,13.82,5.09c-5.61,4.68-5.11,13.61-9.43,19.5a27.5,27.5,0,0,1-6.13,5.57q-18.32,13.5-37.27,26.11-9.35,6.22-18.84,12.22c-1.75,1.1-6.93,5.66-9,5.23-2.86-.6-1.62-6.71-1.62-8.86S561.4,661.57,560.6,661.45Z" transform="translate(-53.25 -44.96)"/><g class="cls-18"><path class="cls-23" d="M560.6,661.45a34,34,0,0,0,27-8c4-3.55,7.13-8,10.2-12.41a101.21,101.21,0,0,0-3,33c5-2.15,10.08-4.38,13.87-8.25a42,42,0,0,0,5.77-8.14,71.54,71.54,0,0,0,6.35-12.44c.93-2.62,1.55-5.34,2.28-8a104.45,104.45,0,0,1,4.87-14,1.57,1.57,0,0,1,.44-.67,1.54,1.54,0,0,1,1-.19,25,25,0,0,1,13.82,5.09c-5.61,4.68-5.11,13.61-9.43,19.5a27.5,27.5,0,0,1-6.13,5.57q-18.32,13.5-37.27,26.11-9.35,6.22-18.84,12.22c-1.75,1.1-6.93,5.66-9,5.23-2.86-.6-1.62-6.71-1.62-8.86S561.4,661.57,560.6,661.45Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-20" d="M618.76,481.46c-3.58,0-7.92.36-9.5,3.58a9.59,9.59,0,0,0-.68,4.06l-2.13,98.17a180.81,180.81,0,0,0,34.45-.75c-2.21-6.75-2.28-14-2.32-21.09l-.17-28.76a101.28,101.28,0,0,1,.41-12c.47-4.13,1.45-8.2,1.66-12.35.25-4.95-.6-9.85-.78-14.79-.12-3.56,1.07-7.89-.42-11.27C636.27,479.39,624.51,481.52,618.76,481.46Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-18"><path class="cls-23" d="M652.25,544q.42-27.32-.87-54.62c-.13-2.8,0-6.14,2.34-7.64a8,8,0,0,1,4.52-.82l11.28.18a2.46,2.46,0,0,1,3,2.44l1.86,9.92c1.53-.69,1.42-3.21,2.93-3.93a3.4,3.4,0,0,1,1.64-.2A117.76,117.76,0,0,1,694.3,491a1.45,1.45,0,0,1,1.53,1.88l-3.67,40.48a59.81,59.81,0,0,0-.35,9.87c.26,3.51,1.15,6.95,1.53,10.45a48.07,48.07,0,0,1-.17,10.79,10.67,10.67,0,0,1-.59,2.76,12.66,12.66,0,0,1-2.09,3.11,67.57,67.57,0,0,0-10.11,17.14,147.26,147.26,0,0,0-16.07-.7c-3.72,0-9.24,1.46-12.55-.81-2.9-2-2.75-5.51-2.27-8.6.83-5.29,1.67-10.51,2.07-15.86C652,555.68,652.16,549.82,652.25,544Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-21"><path class="cls-22" d="M590.16,587.71c-1.45-5.44-5.88-9.46-9.16-14-5.17-7.2-7.61-16.07-12.71-23.33a50.69,50.69,0,0,1-3.54-5.18c-.9-1.69-1.47-3.54-2.34-5.24-1-2-2.55-4-2.77-6.23a11.73,11.73,0,0,1,1.12-5.19c1.69-4.42,3.58-9.11,7.45-11.83,5.85,6.16,8.57,14.61,13.45,21.56,1.1,1.56,2.3,3,3.44,4.56A135.37,135.37,0,0,1,593.95,557q2.83,5,5.65,10,1.41,2.5,2.8,5c.74,1.34,2.23,3.11,2.42,4.65.31,2.54-3.39,4-5.15,5.19Q595.06,585,590.16,587.71Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-21"><path class="cls-22" d="M639.06,496.73c-1.32,8.89-1.12,17.92-.91,26.91l.18,7.91c.31,13.59.63,27.17.85,40.76a79.15,79.15,0,0,1-.68,14.6l11.23-1.48q1.41-23.59,1.67-47.24c.07-6.84.07-13.68.08-20.52v-8.08c0-2.4,0-4.79-.09-7.19-.06-1.61.23-4.24-.84-5.61S639.17,496,639.06,496.73Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M709.39,497.13a.65.65,0,0,0-.78.67l-3.88,25.33c-1,6.83-2.1,13.74-1.52,20.62,4.23-4.28,5.51-10.58,8.36-15.89,1.36-2.54,3.1-4.87,4.28-7.5a39.23,39.23,0,0,0,2.33-8.3c.85-4.17,2.49-9.42,1.85-13.69-.32-2.18-1.46-1.82-3.46-1.69Z" transform="translate(-53.25 -44.96)"/></g></g><g id="SHADOWS"><g class="cls-3"><path d="M195.5,131.62a9.1,9.1,0,0,1,1.78-.56c1.88,5.23-1.12,12.48-1,17.92,0,2.32,0,5.88,1.86,7.58,1.14,1,9.58,1.63,9.52.49.08,1.56.55,3,.34,4.57-.22,1.73-20.35,1.31-22.15,1.31-8.71,0-17.42-.5-26.11-1,3.56-4,9-6.43,12.87-10.29s7.75-7.42,12-10.9C187.92,138,191.39,133.38,195.5,131.62Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M233.33,106.67c-4.37,13.39-11.53,28.24-11.67,42.65-.05,5.33,2.52,6.93,7,9.08,2.48,1.19,8.63,1.47,10,3.51-4.31,2.79-12.76,2.12-17.7,1.1-4.15-.86-8-4.47-10.78-7.51s-.25-5.88.83-9.55c1.74-5.89,3.26-11.78,4.7-17.72,1-4.22,1.49-8.33,2.22-12.58.93-5.4,4-3.06,7.43-6.65" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M262,93c-2.62,0-7.35,3.44-9.67,4.91-3.2,2-3,3.17-2.66,6.69.68,6.61.65,13.22,1,19.9s0,13.5.67,20.1c.29,3.06-1.11,13,1,15.16s12,.57,14.7.57c3.7,0,7.67.38,11.27-.38-.22-1.64-1.85-2.85-2.55-4.59-1.52-3.79-1.51-8.84-2.07-12.86-1.12-8-1.22-16.34-1.59-24.43-.48-10.46.65-21.92,5.58-31.34C272.13,86.33,264.71,90.07,262,93Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M304,79c-3.21-.27-8.87.83-9.68,3.83s.68,8.29.68,11.55c0,4,.2,8,0,12-.64,12.68,0,25.56,0,38.33,0,5.29.1,10.39.38,15.62,4.34,1.18,14.61,1.76,18.85,0-5-2.95-3.89-15.79-4.32-20.87a195.5,195.5,0,0,1-.24-34.41c.56-6.13,1.47-12.29,2.42-18.34.63-4,2.24-8.05,2.57-11.94C311.49,74.47,308.31,76.81,304,79Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M342,68c-3.19.65-10.42,2.59-11.68,5.82-.76,2-.06,6,0,8.1.15,4.29.67,8.41.67,12.73,0,16-1.35,31.81-.67,47.78.28,6.5,1.09,13,1.38,19.53,4.08.45,7.68-1.32,11.59-2-.44-3.71-2.43-7.78-3.13-11.62-1.12-6.14-2.19-12.25-3.09-18.43-1.37-9.37-2.94-20.47-1.69-30,.86-6.51,2.87-12.88,3.45-19.48C339.09,77.63,338.34,71.23,342,68Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M370,63.33c-7,2.77-7.27,13.38-8.07,19.65-1.33,10.37-1.73,20.93-2.27,31.35-.48,9.22,1.67,18.62,3,27.67.83,5.76,1.76,11.21,4.36,16.49,1.79,3.63,1.95,4-2.45,4.17a28.73,28.73,0,0,1-9.16-1.05,575.68,575.68,0,0,1-.73-57.6c.35-8.3,1-16.73,1-25,0-5.52-1.65-12.88,5.33-14" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M397.67,92.67c2.19-.29,12.81-1,14.36,2,.74,1.42-1.14,6.2-1.37,7.76a91.87,91.87,0,0,0-1,12.33c-.16,16.12-.36,32.61-.72,48.54a85.48,85.48,0,0,1-8.57.33c-1.1-11.42-2.39-22.9-3.54-34.4a200.38,200.38,0,0,1-.84-20.12C396,104,397,98.7,397.67,92.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M395.33,130c0,9.54.06,26.48-7,33.92,1.68.68,3.76.46,5.58.37.61-8.25,1-16.67,1.38-24.95" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M444.67,77.33c-5-2.72-3.47,6.66-3.33,8.67.51,7.82.67,15.62.67,23.49,0,8.92.86,17.62,1.36,26.49.36,6.51.46,13.41,1.72,19.83.92,4.69,2.4,7.41,7.87,5.81,1.4-27.34-1.36-55,.38-82.3.21-3.23,1-2.17,2.27-4.4s.27-5,3.75-3.58c4.71,1.88,2.08,14.17,2,17.9-.41,12.3-1.71,24.59-2.23,36.88-.36,8.41-.85,17.68.59,26,.47,2.71,1,9.7,3.75,10.56-6.92-.24-16.09,3.53-22.72.95-.53-16.33-.92-32.79-1-49.17-.05-7.63-.93-15.23-1-22.85C438.63,87.94,437,78.35,444.67,77.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M477,75.67c1.36,2.46,4.09,3.8,5.93,5.91a54.56,54.56,0,0,1,6.25,9.25c4,7.16,7.92,14.39,12.17,21.53,4,6.8,6.95,14.19,10.73,21.13,3,5.58,6.67,9,11.52,12.77s7.41,5.84,13.63,5.73c-5,2.14-8.6,5.62-12.87,8.1-4.58-5.69-8.66-11.58-13-17.43-5.78-7.75-9.34-16.33-14.67-24.34S487.59,101.63,483.33,93c-1.7-3.46-3.87-6.54-4.91-10.28C477.85,80.64,477,71.8,477,75.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M540.67,97c-1.83,6.16-.33,14.59-.33,21,0,6.6,0,13.18-.33,19.73-.24,5.5-.08,11.05-.33,16.51-.24,5.12-1,7.1,4.45,7.09h16.11c-14.28-.76-10.06-20.28-10.59-30.34-.45-8.45.63-16.6.7-25,0-1.21.78-6.42,0-7.37-.89-1.11-2.88-.63-4.36-.64" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M585.33,121.67c-2.71,5.44-.34,16.3-.65,22.68-.26,5.42-1.19,11.08-1.63,16.27,3,.44,7.33-1.1,9.72,0-3.49-5.92-1.46-16.87-1.44-23.48C591.34,134.45,592.46,123.68,585.33,121.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M574.42,211.81c-.24,3.17.63,7,.71,10.31.23,8.73.76,17.45,1.44,26.16,1.35,17.26,3.31,34.47,4.74,51.72.26,3.13,1,2.78-2.46,3.49a30.27,30.27,0,0,1-7.12.47c-1-2.36-.41-5.56-.4-8.06,0-4.31-.52-8.54-.67-12.83-.34-10.21-.32-20.39-.74-30.58-.53-12.83-1.07-25.66-1.2-38.5,0-2.95-.13-11.65,5-10.85C578.63,203.9,574.61,209.27,574.42,211.81Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M531,215.67c3.23-3,8.55-3.56,12.62-4.29-.6,2.26-3.63,4-4.79,6.32-1.31,2.59-1.67,5.95-1.85,8.8-.51,8.39,1.44,16.92,2.85,25.13a303.37,303.37,0,0,0,8.52,34.9c.88,3,1.46,6,2.15,9,.28,1.19,1.64,4,1.59,5.09-.2,4-7.44,3.47-10.71,2.35-.36-6.51-2.73-12.28-4.55-18.54-2.31-8-3.21-16.3-4.09-24.53A223.9,223.9,0,0,1,531.33,236C531.34,229.67,530.38,223.27,531,215.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M628.67,194.67c-1.84-.19-5.55-1.18-7.33-.33-2.42,1.15-1.84,4.47-2.58,7.24-2.05,7.69-5.47,14.8-7.18,22.58-2.26,10.3-6.18,21-10.18,30.77-3.78,9.18-5.74,18.87-9.16,28.16-.87,2.38-4.17,7.24-3.83,9.65.45,3.19,5.93,5,8.52,6.57.42-4.8,0-9.18,1.23-13.95,1.14-4.28,2.27-8.6,3.52-12.86,3.23-11,6.07-22.28,8.48-33.52,1.86-8.7,5.69-17.17,9.19-25.34a63.77,63.77,0,0,0,3.74-9.92C623.66,201.41,623.59,199.54,628.67,194.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M647.67,201.67c-3.32-.28-11.86,3-13,6s.35,8.4.34,11.37c0,4.54-.15,9.13,0,13.67.29,8.56,1.29,17.08,1.67,25.64.33,7.58-.28,15.09.69,22.59.83,6.47,1,12.79,1.36,19.36,2.48.14,5,0,7.51.08-3.78-6.92-2.88-15.86-3.3-23.51-.66-12-.2-23.8-.25-35.77,0-8.69,1.8-17.22,2.17-25.88C645,210.87,646.82,206.06,647.67,201.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M665.33,194c-1.33,0-5.61.45-6.5,1.36-1.38,1.41-.4,6.65-.5,8.64-.4,8.11-1.32,16.31-1.67,24.47-.46,10.71-.54,22,0,32.7.41,8,2.29,15.71,2.67,23.73.19,4.15.3,8.26.33,12.45,0,1.92-.38,3.07,1,4,1.7,1.14,5.48.21,7.33,0,.12-9.45-2.16-20-3.3-29.44a189,189,0,0,1-1.69-29.5C663.49,227.72,666.67,213.23,665.33,194Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M692.33,233c-1,2.21-.24,6.22-.33,8.91-.16,4.61-.33,9.2-.33,13.84,0,6.58.38,13,.67,19.59.39,8.88,1.53,18.17,1.38,26.95,2.28.28,5.82.26,7-1.88,1-1.76-.16-5.48-.34-7.45-.43-4.61-.56-9.28-.72-13.9-.48-14-2.27-26.92-6.36-40.06" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M526.33,221.67c-3.89.57-8.66-.66-9.67,3.83-1.47,6.54,0,15,0,21.75,0,13,.66,25.67,1.33,38.39.31,5.86.11,11.76.38,17.64,3.28.48,6.2,1.43,7.62-1.78,1.06-2.41.23-6.1.33-8.76.17-4.89.31-9.82.68-14.7.8-10.38.32-21,.32-31.38C527.33,238.63,528.54,230.67,526.33,221.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M483.33,210a37.06,37.06,0,0,0-7.67.67c-3.15.66-2.88.1-3,3.65-.29,8.35-.33,16.65-.33,25,0,18.61-.15,37.75,1.66,56.18.77,7.88,5,8.82,12.63,8.44.52-7.8-.95-15.76-.95-23.62,0-9.13-.9-18.22-.5-27.33.31-7.11.5-14.17.5-21.32C485.67,226,487,217.38,483.33,210Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M494,195.67c-2.1-.07-6.24-.32-8,.74-2.8,1.69-1.37,5.65-1.65,8.68-.95,10.14-1.34,20-1.35,30.3,0,10.72.47,21.62,1,32.36.39,8.3.2,17,1,25.24.24,2.46-.07,8,1.33,10,1.91,2.75,6.2,1.28,9.29,1.28.09-2-.74-4-1-6-.83-5.58,0-11.42-.24-17-.38-11.2-.59-22.43-1-33.64C492.75,231.11,492.33,214.57,494,195.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M452,196.33c2.4,0,4.72-.21,6.95.73.46,21.53,1.05,43.38,1.05,65a251,251,0,0,0,1.65,30.56c.48,3.91,2.7,7.64,2.65,11.31-4.41-1.21-9.25.28-13.76,0-5-.27-5.46-.68-6.18-6.19-3.5-26.94-2.84-55.33.13-82.29.36-3.27,1-8.47,3.16-10.53.54-.5,1.93,0,2.66-.87S450.72,199.14,452,196.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M432,205.67c-1.42,0-2.87,0-4.28.06-1.38,2.56-.38,5.48-.38,8.26,0,5.78-1.35,11.52-1.34,17.37,0,13.53,0,27.06,0,40.59,0,4.88.31,10-.35,14.72-.28,2-1.2,4.31-.62,6.16.67,2.15,4.28,5.2,6.3,5.86,5.7,1.87,3.33-8.73,3.33-12.45,0-16.32-.7-32.53-1.5-48.82-.29-6-.85-11.93-.84-17.91C432.34,217.1,431.2,210.4,432,205.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M398.67,205c-3.11,0-10.57-1.34-13,1-1.68,1.61-.67,4.58-.68,7,0,4.23-.54,8.43-.34,12.65.77,16.7,1.85,33.33,1,50.11-.22,4.31-1,8.57-1.34,12.89-.25,3.2.17,6.9-.62,9.94,3.37,1.06,8,.54,11.52.35.49-2.72-.44-5.82-.66-8.6-.43-5.39-.57-10.8-.57-16.21q0-18.08,0-36.17C394,229.47,392.47,212.61,398.67,205Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M359.67,234.67c-1.46-2-10.7-.75-13.62-.28-.55,6.36.72,13.4.95,19.84.26,7.24.33,14.55.33,21.77,0,6.18-.09,12.28-.67,18.36-.12,1.22-1.08,5.63-.35,6.65,1.24,1.75,7.24.65,9.31.28.73-14,.07-28.15,0-42.14,0-5.19-.4-11.29.53-16.39C356.77,239.56,359.33,236.91,359.67,234.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M331.33,218.33c-6.24,0-8.58-.37-8.33,6,.33,8.74-1.14,17.64-1,26.35.12,7.88,1,15.72,1,23.7,0,6-.3,12.18,0,18.22.24,4.9-.34,9.59,5.94,9.37,1.78-6.4-.67-13.62-1-20.07-.44-9.73,0-19.6,0-29.33C328,241.52,331.3,230.49,331.33,218.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M321.33,186.67c-3.29-.81-8-.77-9,2.65-.74,2.42-.31,6-.67,8.59-.44,3.15-1.17,6.33-1.63,9.43-1.3,8.61.3,17.31.3,25.9,0,7.3.61,14.34,1,21.51.37,6.65-.72,13.16-1,19.73s-.33,13.45-.33,20.2c0,1.72-.74,5.42.29,6.83,1.37,1.86,6.5,1.63,8.78,1.15,4.08-.85,3.45-3.94,3.6-8.23.26-7.39.57-14.83.34-22.24-.49-15.74-.84-31.38-.68-47.15.11-11,2.92-22,.33-32.71" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M304.33,217.33a92.36,92.36,0,0,0-6,11.5c-1.54,3.22-3.78,5-5.84,7.89-5,7-8,15.28-13.14,22.28-4.32,5.93-7.89,12.32-12.5,18.19-3.65,4.64-6.94,9.67-11.15,13.8-.93.91-3.52,4.08-5,4-2.07-.06-4-3.81-4-5.49-.14-6.73,6.26-16.49,9.44-22.28,4-7.24,9.45-14.14,14.59-20.59,4.58-5.75,8.7-12.32,14.17-17.21,4.53-4,7.22-8,10.65-13,1.7-2.44,8-6.83,8.12-9.86.08-2.19-4.94-4.82-7.1-4.33s-3.49,4.25-4.66,5.88c-2.09,2.91-4.44,5.69-6.27,8.78-3.81,6.44-7.24,12.82-11.48,19-5.11,7.48-9.09,15.64-14.41,23.07-4.55,6.36-8.29,13.29-13,19.56-2.41,3.2-7.78,9.79-6,14.11,1.27,3,7.08,3.83,9.58,5.88,1.33,1.09,2.47,2.43,3.69,3.4,6.88-7.71,11.65-17.81,19-25" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M224.67,196.67a131.28,131.28,0,0,0-15.57,1c-5.35.63-4.29,3.57-4.09,8.74.67,17.21,1.66,34.69,1.67,51.92,0,11.92-.82,24.36.93,36.08.64,4.29,1.62,6.22,6.46,5.67,1.47-.17,7.39-.15,8.4-1.27,2-2.23-1-11.85-1.14-14.49-.7-18.28,1.25-36.57.28-54.82-.37-7-1.11-14.28-.93-21.31a22.61,22.61,0,0,1,.91-7.21C222.27,199.15,223.54,198.12,224.67,196.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M204.67,210.33c-3,.68-5.94.87-8.95,1.72.25,4-1.05,8.5-1.4,12.53a101,101,0,0,0-.06,17.16c1,11.86-.71,23.56-.26,35.41.18,4.85.8,9.5,1.41,14.25.29,2.26.56,9.72,2.33,11.18s8.62-.51,9.85-1.94c1.48-1.72.93-5.91,1-8,.2-5.19.55-10.38.75-15.56a279.22,279.22,0,0,0-.76-35.67c-.48-5.5-1.74-10.92-1.92-16.43A87.3,87.3,0,0,0,204.67,210.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M185.67,195.67c-2.38,0-8.11-1-10,.32s-1.34,5-1.34,7.34c0,10.89-.33,21.8-.33,32.73,0,18.1,1.33,36.31,1.33,54.35,0,2.37-1,7.67.16,9.76,1.37,2.51,5.08,1.92,7.79,1.78.52-7.72-1.84-15.65-2-23.42-.19-11.48-.31-23-.73-34.44-.35-9.54-.47-18.89.92-28.34C182.24,210.8,184.9,204.63,185.67,195.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M161.33,202.33c-2.42-.07-9.24.23-10.69,2.65-1,1.73.93,9.94,1,12.26.51,13.18,1.67,26.27,1.67,39.58v36.76c0,2.48-.7,7.64,1.64,8.77.91.43,5.06-.29,5.62-1.07,1.66-2.3.07-12.48.07-15,0-17-.33-34-.33-51C160.33,224.91,157.87,213.86,161.33,202.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M129.67,209.67c-11.07-.29-20.32,5.41-18,17.23.75,3.74,2.64,7.41,3.45,11.25.94,4.42,1.24,8.94,2,13.38,1.5,8.85,2.42,17.72,3.83,26.59,1.18,7.45,3.44,16,3.05,23.5,7.14.39,14.55-.13,20.89-3.56-5.07-.36-9-.75-11.13-6.22-3.46-9.12-5.27-20-6.91-29.56-1.86-10.93-3.85-22.35-3.91-33.45C123,222.64,123.32,215.83,129.67,209.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M105,235c-1,3-.51,6.79-1.07,10a90.56,90.56,0,0,0-1.59,13c-.22,6.91,0,13.77-.33,20.67-.4,8-1,15.94-1.39,24-4.41-1.19-7.16,1.32-8.12-4.31-1.19-7-.42-14.47-.76-21.56-.31-6.45-.06-13-.07-19.41,0-3,.08-5.07,1.4-7.72,1.8-3.62,6-6.42,6.93-10.29" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M97.67,328.33c-4.84.56-4.93,4.53-3.92,8.42.89,3.4,3.12,11.19,6.39,13.1,4.42,2.58,8.26-5.29,10.2-8.39a69.68,69.68,0,0,1,8.63-10.7C113.45,327.11,107,327.33,97.67,328.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M201.66,327.34c-8.3.17-16.71-.55-25,.4-7.92.91-15.71,1.69-23.71,1.27-3.21-.17-6.47-.67-9.67-1-2.61-.28-5.72-1.67-8.29-1.37-5.43.63-12,7.74-17,10.31-3,1.53-12.82,4.75-13,9.15-.15,3.57,7.23.11,9.47-.26a71.05,71.05,0,0,1,16.35-.77c3.2.23,7.35.74,10.31,2,3.36,1.47,5.74,4.51,9.24,7.23-.28-3.45-6.64-9.29-5.36-11.76.67-1.29,7-2.82,8.27-3.18,4.36-1.22,9-2,13.45-2.91,8-1.71,15.59-.78,23.63-.32,3.63.21,10.17-.89,11.6,3.7,1.07,3.43-2.31,7.72-3.51,10.73-4.75,11.87-6.4,25.23-2.84,37.65,2.22,7.75,3.75,17.79,10.43,23a45,45,0,0,0,11.3,6.37c-1.4-2.58-4.66-4.33-6.64-6.59a24.09,24.09,0,0,1-5-9.54c-1.12-4.88.52-6.58,4.35-8.5-5.9-2.91-5.52-9.35-4.81-15.68,1-9,4.46-16.78,11.4-22.66,6.07-5.15,13.17-6.94,21-7.34,4.56-.23,7.89,1,12,1.63-2.63-2-2.58-3.06-4-6.36-.71-1.7-2.5-3.34-3-5.06-.52-1.93,1-3.85.55-5.9-4.72-1.35-4.94,1.38-8.09,2.85s-9.28-5.14-12.28-6.35C216.12,325.39,208.74,327.2,201.66,327.34Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M172.33,393c-10.71.93,1.19,11.2,5.88,12.37C174.46,403.8,167.71,393.12,172.33,393Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M174,405c-5.19,1.15-15.55,10.63-6.77,14-3.23,2.42-8.22-2.7-8.87-5.81-1.19-5.64,5.41-9.42,9-12.19" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M174,418c-6.44.18,2.56,13.07,2.28,14.62-7.62.81-24.82-12.92-17.59-21.51-.18,4.11,1.55,8.35,6.07,8.23C167.58,419.26,169.93,417.64,174,418Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M140.67,416.67c-6,2.29-11.74,5.45-17.93,7.59-4.49,1.55-10.5,3.34-14,6.75-2.22,2.17-3.12,5.71-3.4,8.82-.37,4.06,1,6-3.9,6.48-4.45.46-9.54-.13-14.06-.35.71-4.08.7-7.92,1.88-12a64.87,64.87,0,0,0,2.38-12.07c.68-7.46.58-16-1.05-23.26-1.69-7.51-3.93-13.69-3.59-21.65a32.08,32.08,0,0,1,9.61-21.54c7.09-6.64,18.12-10.21,27.72-7.67-1.85,1.82-4.85,2.58-7.22,3.74a30.13,30.13,0,0,0-10.22,8.11,50.51,50.51,0,0,0-9,18.41c-2.18,9-.07,19.94,6.85,26.39,7.58,7.07,18.77,16.22,30,13" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M81.67,522.67c2-4.66,2.61-10.29,3.92-15.26.71-2.68.47-10.63,2.9-12.22,1.75-1.15,10.47.82,11.83,2.48,1.85,2.26-1.93,4.92-2.74,8.09-1.26,5-1,10.52-1.25,15.6-.53,10.79-1,21.55-1.71,32.29-3.41-.53-7.47-13.76-8.76-16.65C83.9,532.61,80.57,526.58,81.67,522.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M124,509.33a9.09,9.09,0,0,0-8.34,1.75c-2.73,2.55-1.36,6-1.33,9.57.11,12.64,2,25.14,2,37.84a163,163,0,0,1-1,16.58c-.22,2.19-2.41,9.69-.94,11.52,1.17,1.45,8,1.34,9.61,0s1-4.36,1-6.56c0-5.42,1-11.13,1.66-16.54,1.33-11-.53-20.62-1.33-31.42a120.43,120.43,0,0,1-.34-13.78C125.15,514.52,126.43,508.82,124,509.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M142.67,480.67c-6,0-10.22-2.33-13.8,3.17-4.47,6.85-3.2,13.41-3.2,20.92,0,10,1.34,19.82.15,29.76-1.08,9.05.94,18.14-.56,27.13a118.71,118.71,0,0,0-1.21,25c4.23.22,8.55.05,12.8.05,3.15,0,6.39,1.06,9.43.61.23-4.22-4.32-8.19-5.36-12.24-1.32-5.14-1.56-10.38-1.92-15.67-.82-12.37-1.68-24.82-1.67-37.22,0-8.39-.7-16.42,3-24.17,2-4.09,6.15-8.91,4.66-14.64-4.72-.09-12.36.92-16.54,3.33-3.06,1.76-3.41,6.25-3.23,10.64" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M156.31,497.08c-1.62,1.43-1.32,2.42-1.31,4.66a183.3,183.3,0,0,0,1.67,21.63c1.78,14.67.33,29.79.33,44.55,0,6.58.35,13.15.72,19.7,3.52.4,14.68,3.46,17-.62,1.08-1.94.07-7.95,0-10.15-.23-4.82-.3-9.63-.3-14.48,0-13.42.72-26.75.67-40.16,0-9.37-1-19.18.33-28.47.56-3.86,1.9-8.3,1.63-12-2.42-.36-5.44.18-7.91.34-1.42,4.4-.88,9.59-1.1,14.22C168,496.25,157.49,496,156.31,497.08Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M196.67,489c-5.26-.25-5,5.59-5,9.33A223.63,223.63,0,0,0,193.34,523c1.84,15.29,1.32,30.9,1.32,46.32,0,5.81.07,11.55.38,17.31,1.47.09,7.26.85,8,.07,1.51-1.49-.07-8.36-.1-10.43-.08-7-.27-13.71-.81-20.65-1.15-14.84-.62-29.9-1.36-44.78-.36-7.26-.31-14.53-.53-21.78C200,489,199.66,488.94,196.67,489Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M220.33,492.33a14.91,14.91,0,0,0-4.29.38c-1.48,5.41,0,12.72.3,18.34.54,9.27.33,18.84.33,28.12,0,7.85.69,15.5.67,23.35,0,4.71,1.57,9.19,1.39,13.77,2.49-.75,11.84-3.8,12.63-6.78.58-2.18-2.41-6.65-2.78-8.95a27.8,27.8,0,0,1,.69-10.8,188.87,188.87,0,0,0,3.38-23.91c.57-6.48.49-13.79-1.88-19.85C229.52,502.83,225.86,490.53,220.33,492.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M160.33,645c-.82-2.4-1.62-10.72-.67-13,1.16-2.8,7.83-3.39,10.69-3.65,3.49-.32,5.62-.25,6.63,3,1.7,5.43.2,12.35,2.11,17.54a106.73,106.73,0,0,0,2.17-19.13c.14-3.27-.79-7.39,3.76-7.08,3,.2,2.5,1.61,3.91,3.67s3.28,3.35,3.74,6.69c.24,1.71-.52,4.12,1,5.41.94.81,2.71,0,3.77.88,2.09,1.71,3.62,8.86,4.51,11.37.44,1.23.07,2.82,1.05,3.68.48.42,3.68,1.09,4.68,1.65,5,2.81,9.48,2.69,15,3.91,6,1.32,11.72.52,12.38,7.72,1,10.3.88,20.9,1,31.24-3.88,1-9.37-2.15-12.9-3.58a85.82,85.82,0,0,1-23.71-15.06c-7.29-6.57-15.24-12.41-22.31-19.17C171.48,655.7,162.74,652,160.33,645Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M561.67,527.33c6.45,4.84,10.16,17,14.33,24.36,3.09,5.46,7.2,10.27,10.17,15.77,2.22,4.11,3.95,8.67,6.42,12.61.77,1.23,2.09,2.32,1.86,3.68-.19,1.15-3.74,4-4.72,4.22-.81-4.32-5.64-8.81-7.86-12.75q-6.05-10.78-12.37-21.38c-2.41-4-5.84-7.35-8.5-11.16C557.33,537.41,558.72,531.81,561.67,527.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M626,481.33c-3.63-.26-7.16,1-10.74,1.34-2,.2-6.08-.33-7.28,1.64s-.12,8.15-.33,10.35a84.26,84.26,0,0,0-.06,15.64c2.07,21.74,1.16,43.75.15,65.53-.1,2.17-1.42,11.59.33,13.1,1.26,1.1,5.54-.4,6.95-.53,2.63-.24,5.32,0,7.95-.1-.88-7.6-2.87-15.28-3.7-23a311.87,311.87,0,0,1-1.6-36.37c.16-15.13,6.53-29.9,6-44.84a2,2,0,0,0-1.63.25" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M648.33,496c-3.37-.09-8.79,1.66-9.68,4.67-1.58,5.33.08,13.48,0,19-.16,13.34-.92,26.72-.26,40.11.3,6.11.63,12.28.93,18.38.25,4.94-1.55,9.27,4.26,9.47,3.07.11,10,1.24,12.73-.24,3-1.64,1.58-6,1.33-9.09-.53-6.93-.33-13.91-.33-20.87,0-16.13-1.18-32.22-.5-48.36.39-9.15,2.24-18.61,1.82-27.72-6.1-.69-7.45,1-8.08,6.31C650.29,490.07,650.29,496.06,648.33,496Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M688.67,489.67c-3.68,0-9-.62-11.58,2.33-3.78,4.38-3.08,13.19-3.08,18.39,0,19.23,4.62,37.9,4.67,57,0,6.94-2.44,14-2,20.87,7.27-1.84,7.85-2.67,8-10.6.19-13.45.68-26.83.68-40.33C685.33,521.17,683.62,505,688.67,489.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M716,497.33c-1,.19-6.34-.36-7.59,1.06-1.92,2.18-1.45,10.76-1.58,13.55-.46,10.06-1.54,19.74-2.86,29.64,4.72-8.76,6.72-20.48,8-30.22C712.61,506.83,712.71,500,716,497.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M621,654.67c3.15-2.21,3.35-6.94,4.58-10.42.93-2.66,2.33-5.19,3.17-7.91,1.28-4.11,4.28-10.25,3.53-14.62a5.33,5.33,0,0,1-3.88-1C625.23,631.09,619,642.5,621,654.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M596.33,646.67c.27,7.17-1.33,14.41-1.33,21.67,0,3.86.14,7.77-.05,11.61-5.35,1.56-9.95,6.33-14.93,8.73-6.16,3-12.76,6.71-19.29,8.63-.46-3,1.06-6.79,1.36-9.89.41-4.19-.06-8.45.57-12.6a60.35,60.35,0,0,0,1-9c0-1.16-.62-5.13.18-6s4.92.09,6.22-.16c3.48-.68,7.05-2.65,10.31-4A98.74,98.74,0,0,0,596.33,646.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M559,329.67a26.61,26.61,0,0,0,7.93-.92c2.35-.48,5.38-2.11,7.61-.43s.28,4.68,3.46,4.94c1.13.09,2.32-1.42,3.25-1.86a35.56,35.56,0,0,1,6.27-2,56.92,56.92,0,0,1,11.82-1.82c12.22-.57,24.58-1.11,36.85-.6,7.21.3,14.41.77,21.63,1a81.75,81.75,0,0,1,9.48,1c4,.58,7.77-.35,11.69.95,3.59,1.19,7.17,2.48,10.68,3.85,1.29.5,3.63,1.78,5,1.5,1.77-.37,2.68-2.29,4.25-3.53,3.3-2.63,9.2-5.13,13.14-2.74-2.2,2-7.7,3.94-8.4,7.19-.95,4.42,3.54,1.36,6.3,1.87.3,1.76-.64,2.86-1.12,4.45-.79,2.56-.13,2.65.17,4.41.2,1.19,1.08,3.68-1.15,4.71-1.67.77-5.39-.72-5.57-2.56-5.18-1.77-11.27.25-15.92,2.59-10.72,5.41-19,10.13-23.71,21.77-6.06,15-4.17,29.79,8.29,40.53-8,.69-15.79-9.3-18.62-15.7a58,58,0,0,1-5.32-23.4c0-7.37,1.91-13.16,4.34-20,2.88-8.09-6.68-7.32-12.73-8.29-7.47-1.19-15.71-2.17-23.29-1.59-6.62.5-5.45,3.86-6,9.62-2.48,0-7.08-5.42-9.6-6.71-4.34-2.23-8.72-2.25-13.54-2.23-9.16,0-17.18,3.75-26,5,.42-3.09-3.08-2.5-4.9-4-3.36-2.69-3-7.84-2.71-11.67C552.92,329.22,553.6,329.16,559,329.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M598.33,348c-5.19-3.16-14.84-.6-20.35.75a28.59,28.59,0,0,0-16.62,10.55c-11,13.86-9.22,29.22-2.85,44.93,1.77,4.36,3.45,9.3,7.14,12.44,2.39,2,5.28,3.15,7.9,4.68-8.89.42-13.19-4.78-17.64-11.51-5.06-7.65-9.3-15.47-9.57-25a38.42,38.42,0,0,1,6.3-22.13,40.56,40.56,0,0,1,6.69-8.66c4.54-4.14,10.7-4.61,16-7.06" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M636.67,393c-4.08-.48-8.65,3.33-7.27,7.68,1,3.21,5.65,4.8,8.23,6.41-5.39,3.38-10.56,3.18-11.58,10.54,2.29,0,4.53.32,6.91.43-.41,2.87-1.68,5.68-.54,8.61.76,1.95,2.72,3.29,4,5-3,3.74-11-.55-14.14-2.42-3.58-2.09-2.09-2.47-3.54-5.58-1.08-2.32-3.8-2.65-5.23-4.9-2.1-3.31-1.3-8,.19-11.34,1.86-4.21,4.22-4.74,7.39-7.42,1.34-1.13,1.64-2.76,2.79-3.85,1.6-1.51,4.07-1.52,6.17-2.14" transform="translate(-53.25 -44.96)"/></g></g><g id="DETAILS"><path class="cls-24" d="M636.33,431.17a1.5,1.5,0,0,1-1.46-1.14c-.77-3.17-.62-6.77-.48-10.25.05-1.32.11-2.57.11-3.77a1.5,1.5,0,0,1,3,0c0,1.26-.05,2.6-.11,3.89-.13,3.28-.27,6.67.4,9.42a1.5,1.5,0,0,1-1.46,1.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M177.34,430.83h-.21a1.5,1.5,0,0,1-1.28-1.69,37.15,37.15,0,0,0-.09-7.5c-.13-1.65-.26-3.35-.26-5a1.5,1.5,0,0,1,3,0c0,1.5.12,3.07.25,4.73a39.23,39.23,0,0,1,.07,8.14A1.5,1.5,0,0,1,177.34,430.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M569,342.17a1.5,1.5,0,0,1-.73-.19c-.63-.35-1.23-.71-1.83-1.07-2.38-1.43-4.43-2.67-7.31-2.41a1.5,1.5,0,1,1-.27-3c3.84-.34,6.53,1.27,9.12,2.83.57.34,1.14.69,1.74,1a1.5,1.5,0,0,1-.73,2.81Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M569,341.5a1.5,1.5,0,0,1-1.42-1,17.5,17.5,0,0,1-.48-6.45c0-.7.07-1.39.07-2a1.5,1.5,0,0,1,3,0c0,.7,0,1.44-.07,2.19a15.14,15.14,0,0,0,.32,5.32,1.5,1.5,0,0,1-1.42,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M700.66,342.78a1.44,1.44,0,0,1-.71-.18,1.46,1.46,0,0,1-.59-2l0-.08c1.39-2.46,3.29-5.84,3.43-8.59a1.5,1.5,0,0,1,3,.15c-.18,3.46-2.28,7.19-3.81,9.91A1.58,1.58,0,0,1,700.66,342.78Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M701,343.83a1.5,1.5,0,0,1-.85-2.74,24.7,24.7,0,0,1,9.93-3.58,1.5,1.5,0,0,1,.5,3,21.84,21.84,0,0,0-8.74,3.09A1.49,1.49,0,0,1,701,343.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M242.33,343.5a1.5,1.5,0,0,1-1.32-2.21l.54-1c1.08-1.95,2.57-4.61,3-6.9a1.5,1.5,0,1,1,3,.52c-.49,2.79-2.11,5.71-3.3,7.84l-.52.95A1.5,1.5,0,0,1,242.33,343.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M243.26,342.84l-.4,0a1.5,1.5,0,1,1,.28-3,28.1,28.1,0,0,0,6.41-1.27,1.5,1.5,0,0,1,.9,2.86A32.77,32.77,0,0,1,243.26,342.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.33,344.17a1.5,1.5,0,0,1-1.41-1c-.71-1.92-4.84-5.23-6.7-5.36a1.5,1.5,0,0,1,.21-3c3.27.23,8.26,4.49,9.3,7.31a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M109.67,343.5a1.5,1.5,0,0,1-1.38-.9c-1-2.2-1.91-9.32.22-11.89a1.5,1.5,0,1,1,2.31,1.91c-1,1.17-.69,6.68.22,8.78a1.5,1.5,0,0,1-1.37,2.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.83,217.59c-3.24,0-6.29-.39-8.5-1.78a1.25,1.25,0,0,1,1.33-2.11c3,1.87,8.76,1.43,13.43,1.07,1.78-.14,3.47-.26,4.9-.26,3.17,0,6.77-.09,9.56-1.17a1.25,1.25,0,0,1,.9,2.33C234.27,216.9,230.38,217,227,217c-1.33,0-3,.12-4.71.26C220.18,217.42,218,217.59,215.83,217.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.7,222.35c-3.13,0-6.2-.35-8.59-1.77a1.25,1.25,0,1,1,1.28-2.15c3,1.77,7.8,1.49,12,1.24,1.43-.08,2.77-.16,4-.16.82,0,1.7,0,2.59.06,2.9.1,5.89.21,8-.71a1.25,1.25,0,1,1,1,2.29c-2.61,1.14-6,1-9.06.92-.86,0-1.71-.06-2.5-.06-1.15,0-2.47.08-3.86.16C219,222.25,217.34,222.35,215.7,222.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M220.25,211.33c-1.06,0-2.08-.74-3-2.2-1.12-1.69-1.28-6.22.52-7.53.38-.27,1.73-1,3.25.87A1.25,1.25,0,0,1,219,204a7.39,7.39,0,0,0,0,3,1.25,1.25,0,0,1,.73-.95,4.58,4.58,0,0,1,2.71-.3,1.25,1.25,0,0,1,1,1.47c-.59,3-1.82,3.82-2.75,4A2.33,2.33,0,0,1,220.25,211.33Zm-.47-2.92a1.84,1.84,0,0,0,.45.39,1.47,1.47,0,0,0,.22-.32A1.26,1.26,0,0,1,219.78,208.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M226.3,210.34a3.82,3.82,0,0,1-1-.15,2.84,2.84,0,0,1-2-2,8.61,8.61,0,0,1,1.22-6.48,3.12,3.12,0,0,0,1.05-.76,1.25,1.25,0,0,1,1.72.41c.31.5,2.64,5.81,1,8A2.38,2.38,0,0,1,226.3,210.34Zm-.38-5.79a5.77,5.77,0,0,0-.2,2.89c.09.31.19.33.23.34a1,1,0,0,0,.4.05C226.61,207.44,226.32,205.89,225.92,204.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M218.77,281.3c-4.57,0-9.06-.65-11-3.31a1.25,1.25,0,1,1,2-1.48c2.21,3,11.17,2.31,16,1.94,1.14-.09,2.15-.17,3-.2,3.06-.12,7.16-1.07,8.9-2.87a1.25,1.25,0,0,1,1.79,1.74c-2.39,2.46-7.2,3.49-10.6,3.63-.79,0-1.77.11-2.87.19C223.8,281.11,221.27,281.3,218.77,281.3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.15,285c-4.72,0-9.85-.19-14.16-2.12a1.25,1.25,0,1,1,1-2.28c4.34,1.95,9.67,1.92,14.82,1.9h1.82c2.67,0,8.25,0,10.18-2.09a1.25,1.25,0,1,1,1.84,1.69c-2.67,2.92-8.75,2.91-12,2.91h-3.49Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M260.15,291.5c-5.17,0-12.44-6.59-14.82-9.15a1.25,1.25,0,1,1,1.83-1.7c3.24,3.49,9.38,8.35,13,8.35h.11a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.75,289a1.24,1.24,0,0,1-.31,0c-5.06-1.3-11.1-5.88-14.85-9.85a1.25,1.25,0,0,1,1.82-1.72c3.38,3.59,9.1,8,13.65,9.15a1.25,1.25,0,0,1-.31,2.46Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M297.25,229.5l-.23,0c-4.42-.83-9.93-2.35-13.26-6.72a1.25,1.25,0,0,1,2-1.52c2.82,3.69,7.75,5,11.74,5.78a1.25,1.25,0,0,1-.23,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M299.5,227.5h0c-3.75,0-7.37-2.34-10.56-4.39a43.46,43.46,0,0,0-3.75-2.25,1.25,1.25,0,1,1,1.12-2.23,44.92,44.92,0,0,1,4,2.38c3,2,6.19,4,9.21,4a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M302.75,224.25h-.07c-4.22-.24-7.69-3.18-10.75-5.78-1.18-1-2.3-1.94-3.39-2.69a1.25,1.25,0,0,1,1.41-2.06,45.3,45.3,0,0,1,3.59,2.85c2.9,2.45,5.89,5,9.27,5.19a1.25,1.25,0,0,1-.07,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M225.2,288.58a84.79,84.79,0,0,1-18-1.61,1.25,1.25,0,0,1,.53-2.44c9,1.94,18.55,1.63,27.82,1.33l3.38-.11a1.25,1.25,0,0,1,.07,2.5l-3.37.11C232.21,288.47,228.71,288.58,225.2,288.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M203.42,226.89a23.26,23.26,0,0,1-6.81-1.45,1.25,1.25,0,0,1,.78-2.37c1.72.57,5.76,1.9,7.58,1.05a1.25,1.25,0,1,1,1.05,2.27A6.16,6.16,0,0,1,203.42,226.89Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M203.75,230.5h0a24.26,24.26,0,0,1-4.32-.53,19.58,19.58,0,0,0-3.91-.47h0a1.25,1.25,0,0,1,0-2.5,22.23,22.23,0,0,1,4.4.51,22.07,22.07,0,0,0,3.88.49,1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M204.21,291.25a17,17,0,0,1-3.78-.54,17.39,17.39,0,0,0-2.75-.47,1.25,1.25,0,0,1-1.17-1.32,1.24,1.24,0,0,1,1.32-1.17,19.55,19.55,0,0,1,3.15.52,13.65,13.65,0,0,0,3.48.48,1.25,1.25,0,0,1,.08,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.25,211.87c-.81,0-1.63,0-2.42-.06s-1.28-.05-1.83-.05a1.25,1.25,0,0,1,0-2.5h0c.58,0,1.23,0,1.93.05,2,.08,4.55.18,5.76-.42a1.25,1.25,0,0,1,1.11,2.24A10.66,10.66,0,0,1,183.25,211.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M182.34,216.06a6,6,0,0,1-3-.5,1.25,1.25,0,0,1,1.28-2.15,15.14,15.14,0,0,0,3.34.11l1.28,0a1.25,1.25,0,0,1,0,2.5l-1.2,0C183.43,216,182.86,216.06,182.34,216.06Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M184.5,286.5h-.25a1.25,1.25,0,0,1,0-2.5h.25a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M162.75,220.25a30,30,0,0,1-6.77-.53,1.25,1.25,0,1,1,.55-2.44,27.88,27.88,0,0,0,6.17.47l.05,1.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M160,229a1.25,1.25,0,0,1-.42-.07c-.27-.09-.63-.26-1-.45s-.71-.33-1.06-.47a1.25,1.25,0,0,1-2-.8,1.55,1.55,0,0,1,.56-1.52c.91-.7,2.12-.13,3.53.53.32.15.61.29.82.36A1.25,1.25,0,0,1,160,229Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M159,295.25a1.25,1.25,0,0,1-.73-2.26,7,7,0,0,1,2.65-1l.75-.18a1.25,1.25,0,1,1,.67,2.41l-.86.21a5.26,5.26,0,0,0-1.74.6A1.24,1.24,0,0,1,159,295.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M121.9,229.57a22.28,22.28,0,0,1-5.46-.61,1.25,1.25,0,0,1,.61-2.42,25,25,0,0,0,8.56.33l1-.09c2.75-.25,7.34-.67,9.07-2.21a1.25,1.25,0,1,1,1.66,1.87c-2.35,2.09-7.26,2.54-10.51,2.84l-1,.09C124.43,229.5,123.12,229.57,121.9,229.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M119,234.75a1.25,1.25,0,0,1,0-2.5c1.84,0,3.7-.15,5.49-.28,1.06-.08,2.13-.16,3.2-.22a1.25,1.25,0,0,1,.13,2.5c-1.05.05-2.1.13-3.14.21-1.84.14-3.74.28-5.67.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M130.92,292.79c-.6,0-1.2,0-1.75-.06l-.4,0a1.25,1.25,0,0,1-1-.66,1.87,1.87,0,0,1-.22-1.13,1.27,1.27,0,0,1,1.11-1.4,1.24,1.24,0,0,1,1.29.74c1.71.08,3.4.05,4.51-.94a1.25,1.25,0,1,1,1.67,1.86A7.39,7.39,0,0,1,130.92,292.79Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M100.65,293a16.77,16.77,0,0,1-6.1-1.1,1.25,1.25,0,0,1,.91-2.33,14.75,14.75,0,0,0,6,.92,1.25,1.25,0,1,1,.12,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M103,253.75H96.75a1.25,1.25,0,0,1,0-2.5H103a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M316.38,201.63a28.3,28.3,0,0,1-4.06-.39,1.25,1.25,0,1,1,.35-2.47h0c2.75.4,4.92.71,7.29-.4a1.25,1.25,0,1,1,1.06,2.26A10.62,10.62,0,0,1,316.38,201.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M315.5,206h0a4,4,0,0,1-2.92-1.45,1.25,1.25,0,1,1,1.92-1.6,1.47,1.47,0,0,0,1.08.55,1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.84,298.77a10.29,10.29,0,0,1-3-.57,8,8,0,0,0-2.3-.45,1.25,1.25,0,0,1-.06-2.5,9.52,9.52,0,0,1,3.08.55,7.1,7.1,0,0,0,2.6.45,1.25,1.25,0,1,1,.21,2.49Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M315.81,294a2,2,0,0,1-1.5-.7A1.25,1.25,0,0,1,316,291.5h0a1.25,1.25,0,0,1,.26,2.47A2.16,2.16,0,0,1,315.81,294Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M331.74,237.75a12.81,12.81,0,0,1-4.15-.82,1.25,1.25,0,1,1,.81-2.37,10.12,10.12,0,0,0,3.55.68,1.25,1.25,0,1,1,.09,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M367.76,250.38c-1,0-2,0-3-.07-1.61-.06-3.14-.07-4.72,0-2.81.1-5.73.2-8.4-1.19a1.25,1.25,0,1,1,1.15-2.22c2.1,1.09,4.56,1,7.17.91,1.64-.06,3.23,0,4.9,0,3,.1,6.07.21,8.68-.74a1.25,1.25,0,1,1,.85,2.35A19.37,19.37,0,0,1,367.76,250.38Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M366.25,253.75c-4,0-7.73-.17-11.37-.51a1.25,1.25,0,0,1,.23-2.49c3.56.33,7.2.49,11.13.49a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M404.37,234.9a10.12,10.12,0,0,1-2.15-.23,10.85,10.85,0,0,1-7.26-5,10.7,10.7,0,0,1-.75-8.67c1.15-3.67,5.93-7.72,10.18-7.23,7.43.77,10.94,7.22,10.61,11.58a10.23,10.23,0,0,1-4.18,7.39A10.8,10.8,0,0,1,404.37,234.9Zm-.69-18.68c-2.82,0-6.29,3-7.09,5.52a8.24,8.24,0,0,0,.53,6.67,8.39,8.39,0,0,0,5.63,3.82,8.13,8.13,0,0,0,6.57-1.51,7.74,7.74,0,0,0,3.18-5.57c.24-3.26-2.6-8.31-8.38-8.91h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M416.68,242.27c-2.57,0-5.17,0-7.74-.14-1.52-.07-3-.16-4.58-.25-3.16-.19-6.45-.35-9.62-.37-.59,0-1.3,0-2.08.07-2.88.14-6.14.3-7.83-.77a1.25,1.25,0,0,1,1.33-2.12c1,.64,4.24.49,6.38.39.89,0,1.67-.08,2.34-.08,3.22,0,6.48.19,9.63.38,1.52.09,3,.18,4.54.25,3.52.16,7.14.15,10.64.13h3.05a1.25,1.25,0,0,1,0,2.5h-6.07Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M432.44,215.28c-.42,0-.84,0-1.25,0a1.25,1.25,0,1,1,.12-2.5,57.87,57.87,0,0,0,8.39-.51c2.29-.25,4.45-.48,6.3-.49h0a1.25,1.25,0,0,1,0,2.5c-1.72,0-3.82.23-6,.47A72.52,72.52,0,0,1,432.44,215.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M430.5,219.5a1.25,1.25,0,0,1-.23-2.48,76.8,76.8,0,0,1,14.48-1,1.25,1.25,0,0,1,0,2.5,74.64,74.64,0,0,0-14,1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M456.75,222c-.43,0-.87,0-1.3,0a1.25,1.25,0,0,1-1.1-1.68c.67-1.81,1.26-3.74,1.83-5.61.72-2.38,1.47-4.84,2.42-7.15a1.25,1.25,0,0,1,2.27-.08,32.87,32.87,0,0,0,2.57,4c2.06,2.9,4.19,5.89,4,8.87a1.25,1.25,0,0,1-1.25,1.18h0a39.69,39.69,0,0,0-4.91.25C459.8,221.86,458.29,222,456.75,222ZM460,210.86c-.52,1.49-1,3-1.44,4.53-.41,1.35-.83,2.74-1.29,4.1,1.23,0,2.48-.14,3.77-.26s2.52-.23,3.81-.27c-.44-1.86-2-4-3.45-6.1C460.93,212.21,460.45,211.53,460,210.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M460.45,247.43a5.05,5.05,0,0,1-4.72-2.68c-1.77-3.28-.51-8.47,1.76-10.75a3.53,3.53,0,0,1,4.22-.91c3.38,1.05,5.33,5.14,5.2,8.38a5.74,5.74,0,0,1-4.7,5.77A8.85,8.85,0,0,1,460.45,247.43Zm-.21-12.19a1.42,1.42,0,0,0-1,.53c-1.57,1.58-2.5,5.64-1.33,7.8.24.45,1,1.8,3.79,1.23a3.28,3.28,0,0,0,2.7-3.41c.1-2.59-1.54-5.35-3.52-5.92a1.25,1.25,0,0,1-.24-.1A.86.86,0,0,0,460.24,235.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M461.06,273.63a15,15,0,0,1-3.85-.46,1.25,1.25,0,0,1-.92-1.17c0-.92-.15-1.86-.27-2.85a23.47,23.47,0,0,1-.27-4.48,1.27,1.27,0,0,1,.1-.42,12.49,12.49,0,0,1,7.33-6.77,3.17,3.17,0,0,1,2.82.29c1.53,1.12,1.8,4.45,1.75,9.83,0,.5,0,.9,0,1.15V269c.08,2.88-.22,3.68-3.23,4.32A16.94,16.94,0,0,1,461.06,273.63Zm-2.33-2.69a15.17,15.17,0,0,0,5.28-.11,8.3,8.3,0,0,0,1.24-.33,10.35,10.35,0,0,0,0-1.47v-.22c0-.28,0-.71,0-1.24.05-5.74-.38-7.41-.75-7.8-.79-.27-4.62,1.71-6.27,5.28a22.69,22.69,0,0,0,.27,3.79C458.59,269.53,458.67,270.23,458.73,270.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M499.19,228.22a9.21,9.21,0,0,1-1.77-.17c-4.48-.87-6.68-3.57-6.92-8.47-.19-3.88,1.83-10.92,6-13.49a6.41,6.41,0,0,1,6.88.07,1.25,1.25,0,0,1-1.23,2.18,4,4,0,0,0-4.34-.12c-3.12,1.93-5,8-4.8,11.24.19,3.77,1.56,5.49,4.9,6.14,2.67.52,5.84-.58,6.76-3.7.62-2.12-.39-6.15-2.41-7.65a2.53,2.53,0,0,0-3.18.08c-.92.6-2.12,3.18-2.24,5.5-.06,1.18.19,1.82.45,2a1,1,0,0,0,1.2.09,1.88,1.88,0,0,0,.89-1.13,1.29,1.29,0,0,1-.42-1.63,1.21,1.21,0,0,1,1.61-.56,2.32,2.32,0,0,1,1.32,2.15,4.19,4.19,0,0,1-2.43,3.49,3.43,3.43,0,0,1-3.74-.46c-1-.8-1.47-2.22-1.37-4.1.14-2.62,1.46-6.22,3.37-7.46a5,5,0,0,1,6,0c2.94,2.19,4.2,7.37,3.32,10.36A8,8,0,0,1,499.19,228.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M496.25,258.25A1.25,1.25,0,0,1,495,257a38,38,0,0,1,.89-8.09c.27-1.5.53-2.92.68-4.3.06-.55.09-1.32.12-2.21.12-3.34.26-7.49,2.26-9.16a1.25,1.25,0,0,1,1.93.44c.62,1.34,1.31,2.72,2,4.05.49,1,1,1.95,1.45,2.92.17.36.41.8.67,1.29,1.5,2.84,2.72,5.34,2.52,7.25-.26,2.38-2.82,3.8-5.29,5.17a15.92,15.92,0,0,0-3.27,2.14,1.25,1.25,0,0,1-1.36.28l-.07,0s0,.1,0,.15a1.25,1.25,0,0,1-1.2,1.3Zm3.59-10.6a39.39,39.39,0,0,0-.52,5.53c.54-.33,1.1-.64,1.66-.95l1-.58a1.24,1.24,0,0,1-.52-.4A12.68,12.68,0,0,1,499.84,247.65Zm-.17-4.88a1.25,1.25,0,0,1,1.06.59,16,16,0,0,1,1.44,3.39,11.14,11.14,0,0,0,1.32,3,1.24,1.24,0,0,1,.25.8A2.77,2.77,0,0,0,505,249c.14-1.3-1.35-4.12-2.24-5.81-.28-.52-.52-1-.71-1.37-.46-1-.95-1.93-1.43-2.89l-.93-1.86a32.17,32.17,0,0,0-.52,5.49v.33a1.24,1.24,0,0,1,.47-.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M493.31,296.12a1.23,1.23,0,0,1-1-.54c-.24-.34-.51-1,.32-1.93a1.25,1.25,0,0,1,1.77-.07,1.17,1.17,0,0,1,.15.17,1.25,1.25,0,0,1-.25,2.14A2.35,2.35,0,0,1,493.31,296.12Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M501.16,296a1.21,1.21,0,0,1-.92-.39c-.37-.42-.61-1.1.33-2a1.29,1.29,0,0,1,1.8,0,1.21,1.21,0,0,1,0,1.73l-.14.13a1.2,1.2,0,0,1-.17.17A1.4,1.4,0,0,1,501.16,296Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M507.58,295.18h-.17a1.33,1.33,0,0,1-1.16-1.3,1.37,1.37,0,1,1,2.67,0l0,.08C508.63,294.79,508.19,295.18,507.58,295.18Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M494.91,292.32c-1.58,0-3.16,0-4.72,0s-3.13,0-4.69,0a1.25,1.25,0,0,1,0-2.5c1.57,0,3.14,0,4.72,0a135.16,135.16,0,0,0,14.23-.34c.88-.08,1.9-.13,3-.18,2.7-.12,6.06-.26,7.75-1.14a1.25,1.25,0,1,1,1.14,2.22c-2.18,1.12-5.69,1.28-8.78,1.41-1,0-2,.09-2.86.17C501.45,292.25,498.17,292.32,494.91,292.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476.59,238.29l-2.13,0-2,0a1.25,1.25,0,1,1,0-2.5h0l2,0a37.3,37.3,0,0,0,8.23-.49,1.25,1.25,0,1,1,.54,2.44A31.24,31.24,0,0,1,476.59,238.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M482,243c-1.25,0-2.52-.07-3.74-.15a42.49,42.49,0,0,0-4.93-.11,1.25,1.25,0,0,1-.14-2.5,45.62,45.62,0,0,1,5.22.11c1.19.07,2.43.14,3.6.14a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M472.5,233a1.25,1.25,0,0,1,0-2.5c1.46,0,2.95-.13,4.39-.25a48.2,48.2,0,0,1,5.41-.25,1.25,1.25,0,0,1,1.21,1.29,1.27,1.27,0,0,1-1.29,1.21,45.31,45.31,0,0,0-5.12.24c-1.49.13-3,.26-4.59.26Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M473,227.25a1.25,1.25,0,0,1-.31-2.46,40.15,40.15,0,0,1,11.14-1,1.25,1.25,0,1,1-.15,2.5,37.41,37.41,0,0,0-10.36,1A1.25,1.25,0,0,1,473,227.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M518.75,239.75a1.25,1.25,0,0,1,0-2.5c2.07,0,5.69-.13,9-.25a1.25,1.25,0,1,1,.09,2.5C524.51,239.62,520.86,239.75,518.75,239.75Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M517.75,235.5a1.25,1.25,0,0,1-.19-2.49,39.94,39.94,0,0,1,6.62-.28l1.82,0a1.25,1.25,0,0,1,0,2.5l-1.85,0a38.16,38.16,0,0,0-6.21.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M542.16,236.15a7.76,7.76,0,0,1-.82,0,5.72,5.72,0,0,1-4.17-2.31,6.49,6.49,0,0,1-.72-5.35,3.89,3.89,0,0,1,2.29-2.58c3-1.57,8.68-3.08,11.54-1.37a3.39,3.39,0,0,1,1.72,2.66c.25,2.56-2.09,5.4-3.36,6.54A10.13,10.13,0,0,1,542.16,236.15Zm4.82-9.92a17.25,17.25,0,0,0-7.15,1.88l-.18.08a1.42,1.42,0,0,0-.82,1,4,4,0,0,0,.36,3.13,3.24,3.24,0,0,0,2.41,1.29,7.54,7.54,0,0,0,5.36-1.8c1.32-1.19,2.66-3.26,2.54-4.44a.91.91,0,0,0-.51-.75A4.07,4.07,0,0,0,547,226.23Zm-7.73.77h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M538.5,227.75a1.25,1.25,0,0,1-1-.45,4.76,4.76,0,0,1-.92-2,1.25,1.25,0,0,1,1.09-1.48,3.57,3.57,0,0,1,2.5.67,2.31,2.31,0,0,1-1.7,3.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M549.25,226a1.72,1.72,0,0,0-2.39-.31,1.25,1.25,0,0,1-.79-1.58,3.66,3.66,0,0,1,1.82-2.2,1.25,1.25,0,0,1,1.72.66,5.17,5.17,0,0,0,.29.57,5.47,5.47,0,0,1,.57,1.31,1.25,1.25,0,0,1-1.21,1.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M533,244a1.25,1.25,0,0,1-.51-2.39c4.39-1.94,9.74-3,14.45-4,1.23-.25,2.43-.5,3.59-.76l1.25-.28a41.06,41.06,0,0,1,5.87-1,1.25,1.25,0,1,1,.19,2.49,39.3,39.3,0,0,0-5.51,1l-1.26.29c-1.17.26-2.38.51-3.62.76-4.82,1-9.8,2-13.95,3.85A1.25,1.25,0,0,1,533,244Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M538.5,293.5a1.25,1.25,0,0,1,0-2.5,79.17,79.17,0,0,0,18.59-2.62c.84-.21,1.75-.38,2.72-.56a20.92,20.92,0,0,0,5.82-1.65,1.25,1.25,0,0,1,1.25,2.17,22,22,0,0,1-6.6,1.94c-.93.18-1.81.34-2.59.53a81.57,81.57,0,0,1-19.18,2.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M541.59,299.51h-.87a1.25,1.25,0,0,1,0-2.5h0c7.63.21,15.26-2.72,22.6-5.55l2.92-1.12a1.25,1.25,0,0,1,.88,2.34l-2.91,1.11C557,296.6,549.45,299.51,541.59,299.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M572.38,217.43a8,8,0,0,1-3.12-.53,1.25,1.25,0,0,1,1-2.3c1.75.74,4.88.13,7.64-.41a32.09,32.09,0,0,1,4.32-.66c.54,0,1.08-.08,1.63-.13a19.47,19.47,0,0,1,3.27-.14,1.25,1.25,0,0,1,1.16,1.33,1.23,1.23,0,0,1-1.33,1.16,17.49,17.49,0,0,0-2.85.13c-.58.06-1.17.11-1.75.14a30.63,30.63,0,0,0-4,.62A32.48,32.48,0,0,1,572.38,217.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M584.5,221H571a1.25,1.25,0,0,1,0-2.5h13.5a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.25,283.25c-2.46,0-4.94-.13-7.34-.26-2.84-.15-5.78-.31-8.63-.24h0a1.25,1.25,0,0,1,0-2.5c2.94-.07,5.93.09,8.82.24,2.37.13,4.82.26,7.21.26a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M588.5,286.75H572.75a1.25,1.25,0,0,1,0-2.5H588.5a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M632,210h-.12a37.79,37.79,0,0,1-14-4.64,1.25,1.25,0,1,1,1.18-2.2,35.33,35.33,0,0,0,13,4.36A1.25,1.25,0,0,1,632,210Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M631.25,215.75a1.25,1.25,0,0,1-.42-.07c-1.36-.49-2.75-1.08-4.22-1.71-3.66-1.56-7.44-3.17-10.88-3.22a1.25,1.25,0,1,1,0-2.5c3.93.05,7.94,1.76,11.82,3.42,1.44.61,2.79,1.19,4.08,1.66a1.25,1.25,0,0,1-.42,2.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.66,291.29a4.59,4.59,0,0,1-4.13-2.24,6.26,6.26,0,0,1,.39-6.52,4.15,4.15,0,0,1,4.34-1.75,1.25,1.25,0,0,1,.84.62,5,5,0,0,1-.73,9.86A6.58,6.58,0,0,1,599.66,291.29Zm-1.06-7.92a2,2,0,0,0-.66.61,3.81,3.81,0,0,0-.26,3.8,2.25,2.25,0,0,0,2.42,1,2.52,2.52,0,0,0-.52-5A1.25,1.25,0,0,1,598.6,283.37Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M639.25,294a1.25,1.25,0,0,1-.7-2.28c2.92-2,11-1.56,14.28-.67a1.25,1.25,0,1,1-.65,2.41c-3.16-.86-10.25-1-12.22.33A1.25,1.25,0,0,1,639.25,294Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M636,217.5a1.25,1.25,0,0,1-.61-2.34c3.3-1.83,11.37-3.43,15.33-1.81a1.25,1.25,0,1,1-.95,2.31c-3.11-1.27-10.41.15-13.17,1.69A1.25,1.25,0,0,1,636,217.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M643.45,235.79a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.64-5.27,5.59-4.85h0a5.23,5.23,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M645.13,254.09a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.65-5.27,5.59-4.85h0a5.22,5.22,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M644.82,272.38a5,5,0,0,1-.9-.08,4.68,4.68,0,0,1-3.91-5.66c.44-2.71,2.65-5.26,5.59-4.85h0a5.22,5.22,0,0,1,2.33,1,5.41,5.41,0,0,1-3.11,9.6Zm.19-8.14c-1.25,0-2.3,1.39-2.53,2.79a2.2,2.2,0,0,0,1.9,2.8,2.56,2.56,0,0,0,2.82-1.7,2.7,2.7,0,0,0-.73-3.34,2.76,2.76,0,0,0-1.21-.54h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M675.75,217a1.25,1.25,0,0,1-.53-.12c-.87-.41-2.74-.3-4.24-.21-.65,0-1.26.07-1.79.07-1.54,0-3.14-.06-4.66-.13s-2.86-.12-4.29-.12a1.25,1.25,0,0,1,0-2.5h0c1.48,0,3,.07,4.39.13s2.95.12,4.42.12h.12c.49,0,1.05,0,1.65-.07,1.87-.11,4-.24,5.44.44a1.25,1.25,0,0,1-.53,2.38Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.5,228.25a1.26,1.26,0,0,1-.47-.09,13.36,13.36,0,0,0-3.59-.54l-1.28-.1a67.49,67.49,0,0,1-12.24-2.62,1.25,1.25,0,0,1-.44-2.18c2.77-2.21,6.45-3.5,10-4.74a49.15,49.15,0,0,0,6.44-2.59,1.25,1.25,0,0,1,1.16,2.21,51.72,51.72,0,0,1-6.78,2.73,47.88,47.88,0,0,0-7.06,2.89,53.81,53.81,0,0,0,9.15,1.8l1.22.09a14.9,14.9,0,0,1,4.35.72,1.25,1.25,0,0,1-.47,2.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M666.44,283.13c-4.71,0-5.74-.45-6.11-1.44a1.25,1.25,0,0,1,2.06-1.32c1.56.5,9.36.15,12.74,0,1.5-.07,2.72-.12,3.38-.13h0a1.25,1.25,0,0,1,.44.08,1.31,1.31,0,0,1,.91,1.26,1.29,1.29,0,0,1-.95,1.21,1.25,1.25,0,0,1-1.4,0l-2.28.1C671.4,283,668.55,283.13,666.44,283.13Zm12.8-.63h0Zm-16.58-1.7h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M239,158.58l-.21,0a73.4,73.4,0,0,1-10.64-2.37,57.77,57.77,0,0,1-5.62-2.28c-3.74-1.67-7.61-3.36-10.84-3.33a1.23,1.23,0,0,1-1.27-1.22,1.25,1.25,0,0,1,1.23-1.27c3.8-.07,7.92,1.76,11.91,3.54a56.19,56.19,0,0,0,5.36,2.19,71.43,71.43,0,0,0,10.3,2.29,1.25,1.25,0,0,1-.21,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M240.33,154.58h-.07a23.16,23.16,0,0,1-7.07-1.93c-.85-.33-1.73-.68-2.59-1-1.62-.55-3.37-1-5.22-1.47-4.74-1.21-9.64-2.47-13.21-5.61a1.25,1.25,0,1,1,1.65-1.87c3.12,2.75,7.72,3.93,12.17,5.06,1.81.46,3.69.94,5.4,1.52.92.31,1.83.67,2.71,1a21,21,0,0,0,6.3,1.76,1.25,1.25,0,0,1-.07,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M200,158.92c-2.45,0-4.2-1.83-4.39-4.59s1.22-5.62,3.88-5.9h0a1.25,1.25,0,0,1,1.6-.57,7,7,0,0,1,3.75,7.29,4.58,4.58,0,0,1-4.71,3.77Zm.62-8.5a1.25,1.25,0,0,1-.87.49c-1.09.12-1.75,1.8-1.65,3.25,0,.7.35,2.32,2,2.26a2.12,2.12,0,0,0,2.33-1.74A4.57,4.57,0,0,0,200.66,150.42Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M252.67,154.58a1.25,1.25,0,0,1,0-2.5,39,39,0,0,0,7.44-.64,1.25,1.25,0,1,1,.47,2.46,41.36,41.36,0,0,1-7.9.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M252.33,149.92a1.25,1.25,0,0,1-.21-2.48,18.9,18.9,0,0,1,2.8-.19,9.51,9.51,0,0,0,3.21-.37,1.25,1.25,0,1,1,1.07,2.26,10.79,10.79,0,0,1-4.24.62,16.86,16.86,0,0,0-2.41.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M295.33,148.92a1.25,1.25,0,0,1-.1-2.5c1.15-.09,2.34-.12,3.5-.16a37.78,37.78,0,0,0,6-.49,1.25,1.25,0,0,1,.48,2.45,39.59,39.59,0,0,1-6.44.54c-1.17,0-2.28.07-3.37.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M295.38,154.58h-.05a1.25,1.25,0,0,1-1.25-1.25,1.27,1.27,0,0,1,1.25-1.25,28.42,28.42,0,0,0,4.5-.5,25.18,25.18,0,0,1,5.92-.5,1.25,1.25,0,1,1-.17,2.49,22.63,22.63,0,0,0-5.33.47A29.61,29.61,0,0,1,295.38,154.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M301.32,98.77a5.18,5.18,0,0,1-1.74-.33c-2.41-.86-3.2-3.61-2.71-5.75a3.86,3.86,0,0,1,4.26-3.26,1.25,1.25,0,0,1,.87,2,4.61,4.61,0,0,1,2.24,5.4A3,3,0,0,1,301.32,98.77Zm-1.57-6.47a2.06,2.06,0,0,0-.44.94c-.25,1.09.11,2.49,1.12,2.85.47.17,1.28.37,1.48-.15a2.16,2.16,0,0,0-1.37-2.44A1.25,1.25,0,0,1,299.75,92.3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M327,87.25H308.67a1.25,1.25,0,0,1,0-2.5H327a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M310,92.25h-2a1.25,1.25,0,0,1,0-2.5h1c3.62,0,7.36,0,11-.17.69,0,1.48,0,2.31,0,1.7,0,3.82.07,4.86-.39a1.25,1.25,0,0,1,1,2.29c-1.54.68-3.76.64-5.92.6-.79,0-1.53,0-2.15,0C316.74,92.24,313.31,92.25,310,92.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.48,117.31c-1.41,0-2.81,0-4.16-.11a1.25,1.25,0,0,1-1.18-1.11,9.07,9.07,0,0,1,1.23-5,7.35,7.35,0,0,0,1.05-3.93,6.4,6.4,0,0,0,2.2-1.49,1.25,1.25,0,0,1,1.74.32l.5.72c1.76,2.5,4.42,6.29,4,9.44a1.25,1.25,0,0,1-1.17,1.08C320.3,117.27,318.89,117.31,317.48,117.31Zm-2.82-2.55c1.87.07,3.8.07,5.69,0-.34-2.07-2.2-4.75-3.43-6.51a11.59,11.59,0,0,1-1.28,3.88A10.13,10.13,0,0,0,314.65,114.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M317.93,132.87a1.25,1.25,0,0,1-.87-.35c-1.54-1.49-2.12-3.64-2.68-5.72-.47-1.75-.91-3.4-1.85-4.18a1.25,1.25,0,0,1,.57-2.19,1.25,1.25,0,0,1,1.75-.91,10.12,10.12,0,0,0,3.66.28c.74,0,1.5,0,2.19,0a1.25,1.25,0,0,1,1.1,1.68,28.14,28.14,0,0,0-1.06,4.49,24.54,24.54,0,0,1-1.69,6.19,1.25,1.25,0,0,1-.91.69Zm-2.54-10.64a16.54,16.54,0,0,1,1.41,3.92,24.47,24.47,0,0,0,.81,2.63c.27-1,.48-2.16.67-3.26s.4-2.17.66-3.23h-.36A19.72,19.72,0,0,1,315.38,122.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M323,153.58a1.25,1.25,0,0,1-.28,0c-3.24-.73-7-.58-10.64-.43-1.47.06-3,.12-4.42.12a1.25,1.25,0,0,1,0-2.5c1.39,0,2.81-.06,4.32-.12,3.8-.16,7.72-.32,11.29.49a1.25,1.25,0,0,1-.27,2.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M340.6,87.54a5.83,5.83,0,0,1-5.79-4.18A7.23,7.23,0,0,1,338,74.92a2.56,2.56,0,0,0,2.84-.48c3.51.62,5.56,4.49,5.43,7.71a5.26,5.26,0,0,1-4.94,5.36A7.74,7.74,0,0,1,340.6,87.54Zm-.82-11a1.24,1.24,0,0,1-.5.53,4.72,4.72,0,0,0-2.1,5.51A3.44,3.44,0,0,0,341.13,85a2.79,2.79,0,0,0,2.7-3c.08-2.14-1.28-4.78-3.37-5.15A1.24,1.24,0,0,1,339.79,76.55Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M347,101.58H332.33a1.25,1.25,0,0,1,0-2.5H347a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M347.33,118.25a1.24,1.24,0,0,1-.45-.09c-2.59-1-6.67-.84-10.28-.69-1.28.05-2.49.1-3.6.1a1.25,1.25,0,0,1,0-2.5c1.06,0,2.24,0,3.5-.1,3.85-.16,8.22-.35,11.29.86a1.25,1.25,0,0,1-.46,2.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M356.33,79.58a1.25,1.25,0,0,1,0-2.5c7.22,0,14.81-.33,22.56-1,1-.09,2.15-.15,3.28-.2a35.06,35.06,0,0,0,8.44-1.08,1.25,1.25,0,1,1,.76,2.38,36.78,36.78,0,0,1-9.07,1.2c-1.1.06-2.18.11-3.2.2C371.28,79.25,363.62,79.58,356.33,79.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M358,87.58a1.25,1.25,0,0,1,0-2.5c5.58,0,11.25-.61,16.73-1.17s11.28-1.15,16.94-1.17h0a1.25,1.25,0,0,1,0,2.5c-5.54,0-11.21.6-16.69,1.16s-11.27,1.15-17,1.18Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M373.19,127.89c-4.6,0-9.16-1.46-11.59-5.48a18.94,18.94,0,0,1,0-19.05,13.71,13.71,0,0,1,12.76-6.94h0c9.7.78,14.87,4.9,15.81,12.61.66,5.4.64,13-7.13,16.69A24.1,24.1,0,0,1,373.19,127.89Zm.43-29a11.12,11.12,0,0,0-9.83,5.74,16.6,16.6,0,0,0,0,16.48c3.35,5.52,12.95,4.89,18.3,2.35,4.94-2.34,6.65-6.57,5.72-14.13-.8-6.52-5-9.73-13.51-10.42Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M367.44,123.21H367a1.25,1.25,0,0,1-1.2-1.15c-.32-3.86.8-7.22,1.88-10.47a28.1,28.1,0,0,1,1.69-3.72c1-1.87,1.94-3.8,2-5.27a1.25,1.25,0,0,1,2.15-.79,21.29,21.29,0,0,1,3.1,4.13,15.17,15.17,0,0,0,1.41,2.06,22.93,22.93,0,0,0,2.73,2.5c2.12,1.75,4.3,3.57,5,6.11a1.25,1.25,0,0,1-1.08,1.58,28.36,28.36,0,0,0-7.69,2.39C373.93,121.87,370.7,123.21,367.44,123.21Zm5.86-17.86a34.89,34.89,0,0,1-1.7,3.65,28.41,28.41,0,0,0-3.35,11.68,27.38,27.38,0,0,0,7.85-2.41A39.11,39.11,0,0,1,382.8,116a18.07,18.07,0,0,0-3.59-3.55,25.06,25.06,0,0,1-3-2.8,17.36,17.36,0,0,1-1.65-2.38C374.16,106.63,373.78,106,373.3,105.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M392.33,145.58h-35a1.25,1.25,0,0,1,0-2.5h35a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M363.79,154.26h-6.46a1.25,1.25,0,0,1,0-2.5h3.23c7.16,0,14.57,0,21.67-.66a38.38,38.38,0,0,1,4.64,0c2.65.08,5.65.17,7.31-.54a1.25,1.25,0,1,1,1,2.3c-2.16.93-5.32.83-8.37.74a36.82,36.82,0,0,0-4.32,0C376.32,154.18,370,154.26,363.79,154.26Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M426.47,108.22c-1.47,0-3-.1-4.37-.19-.73,0-1.4-.09-2-.11-3.38-.13-6.82-.48-10.15-.82-3.74-.38-7.61-.78-11.33-.85a1.25,1.25,0,0,1-1.23-1.27,1.24,1.24,0,0,1,1.27-1.23c3.82.07,7.74.47,11.54.86,3.29.34,6.69.69,10,.81.6,0,1.29.07,2,.12,2.74.18,6.5.43,8.23-.35a1.25,1.25,0,1,1,1,2.28A13.1,13.1,0,0,1,426.47,108.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M446.35,89.6c-.93,0-1.85,0-2.77,0-1.69,0-3.44-.08-5.17,0a1.25,1.25,0,1,1-.15-2.5c1.83-.11,3.64-.07,5.38,0a33,33,0,0,0,9.05-.61,1.25,1.25,0,1,1,.61,2.42A28.08,28.08,0,0,1,446.35,89.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M453.67,95.58H439.33a1.25,1.25,0,0,1,0-2.5h14.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M463.67,82.58h-6a1.25,1.25,0,0,1,0-2.5h6a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M462.26,153.33a8.62,8.62,0,0,1-3.07-.51,1.25,1.25,0,0,1,1-2.31c1.1.45,3.63.44,4.44-.17a1.25,1.25,0,1,1,1.51,2A6.56,6.56,0,0,1,462.26,153.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M520,149.25a1.25,1.25,0,0,1-1-2,50,50,0,0,1,8.81-8.32c.92-.74,1.83-1.47,2.71-2.21a1.25,1.25,0,1,1,1.61,1.92c-.9.75-1.82,1.5-2.76,2.24a48.07,48.07,0,0,0-8.38,7.89A1.25,1.25,0,0,1,520,149.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M522.33,153.58a1.25,1.25,0,0,1-1.13-1.78,17,17,0,0,1,3.55-4.58,13.25,13.25,0,0,0,3.08-4,1.25,1.25,0,1,1,2.32.93,15.26,15.26,0,0,1-3.62,4.84,15,15,0,0,0-3.08,3.89A1.25,1.25,0,0,1,522.33,153.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M481.93,87.59h-.31a1.25,1.25,0,1,1,.09-2.5c2.23.08,5-1.11,7.63-2.27a40.11,40.11,0,0,1,4.3-1.68,1.25,1.25,0,0,1,.71,2.4,38.48,38.48,0,0,0-4,1.58C487.53,86.33,484.63,87.59,481.93,87.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M484,92.92a1.25,1.25,0,0,1-.7-2.29c2.45-1.66,5.83-2.61,9.09-3.53,1.52-.43,3-.83,4.18-1.28a1.25,1.25,0,0,1,.86,2.35c-1.31.48-2.79.9-4.36,1.34-3.07.86-6.25,1.76-8.37,3.19A1.24,1.24,0,0,1,484,92.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M555.52,157.85a6.45,6.45,0,0,1-5.64-3.1,8.58,8.58,0,0,1,1.6-10.51c3.37-3.32,6.34-2.72,7.82-2.07,2.79,1.24,4.72,4.63,4.58,8.07a7.61,7.61,0,0,1-5.44,7.08h0A8.89,8.89,0,0,1,555.52,157.85Zm2.5-1.7h0Zm-1.11-12a5.43,5.43,0,0,0-3.68,1.85,6.06,6.06,0,0,0-1.24,7.41c1.13,1.82,3.18,2.38,5.61,1.54h0a5.14,5.14,0,0,0,3.76-4.83,6.07,6.07,0,0,0-3.09-5.68A3.35,3.35,0,0,0,556.92,144.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M570.67,149.58h-4.33a1.25,1.25,0,0,1,0-2.5h4.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M542.6,151.64a9.44,9.44,0,0,1-1.08-.06,1.25,1.25,0,1,1,.29-2.48,8.67,8.67,0,0,0,3.19-.3,1.25,1.25,0,1,1,.67,2.41A11.65,11.65,0,0,1,542.6,151.64Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M549.58,132.21h-.91a1.25,1.25,0,0,1-1.16-1.61,52.47,52.47,0,0,1,3.39-8,42.37,42.37,0,0,0,3.88-9.88,1.25,1.25,0,0,1,2.42-.12,56.07,56.07,0,0,0,2.43,6.07c1.63,3.67,3.32,7.46,3.24,10.94a1.25,1.25,0,0,1-1.06,1.21l-1.26.2A73.36,73.36,0,0,1,549.58,132.21ZM556.15,117a67.5,67.5,0,0,1-3,6.74,65.08,65.08,0,0,0-2.7,6,79.31,79.31,0,0,0,9.71-1.12l.17,0c-.25-2.67-1.58-5.67-3-8.83C556.94,118.82,556.53,117.91,556.15,117Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603,150.25c-2.34,0-5.13-.15-8.08-.32-3.61-.2-7.34-.41-10.56-.35a1.28,1.28,0,0,1-1.27-1.23,1.25,1.25,0,0,1,1.23-1.27c3.33-.06,7.1.15,10.75.35,2.91.16,5.67.31,7.94.31a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M585.67,144.58a1.25,1.25,0,0,1-.4-2.43c4.81-1.65,10.6-1.54,15.7-1.44,1.27,0,2.52,0,3.7,0h0a1.25,1.25,0,0,1,0,2.5c-1.22,0-2.47,0-3.75,0-5.14-.1-10.45-.19-14.85,1.31A1.25,1.25,0,0,1,585.67,144.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M610.35,152.6H609a1.25,1.25,0,0,1,0-2.5h0c3.29.07,7.09-.14,10.76-.35,2.76-.16,5.37-.3,7.54-.31h0a1.25,1.25,0,0,1,0,2.5c-2.11,0-4.68.16-7.41.31C616.71,152.41,613.39,152.6,610.35,152.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M147.76,501.88c-3.43,0-6.88-.24-10.26-.48s-6.79-.48-10.13-.48h0a1.25,1.25,0,0,1-1.25-1.25,1.29,1.29,0,0,1,1.28-1.25c3.43,0,6.92.25,10.31.49,6.05.43,12.31.87,18.12-.13a1.25,1.25,0,1,1,.42,2.46A49.74,49.74,0,0,1,147.76,501.88Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M138.33,525.58h-.1c-.51,0-1-.1-1.53-.15a18.61,18.61,0,0,0-3-.18,1.23,1.23,0,0,1-1.31-1.19,1.25,1.25,0,0,1,1.19-1.31,21.27,21.27,0,0,1,3.38.19c.48.05,1,.11,1.44.14a1.25,1.25,0,0,1-.09,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M146.58,580.92a90.71,90.71,0,0,1-12-1c-.57-.07-1.27-.11-2-.15-2.76-.14-6.19-.31-7.88-2.71a1.25,1.25,0,1,1,2-1.44c1,1.4,3.74,1.54,6,1.65.79,0,1.54.08,2.2.17a95.08,95.08,0,0,0,11.83,1H147c3.33,0,5.73,0,8.49-1.23a1.25,1.25,0,1,1,1,2.29c-3.24,1.43-6,1.43-9.5,1.44h-.43Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M189.67,506.92h0c-4.84,0-13.33-.8-17.81-1.34a1.25,1.25,0,1,1,.3-2.48c4.42.53,12.79,1.29,17.53,1.33a1.25,1.25,0,0,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M182.45,514.29c-4.67,0-9.59-.2-13.8-1.43a1.25,1.25,0,0,1,.7-2.4c4.87,1.42,11,1.36,16.42,1.3l3.57,0a1.25,1.25,0,0,1,0,2.5,3.43,3.43,0,0,1-.44,0l-3.1,0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M202.33,564.63c-1.34,0-2.86-.1-4.5-.23-1-.08-1.9-.15-2.5-.15a1.25,1.25,0,0,1,0-2.5c.69,0,1.62.07,2.69.16,1.9.15,6.94.55,7.66-.35a1.25,1.25,0,0,1,2,1.56C206.71,564.28,204.82,564.63,202.33,564.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208.67,570.58h-13a1.25,1.25,0,0,1,0-2.5h13a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M201,581.92h-.23c-2.67-.14-3.68-1.28-4.05-2.21-.54-1.35-.05-3,1.31-4.48s3.48-2.61,5.7-1.88c2.5.83,3.09,2.69,2.82,4.15A5.94,5.94,0,0,1,201,581.92Zm1.39-6.29a3.88,3.88,0,0,0-2.54,1.3c-.71.75-.95,1.51-.81,1.84s.66.59,1.86.65h0a3.45,3.45,0,0,0,3.18-2.39c0-.26.17-.88-1.15-1.31A1.71,1.71,0,0,0,202.38,575.63Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.35,517.29a22.47,22.47,0,0,1-8.32-1.93,75.86,75.86,0,0,1-7.71-3.87L93,510.76a23.18,23.18,0,0,0-2.32-1c-1.85-.75-3.94-1.6-5.3-3.27a1.25,1.25,0,1,1,1.94-1.58c1,1.17,2.66,1.86,4.3,2.53a25.54,25.54,0,0,1,2.58,1.16l1.34.74a74.18,74.18,0,0,0,7.45,3.74,18.35,18.35,0,0,0,8.25,1.7,1.25,1.25,0,0,1,.22,2.49Q110.91,517.29,110.35,517.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110,522.92a1.25,1.25,0,0,1-.33,0c-3.36-.9-6.88-2.06-10.49-3.27-.66-.22-1.43-.46-2.26-.72-4.57-1.43-10.83-3.38-13.24-6.44a1.25,1.25,0,0,1,2-1.54c1.93,2.45,8,4.35,12,5.6.85.27,1.64.51,2.31.74,3.57,1.2,7,2.34,10.34,3.23a1.25,1.25,0,0,1-.32,2.46Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M114.33,529.92a1.25,1.25,0,0,1-.47-2.41c2.22-.91,5.17-.72,7.78-.55,1,.06,1.89.12,2.7.12a1.25,1.25,0,1,1,0,2.5c-.89,0-1.84-.06-2.86-.13-2.34-.15-5-.32-6.67.37A1.24,1.24,0,0,1,114.33,529.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M121.32,533c-2.07,0-4.35-.2-6-1.25a1.25,1.25,0,0,1,1.35-2.1c1.53,1,4.41.89,6.51.82h.44a1.22,1.22,0,0,1,1.29,1.21,1.25,1.25,0,0,1-1.21,1.29h-.43C122.67,533,122,533,121.32,533Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M204.06,502.94c-1.59,0-3.19-.1-4.71-.19s-2.79-.17-4-.17a1.25,1.25,0,1,1,0-2.5c1.31,0,2.7.08,4.17.17,3.66.22,7.8.47,10.68-.74a1.25,1.25,0,0,1,1,2.31A18.59,18.59,0,0,1,204.06,502.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.65,507.25c-3.38,0-6.75-.28-10-.54-2.19-.18-4.46-.36-6.69-.46a1.25,1.25,0,1,1,.11-2.5c2.28.1,4.57.29,6.79.47,3.21.26,6.52.53,9.8.53h0a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M626.88,500.82c-2.73,0-5.52-.16-8.27-.32-3.4-.19-6.62-.38-9.55-.25a1.25,1.25,0,1,1-.1-2.5c3.05-.12,6.33.06,9.8.26,6.67.38,13.56.77,18.82-1.18a1.25,1.25,0,0,1,.87,2.34A33.57,33.57,0,0,1,626.88,500.82Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M638.67,506.25c-4.2,0-8.52-.31-12.7-.6a122.36,122.36,0,0,0-17.87-.4,1.25,1.25,0,0,1-.2-2.49,124.15,124.15,0,0,1,18.24.4c4.14.29,8.42.6,12.53.6a1.25,1.25,0,1,1,0,2.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M634.9,576.77c-1.72,0-3.45-.16-5.06-.3-1-.09-2-.18-2.9-.23-1.46-.07-2.93-.09-4.49-.11-4.54-.06-9.24-.12-13.52-1.62a1.25,1.25,0,1,1,.83-2.36c3.9,1.37,8.38,1.43,12.73,1.48,1.52,0,3.08,0,4.59.12,1,0,2,.14,3,.23,3.09.28,6.3.57,8.93-.19a1.25,1.25,0,1,1,.69,2.4A17.52,17.52,0,0,1,634.9,576.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M622.24,579.36a123.7,123.7,0,0,1-13.37-.78,1.25,1.25,0,0,1,.27-2.49,111.6,111.6,0,0,0,17.55.66c.93,0,2-.06,3-.06,2.82,0,6,0,8.2-.86a1.25,1.25,0,0,1,.87,2.34c-2.59,1-6,1-9,1-1,0-2,0-2.91.06Q624.58,579.36,622.24,579.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M662.25,493.36a39.46,39.46,0,0,1-6.09-.66,32.89,32.89,0,0,0-3.53-.45,1.25,1.25,0,1,1,.09-2.5,34,34,0,0,1,3.84.48,26,26,0,0,0,7.42.5,31.79,31.79,0,0,0,4.85-1.31c1-.34,2.11-.69,3.19-1a1.25,1.25,0,1,1,.63,2.42c-1,.26-2,.58-3,.93a34.23,34.23,0,0,1-5.24,1.4A13.65,13.65,0,0,1,662.25,493.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M663.41,498.84a35.43,35.43,0,0,1-10.82-1.66,1.25,1.25,0,1,1,.81-2.36c4.77,1.64,14,2.52,18.25-.2a1.25,1.25,0,0,1,1.35,2.1C670.63,498.25,667.07,498.84,663.41,498.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M620.51,540.9a5.16,5.16,0,0,1-4.57-2.22c-2-3-.88-8.07,1.28-11.54,1.94-3.12,4.47-4.72,6.94-4.38h0c4.22.63,6.67,3.05,6.71,6.65.06,4.85-4.34,10.57-8.72,11.33A9.76,9.76,0,0,1,620.51,540.9Zm3-15.68c-1.36,0-2.9,1.19-4.18,3.24-1.92,3.09-2.52,7.05-1.33,8.82.66,1,1.92,1.31,3.73,1,3.15-.55,6.69-5.25,6.65-8.83,0-2.34-1.57-3.76-4.57-4.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M661.55,536.59a4.66,4.66,0,0,1-4.27-2.25c-1.38-2.4-.59-6,.9-8.31,1.32-2,3.12-3.11,4.94-2.93h0a1.25,1.25,0,0,1,.83.18,8.54,8.54,0,0,1,3.58,9,5.74,5.74,0,0,1-5.69,4.35Zm1.18-11a3.33,3.33,0,0,0-2.45,1.81c-1.22,1.89-1.59,4.4-.83,5.71.15.27.62,1.08,2.32,1a3.28,3.28,0,0,0,3.38-2.49,6,6,0,0,0-2.21-6h-.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M685,507.44a75.46,75.46,0,0,1-8.17-.54,1.25,1.25,0,1,1,.27-2.48c5.78.64,12.24,1,16.33-.89a1.25,1.25,0,0,1,1.06,2.26A22.82,22.82,0,0,1,685,507.44Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.67,512.58a1.25,1.25,0,0,1,0-2.5c2.87,0,5.77-.25,8.58-.5,2.64-.23,5.38-.47,8.07-.5h0a1.25,1.25,0,0,1,0,2.5c-2.6,0-5.17.25-7.88.49S679.64,512.58,676.67,512.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M663.94,579.51c-2.27,0-4.67-.17-6.95-.33-2-.14-3.82-.27-5.33-.27a1.25,1.25,0,0,1,0-2.5c1.6,0,3.5.13,5.5.27,4.81.34,10.79.76,13.55-.78a1.25,1.25,0,1,1,1.21,2.19C670,579.19,667.07,579.51,663.94,579.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M662.37,583.61c-2,0-4.06-.11-5.92-.21-1.42-.08-2.76-.15-3.79-.15a1.25,1.25,0,0,1,0-2.5c1.09,0,2.47.07,3.92.15,4.14.22,9.8.53,12.94-.73a1.25,1.25,0,0,1,.93,2.32A22.89,22.89,0,0,1,662.37,583.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M678.95,578c-.41,0-.77,0-1.07,0a1.25,1.25,0,1,1,.25-2.49c1.78.19,6.62-.33,8.56-1.49a1.25,1.25,0,1,1,1.29,2.14C685.8,577.38,681.47,578,678.95,578Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M707,514.25a1.27,1.27,0,0,1-.28,0,1.25,1.25,0,0,1-.95-1.49c.41-1.81,3-1.88,6.57-2a21,21,0,0,0,3.64-.28,1.25,1.25,0,0,1,.68,2.41,20.75,20.75,0,0,1-4.25.37,20.78,20.78,0,0,0-4.34.38A1.25,1.25,0,0,1,707,514.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.67,582.58a1.25,1.25,0,0,1-1-2c3.71-5.15,8.35-9.53,12.43-11.71a1.25,1.25,0,0,1,1.18,2.21c-3.75,2-8.08,6.1-11.57,11A1.25,1.25,0,0,1,587.67,582.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M583.67,576.58a1.25,1.25,0,0,1-1.07-1.9c2.1-3.48,10.42-10.32,14.9-10.93a1.25,1.25,0,0,1,.33,2.48c-3.31.45-11.2,6.6-13.1,9.74A1.25,1.25,0,0,1,583.67,576.58Z" transform="translate(-53.25 -44.96)"/></g><g id="BACKGROUND"><path class="cls-24" d="M479.9,331.07c-37.71,0-75.29-.27-112.34-.54-33.89-.24-68.94-.49-103.29-.53-31.44,0-63.33-.27-94.18-.5-33.44-.25-68-.5-102.1-.5a2,2,0,0,1,0-4c34.1,0,68.68.26,102.13.5,30.83.23,62.72.46,94.15.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08H728a2,2,0,0,1,0,4H665.58c-4,0-8,0-12-.08-7.82-.08-15.9-.17-23.81.08C580.3,330.59,530,331.07,479.9,331.07Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M479.9,306c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.7,0-62.72-.31-92.72-.58-32-.29-65-.59-98.87-.59a2,2,0,1,1,0-4c33.84,0,66.92.3,98.91.59,30,.27,61,.55,92.69.58,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08h56.53a2,2,0,0,1,0,4H665.58c-4,0-8,0-12-.09-7.82-.08-15.9-.17-23.81.08C580.3,305.5,530,306,479.9,306Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,190.86c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.42,0-63.29-.27-94.12-.5l-32.69-.23a2,2,0,0,1-2-2,2,2,0,0,1,2-2l32.69.23c30.82.23,62.68.46,94.09.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08a2,2,0,0,1,0,4c-4,0-8,0-12-.09-7.82-.08-15.9-.17-23.81.08C576.4,190.38,526.09,190.86,476,190.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,165.77c-37.71,0-75.29-.27-112.33-.54-33.89-.24-68.94-.49-103.29-.53-31.52,0-63.48-.27-94.4-.5l-8.79-.06a2,2,0,0,1,0-4h0l8.79.06c30.91.23,62.87.46,94.38.5,34.36,0,69.41.29,103.31.53,86.22.62,175.37,1.26,262.09-1.53,3.52-.11,7.36-.17,11.75-.17h0a2,2,0,0,1,0,4c-4.34,0-8.14.06-11.62.17C576.4,165.29,526.09,165.77,476,165.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,475.66c-37.71,0-75.29-.27-112.35-.54-33.89-.24-68.93-.5-103.27-.53-31.45,0-63.35-.27-94.2-.5-33.43-.25-68-.5-102.07-.5a2,2,0,1,1,0-4c34.09,0,68.66.25,102.1.5,30.84.23,62.74.46,94.18.5,34.35,0,69.4.29,103.29.53,86.23.62,175.39,1.26,262.11-1.53,8-.25,16.12-.17,24-.09,4,0,7.95.08,11.91.08,10.39,0,22.44-.2,34.11-.4s23.75-.4,34.17-.4a2,2,0,0,1,0,4c-10.39,0-22.45.2-34.11.4s-23.75.4-34.17.4c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08C576.39,475.19,526.08,475.66,476,475.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M733.78,450.57c-10.44,0-23.51-.53-36.14-1s-25.61-1-36-1c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08-86.79,2.79-176,2.15-262.23,1.53-33.9-.24-69-.5-103.31-.53-31.43,0-63.31-.27-94.14-.5-33.45-.25-68-.5-102.13-.5a2,2,0,1,1,0-4c34.11,0,68.7.25,102.16.5,30.83.23,62.7.46,94.12.5,34.37,0,69.43.29,103.33.53,86.21.62,175.36,1.26,262.07-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08,10.44,0,23.5.53,36.13,1s25.61,1,36,1a2,2,0,0,1,0,4Z" transform="translate(-53.25 -44.96)"/><g class="cls-25"><path class="cls-24" d="M167.18,469.74a2.91,2.91,0,0,1-1.53-.42,4.18,4.18,0,0,1-1.65-3.38h0c-.07-.82-.11-1.66-.15-2.5s-.07-1.56-.13-2.32c-.19-2.42-.29-5.09-.29-8.41a4.24,4.24,0,0,1,1.48-3.58c1.55-1.09,3.5-.4,4.66,0a21.31,21.31,0,0,1,9.27,5.93l.19.21c1.06,1.17,2.65,2.94,2,4.76-.35,1-1.32,1.71-2.88,2.76-.28.19-.52.34-.65.45-.95.78-1.93,1.46-2.89,2.13-.56.39-1.13.78-1.68,1.19-.29.22-.58.45-.88.68a14.2,14.2,0,0,1-3.3,2.15A4.14,4.14,0,0,1,167.18,469.74Zm.91-3.46h0Zm-.66-13.63v.05c0,3.21.09,5.78.28,8.09.06.81.1,1.64.14,2.46s.06,1.38.11,2.06a18.62,18.62,0,0,0,1.61-1.2c.33-.27.66-.53,1-.77.59-.43,1.19-.85,1.79-1.27.93-.65,1.81-1.25,2.63-1.93.19-.16.54-.4,1-.68l.9-.62c-.28-.35-.62-.73-.77-.9l-.22-.25a17.5,17.5,0,0,0-7.61-4.8C167.89,452.79,167.63,452.71,167.43,452.65Zm10,5.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M190.73,469.74a4.13,4.13,0,0,1-1.59-.35,14.22,14.22,0,0,1-3.3-2.15c-.3-.24-.59-.47-.88-.68-.55-.41-1.12-.8-1.69-1.19-1-.66-1.94-1.35-2.89-2.13-.13-.11-.37-.26-.65-.45-1.56-1.05-2.54-1.77-2.88-2.76-.63-1.81,1-3.58,2-4.76l.19-.21a21.32,21.32,0,0,1,9.27-5.93c1.16-.42,3.11-1.11,4.66,0a4.24,4.24,0,0,1,1.48,3.58c0,3.32-.09,6-.29,8.41-.06.76-.1,1.54-.13,2.32s-.08,1.69-.15,2.51a4.18,4.18,0,0,1-1.65,3.38A2.91,2.91,0,0,1,190.73,469.74Zm-9.65-10.88.9.62c.41.28.76.52,1,.68.82.67,1.7,1.28,2.62,1.93.6.42,1.2.83,1.79,1.27.33.24.66.5,1,.77a18.47,18.47,0,0,0,1.61,1.2c0-.68.08-1.37.11-2.07s.08-1.64.14-2.45c.19-2.31.27-4.88.28-8.1v-.05c-.2.05-.46.14-.8.26a17.5,17.5,0,0,0-7.61,4.8l-.22.24C181.71,458.13,181.37,458.5,181.09,458.86Zm-.65-.52" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M102.47,354.23a2,2,0,0,1-1.68-3.08,79.22,79.22,0,0,1,7.43-9.73c6.39-7.21,15.4-12.58,27.57-16.43,11.57-3.66,22.64-7.53,30.94-14.54a2,2,0,0,1,3.25,1.91,18.25,18.25,0,0,1-2,5.36c6.95-2,16.48-6.56,19.26-10a2,2,0,0,1,3.55,1.36,16.94,16.94,0,0,1-3,8.82,65.35,65.35,0,0,0,12.58-2.63c1.46-.41,2.94-.82,4.46-1.21a2,2,0,0,1,2.44,2.41,12.34,12.34,0,0,1-1.78,4c17.25,3.33,36.68,15.6,47.45,30.28a2,2,0,1,1-3.23,2.37c-11-15-31.37-27.27-48.49-29.27a2,2,0,0,1-1-3.57,9.19,9.19,0,0,0,1.26-1.18l-.05,0c-5.93,1.65-11.53,3.21-18.5,2.83a2,2,0,0,1-1.09-3.6,12.31,12.31,0,0,0,3.36-3.87c-6.56,4.13-16.49,7.75-21.54,8.2a2,2,0,0,1-1.7-3.3c.35-.4.71-.85,1.08-1.35-7.71,4.74-16.71,7.82-26,10.77-11.46,3.62-19.89,8.62-25.78,15.27a75.18,75.18,0,0,0-7.06,9.24A2,2,0,0,1,102.47,354.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M119.46,422.75c-6.6,0-13.4-1.41-18.19-5.32-12.68-10.37-18.57-28.31-14.66-44.65,3.5-14.6,13.77-24.79,28.19-27.94a50.34,50.34,0,0,1,13.11-1.2h0c21.69,1,33,17.78,34.56,33.91,1.71,17.53-7.28,37.86-31.21,43.77A50.23,50.23,0,0,1,119.46,422.75Zm6.37-75.16a47.77,47.77,0,0,0-10.17,1.15c-12.86,2.81-22,11.91-25.15,25-3.56,14.88,1.78,31.21,13.3,40.62,6.27,5.12,17.82,5.25,26.5,3.11,21.61-5.34,29.73-23.69,28.19-39.5-1.41-14.42-11.46-29.38-30.77-30.3Q126.79,347.59,125.83,347.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M136.19,391.22c6.18-1.2,8.88-12,3.72-16s-15.21,1.36-14.1,8.27C126.6,388.33,131.25,392.18,136.19,391.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M88.65,512.72a2,2,0,0,1-2-2c0-8.37-.06-16.77-.11-24.89-.19-29.54-.38-57.44,1.85-87a2,2,0,1,1,4,.3c-2.22,29.38-2,57.2-1.84,86.66.05,8.13.11,16.53.11,24.91A2,2,0,0,1,88.65,512.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M263.59,512.72h-.2a2,2,0,0,1-1.79-2.19c1.33-13.41.87-37.17.34-58.37-.17-6.66-.6-13.32-1-19.77-.58-8.87-1.18-18-1.07-27.25a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.1,9.06.49,18.15,1.06,26.95.42,6.49.86,13.2,1,19.93.53,21.33,1,45.23-.36,58.87A2,2,0,0,1,263.59,512.72Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="84.62" cy="334.45" r="2.31"/><path class="cls-24" d="M235.5,423.2a50.2,50.2,0,0,1-11.8-1.43c-23.93-5.91-32.92-26.24-31.21-43.77,1.57-16.13,12.87-32.87,34.56-33.91a50.36,50.36,0,0,1,13.11,1.2c14.42,3.15,24.69,13.33,28.19,27.94,3.91,16.34-2,34.29-14.66,44.65C248.9,421.79,242.1,423.2,235.5,423.2ZM229.13,348q-1,0-1.9,0h0c-19.31.92-29.37,15.89-30.77,30.3-1.54,15.81,6.58,34.16,28.19,39.5,8.68,2.14,20.23,2,26.5-3.11,11.52-9.42,16.87-25.74,13.3-40.62-3.13-13.05-12.29-22.15-25.15-25A47.79,47.79,0,0,0,229.13,348Zm-2-2h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M240.76,389.67c-6.18-1.2-8.88-12-3.72-16s15.21,1.36,14.1,8.27C250.36,386.77,245.71,390.62,240.76,389.67Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="191.83" cy="332.89" r="2.31"/><path class="cls-24" d="M176.13,407.12a13.92,13.92,0,0,1-8.83-3.22h0c-3.83-3.15-3.79-5.86-3.09-7.58,1.81-4.42,9.6-5.72,13.19-5.4s8.38,1.36,10,4.47c.61,1.18,1,3.14-.55,5.76a12,12,0,0,1-8.4,5.76A13.24,13.24,0,0,1,176.13,407.12Zm-6.29-6.31a9.78,9.78,0,0,0,7.89,2.17,8.07,8.07,0,0,0,5.65-3.86c.34-.58.7-1.38.43-1.89-.46-.89-2.73-2-6.77-2.31-3.51-.31-8.45,1.28-9.13,2.93-.27.65.46,1.76,1.93,3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M165.22,420.86a8.93,8.93,0,0,1-5.31-1.66,8,8,0,0,1-3.17-7c.2-4.74,3.51-11.08,9.24-13.51a2,2,0,0,1,1.56,3.68c-4,1.7-6.65,6.51-6.8,10a4,4,0,0,0,1.53,3.62,5.83,5.83,0,0,0,5.35.45l1.06-.39c4.27-1.57,7.64-2.81,13.06-2.09a28.21,28.21,0,0,1,3.13.66c3.48.87,5.69,1.27,7.19-.59s.86-4.43.32-5.75c-1.36-3.33-4.58-6.19-7.32-6.52a2,2,0,0,1,.47-4c4.19.5,8.62,4.27,10.55,9,1.49,3.64,1.16,7.2-.9,9.77-3.21,4-7.87,2.83-11.28,2a25.36,25.36,0,0,0-2.68-.58c-4.44-.58-7.12.4-11.16,1.88l-1.08.39A11.06,11.06,0,0,1,165.22,420.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M176.32,432.68c-2.92,0-5.13-.74-6.72-2.25-2.9-2.77-3-7.44-2.79-12.38a2,2,0,1,1,4,.15c-.14,3.84-.14,7.72,1.55,9.34,1,1,2.74,1.31,5.32,1.09l.2,0c3.29-.28,4-.34,4.67-2.76a36.9,36.9,0,0,0,.84-9.07,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,39.11,39.11,0,0,1-1,10.13c-1.45,5.07-4.72,5.35-8.17,5.65l-.2,0Q177.14,432.68,176.32,432.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M104,352.05a2,2,0,0,1-.74-.14C98,349.85,93.29,344,91.72,337.8c-1.24-4.94-.36-9.51,2.47-12.85,3.35-4,10.47-4.29,15-2.12,4.91,2.34,7.35,5.93,9.93,9.73l1.09,1.6a2,2,0,0,1-3.28,2.28l-1.12-1.63c-2.46-3.63-4.41-6.49-8.34-8.37-3.07-1.46-8.22-1.31-10.25,1.09-2.53,3-2.29,6.71-1.64,9.3,1.25,5,5.08,9.77,9.11,11.37a2,2,0,0,1-.74,3.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M251.49,354a2,2,0,0,1-1.5-3.32c3.8-4.33,11.95-15.11,5.66-21.62-2.51-2.6-7.3-2.47-10.55-1-3.57,1.58-5.83,4.67-8,7.65l-.92,1.25a2,2,0,0,1-3.2-2.4l.9-1.21c2.38-3.25,5.08-6.93,9.62-8.94s11.23-2,15,1.91c6.05,6.27,4,16.12-5.53,27A2,2,0,0,1,251.49,354Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-26"><path class="cls-24" d="M625.88,469.74a2.91,2.91,0,0,1-1.54-.42,4.19,4.19,0,0,1-1.65-3.38c-.07-.82-.11-1.67-.15-2.52s-.07-1.55-.13-2.31c-.19-2.42-.29-5.09-.29-8.41a4.24,4.24,0,0,1,1.48-3.58c1.55-1.09,3.5-.4,4.66,0a21.33,21.33,0,0,1,9.27,5.93l.19.21c1.06,1.17,2.65,2.94,2,4.76-.35,1-1.32,1.71-2.88,2.76-.28.19-.52.34-.65.45-.95.78-1.93,1.46-2.89,2.13-.57.39-1.13.79-1.69,1.2-.29.21-.58.45-.88.68a14.24,14.24,0,0,1-3.3,2.15A4.13,4.13,0,0,1,625.88,469.74Zm.91-3.46h0Zm-.66-13.63v.05c0,3.21.09,5.78.28,8.09.06.81.1,1.63.14,2.44s.07,1.4.12,2.08a18.23,18.23,0,0,0,1.61-1.2c.33-.27.66-.53,1-.77.59-.44,1.19-.85,1.79-1.27.93-.64,1.81-1.25,2.62-1.93.19-.16.54-.4,1-.68l.9-.62c-.28-.35-.62-.73-.77-.9l-.22-.25a17.51,17.51,0,0,0-7.61-4.8C626.59,452.79,626.33,452.71,626.13,452.65Zm10,5.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M649.44,469.74a4.13,4.13,0,0,1-1.59-.35,14.23,14.23,0,0,1-3.3-2.15c-.3-.24-.59-.47-.88-.68-.55-.41-1.12-.8-1.68-1.19-1-.66-1.94-1.35-2.89-2.13-.13-.11-.37-.26-.65-.45-1.56-1.05-2.54-1.77-2.88-2.76-.63-1.81,1-3.58,2-4.75l.19-.21a21.33,21.33,0,0,1,9.27-5.93c1.16-.42,3.11-1.11,4.66,0a4.24,4.24,0,0,1,1.48,3.58c0,3.32-.1,6-.29,8.41-.06.77-.1,1.54-.13,2.32s-.08,1.69-.15,2.51h0a4.19,4.19,0,0,1-1.65,3.38A2.91,2.91,0,0,1,649.44,469.74Zm-9.65-10.88c.32.23.67.47.9.62.41.28.76.52,1,.68.82.67,1.7,1.28,2.63,1.93.6.42,1.2.83,1.79,1.27.33.24.66.5,1,.77a18.42,18.42,0,0,0,1.61,1.2c0-.68.08-1.37.11-2.07s.08-1.64.14-2.45c.18-2.31.27-4.88.28-8.1v-.05c-.2.05-.46.14-.8.26a17.51,17.51,0,0,0-7.61,4.8l-.22.24C640.41,458.13,640.07,458.5,639.79,458.86Zm-.65-.52" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M561.17,354.23a2,2,0,0,1-1.68-3.08,79.07,79.07,0,0,1,7.43-9.73c6.39-7.21,15.4-12.58,27.57-16.43,11.57-3.66,22.64-7.53,30.95-14.54a2,2,0,0,1,3.25,1.91,18.24,18.24,0,0,1-2,5.36c6.95-2,16.48-6.56,19.26-10a2,2,0,0,1,3.55,1.36,16.94,16.94,0,0,1-3,8.82A65.37,65.37,0,0,0,659,315.26c1.46-.41,2.94-.82,4.46-1.21a2,2,0,0,1,2.44,2.42,12.35,12.35,0,0,1-1.78,4c17.25,3.33,36.67,15.59,47.45,30.28a2,2,0,1,1-3.22,2.37c-11-15-31.37-27.27-48.49-29.27a2,2,0,0,1-1-3.57,9.15,9.15,0,0,0,1.26-1.18h-.05c-5.93,1.65-11.54,3.21-18.5,2.83a2,2,0,0,1-1.09-3.6,12.32,12.32,0,0,0,3.36-3.87c-6.57,4.13-16.49,7.75-21.54,8.2a2,2,0,0,1-1.7-3.29c.35-.4.71-.86,1.08-1.35-7.71,4.74-16.72,7.82-26,10.77-11.46,3.62-19.89,8.62-25.78,15.27a75.13,75.13,0,0,0-7.06,9.24A2,2,0,0,1,561.17,354.23Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M578.17,422.75c-6.6,0-13.4-1.41-18.19-5.32-12.68-10.37-18.57-28.31-14.66-44.65,3.5-14.6,13.77-24.79,28.19-27.94a50.35,50.35,0,0,1,13.11-1.2h0c21.69,1,33,17.78,34.56,33.91,1.71,17.53-7.28,37.86-31.21,43.77A50.23,50.23,0,0,1,578.17,422.75Zm6.37-75.16a47.79,47.79,0,0,0-10.18,1.15c-12.86,2.81-22,11.91-25.15,25-3.56,14.88,1.78,31.21,13.3,40.62,6.27,5.12,17.82,5.25,26.5,3.11,21.61-5.34,29.73-23.69,28.19-39.5-1.41-14.42-11.47-29.38-30.77-30.3Q585.49,347.59,584.53,347.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M571.9,391.22c6.18-1.2,8.88-12,3.72-16s-15.21,1.36-14.1,8.27C562.3,388.33,567,392.18,571.9,391.22Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M547.36,512.72a2,2,0,0,1-2-2c0-8.37-.06-16.77-.11-24.88-.2-29.54-.38-57.44,1.85-87a2,2,0,0,1,4,.3c-2.22,29.38-2,57.21-1.84,86.66.05,8.12.11,16.52.11,24.91A2,2,0,0,1,547.36,512.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M722.29,512.72h-.2a2,2,0,0,1-1.79-2.19c1.33-13.41.87-37.16.34-58.37-.17-6.66-.6-13.32-1-19.77-.58-8.87-1.17-18-1.07-27.26a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.1,9.06.49,18.16,1.07,27,.42,6.49.86,13.19,1,19.93.53,21.33,1,45.23-.36,58.87A2,2,0,0,1,722.29,512.72Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="520.33" cy="334.45" r="2.31"/><path class="cls-24" d="M694.2,423.2a50.2,50.2,0,0,1-11.8-1.43c-23.93-5.91-32.92-26.24-31.21-43.77,1.57-16.13,12.87-32.87,34.56-33.91a50.16,50.16,0,0,1,13.11,1.2c14.42,3.15,24.69,13.33,28.19,27.94,3.91,16.34-2,34.29-14.66,44.65C707.6,421.79,700.8,423.2,694.2,423.2ZM687.83,348q-1,0-1.9,0h0c-19.31.92-29.37,15.89-30.77,30.3-1.54,15.81,6.58,34.16,28.19,39.5,8.68,2.14,20.23,2,26.5-3.11,11.52-9.42,16.86-25.74,13.3-40.62C720,361.1,710.86,352,698,349.19A47.79,47.79,0,0,0,687.83,348Zm-2-2h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M676.47,389.67c-6.18-1.2-8.88-12-3.72-16s15.21,1.36,14.1,8.27C686.07,386.77,681.41,390.62,676.47,389.67Z" transform="translate(-53.25 -44.96)"/><circle class="cls-7" cx="627.54" cy="332.89" r="2.31"/><path class="cls-24" d="M634.83,407.12A13.92,13.92,0,0,1,626,403.9h0c-3.83-3.15-3.79-5.86-3.09-7.58,1.81-4.42,9.61-5.71,13.19-5.4s8.38,1.36,10,4.47c.61,1.18,1,3.14-.55,5.76a12,12,0,0,1-8.4,5.76A13.24,13.24,0,0,1,634.83,407.12Zm-6.29-6.31a9.78,9.78,0,0,0,7.88,2.17,8.08,8.08,0,0,0,5.65-3.86c.34-.58.7-1.38.43-1.89-.46-.89-2.73-2-6.77-2.31-3.51-.31-8.46,1.28-9.13,2.93-.26.65.46,1.76,1.93,3Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M623.92,420.86a8.93,8.93,0,0,1-5.31-1.66,8,8,0,0,1-3.17-7c.2-4.74,3.51-11.08,9.23-13.51a2,2,0,0,1,1.56,3.68c-4,1.7-6.65,6.51-6.8,10A4,4,0,0,0,621,416a5.83,5.83,0,0,0,5.35.45l1.06-.39c4.27-1.57,7.64-2.82,13.06-2.09a28.19,28.19,0,0,1,3.13.66c3.48.87,5.7,1.27,7.19-.59s.86-4.43.32-5.75c-1.36-3.33-4.58-6.19-7.32-6.52a2,2,0,1,1,.47-4c4.19.5,8.62,4.27,10.55,9,1.49,3.64,1.16,7.2-.9,9.77-3.21,4-7.87,2.83-11.28,2a25.6,25.6,0,0,0-2.68-.58c-4.44-.58-7.12.4-11.16,1.88l-1.08.39A11.05,11.05,0,0,1,623.92,420.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M635,432.68c-2.92,0-5.13-.74-6.72-2.25-2.9-2.76-3-7.44-2.79-12.38a2,2,0,0,1,4,.15c-.14,3.84-.14,7.72,1.55,9.34,1,1,2.74,1.31,5.32,1.09l.2,0c3.29-.28,4-.34,4.67-2.76a36.89,36.89,0,0,0,.84-9.07,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,39.06,39.06,0,0,1-1,10.13c-1.45,5.07-4.71,5.35-8.17,5.65l-.2,0Q635.84,432.68,635,432.68Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M562.68,352.05a2,2,0,0,1-.74-.14c-5.21-2.06-9.95-7.87-11.52-14.11-1.24-4.94-.37-9.51,2.46-12.85,3.35-4,10.47-4.29,15-2.12,4.91,2.34,7.35,5.93,9.93,9.74l1.09,1.59a2,2,0,1,1-3.29,2.28l-1.12-1.63c-2.46-3.63-4.41-6.5-8.34-8.37-3.07-1.47-8.23-1.31-10.25,1.09-2.53,3-2.29,6.71-1.64,9.3,1.25,5,5.08,9.77,9.11,11.37a2,2,0,0,1-.74,3.86Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M710.2,354a2,2,0,0,1-1.5-3.32c3.8-4.33,11.95-15.11,5.66-21.62-2.51-2.6-7.3-2.47-10.54-1-3.57,1.58-5.83,4.67-8,7.65l-.92,1.25a2,2,0,0,1-3.2-2.4l.89-1.21c2.38-3.25,5.08-6.93,9.62-8.94s11.23-2,15,1.91c6.05,6.26,4,16.12-5.53,27A2,2,0,0,1,710.2,354Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M658,401.5a2,2,0,0,1-1.75-3c1.28-2.33,6-3.06,16.21-3.8,1.16-.08,2.16-.16,2.84-.23a186.1,186.1,0,0,1,25.3-.51l3.1.08c6.61.14,14.83.32,19.92,3.76a2,2,0,1,1-2.24,3.31c-4.12-2.78-11.69-2.94-17.77-3.08l-3.16-.08a182.21,182.21,0,0,0-24.75.49c-.72.07-1.75.15-3,.24-3.18.23-11.54.84-13.11,1.92A2,2,0,0,1,658,401.5Zm1.75-1h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M550.5,403a2,2,0,0,1-.85-3.81c22.12-10.34,50.14-5.14,64.87-1.12a2,2,0,1,1-1.05,3.86c-14.2-3.88-41.16-8.92-62.13.88A2,2,0,0,1,550.5,403Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-24" d="M476,616.83c-37.71,0-75.29-.27-112.35-.54-33.89-.24-68.93-.5-103.27-.53-31.46,0-63.37-.27-94.23-.5l-35-.25a2,2,0,0,1,0-4h0l35,.25c30.85.23,62.75.46,94.2.5,34.35,0,69.4.29,103.29.53,86.22.62,175.38,1.26,262.11-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08a2,2,0,0,1,0,4c-4,0-8,0-12-.08-7.82-.08-15.91-.17-23.81.08C576.39,616.35,526.08,616.83,476,616.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M476,591.73c-37.71,0-75.28-.27-112.32-.54-33.9-.24-69-.5-103.31-.53-31.4,0-63.25-.27-94.05-.5q-26.27-.19-52.54-.35a2,2,0,0,1,0-4h0q26.28.14,52.55.35c30.8.23,62.64.46,94,.5,34.37,0,69.43.29,103.33.53,86.21.62,175.36,1.26,262.07-1.53,8-.26,16.12-.17,24-.09,4,0,7.95.08,11.91.08,5.21,0,11.36.13,19.37.4a2,2,0,0,1,1.93,2.07,2,2,0,0,1-2.07,1.93c-8-.27-14.08-.39-19.24-.39-4,0-8,0-12-.08-7.82-.08-15.9-.17-23.81.08C576.4,591.25,526.09,591.73,476,591.73Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M89,396a2,2,0,0,1-.1-4,88.43,88.43,0,0,0,11.52-1.63c3-.56,6.18-1.15,9.26-1.47a131.34,131.34,0,0,1,15.92-.45c1.88,0,3.77.05,5.71,0,1.54,0,3.15,0,4.81-.07,7.7-.16,16.42-.33,23.09,2.2a2,2,0,0,1-1.42,3.74c-5.94-2.26-14.25-2.09-21.59-1.94-1.69,0-3.33.07-4.88.07-2,0-3.87,0-5.77,0a128,128,0,0,0-15.45.42c-2.92.31-6,.88-8.95,1.43A91.36,91.36,0,0,1,89.1,396Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M256,394.5a2,2,0,0,1-.63-.1c-13.31-4.45-28.4-3-43-1.64-5.39.51-11,1-16.28,1.24a2,2,0,1,1-.15-4c5.21-.2,10.48-.7,16.06-1.23,15-1.42,30.54-2.89,44.65,1.83a2,2,0,0,1-.63,3.9Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M91.67,303.33a2,2,0,0,1-2-2V282.07c0-4.12.11-8.41.34-12.75.09-1.79.1-4.22.11-6.8,0-3.27,0-6.64.22-8.83a2,2,0,1,1,4,.35c-.18,2-.19,5.31-.21,8.49,0,2.62,0,5.1-.12,7-.22,4.33-.33,8.44-.33,12.55v19.26A2,2,0,0,1,91.67,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M110.33,303.33a2,2,0,0,1-2-2V222.5a2,2,0,0,1,4,0v78.83A2,2,0,0,1,110.33,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M122.33,303.74a2,2,0,0,1-.93-.23c-1.39-.73-1.91-2.27-2.88-11.69-.08-.74-.14-1.34-.19-1.73-.64-5.16-1.33-10.52-2-16-2.33-18.08-4.73-36.78-6-53.83a2,2,0,1,1,4-.29c1.23,16.93,3.63,35.58,5.95,53.61.7,5.47,1.39,10.83,2,16,.05.41.12,1,.2,1.81.2,1.92.78,7.61,1.31,9a2,2,0,0,1-1.48,3.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M151.33,298.33a2,2,0,0,1-2-1.91,53.62,53.62,0,0,0-1.07-6.68c-.3-1.53-.62-3.1-.83-4.51-.49-3.15-1-6.3-1.55-9.46-.38-2.26-.75-4.52-1.12-6.79-.75-4.62-1.46-9.25-2.18-13.88-2.2-14.2-4.47-28.86-7.59-43.13-5.25-.24-12.81-.26-17,3.52a2,2,0,1,1-2.67-3c5.43-4.85,13.91-4.84,21.43-4.46a2,2,0,0,1,1.85,1.56c3.33,14.87,5.69,30.12,8,44.88.72,4.62,1.43,9.24,2.17,13.86q.55,3.38,1.12,6.76c.53,3.17,1.06,6.34,1.55,9.51.21,1.33.51,2.86.81,4.35a55.52,55.52,0,0,1,1.14,7.28,2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M138.56,304a2,2,0,0,1-.14-4,17.88,17.88,0,0,0,5.7-1.36c.58-.22,1.13-.44,1.7-.59a11.3,11.3,0,0,0,2.52-1.24c.58-.34,1.18-.7,1.81-1a2,2,0,0,1,1.71,3.61c-.46.22-1,.51-1.49.83a14.58,14.58,0,0,1-3.48,1.65c-.38.1-.82.27-1.33.47a21.89,21.89,0,0,1-6.85,1.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M153.33,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.06-3.86.13-7.85,0-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.1-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.44.33,26.71,1,38.39.41,7.12.49,14.44.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,153.33,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M170.33,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.2s-.17-4.93-.17-7.48v-7.94c0-22,0-44.68,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.37-.27-5-1.78-2.09-8.12-1.15-12.31-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.77,38.77,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.86-1,66.78v7.95c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,170.33,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M527.75,303.33a2,2,0,0,1-2-2V222.5a2,2,0,0,1,4,0v78.83A2,2,0,0,1,527.75,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M539.75,303.74a2,2,0,0,1-.93-.23c-1.39-.73-1.91-2.27-2.88-11.68-.08-.74-.14-1.35-.19-1.75l-.58-4.7c-2.64-21.32-5.92-47.86-7.42-68.57a2,2,0,0,1,4-.29c1.49,20.6,4.76,47.09,7.4,68.37l.58,4.7c.05.41.12,1.05.2,1.83.2,1.91.78,7.59,1.31,9a2,2,0,0,1-1.48,3.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M568.75,298.33a2,2,0,0,1-2-1.91,53.52,53.52,0,0,0-1.07-6.67c-.3-1.53-.62-3.11-.84-4.52-.49-3.15-1-6.3-1.54-9.46-.38-2.26-.75-4.52-1.12-6.79-.75-4.62-1.46-9.25-2.18-13.88-2.19-14.18-4.46-28.83-7.58-43.08-6.43.09-17.21,2.45-21.34,6.14a2,2,0,0,1-2.67-3c5.46-4.88,18.89-7.47,25.72-7.12a2,2,0,0,1,1.85,1.56c3.33,14.87,5.69,30.13,8,44.88.72,4.62,1.43,9.24,2.17,13.85.36,2.25.74,4.51,1.12,6.76.53,3.17,1.06,6.34,1.55,9.51.21,1.33.51,2.87.81,4.35a55.44,55.44,0,0,1,1.14,7.27,2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M556,304a2,2,0,0,1-.14-4,17.89,17.89,0,0,0,5.7-1.36c.58-.22,1.13-.44,1.7-.59a11.29,11.29,0,0,0,2.52-1.24c.58-.34,1.18-.7,1.81-1a2,2,0,1,1,1.71,3.61c-.46.22-1,.51-1.49.82a14.58,14.58,0,0,1-3.48,1.65c-.38.1-.82.27-1.33.47a21.89,21.89,0,0,1-6.85,1.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M570.75,302.67a2,2,0,0,1-2-2c0-2,0-4.06.07-6.1.06-3.86.13-7.85-.05-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,570.75,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M587.75,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.84-.16-7.2s-.17-4.93-.17-7.48v-7.93c0-22,0-44.69,1-67,0-.33,0-.69.06-1.08.08-1.2.29-4.37-.27-5-1.78-2.09-8.12-1.15-12.31-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.68-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.87-1,66.8v7.93c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,587.75,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M175.66,301.33a2,2,0,0,1-2-1.66,70.59,70.59,0,0,1-.53-13.69,87.77,87.77,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.77,90.77,0,0,1,.15,10.86,66.62,66.62,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M180.34,197.94a62.68,62.68,0,0,1-7-.33,2,2,0,1,1,.46-4,105.46,105.46,0,0,0,14.11.14c2.39-.08,4.65-.15,6.72-.15a2,2,0,0,1,2,2,2,2,0,0,1-2,2h0c-2,0-4.24.07-6.6.15C185.46,197.85,182.85,197.94,180.34,197.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M197.66,303.33a2,2,0,0,1-2-1.65,139.45,139.45,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59v-4.22a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4A135.63,135.63,0,0,0,199.64,301,2,2,0,0,1,198,303.3,2.05,2.05,0,0,1,197.66,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M207,212.49a2,2,0,0,1-.5-.06c-2.37-.61-8.13-.82-11.23-.84a2,2,0,1,1,0-4c2.94,0,9.26.2,12.22,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21A2,2,0,0,1,208,303Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M239.67,304h0a2,2,0,0,1-2-2c0-2.18-.07-5-.16-8s-.18-5.94-.18-8.58c0-15.56-.34-31.45-.67-46.8-.29-13.42-.59-27.3-.66-40.92a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c.07,13.58.37,27.45.66,40.85.33,15.38.68,31.28.68,46.89,0,2.59.09,5.57.18,8.46s.18,5.89.16,8.15A2,2,0,0,1,239.67,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M238,199.67a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.73,0c-1.77,0-3.59,0-5.36,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,1,1-1.69-3.63c2.26-1,5-1.11,7.28-1.15l1.16,0c1.87-.07,3.74,0,5.56,0l2.68,0c4.73,0,11.73.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M430.83,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.71,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,430.83,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M447.83,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.21s-.17-4.93-.17-7.47v-8c0-22,0-44.66,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,4.94.17,7.33s.17,4.87.17,7.35A2,2,0,0,1,447.83,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M453.16,301.33a2,2,0,0,1-2-1.66,70.61,70.61,0,0,1-.53-13.69,87.64,87.64,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.75,90.75,0,0,1,.15,10.86,66.58,66.58,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M457.84,197.94a62.68,62.68,0,0,1-7-.33,2,2,0,1,1,.46-4,105.2,105.2,0,0,0,14.11.14c2.41-.08,4.65-.13,6.77-.15a2,2,0,0,1,0,4h0c-2,0-4.24.07-6.6.15C463,197.85,460.35,197.94,457.84,197.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M475.16,303.33a2,2,0,0,1-2-1.65,139.55,139.55,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59v-4.22a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4A135.64,135.64,0,0,0,477.13,301a2,2,0,0,1-1.62,2.32A2,2,0,0,1,475.16,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M484.5,212.49a2,2,0,0,1-.5-.06c-2.37-.61-8.13-.84-11.22-.84h0a2,2,0,1,1,0-4h0c2.94,0,9.26.2,12.22,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M485.5,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21a2,2,0,0,1-1.83,2.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M517.17,304h0a2,2,0,0,1-2-2c0-2.18-.07-5-.16-8s-.18-5.94-.18-8.59c0-15.56-.34-31.44-.67-46.79-.29-13.43-.59-27.31-.66-40.93a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c.07,13.58.37,27.45.66,40.86.33,15.38.67,31.28.67,46.88,0,2.59.09,5.58.18,8.47s.18,5.89.16,8.15A2,2,0,0,1,517.17,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M515.5,199.67a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.73,0c-1.77,0-3.59,0-5.36,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,0,1-1.69-3.63c2.26-1,5-1.11,7.28-1.15l1.16,0c1.87-.07,3.74,0,5.56,0l2.68,0c4.73,0,11.73.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M637.34,302.67a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.75-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.71,1,38.39.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,637.34,302.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M654.34,303.33h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.2s-.17-4.93-.17-7.48v-8c0-22,0-44.66,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a40,40,0,0,1-5.15.57h0a2,2,0,0,1,0-4,38.79,38.79,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,654.34,303.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M659.67,301.33a2,2,0,0,1-2-1.66,70.61,70.61,0,0,1-.53-13.69,87.64,87.64,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,1,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.75,90.75,0,0,1,.15,10.86,66.58,66.58,0,0,0,.47,12.91,2,2,0,0,1-2,2.34Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M681.67,303.33a2,2,0,0,1-2-1.65,139.55,139.55,0,0,1-1.7-17.26c-1.2-25.62-1.32-50.17-1.33-73.13a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,22.91.13,47.4,1.33,72.94A135.64,135.64,0,0,0,683.64,301a2,2,0,0,1-2,2.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M692,303a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.2-.08-30.69-.17-45.66l-.06-11.11a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2l.06,11.11c.08,15,.17,30.47.17,45.68,0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21A2,2,0,0,1,692,303Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M253,303.33a2,2,0,0,1-1.19-.4c-.74-.55-1.6-1.25-2.51-2-2.68-2.19-6.36-5.2-8.67-5.64a2,2,0,1,1,.75-3.93c3.31.63,7.27,3.87,10.46,6.47.87.72,1.7,1.39,2.37,1.89a2,2,0,0,1-1.2,3.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M241.33,293a2,2,0,0,1-1.94-2.48c2.64-10.63,9.2-19.77,15.55-28.61,2-2.82,3.94-5.48,5.73-8.19,3.93-5.95,7.81-12.09,11.57-18,4.56-7.21,9.27-14.66,14.11-21.83.44-.66.89-1.29,1.33-1.91a29.33,29.33,0,0,0,3.24-5.33c.53-1.23,2.4-5.38,4.32-7.35a2,2,0,1,1,2.86,2.79,25,25,0,0,0-3.51,6.14,32.85,32.85,0,0,1-3.65,6.06c-.42.6-.85,1.2-1.28,1.84-4.81,7.13-9.5,14.55-14,21.74-3.77,6-7.66,12.11-11.61,18.09-1.83,2.77-3.86,5.59-5.81,8.32-6.13,8.53-12.46,17.35-14.91,27.24A2,2,0,0,1,241.33,293Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M309.67,212a2,2,0,0,1-1.49-.67c-2.4-2.68-5.79-4.76-9.06-6.77-1.18-.72-2.39-1.47-3.55-2.23a2,2,0,0,1,2.21-3.34c1.1.73,2.23,1.42,3.43,2.16,3.52,2.16,7.16,4.39,10,7.51a2,2,0,0,1-1.49,3.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M254,304.33a2,2,0,0,1-1.92-2.58c.78-2.6,2.65-4.64,4.45-6.62a32.78,32.78,0,0,0,2.18-2.56c2.36-3.22,4.48-6.69,6.54-10.05l3.33-5.44c3.09-5.06,6.29-10.29,9.55-15.45a408.31,408.31,0,0,0,21.48-38.44c.38-.79.77-1.6,1.16-2.42,2-4.17,4.2-8.89,7.47-12.18a2,2,0,1,1,2.84,2.82c-2.78,2.8-4.77,7-6.69,11.07-.4.84-.79,1.67-1.18,2.47a412.46,412.46,0,0,1-21.69,38.82c-3.25,5.13-6.44,10.35-9.52,15.39l-3.33,5.44c-2.1,3.43-4.27,7-6.73,10.33a35.92,35.92,0,0,1-2.45,2.89c-1.5,1.65-3.06,3.36-3.58,5.09A2,2,0,0,1,254,304.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603.43,303.32a2,2,0,0,1-.75-.15c-.85-.35-1.86-.81-2.93-1.3-3.15-1.45-7.48-3.43-9.81-3.28a2,2,0,1,1-.26-4c3.38-.23,8,1.92,11.75,3.64,1,.47,2,.92,2.77,1.23a2,2,0,0,1-.76,3.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M589.54,296.25a2,2,0,0,1-2-2c-.12-11,3.94-21.45,7.86-31.6,1.25-3.24,2.43-6.29,3.49-9.36,2.31-6.75,4.53-13.67,6.67-20.36,2.6-8.12,5.29-16.51,8.17-24.67.26-.75.54-1.47.81-2.18a29.41,29.41,0,0,0,1.8-6c.2-1.32,1-5.82,2.34-8.2a2,2,0,1,1,3.47,2,25.08,25.08,0,0,0-1.86,6.83,32.91,32.91,0,0,1-2,6.78c-.26.68-.52,1.38-.78,2.1-2.86,8.1-5.54,16.47-8.13,24.56-2.15,6.71-4.37,13.65-6.7,20.44-1.08,3.14-2.33,6.38-3.54,9.51-3.79,9.8-7.7,19.92-7.59,30.11a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M635.33,200.68a2,2,0,0,1-1.11-.33c-3-2-6.8-3.15-10.47-4.27-1.32-.4-2.68-.82-4-1.27a2,2,0,1,1,1.3-3.78c1.25.43,2.52.82,3.87,1.23,3.95,1.21,8,2.45,11.52,4.77a2,2,0,0,1-1.11,3.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.65,304h-.08a2,2,0,0,1-1.92-2.08c.11-2.71,1.4-5.16,2.65-7.53a32.79,32.79,0,0,0,1.47-3c1.47-3.71,2.66-7.6,3.81-11.37l1.86-6.13c1.72-5.67,3.49-11.52,5.36-17.33A408.38,408.38,0,0,0,628.92,214c.17-.86.34-1.74.51-2.64.86-4.53,1.84-9.66,4.17-13.66a2,2,0,1,1,3.46,2c-2,3.41-2.86,8-3.7,12.39-.17.92-.35,1.82-.52,2.69a412.59,412.59,0,0,1-11.24,43c-1.85,5.77-3.63,11.61-5.34,17.26l-1.86,6.13c-1.17,3.85-2.38,7.83-3.92,11.69a35.72,35.72,0,0,1-1.65,3.41c-1,2-2.12,4-2.19,5.82A2,2,0,0,1,604.65,304Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M310,304.86a2,2,0,0,1-2-1.91c-.52-11.52-.63-20-.34-26,.76-16,.71-32.73.67-48.9,0-13.26-.08-27,.33-40.1a2,2,0,0,1,4,.13c-.41,13.07-.37,26.74-.33,40,0,16.22.1,33-.67,49.1-.28,5.88-.17,14.28.34,25.67a2,2,0,0,1-1.91,2.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M323.33,305.14a2,2,0,0,1-2-2V278.83c0-5.5-.21-11.11-.41-16.53-.3-8.08-.62-16.43-.25-24.7.34-7.62.33-15.47.33-23.06v-2.2c0-2.18.07-4.55.14-7.06a126.8,126.8,0,0,0-.26-17,2,2,0,1,1,4-.46,129.52,129.52,0,0,1,.29,17.58c-.07,2.48-.14,4.82-.14,6.94v2.2c0,7.64,0,15.53-.34,23.24-.36,8.1,0,16.37.25,24.37.21,5.46.42,11.11.42,16.68v24.31A2,2,0,0,1,323.33,305.14Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M340.5,221a2,2,0,0,1-.78-.16c-2.63-1.12-8.49-.91-12.77-.75-1.38.05-2.69.1-3.76.1a2,2,0,0,1,0-4c1,0,2.27,0,3.61-.1,4.92-.18,11-.4,14.49,1.07a2,2,0,0,1-.79,3.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M338.75,305.14a2,2,0,0,1-2-2V289.69c0-11.85.45-23.83.88-35.41s.88-23.52.87-35.28a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,11.84-.44,23.83-.87,35.43s-.87,23.48-.87,35.26v13.45A2,2,0,0,1,338.75,305.14Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M346.25,305.29a2,2,0,0,1-2-2V293c0-9.65-.1-19.65-.19-29.32s-.19-19.77-.19-29.53a2,2,0,1,1,4,0c0,9.74.1,19.78.19,29.49s.19,19.68.19,29.35v10.31A2,2,0,0,1,346.25,305.29Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M380.14,236.27h-.33c-16.41-.09-27.82-.13-33.94-.13a2,2,0,0,1,0-4c6.12,0,17.54,0,34,.13h1.38v2l2,0C383.19,236.15,381.69,236.27,380.14,236.27Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M380,303.28a2,2,0,0,1-2-2c0-9.68.36-21.38,1-32.94.48-8.65.38-17.78.28-26.61,0-2.51-.06-5-.07-7.44a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,2.44,0,4.92.07,7.42.1,8.9.21,18.09-.28,26.88-.64,11.49-1,23.11-1,32.71A2,2,0,0,1,380,303.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M384.18,302.4a2,2,0,0,1-2-2c-.05-4.06-.14-11.62-.4-16.81-.38-7.67,0-15.44.28-22.95.22-5.06.45-10.3.45-15.42,0-6.33.06-13.14.13-19.74s.13-13.42.13-19.76a2,2,0,0,1,4,0c0,6.35-.06,13.19-.12,19.79s-.12,13.39-.12,19.7c0,5.2-.23,10.49-.45,15.59-.32,7.42-.65,15.09-.28,22.58.26,5.27.36,12.88.41,17a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M425,208c-2.64,0-5.15-.2-7.58-.39-2-.16-3.87-.31-5.84-.36-4.83-.13-9.6.07-13.22.26-2.63.14-10.62.24-13.62.24a2,2,0,0,1,0-4c3,0,10.84-.1,13.41-.23,3.69-.19,8.56-.39,13.53-.26,2.08.05,4.1.21,6.05.37,2.35.19,4.78.38,7.26.38a2,2,0,0,1,0,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M424.5,296a2,2,0,0,1-2-2V279.51c0-12.4.19-24.88.38-37s.37-24.48.37-36.81a2,2,0,0,1,4,0c0,12.36-.19,24.82-.37,36.87s-.37,24.52-.37,36.89V294A2,2,0,0,1,424.5,296Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M657.67,197.33a2,2,0,0,1,0-4c1.61,0,3.14-.17,4.77-.34,1.35-.14,2.75-.28,4.18-.33a2,2,0,0,1,.14,4c-1.29,0-2.56.17-3.91.31-1.65.17-3.35.34-5.15.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M516.67,225.33a2,2,0,0,1-.88-3.8c2.92-1.42,9.36-1.86,12.44-.32a2,2,0,0,1-1.79,3.58c-1.87-.94-7-.59-8.9.34A2,2,0,0,1,516.67,225.33Z" transform="translate(-53.25 -44.96)"/><g class="cls-27"><path class="cls-24" d="M161.5,730.09a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.71-.3-6.38-.38-12.91-.45-19.22-.08-7-.17-14.32-.57-21.35-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.38.41,7.12.49,14.45.57,21.53.07,6.28.15,12.77.45,19.08.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,161.5,730.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M178.5,730.76h0a2,2,0,0,1-2-2c0-2.41-.08-4.85-.16-7.21s-.17-4.93-.17-7.47v-7.94c0-22,0-44.67,1-67,0-.32,0-.69.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.32-.53a39.88,39.88,0,0,1-5.15.57h0a2,2,0,0,1,0-4,39,39,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.21,1.21,7.88,0,.36,0,.7-.06,1-1,22.2-1,44.86-1,66.78v7.95c0,2.48.08,4.95.17,7.34s.17,4.87.17,7.35A2,2,0,0,1,178.5,730.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.83,728.76a2,2,0,0,1-2-1.66,70.59,70.59,0,0,1-.53-13.69,87.87,87.87,0,0,0-.14-10.38c-1.94-20.3-1.75-41.52-1.57-62,.05-5.91.11-12,.11-17.95a2,2,0,0,1,4,0c0,5.94-.05,12.06-.11,18-.18,20.42-.37,41.53,1.55,61.62a90.77,90.77,0,0,1,.15,10.86,66.65,66.65,0,0,0,.47,12.91,2,2,0,0,1-1.63,2.31Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M188.51,625.36a62.93,62.93,0,0,1-7-.33,2,2,0,0,1,.46-4,105.22,105.22,0,0,0,14.11.14c2.39-.08,4.65-.15,6.72-.15a2,2,0,1,1,0,4s0,0,0,0c-2,0-4.24.07-6.6.15C193.63,625.28,191,625.36,188.51,625.36Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M205.83,730.76a2,2,0,0,1-2-1.65,139.57,139.57,0,0,1-1.7-17.26c-1.34-28.65-1.34-55.82-1.34-84.59V623a2,2,0,0,1,4,0v4.22c0,28.72,0,55.84,1.33,84.4a135.64,135.64,0,0,0,1.64,16.74,2,2,0,0,1-2,2.35Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M215.17,639.92a2,2,0,0,1-.5-.06c-2.37-.61-8.12-.84-11.21-.84h0a2,2,0,0,1,0-4h0c2.94,0,9.25.2,12.21,1a2,2,0,0,1-.5,3.94Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.17,730.43a2,2,0,0,1-1.84-1.21c-1.15-2.66-1-7-.9-10.92,0-1.08.07-2.11.07-3,0-15.16-.08-30.61-.17-45.54s-.17-30.43-.17-45.64a2,2,0,0,1,4,0c0,15.2.08,30.67.17,45.62s.17,30.39.17,45.56c0,1,0,2-.07,3.15-.1,3.28-.23,7.37.57,9.21a2,2,0,0,1-1.83,2.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M246.16,627.1a2,2,0,0,1-.71-.13c-3.41-1.29-9.72-1.87-14.46-1.87l-2.72,0c-1.77,0-3.6,0-5.37,0l-1.23,0c-1.86,0-4.18.09-5.67.78a2,2,0,1,1-1.69-3.63c2.26-1,5-1.11,7.27-1.15l1.16,0c1.87-.07,3.75,0,5.58,0l2.67,0c4.73,0,11.72.56,15.87,2.13a2,2,0,0,1-.71,3.87Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-28"><path class="cls-24" d="M578.92,730.09a2,2,0,0,1-2-2c0-2,0-4.07.07-6.11.07-3.86.13-7.85,0-11.7-.3-6.39-.38-12.92-.45-19.23-.08-7-.17-14.32-.57-21.34-.67-11.76-1-25.11-1-38.62a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.43.33,26.7,1,38.38.41,7.12.49,14.44.57,21.52.07,6.28.15,12.77.45,19.09.19,4,.12,8,.05,12,0,2-.07,4-.07,6A2,2,0,0,1,578.92,730.09Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M595.92,730.76h0a2,2,0,0,1-2-2c0-2.41-.08-4.84-.16-7.2s-.17-4.93-.17-7.48v-8c0-22,0-44.66,1-66.95,0-.32,0-.68.06-1.07.08-1.2.29-4.38-.27-5-1.78-2.09-8.12-1.15-12.31-.53a39.9,39.9,0,0,1-5.15.57h0a2,2,0,0,1,0-4,39,39,0,0,0,4.58-.52c5.67-.84,12.74-1.89,16,1.9,1.61,1.89,1.39,5.22,1.21,7.89,0,.36,0,.69-.06,1-1,22.19-1,44.85-1,66.76v8c0,2.48.08,5,.17,7.34s.17,4.87.17,7.34A2,2,0,0,1,595.92,730.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M611.59,730.75a2,2,0,0,1-.75-.15c-.85-.35-1.86-.81-2.93-1.3-3.15-1.45-7.45-3.44-9.81-3.28a2,2,0,1,1-.26-4c3.38-.21,8,1.92,11.75,3.64,1,.47,2,.92,2.76,1.23a2,2,0,0,1-.76,3.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M597.71,723.68a2,2,0,0,1-2-2c-.12-11,3.94-21.45,7.86-31.6,1.25-3.24,2.43-6.29,3.48-9.36,2.31-6.75,4.53-13.67,6.67-20.36,2.6-8.12,5.29-16.51,8.17-24.67.26-.75.54-1.47.81-2.18a29.33,29.33,0,0,0,1.8-6c.2-1.32,1-5.82,2.34-8.21a2,2,0,0,1,3.47,2,25.08,25.08,0,0,0-1.86,6.83,32.84,32.84,0,0,1-2,6.78c-.26.68-.52,1.38-.78,2.1-2.86,8.1-5.54,16.47-8.13,24.55-2.15,6.71-4.37,13.65-6.7,20.44-1.08,3.14-2.33,6.38-3.54,9.51-3.79,9.8-7.7,19.93-7.59,30.11a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M643.5,628.11a2,2,0,0,1-1.11-.33c-3-2-6.8-3.15-10.47-4.27-1.32-.4-2.68-.82-4-1.27a2,2,0,1,1,1.3-3.78c1.25.43,2.52.82,3.86,1.23,4,1.21,8,2.45,11.52,4.77a2,2,0,0,1-1.11,3.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M612.81,731.47h-.08a2,2,0,0,1-1.92-2.08c.11-2.71,1.4-5.16,2.65-7.53a32.54,32.54,0,0,0,1.47-3c1.47-3.71,2.66-7.61,3.81-11.38l1.86-6.12c1.72-5.67,3.49-11.53,5.36-17.33a408,408,0,0,0,11.13-42.6c.17-.86.34-1.74.51-2.64.86-4.53,1.84-9.66,4.17-13.67a2,2,0,0,1,3.46,2c-2,3.41-2.86,8-3.7,12.4-.17.92-.35,1.82-.52,2.69a412.27,412.27,0,0,1-11.24,43c-1.86,5.77-3.63,11.61-5.34,17.27l-1.86,6.12c-1.17,3.85-2.38,7.83-3.92,11.69a35.94,35.94,0,0,1-1.65,3.41c-1,2-2.12,4-2.19,5.83A2,2,0,0,1,612.81,731.47Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-29"><path class="cls-24" d="M694.89,584.32h-.09a2,2,0,0,1-1.91-2.09,55.68,55.68,0,0,1,1.14-7.28c.29-1.48.6-3,.8-4.34.49-3.16,1-6.33,1.55-9.5q.57-3.38,1.12-6.77c.75-4.62,1.46-9.24,2.18-13.86,2.28-14.75,4.64-30,8-44.87A2,2,0,0,1,709.5,494c7.52-.39,16-.39,21.43,4.46a2,2,0,1,1-2.67,3c-4.23-3.78-11.79-3.76-17-3.52-3.13,14.27-5.4,28.93-7.59,43.13-.72,4.63-1.43,9.26-2.18,13.89q-.55,3.4-1.12,6.79c-.53,3.16-1.05,6.31-1.54,9.46-.22,1.41-.53,3-.83,4.51a53.58,53.58,0,0,0-1.07,6.68A2,2,0,0,1,694.89,584.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M707.66,590h-.15a21.87,21.87,0,0,1-6.85-1.62c-.51-.2-1-.37-1.33-.47a14.59,14.59,0,0,1-3.49-1.65c-.53-.31-1-.6-1.49-.82a2,2,0,1,1,1.71-3.61c.63.3,1.23.65,1.81,1a11.31,11.31,0,0,0,2.52,1.24c.57.16,1.11.37,1.7.59a17.86,17.86,0,0,0,5.7,1.36,2,2,0,0,1-.14,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M692.88,588.65a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.81.45-19.09.08-7.08.17-14.41.57-21.52.67-11.68,1-25,1-38.39a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.5-.33,26.86-1,38.62-.4,7-.49,14.3-.57,21.34-.07,6.32-.15,12.84-.45,19.23-.18,3.85-.12,7.84,0,11.7,0,2,.07,4.08.07,6.11A2,2,0,0,1,692.88,588.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M675.88,589.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-8c0-21.91,0-44.57-1-66.76,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.22-3.79,10.28-2.74,16-1.9a38.94,38.94,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.38,0,.75.06,1.07,1,22.29,1,45,1,66.95v8c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.21A2,2,0,0,1,675.88,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M670.55,587.32l-.34,0a2,2,0,0,1-1.63-2.31,66.62,66.62,0,0,0,.47-12.9,90.82,90.82,0,0,1,.16-10.87c1.92-20.09,1.73-41.2,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,1,1,4,0c0,5.92.05,12,.11,18,.18,20.52.37,41.73-1.57,62a87.71,87.71,0,0,0-.14,10.38,70.56,70.56,0,0,1-.53,13.69A2,2,0,0,1,670.55,587.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M665.88,483.92c-2.51,0-5.12-.08-7.68-.17-2.36-.08-4.59-.15-6.59-.15h-.05a2,2,0,1,1,.05-4c2.07,0,4.33.07,6.72.15a105.2,105.2,0,0,0,14.1-.14,2,2,0,0,1,.46,4A62.84,62.84,0,0,1,665.88,483.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M648.55,589.32a2,2,0,0,1-2-2.35,135.59,135.59,0,0,0,1.64-16.74c1.34-28.56,1.34-55.68,1.33-84.4V481.6a2,2,0,1,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59a139.52,139.52,0,0,1-1.7,17.26A2,2,0,0,1,648.55,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M639.22,498.47a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,639.22,498.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M638.22,589a2,2,0,0,1-1.83-2.8c.8-1.84.67-5.92.57-9.21,0-1.12-.07-2.19-.07-3.15,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,1,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.92,0,1.95.07,3,.12,3.87.25,8.26-.9,10.92A2,2,0,0,1,638.22,589Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M606.55,590a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.67-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M608.22,485.65a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.88-2.13l2.69,0c1.81,0,3.69,0,5.55,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.5-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.58,0-5.34,0l-2.75,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,608.22,485.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M593.22,589.32a2,2,0,0,1-1.2-3.6c.67-.5,1.49-1.17,2.37-1.89,3.18-2.6,7.14-5.84,10.45-6.47a2,2,0,1,1,.75,3.93c-2.31.44-6,3.45-8.67,5.64-.91.75-1.77,1.45-2.51,2A2,2,0,0,1,593.22,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.88,579a2,2,0,0,1-1.94-1.52c-2.45-9.89-8.79-18.71-14.92-27.24-2-2.72-4-5.54-5.81-8.31-4-6-7.85-12.14-11.61-18.09-4.54-7.18-9.24-14.61-14-21.73-.43-.63-.86-1.24-1.28-1.84a32.89,32.89,0,0,1-3.65-6.05,25,25,0,0,0-3.51-6.14,2,2,0,1,1,2.86-2.79c1.92,2,3.79,6.13,4.32,7.35a29.38,29.38,0,0,0,3.24,5.33c.44.62.89,1.25,1.33,1.92,4.84,7.17,9.55,14.62,14.11,21.83,3.76,5.94,7.64,12.08,11.57,18,1.79,2.71,3.7,5.37,5.72,8.19,6.35,8.84,12.91,18,15.55,28.61a2,2,0,0,1-1.94,2.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M592.22,590.32a2,2,0,0,1-1.91-1.42c-.52-1.73-2.08-3.44-3.58-5.09a36.17,36.17,0,0,1-2.45-2.89c-2.45-3.34-4.62-6.89-6.72-10.31l-3.35-5.49c-3.08-5-6.26-10.25-9.5-15.37A412.7,412.7,0,0,1,543,510.94c-.39-.8-.78-1.63-1.18-2.47-1.92-4.07-3.91-8.27-6.69-11.07a2,2,0,1,1,2.84-2.82c3.26,3.29,5.5,8,7.47,12.18.39.83.78,1.64,1.16,2.43a408.3,408.3,0,0,0,21.47,38.44c3.26,5.15,6.45,10.37,9.54,15.42l3.35,5.48c2.06,3.35,4.18,6.82,6.53,10a32.83,32.83,0,0,0,2.18,2.56c1.8,2,3.67,4,4.45,6.62a2,2,0,0,1-1.92,2.58Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-30"><path class="cls-24" d="M113.55,589.32a2,2,0,0,1-2-2V508.48a2,2,0,0,1,4,0v78.83A2,2,0,0,1,113.55,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M101.55,589.72a2,2,0,0,1-1.48-3.35c.52-1.38,1.11-7.07,1.31-9,.08-.77.15-1.41.2-1.81l.58-4.72c2.63-21.27,5.9-47.75,7.39-68.35a2,2,0,1,1,4,.29c-1.5,20.7-4.78,47.23-7.41,68.55l-.58,4.72c0,.39-.11,1-.19,1.73-1,9.42-1.49,11-2.88,11.69A2,2,0,0,1,101.55,589.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M72.55,584.32h-.09a2,2,0,0,1-1.91-2.09,55.58,55.58,0,0,1,1.14-7.28c.29-1.49.6-3,.81-4.35.49-3.16,1-6.33,1.55-9.5.38-2.25.75-4.51,1.12-6.77.74-4.62,1.46-9.24,2.17-13.86,2.28-14.75,4.64-30,8-44.88A2,2,0,0,1,87.17,494c6.85-.36,20.26,2.25,25.72,7.12a2,2,0,1,1-2.67,3c-4.13-3.69-14.91-6-21.34-6.14-3.12,14.25-5.39,28.9-7.58,43.08-.72,4.63-1.43,9.26-2.18,13.88-.37,2.26-.74,4.53-1.12,6.79-.53,3.16-1.05,6.31-1.54,9.46-.22,1.41-.53,3-.83,4.51a53.65,53.65,0,0,0-1.07,6.68A2,2,0,0,1,72.55,584.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.47,588.65a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.39a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.23-.18,3.86-.11,7.85,0,11.71,0,2,.07,4.08.07,6.11A2,2,0,0,1,210.47,588.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193.47,589.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a39,39,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.95c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.21A2,2,0,0,1,193.47,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M188.14,587.32l-.34,0a2,2,0,0,1-1.63-2.31,66.63,66.63,0,0,0,.47-12.91,90.75,90.75,0,0,1,.15-10.86c1.92-20.09,1.73-41.21,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.95.18,20.52.37,41.74-1.57,62a87.75,87.75,0,0,0-.14,10.38,70.6,70.6,0,0,1-.53,13.69A2,2,0,0,1,188.14,587.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M183.47,483.92c-2.51,0-5.12-.08-7.68-.17-2.38-.08-4.63-.15-6.64-.15h0a2,2,0,0,1,0-4h.05c2.07,0,4.33.07,6.72.15a105.06,105.06,0,0,0,14.1-.14,2,2,0,0,1,.46,4A62.84,62.84,0,0,1,183.47,483.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M166.14,589.32a2,2,0,0,1-2-2.35,135.67,135.67,0,0,0,1.64-16.74c1.34-28.56,1.34-55.68,1.33-84.4V481.6a2,2,0,0,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59a139.43,139.43,0,0,1-1.7,17.26A2,2,0,0,1,166.14,589.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M156.8,498.47a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,156.8,498.47Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M155.81,589a2,2,0,0,1-1.83-2.8c.8-1.84.67-5.92.57-9.21,0-1.12-.07-2.19-.07-3.15,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,1,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.92,0,1.95.07,3,.12,3.87.25,8.26-.9,10.92A2,2,0,0,1,155.81,589Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M124.14,590a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.68-46.88.29-13.41.59-27.28.66-40.87a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M125.81,485.65a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.87-2.13l2.69,0c1.81,0,3.69,0,5.55,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.5-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.58,0-5.35,0l-2.74,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,125.81,485.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.31,494a2,2,0,1,1,0-4c2.48,0,4.91-.19,7.26-.38,2-.16,4-.32,6.06-.37,5-.13,9.84.07,13.53.26,2.43.13,10.08.23,13.41.23a2,2,0,0,1,0,4c-3,0-11-.1-13.61-.24-3.62-.19-8.39-.39-13.22-.26-2,.05-3.85.2-5.85.36C221.45,493.78,218.95,494,216.31,494Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M216.81,582a2,2,0,0,1-2-2V565.5c0-12.37-.19-24.84-.37-36.89s-.37-24.51-.37-36.87a2,2,0,0,1,4,0c0,12.33.19,24.77.37,36.81s.38,24.55.38,37V580A2,2,0,0,1,216.81,582Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M124.64,511.32a2,2,0,0,1-.87-.2c-1.92-.93-7-1.28-8.9-.34a2,2,0,1,1-1.79-3.58c3.07-1.54,9.51-1.1,12.44.32a2,2,0,0,1-.88,3.8Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-31"><path class="cls-24" d="M625.89,161.66a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.81.45-19.09.08-7.08.17-14.41.57-21.52.67-11.68,1-25,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.5-.33,26.86-1,38.62-.4,7-.49,14.3-.57,21.34-.07,6.31-.15,12.84-.45,19.23-.18,3.85-.12,7.84,0,11.7,0,2,.07,4.08.07,6.11A2,2,0,0,1,625.89,161.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M608.89,162.32a2,2,0,0,1-2-2c0-2.47.08-4.95.17-7.34s.17-4.86.17-7.34v-8c0-21.91,0-44.57-1-66.76,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a38.75,38.75,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.56-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,66.95v8c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,608.89,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M251.47,162.32a2,2,0,0,1-2-2V81.49a2,2,0,1,1,4,0v78.83A2,2,0,0,1,251.47,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M238.84,164.65a2,2,0,0,1-1.49-3.34c.21-.53.95-3,2.15-12.73l.58-4.72c2.63-21.27,5.9-47.75,7.39-68.34a2,2,0,0,1,4,.29c-1.5,20.7-4.78,47.23-7.41,68.54l-.58,4.72c-1.77,14.33-2.66,14.8-3.7,15.35A2,2,0,0,1,238.84,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210.47,157.32h-.09a2,2,0,0,1-1.91-2.09,55.62,55.62,0,0,1,1.14-7.28c.29-1.49.6-3,.81-4.35.49-3.16,1-6.33,1.55-9.51.38-2.25.75-4.51,1.12-6.76.74-4.61,1.46-9.24,2.17-13.86,2.28-14.75,4.64-30,8-44.88A2,2,0,0,1,225.08,67c6.84-.35,20.26,2.25,25.72,7.12a2,2,0,1,1-2.67,3c-4.13-3.69-14.91-6-21.34-6.14-3.12,14.26-5.39,28.9-7.58,43.08-.72,4.63-1.43,9.26-2.18,13.88q-.55,3.39-1.12,6.78c-.53,3.16-1.05,6.32-1.55,9.47-.22,1.41-.53,3-.83,4.51a53.54,53.54,0,0,0-1.07,6.68A2,2,0,0,1,210.47,157.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M224.5,164.58h-.15a18.39,18.39,0,0,1-7.71-2.77,11.93,11.93,0,0,0-1.73-.87,14.6,14.6,0,0,1-3.48-1.65c-.53-.31-1-.6-1.49-.82a2,2,0,1,1,1.71-3.61c.63.3,1.23.65,1.81,1a11.28,11.28,0,0,0,2.52,1.24,12.72,12.72,0,0,1,2.62,1.24,14.89,14.89,0,0,0,6,2.27,2,2,0,0,1-.14,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M208.47,161.66a2,2,0,0,1-2-2c0-2,0-4-.07-6-.07-3.92-.13-8,.05-12,.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.22-.18,3.86-.11,7.85,0,11.71,0,2,.07,4.08.07,6.11A2,2,0,0,1,208.47,161.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M191.47,162.32a2,2,0,0,1-2-2c0-2.48.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.17-2.67-.39-6,1.21-7.88,3.21-3.79,10.28-2.74,16-1.9a38.76,38.76,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.57-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.94c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,191.47,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M603.56,163.53a2,2,0,0,1-2-2.34c.7-4.07.59-9.54.47-14.84a109.87,109.87,0,0,1,.16-12.13c1.92-20.09,1.74-41.21,1.55-61.63-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.94.18,20.52.37,41.74-1.57,62a107,107,0,0,0-.14,11.66c.12,5.49.24,11.16-.53,15.61A2,2,0,0,1,603.56,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M598.88,56.92c-2.51,0-5.12-.08-7.69-.17-2.36-.08-4.59-.15-6.59-.15h0a2,2,0,0,1-2-2,2,2,0,0,1,2-2c2.07,0,4.33.07,6.72.15a105.14,105.14,0,0,0,14.11-.14,2,2,0,1,1,.46,4A62.66,62.66,0,0,1,598.88,56.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M581.56,162.32a2,2,0,0,1-2-2.35,135.61,135.61,0,0,0,1.64-16.74c1.34-28.54,1.34-55.65,1.33-84.35V54.61a2,2,0,0,1,4,0v4.27c0,28.75,0,55.9-1.34,84.54a139.52,139.52,0,0,1-1.7,17.26A2,2,0,0,1,581.56,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M572.22,71.48a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1h0a2,2,0,0,1,0,4h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,572.22,71.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M571.72,163.53a2,2,0,0,1-1.83-2.8c.7-1.62.42-6.14.21-9.44-.1-1.64-.2-3.19-.2-4.45,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,0,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,1.13.09,2.62.2,4.19.27,4.32.56,8.78-.53,11.29A2,2,0,0,1,571.72,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M539.56,163a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.67-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,2-2,2,2,0,0,1,2,2c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M541.22,58.66a2,2,0,0,1-.71-3.87c4.15-1.57,11.15-2.13,15.88-2.13l2.68,0c1.82,0,3.7,0,5.56,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,0,1-1.69,3.63c-1.49-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.59,0-5.36,0l-2.73,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,541.22,58.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M349.32,164.65a2,2,0,0,1-2-2c0-2.53-.23-5.64-.47-8.93a109,109,0,0,1-.47-12.06c.3-6.31.37-12.8.45-19.08.08-7.08.17-14.41.57-21.53.67-11.67,1-24.95,1-38.38a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,13.51-.33,26.87-1,38.62-.4,7-.48,14.31-.57,21.35-.07,6.31-.15,12.84-.45,19.22a106.6,106.6,0,0,0,.47,11.58c.25,3.37.48,6.55.48,9.23A2,2,0,0,1,349.32,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M331.39,162.32a2,2,0,0,1-2-2c0-2.48.08-4.95.17-7.34s.17-4.86.17-7.34v-7.95c0-21.92,0-44.58-1-66.78,0-.3,0-.64-.06-1-.18-2.67-.39-6,1.21-7.89,3.21-3.79,10.28-2.74,16-1.9a38.76,38.76,0,0,0,4.58.52,2,2,0,0,1,0,4h0a39.87,39.87,0,0,1-5.15-.57c-4.2-.62-10.54-1.57-12.32.53-.56.66-.35,3.84-.27,5,0,.39,0,.75.06,1.07,1,22.29,1,45,1,67v7.95c0,2.55-.09,5.05-.17,7.48s-.16,4.8-.16,7.2A2,2,0,0,1,331.39,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M326.06,163a2,2,0,0,1-2-2.34c.7-4.06.59-9.38.47-14.52a107.94,107.94,0,0,1,.16-11.92c1.92-20.09,1.73-41.21,1.55-61.62-.05-5.92-.11-12-.11-18a2,2,0,0,1,4,0c0,5.92.05,12,.11,17.95.18,20.52.37,41.74-1.57,62a103.64,103.64,0,0,0-.14,11.45c.12,5.33.24,10.84-.53,15.29A2,2,0,0,1,326.06,163Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M321.39,56.92c-2.51,0-5.12-.08-7.69-.17-2.36-.08-4.59-.15-6.59-.15h0a2,2,0,1,1,0-4c2.07,0,4.33.07,6.72.15a105.3,105.3,0,0,0,14.1-.14,2,2,0,1,1,.46,4A62.65,62.65,0,0,1,321.39,56.92Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M304.06,164.65a2,2,0,0,1-2-2.35,169,169,0,0,0,1.64-19.07c1.34-28.56,1.34-55.68,1.33-84.4V54.61a2,2,0,0,1,4,0v4.22c0,28.77,0,55.94-1.34,84.59A172.17,172.17,0,0,1,306,163,2,2,0,0,1,304.06,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M294.72,71.48a2,2,0,0,1-.5-3.94c3-.76,9.27-1,12.21-1a2,2,0,0,1,2,2,2,2,0,0,1-2,2h0c-3.09,0-8.84.23-11.21.84A2,2,0,0,1,294.72,71.48Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M293.72,164.65a2,2,0,0,1-1.83-2.8c.82-1.89.66-8.07.56-11.76,0-1.24-.06-2.36-.06-3.25,0-15.17.08-30.62.17-45.56s.17-30.42.17-45.62a2,2,0,0,1,4,0c0,15.21-.08,30.68-.17,45.64s-.17,30.38-.17,45.54c0,.86,0,1.95.06,3.15.16,6.1.19,11-.89,13.45A2,2,0,0,1,293.72,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.06,163a2,2,0,0,1-2-2c0-2.26.07-5.12.16-8.15s.18-5.88.18-8.46c0-15.6.34-31.5.68-46.88.29-13.41.59-27.28.66-40.86a2,2,0,0,1,4,0c-.07,13.62-.37,27.5-.66,40.93-.33,15.35-.67,31.23-.67,46.79,0,2.65-.09,5.66-.18,8.58s-.17,5.81-.16,8a2,2,0,0,1-2,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M263.72,58.66a2,2,0,0,1-.71-3.87c4.15-1.57,11.14-2.13,15.87-2.13l2.68,0c1.82,0,3.7,0,5.56,0l1.16,0c2.24,0,5,.1,7.28,1.15a2,2,0,1,1-1.69,3.63c-1.49-.7-3.81-.74-5.67-.78l-1.23,0c-1.76-.07-3.59,0-5.36,0l-2.73,0c-4.74,0-11,.58-14.46,1.87A2,2,0,0,1,263.72,58.66Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M526.22,162.32a2,2,0,0,1-1.2-3.6c.67-.5,1.5-1.17,2.37-1.89,3.18-2.6,7.14-5.84,10.45-6.47a2,2,0,1,1,.75,3.93c-2.32.44-6,3.45-8.67,5.64-.91.75-1.77,1.45-2.51,2A2,2,0,0,1,526.22,162.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M537.89,152a2,2,0,0,1-1.94-1.52c-2.45-9.89-8.79-18.71-14.92-27.24-2-2.72-4-5.54-5.81-8.31-4-6-7.85-12.14-11.61-18.09-4.54-7.18-9.24-14.61-14-21.73-.43-.63-.86-1.24-1.28-1.84a32.83,32.83,0,0,1-3.65-6.06,25,25,0,0,0-3.51-6.14A2,2,0,1,1,484,58.26c1.92,2,3.8,6.13,4.32,7.35a29.37,29.37,0,0,0,3.24,5.33c.44.62.89,1.25,1.33,1.91C497.72,80,502.43,87.48,507,94.68c3.76,5.94,7.64,12.08,11.57,18,1.79,2.71,3.7,5.37,5.72,8.19,6.35,8.84,12.91,18,15.55,28.61a2,2,0,0,1-1.46,2.42A2,2,0,0,1,537.89,152Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M469.56,71a2,2,0,0,1-1.49-3.33c2.79-3.12,6.43-5.35,10-7.51,1.2-.74,2.33-1.43,3.43-2.16a2,2,0,0,1,2.21,3.34c-1.16.77-2.37,1.51-3.55,2.23-3.28,2-6.66,4.08-9.06,6.77A2,2,0,0,1,469.56,71Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M525.22,163.32a2,2,0,0,1-1.91-1.42c-.52-1.73-2.08-3.44-3.58-5.09a35.82,35.82,0,0,1-2.45-2.89c-2.46-3.36-4.63-6.91-6.74-10.34l-3.35-5.48c-3.07-5-6.25-10.23-9.49-15.35A412.58,412.58,0,0,1,476,83.94c-.39-.8-.78-1.63-1.18-2.47-1.92-4.07-3.91-8.27-6.69-11.07A2,2,0,1,1,471,67.58c3.26,3.29,5.5,8,7.47,12.18.39.83.78,1.64,1.16,2.42a408.43,408.43,0,0,0,21.47,38.44c3.26,5.14,6.44,10.36,9.53,15.4L514,141.5c2.06,3.37,4.19,6.85,6.55,10.07a32.68,32.68,0,0,0,2.18,2.56c1.8,2,3.67,4,4.45,6.62a2,2,0,0,1-1.92,2.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M175.8,162.31a2,2,0,0,1-.76-3.85c.77-.31,1.74-.76,2.77-1.23,3.73-1.72,8.37-3.86,11.74-3.64a2,2,0,1,1-.26,4c-2.35-.14-6.66,1.83-9.81,3.28-1.07.49-2.08,1-2.93,1.31A2,2,0,0,1,175.8,162.31Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M189.68,155.24h0a2,2,0,0,1-2-2c.11-10.19-3.81-20.32-7.59-30.11-1.21-3.13-2.46-6.36-3.54-9.51-2.32-6.79-4.55-13.73-6.7-20.44-2.59-8.09-5.27-16.45-8.13-24.55-.25-.72-.52-1.41-.78-2.1a32.89,32.89,0,0,1-2-6.78,25,25,0,0,0-1.86-6.83,2,2,0,1,1,3.47-2c1.37,2.39,2.13,6.89,2.34,8.2a29.35,29.35,0,0,0,1.8,6c.27.71.54,1.43.81,2.18,2.88,8.16,5.57,16.55,8.17,24.67,2.14,6.69,4.36,13.62,6.67,20.36,1.05,3.07,2.23,6.13,3.48,9.36,3.92,10.15,8,20.64,7.86,31.6A2,2,0,0,1,189.68,155.24Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M143.89,59.67A2,2,0,0,1,142.78,56c3.49-2.32,7.57-3.56,11.52-4.77,1.35-.41,2.62-.8,3.86-1.23a2,2,0,0,1,1.3,3.78c-1.31.45-2.67.87-4,1.27-3.68,1.12-7.48,2.28-10.48,4.27A2,2,0,0,1,143.89,59.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M174.57,163a2,2,0,0,1-2-1.92c-.07-1.8-1.15-3.85-2.19-5.82a35.88,35.88,0,0,1-1.65-3.41C167.21,148,166,144,164.83,140.2L163,134.1c-1.72-5.67-3.49-11.52-5.35-17.31a412.5,412.5,0,0,1-11.24-43c-.18-.87-.35-1.78-.52-2.69-.84-4.42-1.71-9-3.7-12.4a2,2,0,1,1,3.46-2c2.33,4,3.31,9.14,4.17,13.66.17.9.34,1.78.51,2.64a408.42,408.42,0,0,0,11.13,42.6c1.87,5.82,3.65,11.69,5.37,17.37l1.85,6.09c1.15,3.77,2.33,7.66,3.81,11.36a32.7,32.7,0,0,0,1.47,3c1.25,2.37,2.54,4.82,2.65,7.53a2,2,0,0,1-1.92,2.08Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M469.22,163.85h-.09a2,2,0,0,1-1.91-2.09c.51-11.39.62-19.78.34-25.67-.77-16.11-.72-32.88-.67-49.1,0-13.22.08-26.89-.33-40a2,2,0,0,1,4-.13c.41,13.13.37,26.84.33,40.09,0,16.17-.1,32.9.67,48.9.29,6,.17,14.53-.34,26A2,2,0,0,1,469.22,163.85Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M455.89,164.13a2,2,0,0,1-2-2V137.82c0-5.58.21-11.22.42-16.68.3-8,.61-16.27.25-24.37-.34-7.72-.34-15.63-.34-23.28V71.32c0-2.12-.07-4.46-.14-6.94a129.62,129.62,0,0,1,.29-17.58,2,2,0,1,1,4,.46,127,127,0,0,0-.26,17c.07,2.51.14,4.87.14,7.05v2.16c0,7.61,0,15.47.33,23.1.37,8.26.05,16.62-.25,24.7-.2,5.42-.41,11-.41,16.53v24.31A2,2,0,0,1,455.89,164.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M438.72,80a2,2,0,0,1-.79-3.84c3.45-1.47,9.57-1.25,14.49-1.07,1.35,0,2.62.1,3.61.1a2,2,0,0,1,0,4c-1.07,0-2.38,0-3.76-.1-4.28-.16-10.15-.37-12.77.75A2,2,0,0,1,438.72,80Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M440.47,164.13a2,2,0,0,1-2-2V148.68c0-11.78-.44-23.72-.87-35.26s-.88-23.59-.87-35.43a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,11.76.44,23.71.87,35.28s.88,23.56.88,35.41v13.45A2,2,0,0,1,440.47,164.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M433,164.28a2,2,0,0,1-2-2V152c0-9.67.09-19.68.19-29.35s.19-19.75.19-29.49a2,2,0,0,1,4,0c0,9.76-.1,19.81-.19,29.53S435,142.32,435,152v10.31A2,2,0,0,1,433,164.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M399.1,95.25c-1.5,0-3.07-.11-3.08-2l2,0v-2h1.37c16.41-.09,27.84-.13,34-.13a2,2,0,1,1,0,4c-6.11,0-17.53,0-33.94.13Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M399.22,164.65a2,2,0,0,1-2-2c0-10.34-.4-24.44-1-35.1-.49-8.79-.39-18-.28-26.87,0-2.5.06-5,.07-7.43a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2c0,2.45,0,4.94-.07,7.45-.1,8.82-.21,18,.28,26.6.6,10.72,1,24.92,1,35.32A2,2,0,0,1,399.22,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395,163.53h0a2,2,0,0,1-2-2l0-1.28c.06-4.91.16-13.14.39-17.83.37-7.49,0-15.16-.28-22.58-.22-5.11-.45-10.39-.45-15.59,0-6.31-.06-13.12-.12-19.7s-.12-13.44-.12-19.79a2,2,0,1,1,4,0c0,6.33.06,13.16.13,19.76s.13,13.41.13,19.74c0,5.12.23,10.35.45,15.42.33,7.51.66,15.28.28,22.95-.23,4.61-.33,12.79-.39,17.68l0,1.28A2,2,0,0,1,395,163.53Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M354.22,67a2,2,0,0,1,0-4c2.48,0,4.91-.19,7.26-.38,2-.16,4-.32,6.06-.37,5-.13,9.83.07,13.53.26,2.42.13,10.07.23,13.41.23a2,2,0,0,1,0,4c-3,0-11-.1-13.62-.24-3.62-.19-8.39-.39-13.22-.26-2,.05-3.85.2-5.84.36C359.37,66.79,356.87,67,354.22,67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M355.5,164.65a2,2,0,0,1-2-2c0-2.37-.2-7.26-.39-12s-.39-9.7-.39-12.15c0-12.37-.19-24.84-.37-36.89S352,77.1,352,64.74a2,2,0,1,1,4,0c0,12.33.19,24.77.37,36.81s.38,24.55.38,37c0,2.37.2,7.26.39,12s.39,9.7.39,12.15A2,2,0,0,1,355.5,164.65Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M262.56,84.32a2,2,0,0,1-.87-.2c-1.92-.93-7-1.28-8.9-.34A2,2,0,1,1,251,80.2c3.07-1.54,9.51-1.1,12.44.32a2,2,0,0,1-.88,3.8Z" transform="translate(-53.25 -44.96)"/></g></g><g id="COLOR-2" data-name="COLOR"><path class="cls-7" d="M348.43,470c-2.63-1-6-1-8.83-1.21-4.22-.38-8.44-.52-12.67-.62-8.68-.21-17.29.23-25.92-.82a58.42,58.42,0,0,0-15.84.35c-4.32.6-8.71,1.09-13,1.84-6.7,1.17-13.45,1.86-20.12,3.25-5.91,1.24-11.79,2.64-17.71,3.83-2.56.52-5.13,1-7.69,1.49-.88.18-3.73.26-4.27,1.08-.74,1.11.42,4.52.63,5.75.67,3.87,1.55,8,3.4,11.51A140.8,140.8,0,0,0,234,508.57c2.85,4.25,4.81,8.24,8.61,11.85a50.38,50.38,0,0,0,12.91,9.06c6.17,2.86,13.11,5.65,19.89,6.31a85.31,85.31,0,0,0,14-.13c2.73-.16,5.46-.65,8.16-1a122,122,0,0,0,14.46-3.5,36.34,36.34,0,0,0,12.24-5.8c7-5.16,12.12-12.82,17.1-19.83a60,60,0,0,0,3.33-5.67,39.58,39.58,0,0,0,2.58-6.66c1.62-4.58,1.84-9.14,2.88-13.77C350.78,476.48,352.27,471.49,348.43,470Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M272.5,468.5c-.55,7,4.53,14,11.81,14,7.66,0,11.95-7.38,12.41-14-3.09-.42-7.19,1.21-10.45,1.23A57.65,57.65,0,0,1,272.5,468.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M290.26,472c-3.34-.13-4.94,3.06-.58,2.67,2.51-.23,5.53-3,1.25-2.83" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M566,470c-2.63-1-6-1-8.83-1.21-4.22-.38-8.44-.52-12.67-.62-8.68-.21-17.29.23-25.92-.82-18.38-2.22-37,.43-55,4.19C455.38,473.24,447,474.6,439,477a22.34,22.34,0,0,0,.84,6.53c.75,3.28,1.14,6.75,2.57,9.82a112.66,112.66,0,0,0,9.11,15.2c2.85,4.25,4.81,8.24,8.61,11.85a50.38,50.38,0,0,0,12.91,9.06c6.17,2.86,13.11,5.65,19.89,6.31a64.13,64.13,0,0,0,22.71-1.38c6.84-1.83,14-4,19.51-8.59,4.69-4,10.07-7.07,14.29-11.55,2.36-2.51,5.09-4.83,7-7.72,2.46-3.72,4-8,5.56-12.17s3.3-8,4.88-12C567.68,480.36,570.64,471.62,566,470Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M492.5,468.5c.12,7,6.16,13.3,13.38,12.25A15.38,15.38,0,0,0,516,474.18a10,10,0,0,0,1.8-4.45c.18-2.63-.45-2.46-2.81-2.49-3.94,0-7.84-.25-11.77-.25C500.19,467,495.9,466.38,492.5,468.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M315,336.21c-3.66-2.95-5.67-7.23-9.3-10.61a61.08,61.08,0,0,0-13.44-9.16c-13.63-7.12-22.83,11.34-15.79,22.31,1.81,2.82,3.9,6.21,5.88,8.72,2.17,2.76,5.2,4.37,6.55,7.9-5.6,3.14-9.54,8.71-14,13.22-4.26,4.27-9.21,8.45-12.54,13.52-6,9.16-8.62,20.26-12.72,30.3-1.67,4.08-3.53,7.71-4.1,11.93.88-.56,2.17-.79,3-1.35-.69,6.27-5.62,4.49-9.37,9.14A81.54,81.54,0,0,0,230,445.5c-2.49,4.82-4,10.2-5.38,15.5a42.67,42.67,0,0,0-1.63,8c-.08,1.43.32,3.13,0,4.52-.24,1.12-2,1.94-2,3,0,5,1.76,2.87,5,2.16,4.82-1.05,9.7-2.48,14.66-3.53,11.74-2.48,23.52-5.57,35.38-7.38,13-2,26.14-1.74,39.38-1.74a121.68,121.68,0,0,1,18.1,1.38c4,.58,8.63-.25,12.5.62,13.48,3.05-4.54,36.54-8,41.74-3.59,5.43-8.81,10.7-13.66,15.14-17.42,16-52.62,19.6-71.13,3.4-3.87-3.39-8.18-6.07-11.48-10-2.56-3.09-4.87-7.49-8.66-8.7-.2,5.41-2.39,12.29-1.1,17.24,1.24,4.78,4.77,10.72,8.52,13.7,10.08,8,23.71,10.68,36.14,12.46,6.95,1,13.36,3.11,19.89,5.3,6.29,2.11,12.84,2.16,19.22,3.75a129.87,129.87,0,0,0,18.63,3.61c19.63,2,38.31,8.92,58.11,10.9,8.06.81,17.29-3,25-5,9.67-2.49,19.64-3.34,29.46-5s19.43-3,29-5c26.08-5.38,52.67-10.58,77.5-20.36,5.66-2.23,6-3,6-9.14,0-4.5.11-9,0-13.5s-.23-9.77-2.39-13.45c-6.66,16.31-24.6,27.61-42.11,29-16.18,1.25-40.74-.14-53-12.53C454.77,514.15,449.39,505,444.5,496c-2.2-4.06-7.86-16-5-20.76,1.8-3,11.67-2,15.14-2.34,7.56-.73,15.16-1.67,22.75-2.42,14.61-1.43,29.36-3.19,44-3.86a166.26,166.26,0,0,1,29.35.78c5.67.76,11.27,2,17,1.57-1.84-6.64-3.32-13.49-5.52-20.14-1.83-5.55-6.93-10.4-10.44-14.94-2.31-3-5.15-5.56-6.5-9.25-1.09-3-.88-6.4-1.87-9.51a106,106,0,0,0-8.23-18.77c-6.24-11.45-12-22.6-21.15-32-2.26-2.33-4.65-4.29-6.76-6.75a20.87,20.87,0,0,0-6.1-5.09c-.54-.29-2.94-1.07-3.1-1.77-.65-3,6.25-6.28,8.11-7.71a21,21,0,0,0,7.09-11.23c1.46-5.57.17-8.86-3.45-13.25s-8.49-6-14.18-6c-6.75,0-10.71,3.57-15.28,8.09a24.4,24.4,0,0,0-5.5,7.9c-1.46,3.52-2.07,7.25-3.21,10.66-1.59-.87-2.6-2.55-4.12-3.59a27,27,0,0,0-8.5-3.24c-4.63-1.12-9.44-1.34-14.09-2.34-4.33-.94-8.63-2.49-12.93-3.73-5.4-1.57-10.35-1.59-16-1.59-12.77,0-25.3.87-38,2-12.39,1.1-25.51,1.3-37.58,4.33a122.83,122.83,0,0,0-13.36,3.92c-2.8,1.05-7.43,1.34-9.43,3A14.6,14.6,0,0,1,315,336.21Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M229.13,623.25c.89,1.17,1.92,3.92,2.74,4.87,1.3,1.5,2.83,2.79,4.21,4.21a82.17,82.17,0,0,1,6.68,7.93c3.71,4.95,4.32,10.93-.5,15.32-5.63,5.12-13.27,6-20.58,4.77-5.58-.92-8.09-4.39-12-8-2.89-2.68-6.07-4.7-8.76-7.58-3.41-3.66-6.39-7.37-2.9-11.67,3.77-4.65,10.31-6.32,15.92-7.45,3.29-.66,11.72-4.79,14.75-2.82A1.88,1.88,0,0,1,229.13,623.25Z" transform="translate(-53.25 -44.96)"/><path class="cls-32" d="M566,624.33c-4.5,5.82-7.4,11.21-12.83,16.15s-4.81,10.93-.67,16.68c4.66,6.47,17.4,5.51,23.58,2.74,9-4,18.16-10.94,22.66-20,1.53-3.07,1.13-2.81-1.62-4.79a69.33,69.33,0,0,0-9.77-5.8C581.45,626.37,576.32,625,566,624.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-10" d="M383.12,470.36c-4.4,2-11.06,9.12-12.45,14-2.15,7.44,4.66,10.07,10.72,8.56,4.63-1.15,8.94-3.74,13.79-4,2.3-.1,4.26.7,6.41,1.39,2.45.79,4.77,1.95,7.27,2.57,6.06,1.51,12.87-1.12,10.72-8.56-1.39-4.83-8.05-12-12.45-14" transform="translate(-53.25 -44.96)"/><path class="cls-9" d="M393.83,462.79a18.23,18.23,0,0,0-7.35,2.06c-2.93,1.7-5.13,5.48-1.36,7.86,4.51,2.85,16.6,2.72,20.71-.84,2.88-2.49,2.1-6.25-1.3-7.7A23.59,23.59,0,0,0,393.83,462.79Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M401,490.33c-2.85-1.27-7.34-1.63-10.46-1.34-3.28.31-3.21,2.87-3.58,5.87-.26,2.07-.66,8.48,1.53,9.5,1.47.69,4.55-.06,6.26.11a15.56,15.56,0,0,0,4.83,0C405,503.31,401.23,493.16,401,490.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-7" d="M510.83,472c-3.34-.13-4.94,3.06-.58,2.67,2.51-.23,5.53-3,1.25-2.83" transform="translate(-53.25 -44.96)"/><path class="cls-33" d="M560.91,668.12c0-1.84.56-4.94-.4-6.62-.74-1.31-2.44-1.5-3.69-2.11a11.57,11.57,0,0,1-5.08-4.89c-3.75-7-.4-12.58,4.49-17.77,2.1-2.22,3.94-4.35,4.32-7.5s-.31-6-.36-9.07c0-1.58.14-3.18.11-4.74,0-.78.26-3.69,0-4.24,1.45,2.88,3.64,5.18,4.62,8.42,1.32,4.38,4,4.19,8,4.76a92.15,92.15,0,0,1,10.5,2c6.07,1.61,14.06,4.53,15.75,11.39.41,1.66,3.47-2.07,3.74-2.9.66-2,.46-4.22.45-6.28,1.23-.16,2.15-1.09,3.38-1.17-.9-1-1.73-2.52-2.91-3.44,1.84-2.05,1.58-3.31-.38-4.65-2.17-1.48-1.34-2.76-1.65-5.3a39.1,39.1,0,0,0-1.89-7.92,58.56,58.56,0,0,0-7.94-14.85c-3.7-5.19-8.79-9.52-13.92-13.24a68.21,68.21,0,0,0-8.86-5.52c-2.45-1.26-6.23-2-8-4.15,1.08-2.54,1.48-5.31,2.46-7.89a13,13,0,0,0,.91-6.71,37.36,37.36,0,0,0-2.8-9c-.76-1.89-1.17-4.3-3.42-4.9-3.36-.9-7.19,2.16-10.17,3.27q-6.93,2.58-14,4.84c-9.38,3-18.89,5.63-28.46,8-25,6.06-50.38,10.09-75.76,14q-11,1.71-22,3.82a57.18,57.18,0,0,0-8.85,2.39c-2.64,1-5.4-.68-8-1.22q-4.67-1-9.35-1.84-9.24-1.73-18.54-3.16c-24.86-3.85-49.68-8.14-74.12-14.14-10.36-2.54-20.65-5.39-30.81-8.66q-7.54-2.43-15-5.18c-2.45-.91-4.91-1.84-7.33-2.83-1.74-.7-3.09-2.28-4.29-.4s-1.61,5.42-2.17,7.66c-1.09,4.37-2.51,9.25-1.29,13.74.72,2.67,3.45,6.2,2.49,9.08-.55,1.66-2.06,1.46-3.53,2.05a37.62,37.62,0,0,0-5.61,2.95,64.39,64.39,0,0,0-18.26,17,58.28,58.28,0,0,0-8,15.09,43.9,43.9,0,0,0-1.84,7.89c-.32,2.28-.07,3.79-1.86,5.29-.72.61-1.35.41-1.48,1.66a4.11,4.11,0,0,0,1.34,2.8c-1.18.92-2,2.49-2.91,3.44,1.24.08,2.16,1,3.38,1.17,0,2.42-.47,5.93,1.21,7.94,1,1.19,2.81,2.33,4,.82s.55-3.19,1.91-4.66c2.44-2.64,6.15-4.18,9.48-5.31a79.51,79.51,0,0,1,14.05-3c3.79-.56,6.63-.61,8.16-4.4.54-1.34,1.66-4.24,2.9-5,1.16,2.17,1.1,4.83,1.3,7.21.32,3.8-.19,8.6,1.75,12,1.64,2.89,4.65,4.7,6.43,7.48a12,12,0,0,1,.35,12.77,10,10,0,0,1-4.13,4.33c-1.71.78-3.68,1.13-3.61,3.32,0,.91.52,1.9.56,2.88.07,1.64,0,3.29.05,4.93.1,8.11.25,15.62-1,23.45-1.39,8.62,2.78,7.83,9.13,11.09,7.41,3.81,14.76,8.81,22.48,11.89,9.71,3.87,21.29,5.47,31.42,8,7.78,1.95,15.39,4.44,23.07,6.74,20.13,6,39.23,12.91,60.46,9.87,29.79-4.26,60-3.23,89.34-10.76,19.65-5,39.24-8.93,58.6-15.13A117.05,117.05,0,0,0,546.43,708c4-2,12.41-4,14.5-8.19,1.47-2.92.11-8.2.07-11.39C560.92,681.63,561,674.88,560.91,668.12Z" transform="translate(-53.25 -44.96)"/><path class="cls-34" d="M399.75,580.86a69.12,69.12,0,0,1,4.48,10.28c.68,1.78,2.41,4.44,2.53,6.3s.46.9-.88,2c-1.09.92-2.07.55-2.95,2a9.39,9.39,0,0,0-.79,3.94,31.94,31.94,0,0,0,.66,8.16c2.37,12.11,1.73,25.25,2.94,37.65.76,7.85,2.22,15,2.26,23.06,0,5.48,3.54,12.13,1.26,17.11-3.09,6.74-8.66,12-13.07,17.81-2.64-1.83-4-6.26-6.06-8.84-2.42-3-5.46-10.59-9.34-11.43-.36-3.59.56-7.58.71-11.2.51-12.06,2.79-23.94,4.6-35.84,1.73-11.41,2.17-22.8,3.15-34.23.11-1.34.63-3.71.2-4.94-1.13-3.26-3.19-4.05-2.63-7.94.47-3.31,2.83-6.07,4.74-8.68C393.71,583.2,396.57,575.41,399.75,580.86Z" transform="translate(-53.25 -44.96)"/></g><g id="SHADOWS-2" data-name="SHADOWS"><g class="cls-3"><path d="M286.67,316.33c-3.62,2.59-8.05,10-3.81,14,1.6,1.53,4.85,2,6.81,3.41,2.36,1.74,4.42,3.91,7,5.31,1.58-1.79,0-13.45,3-5.87,1.94,5,5.63,6.09,9,1.11,1.13.93,2.55,2.49,2.73,4,.29,2.41-2.2,3.24-4.57,5-3.7,2.71-11.85,10.52-16.83,10.1-3-.26-4.52-4.4-6.58-6.61-2.77-3-5.22-5.63-7-9.34-3.52-7.36-3.28-16,4.58-20.73" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M473,335.67c1.84-7.87,8.06-16.08,15.65-19.33,4.8-2.05,13.27-3.46,17.31.6-5.42.4-11.26-.72-12.61,5.72a57.49,57.49,0,0,0-1,14.3c2.79.38,5.42-.8,8.23-.57.12,2.17-3.51,4.44-3,6.12,1.24,3.87,9.78-2.53,11.37-3.39-1.13,4.6-8.65,10.11-12.95,12.18-1.59-4.63-7.3-6.17-11.42-7.77-2.63-1-5.47-1.41-8-2.53C474.89,340.25,473.69,338.9,473,335.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M365.33,466c10-7,24.85-9.09,37-6.83,4.54.84,11.69,1.72,13.68,6.33,1.59,3.69,1.5,9.1,2.46,13.1,1.3,5.39,2.09,10.9,3.57,16.25,1.88,6.83,4.32,14.52,7.56,20.85,6.61,12.94,15.94,22.93,29.41,28.55,8.63,3.6,16.54,4.43,25.89,4.42a53,53,0,0,1-31.73-17.33c-4.93-5.48-8.81-12-12.16-18.56-3.75-7.33-8.36-14.24-10.76-22.18a70.49,70.49,0,0,1-2.92-19.1c-.05-2.64-.45-5.2-.33-7.84.06-1.42.83-3.59.33-5-1.27-3.61-11.3-4.6-15.07-5.1-6.49-.86-13.3-1.32-19.85-1.57-7.06-.26-14.22,1.94-21,3.59-5.23,1.27-11.4,4.17-7.05,11.07" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M392.67,462.33c-4.53.82-10.59,3.67-10,9.15.57,5.25,10.25,5.34,14.22,3.84C393.46,474.42,383.84,469.37,392.67,462.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M390.67,475.67c-3.65,0-8,1.1-10.35,4.33-1.68,2.33-2.7,7.07-.31,8.34,2.8,1.5,8.7-1.34,11.74-1.66s5.78-.19,8.5,1.67a43.92,43.92,0,0,0-14.91,2c-3.09,1-7.17,4-10.5,3.66-3.74-.37-6.27-4.13-6.17-7.67.16-5.81,6.45-9.4,10.67-12.33" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M367.33,487.67c-1.28,4-.14,8.45,3.41,10.58,3,1.8,7.53,1.2,10.1,3.22s1.51,6,4.64,7.22c2.93,1.16,10.37-1,13.08-2.27-3.56-.31-7.68.23-10.14-2.8-3.22-4-.84-8.61-1.14-12.91-4.66,1.53-10.47,4.44-14.95,1" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M489,468.67c-5.68,0-12.84,3.07-18.25,4.91-4.34,1.48-14.53,2.44-17.34,6.16-3.64,4.82-1.14,16.07.59,21,2.81,8.08,9.47,14.77,15.65,20.55,5.66,5.3,12.71,7.83,19,11.6-6,.48-12.19-2.87-17.51-5.44a57.25,57.25,0,0,1-18.2-13.59c-9.08-9.64-12.68-22.75-17.86-34.28-2.53-5.63-1.81-9.69-.66-15.6,1.81-9.28,3.75-17.09,7.85-25.7,9.21-19.37,38.33-29.09,58.26-29.31,15.86-.17,28.66,5.54,42.11,13-5-.46-10.55-2.65-15.66-3.57a83.41,83.41,0,0,0-15.57-1.07c-12.92.08-27.78,5.36-38.33,12.72-8.12,5.66-13.31,12.83-17.7,21.73-2,4.09-2.48,5.44,2.49,5.88,6.77.59,14-1.23,20.66.06-2.85,2.43-8.56,1.42-10.76,4.4,6.37,2.67,16.78,1.08,23.76,1.72s14.54.64,21.47,2.07c-3.85,1.2-8.56,1-12.56,1.52C495.12,468.08,490.24,470.3,489,468.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M267.33,405.67c-7,.76-20.15,6.64-20,15,2.6-.2,5.64-2.17,8.28-3,4.31-1.29,8.75-2.19,13.09-3.42,8.06-2.27,16.47-4.55,24.84-4.93,6.23-.28,13,1.43,18.74,3.81,5.27,2.17,12.38,5.48,16.71,9.18,9.29,7.95,13.51,23.72,17,34.72,1.22,3.88,3.35,7.72,4.32,11.63,1.47,5.87-.26,13.57-.85,19.5-1.08,11-5.36,19.46-11.74,28.58a170.58,170.58,0,0,1-11.57,14.6c-2.36,2.68-4.21,5.15-7.32,7s-7.12,3.23-10.22,5.27C318,545,327,537.3,333.64,532c8-6.39,16.32-12.51,18.54-22.93,2.81-13.21,7-26.41,9.17-39.71,1.74-10.86,1.17-26-6.33-34.8a66.17,66.17,0,0,0-6.51-6.08c-2.72-2.44-4.64-5.5-7.38-7.88a134.89,134.89,0,0,0-12.48-10c-5.13-3.47-11.67-6.74-17.78-8-5.71-1.14-11.71-1-17.49-1.39-8.92-.63-20.34-2.62-28.13,2.81C265.24,404.7,265.6,405,267.33,405.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M290.33,411.33c-6.84,2.45-14.82,2.28-21.6,6-6.22,3.41-12.05,8.64-17.57,13.13s-9.15,11.08-13.51,16.79c-2.55,3.34-7.33,10.5-5.68,15.08,1.5,4.17,8.16,2.08,11.4,1.46,6.78-1.29,13.58-3.3,20.45-3.74-4.71,2.88-11.12,4-15.16,7.86,4.23,1.73,10.8.5,15.34.74,4.19.22,8.4.69,12.58,1A63,63,0,0,0,254,477c-3.91,2.2-11.33,5.54-12.33,10.34-1.1,5.28.29,11.72,2.08,16.6,5.18,14.09,21,22.35,33.93,28a46.07,46.07,0,0,0,10.4,2.82c2.48.46,6.95.12,8.65.92-7.27-.42-15,1.7-22.34,1.67-7.13,0-13.42-2.58-20.06-4.67-5.83-1.84-11.48-2-16.85-5.53-1.73-1.13-4.59-3-5.16-4.62-1-3,.87-5.18,1.3-8a14.57,14.57,0,0,0-.64-6.32c-1.35-4.81-4.41-8.94-5.84-13.72-.92-3.05-1.72-6.36-2.39-9.51-.31-1.43-.38-3.08-.76-4.49-.5-1.87-1.37-2.08-2.27-3.85-1.45-2.87.23-4.52.6-7.48.57-4.54.19-8.55,2.21-12.84,4.8-10.23,10.44-20.13,19.29-27.47A78.1,78.1,0,0,1,259.2,418.5c3.53-1.7,7.13-3.52,10.77-5,4.28-1.71,8.72-1.6,13-2.86" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M334,537c-5.51,4.05-12.08,7.07-18,10.51-3.43,2-6.63,4.54-10.32,6.08-4.62,1.92-11.17,5-14.73.42,1.08-1.31,4.06-2,5.71-2.6,4-1.54,8.12-2.65,12.15-4.07,5.6-2,15.9-3.35,19.85-8" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M392.72,583.1a20.56,20.56,0,0,0-1.53,3.33c-1,2.9-3,6.84-3.2,9.9-.17,3.55,5.58,6.69,8.63,6.62a26.18,26.18,0,0,1-2-4.75,5.52,5.52,0,0,1,4.05-4.71c4.7-1,2.45,5.12,6.65,5.46.51-6.64-5.73-13.69-8-19.91C395.47,579.15,393.86,581.09,392.72,583.1Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M402.67,603.33c-1.55,1.36-2.47,3.56-4,5-1.09,1-2.34,1.24-3,2.63-1.48,3.07-.64,9.55-1,13-.58,5.85-.32,11.69-.65,17.59-.18,3.28-.39,9.08-2,11.72-.15-2.76-2.17-9.55-5.35-9.94-.33,5.78-.57,11.59-1,17.37-.49,6-2.1,12.49-1.65,18.51.57,7.65,1.43,15.64,7.29,21.07,1.56-2.31,3.85-6.63,6.28-7.95.13,1.73,0,3.53.12,5.27,3.76.1,8.61-5.58,10.88-8.27.56,3-3.39,7.63-4.93,10s-4.53,6.88-7.5,8.12c-4.29,1.8-10.9-10.54-14.17-13.86-2.28-2.32-5.7-4.73-7-7.73-2.32-5.23-.64-13.75-.64-19.26,0-13.78.69-26.83,3.46-40.32.55-2.66,2.2-8.53.15-10.86-.92-1-4.1-1.49-5.44-2.35-2.17-1.39-4-3.4-6.09-4.85a48.36,48.36,0,0,0,11.93-1.38c3.61-1.06,3.17-2.56,4.33-5.87,1.82-5.2,2.89-1.82,6.68-.09C392.47,602.37,400.21,602.57,402.67,603.33Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M404.67,600.67c-1.17,3-.47,8-.28,11.31,4.62-4.61,2.15,6.64,3.3,7.87,1.86,2,17.76-5.76,20.65-6.85,17.88-6.73,35.75-14,54-19.43a200.6,200.6,0,0,0,25.22-9.16c-2.34-.3-5,.68-7.22,1.29-4.84,1.33-9.73,2-14.62,3.14-7.89,1.8-15.4,4.6-23.09,7-12.19,3.75-23.7,9.06-35.81,13-4.52,1.45-11.73,4.33-14.45,0-3.19-5-4.43-13.2-6-18.88-1.41-5.16-1.6-6.67,2.29-10.18s8.65-4.38,13.23-6.67c-7.11-.6-16.23.87-23.25,2.66-.29,4.74,2.78,10.93,4.66,15.34C405.1,595.22,408.06,597.12,404.67,600.67Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M421,595.67c-1.36,1.21-2.2,4.47-2.28,6.31,1.62-1.1,2.77-3.11,4.23-4.29-.08,1,.44,1.94.44,2.94,1.16-.49,3.08-6.27,1.88-7.56-2-2.16-4.45,1.91-4.6,3.6" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M520.33,553.33c9.15-3.9,20-7.21,30-8.17,2.22-.21,5.83-1.27,6,1.5s-5,4.7-7.23,5.34c4.14,0,8.17-.85,8.57,4,.36,4.31-1.6,9.12-4.31,12.29,10.7,1.49,13.52-12.74,11.23-20.34-.68-2.26-1.85-7.69-4.26-8.78-4.86-2.2-15.12,5.39-19.33,6.85" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M562,571.67c-.11,2.51,1.66,4.34,2.42,6.58.86,2.53,1.2,5.24,2,7.76,1.42,4.23,2.9,8.37,4.2,12.51,2.39,7.66,8.36,10.46,15.67,11.15,3.63.34,8.25.4,10.72,3.35-3.93,4.38-18.12,1.2-20,6.92,3.86,1.23,8.51.46,12.29,2.17-3.4,1.47-8.66.3-12,1.89,3.57,1.88,7.83,3.39,11,5.62-4.23.31-9-1.32-13.05.46S567,636.2,563.6,639c-3.18,2.6-5.39,6.43-6.94,10.33s-.42,6.65,0,10.29c-2.76-.2-7.7-5.19-8.55-8-1.25-4.1,1.43-9.94,3-13.5,5.47-12.44,2.85-28.16,3.29-41.68.33-10,.32-18.93,2.32-28.48" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M548.67,654c-.32,4.49,2.76,12.28,6.67,14.5,5.9,3.35,4.38-4.76,4.62-8.45A12.91,12.91,0,0,1,548.67,654Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M278.33,551c1.84,2.56,6.92,2.59,9.74,3.33,4.29,1.14,8.62,2,12.93,2.91,5.16,1.13,13.37,1.77,17.63,4.35-11.6,1-22.56-1.3-34-2.18A150.75,150.75,0,0,1,269.32,557c-2.88-.52-10.85-1.35-12.34,2-.49,1.09.91,3.56,1,4.71.17,1.6-.46,3.81.05,5.37,1.07,3.27,6.25,6.05,9.24,7.61a67.67,67.67,0,0,0,13.19,5.19c4.46,1.24,9.51,1.22,13.82,2.76,9,3.2,17.31,7.84,26.68,10.28,6.33,1.65,13,2.17,18.89,4.77-10.65-1.33-21.53-2.58-32.05-4.88-9.17-2-20-3.75-29.5-2.15-7,1.19-11,13.49-12.08,19.46-1.8,9.65-.92,19.28-.91,29,0,4.27-2.06,7.93-2.24,12.31-.18,4.54.48,9.07.24,13.61-.53,10,0,19.72,0,29.68,0,6.15.21,12.38.62,18.22-5-4.71-12.74-5.56-18.72-8.57-2-1-5.91-2-7.31-3.59s-.78-4-.54-6.48c.64-6.56-.42-12.57-1-19-.42-4.44-.39-9.32-1.38-13.52-.39,0-.76,0-1.16,0,.31-2.23,3.13-3,4.95-4.27,3.87-2.68,5.25-5.48,5.94-10.13.6-4,.39-6.59-2.36-9.71-2.06-2.33-5.21-3.94-6.28-7.07-1.5-4.43-.65-10.6-1.29-15.27-.76-5.55-1.75-10.65-1.34-16.3a122.57,122.57,0,0,0-.31-20c-.44-4.87.47-12.84-2.6-16.89-2.24-3-4.2-3.91-3.84-8.33.33-4.08,2.42-8.24,3.76-12.09,1.43-4.11,2.78-7.18,7.39-5.43,6.44,2.45,13.62,7.94,20.52,8.52A74,74,0,0,1,278.33,551Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-3"><path d="M229.33,570c-4.59,1-10.21,6.73-13.46,10.13A142,142,0,0,0,205,592.47c-2.76,3.65-5.61,7.23-8,11.1-2.66,4.32-1.86,7.91-3,12.43-.82,3.24-2.65,3.94-2.57,7.67,0,.83.55,1.58.55,2.47,0,.41-1.29.92-1.24,1.26.35,2.44,2.63,2.17,3.57,4.43.63,1.52-.36,3.16.55,4.67,1.17,1.93,4.15,2.93,5.47,5,3.93,6.08,6.07,10.68,12.69,14.53,6,3.5,12.13,4.91,19,3.38,3.7-.83,12.41-4.35,12-9.26-5.23,3.7-16.81,5.39-17.71-2.9-.32-3-.25-7.19,1.14-10,.89-1.77,2.65-3,3.26-4.88a7.62,7.62,0,0,1,1.76.25c-1.47-3-5-4.91-5.76-8.32-.94-4.51,2.19-9.4,4.16-13.15C237.22,599.1,230.25,585.2,229.33,570Z" transform="translate(-53.25 -44.96)"/></g></g><g id="LIGHTS"><g class="cls-35"><path class="cls-7" d="M552.25,251c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C552.94,253.89,553,252.63,552.25,251Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M543.3,134.37c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C544,137.27,544,136,543.3,134.37Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M467.29,196.29c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C468,199.18,468,197.91,467.29,196.29Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M664,239.37c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C664.73,242.26,664.78,241,664,239.37Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M395.2,206.7c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C395.9,209.6,396,208.33,395.2,206.7Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M490.21,264.49c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C490.91,267.38,491,266.11,490.21,264.49Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M503.78,95.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C504.48,98.75,504.53,97.48,503.78,95.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M681.87,531.06c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C682.56,534,682.62,532.68,681.87,531.06Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M149,482.09c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C149.72,485,149.78,483.72,149,482.09Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M633.27,482.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C634,485.75,634,484.48,633.27,482.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M179.43,517.52c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C180.13,520.42,180.18,519.15,179.43,517.52Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M165.19,633c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C165.88,635.94,165.93,634.67,165.19,633Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M187.74,639.86c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C188.44,642.75,188.49,641.48,187.74,639.86Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M145.49,539.88c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C146.19,542.78,146.24,541.51,145.49,539.88Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M657.92,563.36c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C658.61,566.25,658.67,565,657.92,563.36Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M587.59,553c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36A5.15,5.15,0,0,1,589.4,557C588.28,555.89,588.34,554.63,587.59,553Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M335.84,215.69c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C336.53,218.59,336.58,217.32,335.84,215.69Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M427.19,90.19c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36A5.15,5.15,0,0,1,429,94.19C427.89,93.09,427.94,91.82,427.19,90.19Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M225.82,231.69c0,3.28,0,4.81-2.87,6.4.87,1,2.32,1.66,3,3s.32,3,.73,4.19c0-2.13,1.22-7.54,3.61-8.36a5.15,5.15,0,0,1-2.65-1.25C226.52,234.59,226.57,233.32,225.82,231.69Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M359.42,266.65c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C359.65,267.64,359.67,267.21,359.42,266.65Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M339.39,141c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C339.63,142,339.65,141.57,339.39,141Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M363.07,260.66c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C363.48,262.38,363.51,261.62,363.07,260.66Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M345.15,131.25c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C345.56,133,345.59,132.21,345.15,131.25Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M662.2,258.7c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C662.61,260.41,662.64,259.66,662.2,258.7Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M182.29,542.66c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C182.71,544.37,182.74,543.62,182.29,542.66Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M220.61,677.2c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C221,678.91,221.05,678.16,220.61,677.2Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M116.86,539.75c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C117.27,541.47,117.3,540.71,116.86,539.75Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M669.88,245.85c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C670.29,247.56,670.32,246.81,669.88,245.85Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M592.3,133.64c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C592.71,135.35,592.74,134.6,592.3,133.64Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M99.4,519.52c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C99.81,521.23,99.85,520.48,99.4,519.52Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M629.94,495.14c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C630.35,496.85,630.38,496.1,629.94,495.14Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M578.78,209.48c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C579.19,211.2,579.22,210.45,578.78,209.48Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M498.53,87.64c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95A3,3,0,0,1,499.6,90C498.94,89.35,499,88.6,498.53,87.64Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M621.17,210.72c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C621.58,212.43,621.61,211.68,621.17,210.72Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M129.34,220.08c0,1.12,0,1.64-1,2.18.29.35.79.57,1,1s.11,1,.25,1.43c0-.73.42-2.57,1.23-2.85a1.76,1.76,0,0,1-.9-.43C129.57,221.07,129.59,220.63,129.34,220.08Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-35"><path class="cls-7" d="M133,214.09c0,1.94,0,2.84-1.7,3.79.51.61,1.37,1,1.77,1.79s.19,1.76.43,2.48c0-1.26.72-4.46,2.14-4.95a3,3,0,0,1-1.57-.74C133.4,215.8,133.43,215.05,133,214.09Z" transform="translate(-53.25 -44.96)"/></g></g><g id="DETAILS-2" data-name="DETAILS"><path class="cls-24" d="M479.33,333.67a1,1,0,0,1-.92-1.38c.22-.54.45-1.1.66-1.64a1,1,0,1,1,1.87.72c-.22.56-.45,1.13-.68,1.69A1,1,0,0,1,479.33,333.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M480.33,337a1,1,0,0,1-.38-1.93.65.65,0,0,0,.39-.55,1,1,0,1,1,2,.29,2.62,2.62,0,0,1-1.61,2.11A1,1,0,0,1,480.33,337Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M483.67,332l-.2,0a1,1,0,0,1-.79-1.18,5.48,5.48,0,0,1,1.22-2.46,1,1,0,0,1,1.52,1.31,3.46,3.46,0,0,0-.78,1.54A1,1,0,0,1,483.67,332Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M483,327.67h-.08a1,1,0,0,1-.91-1.08,2.65,2.65,0,0,1,1.54-2.14,1,1,0,1,1,.92,1.78c-.44.23-.46.45-.46.53A1,1,0,0,1,483,327.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M307,335a1,1,0,0,1-.48-.12,4.52,4.52,0,0,1-1.72-1.72,1,1,0,0,1,1.74-1,2.54,2.54,0,0,0,.94,1A1,1,0,0,1,307,335Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M308.67,340.67a1,1,0,0,1-.7-.29,4.44,4.44,0,0,1-1.27-2.15,1,1,0,0,1,1.95-.46,2.52,2.52,0,0,0,.73,1.18,1,1,0,0,1-.7,1.71Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M304,338.67a1,1,0,0,1-.72-.31,5.2,5.2,0,0,1-1.23-2.05,1,1,0,1,1,1.9-.62,3.2,3.2,0,0,0,.77,1.28,1,1,0,0,1-.72,1.69Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M302,330.33a1,1,0,0,1-.69-.28,17,17,0,0,1-2.12-2.48,1,1,0,1,1,1.64-1.15,15,15,0,0,0,1.88,2.19,1,1,0,0,1-.69,1.72Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M261.67,463.67a1,1,0,0,1-.19-2,210.85,210.85,0,0,1,41.19-4,1,1,0,1,1,0,2,208.87,208.87,0,0,0-40.81,4Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M491.33,461.33a1,1,0,0,1-.46-1.89c3.49-1.78,8.65-1.75,13.18-1.72,1.59,0,3.08,0,4.39-.05l.44,0c4.21-.22,9-.48,13,.38a1,1,0,0,1-.42,2c-3.75-.8-8.37-.55-12.46-.34l-.45,0c-1.36.07-2.89.06-4.5.05-4.32,0-9.21-.05-12.27,1.5A1,1,0,0,1,491.33,461.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M394,506.5a1.5,1.5,0,0,1-1.5-1.5V489.67a1.5,1.5,0,0,1,3,0V505A1.5,1.5,0,0,1,394,506.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M397,686.67h-.14a1,1,0,0,1-.85-1.13,6,6,0,0,1,1.2-2.81,1,1,0,1,1,1.58,1.23,4.05,4.05,0,0,0-.8,1.86A1,1,0,0,1,397,686.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M398.67,689a1,1,0,0,1-1-.89,1.25,1.25,0,0,1,1.43-1.43,1.25,1.25,0,0,1-.33,2.32Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M372,601a1,1,0,0,1-.35-.06,1.67,1.67,0,0,1-.94-2.23A1.39,1.39,0,1,1,372,601Zm.6-1.6Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M374.67,599.33a1,1,0,0,1-.65-.24,4,4,0,0,1-1.33-2.22,1,1,0,0,1,2-.42,2,2,0,0,0,.67,1.11,1,1,0,0,1-.65,1.76Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M420.67,598a1,1,0,0,1-1-1v-3a1,1,0,0,1,2,0v3A1,1,0,0,1,420.67,598Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M192,626.33a1,1,0,0,1-.71-1.7c3.28-3.33,12-4.81,15.58-5.29a1,1,0,0,1,.27,2c-5.45.73-12.1,2.35-14.42,4.71A1,1,0,0,1,192,626.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193,630a1,1,0,0,1-.43-1.9,27.69,27.69,0,0,1,3.3-.75,1,1,0,1,1,.24,2c-.68.08-2.55.55-2.81.63A1,1,0,0,1,193,630Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M604.33,629.33l-.21,0a21,21,0,0,1-5-2,21.42,21.42,0,0,0-4.71-2,47.68,47.68,0,0,0-12-1.64h0a1,1,0,0,1,0-2,49.77,49.77,0,0,1,12.52,1.69,22.92,22.92,0,0,1,5.16,2.12,19.2,19.2,0,0,0,4.55,1.87,1,1,0,0,1-.21,2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M605.67,625.67h0a18.9,18.9,0,0,1-5-1.06,14,14,0,0,0-5.2-.94,1,1,0,0,1-1.08-.91,1,1,0,0,1,.91-1.08,15.42,15.42,0,0,1,6,1,17.07,17.07,0,0,0,4.49,1,1,1,0,0,1,0,2Z" transform="translate(-53.25 -44.96)"/></g><g id="LINEART"><path class="cls-24" d="M561,701a2.5,2.5,0,0,1-2.5-2.5V684.63c0-7-.05-14.7-.17-23.48a2.5,2.5,0,1,1,5-.06c.11,8.8.17,16.5.17,23.54V698.5A2.5,2.5,0,0,1,561,701Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M560.38,634.64a2.5,2.5,0,0,1-2.5-2.46c-.25-14.88-.48-30.71-.42-46.42,0-7.15,0-13.43,0-19.2a2.5,2.5,0,0,1,2.49-2.51h0a2.5,2.5,0,0,1,2.5,2.49c0,5.78,0,12.08,0,19.24-.07,15.65.17,31.46.42,46.31a2.5,2.5,0,0,1-2.46,2.54Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M559.63,541.5a2.5,2.5,0,0,1-2.5-2.44c-.29-12.49-.76-23.82-1.45-34.65a2.5,2.5,0,0,1,5-.31c.68,10.89,1.16,22.29,1.45,34.84a2.5,2.5,0,0,1-2.44,2.56Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M547.24,430.29a2.5,2.5,0,0,1-2.4-1.8q-.26-.9-.53-1.8c-5.82-19.3-15-43.91-34.51-63.11-13.58-13.36-32.91-23.48-57.45-30.09-6.15-1.65-11.36-2.85-16-3.66-17.78-3.15-36.76-2.18-55.12-1.24-4,.21-8.05.41-12,.57-35.32,1.43-66.4,13.65-87.49,34.41-19.51,19.2-28.69,43.81-34.51,63.11a2.5,2.5,0,1,1-4.79-1.44c6-19.87,15.47-45.24,35.79-65.23,22-21.63,54.23-34.36,90.8-35.84,4-.16,8-.37,12-.57,18.64-1,37.91-1.94,56.25,1.31,4.74.84,10.1,2.07,16.38,3.76C479,335.49,499.11,346,513.31,360c20.32,20,29.8,45.36,35.79,65.23q.28.92.55,1.85a2.5,2.5,0,0,1-2.4,3.2Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M232,540h0a2.5,2.5,0,0,1-2.46-2.54c.17-9.84.55-19.7,1.1-29.31a2.5,2.5,0,1,1,5,.29c-.55,9.54-.92,19.33-1.1,29.11A2.5,2.5,0,0,1,232,540Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M235.67,635.7a2.5,2.5,0,0,1-2.5-2.38c-.18-3.87-.41-7.43-.7-10.88-1.6-19.07-2.59-38-2.94-56.19a2.5,2.5,0,1,1,5-.1c.35,18.11,1.33,36.91,2.92,55.87.3,3.51.53,7.13.72,11.06a2.5,2.5,0,0,1-2.38,2.62Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M236.44,704.72a2.5,2.5,0,0,1-2.47-2.16c-.71-5.17-.46-6.39,0-7.95.24-.79.55-1.77.36-5.79-.41-9-.49-18.31-.57-27.28v-1.29a2.5,2.5,0,0,1,5,0v1.29c.08,8.93.16,18.16.56,27.1.2,4.52-.14,6.06-.58,7.49-.24.78-.45,1.45.15,5.79a2.5,2.5,0,0,1-2.13,2.82Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M291,354.83a2.49,2.49,0,0,1-1-.23c-7-3.19-17.19-13.06-18.28-23.27-.61-5.75,1.75-10.8,6.83-14.6a16.09,16.09,0,0,1,13.71-3.12c13.11,3,23,20.91,24.85,24.47a2.5,2.5,0,1,1-4.44,2.31c-4.62-8.89-13-20-21.53-21.9a11.15,11.15,0,0,0-9.6,2.25c-3.69,2.76-5.28,6.05-4.85,10.07.85,7.94,9.54,16.56,15.39,19.25a2.5,2.5,0,0,1-1,4.77Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M497.67,352.83a2.5,2.5,0,0,1-1.55-4.46l1.68-1.32c3.62-2.82,7.72-6,10.47-9.17a14.43,14.43,0,0,0,2.58-15.12c-2-4.73-6.39-7.56-11.94-7.77-11-.44-21.13,11.1-24.17,22a2.5,2.5,0,1,1-4.82-1.34c3.63-13,15.5-26.18,29.17-25.66,7.45.28,13.56,4.31,16.34,10.79A19.45,19.45,0,0,1,512,341.18c-3.06,3.5-7.36,6.85-11.15,9.81l-1.66,1.3A2.49,2.49,0,0,1,497.67,352.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.17,481.17a2.49,2.49,0,0,1-1.79-.76c-2.65-2.72-3.46-6.28-2-9.07a13.19,13.19,0,0,0,.68-3.53c.08-.73.16-1.42.28-2.06a67.86,67.86,0,0,1,7-20.67A68.93,68.93,0,0,1,247.25,421a66,66,0,0,1,97.16,20.76c3,5.36,4.85,11.47,6.64,17.78a3.24,3.24,0,0,0,1.57,2.36c2.67,2.24,3,4.42,2.81,5.86s-1.12,3.55-4.45,5.1a2.5,2.5,0,0,1-2.12-4.53c1.26-.59,1.59-1.12,1.6-1.22s-.14-.6-1.07-1.37a7.5,7.5,0,0,1-3.16-4.82c-1.71-6-3.47-11.82-6.2-16.71A60.88,60.88,0,0,0,250.23,425a64,64,0,0,0-18.46,22.4,63.26,63.26,0,0,0-6.56,19.27c-.09.51-.16,1.11-.23,1.73a15.77,15.77,0,0,1-1.19,5.22c-.34.67-.12,2,1.17,3.33a2.5,2.5,0,0,1-1.79,4.24Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.66,540c-.89,0-1.78,0-2.68-.05a66.06,66.06,0,0,1-63.3-61.13,2.5,2.5,0,0,1,5-.37,61.13,61.13,0,0,0,122-2.13c.08-2,.06-3.93,0-5.88a2.5,2.5,0,1,1,5-.27c.12,2.1.13,4.24,0,6.35A66.22,66.22,0,0,1,286.66,540Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M284.37,485.33a15.13,15.13,0,0,1-15-13.82,2.5,2.5,0,0,1,5-.43,10.13,10.13,0,1,0,20.19-1.76,2.5,2.5,0,0,1,5-.43,15.15,15.15,0,0,1-13.76,16.39C285.26,485.31,284.81,485.33,284.37,485.33Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M223.17,481.17a2.5,2.5,0,0,1-.53-4.94l2.9-.63c7.58-1.64,14.74-3.2,22.69-4.56,3.42-.59,6.9-1.29,10.26-2a171.15,171.15,0,0,1,22-3.46c17.18-1.17,34.56-.63,49.51,0,1.58.06,3.28.05,5.09,0,5.17,0,10.51-.05,14.94,1.54a2.5,2.5,0,0,1-1.69,4.71c-3.6-1.29-8.49-1.27-13.22-1.25-1.86,0-3.62,0-5.31,0-14.82-.59-32-1.13-49,0a167.45,167.45,0,0,0-21.4,3.37c-3.4.69-6.92,1.4-10.41,2-7.85,1.35-15,2.89-22.48,4.52l-2.9.63A2.47,2.47,0,0,1,223.17,481.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M439.67,478.95a2.49,2.49,0,0,1-.8-.13c-3.48-1.17-4.63-3.13-5-4.57s-.26-3.61,2.14-6.14a3.25,3.25,0,0,0,1.29-2.52c1.07-6.47,2.23-12.75,4.6-18.41a65.89,65.89,0,0,1,94.21-31.56,68.94,68.94,0,0,1,22.51,21.73,67.86,67.86,0,0,1,9.31,19.75c.19.63.34,1.3.51,2a13.18,13.18,0,0,0,1.08,3.42c1.71,2.61,1.32,6.24-1,9.24a2.5,2.5,0,0,1-4-3.06c1.13-1.46,1.2-2.8.79-3.43a15.75,15.75,0,0,1-1.77-5.05c-.14-.61-.27-1.2-.42-1.7a63.24,63.24,0,0,0-8.68-18.41,64,64,0,0,0-20.86-20.18,61,61,0,0,0-87.09,29.16c-2.16,5.17-3.26,11.13-4.28,17.3a7.5,7.5,0,0,1-2.6,5.15c-.83.88-.93,1.4-.91,1.49s.41.59,1.73,1a2.5,2.5,0,0,1-.8,4.87Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M502.91,538.8a66.23,66.23,0,0,1-65.32-56.08c-.32-2.1-.55-4.22-.67-6.32a2.5,2.5,0,1,1,5-.29c.11,1.94.32,3.91.62,5.85A61.13,61.13,0,0,0,564,470.36a2.5,2.5,0,0,1,5-.2,66.18,66.18,0,0,1-66.13,68.64Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M504.75,483.85a15.13,15.13,0,0,1-15.12-14.74,2.5,2.5,0,0,1,2.43-2.56h.07a2.5,2.5,0,0,1,2.5,2.44,10.13,10.13,0,1,0,20.26-.52,2.5,2.5,0,0,1,2.43-2.56,2.46,2.46,0,0,1,2.56,2.43,15.15,15.15,0,0,1-14.74,15.51Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M440.26,477.84a2.5,2.5,0,0,1-1.11-4.74c4.22-2.08,9.53-2.66,14.67-3.21,1.79-.19,3.48-.38,5-.62,14.79-2.28,32-4.77,49.2-5.53a170.23,170.23,0,0,1,22.29,1c3.42.3,7,.6,10.42.8,8.08.46,15.38,1.2,23.12,2l2.89.29a2.5,2.5,0,0,1-.5,5l-2.89-.29c-7.68-.78-14.93-1.51-22.9-2-3.54-.2-7.11-.51-10.57-.81a168.33,168.33,0,0,0-21.64-.94c-16.95.75-34,3.23-48.66,5.48-1.67.26-3.42.45-5.27.65-4.71.51-9.57,1-13,2.72A2.48,2.48,0,0,1,440.26,477.84Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M393.72,477.54c-4.22,0-8.34-.81-10.74-2.32a6,6,0,0,1-3.13-5.28c0-2.5,1.83-5.12,4.53-6.69a20.53,20.53,0,0,1,8.22-2.34h0a25.62,25.62,0,0,1,11.67,1.54,7.17,7.17,0,0,1,4.44,5.39,6.91,6.91,0,0,1-2.52,6.33C403.56,476.47,398.57,477.54,393.72,477.54Zm-.67-11.65a15.45,15.45,0,0,0-6.16,1.69,3.86,3.86,0,0,0-2,2.46c0,.3.26.62.79,1,3.77,2.38,14.27,2,17.29-.6a2,2,0,0,0,.85-1.78,2.22,2.22,0,0,0-1.46-1.56,20.71,20.71,0,0,0-9.27-1.16Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M377.41,495.74a10.85,10.85,0,0,1-7.91-3c-2.15-2.23-2.76-5.43-1.73-9,1.63-5.66,8.82-13.11,13.56-15.24a2.5,2.5,0,0,1,2,4.56c-3.85,1.73-9.71,8.27-10.8,12.06-.53,1.84-.35,3.23.53,4.15,1.3,1.35,4.16,1.8,7,1.11a43.8,43.8,0,0,0,4.76-1.59,29.73,29.73,0,0,1,9.23-2.35,16.92,16.92,0,0,1,6.25,1.18l.88.29c1.06.34,2.08.74,3.07,1.13a31.94,31.94,0,0,0,3.89,1.34c2.8.69,5.66.24,7-1.11.88-.92,1.06-2.31.53-4.15-1.09-3.79-7-10.33-10.8-12.06a2.5,2.5,0,1,1,2-4.56c4.74,2.13,11.93,9.58,13.56,15.24,1,3.57.42,6.77-1.73,9-2.6,2.69-7.1,3.65-11.76,2.49a36.21,36.21,0,0,1-4.51-1.54c-1-.37-1.85-.73-2.76-1l-.94-.31a12.24,12.24,0,0,0-4.46-.93,25.55,25.55,0,0,0-7.69,2,48.2,48.2,0,0,1-5.31,1.76A16,16,0,0,1,377.41,495.74Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M394.25,507.75a17.94,17.94,0,0,1-5.4-.66c-3.8-1.3-3.85-4.93-3.88-7.34,0-.32,0-.65,0-1-.08-2.48-.06-5.07,0-7.36v-.91a2.5,2.5,0,0,1,2.5-2.48h0a2.5,2.5,0,0,1,2.48,2.52v.91c0,2.24,0,4.78,0,7.16,0,.36,0,.72,0,1.08,0,2.28.17,2.56.5,2.67,1.55.53,5.59.49,7.9.11a6.24,6.24,0,0,0,.89-.2c0-.3,0-.75,0-1.13,0-.63-.09-1.42-.08-2.32,0-1.83,0-3-.08-4.32,0-1.11-.09-2.26-.09-3.82a2.5,2.5,0,0,1,5,0c0,1.47,0,2.57.08,3.63.05,1.29.1,2.63.08,4.58,0,.71,0,1.34.07,1.94.14,2.26.36,5.69-5,6.58A33.27,33.27,0,0,1,394.25,507.75Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.42,555.33A80.37,80.37,0,1,1,366.79,475,80.46,80.46,0,0,1,286.42,555.33Zm0-150.74A70.37,70.37,0,1,0,356.79,475,70.45,70.45,0,0,0,286.42,404.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M503,554.33A80.37,80.37,0,1,1,583.34,474,80.46,80.46,0,0,1,503,554.33Zm0-150.74A70.37,70.37,0,1,0,573.34,474,70.45,70.45,0,0,0,503,403.59Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M426,465a5,5,0,0,1-4.26-2.37c-1.47-2.38-11.35-7.06-25.79-7.89-13.45-.77-24.29,2.35-29,8.36a5,5,0,0,1-7.85-6.19c6.85-8.69,20.51-13.12,37.45-12.15,12.95.74,29,5,33.73,12.62A5,5,0,0,1,426,465Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M210,462h-.27c-5.85-.31-10.27-2.79-12.11-6.8a8.69,8.69,0,0,1,1-9.07c2.79-3.64,8-5.12,14.2-4.06a5,5,0,0,1-1.68,9.86,11.76,11.76,0,0,0-2.75-.18,10.12,10.12,0,0,0,1.86.26,5,5,0,0,1-.26,10Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M579,462a5,5,0,0,1-.26-10,10.1,10.1,0,0,0,1.86-.26,11.7,11.7,0,0,0-2.75.18,5,5,0,0,1-1.68-9.86c6.23-1.07,11.41.42,14.2,4.06a8.69,8.69,0,0,1,1,9.07c-1.85,4-6.26,6.49-12.11,6.8Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M382.36,612.58a2.56,2.56,0,0,1-.46,0c-10.2-1.9-18.76-4.71-27.82-7.67-3.3-1.08-6.7-2.2-10.31-3.31-21.85-6.75-44.73-12.41-66.85-17.89-8.13-2-16.54-4.1-24.7-6.19l-1.4-.36c-8.17-2.07-19.37-4.9-24-13.77-3.18-6.08,0-16.94,2.14-24.13.25-.86.49-1.65.68-2.35a2.5,2.5,0,0,1,4.82,1.35c-.2.71-.44,1.53-.7,2.41-1.66,5.63-4.74,16.12-2.5,20.4,3.62,6.9,13.15,9.31,20.82,11.25l1.41.36c8.14,2.08,16.54,4.16,24.66,6.18,22.19,5.5,45.14,11.18,67.13,18,3.65,1.13,7.08,2.25,10.39,3.33,8.9,2.92,17.31,5.67,27.18,7.51a2.5,2.5,0,0,1-.46,5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M396.13,578.5a2.54,2.54,0,0,1-.52-.06c-11.08-2.36-21.5-4.28-32.79-6-44.24-6.84-90.83-15.53-131.76-32.57a2.5,2.5,0,1,1,1.92-4.62c40.44,16.84,86.67,25.45,130.6,32.25,11.39,1.76,21.9,3.69,33.07,6.08a2.5,2.5,0,0,1-.52,4.95Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M382.36,612.58h-.18a2.5,2.5,0,0,1-2.32-2.67c.53-7.58,4.21-14.32,7.78-20.84,2.44-4.47,4.75-8.69,6.09-13.12a2.5,2.5,0,1,1,4.79,1.45c-1.49,4.92-4,9.58-6.49,14.07-3.46,6.33-6.73,12.3-7.18,18.79A2.5,2.5,0,0,1,382.36,612.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M411,612.58a2.5,2.5,0,0,1-.46-5c9.73-1.82,17.93-4.52,26.61-7.38,3.41-1.13,6.94-2.29,10.73-3.46,22-6.79,44.92-12.47,67.11-18,8.13-2,16.53-4.1,24.68-6.18l.33-.08c7.38-1.89,15.74-4,19.9-10.15,3.84-5.67,2.12-10-.26-15.95a65.76,65.76,0,0,1-2.41-6.77,2.5,2.5,0,1,1,4.81-1.35,61.79,61.79,0,0,0,2.24,6.27c2.5,6.27,5.09,12.75-.25,20.61-5.22,7.69-15,10.18-22.79,12.19l-.33.08c-8.16,2.09-16.58,4.17-24.71,6.19-22.12,5.48-45,11.14-66.83,17.89-3.74,1.16-7.25,2.31-10.64,3.43-8.85,2.92-17.2,5.67-27.26,7.55A2.57,2.57,0,0,1,411,612.58Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M397,578.5a2.5,2.5,0,0,1-.52-4.95c11.18-2.38,21.68-4.32,33.07-6.08,40.41-6.25,86.22-13.34,128.13-30.79a2.5,2.5,0,1,1,1.92,4.62C517.14,559,471,566.12,430.32,572.42c-11.29,1.75-21.71,3.66-32.79,6A2.54,2.54,0,0,1,397,578.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M411,612.58a2.5,2.5,0,0,1-2.49-2.33c-.45-6.45-3.76-12.4-7.27-18.7-2.52-4.53-5.13-9.21-6.63-14.17a2.5,2.5,0,1,1,4.79-1.45c1.34,4.44,3.71,8.69,6.21,13.18,3.62,6.5,7.36,13.22,7.89,20.78a2.5,2.5,0,0,1-2.32,2.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M229.87,663.57a41.28,41.28,0,0,1-16.34-3.66,39.84,39.84,0,0,1-19.73-21.19,2.5,2.5,0,0,1,4.63-1.89,34.79,34.79,0,0,0,17.19,18.54c6.44,3,21.18,6.34,25.68-2,3.47-6.46.36-10.22-5-15.81a36.79,36.79,0,0,1-6.18-7.72,6.23,6.23,0,0,1-2.7-3.22,5.9,5.9,0,0,0-.87-1.53,2.5,2.5,0,0,1,3.93-3.09A10.75,10.75,0,0,1,232,624.6c.29.67.32.74,1.16,1.19a2.5,2.5,0,0,1,1.09,1.14c1.18,2.47,3.34,4.73,5.64,7.13,5,5.18,11.16,11.64,5.8,21.63C242.57,661.53,236.38,663.57,229.87,663.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M193.09,620.7H193a2.5,2.5,0,0,1-2.38-2.61c.45-9.82,3.75-18.54,10.68-28.29,5.72-8,18.92-20.32,30.37-22.5a2.5,2.5,0,1,1,.93,4.91c-9,1.72-21.17,12-27.23,20.49-6.34,8.92-9.36,16.82-9.76,25.62A2.5,2.5,0,0,1,193.09,620.7Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M228.33,626.08a2.5,2.5,0,0,1-2-4.06l0,0a2.5,2.5,0,0,1,.44-2,3.43,3.43,0,0,1,.48-1.3,2.52,2.52,0,0,1,.31-.85,71,71,0,0,0,4.08-8.66,2.5,2.5,0,0,1,4.63,1.89,84,84,0,0,1-3.7,8,2.5,2.5,0,0,1-.55,1.84l-.24.27a2.83,2.83,0,0,1-.18.82,4.76,4.76,0,0,1-1.27,3l-.11.13A2.5,2.5,0,0,1,228.33,626.08Zm-1.22-2.85h0Zm4.08-6.18h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M196.12,640.27a2.51,2.51,0,0,1-2.43-3.1c2.94-11.89,21.33-14.36,31.21-15.68,1.25-.17,2.34-.31,3.19-.45a2.5,2.5,0,1,1,.82,4.93c-.89.15-2,.3-3.34.48-8.08,1.08-24.9,3.34-27,11.93A2.5,2.5,0,0,1,196.12,640.27Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M195.84,640.28a5.69,5.69,0,0,1-4.05-1.56c-2.2-2.12-2.4-5.65-2.39-8.37l-.2-.1a3.72,3.72,0,0,0-.83-.34,2.5,2.5,0,0,1-1.65-4.21,12.38,12.38,0,0,0,.84-1.07c.21-.29.44-.6.68-.9a4.87,4.87,0,0,1-.28-4.23c1.74-4.17,9.13-5.1,16.86-5.49,10.49-.53,22.23,1.82,25.58,2.55a2.5,2.5,0,1,1-1.07,4.88c-6.58-1.44-16.4-2.83-24.2-2.44-9.92.5-12,1.88-12.48,2.35a3.58,3.58,0,0,0,.67,1,2.5,2.5,0,0,1-.33,3.64,3.19,3.19,0,0,0-.29.26,2.5,2.5,0,0,1,1.73,2.39v.79c0,1.45-.09,4.83.84,5.72.06.06.2.2.72.16a2.5,2.5,0,0,1,.29,5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M565.37,663.57c-6.51,0-12.69-2-15.83-7.89-5.36-10,.83-16.45,5.8-21.63,2.3-2.39,4.47-4.66,5.64-7.12a2.49,2.49,0,0,1,1.09-1.14c.85-.45.88-.52,1.16-1.19a10.73,10.73,0,0,1,1.54-2.65,2.5,2.5,0,0,1,3.93,3.09,5.91,5.91,0,0,0-.87,1.53,6.23,6.23,0,0,1-2.7,3.22,36.77,36.77,0,0,1-6.18,7.72c-5.36,5.59-8.47,9.34-5,15.81,4.5,8.39,19.24,5,25.68,2a34.79,34.79,0,0,0,17.19-18.54,2.5,2.5,0,1,1,4.63,1.89,39.84,39.84,0,0,1-19.73,21.19A41.28,41.28,0,0,1,565.37,663.57Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M602.15,620.7a2.5,2.5,0,0,1-2.5-2.38c-.41-8.8-3.42-16.7-9.76-25.62-5.67-8-20.58-19.22-29.88-21a2.5,2.5,0,1,1,.93-4.91c10.84,2.06,26.66,14.06,33,23,6.94,9.74,10.23,18.47,10.68,28.29a2.5,2.5,0,0,1-2.38,2.61Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M566.91,626.08a2.49,2.49,0,0,1-2-.94l-.11-.14a4.77,4.77,0,0,1-1.27-3,2.8,2.8,0,0,1-.18-.83l-.24-.27a2.5,2.5,0,0,1-.55-1.84,84,84,0,0,1-3.7-8,2.5,2.5,0,1,1,4.63-1.89,71.12,71.12,0,0,0,4.08,8.66,2.5,2.5,0,0,1,.31.85,3.43,3.43,0,0,1,.48,1.31,2.48,2.48,0,0,1,.44,1,2.53,2.53,0,0,1,0,1l0,0a2.5,2.5,0,0,1-2,4.06Zm1.22-2.85h0Zm-4.08-6.18h0Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.12,640.27a2.5,2.5,0,0,1-2.42-1.9c-2.12-8.59-18.94-10.84-27-11.93-1.31-.18-2.45-.33-3.34-.48a2.5,2.5,0,1,1,.82-4.93c.85.14,1.93.29,3.19.45,9.88,1.33,28.28,3.79,31.21,15.68a2.5,2.5,0,0,1-2.43,3.1Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M599.4,640.28H599a2.5,2.5,0,1,1,.29-5c.51,0,.66-.11.72-.16.92-.89.86-4.27.84-5.72v-.79a2.5,2.5,0,0,1,1.73-2.39,3.12,3.12,0,0,0-.29-.26,2.5,2.5,0,0,1-.33-3.64,3.58,3.58,0,0,0,.67-1c-.44-.47-2.56-1.85-12.43-2.34-7.86-.39-17.68,1-24.26,2.44a2.5,2.5,0,1,1-1.07-4.88c3.35-.73,15.08-3.08,25.52-2.55,7.79.39,15.18,1.32,16.92,5.49a4.87,4.87,0,0,1-.28,4.23c.24.31.46.61.68.9a12.45,12.45,0,0,0,.84,1.07,2.5,2.5,0,0,1-1.65,4.21,3.73,3.73,0,0,0-.83.34l-.2.1c0,2.72-.18,6.25-2.39,8.37A5.69,5.69,0,0,1,599.4,640.28Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.89,605.19a13.23,13.23,0,0,1-2.15-.17,13.89,13.89,0,0,1-9.52-6.77,2.5,2.5,0,1,1,4.23-2.66,8.94,8.94,0,0,0,6.1,4.49c3.11.51,6.78-.8,10.32-3.69a2.5,2.5,0,1,1,3.16,3.88C404.08,603.49,399.85,605.19,395.89,605.19Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M381.45,690.17h-.18A2.5,2.5,0,0,1,379,687.5c.55-7.7,1.54-17.78,2.59-28.45,2-20.32,4.27-43.35,4.29-57.89a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5c0,14.78-2.3,37.94-4.31,58.37-1,10.64-2,20.68-2.58,28.32A2.5,2.5,0,0,1,381.45,690.17Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M409.89,690.37A2.5,2.5,0,0,1,407.4,688c-.55-7.75-1.55-18-2.62-28.77-2-20.33-4.27-43.38-4.29-58.11a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5c0,14.49,2.27,37.41,4.27,57.63,1.07,10.85,2.08,21.1,2.63,28.91a2.5,2.5,0,0,1-2.32,2.67Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.67,712.41a2.5,2.5,0,0,1-2-.94A128.91,128.91,0,0,1,379.22,689a2.5,2.5,0,1,1,4.5-2.19,123.3,123.3,0,0,0,13.91,21.57,2.5,2.5,0,0,1-2,4.06Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M395.67,712.41a2.5,2.5,0,0,1-2-4.06,124.1,124.1,0,0,0,13.94-21.57,2.5,2.5,0,0,1,4.5,2.19,129.3,129.3,0,0,1-14.52,22.5A2.5,2.5,0,0,1,395.67,712.41Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M222,539.15a40.07,40.07,0,0,1-11.74-1.43c-25.41-7.8-19.39-36.26-14.54-59.13,1.89-8.93,3.68-17.36,3.44-23.49a2.5,2.5,0,1,1,5-.19c.26,6.75-1.59,15.48-3.55,24.72-4.65,22-9.93,46.86,11.12,53.32,4.87,1.5,10.81,1.27,16.55,1,2-.08,4.08-.16,6.05-.16a2.5,2.5,0,0,1,0,5c-1.87,0-3.81.07-5.86.15S224.16,539.15,222,539.15Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M559,542.83a2.5,2.5,0,0,1-2.1-3.85c2.37-3.68,7.95-4.14,13.34-4.59,3.45-.29,7-.59,8.82-1.67,11.8-7.07,17.55-20.9,14.67-35.23-1.06-5.25-2.55-10.19-4-15C587.16,474,584.5,465.2,584.5,455a2.5,2.5,0,0,1,5,0c0,9.46,2.44,17.53,5,26.07,1.48,4.9,3,10,4.11,15.44,3.31,16.43-3.36,32.33-17,40.51-2.79,1.68-7,2-11,2.36-3.8.32-8.52.71-9.55,2.32A2.5,2.5,0,0,1,559,542.83Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M486,344.5a2.5,2.5,0,0,1-1.32-4.62c2.93-1.83,5.25-6.67,6.36-13.29a2.5,2.5,0,1,1,4.93.82c-1,5.77-3.24,13.35-8.64,16.71A2.49,2.49,0,0,1,486,344.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M487,345.5a2.5,2.5,0,0,1-2.07-3.9c2.69-4,7.07-5.2,10.93-6.28.81-.23,1.61-.45,2.37-.7a2.5,2.5,0,1,1,1.53,4.76c-.83.27-1.68.51-2.56.75-3.33.93-6.48,1.82-8.14,4.27A2.5,2.5,0,0,1,487,345.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M300,347.5a2.49,2.49,0,0,1-1.68-.65L297,345.61c-2.17-2-7.92-7.44-10.14-7.13a2.5,2.5,0,1,1-.68-5c4.23-.58,9.15,3.66,14.24,8.44l1.28,1.19A2.5,2.5,0,0,1,300,347.5Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M300.5,347.5a2.5,2.5,0,0,1-2.07-1.1c-2.93-4.33-2.93-10.32-2.93-15.13v-.77A2.5,2.5,0,0,1,298,328h0a2.5,2.5,0,0,1,2.5,2.5v.77c0,4.34,0,9.26,2.07,12.33a2.5,2.5,0,0,1-2.07,3.9Z" transform="translate(-53.25 -44.96)"/></g><g id="HAIR_DETAILS" data-name="HAIR DETAILS"><path class="cls-24" d="M400.45,398h0Z" transform="translate(-53.25 -44.96)"/></g><g id="layers"><g class="cls-36"><circle class="cls-7" cx="233.17" cy="430" r="75.37"/></g><g class="cls-36"><circle class="cls-7" cx="449.72" cy="429" r="75.37"/></g><path class="cls-24" d="M426,465a5,5,0,0,1-4.26-2.37c-1.47-2.38-11.35-7.06-25.79-7.89-13.45-.77-24.29,2.35-29,8.36a5,5,0,0,1-7.85-6.19c6.85-8.69,20.51-13.12,37.45-12.15,12.95.74,29,5,33.73,12.62A5,5,0,0,1,426,465Z" transform="translate(-53.25 -44.96)"/><path class="cls-24" d="M286.42,555.33A80.37,80.37,0,1,1,366.79,475,80.46,80.46,0,0,1,286.42,555.33Zm0-150.74A70.37,70.37,0,1,0,356.79,475,70.45,70.45,0,0,0,286.42,404.59Z" transform="translate(-53.25 -44.96)"/><g class="cls-37"><path class="cls-7" d="M532.48,427.22c1.29,3.14,3.66,6,5.79,8.72a96.55,96.55,0,0,1,18.14,38.2c1,4.5,7.56,4.49,9.69.91a10.2,10.2,0,0,0,1.13-4.2,51.8,51.8,0,0,0-3.32-24.26c-1.32-3.37-3.17-5.84-5.09-8.79-2.11-3.25-3-6.77-6-9.49-3.77-3.43-7.3-7.66-11.88-10.14-2.12-1.15-4.77-2-6.87-.84a5.82,5.82,0,0,0-2.52,4.86A11.66,11.66,0,0,0,532.48,427.22Z" transform="translate(-53.25 -44.96)"/></g><g class="cls-37"><path class="cls-7" d="M316.29,432.4c1.29,3.14,3.66,6,5.79,8.72a96.55,96.55,0,0,1,18.14,38.2c1,4.5,7.56,4.49,9.69.91a10.2,10.2,0,0,0,1.13-4.2,51.8,51.8,0,0,0-3.32-24.26c-1.32-3.37-3.17-5.84-5.09-8.79-2.11-3.25-3-6.77-6-9.49-3.77-3.43-7.3-7.66-11.88-10.14-2.12-1.15-4.77-2-6.87-.84a5.82,5.82,0,0,0-2.52,4.86A11.66,11.66,0,0,0,316.29,432.4Z" transform="translate(-53.25 -44.96)"/></g><path class="cls-24" d="M503,554.33A80.37,80.37,0,1,1,583.34,474,80.46,80.46,0,0,1,503,554.33Zm0-150.74A70.37,70.37,0,1,0,573.34,474,70.45,70.45,0,0,0,503,403.59Z" transform="translate(-53.25 -44.96)"/></g><g id="CIRCLE"><path class="cls-24" d="M397.38,745.79A344.13,344.13,0,0,1,154,158.33,341.87,341.87,0,0,1,397.38,57.54h3l11.29.28h.07a344.13,344.13,0,0,1-14.36,688Zm0-679.25c-184.79,0-335.12,150.34-335.12,335.13S212.59,736.79,397.38,736.79,732.5,586.46,732.5,401.67A334.16,334.16,0,0,0,411.4,66.83l-11.17-.28Z" transform="translate(-53.25 -44.96)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyShadows.png b/vendor/github.com/golang/dep/docs/assets/DigbyShadows.png deleted file mode 100644 index 649214512735de02f57bd0a5b31d71e6d9732d55..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyShadows.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyShadows.svg b/vendor/github.com/golang/dep/docs/assets/DigbyShadows.svg deleted file mode 100644 index 305806cd97af72103c22e99fbe1b2e29a256e786..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyShadows.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720.07 762.53"><defs><style>.cls-1{fill:#ced8d2;}.cls-2{fill:#1d1d1b;}.cls-3{opacity:0.2;}.cls-4{fill:#050505;}.cls-5{fill:#ccbca8;}.cls-6{fill:#b7a38d;}.cls-7{fill:#b79765;}.cls-8{fill:#fff;}.cls-9{fill:#d7b89b;}.cls-10{opacity:0.27;}.cls-11{opacity:0.51;}.cls-12{fill:#e3fbfc;}.cls-13{opacity:0.56;}.cls-14{opacity:0.39;}.cls-15{fill:none;stroke:#1d1d1b;stroke-linecap:round;stroke-linejoin:round;stroke-width:5px;}</style></defs><title>BoyerShadows</title><g id="BACKGROUND_OCLOR" data-name="BACKGROUND OCLOR"><path class="cls-1" d="M604,97c102.41,62,170.85,174.54,170.85,303,0,195.53-158.51,354-354,354s-354-158.51-354-354A352.48,352.48,0,0,1,139,185.68l6.95-8.83A356,356,0,0,1,220.64,108Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M774.33,418.17H743a2.5,2.5,0,0,1,0-5h31.33a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/></g><g id="shadow"><g class="cls-3"><path class="cls-4" d="M683,482.33c-18.83,3.44-37.15,12-54.59,19.58-9,3.89-18.46,6.69-27.67,10.08-5.37,2-15.08,4-18.46,8.83.79-8.35-.94-19-3.12-27.1-2.32-8.64-7.87-15.93-6.74-25.29,10.4-.89,21.59,1.16,32.08,1.24,14.77.12,29.37.81,44.09,1.92C660,472.46,673.68,471.94,683,482.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M291,512.33c-30.31,0-58.76,13-86.18,24.53-16.11,6.77-34.42,9.42-51.16,14.65-10.28,3.21-21.33,5.38-31.33,8.65-5.92,1.94-11.34,5.75-17.38,7.26-3.81-5.92-4.16-13.61-6.52-20.21-3.8-10.67-7.68-21.23-11.12-32C83.14,502,72,486.26,73.7,471.75c10.35.26,20.59,2.61,31.22,2.58,15.75,0,31.49,1.5,47.24,2,23.23.68,46.12,6.64,69,9.85,15.67,2.2,30.65,10.18,46.2,13.66C276.88,501.94,286.34,504.48,291,512.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M267.7,678.5c9.58,1.57,19,4.62,28.83,4.61,8.83,0,17.49-2.54,26.5-2.12,6.67.31,13.14,1.66,19.79,2,15.14.78,28.27,4,42.83,8.8,10.37,3.41,20.13,9,30.39,12.38,8.91,2.93,20.7,1.92,30.18.2,13.06-2.37,25.5-7.44,38.49-10.12,15-3.1,27.84-5.3,42-11.55,12.52-5.54,25.66-10.15,38.37-15.42,4.46-1.85,17.39-3.54,16.48-10.31-.43-3.2-6.84-6.92-9-8.77-7.25-6.25-14.56-10-23.13-14.16-12.82-6.3-19.11-8.37-33.63-7.06-35.83,3.25-71.88,6.13-106.13,17.5-8.81,2.93-20.59,8.56-30,7.84-16.78-1.3-33.56-3-50.42-1.94-10.88.66-21.23,2.49-32.25,1.95-10.47-.52-20.93-3.28-31.32-5-13.79-2.29-29.89-6.58-51.33-3-5.23-.11-14,7.91-14.7,13.33-1.24,9.58,10.32,5.68,16.42,5.39C234.49,662.17,249.83,675.57,267.7,678.5Z" transform="translate(-60.79 2.5)"/></g></g><g id="COLOR"><path class="cls-5" d="M379.67,631.39l50.88-10.2,110.17-24.29,74.73-16.24-13.42-60L594.42,482H680l66-17.43V289l-50.12-6.6V177.1l-23.14-25.84-5.41-2.66L604,148V12.67L539,0,400,5V32H290L222,46V174.2l-83,2.89V312.74L80,314l-3.72,4.24,1,154.1,1.75,2,57.45,11.84,57.15-.53L343,454.5c-.07,0,4.24,22.37,4.47,23.62l4.68,24.73c1.64,8.67,3.73,18.35,2.53,27.22-.51,3.75-.49,7.66-.68,11.44-.17,3.33-.59,6.81,3.25,7.49,1.29.23,2.84-.51,3.7.5s.4,3.3.62,4.55c.37,2.13,1.11,4.34,1.52,6.52l2.81,14.86,5,26.61,5.49,29s.05.34.06.34Z" transform="translate(-60.79 2.5)"/><polygon class="cls-6" points="134.41 488.2 78.21 488.68 13.87 477.07 16.52 316.5 280.95 315.24 352.71 324.5 352.71 390.84 343.71 391 134.41 488.2"/><polygon class="cls-6" points="355.21 150.5 355.21 297.5 635.1 295.83 635.1 179.59 624.21 167 611.96 153.75 591.85 151.83 355.21 150.5"/><polygon class="cls-6" points="161.71 172.5 161.21 48.46 229.21 34.5 366.21 34.5 366.21 148.95 355.21 150.5 354.38 177.49 227.43 179.46 161.71 172.5"/><path class="cls-7" d="M345.88,628.62a19.34,19.34,0,0,0-3.63,1.85c-2.64,1.58-5.9,2.39-8.78,3.45-3.7,1.36-7.63,3.4-11.49,4.23L304,642l-23,.65-32.85-9.12-7.9,6.43-9.5,4.29-10.13,2L217.74,642l4.69-12.72,8.29-7.88-10.09-12.88-6.8-21.21c-.15-4.54-.28-9.09-.46-13.63-.3-7.38-4.83-1.22-7.93-5.12-2.19-2.75,1.31-8.37,2.14-11.07,1.07-3.46,3.65-6.93,4.39-10.37.4-1.85-.79-3.32-.72-5.08,0-1.19.59-1.75.76-2.79.45-2.78-.62-5.74-.77-8.51a117.36,117.36,0,0,0-1.67-11.85c-.45-2.87-.2-6.63-2.31-8.89-1.73-1.86-4.94-2-6.25-4.25-1.1-1.9.2-3.86,0-6-.46-5.23-3.43-9.56-5.81-14.05l-6.84-12.87-8.25-15.52-7.75-20.06,1.3-22.67L182,391.63l3.62-6.63-6.09-2.31-4.76-8.25-.58-11,2.6-4.53,6.43-3.44,5.21,1.25,9.51,9L222.55,355l38.54-8.5,1-7.65,2.74-5.2,5.88-1,3.44,2.58,4.14,9.6,24,.7,32,5.52L350,363.07l8.4-3.82L373.94,355l11.35.35,4.29,3.65L365.95,378.2l6.22,22,14.59,20.54,7.77,6.22-.82,12.28-.82,3.44L343,454.5c-.52.12,6.72,41.69,7.34,45.53.84,5.22,1.15,10.56,2.18,15.72a45.42,45.42,0,0,1,.49,8.61V535.8c0,3.16-.7,9.73,1.75,12.08,1.49,1.43,2.23-.07,3.76.62,2.49,1.13,3,8.54,3.63,11.14L365,572.22c1.27,5.54,3,11.17,3.86,16.79l6.24,40.78,3.37,3.93,3.22-.31.51,6.09-8.08,3.15c-7.9-3.34-15.36-6.95-21.87-12.71a6,6,0,0,0-1.84-1.28A6.58,6.58,0,0,0,345.88,628.62Z" transform="translate(-60.79 2.5)"/><path class="cls-8" d="M367.71,375s25.05-15.79,25.17-15.79,4.73,6.38,4.73,6.38l6.18,19.06-3.15,14-5.14,6.35-5.92,2.45-5.69-4.41-4.45-2.88.39-7.3L371,391.63Z" transform="translate(-60.79 2.5)"/><polygon class="cls-8" points="268 386.47 240.1 389.87 209.14 394.5 194.94 395.41 192.21 407.55 197.47 425.94 207.9 439.05 220.17 446.08 230.11 448.31 240.1 448.06 252.46 444.82 262.21 437.75 268.24 430.09 273.17 419.72 275.01 407.55 273.81 397.65 268 386.47"/><path class="cls-2" d="M362.47,402.31a4.84,4.84,0,0,0,1.79,1l3.11,1.18a10.32,10.32,0,0,0,3.91.92c2.44-.07,4.46-1.82,6.24-3.49a6,6,0,0,0,2.17-3.23A4.82,4.82,0,0,0,378,394.8c-2.45-2.47-7.94-4.68-11.46-3.35C363.61,392.55,359.91,399.72,362.47,402.31Z" transform="translate(-60.79 2.5)"/><path class="cls-9" d="M355,414.41c.84,3.95,4.6,7.43,8.59,6.85,2.93-.42,5.19-2.74,7.93-3.87,4.64-1.92,9.9-.21,14.92-.33a5,5,0,0,0,2-.35,3.89,3.89,0,0,0,1.84-4.23,10.3,10.3,0,0,0-2.31-4.34q-2.11-2.7-4.46-5.2c-1.22-1.3-3-2.65-4.61-1.88a6.15,6.15,0,0,0-1.74,1.69,7.77,7.77,0,0,1-7,2.48c-3.49-.58-7.21-4.17-10.76-2.09S354.24,410.71,355,414.41Z" transform="translate(-60.79 2.5)"/><g class="cls-10"><path class="cls-8" d="M368.81,388.34l-1.1-23.69s8.48-17.33,8.09-18,6.68-6.06,6.68-6.06l13-1,8.29,1.85,9.82,12.28,7.21,15.07L424.21,386l-4.71,21.73-6.39,11.59-8.61,4.11L390.36,422l-5.08-3.31,3.67-3.79v-5.42l-4-6.79-5.56-2.47-1.51-7.57Z" transform="translate(-60.79 2.5)"/></g><g class="cls-10"><polygon class="cls-8" points="226.66 366.6 237.24 361.46 250.18 361.46 265.7 366.6 279.96 384.01 285.01 395.42 287.35 407.55 286.4 422.15 279.23 440.12 268 452.2 253.91 456.94 235.27 454.47 220.17 446.08 208.28 425.94 205.61 398.57 213.7 378.9 226.66 366.6"/></g><g class="cls-11"><path class="cls-8" d="M409,439.75c2.36,4.34,2.22,12.12,2.69,17.5.09,1.06-.14,3.22.56,4,1.48,1.65,1-.36,2.56-.69.63-.14,1.51.46,1.75.39.58-.16,1.31-1.06,1.76-1.16,1.15-.24,3,.52,4.19,0,.76-.35,1-1.35,1.69-1.59.86-.31,1.44.2,2.31.08,1.47-.21,4-2,4.8-.05,1.43.12,1.21-1.24,2.15-1.49.72-.19,1.17.59,1.7.51.9-.12,3.54-.38,4.45-1,2.39-1.52,1-8.77.9-11.83A110.37,110.37,0,0,0,439,431.52c-2.13,0-4.39,1.84-6.54,2.33-5.92,1.36-12,1.57-17.91,3.15" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M536.5,417c-1.36,2.71.54,8.93,1.31,12,.62,2.48,1.22,5,1.73,7.46,1.31-.76,1.41-1.43,3-1.49a14.4,14.4,0,0,0,1.74.77c1.14.13,1.75-.4,2.77-.56,1.84-.29,4.55-.88,6.77-.28-2.06-4.24-3-8.94-3.79-13.6-.18-1,.13-3.81-.67-4.58C547.82,415.29,542.06,417.06,536.5,417Z" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M547.25,294.25c0,9.83-1.48,19.55-1.25,29.38,0,1-.43,3.13,0,4,1.14,2.17,1,.14,2.53.12s2.27,1.32,4.2,1.26c1.21,0,2.66-.62,4-.76,3.52-.36,8.43.88,11.46,2.23.67-11.62-.15-23.39-.24-34.95-.89,0-1.82,0-2.72,0" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M374.75,251c-.19,4,.75,8,.75,12,0,3.31-.18,6.68,0,10,.21,3.74.35,7.47.54,11.21,1.38.2,3.73-1.36,4.73-1,1.66.62.39,3.52,2.47,3.79,1.05.14,1.18-1.19,2-1.3s1.31.73,2,.73,1.89-.48,2.52-.4,1.11.91,1.41.91c4.59,0,3.49-6.39,3.58-10.1.13-5.21,1.23-10.28,1.25-15.49,0-1.39.84-6.83-.05-7.82-.59-.65-1.81-.24-2.59-.25-4.44,0-8.91.19-13.36.19" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M106.25,316.25c-1.22.56-1,9.29-1,11.36,0,3.62.17,7.29,0,10.9-.18,4,.39,8.06.28,12,1.35-.75,2.9-3.06,4.67-2.25.54.25.24,1.64,1,1.93.91.36,1.25-.45,2.07-.48,1.63-.05,2.85.13,4.37-.9,2.49-1.67,1.66-4,1.38-7a76.43,76.43,0,0,1,.5-16.47c.16-1.27,1.52-4.07.75-5.3-1.56-2.48-7.92.65-10.25-1.75" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M164.25,177.75c-1.19,3.13-.24,7.9-.49,11.31a68.35,68.35,0,0,0,.46,11.07c.29,3.43-.16,7.73,1.25,10.84,1-.46,1.46-1.42,2.82-1.47.78,0,2,.77,2.82,1,2.6.78,4.87,1.11,5.37-1.72,1.86-10.4-1.63-22.08,1-32.28" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M314.75,177.5c0,7.1,1,13.7,1.73,20.63.29,2.92-.35,7.68,1,10.32,1.16,2.23.77.49,2.85-.06,2.62-.7,1.29.93,3.27,1.47.61.17,2.79-.54,3.55-.66a40.06,40.06,0,0,0,4.08-.44c.39-.1,2-.76,2.13-.74.87.11,1.12.85,1.65,1,1.47.41,3.44.31,4.72,1.27,2.09-1.86,1.25-6.75,1.25-9.29a111.45,111.45,0,0,1,.28-11.35c.43-4.23,2.08-8.41,2-12.67,0,.13-.45.23-.75.54" transform="translate(-60.79 2.5)"/></g><path class="cls-8" d="M638.75,149.5c0,7.67-.1,15.3-.27,22.94.64-1.54,2.45-3.17,4.22-2.9.54,3.11,1,3.66,3.49,1.74,1.22,3.69,3.36-.27,4.8-1s3.29.33,4.75,0c2-.47,2.21-2.73,2.48-4.73.72-5.42,1.62-10.88,2.52-16.27" transform="translate(-60.79 2.5)"/><g class="cls-11"><path class="cls-8" d="M565.25,4.5c-1.2,3.83-.25,9.22-.25,13.24s-.2,8.22.13,12.26c.34,4.2,1,8.33,1.41,12.49.65-.46,1.79-2.75,2.71-2.77.62,0,1.28,1.34,2,1.55-.51-.15,2.6-.36,2.12-.27.58-.11,1.29.45,2.08-.47,0,.81.59,1.27.81,1.76a1.44,1.44,0,0,1,1.94-.08c1.62-2.72,1.09-7.6,1.24-10.71s.35-6.07.57-9.07c.26-3.51-1.82-10.46-.26-13.18" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M344,32c-.48,1,.06,2.92,0,4.3-.19,2.38-1.19,4.66-1.53,7-.46,3.24-.18,6.66-.18,9.93,0,4-.57,8.72.5,12.48,1.9-1.32,4.18-5.76,6.51-6,.23.57.47,2.78,1.23,3,1.51.34,1.67-2.51,2.77-2.78,1.7-.43,1.94,2.07,3.94.33,1,2.63,1.73,0,3-.48s2.08.81,3.71-.52c.4,1.15,1.06,2.27,2.23,2.45,1.38-2.07,1.35-4.43,1.62-6.86.37-3.41,1.16-6.53,1.19-10,0-4.25-.05-8.71,1.25-12.62" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M247.5,41.25c-.35,3.5,1.76,7.33,2.25,10.81.25,1.81.14,4,1.25,5.48,1.82-3,4.84,1.18,5.79-1,6.84,1.07,2.63-13.17,5-16.54" transform="translate(-60.79 2.5)"/></g><g class="cls-11"><path class="cls-8" d="M709.67,295.33c2.33,3.49,2,11.62,2,16a48.19,48.19,0,0,1-1.63,14c1.82-1.77,2.28-.66,4.27-.64,1.46,0,2.63.09,4.2,0,4.21-.25,4.85.8,4.83-4.4,0-9,1.83-19.42,1.67-27.6" transform="translate(-60.79 2.5)"/></g><path class="cls-7" d="M372.5,517.5c-1,0-4.6-.61-5.25-.27-1.44.77-.83,5.27-1.06,7.08a86.53,86.53,0,0,0-.65,15.65c3.48.21,7.31-1.35,10.34-2.82,2.46-1.19,7-2.37,8.37-5,1.23-2.26-.15-5.42-1.3-7.43C380.22,520,375.95,520.66,372.5,517.5Z" transform="translate(-60.79 2.5)"/><path class="cls-8" d="M364,513.75c-1.64,0-3.47.25-5-.4-1-.43-1.89-2-2.87-2.21-2.63-.57-3.64,4.44-3.93,6.55-.65,4.7,0,9.78-.21,14.56-.18,3.54-.83,7.5-.49,11,.27,2.77,5.17,7.86,7,3.79,2.07,0,2.24,1.42,4.13-.47,2.36-2.36,2.43-8.28,2.58-11.46A89.06,89.06,0,0,0,364,513.75Z" transform="translate(-60.79 2.5)"/><path class="cls-8" d="M346.75,488.75c-4.43-.36-9,1.44-13.25,2.5s-8.35,2.19-12.6,2.12a119.23,119.23,0,0,0-14.92.71c-9.72,1-19.31,3-29,4.43-8,1.18-16.07.42-24.15.8a160.73,160.73,0,0,1-21.67-.3c-3.36-.3-6.5-1.24-9.81-1.71s-7.16.62-10.52,0c-2.57-.5-10.5-4.42-12.24-.89-1.1,2.24,1.65,9,3.37,10.62,1.91,1.8,3.77,2.19,5.08,4.74s1.34,5.38,2.05,8a61.06,61.06,0,0,1,2,12c.21,3.07-.48,6-.26,9,.41,5.51-1.6,10.3-2.13,15.74-.27,2.81-1.92,4.91-2.43,7.58-.45,2.35-1.55,4.24.74,5.47,1.78,1,4.4.33,6.33.6,4.14.59,8.24,1.38,12.37,2.18,10.84,2.11,23,2.42,34,1.95a173.24,173.24,0,0,1,25.22.5c7.15.72,14.39,1.51,21.56,1.87s13.5.73,20.7-.13c4.43-.53,8.73-1,13.2-1.3,3.77-.21,7.17-.5,10.6-2,2.85-1.28,10.28-3.3,11-6.25.81-3.33-1.57-7.8-2-11.1-.3-2.5-.36-4.25-1.34-6.51-5.43.15-6.21-5.74-6.47-10.28-.19-3.35,1.7-6.78,2.08-10.14a70.7,70.7,0,0,0,.18-8.57c-.06-4.81-1.46-9.9-2.56-14.55-.51-2.15-4.41-14.24-4.69-14.24" transform="translate(-60.79 2.5)"/><path class="cls-8" d="M367.67,422.33c-.24-.33.24-.54-.26-.66-.48,7.73,6.38,11.62,12.85,8.57,5.41-2.54,7.2-11,.74-12.92A11.57,11.57,0,0,0,367.67,422.33Z" transform="translate(-60.79 2.5)"/><path class="cls-12" d="M231,391.5c-3,2.57-14.36,15.14-8,18.65C227.9,412.85,231.23,401.12,231,391.5Z" transform="translate(-60.79 2.5)"/><path class="cls-12" d="M230.5,419c-3.25,2.7-10.29,24.24-2.73,21.27C233.1,438.17,229.89,425.67,230.5,419Z" transform="translate(-60.79 2.5)"/></g><g id="shadows"><g class="cls-3"><polygon class="cls-4" points="161.21 48.46 229.21 34.5 229.19 179.59 354.38 179.59 198.21 202.51 165.27 179 161.71 172.5 161.21 48.46"/></g><g class="cls-3"><path class="cls-4" d="M412.5,180c-9,23.6-18.5,48.61-25.84,72.42a252.61,252.61,0,0,0,28.76,0c.84-14.23.89-28.77,1.08-43C416.62,200.39,413.53,192.41,412.5,180Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M290,251c-10.86,19.34-26.07,40.4-36,61.4,11.67,1.24,25-.47,36.87-1C291,291.92,291.49,272.44,290,251Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><polygon class="cls-4" points="138.57 177.49 78.21 179.59 78.21 315.24 138.57 316.5 138.57 177.49"/></g><g class="cls-3"><polygon class="cls-4" points="19.21 316.5 83.21 324.62 83.21 489.21 16.52 476.5 19.21 316.5"/></g><g class="cls-3"><polygon class="cls-4" points="354.64 254.92 229.21 253.5 229.19 316.5 284.48 316.5 352.71 324.5 352.71 354 354.64 387.5 375.37 390.84 373.21 297.5 354.38 296.75 354.64 254.92"/></g><g class="cls-3"><polygon class="cls-4" points="373.21 297.5 373.21 390.49 499.03 390.84 497.21 418.17 519.23 416.91 535.94 484.5 619.21 484.5 621.21 297.5 535.86 298.09 537.21 150.5 354.38 150.5 354.38 296.75 373.21 297.5"/></g><g class="cls-3"><path class="cls-4" d="M408.5,254.5c-1.72,11.63-.54,23.82-1.84,35.55-.81,7.35-1.51,14.57-1.7,22.27a66,66,0,0,1,17.46-1.74c.89,16.3-1.28,32.82-1.95,49.07-.4,9.85.58,19.49,1.1,29.27,3.85-.45,7.23-1.33,11.34-1.5,6-19.23-.34-41,.59-60.82.14-3-.42-8.29,1.69-10.16,2.33-2.07,11.37-2.31,14.31-2.47,22.9-1.22,45.35-4.54,68-7.48,15-1.94,29.77-6.35,44.85-7,5.65-.24,10.71-.52,16.1-2.13,4.42-1.32,12.76-1.92,15.73-4.76-19.4-3.52-39.12-1.68-58.76-2.1-21.15-.45-42.22,0-63.38,0-13.56,0-27.86,2.62-41.3.54-2.23-.35-4.87-.59-6.85-1.92-3.59-2.41-3.44-5.78-4.67-10.64-1.16-4.63-1.79-24.93-5.74-26.48" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><polygon class="cls-4" points="475.7 2.59 339.21 7.5 339.21 34.5 366.21 34.5 366.21 149.74 475.7 151.07 475.7 2.59"/></g><g class="cls-3"><path class="cls-4" d="M341.85,454.31,502,417.85l38.69,179L375.87,633.72l-10.22-53.87-3-15.57c-1.05-5.55-3.3-11.65-3.17-17.26,3.09,1.72,5.12-1.35,5.72-4.28.92-4.53.23-4.23,5.51-4.25,4.9,0,8.53-2.82,12.31-5.76,4.51-3.52.94-6.64-2-10-4.31-4.86-8.66-5.73-15-6.07,0-9.28-10.17-1.72-12.72-8.82-1.68-4.67-2.19-10.14-3.22-15L343,459.5C342.9,459.23,341.84,454.32,341.85,454.31Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M261.67,345.33c.71-3-1.64-12.36,3.83-12.33,4.53,0,2.93,9.79,2.79,12.95-2.3.13-4.85-.24-7,.72" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M185.67,384.33c-6.22,1.13-9.76-9-10.41-13.68-.87-6.31.63-9.24,5.5-13,.47.32.22.28.4.2.73,3.17-1.09,6.15.92,9.13,1.49,2.22,4.23,2.45,6.3,3.52-1.15-.91-2.45-1.66-2.5-3.15,2,.39,4.4,4.37,6.46,3.11,1.5-.91,1.11-5.52.46-6.75,4.1.69,4.17,4.81,2.71,7.25-2.34,3.9-10.33,10.17-9.43,14.94C186.3,385.68,186.39,385.36,185.67,384.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M246.31,350.72c-1.27,1.27-3.4,2.11-5.06,3.18-3.34,2.15-6.16,5-9.25,7.45a83.09,83.09,0,0,0-12.87,12.81c-6.32,7.81-10.75,19.13-12.07,29.1-1,7.23.18,15.24.94,22.44.89,8.47,1.71,17.31,5.26,25.15,6.2,13.7,14.95,28.54,27.78,37,4.94,3.24,10,7.2,15.71,9,4.31,1.39,8.84,1.24,13.23,2.23-3.06,3.07-9.28,2.33-12.72,5.42-2.88,2.59-2.79,5.92.95,7.19,1.69.58,4.05.24,5.86.63,2.82.61,5.36,1.53,8.3,1.71,3.71.23,7.52,0,11.24,0-4.16,0-8.39-.24-12.26,1.54-3.43,1.58-7,2.52-10.31,4s-5.71,4.56-8.28,6.88c-3.22,2.91-6.67,8-2.12,11.25,3,2.13,10.59,2.31,12.25,6.16,1.73,4-4.14,4.18-6.95,4.75-3.63.74-9,1.22-6.26,5.77,2.29,3.86,5.3,3.53,5.33,8.58,0,3.45-1.43,6.07,1.66,8.07s8,1.95,11.52,2.83A65.85,65.85,0,0,0,285.33,576c3.28,0,9-.88,11.31,1.67-5.49,3.45-15.75,3-22.13,4.33-3.3.67-9.6,1.64-11.55,4.74-1.42,2.26-.69,6.78-.06,9.21,1.12,4.33,5,7,8.11,9.71,7.07,6.19,11.31,14.54,20.31,18.52,7.76,3.43,18,3.45,26.41,3.9,5.7.31,12,.81,17.6-.09,1.3-.21,4.62-.53,5.43-1.89,1.26-2.12-1.19-2.72-1.72-4.68,3.66-2.07,10.79,3,14,4.44,3.72,1.65,7.76,2.41,11.4,4.31,2.53,1.33,5.48,3.6,8.5,3.16a27.55,27.55,0,0,0,.48-13.23c-.43,3.89,3.95,16.67,8.8,14.5.53,2.9.1,5.59-2.72,7-7.7,4-22.12-6.42-28.33-10.84-5.24-3.74-6.78-.89-12.26,1.34s-11.38,3.62-17.24,5.13c-13.27,3.42-27.45,4.4-41.22,3.74-6.22-.3-11.5-2.13-17.13-4.47-2.59-1.07-5.4-1.43-8-2.46-1.61-.64-3.45-2.28-5.33-2.07-2.44.27-4.62,4.29-7,6-4.84,3.47-16.18,13.83-22.49,9s-.22-12.28,3-17.15c2.25-3.4,4.66-6.16,5.47-10.1-7-4.26-11.11-13.77-13.31-21.1-2.79-9.27-6.33-20.47-2.68-29.91-2-.35-6,1.29-7.57-.06s-.53-5.59,0-7.34c.93-3.08,2.16-6.15,3.31-9.15.73-1.92,2.61-5.11,2.37-7.18-.1-.91-1.35-1.87-1.35-2.4,0-2,.85-1.63,1.28-2.93,1.06-3.16.25-6.76-.33-10.16-.71-4.15-2.2-8.09-3.37-12.11-.56-1.91-.78-6.27-2.05-7.67-.93-1-2.91-.38-3.93-1.12-1.66-1.21-1.44-2.7-1.74-4.63-.69-4.47.35-8.63-1.27-12.86-1.95-5.08-5.41-9.49-8.65-13.8-2.05-2.73-4.34-5.08-5.69-8.32-1.9-4.58-2.83-9.51-4.9-14-3.89-8.46-5.68-16.8-6.42-26.21a54,54,0,0,1,8-31.47c3-4.62,4.06-9.85,7.65-14.39,6.72-8.49,11.63-17.25,21.5-22.32C221.14,354.82,233.33,349.9,246.31,350.72Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M273.67,368.33c-1.13-4-10.12,5-11.35,6.5-3.26,3.95-6,6.85-7.91,11.76a50.11,50.11,0,0,0-1.75,31.1c2.35,8.41,7.94,19.78,14.9,25.18,8.52,6.6,20.57,8.32,31.14,7.47,7.79-.62,14.35-5.58,19.9-10.8a50.14,50.14,0,0,0,11.1-16.46c-2,6.48-13.41,14.93-19.84,16.73-7.47,2.09-18.4,4.18-25.55.2-12.48-7-24.38-25.35-15.32-39.27,1.93-3,4.76-6,8-7.44,2.18-1,7.74-1.36,8-4.23-4.36-1.48-9.49.89-13.33-2.77-1.72-1.63-3-5.48-3.35-7.8C267.7,374.2,270,374,273.67,368.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M359.67,386.67c-4.3.06-10.59,3.22-11.17,7.85-.33,2.66.75,9.09,2.09,11.12,2-3.53,2.56-7.41,5.28-10.79,3.21-4,5.34-3.32,10.09-3.56C364.29,386.61,362.59,383.8,359.67,386.67Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M360.33,402.67c-2.91.29-6.34,5.53-7,8.35a16,16,0,0,0,1,8.82c1.31,2.8,4.78,4.71,7,7,2.44,2.46,3.76,5.82,6.19,8.2,4.57,4.46,10.14-.65,11.77-5.29-4.84,1.22-7,2.58-8.76-3.54-1.17-4.17.93-5.16,3.54-7.84,1.11-1.15,3.21-1,1.6-2.67-1.4-1.43-5.15.3-6.75.42-2.58.19-4.06-.07-5.6-2.48C362,411.52,359.72,407.17,360.33,402.67Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M359.67,358.33c-.76.31-6.6,4-6.82,4.65-.49,1.41,2.81,4.23,3.75,5.6,2.32,3.38,6.22,6.22,7.66,10a8,8,0,0,0-.28-1.18,30.47,30.47,0,0,0,2.79,7.56c.88,1.57,3.17,6.14,4.59,7.15,2.35,1.66,3.71-1.5,6.4,1.84,1.45,1.79,3,5.84,2.28,7.93,3.41,1.11,4.83,2.88,7.61,4.73,2.32,1.54,1.94,1.59,4.19-.58,1.35-1.3,3.83-4,4.12-5.72-3.86,1.79-7.87,1.35-10.92-1.69s-6.29-6-9.56-9c-2.79-2.59-5-5-4.83-8.95.13-2.92,2.57-6.66,2-9.33C366.92,372.31,363.62,363.75,359.67,358.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M341,454.67c-4.14,3.75-3.56,16.7-4.66,22.34-.85,4.35-3.51,10.22-3,14.61,4-.2,7.16.24,6.62,4.9-.45,3.82-5.52,4.61-4.63,8.09,2.95,1.11,6.66,1.29,7,5.23.39,5-5.31,1.2-8.28,1.55-1,2.37,5.49,3.72,6.64,4.42s1.78,1.62,3.23,2.23,3.23.49,4.56,1.5c2.28,1.73,1.85,4.47,4.18,6.17,2.35-2.21-.25-7,3-8.41,1.49,1.3.19,3.11,2.35,3.71,3.27.9,2.13-2.54,3.66-3.83,3.18-2.68,2.27,5.63,2.39,7.79,2.19-1.18,3.11-.88,5.36.12,1.51.67,6.09,2.23,6.62,3.59,1.42,3.68-6.64,8.48-8.25,11,2.05,1.28,10.43-3,12.74-4.34a10.33,10.33,0,0,0,4.82-6.82c1.65-7.43-5.83-10.9-12.25-11.55-3.49-.35-3.25.33-5.57-2-3.24-3.23-4.07-2.28-8.2-2.66-1.23-.11-6-.63-6.92-1.32-1.46-1.12-1.27-4.38-1.59-5.86-.75-3.48-2.39-6.71-3.1-10.21-1.46-7.27-1-14.8-2.22-22.12-.81-5.08-2.44-10.34-2.17-15.51" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M350.67,541c-3-.23-6.11.62-9,1.25-3.12.68-3.7.34-3.57,3.08.17,3.43,3.3,4.68,4.94,7.07,1.28,1.87,2.56,5.74,3.23,7.93,1.2,3.91,1.76,8.4-1.57,11.42-3.64,3.3-9.51,1.66-12.73,4.58,1.34,1.83,7.16,1.55,9.67,2.25,3.09.86,6.73,1.93,8.65,4.76,3,4.38,3.42,10.73,6.07,15.46,1.72,3.06,2.83,6,5.24,8.52,3.08,3.27,6.61,6.19,9.69,9.4,1.18-15.4-6.86-29-8.6-43.82-.71-6.11-1.3-12.15-1.6-18.31-.08-1.64.39-4.13-.59-5.22-1.18-1.31-5.14-1.94-6.81-3.7" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M384.67,530c.3,8.5-6.07,13.8-11.35,19.33-3.39,3.55-4.81,8.52-5,13.33-.25,7.06.67,13.93.67,20.93,0,5.53-.81,11.5-.34,16.93,1.65-11.38-.9-24.65-4.25-35.53-1.69-5.47-3.45-11.3-3.69-17,6.54,1.48,5.79-3.28,6-8,2.64-.59,5.35-.85,8-1.37,3.17-.61,6.32-2.67,9.27-3" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M435.35,507.66c-4.24,1.67-9.4-.44-13.87-.81-3.78-.31-7.49-1-11.29-1.06-1.72,0-6.63-1.22-8.09-.41-3.43,1.92,3.15,5.19,5.13,6.06a124.84,124.84,0,0,0,16,6.13c10.08,2.86,22.82,1.09,32.08-3.58,7.21-3.64,10.57-8.8,15.72-14.36-5.8,2.45-10.79,5.86-17.25,6.83A116.77,116.77,0,0,1,435.35,507.66Z" transform="translate(-60.79 2.5)"/></g><g class="cls-3"><path class="cls-4" d="M435,527c-2.45,0-4.91,0-7.33,0-4.11,0-3.83,1.13-.38,2.87,5.4,2.72,21.11,6.84,22.34-3.47-3.72-.21-7.54-.06-11.29-.06" transform="translate(-60.79 2.5)"/></g><g class="cls-13"><path class="cls-8" d="M403.49,349.46c-1.42-2-4.26-1.57-6.78-1.52a3.17,3.17,0,0,0-.93,1.51c-2.56,3,4.57,9.28,6.21,12.51,2.07,4.1.56,13.79,3.3,16.77,6.24,6.81,5.75-10.13,5.15-13.27C409.27,359.45,406.45,355.81,403.49,349.46Z" transform="translate(-60.79 2.5)"/></g><g class="cls-13"><path class="cls-8" d="M322,374c-1.2-3.64-13.68-1.56-7.75,5.24,2.13,2.44,6.18,3.72,8.74,5.76a26,26,0,0,1,7.41,8.5c2,4,2.86,14.65,6.09,17,4.07,3,5.05-1,5.51-4.24.83-5.84-1.21-10.45-3.71-15.46C334.78,383.79,330.24,379.88,322,374Z" transform="translate(-60.79 2.5)"/></g></g><g id="DETAILS"><path class="cls-2" d="M391.56,572.73a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,0,1,.5,1.94l-33.32,8.69A1,1,0,0,1,391.56,572.73Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M398.8,603.88a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.1,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M398.8,603.88a1,1,0,0,1-.24-2c11.3-2.76,24.26-5.85,34.69-7.87a1,1,0,1,1,.38,2c-10.39,2-23.32,5.09-34.6,7.85A1,1,0,0,1,398.8,603.88Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M433.44,596a1,1,0,0,1-.92-.61c-2.65-6.23-4.23-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,0,1,1.92-.57c1.08,3.65,2,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M430.55,564.05a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,0,1,.5,1.94L430.8,564A1,1,0,0,1,430.55,564.05Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M437.79,595.21a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.11,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M437.79,595.21a1,1,0,0,1-.24-2c11.3-2.76,24.26-5.85,34.69-7.87a1,1,0,1,1,.38,2c-10.39,2-23.32,5.09-34.6,7.85A1,1,0,0,1,437.79,595.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M472.43,587.35a1,1,0,0,1-.92-.61c-2.65-6.23-4.24-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,0,1,1.92-.57c1.08,3.65,1.95,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M469.54,555.13a1,1,0,0,1-.25-2l33.32-8.69a1,1,0,1,1,.5,1.94l-33.32,8.69A1,1,0,0,1,469.54,555.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M476.78,586.28a1,1,0,0,1-.93-.63c-4.16-10.56-5.82-20.87-7.3-31.38a1,1,0,1,1,2-.28c1.46,10.39,3.11,20.57,7.18,30.93a1,1,0,0,1-.93,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M476.78,586.28a1,1,0,0,1-.24-2c11.31-2.76,24.27-5.86,34.69-7.87a1,1,0,0,1,.38,2c-10.38,2-23.31,5.09-34.6,7.85A1,1,0,0,1,476.78,586.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M511.42,578.43a1,1,0,0,1-.92-.61c-2.65-6.23-4.23-13.44-5.76-20.4-.92-4.17-1.78-8.11-2.84-11.69a1,1,0,1,1,1.92-.57c1.08,3.65,1.95,7.62,2.87,11.83,1.51,6.88,3.07,14,5.65,20a1,1,0,0,1-.92,1.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M411,594.15a1,1,0,0,1-1-.75,147.58,147.58,0,0,1-3-14.59,1,1,0,0,1,2-.3,146,146,0,0,0,2.94,14.39,1,1,0,0,1-1,1.25Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M404.8,579.33a.31.31,0,0,0,0,.19c0,.18.32.13.49,0a15.4,15.4,0,0,1,5.9-1.86,13.93,13.93,0,0,1-2.23-2.31c-.38-.46-1.53-2.3-2.17-2.28-.82,0-.82,2.22-.95,2.8A23.77,23.77,0,0,1,404.8,579.33Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M417.37,592.77a1,1,0,0,1-1-.75,147.58,147.58,0,0,1-3-14.59,1,1,0,0,1,2-.3,146,146,0,0,0,2.94,14.39,1,1,0,0,1-1,1.25Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M411.2,578a.31.31,0,0,0,0,.19c0,.18.32.13.49,0a15.4,15.4,0,0,1,5.9-1.86,13.93,13.93,0,0,1-2.23-2.31c-.38-.46-1.53-2.3-2.17-2.28-.82,0-.82,2.22-.95,2.8A23.77,23.77,0,0,1,411.2,578Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M408.18,597.66a1,1,0,0,1-.14-2,113.17,113.17,0,0,0,12.62-2.59,1,1,0,0,1,.51,1.93,115.38,115.38,0,0,1-12.84,2.63Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M455.14,587.53l-.29,0a3,3,0,0,1-2.33-2.1,16.6,16.6,0,0,1-.68-2l-2.24-7.76a1,1,0,1,1,1.92-.55l2.24,7.76a14.83,14.83,0,0,0,.59,1.77c.22.52.52.88.75.91a.8.8,0,0,0,.62-.44,4.3,4.3,0,0,0,.38-1.52,1,1,0,0,1,2,.26,6,6,0,0,1-.64,2.26A2.74,2.74,0,0,1,455.14,587.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M443.83,577.65a1.81,1.81,0,0,1-1.5-.64c-.86-1.07,0-2.7.28-3.23a9.06,9.06,0,0,1,5.24-4.79,13.43,13.43,0,0,1,5.21-.59,7.57,7.57,0,0,1,4.56,1.92c.75.55,2.14,1.58,2.24,3.18a1,1,0,0,1-.77,1c-3.13.75-6.31,1.44-9.45,2.06-.59.12-1.19.21-1.79.31a28,28,0,0,0-2.87.56A4.39,4.39,0,0,1,443.83,577.65Zm8.13-7.28a10.64,10.64,0,0,0-3.46.52,7.11,7.11,0,0,0-4.12,3.83,4.21,4.21,0,0,0-.38.92,3.18,3.18,0,0,0,.45-.09,29.36,29.36,0,0,1,3.08-.61c.58-.09,1.15-.18,1.72-.3,2.74-.54,5.51-1.14,8.25-1.78a6.36,6.36,0,0,0-1.07-.93,5.68,5.68,0,0,0-3.49-1.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M449.68,569.86a1,1,0,0,1-.95-.68l-.65-1.95a1,1,0,1,1,1.89-.64l.66,2a1,1,0,0,1-.95,1.32Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M487.63,569.34a7.54,7.54,0,0,1-2.89-.62,4.08,4.08,0,0,1-1.66-1.15,4.62,4.62,0,0,1-.81-2l-1.89-9.07a1,1,0,0,1,2-.41l1.89,9.07a3,3,0,0,0,.41,1.2,2.27,2.27,0,0,0,.87.55,5.12,5.12,0,0,0,2.67.42,2.93,2.93,0,0,0,2-1.2c.79-1.21.35-3-.12-4.65L488.21,555a1,1,0,0,1,1.92-.56l1.89,6.42c.6,2,1.14,4.39-.12,6.31a4.88,4.88,0,0,1-3.42,2.08A5.85,5.85,0,0,1,487.63,569.34Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M481.41,557a1,1,0,0,1-.38-1.93,10,10,0,0,1,2.29-.55l5.71-.89a1,1,0,1,1,.31,2l-5.71.89a8.28,8.28,0,0,0-1.84.43A1,1,0,0,1,481.41,557Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.11,579a1,1,0,0,1-1-.73c-.84-3-1.53-6.16-2.07-9.27a1,1,0,0,1,2-.34c.53,3,1.21,6.1,2,9.07a1,1,0,0,1-1,1.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M486.73,580.72a1,1,0,0,1-.4-1.92,11.07,11.07,0,0,1,2.91-.69l.95-.14a13.12,13.12,0,0,0,2.83-.84,1,1,0,1,1,.78,1.84,15.09,15.09,0,0,1-3.26,1l-1,.16a9.4,9.4,0,0,0-2.39.54A1,1,0,0,1,486.73,580.72Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M539.23,438.62h-.05a1,1,0,0,1-.92-.76,100.06,100.06,0,0,1-2.75-19.47,1,1,0,1,1,2-.08,98.07,98.07,0,0,0,2.08,16.38q.29-.45.62-.87a1,1,0,0,1,1.55,0,3,3,0,0,0,1.45,1.13.67.67,0,0,0,.6-.23,1,1,0,0,1,1.91-.48.66.66,0,0,0,.78.29,2.38,2.38,0,0,0,.25-.15,2.75,2.75,0,0,1,1-.43,2.79,2.79,0,0,1,1.72.3l.35.14h.05a1,1,0,0,1,1.57-.38,4,4,0,0,0,1.15.68c-1.13-6.06-2.51-12.14-4.09-18.09a1,1,0,1,1,1.93-.51c1.72,6.47,3.2,13.1,4.39,19.69a1,1,0,0,1-.23.83.94.94,0,0,1-.79.34,6.06,6.06,0,0,1-2.82-.83,2.28,2.28,0,0,1-1.79.15c-.17-.06-.34-.13-.52-.2a2,2,0,0,0-.52-.18,1.72,1.72,0,0,0-.28.16,4.4,4.4,0,0,1-.47.27,2.6,2.6,0,0,1-2,.06l-.29-.12,0,0a2.66,2.66,0,0,1-2.24.61,3.67,3.67,0,0,1-1.69-.87,10.64,10.64,0,0,0-.95,2A1,1,0,0,1,539.23,438.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M413.45,463.26a1,1,0,0,1-.8-.4c-1.36-1.8-1.36-4.11-1.36-6.14v-.54a34.58,34.58,0,0,0-3.39-14.73,1,1,0,1,1,1.8-.87,36.62,36.62,0,0,1,3.59,15.59v.55a13.41,13.41,0,0,0,.31,3.6l.66-.92a1,1,0,0,1,1.67.06.37.37,0,0,0,.31.11.38.38,0,0,0,.31-.12l.07-.15a2.15,2.15,0,0,1,.55-.8c1.06-.91,2.17-.05,2.7.36a3.14,3.14,0,0,0,.62.41.21.21,0,0,0,.19,0,3,3,0,0,0,1-1.69,1,1,0,0,1,1.81-.24,2,2,0,0,0,3.34-.39,1,1,0,0,1,1.69-.34,3.62,3.62,0,0,0,2.06,1.31.43.43,0,0,0,.31-.13,2.09,2.09,0,0,0,.27-.51,4.56,4.56,0,0,1,.43-.81,2.72,2.72,0,0,1,2.6-1.06,3,3,0,0,1,1.39.55l.45-.45a1,1,0,0,1,1.59.25.43.43,0,0,0,.78-.35,1,1,0,0,1,1.77-.91,2.4,2.4,0,0,0,.38.45l-1.72-21.17a1,1,0,0,1,2-.16l1.86,22.86a1,1,0,0,1-1.15,1.07A4.46,4.46,0,0,1,440,457a2.36,2.36,0,0,1-.95.8,2.48,2.48,0,0,1-2.26-.15l-.54.54a1,1,0,0,1-1.64-.35.78.78,0,0,0-.64-.4.79.79,0,0,0-.72.23,3,3,0,0,0-.23.46,3.62,3.62,0,0,1-.64,1.07,2.39,2.39,0,0,1-1.79.77,4.43,4.43,0,0,1-2.59-1.09,4,4,0,0,1-2.48,1.18,4.09,4.09,0,0,1-2.49-.47,3.7,3.7,0,0,1-1.47,1.51,2.18,2.18,0,0,1-1.77.1,4.43,4.43,0,0,1-1.15-.7l-.26-.2-.09.18a2.34,2.34,0,0,1-2,1.14,2.22,2.22,0,0,1-1-.18l-1,1.45a1,1,0,0,1-.8.42Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M568,334.05a2,2,0,0,1-1.63-.84q-.62-.86-1.14-1.78a2.62,2.62,0,0,1-1.57.53,3.26,3.26,0,0,1-2.43-1.15l-.8-.81a3.77,3.77,0,0,1-4.27.95,4,4,0,0,1-1.4-1.09l-.28.46a2.83,2.83,0,0,1-4.34.92l-1.78-1.15a13.94,13.94,0,0,1-1.61,1.75,2,2,0,0,1-3.34-1.73,114.37,114.37,0,0,0,.86-19.86c0-.71-.07-1.42-.11-2.13a46.28,46.28,0,0,1,.41-11.9,2,2,0,0,1,3.92.81,42.57,42.57,0,0,0-.33,10.87c0,.72.08,1.45.11,2.17a118.36,118.36,0,0,1-.32,15.26,2,2,0,0,1,.92.31l2.7,1.75,1.05-1.76a2,2,0,0,1,1.89-1,4,4,0,0,1,3,2.11l.21.31a4.35,4.35,0,0,0,.77-1.08,2,2,0,0,1,3.2-.48l1.59,1.62a2.92,2.92,0,0,1,2.11-1.48,2,2,0,0,1,1.14.17c.08-3.24-.09-6.52-.25-9.73-.35-7-.71-14.15,1.29-21.07a2,2,0,1,1,3.84,1.11c-1.81,6.28-1.48,12.83-1.13,19.77.27,5.39.55,11-.26,16.43a2,2,0,0,1-2,1.71Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M723.53,328.85a2,2,0,0,1-1.7-.94h0a3.37,3.37,0,0,1-1.62.17,3.55,3.55,0,0,1-1.3-.46,2,2,0,0,1-1.19.4,2,2,0,0,1-1.59-.77,4.51,4.51,0,0,0-1.65-1.3,8.46,8.46,0,0,1-2.29,2.39,2,2,0,0,1-3.14-1.52,48.11,48.11,0,0,1,.34-7.82c.06-.61.12-1.22.17-1.83a90.75,90.75,0,0,0-.81-22.43,2,2,0,0,1,3.95-.64,94.8,94.8,0,0,1,.84,23.42c-.06.62-.12,1.25-.18,1.87s-.15,1.48-.21,2.21a2,2,0,0,1,.52,0,8.49,8.49,0,0,1,3.76,1.46,3.43,3.43,0,0,0,4.1-.29h0c.07-9.84.45-19.76,1.14-29.55a2,2,0,0,1,4,.28c-.78,11.06-1.17,22.29-1.15,33.37a2,2,0,0,1-2,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M637.16,177a2,2,0,0,1-2-2.4,143.33,143.33,0,0,0,2.81-24,2,2,0,0,1,4,.13,147.05,147.05,0,0,1-1.22,14.67,2.79,2.79,0,0,1,2.14,1.26l1.59,2.13a3.5,3.5,0,0,1,.5-.66,3.06,3.06,0,0,1,4.17-.17l.15-.26a2,2,0,0,1,1.79-1,2,2,0,0,1,1.73,1.1q.29.58.56,1.17l1.26-1.74a2.6,2.6,0,0,1,2.63-1.2,63.58,63.58,0,0,0,2.49-16.74,2,2,0,0,1,2-2h0a2,2,0,0,1,2,2,67.58,67.58,0,0,1-4,22,2,2,0,0,1-2,1.32,2,2,0,0,1-1.54-.82l-1.84,2.54a3.31,3.31,0,0,0-4.89.84,2,2,0,0,1-1.91-.57l-.1-.11a3.58,3.58,0,0,1-.21.34,2,2,0,0,1-1.61.85,2.09,2.09,0,0,1-1.63-.81l-3-4.05L639,175.74A2,2,0,0,1,637.16,177Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M578.34,48.08a2,2,0,0,1-1-.25,5.11,5.11,0,0,1-2.11-2.27,3,3,0,0,1-1.94-.21,3.58,3.58,0,0,1-1.52-1.43,2,2,0,0,1-3.17-.08L568,43a18.65,18.65,0,0,0-.65,2.92,2,2,0,0,1-4-.28q0-18.63,0-37.26a2,2,0,0,1,2-2h0a2,2,0,0,1,2,2q0,14.29,0,28.57h0a2,2,0,0,1,1.76.82l.71,1q.19-.25.41-.48a2,2,0,0,1,3.22.4l1,1.85a2,2,0,0,1,1.76-1.37c-.05-9.67.38-19.39,1.28-29a2,2,0,1,1,4,.38A288.91,288.91,0,0,0,580.34,46a2,2,0,0,1-2,2.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M341.35,72.24a2,2,0,0,1-2-2.07c.46-12.23,1.44-24.6,2.91-36.75a2,2,0,1,1,4,.48c-1,8.09-1.74,16.27-2.27,24.44a2,2,0,0,1,2.25-.33,11,11,0,0,1,2.36,1.58l.3-.64a2,2,0,0,1,3.7.19l.48,1.37a3.47,3.47,0,0,1,2.3-1.8,2,2,0,0,1,1.66.4l.16.15.08-.15a2,2,0,0,1,2.43-.89q.18-.64.32-1.28a2,2,0,0,1,3.93.11q0,.25.09.51a2,2,0,0,1,2-1.12l2.38-24.32a2,2,0,0,1,4,.39l-3.12,31.83a2,2,0,0,1-3.57,1,8.93,8.93,0,0,1-.56-.81,2,2,0,0,1-3-.59l-.26-.48q-.31.63-.65,1.25a9.33,9.33,0,0,0-4.17,1,2,2,0,0,1-1.71-.68l-.2-.24a3.67,3.67,0,0,1-1.7,1.06,2.83,2.83,0,0,1-2.46-.47,2.94,2.94,0,0,1-.64-.68,2,2,0,0,1-3.08-.44,6.92,6.92,0,0,0-.75-1,31,31,0,0,1-3.55,8A2,2,0,0,1,341.35,72.24Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M250.94,60a2,2,0,0,1-2-1.71L246.6,42.31a2,2,0,1,1,4-.58L252,51.65a2,2,0,0,1,1.31.75l.35.44a2,2,0,0,1,2.52.09,3.33,3.33,0,0,1,.47.5,2.46,2.46,0,0,1,.74-.33,2,2,0,0,1,1,0,2,2,0,0,1,1.21-.66c.05-4.25.07-8.52,0-12.75a2,2,0,0,1,2-2,2,2,0,0,1,2,2c0,5.9,0,11.88-.12,17.78a2,2,0,0,1-3,1.67,5.14,5.14,0,0,1-.61-.43,2,2,0,0,1-2.39-.14,2.66,2.66,0,0,1-1.36.08A3.1,3.1,0,0,1,255,58.1a2,2,0,0,1-1.1.3,2,2,0,0,1-1-.27,2,2,0,0,1-1.82,1.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.36,215.29h-.1a2,2,0,0,1-1.83-1.51c0-.09-.06-.22-.1-.37a2,2,0,0,1-2.54-.55,5.77,5.77,0,0,1-.38-.57,1.5,1.5,0,0,0-2,.7,2.42,2.42,0,0,1-2.31-1.24,3.3,3.3,0,0,1-.73.66,3.23,3.23,0,0,1-2.57.42,3.9,3.9,0,0,1-1.72-.94L326,212a7.25,7.25,0,0,0-3.9.33,2,2,0,0,1-1.52-.63q-.69-.73-1.3-1.52l-.78,1.1a2,2,0,0,1-3.63-1,286.61,286.61,0,0,1-.45-32.05,2,2,0,0,1,2.08-1.91,2,2,0,0,1,1.91,2.08c-.37,8.76-.33,17.62.13,26.4a2,2,0,0,1,2.54.87q.33.6.71,1.16a13.67,13.67,0,0,0,5.52-1.38,2,2,0,0,1,1.48,2v.13a3.09,3.09,0,0,1,3.68-1.4,2.81,2.81,0,0,1,.86.51l.5-1a2,2,0,0,1,3.78.82l0,.35a2,2,0,0,1,1,2,3.47,3.47,0,0,1,.74.11,50.87,50.87,0,0,0,.36-7.37v-.84a208.41,208.41,0,0,1,1.46-24.08,2,2,0,1,1,4,.47,204.43,204.43,0,0,0-1.43,23.61v.84c0,4.07,0,8.28-1.47,12.29A2,2,0,0,1,340.36,215.29Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.18,290.76a2.88,2.88,0,0,1-2.64-1.93,2,2,0,0,1-2.78-.7l-.18.21a2,2,0,0,1-3.18-.19q-.27-.4-.56-.78a16.48,16.48,0,0,0-.57,1.72,2,2,0,0,1-3.93-.47l-1-34.89a2,2,0,1,1,4-.12l.84,28.28a2,2,0,0,1,1.56.52q.68.62,1.29,1.31.2-.34.38-.69A2,2,0,0,1,383.1,282a2,2,0,0,1,1.77,1l.06.11a2,2,0,0,1,3.53.81l.19.87.92-1.57a2,2,0,0,1,3.72.89q0,.2,0,.39l.06,0c1.1-7.19,2-14.54,1.41-21.78,0-.57-.1-1.13-.16-1.7a28.16,28.16,0,0,1,0-7.76,2,2,0,1,1,3.94.7,24.78,24.78,0,0,0,.07,6.67c.06.59.12,1.18.16,1.76.73,8.92-.66,17.76-2,26.32a4,4,0,0,1-6.32.89,2.86,2.86,0,0,1-1.82,1.19A2.66,2.66,0,0,1,388.18,290.76Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M176,215.44a2,2,0,0,1-1.12-.34,8,8,0,0,1-1.65-1.5l-.06.07a2,2,0,0,1-3,.23q-.18-.17-.35-.36a2,2,0,0,1-2.12-.32q-.42-.37-.82-.77l0,.15a2,2,0,0,1-3.94-.14,198.32,198.32,0,0,1-1.3-35.58,2,2,0,1,1,4,.21,194.37,194.37,0,0,0,.65,29.33h.13a2,2,0,0,1,1.72,1,10,10,0,0,0,.56.9l.19-.32a2,2,0,0,1,3.55.21,2,2,0,0,1,2.92.93,2,2,0,0,1,.22-.25,104.51,104.51,0,0,0-.31-12.64c-.42-6.48-.85-13.19.58-19.75a2,2,0,1,1,3.91.85c-1.31,6-.92,12.15-.5,18.64a89.68,89.68,0,0,1,.08,15.77,2,2,0,0,1-1.27,1.64l-.2.61a2,2,0,0,1-1.9,1.38Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M105.57,354.11a2,2,0,0,1-2-2.32,82.63,82.63,0,0,0,.84-19.26c-.09-1.22-.21-2.43-.32-3.65a61.71,61.71,0,0,1-.39-10.8,2,2,0,1,1,4,.32,57.8,57.8,0,0,0,.39,10.1c.12,1.25.24,2.49.33,3.74a86.64,86.64,0,0,1,0,13.21l.17.05a2,2,0,0,1,1.25,1.26,2,2,0,0,1,3.41-.55,2,2,0,0,1,2.72-.39c-.92-8.6.7-17.35,2.13-25.16a2,2,0,0,1,3.93.72c-1.59,8.64-3.24,17.58-1.78,26.27.41,2.42-.13,4.09-1.6,4.95a2,2,0,0,1-2.71-.67,2,2,0,0,1-1.35-.21,2,2,0,0,1-2.37-.24l-.42-.4a3.82,3.82,0,0,1-2.09.58,3.71,3.71,0,0,1-1.5-.36l-.84,1.69A2,2,0,0,1,105.57,354.11Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M312.16,134.92a.81.81,0,0,1,0-1.62L340,133a.83.83,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M311.72,160.82a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.81.81,0,0,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.48,161.46h0c-8.56-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340.48,161.46a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,1.62-.07c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M344.5,135.77a.81.81,0,0,1,0-1.62l27.89-.27a.81.81,0,1,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M344.06,161.67a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.81.81,0,0,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372.82,162.31h0c-8.55-.47-19.32-.58-28.72-.64a.81.81,0,0,1-.81-.81.8.8,0,0,1,.81-.81c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372.82,162.31a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.8.8,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.88,136.43a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.44,162.33a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.81.81,0,1,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M405.21,163h0c-8.57-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.41.05,20.2.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M405.21,163a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.84.84,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M323.19,155.57a.81.81,0,0,1-.81-.8,119.45,119.45,0,0,1,.53-12,.81.81,0,1,1,1.61.15,117.78,117.78,0,0,0-.52,11.88.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M321.06,142.69a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,321.06,142.69Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M328.49,155.74a.81.81,0,0,1-.81-.8,119.74,119.74,0,0,1,.53-12,.81.81,0,1,1,1.61.15,118.08,118.08,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M326.36,142.86a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,326.36,142.86Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M359.46,159.08a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.4,13.4,0,0,1-.14-1.71L357,148.6a.81.81,0,1,1,1.62-.06l.24,6.54a12,12,0,0,0,.12,1.51c.07.45.23.79.41.86a.65.65,0,0,0,.57-.23,3.52,3.52,0,0,0,.6-1.12.81.81,0,1,1,1.5.6,4.84,4.84,0,0,1-.94,1.65A2.32,2.32,0,0,1,359.46,159.08Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M364.67,149.6h0c-2.6,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a22.82,22.82,0,0,0-2.37-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.84,10.84,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,364.67,149.6Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.56.19,6.83.22a5.18,5.18,0,0,0-.66-.94,4.6,4.6,0,0,0-2.44-1.89,9.3,9.3,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.41,3.41,0,0,0-.48.65,2.61,2.61,0,0,0,.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M358.38,144.1a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.61-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M389.22,151.27l-.45,0a5.75,5.75,0,0,1-2.82-1.17,3.27,3.27,0,0,1-1.08-1.23,3.75,3.75,0,0,1-.23-1.76l.3-7.5a.82.82,0,0,1,.84-.78.81.81,0,0,1,.78.84l-.3,7.49a2.47,2.47,0,0,0,.09,1,1.72,1.72,0,0,0,.57.6,4.14,4.14,0,0,0,2,.86,2.37,2.37,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,1,1,1.62-.07l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,389.22,151.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M392.22,140.66h-.07l-4.66-.42a6.73,6.73,0,0,0-1.53,0,.81.81,0,0,1-.23-1.6,8.12,8.12,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.35,159.23a.81.81,0,0,1-.81-.79c-.06-2.56,0-5.14.2-7.69a.81.81,0,0,1,1.62.12c-.19,2.49-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M389.16,160.06q-.43,0-.86,0l-.83-.08a7.63,7.63,0,0,0-2,0,.81.81,0,0,1-.26-1.6,8.9,8.9,0,0,1,2.41,0l.78.07a10.65,10.65,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.24,12.24,0,0,1,389.16,160.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M436.16,110.93a.81.81,0,0,1,0-1.62L464,109a.85.85,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M435.72,136.83a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M464.49,137.47h0c-8.55-.47-19.32-.58-28.73-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M464.48,137.47a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75A.81.81,0,0,1,464,109a.84.84,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M468.5,111.78a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M468.06,137.69a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M496.82,138.33h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M496.82,138.33a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M500.89,112.44a.81.81,0,0,1,0-1.62l27.89-.27a.84.84,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M500.45,138.34a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M529.21,139h0c-8.55-.47-19.32-.59-28.73-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.22.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M529.21,139a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M447.2,131.58a.81.81,0,0,1-.81-.8,119.88,119.88,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.36,118.36,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M445.07,118.7a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,445.07,118.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M452.5,131.76a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M450.37,118.88a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,450.37,118.88Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M483.46,135.1a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.51,13.51,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78l.24,6.54a12.11,12.11,0,0,0,.12,1.51c.08.45.24.79.41.86a.64.64,0,0,0,.57-.23,3.54,3.54,0,0,0,.6-1.12.81.81,0,1,1,1.5.6,4.78,4.78,0,0,1-.94,1.65A2.32,2.32,0,0,1,483.46,135.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M488.68,125.61h0c-2.61,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a21.9,21.9,0,0,0-2.37-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.85,10.85,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,488.68,125.61Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.55.19,6.83.22a5.15,5.15,0,0,0-.66-.94,4.59,4.59,0,0,0-2.44-1.89,9.34,9.34,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.38,3.38,0,0,0-.48.65l.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M482.39,120.11a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.62-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M513.23,127.28l-.45,0a5.74,5.74,0,0,1-2.82-1.17,3.27,3.27,0,0,1-1.08-1.23,3.76,3.76,0,0,1-.23-1.76l.3-7.5a.85.85,0,0,1,.84-.78.81.81,0,0,1,.78.84l-.3,7.49a2.48,2.48,0,0,0,.09,1,1.84,1.84,0,0,0,.57.6,4.14,4.14,0,0,0,2,.86,2.39,2.39,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,.78-.84.8.8,0,0,1,.84.78l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,513.23,127.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M516.23,116.68h-.07l-4.66-.42a6.78,6.78,0,0,0-1.53,0,.81.81,0,1,1-.23-1.6,8.16,8.16,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M512.36,135.24a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.14.2-7.69a.82.82,0,0,1,.87-.75.81.81,0,0,1,.75.87c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M513.16,136.07q-.43,0-.86,0l-.83-.08a7.66,7.66,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.62,10.62,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.27,12.27,0,0,1,513.16,136.07Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.5,258.07a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M490.06,284a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M518.83,284.61h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M518.83,284.61a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M522.84,258.92a.81.81,0,0,1,0-1.62l27.89-.27a.79.79,0,0,1,.82.8.81.81,0,0,1-.8.82l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M522.4,284.82a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.55.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M551.17,285.46h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M551.17,285.46a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.74a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M555.23,259.58a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M554.79,285.48a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M583.56,286.12h0c-8.55-.47-19.32-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M583.55,286.12a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M501.54,278.72a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M499.41,265.84a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,499.41,265.84Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M506.84,278.89a.81.81,0,0,1-.81-.8,119.9,119.9,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.39,118.39,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M504.71,266a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,504.71,266Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M537.81,282.23a1.86,1.86,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.51,13.51,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78l.24,6.54a12.11,12.11,0,0,0,.12,1.51c.08.45.24.79.41.86a.65.65,0,0,0,.57-.23,3.49,3.49,0,0,0,.6-1.12.81.81,0,1,1,1.51.6,4.85,4.85,0,0,1-.94,1.65A2.32,2.32,0,0,1,537.81,282.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M543,272.75h0c-2.6,0-5.24-.11-7.83-.24-.48,0-1-.07-1.46-.11a23.26,23.26,0,0,0-2.38-.12c-1,0-1.7-.28-2-.89-.46-1,.53-2.12.86-2.48a7.33,7.33,0,0,1,5.06-2.73,10.88,10.88,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.76,3.76,0,0,1,1.13,2.94A.81.81,0,0,1,543,272.75Zm-11.45-2.09c.77,0,1.54.07,2.28.13.47,0,.94.08,1.4.1,2.26.11,4.55.19,6.83.22a5.25,5.25,0,0,0-.66-.94,4.6,4.6,0,0,0-2.44-1.89,9.31,9.31,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.47,3.47,0,0,0-.48.65,2.52,2.52,0,0,0,.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M536.73,267.24a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,1.62-.13l.13,1.66a.81.81,0,0,1-.74.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567.57,274.42l-.45,0a5.76,5.76,0,0,1-2.82-1.17,3.26,3.26,0,0,1-1.08-1.23,3.8,3.8,0,0,1-.23-1.76l.3-7.49a.81.81,0,0,1,.81-.78h0a.81.81,0,0,1,.78.84l-.3,7.49a2.49,2.49,0,0,0,.09,1,1.85,1.85,0,0,0,.57.6,4.15,4.15,0,0,0,2,.86,2.37,2.37,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,1.62-.07l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,567.57,274.42Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M570.57,263.81h-.07l-4.66-.42a6.7,6.7,0,0,0-1.53,0,.81.81,0,1,1-.23-1.6,8.16,8.16,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M566.7,282.37a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.13.2-7.69a.82.82,0,0,1,.87-.75.81.81,0,0,1,.75.87c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567.51,283.21q-.43,0-.86,0l-.83-.08a7.59,7.59,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.58,10.58,0,0,0,2.38-.1.81.81,0,0,1,.25,1.6A12.27,12.27,0,0,1,567.51,283.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M587.27,441.82a.81.81,0,0,1,0-1.62l23.12-.22a.81.81,0,1,1,0,1.62l-23.12.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M610.83,468.41h0c-5.06-.28-11.42-.46-19.44-.56a.81.81,0,0,1,0-1.62h0c8,.1,14.43.28,19.51.56a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M610.82,468.41a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M614.84,442.72a.81.81,0,0,1,0-1.62l27.89-.27h0a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M614.4,468.62a.81.81,0,0,1-.8-.71c-1.19-9.12-.47-17.54.44-26.09a.8.8,0,0,1,.89-.72.81.81,0,0,1,.72.89c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M643.17,469.26h0c-8.55-.47-19.32-.58-28.72-.64a.81.81,0,0,1,0-1.62h0c9.42.05,20.21.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M643.16,469.26a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.86.86,0,0,1,.84.78c.13,3.08,0,6.37-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M647.23,443.38a.81.81,0,0,1,0-1.62l27.89-.27a.81.81,0,0,1,0,1.62l-27.89.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.79,469.28a.81.81,0,0,1-.8-.71c-1.19-9.11-.47-17.54.44-26.09a.81.81,0,1,1,1.61.17c-.9,8.45-1.61,16.77-.44,25.71a.81.81,0,0,1-.7.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M675.55,469.92h0c-8.57-.47-19.33-.59-28.72-.64a.81.81,0,0,1,0-1.62h0c9.41.05,20.2.17,28.8.64a.81.81,0,0,1,0,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M675.55,469.92a.81.81,0,0,1-.8-.68c-.86-5.42-.68-11.39-.52-17.16.1-3.46.2-6.72.07-9.75a.81.81,0,0,1,.78-.84.85.85,0,0,1,.84.78c.13,3.08,0,6.38-.07,9.86-.17,5.7-.34,11.59.5,16.86a.81.81,0,0,1-.67.93Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M593.54,462.51a.81.81,0,0,1-.81-.8,119.92,119.92,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.4,118.4,0,0,0-.52,11.89.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M591.41,449.64a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,591.41,449.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M598.84,462.69a.81.81,0,0,1-.81-.8,119.87,119.87,0,0,1,.53-12,.81.81,0,0,1,1.61.15,118.37,118.37,0,0,0-.52,11.88.81.81,0,0,1-.8.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M596.71,449.81a.25.25,0,0,0-.06.14c0,.15.23.16.38.12a12.47,12.47,0,0,1,5-.3,11.28,11.28,0,0,1-1.29-2.25c-.21-.43-.75-2.1-1.26-2.22s-1.08,1.58-1.29,2A19.26,19.26,0,0,1,596.71,449.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M629.8,466a1.87,1.87,0,0,1-.68-.13,2.44,2.44,0,0,1-1.42-2.11,13.55,13.55,0,0,1-.14-1.71l-.24-6.54a.81.81,0,0,1,.78-.84.84.84,0,0,1,.84.78l.24,6.54a11.94,11.94,0,0,0,.12,1.51c.07.45.24.79.41.86a.64.64,0,0,0,.57-.23,3.49,3.49,0,0,0,.6-1.12.81.81,0,0,1,1.51.6,4.82,4.82,0,0,1-.94,1.65A2.32,2.32,0,0,1,629.8,466Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M635,456.54h0c-2.59,0-5.23-.11-7.83-.24-.48,0-1-.07-1.47-.11-.79-.07-1.6-.13-2.37-.12-1,0-1.71-.28-2-.89-.46-1,.53-2.12.86-2.48a7.32,7.32,0,0,1,5.06-2.73,10.87,10.87,0,0,1,4.21.56,6.13,6.13,0,0,1,3.2,2.4,3.77,3.77,0,0,1,1.13,2.94A.81.81,0,0,1,635,456.54Zm-11.45-2.09c.76,0,1.53.07,2.28.13.47,0,.94.08,1.41.1,2.27.11,4.56.19,6.83.22a5.12,5.12,0,0,0-.66-.94,4.59,4.59,0,0,0-2.44-1.89,9.45,9.45,0,0,0-3.58-.49,5.76,5.76,0,0,0-4,2.2,3.43,3.43,0,0,0-.48.65l.37,0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M628.73,451a.81.81,0,0,1-.81-.75l-.13-1.66a.81.81,0,0,1,.74-.87.8.8,0,0,1,.87.74l.13,1.66a.81.81,0,0,1-.75.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M659.57,458.22l-.45,0A5.76,5.76,0,0,1,656.3,457a3.27,3.27,0,0,1-1.08-1.23A3.76,3.76,0,0,1,655,454l.3-7.49a.81.81,0,0,1,.81-.78h0a.81.81,0,0,1,.78.84l-.3,7.49a2.51,2.51,0,0,0,.09,1,1.72,1.72,0,0,0,.57.6,4.16,4.16,0,0,0,2,.86,2.39,2.39,0,0,0,1.83-.54c.86-.8.88-2.32.82-3.68l-.22-5.41a.81.81,0,0,1,.78-.84.83.83,0,0,1,.84.78l.22,5.41c.07,1.72,0,3.67-1.34,4.94A3.88,3.88,0,0,1,659.57,458.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M662.57,447.61h-.07l-4.66-.42a6.67,6.67,0,0,0-1.53,0,.81.81,0,0,1-.23-1.6,8,8,0,0,1,1.91,0l4.66.42a.81.81,0,0,1-.07,1.62Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M658.7,466.17a.81.81,0,0,1-.81-.79c-.06-2.55,0-5.14.2-7.69a.81.81,0,1,1,1.62.12c-.19,2.5-.25,5-.19,7.53a.81.81,0,0,1-.79.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M659.5,467c-.29,0-.57,0-.86,0l-.83-.08a7.66,7.66,0,0,0-2,0,.81.81,0,1,1-.26-1.6,9,9,0,0,1,2.42,0l.77.07a10.54,10.54,0,0,0,2.38-.1.81.81,0,1,1,.25,1.6A12.16,12.16,0,0,1,659.5,467Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M649.15,174.82a1.5,1.5,0,0,1-1.06-2.56l1.28-1.28a1.5,1.5,0,0,1,2.12,2.12l-1.29,1.28A1.5,1.5,0,0,1,649.15,174.82Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.76,297.47a1.91,1.91,0,0,1-.54-.08c-.46-.14-2-.78-1.73-3.32a821.6,821.6,0,0,0,2-121.16,1.5,1.5,0,1,1,3-.17,824.54,824.54,0,0,1-1.89,120.89,1.64,1.64,0,0,1,.42.25,2.14,2.14,0,0,1,.42,2.58A1.82,1.82,0,0,1,646.76,297.47Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M720.11,472.24h0a1.5,1.5,0,0,1-1.49-1.51c.17-47.52-.5-95.68-2-143.15a1.5,1.5,0,0,1,1.45-1.55,1.48,1.48,0,0,1,1.55,1.45c1.5,47.5,2.17,95.7,2,143.26A1.5,1.5,0,0,1,720.11,472.24Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M580,590.51c-.85,0-2.61-.4-3.33-3.53l-34.2-149.63a1.5,1.5,0,0,1,2.92-.67L579.55,586a1.76,1.76,0,0,1,1.05,0,2.53,2.53,0,0,1,1.49,2.71,2,2,0,0,1-1.94,1.81Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M509.61,417.68a1.5,1.5,0,0,1-1.49-1.35c-.91-9-1.45-18.11-1.61-27.13a1.5,1.5,0,0,1,1.47-1.53h0a1.5,1.5,0,0,1,1.5,1.47c.16,8.93.69,18,1.59,26.88a1.5,1.5,0,0,1-1.34,1.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M172.54,314.24a1.5,1.5,0,0,1-1.5-1.4c-2.16-33.64-3.43-67.8-3.77-101.51a1.5,1.5,0,0,1,1.48-1.52h0a1.5,1.5,0,0,1,1.5,1.48c.34,33.66,1.61,67.76,3.77,101.35a1.5,1.5,0,0,1-1.4,1.59Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M102.22,479.3a1.5,1.5,0,0,1-1.5-1.5,976.48,976.48,0,0,1,8.15-126.63,1.5,1.5,0,0,1,3,.39,973.51,973.51,0,0,0-8.13,126.24,1.5,1.5,0,0,1-1.5,1.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M382.09,318.12a1.5,1.5,0,0,1-1.5-1.46,137.6,137.6,0,0,1,2.19-27.88,1.5,1.5,0,0,1,3,.54,134.6,134.6,0,0,0-2.15,27.27,1.5,1.5,0,0,1-1.46,1.53Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M567,147.95h-.11a1.5,1.5,0,0,1-1.39-1.61c2.5-34.22,3.92-69,4.21-103.28a1.5,1.5,0,0,1,1.5-1.49h0a1.5,1.5,0,0,1,1.49,1.51c-.29,34.38-1.71,69.19-4.22,103.47A1.5,1.5,0,0,1,567,147.95Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M254.41,176.21a1.5,1.5,0,0,1-1.5-1.49l-.43-115.58A1.5,1.5,0,0,1,254,57.63h0a1.5,1.5,0,0,1,1.5,1.49l.43,115.58a1.5,1.5,0,0,1-1.49,1.51Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M323.06,194a.88.88,0,0,1-.34-1.68,20.41,20.41,0,0,0,8.61-6.82.88.88,0,1,1,1.42,1A21.88,21.88,0,0,1,323.4,194,.88.88,0,0,1,323.06,194Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M329.51,195.91a.88.88,0,0,1-.31-1.69,7.32,7.32,0,0,0,3.11-2.27.87.87,0,0,1,1.37,1.09,9.07,9.07,0,0,1-3.85,2.81A.88.88,0,0,1,329.51,195.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M383.94,269.31a.88.88,0,0,1-.59-1.52,18.54,18.54,0,0,0,4.38-6.13.87.87,0,1,1,1.6.7,20.31,20.31,0,0,1-4.8,6.71A.88.88,0,0,1,383.94,269.31Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M387,272.83a.87.87,0,0,1-.61-1.5l3-3a.87.87,0,0,1,1.22,1.25l-3,3A.87.87,0,0,1,387,272.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M550.94,316.28a.87.87,0,0,1-.46-1.62,10.51,10.51,0,0,0,4.81-7.27.88.88,0,0,1,1.73.26,12.29,12.29,0,0,1-5.62,8.49A.87.87,0,0,1,550.94,316.28Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M555.08,319.94a.88.88,0,0,1-.68-1.43l4.05-5a.88.88,0,0,1,1.36,1.11l-4.05,5A.87.87,0,0,1,555.08,319.94Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M646.36,158.78a.87.87,0,0,1-.72-1.36l6.27-9.32a.87.87,0,1,1,1.45,1l-6.27,9.32A.87.87,0,0,1,646.36,158.78Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M647.38,163.19a.88.88,0,0,1-.49-1.6,22.85,22.85,0,0,0,6.44-6.52.88.88,0,0,1,1.47,1,24.63,24.63,0,0,1-6.94,7A.87.87,0,0,1,647.38,163.19Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M715.47,312.87a.88.88,0,0,1-.23,0,.87.87,0,0,1-.61-1.08,45.45,45.45,0,0,0,1.57-9.31.87.87,0,0,1,1.75.11,47.17,47.17,0,0,1-1.63,9.67A.87.87,0,0,1,715.47,312.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M717.5,317.38a.87.87,0,0,1-.87-.87V314a.88.88,0,0,1,1.75,0v2.5A.87.87,0,0,1,717.5,317.38Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M569.57,20.39h-.13a.88.88,0,0,1-.74-1l.52-3.5a.87.87,0,1,1,1.73.26l-.52,3.5A.88.88,0,0,1,569.57,20.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M572.25,30a.86.86,0,0,1-.28,0,.88.88,0,0,1-.55-1.11A43.82,43.82,0,0,0,573.68,17a.91.91,0,0,1,.92-.83.87.87,0,0,1,.83.92,45.63,45.63,0,0,1-2.35,12.32A.88.88,0,0,1,572.25,30Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M351.81,47.69a.88.88,0,0,1-.63-1.48,27.74,27.74,0,0,0,5.53-8.54.87.87,0,1,1,1.62.66,29.07,29.07,0,0,1-5.89,9.08A.87.87,0,0,1,351.81,47.69Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M356.83,51.68a.88.88,0,0,1-.58-1.53A45.23,45.23,0,0,0,362,44.08a.87.87,0,1,1,1.38,1.08,47,47,0,0,1-5.94,6.3A.87.87,0,0,1,356.83,51.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M255.46,48.4a.87.87,0,0,1-.77-.46L253.09,45a.87.87,0,1,1,1.54-.83l1.59,2.95a.87.87,0,0,1-.77,1.29Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M173.55,192.77a.87.87,0,0,1-.4-.1,12.56,12.56,0,0,1-6.25-7.89.88.88,0,0,1,1.7-.43,10.78,10.78,0,0,0,5.36,6.77.88.88,0,0,1-.41,1.65Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M171.49,204.89a.87.87,0,0,1-.48-.15,10,10,0,0,1-4.38-8.8.88.88,0,1,1,1.75.11,8.22,8.22,0,0,0,3.6,7.23.87.87,0,0,1-.48,1.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M114,331.87a.88.88,0,0,1-.81-.53l-1.49-3.5a.88.88,0,0,1,1.61-.69l1.49,3.5a.87.87,0,0,1-.8,1.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M112.89,344.45a.88.88,0,0,1-.72-.38,24.28,24.28,0,0,1-3.57-7.84.87.87,0,0,1,1.7-.43,22.53,22.53,0,0,0,3.32,7.28.87.87,0,0,1-.72,1.37Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M190.82,374.17a.88.88,0,0,1-.82-.58,9.05,9.05,0,0,0-7.67-5.79.88.88,0,0,1,.12-1.75,10.85,10.85,0,0,1,9.19,6.94.87.87,0,0,1-.82,1.17Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M189.51,373.73a.87.87,0,0,1-.62-.25,4.18,4.18,0,0,0-5.15-.45.87.87,0,0,1-1-1.43,5.92,5.92,0,0,1,7.39.64.88.88,0,0,1-.62,1.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M269.07,343.71a.87.87,0,0,1-.86-.72,17.45,17.45,0,0,1-.2-4.76.88.88,0,0,1,1.74.17,15.71,15.71,0,0,0,.18,4.28.87.87,0,0,1-.71,1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M268.36,343.16a.87.87,0,0,1-.57-1.54l3.13-2.7a.87.87,0,1,1,1.14,1.33l-3.13,2.7A.87.87,0,0,1,268.36,343.16Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M377.93,433.36h-.11a.88.88,0,0,1-.76-1,26.76,26.76,0,0,0-1.74-14.15.88.88,0,1,1,1.63-.63,28.38,28.38,0,0,1,1.85,15A.88.88,0,0,1,377.93,433.36Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M420.89,450.7a1,1,0,0,1-.53-1.85l9.92-6.12a1,1,0,0,1,1,1.7l-9.92,6.12A1,1,0,0,1,420.89,450.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M424.36,453.7a1,1,0,0,1-.45-1.89l2.94-1.46a1,1,0,1,1,.89,1.79l-2.93,1.46A1,1,0,0,1,424.36,453.7Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M544.14,426.87a1,1,0,0,1-.45-1.89l2-1a1,1,0,1,1,.89,1.79l-2,1A1,1,0,0,1,544.14,426.87Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M545.1,431.23h-.49a1,1,0,0,1,0-2h.49a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M475.12,219.77a1,1,0,0,1,0-2A235.3,235.3,0,0,0,547,203.46a1,1,0,0,1,.69,1.88,237.28,237.28,0,0,1-72.48,14.43Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M510.53,226.27a1,1,0,0,1-.25-2l9.8-2.54a1,1,0,0,1,.5,1.94l-9.8,2.54A1,1,0,0,1,510.53,226.27Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M544.37,369.75a1,1,0,0,1-.07-2c16.71-1.22,32.23-8.25,47.24-15.05a1,1,0,0,1,.83,1.82c-14.46,6.55-30.85,14-47.92,15.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M580.71,394.05a1,1,0,0,1-.45-1.89l5.5-2.76a1,1,0,0,1,.9,1.79l-5.5,2.76A1,1,0,0,1,580.71,394.05Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M454.49,60.42a1,1,0,0,1,0-2,214.71,214.71,0,0,0,53.3-9.11,1,1,0,1,1,.58,1.91,216.68,216.68,0,0,1-53.8,9.19Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M327.29,102.14a1,1,0,0,1-.06-2,192.46,192.46,0,0,0,70.27-18,1,1,0,1,1,.86,1.81,194.47,194.47,0,0,1-71,18.23Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M432.07,510.83c-10.54,0-21-1.47-31.26-2.9a1,1,0,1,1,.28-2c12.26,1.72,24.94,3.49,37.49,2.68,13.92-.91,25.89-5.09,34.6-12.1a1,1,0,1,1,1.25,1.56c-9,7.27-21.39,11.6-35.73,12.54C436.49,510.76,434.28,510.83,432.07,510.83Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M450.56,528.21h-.06c-9.42-.56-19-.73-28.4-.49h0a1,1,0,0,1,0-2c9.48-.23,19.09-.06,28.57.5a1,1,0,0,1-.06,2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M359,529.5a1,1,0,0,1-1-1,55.34,55.34,0,0,1,.78-8.08c.31-2.13.63-4.32.73-6.47a1,1,0,0,1,1-1,1,1,0,0,1,1,1,66.87,66.87,0,0,1-.74,6.67,53.91,53.91,0,0,0-.75,7.79,1,1,0,0,1-1,1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M357.5,544.5a1,1,0,0,1-1-1v-6a1,1,0,0,1,2,0v6A1,1,0,0,1,357.5,544.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M227.31,549.06c-4.17,0-11.51-.6-15.38-4.5a1.5,1.5,0,1,1,2.13-2.11c3.07,3.09,9.95,3.87,15.35,3.56a1.5,1.5,0,0,1,.17,3C229,549,228.26,549.06,227.31,549.06Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M227.5,541a1.46,1.46,0,0,1-.31,0,20.42,20.42,0,0,0-5.58-.47,1.5,1.5,0,0,1-.22-3,23.41,23.41,0,0,1,6.42.53,1.5,1.5,0,0,1-.31,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M328.5,560a1.5,1.5,0,0,1-.7-2.83c1.12-.59,2.3-1.27,3.42-2a1.5,1.5,0,1,1,1.57,2.56c-1.17.72-2.41,1.43-3.58,2A1.48,1.48,0,0,1,328.5,560Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M340,561a1.5,1.5,0,0,1-.55-2.9,4.24,4.24,0,0,0,1.83-1.48,1.5,1.5,0,1,1,2.44,1.74,7.21,7.21,0,0,1-3.17,2.52A1.5,1.5,0,0,1,340,561Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M230.5,604a1.5,1.5,0,0,1-1.07-.45,8.85,8.85,0,0,1-2.42-4.84,1.5,1.5,0,0,1,3-.43,5.86,5.86,0,0,0,1.58,3.16A1.5,1.5,0,0,1,230.5,604Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M236.5,613a1.49,1.49,0,0,1-.89-.29,5.41,5.41,0,0,1-2.11-4.15,1.5,1.5,0,0,1,1.44-1.55,1.47,1.47,0,0,1,1.55,1.44,2.46,2.46,0,0,0,.89,1.85,1.5,1.5,0,0,1-.89,2.71Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M239.5,604.5a1.5,1.5,0,0,1-1.16-.55,3.88,3.88,0,0,1-.81-3.23,1.5,1.5,0,0,1,2.95.56.86.86,0,0,0,.19.77,1.5,1.5,0,0,1-1.16,2.45Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M184.5,419a1.5,1.5,0,0,1-1.48-1.25,8,8,0,0,1,.7-5,1.5,1.5,0,0,1,2.57,1.55,5.2,5.2,0,0,0-.3,3,1.5,1.5,0,0,1-1.23,1.73Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M186,431.5a1.5,1.5,0,0,1-1.22-.63,7.49,7.49,0,0,1-1.28-4.41,1.5,1.5,0,1,1,3,.07,4.53,4.53,0,0,0,.72,2.59A1.5,1.5,0,0,1,186,431.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M192,424.5a1.5,1.5,0,0,1-1.37-.9,14.86,14.86,0,0,1-1.11-3.89,1.5,1.5,0,1,1,3-.42,11.86,11.86,0,0,0,.89,3.11,1.5,1.5,0,0,1-1.37,2.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204.5,533h-36a1.5,1.5,0,0,1,0-3h36a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204,549.5H185.5a1.5,1.5,0,0,1,0-3H204a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M189.5,578.5c-6,0-12.13-.13-18-.25s-12-.25-18-.25a1.5,1.5,0,0,1,0-3c6,0,12.13.13,18,.25s12,.25,18,.25a1.5,1.5,0,0,1,0,3Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M194.74,597.1c-1.16,0-2.31,0-3.45-.05s-2.2,0-3.29,0a1.5,1.5,0,0,1,0-3h0c1.11,0,2.23,0,3.36,0a47.35,47.35,0,0,0,10.34-.52,1.5,1.5,0,0,1,.6,2.94A37.75,37.75,0,0,1,194.74,597.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M204.57,643.61c-1.36,0-2.93-.29-3.46-1.53a1.5,1.5,0,0,1,2.52-1.56,6.25,6.25,0,0,0,2.15,0,1.5,1.5,0,0,1,.43,3A11.65,11.65,0,0,1,204.57,643.61Zm-.69-2.69h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M224.41,412a4.41,4.41,0,0,1-2.14-.58,4.94,4.94,0,0,1-2.65-4c-.63-6.22,8.66-15.66,10.4-17.13a1.5,1.5,0,0,1,2.47,1.11c.19,7.81-1.82,17.46-5.91,19.94A4.16,4.16,0,0,1,224.41,412Zm5-16.86c-3.19,3.51-7.12,8.94-6.81,12a2,2,0,0,0,1.11,1.64,1.14,1.14,0,0,0,1.3,0C227.15,407.56,229,401.53,229.42,395.18Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M226.47,442.05a3.21,3.21,0,0,1-2.82-1.63c-2.75-4.65,2.88-20.07,5.89-22.57a1.5,1.5,0,0,1,2.45,1.29,49.5,49.5,0,0,0,.16,7c.44,6.71.89,13.65-3.83,15.5A5.05,5.05,0,0,1,226.47,442.05ZM229,424.37c-2.07,4.91-4,12.42-2.8,14.52.07.11.18.3,1,0,2.69-1.05,2.27-7.41,1.94-12.52C229.11,425.68,229.07,425,229,424.37Z" transform="translate(-60.79 2.5)"/><g class="cls-14"><path class="cls-2" d="M659,528.67a1,1,0,0,1-.06-2l1.29-.08c4.56-.29,8.88-.57,13.44-.59h0a1,1,0,0,1,0,2c-4.5,0-8.79.29-13.32.58l-1.29.08Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M680.33,545.33H669.67a1,1,0,0,1,0-2h10.67a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M638.33,570H633a1,1,0,0,1,0-2h5.33a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M421,664.7c-.45,0-.91,0-1.36,0a1,1,0,0,1,.1-2,43.87,43.87,0,0,0,6.81-.34c1.22-.12,2.49-.25,3.75-.32a1,1,0,0,1,1.06.94,1,1,0,0,1-.94,1.06c-1.22.07-2.46.2-3.66.32A57,57,0,0,1,421,664.7Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M457.67,654a1,1,0,0,1-.36-1.93c3.28-1.27,7.31-1.07,11.22-.87,1.35.07,2.62.13,3.81.13a1,1,0,0,1,0,2c-1.25,0-2.54-.07-3.91-.14-3.69-.19-7.51-.38-10.39.74A1,1,0,0,1,457.67,654Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M503,674H490.33a1,1,0,1,1,0-2H503a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M340.77,690.77a22.36,22.36,0,0,1-6-.81,1,1,0,1,1,.54-1.93,21.35,21.35,0,0,0,7.64.63,1,1,0,0,1,.19,2Q341.92,690.77,340.77,690.77Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M393,700h-8a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M645,630.67h-7.33a1,1,0,0,1,0-2H645a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M731,508.67h-2.67a1,1,0,0,1,0-2H731a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M630.33,513.33a1,1,0,0,1-.35-1.94,11.21,11.21,0,0,1,4.38-.73,1,1,0,0,1,1,1,1,1,0,0,1-1,1,9.37,9.37,0,0,0-3.62.6A1,1,0,0,1,630.33,513.33Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M753,472h-2.67a1,1,0,1,1,0-2H753a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M765.67,446H763a1,1,0,0,1,0-2h2.67a1,1,0,1,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M111,505.33h-5.33a1,1,0,1,1,0-2H111a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M144.33,500.67h-4a1,1,0,1,1,0-2h4a1,1,0,0,1,0,2Z" transform="translate(-60.79 2.5)"/></g><g class="cls-14"><path class="cls-2" d="M120.56,518.83a7.62,7.62,0,0,1-4.12-1,1,1,0,0,1,1.14-1.65,7.18,7.18,0,0,0,4.58.51,1,1,0,1,1,.38,2A10.47,10.47,0,0,1,120.56,518.83Z" transform="translate(-60.79 2.5)"/></g></g><g id="LINEART"><path class="cls-15" d="M145.95,176.85" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M255.72,395.42a2.5,2.5,0,0,1-.07-5c14.6-.4,26.34-2.39,38.77-4.49a316.57,316.57,0,0,1,34.2-4.45,2.5,2.5,0,0,1,.32,5,312.48,312.48,0,0,0-33.68,4.38c-12,2-24.51,4.16-39.46,4.56Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M365,378.9a2.5,2.5,0,0,1-1.06-4.76c5.28-2.48,9.35-5.59,13.65-8.88a95.33,95.33,0,0,1,12-8.2,2.5,2.5,0,0,1,2.42,4.38,91.32,91.32,0,0,0-11.39,7.8c-4.33,3.31-8.8,6.72-14.56,9.43A2.49,2.49,0,0,1,365,378.9Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M371.49,408.63a13.15,13.15,0,0,1-1.43-.08,12.82,12.82,0,0,1-8.47-4.94,9.18,9.18,0,0,1-1.83-7.18c1.23-6.66,9.76-7.66,14.6-7.21h0a9.63,9.63,0,0,1,4.79,1.55,8.4,8.4,0,0,1,3.17,7.19,11.07,11.07,0,0,1-6.4,9.79A11.23,11.23,0,0,1,371.49,408.63Zm.79-14.5c-3.31,0-7.17.89-7.6,3.21a4.26,4.26,0,0,0,.92,3.28,7.71,7.71,0,0,0,5,3,6.7,6.7,0,0,0,3.36-.42,6.08,6.08,0,0,0,3.38-5.35,3.59,3.59,0,0,0-1.08-3,5.2,5.2,0,0,0-2.35-.64h0C373.39,394.15,372.85,394.13,372.29,394.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M363.66,424.5a11.22,11.22,0,0,1-7.68-3,12.76,12.76,0,0,1-3.34-12.21,15.39,15.39,0,0,1,7.71-9.63,2.5,2.5,0,0,1,2.39,4.39,10.53,10.53,0,0,0-5.24,6.45,7.79,7.79,0,0,0,1.94,7.37,6.05,6.05,0,0,0,6.84,1,13.26,13.26,0,0,0,1.65-1.22,18.82,18.82,0,0,1,2.06-1.53c3.61-2.23,8-2,11.37-1.58,1.91.24,4,.51,5-.3s.89-3.23,0-5c-1.06-2.1-5.27-5.48-8-6.77a2.5,2.5,0,0,1,2.15-4.51c3.08,1.47,8.52,5.54,10.28,9s2,8.39-1.34,11.12c-2.66,2.14-6.14,1.7-8.68,1.37s-5.91-.53-8.19.87a14.67,14.67,0,0,0-1.52,1.14,17.46,17.46,0,0,1-2.31,1.68A10.19,10.19,0,0,1,363.66,424.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.27,435a8.13,8.13,0,0,1-4-1,13,13,0,0,1-3.16-2.74,12,12,0,0,1-1.82-2.39c-1.18-2.18-2.32-5.7-2-8.26a2.5,2.5,0,1,1,5,.56,11.53,11.53,0,0,0,1.46,5.31,8.1,8.1,0,0,0,1.12,1.4,8.88,8.88,0,0,0,1.92,1.75,4,4,0,0,0,4-.44,6.94,6.94,0,0,0,2.53-4.42,20.49,20.49,0,0,0-.59-7,2.5,2.5,0,1,1,4.89-1,24.37,24.37,0,0,1,.62,8.94,11.8,11.8,0,0,1-4.51,7.58A9.3,9.3,0,0,1,376.27,435Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M388.38,410.24a2.5,2.5,0,0,1-.38-5c5.57-.87,10.41-5.64,12.34-12.16,2.08-7,.34-14.44-1.48-19.41a28.74,28.74,0,0,0-3.29-6.64c-4.09-5.88-11.69-9.55-19.85-9.6h-.15c-9,0-17,4.08-22.08,7.51a2.5,2.5,0,0,1-2.79-4.15c8.19-5.51,16.84-8.38,25-8.36,9.76,0,18.92,4.55,23.93,11.74a33.58,33.58,0,0,1,3.88,7.78c3,8.15,3.54,16,1.58,22.56-2.48,8.36-8.9,14.52-16.37,15.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M291.58,645.16a94,94,0,0,1-26.67-3.83,95.29,95.29,0,0,1-38-21.85c-11.07-10.39-14.37-23.33-16.28-35.77a40.63,40.63,0,0,1,0-12.24,2.5,2.5,0,0,1,5,.53,35.69,35.69,0,0,0,0,11c2.05,13.35,5.35,24,14.76,32.88a89.3,89.3,0,0,0,82.71,21.78c2-.48,4-.93,6-1.37,10.24-2.28,19.91-4.44,28.15-10.85a2.5,2.5,0,0,1,3.07,3.95c-9.13,7.1-19.33,9.38-30.14,11.79-2,.44-3.95.88-5.94,1.36A97.5,97.5,0,0,1,291.58,645.16Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M200.22,497.51a2.5,2.5,0,0,1-2.21-1.33c-2.34-4.4-4.81-8.85-7.19-13.15-2.67-4.82-5.43-9.81-8-14.76-6.07-11.51-11.81-24-12.76-37.34-1-13.78,3-28.47,12.17-44.91,4.35-7.8,8.33-13.25,12.9-17.67a67.46,67.46,0,0,1,17.65-11.86c27.92-13.6,60.15-14.28,88-13.15,28.91,1.17,48.72,11.29,66.24,33.85a2.5,2.5,0,1,1-3.95,3.07c-16.52-21.27-35.21-30.82-62.49-31.92s-58.7-.46-85.61,12.65a62.58,62.58,0,0,0-16.36,11c-4.2,4.06-7.9,9.15-12,16.51C177.87,404,174.09,417.8,175,430.58c.88,12.41,6.39,24.33,12.2,35.36,2.59,4.91,5.34,9.87,8,14.67,2.39,4.32,4.87,8.79,7.23,13.22a2.5,2.5,0,0,1-2.21,3.68Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M261.89,349a2.49,2.49,0,0,1-1.67-.64,4.61,4.61,0,0,1-1.32-3.69,34.16,34.16,0,0,1,.75-6.35,12.71,12.71,0,0,1,2-5,8.89,8.89,0,0,1,9.85-3.06c3,1.06,5.42,3.7,7.23,8.08a43.72,43.72,0,0,1,2,5.84,2.5,2.5,0,0,1-4.84,1.25,38.8,38.8,0,0,0-1.73-5.17c-1.24-3-2.63-4.71-4.25-5.28a3.88,3.88,0,0,0-4.19,1.3,8.26,8.26,0,0,0-1.17,3.09,29.18,29.18,0,0,0-.64,5.42c0,.09,0,.16,0,.21a2.5,2.5,0,0,1-2,4Zm1.67-4.36h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M183.89,387.5a2.52,2.52,0,0,1-.41,0c-3.94-.65-7.3-3.73-9.72-8.89-2.67-5.71-3.34-11.18-1.95-15.82,1.62-5.36,7.07-10.44,13.41-9.67,5,.61,8.67,4.6,11.1,7.24l4.87,5.3a2.5,2.5,0,1,1-3.68,3.38l-4.87-5.3c-2.55-2.78-5.08-5.3-8-5.66-3.68-.45-7,2.84-8,6.15-1.31,4.35.2,9.06,1.69,12.25,1.17,2.51,3.17,5.61,6,6.08a2.5,2.5,0,0,1-.41,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M294.85,448.5A43.45,43.45,0,1,1,338.3,405,43.5,43.5,0,0,1,294.85,448.5Zm0-81.9A38.45,38.45,0,1,0,333.3,405,38.49,38.49,0,0,0,294.85,366.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M394.52,444.82a2.5,2.5,0,0,1-2.5-2.41c-.18-4.94-.79-11.63-1.59-17.47a4.05,4.05,0,0,1,0-1.16A2.53,2.53,0,0,1,392.5,421a2.46,2.46,0,0,1,2.86,2,4.07,4.07,0,0,1,0,1.28c.82,6,1.44,12.85,1.63,17.9a2.5,2.5,0,0,1-2.41,2.59Zm-4.09-20.91h0Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M375.87,636.22a2.5,2.5,0,0,1-2.46-2l-16-84.58a2.5,2.5,0,0,1,4.91-.93l15.56,82L537.75,595,500.12,420.84,344.73,456.22l10,56.84a2.5,2.5,0,0,1-4.92.87l-10.45-59.18a2.5,2.5,0,0,1,1.91-2.87l160.17-36.47a2.5,2.5,0,0,1,3,1.91l38.69,179a2.5,2.5,0,0,1-1.9,3L376.42,636.16A2.45,2.45,0,0,1,375.87,636.22Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M542.38,599.64a2.5,2.5,0,0,1-.49-5c23.54-4.76,47.28-10.1,70.61-15.88L578,417l-53.49,1.44c-6.61.18-13.44.36-20.07,1a2.5,2.5,0,0,1-.51-5c6.82-.7,13.74-.89,20.44-1.07L580,411.91a2.46,2.46,0,0,1,2.51,2l35.43,166.24a2.5,2.5,0,0,1-1.84,2.95c-24.16,6-48.78,11.58-73.18,16.51A2.48,2.48,0,0,1,542.38,599.64Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M339.58,545.66a2.5,2.5,0,0,1-.67-4.91A92.52,92.52,0,0,1,350.66,539l1.36-.16a2.5,2.5,0,0,1,.57,5l-1.36.15a94.18,94.18,0,0,0-11,1.58A2.5,2.5,0,0,1,339.58,545.66Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M365,542.15a2.5,2.5,0,0,1-.41-5c10.27-1.72,16.43-4,18.3-6.92a3.28,3.28,0,0,0,.4-2.81c-1-4-7.08-6.94-18-8.69a2.5,2.5,0,0,1,.79-4.94c8.44,1.36,19.9,4.12,22,12.38a8.33,8.33,0,0,1-1.05,6.79c-2.78,4.27-9.46,7.09-21.67,9.13A2.49,2.49,0,0,1,365,542.15Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M353,517.24l-.28,0A200,200,0,0,0,330.45,516a2.5,2.5,0,0,1,0-5,205,205,0,0,1,22.86,1.26,2.5,2.5,0,0,1-.27,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M374.91,644.09a19.3,19.3,0,0,1-7.71-1.6,35.5,35.5,0,0,1-5.75-3.38l-23.4-15.86a2.5,2.5,0,0,1,2.8-4.14L364.26,635a31.89,31.89,0,0,0,4.94,2.93,14.31,14.31,0,0,0,7.26,1.1,4.63,4.63,0,0,0,2.48-.81c1-.83,1-2.61.47-3.86a2.5,2.5,0,0,1,4.65-1.85c1.39,3.49.62,7.4-1.87,9.52a9.29,9.29,0,0,1-5.17,2A19.23,19.23,0,0,1,374.91,644.09Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M224.4,649.13a19.38,19.38,0,0,1-5.42-.75,5.09,5.09,0,0,1-3-2,5.2,5.2,0,0,1-.74-3c.17-10,7.38-17.73,14.76-24.76a2.5,2.5,0,1,1,3.45,3.62c-6.61,6.3-13.07,13.13-13.21,21.23v.08l.14,0c4.2,1.22,9.32.4,14-2.26,4.56-2.56,8.4-6.47,11.86-10.31a2.5,2.5,0,0,1,3.71,3.35c-3.75,4.16-7.94,8.4-13.13,11.32A25.75,25.75,0,0,1,224.4,649.13Zm-4.15-5.26h0Zm-.31-.44Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M559.82,416.91a2.5,2.5,0,0,1-2.5-2.5V390.84H404.5a2.5,2.5,0,0,1,0-5H559.82a2.5,2.5,0,0,1,2.5,2.5v26.08A2.5,2.5,0,0,1,559.82,416.91Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M447.94,433.1a2.5,2.5,0,0,1-2.5-2.5V388.34a2.5,2.5,0,0,1,5,0V430.6A2.5,2.5,0,0,1,447.94,433.1Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M682,484.5H594.42a2.5,2.5,0,1,1,0-5H679.5v-182h-243v90.84a2.5,2.5,0,0,1-5,0V295a2.5,2.5,0,0,1,2.5-2.5H682a2.5,2.5,0,0,1,2.5,2.5V482A2.5,2.5,0,0,1,682,484.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M682,484.5a2.5,2.5,0,0,1-.66-4.91l62.16-16.93V291.75l-61.27,5.74a2.5,2.5,0,1,1-.47-5l64-6A2.5,2.5,0,0,1,748.5,289V464.57a2.5,2.5,0,0,1-1.84,2.41l-64,17.43A2.52,2.52,0,0,1,682,484.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M598,297.5a2.5,2.5,0,0,1-2.5-2.5V150.5H417.66v142H434a2.5,2.5,0,0,1,0,5H415.16a2.5,2.5,0,0,1-2.5-2.5V148a2.5,2.5,0,0,1,2.5-2.5H598a2.5,2.5,0,0,1,2.5,2.5V295A2.5,2.5,0,0,1,598,297.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M670.74,151.74h0L598,150.5a2.5,2.5,0,1,1,.09-5l72.74,1.24a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M695.88,296.2a2.5,2.5,0,0,1-2.5-2.5V177.1a2.5,2.5,0,0,1,5,0V293.7A2.5,2.5,0,0,1,695.88,296.2Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M604,150.5a2.5,2.5,0,0,1-2.5-2.5V16L541.5,3.1V148a2.5,2.5,0,0,1-5,0V0a2.5,2.5,0,0,1,.93-1.94,2.5,2.5,0,0,1,2.1-.5l65,14a2.5,2.5,0,0,1,2,2.44V148A2.5,2.5,0,0,1,604,150.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M400,30.5a2.5,2.5,0,0,1-2.5-2.5V5a2.5,2.5,0,0,1,2.41-2.5l139-5A2.51,2.51,0,0,1,541.5-.09a2.5,2.5,0,0,1-2.41,2.59L402.5,7.41V28A2.5,2.5,0,0,1,400,30.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,179.6H289.78l-68-5.1A2.5,2.5,0,0,1,219.5,172V46a2.5,2.5,0,0,1,2-2.45l68-14a2.49,2.49,0,0,1,.5-.05H427a2.5,2.5,0,0,1,2.5,2.5V148a2.5,2.5,0,0,1-5,0V34.5H290.25L224.5,48V169.68l65.56,4.92h125.1a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M290,179.6h0a2.5,2.5,0,0,1-2.5-2.5l0-145.1a2.5,2.5,0,0,1,2.5-2.5h0a2.5,2.5,0,0,1,2.5,2.5l0,145.1A2.5,2.5,0,0,1,290,179.6Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M290,316.5H139a2.5,2.5,0,0,1-2.5-2.5V177.1a2.5,2.5,0,0,1,2.41-2.5L242,171a2.5,2.5,0,1,1,.17,5L141.5,179.51v132h146l0-59.5a2.5,2.5,0,0,1,.74-1.77,2.38,2.38,0,0,1,1.78-.72l125.16,1a2.5,2.5,0,1,1,0,5l-122.64-1,0,59.48A2.5,2.5,0,0,1,290,316.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M199.36,316.5a2.5,2.5,0,0,1-2.5-2.5V175a2.5,2.5,0,0,1,5,0V314A2.5,2.5,0,0,1,199.36,316.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,324.62H144l-.3,0L77,316.48a2.5,2.5,0,0,1,.3-5H139a2.5,2.5,0,0,1,0,5H118.54l25.61,3.12H369.87l-28.15-3.12H290a2.5,2.5,0,0,1,0-5h51.88l.27,0,73.31,8.12a2.5,2.5,0,0,1-.28,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M195.71,489.21H139a2.51,2.51,0,0,1-.5-.05L76.81,476.45a2.5,2.5,0,0,1-2-2.45V314a2.5,2.5,0,0,1,5,0V472l59.44,12.25h56.46a2.5,2.5,0,0,1,0,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M144,489.21a2.5,2.5,0,0,1-2.5-2.5V322.12a2.5,2.5,0,0,1,5,0v164.6A2.5,2.5,0,0,1,144,489.21Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M415.16,391a2.5,2.5,0,0,1-2.5-2.5V322.12a2.5,2.5,0,0,1,5,0V388.5A2.5,2.5,0,0,1,415.16,391Z" transform="translate(-60.79 2.5)"/><circle class="cls-2" cx="268" cy="397.88" r="4.97"/><circle class="cls-2" cx="332.92" cy="374.31" r="4.97"/><path class="cls-2" d="M746,291.5l-.33,0-50.12-6.6a2.5,2.5,0,1,1,.65-5l50.12,6.6a2.5,2.5,0,0,1-.32,5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M260.2,516c-11.18,0-22.1-.85-32.78-1.67-5.72-.44-11.25-1.28-17.79-2.41-.42-.07-1.15-.13-1.93-.2-3.83-.31-6.88-.7-8.48-2.55-2.33-2.7-2.49-14.1-2.49-14.21a2.5,2.5,0,0,1,.76-1.78,2.43,2.43,0,0,1,1.81-.7,86.45,86.45,0,0,1,11.45,1.34c2.72.44,5.53.9,8.3,1.14,2.19.19,4.39.43,6.52.67,2.37.27,4.82.54,7.24.73,11.37.88,23.05.62,37.87-.85,4.78-.47,9.53-.91,14.27-1.34,8.69-.79,17.68-1.62,26.58-2.67,6.31-.75,12-1.48,17.45-2.22,4.9-.67,9.64-1.59,14.23-2.48l3-.57a2.5,2.5,0,0,1,.94,4.91l-3,.57c-4.65.9-9.46,1.83-14.5,2.52-5.46.75-11.2,1.48-17.54,2.23-9,1.06-18,1.89-26.71,2.69-4.73.43-9.47.87-14.23,1.34-15.12,1.5-27.08,1.76-38.75.86-2.5-.19-5-.47-7.41-.74-2.1-.23-4.26-.48-6.39-.66-3-.25-5.88-.73-8.69-1.18s-5.43-.89-8.12-1.12c.21,3.07.69,7.15,1.22,8.31.74.45,3.75.69,5.05.8.93.08,1.73.14,2.37.25,6.4,1.1,11.79,1.92,17.33,2.35,16.15,1.25,32.85,2.55,49.94.84,3.43-.34,7-.56,10.36-.78,4.63-.29,9.41-.59,14-1.2,3.91-.53,7.81-1.15,11.58-1.76a221.82,221.82,0,0,1,23.71-2.93c2.85-.15,5.73-.1,8.52-.05,1.38,0,2.75,0,4.11,0a2.5,2.5,0,0,1,0,5c-1.39,0-2.8,0-4.2,0-2.7,0-5.49-.1-8.17,0a215,215,0,0,0-23.18,2.88c-3.81.61-7.74,1.25-11.71,1.78-4.73.63-9.6.94-14.31,1.23-3.36.21-6.84.43-10.18.76C272.16,515.75,266.14,516,260.2,516Zm-57.09-10Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M312.32,579.89q-1.43,0-2.86,0c-15-.5-31.12-1.47-50.81-3.05-3.23-.26-6.56-.34-9.77-.42-3.72-.09-7.57-.19-11.4-.55a74,74,0,0,1-8.77-1.55c-2-.44-4.12-.9-6.18-1.21a55.21,55.21,0,0,0-9.94-.29c-2.27.07-4.62.13-7,0a2.5,2.5,0,0,1-2.38-2.36c-.21-3.82-.29-8.26,1.5-12.54a66.07,66.07,0,0,0,3.9-11.72,3.41,3.41,0,0,0-.06-2.55l-.09-.07a4.08,4.08,0,0,1-1.68-3.3,3.78,3.78,0,0,1,1.78-2.78l.12-.09c1.49-5.19-.17-11.18-1.78-17a76.62,76.62,0,0,1-2.05-8.66,2.5,2.5,0,0,1,4.94-.76,71.94,71.94,0,0,0,1.93,8.08c1.86,6.69,3.78,13.6,1.57,20.34a3.23,3.23,0,0,1-.73,1.2,3.74,3.74,0,0,1,.63,1.13,7.77,7.77,0,0,1,.32,5.48,70.61,70.61,0,0,1-4.19,12.63,19.26,19.26,0,0,0-1.21,8c1.44,0,2.85,0,4.33-.08a59.92,59.92,0,0,1,10.83.34c2.22.33,4.4.81,6.51,1.27a69.34,69.34,0,0,0,8.18,1.46c3.64.35,7.4.44,11,.53,3.29.08,6.68.16,10.05.43,19.61,1.58,35.68,2.55,50.57,3,12.67.43,25.17-2.26,37.24-4.86,7.23-1.55,12.09-2.88,14.44-3.93a2.5,2.5,0,0,1,2,4.56c-2.71,1.21-7.75,2.6-15.43,4.25C336.44,577.34,324.6,579.89,312.32,579.89Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M372,620.83a2.49,2.49,0,0,1-1.73-.69c-1.32-1.27-2.55-2.67-3.74-4a39,39,0,0,0-5.07-5.14,2.5,2.5,0,0,1,3.07-3.94,43.31,43.31,0,0,1,5.76,5.79c1.17,1.33,2.27,2.59,3.43,3.71a2.5,2.5,0,0,1-1.73,4.31Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M357,551.65a5.21,5.21,0,0,1-2.67-1c-5.24-3.3-4.58-11.16-4.14-16.36.07-.8.13-1.54.16-2.18.06-1.23.14-2.47.22-3.7.17-2.67.34-5.43.34-8.11,0-.37-.07-1-.15-1.64-.32-2.75-.76-6.51,1.74-8.64a5,5,0,0,1,2.09-1,4.05,4.05,0,0,1,3.34.57,3.84,3.84,0,0,1,.47-.26,2.5,2.5,0,0,1,3.11.82l.07.09a3.77,3.77,0,0,1,5.15,1c1.64,2.09,1.54,5.24,1.47,7.55,0,.38,0,.72,0,1,0,4.07,0,8.45-.34,12.9,0,.57-.06,1.32-.08,2.17-.17,6.18-.56,11.92-3.51,14.29-.94.76-1.91,1.54-3.26,1.25a2.59,2.59,0,0,1-1.34-.75,2.73,2.73,0,0,1-2.64,2Zm-1.41-37.47a16,16,0,0,0,.13,3.87,20.36,20.36,0,0,1,.18,2.21c0,2.84-.18,5.68-.35,8.43-.08,1.21-.15,2.42-.21,3.64,0,.69-.1,1.49-.17,2.34-.28,3.34-.73,8.69,1.06,11l.18-.14a3.3,3.3,0,0,1,3.06-2,2.86,2.86,0,0,1,2.16.91c.92-2.23,1.07-7.73,1.13-9.73,0-.93,0-1.74.09-2.36.28-4.31.32-8.59.33-12.58,0-.35,0-.75,0-1.18a22.32,22.32,0,0,0-.07-3.18,2.63,2.63,0,0,1-3.27.36,2.5,2.5,0,0,1-3.7-.65l-.09-.14C355.94,514.73,355.76,514.44,355.59,514.19Zm4.89,30.51h0Zm-4.74-30.9h0Zm-1.62-1.9h0Z" transform="translate(-60.79 2.5)"/></g><g id="circle"><path class="cls-2" d="M153.52,177.1A349.71,349.71,0,0,1,222,114.31L221,102a6,6,0,0,0-3.76,1,361.7,361.7,0,0,0-75.95,70.06,6,6,0,0,0-1.31,4.4" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M139.38,195.21A344.77,344.77,0,0,0,72.79,400c0,191.91,156.13,348,348,348s348-156.13,348-348c0-121.6-61.55-232-164.86-296l.87-13a6,6,0,0,1,2.24.81A359.84,359.84,0,0,1,780.86,400,360.13,360.13,0,0,1,89.08,540.14,360.53,360.53,0,0,1,134.23,182a6,6,0,0,1,3.74-2.26Z" transform="translate(-60.79 2.5)"/></g><g id="layers"><g class="cls-10"><path class="cls-8" d="M368.81,388.34l-1.1-23.69s8.48-17.33,8.09-18,6.68-6.06,6.68-6.06l13-1,8.29,1.85,9.82,12.28,7.21,15.07L424.21,386l-4.71,21.73-6.39,11.59-8.61,4.11L390.36,422l-5.08-3.31,3.67-3.79v-5.42l-4-6.79-5.56-2.47-1.51-7.57Z" transform="translate(-60.79 2.5)"/></g><g class="cls-10"><polygon class="cls-8" points="226.66 366.6 237.24 361.46 250.18 361.46 265.7 366.6 279.96 384.01 285.01 395.42 287.35 407.55 286.4 422.15 279.23 440.12 268 452.2 253.91 456.94 235.27 454.47 220.17 446.08 208.28 425.94 205.61 398.57 213.7 378.9 226.66 366.6"/></g><path class="cls-2" d="M426,376.14c-2.08-12-7.08-22.86-14.06-30.5-7.32-8-16-11.61-24.38-10.16s-15.34,7.76-19.54,17.76c-3.34,7.95-4.62,17.52-3.76,27.46a26.09,26.09,0,0,0-17.18,6.73c-8.49-20.91-28.27-34.1-48.45-30.6-23.83,4.13-39.32,30-34.53,57.59,4.35,25.11,24,43.19,45.38,43.19a38.08,38.08,0,0,0,6.5-.56c11.63-2,21.63-9.18,28.14-20.17a55,55,0,0,0,6.39-37.42c-.32-1.87-.74-3.7-1.23-5.49a19.71,19.71,0,0,1,15.78-7.13c.22,1.27.63,3.21.91,4.42a3.06,3.06,0,0,0,6-1.36c-.26-1.15-.67-3.1-.87-4.24-1.89-10.9-1-21.56,2.6-30,3.37-8,8.67-13,14.95-14.1s13,1.85,18.82,8.26c6.2,6.78,10.66,16.52,12.54,27.41,3.81,22-4.06,41.81-17.54,44.14a13,13,0,0,1-3.13.12,23.62,23.62,0,0,1-10.67-3.64,11.5,11.5,0,0,0-1.58-1.14c-.49-.19-1.28.36-1.83.46a9.58,9.58,0,0,0-1.67.32,1.45,1.45,0,0,0-1,1.23,2.66,2.66,0,0,0,.7,1.39,13,13,0,0,1,.83,1.85c.22.45.71.67,1.13.94a28.53,28.53,0,0,0,15.33,4.73,17.49,17.49,0,0,0,3-.24C420.27,424.45,430.38,401.47,426,376.14Zm-87.14,57.62c-5.59,9.43-14.08,15.56-23.92,17.26-20.5,3.55-40.6-13.34-44.81-37.64s9-47,29.55-50.52a32.07,32.07,0,0,1,5.48-.47c18.49,0,35.5,16,39.33,38.11A48.84,48.84,0,0,1,338.85,433.76Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M309.47,458.61c-22.09,0-42-18.92-46.37-44-4.88-28.17,11-54.53,35.35-58.75,19.89-3.45,39.86,8.82,49,29.93a27.19,27.19,0,0,1,15.71-6,58.73,58.73,0,0,1,3.92-26.87c4.34-10.33,11.55-16.85,20.3-18.36s17.73,2.2,25.29,10.47c7.11,7.77,12.19,18.78,14.3,31h0c4.48,25.87-6,49.37-23.34,52.37a18.5,18.5,0,0,1-3.14.25,29.35,29.35,0,0,1-15.87-4.89l-.23-.14a3,3,0,0,1-1.25-1.2c-.13-.27-.23-.54-.33-.81a4.14,4.14,0,0,0-.42-.92l-.16-.22a2.91,2.91,0,0,1-.72-1.74,2.4,2.4,0,0,1,1.67-2.16,5.81,5.81,0,0,1,1.34-.29l.5-.07a3.31,3.31,0,0,0,.46-.17,2.52,2.52,0,0,1,1.92-.24,4.9,4.9,0,0,1,1.26.85,5.44,5.44,0,0,0,.5.39,21.77,21.77,0,0,0,3.33,1.76,21.47,21.47,0,0,0,6.86,1.72,12,12,0,0,0,2.89-.11c12.94-2.24,20.45-21.52,16.73-43-1.85-10.71-6.22-20.27-12.3-26.91-5.63-6.15-12-9-17.91-7.95s-11,5.82-14.2,13.51c-3.49,8.3-4.39,18.77-2.53,29.48.2,1.14.6,3.06.86,4.19a4.06,4.06,0,1,1-7.91,1.81c-.22-1-.53-2.43-.77-3.66a18.76,18.76,0,0,0-13.84,6.39c.45,1.71.82,3.41,1.11,5.07a56,56,0,0,1-6.51,38.1C338.31,448.64,328.07,456,316.15,458A39.24,39.24,0,0,1,309.47,458.61Zm-4.33-101.34a37.16,37.16,0,0,0-6.35.55c-23.28,4-38.41,29.35-33.72,56.44,4.18,24.15,23.27,42.36,44.4,42.36a37.25,37.25,0,0,0,6.33-.54c11.34-2,21.09-9,27.45-19.69a54,54,0,0,0,6.26-36.74c-.31-1.77-.71-3.58-1.21-5.4l-.14-.5.32-.4a20.76,20.76,0,0,1,16.59-7.5l.81,0,.14.79c.23,1.3.63,3.22.9,4.37a2.06,2.06,0,0,0,2.47,1.55,2.06,2.06,0,0,0,1.55-2.47c-.27-1.16-.68-3.13-.88-4.3-1.92-11.08-1-21.95,2.66-30.59,3.5-8.33,9.08-13.56,15.7-14.7s13.62,1.89,19.73,8.57C414.49,356,419,365.93,420.95,377c3.9,22.55-4.33,42.87-18.36,45.3a14,14,0,0,1-3.37.13,23.47,23.47,0,0,1-7.5-1.87,23.81,23.81,0,0,1-3.64-1.93,7.5,7.5,0,0,1-.69-.53,5.15,5.15,0,0,0-.63-.48,4.85,4.85,0,0,0-.5.19,4.3,4.3,0,0,1-.86.29l-.6.09a4.18,4.18,0,0,0-.89.18.65.65,0,0,0-.38.3,1.91,1.91,0,0,0,.33.55l.19.27a5.89,5.89,0,0,1,.65,1.35c.08.21.16.42.26.63a1.78,1.78,0,0,0,.49.36l.29.18a27.71,27.71,0,0,0,14.78,4.57,16.5,16.5,0,0,0,2.8-.22c16.26-2.82,26-25.27,21.71-50.06h0c-2.05-11.85-7-22.5-13.81-30-7.08-7.75-15.42-11.24-23.47-9.85S373,344,368.94,353.64c-3.27,7.78-4.54,17.11-3.68,27l.09,1.08h-1.09a25.09,25.09,0,0,0-16.52,6.47l-1.06,1-.54-1.33C338.55,369.1,322.28,357.27,305.14,357.27Zm4.32,95.22c-19,0-36.41-16.32-40.32-38.94-4.3-24.85,9.32-48,30.36-51.67a33.19,33.19,0,0,1,5.65-.49c19.14,0,36.48,16.74,40.32,38.94a49.84,49.84,0,0,1-5.75,33.94C334,444,325.23,450.25,315.1,452A33,33,0,0,1,309.46,452.49Zm-4.31-89.1a31.2,31.2,0,0,0-5.31.46c-20,3.46-32.85,25.6-28.73,49.36S294.8,453.49,314.76,450c9.55-1.65,17.8-7.61,23.23-16.79h0a47.84,47.84,0,0,0,5.5-32.58C339.81,379.42,323.32,363.39,305.14,363.39Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M371.49,408.63a13.15,13.15,0,0,1-1.43-.08,12.82,12.82,0,0,1-8.47-4.94,9.18,9.18,0,0,1-1.83-7.18c1.23-6.66,9.76-7.66,14.6-7.21h0a9.63,9.63,0,0,1,4.79,1.55,8.4,8.4,0,0,1,3.17,7.19,11.07,11.07,0,0,1-6.4,9.79A11.23,11.23,0,0,1,371.49,408.63Zm.79-14.5c-3.31,0-7.17.89-7.6,3.21a4.26,4.26,0,0,0,.92,3.28,7.71,7.71,0,0,0,5,3,6.7,6.7,0,0,0,3.36-.42,6.08,6.08,0,0,0,3.38-5.35,3.59,3.59,0,0,0-1.08-3,5.2,5.2,0,0,0-2.35-.64h0C373.39,394.15,372.85,394.13,372.29,394.13Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M363.66,424.5a11.22,11.22,0,0,1-7.68-3,12.76,12.76,0,0,1-3.34-12.21,15.39,15.39,0,0,1,7.71-9.63,2.5,2.5,0,0,1,2.39,4.39,10.53,10.53,0,0,0-5.24,6.45,7.79,7.79,0,0,0,1.94,7.37,6.05,6.05,0,0,0,6.84,1,13.26,13.26,0,0,0,1.65-1.22,18.82,18.82,0,0,1,2.06-1.53c3.61-2.23,8-2,11.37-1.58,1.91.24,4,.51,5-.3s.89-3.23,0-5c-1.06-2.1-5.27-5.48-8-6.77a2.5,2.5,0,0,1,2.15-4.51c3.08,1.47,8.52,5.54,10.28,9s2,8.39-1.34,11.12c-2.66,2.14-6.14,1.7-8.68,1.37s-5.91-.53-8.19.87a14.67,14.67,0,0,0-1.52,1.14,17.46,17.46,0,0,1-2.31,1.68A10.19,10.19,0,0,1,363.66,424.5Z" transform="translate(-60.79 2.5)"/><path class="cls-2" d="M376.27,435a8.13,8.13,0,0,1-4-1,13,13,0,0,1-3.16-2.74,12,12,0,0,1-1.82-2.39c-1.18-2.18-2.32-5.7-2-8.26a2.5,2.5,0,1,1,5,.56,11.53,11.53,0,0,0,1.46,5.31,8.1,8.1,0,0,0,1.12,1.4,8.88,8.88,0,0,0,1.92,1.75,4,4,0,0,0,4-.44,6.94,6.94,0,0,0,2.53-4.42,20.49,20.49,0,0,0-.59-7,2.5,2.5,0,1,1,4.89-1,24.37,24.37,0,0,1,.62,8.94,11.8,11.8,0,0,1-4.51,7.58A9.3,9.3,0,0,1,376.27,435Z" transform="translate(-60.79 2.5)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.png b/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.png deleted file mode 100644 index 0d72555c531d2fe464c6ebf07a744a87d33ab1f1..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.svg b/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.svg deleted file mode 100644 index 4132cb3caef9266812f9b11f690e0991e24bb103..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/assets/DigbyShadowsScene2.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 725.13 841.56"><defs><style>.cls-1{fill:#1c1c1b;}.cls-2{fill:#ced8d2;}.cls-3{opacity:0.2;}.cls-4{opacity:0.45;}.cls-5{fill:#ccbca8;}.cls-6{fill:#b79765;}.cls-7{fill:#fff;}.cls-8{opacity:0.38;}.cls-9{fill:#f6d2a2;}.cls-10{fill:#b7a38d;}.cls-11{fill:#1d1d1b;}.cls-12{opacity:0.19;}</style></defs><title>BoyerShadowsScene2</title><g id="Capa_10" data-name="Capa 10"><path class="cls-1" d="M764.83,322.58A357.59,357.59,0,0,0,608.13,193.31l.36-11,36.64-58.43a2.5,2.5,0,0,0-2.34-3.82l-24.27,2.17,11.87-36.4a2.5,2.5,0,0,0-1.76-3.2l-134.5-34a2.5,2.5,0,0,0-3.05,1.89l-21.16,96.39L429.15,79.7a2.51,2.51,0,0,0-2.31-1.2L276.83,89a2.5,2.5,0,0,0-2.15,3.41l3.72,9.52-17.26-4.35a2.5,2.5,0,0,0-2.5,4.06l53.29,61.29V202.7a3.52,3.52,0,0,0-3.42-.16,357.58,357.58,0,1,0,456.3,120Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M468.33,885.06a362.61,362.61,0,0,1-162-687q.32-.16.65-.29v-33l-52.07-59.88a7.5,7.5,0,0,1,7.49-12.19l7.84,2-.18-.47A7.5,7.5,0,0,1,276.48,84l150-10.5a7.49,7.49,0,0,1,6.93,3.59l34.28,56.48,18.48-84.19a7.5,7.5,0,0,1,9.15-5.67l134.51,34a7.5,7.5,0,0,1,5.29,9.6l-9.52,29.2L642.34,115a7.5,7.5,0,0,1,7,11.45l-35.92,57.28-.2,6.29a362.56,362.56,0,0,1-144.91,695ZM310,207.39a352.51,352.51,0,1,0,296.15-9.48L603,196.57l.51-15.82,34.68-55.31-26.8,2.39L624.8,86.77,495.4,54.06,472.12,160.13,425.66,83.6,280.58,93.76l6,15.39-18.95-4.78,49.29,56.69v50.56Z" transform="translate(-105.77 -43.5)"/></g><g id="background_color" data-name="background color"><path class="cls-2" d="M606.14,196.29C733.21,250,822.37,375.85,822.37,522.5c0,195.53-158.51,354-354,354s-354-158.51-354-354c0-138.66,79.71-258.7,195.81-316.8" transform="translate(-105.77 -43.5)"/></g><g id="background_shadows" data-name="background shadows"><g class="cls-3"><polygon points="655.41 575.12 531.59 650.5 494.43 631.06 496.06 597.66 556.54 578.75 655.41 575.12"/></g><g class="cls-3"><path d="M168.51,577.42l-52.39,5.17s20.59,65.66,26.2,78.18S178.74,727,185.62,737.5s37.45,40.32,37.45,40.32L383.61,705Z" transform="translate(-105.77 -43.5)"/></g></g><g id="Capa_9" data-name="Capa 9"><path class="cls-1" d="M770.15,537.19c-5.12,0-9.59-.48-13-1.76a2.5,2.5,0,0,1,1.78-4.67c7.58,2.88,23.89.83,38.27-1,8.92-1.12,17.34-2.18,23.83-2.18a2.5,2.5,0,0,1,0,5c-6.19,0-14.46,1-23.21,2.14C788.21,535.95,778.35,537.19,770.15,537.19Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M116.11,585.09a2.5,2.5,0,0,1-.58-4.93c12-2.85,23.67-3.07,36.58-3.07a2.5,2.5,0,0,1,0,5h0c-12.64,0-24,.21-35.42,2.93A2.48,2.48,0,0,1,116.11,585.09Z" transform="translate(-105.77 -43.5)"/><g class="cls-4"><path class="cls-1" d="M307.84,758.67h-4.67a2.5,2.5,0,0,1,0-5h4.67a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M348.51,782.67h-6a2.5,2.5,0,1,1,0-5h6a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M491.18,824.67h-2.67a2.5,2.5,0,1,1,0-5h2.67a2.5,2.5,0,1,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M546.51,806h-2.67a2.5,2.5,0,0,1,0-5h2.67a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M693.18,678.67a2.5,2.5,0,0,1-1-4.78,9.8,9.8,0,0,1,4.46-.89,2.5,2.5,0,0,1,2.41,2.59,2.53,2.53,0,0,1-2.59,2.41,4.85,4.85,0,0,0-2.2.44A2.49,2.49,0,0,1,693.18,678.67Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M671.17,663.33a2.5,2.5,0,0,1-.21-5l3.06-.29c1.43-.14,2.86-.28,4.3-.38a2.5,2.5,0,0,1,.36,5c-1.4.1-2.79.24-4.18.37l-3.13.29Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M743.84,654h-6a2.5,2.5,0,0,1,0-5h6a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M787.18,579.33h-8a2.5,2.5,0,0,1,0-5h8a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M628.13,800.15a18.45,18.45,0,0,1-6.49-1,2.5,2.5,0,1,1,1.73-4.69c2.16.8,4.77.7,7.54.59,1,0,2-.07,2.94-.07a2.5,2.5,0,0,1,0,5h-.09c-.87,0-1.75,0-2.65.07S629.13,800.15,628.13,800.15Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M302.11,802.76a25.61,25.61,0,0,1-6.21-.84,2.5,2.5,0,0,1,1.22-4.85,18.38,18.38,0,0,0,6.44.61,2.5,2.5,0,1,1,.57,5A17.58,17.58,0,0,1,302.11,802.76Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M354.79,816.06a18.53,18.53,0,0,1-8-1.64,2.5,2.5,0,0,1,2.15-4.51,14.84,14.84,0,0,0,7.42,1.1,2.5,2.5,0,0,1,.35,5Q355.72,816.06,354.79,816.06Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-4"><path class="cls-1" d="M239.84,748.67h-5.33a2.5,2.5,0,1,1,0-5h5.33a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/></g></g><g id="COLOR"><path class="cls-5" d="M636.94,672.51l.8-29.52,123.44-24.37V376.75L670.5,347.84,601.4,325l3.79-143.43L643,122.5,615,125,627.37,87,493.51,51,468.33,152.25,427,81,277,91.5l5.55,14.05L262,101.71,313.76,162l.69,106.83L247.51,274l-11.2-.75,8.12,48.44-1.59,103.56v2.92l-42.58,5.43V470.5l-50.82,8v45l-4.36,2,12.4,36-2,100.22,95.38,63.2c.75.5,131-19.64,131-19.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M488,791.08c1.73.41,3.46.83,5.22,1.13,6.25,1.07,11.6,2.26,18.06,1.63,15.87-1.55,33.24-1.7,48.46-6.84,9.3-3.14,17.6-8.61,25.79-14l21.6-14.3c7.14-4.73,14.35-9.51,20.21-15.76,3.07-3.27,6-7.1,10.28-8.44,3.42-1.07,6.91,0,10.21-1s6.54-3.75,8.88-6.16a28.13,28.13,0,0,0,8.11-19.64c-.06-4.51-1.64-9.52-5.69-11.52-5.15-2.55-8.9,1.34-12.27,4.65-2.85,2.8-5.23,7.7-7.65,2-1.27-3-1-5.72-1.82-8.82-2-7.49-2.87-17.1-6.28-24.09s-13.47-5.69-19.9-5c-3.27.35-6.28,2.14-9.35,2.57-5.08.73-10.24-.11-15.36.77-10,1.71-20.73,3.63-30.14,7.61-10.29,4.35-19,11.78-28.48,17.55-6.62,4-8.49,8.54-12.51,14.63-2.18,3.29-2.85,4.21-7.09,4.81a13.21,13.21,0,0,0-7.4,3,133.18,133.18,0,0,0-20,17.45A147.06,147.06,0,0,0,464.33,755c-2.47,4-4.95,7.94-7.57,11.93-2.18,3.31-7.21,7.6-8.2,11.21,4.48.44,9.38,4.8,13.63,6.63,4,1.74,8.69,4.48,13,5.08,2.75.39,5.59-.06,8.33.34C485,790.4,486.49,790.73,488,791.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M577.72,629.6q1.12-1.14,2.21-2.32c2.31-2.5,6.69-5.41,7.4-8.85a12.6,12.6,0,0,0-.2-4.62c-.49-2.9-4-13.59-1.07-15.25a6.65,6.65,0,0,1,2.48-.54c4.88-.6,8.84-4.32,11.51-8.45,7.67-11.89,6.78-30.25-1.48-41.48l-5.77-7.85a42.81,42.81,0,0,0-6.15-7.19,24.19,24.19,0,0,0-19.1-5.79c-5.24.6-10.62,1.84-15.71.44-6.12-1.68-10.55-6.81-15.62-10.61-11.44-8.57-26.51-10.51-40.81-10.52a6.36,6.36,0,0,1-3.58-.7,7.41,7.41,0,0,1-2-2.67,19.85,19.85,0,0,0-6.55-6.83,7,7,0,0,0-4.88-1.36,8.49,8.49,0,0,0-3.73,2.19c-2.45,2.07-5.11,4.3-6.63,7.19-1.34,2.55-.75,6.11-3.41,7.46-2.07,1.05-6.25,1-8.69,1.86q-6,2.11-11.86,4.63c-11.08,4.77-21.65,10.62-32.2,16.46-9.48,5.25-19.69,11.33-23.34,21.53-.76,2.13-2.21,3-3.16,5a22.16,22.16,0,0,0-23.17,2.28,10.31,10.31,0,0,0-4.1,5.86,10.86,10.86,0,0,0,1.44,6.8,28,28,0,0,0,16.12,13.78,4.73,4.73,0,0,1,2.38,1.28c1.42,1.8-.31,4.55-1,6.29a16.18,16.18,0,0,0-1.49,6.8v50.12c0,5.83.09,12,3.07,17,24.4.82,49.14-5.34,73.43-7.85,10.86-1.13,21.79-1.25,32.68-2,13.67-1,27.24-2.89,40.81-4.83,6.15-.88,12.4-1.86,18.23-4.11a93,93,0,0,0,25.29-15.26A110.36,110.36,0,0,0,577.72,629.6Z" transform="translate(-105.77 -43.5)"/><path class="cls-7" d="M551.14,648.24a67.44,67.44,0,0,1-9.66,4.38,66.76,66.76,0,0,1-13.13,2.49q-36.59,4.39-73.27,7.93c-22.21,2.14-43.57,6.23-65.86,7.06a40.19,40.19,0,0,0-15.61,3.34c-.16,3.1-.3,6.31.75,9.23s3.64,5.53,6.75,5.62a31.17,31.17,0,0,0,1.32,12.18,62.17,62.17,0,0,0,3.63,8.47c2.84,5.82,5.29,12.19,8.67,17.71,2.63,4.3,5.48,8.34,6.8,13.35,1.23,4.67,3.06,6.19,6.32,9.51,3.59,3.65,7.3,7.54,11,11.31,5.46,5.63,10.9,9.18,18,12.77,1.93,1,3.89,1.83,5.74,2.84,3.09,1.68,3.64,2.29,6.11-.71,3.95-4.81,7.13-10.25,11.23-14.92,3.41-3.88,6.75-7.86,9.78-12,4.73-6.42,9.78-12.61,14.9-18.73,4.32-5.16,10.41-8.76,15-13.52,2.82-2.94.35-3.06-.08-7.15-.74-7,2.48-24.26,12.5-18.55,3.65,2.08,4.47,6.22,7.77,7.92,1-2.83,4.22-5.08,6.75-6.63,4.12-2.52,7.95-5.48,12.35-7.42,6.86-3,13.52-6.36,20.46-9.1,7.16-2.83,14.43-6.14,22-7.72,8.37-1.74,16.44-1.92,25-2.34,6.53-.32,13.08-.12,19.43-1.12,0-1.92-3.18-4.81-4.48-6.45a70.75,70.75,0,0,0-5.79-6.52c-4.4-4.28-8.58-.64-12.84,2.51s-15.29,11-19.27,3.36c-4.43-8.46,2.81-15.4,10.76-15.85,4.41-.25,7.76.45,11.09,3.34,2.94,2.54,5,6.21,8.85,7.3,3.25-5.74-.65-13.37-5.28-16.92-5-3.86-11-3.82-15.33-8.71-1.53-1.75-3-6-5-7-2.57-1.27-4.3,2.26-6,4.44-4,5.2-7.54,10.85-13.37,14.23S557.26,645.07,551.14,648.24Z" transform="translate(-105.77 -43.5)"/><g class="cls-8"><path class="cls-7" d="M548.55,520.1a25.14,25.14,0,0,1,6.58-6.75,23.42,23.42,0,0,1,7.31-2.95,40.69,40.69,0,0,1,35.7,8.76c11.42,10,15.88,25.19,17.67,39.75.86,7,2.84,12.83,1.86,20a46.19,46.19,0,0,1-9.29,22.14,24.82,24.82,0,0,1-7.23,6.57c-4.26,2.37-9.29,2.79-14.15,3.17l-12.41,1c-3,.23-6.28.43-9-1-2.14-1.16-3.63-3.21-5-5.2C543.23,581.15,529,547.74,548.55,520.1Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-8"><path class="cls-7" d="M423.16,562.28a25.14,25.14,0,0,1,6.58-6.75c17.24-11.2,40.27-11.29,59.15-4.76,7.48,2.59,15,6.48,19.15,13.23,2.19,3.57,3.27,7.7,5.06,11.48,2.78,5.88,5.22,8.87,5.62,15.37.35,5.59,1.06,11.13,1.07,16.75,0,10.38-1.67,22-10.26,29-9.82,7.93-21.24,14.51-33.77,16-11.55,1.37-23.07-1.78-33.34-6.94-4.59-2.31-11.26-5.26-14.7-9.17-2.83-3.22-4.69-8.71-6.44-12.64C412.37,603.93,410,580.92,423.16,562.28Z" transform="translate(-105.77 -43.5)"/></g><path class="cls-9" d="M521.44,619.75a4.06,4.06,0,0,0,.1,2.17,3.59,3.59,0,0,0,1.47,1.52,10.39,10.39,0,0,0,11.8-.66c2.25-1.82,3.66-4.55,6-6.22,4.47-3.15,10.66-1.55,15.94-3a8.15,8.15,0,0,0,5.21-3.66c1.57-2.92.15-6.82-2.56-8.74s-6.3-2.16-9.56-1.52a7.14,7.14,0,0,0-2.58.94c-.5.33-.92.76-1.44,1.07a7.24,7.24,0,0,1-2.14.74,91,91,0,0,1-9.6,2.15c-1.8.21-4-.33-5.66.51C524.25,607.22,522.06,615.55,521.44,619.75Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M539.69,595.19a16.74,16.74,0,0,0-5.23,2.53,7.4,7.4,0,0,0-2.66,3.05,2.77,2.77,0,0,0-.21,1.58,3,3,0,0,0,1.52,1.83,8.09,8.09,0,0,0,4.66.9,34.56,34.56,0,0,0,4.74-.86,12.39,12.39,0,0,0,4.27-1.41,3.67,3.67,0,0,0,1.78-3.83,4.43,4.43,0,0,0-2.74-2.55,12.88,12.88,0,0,0-7.51-.78" transform="translate(-105.77 -43.5)"/><path class="cls-7" d="M538.59,620.55a4.57,4.57,0,0,0,.24,1.64c.34,1.06,2.86,5.74,4,6.17,3.37,1.25,12-3.91,12-7.67-.11-7-5.46-6-10.54-4.6C541.69,616.81,538.73,617.93,538.59,620.55Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M511.18,690.5c-9.54-4.09-12.13,7.26-11.68,14.67.27,4.56,1.43,7.6,6.67,7.33,4.82-.25,10.48-4.16,12.43-8.64S516.34,693.51,511.18,690.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-6" d="M601.84,640.83c-4.64-2.27-18.77,2-20.76,7.33-5.05,13.47,13.34,13.65,20.77,9.07C608.25,653.3,614.29,646.82,601.84,640.83Z" transform="translate(-105.77 -43.5)"/><polygon class="cls-10" points="261.69 395.02 182.17 404.84 135.41 383.03 140.61 281.16 130.54 229.75 142.41 232.33 236.08 222.66 247.41 240.66 251.49 239.66 264.08 210.62 310.13 222.66 306.47 236.45 312.74 236 302.08 275.33 302.33 355.11 274.9 357.33 280.37 390.09 254.85 381.34 261.69 395.02"/></g><g id="shadows"><g class="cls-3"><path d="M397.5,545.11c5-5.27,11.18-9.17,17.39-13.1A178.07,178.07,0,0,1,454,513.52c9.72-3.16,11.15,1.58,1.09,5.49-13.06,5.07-23.87,13.14-34.14,22.5-5,4.57-9.92,9.43-12.86,15.51-1.65,3.4-2.59,7.48-5.24,10.47-3.92,4.43-14.43-.32-16.81-4.62C382.68,556.72,393.35,549.5,397.5,545.11Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M382,562c-5.63,0-12.67-3.47-18-.5-4.91,2.72-4.43,8.73-2.47,13.29s24.31,23.4,28.12,14.83c3.14-7.07-16.95-5.47-16.56-12.54a19.12,19.12,0,0,1,7.37-1.17C378.68,571.07,368.68,567.89,382,562Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M384,591c7.86,3.69,6.66,5.87,5.47,14.64-1.21,9-1.08,18.17-1.47,27.24-.3,6.87-1.18,15,3.13,21,4.79,6.71,16.64,7.09,24.13,8.07,8,1,18.91-.5,26.2,3.17-3.93,3.94-14.31,4.92-19.68,6.17-4.66,1.08-15.51,2.6-18.16,7.19-7,12.16,24.8,5.86,29.86,6.61C430.25,689,423,689.26,419.59,694c-3.68,5.12-3.85,13.11-4.19,19.11-.23,4-1.78,10.13,1.1,13.51,3.7,4.34,9.49-.2,14.53.43-2.72,3.86-10.18,13.25-3.22,15.51,5.82,1.89,4.29-2.58,6.7,3.49,1.45,3.66,1.39,8.13,5.53,10.21,7.8,3.9,21.8-9.37,27.09-14.47,6.7-6.46,11.79-11.78,19.74-16.69-.87,11.91-14.7,18-9.25,31.79,2.53,6.4,8.75,6.78,14.38,8.92,8.59,3.25,15.42,8.84,25,9.72,13.5,1.24,33.1,1.14,42-10.27,2.18-2.8,3.23-5.43,4.67-8.7,1.78-4,3.92-5.88,6.72-9-1,5.36-8.77,20-1.41,23.71,13.74,6.92,12.34-18.61,19-20.89,1.43-.49,5.89.68,8,.15,3.36-.85,6.88-3.07,10-4.63,5.77-2.91,12-4.53,17.39-8,3.74-2.42,7.76-5.79,11.54-7.81.46,4.6-7.45,12.32-10.55,15.42-4.11,4.11-10.12,7.33-15,10.76s-9.45,7.28-14.4,10.37c-4.23,2.65-9.38,3.45-13.18,6.19s-7.22,7.6-11.81,9.46c-2.16.88-4.08.2-6.25.73-2.45.6-5,2.09-7.69,3-13.71,4.59-29,9.28-43.56,8.5-8-.42-15-2.41-22.5-4.38-8.37-2.18-16.81-1.56-25-5.12-3.7-1.61-6.83-4.38-10.5-5.89-4.3-1.76-7.44-.64-11.5-1.1-7.84-.9-15.56-9.4-22-13.38-5.16-3.2-7.15-4.55-9.89-10.14a35.34,35.34,0,0,0-6.62-9.37c-4-4.35-3.95-10.18-8-14.61a57.14,57.14,0,0,1-6.5-8.39c-2.83-4.55-4.85-10.14-7.38-14.9a40.53,40.53,0,0,1-4.22-19.15c-5.68-.11-6.63-13.83-2.5-13.65.6-5.41-.77-12.84-1.3-18.39-.71-7.47-.6-14.91-.62-22.45,0-13.08,2.26-27.58,5.5-40.09" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M426.51,572c1.41-7.49,16.39-15.55,23.46-15.42-3.75,6.73-9.32,11.19-11.58,19.07a45.42,45.42,0,0,0-1.77,18.11A40.07,40.07,0,0,0,441.13,608c2.54,4.31,6.43,5.21,9.94,8-3,3.14-4.63,3.31-2.09,7.76,2.93,5.14,8.72,6.95,14.14,8.37,10.51,2.77,28.08,4.58,34.86-6.49-16.19,15.3-36.68,25.36-58.07,12.58-12.57-7.51-19.57-13.86-23.88-28.61-1.87-6.42-3.34-12.12-.9-18.64C417.81,583.78,425.11,577.49,426.51,572Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M531,599c-3.57,4.47-7.85,6.24-9.5,12a57.08,57.08,0,0,0-2,12.5c-.29,5.67,1,8.58,7.25,8,5.91-.53,7-2.14,12.5,0,6.66,2.55,8.28-.52,12.58-5.54-4.84,1.41-5.52,1.57-8.1-2.32-1.2-1.81-1.57-7.2-4-7.68-3.17-.63-5.09,5-8.61,4.07C526.64,618.81,526.54,607.42,531,599Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M550.51,537c-4.84,2.19-3.83,18.15-3.61,22.88.17,3.51-.69,7.91.13,11.32,1,4,4.64,8.32,6.79,11.76,3.47,5.55,6.81,14.68,12.42,18.55,2.47,1.71,5.68,1.68,8.27,3,2,1,4,3.89,6.48,4,9.84.57,2.46-8.92,4.07-12.52-1.59-1.66-2.65-.1-4.69-1.08-2.83-1.35-4.65-3.69-6.49-6.16-2.19-2.94-10.08-12.09-8.81-15.26C556.24,566.71,556.23,550.37,550.51,537Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M541,653.5c-4.87,1.15-16.92,1.11-19,6.51,2.92,2.72,8.27,1.67,10,5,1.52,2.94-1.09,7.9-.94,10.93,1.35-.47,1.81,0,3-1.23-.18.23-.84,1.14-1,1.24,11.63-9.73,25.33-19.65,39.84-24.52a46.33,46.33,0,0,0,1.51-8.3c-2.32,3.22-7.76,10.68-12.17,10.41-4.11-.26-5.75-6-10.75-3.52" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M453,696.5c-2.61-11.13,16.36,1.09,19,2.51s8.67,6,12,5c2.82-.81,4-6.32,4.5-9.37.67,3.88,1.2,13.8,6,7.29,1.12,2,3.18,1.81,4.88.63,2.47,7.16,8.24,2.66,13.12,2.08,5.19-.62,4.57,2.06,1.09,5.5-3.27,3.22-7.93,5-11.6,7.86-4.18,3.22-9.4,11.64-15.46,10.93-.22-3,2.27-5.72,0-8.33s-8.35-1.45-11.26-1.64C465.86,718.33,452.75,711.41,453,696.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M522,674c-8-.49-16.6,3.35-24.53,4.11-6.43.62-13.74,1.36-20,3.52,2.5,2.54,8.24,1.53,11.48,1.48,1.54,0,3.76-.59,5.25-.13,3.06.95,2.36,2.71,4.44,4.23,3.43,2.5,6,0,10.7.89,3.2.61,6.72,2.68,10,3.34.81-5.63-1.54-4.06,2.59-8.94C524,680.17,527.32,675.21,522,674Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M587.51,635.5c-2.71,2.1-4,5.66-6.25,8.25-1.88,2.15-4.78,2.8-4.17,6.17,7-1.05,3.11,7.88,7.44,10.45,4.76,2.83,11.54-2.32,13.93-5.55-2.39,1.91-6.4,2.54-9.36,2.1-2.8-7.06-.07-13.59,6.91-15.68,2.73-.82,6.22.58,3.81-2.65-1.29-1.72-5.39,1.22-4.12-3.25.6-2.11,4.27-1.68,5.28-3.76C597.63,631,589.38,625.44,587.51,635.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M638,714.5c-.73-4.45,7.31-16.33,12.42-15.42C651.87,705,642.81,714,643.5,721c.88,9,10.68,2.07,14.41-1.45.53,7.84-12.88,16.15-19.61,17-1.17.14-3.7.38-4.79,0-3.38-1.19-2.44.34-2-3.33C632.39,725.34,636.61,717.18,638,714.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M149.44,520V478.5L278.51,461l9,79.5,33-75L427,514.83l-3.29,9.8-18.49,11.77c.57-.36-1.54-8.07-1.79-9a193.18,193.18,0,0,1-25.81,4.06c-26.8,2.53-54.93,12.18-78.25,26.11-13,7.79-25.92,20.72-34.38,33.37a62.39,62.39,0,0,0-6.54,11.79c-2.89,7.39-.68,11.48-.05,18.7.46,5.29-.47,11-.78,16.28l-2.2,37.91L252.51,726l-97-64.27,2-101.09L142,522.5l7,1.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M238.51,426.5C232,427,225.38,430,219,430.89c-3.94.57-12.23.11-15.32,2.54-3.36,2.64-1.89,12.95-2.18,17.08-.37,5.2-2.53,13.57-1.42,18.43,9.62-2.43,19.82-2.39,29.79-3.41,10.33-1.06,21.15-3,31.39-3.5,3.72-.18,12.9-2.25,15.62.46,2.25,2.24,1.78,8.66,2.11,11.55.8,6.93,1.46,13.84,2.47,20.71,1.2,8.15,2.61,16.1,4,24.25,1.06,6,.85,12.5,3.12,18.26,6.35-9.54,13-21.37,16.62-32.52,2.25-6.92,3.77-13.84,6.26-20.75,2-5.68,3.07-15,9.83-17,8-2.32,18.46,6.73,25.46,9.47A140.2,140.2,0,0,1,370.51,489c6.61,4.21,18.87,10.6,26.93,11a141,141,0,0,0,.09-21.89C396.9,471.33,392,470.72,387,466c-2.93-2.78-5.59-6-8.31-8.93s-3.23-5.8-4.75-9.29c-1.35-3.11-3.44-5.93-4.14-9.21-6.1-.5-12.51,2.61-18.74,2.9-6.91.32-13,1.68-19.78,3.06A249.22,249.22,0,0,1,294.35,449c-7.85.36-12.06-3.22-18.83-7-5.83-3.28-11.78-5.78-17.87-8.5C251.93,431,245.54,425.89,238.51,426.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><polygon points="137.08 381.75 138.66 278.19 130.54 228.5 143.74 231.78 236.73 222.66 245.81 240.49 194.74 245.5 179 285.98 182.46 404.33 137.08 381.75"/></g><g class="cls-3"><polyline points="208.66 222.66 208.68 118.5 154.77 56.5 275.74 87 330.85 154.64 330.74 352.89 302.33 355.11 302.24 272.5 313.05 235.7 306.24 236.47 310.13 224.59 262.74 208.7 251.69 240.49 245.81 240.49 236.73 222.66 208.68 225.41"/></g><g class="cls-3"><path d="M357.26,283.5c2.08-1.83,1.64-6,4.49-7.27,1.34-.57,4.9-.4,6.45-.55,3.69-.35,7.36-.09,11-.58,11.07-1.49,22.26-.56,33-.3a22.58,22.58,0,0,0-1.33,5.22c-9.5-.26-19,2.65-28.28,4.23-5.37.91-10.91,1.35-16.31,2C364.25,286.52,360.31,287.34,357.26,283.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M301,290.75c5.31-2.94,15.62-2.08,21.84-2.25,4.48-.12,9.5-1,13.88-.46-.6,1.65-2.53,3.08-3.47,4.71-1.53,2.65-3,5.16-4.72,7.74a119.15,119.15,0,0,0-8.1,13.25c-.72,1.47-1.54,3.09-.48,4.26,1.93,2.12,9.39,2,12,2.25,10.58,1.17,22,1.52,32.51,0,4.11-.59,8.19-.46,12.31-.81,3.62-.31,7.26-1.66,10.91-1.45-5.2-.24-12.24,2.24-17.18,3.76-6.67,2.05-13.53,3.4-20.15,5.55-12.44,4-25.07,7.38-37.65,10.9-9.71,2.72-16.76,8.44-20.84,17.72a69.12,69.12,0,0,0-5.36,18.3c-.29-4.92-1-9.78-1-14.72,0-4.35.48-9-.13-13.27-.9-6.39-1.86-13.37.57-19.54C290.84,314.24,293.23,301.07,301,290.75Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M380.84,407.17c-1.77,5.07-3,10-6.17,14.5-.91,1.32-2.1,3.7-3.37,4.64s-2.7.82-3.84,1.51c2.48,3.34,13.65,5,17.67,5.3,0-3.72-1.84-7.9-2.46-11.65C382.12,418.17,383,412.71,380.84,407.17Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M397.91,409.93a180.76,180.76,0,0,1,18,11.59c5.38,3.79,11.2,6.89,16.6,10.66,4.38,3.06,7.88,6.76,13.23,8a139.68,139.68,0,0,1,14.18,4.34c3.94,1.35,8.21,1.38,12.24,2.32,5.63,1.31,11.3,1.65,16.92,2.92,5.05,1.14,12.39,6.53,17.75,5.08,4.42-1.19,6.07-11.94,8.39-15.6,4.34-6.84,8-13.64,9.68-21.74.88-4.22,1.25-8.22,3.34-12.07,2-3.66,5.26-15.42,9.31-8s3.58,14.83,10.13,21a70.59,70.59,0,0,1,9.66,10.69c3,4.1,7.16,9.47,11.21,12.49,4.2,3.14,10.07,3.95,14.64,6.63,3.68,2.16,7.61,3.82,11.31,6a60.37,60.37,0,0,0,18.37,7.09c12.47,2.52,25.74-2.17,37.9-4-.55,2.26-3.1,4-4.44,6-1.06,1.58-1.43,3.29-2.78,4.64-1.74,1.73-1.53,1.43-4.29,1.68-5.33.48-10.51,1.73-15.8,2.33-13.56,1.53-27.06,3.54-40.6,5.25-6.48.82-13,1.48-19.45,2.18-4.19.45-7.6,2.14-11.62,3.26-2.92.81-5.81.72-8.65,1.32-4.63,1-5.85,6.3-8,10.27-2.56,4.67-4.6,9.71-7.45,14.24s-6.54,1-10.65-.1c-6.11-1.59-13.92-1.39-20.22-1.07-2.53.13-4.53.13-5.91-1.69-1.81-2.39-1.4-4.13-4.1-6-5.81-4-12.71-.16-16.07,5.25-1.53,2.47-2.14,6.12-4.26,7.85-3.86,3.16-12.35,4-17.09,5.33-5.67,1.61-11,2.55-16.51,4.82a63.19,63.19,0,0,1-9.37,3c1.67-2.65,3.33-6.34,2.92-9.57-2.71-.41-4.59-3.14-6.62-4.8-2.82-2.31-6.19-3.9-9.31-5.58-6.3-3.39-14.42-.82-15-9.87-.39-5.76,2.56-12.55.66-18.13s-7.08-10.94-10.34-16c-3.81-5.89-8.77-11.11-12.49-17-2.23-3.55-3.8-7-6.53-10.32-2.24-2.74-5.24-5.44-6.2-9,5.23-.55,12.68,4.75,17.59,6.64,3.15,1.21,7.1,3.56,10.53,3.34a83.1,83.1,0,0,1-7.71-20.4,37.54,37.54,0,0,1-.85-9.78c.16-3.59,3.17-6.26,6.93-4.33,1.7.87,2.56,3.33,4.13,4.72A35.08,35.08,0,0,0,397.91,409.93Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M498.84,341.5c-1.85,2.24-2.51,5.38-3.74,8-1.85,4-4.24,7.62-5.94,11.67-2.29,5.46-4.64,10.71-7.11,16s-4.92,10.64-7.84,15.56c9,1.25,19.34-6.2,28.13-2.94,5.28,2,3.3,10.27,3.57,14.54.38,6.06,1.32,12.13,1.59,18.21.21,4.91,1,9.78,1.35,14.67s.27,10.82,1.91,15.26c1.49-11,7.73-20.76,12.08-30.66,3.34-7.59,7.26-15.17,11.32-22.34,3.58-6.33,10.87-2.74,16.41-.57,10.71,4.18,21.14,8.74,32.28,11.34a116.68,116.68,0,0,1,11.65,3.9c7,2.42,14,5.37,20.69,8.34,8.65,3.83,18.84,9.26,28.28,9.28-2.75-4.55-1.46-10.57-2-15.74s-1-10.33-1-15.55c0-3.66.2-4.46-3-5.89-6.12-2.74-13.07-3.65-19.15-6.43-13.72-6.28-27.27-13-41.12-18.93-8.26-3.52-17.18-5.41-25.28-9.06-7-3.14-14.15-4-21.15-6.69-4.64-1.78-8.43-6-13.31-6.93-2-.39-4.17.41-6.07-.28-2.49-.91-4-3.38-6.92-3.78" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M433.43,154.58c-6.07,1.08-12.36.51-18.52.58-3.35,0-9-.6-12,.73,1.38-.62,6.78,8.19,7.55,9.6,2.42,4.42,6.84,6.94,10,10.75,3,3.58,5.09,7.55,7.57,11.43,2.9,4.53,6.57,10.87,11.43,13.47,4.53-10.25,13.06-19.2,19.41-28.39,2.56-3.71,4-7.7,6.66-11.3s6.15-7.6,7-12.23c-3.25-.48-6,1.2-9.06,1.54-2.73.3-5.54,0-8.32.34C447.82,152,440.62,153.31,433.43,154.58Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M472.51,143.5c2.59-2.07,2.86-7.34,3.66-10.48,1-4.06,2.45-8.06,3.5-12.15a92.72,92.72,0,0,0,2.84-19c.54-11.33,3.49-22.76,6.25-33.74,1.25-5,1.45-10.37,2.79-15.19a27.26,27.26,0,0,1,9.75.44c5.54,1.34,10.83,2.11,16.38,3.33,11.54,2.52,23,4.73,34.35,7.91,9.32,2.6,18.55,5.52,28,7.86,9.07,2.26,18.78,3.33,27.66,6.23a35.11,35.11,0,0,1,9.52,4.59c.81.58,3.62,2,3.93,2.66,1.11,2.55-4,8.71-5.42,11-3.23,5.28-6.39,10.37-9.84,15.49-2.1,3.12-3.41,7-5.73,9.89s-4.23,2.61-7.68,3.16c-4,.63-7.45,2.4-11.34,3.44-4.83,1.29-10,1.63-15,2.31-10.49,1.44-21,2.34-31.52,3.85-8.37,1.2-16.91-.11-25.32.85-6.48.73-12.91,2-19.41,2.68C484.44,139.1,477.72,138.2,472.51,143.5Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M476.51,142.17c-.26,2.37-2.93,5.46-4.82,7.49-3.76,4.05-5.93,8-8.85,12.65-5.36,8.61-11.9,16.14-16.32,25.32a95,95,0,0,1-7,12.15c-1.54,2.29-1.7,3.79-2,6.8-.91,9.54.39,18.75,1,28.22.52,8,1.31,16,1.33,24,0,8.83-2.32,17.54-2.33,26.3.38-12.56,5.41-26.66,10.59-37.93,4.26-9.26,8.41-17.29,15.17-25,3.35-3.82,7.22-6.77,11.1-10,5.25-4.35,10.9-8.67,17.52-11,6.4-2.2,13.1-3,19.48-5.2,15-5.09,30.4-11,46.42-11.86-6.77.32-13.86-.56-20.63-.93-10.38-.56-20.83.27-31.22.27-3.42,0-12.51,2.09-10.53-2.58,1-2.39,5.17-5.25,7.15-6.83,12-9.58,24.27-18.84,37.91-26,8.8-4.64,18.27-8.1,27.56-11.57,7.69-2.87,15.67-6.69,24-7.32-5.87-.3-11.73,1.6-17.48,2.52a201.78,201.78,0,0,1-21.49,2.13c-9.89.48-19.93.34-29.81,0-14.37-.48-28.51,3.68-42.73,3.68" transform="translate(-105.77 -43.5)"/></g><g class="cls-3"><path d="M401.84,536.83c-11,0-18.59,4.06-27.85,9.48-6.91,4-17.08,9-21.31,16-6.15,10.22-3.41,26-1.5,37.2,2.22,13-3.3,22.81-4.68,35.32-1,8.85-.12,18.69.68,27.45,1.25,13.73-3.83,33.5,2.05,46.16,2.56,5.5,10.14,6.08,14.65,10.37,3.14,3,7.47,6.92,9.33,11,2.15,4.72,1.93,10.11,5.35,14.67,4.08,5.44,10.34,9.23,15.3,13.69,3.81,3.42,6.72,7.37,11.49,9.52,7.94,3.57,17.77,4.79,26.39,4.37-.38-4.86-13.29-10.74-17.08-14.57-6.59-6.66-12-17.42-16.65-25.63-5.39-9.57-15-21.1-16.75-32.06-.25-1.6,0-7.54-.88-8.84-1.44-2.15-4.58-.58-6.38-3.62-2.52-4.25-.48-16.51,4.4-18-2-21.66-1.22-43.66-1.22-65.61,0-4.4.8-9.45-1.17-13.11-2.12-3.93-7.74-6.1-10.72-9.19-6.12-6.34-9.28-21.65,2.28-24.59,5.56-1.41,10.68,4.26,14.91,2.32,3.16-1.45,5-8.12,6.83-10.73a64.56,64.56,0,0,1,8.53-9" transform="translate(-105.77 -43.5)"/></g></g><g id="DETAILS"><path class="cls-11" d="M652,604.19a1.5,1.5,0,0,1-.3-3l27.16-5.51a1.5,1.5,0,0,1,.6,2.94l-27.15,5.51A1.5,1.5,0,0,1,652,604.19Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M656.45,629.7a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,1.37-1.62,1.52,1.52,0,0,1,1.62,1.37c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M656.44,629.7a1.5,1.5,0,0,1-.27-3c9.22-1.72,19.79-3.64,28.25-4.79a1.5,1.5,0,0,1,.41,3c-8.4,1.15-18.92,3.05-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M684.63,624.91a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.81-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,0,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.37,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M683.75,598.95a1.5,1.5,0,0,1-.3-3l27.16-5.51a1.5,1.5,0,1,1,.6,2.94l-27.15,5.51A1.5,1.5,0,0,1,683.75,598.95Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M688.15,624.45a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,1.37-1.62,1.52,1.52,0,0,1,1.62,1.37c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M688.15,624.45a1.5,1.5,0,0,1-.27-3c9.21-1.72,19.77-3.64,28.25-4.79a1.5,1.5,0,0,1,.41,3c-8.42,1.15-18.93,3.06-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M716.33,619.67a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.81-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,1,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.37,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M715.47,593.5a1.5,1.5,0,0,1-.3-3L742.33,585a1.5,1.5,0,0,1,.6,2.94l-27.16,5.51A1.49,1.49,0,0,1,715.47,593.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M719.87,619a1.5,1.5,0,0,1-1.43-1c-2.88-8.79-3.75-17.24-4.47-25.85a1.5,1.5,0,0,1,3-.25c.7,8.42,1.55,16.68,4.33,25.16a1.5,1.5,0,0,1-1.43,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M719.87,619a1.5,1.5,0,0,1-.27-3c9.21-1.72,19.76-3.64,28.25-4.79a1.5,1.5,0,1,1,.4,3c-8.43,1.15-18.94,3.06-28.11,4.77Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M748.05,614.22a1.5,1.5,0,0,1-1.41-1c-1.87-5.22-2.82-11.14-3.73-16.87-.54-3.4-1.06-6.61-1.74-9.53a1.5,1.5,0,0,1,2.92-.68c.7,3,1.23,6.29,1.78,9.74.89,5.59,1.82,11.38,3.59,16.33a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M666.66,622.38a1.5,1.5,0,0,1-1.47-1.21,120.78,120.78,0,0,1-1.74-12,1.5,1.5,0,1,1,3-.28,118,118,0,0,0,1.7,11.69,1.5,1.5,0,0,1-1.47,1.79Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M662.34,609.44a.26.26,0,0,0,0,.15c0,.15.25.12.39.05a12.33,12.33,0,0,1,4.83-1.24,11.24,11.24,0,0,1-1.68-2c-.28-.39-1.12-1.92-1.64-1.94s-.76,1.76-.89,2.22A19.33,19.33,0,0,1,662.34,609.44Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M671.86,621.56a1.5,1.5,0,0,1-1.47-1.21,120.75,120.75,0,0,1-1.74-12,1.5,1.5,0,1,1,3-.28,117.9,117.9,0,0,0,1.7,11.69,1.5,1.5,0,0,1-1.18,1.76Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M667.54,608.61a.26.26,0,0,0,0,.15c0,.15.25.12.39.05a12.33,12.33,0,0,1,4.83-1.24,11.24,11.24,0,0,1-1.68-2c-.28-.39-1.12-1.92-1.64-1.94s-.76,1.76-.89,2.22A19.33,19.33,0,0,1,667.54,608.61Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M702.49,619a2.52,2.52,0,0,1-.46,0,3.11,3.11,0,0,1-2.3-2.24,14.26,14.26,0,0,1-.48-1.74l-1.45-6.37a1.5,1.5,0,1,1,2.93-.67l1.45,6.37a12.26,12.26,0,0,0,.35,1.31,5.84,5.84,0,0,0,.14-.61,1.5,1.5,0,0,1,2.95.56,5.49,5.49,0,0,1-.71,2A2.91,2.91,0,0,1,702.49,619Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M693.91,610.54a2.17,2.17,0,0,1-1.89-.87c-.61-.85-.49-2,.34-3.36a8.16,8.16,0,0,1,4.83-3.94,11.49,11.49,0,0,1,4.48-.26,6.73,6.73,0,0,1,3.94,1.92,4.41,4.41,0,0,1,1.9,3.2,1.5,1.5,0,0,1-1.23,1.49c-2.55.46-5.14.88-7.71,1.25-.48.07-1,.12-1.47.17a21.5,21.5,0,0,0-2.27.32A4.39,4.39,0,0,1,693.91,610.54ZM700,605a7.29,7.29,0,0,0-2,.25,4.76,4.76,0,0,0-2.72,2.06c.51-.07,1-.12,1.51-.18s.91-.09,1.36-.16c1.77-.25,3.56-.53,5.33-.83a3.56,3.56,0,0,0-2.16-1.06A11.39,11.39,0,0,0,700,605Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M698.86,604.5a1.5,1.5,0,0,1-1.45-1.11l-.44-1.6a1.5,1.5,0,1,1,2.89-.79l.44,1.6a1.5,1.5,0,0,1-1.45,1.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M729.58,605.81a6.59,6.59,0,0,1-2.87-.71,4,4,0,0,1-1.54-1.23,4.38,4.38,0,0,1-.67-2l-1.1-7.41a1.5,1.5,0,1,1,3-.44l1.1,7.41a2.64,2.64,0,0,0,.16.7,1.16,1.16,0,0,0,.41.26,3.42,3.42,0,0,0,1.76.39,1.67,1.67,0,0,0,1.19-.6c.52-.71.27-2,0-3.21l-1.22-5.27a1.5,1.5,0,1,1,2.92-.68l1.22,5.27c.31,1.32.88,3.77-.5,5.66a4.62,4.62,0,0,1-3.34,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M724.92,595.53a1.5,1.5,0,0,1-.49-2.92,8.6,8.6,0,0,1,2-.38l4.62-.46a1.5,1.5,0,0,1,.3,3l-4.62.46a6.16,6.16,0,0,0-1.34.23A1.5,1.5,0,0,1,724.92,595.53Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M730.91,613.71a1.5,1.5,0,0,1-1.46-1.19c-.54-2.52-1-5.09-1.25-7.65a1.5,1.5,0,1,1,3-.34c.28,2.46.68,4.93,1.2,7.36a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M728.12,615a1.5,1.5,0,0,1-.52-2.91,9.5,9.5,0,0,1,2.54-.46l.75-.07A9.73,9.73,0,0,0,733,611a1.5,1.5,0,1,1,1,2.82,12.73,12.73,0,0,1-2.81.67l-.85.08a7.07,7.07,0,0,0-1.76.29A1.49,1.49,0,0,1,728.12,615Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M500.65,218.38a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3l-27.59,2.52Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M502.24,244.21a1.5,1.5,0,0,1-1.47-1.19c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M502.24,244.21a1.5,1.5,0,0,1-.11-3c9.34-.71,20.05-1.46,28.61-1.69h0a1.5,1.5,0,0,1,0,3c-8.49.22-19.15,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M530.77,242.53a1.5,1.5,0,0,1-1.46-1.15C528,236,527.73,230,527.44,224.2c-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M532.74,216.62a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3l-27.59,2.52Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M534.33,242.45a1.5,1.5,0,0,1-1.47-1.19c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M534.33,242.45a1.5,1.5,0,0,1-.11-3c9.34-.71,20.05-1.46,28.61-1.69a1.5,1.5,0,0,1,.08,3c-8.49.22-19.15,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M562.86,240.77a1.5,1.5,0,0,1-1.46-1.15c-1.29-5.39-1.58-11.38-1.87-17.17-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M564.86,214.67a1.5,1.5,0,0,1-.13-3l27.59-2.52a1.5,1.5,0,1,1,.27,3L565,214.66Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M566.45,240.5A1.5,1.5,0,0,1,565,239.3c-1.9-9.06-1.85-17.55-1.62-26.18a1.5,1.5,0,1,1,3,.08c-.23,8.44-.28,16.74,1.56,25.48a1.5,1.5,0,0,1-1.47,1.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M566.45,240.5a1.5,1.5,0,0,1-.11-3c9.33-.71,20-1.46,28.61-1.69a1.5,1.5,0,0,1,.08,3c-8.51.22-19.16,1-28.46,1.68Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M595,238.81a1.5,1.5,0,0,1-1.46-1.15c-1.29-5.39-1.58-11.38-1.87-17.18-.17-3.44-.33-6.68-.69-9.66a1.5,1.5,0,0,1,3-.36c.37,3.08.53,6.38.71,9.87.28,5.66.57,11.51,1.79,16.63a1.5,1.5,0,0,1-1.46,1.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M513.19,238.06a1.5,1.5,0,0,1-1.49-1.37,120.8,120.8,0,0,1-.42-12.11,1.52,1.52,0,0,1,1.52-1.48,1.5,1.5,0,0,1,1.48,1.52,118,118,0,0,0,.41,11.81,1.5,1.5,0,0,1-1.37,1.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M510.14,224.71a.26.26,0,0,0,0,.15c0,.15.24.14.38.09a12.33,12.33,0,0,1,4.93-.71,11.24,11.24,0,0,1-1.46-2.14c-.24-.42-.91-2-1.42-2.11s-.95,1.66-1.12,2.11A19.33,19.33,0,0,1,510.14,224.71Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M518.45,237.8a1.5,1.5,0,0,1-1.49-1.37,120.79,120.79,0,0,1-.42-12.11,1.5,1.5,0,0,1,1.5-1.48h0a1.5,1.5,0,0,1,1.48,1.52,118,118,0,0,0,.41,11.81,1.5,1.5,0,0,1-1.37,1.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M515.4,224.46a.26.26,0,0,0,0,.15c0,.15.24.14.38.09a12.33,12.33,0,0,1,4.93-.71,11.24,11.24,0,0,1-1.46-2.14c-.24-.42-.91-2-1.42-2.11s-.95,1.66-1.12,2.11A19.33,19.33,0,0,1,515.4,224.46Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M549.29,238.63a2.53,2.53,0,0,1-.73-.11,3.11,3.11,0,0,1-2-2.48,14,14,0,0,1-.28-1.78l-.75-6.5a1.5,1.5,0,1,1,3-.34l.74,6.49a12.42,12.42,0,0,0,.2,1.34,5.71,5.71,0,0,0,.21-.59,1.5,1.5,0,1,1,2.87.88,5.48,5.48,0,0,1-.93,2A3,3,0,0,1,549.29,238.63Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M541.83,229.26a2.3,2.3,0,0,1-2.2-1.1c-.51-.91-.27-2,.7-3.3a8.16,8.16,0,0,1,5.24-3.39,11.43,11.43,0,0,1,4.48.23,6.71,6.71,0,0,1,3.71,2.33,4.4,4.4,0,0,1,1.54,3.39,1.5,1.5,0,0,1-1.39,1.34c-2.58.18-5.21.32-7.8.4-.49,0-1,0-1.48,0a22.18,22.18,0,0,0-2.28.07Zm12-2h0Zm-6.65-2.92a6.64,6.64,0,0,0-1.09.09,4.76,4.76,0,0,0-2.93,1.75c.51,0,1,0,1.51,0s.92,0,1.37,0c1.79-.06,3.59-.14,5.39-.24a3.56,3.56,0,0,0-2-1.29A10,10,0,0,0,547.15,224.35Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M547.14,223.79a1.5,1.5,0,0,1-1.48-1.27l-.26-1.64a1.5,1.5,0,1,1,3-.47l.26,1.64a1.5,1.5,0,0,1-1.25,1.72Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M578,228.46h-.11a6.37,6.37,0,0,1-3.25-1,4,4,0,0,1-1.4-1.39,4.39,4.39,0,0,1-.46-2l-.29-7.49a1.5,1.5,0,0,1,3-.12l.29,7.49a2.64,2.64,0,0,0,.08.71,1.17,1.17,0,0,0,.38.3,3.4,3.4,0,0,0,1.7.58,1.69,1.69,0,0,0,1.25-.46c.6-.65.49-2,.35-3.19l-.64-5.37a1.5,1.5,0,0,1,3-.35l.64,5.37c.16,1.34.46,3.85-1.12,5.57A4.6,4.6,0,0,1,578,228.46Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M574,217.71a1.5,1.5,0,0,1-.33-3,8.77,8.77,0,0,1,2.05-.15l4.65,0a1.5,1.5,0,0,1,0,3h0l-4.64,0a6.15,6.15,0,0,0-1.35.08A1.53,1.53,0,0,1,574,217.71Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M578,236.44a1.5,1.5,0,0,1-1.49-1.35c-.26-2.55-.4-5.16-.41-7.74a1.5,1.5,0,0,1,1.49-1.51h0a1.5,1.5,0,0,1,1.5,1.49c0,2.48.14,5,.39,7.45a1.5,1.5,0,0,1-1.34,1.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M575.09,237.37a1.5,1.5,0,0,1-.36-3,9.55,9.55,0,0,1,2.58-.18h.75a9.75,9.75,0,0,0,2.19-.27,1.5,1.5,0,1,1,.71,2.92,12.81,12.81,0,0,1-2.87.36h-.85a7.06,7.06,0,0,0-1.79.1A1.52,1.52,0,0,1,575.09,237.37Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M266.5,686.83a1.5,1.5,0,0,1-.31-3l27.11-5.73a1.5,1.5,0,1,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,266.5,686.83Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M271.1,712.29a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.21-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.13a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,271.1,712.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M271.1,712.29a1.5,1.5,0,0,1-.29-3c9.18-1.79,19.71-3.79,28.21-5a1.5,1.5,0,0,1,.43,3c-8.43,1.22-18.92,3.21-28.07,5A1.46,1.46,0,0,1,271.1,712.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M299.24,707.28a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.84-.57-3.39-1.11-6.6-1.81-9.51a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.27,1.86,9.72.94,5.59,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M298.16,681.32a1.5,1.5,0,0,1-.31-3L325,672.62a1.5,1.5,0,0,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,298.16,681.32Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M302.77,706.79a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.22-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.13a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,302.77,706.79Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M302.77,706.79a1.5,1.5,0,0,1-.29-3c9.2-1.8,19.75-3.8,28.21-5a1.5,1.5,0,1,1,.43,3c-8.4,1.21-18.9,3.21-28.07,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M330.91,701.78a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.84-.57-3.39-1.11-6.6-1.81-9.51a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.27,1.86,9.72.94,5.58,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M329.83,675.62a1.5,1.5,0,0,1-.31-3l27.11-5.73a1.5,1.5,0,1,1,.62,2.94l-27.11,5.73A1.55,1.55,0,0,1,329.83,675.62Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M334.44,701.08a1.5,1.5,0,0,1-1.42-1c-3-8.77-3.9-17.21-4.68-25.81a1.5,1.5,0,1,1,3-.27c.76,8.41,1.68,16.66,4.53,25.12a1.5,1.5,0,0,1-.94,1.9A1.52,1.52,0,0,1,334.44,701.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M334.44,701.08a1.5,1.5,0,0,1-.29-3c9.19-1.79,19.74-3.8,28.21-5a1.5,1.5,0,0,1,.43,3c-8.41,1.22-18.91,3.21-28.07,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M362.58,696.07a1.5,1.5,0,0,1-1.41-1c-1.91-5.2-2.91-11.12-3.87-16.83-.57-3.39-1.11-6.6-1.82-9.52a1.5,1.5,0,0,1,2.92-.71c.73,3,1.28,6.28,1.86,9.72.94,5.58,1.91,11.36,3.73,16.3a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M281.26,704.9a1.5,1.5,0,0,1-1.47-1.2c-.81-3.95-1.43-8-1.84-12a1.5,1.5,0,1,1,3-.3c.4,3.9,1,7.83,1.79,11.68a1.5,1.5,0,0,1-1.17,1.77A1.54,1.54,0,0,1,281.26,704.9Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M276.84,692a.26.26,0,0,0,0,.15c0,.15.25.12.39,0a12.33,12.33,0,0,1,4.82-1.28,11.24,11.24,0,0,1-1.7-2c-.29-.39-1.14-1.92-1.66-1.93s-.75,1.76-.87,2.23A19.33,19.33,0,0,1,276.84,692Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M286.45,704a1.5,1.5,0,0,1-1.47-1.2,120.91,120.91,0,0,1-1.84-12,1.5,1.5,0,1,1,3-.3,118,118,0,0,0,1.79,11.68,1.5,1.5,0,0,1-1.17,1.77A1.53,1.53,0,0,1,286.45,704Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M282,691.12a.26.26,0,0,0,0,.15c0,.15.25.12.39,0a12.33,12.33,0,0,1,4.82-1.28,11.24,11.24,0,0,1-1.7-2c-.29-.39-1.14-1.92-1.66-1.93s-.75,1.76-.87,2.23A19.33,19.33,0,0,1,282,691.12Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M317.05,701.25a2.49,2.49,0,0,1-.44,0,3.11,3.11,0,0,1-2.32-2.23,14.09,14.09,0,0,1-.49-1.73l-1.5-6.36a1.5,1.5,0,0,1,2.92-.69l1.5,6.36a12.44,12.44,0,0,0,.36,1.31,5.79,5.79,0,0,0,.13-.61,1.5,1.5,0,1,1,3,.54,5.42,5.42,0,0,1-.7,2.05A2.91,2.91,0,0,1,317.05,701.25Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M308.39,692.83a2.17,2.17,0,0,1-1.87-.86c-.61-.84-.51-2,.31-3.36a8.15,8.15,0,0,1,4.8-4,11.42,11.42,0,0,1,4.48-.3,6.72,6.72,0,0,1,4,1.88,4.4,4.4,0,0,1,1.93,3.18,1.5,1.5,0,0,1-1.22,1.49c-2.56.49-5.15.93-7.7,1.31-.48.07-1,.13-1.46.18a21.61,21.61,0,0,0-2.27.33A4.39,4.39,0,0,1,308.39,692.83Zm6.15-5.59a7.42,7.42,0,0,0-2.07.27,4.76,4.76,0,0,0-2.71,2.08c.51-.08,1-.13,1.51-.19s.91-.1,1.36-.17c1.76-.26,3.54-.56,5.32-.87a3.57,3.57,0,0,0-2.17-1A11.49,11.49,0,0,0,314.55,687.24Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M313.31,686.76a1.5,1.5,0,0,1-1.44-1.09l-.45-1.6a1.5,1.5,0,1,1,2.89-.81l.45,1.6a1.5,1.5,0,0,1-1.44,1.91Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M344,687.81a6.59,6.59,0,0,1-2.83-.68,3.93,3.93,0,0,1-1.55-1.22,4.38,4.38,0,0,1-.69-2l-1.16-7.4a1.5,1.5,0,0,1,3-.47l1.16,7.4a2.62,2.62,0,0,0,.17.69,1.14,1.14,0,0,0,.41.26,3.37,3.37,0,0,0,1.76.38,1.67,1.67,0,0,0,1.18-.61c.52-.72.26-2,0-3.21l-1.27-5.26A1.5,1.5,0,0,1,347,675l1.27,5.26c.32,1.32.91,3.77-.46,5.66a4.62,4.62,0,0,1-3.33,1.84Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M339.3,677.57a1.5,1.5,0,0,1-.5-2.91,8.62,8.62,0,0,1,2-.39l4.62-.5a1.5,1.5,0,1,1,.32,3l-4.62.5a6.21,6.21,0,0,0-1.34.24A1.49,1.49,0,0,1,339.3,677.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M345.44,695.71a1.5,1.5,0,0,1-1.46-1.17c-.56-2.51-1-5.08-1.31-7.64a1.5,1.5,0,1,1,3-.36c.3,2.46.73,4.93,1.26,7.35a1.5,1.5,0,0,1-1.47,1.83Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M342.65,697a1.5,1.5,0,0,1-.53-2.9,9.58,9.58,0,0,1,2.54-.48l.74-.08a9.78,9.78,0,0,0,2.15-.53,1.5,1.5,0,0,1,1,2.81,12.85,12.85,0,0,1-2.81.69l-.84.09a7.08,7.08,0,0,0-1.77.31A1.5,1.5,0,0,1,342.65,697Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M698.06,387.11a3.52,3.52,0,0,1-1.07-.17c-19.51-6.22-39-13.58-57.77-20.69-27.37-10.35-55.66-21.06-84.39-28.32a3.53,3.53,0,1,1,1.73-6.84c29.12,7.36,57.61,18.14,85.16,28.56,18.72,7.08,38.09,14.41,57.42,20.57a3.53,3.53,0,0,1-1.07,6.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M233.85,453.13a3.53,3.53,0,0,1-.9-6.94c12.29-3.27,24.88-6.06,37.4-8.29a3.53,3.53,0,0,1,1.24,6.95c-12.33,2.19-24.72,4.94-36.82,8.16A3.55,3.55,0,0,1,233.85,453.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M557.18,676.67a1.5,1.5,0,0,1-1.35-.85,43.4,43.4,0,0,1-1.72-4.29c-1-2.89-1.94-5.39-4.29-7.6a1.5,1.5,0,1,1,2.05-2.19c2.88,2.7,4,5.79,5.06,8.78a41,41,0,0,0,1.6,4,1.5,1.5,0,0,1-1.35,2.15Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M564.18,672.33a1.5,1.5,0,0,1-1.22-.62,9.23,9.23,0,0,1-1.36-4.23,12.75,12.75,0,0,0-.42-2.11,8.8,8.8,0,0,0-1.28-2.19,8.19,8.19,0,0,1-1.89-4.25,1.5,1.5,0,0,1,3-.18,5.7,5.7,0,0,0,1.34,2.7,11.35,11.35,0,0,1,1.68,3,15.14,15.14,0,0,1,.54,2.62,6.87,6.87,0,0,0,.83,2.91,1.5,1.5,0,0,1-1.22,2.38Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M411.84,735.33a1.5,1.5,0,0,1-.95-2.66c4.89-4,15-6.91,21.52-7.33a1.5,1.5,0,1,1,.19,3c-6.1.39-15.52,3.16-19.81,6.67A1.49,1.49,0,0,1,411.84,735.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M425.84,743a1.5,1.5,0,0,1-.73-2.81c.79-.43,1.54-.93,2.35-1.46a21.68,21.68,0,0,1,4.89-2.64,1.5,1.5,0,0,1,1,2.84,19.12,19.12,0,0,0-4.21,2.31c-.81.54-1.66,1.09-2.55,1.58A1.49,1.49,0,0,1,425.84,743Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,698.67h-.07a1.5,1.5,0,0,1-1.43-1.57c.16-3.24,3.28-9.69,5.4-12a1.5,1.5,0,1,1,2.19,2.05c-1.71,1.82-4.47,7.53-4.6,10A1.5,1.5,0,0,1,492.18,698.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,708.33a1.5,1.5,0,0,1-1.37-2.12,14.94,14.94,0,0,0,1.2-4.79,1.5,1.5,0,0,1,3,.14,17.83,17.83,0,0,1-1.46,5.88A1.5,1.5,0,0,1,492.18,708.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M488.84,783.33a1.5,1.5,0,0,1-.57-.11c-.86-.35-1.75-.69-2.57-1a1.5,1.5,0,1,1,1-2.84c.89.3,1.84.66,2.76,1a1.5,1.5,0,0,1-.57,2.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M492.18,776.67H492a9.22,9.22,0,0,1-3.59-1.2,1.5,1.5,0,1,1,1.51-2.59,6.19,6.19,0,0,0,2.41.8,1.5,1.5,0,0,1-.17,3Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M498.45,782.38a6.56,6.56,0,0,1-2.51-.49,1.5,1.5,0,0,1,1.14-2.78,3.67,3.67,0,0,0,1.9.23,1.5,1.5,0,1,1,.39,3A7.09,7.09,0,0,1,498.45,782.38Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M631.18,690.67a1.5,1.5,0,0,1-1.5-1.5v-3a1.5,1.5,0,0,1,3,0v3A1.5,1.5,0,0,1,631.18,690.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M632.51,700.67h-.21A1.5,1.5,0,0,1,631,699a2.59,2.59,0,0,0-.21-1.5,1.5,1.5,0,0,1,2.72-1.26,5.58,5.58,0,0,1,.46,3.17A1.5,1.5,0,0,1,632.51,700.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M627.18,696.33a1.5,1.5,0,0,1-1.5-1.5v-1.67a1.5,1.5,0,0,1,3,0v1.67A1.5,1.5,0,0,1,627.18,696.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M372.18,581.33a1.5,1.5,0,0,1-.72-2.82c3.81-2.08,14.85-4.39,18.79-.4a1.5,1.5,0,1,1-2.13,2.11c-2.49-2.52-11.85-.91-15.21.93A1.49,1.49,0,0,1,372.18,581.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M388.51,580.33a1.5,1.5,0,0,1-1.14-.52,24.8,24.8,0,0,0-5.8-4.47c-3.37-2.12-6.86-4.32-8.77-8.56a1.5,1.5,0,1,1,2.74-1.23c1.54,3.42,4.5,5.28,7.63,7.25a27.44,27.44,0,0,1,6.47,5.05,1.5,1.5,0,0,1-1.14,2.48Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M510.58,669.36l-1.18,0h-1.23a1.5,1.5,0,0,1,0-3h1.29a13.85,13.85,0,0,0,4-.29,1.5,1.5,0,1,1,.81,2.89A13.35,13.35,0,0,1,510.58,669.36Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M521.51,671.33h-2a1.5,1.5,0,0,1,0-3h2a1.5,1.5,0,0,1,0,3Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M549.17,628a1.5,1.5,0,0,1-1.47-1.21A30,30,0,0,0,543,616.46a1.5,1.5,0,1,1,2.31-1.92c2.25,2.71,4.66,8.39,5.32,11.67a1.5,1.5,0,0,1-1.18,1.76A1.46,1.46,0,0,1,549.17,628Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M268.51,659a1.5,1.5,0,0,1-1.5-1.5v-4.67a1.5,1.5,0,0,1,3,0v4.67A1.5,1.5,0,0,1,268.51,659Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M267.84,666.67a1.5,1.5,0,0,1-1.49-1.33,8.15,8.15,0,0,1,.41-3.67,1.5,1.5,0,0,1,2.83,1,5.18,5.18,0,0,0-.26,2.33,1.5,1.5,0,0,1-1.32,1.66Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M273.17,659.33a1.5,1.5,0,0,1-1.48-1.3,4.89,4.89,0,0,1,.48-2.88,1.5,1.5,0,1,1,2.68,1.35,1.89,1.89,0,0,0-.19,1.12,1.5,1.5,0,0,1-1.28,1.69Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M165.51,652.67a1.5,1.5,0,0,1-1.4-.95,33.38,33.38,0,0,1-2.1-13,1.5,1.5,0,0,1,3,.16,30.59,30.59,0,0,0,1.9,11.7,1.5,1.5,0,0,1-1.39,2.05Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M170.51,646.67a1.5,1.5,0,0,1-1.2-.59,17.13,17.13,0,0,1-1.55-2.73c-.19-.39-.38-.77-.57-1.13a1.5,1.5,0,0,1,2.65-1.42c.21.39.41.81.62,1.22a15.28,15.28,0,0,0,1.25,2.25,1.5,1.5,0,0,1-1.19,2.41Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M270.84,441.67h0a1.5,1.5,0,0,1-1.5-1.5,15.5,15.5,0,0,0-.58-3.65,27.65,27.65,0,0,1-.57-2.81,30,30,0,0,1-.21-3.51c0-.44,0-.87,0-1.29a1.5,1.5,0,0,1-1.85-.73,8.88,8.88,0,0,1-.72-2.27,3.93,3.93,0,0,1-.73.54,1.5,1.5,0,0,1-2.2-.92l-.08-.3-.06-.22c-.17.32-.34.63-.53.93a1.5,1.5,0,0,1-2.17.42,6.21,6.21,0,0,1-.52-.43,28.48,28.48,0,0,1,.58,7.39,1.5,1.5,0,1,1-3-.26,27.61,27.61,0,0,0-.63-7.12,35.76,35.76,0,0,1-.73-6.67,1.5,1.5,0,0,1,2.74-.82,18.52,18.52,0,0,1,1.35,2.49c.26.54.51,1.07.78,1.55.22-.52.42-1.09.62-1.72a1.5,1.5,0,0,1,2.46-.64,5.09,5.09,0,0,1,1.07,1.51c.07-.19.13-.37.2-.55a1.5,1.5,0,0,1,2.78,0,12.55,12.55,0,0,1,.71,2.64,1.41,1.41,0,0,1,.86-.25,1.5,1.5,0,0,1,1.4,1,19,19,0,0,1,.69,5.67,27.31,27.31,0,0,0,.18,3.17,24.77,24.77,0,0,0,.52,2.51,18,18,0,0,1,.67,4.36A1.5,1.5,0,0,1,270.84,441.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M206.51,695.33a1.5,1.5,0,0,1-1.41-1c-1.2-3.37-.75-7-.32-10.57a34.32,34.32,0,0,0,.4-6.41,2.38,2.38,0,0,1-1.44.28c-1.77-.24-2.37-2.24-3-4.35l0-.13a4.77,4.77,0,0,1-1.67,2.22,1.5,1.5,0,0,1-2.18-.57,15.46,15.46,0,0,1-1.05-3.23l-.14-.57-.12.56a21.28,21.28,0,0,1-.67,2.66,1.5,1.5,0,0,1-1.35,1,1.49,1.49,0,0,1-1.43-.89,38.93,38.93,0,0,1-2-6.27c-.21-.8-.41-1.59-.62-2.35-.15.79-.28,1.6-.42,2.43s-.23,1.4-.35,2.12-.29,1.44-.47,2.28c-.65,3-1.64,7.55-.66,9.66a1.5,1.5,0,0,1-2.72,1.26c-1.41-3-.38-7.76.45-11.56.17-.8.33-1.54.45-2.17s.24-1.38.35-2.06a31.06,31.06,0,0,1,1.81-7.32,1.5,1.5,0,0,1,2.72-.09,34.45,34.45,0,0,1,2.38,7.07l.26,1a7.69,7.69,0,0,1,1.07-2.13,1.5,1.5,0,0,1,1.13-.61,1.53,1.53,0,0,1,1.19.49,9.35,9.35,0,0,1,1.9,4.11,9.09,9.09,0,0,1,.77-1.8,1.5,1.5,0,0,1,2.42-.22,11.77,11.77,0,0,1,1.88,4.24c.17.57.4,1.33.61,1.85a8.94,8.94,0,0,0,.62-.88,1.5,1.5,0,0,1,2.69.34c1.09,3.36.65,6.94.23,10.41s-.8,6.49.17,9.19a1.5,1.5,0,0,1-1.41,2Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M455.51,328.33a1.5,1.5,0,0,1-1.5-1.43c0-.59-.09-1.18-.15-1.76a24.68,24.68,0,0,1-.18-2.65,1.5,1.5,0,0,1,3,0,21.91,21.91,0,0,0,.17,2.33c.07.64.13,1.28.17,1.93a1.5,1.5,0,0,1-1.43,1.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M455.51,339.67a1.5,1.5,0,0,1-1.5-1.5v-2a1.5,1.5,0,0,1,3,0v2A1.5,1.5,0,0,1,455.51,339.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M462.18,330.33a1.5,1.5,0,0,1-1.45-1.13c-.24-.93-.51-2.33-.69-3.47a1.5,1.5,0,1,1,3-.47c.17,1,.43,2.36.64,3.2a1.5,1.5,0,0,1-1.46,1.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M496.84,441h-.06a1.5,1.5,0,0,1-1.44-1.56v-.35a26,26,0,0,1,.71-6,1.5,1.5,0,0,1,2.88.83,23.86,23.86,0,0,0-.6,5.29v.36A1.5,1.5,0,0,1,496.84,441Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M497.18,450.33a1.5,1.5,0,0,1-1.27-2.3,1.23,1.23,0,0,0,.13-.9,1.5,1.5,0,1,1,2.94-.6,4.22,4.22,0,0,1-.53,3.1A1.5,1.5,0,0,1,497.18,450.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M636.84,488.33a1.5,1.5,0,0,1-1.31-2.22,10.57,10.57,0,0,1,2.73-3.13,1.5,1.5,0,1,1,1.83,2.38,7.6,7.6,0,0,0-1.94,2.2A1.5,1.5,0,0,1,636.84,488.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M743.18,547a1.5,1.5,0,0,1-1.28-2.28,17.16,17.16,0,0,0,1.4-3.36c.16-.46.31-.93.48-1.38a1.5,1.5,0,0,1,2.81,1c-.16.43-.3.86-.45,1.3a19.66,19.66,0,0,1-1.67,4A1.5,1.5,0,0,1,743.18,547Z" transform="translate(-105.77 -43.5)"/><path class="cls-11" d="M747.18,559a1.5,1.5,0,0,1-1-2.61.53.53,0,0,0,.18-.47,1.5,1.5,0,0,1,3-.18,3.52,3.52,0,0,1-1.15,2.87A1.49,1.49,0,0,1,747.18,559Z" transform="translate(-105.77 -43.5)"/></g><g id="LINEART"><path class="cls-1" d="M389.53,594.58a2.5,2.5,0,0,1-.54-.06l-.89-.19c-12.57-2.76-33.6-7.38-31.41-25.13.7-5.64,2.85-9.58,6.39-11.73,7-4.23,17.46-.3,25.87,2.86,2.22.83,4.31,1.62,6.1,2.16a2.5,2.5,0,1,1-1.46,4.78c-1.94-.59-4.1-1.4-6.4-2.26-7.4-2.78-16.62-6.24-21.52-3.26-2.2,1.33-3.51,4-4,8.06-1.51,12.21,12.77,16.39,27.52,19.63l.89.2a2.5,2.5,0,0,1-.54,4.94Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M586.6,621.13h-.12a2.5,2.5,0,0,1-2.37-2.62c.31-6.34.06-8.26-.76-14.61-.25-1.94-.6-4-1-6a2.5,2.5,0,0,1,4.9-1c.45,2.18.81,4.33,1.08,6.39a67.68,67.68,0,0,1,.8,15.5A2.5,2.5,0,0,1,586.6,621.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M384.51,562.5a2.5,2.5,0,0,1-2.11-3.83,92.9,92.9,0,0,1,26.15-27.28,106.28,106.28,0,0,1,34-15.26c4.37-1.1,8.81-2.41,13.1-3.68,8.43-2.49,17.14-5.07,26.13-6.25,1.59-.21,3.17-.44,4.75-.66,6.18-.88,12.57-1.8,19-1.59,8.11.27,13.78,2.23,20.9,5a72,72,0,0,1,29.78,21.5,2.5,2.5,0,0,1-3.83,3.22,67.07,67.07,0,0,0-27.75-20.05c-6.87-2.65-11.92-4.4-19.27-4.65-6-.2-11.92.65-18.16,1.54-1.6.23-3.2.46-4.8.67-8.59,1.13-17.12,3.65-25.36,6.09-4.34,1.28-8.82,2.61-13.3,3.73a101.32,101.32,0,0,0-32.41,14.54,87.87,87.87,0,0,0-24.72,25.8A2.5,2.5,0,0,1,384.51,562.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M378.15,676a2.5,2.5,0,0,1-2.48-2.17c-3.25-24.48-5.7-53.7.79-84.83a2.5,2.5,0,0,1,4.89,1c-6.33,30.4-3.92,59.1-.73,83.16a2.5,2.5,0,0,1-2.15,2.81Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.25,702.13a2.5,2.5,0,0,1-1.5-4.5A210.35,210.35,0,0,1,546.49,679a136.83,136.83,0,0,1,39.61-13.51c3.2-.56,6.43-.83,9.57-1.09a92.3,92.3,0,0,0,9.49-1.1,104.21,104.21,0,0,1,15.61-1.72l-.75-.81c-3.51-3.81-7.88-8.55-11.65-8.77a2.5,2.5,0,0,1,.29-5c5.79.33,10.71,5.66,15,10.37a49.59,49.59,0,0,0,4.7,4.71,2.5,2.5,0,0,1-1.56,4.45h-.06a98.51,98.51,0,0,0-20.7,1.67,97,97,0,0,1-10,1.17c-3,.25-6.14.5-9.1,1a131.83,131.83,0,0,0-38.16,13,205.28,205.28,0,0,0-28.06,18.21A2.49,2.49,0,0,1,519.25,702.13Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M445.87,782.45a2.5,2.5,0,0,1-1.79-.76c-2.5-2.57-6-4.44-9.79-6.42a61.91,61.91,0,0,1-8-4.77c-1.3-1-2.69-1.91-4.17-2.91a59.53,59.53,0,0,1-9.12-7.07,16.94,16.94,0,0,1-3.32-5.47,13.19,13.19,0,0,0-2-3.59,10.17,10.17,0,0,0-1.83-1.43,10.61,10.61,0,0,1-4.93-6.24,12.12,12.12,0,0,0-.93-2,61.62,61.62,0,0,1-3-5.52c-.79-1.56-1.53-3-2.4-4.48-.58-1-1.24-1.9-1.93-2.89-.57-.81-1.16-1.65-1.71-2.52-1.32-2.08-2.37-4.14-3.38-6.14-.52-1-1-2.06-1.61-3.1C381,708,379.4,699.4,378,689.9a2.5,2.5,0,1,1,4.95-.74c1.35,9,2.83,17.18,7.38,25.56.59,1.08,1.13,2.16,1.67,3.22,1,2,1.95,3.84,3.14,5.71.49.78,1,1.53,1.59,2.33.71,1,1.45,2.07,2.13,3.19,1,1.61,1.79,3.24,2.58,4.81a57.23,57.23,0,0,0,2.78,5.08,16.18,16.18,0,0,1,1.37,2.9,5.94,5.94,0,0,0,3.08,3.91,14.23,14.23,0,0,1,2.74,2.23,17.39,17.39,0,0,1,2.87,4.94,12.66,12.66,0,0,0,2.3,4,55.94,55.94,0,0,0,8.36,6.44c1.46,1,3,2,4.35,3a57.43,57.43,0,0,0,7.38,4.36,57,57,0,0,1,8.81,5.36c3-4.17,6.22-8.18,9.37-12.08a177.59,177.59,0,0,0,12.68-17c7.6-12.15,18.9-24.48,32.7-35.65a2.5,2.5,0,0,1,3.15,3.88C490,726.16,479,738.06,471.72,749.75a181.62,181.62,0,0,1-13,17.53c-3.67,4.54-7.46,9.23-10.75,14.08a2.5,2.5,0,0,1-1.85,1.09Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M518.09,796a170.73,170.73,0,0,1-28.22-2.37c-5.62.34-10.17-1.06-15-2.54-1.41-.43-2.87-.88-4.37-1.29a104,104,0,0,1-23.77-9.44,2.5,2.5,0,1,1,2.44-4.37,99,99,0,0,0,22.64,9c1.59.43,3.09.89,4.54,1.34,4.63,1.43,8.63,2.66,13.46,2.31a2.51,2.51,0,0,1,.6,0,162.56,162.56,0,0,0,38.24,2c12.47-.88,24.46-5.86,34.53-10.61a2.5,2.5,0,0,1,2.13,4.52c-10.49,5-23,10.14-36.31,11.08C525.44,795.85,521.79,796,518.09,796Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M579.89,776.93a2.5,2.5,0,0,1-1.2-4.7,168.65,168.65,0,0,0,16.36-10.06c3.14-2.2,6.54-4.29,9.82-6.3,7.82-4.8,15.91-9.76,21.57-16.9,18.62-23.46,11.39-59.13-7-77.71-1.25-1.26-2.29-2.46-3.21-3.52-2.36-2.71-4.06-4.66-7.51-5.89a2.5,2.5,0,0,1,1.68-4.71c4.69,1.67,7.08,4.41,9.61,7.32.92,1.05,1.86,2.14,3,3.28,10.43,10.51,17.37,25.4,19,40.85,1.78,16.35-2.36,31.79-11.64,43.49-6.22,7.83-14.68,13-22.87,18.05-3.37,2.07-6.55,4-9.56,6.13a173.37,173.37,0,0,1-16.84,10.35A2.49,2.49,0,0,1,579.89,776.93Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.17,513.92l-.39,0a2.5,2.5,0,0,1-2.09-2.85c1.1-7.09,5.21-16,13.17-17.81,7.2-1.64,14,4.06,16.22,13.56a2.5,2.5,0,0,1-4.87,1.12c-1.32-5.73-5.27-10.94-10.24-9.81-5.13,1.16-8.43,7.92-9.33,13.7A2.5,2.5,0,0,1,467.17,513.92Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M537.44,607.22h-.74c-4-.16-6.74-1.62-7.5-4s.57-5,4-7.56c2.92-2.24,11.31-4.41,15.13-1.5,1,.74,3,2.91,1.3,7.16S542.27,607.22,537.44,607.22Zm-3.33-5.55a10.86,10.86,0,0,0,6,.29c2.43-.46,4.36-1.49,4.79-2.56h0a2.43,2.43,0,0,0,.29-1.33c-1-1-7.07,0-9,1.52A8.16,8.16,0,0,0,534.12,601.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M461.94,640.88c-1.43,0-2.8,0-4.09-.05-14.46-.36-26.11-9.2-32.81-24.88a71.6,71.6,0,0,1-3.63-12.73,55.67,55.67,0,0,1-1.47-13c.18-9.12,3.38-16.86,10.38-25.08,4.1-4.82,12-9.22,18.08-11.46,20.17-7.44,48.23-1.52,57.84,19.15A94.12,94.12,0,0,1,511,586.68c3.92,13.69,2.82,25.54-3.26,35.23-4.81,7.67-14,13.74-25.16,16.67A82.12,82.12,0,0,1,461.94,640.88ZM466,555.62a46.28,46.28,0,0,0-15.89,2.71c-5.42,2-12.66,6.08-16,10-6.2,7.28-9,14-9.18,21.94h0a50.76,50.76,0,0,0,1.36,11.86A67.88,67.88,0,0,0,429.64,614c3.41,8,11.62,21.43,28.33,21.85,6.55.16,15.12.07,23.35-2.08,9.81-2.57,18.1-8,22.19-14.49,5.3-8.44,6.2-18.94,2.69-31.2a90.18,90.18,0,0,0-4.51-13.16C495.66,561.92,480.59,555.62,466,555.62Zm-43.57,34.61h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.07,655.25a61.92,61.92,0,0,1-23.16-4.39,51.53,51.53,0,0,1-28.79-28c-2.13-5-3.34-10.51-4.51-15.82a69.67,69.67,0,0,1-1.84-16.21h0c.2-11.39,4.16-21,12.81-31.27,5.09-6,14.91-11.5,22.39-14.27,19.5-7.21,44.36-3.48,60.45,9.07,12.67,9.89,16,25.19,18.73,37.49,6.14,28-10.29,53.73-39.07,61.25A67.41,67.41,0,0,1,467.07,655.25Zm-2-106.55a54.06,54.06,0,0,0-18.65,3.16c-6.6,2.45-15.41,7.42-19.45,12.21-7.54,8.91-11,17.19-11.15,26.84h0a62.8,62.8,0,0,0,1.68,14.57c1.1,5,2.23,10.16,4.11,14.57,10.56,24.83,38.53,32,60.69,26.17,25.38-6.63,39.34-28.39,34-52.91-3.12-14.23-6.3-25.72-16.18-33.44C490.8,552.63,477.77,548.7,465.08,548.7ZM412.3,590.85h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M578.15,615.43c-5.87,0-12-1.19-17.83-6.13-8-6.76-13.43-15.13-18.08-28a126.1,126.1,0,0,1-4.16-15.7,97.31,97.31,0,0,1-2.3-15.87A51.14,51.14,0,0,1,543,519.87c3.39-5.84,10.34-10.84,15.73-13.2,14.07-6.15,32.68-.86,45.25,12.87,9.54,10.41,12.86,25.54,15.52,37.7,3.71,16.92,2.33,31.23-4.12,42.55-7.37,12.93-19.3,14.13-28.88,15.1A82.79,82.79,0,0,1,578.15,615.43Zm-7-104.21a24,24,0,0,0-9.66,1.92c-4.33,1.9-10,6-12.45,10.27a44.47,44.47,0,0,0-6.25,26h0A90.27,90.27,0,0,0,545,564.08a121,121,0,0,0,3.9,14.81c4.26,11.78,8.89,19,16,25,6.42,5.41,13.41,4.71,20.81,4,10.88-1.09,18.35-2.49,23.53-11.58,5.56-9.75,6.69-22.39,3.36-37.54-3.16-14.41-6.19-26.09-13.84-34.44S580.64,511.22,571.19,511.22Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M583.65,599.89c-12.91,0-24.11-8.93-30.41-24.49-6.2-15.29-11.87-34.24-.67-45.15h0c.33-.32.68-.64,1-.95,9.59-8.13,26.29-5.09,35.28,2.74,12.16,10.58,16.24,24.2,18.63,36.13a28.15,28.15,0,0,1-4.45,22,23,23,0,0,1-16,9.47A28.62,28.62,0,0,1,583.65,599.89ZM556,533.84c-9.16,8.93-3.35,26.93,1.82,39.69,2.86,7.05,11.35,23.23,28.56,21.2A18,18,0,0,0,599,587.28a23.14,23.14,0,0,0,3.59-18.12c-3.15-15.74-8.23-25.71-17-33.34-7.45-6.48-21.33-9-28.78-2.69-.28.24-.54.47-.79.72Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M502.34,715.06a12.41,12.41,0,0,1-1.45-.08,2.5,2.5,0,1,1,.59-5c3.81.45,12.26-2.27,14.54-5.22,1.69-2.17.74-5.17.25-6.36a12.76,12.76,0,0,0-10.33-7.21l-2.56-.05a2.5,2.5,0,0,1,0-5h0l2.66.06a17.75,17.75,0,0,1,14.8,10.31c1.72,4.21,1.38,8.33-.93,11.31C516.83,711.92,508,715.06,502.34,715.06Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M567.78,785.4a11.33,11.33,0,0,1-5.54-1.29,6.36,6.36,0,0,1-2.08-1.92h0c-1.34-2-1.28-4.29-1.24-6.16a54.15,54.15,0,0,1,.73-7.32,57.41,57.41,0,0,1,3.61-13.28c1.85-4.36,7.79-13.46,14.3-13.77,2.15-.11,5.22.7,7.6,5.1a20.48,20.48,0,0,1,2.14,10c0,8.79-3.16,17.45-8.36,23.17-3,3.28-6.47,5.15-10.1,5.42C568.57,785.38,568.21,785.4,567.78,785.4Zm10.15-38.76h-.14c-3.3.16-8.17,6.56-9.94,10.73a52.57,52.57,0,0,0-3.27,12.13,49.13,49.13,0,0,0-.66,6.58c0,1.34-.07,2.65.36,3.28h0a1.35,1.35,0,0,0,.47.41,7.22,7.22,0,0,0,3.72.59c2.94-.22,5.3-2.18,6.77-3.79,4.32-4.76,7-12.36,7.06-19.83a15.72,15.72,0,0,0-1.53-7.62C579.51,746.83,578.42,746.65,577.93,746.65Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M638.39,738.56a8.38,8.38,0,0,1-2.86-.48,7.6,7.6,0,0,1-4.72-5.53,2.5,2.5,0,1,1,4.82-1.34c.49,1.77,1.3,2.06,1.6,2.17,3.61,1.3,12-4.53,14.77-6.45l.64-.44c4.49-3.09,7.55-11.34,8.59-18.14.57-3.7.06-8.38-2-10.17-.35-.3-1.41-1.21-4-.4-5.1,1.57-10.45,7.24-12.17,12.9a2.5,2.5,0,1,1-4.78-1.46C640.4,702,647.05,695,653.69,693c4.37-1.34,7.19,0,8.78,1.39,3.87,3.34,4.41,10,3.69,14.71-.4,2.64-2.81,16.08-10.69,21.5l-.63.43C649.12,735,643.25,738.56,638.39,738.56Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M447.81,618.41c-8.8,0-17.45-1.38-23.25-7.2a2.5,2.5,0,0,1,3.54-3.53c6.33,6.33,18,6.1,28.43,5.37,16.86-1.17,34.34-8.73,52-22.5a2.5,2.5,0,0,1,3.08,3.94c-18.43,14.39-36.84,22.31-54.71,23.54C453.9,618.24,450.84,618.41,447.81,618.41Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M566.29,578.89a30.83,30.83,0,0,1-11.69-2.11,2.5,2.5,0,0,1,1.9-4.62c13.85,5.69,37.34-3,43.33-16.07a2.5,2.5,0,0,1,4.54,2.09C598.86,570.2,581.39,578.89,566.29,578.89Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M556.63,603.14a2.49,2.49,0,0,1-1.14-.28,30.21,30.21,0,0,0-8.12-2.49,2.5,2.5,0,0,1,.78-4.94,34.78,34.78,0,0,1,9.62,3,2.5,2.5,0,0,1-1.14,4.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M529.43,626.73a8,8,0,0,1-6-2.45c-2.56-2.71-2.92-7-1-12,2.31-6.09,4.85-10,7.76-12A2.5,2.5,0,1,1,533,604.5c-2,1.35-4,4.58-5.88,9.6-.55,1.45-1.66,5,0,6.75s5,.78,7.32-.94c1-.71,1.89-1.55,2.86-2.43a17.66,17.66,0,0,1,14-6c1.06-.05,2.07-.1,3-.23,2.09-.27,4.7-1.25,5.3-3.11,0-.29,0-.8.06-1.22s0-.87.05-1a2.5,2.5,0,1,1,5,.57c0,.05,0,.3,0,.6a10.56,10.56,0,0,1-.18,2.17c-1.16,4.34-5.68,6.42-9.53,6.92-1.17.15-2.32.21-3.43.27a13,13,0,0,0-10.91,4.69c-1,.92-2.08,1.88-3.24,2.74A13.82,13.82,0,0,1,529.43,626.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.85,593.87a3.53,3.53,0,0,1-2.47-6,44.74,44.74,0,0,1,26.81-12.52,3.53,3.53,0,0,1,.7,7,37.66,37.66,0,0,0-22.57,10.54A3.52,3.52,0,0,1,519.85,593.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M491.51,718.37a2.5,2.5,0,0,1-1.68-.65,6.89,6.89,0,0,1-.56-.57,3.4,3.4,0,0,1-2,.17c-3.42-.68-4.15-5.85-4.29-7.42-.39-4.33,1.18-20.68,7.72-27h0a8.46,8.46,0,0,1,7.46-2.49,2.5,2.5,0,0,1,1.95,1.64,4.71,4.71,0,0,1,1.85,0,2.5,2.5,0,0,1,1.12.58,4.43,4.43,0,0,1,3.88,1.52c1.49,2.13.1,4.4-.56,5.5a5.42,5.42,0,0,0-.3.51,66.63,66.63,0,0,0-2.4,9.82l0,.23c-1.5,7.72-1.78,11.54-1.71,12.87a2.5,2.5,0,0,1-1.77,4.15c-1.32.06-2.6.05-3.84,0-1,0-1.92,0-2.87,0a2.5,2.5,0,0,1-1.74,1Zm-2.59-5.64h0Zm1-2.27a2.43,2.43,0,0,1,.38,0,2.5,2.5,0,0,1,2.06,1.9c1.4-.07,2.75-.06,4-.05H497a81.17,81.17,0,0,1,1.79-13l0-.22a71.26,71.26,0,0,1,2.62-10.6,5,5,0,0,1,.23-.54,2.51,2.51,0,0,1-1.52-.41l0,0c-.31.25-.62.48-.92.67a2.5,2.5,0,0,1-3.83-2.3c0-.09,0-.19,0-.29a4.89,4.89,0,0,0-1.19.87h0c-4.59,4.42-6.62,18.44-6.21,22.93a10.75,10.75,0,0,0,.28,1.64A2.5,2.5,0,0,1,489.94,710.45ZM500,712.29h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M374,676.5a2.5,2.5,0,0,1-.3-5c52.83-6.38,114.94-14,175.09-21.86a2.5,2.5,0,1,1,.65,5c-60.17,7.9-122.3,15.49-175.14,21.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M550.07,654.18a2.5,2.5,0,0,1-1.68-4.35c4.28-3.89,9.64-7.94,14.83-11.86,9.22-7,18.75-14.15,22.48-20.59a2.5,2.5,0,1,1,4.33,2.51c-4.24,7.32-14.18,14.82-23.79,22.08-5.1,3.85-10.37,7.83-14.48,11.57A2.49,2.49,0,0,1,550.07,654.18Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M378.4,692q-2,0-3.93,0a2.5,2.5,0,0,1-2.42-2.2,88.85,88.85,0,0,1-.51-15.92,2.5,2.5,0,1,1,5,.29,83.89,83.89,0,0,0,.24,12.87c12.87.14,25.88-1.39,38.49-2.87,16.89-2,38.15-4.31,58.71-6.56s41.89-4.58,58.8-6.57a2.5,2.5,0,1,1,.58,5c-16.93,2-38.23,4.32-58.83,6.57s-41.8,4.58-58.67,6.55C403.63,690.55,391,692,378.4,692Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,676a2.5,2.5,0,0,1-2.5-2.5V517.87l-33.42,6.51a2.5,2.5,0,1,1-1-4.91l36.4-7.09a2.5,2.5,0,0,1,3,2.45V673.51A2.5,2.5,0,0,1,637.74,676Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,645.49a2.5,2.5,0,0,1-.48-5l121.42-24V378.4L641.23,396a2.51,2.51,0,0,1-1.25-.13l-140.5-52.67a2.5,2.5,0,0,1,.53-4.82l101-14.1a2.52,2.52,0,0,1,1.08.08l159.83,48.76h0a2.49,2.49,0,0,1,1.42,1.16h0l0,0h0a2.49,2.49,0,0,1,.26,1.17V618.63a2.5,2.5,0,0,1-2,2.45L638.22,645.45A2.52,2.52,0,0,1,637.74,645.49ZM510.46,341.95l130.67,49,108.74-16.27L601.14,329.29Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M640.86,433a2.5,2.5,0,0,1-2.5-2.5v-37a2.5,2.5,0,0,1,5,0v37A2.5,2.5,0,0,1,640.86,433Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M500.36,393.33a2.5,2.5,0,0,1-2.5-2.5V344a2.5,2.5,0,0,1,5,0v46.83A2.5,2.5,0,0,1,500.36,393.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M637.74,517.35a2.51,2.51,0,0,1-2.41-3.21c.7-2.41,15.84-32.87,22.19-45.59l-113,13.94-16.81,30a2.5,2.5,0,1,1-4.36-2.44l17.42-31.1a2.5,2.5,0,0,1,1.88-1.26L661.54,463a2.5,2.5,0,0,1,2.54,3.6c-9.21,18.41-23.18,46.64-23.95,48.94A2.48,2.48,0,0,1,637.74,517.35Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M467.63,512.6a2.49,2.49,0,0,1-.93-.18L398.53,485.2a2.5,2.5,0,0,1-1.13-.9L357,425.58a2.5,2.5,0,0,1,3.05-3.71l120.36,52a2.49,2.49,0,0,1,1.07.87l19.66,28.47a2.5,2.5,0,1,1-4.11,2.84l-19.26-27.88L366,429.91l35.05,50.93,67.48,26.95a2.5,2.5,0,0,1-.93,4.82Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M396.21,500.85a2.5,2.5,0,0,1-2.5-2.5V480.93a2.5,2.5,0,0,1,5,0v17.42A2.5,2.5,0,0,1,396.21,500.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M287.51,543a2.47,2.47,0,0,1-.38,0,2.5,2.5,0,0,1-2.11-2.19l-8.71-77L151.94,480.69V522.5a2.5,2.5,0,0,1-5,0v-44a2.5,2.5,0,0,1,2.16-2.48l129.07-17.5a2.5,2.5,0,0,1,2.82,2.2l8,70.3,29.27-66.52a2.5,2.5,0,0,1,3.34-1.26l106.5,49.33a2.5,2.5,0,0,1,1.32,3.06l-3.65,10.88a2.5,2.5,0,1,1-4.74-1.59l2.94-8.76L321.77,468.84l-32,72.67A2.5,2.5,0,0,1,287.51,543Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M256.51,614.13a2.5,2.5,0,0,1-2.47-2.87l10-66.48a2.5,2.5,0,0,1,2.15-2.11L404.9,524.54a2.5,2.5,0,0,1,2.82,2.48v9.9a2.5,2.5,0,0,1-5,0v-7.06l-134,17.53-9.22,61.32,118-16a2.5,2.5,0,0,1,.67,5L256.84,614.11Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M256.51,614.13a2.5,2.5,0,0,1-1.15-.28l-99-51.63a2.5,2.5,0,0,1-1.2-1.37l-13.5-37.5A2.5,2.5,0,0,1,145,520.2l79.5,33.5a2.5,2.5,0,0,1,1.18,1l33,55.63a2.5,2.5,0,0,1-2.15,3.78Zm-97-55.89,90.35,47.12L221.78,558l-73.49-31Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M207.35,551.69a2.5,2.5,0,0,1-.17-5l59.16-4a2.5,2.5,0,0,1,.34,5l-59.16,4Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M252.51,728.5a2.5,2.5,0,0,1-1.38-.42l-97-64.28a2.5,2.5,0,0,1-1.12-2.13L155,560a2.5,2.5,0,0,1,2.5-2.45h.05A2.5,2.5,0,0,1,160,560L158,660.4l95,63,130.14-20.83a2.5,2.5,0,1,1,.79,4.94l-131.1,21A2.56,2.56,0,0,1,252.51,728.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M252.51,728.5h-.09a2.5,2.5,0,0,1-2.41-2.58l4-114.37a2.5,2.5,0,0,1,5,.17l-4,114.37A2.5,2.5,0,0,1,252.51,728.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M454.71,468a2.5,2.5,0,0,1-.2-5l52.56-4.31-1.75-65.17L383.58,403l5.43,32.6a2.5,2.5,0,0,1-4.93.82l-5.88-35.29a2.5,2.5,0,0,1,2.27-2.9l127.09-9.92a2.5,2.5,0,0,1,2.69,2.43l1.88,70.17a2.5,2.5,0,0,1-2.29,2.56L454.92,468Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M560.41,480.52a2.49,2.49,0,0,1-.79-.13l-50.78-17a2.5,2.5,0,0,1,1.59-4.74l50.78,17a2.5,2.5,0,0,1-.79,4.87Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M645.36,469.64a2.5,2.5,0,0,1-2.17-3.73l15-26.56L538,396.62l-26.32,57.8a2.5,2.5,0,0,1-4.55-2.07l27.28-59.88a2.5,2.5,0,0,1,3.11-1.32l125.14,44.48a2.5,2.5,0,0,1,1.34,3.59l-16.48,29.15A2.5,2.5,0,0,1,645.36,469.64Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M279,468a2.5,2.5,0,0,1-.28-5l95.89-11a2.5,2.5,0,1,1,.57,5L279.3,468Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M200.26,474.11a2.5,2.5,0,0,1-2.5-2.5v-38a2.5,2.5,0,0,1,5,0v38A2.5,2.5,0,0,1,200.26,474.11Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M259,466.15a2.49,2.49,0,0,1-1.14-.27l-58.72-30.05a2.5,2.5,0,0,1,.82-4.71l42.58-5.43a2.53,2.53,0,0,1,1.33.2l44.76,19.9L369,436.54a2.5,2.5,0,1,1,.57,5l-81,9.31a2.5,2.5,0,0,1-1.3-.2l-44.74-19.89-33.87,4.32,51.52,26.37a2.5,2.5,0,0,1-1.14,4.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M288.23,450.84a2.5,2.5,0,0,1-2.5-2.43l-3.4-116.85-35.44-6.85L245.34,428.2a2.5,2.5,0,0,1-2.5,2.46h0a2.5,2.5,0,0,1-2.46-2.54l1.59-106.47a2.5,2.5,0,0,1,3-2.42L285.24,327a2.5,2.5,0,0,1,2,2.38l3.46,118.85a2.5,2.5,0,0,1-2.43,2.57Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M408.1,401.12a2.5,2.5,0,0,1-2.5-2.5V320c-12.94.83-77.13,7.39-120.57,12a2.5,2.5,0,0,1-2.61-3.33l14.87-41.24a2.5,2.5,0,0,1,2.17-1.65L418.63,277a2.5,2.5,0,0,1,2.59,3.17L410.6,317.82v80.8A2.5,2.5,0,0,1,408.1,401.12ZM301.44,290.62l-13,36c9.27-1,33.4-3.49,57.35-5.92,17.84-1.81,32.09-3.21,42.37-4.18s15.31-1.42,18-1.52l9.23-32.73Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M357.46,286.49a2.5,2.5,0,0,1-2.35-3.34l11.34-31.79a2.5,2.5,0,0,1,3-1.56l47.09,13.64a2.5,2.5,0,0,1,1.72,3.06l-3.88,14.14a2.5,2.5,0,1,1-4.82-1.32l3.23-11.76-42.46-12.3-10.55,29.58A2.5,2.5,0,0,1,357.46,286.49Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M351.79,286.91a2.5,2.5,0,0,1-2.23-1.37L341,268.81l-94.43,9a2.5,2.5,0,1,1-.47-5l96.12-9.12a2.49,2.49,0,0,1,2.46,1.35L354,283.27a2.5,2.5,0,0,1-2.23,3.63Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M284.76,332a2.5,2.5,0,0,1-2.47-2.12l-6.65-43.51-36.22-10.81,7.47,45.74a2.5,2.5,0,0,1-4.93.81l-8.12-49.69a2.5,2.5,0,0,1,3.18-2.8L278.59,282a2.5,2.5,0,0,1,1.76,2l6.89,45.08a2.5,2.5,0,0,1-2.09,2.85Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M601.34,329.24h-.08a2.5,2.5,0,0,1-2.42-2.58l4.57-142.37-163.65,17.2a2.5,2.5,0,0,1-.52-5L605.75,179a2.5,2.5,0,0,1,2.76,2.57l-4.67,145.24A2.5,2.5,0,0,1,601.34,329.24Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M436.5,398.9h0a2.5,2.5,0,0,1-2.46-2.54l3-195.5-120-35.51V268.83a2.5,2.5,0,0,1-5,0V162a2.5,2.5,0,0,1,3.21-2.4l125.06,37A2.5,2.5,0,0,1,442,199l-3,197.4A2.5,2.5,0,0,1,436.5,398.9Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M439.51,201.5a2.5,2.5,0,0,1-2.08-3.88l41-62a2.5,2.5,0,0,1,1.86-1.11L642.79,120a2.5,2.5,0,0,1,2.34,3.82l-37,59a2.5,2.5,0,0,1-4.24-2.66l34.33-54.73L481.93,139.38l-40.34,61A2.5,2.5,0,0,1,439.51,201.5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M403.51,157.5a2.5,2.5,0,0,1-.17-5l66.33-4.57,21.4-97.47a2.5,2.5,0,0,1,3.05-1.89l134.5,34a2.5,2.5,0,0,1,1.76,3.2l-13,40a2.5,2.5,0,1,1-4.75-1.55L624.8,86.77,495.4,54.06l-21.25,96.78a2.5,2.5,0,0,1-2.27,2l-68.2,4.7Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M436.62,200.64a2.5,2.5,0,0,1-1.94-.92l-54.58-67L267.65,104.37l48.68,56a2.5,2.5,0,1,1-3.77,3.28l-53.91-62a2.5,2.5,0,0,1,2.5-4.06l121,30.5a2.51,2.51,0,0,1,1.33.85l55.11,67.64a2.5,2.5,0,0,1-1.94,4.08Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M468.33,151.57a2.5,2.5,0,0,1-2.14-1.2L425.66,83.6,280.58,93.76l3.26,8.33a2.5,2.5,0,1,1-4.66,1.82l-4.5-11.5A2.5,2.5,0,0,1,276.83,89l150-10.5a2.51,2.51,0,0,1,2.31,1.2l41.32,68.07a2.5,2.5,0,0,1-2.13,3.8Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M522.51,687.33a2.5,2.5,0,0,1-2-4,77.06,77.06,0,0,1,20-18.5c2.69-1.64,26.72-16.06,40.51-16.42h.07a2.5,2.5,0,0,1,.07,5c-10.15.27-28.69,10-38,15.69a71.62,71.62,0,0,0-18.59,17.2A2.5,2.5,0,0,1,522.51,687.33Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M540.51,669.67a2.5,2.5,0,0,1-2-4,33.69,33.69,0,0,0,2.67-5.27c1.9-4.25,3.69-8.26,6.47-9.77A2.5,2.5,0,0,1,550,655c-1.29.7-3.09,4.74-4.29,7.41a35.3,35.3,0,0,1-3.23,6.22A2.5,2.5,0,0,1,540.51,669.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M558.51,659.67a2.49,2.49,0,0,1-1.23-.33c-.71-.4-1.68-.83-2.71-1.29-2.24-1-4.78-2.11-6.47-3.76a2.5,2.5,0,1,1,3.49-3.58,19.25,19.25,0,0,0,5,2.77c1.14.5,2.22,1,3.15,1.51a2.5,2.5,0,0,1-1.23,4.67Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M484.51,715c-.87,0-1.8,0-2.85-.08-5.32-.27-26.21-3.31-31.25-13.33-1.28-2.54-2.08-6.67,1.4-11.88,6-8.94,19.6-7.5,30.55-6.35,3.06.32,5.94.63,8.15.63a2.5,2.5,0,0,1,0,5c-2.47,0-5.48-.32-8.67-.65-9.62-1-21.58-2.28-25.87,4.15-1.74,2.61-2.1,4.85-1.09,6.85,3.33,6.61,19.51,10.2,27,10.58,1,0,1.82.07,2.6.07a2.5,2.5,0,0,1,0,5Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M593,628a2.5,2.5,0,0,1-2.32-1.57,19.54,19.54,0,0,0-4-5.67,2.5,2.5,0,0,1,3.54-3.53,24.33,24.33,0,0,1,5,7.33A2.5,2.5,0,0,1,593,628Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M572.5,655a2.61,2.61,0,0,1-.7-.1,2.54,2.54,0,0,1-1.71-3.13c.92-3.26,15-19.9,15.16-20.06a25.2,25.2,0,0,0,2.06-3,22,22,0,0,1,3.52-4.63,2.5,2.5,0,0,1,3.38,3.69,18.24,18.24,0,0,0-2.66,3.61A29.11,29.11,0,0,1,589,635c-3.08,3.56-13.32,16.19-14.16,18.23A2.44,2.44,0,0,1,572.5,655Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M614.19,654a2.49,2.49,0,0,1-.67-.09c-3.05-.85-4.95-3.27-6.78-5.6-1.67-2.13-3.25-4.14-5.5-4.68a32.78,32.78,0,0,0-4.7.14c-6.27.42-10.21.53-12.15-1.51a3.61,3.61,0,0,1-1-3,2.49,2.49,0,0,1,.64-1.4,2.39,2.39,0,0,1,.14-.65c1.66-4.44,6-7.31,12-7.88h0a23.37,23.37,0,0,1,9.1.94,18.94,18.94,0,0,1,11.2,10.37,14.19,14.19,0,0,1,0,11.89A2.5,2.5,0,0,1,614.19,654Zm-13.86-15.42a9.08,9.08,0,0,1,2.07.19c3.95.94,6.25,3.87,8.27,6.46a29.17,29.17,0,0,0,2,2.43,10.16,10.16,0,0,0-.84-5,14,14,0,0,0-8.15-7.58,18.26,18.26,0,0,0-7.08-.72h0a11,11,0,0,0-6.19,2.33,2.58,2.58,0,0,1,.36.61,2.45,2.45,0,0,1,.05,1.71h0c1.82,0,4-.14,5.32-.23C597.94,638.62,599.27,638.54,600.33,638.54Zm-3.91-6.71h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M590.08,663.44a11.54,11.54,0,0,1-8.33-3.41,8.64,8.64,0,0,1-2.31-6.88c.26-4.44,2.92-9.72,6.2-12.28a2.5,2.5,0,0,1,3.08,3.94,13.56,13.56,0,0,0-4.29,8.63,4,4,0,0,0,.84,3c4.68,4.63,11.85,0,14.71-2.27,1.12-.87,2.2-1.82,3.34-2.84a53.86,53.86,0,0,1,4.76-3.91,2.5,2.5,0,1,1,2.87,4.1,49.44,49.44,0,0,0-4.31,3.56c-1.15,1-2.34,2.08-3.59,3C598.52,661.66,594.05,663.44,590.08,663.44Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M608.54,636a2.49,2.49,0,0,1-1.28-.35c-3.93-2.35-12.45-5.87-15.18-5.62a2.5,2.5,0,0,1-.48-5c5-.49,15.66,4.78,18.23,6.31a2.5,2.5,0,0,1-1.29,4.65Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M545.57,631.36h-.23c-3.13-.2-4.86-3.22-6.24-5.64a11.71,11.71,0,0,0-1.85-2.72,2.5,2.5,0,0,1,2.52-4.32c1.6.94,2.65,2.77,3.67,4.55a13.1,13.1,0,0,0,2.12,3.07,20.3,20.3,0,0,0,2-1.2,15.74,15.74,0,0,1,1.92-1.13,34.39,34.39,0,0,1,3.19-1.28c-.36-.67-.75-1.35-1.17-2a24.07,24.07,0,0,1-2.75-5.82,2.5,2.5,0,0,1,4.82-1.31,20.12,20.12,0,0,0,2.23,4.59,25.17,25.17,0,0,1,2.71,5.64,2.5,2.5,0,0,1-2.16,3.19,17.73,17.73,0,0,0-4.84,1.59c-.21.1-.81.48-1.25.76C548.38,630.53,547,631.36,545.57,631.36Z" transform="translate(-105.77 -43.5)"/></g><g id="circle"><g class="cls-12"><path class="cls-7" d="M412.3,590.85c.19-10.39,3.77-19.35,12-29.06C429,556.25,438.5,551,445.2,548.55c18-6.67,41.77-3.38,57.05,8.54,11.26,8.79,14.51,22.08,17.45,35.46,5.89,26.81-10.08,50.17-36.51,57.08-25.62,6.69-54-2.76-64.83-28.2-2-4.68-3.14-9.87-4.31-15.2A66.21,66.21,0,0,1,412.3,590.85Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-12"><path class="cls-7" d="M539.3,549.54a47.78,47.78,0,0,1,6.72-27.9c3-5.17,9.47-9.71,14.09-11.74,12.44-5.44,29.58-.7,41.23,12,8.59,9.38,11.74,22.69,14.68,36.07,3.29,15,2.67,28.79-3.74,40-6.27,11-15.81,12.29-26.17,13.33-7.79.78-15.93,1.62-23.52-4.77-8-6.75-12.87-15-17-26.51a122.75,122.75,0,0,1-4-15.26A93.72,93.72,0,0,1,539.3,549.54Z" transform="translate(-105.77 -43.5)"/></g><path class="cls-1" d="M467.07,655.25a61.92,61.92,0,0,1-23.16-4.39,51.53,51.53,0,0,1-28.79-28c-2.13-5-3.34-10.51-4.51-15.82a69.67,69.67,0,0,1-1.84-16.21h0c.2-11.39,4.16-21,12.81-31.27,5.09-6,14.91-11.5,22.39-14.27,19.5-7.21,44.36-3.48,60.45,9.07,12.67,9.89,16,25.19,18.73,37.49,6.14,28-10.29,53.73-39.07,61.25A67.41,67.41,0,0,1,467.07,655.25Zm-2-106.55a54.06,54.06,0,0,0-18.65,3.16c-6.6,2.45-15.41,7.42-19.45,12.21-7.54,8.91-11,17.19-11.15,26.84h0a62.8,62.8,0,0,0,1.68,14.57c1.1,5,2.23,10.16,4.11,14.57,10.56,24.83,38.53,32,60.69,26.17,25.38-6.63,39.34-28.39,34-52.91-3.12-14.23-6.3-25.72-16.18-33.44C490.8,552.63,477.77,548.7,465.08,548.7ZM412.3,590.85h0Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M578.15,615.43c-5.87,0-12-1.19-17.83-6.13-8-6.76-13.43-15.13-18.08-28a126.1,126.1,0,0,1-4.16-15.7,97.31,97.31,0,0,1-2.3-15.87A51.14,51.14,0,0,1,543,519.87c3.39-5.84,10.34-10.84,15.73-13.2,14.07-6.15,32.68-.86,45.25,12.87,9.54,10.41,12.86,25.54,15.52,37.7,3.71,16.92,2.33,31.23-4.12,42.55-7.37,12.93-19.3,14.13-28.88,15.1A82.79,82.79,0,0,1,578.15,615.43Zm-7-104.21a24,24,0,0,0-9.66,1.92c-4.33,1.9-10,6-12.45,10.27a44.47,44.47,0,0,0-6.25,26h0A90.27,90.27,0,0,0,545,564.08a121,121,0,0,0,3.9,14.81c4.26,11.78,8.89,19,16,25,6.42,5.41,13.41,4.71,20.81,4,10.88-1.09,18.35-2.49,23.53-11.58,5.56-9.75,6.69-22.39,3.36-37.54-3.16-14.41-6.19-26.09-13.84-34.44S580.64,511.22,571.19,511.22Z" transform="translate(-105.77 -43.5)"/><path class="cls-1" d="M519.85,593.87a3.53,3.53,0,0,1-2.47-6,44.74,44.74,0,0,1,26.81-12.52,3.53,3.53,0,0,1,.7,7,37.66,37.66,0,0,0-22.57,10.54A3.52,3.52,0,0,1,519.85,593.87Z" transform="translate(-105.77 -43.5)"/><g class="cls-12"><path class="cls-7" d="M594.18,528.83c-2.91-2.27-6.89-1-6.33,3,.48,3.5,3.92,7.78,5.33,11.35,1.52,3.85,1.69,9.59,4.15,12.83,6.11,8,5.64-6.3,4.59-9.76C600,539.94,598.74,534.06,594.18,528.83Z" transform="translate(-105.77 -43.5)"/></g><g class="cls-12"><path class="cls-7" d="M496.84,563.83c-1-3.57-9.51-2.83-8.77,1.67.41,2.44,3.62,5.41,4.9,7.54a40.24,40.24,0,0,1,4.21,9.12c1.7,5.77-.86,14.73,3.3,19.67,3.29,3.9,6.35,1.12,6.68-2.86.42-5.1-.18-10.25-.7-15.28C505.86,577.61,503,567.14,496.84,563.83Z" transform="translate(-105.77 -43.5)"/></g></g><g id="layers"><path class="cls-1" d="M468.33,880.06a357.61,357.61,0,0,1-159.8-677.52,3.53,3.53,0,1,1,3.16,6.31c-119.58,59.84-193.86,180-193.86,313.64C117.82,715.77,275.06,873,468.33,873S818.84,715.77,818.84,522.5a350,350,0,0,0-214.08-323,3.53,3.53,0,0,1,2.75-6.5,357.56,357.56,0,0,1-139.18,687Z" transform="translate(-105.77 -43.5)"/></g></svg> \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/assets/StatusGraph.png b/vendor/github.com/golang/dep/docs/assets/StatusGraph.png deleted file mode 100644 index 5380aecae1ee420bfb1bf7e4a9058789eb35e40f..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/StatusGraph.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/annotated-func-arrows.png b/vendor/github.com/golang/dep/docs/assets/annotated-func-arrows.png deleted file mode 100644 index cc9190f2a0431c36d7d53bce3ceb2198ca3e67fa..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/annotated-func-arrows.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/base-arrows.png b/vendor/github.com/golang/dep/docs/assets/base-arrows.png deleted file mode 100644 index d60e598c86421c9ccd0630cb1edd5fcfe0b15dc4..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/base-arrows.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/four-states.png b/vendor/github.com/golang/dep/docs/assets/four-states.png deleted file mode 100644 index a1aa5a566e59e21451e044e241e5fe0d586911f9..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/four-states.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/func-toggles.png b/vendor/github.com/golang/dep/docs/assets/func-toggles.png deleted file mode 100644 index 8e081b30fcf908a8b1e9debaed5f6647e0df1aa6..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/func-toggles.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/in-sync.png b/vendor/github.com/golang/dep/docs/assets/in-sync.png deleted file mode 100644 index 094148a5c04c92d363c4cf3fcf86ab70f9a9f495..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/in-sync.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/lock-back.png b/vendor/github.com/golang/dep/docs/assets/lock-back.png deleted file mode 100644 index ad769756d36b3179018e919d5d4ad6a72eba4d29..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/lock-back.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/assets/required-arrows.png b/vendor/github.com/golang/dep/docs/assets/required-arrows.png deleted file mode 100644 index 791076f991fb7a82b408ce99932718ce32fc1616..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/docs/assets/required-arrows.png and /dev/null differ diff --git a/vendor/github.com/golang/dep/docs/daily-dep.md b/vendor/github.com/golang/dep/docs/daily-dep.md deleted file mode 100644 index faf22617cd98ff40f37f8982dd2480d8447020ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/daily-dep.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: Daily Dep ---- - -This guide is an introduction to the day-to-day use of dep. If you haven't set up a Go project at all yet, though, run through [Creating a New Project](new-project.md) first. - -Dep is a tool you'll use regularly in the course of normal Go development. Regularly, but briefly - dependency management is never the place we want to be spending our time or energy! In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface; there are only two commands you're likely to run regularly: - -* `dep ensure` is the primary workhorse command, and is the only command that changes disk state. -* `dep status` reports on the state of your project, and the visible universe of Go software projects. - -This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [Models and Mechanisms](ensure-mechanics.md) reference document details how the things work under the hood, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). - -## Basics - -Let's start with words! - -Dep's main command is `dep ensure`. The verb is "ensure" to imply that the action is not just some single, discrete action (like adding a dependency), but enforcing some kind of broader guarantee. If we wanted to express the `dep ensure` guarantee as a sentence, it would go something like this: - -> Hey dep, please make sure that [my project](glossary.md#current-project) is [in sync](glossary.md#sync): that [`Gopkg.lock`](Gopkg.lock.md) satisfies all the imports in my project, and all the rules in[ `Gopkg.toml`](Gopkg.toml.md), and that `vendor/` contains exactly what `Gopkg.lock` says it should." - -As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a safe, complete, and reproducible set of dependencies with respect to the current state of your project. You might imagine repeated runs of `dep ensure` as being a bit like a frog, hopping from one lilypad to the next. - - `dep ensure` also guarantees that, barring `kill -9`, power failure, or a critical bug, its disk writes are all-or-nothing: on any given run, either nothing changes (and you get an error), or you're on the nearest safe lilypad. This makes `dep ensure` fine to run at most any time. - - -## Using `dep ensure` - -There are four times when you'll run `dep ensure`: - -- To add a new dependency -- To update an existing dependency -- To catch up after importing a package for the first time in your project, or removing the last import of a package in your project -- To catch up to a change to a rule in `Gopkg.toml` - -There's also an implicit fifth time: when you're not sure if one of the above has happened. Running `dep ensure` without any additional flags will get your project back in sync - a known good state. As such, it's generally safe to defensively run `dep ensure` as a way of simply making sure that your project is in that state. - -Let's explore each of moments. To play along, you'll need to `cd` into a project that's already been set up by `dep init`. If you haven't done that yet, check out the guides for [new projects](new-project.md) and [migrations](migrating.md). - -### Adding a new dependency - -Let's say that we want to introduce a new dependency on `github.com/pkg/errors`. This can be accomplished with one command: - -```bash -$ dep ensure -add github.com/pkg/errors -``` - -> Much like git, `dep status` and `dep ensure` can also be run from any subdirectory of your project root, which is determined by the presence of a `Gopkg.toml` file. - -This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` directory, as well as injecting a best-guess version constraint for `github.com/pkg/errors` into our `Gopkg.toml`. But, it will also report a warning: - -```bash -"github.com/pkg/errors" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/. -If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. -``` - -As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, the sooner the better. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically remove it from `Gopkg.lock` and `vendor/`. This also means that if you want to add multiple dependencies at once, you'll need to do it in a single command, rather than one after the other: - -```bash -$ dep ensure -add github.com/pkg/errors github.com/foo/bar -``` - -Dep works this way because it considers the import statements it discovers through static analysis of your project's code to be the canonical indicator of what dependencies must be present. That choice does add some pain at this moment, but it reduces friction and automates cleanup elsewhere. Tradeoffs! - -Of course, given this model, you don't _have to_ use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. However, this approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. - -The [ensure mechanics section on `-add`](ensure-mechanics.md#add) has a more thorough exploration, including some ways that `dep ensure -add`'s behavior subtly varies depending on the state of your project. - -### Updating dependencies - -Ideally, updating a dependency project to a newer version is a single command: - -```bash -$ dep ensure -update github.com/foo/bar -``` - -This also works without arguments to try to update all dependencies, though it's generally not recommended: - -```bash -$ dep ensure -update -``` - -`dep ensure -update` searches for versions that work with the `branch`, `version`, or `revision` constraint defined in `Gopkg.toml`. These constraint types have different semantics, some of which allow `dep ensure -update` to effectively find a "newer" version, while others will necessitate hand-updating the `Gopkg.toml`. The [ensure mechanics](ensure-mechanics.md#update-and-constraint-types) guide explains this in greater detail, but if you want to know what effect a `dep ensure -update` is likely to have for a particular project, the `LATEST` field in `dep status` output will tell you. - -### Adding and removing `import` statements - -As noted in [the section on adding dependencies](#adding-a-new-dependency), dep relies on the import statements in your code to figure out which dependencies your project actually needs. Thus, when you add or remove import statements, dep might need to care about it. - -It's only "might," though, because most of the time, adding or removing imports doesn't matter to dep. Only if one of the following has occurred will a `dep ensure` be necessary to bring the project back in sync: - -1. You've added the first `import` of a package, but already `import` other packages from that project. -2. You've removed the last `import` of a package, but still `import` other packages from that project. -3. You've added the first `import` of any package within a particular project. (Note: this is the [alternate adding approach](#adding-a-new-dependency)) -4. You've removed the last `import` of a package from within a particular project. - -In short, dep is concerned with the set of unique import paths across your entire project, and only cares when you make a change that adds or removes an import path from that set. - -Of course, especially on large projects, it can be tough to keep track of whether adding or removing (especially removing) a particular import statement actually does change the overall set. Fortunately, you needn't keep close track, as you can run `dep ensure` and it will automatically pick up any additions or removals, and bring your project back in sync. - -Only if it is the first/last import of a project being added/removed - cases 3 and 4 - are additional steps needed: `Gopkg.toml` should be updated to add/remove the corresponding project's `[[constraint]]`. - -### Rule changes in `Gopkg.toml` - -`Gopkg.toml` files contain five basic types of rules. The [`Gopkg.toml` docs](#gopkg.toml.md) explain them in detail, but here's an overview: - -* `required`, which are mostly equivalent to `import` statements in `.go` files, except that it's OK to list a `main` package here -* `ignored`, which causes dep to black hole an import path (and any imports it uniquely introduces) -* `[[constraint]]`, stanzas that express version constraints and some other rules on a per-project dependency basis -* `[[override]]`, stanzas identical to `[[constraint]]` except that only the current project can express them and they supersede `[[constraint]]` in both the current project and dependencies -* `[prune]`, global and per-project rules that govern what kinds of files should be removed from `vendor/` - -Changes to any one of these rules will likely necessitate changes in `Gopkg.lock` and `vendor/`; a single successful `dep ensure` run will incorporate all such changes at once, bringing your project back in sync. - -## Key Takeaways - -Here are the key takeaways from this guide: - -- `dep ensure -update` is the preferred way to update dependencies, though it's less effective for projects that don't publish semver releases. -- `dep ensure -add` is usually the easiest way to introduce new dependencies, though it's not the only one. To add more than one at a time, you'll need to use multiple arguments, not multiple invocations - and make sure to add real `import` statements for the projects after the command completes! -- If you ever make a manual change in `Gopkg.toml`, it's best to run `dep ensure` to make sure everything's in sync. -- `dep ensure` is almost never the wrong thing to run; if you're not sure what's going on, running it will bring you back to safety ("the nearest lilypad"), or fail informatively. - -Also, a couple other miscellaneous tidbits: - -- As in the Go toolchain generally, avoid symlinks within your own project. dep tolerates a bit of this, but like the Go toolchain itself, is generally not terribly supportive of symlinks. -- Never directly edit anything in `vendor/`; dep will unconditionally overwrite such changes. If you need to modify a dependency, fork it and do it properly. - diff --git a/vendor/github.com/golang/dep/docs/deduction.md b/vendor/github.com/golang/dep/docs/deduction.md deleted file mode 100644 index 3675c194a2b26db4ff11c817a4878dc76904fdce..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/deduction.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Import Path Deduction ---- - -Deduction is dep's algorithm for looking at an import path and determining the portion of the path that corresponds to the source root. The algorithm has a static component, by which a small set of known, popular hosts like GitHub and Bitbucket have their roots deduced: - -- `github.com/golang/dep/gps` -> `github.com/golang/dep` -- `bitbucket.org/foo/bar/baz` -> `bitbucket.org/foo/bar` - -The set of hosts supported by static deduction are the same as [those supported by `go get`](https://golang.org/cmd/go/#hdr-Remote_import_paths): - -* GitHub -* Bitbucket -* Launchpad -* IBM DevOps Services - -In addition, dep also handles [gopkg.in](http://gopkg.in) directly with static deduction because, owing to internal implementation details, it is the easiest way of also attaching filters to adapt the versioning semantics of gopkg.in import paths into dep's versioning model. This turns out fine, as gopkg.in's rules mapping rules are themselves entirely static. - -If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component: dep makes an HTTP(S) request to the import path, and a server is expected to send back the root import path embedded within the HTML response. Again, this directly emulates the behavior of `go get`. - -Import path deduction is applied to all of the following: - -* `import` statements found in all `.go` files -* Import paths in the [`required`](gopkg.toml.md#required) list in `Gopkg.toml` -* `name` properties in both [`[[constraint]]`](Gopkg.toml.md#constraint) and [`[[override]]`](Gopkg.toml.md#override) stanzas in `Gopkg.toml`. This is solely for validation purposes, enforcing that these names correspond only to project/source roots. - diff --git a/vendor/github.com/golang/dep/docs/ensure-mechanics.md b/vendor/github.com/golang/dep/docs/ensure-mechanics.md deleted file mode 100644 index e7173425a8625fef954dc6cc3549dd0cd0640199..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/ensure-mechanics.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -title: Models and Mechanisms ---- - -While dep has many discrete components and moving parts, all of these parts revolve around a central model. This document explains that model, then explores the dep's primary mechanisms in the context of that model. - -## States and flows - -Dep is centered around the idea of the "four state system" - a model for classifying and organizing the on-disk state with which a package manager interacts. This was first articulated as a coherent, general model in [this (long) article](https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527), though many of the principles in the four state model were derived from existing package managers. - -Briefly, the four states are: - -1. The [current project's](glossary.md#current-project) source code. -2. A [manifest](glossary.md#manifest) - a file describing the current project's dependency requirements. In dep, this is the [`Gopkg.toml`](Gopkg.toml.md) file. -3. A [lock](glossary.md#lock) - a file containing a transitively-complete, reproducible description of the dependency graph. In dep, this is the [`Gopkg.lock`](Gopkg.lock.md) file. -4. The source code of the dependences themselves. In dep's current design, this is the `vendor/` directory. - -We can visually represent these four states as follows: - - - -### Functional flow - -It's useful to think of dep as a system that imposes a unidirectional, functional flow on the relationships between these states. These functions treat the above states as inputs and outputs, moving them from left to right. Specifically, there are two functions: - -* A _solving function_, that takes as its input the set of imports in the current project and the rules in `Gopkg.toml`, and returns as its output a transitively-complete, immutable dependency graph - the information in a `Gopkg.lock`. -* A _vendoring function_, that takes the information in a `Gopkg.lock` as its input and ensures an on-disk arrangement of source files such that the compiler will use the versions designated in the lock. - -We can represent these two functions visually: - - - -This is `dep ensure` - the typical flow, used when a `Gopkg.toml` already exists. When a project does not yet have a `Gopkg.toml`, `dep init` can generate one. The essential flow remains the same, but with changed inputs: instead of reading from an existing `Gopkg.toml` file, `dep init` constructs one out of data inferred from the user's GOPATH, and/or [a metadata file from another tool](). (In other words, `dep init` automatically migrates a project from other approaches to organizing dependencies.) - -This diagram directly corresponds directly to code, as well. The solving function is actually split into a constructor and a method - we first create a [`Solver`](https://godoc.org/github.com/golang/dep/gps#Solver) type, then call its `Solve()` method. The inputs to the constructor are wrapped up in a [`SolveParameters`](https://godoc.org/github.com/golang/dep/gps#SolveParameters), which should look familiar: - -```go -type SolveParameters struct { - RootPackageTree pkgtree.PackageTree // Parsed project src; contains lists of imports - Manifest gps.RootManifest // Gopkg.toml - ... -} -``` - -The vendoring function is [`gps.WriteDepTree()`](https://godoc.org/github.com/golang/dep/gps#WriteDepTree). While it takes a handful of arguments, the relevant one is a [`gps.Lock`](https://godoc.org/github.com/golang/dep/gps#Lock) - an interface representing an abstracted form of the data held in a `Gopkg.lock`. - -The four state system, and these functional flows through it, are the foundation on which all of dep's behavior is built. If you want to understand dep's mechanics, keep this model at the forefront of your mind. - -### Staying in sync - -One of dep's design goals is that both of its "functions" minimize both the work they do, and the change they induce in their respective results. (Note: "minimize" is not currently formally defined with respect to a cost function.) Consequently, both functions peek ahead at the pre-existing result to understand what work actually needs to be done: - -* The solving function checks the existing `Gopkg.lock` to determine if all of its inputs (project import statements + `Gopkg.toml` rules) are satisfied. If they are, the solving function can be bypassed entirely. If not, the solving function proceeds, but attempts to change as few of the selections in `Gopkg.lock` as possible. - * WIP: The current implementation's check relies on a coarse heuristic check that can be wrong in some cases. There is a [plan to fix this](https://github.com/golang/dep/issues/1496). -* The vendoring function hashes each discrete project already in `vendor/` to see if the code present on disk is what `Gopkg.lock` indicates it should be. Only projects that deviate from expectations are written out. - * WIP: the hashing check is generally referred to as "vendor verification," and [is not yet complete](https://github.com/golang/dep/issues/121). Without this verification, dep is blind to whether code in `vendor/` is correct or not; as such, dep must defensively re-write all projects to ensure the state of `vendor/` is correct. - -Of course, it's possible that, in peeking ahead, either function might discover that the pre-existing result is already correct - so no work need be done at all. Either way, when each function completes, we can be sure that the output, changed or not, is correct with respect to the inputs. In other words, the inputs and outputs are "in sync." Indeed, being in sync is the "known good state" of dep; `dep ensure` (without flags) guarantees that if it exits 0, all four states in the project are in sync. - -## `dep ensure` flags and behavior variations - -Each of `dep ensure`'s various flags affects the behavior of the solving and vendoring functions - or even whether they run at all. Some flags can also marginally push the project out of sync, temporarily. Thinking about these effects in the context of dep's basic model is the fastest path to understanding. - -### `-no-vendor` and `-vendor-only` - -These two flags are mutually exclusive, and determine which of `dep ensure`'s two functions are actually performed. Passing `-no-vendor` will cause only the solving function to be run, resulting in the creation of a new `Gopkg.lock`; `-vendor-only` will skip solving and run only the vendoring function, causing `vendor/` to be repopulated from the pre-existing `Gopkg.lock`. - - - -Passing `-no-vendor` has the additional effect of causing the solving function to run unconditionally, bypassing the pre-check ordinarily made against `Gopkg.lock` to see if it already satisfies all inputs. - -### `-add` - -The general purpose of `dep ensure -add` is to facilitate the introduction of new dependencies into the depgraph. Whereas `-update` is restricted to [source roots](glossary.md#source-root), (e.g. `github.com/foo/bar`), `-add` can take any package import path as an argument (e.g. `github.com/foo/bar` OR `github.com/foo/bar/baz`). - -Conceptually, there are two possible things that `-add` might be introducing. Any `dep ensure -add` run will do at least one of these: - -1. Running the solving function in order to generate a new `Gopkg.lock` with the new dependenc(ies) -2. Appending a version constraint into `Gopkg.toml` - -This implies two preconditions for `dep ensure -add`, at least one of which must be met: - -1. The named import path is not currently in the project's import statements, or in `Gopkg.toml`'s `required` list -2. There is no `[[constraint]]` stanza in `Gopkg.toml` for the project root corresponding to the named import path - - -It is also possible to explicitly specify a version constraint: - -```bash -$ dep ensure -add github.com/foo/bar@v1.0.0 -``` - -When no version constraint is included in the argument, the solving function will select the latest version that works (generally, the newest semver release, or the default branch if there are no semver releases). If solving succeeds, then either the argument-specified version, or if none then the version selected by the solver, will be appended into `Gopkg.toml`. - -The behavioral variations that arise from the assorted differences in input and current project state are best expressed as a matrix: - -| Argument to `dep ensure -add` | Has `[[constraint]]` stanza in `Gopkg.toml` | In imports or `required` | Result | -| ----------------------------- | ---------------------------------------- | ------------------------ | ---------------------------------------- | -| `github.com/foo/bar` | N | N | Added temporarily to `Gopkg.lock` & `vendor/`; inferred version constraint appended to `Gopkg.toml` | -| `github.com/foo/bar@v1.0.0` | N | N | Added temporarily to `Gopkg.lock` & `vendor/`; specified version constraint appended to `Gopkg.toml` | -| `github.com/foo/bar` | Y | N | Added temporarily to `Gopkg.lock` & `vendor/` | -| `github.com/foo/bar@v1.0.0` | Y | - | **Immediate error**: constraint already present in `Gopkg.toml` | -| `github.com/foo/bar` | N | Y | Infer version constraint from `Gopkg.lock` and add to `Gopkg.toml` | -| `github.com/foo/bar` | Y | Y | **Immediate error:** nothing to do | - -For any of the paths where `dep ensure -add` needs to run the solving function in order to generate an updated `Gopkg.lock`, the relevant information from CLI arguments is applied to the in-memory representation of `Gopkg.toml`: - - - -Import path arguments that need to be added are injected via the `required` list, and if an explicit version requirement was specified, the equivalent of a `[[constraint]]` is created. - -Though these rules may ultimately be persisted if solving succeeds, they are ephemeral at least until solving succeeds. And, from the solver's perspective, the ephemeral rules are indistinguishable from rules sourced directly from disk. Thus, to the solver, `dep ensure -add foo@v1.0.0` is identical to modifying `Gopkg.toml` by adding `"foo"` to the `required` list, plus a `[[constraint]]` stanza with `version = "v1.0.0"`, then running `dep ensure`. - -However, because these modifications are ephemeral, a successful `dep ensure -add` may actually push the project out of sync. Constraint modifications generally do not, but if the `required` list is modified, then the project will desync. The user is warned accordingly: - -```bash -$ dep ensure -add github.com/foo/bar -"github.com/foo/bar" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/. -If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. -``` - -### `-update` - -The behavior of `dep ensure -update` is intimately linked to the behavior of the solver itself. Full detail on that is a topic for the [solver reference material](the-solver.md), but for the purposes of understanding `-update`, we can simplify a bit. - -First, to solidify an implication in the discussion of [functional optimizations](#staying-in-sync), the solving function actually takes into account the pre-existing `Gopkg.lock` when it runs: - - - -Injecting `Gopkg.lock` into the solver is a necessity. If we want the solver to preserve previously-selected versions by default, then the solver has to learn about the existing `Gopkg.lock` from somewhere. Otherwise, it wouldn't know what to preserve! - -As such, the lock is another one of the properties encoded onto the [previously-discussed]() `SolveParameters` struct. That, plus two other properties, are the salient ones for `-update`: - -```go -type SolveParameters struct { - ... - Lock gps.Lock // Gopkg.lock - ToChange []gps.ProjectRoot // args to -update - ChangeAll bool // true if no -update args passed - ... -} -``` - -Ordinarily, when the solver encounters a project name for which there's an entry in `Gopkg.lock`, it pulls that version out and puts it at the head of the queue of possible versions for that project. When a specific dependency is passed to `dep ensure -update`, however, it is added to the `ToChange` list; when the solver encounters a project listed in `ToChange`, it simply skips pulling the version from the lock. - -"Skips pulling the version from the lock" would imply that `dep ensure -update github.com/foo/bar` is equivalent to removing the `[[project]]` stanza for `github.com/foo/bar` from your `Gopkg.lock`, then running `dep ensure`. And indeed it is - however, that approach is not recommended, and subtle changes may be introduced in the future that complicate the equivalency. - -If `-update` is passed with no arguments, then `ChangeAll` is set to `true`, resulting in the solver ignoring `Gopkg.lock` for all newly-encountered project names. This is equivalent to explicitly passing all of your dependences as arguments to `dep ensure -update`, as well as `rm Gopkg.lock && dep ensure`. Again, however, neither of these approaches are recommended, and future changes may introduce subtle differences. - -When a version hint from `Gopkg.lock` is not placed at the head of the version queue, it means that dep will explore the set of possible versions for a particular dependency. This exploration is performed according to a [fixed sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade), where newer versions are tried first, resulting in an update. - -For example, say there is a project, `github.com/foo/bar`, with the following versions: - -```bash -v1.2.0, v1.1.1, v1.1.0, v1.0.0, master -``` - -If we depend on that project with `^1.1.0`, and have `v1.1.0` in our `Gopkg.lock` , then it means there are three versions that match our constraint, and two of them are newer than the one currently selected. (There's also an older version, `v1.0.0`, and a `master` branch, but these aren't allowed by a `^1.1.0` constraint.) An ordinary `dep ensure` run will duplicate and push `v1.1.0` ahead of all the others in the queue: - -```bash -[v1.1.0, v1.2.0, v1.1.1, v1.1.0, v1.0.0, master] -``` - -And `v1.1.0` will be selected again, unless some other condition is presented that forces the solver to discard it. When running `dep ensure -update github.com/foo/bar`, however, the locked version is not prepended: - -```bash -[v1.2.0, v1.1.1, v1.1.0, v1.0.0, master] -``` - -So, barring some other conflict, `v1.2.0` is selected, resulting in the desired update. - -#### `-update` and constraint types - -Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version. It just skips adding a hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. - -It does work with branch constraints, which we can observe by including the underlying revision. If the user has constrained on `branch = "master"`, and `Gopkg.lock` points at a topologically older revision (say, `aabbccd`) than the tip of the canonical source's `master` branch (say, `bbccdde`), then `dep ensure` will end up contructing a queue that looks like this: - -```bash -[master@aabbccd, v1.1.0, v1.2.0, v1.1.1, v1.1.0, v1.0.0, master@bbccdde] -``` - -With `-update`, the hint at the head will be omitted; `branch = "master"` will cause the solver to reject all of the semantic versions, and finally settle on `master@bbccdde`. - -All versions in the version queue keep track of an underlying revision, which means the same is true if, for example, some upstream project force-pushes a git tag: - -```bash -[v1.1.0@aabbccd, v1.1.0, v1.2.0, v1.1.1, v1.1.0@bbccdde, v1.0.0, master] -``` - -Thus, even if an upstream tag is force-pushed in one of your project's dependences, dep will retain the original revision until you explicitly allow it to change via a `dep ensure -update`. - -The key takeaway here is that `-update`'s behavior is governed by the type of constraints specified: - -| `Gopkg.toml` version constraint type | Constraint example | `dep ensure -update` behavior | -| ------------------------------------ | ------------------ | ---------------------------------------- | -| `version` (semver range) | `"^1.0.0"` | Tries to get the latest version allowed by the range | -| `branch` | `"master"` | Tries to move to the current tip of the named branch | -| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved (e.g. `git push --force <tag>`) | -| `version` (non-semver) | `"foo"` | Change can only occur if the upstream release was moved | -| `revision` | `aabbccd...` | No change is possible | -| (none) | (none) | The first version that works, according to [the sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade) (not recommended) | - - diff --git a/vendor/github.com/golang/dep/docs/failure-modes.md b/vendor/github.com/golang/dep/docs/failure-modes.md deleted file mode 100644 index f06acca0a7b970f04fcf6a5921351a1e293e9fc1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/failure-modes.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Failure Modes ---- - -Like all complex, network-oriented software, dep has known failure modes. These generally fall into two categories: I/O and logical. I/O errors arise from unexpected responses to system calls that interact with the network or local disk. Logical failures occur when dep encounters issues within the package management problem domain. - -## I/O errors - -dep reads from the network, and reads and writes to disk, and is thus subject to all the typical errors that are possible with such activities: full disks, failed disks, lack of permissions, network partitions, firewalls, etc. However, there are three classes of I/O errors that are worth addressing specifically: - -* Network failures -* Bad local cache state -* `vendor` write errors - -In general, these problems aren't things we can reasonably program around in dep. Therefore, they can't be considered bugs for us to fix. Fortunately, most of these problems have straightforward remediations. - -### Network failures - -> **Remediation tl;dr:** most network issues are ephemeral, even if they may last for a few minutes, and can be addressed simply by re-running the same command. Always try this before attempting more invasive solutions. - -dep talks to the network at several different points. These vary somewhat depending on source (VCS) type and local disk state, but this list of operations is generally instructive: - -* When dep cannot [statically deduce](deduction.md#static-deduction) the source root of an import path, it issues a `go-get` HTTP metadata request to a URL constructed from the import path. -* Retrieving the list of available versions for a source (think `git ls-remote`) necessarily requires network activity. -* Initially downloading (in git terms, `git clone`) an upstream source into the local cache also necessarily requires network activity. -* Updating a local cache (in git terms, `git fetch`) with the latest changes from an upstream source. -* Writing out code trees under `vendor` is typically done from the local cache, but under some circumstances a tarball may be fetched on-the-fly from a remote source. - - -Network failures that you actually may observe are biased towards the earlier items in the list, simply because those operations tend to happen first: you generally don't see update failures as much as version-listing failures, because they usually have the same underlying cause (source host is down, network partition, etc.), but the version-list request happens first on most paths. - -#### Persistent network failures - -Although most network failures are ephemeral, there are three well-defined cases where they're more permanent: - -* **The network on which the source resides is permanently unreachable from the user's location:** in practice, this generally means one of two things: you've forgotten to log into your company VPN, or you're behind [the GFW](https://en.wikipedia.org/wiki/Great_Firewall). In the latter case, setting the *de facto* standard HTTP proxy environment variables that [`http.ProxyFromEnvironment()`](https://golang.org/pkg/net/http/#ProxyFromEnvironment) respects will cause dep's `go-get` HTTP metadata requests, as well as git, bzr, and hg subcommands, to utilize the proxy. - - * Remediation is also exactly the same when the custom `go-get` HTTP metadata service for a source is similarly unreachable. The failure messages, however, will look like [deduction failures](#deduction-failures). - -* **The source has been permanently deleted or moved:** these are [left-pad](https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/) events, though note that [GitHub automatically redirects traffic after renames](https://help.github.com/articles/renaming-a-repository/), mitigating the rename problem. But, if an upstream source is removed, dep will be unable to proceed until a new upstream source is established for the import path. To that end: - - * If you still have a copy of the source repository in your local cache or GOPATH, consider uploading it to a new location (e.g. forking it) and using a [`source`](Gopkg.toml.md#source) rule to point to the fork. - * If you don't have a whole repository locally, then extracting the code currently in your `vendor` directory into a new repository and pushing it to a . (Note: this may have licensing implications.) - * If you have no instances of the code locally, then there's little that can be done - that code is simply gone, and you'll need to refactor your project. - - Future versions of dep will be able to better handle an interim period before a new upstream/forked source is created, or simply living in a world where a given code tree exists solely in your project's `vendor` directory. - -* **The user lacks the necessary credentials to interact with a source:** see the [FAQ on configuring credentials](FAQ.md#how-do-i-get-dep-to-authenticate-to-a-git-repo). - -The exact error text will vary depending on which of the operations is running, what type of source dep is trying to communicate with, and what actual network problem has occurred. The error text may not always make it immediately clear which combination of these you're dealing with, but for persistent problems, it should at least reduce the search space. - -#### Hangs - -> **Remediation tl;dr:** hangs are almost always network congestion, or sheer amount of network data to fetch. Wait, or cancel and try again with `-v` to try to get more context. - -Almost any case where a dep command, run with `-v`, hangs for more than ten minutes will ultimately be a bug. However, the most common explanation for an apparent dep hangs is actually normal behavior: because dep's operation requires that it keep its own copies of upstream sources hidden away in the [local cache](glossary.md#local-cache), the first run of dep against a project, especially large projects, can take a long time while it populates the cache. - -The only known case where dep may hang indefinitely is if one of the underlying VCS binaries it calls is prompting for some kind of input. Typically this means credentials (though not always - make sure to accept remote hosts' SSH keys into your known hosts!), and dep's normal assumption is that necessary credentials have been provided via environmental mechanisms - [configuration files or daemons](FAQ.md#how-do-i-get-dep-to-authenticate-to-a-git-repo), SSH agents, etc. This assumption is necessary for dep's concurrent network activity to work. If your use case absolutely cannot support the use of any such environmental caching mechanism, [please weigh in on this issue](). - -Unfortunately, until dep [improves the observability of its ongoing I/O operations](), it cannot accurately report to the user which operations are actually underway at any given moment. This can make it difficult to differentiate from other hangs - credentials prompts, long network timeouts induced by firewalls, sluggish TCP when faced with packet loss, etc. - -### Bad local cache state - -> **Remediation tl;dr:** Remove the local cache dir: `rm -rf $GOPATH/pkg/dep/sources`. - -It is possible for parts of the [local cache](glossary.md#local-cache) maintained by dep to get into a bad state. This primarily happens when dep processes are forcibly terminated (e.g. Ctrl-C). This can, for example, terminate a `git` command partway through, leaving bad state on disk. By dep's definition, a [dirty git working copy]() is bad state. - -The error messages arising from bad local cache state often do not include full paths, so it may not be immediately obvious that problems are originating in the local cache. If full paths aren't included, then the best hint tends to be that the errors look like local VCS errors, but they're not on files from your own project. - -However, for the most part, **dep automatically discovers and recovers from bad local cache state problems**, rebounding back into a good state as it bootstraps each command execution. If you do encounter what appears to be a local cache problem from which dep does not automatically recover, then the fix is typically to just throw out the cache, `rm -rf $GOPATH/pkg/dep/sources`; dep will repopulate it automatically on the next run. However, if you have time, please preserve the local cache dir and report it as a bug! - -There are no known cases where, in the course of normal operations, dep can irreparably corrupt its own local cache. Any such case would be considered a critical bug in dep, and you should report it! If you think you've encountered such a case, it should have the following characteristics: - -* The error message you're seeing is consistent with some sort of disk state error in a downloaded source within `$GOPATH/pkg/dep/sources` -* You can identify a bad state (generally: a vcs "status"-type command will either fail outright, or report a modified working tree) in a subdirectory of `$GOPATH/pkg/dep/sources` suggested by the above error -* The exact same error recurs after removing the local cache dir and running the same command, **without** prematurely terminating the project (e.g. via Ctrl-C) - -### `vendor` write errors - -Dep may encounter errors while attempting to write out the `vendor` directory itself (any such errors will result in a full rollback; causing no changes to be made to disk). To help pinpoint where the problem may be, know that this is the flow for populating `vendor`: - -1. Allocate a new temporary directory within the system temporary directory. -2. Rename the existing `vendor` directory to `vendor.orig`. Do this within the current project's root directory if possible; if not, rename and move it to the tempdir. -3. Create a new `vendor` directory within the tempdir and concurrently populate it with all the projects named in `Gopkg.lock`. -4. Move the new `vendor` directory into place in the current project's root directory. -5. Delete the old `vendor` directory. - -Note: this flow will become more targeted after [vendor verification]() allows dep to identify and target the subset of projects currently in `vendor` that need to be changed. - -Known problems in this category include: - -* Insufficient space in the temporary directory will cause an error, triggering a rollback. However, because the rollback process cleans up files written so-far, the temporary partition won't actually be full after dep exits, which can be misleading. -* Attempting to [re]move the original `vendor` directory can fail with permissions errors if any of the files therein are "open", in some editors/on some OSes (particularly Windows). [There's an issue for this](). - -## Logical failures - -Logical failures encompass everything that can happen within dep's logical problem-solving domain - after - -Some of these failures can be as straightforward as typos, and are just as easily resolved. Others, unfortunately, may necessitate forking and modifying an upstream project - although such cases are very rare. - -### Deduction failures - -Import path deduction, as detailed in the [deduction reference](deduction.md), has both static and dynamic phases. When neither of these phases is able to determine the source root for a given import path, it is considered to be a deduction failure. Deduction failures all contain this key error text: - -```bash -...unable to deduce repository and source type for "<bad path>"... -``` - -_Note: there are [more varied error messages for the small subset of cases](#malformed-import-paths) where an import path appears to be deducible, but is somehow malformed._ - -When a deduction failure occurs on a given import path, the proximal cause will have been one of following five scenarios (arranged from most to least likely): - -* The import path was never deducible. -* **Dynamic deduction failures:** - * The import path was, at one time, dynamically deducible, and the metadata service for it is up, but it is unreachable by dep. - * The import path was, at one time, dynamically deducible, but the metadata service for it is down. -* **Static rule changes:** - * The import path cannot be statically deduced by the running version of dep, but a newer version of dep has added rules that can statically deduce it. - * The import path was once statically deducible, but the running version of dep has discontinued support for it. - -In all of these cases, your last recourse will be to add a [`source`](Gopkg.toml.md#source) directive to fix the problem. However, these directives are brittle, and should only be used when other options have been exhausted; also, until [this problem is solved](https://github.com/golang/dep/issues/860), even `source` may not be able to help. - -#### Undeducible paths - -> **Remediation tl;dr:** You made a typo; fix it. If not, you may need a `source`, but be sparing with those. - -The most likely cause of deduction failure is minor user error. Specifically, the user is the _current_ user (you), and the error is there is a mistyped import path somewhere in the current (your) project. The problem may be in your `Gopkg.toml`, or one of your imports, but the error message should point you directly at the problem, and the solution is usually obvious - e.g., "gihtub". - -Validation of the inputs from the current project are made fast and up front in dep, so these errors will tend to present themselves immediately. Between this fast validation, and the fact that projects are typically uncompilable, or at least not `go get`-able, with these kinds of errors, they tend to be caught early. This is why truly undeducible paths pop up primarily as temporary accidents while hacking on your own projects - you have to fix them to move on. - -That undeducibility is an immediate and hard blocker, however, has led to this being a sticking point for migration to dep. In particular, there are two issues: - -* Several other Go dependency management tools do allow specifying arbitrary VCS/source URLs, and [but support for that via `source` in dep is still pending](https://github.com/golang/dep/issues/860). -* GitHub Enterprise only implements `go-get` HTTP metadata correctly for the root package of a repository. In practice, this makes all import paths pointing to GHE undeducible, and `source` can't help either without the aforementioned improvement. - -If the problem import path is in your current project, but the problem isn't an obvious typo, then you're likely experiencing a dynamic failure, or may need to check the [deduction reference](deduction.md) to understand what what a deducible import path looks like. - -#### Dynamic deduction failures - -Most dynamic deduction failures are either ephemeral network or service availability issues, and will go away by re-running the previous command. Always try that first. - -If the issue persists, and you're certain the import path should be deducible, network issues are the first culprit to check. The typical causes (VPN, firewalls) and remediation for when a metadata service is unreachable are the same as [when a source itself is unreachable](#persistent-network-failures). - -The next possibility is a metadata service that's permanently gone away. Whereas network errors are still reasonably common, it is rare to encounter an import path pointing to a defunct public metadata service. Consider: that one import path can render the entire project unfetchable and/or uncompilable, and neither of those are states that popular projects can afford to be in for long. So, being that most (public Go ecosystem) dependencies are on the more popular projects, as long as you're also depending on the more popular projects, you're unlikely to encounter this. - -Of course, defunct _private_ metadata services may be much more common, as they are subject to entirely different incentives. - -If you think you've encountered a defunct metadata service, try probing the domain portion of the import path directly to see if there is an HTTP(S) server there at all. If not, you can only force with `source` - assuming you know what source URL you should use. If not, you may need to refactor your code (if the problem is in your project), pick a different version of the problem dependency, or drop the problem dependency entirely; sometimes, you just have to get rid of dead code. - -#### Static rule changes - -> **Remediation tl;dr:** make sure you have the latest released version of dep. - -Static rule changes are very unlikely to be the cause of your deduction failures. - -It is plausible that dep will add new static deduction rules in the future. And it is possible that, if you have an older version of dep, and you collaborate with or pull in code from someone using a newer version of dep, then their code may take advantage of new import path patterns that your dep doesn't know about yet. But very, very few static rules additions are likely to ever be made to dep over its lifetime - and getting access to them is just a question of updating once. - -The final scenario - dep discontinuing support for a static deduction pattern - is included for clarity and completeness, but simply should never happen. Even if a hosting service covered by static rules today were to shut down, dep would retain the existing static rules; if hosted code had been migrated elsewhere, then dep would attempt to perform a remapping automatically. If no such remapping were possible, then dep would still recognize the basic host pattern, but may fall back on using malformed import path errors - the next topic - to informatively reject new imports from the host. - -#### Malformed import paths - -For the most part, static ("is it one of the handful of hosts we know?") and dynamic ("just do whatever the metadata service tells us to do") deduction are single-pass checks. However, both cases can perform some minor additional validation: - -* In static deduction, the rules are necessarily specific to each host, but most enforce allowable characters and schemes in URLs that are known to be required by the underlying host. -* In dynamic deduction, responses from the metadata service are minimally validated to ensure that the source type and scheme are all supported, and that the URL contains valid characters. - -### Solving failures - -When `dep ensure` or `dep init` exit with an error message looking something like this: - -```bash -$ dep init -init failed: unable to solve the dependency graph: Solving failure: No versions of github.com/foo/bar met constraints: - v1.0.1: Could not introduce github.com/foo/bar@v1.13.1, as its subpackage github.com/foo/bar/foo is missing. (Package is required by (root).) - v1.0.0: Could not introduce github.com/foo/bar@v1.13.0, as... - v0.1.0: (another error) - master: (another error) -``` - -_Note: all three of the other hard failure types can sometimes be reported as the errors for individual versions in a list like this. This primarily happens because dep is in need of a [thorough refactor of its error handling](https://github.com/golang/dep/issues/288)._ - -It means that the solver was unable to find a combination of versions for all dependencies that satisfy all the rules enforced by the solver. It is crucial to note that, just because dep provides a big list of reasons why each version failed _doesn't mean_ you have to address each one! That's just dep telling you why it ultimately couldn't use each of those versions in a solution. - -These rules, and specific remediations for failing to meet them, are described in detail in the section on [solver invariants](the-solver.md#solving-invariants). This section is about the steps to take when solving failures occur in general. But, to set context, here's a summary: - -* **`[[constraint]]` conflicts:** when projects in the dependency graph disagree on what [versions](gopkg.toml.md#version-rules) are acceptable for a project, or where to [source](gopkg.toml.md#source) it from. - * Remediation will usually be either changing a `[[constraint]]` or adding an `[[override]]`, but genuine conflicts may require forking and hacking code. -* **Package validity failure:** when an imported package is quite obviously not capable of being built. - * There usually isn't much remediation here beyond "stop importing that," as it indicates something broken at a particular version. -* **Import comment failure:** when the import path used to address a package differs from the [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) the package uses to specify how it should be imported. - * Remediation is to use the specified import path, instead of whichever one you used. -* **Case-only import variation failure:** when two equal-except-for-case imports exist in the same build. - * Remediation is to pick one case variation to use throughout your project, then manually update all projects in your depgraph to use the new casing. - - -Let's break down the process of addressing a solving failure into a series of steps: - -1. First, look through the failed versions list for a version of the dependency that works for you (or a failure that seems fixable), then try to work that one out. Often enough, you'll see a single failure repeated across the entire version list, which makes it pretty clear what problem you need to solve. -2. Take the remediation steps specific to that failure. -3. Re-run the same command you ran that produced the failure. There are three possible outcomes: - 1. Success! - 2. Your fix was ineffective - the same failure re-occurs. Either re-examine your fix (step 2), or look for a new failure to fix (step 1). - 3. Your fix was effective, but some new failure arose. Return to step 1 with the new failure list. - diff --git a/vendor/github.com/golang/dep/docs/glossary.md b/vendor/github.com/golang/dep/docs/glossary.md deleted file mode 100644 index 0cb3aab9324c72c8c5a703b38512d8c995a96956..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/glossary.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: glossary -title: Glossary ---- - -dep uses some specialized terminology. Learn about it here! - -* [Atom](#atom) -* [Cache lock](#cache-lock) -* [Constraint](#constraint) -* [Current Project](#current-project) -* [Deducible](#deducible) -* [Deduction](#deduction) -* [Direct Dependency](#direct-dependency) -* [External Import](#external-import) -* [GPS](#gps) -* [Local cache](#local-cache) -* [Lock](#lock) -* [Manifest](#manifest) -* [Metadata Service](#metadata-service) -* [Override](#override) -* [Project](#project) -* [Project Root](#project-root) -* [Solver](#solver) -* [Source](#source) -* [Source Root](#source-root) -* [Sync](#sync) -* [Transitive Dependency](#transitive-dependency) - ---- - -### Atom - -Atoms are a source at a particular version. In practice, this means a two-tuple of [project root](#project-root) and version, e.g. `github.com/foo/bar@master`. Atoms are primarily internal to the [solver](#solver), and the term is rarely used elsewhere. - -### Cache lock - -Also "cache lock file." A file, named `sm.lock`, used to ensure only a single dep process operates on the [local cache](#local-cache) at a time, as it is unsafe in dep's current design for multiple processes to access the local cache. - -### Constraint - -Constraints have both a narrow and a looser meaning. The narrow sense refers to a [`[[constraint]]`](Gopkg.toml.md#constraint) stanza in `Gopkg.toml`. However, in some contexts, the word may be used more loosely to refer to the idea of applying rules and requirements to dependency management in general. - -### Current Project - -The project on which dep is operating - writing its `Gopkg.lock` and populating its `vendor` directory. - -Also called the "root project." - -### Deducible - -A shorthand way of referring to whether or not import path [deduction](#deduction) will return successfully for a given import path. "Undeducible" is also often used, to refer to an import path for which deduction fails. - -### Deduction - -Deduction is the process of determining the subset of an import path that corresponds to a source root. Some patterns are known a priori (static); others must be discovered via network requests (dynamic). See the reference on [import path deduction](deduction.md) for specifics. - -### Direct Dependency - -A project's direct dependencies are those that it _imports_ from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. - - If each letter in `A -> B -> C -> D` represents a distinct project containing only a single package, and `->` indicates an import statement, then `B` is `A`'s direct dependency, whereas `C` and `D` are [transitive dependencies](#transitive-dependency) of `A`. - -Dep only incorporates the `required` rules from the [current project's](#current-project) `Gopkg.toml`. Therefore, if `=>` represents `required` rather than a standard import, and `A -> B => C`, then `C` is a direct dependency of `B` _only_ when `B` is the current project. Because the `B`-to-`C` link does not exist when `A` is the current project, then `C` won't actually be in the graph at all. - -### External Import - -An `import` statement that points to a package in a project other than the one in which it originates. For example, an `import` in package `github.com/foo/bar` will be considered an external import if it points to anything _other_ than stdlib or `github.com/foo/bar/*`. - -### GPS - -Stands for "Go packaging solver", it is [a subtree of library-style packages within dep](https://godoc.org/github.com/golang/dep/gps), and is the engine around which dep is built. Most commonly referred to as "gps." - -### Local cache - -dep maintains its own, pristine set of upstream sources (so, generally, git repository clones). This is kept separate from `$GOPATH/src` so that there is no obligation to maintain disk state within `$GOPATH`, as dep frequently needs to change disk state in order to do its work. - -By default, the local cache lives at `$GOPATH/pkg/dep`. If you have multiple `$GOPATH` entries, dep will use whichever is the logical parent of the process' working directory. Alternatively, the location can be forced via the `DEPCACHEDIR` environment variable. - -### Lock - -A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.lock` file. - -### Manifest - -A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.toml` file. - -### Metadata Service - -An HTTP service that, when it receives an HTTP request containing a `go-get=1` in the query string, treats interprets the path portion of the request as an import path, and responds by embedding data in HTML `<meta>` tags that indicate the type and URL of of the underlying source root. This is the server-side component of dynamic [deduction](#deduction). - -The behavior of metadata services is defined in the [Go documentation on remote import paths](https://golang.org/cmd/go/#hdr-Remote_import_paths). - -Variously referenced as "HTTP metadata service", "`go-get` HTTP metadata service", "`go-get` service", etc. - -### Override - -An override is a [`[[override]]`](Gopkg.toml.md#override) stanza in `Gopkg.toml`. - -### Project - -A project is a tree of Go packages. Projects cannot be nested. See [Project Root](#project-root) for more information about how the root of the tree is determined. - -### Project Root - -The root import path for a project. A project root is defined as: - -* For the current project, the location of the `Gopkg.toml` file defines the project root -* For dependencies, the root of the network [source](#source) (VCS repository) is treated as the project root - -These are generally one and the same, though not always. When using dep inside a monorepo, multiple `Gopkg.toml` files may exist at subpaths for discrete projects, designating each of those import paths as Project Roots. This works fine when working directly on those projects. If, however, any project not in the repository seeks to import the monorepo, dep will treat the monorepo's as one big Project, with the root directory being the Project Root; it will disregard any and all `Gopkg.toml` files in subdirectories. - -This may also be referred to as the "import root" or "root import path." - -### Solver - -"The solver" is a reference to the domain-specific SAT solver contained in [gps](#gps). More detail can be found on its [reference page](the-solver.md). - -### Source - -The remote entities that hold versioned code. Sources are specifically the entity containing the code, not any particular version of thecode itself. - -"Source" is used in lieu of "VCS" because Go package management tools will soon learn to use more than just VCS systems. - -### Source Root - -The portion of an import path that corresponds to the network location of a source. This is similar to [Project Root](#project-root), but refers strictly to the second, network-oriented definition. - -### Sync - -Dep's interaction model is based around the idea of maintaining a well-defined relationship between your project's import statements and `Gopkg.toml`, and your project's `Gopkg.lock` - keeping them "in sync". When the `Gopkg.lock` has more or fewer entries than are necessary, or entries that are incompatible with constraint rules established in `Gopkg.toml`, your project is "out of sync". - -This concept is explored in detail on [the ensure mechanics reference page](ensure-mechanics.md#staying-in-sync). - -### Transitive Dependency - -A project's transitive dependencies are those dependencies that it does not import itself, but are imported by one of its dependencies. - -If each letter in `A -> B -> C -> D` represents a distinct project containing only a single package, and `->` indicates an import statement, then `C` and `D` are `A`'s transitive dependencies, whereas `B` is a [direct dependency](#transitive-dependency) of `A`. \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/installation.md b/vendor/github.com/golang/dep/docs/installation.md deleted file mode 100644 index 75171815b8425cab6bef302b900ec7fd199db81e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/installation.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Installation ---- - -It is strongly recommended that you use a released version of dep. While tip is never purposefully broken, its stability is not guaranteed. - -Pre-compiled binaries are available on the [releases](https://github.com/golang/dep/releases) page. On MacOS, you can also install or upgrade to the latest released version with Homebrew: - -```sh -$ brew install dep -$ brew upgrade dep -``` - -If you want to hack on dep, you can install via `go get`: - -```sh -go get -u github.com/golang/dep/cmd/dep -``` -Note that dep requires a functioning Go workspace and GOPATH. If you're unfamiliar with Go workspaces and GOPATH, have a look at [the language documentation](https://golang.org/doc/code.html#Organization) and get your local workspace set up. Dep's model could lead to being able to work without GOPATH, but we're not there yet. \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/introduction.md b/vendor/github.com/golang/dep/docs/introduction.md deleted file mode 100644 index 0367ebd5d478e432c3b98f753d50f9424e64fdc3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/introduction.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -id: introduction -title: Getting Started ---- - - -Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. Dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is _not_ intended for end users who are installing Go software - that's what `go get` does. - -This site has both guides and reference documents. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! - -After [installing dep](installation.md), if you're using it for the first time, check out [Creating a New Project](new-project.md). Or, if you have an existing Go project that you want to convert to dep, [Migrating to Dep](migrating.md) is probably the place to start. \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/migrating.md b/vendor/github.com/golang/dep/docs/migrating.md deleted file mode 100644 index c48843b7d3d9300f90e23822e59890dcde0c13a7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/migrating.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Migrating to Dep ---- - -Ideally, migrating an existing Go project to dep is straightforward: - -```bash -$ cd $GOPATH/src/path/to/project/root -$ dep init -``` - -For many projects, this will just work. `dep init` will make educated guesses about what versions to use for your dependencies, generate sane `Gopkg.toml`, `Gopkg.lock`, and `vendor/`, and if your tests pass and builds work, then you're probably done. (If so, congratulations! You should check out [Daily Dep](daily-dep.md) next.) - -The migration process is still difficult for some projects. If you're trying dep for the first time, this can be particularly frustrating, as you're trying to simultaneously learn how to use dep, and how your project *should* be managed in dep. The good news is, `dep init` is usually the big difficulty hump; once you're over it, things get much easier. - -The goal of this guide is to provide enough information for you to reason about what's happening during `dep init`, so that you can at least understand what class of problems you're encountering, and what steps you might take to address them. To that end, we'll start with an overview of what `dep init` is doing. - -> Note: the first run of `dep init` can take quite a long time, as dep is creating fresh clones of all your dependencies into a special location, `$GOPATH/pkg/dep/sources/`. This is necessary for dep's normal operations, and is largely a one-time cost. - -## `dep init` mechanics - -When migrating existing projects, the primary goal of `dep init` is to automate as much of the work of creating a `Gopkg.toml` as possible. This is necessarily a heuristic goal, as dep may not have a 1:1 correspondence for everything you may have done before. As such, it's important to only expect that `dep init`'s automated migrations are operating on a best-effort basis. - -The behavior of `dep init` varies depending on what's in your existing codebase, and the flags that are passed to it. However, it always proceeds in two phases: - -1. *Inference phase:* Infer, from various sources, rules and hints about which versions of dependencies to use. -2. *Solving phase:* Work out a solution that is acceptable under dep's model, while incorporating the above inferences as much as possible. - -### The Inference Phase - -The inference phase is where `dep init`'s behavior varies. By default, `dep init` will look in your codebase for metadata files from [other Go package management tools that it understands](https://github.com/golang/dep/tree/master/internal/importers), and attempt to automatically migrate the data in these files into concepts that make sense in a dep. Depending on the tool and the particular values dep finds, metadata from the tool may be treated as either: - -* A hint: information that dep will try to honor in the solving phase, but will discard if it cannot find a solution that respects the hint. -* A rule: information that must obeyed in the solving phase, and will ultimately appear in `Gopkg.toml` as a `[[constraint]]`. If the solving phase cannot find a solution that satisfies the rules, it will fail with an informative message. - -There are three circumstances that can lead dep not to make any tool-based inferences: - -- Your project doesn't use a package management tool -- dep doesn't yet support the tool you use yet -- You tell it not to, by running `dep init -skip-tools` - -After tool-based inference is complete, dep will normally proceed to the solving phase. However, if the user passes the `-gopath` flag, dep will first try to fill in any holes in the inferences drawn from tool metadata by checking the current project's containing GOPATH. Only hints are gleaned from GOPATH, and they will never supersede inferences from tool metadata. If you want to put GOPATH fully in charge, pass both flags: `dep init -skip-tools -gopath`. - -Once dep has compiled its set of inferences, it proceeds to solving. - -### The Solving Phase - -Once the inference phase is completed, the set of rules and hints dep has assembled will be passed to its [solver](solver.md) to work out a transitively complete depgraph, which will ultimately be recorded as the `Gopkg.lock`. This is the same solving process used by `dep ensure`, and completing it successfully means that dep has found a combination of dependency versions that respects all inferred rules, and as many inferred hints as possible. If solving succeeds, then the hard work is done; most of what remains is writing out `Gopkg.toml`, `Gopkg.lock`, and `vendor/`. - -The solver returns a solution, which itself is just [a representation](https://godoc.org/github.com/golang/dep/gps#Solution) of [the data stored in a `Gopkg.lock`](https://godoc.org/github.com/golang/dep#Lock): a transitively-complete, reproducible snapshot of the entire dependency graph. Writing out the `Gopkg.lock` from a solution is little more than a copy-and-encode operation, and writing `vendor/` is a matter of placing each project listed in the solution into its appropriate place, at the designated revision. This is exactly the same as `dep ensure`'s behavior. - -`Gopkg.toml` is a little different. There's no guarantee that rules were inferred for all (or even any) of your project's dependencies, but we still want to populate `Gopkg.toml` with sane values. So, for any dependency for which a rule was not inferred, dep inspects the solution to see what version was ultimately selected, and creates a constraint based on that: - -* If a branch, like `master`, was picked in the solution, then `branch: "master"` will appear in `Gopkg.toml`. -* If a semantic version-compliant version was selected, like `v1.2.0`, then that will be specified as a minimum version: `version: "v1.2.0"`. -* If only a raw revision was selected, nothing will be put in `Gopkg.toml`. While dep does allow `revision: "…"` constraints in `Gopkg.toml`, use of them is considered an antipattern, so dep does not create them automatically in order to avoid implicitly encouraging their use. - -## Dealing with failures - -First and foremost, make sure that you're running `dep init` with the `-v` flag. That will provide a lot more information. - -`dep init`, like dep in general, has both hard and soft failure modes. Hard failures result in the process hanging or aborting entirely, without anything being written to disk. Soft failures may or may not include warnings, but do ultimately write out a `Gopkg.toml`, `Gopkg.lock`, and `vendor/` - just, not the ones you wanted. Before we dig into those, though, let's set some context. - -While dep contributors have invested enormous effort into creating automated migration paths into dep, these paths will always best-effort and imprecise. It's simply not always possible to convert from other tools or GOPATH with full fidelity. dep is an opinionated tool, with a correspondingly opinionated model, and that model does sometimes fundamentally differ from that of other tools. Sometimes these model mismatches result in hard failures, sometimes soft, and sometimes there's no harm at all. - -Because these are deep assumptions, their symptoms can be varied and surprising. Keeping these assumptions in mind could save you some hair-pulling later on. - -- dep does not allow nested `vendor/` directories; it flattens all dependencies to the topmost `vendor/` directory, at the root of your project. This is foundational to dep's model, and cannot be disabled. -- dep wholly controls `vendor`, and will blow away any manual changes or additions made to it that deviate from the version of an upstream source dep selects. -- dep requires that all packages from a given project/repository be at the same version. -- dep generally does not care about what's on your GOPATH; it deals exclusively with projects sourced from remote network locations. (Hint inference is the only exception to this; once solving begins, GOPATH - and any custom changes you've made to code therein - is ignored.) -- dep generally prefers semantic versioning-tagged releases to branches (when not given any additional rules). This is a significant shift from the "default branch" model of `go get` and some other tools. It can result in dep making surprising choices for dependencies for which it could not infer a rule. -- dep assumes that all generated code exists, and has been committed to the source. - -A small number of projects that have reported being unable, thus far, to find a reasonable way of adapting to these requirements. If you can't figure out how to make your project fit, please file an issue - while dep necessarily cannot accommodate every single existing approach, it is dep's goal is define rules to which all Go projects can reasonably adapt. - -### Hard failures - -All of the hard failure modes are covered extensively in the reference on [failure modes](failure-modes.md). - -Because the solver, and all its possible failures, are the same for `dep init` as for `dep ensure`, there's a separate section for understanding and dealing with them: [dealing with solving failures](failure-modes.md#solving-failures). It can be trickier with `dep init`, however, as many remediations require tweaking `Gopkg.toml`. - -Unfortunately, `dep init` does not write out a partial `Gopkg.toml` when it fails. This is a known, critical problem, and [we have an open issue (help wanted!)](https://github.com/golang/dep/issues/909). - -In the meantime, if the particular errors you are encountering do entail `Gopkg.toml` tweaks, you unfortunately may have to do without the automation of `dep init`: create an empty [`Gopkg.toml`](Gopkg.toml.md), and populate it with rules by hand. Before resorting to that, make sure you've run `dep init` with various combinations of the inferencing flags (`-skip-tools` and `-gopath`) to see if they can at least give you something to start from. - -### Soft failures - -Soft failures are cases where `dep init` appears to exit cleanly, but a subsequent `go build` or `go test` fails. Dep's soft failures are usually more drastically than subtly wrong - e.g., an explosion of type errors when you try to build, because a wildly incorrect version for some dependency got selected. - -If you do encounter problems like this, `dep status` is your first diagnostic step; it will report what versions were selected for all your dependencies. It may be clear which dependencies are a problem simply from your building or testing error messages. If not, compare the `dep status` list against the versions recorded by your previous tool to find the differences. - -Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. - -For each of the following items, assume that you should run `dep ensure` after making the suggested change. If that fails, consult [dealing with solving failures](). - -* If the wrong `[[constraint]]` was inferred for one of your direct dependencies, change it. Then, file an issue against dep (please!) - while `dep init` may choose to omit a constraint, converting one incorrectly is considered a bug. -* If one of your transitive dependencies is at the wrong version, define an `[[override]]` on it to force it to the version you need. - * If the version you need is a specific git commit, it's preferable to instead manually change the `revision` to the desired hash in `Gopkg.lock` for that project, then drop the `version` or `branch` fields (if any). -* If one of your direct dependencies is at the wrong version and there's no `[[constraint]]` on it in `Gopkg.toml` already, then define an appropriate one. - * As with the transitive dependencies, if the version you need is a specific git commit, prefer doing that manually in `Gopkg.lock`. - -Hopefully this information is enough to get you through your project's migration to dep. If not, please feel free to file an issue, or join us in [#vendor on the Gopher's slack](https://gophers.slack.com/messages/C0M5YP9LN) for help! \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/new-project.md b/vendor/github.com/golang/dep/docs/new-project.md deleted file mode 100644 index 63beb68b6c95886e022b3845f2a68afa8822aba5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/new-project.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Creating a New Project ---- - -Once you have [dep installed](installation.md), we need to pick a root directory for our project. This is primarily about picking the right root import path, and corresponding directory beneath `$GOPATH/src`, at which to situate your project. There are four basic possibilities: - -1. A project that is now or eventually may be shared with or imported by other projects/people. In this case, pick the import path corresponding to the VCS root of its intended network location, e.g., `$GOPATH/src/github.com/golang/dep`. -2. An entirely local project - one that you have no intention of pushing to a central server (like GitHub). In this case, any subdirectory beneath `$GOPATH/src` will do. -3. A project that needs to live within a large repository, such as a company monorepo. This may be possible, but gets more complicated. (Unfortunately, no docs on this yet - coming soon!) -4. Treat the entire GOPATH as a single project, where `$GOPATH/src` is the root. dep [does not currently support this](https://github.com/golang/dep/issues/417) - it needs a non-empty import path to treat as the root of your project's import namespace. - -We'll assume the first case, as it's the most common. Create and move into the directory: - -```bash -$ mkdir -p $GOPATH/src/github.com/me/example -$ cd $GOPATH/src/github.com/me/example -``` - -Now, we'll initialize the project: - -```bash -$ dep init -$ ls -Gopkg.toml Gopkg.lock vendor/ -``` - -In a new project like this one, both files and the `vendor` directory will be effectively empty. - -This would also be a good time to set up a version control, such as [git](https://git-scm.com/). While dep in no way requires version control for your project, it can make inspecting the changes made by normal dep operations easier. Plus, it's basically best practice #1 of modern software development! - -At this point, our project is initialized, and we're ready to start writing code. You can open up a `.go` file in an editor and start hacking away. Or, if you already know some projects you'll need, you can pre-populate your `vendor` directory with them: - -```bash -$ dep ensure -add github.com/foo/bar github.com/baz/quux -``` - -Now you're ready to move on to [Daily Dep](daily-dep.md)! \ No newline at end of file diff --git a/vendor/github.com/golang/dep/docs/the-solver.md b/vendor/github.com/golang/dep/docs/the-solver.md deleted file mode 100644 index 25854dbd5f53f65a06645c8adf7dee92615f28bc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/docs/the-solver.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: The Solver ---- - -At the heart of dep is a constraint solving engine - a [CDCL]()-style [SMT]() solver, tailored specifically to the domain of Go package management. It lives in the `github.com/golang/dep/gps` package, and is where the work of determining a valid, transitively complete dependency graph (aka, the contents of `Gopkg.lock`) is performed. - -This page will eventually detail the solver's mechanics, but in the meantime, there are [docs for an older version of the solver](https://github.com/sdboyer/gps/wiki/gps-for-Contributors) that are still accurate enough to provide a rough picture of its behavior. - -## Solving invariants - -The solver guarantees certain invariants in every complete solution it returns. Each invariant is explored in detail later, but they can be summarized as follows: - -* All rules specified in activated `[[constraint]]` stanzas in both the current project and dependency projects will be satisfied, unless superseded by a `[[override]]` stanza in the current project. -* For all import paths pointing into a given project, the version of the project selected will contain "valid" Go packages in the corresponding directory. -* If an [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) is specified by a package, any import paths addressing that package will be of the form specified in the comment. -* For any given import path, all instances of that import path will use the exact same casing. - -The solver is an iterative algorithm, working its way project-by-project through possible dependency graphs. In order to select a project, it must first prove that, to the best of its current knowledge, all of the above conditions are met. When the solver cannot find a solution, failure is defined in terms of a project's version's inability to meet one of the above criteria. - -### `[[constraint]]` rules - -As described in the `Gopkg.toml` docs, each [`[[constraint]]`](gopkg.toml.md#constraint) stanza is associated with a single project, and each stanza can contain both [a version rule](Gopkg.toml.md#version-rules) and a [source rule](Gopkg.toml.md#source). For any given project `P`, all dependers on `P` whose constraint rules are "activated" must express mutually compatible rules. That means: - -* For version rules, all activated constraints on `P` must [intersect](https://en.wikipedia.org/wiki/Intersection_(set_theory)), and and there must be at least one published version must exist in the intersecting space. Intersection varies depending on version rule type: - * For `revision` and `branch`, it must be a string-literal match. - * For `version`, if the string is not a valid semantic version, then it must be a string-literal match. - * For `version` that are valid semantic version ranges, intersection is standard set-theoretic intersection of the possible values in each range range. Semantic versions without ranges are treated as a single element set (e.g., `version = "=v1.0.0"`) for intersection purposes. -* For `source` rules, all projects with a particular dependency must either express a string-equal `source` value, or have no `source` value at all. This allows one dependency to specify an alternate `source`, and other dependencies to play along if they have no opinion. (NB: this play-along behavior may be removed in a future version.) - -If the current project's `Gopkg.toml` has an [`[[override]]`](gopkg.toml.md#override) on `P`, then all `[[constraint]]` declarations (including any in the current project) are ignored, obviating the possibility of conflict. - -#### Activated constraints - -Just because a `[[constraint]]` on `P` appears in `D`'s `Gopkg.toml` doesn't necessarily mean the constraint on `P` is considered active. A package in `P` must be imported by a package in `D` - and, if `D` is not the current project, then one of its packages importing `P` must also be imported. - -Given the following dependency graph, where `C` is the current project: - -``` -C -> D -C -> P -D/subpkg -> P -``` - -Even though `C` imports `D`, because `D/subpkg` is not reachable through `C`'s imports, any `[[constraint]]` declared in `D`'s `Gopkg.toml`' on `P` will not be active. - -The reasoning behind this behavior is explained further [in this gist](https://gist.github.com/sdboyer/b0813bf2b9dba58a335a85092085472f). - -### Package validity - -dep does only superficial validaton of code in packages, but it does do some. For a package to be considered valid, three things must be true: - -* There must be at least one `.go` file. -* No errors are reported from [`parser.ParseFile()`](https://golang.org/pkg/go/parser/#ParseFile) when called with [`parser.ImportsOnly|parser.ParseComments`](https://golang.org/pkg/go/parser/#Mode) on any file in the package directory. - -- The package must not contain any [local imports](https://golang.org/pkg/go/build/#IsLocalImport). Note: this disallows something the standard toolchain compiler does allow, which is normally means dep must support it. However, local imports are already strongly discouraged in the toolchain, and skipping them allows dep to avoid [dot-dot hell](https://9p.io/sys/doc/lexnames.html). - -If any of the above are untrue, the code in a package is considered malformed, and cannot be used in a solution. - -It is not immediately disqualifying for a project to merely contain some invalid packages; they must be imported for the invariant to be broken. So, if `P/invalid` is a subpackage with invalid code in it, then it is still acceptable if `C -> P`. However, internal imports within `P` are also considered, so this import chain: - -``` -C -> P -P -> invalid -``` - -will result in an error, as `C` imports a package that will necessarily result in the import of an invalid package. - -### Import comments - -Go 1.4 introduced [import comments](https://golang.org/cmd/go/#hdr-Import_path_checking), which allow a package to specify the import path that must be used when addressing it. For example, `import "github.com/golang/net/dict"` would point to a valid package, but because [it uses an import comment](https://github.com/golang/net/blob/42fe2e1c20de1054d3d30f82cc9fb5b41e2e3767/dict/dict.go#L7) to enforce that it must be imported as `golang.org/x/net/dict`, dep would reject any project attempting to import it directly through its github address. - -Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. - -> Note: dep does not currently enforce this rule, but [it needs to](https://github.com/golang/dep/issues/902). - -**Remediation:** change the code by fixing the offending import paths. If the offending import paths are not in the current project and you don't directly control the dependency, you'll have to fork and fix it yourself, then use `source` to point to your fork. - -### Import path casing - -The standard Go toolchain compiler [does not](https://github.com/golang/go/issues/4773) [allow](https://github.com/golang/go/issues/20264) import paths that vary only in case to exist in the same build. For example, either of `github.com/sirupsen/logrus` or `github.com/Sirupsen/logrus` are fine (GitHub treats usernames as case-insensitive) individually, but they cannot exist in the same project. - -The solver keeps track of the accepted case variant for each import path it's processed. Any subsequent projects it sees that introduces a case-only variation for a known import path will be rejected. - -**Remediation:** Pick a casing variation (all lowercase is usually the right answer), and enforce it universally across the depgraph. As it has to be respected in all dependencies, as well, this may necessitate pull requests and possibly forking of dependencies, if you don't control them directly. \ No newline at end of file diff --git a/vendor/github.com/golang/dep/gps/BUILD.bazel b/vendor/github.com/golang/dep/gps/BUILD.bazel deleted file mode 100644 index a86871b51919587edbcb2c8baadfe45d60f29732..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/BUILD.bazel +++ /dev/null @@ -1,64 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "bridge.go", - "cmd.go", - "cmd_unix.go", - "cmd_windows.go", - "constraints.go", - "deduce.go", - "discovery.go", - "filesystem.go", - "hash.go", - "identifier.go", - "lock.go", - "lockdiff.go", - "manifest.go", - "maybe_source.go", - "metrics.go", - "prune.go", - "rootdata.go", - "satisfy.go", - "selection.go", - "solution.go", - "solve_failures.go", - "solver.go", - "source.go", - "source_cache.go", - "source_cache_bolt.go", - "source_cache_bolt_encode.go", - "source_cache_multi.go", - "source_errors.go", - "source_manager.go", - "strings.go", - "trace.go", - "typed_radix.go", - "vcs_repo.go", - "vcs_source.go", - "vcs_version.go", - "version.go", - "version_queue.go", - "version_unifier.go", - ], - importmap = "vendor/github.com/golang/dep/gps", - importpath = "github.com/golang/dep/gps", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/Masterminds/semver:go_default_library", - "//vendor/github.com/Masterminds/vcs:go_default_library", - "//vendor/github.com/armon/go-radix:go_default_library", - "//vendor/github.com/boltdb/bolt:go_default_library", - "//vendor/github.com/golang/dep/gps/internal/pb:go_default_library", - "//vendor/github.com/golang/dep/gps/paths:go_default_library", - "//vendor/github.com/golang/dep/gps/pkgtree:go_default_library", - "//vendor/github.com/golang/dep/internal/fs:go_default_library", - "//vendor/github.com/golang/protobuf/proto:go_default_library", - "//vendor/github.com/jmank88/nuts:go_default_library", - "//vendor/github.com/nightlyone/lockfile:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - "//vendor/github.com/sdboyer/constext:go_default_library", - "//vendor/golang.org/x/sync/errgroup:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/badrepo/README.md b/vendor/github.com/golang/dep/gps/_testdata/badrepo/README.md deleted file mode 100644 index 14232159c3a1a379b141fda061e7602f8d2fe7cc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/badrepo/README.md +++ /dev/null @@ -1,5 +0,0 @@ -### Test Data - -This directory contains artifacts that represent malformed repo archives. Its purpose is to ensure `dep` can recover from such corrupted repositories in specific test scenarios. - -- `corrupt_dot_git_directory.tar`: is a repo with a corrupt `.git` directory. Dep can put a directory in such malformed state when a user hits `Ctrl+C` in the middle of a `dep init` process or others. `TestNewCtxRepoRecovery` uses this file to ensure recovery. diff --git a/vendor/github.com/golang/dep/gps/_testdata/badrepo/corrupt_dot_git_directory.tar b/vendor/github.com/golang/dep/gps/_testdata/badrepo/corrupt_dot_git_directory.tar deleted file mode 100644 index 7a847318395c721a0bee0e7f189c00792e05caef..0000000000000000000000000000000000000000 Binary files a/vendor/github.com/golang/dep/gps/_testdata/badrepo/corrupt_dot_git_directory.tar and /dev/null differ diff --git a/vendor/github.com/golang/dep/gps/_testdata/cmd/echosleep/echosleep.go b/vendor/github.com/golang/dep/gps/_testdata/cmd/echosleep/echosleep.go deleted file mode 100644 index 70de0e5032222696cdee34023595fc5a8bcf0a8b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/cmd/echosleep/echosleep.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 main - -import ( - "flag" - "fmt" - "time" -) - -func main() { - n := flag.Int("n", 1, "number of iterations before stopping") - flag.Parse() - - for i := 0; i < *n; i++ { - fmt.Println("foo") - time.Sleep(time.Duration(i) * 250 * time.Millisecond) - } -} diff --git a/vendor/github.com/golang/dep/gps/_testdata/cmd/stdout_stderr/stdout_stderr.go b/vendor/github.com/golang/dep/gps/_testdata/cmd/stdout_stderr/stdout_stderr.go deleted file mode 100644 index 806d18912b47a8793ed63824001eb1dab67903de..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/cmd/stdout_stderr/stdout_stderr.go +++ /dev/null @@ -1,14 +0,0 @@ -// 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 main - -import ( - "os" -) - -func main() { - os.Stdout.WriteString("stdout") - os.Stderr.WriteString("stderr") -} diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/match/match.go b/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/match/match.go deleted file mode 100644 index ab5f875285c32186c4c990d844299c2ac886b8e5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/match/match.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 match diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/mismatch/mismatch.go b/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/mismatch/mismatch.go deleted file mode 100644 index 1ace4e76833ec9e0c4eee713a76ad6256d58fcf0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/mismatch/mismatch.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 mismatch diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/notInLock/notInLock.go b/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/notInLock/notInLock.go deleted file mode 100644 index 5b2914de73539575d73b1b754b2a519ad9b84dd5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/alice/notInLock/notInLock.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 notInLock diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/emptyDigest/emptyDigest.go b/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/emptyDigest/emptyDigest.go deleted file mode 100644 index 2d6067bc8eb6a2ba16c89c35e46384d39071124b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/emptyDigest/emptyDigest.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 emptyDigest diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/match/match.go b/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/match/match.go deleted file mode 100644 index ab5f875285c32186c4c990d844299c2ac886b8e5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/github.com/bob/match/match.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 match diff --git a/vendor/github.com/golang/dep/gps/_testdata/digest/launchpad.net/match/match.go b/vendor/github.com/golang/dep/gps/_testdata/digest/launchpad.net/match/match.go deleted file mode 100644 index ab5f875285c32186c4c990d844299c2ac886b8e5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/digest/launchpad.net/match/match.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 match diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/bad/bad.go b/vendor/github.com/golang/dep/gps/_testdata/src/bad/bad.go deleted file mode 100644 index dfc89bee0863403ea5651815b696a00b972e5042..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/bad/bad.go +++ /dev/null @@ -1,6 +0,0 @@ -// 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. - -// This ill-formed Go source file is here to ensure the tool is robust -// against bad packages in the workspace. diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/buildtag/invalid.go b/vendor/github.com/golang/dep/gps/_testdata/src/buildtag/invalid.go deleted file mode 100644 index 20c43146f0f62139c73296922ab0066eab80f4cb..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/buildtag/invalid.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -// Hello -// Not a valid +build ignore -// No Really - -package buildtag - -import ( - "sort" -) - -var ( - _ = sort.Strings -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/a.go deleted file mode 100644 index 98153451184fd032f614ad41ec6b02c772aafd70..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/a.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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 canonical // import "vanity1" - -var ( - A = "A" -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/b.go deleted file mode 100644 index b8b706bbd493f975dd8e893c21e9035c37d38c6f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/canon_confl/b.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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 canonical // import "vanity2" - -var ( - B = "B" -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/canonical/main.go b/vendor/github.com/golang/dep/gps/_testdata/src/canonical/main.go deleted file mode 100644 index 4fe31ce3d5620b36bc9cf8116b668e987c8c83d7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/canonical/main.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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 pkg // import "canonical" - -var ( - A = "A" -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/canonical/sub/sub.go b/vendor/github.com/golang/dep/gps/_testdata/src/canonical/sub/sub.go deleted file mode 100644 index 783186dfc2b28091e696d6092fc9a80edfa4bb19..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/canonical/sub/sub.go +++ /dev/null @@ -1,5 +0,0 @@ -// 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 sub // import "canonical/subpackage" diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/cycle/a.go deleted file mode 100644 index 443db7798518ff8f6cbb147288a7492fd9cd584b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 cycle - -import ( - "cycle/one" - - "github.com/golang/dep/gps" -) - -var ( - A = gps.Solve - B = one.A -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/one/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/cycle/one/a.go deleted file mode 100644 index 055d98db2d450029f3c445b404699239e5e6f319..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/one/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 one - -import ( - "cycle/two" - - "github.com/golang/dep/gps" -) - -var ( - A = gps.Solve - B = two.A -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/two/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/cycle/two/a.go deleted file mode 100644 index a44003adf531149bef0ee7aeb92041a6b52311ed..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/cycle/two/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 two - -import ( - "cycle" - - "github.com/golang/dep/gps" -) - -var ( - A = gps.Solve - B = cycle.A -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/disallow/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/disallow/a.go deleted file mode 100644 index 99dd6f3512fc7f5491b7e1397cb98809bca87380..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/disallow/a.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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 disallow - -import ( - "disallow/testdata" - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve - _ = testdata.H -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/disallow/testdata/another.go b/vendor/github.com/golang/dep/gps/_testdata/src/disallow/testdata/another.go deleted file mode 100644 index f2d60b88f991740dc6de9fbdc88e2c6d7c62eae0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/disallow/testdata/another.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 testdata - -import "hash" - -var ( - H = hash.Hash -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.go/.gitkeep b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.go/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.go/dot.go b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.go/dot.go deleted file mode 100644 index bb51d69f9ad19bdf6988f01c222ae17f65b73ee2..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.go/dot.go +++ /dev/null @@ -1,7 +0,0 @@ -// 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 dot - -// nothing to see here diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/a.go deleted file mode 100644 index 6a88c12022b21f47518b4bdbd8ddf7adab8e7bd6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - S = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/.m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/foo.go/.gitkeep b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/foo.go/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/foo.go/foo.go b/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/foo.go/foo.go deleted file mode 100644 index 1de8b0ab15b069c4fa56c6593ce31c9964ac28d9..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/dotgodir/foo.go/foo.go +++ /dev/null @@ -1,12 +0,0 @@ -// 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 foo - -import "sort" - -var _ = sort.Strings - -// yes, this is dumb, don't use ".go" in your directory names -// See https://github.com/golang/dep/issues/550 for more information diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/a.go deleted file mode 100644 index fca9b43a330f03790be3a7af0e4ea23e65a7ae15..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 base - -import ( - "go/parser" - - "github.com/golang/dep/gps" -) - -var ( - _ = parser.ParseFile - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/a.go deleted file mode 100644 index 78f859bb867cb8001f91630bd01c477ef487c419..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/nm.go b/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/nm.go deleted file mode 100644 index 6c4a42fcc3d2c8f573cd927b6e08bd7a728c5258..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/doublenest/namemismatch/nm.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 nm - -import ( - "os" - - "github.com/Masterminds/semver" -) - -var ( - V = os.FileInfo - _ = semver.Constraint -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/empty/.gitkeep b/vendor/github.com/golang/dep/gps/_testdata/src/empty/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/locals.go deleted file mode 100644 index 38dbe7aaab36cf46c12e2783e80ccb86558408a7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/locals.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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 main - -import ( - "github.com/example/varied/namemismatch" - "github.com/example/varied/otherpath" - "github.com/example/varied/simple" -) - -var ( - _ = simple.S - _ = nm.V - _ = otherpath.O -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/a.go deleted file mode 100644 index 9fae843c5df2756d9a0d50567fb2ac888ffad1e7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - M = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/main.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/main.go deleted file mode 100644 index 0812e3ca60d2258975796bca23cd088807689208..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/main.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 main - -import ( - "net/http" -) - -var ( - _ = http.Client -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/namemismatch/nm.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/namemismatch/nm.go deleted file mode 100644 index 6c4a42fcc3d2c8f573cd927b6e08bd7a728c5258..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/namemismatch/nm.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 nm - -import ( - "os" - - "github.com/Masterminds/semver" -) - -var ( - V = os.FileInfo - _ = semver.Constraint -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/another.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/another.go deleted file mode 100644 index c453a8ea1b845355c4bebc380b9aca8d8e30734c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/another.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 another - -import "hash" - -var ( - H = hash.Hash -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/locals.go deleted file mode 100644 index 6995b92543d567ce9ef895991680dee644a7218b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/another/locals.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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 another - -import "github.com/example/varied/m1p" - -var _ = m1p.M diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/locals.go deleted file mode 100644 index c5a0ae3a6c11122a58dbd96438e1a40077c47f6e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/locals.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 simple - -import "github.com/example/varied/simple/another" - -var ( - _ = another.H -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/simple.go b/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/simple.go deleted file mode 100644 index 6dfd049488e5ee3e91075c8cc87ca29326a01b8b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/github.com/example/varied/simple/simple.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "go/parser" - - "github.com/golang/dep/gps" -) - -var ( - _ = parser.ParseFile - S = gps.Prepare -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmain/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmain/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmain/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmain/igmain.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmain/igmain.go deleted file mode 100644 index eaab15bd2297c1259b97dde550f5dd69d4f814a8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmain/igmain.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 ignore - -package main - -import "unicode" - -var _ = unicode.In diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/igmain.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/igmain.go deleted file mode 100644 index eaab15bd2297c1259b97dde550f5dd69d4f814a8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/igmain.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 ignore - -package main - -import "unicode" - -var _ = unicode.In diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/z.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/z.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmainfirst/z.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/igmain.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/igmain.go deleted file mode 100644 index 849ceab43d670d76825845ccd73364a2f6160d4b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmainlong/igmain.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -// Another comment, which the parser should ignore and still see builds tags - -// +build ignore - -package main - -import "unicode" - -var _ = unicode.In diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/igmain.go b/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/igmain.go deleted file mode 100644 index eaab15bd2297c1259b97dde550f5dd69d4f814a8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/igmaint/igmain.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 ignore - -package main - -import "unicode" - -var _ = unicode.In diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/m1p/a.go deleted file mode 100644 index 78f859bb867cb8001f91630bd01c477ef487c419..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/missing/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/missing/a.go deleted file mode 100644 index 619b1bc5ca692330a80da01ba4390d193532fbeb..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/missing/a.go +++ /dev/null @@ -1,19 +0,0 @@ -// 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 simple - -import ( - "sort" - - "missing/missing" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve - _ = missing.Foo -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/a.go deleted file mode 100644 index 78f859bb867cb8001f91630bd01c477ef487c419..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/missing/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/nest/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/nest/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/nest/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/a.go deleted file mode 100644 index 78f859bb867cb8001f91630bd01c477ef487c419..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/nest/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/relimport/a.go deleted file mode 100644 index ccfa73a945de67169d85332af405501f735b82a7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 relimport - -import ( - "sort" -) - -var ( - A = sort.Strings -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dot/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dot/a.go deleted file mode 100644 index a1dd285380d0cbbe32b331dfea2354b2fe340b84..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dot/a.go +++ /dev/null @@ -1,14 +0,0 @@ -// 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 dot - -import ( - "." - "sort" -) - -var ( - A = sort.Strings -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdot/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdot/a.go deleted file mode 100644 index 6cfc99f288e5483eef629381107ffae8a00e3044..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdot/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 dotdot - -import ( - relimport ".." -) - -var ( - A = relimport.A -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdotslash/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdotslash/a.go deleted file mode 100644 index b4caf2fab2a66431683e70096701965f3216d8d7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotdotslash/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 dotslash - -import ( - "../github.com/golang/dep/gps" -) - -var ( - A = gps.Solver -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotslash/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotslash/a.go deleted file mode 100644 index b904565dd76be6d5078f75160ba53635c458f76e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/relimport/dotslash/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 dotslash - -import ( - "./simple" -) - -var ( - A = simple.A -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/a.go deleted file mode 100644 index 78f859bb867cb8001f91630bd01c477ef487c419..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/ren/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/ren/simple/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/ren/simple/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/ren/simple/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/simple/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/simple/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/simple/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/simpleallt/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/simpleallt/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/simpleallt/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/simplet/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/simplet/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/simplet/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/simplext/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/simplext/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/simplext/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/skip_/_a.go b/vendor/github.com/golang/dep/gps/_testdata/src/skip_/_a.go deleted file mode 100644 index b53a03b55ab1ca5399b972f29d54586a3686d16c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/skip_/_a.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 skip - -import ( - "bytes" - "sort" -) - -var ( - _ = sort.Strings - _ = bytes.Buffer -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/skip_/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/skip_/a.go deleted file mode 100644 index fc99a11da5b4dc4765c8e355ae5a9a36db8eaceb..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/skip_/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 skip - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/a.go deleted file mode 100644 index f772b57e72e02332d590f7c6e16869029ac0697e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - _ = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/twopkgs/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/locals.go deleted file mode 100644 index d9dcdec11a86f67b4316d35a53da897271d327d4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/locals.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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 main - -import ( - "varied/namemismatch" - "varied/otherpath" - "varied/simple" -) - -var ( - _ = simple.S - _ = nm.V - _ = otherpath.O -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/a.go deleted file mode 100644 index 9fae843c5df2756d9a0d50567fb2ac888ffad1e7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 m1p - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - M = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/b.go deleted file mode 100644 index de4eb0b563df3406c097acc6e397df696b75c4ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/m1p/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 m1p - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/main.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/main.go deleted file mode 100644 index 0812e3ca60d2258975796bca23cd088807689208..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/main.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 main - -import ( - "net/http" -) - -var ( - _ = http.Client -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/namemismatch/nm.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/namemismatch/nm.go deleted file mode 100644 index 6c4a42fcc3d2c8f573cd927b6e08bd7a728c5258..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/namemismatch/nm.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 nm - -import ( - "os" - - "github.com/Masterminds/semver" -) - -var ( - V = os.FileInfo - _ = semver.Constraint -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/another.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/another.go deleted file mode 100644 index c453a8ea1b845355c4bebc380b9aca8d8e30734c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/another.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 another - -import "hash" - -var ( - H = hash.Hash -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/locals.go deleted file mode 100644 index befa5c683af64fa0307f7e8f6ab51c93f094e39b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/another/locals.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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 another - -import "varied/m1p" - -var _ = m1p.M diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/locals.go deleted file mode 100644 index 3f592af781c4e302a2251c880ca570cd881487fe..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/locals.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 simple - -import "varied/simple/another" - -var ( - _ = another.H -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/simple.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/simple.go deleted file mode 100644 index 6dfd049488e5ee3e91075c8cc87ca29326a01b8b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied/simple/simple.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "go/parser" - - "github.com/golang/dep/gps" -) - -var ( - _ = parser.ParseFile - S = gps.Prepare -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/a.go deleted file mode 100644 index 676dbae1ad9aab0a1908f8503b4130e821aaecea..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/a.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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 onlyfromtests - -import ( - "sort" - - _ "varied/_secondorder" - - "github.com/golang/dep/gps" -) - -var ( - M = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/b.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/b.go deleted file mode 100644 index fa353864bf572d26af3db2e6e05926483919ae14..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/.onlyfromtests/b.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 onlyfromtests - -import ( - "os" - "sort" -) - -var ( - _ = sort.Strings - _ = os.PathSeparator -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_frommain/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_frommain/a.go deleted file mode 100644 index 67634a859845fd2a943d9e0b999c97e6125755c4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_frommain/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 frommain - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - M = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_never/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_never/a.go deleted file mode 100644 index f2bdd5b007000542738ca3eff322b63b1a0457a8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_never/a.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 never - -import ( - "sort" - - "github.com/golang/dep/gps" -) - -var ( - M = sort.Strings - _ = gps.Solve -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_secondorder/secondorder.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_secondorder/secondorder.go deleted file mode 100644 index 4224b81e1e67ec3b4b286f8194201c3ddccaa861..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/_secondorder/secondorder.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 secondorder - -import "hash" - -var ( - H = hash.Hash -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/dotdotslash/a.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/dotdotslash/a.go deleted file mode 100644 index b4caf2fab2a66431683e70096701965f3216d8d7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/dotdotslash/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 dotslash - -import ( - "../github.com/golang/dep/gps" -) - -var ( - A = gps.Solver -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/locals.go deleted file mode 100644 index 4afaa8bfd3963675b21aab93c64f2310db19bfec..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/locals.go +++ /dev/null @@ -1,14 +0,0 @@ -// 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 main - -import ( - _ "varied/_frommain" - "varied/simple" -) - -var ( - _ = simple.S -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/main.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/main.go deleted file mode 100644 index 0812e3ca60d2258975796bca23cd088807689208..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/main.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 main - -import ( - "net/http" -) - -var ( - _ = http.Client -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/locals.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/locals.go deleted file mode 100644 index 7d682c4e753582cf59dd97ac57a12e9a7a945f8b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/locals.go +++ /dev/null @@ -1,11 +0,0 @@ -// 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 simple - -import "varied/simple/testdata" - -var ( - _ = testdata.H -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/simple.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/simple.go deleted file mode 100644 index 6dfd049488e5ee3e91075c8cc87ca29326a01b8b..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/simple.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 simple - -import ( - "go/parser" - - "github.com/golang/dep/gps" -) - -var ( - _ = parser.ParseFile - S = gps.Prepare -) diff --git a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/testdata/another.go b/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/testdata/another.go deleted file mode 100644 index 02eab2a200c9e2d2bcbcaea07e951d40f502bbf5..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/_testdata/src/varied_hidden/simple/testdata/another.go +++ /dev/null @@ -1,7 +0,0 @@ -// 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 testdata - -import _ "varied/dotdotslash" diff --git a/vendor/github.com/golang/dep/gps/bridge.go b/vendor/github.com/golang/dep/gps/bridge.go deleted file mode 100644 index 819d0ae58bb1c689a74c6a27fa4698b868c9b286..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/bridge.go +++ /dev/null @@ -1,223 +0,0 @@ -// 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 gps - -import ( - "fmt" - "os" - "path/filepath" - "sync/atomic" - - "github.com/golang/dep/gps/pkgtree" -) - -// sourceBridge is an adapter to SourceManagers that tailor operations for a -// single solve run. -type sourceBridge interface { - // sourceBridge includes all the methods in the SourceManager interface except - // for Release(). - SourceExists(ProjectIdentifier) (bool, error) - SyncSourceFor(ProjectIdentifier) error - RevisionPresentIn(ProjectIdentifier, Revision) (bool, error) - ListPackages(ProjectIdentifier, Version) (pkgtree.PackageTree, error) - GetManifestAndLock(ProjectIdentifier, Version, ProjectAnalyzer) (Manifest, Lock, error) - ExportProject(ProjectIdentifier, Version, string) error - DeduceProjectRoot(ip string) (ProjectRoot, error) - - //sourceExists(ProjectIdentifier) (bool, error) - //syncSourceFor(ProjectIdentifier) error - listVersions(ProjectIdentifier) ([]Version, error) - //revisionPresentIn(ProjectIdentifier, Revision) (bool, error) - //listPackages(ProjectIdentifier, Version) (pkgtree.PackageTree, error) - //getManifestAndLock(ProjectIdentifier, Version, ProjectAnalyzer) (Manifest, Lock, error) - //exportProject(ProjectIdentifier, Version, string) error - //deduceProjectRoot(ip string) (ProjectRoot, error) - verifyRootDir(path string) error - vendorCodeExists(ProjectIdentifier) (bool, error) - breakLock() -} - -// bridge is an adapter around a proper SourceManager. It provides localized -// caching that's tailored to the requirements of a particular solve run. -// -// Finally, it provides authoritative version/constraint operations, ensuring -// that any possible approach to a match - even those not literally encoded in -// the inputs - is achieved. -type bridge struct { - // The underlying, adapted-to SourceManager - sm SourceManager - - // The solver which we're assisting. - // - // The link between solver and bridge is circular, which is typically a bit - // awkward, but the bridge needs access to so many of the input arguments - // held by the solver that it ends up being easier and saner to do this. - s *solver - - // Map of project root name to their available version list. This cache is - // layered on top of the proper SourceManager's cache; the only difference - // is that this keeps the versions sorted in the direction required by the - // current solve run. - vlists map[ProjectIdentifier][]Version - - // Indicates whether lock breaking has already been run - lockbroken int32 - - // Whether to sort version lists for downgrade. - down bool - - // The cancellation context provided to the solver. Threading it through the - // various solver methods is needlessly verbose so long as we maintain the - // lifetime guarantees that a solver can only be run once. - // TODO(sdboyer) uncomment this and thread it through SourceManager methods - //ctx context.Context -} - -// mkBridge creates a bridge -func mkBridge(s *solver, sm SourceManager, down bool) *bridge { - return &bridge{ - sm: sm, - s: s, - down: down, - vlists: make(map[ProjectIdentifier][]Version), - } -} - -func (b *bridge) GetManifestAndLock(id ProjectIdentifier, v Version, an ProjectAnalyzer) (Manifest, Lock, error) { - if b.s.rd.isRoot(id.ProjectRoot) { - return b.s.rd.rm, b.s.rd.rl, nil - } - - b.s.mtr.push("b-gmal") - m, l, e := b.sm.GetManifestAndLock(id, v, an) - b.s.mtr.pop() - return m, l, e -} - -func (b *bridge) listVersions(id ProjectIdentifier) ([]Version, error) { - if vl, exists := b.vlists[id]; exists { - return vl, nil - } - - b.s.mtr.push("b-list-versions") - pvl, err := b.sm.ListVersions(id) - if err != nil { - b.s.mtr.pop() - return nil, err - } - - vl := hidePair(pvl) - if b.down { - SortForDowngrade(vl) - } else { - SortForUpgrade(vl) - } - - b.vlists[id] = vl - b.s.mtr.pop() - return vl, nil -} - -func (b *bridge) RevisionPresentIn(id ProjectIdentifier, r Revision) (bool, error) { - b.s.mtr.push("b-rev-present-in") - i, e := b.sm.RevisionPresentIn(id, r) - b.s.mtr.pop() - return i, e -} - -func (b *bridge) SourceExists(id ProjectIdentifier) (bool, error) { - b.s.mtr.push("b-source-exists") - i, e := b.sm.SourceExists(id) - b.s.mtr.pop() - return i, e -} - -func (b *bridge) vendorCodeExists(id ProjectIdentifier) (bool, error) { - fi, err := os.Stat(filepath.Join(b.s.rd.dir, "vendor", string(id.ProjectRoot))) - if err != nil { - return false, err - } else if fi.IsDir() { - return true, nil - } - - return false, nil -} - -// listPackages lists all the packages contained within the given project at a -// particular version. -// -// The root project is handled separately, as the source manager isn't -// responsible for that code. -func (b *bridge) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) { - if b.s.rd.isRoot(id.ProjectRoot) { - return b.s.rd.rpt, nil - } - - b.s.mtr.push("b-list-pkgs") - pt, err := b.sm.ListPackages(id, v) - b.s.mtr.pop() - return pt, err -} - -func (b *bridge) ExportProject(id ProjectIdentifier, v Version, path string) error { - panic("bridge should never be used to ExportProject") -} - -// verifyRoot ensures that the provided path to the project root is in good -// working condition. This check is made only once, at the beginning of a solve -// run. -func (b *bridge) verifyRootDir(path string) error { - if fi, err := os.Stat(path); err != nil { - return badOptsFailure(fmt.Sprintf("could not read project root (%s): %s", path, err)) - } else if !fi.IsDir() { - return badOptsFailure(fmt.Sprintf("project root (%s) is a file, not a directory", path)) - } - - return nil -} - -func (b *bridge) DeduceProjectRoot(ip string) (ProjectRoot, error) { - b.s.mtr.push("b-deduce-proj-root") - pr, e := b.sm.DeduceProjectRoot(ip) - b.s.mtr.pop() - return pr, e -} - -// breakLock is called when the solver has to break a version recorded in the -// lock file. It prefetches all the projects in the solver's lock, so that the -// information is already on hand if/when the solver needs it. -// -// Projects that have already been selected are skipped, as it's generally unlikely that the -// solver will have to backtrack through and fully populate their version queues. -func (b *bridge) breakLock() { - // No real conceivable circumstance in which multiple calls are made to - // this, but being that this is the entrance point to a bunch of async work, - // protect it with an atomic CAS in case things change in the future. - // - // We avoid using a sync.Once here, as there's no reason for other callers - // to block until completion. - if !atomic.CompareAndSwapInt32(&b.lockbroken, 0, 1) { - return - } - - for _, lp := range b.s.rd.rl.Projects() { - if _, is := b.s.sel.selected(lp.pi); !is { - pi, v := lp.pi, lp.Version() - go func() { - // Sync first - b.sm.SyncSourceFor(pi) - // Preload the package info for the locked version, too, as - // we're more likely to need that - b.sm.ListPackages(pi, v) - }() - } - } -} - -func (b *bridge) SyncSourceFor(id ProjectIdentifier) error { - // we don't track metrics here b/c this is often called in its own goroutine - // by the solver, and the metrics design is for wall time on a single thread - return b.sm.SyncSourceFor(id) -} diff --git a/vendor/github.com/golang/dep/gps/cmd.go b/vendor/github.com/golang/dep/gps/cmd.go deleted file mode 100644 index 1166cb9c8be242a0916dfbef9cea76ae62043a23..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/cmd.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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 gps - -func (c cmd) Args() []string { - return c.Cmd.Args -} - -func (c cmd) SetDir(dir string) { - c.Cmd.Dir = dir -} - -func (c cmd) SetEnv(env []string) { - c.Cmd.Env = env -} diff --git a/vendor/github.com/golang/dep/gps/cmd_unix.go b/vendor/github.com/golang/dep/gps/cmd_unix.go deleted file mode 100644 index 413f6b3980db9b5a0ab2627ddd71e13a7649ae67..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/cmd_unix.go +++ /dev/null @@ -1,82 +0,0 @@ -// 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 !windows - -package gps - -import ( - "bytes" - "context" - "os" - "os/exec" - "syscall" - "time" - - "github.com/pkg/errors" -) - -type cmd struct { - // ctx is provided by the caller; SIGINT is sent when it is cancelled. - ctx context.Context - Cmd *exec.Cmd -} - -func commandContext(ctx context.Context, name string, arg ...string) cmd { - c := exec.Command(name, arg...) - - // Force subprocesses into their own process group, rather than being in the - // same process group as the dep process. Because Ctrl-C sent from a - // terminal will send the signal to the entire currently running process - // group, this allows us to directly manage the issuance of signals to - // subprocesses. - c.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - Pgid: 0, - } - - return cmd{ctx: ctx, Cmd: c} -} - -// CombinedOutput is like (*os/exec.Cmd).CombinedOutput except that it -// terminates subprocesses gently (via os.Interrupt), but resorts to Kill if -// the subprocess fails to exit after 1 minute. -func (c cmd) CombinedOutput() ([]byte, error) { - // Adapted from (*os/exec.Cmd).CombinedOutput - if c.Cmd.Stdout != nil { - return nil, errors.New("exec: Stdout already set") - } - if c.Cmd.Stderr != nil { - return nil, errors.New("exec: Stderr already set") - } - var b bytes.Buffer - c.Cmd.Stdout = &b - c.Cmd.Stderr = &b - if err := c.Cmd.Start(); err != nil { - return nil, err - } - - // Adapted from (*os/exec.Cmd).Start - waitDone := make(chan struct{}) - defer close(waitDone) - go func() { - select { - case <-c.ctx.Done(): - if err := c.Cmd.Process.Signal(os.Interrupt); err != nil { - // If an error comes back from attempting to signal, proceed - // immediately to hard kill. - _ = c.Cmd.Process.Kill() - } else { - defer time.AfterFunc(time.Minute, func() { - _ = c.Cmd.Process.Kill() - }).Stop() - <-waitDone - } - case <-waitDone: - } - }() - - err := c.Cmd.Wait() - return b.Bytes(), err -} diff --git a/vendor/github.com/golang/dep/gps/cmd_windows.go b/vendor/github.com/golang/dep/gps/cmd_windows.go deleted file mode 100644 index ce1a0347ddf7f73519c11d84f29ae4003b316e3f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/cmd_windows.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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 gps - -import ( - "context" - "os/exec" -) - -type cmd struct { - *exec.Cmd -} - -func commandContext(ctx context.Context, name string, arg ...string) cmd { - return cmd{Cmd: exec.CommandContext(ctx, name, arg...)} -} diff --git a/vendor/github.com/golang/dep/gps/constraints.go b/vendor/github.com/golang/dep/gps/constraints.go deleted file mode 100644 index b6550700bc033694fa93a9d03600033753aa3df6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/constraints.go +++ /dev/null @@ -1,453 +0,0 @@ -// 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 gps - -import ( - "fmt" - "sort" - - "github.com/Masterminds/semver" - "github.com/golang/dep/gps/internal/pb" -) - -var ( - none = noneConstraint{} - any = anyConstraint{} -) - -// A Constraint provides structured limitations on the versions that are -// admissible for a given project. -// -// As with Version, it has a private method because the gps's internal -// implementation of the problem is complete, and the system relies on type -// magic to operate. -type Constraint interface { - fmt.Stringer - - // ImpliedCaretString converts the Constraint to a string in the same manner - // as String(), but treats the empty operator as equivalent to ^, rather - // than =. - // - // In the same way that String() is the inverse of NewConstraint(), this - // method is the inverse of NewSemverConstraintIC(). - ImpliedCaretString() string - - // Matches indicates if the provided Version is allowed by the Constraint. - Matches(Version) bool - - // MatchesAny indicates if the intersection of the Constraint with the - // provided Constraint would yield a Constraint that could allow *any* - // Version. - MatchesAny(Constraint) bool - - // Intersect computes the intersection of the Constraint with the provided - // Constraint. - Intersect(Constraint) Constraint - - // typedString emits the normal stringified representation of the provided - // constraint, prefixed with a string that uniquely identifies the type of - // the constraint. - // - // It also forces Constraint to be a private/sealed interface, which is a - // design goal of the system. - typedString() string - - // copyTo copies fields into a serializable representation which can be - // converted back into an identical Constraint with constraintFromCache. - copyTo(*pb.Constraint) - - // identical returns true if the constraints are identical. - // - // Identical Constraints behave identically for all methods defined by the - // interface. A Constraint is always identical to itself. - // - // Constraints serialized for caching are de-serialized into identical instances. - identical(Constraint) bool -} - -// constraintFromCache returns a Constraint identical to the one which produced m. -func constraintFromCache(m *pb.Constraint) (Constraint, error) { - switch m.Type { - case pb.Constraint_Revision: - return Revision(m.Value), nil - case pb.Constraint_Branch: - return NewBranch(m.Value), nil - case pb.Constraint_DefaultBranch: - return newDefaultBranch(m.Value), nil - case pb.Constraint_Version: - return plainVersion(m.Value), nil - case pb.Constraint_Semver: - return NewSemverConstraint(m.Value) - - default: - return nil, fmt.Errorf("unrecognized Constraint type: %#v", m) - } -} - -// unpairedVersionFromCache returns an UnpairedVersion identical to the one which produced m. -func unpairedVersionFromCache(m *pb.Constraint) (UnpairedVersion, error) { - switch m.Type { - case pb.Constraint_Branch: - return NewBranch(m.Value), nil - case pb.Constraint_DefaultBranch: - return newDefaultBranch(m.Value), nil - case pb.Constraint_Version: - return plainVersion(m.Value), nil - case pb.Constraint_Semver: - sv, err := semver.NewVersion(m.Value) - if err != nil { - return nil, err - } - return semVersion{sv: sv}, nil - - default: - return nil, fmt.Errorf("unrecognized UnpairedVersion type: %#v", m) - } -} - -// NewSemverConstraint attempts to construct a semver Constraint object from the -// input string. -// -// If the input string cannot be made into a valid semver Constraint, an error -// is returned. -func NewSemverConstraint(body string) (Constraint, error) { - c, err := semver.NewConstraint(body) - if err != nil { - return nil, err - } - // If we got a simple semver.Version, simplify by returning our - // corresponding type - if sv, ok := c.(semver.Version); ok { - return semVersion{sv: sv}, nil - } - return semverConstraint{c: c}, nil -} - -// NewSemverConstraintIC attempts to construct a semver Constraint object from the -// input string, defaulting to a caret, ^, when no operator is specified. Put -// differently, ^ is the default operator for NewSemverConstraintIC, while = -// is the default operator for NewSemverConstraint. -// -// If the input string cannot be made into a valid semver Constraint, an error -// is returned. -func NewSemverConstraintIC(body string) (Constraint, error) { - c, err := semver.NewConstraintIC(body) - if err != nil { - return nil, err - } - // If we got a simple semver.Version, simplify by returning our - // corresponding type - if sv, ok := c.(semver.Version); ok { - return semVersion{sv: sv}, nil - } - return semverConstraint{c: c}, nil -} - -type semverConstraint struct { - c semver.Constraint -} - -func (c semverConstraint) String() string { - return c.c.String() -} - -// ImpliedCaretString converts the Constraint to a string in the same manner -// as String(), but treats the empty operator as equivalent to ^, rather -// than =. -// -// In the same way that String() is the inverse of NewConstraint(), this -// method is the inverse of NewSemverConstraintIC(). -func (c semverConstraint) ImpliedCaretString() string { - return c.c.ImpliedCaretString() -} - -func (c semverConstraint) typedString() string { - return fmt.Sprintf("svc-%s", c.c.String()) -} - -func (c semverConstraint) Matches(v Version) bool { - switch tv := v.(type) { - case versionTypeUnion: - for _, elem := range tv { - if c.Matches(elem) { - return true - } - } - case semVersion: - return c.c.Matches(tv.sv) == nil - case versionPair: - if tv2, ok := tv.v.(semVersion); ok { - return c.c.Matches(tv2.sv) == nil - } - } - - return false -} - -func (c semverConstraint) MatchesAny(c2 Constraint) bool { - return c.Intersect(c2) != none -} - -func (c semverConstraint) Intersect(c2 Constraint) Constraint { - switch tc := c2.(type) { - case anyConstraint: - return c - case versionTypeUnion: - for _, elem := range tc { - if rc := c.Intersect(elem); rc != none { - return rc - } - } - case semverConstraint: - rc := c.c.Intersect(tc.c) - if !semver.IsNone(rc) { - return semverConstraint{c: rc} - } - case semVersion: - rc := c.c.Intersect(tc.sv) - if !semver.IsNone(rc) { - // If single version intersected with constraint, we know the result - // must be the single version, so just return it back out - return c2 - } - case versionPair: - if tc2, ok := tc.v.(semVersion); ok { - rc := c.c.Intersect(tc2.sv) - if !semver.IsNone(rc) { - // same reasoning as previous case - return c2 - } - } - } - - return none -} - -func (c semverConstraint) identical(c2 Constraint) bool { - sc2, ok := c2.(semverConstraint) - if !ok { - return false - } - return c.c.String() == sc2.c.String() -} - -func (c semverConstraint) copyTo(msg *pb.Constraint) { - msg.Type = pb.Constraint_Semver - msg.Value = c.String() -} - -// IsAny indicates if the provided constraint is the wildcard "Any" constraint. -func IsAny(c Constraint) bool { - _, ok := c.(anyConstraint) - return ok -} - -// Any returns a constraint that will match anything. -func Any() Constraint { - return anyConstraint{} -} - -// anyConstraint is an unbounded constraint - it matches all other types of -// constraints. It mirrors the behavior of the semver package's any type. -type anyConstraint struct{} - -func (anyConstraint) String() string { - return "*" -} - -func (anyConstraint) ImpliedCaretString() string { - return "*" -} - -func (anyConstraint) typedString() string { - return "any-*" -} - -func (anyConstraint) Matches(Version) bool { - return true -} - -func (anyConstraint) MatchesAny(Constraint) bool { - return true -} - -func (anyConstraint) Intersect(c Constraint) Constraint { - return c -} - -func (anyConstraint) identical(c Constraint) bool { - return IsAny(c) -} - -func (anyConstraint) copyTo(*pb.Constraint) { - panic("anyConstraint should never be serialized; it is solver internal-only") -} - -// noneConstraint is the empty set - it matches no versions. It mirrors the -// behavior of the semver package's none type. -type noneConstraint struct{} - -func (noneConstraint) String() string { - return "" -} - -func (noneConstraint) ImpliedCaretString() string { - return "" -} - -func (noneConstraint) typedString() string { - return "none-" -} - -func (noneConstraint) Matches(Version) bool { - return false -} - -func (noneConstraint) MatchesAny(Constraint) bool { - return false -} - -func (noneConstraint) Intersect(Constraint) Constraint { - return none -} - -func (noneConstraint) identical(c Constraint) bool { - _, ok := c.(noneConstraint) - return ok -} - -func (noneConstraint) copyTo(*pb.Constraint) { - panic("noneConstraint should never be serialized; it is solver internal-only") -} - -// A ProjectConstraint combines a ProjectIdentifier with a Constraint. It -// indicates that, if packages contained in the ProjectIdentifier enter the -// depgraph, they must do so at a version that is allowed by the Constraint. -type ProjectConstraint struct { - Ident ProjectIdentifier - Constraint Constraint -} - -// ProjectConstraints is a map of projects, as identified by their import path -// roots (ProjectRoots) to the corresponding ProjectProperties. -// -// They are the standard form in which Manifests declare their required -// dependency properties - constraints and network locations - as well as the -// form in which RootManifests declare their overrides. -type ProjectConstraints map[ProjectRoot]ProjectProperties - -type workingConstraint struct { - Ident ProjectIdentifier - Constraint Constraint - overrNet, overrConstraint bool -} - -func pcSliceToMap(l []ProjectConstraint, r ...[]ProjectConstraint) ProjectConstraints { - final := make(ProjectConstraints) - - for _, pc := range l { - final[pc.Ident.ProjectRoot] = ProjectProperties{ - Source: pc.Ident.Source, - Constraint: pc.Constraint, - } - } - - for _, pcs := range r { - for _, pc := range pcs { - if pp, exists := final[pc.Ident.ProjectRoot]; exists { - // Technically this should be done through a bridge for - // cross-version-type matching...but this is a one off for root and - // that's just ridiculous for this. - pp.Constraint = pp.Constraint.Intersect(pc.Constraint) - final[pc.Ident.ProjectRoot] = pp - } else { - final[pc.Ident.ProjectRoot] = ProjectProperties{ - Source: pc.Ident.Source, - Constraint: pc.Constraint, - } - } - } - } - - return final -} - -func (m ProjectConstraints) asSortedSlice() []ProjectConstraint { - pcs := make([]ProjectConstraint, len(m)) - - k := 0 - for pr, pp := range m { - pcs[k] = ProjectConstraint{ - Ident: ProjectIdentifier{ - ProjectRoot: pr, - Source: pp.Source, - }, - Constraint: pp.Constraint, - } - k++ - } - - sort.SliceStable(pcs, func(i, j int) bool { - return pcs[i].Ident.Less(pcs[j].Ident) - }) - return pcs -} - -// overrideAll treats the receiver ProjectConstraints map as a set of override -// instructions, and applies overridden values to the ProjectConstraints. -// -// A slice of workingConstraint is returned, allowing differentiation between -// values that were or were not overridden. -func (m ProjectConstraints) overrideAll(pcm ProjectConstraints) (out []workingConstraint) { - out = make([]workingConstraint, len(pcm)) - k := 0 - for pr, pp := range pcm { - out[k] = m.override(pr, pp) - k++ - } - - sort.SliceStable(out, func(i, j int) bool { - return out[i].Ident.Less(out[j].Ident) - }) - return -} - -// override replaces a single ProjectConstraint with a workingConstraint, -// overriding its values if a corresponding entry exists in the -// ProjectConstraints map. -func (m ProjectConstraints) override(pr ProjectRoot, pp ProjectProperties) workingConstraint { - wc := workingConstraint{ - Ident: ProjectIdentifier{ - ProjectRoot: pr, - Source: pp.Source, - }, - Constraint: pp.Constraint, - } - - if opp, has := m[pr]; has { - // The rule for overrides is that *any* non-zero value for the prop - // should be considered an override, even if it's equal to what's - // already there. - if opp.Constraint != nil { - wc.Constraint = opp.Constraint - wc.overrConstraint = true - } - - // This may appear incorrect, because the solver encodes meaning into - // the empty string for NetworkName (it means that it would use the - // import path by default, but could be coerced into using an alternate - // URL). However, that 'coercion' can only happen if there's a - // disagreement between projects on where a dependency should be sourced - // from. Such disagreement is exactly what overrides preclude, so - // there's no need to preserve the meaning of "" here - thus, we can - // treat it as a zero value and ignore it, rather than applying it. - if opp.Source != "" { - wc.Ident.Source = opp.Source - wc.overrNet = true - } - } - - return wc -} diff --git a/vendor/github.com/golang/dep/gps/deduce.go b/vendor/github.com/golang/dep/gps/deduce.go deleted file mode 100644 index d29481d46cab1cfc8fd8ea23d4475bc2a20d8f95..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/deduce.go +++ /dev/null @@ -1,892 +0,0 @@ -// 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 gps - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "path" - "regexp" - "strconv" - "strings" - "sync" - - radix "github.com/armon/go-radix" - "github.com/pkg/errors" -) - -var ( - gitSchemes = []string{"https", "ssh", "git", "http"} - bzrSchemes = []string{"https", "bzr+ssh", "bzr", "http"} - hgSchemes = []string{"https", "ssh", "http"} - svnSchemes = []string{"https", "http", "svn", "svn+ssh"} - gopkginSchemes = []string{"https", "http"} -) - -const gopkgUnstableSuffix = "-unstable" - -func validateVCSScheme(scheme, typ string) bool { - // everything allows plain ssh - if scheme == "ssh" { - return true - } - - var schemes []string - switch typ { - case "git": - schemes = gitSchemes - case "bzr": - schemes = bzrSchemes - case "hg": - schemes = hgSchemes - case "svn": - schemes = svnSchemes - default: - panic(fmt.Sprint("unsupported vcs type", scheme)) - } - - for _, valid := range schemes { - if scheme == valid { - return true - } - } - return false -} - -// Regexes for the different known import path flavors -var ( - // This regex allows some usernames that github currently disallows. They - // have allowed them in the past. - ghRegex = regexp.MustCompile(`^(?P<root>github\.com(/[A-Za-z0-9][-A-Za-z0-9]*/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`) - gpinNewRegex = regexp.MustCompile(`^(?P<root>gopkg\.in(?:(/[a-zA-Z0-9][-a-zA-Z0-9]+)?)(/[a-zA-Z][-.a-zA-Z0-9]*)\.((?:v0|v[1-9][0-9]*)(?:\.0|\.[1-9][0-9]*){0,2}(?:-unstable)?)(?:\.git)?)((?:/[a-zA-Z0-9][-.a-zA-Z0-9]*)*)$`) - //gpinOldRegex = regexp.MustCompile(`^(?P<root>gopkg\.in/(?:([a-z0-9][-a-z0-9]+)/)?((?:v0|v[1-9][0-9]*)(?:\.0|\.[1-9][0-9]*){0,2}(-unstable)?)/([a-zA-Z][-a-zA-Z0-9]*)(?:\.git)?)((?:/[a-zA-Z][-a-zA-Z0-9]*)*)$`) - bbRegex = regexp.MustCompile(`^(?P<root>bitbucket\.org(?P<bitname>/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`) - //lpRegex = regexp.MustCompile(`^(?P<root>launchpad\.net/([A-Za-z0-9-._]+)(/[A-Za-z0-9-._]+)?)(/.+)?`) - lpRegex = regexp.MustCompile(`^(?P<root>launchpad\.net(/[A-Za-z0-9-._]+))((?:/[A-Za-z0-9_.\-]+)*)?$`) - //glpRegex = regexp.MustCompile(`^(?P<root>git\.launchpad\.net/([A-Za-z0-9_.\-]+)|~[A-Za-z0-9_.\-]+/(\+git|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+)$`) - glpRegex = regexp.MustCompile(`^(?P<root>git\.launchpad\.net(/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`) - //gcRegex = regexp.MustCompile(`^(?P<root>code\.google\.com/[pr]/(?P<project>[a-z0-9\-]+)(\.(?P<subrepo>[a-z0-9\-]+))?)(/[A-Za-z0-9_.\-]+)*$`) - jazzRegex = regexp.MustCompile(`^(?P<root>hub\.jazz\.net(/git/[a-z0-9]+/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`) - apacheRegex = regexp.MustCompile(`^(?P<root>git\.apache\.org(/[a-z0-9_.\-]+\.git))((?:/[A-Za-z0-9_.\-]+)*)$`) - vcsExtensionRegex = regexp.MustCompile(`^(?P<root>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/~]*?\.(?P<vcs>bzr|git|hg|svn))((?:/[A-Za-z0-9_.\-]+)*)$`) -) - -// Other helper regexes -var ( - scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) - pathvld = regexp.MustCompile(`^([A-Za-z0-9-]+)(\.[A-Za-z0-9-]+)+(/[A-Za-z0-9-_.~]+)*$`) -) - -func pathDeducerTrie() *deducerTrie { - dxt := newDeducerTrie() - - dxt.Insert("github.com/", githubDeducer{regexp: ghRegex}) - dxt.Insert("gopkg.in/", gopkginDeducer{regexp: gpinNewRegex}) - dxt.Insert("bitbucket.org/", bitbucketDeducer{regexp: bbRegex}) - dxt.Insert("launchpad.net/", launchpadDeducer{regexp: lpRegex}) - dxt.Insert("git.launchpad.net/", launchpadGitDeducer{regexp: glpRegex}) - dxt.Insert("hub.jazz.net/", jazzDeducer{regexp: jazzRegex}) - dxt.Insert("git.apache.org/", apacheDeducer{regexp: apacheRegex}) - - return dxt -} - -type pathDeducer interface { - // deduceRoot takes an import path such as - // "github.com/some-user/some-package/some-subpackage" - // and returns the root folder to where the version control - // system exists. For example, the root folder where .git exists. - // So the return of the above string would be - // "github.com/some-user/some-package" - deduceRoot(string) (string, error) - deduceSource(string, *url.URL) (maybeSource, error) -} - -type githubDeducer struct { - regexp *regexp.Regexp -} - -func (m githubDeducer) deduceRoot(path string) (string, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on github.com", path) - } - - return "github.com" + v[2], nil -} - -func (m githubDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on github.com", path) - } - - u.Host = "github.com" - u.Path = v[2] - - if u.Scheme == "ssh" && u.User != nil && u.User.Username() != "git" { - return nil, fmt.Errorf("github ssh must be accessed via the 'git' user; %s was provided", u.User.Username()) - } else if u.Scheme != "" { - if !validateVCSScheme(u.Scheme, "git") { - return nil, fmt.Errorf("%s is not a valid scheme for accessing a git repository", u.Scheme) - } - if u.Scheme == "ssh" { - u.User = url.User("git") - } - return maybeGitSource{url: u}, nil - } - - mb := make(maybeSources, len(gitSchemes)) - for k, scheme := range gitSchemes { - u2 := *u - if scheme == "ssh" { - u2.User = url.User("git") - } - u2.Scheme = scheme - mb[k] = maybeGitSource{url: &u2} - } - - return mb, nil -} - -type bitbucketDeducer struct { - regexp *regexp.Regexp -} - -func (m bitbucketDeducer) deduceRoot(path string) (string, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on bitbucket.org", path) - } - - return "bitbucket.org" + v[2], nil -} - -func (m bitbucketDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on bitbucket.org", path) - } - - u.Host = "bitbucket.org" - u.Path = v[2] - - // This isn't definitive, but it'll probably catch most - isgit := strings.HasSuffix(u.Path, ".git") || (u.User != nil && u.User.Username() == "git") - ishg := strings.HasSuffix(u.Path, ".hg") || (u.User != nil && u.User.Username() == "hg") - - // TODO(sdboyer) resolve scm ambiguity if needed by querying bitbucket's REST API - if u.Scheme != "" { - validgit, validhg := validateVCSScheme(u.Scheme, "git"), validateVCSScheme(u.Scheme, "hg") - if isgit { - if !validgit { - // This is unreachable for now, as the git schemes are a - // superset of the hg schemes - return nil, fmt.Errorf("%s is not a valid scheme for accessing a git repository", u.Scheme) - } - return maybeGitSource{url: u}, nil - } else if ishg { - if !validhg { - return nil, fmt.Errorf("%s is not a valid scheme for accessing an hg repository", u.Scheme) - } - return maybeHgSource{url: u}, nil - } else if !validgit && !validhg { - return nil, fmt.Errorf("%s is not a valid scheme for accessing either a git or hg repository", u.Scheme) - } - - // No other choice, make an option for both git and hg - return maybeSources{ - maybeHgSource{url: u}, - maybeGitSource{url: u}, - }, nil - } - - mb := make(maybeSources, 0) - // git is probably more common, even on bitbucket. however, bitbucket - // appears to fail _extremely_ slowly on git pings (ls-remote) when the - // underlying repository is actually an hg repository, so it's better - // to try hg first. - if !isgit { - for _, scheme := range hgSchemes { - u2 := *u - if scheme == "ssh" { - u2.User = url.User("hg") - } - u2.Scheme = scheme - mb = append(mb, maybeHgSource{url: &u2}) - } - } - - if !ishg { - for _, scheme := range gitSchemes { - u2 := *u - if scheme == "ssh" { - u2.User = url.User("git") - } - u2.Scheme = scheme - mb = append(mb, maybeGitSource{url: &u2}) - } - } - - return mb, nil -} - -type gopkginDeducer struct { - regexp *regexp.Regexp -} - -func (m gopkginDeducer) deduceRoot(p string) (string, error) { - v, err := m.parseAndValidatePath(p) - if err != nil { - return "", err - } - - return v[1], nil -} - -func (m gopkginDeducer) parseAndValidatePath(p string) ([]string, error) { - v := m.regexp.FindStringSubmatch(p) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on gopkg.in", p) - } - - // We duplicate some logic from the gopkg.in server in order to validate the - // import path string without having to make a network request - if strings.Contains(v[4], ".") { - return nil, fmt.Errorf("%s is not a valid import path; gopkg.in only allows major versions (%q instead of %q)", - p, v[4][:strings.Index(v[4], ".")], v[4]) - } - - return v, nil -} - -func (m gopkginDeducer) deduceSource(p string, u *url.URL) (maybeSource, error) { - // Reuse root detection logic for initial validation - v, err := m.parseAndValidatePath(p) - if err != nil { - return nil, err - } - - // Putting a scheme on gopkg.in would be really weird, disallow it - if u.Scheme != "" { - return nil, fmt.Errorf("specifying alternate schemes on gopkg.in imports is not permitted") - } - - // gopkg.in is always backed by github - u.Host = "github.com" - if v[2] == "" { - elem := v[3][1:] - u.Path = path.Join("/go-"+elem, elem) - } else { - u.Path = path.Join(v[2], v[3]) - } - - unstable := false - majorStr := v[4] - - if strings.HasSuffix(majorStr, gopkgUnstableSuffix) { - unstable = true - majorStr = strings.TrimSuffix(majorStr, gopkgUnstableSuffix) - } - major, err := strconv.ParseUint(majorStr[1:], 10, 64) - if err != nil { - // this should only be reachable if there's an error in the regex - return nil, fmt.Errorf("could not parse %q as a gopkg.in major version", majorStr[1:]) - } - - mb := make(maybeSources, len(gopkginSchemes)) - for k, scheme := range gopkginSchemes { - u2 := *u - u2.Scheme = scheme - mb[k] = maybeGopkginSource{ - opath: v[1], - url: &u2, - major: major, - unstable: unstable, - } - } - - return mb, nil -} - -type launchpadDeducer struct { - regexp *regexp.Regexp -} - -func (m launchpadDeducer) deduceRoot(path string) (string, error) { - // TODO(sdboyer) lp handling is nasty - there's ambiguities which can only really - // be resolved with a metadata request. See https://github.com/golang/go/issues/11436 - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on launchpad.net", path) - } - - return "launchpad.net" + v[2], nil -} - -func (m launchpadDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on launchpad.net", path) - } - - u.Host = "launchpad.net" - u.Path = v[2] - - if u.Scheme != "" { - if !validateVCSScheme(u.Scheme, "bzr") { - return nil, fmt.Errorf("%s is not a valid scheme for accessing a bzr repository", u.Scheme) - } - return maybeBzrSource{url: u}, nil - } - - mb := make(maybeSources, len(bzrSchemes)) - for k, scheme := range bzrSchemes { - u2 := *u - u2.Scheme = scheme - mb[k] = maybeBzrSource{url: &u2} - } - - return mb, nil -} - -type launchpadGitDeducer struct { - regexp *regexp.Regexp -} - -func (m launchpadGitDeducer) deduceRoot(path string) (string, error) { - // TODO(sdboyer) same ambiguity issues as with normal bzr lp - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on git.launchpad.net", path) - } - - return "git.launchpad.net" + v[2], nil -} - -func (m launchpadGitDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on git.launchpad.net", path) - } - - u.Host = "git.launchpad.net" - u.Path = v[2] - - if u.Scheme != "" { - if !validateVCSScheme(u.Scheme, "git") { - return nil, fmt.Errorf("%s is not a valid scheme for accessing a git repository", u.Scheme) - } - return maybeGitSource{url: u}, nil - } - - mb := make(maybeSources, len(gitSchemes)) - for k, scheme := range gitSchemes { - u2 := *u - u2.Scheme = scheme - mb[k] = maybeGitSource{url: &u2} - } - - return mb, nil -} - -type jazzDeducer struct { - regexp *regexp.Regexp -} - -func (m jazzDeducer) deduceRoot(path string) (string, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on hub.jazz.net", path) - } - - return "hub.jazz.net" + v[2], nil -} - -func (m jazzDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on hub.jazz.net", path) - } - - u.Host = "hub.jazz.net" - u.Path = v[2] - - switch u.Scheme { - case "": - u.Scheme = "https" - fallthrough - case "https": - return maybeGitSource{url: u}, nil - default: - return nil, fmt.Errorf("IBM's jazz hub only supports https, %s is not allowed", u.String()) - } -} - -type apacheDeducer struct { - regexp *regexp.Regexp -} - -func (m apacheDeducer) deduceRoot(path string) (string, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s is not a valid path for a source on git.apache.org", path) - } - - return "git.apache.org" + v[2], nil -} - -func (m apacheDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s is not a valid path for a source on git.apache.org", path) - } - - u.Host = "git.apache.org" - u.Path = v[2] - - if u.Scheme != "" { - if !validateVCSScheme(u.Scheme, "git") { - return nil, fmt.Errorf("%s is not a valid scheme for accessing a git repository", u.Scheme) - } - return maybeGitSource{url: u}, nil - } - - mb := make(maybeSources, len(gitSchemes)) - for k, scheme := range gitSchemes { - u2 := *u - u2.Scheme = scheme - mb[k] = maybeGitSource{url: &u2} - } - - return mb, nil -} - -type vcsExtensionDeducer struct { - regexp *regexp.Regexp -} - -func (m vcsExtensionDeducer) deduceRoot(path string) (string, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return "", fmt.Errorf("%s contains no vcs extension hints for matching", path) - } - - return v[1], nil -} - -func (m vcsExtensionDeducer) deduceSource(path string, u *url.URL) (maybeSource, error) { - v := m.regexp.FindStringSubmatch(path) - if v == nil { - return nil, fmt.Errorf("%s contains no vcs extension hints for matching", path) - } - - switch v[4] { - case "git", "hg", "bzr": - x := strings.SplitN(v[1], "/", 2) - // TODO(sdboyer) is this actually correct for bzr? - u.Host = x[0] - u.Path = "/" + x[1] - - if u.Scheme != "" { - if !validateVCSScheme(u.Scheme, v[4]) { - return nil, fmt.Errorf("%s is not a valid scheme for accessing %s repositories (path %s)", u.Scheme, v[4], path) - } - - switch v[4] { - case "git": - return maybeGitSource{url: u}, nil - case "bzr": - return maybeBzrSource{url: u}, nil - case "hg": - return maybeHgSource{url: u}, nil - } - } - - var schemes []string - var mb maybeSources - var f func(k int, u *url.URL) - - switch v[4] { - case "git": - schemes = gitSchemes - f = func(k int, u *url.URL) { - mb[k] = maybeGitSource{url: u} - } - case "bzr": - schemes = bzrSchemes - f = func(k int, u *url.URL) { - mb[k] = maybeBzrSource{url: u} - } - case "hg": - schemes = hgSchemes - f = func(k int, u *url.URL) { - mb[k] = maybeHgSource{url: u} - } - } - - mb = make(maybeSources, len(schemes)) - for k, scheme := range schemes { - u2 := *u - u2.Scheme = scheme - f(k, &u2) - } - - return mb, nil - default: - return nil, fmt.Errorf("unknown repository type: %q", v[4]) - } -} - -// A deducer takes an import path and inspects it to determine where the -// corresponding project root should be. It applies a number of matching -// techniques, eventually falling back to an HTTP request for go-get metadata if -// none of the explicit rules succeed. -// -// The only real implementation is deductionCoordinator. The interface is -// primarily intended for testing purposes. -type deducer interface { - deduceRootPath(ctx context.Context, path string) (pathDeduction, error) -} - -type deductionCoordinator struct { - suprvsr *supervisor - mut sync.RWMutex - rootxt *radix.Tree - deducext *deducerTrie -} - -func newDeductionCoordinator(superv *supervisor) *deductionCoordinator { - dc := &deductionCoordinator{ - suprvsr: superv, - rootxt: radix.New(), - deducext: pathDeducerTrie(), - } - - return dc -} - -// deduceRootPath takes an import path and attempts to deduce various -// metadata about it - what type of source should handle it, and where its -// "root" is (for vcs repositories, the repository root). -// -// If no errors are encountered, the returned pathDeduction will contain both -// the root path and a list of maybeSources, which can be subsequently used to -// create a handler that will manage the particular source. -func (dc *deductionCoordinator) deduceRootPath(ctx context.Context, path string) (pathDeduction, error) { - if err := dc.suprvsr.ctx.Err(); err != nil { - return pathDeduction{}, err - } - - // First, check the rootxt to see if there's a prefix match - if so, we - // can return that and move on. - dc.mut.RLock() - prefix, data, has := dc.rootxt.LongestPrefix(path) - dc.mut.RUnlock() - if has && isPathPrefixOrEqual(prefix, path) { - switch d := data.(type) { - case maybeSource: - return pathDeduction{root: prefix, mb: d}, nil - case *httpMetadataDeducer: - // Multiple calls have come in for a similar path shape during - // the window in which the HTTP request to retrieve go get - // metadata is in flight. Fold this request in with the existing - // one(s) by calling the deduction method, which will avoid - // duplication of work through a sync.Once. - return d.deduce(ctx, path) - } - - panic(fmt.Sprintf("unexpected %T in deductionCoordinator.rootxt: %v", data, data)) - } - - // No match. Try known path deduction first. - pd, err := dc.deduceKnownPaths(path) - if err == nil { - // Deduction worked; store it in the rootxt, send on retchan and - // terminate. - // FIXME(sdboyer) deal with changing path vs. root. Probably needs - // to be predeclared and reused in the hmd returnFunc - dc.mut.Lock() - dc.rootxt.Insert(pd.root, pd.mb) - dc.mut.Unlock() - return pd, nil - } - - if err != errNoKnownPathMatch { - return pathDeduction{}, err - } - - // The err indicates no known path matched. It's still possible that - // retrieving go get metadata might do the trick. - hmd := &httpMetadataDeducer{ - basePath: path, - suprvsr: dc.suprvsr, - // The vanity deducer will call this func with a completed - // pathDeduction if it succeeds in finding one. We process it - // back through the action channel to ensure serialized - // access to the rootxt map. - returnFunc: func(pd pathDeduction) { - dc.mut.Lock() - dc.rootxt.Insert(pd.root, pd.mb) - dc.mut.Unlock() - }, - } - - // Save the hmd in the rootxt so that calls checking on similar - // paths made while the request is in flight can be folded together. - dc.mut.Lock() - dc.rootxt.Insert(path, hmd) - dc.mut.Unlock() - - // Trigger the HTTP-backed deduction process for this requestor. - return hmd.deduce(ctx, path) -} - -// pathDeduction represents the results of a successful import path deduction - -// a root path, plus a maybeSource that can be used to attempt to connect to -// the source. -type pathDeduction struct { - root string - mb maybeSource -} - -var errNoKnownPathMatch = errors.New("no known path match") - -func (dc *deductionCoordinator) deduceKnownPaths(path string) (pathDeduction, error) { - u, path, err := normalizeURI(path) - if err != nil { - return pathDeduction{}, err - } - - // First, try the root path-based matches - if _, mtch, has := dc.deducext.LongestPrefix(path); has { - root, err := mtch.deduceRoot(path) - if err != nil { - return pathDeduction{}, err - } - mb, err := mtch.deduceSource(path, u) - if err != nil { - return pathDeduction{}, err - } - - return pathDeduction{ - root: root, - mb: mb, - }, nil - } - - // Next, try the vcs extension-based (infix) matcher - exm := vcsExtensionDeducer{regexp: vcsExtensionRegex} - if root, err := exm.deduceRoot(path); err == nil { - mb, err := exm.deduceSource(path, u) - if err != nil { - return pathDeduction{}, err - } - - return pathDeduction{ - root: root, - mb: mb, - }, nil - } - - return pathDeduction{}, errNoKnownPathMatch -} - -type httpMetadataDeducer struct { - once sync.Once - deduced pathDeduction - deduceErr error - basePath string - returnFunc func(pathDeduction) - suprvsr *supervisor -} - -func (hmd *httpMetadataDeducer) deduce(ctx context.Context, path string) (pathDeduction, error) { - hmd.once.Do(func() { - opath := path - u, path, err := normalizeURI(path) - if err != nil { - err = errors.Wrapf(err, "unable to normalize URI") - hmd.deduceErr = err - return - } - - pd := pathDeduction{} - - // Make the HTTP call to attempt to retrieve go-get metadata - var root, vcs, reporoot string - err = hmd.suprvsr.do(ctx, path, ctHTTPMetadata, func(ctx context.Context) error { - root, vcs, reporoot, err = getMetadata(ctx, path, u.Scheme) - if err != nil { - err = errors.Wrapf(err, "unable to read metadata") - } - return err - }) - if err != nil { - err = errors.Wrapf(err, "unable to deduce repository and source type for %q", opath) - hmd.deduceErr = err - return - } - pd.root = root - - // If we got something back at all, then it supersedes the actual input for - // the real URL to hit - repoURL, err := url.Parse(reporoot) - if err != nil { - err = errors.Wrapf(err, "server returned bad URL in go-get metadata, reporoot=%q", reporoot) - hmd.deduceErr = err - return - } - - // If the input path specified a scheme, then try to honor it. - if u.Scheme != "" && repoURL.Scheme != u.Scheme { - // If the input scheme was http, but the go-get metadata - // nevertheless indicated https should be used for the repo, then - // trust the metadata and use https. - // - // To err on the secure side, do NOT allow the same in the other - // direction (https -> http). - if u.Scheme != "http" || repoURL.Scheme != "https" { - hmd.deduceErr = errors.Errorf("scheme mismatch for %q: input asked for %q, but go-get metadata specified %q", path, u.Scheme, repoURL.Scheme) - return - } - } - - switch vcs { - case "git": - pd.mb = maybeGitSource{url: repoURL} - case "bzr": - pd.mb = maybeBzrSource{url: repoURL} - case "hg": - pd.mb = maybeHgSource{url: repoURL} - default: - hmd.deduceErr = errors.Errorf("unsupported vcs type %s in go-get metadata from %s", vcs, path) - return - } - - hmd.deduced = pd - // All data is assigned for other goroutines that may be waiting. Now, - // send the pathDeduction back to the deductionCoordinator by calling - // the returnFunc. This will also remove the reference to this hmd in - // the coordinator's trie. - // - // When this call finishes, it is guaranteed the coordinator will have - // at least begun running the action to insert the path deduction, which - // means no other deduction request will be able to interleave and - // request the same path before the pathDeduction can be processed, but - // after this hmd has been dereferenced from the trie. - hmd.returnFunc(pd) - }) - - return hmd.deduced, hmd.deduceErr -} - -// normalizeURI takes a path string - which can be a plain import path, or a -// proper URI, or something SCP-shaped - performs basic validity checks, and -// returns both a full URL and just the path portion. -func normalizeURI(p string) (*url.URL, string, error) { - var u *url.URL - var newpath string - if m := scpSyntaxRe.FindStringSubmatch(p); m != nil { - // Match SCP-like syntax and convert it to a URL. - // Eg, "git@github.com:user/repo" becomes - // "ssh://git@github.com/user/repo". - u = &url.URL{ - Scheme: "ssh", - User: url.User(m[1]), - Host: m[2], - Path: "/" + m[3], - // TODO(sdboyer) This is what stdlib sets; grok why better - //RawPath: m[3], - } - } else { - var err error - u, err = url.Parse(p) - if err != nil { - return nil, "", errors.Errorf("%q is not a valid URI", p) - } - } - - // If no scheme was passed, then the entire path will have been put into - // u.Path. Either way, construct the normalized path correctly. - if u.Host == "" { - newpath = p - } else { - newpath = path.Join(u.Host, u.Path) - } - - return u, newpath, nil -} - -// fetchMetadata fetches the remote metadata for path. -func fetchMetadata(ctx context.Context, path, scheme string) (rc io.ReadCloser, err error) { - if scheme == "http" { - rc, err = doFetchMetadata(ctx, "http", path) - return - } - - rc, err = doFetchMetadata(ctx, "https", path) - if err == nil { - return - } - - rc, err = doFetchMetadata(ctx, "http", path) - return -} - -func doFetchMetadata(ctx context.Context, scheme, path string) (io.ReadCloser, error) { - url := fmt.Sprintf("%s://%s?go-get=1", scheme, path) - switch scheme { - case "https", "http": - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, errors.Wrapf(err, "unable to build HTTP request for URL %q", url) - } - - resp, err := http.DefaultClient.Do(req.WithContext(ctx)) - if err != nil { - return nil, errors.Wrapf(err, "failed HTTP request to URL %q", url) - } - - return resp.Body, nil - default: - return nil, errors.Errorf("unknown remote protocol scheme: %q", scheme) - } -} - -// getMetadata fetches and decodes remote metadata for path. -// -// scheme is optional. If it's http, only http will be attempted for fetching. -// Any other scheme (including none) will first try https, then fall back to -// http. -func getMetadata(ctx context.Context, path, scheme string) (string, string, string, error) { - rc, err := fetchMetadata(ctx, path, scheme) - if err != nil { - return "", "", "", errors.Wrapf(err, "unable to fetch raw metadata") - } - defer rc.Close() - - imports, err := parseMetaGoImports(rc) - if err != nil { - return "", "", "", errors.Wrapf(err, "unable to parse go-import metadata") - } - match := -1 - for i, im := range imports { - if !strings.HasPrefix(path, im.Prefix) { - continue - } - if match != -1 { - return "", "", "", errors.Errorf("multiple meta tags match import path %q", path) - } - match = i - } - if match == -1 { - return "", "", "", errors.Errorf("go-import metadata not found") - } - return imports[match].Prefix, imports[match].VCS, imports[match].RepoRoot, nil -} diff --git a/vendor/github.com/golang/dep/gps/discovery.go b/vendor/github.com/golang/dep/gps/discovery.go deleted file mode 100644 index 8da4a66d4b53bdc82f2acabeb0a7420eeec2e6ba..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/discovery.go +++ /dev/null @@ -1,83 +0,0 @@ -// 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 gps - -// This code is taken from cmd/go/discovery.go; it is the logic go get itself -// uses to interpret meta imports information. - -import ( - "encoding/xml" - "fmt" - "io" - "strings" -) - -// charsetReader returns a reader for the given charset. Currently -// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful -// error which is printed by go get, so the user can find why the package -// wasn't downloaded if the encoding is not supported. Note that, in -// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters -// greater than 0x7f are not rejected). -func charsetReader(charset string, input io.Reader) (io.Reader, error) { - switch strings.ToLower(charset) { - case "ascii": - return input, nil - default: - return nil, fmt.Errorf("can't decode XML document using charset %q", charset) - } -} - -type metaImport struct { - Prefix, VCS, RepoRoot string -} - -// parseMetaGoImports returns meta imports from the HTML in r. -// Parsing ends at the end of the <head> section or the beginning of the <body>. -func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) { - d := xml.NewDecoder(r) - d.CharsetReader = charsetReader - d.Strict = false - var t xml.Token - for { - t, err = d.RawToken() - if err != nil { - if err == io.EOF || len(imports) > 0 { - err = nil - } - return - } - if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") { - return - } - if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") { - return - } - e, ok := t.(xml.StartElement) - if !ok || !strings.EqualFold(e.Name.Local, "meta") { - continue - } - if attrValue(e.Attr, "name") != "go-import" { - continue - } - if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 { - imports = append(imports, metaImport{ - Prefix: f[0], - VCS: f[1], - RepoRoot: f[2], - }) - } - } -} - -// attrValue returns the attribute value for the case-insensitive key -// `name', or the empty string if nothing is found. -func attrValue(attrs []xml.Attr, name string) string { - for _, a := range attrs { - if strings.EqualFold(a.Name.Local, name) { - return a.Value - } - } - return "" -} diff --git a/vendor/github.com/golang/dep/gps/example.go b/vendor/github.com/golang/dep/gps/example.go deleted file mode 100644 index 29657e0f562428fefb783b8396b57265917d4eb6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/example.go +++ /dev/null @@ -1,79 +0,0 @@ -// 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 ignore - -package main - -import ( - "go/build" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" - - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/pkgtree" -) - -// This is probably the simplest possible implementation of gps. It does the -// substantive work that `go get` does, except: -// 1. It drops the resulting tree into vendor instead of GOPATH -// 2. It prefers semver tags (if available) over branches -// 3. It removes any vendor directories nested within dependencies -// -// This will compile and work...and then blow away any vendor directory present -// in the cwd. Be careful! -func main() { - // Assume the current directory is correctly placed on a GOPATH, and that it's the - // root of the project. - root, _ := os.Getwd() - srcprefix := filepath.Join(build.Default.GOPATH, "src") + string(filepath.Separator) - importroot := filepath.ToSlash(strings.TrimPrefix(root, srcprefix)) - - // Set up params, including tracing - params := gps.SolveParameters{ - RootDir: root, - TraceLogger: log.New(os.Stdout, "", 0), - ProjectAnalyzer: NaiveAnalyzer{}, - } - // Perform static analysis on the current project to find all of its imports. - params.RootPackageTree, _ = pkgtree.ListPackages(root, importroot) - - // Set up a SourceManager. This manages interaction with sources (repositories). - tempdir, _ := ioutil.TempDir("", "gps-repocache") - sourcemgr, _ := gps.NewSourceManager(gps.SourceManagerConfig{Cachedir: filepath.Join(tempdir)}) - defer sourcemgr.Release() - - // Prep and run the solver - solver, _ := gps.Prepare(params, sourcemgr) - solution, err := solver.Solve() - if err == nil { - // If no failure, blow away the vendor dir and write a new one out, - // stripping nested vendor directories as we go. - os.RemoveAll(filepath.Join(root, "vendor")) - gps.WriteDepTree(filepath.Join(root, "vendor"), solution, sourcemgr, true) - } -} - -// NaiveAnalyzer is a project analyzer that implements gps.ProjectAnalyzer interface. -type NaiveAnalyzer struct{} - -// DeriveManifestAndLock is called when the solver needs manifest/lock data -// for a particular dependency project (identified by the gps.ProjectRoot -// parameter) at a particular version. That version will be checked out in a -// directory rooted at path. -func (a NaiveAnalyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) { - return nil, nil, nil -} - -// Info reports the name and version of the analyzer. This is used internally as part -// of gps' hashing memoization scheme. -func (a NaiveAnalyzer) Info() gps.ProjectAnalyzerInfo { - return gps.ProjectAnalyzerInfo{ - Name: "example-analyzer", - Version: 1, - } -} diff --git a/vendor/github.com/golang/dep/gps/filesystem.go b/vendor/github.com/golang/dep/gps/filesystem.go deleted file mode 100644 index fd683f325c364c10c332f9ce0938fb977ccaac06..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/filesystem.go +++ /dev/null @@ -1,136 +0,0 @@ -// 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 gps - -import ( - "os" - "path/filepath" - "strings" - - "github.com/pkg/errors" -) - -// fsLink represents a symbolic link. -type fsLink struct { - path string - to string - - // circular denotes if evaluating the symlink fails with "too many links" error. - // This errors means that it's very likely that the symlink has circual refernce. - circular bool - - // broken denotes that attempting to resolve the link fails, most likely because - // the destaination doesn't exist. - broken bool -} - -// filesystemState represents the state of a file system. -type filesystemState struct { - root string - dirs []string - files []string - links []fsLink -} - -func (s filesystemState) setup() error { - for _, dir := range s.dirs { - p := filepath.Join(s.root, dir) - - if err := os.MkdirAll(p, 0777); err != nil { - return errors.Errorf("os.MkdirAll(%q, 0777) err=%q", p, err) - } - } - - for _, file := range s.files { - p := filepath.Join(s.root, file) - - f, err := os.Create(p) - if err != nil { - return errors.Errorf("os.Create(%q) err=%q", p, err) - } - - if err := f.Close(); err != nil { - return errors.Errorf("file %q Close() err=%q", p, err) - } - } - - for _, link := range s.links { - p := filepath.Join(s.root, link.path) - - // On Windows, relative symlinks confuse filepath.Walk. So, we'll just sigh - // and do absolute links, assuming they are relative to the directory of - // link.path. - // - // Reference: https://github.com/golang/go/issues/17540 - // - // TODO(ibrasho): This was fixed in Go 1.9. Remove this when support for - // 1.8 is dropped. - dir := filepath.Dir(p) - to := "" - if link.to != "" { - to = filepath.Join(dir, link.to) - } - - if err := os.Symlink(to, p); err != nil { - return errors.Errorf("os.Symlink(%q, %q) err=%q", to, p, err) - } - } - - return nil -} - -// deriveFilesystemState returns a filesystemState based on the state of -// the filesystem on root. -func deriveFilesystemState(root string) (filesystemState, error) { - fs := filesystemState{root: root} - - err := filepath.Walk(fs.root, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if path == fs.root { - return nil - } - - relPath, err := filepath.Rel(fs.root, path) - if err != nil { - return err - } - - if (info.Mode() & os.ModeSymlink) != 0 { - l := fsLink{path: relPath} - - l.to, err = filepath.EvalSymlinks(path) - if err != nil && strings.HasSuffix(err.Error(), "too many links") { - l.circular = true - } else if err != nil && os.IsNotExist(err) { - l.broken = true - } else if err != nil { - return err - } - - fs.links = append(fs.links, l) - - return nil - } - - if info.IsDir() { - fs.dirs = append(fs.dirs, relPath) - - return nil - } - - fs.files = append(fs.files, relPath) - - return nil - }) - - if err != nil { - return filesystemState{}, err - } - - return fs, nil -} diff --git a/vendor/github.com/golang/dep/gps/hash.go b/vendor/github.com/golang/dep/gps/hash.go deleted file mode 100644 index 556933bcf3d1d2eef23743c8980cc6b9fa038b93..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/hash.go +++ /dev/null @@ -1,133 +0,0 @@ -// 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 gps - -import ( - "bytes" - "crypto/sha256" - "io" - "sort" - "strconv" - "strings" -) - -// string headers used to demarcate sections in hash input creation -const ( - hhConstraints = "-CONSTRAINTS-" - hhImportsReqs = "-IMPORTS/REQS-" - hhIgnores = "-IGNORES-" - hhOverrides = "-OVERRIDES-" - hhAnalyzer = "-ANALYZER-" -) - -// HashInputs computes a hash digest of all data in SolveParams and the -// RootManifest that act as function inputs to Solve(). -// -// The digest returned from this function is the same as the digest that would -// be included with a Solve() Result. As such, it's appropriate for comparison -// against the digest stored in a lock file, generated by a previous Solve(): if -// the digests match, then manifest and lock are in sync, and a Solve() is -// unnecessary. -// -// (Basically, this is for memoization.) -func (s *solver) HashInputs() (digest []byte) { - h := sha256.New() - s.writeHashingInputs(h) - - hd := h.Sum(nil) - digest = hd[:] - return -} - -func (s *solver) writeHashingInputs(w io.Writer) { - writeString := func(s string) { - // Skip zero-length string writes; it doesn't affect the real hash - // calculation, and keeps misleading newlines from showing up in the - // debug output. - if s != "" { - // All users of writeHashingInputs cannot error on Write(), so just - // ignore it - w.Write([]byte(s)) - } - } - - // We write "section headers" into the hash purely to ease scanning when - // debugging this input-constructing algorithm; as long as the headers are - // constant, then they're effectively a no-op. - writeString(hhConstraints) - - // getApplicableConstraints will apply overrides, incorporate requireds, - // apply local ignores, drop stdlib imports, and finally trim out - // ineffectual constraints. - for _, pd := range s.rd.getApplicableConstraints(s.stdLibFn) { - writeString(string(pd.Ident.ProjectRoot)) - writeString(pd.Ident.Source) - writeString(pd.Constraint.typedString()) - } - - // Write out each discrete import, including those derived from requires. - writeString(hhImportsReqs) - imports := s.rd.externalImportList(s.stdLibFn) - sort.Strings(imports) - for _, im := range imports { - writeString(im) - } - - // Add ignores, skipping any that point under the current project root; - // those will have already been implicitly incorporated by the import - // lister. - writeString(hhIgnores) - - ig := s.rd.ir.ToSlice() - sort.Strings(ig) - for _, igp := range ig { - // Typical prefix comparison checks will erroneously fail if the wildcard - // is present. Trim it off, if present. - tigp := strings.TrimSuffix(igp, "*") - if !strings.HasPrefix(tigp, s.rd.rpt.ImportRoot) || !isPathPrefixOrEqual(s.rd.rpt.ImportRoot, tigp) { - writeString(igp) - } - } - - // Overrides *also* need their own special entry distinct from basic - // constraints, to represent the unique effects they can have on the entire - // solving process beyond root's immediate scope. - writeString(hhOverrides) - for _, pc := range s.rd.ovr.asSortedSlice() { - writeString(string(pc.Ident.ProjectRoot)) - if pc.Ident.Source != "" { - writeString(pc.Ident.Source) - } - if pc.Constraint != nil { - writeString(pc.Constraint.typedString()) - } - } - - writeString(hhAnalyzer) - ai := s.rd.an.Info() - writeString(ai.Name) - writeString(strconv.Itoa(ai.Version)) -} - -// bytes.Buffer wrapper that injects newlines after each call to Write(). -type nlbuf bytes.Buffer - -func (buf *nlbuf) Write(p []byte) (n int, err error) { - n, _ = (*bytes.Buffer)(buf).Write(p) - (*bytes.Buffer)(buf).WriteByte('\n') - return n + 1, nil -} - -// HashingInputsAsString returns the raw input data used by Solver.HashInputs() -// as a string. -// -// This is primarily intended for debugging purposes. -func HashingInputsAsString(s Solver) string { - ts := s.(*solver) - buf := new(nlbuf) - ts.writeHashingInputs(buf) - - return (*bytes.Buffer)(buf).String() -} diff --git a/vendor/github.com/golang/dep/gps/identifier.go b/vendor/github.com/golang/dep/gps/identifier.go deleted file mode 100644 index cf3ca235137ef6b6a7ca2124267d35f05dc80242..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/identifier.go +++ /dev/null @@ -1,226 +0,0 @@ -// 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 gps - -import ( - "fmt" - "math/rand" - "strconv" -) - -// ProjectRoot is the topmost import path in a tree of other import paths - the -// root of the tree. In gps' current design, ProjectRoots have to correspond to -// a repository root (mostly), but their real purpose is to identify the root -// import path of a "project", logically encompassing all child packages. -// -// Projects are a crucial unit of operation in gps. Constraints are declared by -// a project's manifest, and apply to all packages in a ProjectRoot's tree. -// Solving itself mostly proceeds on a project-by-project basis. -// -// Aliasing string types is usually a bit of an anti-pattern. gps does it here -// as a means of clarifying API intent. This is important because Go's package -// management domain has lots of different path-ish strings floating around: -// -// actual directories: -// /home/sdboyer/go/src/github.com/sdboyer/gps/example -// URLs: -// https://github.com/sdboyer/gps -// import paths: -// github.com/sdboyer/gps/example -// portions of import paths that refer to a package: -// example -// portions that could not possibly refer to anything sane: -// github.com/sdboyer -// portions that correspond to a repository root: -// github.com/sdboyer/gps -// -// While not a panacea, having ProjectRoot allows gps to clearly indicate via -// the type system when a path-ish string must have particular semantics. -type ProjectRoot string - -// A ProjectIdentifier provides the name and source location of a dependency. It -// is related to, but differs in two key ways from, a plain import path. -// -// First, ProjectIdentifiers do not identify a single package. Rather, they -// encompass the whole tree of packages, including tree's root - the -// ProjectRoot. In gps' current design, this ProjectRoot almost always -// corresponds to the root of a repository. -// -// Second, ProjectIdentifiers can optionally carry a Source, which -// identifies where the underlying source code can be located on the network. -// These can be either a full URL, including protocol, or plain import paths. -// So, these are all valid data for Source: -// -// github.com/sdboyer/gps -// github.com/fork/gps -// git@github.com:sdboyer/gps -// https://github.com/sdboyer/gps -// -// With plain import paths, network addresses are derived purely through an -// algorithm. By having an explicit network name, it becomes possible to, for -// example, transparently substitute a fork for the original upstream source -// repository. -// -// Note that gps makes no guarantees about the actual import paths contained in -// a repository aligning with ImportRoot. If tools, or their users, specify an -// alternate Source that contains a repository with incompatible internal -// import paths, gps' solving operations will error. (gps does no import -// rewriting.) -// -// Also note that if different projects' manifests report a different -// Source for a given ImportRoot, it is a solve failure. Everyone has to -// agree on where a given import path should be sourced from. -// -// If Source is not explicitly set, gps will derive the network address from -// the ImportRoot using a similar algorithm to that utilized by `go get`. -type ProjectIdentifier struct { - ProjectRoot ProjectRoot - Source string -} - -// Less compares by ProjectRoot then normalized Source. -func (i ProjectIdentifier) Less(j ProjectIdentifier) bool { - if i.ProjectRoot < j.ProjectRoot { - return true - } - if j.ProjectRoot < i.ProjectRoot { - return false - } - return i.normalizedSource() < j.normalizedSource() -} - -func (i ProjectIdentifier) eq(j ProjectIdentifier) bool { - if i.ProjectRoot != j.ProjectRoot { - return false - } - if i.Source == j.Source { - return true - } - - if (i.Source == "" && j.Source == string(j.ProjectRoot)) || - (j.Source == "" && i.Source == string(i.ProjectRoot)) { - return true - } - - return false -} - -// equiv will check if the two identifiers are "equivalent," under special -// rules. -// -// Given that the ProjectRoots are equal (==), equivalency occurs if: -// -// 1. The Sources are equal (==), OR -// 2. The LEFT (the receiver) Source is non-empty, and the right -// Source is empty. -// -// *This is asymmetry in this binary relation is intentional.* It facilitates -// the case where we allow for a ProjectIdentifier with an explicit Source -// to match one without. -func (i ProjectIdentifier) equiv(j ProjectIdentifier) bool { - if i.ProjectRoot != j.ProjectRoot { - return false - } - if i.Source == j.Source { - return true - } - - if i.Source != "" && j.Source == "" { - return true - } - - return false -} - -func (i ProjectIdentifier) normalizedSource() string { - if i.Source == "" { - return string(i.ProjectRoot) - } - return i.Source -} - -func (i ProjectIdentifier) String() string { - if i.Source == "" || i.Source == string(i.ProjectRoot) { - return string(i.ProjectRoot) - } - return fmt.Sprintf("%s (from %s)", i.ProjectRoot, i.Source) -} - -func (i ProjectIdentifier) normalize() ProjectIdentifier { - if i.Source == "" { - i.Source = string(i.ProjectRoot) - } - - return i -} - -// ProjectProperties comprise the properties that can be attached to a -// ProjectRoot. -// -// In general, these are declared in the context of a map of ProjectRoot to its -// ProjectProperties; they make little sense without their corresponding -// ProjectRoot. -type ProjectProperties struct { - Source string - Constraint Constraint -} - -// bimodalIdentifiers are used to track work to be done in the unselected queue. -type bimodalIdentifier struct { - id ProjectIdentifier - // List of packages required within/under the ProjectIdentifier - pl []string - // prefv is used to indicate a 'preferred' version. This is expected to be - // derived from a dep's lock data, or else is empty. - prefv Version - // Indicates that the bmi came from the root project originally - fromRoot bool -} - -type atom struct { - id ProjectIdentifier - v Version -} - -// With a random revision and no name, collisions are...unlikely -var nilpa = atom{ - v: Revision(strconv.FormatInt(rand.Int63(), 36)), -} - -type atomWithPackages struct { - a atom - pl []string -} - -// bmi converts an atomWithPackages into a bimodalIdentifier. -// -// This is mostly intended for (read-only) trace use, so the package list slice -// is not copied. It is the callers responsibility to not modify the pl slice, -// lest that backpropagate and cause inconsistencies. -func (awp atomWithPackages) bmi() bimodalIdentifier { - return bimodalIdentifier{ - id: awp.a.id, - pl: awp.pl, - } -} - -// completeDep (name hopefully to change) provides the whole picture of a -// dependency - the root (repo and project, since currently we assume the two -// are the same) name, a constraint, and the actual packages needed that are -// under that root. -type completeDep struct { - // The base workingConstraint - workingConstraint - // The specific packages required from the ProjectDep - pl []string -} - -// dependency represents an incomplete edge in the depgraph. It has a -// fully-realized atom as the depender (the tail/source of the edge), and a set -// of requirements that any atom to be attached at the head/target must satisfy. -type dependency struct { - depender atom - dep completeDep -} diff --git a/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel b/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel deleted file mode 100644 index fafa65ddf55f1bb7cb543eee99e6d98b0976a4fe..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel +++ /dev/null @@ -1,13 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "pb.go", - "source_cache.pb.go", - ], - importmap = "vendor/github.com/golang/dep/gps/internal/pb", - importpath = "github.com/golang/dep/gps/internal/pb", - visibility = ["//vendor/github.com/golang/dep/gps:__subpackages__"], - deps = ["//vendor/github.com/golang/protobuf/proto:go_default_library"], -) diff --git a/vendor/github.com/golang/dep/gps/internal/pb/pb.go b/vendor/github.com/golang/dep/gps/internal/pb/pb.go deleted file mode 100644 index f622f388e7b5877529d8977600d25ba796ffa6b1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/internal/pb/pb.go +++ /dev/null @@ -1,8 +0,0 @@ -// 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 pb provides generated Protocol Buffers for cache serialization. -package pb - -//go:generate protoc --go_out=. source_cache.proto diff --git a/vendor/github.com/golang/dep/gps/internal/pb/source_cache.pb.go b/vendor/github.com/golang/dep/gps/internal/pb/source_cache.pb.go deleted file mode 100644 index 8f9436c9b103393ad5f42ab4dcc47d7865753d97..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/internal/pb/source_cache.pb.go +++ /dev/null @@ -1,199 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: source_cache.proto - -/* -Package pb is a generated protocol buffer package. - -It is generated from these files: - source_cache.proto - -It has these top-level messages: - Constraint - ProjectProperties - LockedProject -*/ -package pb - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// 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 Constraint_Type int32 - -const ( - Constraint_Revision Constraint_Type = 0 - Constraint_Branch Constraint_Type = 1 - Constraint_DefaultBranch Constraint_Type = 2 - Constraint_Version Constraint_Type = 3 - Constraint_Semver Constraint_Type = 4 -) - -var Constraint_Type_name = map[int32]string{ - 0: "Revision", - 1: "Branch", - 2: "DefaultBranch", - 3: "Version", - 4: "Semver", -} -var Constraint_Type_value = map[string]int32{ - "Revision": 0, - "Branch": 1, - "DefaultBranch": 2, - "Version": 3, - "Semver": 4, -} - -func (x Constraint_Type) String() string { - return proto.EnumName(Constraint_Type_name, int32(x)) -} -func (Constraint_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } - -// Constraint is a serializable representation of a gps.Constraint or gps.UnpairedVersion. -type Constraint struct { - Type Constraint_Type `protobuf:"varint,1,opt,name=type,enum=pb.Constraint_Type" json:"type,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *Constraint) Reset() { *m = Constraint{} } -func (m *Constraint) String() string { return proto.CompactTextString(m) } -func (*Constraint) ProtoMessage() {} -func (*Constraint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *Constraint) GetType() Constraint_Type { - if m != nil { - return m.Type - } - return Constraint_Revision -} - -func (m *Constraint) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -// ProjectProperties is a serializable representation of gps.ProjectRoot and gps.ProjectProperties. -type ProjectProperties struct { - Root string `protobuf:"bytes,1,opt,name=root" json:"root,omitempty"` - Source string `protobuf:"bytes,2,opt,name=source" json:"source,omitempty"` - Constraint *Constraint `protobuf:"bytes,3,opt,name=constraint" json:"constraint,omitempty"` -} - -func (m *ProjectProperties) Reset() { *m = ProjectProperties{} } -func (m *ProjectProperties) String() string { return proto.CompactTextString(m) } -func (*ProjectProperties) ProtoMessage() {} -func (*ProjectProperties) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *ProjectProperties) GetRoot() string { - if m != nil { - return m.Root - } - return "" -} - -func (m *ProjectProperties) GetSource() string { - if m != nil { - return m.Source - } - return "" -} - -func (m *ProjectProperties) GetConstraint() *Constraint { - if m != nil { - return m.Constraint - } - return nil -} - -// LockedProject is a serializable representation of gps.LockedProject. -type LockedProject struct { - Root string `protobuf:"bytes,1,opt,name=root" json:"root,omitempty"` - Source string `protobuf:"bytes,2,opt,name=source" json:"source,omitempty"` - UnpairedVersion *Constraint `protobuf:"bytes,3,opt,name=unpairedVersion" json:"unpairedVersion,omitempty"` - Revision string `protobuf:"bytes,4,opt,name=revision" json:"revision,omitempty"` - Packages []string `protobuf:"bytes,5,rep,name=packages" json:"packages,omitempty"` -} - -func (m *LockedProject) Reset() { *m = LockedProject{} } -func (m *LockedProject) String() string { return proto.CompactTextString(m) } -func (*LockedProject) ProtoMessage() {} -func (*LockedProject) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *LockedProject) GetRoot() string { - if m != nil { - return m.Root - } - return "" -} - -func (m *LockedProject) GetSource() string { - if m != nil { - return m.Source - } - return "" -} - -func (m *LockedProject) GetUnpairedVersion() *Constraint { - if m != nil { - return m.UnpairedVersion - } - return nil -} - -func (m *LockedProject) GetRevision() string { - if m != nil { - return m.Revision - } - return "" -} - -func (m *LockedProject) GetPackages() []string { - if m != nil { - return m.Packages - } - return nil -} - -func init() { - proto.RegisterType((*Constraint)(nil), "pb.Constraint") - proto.RegisterType((*ProjectProperties)(nil), "pb.ProjectProperties") - proto.RegisterType((*LockedProject)(nil), "pb.LockedProject") - proto.RegisterEnum("pb.Constraint_Type", Constraint_Type_name, Constraint_Type_value) -} - -func init() { proto.RegisterFile("source_cache.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 294 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x4f, 0x4f, 0xc2, 0x40, - 0x14, 0xc4, 0x5d, 0x28, 0x08, 0x0f, 0x41, 0x78, 0x1a, 0xd3, 0x78, 0x6a, 0x7a, 0x91, 0x53, 0x0f, - 0x78, 0xf1, 0xac, 0x1e, 0x39, 0x90, 0x6a, 0xbc, 0x9a, 0xed, 0xf2, 0x94, 0x0a, 0x76, 0x37, 0xaf, - 0xdb, 0x26, 0x7c, 0x14, 0x3f, 0x84, 0xdf, 0xd1, 0x74, 0x59, 0xf1, 0x4f, 0xe2, 0xc1, 0x5b, 0xa7, - 0xf3, 0xcb, 0xce, 0xcc, 0x2e, 0x60, 0xa9, 0x2b, 0x56, 0xf4, 0xa8, 0xa4, 0x5a, 0x51, 0x62, 0x58, - 0x5b, 0x8d, 0x2d, 0x93, 0xc5, 0x6f, 0x02, 0xe0, 0x46, 0x17, 0xa5, 0x65, 0x99, 0x17, 0x16, 0x2f, - 0x20, 0xb0, 0x5b, 0x43, 0xa1, 0x88, 0xc4, 0x74, 0x34, 0x3b, 0x49, 0x4c, 0x96, 0x7c, 0xb9, 0xc9, - 0xfd, 0xd6, 0x50, 0xea, 0x00, 0x3c, 0x85, 0x4e, 0x2d, 0x37, 0x15, 0x85, 0xad, 0x48, 0x4c, 0xfb, - 0xe9, 0x4e, 0xc4, 0x73, 0x08, 0x1a, 0x06, 0x8f, 0xa0, 0x97, 0x52, 0x9d, 0x97, 0xb9, 0x2e, 0xc6, - 0x07, 0x08, 0xd0, 0xbd, 0x66, 0x59, 0xa8, 0xd5, 0x58, 0xe0, 0x04, 0x86, 0xb7, 0xf4, 0x24, 0xab, - 0x8d, 0xf5, 0xbf, 0x5a, 0x38, 0x80, 0xc3, 0x07, 0x62, 0xc7, 0xb6, 0x1b, 0xf6, 0x8e, 0x5e, 0x6b, - 0xe2, 0x71, 0x10, 0x6b, 0x98, 0x2c, 0x58, 0xbf, 0x90, 0xb2, 0x0b, 0xd6, 0x86, 0xd8, 0xe6, 0x54, - 0x22, 0x42, 0xc0, 0x5a, 0x5b, 0xd7, 0xb0, 0x9f, 0xba, 0x6f, 0x3c, 0x83, 0xee, 0x6e, 0x9e, 0x6f, - 0xe3, 0x15, 0x26, 0x00, 0x6a, 0xdf, 0x3e, 0x6c, 0x47, 0x62, 0x3a, 0x98, 0x8d, 0x7e, 0x6e, 0x4a, - 0xbf, 0x11, 0xf1, 0xbb, 0x80, 0xe1, 0x5c, 0xab, 0x35, 0x2d, 0x7d, 0xee, 0xbf, 0xd2, 0xae, 0xe0, - 0xb8, 0x2a, 0x8c, 0xcc, 0x99, 0x96, 0x7e, 0xcf, 0x1f, 0x91, 0xbf, 0x31, 0x3c, 0x87, 0x1e, 0xfb, - 0xeb, 0x0a, 0x03, 0x77, 0xe6, 0x5e, 0x37, 0x9e, 0x91, 0x6a, 0x2d, 0x9f, 0xa9, 0x0c, 0x3b, 0x51, - 0xbb, 0xf1, 0x3e, 0x75, 0xd6, 0x75, 0xef, 0x78, 0xf9, 0x11, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x52, - 0x77, 0xb3, 0xdd, 0x01, 0x00, 0x00, -} diff --git a/vendor/github.com/golang/dep/gps/internal/pb/source_cache.proto b/vendor/github.com/golang/dep/gps/internal/pb/source_cache.proto deleted file mode 100644 index 7245318e607652eba1388f2cd77e61b7a8fbff7d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/internal/pb/source_cache.proto +++ /dev/null @@ -1,36 +0,0 @@ -// 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. - -syntax = "proto3"; -package pb; - -// Constraint is a serializable representation of a gps.Constraint or gps.UnpairedVersion. -message Constraint { - enum Type { - Revision = 0; - Branch = 1; - DefaultBranch = 2; - Version = 3; - Semver = 4; - } - Type type = 1; - string value = 2; - //TODO strongly typed Semver field -} - -// ProjectProperties is a serializable representation of gps.ProjectRoot and gps.ProjectProperties. -message ProjectProperties { - string root = 1; - string source = 2; - Constraint constraint = 3; -} - -// LockedProject is a serializable representation of gps.LockedProject. -message LockedProject { - string root = 1; - string source = 2; - Constraint unpairedVersion = 3; - string revision = 4; - repeated string packages = 5; -} diff --git a/vendor/github.com/golang/dep/gps/lock.go b/vendor/github.com/golang/dep/gps/lock.go deleted file mode 100644 index 8b776213df0c62d2ec64b5ff16dd5639a09213be..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/lock.go +++ /dev/null @@ -1,235 +0,0 @@ -// 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 gps - -import ( - "bytes" - "fmt" - "sort" -) - -// Lock represents data from a lock file (or however the implementing tool -// chooses to store it) at a particular version that is relevant to the -// satisfiability solving process. -// -// In general, the information produced by gps on finding a successful -// solution is all that would be necessary to constitute a lock file, though -// tools can include whatever other information they want in their storage. -type Lock interface { - // The hash digest of inputs to gps that resulted in this lock data. - InputsDigest() []byte - - // Projects returns the list of LockedProjects contained in the lock data. - Projects() []LockedProject -} - -// LocksAreEq checks if two locks are equivalent. This checks that -// all contained LockedProjects are equal, and optionally (if the third -// parameter is true) whether the locks' input hashes are equal. -func LocksAreEq(l1, l2 Lock, checkHash bool) bool { - // Cheapest ops first - if checkHash && !bytes.Equal(l1.InputsDigest(), l2.InputsDigest()) { - return false - } - - p1, p2 := l1.Projects(), l2.Projects() - if len(p1) != len(p2) { - return false - } - - p1 = sortedLockedProjects(p1) - p2 = sortedLockedProjects(p2) - - for k, lp := range p1 { - if !lp.Eq(p2[k]) { - return false - } - } - return true -} - -// sortedLockedProjects returns a sorted copy of lps, or itself if already sorted. -func sortedLockedProjects(lps []LockedProject) []LockedProject { - if len(lps) <= 1 || sort.SliceIsSorted(lps, func(i, j int) bool { - return lps[i].Ident().Less(lps[j].Ident()) - }) { - return lps - } - cp := make([]LockedProject, len(lps)) - copy(cp, lps) - sort.Slice(cp, func(i, j int) bool { - return cp[i].Ident().Less(cp[j].Ident()) - }) - return cp -} - -// LockedProject is a single project entry from a lock file. It expresses the -// project's name, one or both of version and underlying revision, the network -// URI for accessing it, the path at which it should be placed within a vendor -// directory, and the packages that are used in it. -type LockedProject struct { - pi ProjectIdentifier - v UnpairedVersion - r Revision - pkgs []string -} - -// SimpleLock is a helper for tools to easily describe lock data when they know -// that no hash, or other complex information, is available. -type SimpleLock []LockedProject - -var _ Lock = SimpleLock{} - -// InputsDigest always returns an empty string for SimpleLock. This makes it useless -// as a stable lock to be written to disk, but still useful for some ephemeral -// purposes. -func (SimpleLock) InputsDigest() []byte { - return nil -} - -// Projects returns the entire contents of the SimpleLock. -func (l SimpleLock) Projects() []LockedProject { - return l -} - -// NewLockedProject creates a new LockedProject struct with a given -// ProjectIdentifier (name and optional upstream source URL), version. and list -// of packages required from the project. -// -// Note that passing a nil version will cause a panic. This is a correctness -// measure to ensure that the solver is never exposed to a version-less lock -// entry. Such a case would be meaningless - the solver would have no choice but -// to simply dismiss that project. By creating a hard failure case via panic -// instead, we are trying to avoid inflicting the resulting pain on the user by -// instead forcing a decision on the Analyzer implementation. -func NewLockedProject(id ProjectIdentifier, v Version, pkgs []string) LockedProject { - if v == nil { - panic("must provide a non-nil version to create a LockedProject") - } - - lp := LockedProject{ - pi: id, - pkgs: pkgs, - } - - switch tv := v.(type) { - case Revision: - lp.r = tv - case branchVersion: - lp.v = tv - case semVersion: - lp.v = tv - case plainVersion: - lp.v = tv - case versionPair: - lp.r = tv.r - lp.v = tv.v - } - - return lp -} - -// Ident returns the identifier describing the project. This includes both the -// local name (the root name by which the project is referenced in import paths) -// and the network name, where the upstream source lives. -func (lp LockedProject) Ident() ProjectIdentifier { - return lp.pi -} - -// Version assembles together whatever version and/or revision data is -// available into a single Version. -func (lp LockedProject) Version() Version { - if lp.r == "" { - return lp.v - } - - if lp.v == nil { - return lp.r - } - - return lp.v.Pair(lp.r) -} - -// Eq checks if two LockedProject instances are equal. -func (lp LockedProject) Eq(lp2 LockedProject) bool { - if lp.pi != lp2.pi { - return false - } - - if lp.r != lp2.r { - return false - } - - if len(lp.pkgs) != len(lp2.pkgs) { - return false - } - - for k, v := range lp.pkgs { - if lp2.pkgs[k] != v { - return false - } - } - - v1n := lp.v == nil - v2n := lp2.v == nil - - if v1n != v2n { - return false - } - - if !v1n && !lp.v.Matches(lp2.v) { - return false - } - - return true -} - -// Packages returns the list of packages from within the LockedProject that are -// actually used in the import graph. Some caveats: -// -// * The names given are relative to the root import path for the project. If -// the root package itself is imported, it's represented as ".". -// * Just because a package path isn't included in this list doesn't mean it's -// safe to remove - it could contain C files, or other assets, that can't be -// safely removed. -// * The slice is not a copy. If you need to modify it, copy it first. -func (lp LockedProject) Packages() []string { - return lp.pkgs -} - -func (lp LockedProject) String() string { - return fmt.Sprintf("%s@%s with packages: %v", - lp.Ident(), lp.Version(), lp.pkgs) -} - -type safeLock struct { - h []byte - p []LockedProject -} - -func (sl safeLock) InputsDigest() []byte { - return sl.h -} - -func (sl safeLock) Projects() []LockedProject { - return sl.p -} - -// prepLock ensures a lock is prepared and safe for use by the solver. This is -// mostly about defensively ensuring that no outside routine can modify the lock -// while the solver is in-flight. -// -// This is achieved by copying the lock's data into a new safeLock. -func prepLock(l Lock) safeLock { - pl := l.Projects() - - rl := safeLock{ - h: l.InputsDigest(), - p: make([]LockedProject, len(pl)), - } - copy(rl.p, pl) - - return rl -} diff --git a/vendor/github.com/golang/dep/gps/lockdiff.go b/vendor/github.com/golang/dep/gps/lockdiff.go deleted file mode 100644 index 839b49c5e53fb8ae1c147befe57737cb172473b2..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/lockdiff.go +++ /dev/null @@ -1,245 +0,0 @@ -// 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 gps - -import ( - "encoding/hex" - "fmt" - "sort" - "strings" -) - -// StringDiff represents a modified string value. -// * Added: Previous = nil, Current != nil -// * Deleted: Previous != nil, Current = nil -// * Modified: Previous != nil, Current != nil -// * No Change: Previous = Current, or a nil pointer -type StringDiff struct { - Previous string - Current string -} - -func (diff *StringDiff) String() string { - if diff == nil { - return "" - } - - if diff.Previous == "" && diff.Current != "" { - return fmt.Sprintf("+ %s", diff.Current) - } - - if diff.Previous != "" && diff.Current == "" { - return fmt.Sprintf("- %s", diff.Previous) - } - - if diff.Previous != diff.Current { - return fmt.Sprintf("%s -> %s", diff.Previous, diff.Current) - } - - return diff.Current -} - -// LockDiff is the set of differences between an existing lock file and an updated lock file. -// Fields are only populated when there is a difference, otherwise they are empty. -type LockDiff struct { - HashDiff *StringDiff - Add []LockedProjectDiff - Remove []LockedProjectDiff - Modify []LockedProjectDiff -} - -// LockedProjectDiff contains the before and after snapshot of a project reference. -// Fields are only populated when there is a difference, otherwise they are empty. -type LockedProjectDiff struct { - Name ProjectRoot - Source *StringDiff - Version *StringDiff - Branch *StringDiff - Revision *StringDiff - Packages []StringDiff -} - -// DiffLocks compares two locks and identifies the differences between them. -// Returns nil if there are no differences. -func DiffLocks(l1 Lock, l2 Lock) *LockDiff { - // Default nil locks to empty locks, so that we can still generate a diff - if l1 == nil { - l1 = &SimpleLock{} - } - if l2 == nil { - l2 = &SimpleLock{} - } - - p1, p2 := l1.Projects(), l2.Projects() - - p1 = sortedLockedProjects(p1) - p2 = sortedLockedProjects(p2) - - diff := LockDiff{} - - h1 := hex.EncodeToString(l1.InputsDigest()) - h2 := hex.EncodeToString(l2.InputsDigest()) - if h1 != h2 { - diff.HashDiff = &StringDiff{Previous: h1, Current: h2} - } - - var i2next int - for i1 := 0; i1 < len(p1); i1++ { - lp1 := p1[i1] - pr1 := lp1.pi.ProjectRoot - - var matched bool - for i2 := i2next; i2 < len(p2); i2++ { - lp2 := p2[i2] - pr2 := lp2.pi.ProjectRoot - - switch strings.Compare(string(pr1), string(pr2)) { - case 0: // Found a matching project - matched = true - pdiff := DiffProjects(lp1, lp2) - if pdiff != nil { - diff.Modify = append(diff.Modify, *pdiff) - } - i2next = i2 + 1 // Don't evaluate to this again - case +1: // Found a new project - add := buildLockedProjectDiff(lp2) - diff.Add = append(diff.Add, add) - i2next = i2 + 1 // Don't evaluate to this again - continue // Keep looking for a matching project - case -1: // Project has been removed, handled below - continue - } - - break // Done evaluating this project, move onto the next - } - - if !matched { - remove := buildLockedProjectDiff(lp1) - diff.Remove = append(diff.Remove, remove) - } - } - - // Anything that still hasn't been evaluated are adds - for i2 := i2next; i2 < len(p2); i2++ { - lp2 := p2[i2] - add := buildLockedProjectDiff(lp2) - diff.Add = append(diff.Add, add) - } - - if diff.HashDiff == nil && len(diff.Add) == 0 && len(diff.Remove) == 0 && len(diff.Modify) == 0 { - return nil // The locks are the equivalent - } - return &diff -} - -func buildLockedProjectDiff(lp LockedProject) LockedProjectDiff { - s2 := lp.pi.Source - r2, b2, v2 := VersionComponentStrings(lp.Version()) - - var rev, version, branch, source *StringDiff - if s2 != "" { - source = &StringDiff{Previous: s2, Current: s2} - } - if r2 != "" { - rev = &StringDiff{Previous: r2, Current: r2} - } - if b2 != "" { - branch = &StringDiff{Previous: b2, Current: b2} - } - if v2 != "" { - version = &StringDiff{Previous: v2, Current: v2} - } - - add := LockedProjectDiff{ - Name: lp.pi.ProjectRoot, - Source: source, - Revision: rev, - Version: version, - Branch: branch, - Packages: make([]StringDiff, len(lp.Packages())), - } - for i, pkg := range lp.Packages() { - add.Packages[i] = StringDiff{Previous: pkg, Current: pkg} - } - return add -} - -// DiffProjects compares two projects and identifies the differences between them. -// Returns nil if there are no differences -func DiffProjects(lp1 LockedProject, lp2 LockedProject) *LockedProjectDiff { - diff := LockedProjectDiff{Name: lp1.pi.ProjectRoot} - - s1 := lp1.pi.Source - s2 := lp2.pi.Source - if s1 != s2 { - diff.Source = &StringDiff{Previous: s1, Current: s2} - } - - r1, b1, v1 := VersionComponentStrings(lp1.Version()) - r2, b2, v2 := VersionComponentStrings(lp2.Version()) - if r1 != r2 { - diff.Revision = &StringDiff{Previous: r1, Current: r2} - } - if b1 != b2 { - diff.Branch = &StringDiff{Previous: b1, Current: b2} - } - if v1 != v2 { - diff.Version = &StringDiff{Previous: v1, Current: v2} - } - - p1 := lp1.Packages() - p2 := lp2.Packages() - if !sort.StringsAreSorted(p1) { - p1 = make([]string, len(p1)) - copy(p1, lp1.Packages()) - sort.Strings(p1) - } - if !sort.StringsAreSorted(p2) { - p2 = make([]string, len(p2)) - copy(p2, lp2.Packages()) - sort.Strings(p2) - } - - var i2next int - for i1 := 0; i1 < len(p1); i1++ { - pkg1 := p1[i1] - - var matched bool - for i2 := i2next; i2 < len(p2); i2++ { - pkg2 := p2[i2] - - switch strings.Compare(pkg1, pkg2) { - case 0: // Found matching package - matched = true - i2next = i2 + 1 // Don't evaluate to this again - case +1: // Found a new package - add := StringDiff{Current: pkg2} - diff.Packages = append(diff.Packages, add) - i2next = i2 + 1 // Don't evaluate to this again - continue // Keep looking for a match - case -1: // Package has been removed (handled below) - continue - } - - break // Done evaluating this package, move onto the next - } - - if !matched { - diff.Packages = append(diff.Packages, StringDiff{Previous: pkg1}) - } - } - - // Anything that still hasn't been evaluated are adds - for i2 := i2next; i2 < len(p2); i2++ { - pkg2 := p2[i2] - add := StringDiff{Current: pkg2} - diff.Packages = append(diff.Packages, add) - } - - if diff.Source == nil && diff.Version == nil && diff.Revision == nil && len(diff.Packages) == 0 { - return nil // The projects are equivalent - } - return &diff -} diff --git a/vendor/github.com/golang/dep/gps/manifest.go b/vendor/github.com/golang/dep/gps/manifest.go deleted file mode 100644 index d36f893513d497b092b7902d25df1d23fe712f45..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/manifest.go +++ /dev/null @@ -1,155 +0,0 @@ -// 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 gps - -import "github.com/golang/dep/gps/pkgtree" - -// Manifest represents manifest-type data for a project at a particular version. -// The constraints expressed in a manifest determine the set of versions that -// are acceptable to try for a given project. -// -// Expressing a constraint in a manifest does not guarantee that a particular -// dependency will be present. It only guarantees that if packages in the -// project specified by the dependency are discovered through static analysis of -// the (transitive) import graph, then they will conform to the constraint. -// -// This does entail that manifests can express constraints on projects they do -// not themselves import. This is by design, but its implications are complex. -// See the gps docs for more information: https://github.com/sdboyer/gps/wiki -type Manifest interface { - // Returns a list of project-level constraints. - DependencyConstraints() ProjectConstraints -} - -// RootManifest extends Manifest to add special controls over solving that are -// only afforded to the root project. -type RootManifest interface { - Manifest - - // Overrides returns a list of ProjectConstraints that will unconditionally - // supersede any ProjectConstraint declarations made in either the root - // manifest, or in any dependency's manifest. - // - // Overrides are a special control afforded only to root manifests. Tool - // users should be encouraged to use them only as a last resort; they do not - // "play well with others" (that is their express goal), and overreliance on - // them can harm the ecosystem as a whole. - Overrides() ProjectConstraints - - // IngoredPackages returns a pkgtree.IgnoredRuleset, which comprises a set - // of import paths, or import path patterns, that are to be ignored during - // solving. These ignored import paths can be within the root project, or - // part of other projects. Ignoring a package means that both it and its - // (unique) imports will be disregarded by all relevant solver operations. - // - // It is an error to include a package in both the ignored and required - // sets. - IgnoredPackages() *pkgtree.IgnoredRuleset - - // RequiredPackages returns a set of import paths to require. These packages - // are required to be present in any solution. The list can include main - // packages. - // - // It is meaningless to specify packages that are within the - // PackageTree of the ProjectRoot (though not an error, because the - // RootManifest itself does not report a ProjectRoot). - // - // It is an error to include a package in both the ignored and required - // sets. - RequiredPackages() map[string]bool -} - -// SimpleManifest is a helper for tools to enumerate manifest data. It's -// generally intended for ephemeral manifests, such as those Analyzers create on -// the fly for projects with no manifest metadata, or metadata through a foreign -// tool's idioms. -type SimpleManifest struct { - Deps ProjectConstraints -} - -var _ Manifest = SimpleManifest{} - -// DependencyConstraints returns the project's dependencies. -func (m SimpleManifest) DependencyConstraints() ProjectConstraints { - return m.Deps -} - -// simpleRootManifest exists so that we have a safe value to swap into solver -// params when a nil Manifest is provided. -type simpleRootManifest struct { - c, ovr ProjectConstraints - ig *pkgtree.IgnoredRuleset - req map[string]bool -} - -func (m simpleRootManifest) DependencyConstraints() ProjectConstraints { - return m.c -} -func (m simpleRootManifest) Overrides() ProjectConstraints { - return m.ovr -} -func (m simpleRootManifest) IgnoredPackages() *pkgtree.IgnoredRuleset { - return m.ig -} -func (m simpleRootManifest) RequiredPackages() map[string]bool { - return m.req -} -func (m simpleRootManifest) dup() simpleRootManifest { - m2 := simpleRootManifest{ - c: make(ProjectConstraints, len(m.c)), - ovr: make(ProjectConstraints, len(m.ovr)), - req: make(map[string]bool, len(m.req)), - } - - for k, v := range m.c { - m2.c[k] = v - } - for k, v := range m.ovr { - m2.ovr[k] = v - } - for k, v := range m.req { - m2.req[k] = v - } - - // IgnoredRulesets are immutable, and safe to reuse. - m2.ig = m.ig - - return m2 -} - -// prepManifest ensures a manifest is prepared and safe for use by the solver. -// This is mostly about ensuring that no outside routine can modify the manifest -// while the solver is in-flight, but it also filters out any empty -// ProjectProperties. -// -// This is achieved by copying the manifest's data into a new SimpleManifest. -func prepManifest(m Manifest) SimpleManifest { - if m == nil { - return SimpleManifest{} - } - - deps := m.DependencyConstraints() - - rm := SimpleManifest{ - Deps: make(ProjectConstraints, len(deps)), - } - - for k, d := range deps { - // A zero-value ProjectProperties is equivalent to one with an - // anyConstraint{} in terms of how the solver will treat it. However, we - // normalize between these two by omitting such instances entirely, as - // it negates some possibility for false mismatches in input hashing. - if d.Constraint == nil { - if d.Source == "" { - continue - } - d.Constraint = anyConstraint{} - } - - rm.Deps[k] = d - } - - return rm -} diff --git a/vendor/github.com/golang/dep/gps/maybe_source.go b/vendor/github.com/golang/dep/gps/maybe_source.go deleted file mode 100644 index 3128181dcd8aaf6d2ee54763cea8355eafb22a83..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/maybe_source.go +++ /dev/null @@ -1,262 +0,0 @@ -// 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 gps - -import ( - "bytes" - "context" - "fmt" - "net/url" - "path/filepath" - - "github.com/Masterminds/vcs" - "github.com/pkg/errors" -) - -// A maybeSource represents a set of information that, given some -// typically-expensive network effort, could be transformed into a proper source. -// -// Wrapping these up as their own type achieves two goals: -// -// * Allows control over when deduction logic triggers network activity -// * Makes it easy to attempt multiple URLs for a given import path -type maybeSource interface { - try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) - possibleURLs() []*url.URL -} - -type errorSlice []error - -func (errs *errorSlice) Error() string { - var buf bytes.Buffer - for _, err := range *errs { - fmt.Fprintf(&buf, "\n\t%s", err) - } - return buf.String() -} - -type maybeSources []maybeSource - -func (mbs maybeSources) try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) { - var errs errorSlice - for _, mb := range mbs { - src, state, err := mb.try(ctx, cachedir, c, superv) - if err == nil { - return src, state, nil - } - urls := "" - for _, url := range mb.possibleURLs() { - urls += url.String() + "\n" - } - errs = append(errs, errors.Wrapf(err, "failed to set up sources from the following URLs:\n%s", urls)) - } - - return nil, 0, errors.Wrap(&errs, "no valid source could be created") -} - -// This really isn't generally intended to be used - the interface is for -// maybeSources to be able to interrogate its members, not other things to -// interrogate a maybeSources. -func (mbs maybeSources) possibleURLs() []*url.URL { - urlslice := make([]*url.URL, 0, len(mbs)) - for _, mb := range mbs { - urlslice = append(urlslice, mb.possibleURLs()...) - } - return urlslice -} - -// sourceCachePath returns a url-sanitized source cache dir path. -func sourceCachePath(cacheDir, sourceURL string) string { - return filepath.Join(cacheDir, "sources", sanitizer.Replace(sourceURL)) -} - -type maybeGitSource struct { - url *url.URL -} - -func (m maybeGitSource) try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) { - ustr := m.url.String() - - r, err := newCtxRepo(vcs.Git, ustr, sourceCachePath(cachedir, ustr)) - if err != nil { - return nil, 0, unwrapVcsErr(err) - } - - src := &gitSource{ - baseVCSSource: baseVCSSource{ - repo: r, - }, - } - - // Pinging invokes the same action as calling listVersions, so just do that. - var vl []PairedVersion - if err := superv.do(ctx, "git:lv:maybe", ctListVersions, func(ctx context.Context) error { - var err error - vl, err = src.listVersions(ctx) - return errors.Wrapf(err, "remote repository at %s does not exist, or is inaccessible", ustr) - }); err != nil { - return nil, 0, err - } - - state := sourceIsSetUp | sourceExistsUpstream | sourceHasLatestVersionList - - if r.CheckLocal() { - state |= sourceExistsLocally - - if err := superv.do(ctx, "git", ctValidateLocal, func(ctx context.Context) error { - // If repository already exists on disk, make a pass to be sure - // everything's clean. - return src.ensureClean(ctx) - }); err != nil { - return nil, 0, err - } - } - - c.setVersionMap(vl) - return src, state, nil -} - -func (m maybeGitSource) possibleURLs() []*url.URL { - return []*url.URL{m.url} -} - -type maybeGopkginSource struct { - // the original gopkg.in import path. this is used to create the on-disk - // location to avoid duplicate resource management - e.g., if instances of - // a gopkg.in project are accessed via different schemes, or if the - // underlying github repository is accessed directly. - opath string - // the actual upstream URL - always github - url *url.URL - // the major version to apply for filtering - major uint64 - // whether or not the source package is "unstable" - unstable bool -} - -func (m maybeGopkginSource) try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) { - // We don't actually need a fully consistent transform into the on-disk path - // - just something that's unique to the particular gopkg.in domain context. - // So, it's OK to just dumb-join the scheme with the path. - aliasURL := m.url.Scheme + "://" + m.opath - path := sourceCachePath(cachedir, aliasURL) - ustr := m.url.String() - - r, err := newCtxRepo(vcs.Git, ustr, path) - if err != nil { - return nil, 0, unwrapVcsErr(err) - } - - src := &gopkginSource{ - gitSource: gitSource{ - baseVCSSource: baseVCSSource{ - repo: r, - }, - }, - major: m.major, - unstable: m.unstable, - aliasURL: aliasURL, - } - - var vl []PairedVersion - if err := superv.do(ctx, "git:lv:maybe", ctListVersions, func(ctx context.Context) error { - var err error - vl, err = src.listVersions(ctx) - return errors.Wrapf(err, "remote repository at %s does not exist, or is inaccessible", ustr) - }); err != nil { - return nil, 0, err - } - - c.setVersionMap(vl) - state := sourceIsSetUp | sourceExistsUpstream | sourceHasLatestVersionList - - if r.CheckLocal() { - state |= sourceExistsLocally - } - - return src, state, nil -} - -func (m maybeGopkginSource) possibleURLs() []*url.URL { - return []*url.URL{m.url} -} - -type maybeBzrSource struct { - url *url.URL -} - -func (m maybeBzrSource) try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) { - ustr := m.url.String() - - r, err := newCtxRepo(vcs.Bzr, ustr, sourceCachePath(cachedir, ustr)) - if err != nil { - return nil, 0, unwrapVcsErr(err) - } - - if err := superv.do(ctx, "bzr:ping", ctSourcePing, func(ctx context.Context) error { - if !r.Ping() { - return fmt.Errorf("remote repository at %s does not exist, or is inaccessible", ustr) - } - return nil - }); err != nil { - return nil, 0, err - } - - state := sourceIsSetUp | sourceExistsUpstream - if r.CheckLocal() { - state |= sourceExistsLocally - } - - src := &bzrSource{ - baseVCSSource: baseVCSSource{ - repo: r, - }, - } - - return src, state, nil -} - -func (m maybeBzrSource) possibleURLs() []*url.URL { - return []*url.URL{m.url} -} - -type maybeHgSource struct { - url *url.URL -} - -func (m maybeHgSource) try(ctx context.Context, cachedir string, c singleSourceCache, superv *supervisor) (source, sourceState, error) { - ustr := m.url.String() - - r, err := newCtxRepo(vcs.Hg, ustr, sourceCachePath(cachedir, ustr)) - if err != nil { - return nil, 0, unwrapVcsErr(err) - } - - if err := superv.do(ctx, "hg:ping", ctSourcePing, func(ctx context.Context) error { - if !r.Ping() { - return fmt.Errorf("remote repository at %s does not exist, or is inaccessible", ustr) - } - return nil - }); err != nil { - return nil, 0, err - } - - state := sourceIsSetUp | sourceExistsUpstream - if r.CheckLocal() { - state |= sourceExistsLocally - } - - src := &hgSource{ - baseVCSSource: baseVCSSource{ - repo: r, - }, - } - - return src, state, nil -} - -func (m maybeHgSource) possibleURLs() []*url.URL { - return []*url.URL{m.url} -} diff --git a/vendor/github.com/golang/dep/gps/metrics.go b/vendor/github.com/golang/dep/gps/metrics.go deleted file mode 100644 index 5462f4bf3fbc7a326c51bbe06464e0f69dc5179e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/metrics.go +++ /dev/null @@ -1,84 +0,0 @@ -// 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 gps - -import ( - "bytes" - "fmt" - "log" - "sort" - "text/tabwriter" - "time" -) - -type metrics struct { - stack []string - times map[string]time.Duration - last time.Time -} - -func newMetrics() *metrics { - return &metrics{ - stack: []string{"other"}, - times: map[string]time.Duration{ - "other": 0, - }, - last: time.Now(), - } -} - -func (m *metrics) push(name string) { - cn := m.stack[len(m.stack)-1] - m.times[cn] = m.times[cn] + time.Since(m.last) - - m.stack = append(m.stack, name) - m.last = time.Now() -} - -func (m *metrics) pop() { - on := m.stack[len(m.stack)-1] - m.times[on] = m.times[on] + time.Since(m.last) - - m.stack = m.stack[:len(m.stack)-1] - m.last = time.Now() -} - -func (m *metrics) dump(l *log.Logger) { - s := make(ndpairs, len(m.times)) - k := 0 - for n, d := range m.times { - s[k] = ndpair{ - n: n, - d: d, - } - k++ - } - - sort.Sort(sort.Reverse(s)) - - var tot time.Duration - var buf bytes.Buffer - w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', tabwriter.AlignRight) - for _, nd := range s { - tot += nd.d - fmt.Fprintf(w, "\t%s:\t%v\t\n", nd.n, nd.d) - } - fmt.Fprintf(w, "\n\tTOTAL:\t%v\t\n", tot) - w.Flush() - - l.Println("\nSolver wall times by segment:") - l.Println((&buf).String()) -} - -type ndpair struct { - n string - d time.Duration -} - -type ndpairs []ndpair - -func (s ndpairs) Less(i, j int) bool { return s[i].d < s[j].d } -func (s ndpairs) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s ndpairs) Len() int { return len(s) } diff --git a/vendor/github.com/golang/dep/gps/paths/BUILD.bazel b/vendor/github.com/golang/dep/gps/paths/BUILD.bazel deleted file mode 100644 index 4dad14b3c38fe2737a8e1fc1f0d3f28bd00cc7db..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/paths/BUILD.bazel +++ /dev/null @@ -1,9 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["paths.go"], - importmap = "vendor/github.com/golang/dep/gps/paths", - importpath = "github.com/golang/dep/gps/paths", - visibility = ["//visibility:public"], -) diff --git a/vendor/github.com/golang/dep/gps/paths/paths.go b/vendor/github.com/golang/dep/gps/paths/paths.go deleted file mode 100644 index af930494e0e718327858310ab779675d8e741ce4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/paths/paths.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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 paths - -import "strings" - -// IsStandardImportPath reports whether $GOROOT/src/path should be considered -// part of the standard distribution. For historical reasons we allow people to add -// their own code to $GOROOT instead of using $GOPATH, but we assume that -// code will start with a domain name (dot in the first element). -// This was lovingly taken from src/cmd/go/pkg.go in Go's code (isStandardImportPath). -func IsStandardImportPath(path string) bool { - i := strings.Index(path, "/") - if i < 0 { - i = len(path) - } - - return !strings.Contains(path[:i], ".") -} diff --git a/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel b/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel deleted file mode 100644 index 2c64bdfad3ed5ced70decbd41a3279534b283e7d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel +++ /dev/null @@ -1,19 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "digest.go", - "dirwalk.go", - "ignored_ruleset.go", - "pkgtree.go", - "reachmap.go", - ], - importmap = "vendor/github.com/golang/dep/gps/pkgtree", - importpath = "github.com/golang/dep/gps/pkgtree", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/armon/go-radix:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/gps/pkgtree/digest.go b/vendor/github.com/golang/dep/gps/pkgtree/digest.go deleted file mode 100644 index 31ed243ab3b64b4828cb00362978f060be2592d0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/digest.go +++ /dev/null @@ -1,472 +0,0 @@ -// 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 pkgtree - -import ( - "bytes" - "crypto/sha256" - "encoding/binary" - "hash" - "io" - "os" - "path/filepath" - "strconv" - - "github.com/pkg/errors" -) - -const osPathSeparator = string(filepath.Separator) - -// lineEndingReader is a `io.Reader` that converts CRLF sequences to LF. -// -// When cloning or checking out repositories, some Version Control Systems, -// VCSs, on some supported Go Operating System architectures, GOOS, will -// automatically convert line endings that end in a single line feed byte, LF, -// to line endings that end in a two byte sequence of carriage return, CR, -// followed by LF. This LF to CRLF conversion would cause otherwise identical -// versioned files to have different on disk contents simply based on which VCS -// and GOOS are involved. Different file contents for the same file would cause -// the resultant hashes to differ. In order to ensure file contents normalize -// and produce the same hash, this structure wraps an io.Reader that modifies -// the file's contents when it is read, translating all CRLF sequences to LF. -type lineEndingReader struct { - src io.Reader // source io.Reader from which this reads - prevReadEndedCR bool // used to track whether final byte of previous Read was CR -} - -// newLineEndingReader returns a new lineEndingReader that reads from the -// specified source io.Reader. -func newLineEndingReader(src io.Reader) *lineEndingReader { - return &lineEndingReader{src: src} -} - -var crlf = []byte("\r\n") - -// Read consumes bytes from the structure's source io.Reader to fill the -// specified slice of bytes. It converts all CRLF byte sequences to LF, and -// handles cases where CR and LF straddle across two Read operations. -func (f *lineEndingReader) Read(buf []byte) (int, error) { - buflen := len(buf) - if f.prevReadEndedCR { - // Read one fewer bytes so we have room if the first byte of the - // upcoming Read is not a LF, in which case we will need to insert - // trailing CR from previous read. - buflen-- - } - nr, er := f.src.Read(buf[:buflen]) - if nr > 0 { - if f.prevReadEndedCR && buf[0] != '\n' { - // Having a CRLF split across two Read operations is rare, so the - // performance impact of copying entire buffer to the right by one - // byte, while suboptimal, will at least will not happen very - // often. This negative performance impact is mitigated somewhat on - // many Go compilation architectures, GOARCH, because the `copy` - // builtin uses a machine opcode for performing the memory copy on - // possibly overlapping regions of memory. This machine opcodes is - // not instantaneous and does require multiple CPU cycles to - // complete, but is significantly faster than the application - // looping through bytes. - copy(buf[1:nr+1], buf[:nr]) // shift data to right one byte - buf[0] = '\r' // insert the previous skipped CR byte at start of buf - nr++ // pretend we read one more byte - } - - // Remove any CRLF sequences in the buffer using `bytes.Index` because, - // like the `copy` builtin on many GOARCHs, it also takes advantage of a - // machine opcode to search for byte patterns. - var searchOffset int // index within buffer from whence the search will commence for each loop; set to the index of the end of the previous loop. - var shiftCount int // each subsequenct shift operation needs to shift bytes to the left by one more position than the shift that preceded it. - previousIndex := -1 // index of previously found CRLF; -1 means no previous index - for { - index := bytes.Index(buf[searchOffset:nr], crlf) - if index == -1 { - break - } - index += searchOffset // convert relative index to absolute - if previousIndex != -1 { - // shift substring between previous index and this index - copy(buf[previousIndex-shiftCount:], buf[previousIndex+1:index]) - shiftCount++ // next shift needs to be 1 byte to the left - } - previousIndex = index - searchOffset = index + 2 // start next search after len(crlf) - } - if previousIndex != -1 { - // handle final shift - copy(buf[previousIndex-shiftCount:], buf[previousIndex+1:nr]) - shiftCount++ - } - nr -= shiftCount // shorten byte read count by number of shifts executed - - // When final byte from a read operation is CR, do not emit it until - // ensure first byte on next read is not LF. - if f.prevReadEndedCR = buf[nr-1] == '\r'; f.prevReadEndedCR { - nr-- // pretend byte was never read from source - } - } else if f.prevReadEndedCR { - // Reading from source returned nothing, but this struct is sitting on a - // trailing CR from previous Read, so let's give it to client now. - buf[0] = '\r' - nr = 1 - er = nil - f.prevReadEndedCR = false // prevent infinite loop - } - return nr, er -} - -// writeBytesWithNull appends the specified data to the specified hash, followed by -// the NULL byte, in order to make accidental hash collisions less likely. -func writeBytesWithNull(h hash.Hash, data []byte) { - // Ignore return values from writing to the hash, because hash write always - // returns nil error. - _, _ = h.Write(append(data, 0)) -} - -// dirWalkClosure is used to reduce number of allocation involved in closing -// over these variables. -type dirWalkClosure struct { - someCopyBufer []byte // allocate once and reuse for each file copy - someModeBytes []byte // allocate once and reuse for each node - someDirLen int - someHash hash.Hash -} - -// DigestFromDirectory returns a hash of the specified directory contents, which -// will match the hash computed for any directory on any supported Go platform -// whose contents exactly match the specified directory. -// -// This function ignores any file system node named `vendor`, `.bzr`, `.git`, -// `.hg`, and `.svn`, as these are typically used as Version Control System -// (VCS) directories. -// -// Other than the `vendor` and VCS directories mentioned above, the calculated -// hash includes the pathname to every discovered file system node, whether it -// is an empty directory, a non-empty directory, empty file, non-empty file, or -// symbolic link. If a symbolic link, the referent name is included. If a -// non-empty file, the file's contents are included. If a non-empty directory, -// the contents of the directory are included. -// -// While filepath.Walk could have been used, that standard library function -// skips symbolic links, and for now, we want the hash to include the symbolic -// link referents. -func DigestFromDirectory(osDirname string) ([]byte, error) { - osDirname = filepath.Clean(osDirname) - - // Create a single hash instance for the entire operation, rather than a new - // hash for each node we encounter. - - closure := dirWalkClosure{ - someCopyBufer: make([]byte, 4*1024), // only allocate a single page - someModeBytes: make([]byte, 4), // scratch place to store encoded os.FileMode (uint32) - someDirLen: len(osDirname) + len(osPathSeparator), - someHash: sha256.New(), - } - - err := DirWalk(osDirname, func(osPathname string, info os.FileInfo, err error) error { - if err != nil { - return err // DirWalk received an error during initial Lstat - } - - var osRelative string - if len(osPathname) > closure.someDirLen { - osRelative = osPathname[closure.someDirLen:] - } - - switch filepath.Base(osRelative) { - case "vendor", ".bzr", ".git", ".hg", ".svn": - return filepath.SkipDir - } - - // We could make our own enum-like data type for encoding the file type, - // but Go's runtime already gives us architecture independent file - // modes, as discussed in `os/types.go`: - // - // Go's runtime FileMode type has same definition on all systems, so - // that information about files can be moved from one system to - // another portably. - var mt os.FileMode - - // We only care about the bits that identify the type of a file system - // node, and can ignore append, exclusive, temporary, setuid, setgid, - // permission bits, and sticky bits, which are coincident to bits which - // declare type of the file system node. - modeType := info.Mode() & os.ModeType - var shouldSkip bool // skip some types of file system nodes - - switch { - case modeType&os.ModeDir > 0: - mt = os.ModeDir - // DirWalkFunc itself does not need to enumerate children, because - // DirWalk will do that for us. - shouldSkip = true - case modeType&os.ModeSymlink > 0: - mt = os.ModeSymlink - case modeType&os.ModeNamedPipe > 0: - mt = os.ModeNamedPipe - shouldSkip = true - case modeType&os.ModeSocket > 0: - mt = os.ModeSocket - shouldSkip = true - case modeType&os.ModeDevice > 0: - mt = os.ModeDevice - shouldSkip = true - } - - // Write the relative pathname to hash because the hash is a function of - // the node names, node types, and node contents. Added benefit is that - // empty directories, named pipes, sockets, devices, and symbolic links - // will also affect final hash value. Use `filepath.ToSlash` to ensure - // relative pathname is os-agnostic. - writeBytesWithNull(closure.someHash, []byte(filepath.ToSlash(osRelative))) - - binary.LittleEndian.PutUint32(closure.someModeBytes, uint32(mt)) // encode the type of mode - writeBytesWithNull(closure.someHash, closure.someModeBytes) // and write to hash - - if shouldSkip { - return nil // nothing more to do for some of the node types - } - - if mt == os.ModeSymlink { // okay to check for equivalence because we set to this value - osRelative, err = os.Readlink(osPathname) // read the symlink referent - if err != nil { - return errors.Wrap(err, "cannot Readlink") - } - writeBytesWithNull(closure.someHash, []byte(filepath.ToSlash(osRelative))) // write referent to hash - return nil // proceed to next node in queue - } - - // If we get here, node is a regular file. - fh, err := os.Open(osPathname) - if err != nil { - return errors.Wrap(err, "cannot Open") - } - - var bytesWritten int64 - bytesWritten, err = io.CopyBuffer(closure.someHash, newLineEndingReader(fh), closure.someCopyBufer) // fast copy of file contents to hash - err = errors.Wrap(err, "cannot Copy") // errors.Wrap only wraps non-nil, so skip extra check - writeBytesWithNull(closure.someHash, []byte(strconv.FormatInt(bytesWritten, 10))) // 10: format file size as base 10 integer - - // Close the file handle to the open file without masking - // possible previous error value. - if er := fh.Close(); err == nil { - err = errors.Wrap(er, "cannot Close") - } - return err - }) - if err != nil { - return nil, err - } - return closure.someHash.Sum(nil), nil -} - -// VendorStatus represents one of a handful of possible status conditions for a -// particular file system node in the vendor directory tree. -type VendorStatus uint8 - -const ( - // NotInLock is used when a file system node exists for which there is no - // corresponding dependency in the lock file. - NotInLock VendorStatus = iota - - // NotInTree is used when a lock file dependency exists for which there is - // no corresponding file system node. - NotInTree - - // NoMismatch is used when the digest for a dependency listed in the - // lockfile matches what is calculated from the file system. - NoMismatch - - // EmptyDigestInLock is used when the digest for a dependency listed in the - // lock file is the empty string. While this is a special case of - // DigestMismatchInLock, keeping both cases discrete is a desired feature. - EmptyDigestInLock - - // DigestMismatchInLock is used when the digest for a dependency listed in - // the lock file does not match what is calculated from the file system. - DigestMismatchInLock -) - -func (ls VendorStatus) String() string { - switch ls { - case NotInTree: - return "not in tree" - case NotInLock: - return "not in lock" - case NoMismatch: - return "match" - case EmptyDigestInLock: - return "empty digest in lock" - case DigestMismatchInLock: - return "mismatch" - } - return "unknown" -} - -// fsnode is used to track which file system nodes are required by the lock -// file. When a directory is found whose name matches one of the declared -// projects in the lock file, e.g., "github.com/alice/alice1", an fsnode is -// created for that directory, but not for any of its children. All other file -// system nodes encountered will result in a fsnode created to represent it. -type fsnode struct { - osRelative string // os-specific relative path of a resource under vendor root - isRequiredAncestor bool // true iff this node or one of its descendants is in the lock file - myIndex, parentIndex int // index of this node and its parent in the tree's slice -} - -// VerifyDepTree verifies a dependency tree according to expected digest sums, -// and returns an associative array of file system nodes and their respective -// vendor status conditions. -// -// The keys to the expected digest sums associative array represent the -// project's dependencies, and each is required to be expressed using the -// solidus character, `/`, as its path separator. For example, even on a GOOS -// platform where the file system path separator is a character other than -// solidus, one particular dependency would be represented as -// "github.com/alice/alice1". -func VerifyDepTree(osDirname string, wantSums map[string][]byte) (map[string]VendorStatus, error) { - osDirname = filepath.Clean(osDirname) - - // Ensure top level pathname is a directory - fi, err := os.Stat(osDirname) - if err != nil { - return nil, errors.Wrap(err, "cannot Stat") - } - if !fi.IsDir() { - return nil, errors.Errorf("cannot verify non directory: %q", osDirname) - } - - // Initialize work queue with a node representing the specified directory - // name by declaring its relative pathname under the directory name as the - // empty string. - currentNode := &fsnode{osRelative: "", parentIndex: -1, isRequiredAncestor: true} - queue := []*fsnode{currentNode} // queue of directories that must be inspected - - // In order to identify all file system nodes that are not in the lock file, - // represented by the specified expected sums parameter, and in order to - // only report the top level of a subdirectory of file system nodes, rather - // than every node internal to them, we will create a tree of nodes stored - // in a slice. We do this because we cannot predict the depth at which - // project roots occur. Some projects are fewer than and some projects more - // than the typical three layer subdirectory under the vendor root - // directory. - // - // For a following few examples, assume the below vendor root directory: - // - // github.com/alice/alice1/a1.go - // github.com/alice/alice2/a2.go - // github.com/bob/bob1/b1.go - // github.com/bob/bob2/b2.go - // launchpad.net/nifty/n1.go - // - // 1) If only the `alice1` and `alice2` projects were in the lock file, we'd - // prefer the output to state that `github.com/bob` is `NotInLock`, and - // `launchpad.net/nifty` is `NotInLock`. - // - // 2) If `alice1`, `alice2`, and `bob1` were in the lock file, we'd want to - // report `github.com/bob/bob2` as `NotInLock`, and `launchpad.net/nifty` is - // `NotInLock`. - // - // 3) If none of `alice1`, `alice2`, `bob1`, or `bob2` were in the lock - // file, the entire `github.com` directory would be reported as `NotInLock`, - // along with `launchpad.net/nifty` is `NotInLock`. - // - // Each node in our tree has the slice index of its parent node, so once we - // can categorically state a particular directory is required because it is - // in the lock file, we can mark all of its ancestors as also being - // required. Then, when we finish walking the directory hierarchy, any nodes - // which are not required but have a required parent will be marked as - // `NotInLock`. - nodes := []*fsnode{currentNode} - - // Create associative array to store the results of calling this function. - slashStatus := make(map[string]VendorStatus) - - // Mark directories of expected projects as required. When each respective - // project is later found while traversing the vendor root hierarchy, its - // status will be updated to reflect whether its digest is empty, or, - // whether or not it matches the expected digest. - for slashPathname := range wantSums { - slashStatus[slashPathname] = NotInTree - } - - for len(queue) > 0 { - // Pop node from the top of queue (depth first traversal, reverse - // lexicographical order inside a directory), clearing the value stored - // in the slice's backing array as we proceed. - lq1 := len(queue) - 1 - currentNode, queue[lq1], queue = queue[lq1], nil, queue[:lq1] - slashPathname := filepath.ToSlash(currentNode.osRelative) - osPathname := filepath.Join(osDirname, currentNode.osRelative) - - if expectedSum, ok := wantSums[slashPathname]; ok { - ls := EmptyDigestInLock - if len(expectedSum) > 0 { - projectSum, err := DigestFromDirectory(osPathname) - if err != nil { - return nil, errors.Wrap(err, "cannot compute dependency hash") - } - if bytes.Equal(projectSum, expectedSum) { - ls = NoMismatch - } else { - ls = DigestMismatchInLock - } - } - slashStatus[slashPathname] = ls - - // Mark current nodes and all its parents as required. - for i := currentNode.myIndex; i != -1; i = nodes[i].parentIndex { - nodes[i].isRequiredAncestor = true - } - - // Do not need to process this directory's contents because we - // already accounted for its contents while calculating its digest. - continue - } - - osChildrenNames, err := sortedChildrenFromDirname(osPathname) - if err != nil { - return nil, errors.Wrap(err, "cannot get sorted list of directory children") - } - for _, osChildName := range osChildrenNames { - switch osChildName { - case ".", "..", "vendor", ".bzr", ".git", ".hg", ".svn": - // skip - default: - osChildRelative := filepath.Join(currentNode.osRelative, osChildName) - osChildPathname := filepath.Join(osDirname, osChildRelative) - - // Create a new fsnode for this file system node, with a parent - // index set to the index of the current node. - otherNode := &fsnode{osRelative: osChildRelative, myIndex: len(nodes), parentIndex: currentNode.myIndex} - - fi, err := os.Stat(osChildPathname) - if err != nil { - return nil, errors.Wrap(err, "cannot Stat") - } - nodes = append(nodes, otherNode) // Track all file system nodes... - if fi.IsDir() { - queue = append(queue, otherNode) // but only need to add directories to the work queue. - } - } - } - } - - // Ignoring first node in the list, walk nodes from last to first. Whenever - // the current node is not required, but its parent is required, then the - // current node ought to be marked as `NotInLock`. - for len(nodes) > 1 { - // Pop node from top of queue, clearing the value stored in the slice's - // backing array as we proceed. - ln1 := len(nodes) - 1 - currentNode, nodes[ln1], nodes = nodes[ln1], nil, nodes[:ln1] - - if !currentNode.isRequiredAncestor && nodes[currentNode.parentIndex].isRequiredAncestor { - slashStatus[filepath.ToSlash(currentNode.osRelative)] = NotInLock - } - } - currentNode, nodes = nil, nil - - return slashStatus, nil -} diff --git a/vendor/github.com/golang/dep/gps/pkgtree/dirwalk.go b/vendor/github.com/golang/dep/gps/pkgtree/dirwalk.go deleted file mode 100644 index 350c1606c33847fb3370fa7a1af145d9962aeb1d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/dirwalk.go +++ /dev/null @@ -1,139 +0,0 @@ -// 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 pkgtree - -import ( - "os" - "path/filepath" - "sort" - "strings" - - "github.com/pkg/errors" -) - -// DirWalkFunc is the type of the function called for each file system node -// visited by DirWalk. The path argument contains the argument to DirWalk as a -// prefix; that is, if DirWalk is called with "dir", which is a directory -// containing the file "a", the walk function will be called with the argument -// "dir/a", using the correct os.PathSeparator for the Go Operating System -// architecture, GOOS. The info argument is the os.FileInfo for the named path. -// -// If there was a problem walking to the file or directory named by path, the -// incoming error will describe the problem and the function can decide how to -// handle that error (and DirWalk will not descend into that directory). If an -// error is returned, processing stops. The sole exception is when the function -// returns the special value filepath.SkipDir. If the function returns -// filepath.SkipDir when invoked on a directory, DirWalk skips the directory's -// contents entirely. If the function returns filepath.SkipDir when invoked on a -// non-directory file system node, DirWalk skips the remaining files in the -// containing directory. -type DirWalkFunc func(osPathname string, info os.FileInfo, err error) error - -// DirWalk walks the file tree rooted at osDirname, calling for each file system -// node in the tree, including root. All errors that arise visiting nodes are -// filtered by walkFn. The nodes are walked in lexical order, which makes the -// output deterministic but means that for very large directories DirWalk can be -// inefficient. Unlike filepath.Walk, DirWalk does follow symbolic links. -func DirWalk(osDirname string, walkFn DirWalkFunc) error { - osDirname = filepath.Clean(osDirname) - - // Ensure parameter is a directory - fi, err := os.Stat(osDirname) - if err != nil { - return errors.Wrap(err, "cannot read node") - } - if !fi.IsDir() { - return errors.Errorf("cannot walk non directory: %q", osDirname) - } - - // Initialize a work queue with the empty string, which signifies the - // starting directory itself. - queue := []string{""} - - var osRelative string // os-specific relative pathname under directory name - - // As we enumerate over the queue and encounter a directory, its children - // will be added to the work queue. - for len(queue) > 0 { - // Unshift a pathname from the queue (breadth-first traversal of - // hierarchy) - osRelative, queue = queue[0], queue[1:] - osPathname := filepath.Join(osDirname, osRelative) - - // walkFn needs to choose how to handle symbolic links, therefore obtain - // lstat rather than stat. - fi, err = os.Lstat(osPathname) - if err == nil { - err = walkFn(osPathname, fi, nil) - } else { - err = walkFn(osPathname, nil, errors.Wrap(err, "cannot read node")) - } - - if err != nil { - if err == filepath.SkipDir { - if fi.Mode()&os.ModeSymlink > 0 { - // Resolve symbolic link referent to determine whether node - // is directory or not. - fi, err = os.Stat(osPathname) - if err != nil { - return errors.Wrap(err, "cannot visit node") - } - } - // If current node is directory, then skip this - // directory. Otherwise, skip all nodes in the same parent - // directory. - if !fi.IsDir() { - // Consume nodes from queue while they have the same parent - // as the current node. - osParent := filepath.Dir(osPathname) + osPathSeparator - for len(queue) > 0 && strings.HasPrefix(queue[0], osParent) { - queue = queue[1:] // drop sibling from queue - } - } - - continue - } - return errors.Wrap(err, "DirWalkFunction") // wrap error returned by walkFn - } - - if fi.IsDir() { - osChildrenNames, err := sortedChildrenFromDirname(osPathname) - if err != nil { - return errors.Wrap(err, "cannot get list of directory children") - } - for _, osChildName := range osChildrenNames { - switch osChildName { - case ".", "..": - // skip - default: - queue = append(queue, filepath.Join(osRelative, osChildName)) - } - } - } - } - return nil -} - -// sortedChildrenFromDirname returns a lexicographically sorted list of child -// nodes for the specified directory. -func sortedChildrenFromDirname(osDirname string) ([]string, error) { - fh, err := os.Open(osDirname) - if err != nil { - return nil, errors.Wrap(err, "cannot Open") - } - - osChildrenNames, err := fh.Readdirnames(0) // 0: read names of all children - if err != nil { - return nil, errors.Wrap(err, "cannot Readdirnames") - } - sort.Strings(osChildrenNames) - - // Close the file handle to the open directory without masking possible - // previous error value. - if er := fh.Close(); err == nil { - err = errors.Wrap(er, "cannot Close") - } - return osChildrenNames, err -} diff --git a/vendor/github.com/golang/dep/gps/pkgtree/ignored_ruleset.go b/vendor/github.com/golang/dep/gps/pkgtree/ignored_ruleset.go deleted file mode 100644 index 30b92bd8e97cdc6ffe26c9b12f79f8e62c69328d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/ignored_ruleset.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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 pkgtree - -import ( - "sort" - "strings" - - "github.com/armon/go-radix" -) - -// IgnoredRuleset comprises a set of rules for ignoring import paths. It can -// manage both literal and prefix-wildcard matches. -type IgnoredRuleset struct { - t *radix.Tree -} - -// NewIgnoredRuleset processes a set of strings into an IgnoredRuleset. Strings -// that end in "*" are treated as wildcards, where any import path with a -// matching prefix will be ignored. IgnoredRulesets are immutable once created. -// -// Duplicate and redundant (i.e. a literal path that has a prefix of a wildcard -// path) declarations are discarded. Consequently, it is possible that the -// returned IgnoredRuleset may have a smaller Len() than the input slice. -func NewIgnoredRuleset(ig []string) *IgnoredRuleset { - if len(ig) == 0 { - return &IgnoredRuleset{} - } - - ir := &IgnoredRuleset{ - t: radix.New(), - } - - // Sort the list of all the ignores in order to ensure that wildcard - // precedence is recorded correctly in the trie. - sort.Strings(ig) - for _, i := range ig { - // Skip global ignore and empty string. - if i == "*" || i == "" { - continue - } - - _, wildi, has := ir.t.LongestPrefix(i) - // We may not always have a value here, but if we do, then it's a bool. - wild, _ := wildi.(bool) - // Check if it's a wildcard ignore. - if strings.HasSuffix(i, "*") { - // Check if it is ineffectual. - if has && wild { - // Skip ineffectual wildcard ignore. - continue - } - // Create the ignore prefix and insert in the radix tree. - ir.t.Insert(i[:len(i)-1], true) - } else if !has || !wild { - ir.t.Insert(i, false) - } - } - - if ir.t.Len() == 0 { - ir.t = nil - } - - return ir -} - -// IsIgnored indicates whether the provided path should be ignored, according to -// the ruleset. -func (ir *IgnoredRuleset) IsIgnored(path string) bool { - if path == "" || ir == nil || ir.t == nil { - return false - } - - prefix, wildi, has := ir.t.LongestPrefix(path) - return has && (wildi.(bool) || path == prefix) -} - -// Len indicates the number of rules in the ruleset. -func (ir *IgnoredRuleset) Len() int { - if ir == nil || ir.t == nil { - return 0 - } - - return ir.t.Len() -} - -// ToSlice converts the contents of the IgnoredRuleset to a string slice. -// -// This operation is symmetrically dual to NewIgnoredRuleset. -func (ir *IgnoredRuleset) ToSlice() []string { - irlen := ir.Len() - if irlen == 0 { - return nil - } - - items := make([]string, 0, irlen) - ir.t.Walk(func(s string, v interface{}) bool { - if s != "" { - if v.(bool) { - items = append(items, s+"*") - } else { - items = append(items, s) - } - } - return false - }) - - return items -} diff --git a/vendor/github.com/golang/dep/gps/pkgtree/pkgtree.go b/vendor/github.com/golang/dep/gps/pkgtree/pkgtree.go deleted file mode 100644 index 7938b8908319332afbc0cc9ba141f20d706f9ecd..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/pkgtree.go +++ /dev/null @@ -1,1108 +0,0 @@ -// 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 pkgtree - -import ( - "bytes" - "fmt" - "go/ast" - "go/build" - "go/parser" - gscan "go/scanner" - "go/token" - "os" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "unicode" -) - -// Package represents a Go package. It contains a subset of the information -// go/build.Package does. -type Package struct { - Name string // Package name, as declared in the package statement - ImportPath string // Full import path, including the prefix provided to ListPackages() - CommentPath string // Import path given in the comment on the package statement - Imports []string // Imports from all go and cgo files - TestImports []string // Imports from all go test files (in go/build parlance: both TestImports and XTestImports) -} - -// vcsRoots is a set of directories we should not descend into in ListPackages when -// searching for Go packages -var vcsRoots = map[string]struct{}{ - ".git": {}, - ".bzr": {}, - ".svn": {}, - ".hg": {}, -} - -// ListPackages reports Go package information about all directories in the tree -// at or below the provided fileRoot. -// -// The importRoot parameter is prepended to the relative path when determining -// the import path for each package. The obvious case is for something typical, -// like: -// -// fileRoot = "/home/user/go/src/github.com/foo/bar" -// importRoot = "github.com/foo/bar" -// -// where the fileRoot and importRoot align. However, if you provide: -// -// fileRoot = "/home/user/workspace/path/to/repo" -// importRoot = "github.com/foo/bar" -// -// then the root package at path/to/repo will be ascribed import path -// "github.com/foo/bar", and the package at -// "/home/user/workspace/path/to/repo/baz" will be "github.com/foo/bar/baz". -// -// A PackageTree is returned, which contains the ImportRoot and map of import path -// to PackageOrErr - each path under the root that exists will have either a -// Package, or an error describing why the directory is not a valid package. -func ListPackages(fileRoot, importRoot string) (PackageTree, error) { - ptree := PackageTree{ - ImportRoot: importRoot, - Packages: make(map[string]PackageOrErr), - } - - var err error - fileRoot, err = filepath.Abs(fileRoot) - if err != nil { - return PackageTree{}, err - } - - err = filepath.Walk(fileRoot, func(wp string, fi os.FileInfo, err error) error { - if err != nil && err != filepath.SkipDir { - if os.IsPermission(err) { - return filepath.SkipDir - } - return err - } - if !fi.IsDir() { - return nil - } - - // Skip dirs that are known to hold non-local/dependency code. - // - // We don't skip _*, or testdata dirs because, while it may be poor - // form, importing them is not a compilation error. - switch fi.Name() { - case "vendor", "Godeps": - return filepath.SkipDir - } - - // Skip dirs that are known to be VCS roots. - // - // Note that there are some pathological edge cases this doesn't cover, - // such as a user using Git for version control, but having a package - // named "svn" in a directory named ".svn". - if _, ok := vcsRoots[fi.Name()]; ok { - return filepath.SkipDir - } - - { - // For Go 1.9 and earlier: - // - // The entry error is nil when visiting a directory that itself is - // untraversable, as it's still governed by the parent directory's - // perms. We have to check readability of the dir here, because - // otherwise we'll have an empty package entry when we fail to read any - // of the dir's contents. - // - // If we didn't check here, then the next time this closure is called it - // would have an err with the same path as is called this time, as only - // then will filepath.Walk have attempted to descend into the directory - // and encountered an error. - var f *os.File - f, err = os.Open(wp) - if err != nil { - if os.IsPermission(err) { - return filepath.SkipDir - } - return err - } - f.Close() - } - - // Compute the import path. Run the result through ToSlash(), so that - // windows file paths are normalized to slashes, as is expected of - // import paths. - ip := filepath.ToSlash(filepath.Join(importRoot, strings.TrimPrefix(wp, fileRoot))) - - // Find all the imports, across all os/arch combos - p := &build.Package{ - Dir: wp, - ImportPath: ip, - } - err = fillPackage(p) - - if err != nil { - switch err.(type) { - case gscan.ErrorList, *gscan.Error, *build.NoGoError, *ConflictingImportComments: - // Assorted cases in which we've encounter malformed or - // nonexistent Go source code. - ptree.Packages[ip] = PackageOrErr{ - Err: err, - } - return nil - default: - return err - } - } - - pkg := Package{ - ImportPath: ip, - CommentPath: p.ImportComment, - Name: p.Name, - Imports: p.Imports, - TestImports: dedupeStrings(p.TestImports, p.XTestImports), - } - - if pkg.CommentPath != "" && !strings.HasPrefix(pkg.CommentPath, importRoot) { - ptree.Packages[ip] = PackageOrErr{ - Err: &NonCanonicalImportRoot{ - ImportRoot: importRoot, - Canonical: pkg.CommentPath, - }, - } - return nil - } - - // This area has some...fuzzy rules, but check all the imports for - // local/relative/dot-ness, and record an error for the package if we - // see any. - var lim []string - for _, imp := range append(pkg.Imports, pkg.TestImports...) { - if build.IsLocalImport(imp) { - // Do allow the single-dot, at least for now - if imp == "." { - continue - } - lim = append(lim, imp) - } - } - - if len(lim) > 0 { - ptree.Packages[ip] = PackageOrErr{ - Err: &LocalImportsError{ - Dir: wp, - ImportPath: ip, - LocalImports: lim, - }, - } - } else { - ptree.Packages[ip] = PackageOrErr{ - P: pkg, - } - } - - return nil - }) - - if err != nil { - return PackageTree{}, err - } - - return ptree, nil -} - -// fillPackage full of info. Assumes p.Dir is set at a minimum -func fillPackage(p *build.Package) error { - var buildPrefix = "// +build " - var buildFieldSplit = func(r rune) bool { - return unicode.IsSpace(r) || r == ',' - } - - gofiles, err := filepath.Glob(filepath.Join(p.Dir, "*.go")) - if err != nil { - return err - } - - if len(gofiles) == 0 { - return &build.NoGoError{Dir: p.Dir} - } - - var testImports []string - var imports []string - var importComments []string - for _, file := range gofiles { - // Skip underscore-led or dot-led files, in keeping with the rest of the toolchain. - bPrefix := filepath.Base(file)[0] - if bPrefix == '_' || bPrefix == '.' { - continue - } - - // Skip any directories that happened to get caught by glob - if stat, err := os.Stat(file); err == nil && stat.IsDir() { - continue - } - - pf, err := parser.ParseFile(token.NewFileSet(), file, nil, parser.ImportsOnly|parser.ParseComments) - if err != nil { - if os.IsPermission(err) { - continue - } - return err - } - testFile := strings.HasSuffix(file, "_test.go") - fname := filepath.Base(file) - - var ignored bool - for _, c := range pf.Comments { - ic := findImportComment(pf.Name, c) - if ic != "" { - importComments = append(importComments, ic) - } - if c.Pos() > pf.Package { // +build comment must come before package - continue - } - - var ct string - for _, cl := range c.List { - if strings.HasPrefix(cl.Text, buildPrefix) { - ct = cl.Text - break - } - } - if ct == "" { - continue - } - - for _, t := range strings.FieldsFunc(ct[len(buildPrefix):], buildFieldSplit) { - // hardcoded (for now) handling for the "ignore" build tag - // We "soft" ignore the files tagged with ignore so that we pull in their imports. - if t == "ignore" { - ignored = true - } - } - } - - if testFile { - p.TestGoFiles = append(p.TestGoFiles, fname) - if p.Name == "" && !ignored { - p.Name = strings.TrimSuffix(pf.Name.Name, "_test") - } - } else { - if p.Name == "" && !ignored { - p.Name = pf.Name.Name - } - p.GoFiles = append(p.GoFiles, fname) - } - - for _, is := range pf.Imports { - name, err := strconv.Unquote(is.Path.Value) - if err != nil { - return err // can't happen? - } - if testFile { - testImports = append(testImports, name) - } else { - imports = append(imports, name) - } - } - } - importComments = uniq(importComments) - if len(importComments) > 1 { - return &ConflictingImportComments{ - ImportPath: p.ImportPath, - ConflictingImportComments: importComments, - } - } - if len(importComments) > 0 { - p.ImportComment = importComments[0] - } - imports = uniq(imports) - testImports = uniq(testImports) - p.Imports = imports - p.TestImports = testImports - return nil -} - -var ( - slashSlash = []byte("//") - slashStar = []byte("/*") - starSlash = []byte("*/") - importKwd = []byte("import ") -) - -func findImportComment(pkgName *ast.Ident, c *ast.CommentGroup) string { - afterPkg := pkgName.NamePos + token.Pos(len(pkgName.Name)) + 1 - commentSlash := c.List[0].Slash - if afterPkg != commentSlash { - return "" - } - text := []byte(c.List[0].Text) - switch { - case bytes.HasPrefix(text, slashSlash): - eol := bytes.IndexByte(text, '\n') - if eol < 0 { - eol = len(text) - } - text = text[2:eol] - case bytes.HasPrefix(text, slashStar): - text = text[2:] - end := bytes.Index(text, starSlash) - if end < 0 { - // malformed comment - return "" - } - text = text[:end] - if bytes.IndexByte(text, '\n') > 0 { - // multiline comment, can't be an import comment - return "" - } - } - text = bytes.TrimSpace(text) - if !bytes.HasPrefix(text, importKwd) { - return "" - } - quotedPath := bytes.TrimSpace(text[len(importKwd):]) - return string(bytes.Trim(quotedPath, `"`)) -} - -// ConflictingImportComments indicates that the package declares more than one -// different canonical path. -type ConflictingImportComments struct { - ImportPath string // An import path referring to this package - ConflictingImportComments []string // All distinct "canonical" paths encountered in the package files -} - -func (e *ConflictingImportComments) Error() string { - return fmt.Sprintf("import path %s had conflicting import comments: %s", - e.ImportPath, quotedPaths(e.ConflictingImportComments)) -} - -// NonCanonicalImportRoot reports the situation when the dependee imports a -// package via something other than the package's declared canonical path. -type NonCanonicalImportRoot struct { - ImportRoot string // A root path that is being used to import a package - Canonical string // A canonical path declared by the package being imported -} - -func (e *NonCanonicalImportRoot) Error() string { - return fmt.Sprintf("import root %q is not a prefix for the package's declared canonical path %q", - e.ImportRoot, e.Canonical) -} - -func quotedPaths(ps []string) string { - quoted := make([]string, 0, len(ps)) - for _, p := range ps { - quoted = append(quoted, fmt.Sprintf("%q", p)) - } - return strings.Join(quoted, ", ") -} - -// LocalImportsError indicates that a package contains at least one relative -// import that will prevent it from compiling. -// -// TODO(sdboyer) add a Files property once we're doing our own per-file parsing -type LocalImportsError struct { - ImportPath string - Dir string - LocalImports []string -} - -func (e *LocalImportsError) Error() string { - switch len(e.LocalImports) { - case 0: - // shouldn't be possible, but just cover the case - return fmt.Sprintf("import path %s had bad local imports", e.ImportPath) - case 1: - return fmt.Sprintf("import path %s had a local import: %q", e.ImportPath, e.LocalImports[0]) - default: - return fmt.Sprintf("import path %s had local imports: %s", e.ImportPath, quotedPaths(e.LocalImports)) - } -} - -type wm struct { - err error - ex map[string]bool - in map[string]bool -} - -// PackageOrErr stores the results of attempting to parse a single directory for -// Go source code. -type PackageOrErr struct { - P Package - Err error -} - -// ProblemImportError describes the reason that a particular import path is -// not safely importable. -type ProblemImportError struct { - // The import path of the package with some problem rendering it - // unimportable. - ImportPath string - // The path to the internal package the problem package imports that is the - // original cause of this issue. If empty, the package itself is the - // problem. - Cause []string - // The actual error from ListPackages that is undermining importability for - // this package. - Err error -} - -// Error formats the ProblemImportError as a string, reflecting whether the -// error represents a direct or transitive problem. -func (e *ProblemImportError) Error() string { - switch len(e.Cause) { - case 0: - return fmt.Sprintf("%q contains malformed code: %s", e.ImportPath, e.Err.Error()) - case 1: - return fmt.Sprintf("%q imports %q, which contains malformed code: %s", e.ImportPath, e.Cause[0], e.Err.Error()) - default: - return fmt.Sprintf("%q transitively (through %v packages) imports %q, which contains malformed code: %s", e.ImportPath, len(e.Cause)-1, e.Cause[len(e.Cause)-1], e.Err.Error()) - } -} - -// Helper func to create an error when a package is missing. -func missingPkgErr(pkg string) error { - return fmt.Errorf("no package exists at %q", pkg) -} - -// A PackageTree represents the results of recursively parsing a tree of -// packages, starting at the ImportRoot. The results of parsing the files in the -// directory identified by each import path - a Package or an error - are stored -// in the Packages map, keyed by that import path. -type PackageTree struct { - ImportRoot string - Packages map[string]PackageOrErr -} - -// ToReachMap looks through a PackageTree and computes the list of external -// import statements (that is, import statements pointing to packages that are -// not logical children of PackageTree.ImportRoot) that are transitively -// imported by the internal packages in the tree. -// -// main indicates whether (true) or not (false) to include main packages in the -// analysis. When utilized by gps' solver, main packages are generally excluded -// from analyzing anything other than the root project, as they necessarily can't -// be imported. -// -// tests indicates whether (true) or not (false) to include imports from test -// files in packages when computing the reach map. -// -// backprop indicates whether errors (an actual PackageOrErr.Err, or an import -// to a nonexistent internal package) should be backpropagated, transitively -// "poisoning" all corresponding importers to all importers. -// -// ignore is a map of import paths that, if encountered, should be excluded from -// analysis. This exclusion applies to both internal and external packages. If -// an external import path is ignored, it is simply omitted from the results. -// -// If an internal path is ignored, then it not only does not appear in the final -// map, but it is also excluded from the transitive calculations of other -// internal packages. That is, if you ignore A/foo, then the external package -// list for all internal packages that import A/foo will not include external -// packages that are only reachable through A/foo. -// -// Visually, this means that, given a PackageTree with root A and packages at A, -// A/foo, and A/bar, and the following import chain: -// -// A -> A/foo -> A/bar -> B/baz -// -// In this configuration, all of A's packages transitively import B/baz, so the -// returned map would be: -// -// map[string][]string{ -// "A": []string{"B/baz"}, -// "A/foo": []string{"B/baz"} -// "A/bar": []string{"B/baz"}, -// } -// -// However, if you ignore A/foo, then A's path to B/baz is broken, and A/foo is -// omitted entirely. Thus, the returned map would be: -// -// map[string][]string{ -// "A": []string{}, -// "A/bar": []string{"B/baz"}, -// } -// -// If there are no packages to ignore, it is safe to pass a nil map. -// -// Finally, if an internal PackageOrErr contains an error, it is always omitted -// from the result set. If backprop is true, then the error from that internal -// package will be transitively propagated back to any other internal -// PackageOrErrs that import it, causing them to also be omitted. So, with the -// same import chain: -// -// A -> A/foo -> A/bar -> B/baz -// -// If A/foo has an error, then it would backpropagate to A, causing both to be -// omitted, and the returned map to contain only A/bar: -// -// map[string][]string{ -// "A/bar": []string{"B/baz"}, -// } -// -// If backprop is false, then errors will not backpropagate to internal -// importers. So, with an error in A/foo, this would be the result map: -// -// map[string][]string{ -// "A": []string{}, -// "A/bar": []string{"B/baz"}, -// } -func (t PackageTree) ToReachMap(main, tests, backprop bool, ignore *IgnoredRuleset) (ReachMap, map[string]*ProblemImportError) { - // world's simplest adjacency list - workmap := make(map[string]wm) - - var imps []string - for ip, perr := range t.Packages { - if perr.Err != nil { - workmap[ip] = wm{ - err: perr.Err, - } - continue - } - p := perr.P - - // Skip main packages, unless param says otherwise - if p.Name == "main" && !main { - continue - } - // Skip ignored packages - if ignore.IsIgnored(ip) { - continue - } - - // TODO (kris-nova) Disable to get staticcheck passing - //imps = imps[:0] - - if tests { - imps = dedupeStrings(p.Imports, p.TestImports) - } else { - imps = p.Imports - } - - w := wm{ - ex: make(map[string]bool), - in: make(map[string]bool), - } - - // For each import, decide whether it should be ignored, or if it - // belongs in the external or internal imports list. - for _, imp := range imps { - if ignore.IsIgnored(imp) || imp == "." { - continue - } - - if !eqOrSlashedPrefix(imp, t.ImportRoot) { - w.ex[imp] = true - } else { - w.in[imp] = true - } - } - - workmap[ip] = w - } - - return wmToReach(workmap, backprop) -} - -// Copy copies the PackageTree. -// -// This is really only useful as a defensive measure to prevent external state -// mutations. -func (t PackageTree) Copy() PackageTree { - t2 := PackageTree{ - ImportRoot: t.ImportRoot, - Packages: make(map[string]PackageOrErr, len(t.Packages)), - } - - // Walk through and count up the total number of string slice elements we'll - // need, then allocate them all at once. - strcount := 0 - for _, poe := range t.Packages { - strcount = strcount + len(poe.P.Imports) + len(poe.P.TestImports) - } - pool := make([]string, strcount) - - for path, poe := range t.Packages { - var poe2 PackageOrErr - - if poe.Err != nil { - refl := reflect.ValueOf(poe.Err) - switch refl.Kind() { - case reflect.Ptr: - poe2.Err = reflect.New(refl.Elem().Type()).Interface().(error) - case reflect.Slice: - err2 := reflect.MakeSlice(refl.Type(), refl.Len(), refl.Len()) - reflect.Copy(err2, refl) - poe2.Err = err2.Interface().(error) - default: - // This shouldn't be too onerous to maintain - the set of errors - // we can get here is restricted by what ListPackages() allows. - // So just panic if one is outside the expected kinds of ptr or - // slice, as that would mean we've missed something notable. - panic(fmt.Sprintf("unrecognized PackgeOrErr error type, %T", poe.Err)) - } - } else { - poe2.P = poe.P - il, til := len(poe.P.Imports), len(poe.P.TestImports) - if il > 0 { - poe2.P.Imports, pool = pool[:il], pool[il:] - copy(poe2.P.Imports, poe.P.Imports) - } - if til > 0 { - poe2.P.TestImports, pool = pool[:til], pool[til:] - copy(poe2.P.TestImports, poe.P.TestImports) - } - } - - t2.Packages[path] = poe2 - } - - return t2 -} - -// TrimHiddenPackages returns a new PackageTree where packages that are ignored, -// or both hidden and unreachable, have been removed. -// -// The package list is partitioned into two sets: visible, and hidden, where -// packages are considered hidden if they are within or beneath directories -// with: -// -// * leading dots -// * leading underscores -// * the exact name "testdata" -// -// Packages in the hidden set are dropped from the returned PackageTree, unless -// they are transitively reachable from imports in the visible set. -// -// The "main", "tests" and "ignored" parameters have the same behavior as with -// PackageTree.ToReachMap(): the first two determine, respectively, whether -// imports from main packages, and imports from tests, should be considered for -// reachability checks. Setting 'main' to true will additionally result in main -// packages being trimmed. -// -// "ignored" designates import paths, or patterns of import paths, where the -// corresponding packages should be excluded from reachability checks, if -// encountered. Ignored packages are also removed from the final set. -// -// Note that it is not recommended to call this method if the goal is to obtain -// a set of tree-external imports; calling ToReachMap and FlattenFn will achieve -// the same effect. -func (t PackageTree) TrimHiddenPackages(main, tests bool, ignore *IgnoredRuleset) PackageTree { - rm, pie := t.ToReachMap(main, tests, false, ignore) - t2 := t.Copy() - preserve := make(map[string]bool) - - for pkg, ie := range rm { - if pkgFilter(pkg) && !ignore.IsIgnored(pkg) { - preserve[pkg] = true - for _, in := range ie.Internal { - preserve[in] = true - } - } - } - - // Also process the problem map, as packages in the visible set with errors - // need to be included in the return values. - for pkg := range pie { - if pkgFilter(pkg) && !ignore.IsIgnored(pkg) { - preserve[pkg] = true - } - } - - for ip := range t.Packages { - if !preserve[ip] { - delete(t2.Packages, ip) - } - } - - return t2 -} - -// wmToReach takes an internal "workmap" constructed by -// PackageTree.ExternalReach(), transitively walks (via depth-first traversal) -// all internal imports until they reach an external path or terminate, then -// translates the results into a slice of external imports for each internal -// pkg. -// -// It drops any packages with errors, and - if backprop is true - backpropagates -// those errors, causing internal packages that (transitively) import other -// internal packages having errors to also be dropped. -func wmToReach(workmap map[string]wm, backprop bool) (ReachMap, map[string]*ProblemImportError) { - // Uses depth-first exploration to compute reachability into external - // packages, dropping any internal packages on "poisoned paths" - a path - // containing a package with an error, or with a dep on an internal package - // that's missing. - - const ( - white uint8 = iota - grey - black - ) - - colors := make(map[string]uint8) - exrsets := make(map[string]map[string]struct{}) - inrsets := make(map[string]map[string]struct{}) - errmap := make(map[string]*ProblemImportError) - - // poison is a helper func to eliminate specific reachsets from exrsets and - // inrsets, and populate error information along the way. - poison := func(path []string, err *ProblemImportError) { - for k, ppkg := range path { - delete(exrsets, ppkg) - delete(inrsets, ppkg) - - // Duplicate the err for this package - kerr := &ProblemImportError{ - ImportPath: ppkg, - Err: err.Err, - } - - // Shift the slice bounds on the incoming err.Cause. - // - // This check will only be false on the final path element when - // entering via poisonWhite, where the last pkg is the underlying - // cause of the problem, and is thus expected to have an empty Cause - // slice. - if k+1 < len(err.Cause) { - // reuse the slice - kerr.Cause = err.Cause[k+1:] - } - - // Both black and white cases can have the final element be a - // package that doesn't exist. If that's the case, don't write it - // directly to the errmap, as presence in the errmap indicates the - // package was present in the input PackageTree. - if k == len(path)-1 { - if _, exists := workmap[path[len(path)-1]]; !exists { - continue - } - } - - // Direct writing to the errmap means that if multiple errors affect - // a given package, only the last error visited will be reported. - // But that should be sufficient; presumably, the user can - // iteratively resolve the errors. - errmap[ppkg] = kerr - } - } - - // poisonWhite wraps poison for error recording in the white-poisoning case, - // where we're constructing a new poison path. - poisonWhite := func(path []string) { - err := &ProblemImportError{ - Cause: make([]string, len(path)), - } - copy(err.Cause, path) - - // find the tail err - tail := path[len(path)-1] - if w, exists := workmap[tail]; exists { - // If we make it to here, the dfe guarantees that the workmap - // will contain an error for this pkg. - err.Err = w.err - } else { - err.Err = missingPkgErr(tail) - } - - poison(path, err) - } - // poisonBlack wraps poison for error recording in the black-poisoning case, - // where we're connecting to an existing poison path. - poisonBlack := func(path []string, from string) { - // Because the outer dfe loop ensures we never directly re-visit a pkg - // that was already completed (black), we don't have to defend against - // an empty path here. - - fromErr, exists := errmap[from] - // FIXME: It should not be possible for fromErr to not exist, - // See issue https://github.com/golang/dep/issues/351 - // This is a temporary solution to avoid a panic. - if !exists { - fromErr = &ProblemImportError{ - Err: fmt.Errorf("unknown error for %q, if you get this error see https://github.com/golang/dep/issues/351", from), - } - } - err := &ProblemImportError{ - Err: fromErr.Err, - Cause: make([]string, 0, len(path)+len(fromErr.Cause)+1), - } - err.Cause = append(err.Cause, path...) - err.Cause = append(err.Cause, from) - err.Cause = append(err.Cause, fromErr.Cause...) - - poison(path, err) - } - - var dfe func(string, []string) bool - - // dfe is the depth-first-explorer that computes a safe, error-free external - // reach map. - // - // pkg is the import path of the pkg currently being visited; path is the - // stack of parent packages we've visited to get to pkg. The return value - // indicates whether the level completed successfully (true) or if it was - // poisoned (false). - dfe = func(pkg string, path []string) bool { - // white is the zero value of uint8, which is what we want if the pkg - // isn't in the colors map, so this works fine - switch colors[pkg] { - case white: - // first visit to this pkg; mark it as in-process (grey) - colors[pkg] = grey - - // make sure it's present and w/out errs - w, exists := workmap[pkg] - - // Push current visitee onto the path slice. Passing path through - // recursion levels as a value has the effect of auto-popping the - // slice, while also giving us safe memory reuse. - path = append(path, pkg) - - if !exists || w.err != nil { - if backprop { - // Does not exist or has an err; poison self and all parents - poisonWhite(path) - } else if exists { - // Only record something in the errmap if there's actually a - // package there, per the semantics of the errmap - errmap[pkg] = &ProblemImportError{ - ImportPath: pkg, - Err: w.err, - } - } - - // we know we're done here, so mark it black - colors[pkg] = black - return false - } - // pkg exists with no errs; start internal and external reachsets for it. - rs := make(map[string]struct{}) - irs := make(map[string]struct{}) - - // Dump this package's external pkgs into its own reachset. Separate - // loop from the parent dump to avoid nested map loop lookups. - for ex := range w.ex { - rs[ex] = struct{}{} - } - exrsets[pkg] = rs - // Same deal for internal imports - for in := range w.in { - irs[in] = struct{}{} - } - inrsets[pkg] = irs - - // Push this pkg's imports into all parent reachsets. Not all - // parents will necessarily have a reachset; none, some, or all - // could have been poisoned by a different path than what we're on - // right now. - for _, ppkg := range path { - if prs, exists := exrsets[ppkg]; exists { - for ex := range w.ex { - prs[ex] = struct{}{} - } - } - - if prs, exists := inrsets[ppkg]; exists { - for in := range w.in { - prs[in] = struct{}{} - } - } - } - - // Now, recurse until done, or a false bubbles up, indicating the - // path is poisoned. - for in := range w.in { - // It's possible, albeit weird, for a package to import itself. - // If we try to visit self, though, then it erroneously poisons - // the path, as it would be interpreted as grey. In practice, - // self-imports are a no-op, so we can just skip it. - if in == pkg { - continue - } - - clean := dfe(in, path) - if !clean && backprop { - // Path is poisoned. If we're backpropagating errors, then - // the reachmap for the visitee was already deleted by the - // path we're returning from; mark the visitee black, then - // return false to bubble up the poison. This is OK to do - // early, before exploring all internal imports, because the - // outer loop visits all internal packages anyway. - // - // In fact, stopping early is preferable - white subpackages - // won't have to iterate pointlessly through a parent path - // with no reachset. - colors[pkg] = black - return false - } - } - - // Fully done with this pkg; no transitive problems. - colors[pkg] = black - return true - - case grey: - // Import cycles can arise in healthy situations through xtests, so - // allow them for now. - // - // FIXME(sdboyer) we need an improved model that allows us to - // accurately reject real import cycles. - return true - // grey means an import cycle; guaranteed badness right here. You'd - // hope we never encounter it in a dependency (really? you published - // that code?), but we have to defend against it. - //colors[pkg] = black - //poison(append(path, pkg)) // poison self and parents - - case black: - // black means we're revisiting a package that was already - // completely explored. If it has an entry in exrsets, it completed - // successfully. If not, it was poisoned, and we need to bubble the - // poison back up. - rs, exists := exrsets[pkg] - if !exists { - if backprop { - // just poison parents; self was necessarily already poisoned - poisonBlack(path, pkg) - } - return false - } - // If external reachset existed, internal must (even if empty) - irs := inrsets[pkg] - - // It's good; pull over the imports from its reachset into all - // non-poisoned parent reachsets - for _, ppkg := range path { - if prs, exists := exrsets[ppkg]; exists { - for ex := range rs { - prs[ex] = struct{}{} - } - } - - if prs, exists := inrsets[ppkg]; exists { - for in := range irs { - prs[in] = struct{}{} - } - } - } - return true - - default: - panic(fmt.Sprintf("invalid color marker %v for %s", colors[pkg], pkg)) - } - } - - // Run the depth-first exploration. - // - // Don't bother computing graph sources, this straightforward loop works - // comparably well, and fits nicely with an escape hatch in the dfe. - var path []string - for pkg := range workmap { - // However, at least check that the package isn't already fully visited; - // this saves a bit of time and implementation complexity inside the - // closures. - if colors[pkg] != black { - dfe(pkg, path) - } - } - - type ie struct { - Internal, External []string - } - - // Flatten exrsets into reachmap - rm := make(ReachMap) - for pkg, rs := range exrsets { - rlen := len(rs) - if rlen == 0 { - rm[pkg] = ie{} - continue - } - - edeps := make([]string, 0, rlen) - for opkg := range rs { - edeps = append(edeps, opkg) - } - - sort.Strings(edeps) - - sets := rm[pkg] - sets.External = edeps - rm[pkg] = sets - } - - // Flatten inrsets into reachmap - for pkg, rs := range inrsets { - rlen := len(rs) - if rlen == 0 { - continue - } - - ideps := make([]string, 0, rlen) - for opkg := range rs { - ideps = append(ideps, opkg) - } - - sort.Strings(ideps) - - sets := rm[pkg] - sets.Internal = ideps - rm[pkg] = sets - } - - return rm, errmap -} - -// eqOrSlashedPrefix checks to see if the prefix is either equal to the string, -// or that it is a prefix and the next char in the string is "/". -func eqOrSlashedPrefix(s, prefix string) bool { - if !strings.HasPrefix(s, prefix) { - return false - } - - prflen, pathlen := len(prefix), len(s) - return prflen == pathlen || strings.Index(s[prflen:], "/") == 0 -} - -// helper func to merge, dedupe, and sort strings -func dedupeStrings(s1, s2 []string) (r []string) { - dedupe := make(map[string]bool) - - if len(s1) > 0 && len(s2) > 0 { - for _, i := range s1 { - dedupe[i] = true - } - for _, i := range s2 { - dedupe[i] = true - } - - for i := range dedupe { - r = append(r, i) - } - // And then re-sort them - sort.Strings(r) - } else if len(s1) > 0 { - r = s1 - } else if len(s2) > 0 { - r = s2 - } - - return -} - -func uniq(a []string) []string { - if a == nil { - return make([]string, 0) - } - var s string - var i int - if !sort.StringsAreSorted(a) { - sort.Strings(a) - } - for _, t := range a { - if t != s { - a[i] = t - i++ - s = t - } - } - return a[:i] -} diff --git a/vendor/github.com/golang/dep/gps/pkgtree/reachmap.go b/vendor/github.com/golang/dep/gps/pkgtree/reachmap.go deleted file mode 100644 index 27af5e90ba069b8745bfa616852bca408cc8874c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/pkgtree/reachmap.go +++ /dev/null @@ -1,65 +0,0 @@ -// 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 pkgtree - -import ( - "sort" - "strings" -) - -// ReachMap maps a set of import paths (keys) to the sets of transitively -// reachable tree-internal packages, and all the tree-external packages -// reachable through those internal packages. -// -// See PackageTree.ToReachMap() for more information. -type ReachMap map[string]struct { - Internal, External []string -} - -// Eliminate import paths with any elements having leading dots, leading -// underscores, or testdata. If these are internally reachable (which is -// a no-no, but possible), any external imports will have already been -// pulled up through ExternalReach. The key here is that we don't want -// to treat such packages as themselves being sources. -func pkgFilter(pkg string) bool { - for _, elem := range strings.Split(pkg, "/") { - if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" { - return false - } - } - return true -} - -// FlattenFn flattens a reachmap into a sorted, deduplicated list of all the -// external imports named by its contained packages, but excludes imports coming -// from packages with disallowed patterns in their names: any path element with -// a leading dot, a leading underscore, with the name "testdata". -// -// Imports for which exclude returns true will be left out. -func (rm ReachMap) FlattenFn(exclude func(string) bool) []string { - exm := make(map[string]struct{}) - for pkg, ie := range rm { - if pkgFilter(pkg) { - for _, ex := range ie.External { - if exclude != nil && exclude(ex) { - continue - } - exm[ex] = struct{}{} - } - } - } - - if len(exm) == 0 { - return []string{} - } - - ex := make([]string, 0, len(exm)) - for p := range exm { - ex = append(ex, p) - } - - sort.Strings(ex) - return ex -} diff --git a/vendor/github.com/golang/dep/gps/prune.go b/vendor/github.com/golang/dep/gps/prune.go deleted file mode 100644 index aa8671c41422ae5f29d25f5707a2f4a771ccce80..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/prune.go +++ /dev/null @@ -1,382 +0,0 @@ -// 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 gps - -import ( - "log" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -// PruneOptions represents the pruning options used to write the dependecy tree. -type PruneOptions uint8 - -const ( - // PruneNestedVendorDirs indicates if nested vendor directories should be pruned. - PruneNestedVendorDirs PruneOptions = 1 << iota - // PruneUnusedPackages indicates if unused Go packages should be pruned. - PruneUnusedPackages - // PruneNonGoFiles indicates if non-Go files should be pruned. - // Files matching licenseFilePrefixes and legalFileSubstrings are kept in - // an attempt to comply with legal requirements. - PruneNonGoFiles - // PruneGoTestFiles indicates if Go test files should be pruned. - PruneGoTestFiles -) - -// PruneOptionSet represents trinary distinctions for each of the types of -// prune rules (as expressed via PruneOptions): nested vendor directories, -// unused packages, non-go files, and go test files. -// -// The three-way distinction is between "none", "true", and "false", represented -// by uint8 values of 0, 1, and 2, respectively. -// -// This trinary distinction is necessary in order to record, with full fidelity, -// a cascading tree of pruning values, as expressed in CascadingPruneOptions; a -// simple boolean cannot delineate between "false" and "none". -type PruneOptionSet struct { - NestedVendor uint8 - UnusedPackages uint8 - NonGoFiles uint8 - GoTests uint8 -} - -// CascadingPruneOptions is a set of rules for pruning a dependency tree. -// -// The DefaultOptions are the global default pruning rules, expressed as a -// single PruneOptions bitfield. These global rules will cascade down to -// individual project rules, unless superseded. -type CascadingPruneOptions struct { - DefaultOptions PruneOptions - PerProjectOptions map[ProjectRoot]PruneOptionSet -} - -// PruneOptionsFor returns the PruneOptions bits for the given project, -// indicating which pruning rules should be applied to the project's code. -// -// It computes the cascade from default to project-specific options (if any) on -// the fly. -func (o CascadingPruneOptions) PruneOptionsFor(pr ProjectRoot) PruneOptions { - po, has := o.PerProjectOptions[pr] - if !has { - return o.DefaultOptions - } - - ops := o.DefaultOptions - if po.NestedVendor != 0 { - if po.NestedVendor == 1 { - ops |= PruneNestedVendorDirs - } else { - ops &^= PruneNestedVendorDirs - } - } - - if po.UnusedPackages != 0 { - if po.UnusedPackages == 1 { - ops |= PruneUnusedPackages - } else { - ops &^= PruneUnusedPackages - } - } - - if po.NonGoFiles != 0 { - if po.NonGoFiles == 1 { - ops |= PruneNonGoFiles - } else { - ops &^= PruneNonGoFiles - } - } - - if po.GoTests != 0 { - if po.GoTests == 1 { - ops |= PruneGoTestFiles - } else { - ops &^= PruneGoTestFiles - } - } - - return ops -} - -func defaultCascadingPruneOptions() CascadingPruneOptions { - return CascadingPruneOptions{ - DefaultOptions: PruneNestedVendorDirs, - PerProjectOptions: map[ProjectRoot]PruneOptionSet{}, - } -} - -var ( - // licenseFilePrefixes is a list of name prefixes for license files. - licenseFilePrefixes = []string{ - "license", - "licence", - "copying", - "unlicense", - "copyright", - "copyleft", - } - // legalFileSubstrings contains substrings that are likey part of a legal - // declaration file. - legalFileSubstrings = []string{ - "authors", - "contributors", - "legal", - "notice", - "disclaimer", - "patent", - "third-party", - "thirdparty", - } -) - -// PruneProject remove excess files according to the options passed, from -// the lp directory in baseDir. -func PruneProject(baseDir string, lp LockedProject, options PruneOptions, logger *log.Logger) error { - fsState, err := deriveFilesystemState(baseDir) - - if err != nil { - return errors.Wrap(err, "could not derive filesystem state") - } - - if (options & PruneNestedVendorDirs) != 0 { - if err := pruneVendorDirs(fsState); err != nil { - return errors.Wrapf(err, "failed to prune nested vendor directories") - } - } - - if (options & PruneUnusedPackages) != 0 { - if _, err := pruneUnusedPackages(lp, fsState); err != nil { - return errors.Wrap(err, "failed to prune unused packages") - } - } - - if (options & PruneNonGoFiles) != 0 { - if err := pruneNonGoFiles(fsState); err != nil { - return errors.Wrap(err, "failed to prune non-Go files") - } - } - - if (options & PruneGoTestFiles) != 0 { - if err := pruneGoTestFiles(fsState); err != nil { - return errors.Wrap(err, "failed to prune Go test files") - } - } - - if err := deleteEmptyDirs(fsState); err != nil { - return errors.Wrap(err, "could not delete empty dirs") - } - - return nil -} - -// pruneVendorDirs deletes all nested vendor directories within baseDir. -func pruneVendorDirs(fsState filesystemState) error { - for _, dir := range fsState.dirs { - if filepath.Base(dir) == "vendor" { - err := os.RemoveAll(filepath.Join(fsState.root, dir)) - if err != nil && !os.IsNotExist(err) { - return err - } - } - } - - for _, link := range fsState.links { - if filepath.Base(link.path) == "vendor" { - err := os.Remove(filepath.Join(fsState.root, link.path)) - if err != nil && !os.IsNotExist(err) { - return err - } - } - } - - return nil -} - -// pruneUnusedPackages deletes unimported packages found in fsState. -// Determining whether packages are imported or not is based on the passed LockedProject. -func pruneUnusedPackages(lp LockedProject, fsState filesystemState) (map[string]interface{}, error) { - unusedPackages := calculateUnusedPackages(lp, fsState) - toDelete := collectUnusedPackagesFiles(fsState, unusedPackages) - - for _, path := range toDelete { - if err := os.Remove(path); err != nil && !os.IsNotExist(err) { - return nil, err - } - } - - return unusedPackages, nil -} - -// calculateUnusedPackages generates a list of unused packages in lp. -func calculateUnusedPackages(lp LockedProject, fsState filesystemState) map[string]interface{} { - unused := make(map[string]interface{}) - imported := make(map[string]interface{}) - - for _, pkg := range lp.Packages() { - imported[pkg] = nil - } - - // Add the root package if it's not imported. - if _, ok := imported["."]; !ok { - unused["."] = nil - } - - for _, dirPath := range fsState.dirs { - pkg := filepath.ToSlash(dirPath) - - if _, ok := imported[pkg]; !ok { - unused[pkg] = nil - } - } - - return unused -} - -// collectUnusedPackagesFiles returns a slice of all files in the unused -// packages based on fsState. -func collectUnusedPackagesFiles(fsState filesystemState, unusedPackages map[string]interface{}) []string { - // TODO(ibrasho): is this useful? - files := make([]string, 0, len(unusedPackages)) - - for _, path := range fsState.files { - // Keep perserved files. - if isPreservedFile(filepath.Base(path)) { - continue - } - - pkg := filepath.ToSlash(filepath.Dir(path)) - - if _, ok := unusedPackages[pkg]; ok { - files = append(files, filepath.Join(fsState.root, path)) - } - } - - return files -} - -// pruneNonGoFiles delete all non-Go files existing in fsState. -// -// Files matching licenseFilePrefixes and legalFileSubstrings are not pruned. -func pruneNonGoFiles(fsState filesystemState) error { - toDelete := make([]string, 0, len(fsState.files)/4) - - for _, path := range fsState.files { - ext := fileExt(path) - - // Refer to: https://github.com/golang/go/blob/release-branch.go1.9/src/go/build/build.go#L750 - switch ext { - case ".go": - continue - case ".c": - continue - case ".cc", ".cpp", ".cxx": - continue - case ".m": - continue - case ".h", ".hh", ".hpp", ".hxx": - continue - case ".f", ".F", ".for", ".f90": - continue - case ".s": - continue - case ".S": - continue - case ".swig": - continue - case ".swigcxx": - continue - case ".syso": - continue - } - - // Ignore perserved files. - if isPreservedFile(filepath.Base(path)) { - continue - } - - toDelete = append(toDelete, filepath.Join(fsState.root, path)) - } - - for _, path := range toDelete { - if err := os.Remove(path); err != nil && !os.IsNotExist(err) { - return err - } - } - - return nil -} - -// isPreservedFile checks if the file name indicates that the file should be -// preserved based on licenseFilePrefixes or legalFileSubstrings. -func isPreservedFile(name string) bool { - name = strings.ToLower(name) - - for _, prefix := range licenseFilePrefixes { - if strings.HasPrefix(name, prefix) { - return true - } - } - - for _, substring := range legalFileSubstrings { - if strings.Contains(name, substring) { - return true - } - } - - return false -} - -// pruneGoTestFiles deletes all Go test files (*_test.go) in fsState. -func pruneGoTestFiles(fsState filesystemState) error { - toDelete := make([]string, 0, len(fsState.files)/2) - - for _, path := range fsState.files { - if strings.HasSuffix(path, "_test.go") { - toDelete = append(toDelete, filepath.Join(fsState.root, path)) - } - } - - for _, path := range toDelete { - if err := os.Remove(path); err != nil && !os.IsNotExist(err) { - return err - } - } - - return nil -} - -func deleteEmptyDirs(fsState filesystemState) error { - sort.Sort(sort.Reverse(sort.StringSlice(fsState.dirs))) - - for _, dir := range fsState.dirs { - path := filepath.Join(fsState.root, dir) - - notEmpty, err := fs.IsNonEmptyDir(path) - if err != nil { - return err - } - - if !notEmpty { - if err := os.Remove(path); err != nil && !os.IsNotExist(err) { - return err - } - } - } - - return nil -} - -func fileExt(name string) string { - i := strings.LastIndex(name, ".") - if i < 0 { - return "" - } - return name[i:] -} diff --git a/vendor/github.com/golang/dep/gps/rootdata.go b/vendor/github.com/golang/dep/gps/rootdata.go deleted file mode 100644 index ee78bdf265c1adb0ef802094d3d37aa6cb185852..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/rootdata.go +++ /dev/null @@ -1,204 +0,0 @@ -// 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 gps - -import ( - "sort" - - "github.com/armon/go-radix" - "github.com/golang/dep/gps/pkgtree" -) - -// rootdata holds static data and constraining rules from the root project for -// use in solving. -type rootdata struct { - // Path to the root of the project on which gps is operating. - dir string - - // Ruleset for ignored import paths. - ir *pkgtree.IgnoredRuleset - - // Map of packages to require. - req map[string]bool - - // A ProjectConstraints map containing the validated (guaranteed non-empty) - // overrides declared by the root manifest. - ovr ProjectConstraints - - // A map of the ProjectRoot (local names) that should be allowed to change - chng map[ProjectRoot]struct{} - - // Flag indicating all projects should be allowed to change, without regard - // for lock. - chngall bool - - // A map of the project names listed in the root's lock. - rlm map[ProjectRoot]LockedProject - - // A defensively copied instance of the root manifest. - rm SimpleManifest - - // A defensively copied instance of the root lock. - rl safeLock - - // A defensively copied instance of params.RootPackageTree - rpt pkgtree.PackageTree - - // The ProjectAnalyzer to use for all GetManifestAndLock calls. - an ProjectAnalyzer -} - -// externalImportList returns a list of the unique imports from the root data. -// Ignores and requires are taken into consideration, stdlib is excluded, and -// errors within the local set of package are not backpropagated. -func (rd rootdata) externalImportList(stdLibFn func(string) bool) []string { - rm, _ := rd.rpt.ToReachMap(true, true, false, rd.ir) - reach := rm.FlattenFn(stdLibFn) - - // If there are any requires, slide them into the reach list, as well. - if len(rd.req) > 0 { - // Make a map of imports that are both in the import path list and the - // required list to avoid duplication. - skip := make(map[string]bool, len(rd.req)) - for _, r := range reach { - if rd.req[r] { - skip[r] = true - } - } - - for r := range rd.req { - if !skip[r] { - reach = append(reach, r) - } - } - } - - sort.Strings(reach) - return reach -} - -func (rd rootdata) getApplicableConstraints(stdLibFn func(string) bool) []workingConstraint { - pc := rd.rm.DependencyConstraints() - - // Ensure that overrides which aren't in the combined pc map already make it - // in. Doing so makes input hashes equal in more useful cases. - for pr, pp := range rd.ovr { - if _, has := pc[pr]; !has { - cpp := ProjectProperties{ - Constraint: pp.Constraint, - Source: pp.Source, - } - if cpp.Constraint == nil { - cpp.Constraint = anyConstraint{} - } - - pc[pr] = cpp - } - } - - // Now override them all to produce a consolidated workingConstraint slice - combined := rd.ovr.overrideAll(pc) - - type wccount struct { - count int - wc workingConstraint - } - xt := radix.New() - for _, wc := range combined { - xt.Insert(string(wc.Ident.ProjectRoot), wccount{wc: wc}) - } - - // Walk all dep import paths we have to consider and mark the corresponding - // wc entry in the trie, if any - for _, im := range rd.externalImportList(stdLibFn) { - if stdLibFn(im) { - continue - } - - if pre, v, match := xt.LongestPrefix(im); match && isPathPrefixOrEqual(pre, im) { - wcc := v.(wccount) - wcc.count++ - xt.Insert(pre, wcc) - } - } - - var ret []workingConstraint - - xt.Walk(func(s string, v interface{}) bool { - wcc := v.(wccount) - if wcc.count > 0 { - ret = append(ret, wcc.wc) - } - return false - }) - - return ret -} - -func (rd rootdata) combineConstraints() []workingConstraint { - return rd.ovr.overrideAll(rd.rm.DependencyConstraints()) -} - -// needVersionListFor indicates whether we need a version list for a given -// project root, based solely on general solver inputs (no constraint checking -// required). Assuming the argument is not the root project itself, this will be -// true if any of the following conditions hold: -// -// - ChangeAll is on -// - The project is not in the lock -// - The project is in the lock, but is also in the list of projects to change -func (rd rootdata) needVersionsFor(pr ProjectRoot) bool { - if rd.isRoot(pr) { - return false - } - - if rd.chngall { - return true - } - - if _, has := rd.rlm[pr]; !has { - // not in the lock - return true - } - - if _, has := rd.chng[pr]; has { - // in the lock, but marked for change - return true - } - // in the lock, not marked for change - return false - -} - -func (rd rootdata) isRoot(pr ProjectRoot) bool { - return pr == ProjectRoot(rd.rpt.ImportRoot) -} - -// rootAtom creates an atomWithPackages that represents the root project. -func (rd rootdata) rootAtom() atomWithPackages { - a := atom{ - id: ProjectIdentifier{ - ProjectRoot: ProjectRoot(rd.rpt.ImportRoot), - }, - // This is a hack so that the root project doesn't have a nil version. - // It's sort of OK because the root never makes it out into the results. - // We may need a more elegant solution if we discover other side - // effects, though. - v: rootRev, - } - - list := make([]string, 0, len(rd.rpt.Packages)) - for path, pkg := range rd.rpt.Packages { - if pkg.Err != nil && !rd.ir.IsIgnored(path) { - list = append(list, path) - } - } - sort.Strings(list) - - return atomWithPackages{ - a: a, - pl: list, - } -} diff --git a/vendor/github.com/golang/dep/gps/satisfy.go b/vendor/github.com/golang/dep/gps/satisfy.go deleted file mode 100644 index abac0ea7ef2ebf8e6a46fbd7d96251c7e87298e9..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/satisfy.go +++ /dev/null @@ -1,337 +0,0 @@ -// 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 gps - -// check performs constraint checks on the provided atom. The set of checks -// differ slightly depending on whether the atom is pkgonly, or if it's the -// entire project being added for the first time. -// -// The goal is to determine whether selecting the atom would result in a state -// where all the solver requirements are still satisfied. -func (s *solver) check(a atomWithPackages, pkgonly bool) error { - pa := a.a - if nilpa == pa { - // This shouldn't be able to happen, but if it does, it unequivocally - // indicates a logical bug somewhere, so blowing up is preferable - panic("canary - checking version of empty ProjectAtom") - } - - s.mtr.push("satisfy") - var err error - defer func() { - if err != nil { - s.traceInfo(err) - } - s.mtr.pop() - }() - - // If we're pkgonly, then base atom was already determined to be allowable, - // so we can skip the checkAtomAllowable step. - if !pkgonly { - if err = s.checkAtomAllowable(pa); err != nil { - return err - } - } - - if err = s.checkRequiredPackagesExist(a); err != nil { - return err - } - - var deps []completeDep - _, deps, err = s.getImportsAndConstraintsOf(a) - if err != nil { - // An err here would be from the package fetcher; pass it straight back - return err - } - - // TODO(sdboyer) this deps list contains only packages not already selected - // from the target atom (assuming one is selected at all). It's fine for - // now, but won't be good enough when we get around to doing static - // analysis. - for _, dep := range deps { - if err = s.checkIdentMatches(a, dep); err != nil { - return err - } - if err = s.checkRootCaseConflicts(a, dep); err != nil { - return err - } - if err = s.checkDepsConstraintsAllowable(a, dep); err != nil { - return err - } - if err = s.checkDepsDisallowsSelected(a, dep); err != nil { - return err - } - if err = s.checkRevisionExists(a, dep); err != nil { - return err - } - if err = s.checkPackageImportsFromDepExist(a, dep); err != nil { - return err - } - - // TODO(sdboyer) add check that fails if adding this atom would create a loop - } - - return nil -} - -// checkAtomAllowable ensures that an atom itself is acceptable with respect to -// the constraints established by the current solution. -func (s *solver) checkAtomAllowable(pa atom) error { - constraint := s.sel.getConstraint(pa.id) - if s.vUnify.matches(pa.id, constraint, pa.v) { - return nil - } - // TODO(sdboyer) collect constraint failure reason (wait...aren't we, below?) - - deps := s.sel.getDependenciesOn(pa.id) - var failparent []dependency - for _, dep := range deps { - if !s.vUnify.matches(pa.id, dep.dep.Constraint, pa.v) { - s.fail(dep.depender.id) - failparent = append(failparent, dep) - } - } - - err := &versionNotAllowedFailure{ - goal: pa, - failparent: failparent, - c: constraint, - } - - return err -} - -// checkRequiredPackagesExist ensures that all required packages enumerated by -// existing dependencies on this atom are actually present in the atom. -func (s *solver) checkRequiredPackagesExist(a atomWithPackages) error { - ptree, err := s.b.ListPackages(a.a.id, a.a.v) - if err != nil { - // TODO(sdboyer) handle this more gracefully - return err - } - - deps := s.sel.getDependenciesOn(a.a.id) - fp := make(map[string]errDeppers) - // We inspect these in a bit of a roundabout way, in order to incrementally - // build up the failure we'd return if there is, indeed, a missing package. - // TODO(sdboyer) rechecking all of these every time is wasteful. Is there a shortcut? - for _, dep := range deps { - for _, pkg := range dep.dep.pl { - if errdep, seen := fp[pkg]; seen { - errdep.deppers = append(errdep.deppers, dep.depender) - fp[pkg] = errdep - } else { - perr, has := ptree.Packages[pkg] - if !has || perr.Err != nil { - fp[pkg] = errDeppers{ - err: perr.Err, - deppers: []atom{dep.depender}, - } - } - } - } - } - - if len(fp) > 0 { - return &checkeeHasProblemPackagesFailure{ - goal: a.a, - failpkg: fp, - } - } - return nil -} - -// checkDepsConstraintsAllowable checks that the constraints of an atom on a -// given dep are valid with respect to existing constraints. -func (s *solver) checkDepsConstraintsAllowable(a atomWithPackages, cdep completeDep) error { - dep := cdep.workingConstraint - constraint := s.sel.getConstraint(dep.Ident) - // Ensure the constraint expressed by the dep has at least some possible - // intersection with the intersection of existing constraints. - if s.vUnify.matchesAny(dep.Ident, constraint, dep.Constraint) { - return nil - } - - siblings := s.sel.getDependenciesOn(dep.Ident) - // No admissible versions - visit all siblings and identify the disagreement(s) - var failsib []dependency - var nofailsib []dependency - for _, sibling := range siblings { - if !s.vUnify.matchesAny(dep.Ident, sibling.dep.Constraint, dep.Constraint) { - s.fail(sibling.depender.id) - failsib = append(failsib, sibling) - } else { - nofailsib = append(nofailsib, sibling) - } - } - - return &disjointConstraintFailure{ - goal: dependency{depender: a.a, dep: cdep}, - failsib: failsib, - nofailsib: nofailsib, - c: constraint, - } -} - -// checkDepsDisallowsSelected ensures that an atom's constraints on a particular -// dep are not incompatible with the version of that dep that's already been -// selected. -func (s *solver) checkDepsDisallowsSelected(a atomWithPackages, cdep completeDep) error { - dep := cdep.workingConstraint - selected, exists := s.sel.selected(dep.Ident) - if exists && !s.vUnify.matches(dep.Ident, dep.Constraint, selected.a.v) { - s.fail(dep.Ident) - - return &constraintNotAllowedFailure{ - goal: dependency{depender: a.a, dep: cdep}, - v: selected.a.v, - } - } - return nil -} - -// checkIdentMatches ensures that the LocalName of a dep introduced by an atom, -// has the same Source as what's already been selected (assuming anything's been -// selected). -// -// In other words, this ensures that the solver never simultaneously selects two -// identifiers with the same local name, but that disagree about where their -// network source is. -func (s *solver) checkIdentMatches(a atomWithPackages, cdep completeDep) error { - dep := cdep.workingConstraint - if curid, has := s.sel.getIdentFor(dep.Ident.ProjectRoot); has && !curid.equiv(dep.Ident) { - deps := s.sel.getDependenciesOn(a.a.id) - // Fail all the other deps, as there's no way atom can ever be - // compatible with them - for _, d := range deps { - s.fail(d.depender.id) - } - - return &sourceMismatchFailure{ - shared: dep.Ident.ProjectRoot, - sel: deps, - current: curid.normalizedSource(), - mismatch: dep.Ident.normalizedSource(), - prob: a.a, - } - } - - return nil -} - -// checkRootCaseConflicts ensures that the ProjectRoot specified in the completeDep -// does not have case conflicts with any existing dependencies. -// -// We only need to check the ProjectRoot, rather than any packages therein, as -// the later check for package existence is case-sensitive. -func (s *solver) checkRootCaseConflicts(a atomWithPackages, cdep completeDep) error { - pr := cdep.workingConstraint.Ident.ProjectRoot - hasConflict, current := s.sel.findCaseConflicts(pr) - if !hasConflict { - return nil - } - - curid, _ := s.sel.getIdentFor(current) - deps := s.sel.getDependenciesOn(curid) - for _, d := range deps { - s.fail(d.depender.id) - } - - // If a project has multiple packages that import each other, we treat that - // as establishing a canonical case variant for the ProjectRoot. It's possible, - // however, that that canonical variant is not the same one that others - // imported it under. If that's the situation, then we'll have arrived here - // when visiting the project, not its dependers, having misclassified its - // internal imports as external. That means the atomWithPackages will - // be the wrong case variant induced by the importers, and the cdep will be - // a link pointing back at the canonical case variant. - // - // If this is the case, use a special failure, wrongCaseFailure, that - // makes a stronger statement as to the correctness of case variants. - // - // TODO(sdboyer) This approach to marking failure is less than great, as - // this will mark the current atom as failed, as well, causing the - // backtracker to work through it. While that could prove fruitful, it's - // quite likely just to be wasted effort. Addressing this - if that's a good - // idea - would entail creating another path back out of checking to enable - // backjumping directly to the incorrect importers. - if current == a.a.id.ProjectRoot { - return &wrongCaseFailure{ - correct: pr, - goal: dependency{depender: a.a, dep: cdep}, - badcase: deps, - } - } - - return &caseMismatchFailure{ - goal: dependency{depender: a.a, dep: cdep}, - current: current, - failsib: deps, - } -} - -// checkPackageImportsFromDepExist ensures that, if the dep is already selected, -// the newly-required set of packages being placed on it exist and are valid. -func (s *solver) checkPackageImportsFromDepExist(a atomWithPackages, cdep completeDep) error { - sel, is := s.sel.selected(cdep.workingConstraint.Ident) - if !is { - // dep is not already selected; nothing to do - return nil - } - - ptree, err := s.b.ListPackages(sel.a.id, sel.a.v) - if err != nil { - // TODO(sdboyer) handle this more gracefully - return err - } - - e := &depHasProblemPackagesFailure{ - goal: dependency{ - depender: a.a, - dep: cdep, - }, - v: sel.a.v, - prob: make(map[string]error), - } - - for _, pkg := range cdep.pl { - perr, has := ptree.Packages[pkg] - if !has || perr.Err != nil { - if has { - e.prob[pkg] = perr.Err - } else { - e.prob[pkg] = nil - } - } - } - - if len(e.prob) > 0 { - return e - } - return nil -} - -// checkRevisionExists ensures that if a dependency is constrained by a -// revision, that that revision actually exists. -func (s *solver) checkRevisionExists(a atomWithPackages, cdep completeDep) error { - r, isrev := cdep.Constraint.(Revision) - if !isrev { - // Constraint is not a revision; nothing to do - return nil - } - - present, _ := s.b.RevisionPresentIn(cdep.Ident, r) - if present { - return nil - } - - return &nonexistentRevisionFailure{ - goal: dependency{ - depender: a.a, - dep: cdep, - }, - r: r, - } -} diff --git a/vendor/github.com/golang/dep/gps/selection.go b/vendor/github.com/golang/dep/gps/selection.go deleted file mode 100644 index a74c60ae8d6500e145397220c8c36277c732ff2a..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/selection.go +++ /dev/null @@ -1,242 +0,0 @@ -// 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 gps - -type selection struct { - // projects is a stack of the atoms that have currently been selected by the - // solver. It can also be thought of as the vertex set of the current - // selection graph. - projects []selected - // deps records the set of dependers on a given ProjectRoot. It is - // essentially an adjacency list of *inbound* edges. - deps map[ProjectRoot][]dependency - // foldRoots records a mapping from a canonical, case-folded form of - // ProjectRoots to the particular case variant that has currently been - // selected. - foldRoots map[string]ProjectRoot - // The versoinUnifier in use for this solve run. - vu *versionUnifier -} - -type selected struct { - a atomWithPackages - first bool -} - -func (s *selection) getDependenciesOn(id ProjectIdentifier) []dependency { - if deps, exists := s.deps[id.ProjectRoot]; exists { - return deps - } - - return nil -} - -// getIdentFor returns the ProjectIdentifier (so, the network name) currently in -// use for the provided ProjectRoot. -// -// If no dependencies are present yet that designate a network name for -// the provided root, this will return an empty ProjectIdentifier and false. -func (s *selection) getIdentFor(pr ProjectRoot) (ProjectIdentifier, bool) { - deps := s.getDependenciesOn(ProjectIdentifier{ProjectRoot: pr}) - if len(deps) == 0 { - return ProjectIdentifier{}, false - } - - // For now, at least, the solver maintains (assumes?) the invariant that - // whatever is first in the deps list decides the net name to be used. - return deps[0].dep.Ident, true -} - -// pushSelection pushes a new atomWithPackages onto the selection stack, along -// with an indicator as to whether this selection indicates a new project *and* -// packages, or merely some new packages on a project that was already selected. -func (s *selection) pushSelection(a atomWithPackages, pkgonly bool) { - s.projects = append(s.projects, selected{ - a: a, - first: !pkgonly, - }) -} - -// popSelection removes and returns the last atomWithPackages from the selection -// stack, along with an indication of whether that element was the first from -// that project - that is, if it represented an addition of both a project and -// one or more packages to the overall selection. -func (s *selection) popSelection() (atomWithPackages, bool) { - var sel selected - sel, s.projects = s.projects[len(s.projects)-1], s.projects[:len(s.projects)-1] - return sel.a, sel.first -} - -// findCaseConflicts checks to see if the given ProjectRoot has a -// case-insensitive overlap with another, different ProjectRoot that's already -// been picked. -func (s *selection) findCaseConflicts(pr ProjectRoot) (bool, ProjectRoot) { - if current, has := s.foldRoots[toFold(string(pr))]; has && pr != current { - return true, current - } - - return false, "" -} - -func (s *selection) pushDep(dep dependency) { - pr := dep.dep.Ident.ProjectRoot - deps := s.deps[pr] - if len(deps) == 0 { - s.foldRoots[toFold(string(pr))] = pr - } - - s.deps[pr] = append(deps, dep) -} - -func (s *selection) popDep(id ProjectIdentifier) (dep dependency) { - deps := s.deps[id.ProjectRoot] - dlen := len(deps) - if dlen == 1 { - delete(s.foldRoots, toFold(string(id.ProjectRoot))) - } - - dep, s.deps[id.ProjectRoot] = deps[dlen-1], deps[:dlen-1] - return dep -} - -func (s *selection) depperCount(id ProjectIdentifier) int { - return len(s.deps[id.ProjectRoot]) -} - -// Compute a list of the unique packages within the given ProjectIdentifier that -// have dependers, and the number of dependers they have. -func (s *selection) getRequiredPackagesIn(id ProjectIdentifier) map[string]int { - // TODO(sdboyer) this is horribly inefficient to do on the fly; we need a method to - // precompute it on pushing a new dep, and preferably with an immut - // structure so that we can pop with zero cost. - uniq := make(map[string]int) - for _, dep := range s.deps[id.ProjectRoot] { - for _, pkg := range dep.dep.pl { - uniq[pkg] = uniq[pkg] + 1 - } - } - - return uniq -} - -// Suppress unused warning. -var _ = (*selection)(nil).getSelectedPackagesIn - -// Compute a list of the unique packages within the given ProjectIdentifier that -// are currently selected, and the number of times each package has been -// independently selected. -func (s *selection) getSelectedPackagesIn(id ProjectIdentifier) map[string]int { - // TODO(sdboyer) this is horribly inefficient to do on the fly; we need a method to - // precompute it on pushing a new dep, and preferably with an immut - // structure so that we can pop with zero cost. - uniq := make(map[string]int) - for _, p := range s.projects { - if p.a.a.id.eq(id) { - for _, pkg := range p.a.pl { - uniq[pkg] = uniq[pkg] + 1 - } - } - } - - return uniq -} - -func (s *selection) getConstraint(id ProjectIdentifier) Constraint { - deps, exists := s.deps[id.ProjectRoot] - if !exists || len(deps) == 0 { - return any - } - - // TODO(sdboyer) recomputing this sucks and is quite wasteful. Precompute/cache it - // on changes to the constraint set, instead. - - // The solver itself is expected to maintain the invariant that all the - // constraints kept here collectively admit a non-empty set of versions. We - // assume this is the case here while assembling a composite constraint. - - // Start with the open set - var ret Constraint = any - for _, dep := range deps { - ret = s.vu.intersect(id, ret, dep.dep.Constraint) - } - - return ret -} - -// selected checks to see if the given ProjectIdentifier has been selected, and -// if so, returns the corresponding atomWithPackages. -// -// It walks the projects selection list from front to back and returns the first -// match it finds, which means it will always and only return the base selection -// of the project, without any additional package selections that may or may not -// have happened later. -func (s *selection) selected(id ProjectIdentifier) (atomWithPackages, bool) { - for _, p := range s.projects { - if p.a.a.id.ProjectRoot == id.ProjectRoot { - return p.a, true - } - } - - return atomWithPackages{a: nilpa}, false -} - -type unselected struct { - sl []bimodalIdentifier - cmp func(i, j int) bool -} - -func (u unselected) Len() int { - return len(u.sl) -} - -func (u unselected) Less(i, j int) bool { - return u.cmp(i, j) -} - -func (u unselected) Swap(i, j int) { - u.sl[i], u.sl[j] = u.sl[j], u.sl[i] -} - -func (u *unselected) Push(x interface{}) { - u.sl = append(u.sl, x.(bimodalIdentifier)) -} - -func (u *unselected) Pop() (v interface{}) { - v, u.sl = u.sl[len(u.sl)-1], u.sl[:len(u.sl)-1] - return v -} - -// remove takes a bimodalIdentifier out of the priority queue, if present. Only -// the first matching bmi will be removed. -// -// There are two events that cause this to be called: bmi selection, when the -// bmi at the front of the queue is removed, and backtracking, when a bmi -// becomes unnecessary because the dependency that induced it was backtracked -// and popped off. -// -// The worst case for both of these is O(n), but in practice the first case is -// O(1), as we iterate the queue from front to back. -func (u *unselected) remove(bmi bimodalIdentifier) { - plen := len(bmi.pl) -outer: - for i, pi := range u.sl { - if pi.id.eq(bmi.id) && len(pi.pl) == plen { - // Simple slice comparison - assume they're both sorted the same - for i2, pkg := range pi.pl { - if bmi.pl[i2] != pkg { - continue outer - } - } - - if i == len(u.sl)-1 { - // if we're on the last element, just pop, no splice - u.sl = u.sl[:len(u.sl)-1] - } else { - u.sl = append(u.sl[:i], u.sl[i+1:]...) - } - break - } - } -} diff --git a/vendor/github.com/golang/dep/gps/solution.go b/vendor/github.com/golang/dep/gps/solution.go deleted file mode 100644 index 7eb419e40b441b18d6497256294774934e0f1fa7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/solution.go +++ /dev/null @@ -1,159 +0,0 @@ -// 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 gps - -import ( - "context" - "fmt" - "log" - "os" - "path/filepath" - "sync" - - "github.com/pkg/errors" - "golang.org/x/sync/errgroup" -) - -// A Solution is returned by a solver run. It is mostly just a Lock, with some -// additional methods that report information about the solve run. -type Solution interface { - Lock - // The name of the ProjectAnalyzer used in generating this solution. - AnalyzerName() string - // The version of the ProjectAnalyzer used in generating this solution. - AnalyzerVersion() int - // The name of the Solver used in generating this solution. - SolverName() string - // The version of the Solver used in generating this solution. - SolverVersion() int - Attempts() int -} - -type solution struct { - // A list of the projects selected by the solver. - p []LockedProject - - // The number of solutions that were attempted - att int - - // The hash digest of the input opts - hd []byte - - // The analyzer info - analyzerInfo ProjectAnalyzerInfo - - // The solver used in producing this solution - solv Solver -} - -const concurrentWriters = 16 - -// WriteDepTree takes a basedir, a Lock and a RootPruneOptions and exports all -// the projects listed in the lock to the appropriate target location within basedir. -// -// If the goal is to populate a vendor directory, basedir should be the absolute -// path to that vendor directory, not its parent (a project root, typically). -// -// It requires a SourceManager to do the work. Prune options are read from the -// passed manifest. -func WriteDepTree(basedir string, l Lock, sm SourceManager, co CascadingPruneOptions, logger *log.Logger) error { - if l == nil { - return fmt.Errorf("must provide non-nil Lock to WriteDepTree") - } - - if err := os.MkdirAll(basedir, 0777); err != nil { - return err - } - - g, ctx := errgroup.WithContext(context.TODO()) - lps := l.Projects() - sem := make(chan struct{}, concurrentWriters) - var cnt struct { - sync.Mutex - i int - } - - for i := range lps { - p := lps[i] // per-iteration copy - - g.Go(func() error { - err := func() error { - select { - case sem <- struct{}{}: - defer func() { <-sem }() - case <-ctx.Done(): - return ctx.Err() - } - - ident := p.Ident() - projectRoot := string(ident.ProjectRoot) - to := filepath.FromSlash(filepath.Join(basedir, projectRoot)) - - if err := sm.ExportProject(ctx, ident, p.Version(), to); err != nil { - return errors.Wrapf(err, "failed to export %s", projectRoot) - } - - err := PruneProject(to, p, co.PruneOptionsFor(ident.ProjectRoot), logger) - if err != nil { - return errors.Wrapf(err, "failed to prune %s", projectRoot) - } - - return ctx.Err() - }() - - switch err { - case context.Canceled, context.DeadlineExceeded: - // Don't log "secondary" errors. - default: - msg := "Wrote" - if err != nil { - msg = "Failed to write" - } - - // Log and increment atomically to prevent re-ordering. - cnt.Lock() - cnt.i++ - logger.Printf("(%d/%d) %s %s@%s\n", cnt.i, len(lps), msg, p.Ident(), p.Version()) - cnt.Unlock() - } - - return err - }) - } - - err := g.Wait() - if err != nil { - os.RemoveAll(basedir) - } - return errors.Wrap(err, "failed to write dep tree") -} - -func (r solution) Projects() []LockedProject { - return r.p -} - -func (r solution) Attempts() int { - return r.att -} - -func (r solution) InputsDigest() []byte { - return r.hd -} - -func (r solution) AnalyzerName() string { - return r.analyzerInfo.Name -} - -func (r solution) AnalyzerVersion() int { - return r.analyzerInfo.Version -} - -func (r solution) SolverName() string { - return r.solv.Name() -} - -func (r solution) SolverVersion() int { - return r.solv.Version() -} diff --git a/vendor/github.com/golang/dep/gps/solve_failures.go b/vendor/github.com/golang/dep/gps/solve_failures.go deleted file mode 100644 index 05daedd707997f2ae80b4ab661c8f4265767a79d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/solve_failures.go +++ /dev/null @@ -1,572 +0,0 @@ -// 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 gps - -import ( - "bytes" - "fmt" - "sort" - "strings" -) - -func a2vs(a atom) string { - if a.v == rootRev || a.v == nil { - return "(root)" - } - - return fmt.Sprintf("%s@%s", a.id, a.v) -} - -type traceError interface { - traceString() string -} - -type noVersionError struct { - pn ProjectIdentifier - fails []failedVersion -} - -func (e *noVersionError) Error() string { - if len(e.fails) == 0 { - return fmt.Sprintf("No versions found for project %q.", e.pn.ProjectRoot) - } - - var buf bytes.Buffer - fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot) - for _, f := range e.fails { - fmt.Fprintf(&buf, "\n\t%s: %s", f.v, f.f.Error()) - } - - return buf.String() -} - -func (e *noVersionError) traceString() string { - if len(e.fails) == 0 { - return fmt.Sprintf("No versions found") - } - - var buf bytes.Buffer - fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot) - for _, f := range e.fails { - if te, ok := f.f.(traceError); ok { - fmt.Fprintf(&buf, "\n %s: %s", f.v, te.traceString()) - } else { - fmt.Fprintf(&buf, "\n %s: %s", f.v, f.f.Error()) - } - } - - return buf.String() -} - -// caseMismatchFailure occurs when there are import paths that differ only by -// case. The compiler disallows this case. -type caseMismatchFailure struct { - // goal is the depender atom that tried to introduce the case-varying name, - // along with the case-varying name. - goal dependency - // current is the specific casing of a ProjectRoot that is presently - // selected for all possible case variations of its contained unicode code - // points. - current ProjectRoot - // failsib is the list of active dependencies that have determined the - // specific casing for the target project. - failsib []dependency -} - -func (e *caseMismatchFailure) Error() string { - if len(e.failsib) == 1 { - str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by depender %s" - return fmt.Sprintf(str, a2vs(e.goal.depender), e.goal.dep.Ident.ProjectRoot, e.current, a2vs(e.failsib[0].depender)) - } - - var buf bytes.Buffer - - str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by the following other dependers:\n" - fmt.Fprintf(&buf, str, a2vs(e.goal.depender), e.goal.dep.Ident.ProjectRoot, e.current) - - for _, c := range e.failsib { - fmt.Fprintf(&buf, "\t%s\n", a2vs(c.depender)) - } - - return buf.String() -} - -func (e *caseMismatchFailure) traceString() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "case-only variation in dependency on %q; %q already established by:\n", e.goal.dep.Ident.ProjectRoot, e.current) - for _, f := range e.failsib { - fmt.Fprintf(&buf, "%s\n", a2vs(f.depender)) - } - - return buf.String() -} - -// wrongCaseFailure occurs when one or more projects - A, B, ... - depend on -// another project - Z - with an incorrect case variant, as indicated by the -// case variant used internally by Z to reference its own packages. -// -// For example, github.com/sirupsen/logrus/hooks/syslog references itself via -// github.com/sirupsen/logrus, establishing that as the canonical case variant. -type wrongCaseFailure struct { - // correct is the canonical representation of the ProjectRoot - correct ProjectRoot - // goal is the incorrectly-referenced target project - goal dependency - // badcase is the list of active dependencies that have specified an - // incorrect ProjectRoot casing for the project in question. - badcase []dependency -} - -func (e *wrongCaseFailure) Error() string { - if len(e.badcase) == 1 { - str := "Could not introduce %s; imports amongst its packages establish %q as the canonical casing for root, but %s tried to import it as %q" - return fmt.Sprintf(str, a2vs(e.goal.depender), e.correct, a2vs(e.badcase[0].depender), e.badcase[0].dep.Ident.ProjectRoot) - } - - var buf bytes.Buffer - - str := "Could not introduce %s; imports amongst its packages establish %q as the canonical casing for root, but the following projects tried to import it as %q" - fmt.Fprintf(&buf, str, a2vs(e.goal.depender), e.correct, e.badcase[0].dep.Ident.ProjectRoot) - - for _, c := range e.badcase { - fmt.Fprintf(&buf, "\t%s\n", a2vs(c.depender)) - } - - return buf.String() -} - -func (e *wrongCaseFailure) traceString() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "internal imports establish %q as correct casing; %q was used by:\n", e.correct, e.goal.dep.Ident.ProjectRoot) - for _, f := range e.badcase { - fmt.Fprintf(&buf, "%s\n", a2vs(f.depender)) - } - - return buf.String() -} - -// disjointConstraintFailure occurs when attempting to introduce an atom that -// itself has an acceptable version, but one of its dependency constraints is -// disjoint with one or more dependency constraints already active for that -// identifier. -type disjointConstraintFailure struct { - // goal is the dependency with the problematic constraint, forcing us to - // reject the atom that introduces it. - goal dependency - // failsib is the list of active dependencies that are disjoint with the - // goal dependency. This will be at least one, but may not be all of the - // active dependencies. - failsib []dependency - // nofailsib is the list of active dependencies that are NOT disjoint with - // the goal dependency. The total of nofailsib and failsib will always be - // the total number of active dependencies on target identifier. - nofailsib []dependency - // c is the current constraint on the target identifier. It is intersection - // of all the active dependencies' constraints. - c Constraint -} - -func (e *disjointConstraintFailure) Error() string { - if len(e.failsib) == 1 { - str := "Could not introduce %s, as it has a dependency on %s with constraint %s, which has no overlap with existing constraint %s from %s" - return fmt.Sprintf(str, a2vs(e.goal.depender), e.goal.dep.Ident, e.goal.dep.Constraint.String(), e.failsib[0].dep.Constraint.String(), a2vs(e.failsib[0].depender)) - } - - var buf bytes.Buffer - - var sibs []dependency - if len(e.failsib) > 1 { - sibs = e.failsib - - str := "Could not introduce %s, as it has a dependency on %s with constraint %s, which has no overlap with the following existing constraints:\n" - fmt.Fprintf(&buf, str, a2vs(e.goal.depender), e.goal.dep.Ident, e.goal.dep.Constraint.String()) - } else { - sibs = e.nofailsib - - str := "Could not introduce %s, as it has a dependency on %s with constraint %s, which does not overlap with the intersection of existing constraints from other currently selected packages:\n" - fmt.Fprintf(&buf, str, a2vs(e.goal.depender), e.goal.dep.Ident, e.goal.dep.Constraint.String()) - } - - for _, c := range sibs { - fmt.Fprintf(&buf, "\t%s from %s\n", c.dep.Constraint.String(), a2vs(c.depender)) - } - - return buf.String() -} - -func (e *disjointConstraintFailure) traceString() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "constraint %s on %s disjoint with other dependers:\n", e.goal.dep.Constraint.String(), e.goal.dep.Ident) - for _, f := range e.failsib { - fmt.Fprintf( - &buf, - "%s from %s (no overlap)\n", - f.dep.Constraint.String(), - a2vs(f.depender), - ) - } - for _, f := range e.nofailsib { - fmt.Fprintf( - &buf, - "%s from %s (some overlap)\n", - f.dep.Constraint.String(), - a2vs(f.depender), - ) - } - - return buf.String() -} - -// Indicates that an atom could not be introduced because one of its dep -// constraints does not admit the currently-selected version of the target -// project. -type constraintNotAllowedFailure struct { - // The dependency with the problematic constraint that could not be - // introduced. - goal dependency - // The (currently selected) version of the target project that was not - // admissible by the goal dependency. - v Version -} - -func (e *constraintNotAllowedFailure) Error() string { - return fmt.Sprintf( - "Could not introduce %s, as it has a dependency on %s with constraint %s, which does not allow the currently selected version of %s", - a2vs(e.goal.depender), - e.goal.dep.Ident, - e.goal.dep.Constraint, - e.v, - ) -} - -func (e *constraintNotAllowedFailure) traceString() string { - return fmt.Sprintf( - "%s depends on %s with %s, but that's already selected at %s", - a2vs(e.goal.depender), - e.goal.dep.Ident.ProjectRoot, - e.goal.dep.Constraint, - e.v, - ) -} - -// versionNotAllowedFailure describes a failure where an atom is rejected -// because its version is not allowed by current constraints. -// -// (This is one of the more straightforward types of failures) -type versionNotAllowedFailure struct { - // goal is the atom that was rejected by current constraints. - goal atom - // failparent is the list of active dependencies that caused the atom to be - // rejected. Note that this only includes dependencies that actually - // rejected the atom, which will be at least one, but may not be all the - // active dependencies on the atom's identifier. - failparent []dependency - // c is the current constraint on the atom's identifier. This is the intersection - // of all active dependencies' constraints. - c Constraint -} - -func (e *versionNotAllowedFailure) Error() string { - if len(e.failparent) == 1 { - return fmt.Sprintf( - "Could not introduce %s, as it is not allowed by constraint %s from project %s.", - a2vs(e.goal), - e.failparent[0].dep.Constraint.String(), - e.failparent[0].depender.id, - ) - } - - var buf bytes.Buffer - - fmt.Fprintf(&buf, "Could not introduce %s, as it is not allowed by constraints from the following projects:\n", a2vs(e.goal)) - - for _, f := range e.failparent { - fmt.Fprintf(&buf, "\t%s from %s\n", f.dep.Constraint.String(), a2vs(f.depender)) - } - - return buf.String() -} - -func (e *versionNotAllowedFailure) traceString() string { - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%s not allowed by constraint %s:\n", a2vs(e.goal), e.c.String()) - for _, f := range e.failparent { - fmt.Fprintf(&buf, " %s from %s\n", f.dep.Constraint.String(), a2vs(f.depender)) - } - - return buf.String() -} - -type missingSourceFailure struct { - goal ProjectIdentifier - prob string -} - -func (e *missingSourceFailure) Error() string { - return fmt.Sprintf(e.prob, e.goal) -} - -type badOptsFailure string - -func (e badOptsFailure) Error() string { - return string(e) -} - -type sourceMismatchFailure struct { - // The ProjectRoot over which there is disagreement about where it should be - // sourced from - shared ProjectRoot - // The current value for the network source - current string - // The mismatched value for the network source - mismatch string - // The currently selected dependencies which have agreed upon/established - // the given network source - sel []dependency - // The atom with the constraint that has the new, incompatible network source - prob atom -} - -func (e *sourceMismatchFailure) Error() string { - var cur []string - for _, c := range e.sel { - cur = append(cur, string(c.depender.id.ProjectRoot)) - } - - str := "Could not introduce %s, as it depends on %s from %s, but %s is already marked as coming from %s by %s" - return fmt.Sprintf(str, a2vs(e.prob), e.shared, e.mismatch, e.shared, e.current, strings.Join(cur, ", ")) -} - -func (e *sourceMismatchFailure) traceString() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "disagreement on network addr for %s:\n", e.shared) - - fmt.Fprintf(&buf, " %s from %s\n", e.mismatch, e.prob.id) - for _, dep := range e.sel { - fmt.Fprintf(&buf, " %s from %s\n", e.current, dep.depender.id) - } - - return buf.String() -} - -type errDeppers struct { - err error - deppers []atom -} - -// checkeeHasProblemPackagesFailure indicates that the goal atom was rejected -// because one or more of the packages required by its deppers had errors. -// -// "errors" includes package nonexistence, which is indicated by a nil err in -// the corresponding errDeppers failpkg map value. -// -// checkeeHasProblemPackagesFailure complements depHasProblemPackagesFailure; -// one or the other could appear to describe the same fundamental issue, -// depending on the order in which dependencies were visited. -type checkeeHasProblemPackagesFailure struct { - // goal is the atom that was rejected due to problematic packages. - goal atom - // failpkg is a map of package names to the error describing the problem - // with them, plus a list of the selected atoms that require that package. - failpkg map[string]errDeppers -} - -func (e *checkeeHasProblemPackagesFailure) Error() string { - var buf bytes.Buffer - indent := "" - - if len(e.failpkg) > 1 { - indent = "\t" - fmt.Fprintf( - &buf, "Could not introduce %s due to multiple problematic subpackages:\n", - a2vs(e.goal), - ) - } - - for pkg, errdep := range e.failpkg { - var cause string - if errdep.err == nil { - cause = "is missing" - } else { - cause = fmt.Sprintf("does not contain usable Go code (%T).", errdep.err) - } - - if len(e.failpkg) == 1 { - fmt.Fprintf( - &buf, "Could not introduce %s, as its subpackage %s %s.", - a2vs(e.goal), - pkg, - cause, - ) - } else { - fmt.Fprintf(&buf, "\tSubpackage %s %s.", pkg, cause) - } - - if len(errdep.deppers) == 1 { - fmt.Fprintf( - &buf, " (Package is required by %s.)", - a2vs(errdep.deppers[0]), - ) - } else { - fmt.Fprintf(&buf, " Package is required by:") - for _, pa := range errdep.deppers { - fmt.Fprintf(&buf, "\n%s\t%s", indent, a2vs(pa)) - } - } - } - - return buf.String() -} - -func (e *checkeeHasProblemPackagesFailure) traceString() string { - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%s at %s has problem subpkg(s):\n", e.goal.id.ProjectRoot, e.goal.v) - for pkg, errdep := range e.failpkg { - if errdep.err == nil { - fmt.Fprintf(&buf, "\t%s is missing; ", pkg) - } else { - fmt.Fprintf(&buf, "\t%s has err (%T); ", pkg, errdep.err) - } - - if len(errdep.deppers) == 1 { - fmt.Fprintf(&buf, "required by %s.", a2vs(errdep.deppers[0])) - } else { - fmt.Fprintf(&buf, " required by:") - for _, pa := range errdep.deppers { - fmt.Fprintf(&buf, "\n\t\t%s at %s", pa.id, pa.v) - } - } - } - - return buf.String() -} - -// depHasProblemPackagesFailure indicates that the goal dependency was rejected -// because there were problems with one or more of the packages the dependency -// requires in the atom currently selected for that dependency. (This failure -// can only occur if the target dependency is already selected.) -// -// "errors" includes package nonexistence, which is indicated by a nil err as -// the corresponding prob map value. -// -// depHasProblemPackagesFailure complements checkeeHasProblemPackagesFailure; -// one or the other could appear to describe the same fundamental issue, -// depending on the order in which dependencies were visited. -type depHasProblemPackagesFailure struct { - // goal is the dependency that was rejected due to the atom currently - // selected for the dependency's target id having errors (including, and - // probably most commonly, - // nonexistence) in one or more packages named by the dependency. - goal dependency - // v is the version of the currently selected atom targeted by the goal - // dependency. - v Version - // prob is a map of problem packages to their specific error. It does not - // include missing packages. - prob map[string]error -} - -func (e *depHasProblemPackagesFailure) Error() string { - fcause := func(pkg string) string { - if err := e.prob[pkg]; err != nil { - return fmt.Sprintf("does not contain usable Go code (%T).", err) - } - return "is missing." - } - - if len(e.prob) == 1 { - var pkg string - for pkg = range e.prob { - } - - return fmt.Sprintf( - "Could not introduce %s, as it requires package %s from %s, but in version %s that package %s", - a2vs(e.goal.depender), - pkg, - e.goal.dep.Ident, - e.v, - fcause(pkg), - ) - } - - var buf bytes.Buffer - fmt.Fprintf( - &buf, "Could not introduce %s, as it requires problematic packages from %s (current version %s):", - a2vs(e.goal.depender), - e.goal.dep.Ident, - e.v, - ) - - pkgs := make([]string, len(e.prob)) - k := 0 - for pkg := range e.prob { - pkgs[k] = pkg - k++ - } - sort.Strings(pkgs) - for _, pkg := range pkgs { - fmt.Fprintf(&buf, "\t%s %s", pkg, fcause(pkg)) - } - - return buf.String() -} - -func (e *depHasProblemPackagesFailure) traceString() string { - var buf bytes.Buffer - fcause := func(pkg string) string { - if err := e.prob[pkg]; err != nil { - return fmt.Sprintf("has parsing err (%T).", err) - } - return "is missing" - } - - fmt.Fprintf( - &buf, "%s depping on %s at %s has problem subpkg(s):", - a2vs(e.goal.depender), - e.goal.dep.Ident, - e.v, - ) - - pkgs := make([]string, len(e.prob)) - k := 0 - for pkg := range e.prob { - pkgs[k] = pkg - k++ - } - sort.Strings(pkgs) - for _, pkg := range pkgs { - fmt.Fprintf(&buf, "\t%s %s", pkg, fcause(pkg)) - } - - return buf.String() -} - -// nonexistentRevisionFailure indicates that a revision constraint was specified -// for a given project, but that that revision does not exist in the source -// repository. -type nonexistentRevisionFailure struct { - goal dependency - r Revision -} - -func (e *nonexistentRevisionFailure) Error() string { - return fmt.Sprintf( - "Could not introduce %s, as it requires %s at revision %s, but that revision does not exist", - a2vs(e.goal.depender), - e.goal.dep.Ident, - e.r, - ) -} - -func (e *nonexistentRevisionFailure) traceString() string { - return fmt.Sprintf( - "%s wants missing rev %s of %s", - a2vs(e.goal.depender), - e.r, - e.goal.dep.Ident, - ) -} diff --git a/vendor/github.com/golang/dep/gps/solver.go b/vendor/github.com/golang/dep/gps/solver.go deleted file mode 100644 index bede9d53b4bcf349f984c7d2b91245375df63454..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/solver.go +++ /dev/null @@ -1,1421 +0,0 @@ -// 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 gps - -import ( - "container/heap" - "context" - "fmt" - "log" - "sort" - "strings" - "sync" - "sync/atomic" - - "github.com/armon/go-radix" - "github.com/golang/dep/gps/paths" - "github.com/golang/dep/gps/pkgtree" - "github.com/pkg/errors" -) - -var rootRev = Revision("") - -// SolveParameters hold all arguments to a solver run. -// -// Only RootDir and RootPackageTree are absolutely required. A nil Manifest is -// allowed, though it usually makes little sense. -// -// Of these properties, only the Manifest and RootPackageTree are (directly) -// incorporated in memoization hashing. -type SolveParameters struct { - // The path to the root of the project on which the solver should operate. - // This should point to the directory that should contain the vendor/ - // directory. - // - // In general, it is wise for this to be under an active GOPATH, though it - // is not (currently) required. - // - // A real path to a readable directory is required. - RootDir string - - // The ProjectAnalyzer is responsible for extracting Manifest and - // (optionally) Lock information from dependencies. The solver passes it - // along to its SourceManager's GetManifestAndLock() method as needed. - // - // An analyzer is required. - ProjectAnalyzer ProjectAnalyzer - - // The tree of packages that comprise the root project, as well as the - // import path that should identify the root of that tree. - // - // In most situations, tools should simply pass the result of ListPackages() - // directly through here. - // - // The ImportRoot property must be a non-empty string, and at least one - // element must be present in the Packages map. - RootPackageTree pkgtree.PackageTree - - // The root manifest. This contains all the dependency constraints - // associated with normal Manifests, as well as the particular controls - // afforded only to the root project. - // - // May be nil, but for most cases, that would be unwise. - Manifest RootManifest - - // The root lock. Optional. Generally, this lock is the output of a previous - // solve run. - // - // If provided, the solver will attempt to preserve the versions specified - // in the lock, unless ToChange or ChangeAll settings indicate otherwise. - Lock Lock - - // ToChange is a list of project names that should be changed - that is, any - // versions specified for those projects in the root lock file should be - // ignored. - // - // Passing ChangeAll has subtly different behavior from enumerating all - // projects into ToChange. In general, ToChange should *only* be used if the - // user expressly requested an upgrade for a specific project. - ToChange []ProjectRoot - - // ChangeAll indicates that all projects should be changed - that is, any - // versions specified in the root lock file should be ignored. - ChangeAll bool - - // Downgrade indicates whether the solver will attempt to upgrade (false) or - // downgrade (true) projects that are not locked, or are marked for change. - // - // Upgrading is, by far, the most typical case. The field is named - // 'Downgrade' so that the bool's zero value corresponds to that most - // typical case. - Downgrade bool - - // TraceLogger is the logger to use for generating trace output. If set, the - // solver will generate informative trace output as it moves through the - // solving process. - TraceLogger *log.Logger - - // stdLibFn is the function to use to recognize standard library import paths. - // Only overridden for tests. Defaults to paths.IsStandardImportPath if nil. - stdLibFn func(string) bool - - // mkBridgeFn is the function to use to create sourceBridges. - // Only overridden for tests (so we can run with virtual RootDir). - // Defaults to mkBridge if nil. - mkBridgeFn func(*solver, SourceManager, bool) sourceBridge -} - -// solver is a CDCL-style constraint solver with satisfiability conditions -// hardcoded to the needs of the Go package management problem space. -type solver struct { - // The current number of attempts made over the course of this solve. This - // number increments each time the algorithm completes a backtrack and - // starts moving forward again. - attempts int - - // Logger used exclusively for trace output, or nil to suppress. - tl *log.Logger - - // The function to use to recognize standard library import paths. - stdLibFn func(string) bool - - // A bridge to the standard SourceManager. The adapter does some local - // caching of pre-sorted version lists, as well as translation between the - // full-on ProjectIdentifiers that the solver deals with and the simplified - // names a SourceManager operates on. - b sourceBridge - - // A versionUnifier, to facilitate cross-type version comparison and set - // operations. - vUnify *versionUnifier - - // A stack containing projects and packages that are currently "selected" - - // that is, they have passed all satisfiability checks, and are part of the - // current solution. - // - // The *selection type is mostly just a dumb data container; the solver - // itself is responsible for maintaining that invariant. - sel *selection - - // The current list of projects that we need to incorporate into the solution in - // order for the solution to be complete. This list is implemented as a - // priority queue that places projects least likely to induce errors at the - // front, in order to minimize the amount of backtracking required to find a - // solution. - // - // Entries are added to and removed from this list by the solver at the same - // time that the selected queue is updated, either with an addition or - // removal. - unsel *unselected - - // A stack of all the currently active versionQueues in the solver. The set - // of projects represented here corresponds closely to what's in s.sel, - // although s.sel will always contain the root project, and s.vqs never - // will. Also, s.vqs is only added to (or popped from during backtracking) - // when a new project is selected; it is untouched when new packages are - // added to an existing project. - vqs []*versionQueue - - // Contains data and constraining information from the root project - rd rootdata - - // metrics for the current solve run. - mtr *metrics - - // Indicates whether the solver has been run. It is invalid to run this type - // of solver more than once. - hasrun int32 -} - -func (params SolveParameters) toRootdata() (rootdata, error) { - if params.ProjectAnalyzer == nil { - return rootdata{}, badOptsFailure("must provide a ProjectAnalyzer") - } - if params.RootDir == "" { - return rootdata{}, badOptsFailure("params must specify a non-empty root directory") - } - if params.RootPackageTree.ImportRoot == "" { - return rootdata{}, badOptsFailure("params must include a non-empty import root") - } - if len(params.RootPackageTree.Packages) == 0 { - return rootdata{}, badOptsFailure("at least one package must be present in the PackageTree") - } - if params.Lock == nil && len(params.ToChange) != 0 { - return rootdata{}, badOptsFailure(fmt.Sprintf("update specifically requested for %s, but no lock was provided to upgrade from", params.ToChange)) - } - - if params.Manifest == nil { - params.Manifest = simpleRootManifest{} - } - - rd := rootdata{ - ir: params.Manifest.IgnoredPackages(), - req: params.Manifest.RequiredPackages(), - ovr: params.Manifest.Overrides(), - rpt: params.RootPackageTree.Copy(), - chng: make(map[ProjectRoot]struct{}), - rlm: make(map[ProjectRoot]LockedProject), - chngall: params.ChangeAll, - dir: params.RootDir, - an: params.ProjectAnalyzer, - } - - // Ensure the required and overrides maps are at least initialized - if rd.req == nil { - rd.req = make(map[string]bool) - } - if rd.ovr == nil { - rd.ovr = make(ProjectConstraints) - } - - if rd.ir.Len() > 0 { - var both []string - for pkg := range params.Manifest.RequiredPackages() { - if rd.ir.IsIgnored(pkg) { - both = append(both, pkg) - } - } - switch len(both) { - case 0: - break - case 1: - return rootdata{}, badOptsFailure(fmt.Sprintf("%q was given as both a required and ignored package", both[0])) - default: - return rootdata{}, badOptsFailure(fmt.Sprintf("multiple packages given as both required and ignored: %s", strings.Join(both, ", "))) - } - } - - // Validate no empties in the overrides map - var eovr []string - for pr, pp := range rd.ovr { - if pp.Constraint == nil && pp.Source == "" { - eovr = append(eovr, string(pr)) - } - } - - if eovr != nil { - // Maybe it's a little nitpicky to do this (we COULD proceed; empty - // overrides have no effect), but this errs on the side of letting the - // tool/user know there's bad input. Purely as a principle, that seems - // preferable to silently allowing progress with icky input. - if len(eovr) > 1 { - return rootdata{}, badOptsFailure(fmt.Sprintf("Overrides lacked any non-zero properties for multiple project roots: %s", strings.Join(eovr, " "))) - } - return rootdata{}, badOptsFailure(fmt.Sprintf("An override was declared for %s, but without any non-zero properties", eovr[0])) - } - - // Prep safe, normalized versions of root manifest and lock data - rd.rm = prepManifest(params.Manifest) - - if params.Lock != nil { - for _, lp := range params.Lock.Projects() { - rd.rlm[lp.Ident().ProjectRoot] = lp - } - - // Also keep a prepped one, mostly for the bridge. This is probably - // wasteful, but only minimally so, and yay symmetry - rd.rl = prepLock(params.Lock) - } - - for _, p := range params.ToChange { - if _, exists := rd.rlm[p]; !exists { - return rootdata{}, badOptsFailure(fmt.Sprintf("cannot update %s as it is not in the lock", p)) - } - rd.chng[p] = struct{}{} - } - - return rd, nil -} - -// Prepare readies a Solver for use. -// -// This function reads and validates the provided SolveParameters. If a problem -// with the inputs is detected, an error is returned. Otherwise, a Solver is -// returned, ready to hash and check inputs or perform a solving run. -func Prepare(params SolveParameters, sm SourceManager) (Solver, error) { - if sm == nil { - return nil, badOptsFailure("must provide non-nil SourceManager") - } - - rd, err := params.toRootdata() - if err != nil { - return nil, err - } - - if params.stdLibFn == nil { - params.stdLibFn = paths.IsStandardImportPath - } - - s := &solver{ - tl: params.TraceLogger, - stdLibFn: params.stdLibFn, - rd: rd, - } - - // Set up the bridge and ensure the root dir is in good, working order - // before doing anything else. - if params.mkBridgeFn == nil { - s.b = mkBridge(s, sm, params.Downgrade) - } else { - s.b = params.mkBridgeFn(s, sm, params.Downgrade) - } - err = s.b.verifyRootDir(params.RootDir) - if err != nil { - return nil, err - } - s.vUnify = &versionUnifier{ - b: s.b, - } - - // Initialize stacks and queues - s.sel = &selection{ - deps: make(map[ProjectRoot][]dependency), - foldRoots: make(map[string]ProjectRoot), - vu: s.vUnify, - } - s.unsel = &unselected{ - sl: make([]bimodalIdentifier, 0), - cmp: s.unselectedComparator, - } - - return s, nil -} - -// A Solver is the main workhorse of gps: given a set of project inputs, it -// performs a constraint solving analysis to develop a complete Solution, or -// else fail with an informative error. -// -// If a Solution is found, an implementing tool may persist it - typically into -// a "lock file" - and/or use it to write out a directory tree of dependencies, -// suitable to be a vendor directory, via CreateVendorTree. -type Solver interface { - // HashInputs hashes the unique inputs to this solver, returning the hash - // digest. It is guaranteed that, if the resulting digest is equal to the - // digest returned from a previous Solution.InputHash(), that that Solution - // is valid for this Solver's inputs. - // - // In such a case, it may not be necessary to run Solve() at all. - HashInputs() []byte - - // Solve initiates a solving run. It will either abort due to a canceled - // Context, complete successfully with a Solution, or fail with an - // informative error. - // - // It is generally not allowed that this method be called twice for any - // given solver. - Solve(context.Context) (Solution, error) - - // Name returns a string identifying the particular solver backend. - // - // Different solvers likely have different invariants, and likely will not - // have the same result sets for any particular inputs. - Name() string - - // Version returns an int indicating the version of the solver of the given - // Name(). Implementations should change their reported version ONLY when - // the logic is changed in such a way that substantially changes the result - // set that is possible for a substantial subset of likely inputs. - // - // "Substantial" is an imprecise term, and it is used intentionally. There - // are no easy, general ways of subdividing constraint solving problems such - // that one can know, a priori, the full impact that subtle algorithmic - // changes will have on possible result sets. Consequently, we have to fall - // back on coarser, intuition-based reasoning as to whether a change is - // large enough that it is likely to be broadly user-visible. - // - // This is acceptable, because this value is not used programmatically by - // the solver in any way. Rather, it is intend for implementing tools to - // use as a coarse signal to users about compatibility between their tool's - // version and the current data, typically via persistence to a Lock. - // Changes to the version number reported should be weighed between - // confusing teams by having two members' tools continuously rolling back - // each others' chosen Solutions for no apparent reason, and annoying teams - // by changing the number for changes so remote that warnings about solver - // version mismatches become meaningless. - // - // Err on the side of caution. - // - // Chronology is the only implication of the ordering - that lower version - // numbers were published before higher numbers. - Version() int -} - -func (s *solver) Name() string { - return "gps-cdcl" -} - -func (s *solver) Version() int { - return 1 -} - -// DeductionErrs maps package import path to errors occurring during deduction. -type DeductionErrs map[string]error - -func (e DeductionErrs) Error() string { - return "could not deduce external imports' project roots" -} - -// ValidateParams validates the solver parameters to ensure solving can be completed. -func ValidateParams(params SolveParameters, sm SourceManager) error { - // Ensure that all packages are deducible without issues. - var deducePkgsGroup sync.WaitGroup - deductionErrs := make(DeductionErrs) - var errsMut sync.Mutex - - rd, err := params.toRootdata() - if err != nil { - return err - } - - deducePkg := func(ip string, sm SourceManager) { - _, err := sm.DeduceProjectRoot(ip) - if err != nil { - errsMut.Lock() - deductionErrs[ip] = err - errsMut.Unlock() - } - deducePkgsGroup.Done() - } - - for _, ip := range rd.externalImportList(paths.IsStandardImportPath) { - deducePkgsGroup.Add(1) - go deducePkg(ip, sm) - } - - deducePkgsGroup.Wait() - - if len(deductionErrs) > 0 { - return deductionErrs - } - - return nil -} - -// Solve attempts to find a dependency solution for the given project, as -// represented by the SolveParameters with which this Solver was created. -// -// This is the entry point to the main gps workhorse. -func (s *solver) Solve(ctx context.Context) (Solution, error) { - // Solving can only be run once per solver. - if !atomic.CompareAndSwapInt32(&s.hasrun, 0, 1) { - return nil, errors.New("solve method can only be run once per instance") - } - // Make sure the bridge has the context before we start. - //s.b.ctx = ctx - - // Set up a metrics object - s.mtr = newMetrics() - s.vUnify.mtr = s.mtr - - // Prime the queues with the root project - if err := s.selectRoot(); err != nil { - return nil, err - } - - all, err := s.solve(ctx) - - s.mtr.pop() - var soln solution - if err == nil { - soln = solution{ - att: s.attempts, - solv: s, - } - soln.analyzerInfo = s.rd.an.Info() - soln.hd = s.HashInputs() - - // Convert ProjectAtoms into LockedProjects - soln.p = make([]LockedProject, len(all)) - k := 0 - for pa, pl := range all { - soln.p[k] = pa2lp(pa, pl) - k++ - } - } - - s.traceFinish(soln, err) - if s.tl != nil { - s.mtr.dump(s.tl) - } - return soln, err -} - -// solve is the top-level loop for the solving process. -func (s *solver) solve(ctx context.Context) (map[atom]map[string]struct{}, error) { - // Pull out the donechan once up front so that we're not potentially - // triggering mutex cycling and channel creation on each iteration. - donechan := ctx.Done() - - // Main solving loop - for { - select { - case <-donechan: - return nil, ctx.Err() - default: - } - - bmi, has := s.nextUnselected() - - if !has { - // no more packages to select - we're done. - break - } - - // This split is the heart of "bimodal solving": we follow different - // satisfiability and selection paths depending on whether we've already - // selected the base project/repo that came off the unselected queue. - // - // (If we've already selected the project, other parts of the algorithm - // guarantee the bmi will contain at least one package from this project - // that has yet to be selected.) - if awp, is := s.sel.selected(bmi.id); !is { - s.mtr.push("new-atom") - // Analysis path for when we haven't selected the project yet - need - // to create a version queue. - queue, err := s.createVersionQueue(bmi) - if err != nil { - s.mtr.pop() - // Err means a failure somewhere down the line; try backtracking. - s.traceStartBacktrack(bmi, err, false) - success, berr := s.backtrack(ctx) - if berr != nil { - err = berr - } else if success { - // backtracking succeeded, move to the next unselected id - continue - } - return nil, err - } - - if queue.current() == nil { - panic("canary - queue is empty, but flow indicates success") - } - - awp := atomWithPackages{ - a: atom{ - id: queue.id, - v: queue.current(), - }, - pl: bmi.pl, - } - err = s.selectAtom(awp, false) - s.mtr.pop() - if err != nil { - // Only a released SourceManager should be able to cause this. - return nil, err - } - - s.vqs = append(s.vqs, queue) - } else { - s.mtr.push("add-atom") - // We're just trying to add packages to an already-selected project. - // That means it's not OK to burn through the version queue for that - // project as we do when first selecting a project, as doing so - // would upend the guarantees on which all previous selections of - // the project are based (both the initial one, and any package-only - // ones). - - // Because we can only safely operate within the scope of the - // single, currently selected version, we can skip looking for the - // queue and just use the version given in what came back from - // s.sel.selected(). - nawp := atomWithPackages{ - a: atom{ - id: bmi.id, - v: awp.a.v, - }, - pl: bmi.pl, - } - - s.traceCheckPkgs(bmi) - err := s.check(nawp, true) - if err != nil { - s.mtr.pop() - // Err means a failure somewhere down the line; try backtracking. - s.traceStartBacktrack(bmi, err, true) - success, berr := s.backtrack(ctx) - if berr != nil { - err = berr - } else if success { - // backtracking succeeded, move to the next unselected id - continue - } - return nil, err - } - err = s.selectAtom(nawp, true) - s.mtr.pop() - if err != nil { - // Only a released SourceManager should be able to cause this. - return nil, err - } - - // We don't add anything to the stack of version queues because the - // backtracker knows not to pop the vqstack if it backtracks - // across a pure-package addition. - } - } - - // Getting this far means we successfully found a solution. Combine the - // selected projects and packages. - projs := make(map[atom]map[string]struct{}) - - // Skip the first project. It's always the root, and that shouldn't be - // included in results. - for _, sel := range s.sel.projects[1:] { - pm, exists := projs[sel.a.a] - if !exists { - pm = make(map[string]struct{}) - projs[sel.a.a] = pm - } - - for _, path := range sel.a.pl { - pm[path] = struct{}{} - } - } - return projs, nil -} - -// selectRoot is a specialized selectAtom, used solely to initially -// populate the queues at the beginning of a solve run. -func (s *solver) selectRoot() error { - s.mtr.push("select-root") - // Push the root project onto the queue. - awp := s.rd.rootAtom() - s.sel.pushSelection(awp, false) - - // If we're looking for root's deps, get it from opts and local root - // analysis, rather than having the sm do it. - deps, err := s.intersectConstraintsWithImports(s.rd.combineConstraints(), s.rd.externalImportList(s.stdLibFn)) - if err != nil { - if contextCanceledOrSMReleased(err) { - return err - } - // TODO(sdboyer) this could well happen; handle it with a more graceful error - panic(fmt.Sprintf("canary - shouldn't be possible %s", err)) - } - - for _, dep := range deps { - // If we have no lock, or if this dep isn't in the lock, then prefetch - // it. See longer explanation in selectAtom() for how we benefit from - // parallelism here. - if s.rd.needVersionsFor(dep.Ident.ProjectRoot) { - go s.b.SyncSourceFor(dep.Ident) - } - - s.sel.pushDep(dependency{depender: awp.a, dep: dep}) - // Add all to unselected queue - heap.Push(s.unsel, bimodalIdentifier{id: dep.Ident, pl: dep.pl, fromRoot: true}) - } - - s.traceSelectRoot(s.rd.rpt, deps) - s.mtr.pop() - return nil -} - -func (s *solver) getImportsAndConstraintsOf(a atomWithPackages) ([]string, []completeDep, error) { - var err error - - if s.rd.isRoot(a.a.id.ProjectRoot) { - panic("Should never need to recheck imports/constraints from root during solve") - } - - // Work through the source manager to get project info and static analysis - // information. - m, _, err := s.b.GetManifestAndLock(a.a.id, a.a.v, s.rd.an) - if err != nil { - return nil, nil, err - } - - ptree, err := s.b.ListPackages(a.a.id, a.a.v) - if err != nil { - return nil, nil, err - } - - rm, em := ptree.ToReachMap(true, false, true, s.rd.ir) - // Use maps to dedupe the unique internal and external packages. - exmap, inmap := make(map[string]struct{}), make(map[string]struct{}) - - for _, pkg := range a.pl { - inmap[pkg] = struct{}{} - for _, ipkg := range rm[pkg].Internal { - inmap[ipkg] = struct{}{} - } - } - - var pl []string - // If lens are the same, then the map must have the same contents as the - // slice; no need to build a new one. - if len(inmap) == len(a.pl) { - pl = a.pl - } else { - pl = make([]string, 0, len(inmap)) - for pkg := range inmap { - pl = append(pl, pkg) - } - sort.Strings(pl) - } - - // Add to the list those packages that are reached by the packages - // explicitly listed in the atom - for _, pkg := range a.pl { - // Skip ignored packages - if s.rd.ir.IsIgnored(pkg) { - continue - } - - ie, exists := rm[pkg] - if !exists { - // Missing package here *should* only happen if the target pkg was - // poisoned; check the errors map. - if importErr, eexists := em[pkg]; eexists { - return nil, nil, importErr - } - - // Nope, it's actually full-on not there. - return nil, nil, fmt.Errorf("package %s does not exist within project %s", pkg, a.a.id) - } - - for _, ex := range ie.External { - exmap[ex] = struct{}{} - } - } - - reach := make([]string, 0, len(exmap)) - for pkg := range exmap { - reach = append(reach, pkg) - } - sort.Strings(reach) - - deps := s.rd.ovr.overrideAll(m.DependencyConstraints()) - cd, err := s.intersectConstraintsWithImports(deps, reach) - return pl, cd, err -} - -// intersectConstraintsWithImports takes a list of constraints and a list of -// externally reached packages, and creates a []completeDep that is guaranteed -// to include all packages named by import reach, using constraints where they -// are available, or Any() where they are not. -func (s *solver) intersectConstraintsWithImports(deps []workingConstraint, reach []string) ([]completeDep, error) { - // Create a radix tree with all the projects we know from the manifest - xt := radix.New() - for _, dep := range deps { - xt.Insert(string(dep.Ident.ProjectRoot), dep) - } - - // Step through the reached packages; if they have prefix matches in - // the trie, assume (mostly) it's a correct correspondence. - dmap := make(map[ProjectRoot]completeDep) - for _, rp := range reach { - // If it's a stdlib-shaped package, skip it. - if s.stdLibFn(rp) { - continue - } - - // Look for a prefix match; it'll be the root project/repo containing - // the reached package - if pre, idep, match := xt.LongestPrefix(rp); match && isPathPrefixOrEqual(pre, rp) { - // Match is valid; put it in the dmap, either creating a new - // completeDep or appending it to the existing one for this base - // project/prefix. - dep := idep.(workingConstraint) - if cdep, exists := dmap[dep.Ident.ProjectRoot]; exists { - cdep.pl = append(cdep.pl, rp) - dmap[dep.Ident.ProjectRoot] = cdep - } else { - dmap[dep.Ident.ProjectRoot] = completeDep{ - workingConstraint: dep, - pl: []string{rp}, - } - } - continue - } - - // No match. Let the SourceManager try to figure out the root - root, err := s.b.DeduceProjectRoot(rp) - if err != nil { - // Nothing we can do if we can't suss out a root - return nil, err - } - - // Make a new completeDep with an open constraint, respecting overrides - pd := s.rd.ovr.override(root, ProjectProperties{Constraint: Any()}) - - // Insert the pd into the trie so that further deps from this - // project get caught by the prefix search - xt.Insert(string(root), pd) - // And also put the complete dep into the dmap - dmap[root] = completeDep{ - workingConstraint: pd, - pl: []string{rp}, - } - } - - // Dump all the deps from the map into the expected return slice - cdeps := make([]completeDep, 0, len(dmap)) - for _, cdep := range dmap { - cdeps = append(cdeps, cdep) - } - - return cdeps, nil -} - -func (s *solver) createVersionQueue(bmi bimodalIdentifier) (*versionQueue, error) { - id := bmi.id - // If on the root package, there's no queue to make - if s.rd.isRoot(id.ProjectRoot) { - return newVersionQueue(id, nil, nil, s.b) - } - - exists, err := s.b.SourceExists(id) - if err != nil { - return nil, err - } - if !exists { - exists, err = s.b.vendorCodeExists(id) - if err != nil { - return nil, err - } - if exists { - // Project exists only in vendor - // FIXME(sdboyer) this just totally doesn't work at all right now - } else { - return nil, fmt.Errorf("project '%s' could not be located", id) - } - } - - var lockv Version - if len(s.rd.rlm) > 0 { - lockv, err = s.getLockVersionIfValid(id) - if err != nil { - // Can only get an error here if an upgrade was expressly requested on - // code that exists only in vendor - return nil, err - } - } - - var prefv Version - if bmi.fromRoot { - // If this bmi came from the root, then we want to search through things - // with a dependency on it in order to see if any have a lock that might - // express a prefv - // - // TODO(sdboyer) nested loop; prime candidate for a cache somewhere - for _, dep := range s.sel.getDependenciesOn(bmi.id) { - // Skip the root, of course - if s.rd.isRoot(dep.depender.id.ProjectRoot) { - continue - } - - _, l, err := s.b.GetManifestAndLock(dep.depender.id, dep.depender.v, s.rd.an) - if err != nil || l == nil { - // err being non-nil really shouldn't be possible, but the lock - // being nil is quite likely - continue - } - - for _, lp := range l.Projects() { - if lp.Ident().eq(bmi.id) { - prefv = lp.Version() - } - } - } - - // OTHER APPROACH - WRONG, BUT MAYBE USEFUL FOR REFERENCE? - // If this bmi came from the root, then we want to search the unselected - // queue to see if anything *else* wants this ident, in which case we - // pick up that prefv - //for _, bmi2 := range s.unsel.sl { - //// Take the first thing from the queue that's for the same ident, - //// and has a non-nil prefv - //if bmi.id.eq(bmi2.id) { - //if bmi2.prefv != nil { - //prefv = bmi2.prefv - //} - //} - //} - - } else { - // Otherwise, just use the preferred version expressed in the bmi - prefv = bmi.prefv - } - - q, err := newVersionQueue(id, lockv, prefv, s.b) - if err != nil { - // TODO(sdboyer) this particular err case needs to be improved to be ONLY for cases - // where there's absolutely nothing findable about a given project name - return nil, err - } - - // Hack in support for revisions. - // - // By design, revs aren't returned from ListVersion(). Thus, if the dep in - // the bmi was has a rev constraint, it is (almost) guaranteed to fail, even - // if that rev does exist in the repo. So, detect a rev and push it into the - // vq here, instead. - // - // Happily, the solver maintains the invariant that constraints on a given - // ident cannot be incompatible, so we know that if we find one rev, then - // any other deps will have to also be on that rev (or Any). - // - // TODO(sdboyer) while this does work, it bypasses the interface-implied guarantees - // of the version queue, and is therefore not a great strategy for API - // coherency. Folding this in to a formal interface would be better. - if tc, ok := s.sel.getConstraint(bmi.id).(Revision); ok && q.pi[0] != tc { - // We know this is the only thing that could possibly match, so put it - // in at the front - if it isn't there already. - // TODO(sdboyer) existence of the revision is guaranteed by checkRevisionExists(); restore that call. - q.pi = append([]Version{tc}, q.pi...) - } - - // Having assembled the queue, search it for a valid version. - s.traceCheckQueue(q, bmi, false, 1) - return q, s.findValidVersion(q, bmi.pl) -} - -// findValidVersion walks through a versionQueue until it finds a version that -// satisfies the constraints held in the current state of the solver. -// -// The satisfiability checks triggered from here are constrained to operate only -// on those dependencies induced by the list of packages given in the second -// parameter. -func (s *solver) findValidVersion(q *versionQueue, pl []string) error { - if nil == q.current() { - // this case should not be reachable, but reflects improper solver state - // if it is, so panic immediately - panic("version queue is empty, should not happen") - } - - faillen := len(q.fails) - - for { - cur := q.current() - s.traceInfo("try %s@%s", q.id, cur) - err := s.check(atomWithPackages{ - a: atom{ - id: q.id, - v: cur, - }, - pl: pl, - }, false) - if err == nil { - // we have a good version, can return safely - return nil - } - - if q.advance(err) != nil { - // Error on advance, have to bail out - break - } - if q.isExhausted() { - // Queue is empty, bail with error - break - } - } - - s.fail(s.sel.getDependenciesOn(q.id)[0].depender.id) - - // Return a compound error of all the new errors encountered during this - // attempt to find a new, valid version - return &noVersionError{ - pn: q.id, - fails: q.fails[faillen:], - } -} - -// getLockVersionIfValid finds an atom for the given ProjectIdentifier from the -// root lock, assuming: -// -// 1. A root lock was provided -// 2. The general flag to change all projects was not passed -// 3. A flag to change this particular ProjectIdentifier was not passed -// -// If any of these three conditions are true (or if the id cannot be found in -// the root lock), then no atom will be returned. -func (s *solver) getLockVersionIfValid(id ProjectIdentifier) (Version, error) { - // If the project is specifically marked for changes, then don't look for a - // locked version. - if _, explicit := s.rd.chng[id.ProjectRoot]; explicit || s.rd.chngall { - // For projects with an upstream or cache repository, it's safe to - // ignore what's in the lock, because there's presumably more versions - // to be found and attempted in the repository. If it's only in vendor, - // though, then we have to try to use what's in the lock, because that's - // the only version we'll be able to get. - if exist, _ := s.b.SourceExists(id); exist { - // Upgrades mean breaking the lock - s.b.breakLock() - return nil, nil - } - - // However, if a change was *expressly* requested for something that - // exists only in vendor, then that guarantees we don't have enough - // information to complete a solution. In that case, error out. - if explicit { - return nil, &missingSourceFailure{ - goal: id, - prob: "Cannot upgrade %s, as no source repository could be found.", - } - } - } - - lp, exists := s.rd.rlm[id.ProjectRoot] - if !exists { - return nil, nil - } - - constraint := s.sel.getConstraint(id) - v := lp.Version() - if !constraint.Matches(v) { - var found bool - if tv, ok := v.(Revision); ok { - // If we only have a revision from the root's lock, allow matching - // against other versions that have that revision - for _, pv := range s.vUnify.pairRevision(id, tv) { - if constraint.Matches(pv) { - v = pv - found = true - break - } - } - //} else if _, ok := constraint.(Revision); ok { - //// If the current constraint is itself a revision, and the lock gave - //// an unpaired version, see if they match up - //// - //if u, ok := v.(UnpairedVersion); ok { - //pv := s.sm.pairVersion(id, u) - //if constraint.Matches(pv) { - //v = pv - //found = true - //} - //} - } - - if !found { - // No match found, which means we're going to be breaking the lock - // Still return the invalid version so that is included in the trace - s.b.breakLock() - } - } - - return v, nil -} - -// backtrack works backwards from the current failed solution to find the next -// solution to try. -func (s *solver) backtrack(ctx context.Context) (bool, error) { - if len(s.vqs) == 0 { - // nothing to backtrack to - return false, nil - } - - donechan := ctx.Done() - s.mtr.push("backtrack") - defer s.mtr.pop() - for { - for { - select { - case <-donechan: - return false, ctx.Err() - default: - } - - if len(s.vqs) == 0 { - // no more versions, nowhere further to backtrack - return false, nil - } - if s.vqs[len(s.vqs)-1].failed { - break - } - - s.vqs, s.vqs[len(s.vqs)-1] = s.vqs[:len(s.vqs)-1], nil - - // Pop selections off until we get to a project. - var proj bool - var awp atomWithPackages - for !proj { - var err error - awp, proj, err = s.unselectLast() - if err != nil { - if !contextCanceledOrSMReleased(err) { - panic(fmt.Sprintf("canary - should only have been able to get a context cancellation or SM release, got %T %s", err, err)) - } - return false, err - } - s.traceBacktrack(awp.bmi(), !proj) - } - } - - // Grab the last versionQueue off the list of queues - q := s.vqs[len(s.vqs)-1] - - // Walk back to the next project. This may entail walking through some - // package-only selections. - var proj bool - var awp atomWithPackages - for !proj { - var err error - awp, proj, err = s.unselectLast() - if err != nil { - if !contextCanceledOrSMReleased(err) { - panic(fmt.Sprintf("canary - should only have been able to get a context cancellation or SM release, got %T %s", err, err)) - } - return false, err - } - s.traceBacktrack(awp.bmi(), !proj) - } - - if !q.id.eq(awp.a.id) { - panic("canary - version queue stack and selected project stack are misaligned") - } - - // Advance the queue past the current version, which we know is bad - // TODO(sdboyer) is it feasible to make available the failure reason here? - if q.advance(nil) == nil && !q.isExhausted() { - // Search for another acceptable version of this failed dep in its queue - s.traceCheckQueue(q, awp.bmi(), true, 0) - if s.findValidVersion(q, awp.pl) == nil { - // Found one! Put it back on the selected queue and stop - // backtracking - - // reusing the old awp is fine - awp.a.v = q.current() - err := s.selectAtom(awp, false) - if err != nil { - if !contextCanceledOrSMReleased(err) { - panic(fmt.Sprintf("canary - should only have been able to get a context cancellation or SM release, got %T %s", err, err)) - } - return false, err - } - break - } - } - - s.traceBacktrack(awp.bmi(), false) - - // No solution found; continue backtracking after popping the queue - // we just inspected off the list - // GC-friendly pop pointer elem in slice - s.vqs, s.vqs[len(s.vqs)-1] = s.vqs[:len(s.vqs)-1], nil - } - - // Backtracking was successful if loop ended before running out of versions - if len(s.vqs) == 0 { - return false, nil - } - s.attempts++ - return true, nil -} - -func (s *solver) nextUnselected() (bimodalIdentifier, bool) { - if len(s.unsel.sl) > 0 { - return s.unsel.sl[0], true - } - - return bimodalIdentifier{}, false -} - -func (s *solver) unselectedComparator(i, j int) bool { - ibmi, jbmi := s.unsel.sl[i], s.unsel.sl[j] - iname, jname := ibmi.id, jbmi.id - - // Most important thing is pushing package additions ahead of project - // additions. Package additions can't walk their version queue, so all they - // do is narrow the possibility of success; better to find out early and - // fast if they're going to fail than wait until after we've done real work - // on a project and have to backtrack across it. - - // FIXME the impl here is currently O(n) in the number of selections; it - // absolutely cannot stay in a hot sorting path like this - // FIXME while other solver invariants probably protect us from it, this - // call-out means that it's possible for external state change to invalidate - // heap invariants. - _, isel := s.sel.selected(iname) - _, jsel := s.sel.selected(jname) - - if isel && !jsel { - return true - } - if !isel && jsel { - return false - } - - if iname.eq(jname) { - return false - } - - _, ilock := s.rd.rlm[iname.ProjectRoot] - _, jlock := s.rd.rlm[jname.ProjectRoot] - - switch { - case ilock && !jlock: - return true - case !ilock && jlock: - return false - case ilock && jlock: - return iname.Less(jname) - } - - // Now, sort by number of available versions. This will trigger network - // activity, but at this point we know that the project we're looking at - // isn't locked by the root. And, because being locked by root is the only - // way avoid that call when making a version queue, we know we're gonna have - // to pay that cost anyway. - - // We can safely ignore an err from listVersions here because, if there is - // an actual problem, it'll be noted and handled somewhere else saner in the - // solving algorithm. - ivl, _ := s.b.listVersions(iname) - jvl, _ := s.b.listVersions(jname) - iv, jv := len(ivl), len(jvl) - - // Packages with fewer versions to pick from are less likely to benefit from - // backtracking, so deal with them earlier in order to minimize the amount - // of superfluous backtracking through them we do. - switch { - case iv == 0 && jv != 0: - return true - case iv != 0 && jv == 0: - return false - case iv != jv: - return iv < jv - } - - // Finally, if all else fails, fall back to comparing by name - return iname.Less(jname) -} - -func (s *solver) fail(id ProjectIdentifier) { - // TODO(sdboyer) does this need updating, now that we have non-project package - // selection? - - // skip if the root project - if !s.rd.isRoot(id.ProjectRoot) { - // just look for the first (oldest) one; the backtracker will necessarily - // traverse through and pop off any earlier ones - for _, vq := range s.vqs { - if vq.id.eq(id) { - vq.failed = true - return - } - } - } -} - -// selectAtom pulls an atom into the selection stack, alongside some of -// its contained packages. New resultant dependency requirements are added to -// the unselected priority queue. -// -// Behavior is slightly diffferent if pkgonly is true. -func (s *solver) selectAtom(a atomWithPackages, pkgonly bool) error { - s.mtr.push("select-atom") - s.unsel.remove(bimodalIdentifier{ - id: a.a.id, - pl: a.pl, - }) - - pl, deps, err := s.getImportsAndConstraintsOf(a) - if err != nil { - if contextCanceledOrSMReleased(err) { - return err - } - // This shouldn't be possible; other checks should have ensured all - // packages and deps are present for any argument passed to this method. - panic(fmt.Sprintf("canary - shouldn't be possible %s", err)) - } - // Assign the new internal package list into the atom, then push it onto the - // selection stack - a.pl = pl - s.sel.pushSelection(a, pkgonly) - - // If this atom has a lock, pull it out so that we can potentially inject - // preferred versions into any bmis we enqueue - // - // TODO(sdboyer) making this call here could be the first thing to trigger - // network activity...maybe? if so, can we mitigate by deferring the work to - // queue consumption time? - _, l, _ := s.b.GetManifestAndLock(a.a.id, a.a.v, s.rd.an) - var lmap map[ProjectIdentifier]Version - if l != nil { - lmap = make(map[ProjectIdentifier]Version) - for _, lp := range l.Projects() { - lmap[lp.Ident()] = lp.Version() - } - } - - for _, dep := range deps { - // Root can come back up here if there's a project-level cycle. - // Satisfiability checks have already ensured invariants are maintained, - // so we know we can just skip it here. - if s.rd.isRoot(dep.Ident.ProjectRoot) { - continue - } - // If this is dep isn't in the lock, do some prefetching. (If it is, we - // might be able to get away with zero network activity for it, so don't - // prefetch). This provides an opportunity for some parallelism wins, on - // two fronts: - // - // 1. Because this loop may have multiple deps in it, we could end up - // simultaneously fetching both in the background while solving proceeds - // - // 2. Even if only one dep gets prefetched here, the worst case is that - // that same dep comes out of the unselected queue next, and we gain a - // few microseconds before blocking later. Best case, the dep doesn't - // come up next, but some other dep comes up that wasn't prefetched, and - // both fetches proceed in parallel. - if s.rd.needVersionsFor(dep.Ident.ProjectRoot) { - go s.b.SyncSourceFor(dep.Ident) - } - - s.sel.pushDep(dependency{depender: a.a, dep: dep}) - // Go through all the packages introduced on this dep, selecting only - // the ones where the only depper on them is what the preceding line just - // pushed in. Then, put those into the unselected queue. - rpm := s.sel.getRequiredPackagesIn(dep.Ident) - var newp []string - for _, pkg := range dep.pl { - // Just one means that the dep we're visiting is the sole importer. - if rpm[pkg] == 1 { - newp = append(newp, pkg) - } - } - - if len(newp) > 0 { - // If there was a previously-established alternate source for this - // dependency, but the current atom did not express one (and getting - // here means the atom passed the source hot-swapping check - see - // checkIdentMatches()), then we have to create the new bmi with the - // alternate source. Otherwise, we end up with two discrete project - // entries for the project root in the final output, one with the - // alternate source, and one without. See #969. - id, _ := s.sel.getIdentFor(dep.Ident.ProjectRoot) - bmi := bimodalIdentifier{ - id: id, - pl: newp, - // This puts in a preferred version if one's in the map, else - // drops in the zero value (nil) - prefv: lmap[dep.Ident], - } - heap.Push(s.unsel, bmi) - } - } - - s.traceSelect(a, pkgonly) - s.mtr.pop() - - return nil -} - -func (s *solver) unselectLast() (atomWithPackages, bool, error) { - s.mtr.push("unselect") - defer s.mtr.pop() - awp, first := s.sel.popSelection() - heap.Push(s.unsel, bimodalIdentifier{id: awp.a.id, pl: awp.pl}) - - _, deps, err := s.getImportsAndConstraintsOf(awp) - if err != nil { - if contextCanceledOrSMReleased(err) { - return atomWithPackages{}, false, err - } - // This shouldn't be possible; other checks should have ensured all - // packages and deps are present for any argument passed to this method. - panic(fmt.Sprintf("canary - shouldn't be possible %s", err)) - } - - for _, dep := range deps { - // Skip popping if the dep is the root project, which can occur if - // there's a project-level import cycle. (This occurs frequently with - // e.g. kubernetes and docker) - if s.rd.isRoot(dep.Ident.ProjectRoot) { - continue - } - s.sel.popDep(dep.Ident) - - // if no parents/importers, remove from unselected queue - if s.sel.depperCount(dep.Ident) == 0 { - s.unsel.remove(bimodalIdentifier{id: dep.Ident, pl: dep.pl}) - } - } - - return awp, first, nil -} - -// simple (temporary?) helper just to convert atoms into locked projects -func pa2lp(pa atom, pkgs map[string]struct{}) LockedProject { - lp := LockedProject{ - pi: pa.id, - } - - switch v := pa.v.(type) { - case UnpairedVersion: - lp.v = v - case Revision: - lp.r = v - case versionPair: - lp.v = v.v - lp.r = v.r - default: - panic("unreachable") - } - - lp.pkgs = make([]string, len(pkgs)) - k := 0 - - pr := string(pa.id.ProjectRoot) - trim := pr + "/" - for pkg := range pkgs { - if pkg == string(pa.id.ProjectRoot) { - lp.pkgs[k] = "." - } else { - lp.pkgs[k] = strings.TrimPrefix(pkg, trim) - } - k++ - } - sort.Strings(lp.pkgs) - - return lp -} - -func contextCanceledOrSMReleased(err error) bool { - return err == context.Canceled || err == context.DeadlineExceeded || err == ErrSourceManagerIsReleased -} diff --git a/vendor/github.com/golang/dep/gps/source.go b/vendor/github.com/golang/dep/gps/source.go deleted file mode 100644 index 54723754d09147308e5006f9c4db569530133249..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source.go +++ /dev/null @@ -1,638 +0,0 @@ -// 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 gps - -import ( - "context" - "fmt" - "log" - "sync" - - "github.com/golang/dep/gps/pkgtree" - "github.com/pkg/errors" -) - -// sourceState represent the states that a source can be in, depending on how -// much search and discovery work ahs been done by a source's managing gateway. -// -// These are basically used to achieve a cheap approximation of a FSM. -type sourceState int32 - -const ( - sourceIsSetUp sourceState = 1 << iota - sourceExistsUpstream - sourceExistsLocally - sourceHasLatestVersionList - sourceHasLatestLocally -) - -type srcReturnChans struct { - ret chan *sourceGateway - err chan error -} - -func (rc srcReturnChans) awaitReturn() (sg *sourceGateway, err error) { - select { - case sg = <-rc.ret: - case err = <-rc.err: - } - return -} - -type sourceCoordinator struct { - supervisor *supervisor - srcmut sync.RWMutex // guards srcs and nameToURL maps - srcs map[string]*sourceGateway - nameToURL map[string]string - psrcmut sync.Mutex // guards protoSrcs map - protoSrcs map[string][]srcReturnChans - deducer deducer - cachedir string - logger *log.Logger -} - -func newSourceCoordinator(superv *supervisor, deducer deducer, cachedir string, logger *log.Logger) *sourceCoordinator { - return &sourceCoordinator{ - supervisor: superv, - deducer: deducer, - cachedir: cachedir, - logger: logger, - srcs: make(map[string]*sourceGateway), - nameToURL: make(map[string]string), - protoSrcs: make(map[string][]srcReturnChans), - } -} - -func (sc *sourceCoordinator) close() {} - -func (sc *sourceCoordinator) getSourceGatewayFor(ctx context.Context, id ProjectIdentifier) (*sourceGateway, error) { - if err := sc.supervisor.ctx.Err(); err != nil { - return nil, err - } - - normalizedName := id.normalizedSource() - - sc.srcmut.RLock() - if url, has := sc.nameToURL[normalizedName]; has { - srcGate, has := sc.srcs[url] - sc.srcmut.RUnlock() - if has { - return srcGate, nil - } - panic(fmt.Sprintf("%q was URL for %q in nameToURL, but no corresponding srcGate in srcs map", url, normalizedName)) - } - - // Without a direct match, we must fold the input name to a generally - // stable, caseless variant and primarily work from that. This ensures that - // on case-insensitive filesystems, we do not end up with multiple - // sourceGateways for paths that vary only by case. We perform folding - // unconditionally, independent of whether the underlying fs is - // case-sensitive, in order to ensure uniform behavior. - // - // This has significant implications. It is effectively deciding that the - // ProjectRoot portion of import paths are case-insensitive, which is by no - // means an invariant maintained by all hosting systems. If this presents a - // problem in practice, then we can explore expanding the deduction system - // to include case-sensitivity-for-roots metadata and treat it on a - // host-by-host basis. Such cases would still be rejected by the Go - // toolchain's compiler, though, and case-sensitivity in root names is - // likely to be at least frowned on if not disallowed by most hosting - // systems. So we follow this path, which is both a vastly simpler solution - // and one that seems quite likely to work in practice. - foldedNormalName := toFold(normalizedName) - notFolded := foldedNormalName != normalizedName - if notFolded { - // If the folded name differs from the input name, then there may - // already be an entry for it in the nameToURL map, so check again. - if url, has := sc.nameToURL[foldedNormalName]; has { - // There was a match on the canonical folded variant. Upgrade to a - // write lock, so that future calls on this name don't need to - // burn cycles on folding. - sc.srcmut.RUnlock() - sc.srcmut.Lock() - // It may be possible that another goroutine could interleave - // between the unlock and re-lock. Even if they do, though, they'll - // only have recorded the same url value as we have here. In other - // words, these operations commute, so we can safely write here - // without checking again. - sc.nameToURL[normalizedName] = url - - srcGate, has := sc.srcs[url] - sc.srcmut.Unlock() - if has { - return srcGate, nil - } - panic(fmt.Sprintf("%q was URL for %q in nameToURL, but no corresponding srcGate in srcs map", url, normalizedName)) - } - } - sc.srcmut.RUnlock() - - // No gateway exists for this path yet; set up a proto, being careful to fold - // together simultaneous attempts on the same case-folded path. - sc.psrcmut.Lock() - if chans, has := sc.protoSrcs[foldedNormalName]; has { - // Another goroutine is already working on this normalizedName. Fold - // in with that work by attaching our return channels to the list. - rc := srcReturnChans{ - ret: make(chan *sourceGateway, 1), - err: make(chan error, 1), - } - sc.protoSrcs[foldedNormalName] = append(chans, rc) - sc.psrcmut.Unlock() - return rc.awaitReturn() - } - - sc.protoSrcs[foldedNormalName] = []srcReturnChans{} - sc.psrcmut.Unlock() - - doReturn := func(sg *sourceGateway, err error) { - sc.psrcmut.Lock() - if sg != nil { - for _, rc := range sc.protoSrcs[foldedNormalName] { - rc.ret <- sg - } - } else if err != nil { - for _, rc := range sc.protoSrcs[foldedNormalName] { - rc.err <- err - } - } else { - panic("sg and err both nil") - } - - delete(sc.protoSrcs, foldedNormalName) - sc.psrcmut.Unlock() - } - - pd, err := sc.deducer.deduceRootPath(ctx, normalizedName) - if err != nil { - // As in the deducer, don't cache errors so that externally-driven retry - // strategies can be constructed. - doReturn(nil, err) - return nil, err - } - - // It'd be quite the feat - but not impossible - for a gateway - // corresponding to this normalizedName to have slid into the main - // sources map after the initial unlock, but before this goroutine got - // scheduled. Guard against that by checking the main sources map again - // and bailing out if we find an entry. - var srcGate *sourceGateway - sc.srcmut.RLock() - if url, has := sc.nameToURL[foldedNormalName]; has { - if srcGate, has := sc.srcs[url]; has { - sc.srcmut.RUnlock() - doReturn(srcGate, nil) - return srcGate, nil - } - panic(fmt.Sprintf("%q was URL for %q in nameToURL, but no corresponding srcGate in srcs map", url, normalizedName)) - } - sc.srcmut.RUnlock() - - srcGate = newSourceGateway(pd.mb, sc.supervisor, sc.cachedir) - - // The normalized name is usually different from the source URL- e.g. - // github.com/sdboyer/gps vs. https://github.com/sdboyer/gps. But it's - // possible to arrive here with a full URL as the normalized name - and both - // paths *must* lead to the same sourceGateway instance in order to ensure - // disk access is correctly managed. - // - // Therefore, we now must query the sourceGateway to get the actual - // sourceURL it's operating on, and ensure it's *also* registered at - // that path in the map. This will cause it to actually initiate the - // maybeSource.try() behavior in order to settle on a URL. - url, err := srcGate.sourceURL(ctx) - if err != nil { - doReturn(nil, err) - return nil, err - } - - // If the normalizedName and foldedNormalName differ, then we're pretty well - // guaranteed that returned URL will also need folding into canonical form. - var unfoldedURL string - if notFolded { - unfoldedURL = url - url = toFold(url) - } - - // We know we have a working srcGateway at this point, and need to - // integrate it back into the main map. - sc.srcmut.Lock() - defer sc.srcmut.Unlock() - // Record the name -> URL mapping, making sure that we also get the - // self-mapping. - sc.nameToURL[foldedNormalName] = url - if url != foldedNormalName { - sc.nameToURL[url] = url - } - - // Make sure we have both the folded and unfolded names and URLs recorded in - // the map, if the input needed folding. - if notFolded { - sc.nameToURL[normalizedName] = url - sc.nameToURL[unfoldedURL] = url - } - - if sa, has := sc.srcs[url]; has { - // URL already had an entry in the main map; use that as the result. - doReturn(sa, nil) - return sa, nil - } - - sc.srcs[url] = srcGate - doReturn(srcGate, nil) - return srcGate, nil -} - -// sourceGateways manage all incoming calls for data from sources, serializing -// and caching them as needed. -type sourceGateway struct { - cachedir string - maybe maybeSource - srcState sourceState - src source - cache singleSourceCache - mu sync.Mutex // global lock, serializes all behaviors - suprvsr *supervisor -} - -func newSourceGateway(maybe maybeSource, superv *supervisor, cachedir string) *sourceGateway { - sg := &sourceGateway{ - maybe: maybe, - cachedir: cachedir, - suprvsr: superv, - } - sg.cache = sg.createSingleSourceCache() - - return sg -} - -func (sg *sourceGateway) syncLocal(ctx context.Context) error { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsLocally|sourceHasLatestLocally) - return err -} - -func (sg *sourceGateway) existsInCache(ctx context.Context) bool { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return false - } - - return sg.srcState&sourceExistsLocally != 0 -} - -func (sg *sourceGateway) existsUpstream(ctx context.Context) bool { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsUpstream) - if err != nil { - return false - } - - return sg.srcState&sourceExistsUpstream != 0 -} - -func (sg *sourceGateway) exportVersionTo(ctx context.Context, v Version, to string) error { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return err - } - - r, err := sg.convertToRevision(ctx, v) - if err != nil { - return err - } - - err = sg.suprvsr.do(ctx, sg.src.upstreamURL(), ctExportTree, func(ctx context.Context) error { - return sg.src.exportRevisionTo(ctx, r, to) - }) - - // It's possible (in git) that we may have tried this against a version that - // doesn't exist in the repository cache, even though we know it exists in - // the upstream. If it looks like that might be the case, update the local - // and retry. - // TODO(sdboyer) It'd be better if we could check the error to see if this - // actually was the cause of the problem. - if err != nil && sg.srcState&sourceHasLatestLocally == 0 { - if _, err = sg.require(ctx, sourceHasLatestLocally); err == nil { - err = sg.suprvsr.do(ctx, sg.src.upstreamURL(), ctExportTree, func(ctx context.Context) error { - return sg.src.exportRevisionTo(ctx, r, to) - }) - } - } - - return err -} - -func (sg *sourceGateway) getManifestAndLock(ctx context.Context, pr ProjectRoot, v Version, an ProjectAnalyzer) (Manifest, Lock, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - r, err := sg.convertToRevision(ctx, v) - if err != nil { - return nil, nil, err - } - - m, l, has := sg.cache.getManifestAndLock(r, an.Info()) - if has { - return m, l, nil - } - - _, err = sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return nil, nil, err - } - - label := fmt.Sprintf("%s:%s", sg.src.upstreamURL(), an.Info()) - err = sg.suprvsr.do(ctx, label, ctGetManifestAndLock, func(ctx context.Context) error { - m, l, err = sg.src.getManifestAndLock(ctx, pr, r, an) - return err - }) - - // It's possible (in git) that we may have tried this against a version that - // doesn't exist in the repository cache, even though we know it exists in - // the upstream. If it looks like that might be the case, update the local - // and retry. - // TODO(sdboyer) It'd be better if we could check the error to see if this - // actually was the cause of the problem. - if err != nil && sg.srcState&sourceHasLatestLocally == 0 { - // TODO(sdboyer) we should warn/log/something in adaptive recovery - // situations like this - _, err = sg.require(ctx, sourceHasLatestLocally) - if err != nil { - return nil, nil, err - } - - err = sg.suprvsr.do(ctx, label, ctGetManifestAndLock, func(ctx context.Context) error { - m, l, err = sg.src.getManifestAndLock(ctx, pr, r, an) - return err - }) - } - - if err != nil { - return nil, nil, err - } - - sg.cache.setManifestAndLock(r, an.Info(), m, l) - return m, l, nil -} - -// FIXME ProjectRoot input either needs to parameterize the cache, or be -// incorporated on the fly on egress...? -func (sg *sourceGateway) listPackages(ctx context.Context, pr ProjectRoot, v Version) (pkgtree.PackageTree, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - r, err := sg.convertToRevision(ctx, v) - if err != nil { - return pkgtree.PackageTree{}, err - } - - ptree, has := sg.cache.getPackageTree(r) - if has { - return ptree, nil - } - - _, err = sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return pkgtree.PackageTree{}, err - } - - label := fmt.Sprintf("%s:%s", pr, sg.src.upstreamURL()) - err = sg.suprvsr.do(ctx, label, ctListPackages, func(ctx context.Context) error { - ptree, err = sg.src.listPackages(ctx, pr, r) - return err - }) - - // It's possible (in git) that we may have tried this against a version that - // doesn't exist in the repository cache, even though we know it exists in - // the upstream. If it looks like that might be the case, update the local - // and retry. - // TODO(sdboyer) It'd be better if we could check the error to see if this - // actually was the cause of the problem. - if err != nil && sg.srcState&sourceHasLatestLocally == 0 { - // TODO(sdboyer) we should warn/log/something in adaptive recovery - // situations like this - _, err = sg.require(ctx, sourceHasLatestLocally) - if err != nil { - return pkgtree.PackageTree{}, err - } - - err = sg.suprvsr.do(ctx, label, ctListPackages, func(ctx context.Context) error { - ptree, err = sg.src.listPackages(ctx, pr, r) - return err - }) - } - - if err != nil { - return pkgtree.PackageTree{}, err - } - - sg.cache.setPackageTree(r, ptree) - return ptree, nil -} - -func (sg *sourceGateway) convertToRevision(ctx context.Context, v Version) (Revision, error) { - // When looking up by Version, there are four states that may have - // differing opinions about version->revision mappings: - // - // 1. The upstream source/repo (canonical) - // 2. The local source/repo - // 3. The local cache - // 4. The input (params to this method) - // - // If the input differs from any of the above, it's likely because some lock - // got written somewhere with a version/rev pair that has since changed or - // been removed. But correct operation dictates that such a mis-mapping be - // respected; if the mis-mapping is to be corrected, it has to be done - // intentionally by the caller, not automatically here. - r, has := sg.cache.toRevision(v) - if has { - return r, nil - } - - if sg.srcState&sourceHasLatestVersionList != 0 { - // We have the latest version list already and didn't get a match, so - // this is definitely a failure case. - return "", fmt.Errorf("version %q does not exist in source", v) - } - - // The version list is out of date; it's possible this version might - // show up after loading it. - _, err := sg.require(ctx, sourceIsSetUp|sourceHasLatestVersionList) - if err != nil { - return "", err - } - - r, has = sg.cache.toRevision(v) - if !has { - return "", fmt.Errorf("version %q does not exist in source", v) - } - - return r, nil -} - -func (sg *sourceGateway) listVersions(ctx context.Context) ([]PairedVersion, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - // TODO(sdboyer) The problem here is that sourceExistsUpstream may not be - // sufficient (e.g. bzr, hg), but we don't want to force local b/c git - // doesn't need it - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsUpstream|sourceHasLatestVersionList) - if err != nil { - return nil, err - } - if pvs, ok := sg.cache.getAllVersions(); ok { - return pvs, nil - } - return nil, nil -} - -func (sg *sourceGateway) revisionPresentIn(ctx context.Context, r Revision) (bool, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return false, err - } - - if _, exists := sg.cache.getVersionsFor(r); exists { - return true, nil - } - - present, err := sg.src.revisionPresentIn(r) - if err == nil && present { - sg.cache.markRevisionExists(r) - } - return present, err -} - -func (sg *sourceGateway) disambiguateRevision(ctx context.Context, r Revision) (Revision, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp|sourceExistsLocally) - if err != nil { - return "", err - } - - return sg.src.disambiguateRevision(ctx, r) -} - -func (sg *sourceGateway) sourceURL(ctx context.Context) (string, error) { - sg.mu.Lock() - defer sg.mu.Unlock() - - _, err := sg.require(ctx, sourceIsSetUp) - if err != nil { - return "", err - } - - return sg.src.upstreamURL(), nil -} - -// createSingleSourceCache creates a singleSourceCache instance for use by -// the encapsulated source. -func (sg *sourceGateway) createSingleSourceCache() singleSourceCache { - // TODO(sdboyer) when persistent caching is ready, just drop in the creation - // of a source-specific handle here - return newMemoryCache() -} - -func (sg *sourceGateway) require(ctx context.Context, wanted sourceState) (errState sourceState, err error) { - todo := (^sg.srcState) & wanted - var flag sourceState = 1 - - for todo != 0 { - if todo&flag != 0 { - // Assign the currently visited bit to errState so that we can - // return easily later. - // - // Also set up addlState so that individual ops can easily attach - // more states that were incidentally satisfied by the op. - errState = flag - var addlState sourceState - - switch flag { - case sourceIsSetUp: - sg.src, addlState, err = sg.maybe.try(ctx, sg.cachedir, sg.cache, sg.suprvsr) - case sourceExistsUpstream: - err = sg.suprvsr.do(ctx, sg.src.sourceType(), ctSourcePing, func(ctx context.Context) error { - if !sg.src.existsUpstream(ctx) { - return fmt.Errorf("%s does not exist upstream", sg.src.upstreamURL()) - } - return nil - }) - case sourceExistsLocally: - if !sg.src.existsLocally(ctx) { - err = sg.suprvsr.do(ctx, sg.src.sourceType(), ctSourceInit, func(ctx context.Context) error { - return sg.src.initLocal(ctx) - }) - - if err == nil { - addlState |= sourceHasLatestLocally - } else { - err = errors.Wrapf(err, "%s does not exist in the local cache and fetching failed", sg.src.upstreamURL()) - } - } - case sourceHasLatestVersionList: - var pvl []PairedVersion - err = sg.suprvsr.do(ctx, sg.src.sourceType(), ctListVersions, func(ctx context.Context) error { - pvl, err = sg.src.listVersions(ctx) - return err - }) - - if err == nil { - sg.cache.setVersionMap(pvl) - } - case sourceHasLatestLocally: - err = sg.suprvsr.do(ctx, sg.src.sourceType(), ctSourceFetch, func(ctx context.Context) error { - return sg.src.updateLocal(ctx) - }) - } - - if err != nil { - return - } - - checked := flag | addlState - sg.srcState |= checked - todo &= ^checked - } - - flag <<= 1 - } - - return 0, nil -} - -// source is an abstraction around the different underlying types (git, bzr, hg, -// svn, maybe raw on-disk code, and maybe eventually a registry) that can -// provide versioned project source trees. -type source interface { - existsLocally(context.Context) bool - existsUpstream(context.Context) bool - upstreamURL() string - initLocal(context.Context) error - updateLocal(context.Context) error - listVersions(context.Context) ([]PairedVersion, error) - getManifestAndLock(context.Context, ProjectRoot, Revision, ProjectAnalyzer) (Manifest, Lock, error) - listPackages(context.Context, ProjectRoot, Revision) (pkgtree.PackageTree, error) - revisionPresentIn(Revision) (bool, error) - disambiguateRevision(context.Context, Revision) (Revision, error) - exportRevisionTo(context.Context, Revision, string) error - sourceType() string -} diff --git a/vendor/github.com/golang/dep/gps/source_cache.go b/vendor/github.com/golang/dep/gps/source_cache.go deleted file mode 100644 index 7b5b56606428cc932e794a8b863418cb3010efa7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_cache.go +++ /dev/null @@ -1,226 +0,0 @@ -// 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 gps - -import ( - "fmt" - "sync" - - "github.com/golang/dep/gps/pkgtree" -) - -// singleSourceCache provides a method set for storing and retrieving data about -// a single source. -type singleSourceCache interface { - // Store the manifest and lock information for a given revision, as defined by - // a particular ProjectAnalyzer. - setManifestAndLock(Revision, ProjectAnalyzerInfo, Manifest, Lock) - - // Get the manifest and lock information for a given revision, as defined by - // a particular ProjectAnalyzer. - getManifestAndLock(Revision, ProjectAnalyzerInfo) (Manifest, Lock, bool) - - // Store a PackageTree for a given revision. - setPackageTree(Revision, pkgtree.PackageTree) - - // Get the PackageTree for a given revision. - getPackageTree(Revision) (pkgtree.PackageTree, bool) - - // Indicate to the cache that an individual revision is known to exist. - markRevisionExists(r Revision) - - // Store the mappings between a set of PairedVersions' surface versions - // their corresponding revisions. - // - // The existing list of versions will be purged before writing. Revisions - // will have their pairings purged, but record of the revision existing will - // be kept, on the assumption that revisions are immutable and permanent. - setVersionMap(versionList []PairedVersion) - - // Get the list of unpaired versions corresponding to the given revision. - getVersionsFor(Revision) ([]UnpairedVersion, bool) - - // Gets all the version pairs currently known to the cache. - getAllVersions() ([]PairedVersion, bool) - - // Get the revision corresponding to the given unpaired version. - getRevisionFor(UnpairedVersion) (Revision, bool) - - // Attempt to convert the given Version to a Revision, given information - // currently present in the cache, and in the Version itself. - toRevision(v Version) (Revision, bool) - - // Attempt to convert the given Version to an UnpairedVersion, given - // information currently present in the cache, or in the Version itself. - // - // If the input is a revision and multiple UnpairedVersions are associated - // with it, whatever happens to be the first is returned. - toUnpaired(v Version) (UnpairedVersion, bool) -} - -type singleSourceCacheMemory struct { - mut sync.RWMutex // protects all fields - infos map[ProjectAnalyzerInfo]map[Revision]projectInfo - ptrees map[Revision]pkgtree.PackageTree - vList []PairedVersion // replaced, never modified - vMap map[UnpairedVersion]Revision - rMap map[Revision][]UnpairedVersion -} - -func newMemoryCache() singleSourceCache { - return &singleSourceCacheMemory{ - infos: make(map[ProjectAnalyzerInfo]map[Revision]projectInfo), - ptrees: make(map[Revision]pkgtree.PackageTree), - vMap: make(map[UnpairedVersion]Revision), - rMap: make(map[Revision][]UnpairedVersion), - } -} - -type projectInfo struct { - Manifest - Lock -} - -func (c *singleSourceCacheMemory) setManifestAndLock(r Revision, pai ProjectAnalyzerInfo, m Manifest, l Lock) { - c.mut.Lock() - inner, has := c.infos[pai] - if !has { - inner = make(map[Revision]projectInfo) - c.infos[pai] = inner - } - inner[r] = projectInfo{Manifest: m, Lock: l} - - // Ensure there's at least an entry in the rMap so that the rMap always has - // a complete picture of the revisions we know to exist - if _, has = c.rMap[r]; !has { - c.rMap[r] = nil - } - c.mut.Unlock() -} - -func (c *singleSourceCacheMemory) getManifestAndLock(r Revision, pai ProjectAnalyzerInfo) (Manifest, Lock, bool) { - c.mut.Lock() - defer c.mut.Unlock() - - inner, has := c.infos[pai] - if !has { - return nil, nil, false - } - - pi, has := inner[r] - if has { - return pi.Manifest, pi.Lock, true - } - return nil, nil, false -} - -func (c *singleSourceCacheMemory) setPackageTree(r Revision, ptree pkgtree.PackageTree) { - c.mut.Lock() - c.ptrees[r] = ptree - - // Ensure there's at least an entry in the rMap so that the rMap always has - // a complete picture of the revisions we know to exist - if _, has := c.rMap[r]; !has { - c.rMap[r] = nil - } - c.mut.Unlock() -} - -func (c *singleSourceCacheMemory) getPackageTree(r Revision) (pkgtree.PackageTree, bool) { - c.mut.Lock() - ptree, has := c.ptrees[r] - c.mut.Unlock() - return ptree, has -} - -func (c *singleSourceCacheMemory) setVersionMap(versionList []PairedVersion) { - c.mut.Lock() - c.vList = versionList - // TODO(sdboyer) how do we handle cache consistency here - revs that may - // be out of date vis-a-vis the ptrees or infos maps? - for r := range c.rMap { - c.rMap[r] = nil - } - - c.vMap = make(map[UnpairedVersion]Revision, len(versionList)) - - for _, pv := range versionList { - u, r := pv.Unpair(), pv.Revision() - c.vMap[u] = r - c.rMap[r] = append(c.rMap[r], u) - } - c.mut.Unlock() -} - -func (c *singleSourceCacheMemory) markRevisionExists(r Revision) { - c.mut.Lock() - if _, has := c.rMap[r]; !has { - c.rMap[r] = nil - } - c.mut.Unlock() -} - -func (c *singleSourceCacheMemory) getVersionsFor(r Revision) ([]UnpairedVersion, bool) { - c.mut.Lock() - versionList, has := c.rMap[r] - c.mut.Unlock() - return versionList, has -} - -func (c *singleSourceCacheMemory) getAllVersions() ([]PairedVersion, bool) { - c.mut.Lock() - vList := c.vList - c.mut.Unlock() - - if vList == nil { - return nil, false - } - cp := make([]PairedVersion, len(vList)) - copy(cp, vList) - return cp, true -} - -func (c *singleSourceCacheMemory) getRevisionFor(uv UnpairedVersion) (Revision, bool) { - c.mut.Lock() - r, has := c.vMap[uv] - c.mut.Unlock() - return r, has -} - -func (c *singleSourceCacheMemory) toRevision(v Version) (Revision, bool) { - switch t := v.(type) { - case Revision: - return t, true - case PairedVersion: - return t.Revision(), true - case UnpairedVersion: - c.mut.Lock() - r, has := c.vMap[t] - c.mut.Unlock() - return r, has - default: - panic(fmt.Sprintf("Unknown version type %T", v)) - } -} - -func (c *singleSourceCacheMemory) toUnpaired(v Version) (UnpairedVersion, bool) { - switch t := v.(type) { - case UnpairedVersion: - return t, true - case PairedVersion: - return t.Unpair(), true - case Revision: - c.mut.Lock() - upv, has := c.rMap[t] - c.mut.Unlock() - - if has && len(upv) > 0 { - return upv[0], true - } - return nil, false - default: - panic(fmt.Sprintf("unknown version type %T", v)) - } -} diff --git a/vendor/github.com/golang/dep/gps/source_cache_bolt.go b/vendor/github.com/golang/dep/gps/source_cache_bolt.go deleted file mode 100644 index 02d700988fa53e5c69b18021a5d08def9f915f86..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_cache_bolt.go +++ /dev/null @@ -1,515 +0,0 @@ -// 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 gps - -import ( - "fmt" - "log" - "os" - "path/filepath" - "time" - - "github.com/boltdb/bolt" - "github.com/golang/dep/gps/internal/pb" - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/protobuf/proto" - "github.com/jmank88/nuts" - "github.com/pkg/errors" -) - -// boltCache manages a bolt.DB cache and provides singleSourceCaches. -type boltCache struct { - db *bolt.DB - epoch int64 // getters will not return values older than this unix timestamp - logger *log.Logger // info logging -} - -// newBoltCache returns a new boltCache backed by a BoltDB file under the cache directory. -func newBoltCache(cd string, epoch int64, logger *log.Logger) (*boltCache, error) { - path := sourceCachePath(cd, "bolt") + ".db" - dir := filepath.Dir(path) - if fi, err := os.Stat(dir); os.IsNotExist(err) { - if err := os.MkdirAll(dir, os.ModeDir|os.ModePerm); err != nil { - return nil, errors.Wrapf(err, "failed to create source cache directory: %s", dir) - } - } else if err != nil { - return nil, errors.Wrapf(err, "failed to check source cache directory: ", dir) - } else if !fi.IsDir() { - return nil, errors.Wrapf(err, "source cache path is not directory: %s", dir) - } - db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) - if err != nil { - return nil, errors.Wrapf(err, "failed to open BoltDB cache file %q", path) - } - return &boltCache{ - db: db, - epoch: epoch, - logger: logger, - }, nil -} - -// newSingleSourceCache returns a new singleSourceCache for pi. -func (c *boltCache) newSingleSourceCache(pi ProjectIdentifier) singleSourceCache { - return &singleSourceCacheBolt{ - boltCache: c, - pi: pi, - sourceName: []byte(pi.normalizedSource()), - } -} - -// close releases all cache resources. -func (c *boltCache) close() error { - return errors.Wrapf(c.db.Close(), "error closing Bolt database %q", c.db.String()) -} - -// singleSourceCacheBolt implements a singleSourceCache backed by a persistent BoltDB file. -// Version mappings are timestamped, and the `epoch` field limits the age of returned values. -// Database access methods are safe for concurrent use. -// -// Implementation: -// -// Each source has a top-level bucket containing sub-buckets for (1) versions and (2) revisions. -// -// 1) Versions buckets hold version keys with revision values: -// -// Bucket: "v<timestamp>" -// Keys: Unpaired Versions serialized via ConstraintMsg -// Values: "<revision>" -// -// 2) Revision buckets hold (a) manifest and lock data for various ProjectAnalyzers, -// (b) package trees, and (c) version lists. -// -// Bucket: "r<revision>" -// -// a) Manifest and Lock info are stored in buckets derived from ProjectAnalyzer.Info: -// -// Sub-Bucket: "<name>.<version>m", "<name>.<version>l" -// Keys/Values: Manifest or Lock fields -// -// b) Package tree buckets contain package import path keys and package-or-error buckets: -// -// Sub-Bucket: "p" -// Sub-Bucket: "<import_path>" -// Key/Values: PackageOrErr fields -// -// c) Revision-versions buckets contain lists of version values: -// -// Sub-Bucket: "v<timestamp>" -// Keys: "<sequence_number>" -// Values: Unpaired Versions serialized via ConstraintMsg -type singleSourceCacheBolt struct { - *boltCache - pi ProjectIdentifier - sourceName []byte -} - -func (s *singleSourceCacheBolt) setManifestAndLock(rev Revision, ai ProjectAnalyzerInfo, m Manifest, l Lock) { - err := s.updateRevBucket(rev, func(b *bolt.Bucket) error { - info := ai.String() - name := make([]byte, len(info)+1) - copy(name, info) - name[len(info)] = 'm' - - if b.Bucket(name) != nil { - if err := b.DeleteBucket(name); err != nil { - return err - } - } - - // Manifest - mb, err := b.CreateBucket(name) - if err != nil { - return err - } - if err := cachePutManifest(mb, m); err != nil { - return errors.Wrap(err, "failed to put manifest") - } - if l == nil { - return nil - } - - // Lock - name[len(info)] = 'l' - if b.Bucket(name) != nil { - if err := b.DeleteBucket(name); err != nil { - return err - } - } - lb, err := b.CreateBucket(name) - if err != nil { - return err - } - return errors.Wrap(cachePutLock(lb, l), "failed to put lock") - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to cache manifest/lock for revision %q, analyzer: %v", rev, ai)) - } -} - -func (s *singleSourceCacheBolt) getManifestAndLock(rev Revision, ai ProjectAnalyzerInfo) (m Manifest, l Lock, ok bool) { - err := s.viewRevBucket(rev, func(b *bolt.Bucket) error { - info := ai.String() - name := make([]byte, len(info)+1) - copy(name, info) - name[len(info)] = 'm' - - // Manifest - mb := b.Bucket(name) - if mb == nil { - return nil - } - var err error - m, err = cacheGetManifest(mb) - if err != nil { - return errors.Wrap(err, "failed to get manifest") - } - - // Lock - name[len(info)] = 'l' - lb := b.Bucket(name) - if lb == nil { - ok = true - return nil - } - l, err = cacheGetLock(lb) - if err != nil { - return errors.Wrap(err, "failed to get lock") - } - - ok = true - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to get cached manifest/lock for revision %q, analyzer: %v", rev, ai)) - } - return -} - -func (s *singleSourceCacheBolt) setPackageTree(rev Revision, ptree pkgtree.PackageTree) { - err := s.updateRevBucket(rev, func(b *bolt.Bucket) error { - if b.Bucket(cacheKeyPTree) != nil { - if err := b.DeleteBucket(cacheKeyPTree); err != nil { - return err - } - } - ptrees, err := b.CreateBucket(cacheKeyPTree) - if err != nil { - return err - } - - for ip, poe := range ptree.Packages { - pb, err := ptrees.CreateBucket([]byte(ip)) - if err != nil { - return err - } - - if err := cachePutPackageOrErr(pb, poe); err != nil { - return err - } - } - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to cache package tree for revision %q", rev)) - } -} - -func (s *singleSourceCacheBolt) getPackageTree(rev Revision) (ptree pkgtree.PackageTree, ok bool) { - err := s.viewRevBucket(rev, func(b *bolt.Bucket) error { - ptrees := b.Bucket(cacheKeyPTree) - if ptrees == nil { - return nil - } - - pkgs := make(map[string]pkgtree.PackageOrErr) - err := ptrees.ForEach(func(ip, _ []byte) error { - poe, err := cacheGetPackageOrErr(ptrees.Bucket(ip)) - if err != nil { - return err - } - if poe.Err == nil { - poe.P.ImportPath = string(ip) - } - pkgs[string(ip)] = poe - return nil - }) - if err != nil { - return err - } - ptree.ImportRoot = string(s.pi.ProjectRoot) - ptree.Packages = pkgs - ok = true - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to get cached package tree for revision %q", rev)) - } - return -} - -func (s *singleSourceCacheBolt) markRevisionExists(rev Revision) { - err := s.updateRevBucket(rev, func(versions *bolt.Bucket) error { - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to mark revision %q in cache", rev)) - } -} - -func (s *singleSourceCacheBolt) setVersionMap(pvs []PairedVersion) { - err := s.updateSourceBucket(func(src *bolt.Bucket) error { - if err := cachePrefixDelete(src, cacheVersion); err != nil { - return err - } - vk := cacheTimestampedKey(cacheVersion, time.Now()) - versions, err := src.CreateBucket(vk) - if err != nil { - return err - } - - c := src.Cursor() - for k, _ := c.Seek(cacheKeyRevision); len(k) > 0 && k[0] == cacheRevision; k, _ = c.Next() { - rb := src.Bucket(k) - if err := cachePrefixDelete(rb, cacheVersion); err != nil { - return err - } - } - - revVersions := make(map[Revision]*bolt.Bucket) - key := make(nuts.Key, nuts.KeyLen(uint64(len(pvs)-1))) - var msg pb.Constraint - for i, pv := range pvs { - uv, rev := pv.Unpair(), pv.Revision() - uv.copyTo(&msg) - uvB, err := proto.Marshal(&msg) - if err != nil { - return errors.Wrapf(err, "failed to serialize UnpairedVersion: %#v", uv) - } - - if err := versions.Put(uvB, []byte(rev)); err != nil { - return errors.Wrap(err, "failed to put version->revision") - } - - b, err := src.CreateBucketIfNotExists(cacheRevisionName(rev)) - if err != nil { - return errors.Wrapf(err, "failed to create bucket for revision: %s", rev) - } - - var versions *bolt.Bucket - if versions = revVersions[rev]; versions == nil { - err := cachePrefixDelete(b, cacheVersion) - if err != nil { - return err - } - versions, err = b.CreateBucket(vk) - if err != nil { - return errors.Wrapf(err, "failed to create bucket for revision versions: %s", rev) - } - revVersions[rev] = versions - } - - key.Put(uint64(i)) - if err := versions.Put(key, uvB); err != nil { - return errors.Wrap(err, "failed to put revision->version") - } - } - return nil - }) - if err != nil { - s.logger.Println(errors.Wrap(err, "failed to cache version map")) - } -} - -func (s *singleSourceCacheBolt) getVersionsFor(rev Revision) (uvs []UnpairedVersion, ok bool) { - err := s.viewRevBucket(rev, func(b *bolt.Bucket) error { - versions := cacheFindLatestValid(b, cacheVersion, s.epoch) - if versions == nil { - return nil - } - - ok = true - - var msg pb.Constraint - return versions.ForEach(func(_, v []byte) error { - if err := proto.Unmarshal(v, &msg); err != nil { - return err - } - uv, err := unpairedVersionFromCache(&msg) - if err != nil { - return err - } - uvs = append(uvs, uv) - return nil - }) - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to get cached versions for revision %q", rev)) - return nil, false - } - return -} - -func (s *singleSourceCacheBolt) getAllVersions() (pvs []PairedVersion, ok bool) { - err := s.viewSourceBucket(func(src *bolt.Bucket) error { - versions := cacheFindLatestValid(src, cacheVersion, s.epoch) - if versions == nil { - return nil - } - - var msg pb.Constraint - return versions.ForEach(func(k, v []byte) error { - if err := proto.Unmarshal(k, &msg); err != nil { - return err - } - uv, err := unpairedVersionFromCache(&msg) - if err != nil { - return err - } - pvs = append(pvs, uv.Pair(Revision(v))) - ok = true - return nil - }) - }) - if err != nil { - s.logger.Println(errors.Wrap(err, "failed to get all cached versions")) - return nil, false - } - return -} - -func (s *singleSourceCacheBolt) getRevisionFor(uv UnpairedVersion) (rev Revision, ok bool) { - err := s.viewSourceBucket(func(src *bolt.Bucket) error { - versions := cacheFindLatestValid(src, cacheVersion, s.epoch) - if versions == nil { - return nil - } - - var msg pb.Constraint - uv.copyTo(&msg) - b, err := proto.Marshal(&msg) - if err != nil { - return errors.Wrapf(err, "failed to serialize UnpairedVersion: %#v", uv) - } - - v := versions.Get(b) - if len(v) > 0 { - rev = Revision(v) - ok = true - } - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, "failed to get cached revision for unpaired version: %v", uv)) - } - return -} - -func (s *singleSourceCacheBolt) toRevision(v Version) (rev Revision, ok bool) { - switch t := v.(type) { - case Revision: - return t, true - case PairedVersion: - return t.Revision(), true - case UnpairedVersion: - return s.getRevisionFor(t) - default: - s.logger.Println(fmt.Sprintf("failed to get cached revision for version %v: unknown type %T", v, v)) - return "", false - } -} - -func (s *singleSourceCacheBolt) toUnpaired(v Version) (uv UnpairedVersion, ok bool) { - const errMsg = "failed to get cached unpaired version for version: %v" - switch t := v.(type) { - case UnpairedVersion: - return t, true - case PairedVersion: - return t.Unpair(), true - case Revision: - err := s.viewRevBucket(t, func(b *bolt.Bucket) error { - versions := cacheFindLatestValid(b, cacheVersion, s.epoch) - if versions == nil { - return nil - } - - _, v := versions.Cursor().First() - if len(v) == 0 { - return nil - } - var msg pb.Constraint - if err := proto.Unmarshal(v, &msg); err != nil { - return err - } - var err error - uv, err = unpairedVersionFromCache(&msg) - if err != nil { - return err - } - - ok = true - return nil - }) - if err != nil { - s.logger.Println(errors.Wrapf(err, errMsg, v)) - } - return - default: - s.logger.Println(fmt.Sprintf(errMsg, v)) - return - } -} - -// cacheRevisionName returns the bucket name for rev. -func cacheRevisionName(rev Revision) []byte { - name := make([]byte, 1+len(rev)) - name[0] = 'r' - copy(name[1:], string(rev)) - return name -} - -// viewSourceBucket executes view with the source bucket, if it exists. -func (s *singleSourceCacheBolt) viewSourceBucket(view func(b *bolt.Bucket) error) error { - return s.db.View(func(tx *bolt.Tx) error { - b := tx.Bucket(s.sourceName) - if b == nil { - return nil - } - return view(b) - }) -} - -// updateSourceBucket executes update (in batch) with the source bucket, creating it first if necessary. -func (s *singleSourceCacheBolt) updateSourceBucket(update func(b *bolt.Bucket) error) error { - return s.db.Batch(func(tx *bolt.Tx) error { - b, err := tx.CreateBucketIfNotExists(s.sourceName) - if err != nil { - return errors.Wrapf(err, "failed to create bucket: %s", s.sourceName) - } - return update(b) - }) -} - -// viewRevBucket executes view with rev's bucket for this source, if it exists. -func (s *singleSourceCacheBolt) viewRevBucket(rev Revision, view func(b *bolt.Bucket) error) error { - return s.viewSourceBucket(func(src *bolt.Bucket) error { - b := src.Bucket(cacheRevisionName(rev)) - if b == nil { - return nil - } - return view(b) - }) -} - -// updateRevBucket executes update with rev's bucket for this source, creating it first if necessary. -func (s *singleSourceCacheBolt) updateRevBucket(rev Revision, update func(b *bolt.Bucket) error) error { - return s.updateSourceBucket(func(src *bolt.Bucket) error { - name := cacheRevisionName(rev) - b, err := src.CreateBucketIfNotExists(name) - if err != nil { - return errors.Wrapf(err, "failed to create bucket: %s", name) - } - return update(b) - }) -} diff --git a/vendor/github.com/golang/dep/gps/source_cache_bolt_encode.go b/vendor/github.com/golang/dep/gps/source_cache_bolt_encode.go deleted file mode 100644 index 2851b24b31448caaf19fd6e5743ff46270d52b36..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_cache_bolt_encode.go +++ /dev/null @@ -1,465 +0,0 @@ -// 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 gps - -import ( - "encoding/binary" - "time" - - "github.com/boltdb/bolt" - "github.com/golang/dep/gps/internal/pb" - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/protobuf/proto" - "github.com/jmank88/nuts" - "github.com/pkg/errors" -) - -var ( - cacheKeyComment = []byte("c") - cacheKeyConstraint = cacheKeyComment - cacheKeyError = []byte("e") - cacheKeyHash = []byte("h") - cacheKeyIgnored = []byte("i") - cacheKeyImport = cacheKeyIgnored - cacheKeyLock = []byte("l") - cacheKeyName = []byte("n") - cacheKeyOverride = []byte("o") - cacheKeyPTree = []byte("p") - cacheKeyRequired = []byte("r") - cacheKeyRevision = cacheKeyRequired - cacheKeyTestImport = []byte("t") - - cacheRevision = byte('r') - cacheVersion = byte('v') -) - -// propertiesFromCache returns a new ProjectRoot and ProjectProperties with the fields from m. -func propertiesFromCache(m *pb.ProjectProperties) (ProjectRoot, ProjectProperties, error) { - ip := ProjectRoot(m.Root) - var pp ProjectProperties - pp.Source = m.Source - - if m.Constraint == nil { - pp.Constraint = Any() - } else { - c, err := constraintFromCache(m.Constraint) - if err != nil { - return "", ProjectProperties{}, err - } - pp.Constraint = c - } - - return ip, pp, nil -} - -// projectPropertiesMsgs is a convenience tuple. -type projectPropertiesMsgs struct { - pp pb.ProjectProperties - c pb.Constraint -} - -// copyFrom sets the ProjectPropertiesMsg fields from ip and pp. -func (ms *projectPropertiesMsgs) copyFrom(ip ProjectRoot, pp ProjectProperties) { - ms.pp.Root = string(ip) - ms.pp.Source = pp.Source - - if pp.Constraint != nil && !IsAny(pp.Constraint) { - pp.Constraint.copyTo(&ms.c) - ms.pp.Constraint = &ms.c - } else { - ms.pp.Constraint = nil - } -} - -// cachePutManifest stores a Manifest in the bolt.Bucket. -func cachePutManifest(b *bolt.Bucket, m Manifest) error { - var ppMsg projectPropertiesMsgs - - constraints := m.DependencyConstraints() - if len(constraints) > 0 { - cs, err := b.CreateBucket(cacheKeyConstraint) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(constraints)-1))) - var i uint64 - for ip, pp := range constraints { - ppMsg.copyFrom(ip, pp) - v, err := proto.Marshal(&ppMsg.pp) - if err != nil { - return err - } - key.Put(i) - i++ - if err := cs.Put(key, v); err != nil { - return err - } - } - } - - rm, ok := m.(RootManifest) - if !ok { - return nil - } - - ignored := rm.IgnoredPackages().ToSlice() - if len(ignored) > 0 { - ig, err := b.CreateBucket(cacheKeyIgnored) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(ignored)-1))) - var i uint64 - for _, ip := range ignored { - key.Put(i) - i++ - if err := ig.Put(key, []byte(ip)); err != nil { - return err - } - } - } - - overrides := rm.Overrides() - if len(overrides) > 0 { - ovr, err := b.CreateBucket(cacheKeyOverride) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(overrides)-1))) - var i uint64 - for ip, pp := range overrides { - ppMsg.copyFrom(ip, pp) - v, err := proto.Marshal(&ppMsg.pp) - if err != nil { - return err - } - key.Put(i) - i++ - if err := ovr.Put(key, v); err != nil { - return err - } - } - } - - required := rm.RequiredPackages() - if len(required) > 0 { - req, err := b.CreateBucket(cacheKeyRequired) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(required)-1))) - var i uint64 - for ip, ok := range required { - if ok { - key.Put(i) - i++ - if err := req.Put(key, []byte(ip)); err != nil { - return err - } - } - } - } - - return nil -} - -// cacheGetManifest returns a new RootManifest with the data retrieved from the bolt.Bucket. -func cacheGetManifest(b *bolt.Bucket) (RootManifest, error) { - //TODO consider storing slice/map lens to enable calling make() with capacity - m := &simpleRootManifest{ - c: make(ProjectConstraints), - ovr: make(ProjectConstraints), - req: make(map[string]bool), - } - - // Constraints - if cs := b.Bucket(cacheKeyConstraint); cs != nil { - var msg pb.ProjectProperties - err := cs.ForEach(func(_, v []byte) error { - if err := proto.Unmarshal(v, &msg); err != nil { - return err - } - ip, pp, err := propertiesFromCache(&msg) - if err != nil { - return err - } - m.c[ip] = pp - return nil - }) - if err != nil { - return nil, errors.Wrap(err, "failed to get constraints") - } - } - - // Ignored - if ig := b.Bucket(cacheKeyIgnored); ig != nil { - var igslice []string - err := ig.ForEach(func(_, v []byte) error { - igslice = append(igslice, string(v)) - return nil - }) - m.ig = pkgtree.NewIgnoredRuleset(igslice) - if err != nil { - return nil, errors.Wrap(err, "failed to get ignored") - } - } - - // Overrides - if os := b.Bucket(cacheKeyOverride); os != nil { - var msg pb.ProjectProperties - err := os.ForEach(func(_, v []byte) error { - if err := proto.Unmarshal(v, &msg); err != nil { - return err - } - ip, pp, err := propertiesFromCache(&msg) - if err != nil { - return err - } - m.ovr[ip] = pp - return nil - }) - if err != nil { - return nil, errors.Wrap(err, "failed to get overrides") - } - } - - // Required - if req := b.Bucket(cacheKeyRequired); req != nil { - err := req.ForEach(func(_, v []byte) error { - m.req[string(v)] = true - return nil - }) - if err != nil { - return nil, errors.Wrap(err, "failed to get required") - } - } - - return m, nil -} - -// copyTo returns a serializable representation of lp. -func (lp LockedProject) copyTo(msg *pb.LockedProject, c *pb.Constraint) { - if lp.v == nil { - msg.UnpairedVersion = nil - } else { - lp.v.copyTo(c) - msg.UnpairedVersion = c - } - msg.Root = string(lp.pi.ProjectRoot) - msg.Source = lp.pi.Source - msg.Revision = string(lp.r) - msg.Packages = lp.pkgs -} - -// lockedProjectFromCache returns a new LockedProject with fields from m. -func lockedProjectFromCache(m *pb.LockedProject) (LockedProject, error) { - var uv UnpairedVersion - var err error - if m.UnpairedVersion != nil { - uv, err = unpairedVersionFromCache(m.UnpairedVersion) - if err != nil { - return LockedProject{}, err - } - } - return LockedProject{ - pi: ProjectIdentifier{ - ProjectRoot: ProjectRoot(m.Root), - Source: m.Source, - }, - v: uv, - r: Revision(m.Revision), - pkgs: m.Packages, - }, nil -} - -// cachePutLock stores the Lock as fields in the bolt.Bucket. -func cachePutLock(b *bolt.Bucket, l Lock) error { - // InputHash - if v := l.InputsDigest(); len(v) > 0 { - if err := b.Put(cacheKeyHash, v); err != nil { - return errors.Wrap(err, "failed to put hash") - } - } - - // Projects - if projects := l.Projects(); len(projects) > 0 { - lb, err := b.CreateBucket(cacheKeyLock) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(projects)-1))) - var msg pb.LockedProject - var cMsg pb.Constraint - for i, lp := range projects { - lp.copyTo(&msg, &cMsg) - v, err := proto.Marshal(&msg) - if err != nil { - return err - } - key.Put(uint64(i)) - if err := lb.Put(key, v); err != nil { - return err - } - } - } - - return nil -} - -// cacheGetLock returns a new *safeLock with the fields retrieved from the bolt.Bucket. -func cacheGetLock(b *bolt.Bucket) (*safeLock, error) { - l := &safeLock{ - h: b.Get(cacheKeyHash), - } - if locked := b.Bucket(cacheKeyLock); locked != nil { - var msg pb.LockedProject - err := locked.ForEach(func(_, v []byte) error { - if err := proto.Unmarshal(v, &msg); err != nil { - return err - } - lp, err := lockedProjectFromCache(&msg) - if err != nil { - return err - } - l.p = append(l.p, lp) - return nil - }) - if err != nil { - return nil, errors.Wrap(err, "failed to get locked projects") - } - } - return l, nil -} - -// cachePutPackageOrError stores the pkgtree.PackageOrErr as fields in the bolt.Bucket. -func cachePutPackageOrErr(b *bolt.Bucket, poe pkgtree.PackageOrErr) error { - if poe.Err != nil { - err := b.Put(cacheKeyError, []byte(poe.Err.Error())) - return errors.Wrapf(err, "failed to put error: %v", poe.Err) - } - if len(poe.P.CommentPath) > 0 { - err := b.Put(cacheKeyComment, []byte(poe.P.CommentPath)) - if err != nil { - return errors.Wrapf(err, "failed to put package: %v", poe.P) - } - } - if len(poe.P.Imports) > 0 { - ip, err := b.CreateBucket(cacheKeyImport) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(poe.P.Imports)-1))) - for i := range poe.P.Imports { - v := []byte(poe.P.Imports[i]) - key.Put(uint64(i)) - if err := ip.Put(key, v); err != nil { - return err - } - } - } - - if len(poe.P.Name) > 0 { - err := b.Put(cacheKeyName, []byte(poe.P.Name)) - if err != nil { - return errors.Wrapf(err, "failed to put package: %v", poe.P) - } - } - - if len(poe.P.TestImports) > 0 { - ip, err := b.CreateBucket(cacheKeyTestImport) - if err != nil { - return err - } - key := make(nuts.Key, nuts.KeyLen(uint64(len(poe.P.TestImports)-1))) - for i := range poe.P.TestImports { - v := []byte(poe.P.TestImports[i]) - key.Put(uint64(i)) - if err := ip.Put(key, v); err != nil { - return err - } - } - } - return nil -} - -// cacheGetPackageOrErr returns a new pkgtree.PackageOrErr with fields retrieved -// from the bolt.Bucket. -func cacheGetPackageOrErr(b *bolt.Bucket) (pkgtree.PackageOrErr, error) { - if v := b.Get(cacheKeyError); len(v) > 0 { - return pkgtree.PackageOrErr{ - Err: errors.New(string(v)), - }, nil - } - - var p pkgtree.Package - p.CommentPath = string(b.Get(cacheKeyComment)) - if ip := b.Bucket(cacheKeyImport); ip != nil { - err := ip.ForEach(func(_, v []byte) error { - p.Imports = append(p.Imports, string(v)) - return nil - }) - if err != nil { - return pkgtree.PackageOrErr{}, err - } - } - p.Name = string(b.Get(cacheKeyName)) - if tip := b.Bucket(cacheKeyTestImport); tip != nil { - err := tip.ForEach(func(_, v []byte) error { - p.TestImports = append(p.TestImports, string(v)) - return nil - }) - if err != nil { - return pkgtree.PackageOrErr{}, err - } - } - return pkgtree.PackageOrErr{P: p}, nil -} - -// cacheTimestampedKey returns a prefixed key with a trailing timestamp. -func cacheTimestampedKey(pre byte, t time.Time) []byte { - b := make([]byte, 9) - b[0] = pre - binary.BigEndian.PutUint64(b[1:], uint64(t.Unix())) - return b -} - -// boltTxOrBucket is a minimal interface satisfied by bolt.Tx and bolt.Bucket. -type boltTxOrBucket interface { - Cursor() *bolt.Cursor - DeleteBucket([]byte) error - Bucket([]byte) *bolt.Bucket -} - -// cachePrefixDelete prefix scans and deletes each bucket. -func cachePrefixDelete(tob boltTxOrBucket, pre byte) error { - c := tob.Cursor() - for k, _ := c.Seek([]byte{pre}); len(k) > 0 && k[0] == pre; k, _ = c.Next() { - if err := tob.DeleteBucket(k); err != nil { - return errors.Wrapf(err, "failed to delete bucket: %s", k) - } - } - return nil -} - -// cacheFindLatestValid prefix scans for the latest bucket which is timestamped >= epoch, -// or returns nil if none exists. -func cacheFindLatestValid(tob boltTxOrBucket, pre byte, epoch int64) *bolt.Bucket { - c := tob.Cursor() - var latest []byte - for k, _ := c.Seek([]byte{pre}); len(k) > 0 && k[0] == pre; k, _ = c.Next() { - latest = k - } - if latest == nil { - return nil - } - ts := latest[1:] - if len(ts) != 8 { - return nil - } - if int64(binary.BigEndian.Uint64(ts)) < epoch { - return nil - } - return tob.Bucket(latest) -} diff --git a/vendor/github.com/golang/dep/gps/source_cache_multi.go b/vendor/github.com/golang/dep/gps/source_cache_multi.go deleted file mode 100644 index e28a2b1cadd71250a355d5b86960416c4d1632f6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_cache_multi.go +++ /dev/null @@ -1,120 +0,0 @@ -// 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 gps - -import ( - "github.com/golang/dep/gps/pkgtree" -) - -// A multiCache manages two cache levels, ephemeral in-memory and persistent on-disk. -// -// The in-memory cache is always checked first, with the on-disk used as a fallback. -// Values read from disk are set in-memory when an appropriate method exists. -// -// Set values are cached both in-memory and on-disk. -type multiCache struct { - mem, disk singleSourceCache -} - -func (c *multiCache) setManifestAndLock(r Revision, ai ProjectAnalyzerInfo, m Manifest, l Lock) { - c.mem.setManifestAndLock(r, ai, m, l) - c.disk.setManifestAndLock(r, ai, m, l) -} - -func (c *multiCache) getManifestAndLock(r Revision, ai ProjectAnalyzerInfo) (Manifest, Lock, bool) { - m, l, ok := c.mem.getManifestAndLock(r, ai) - if ok { - return m, l, true - } - - m, l, ok = c.disk.getManifestAndLock(r, ai) - if ok { - c.mem.setManifestAndLock(r, ai, m, l) - return m, l, true - } - - return nil, nil, false -} - -func (c *multiCache) setPackageTree(r Revision, ptree pkgtree.PackageTree) { - c.mem.setPackageTree(r, ptree) - c.disk.setPackageTree(r, ptree) -} - -func (c *multiCache) getPackageTree(r Revision) (pkgtree.PackageTree, bool) { - ptree, ok := c.mem.getPackageTree(r) - if ok { - return ptree, true - } - - ptree, ok = c.disk.getPackageTree(r) - if ok { - c.mem.setPackageTree(r, ptree) - return ptree, true - } - - return pkgtree.PackageTree{}, false -} - -func (c *multiCache) markRevisionExists(r Revision) { - c.mem.markRevisionExists(r) - c.disk.markRevisionExists(r) -} - -func (c *multiCache) setVersionMap(pvs []PairedVersion) { - c.mem.setVersionMap(pvs) - c.disk.setVersionMap(pvs) -} - -func (c *multiCache) getVersionsFor(rev Revision) ([]UnpairedVersion, bool) { - uvs, ok := c.mem.getVersionsFor(rev) - if ok { - return uvs, true - } - - return c.disk.getVersionsFor(rev) -} - -func (c *multiCache) getAllVersions() ([]PairedVersion, bool) { - pvs, ok := c.mem.getAllVersions() - if ok { - return pvs, true - } - - pvs, ok = c.disk.getAllVersions() - if ok { - c.mem.setVersionMap(pvs) - return pvs, true - } - - return nil, false -} - -func (c *multiCache) getRevisionFor(uv UnpairedVersion) (Revision, bool) { - rev, ok := c.mem.getRevisionFor(uv) - if ok { - return rev, true - } - - return c.disk.getRevisionFor(uv) -} - -func (c *multiCache) toRevision(v Version) (Revision, bool) { - rev, ok := c.mem.toRevision(v) - if ok { - return rev, true - } - - return c.disk.toRevision(v) -} - -func (c *multiCache) toUnpaired(v Version) (UnpairedVersion, bool) { - uv, ok := c.mem.toUnpaired(v) - if ok { - return uv, true - } - - return c.disk.toUnpaired(v) -} diff --git a/vendor/github.com/golang/dep/gps/source_errors.go b/vendor/github.com/golang/dep/gps/source_errors.go deleted file mode 100644 index e8aab9a77e0c679e651cd5f41012412e6a01ead0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_errors.go +++ /dev/null @@ -1,35 +0,0 @@ -// 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 gps - -import ( - "github.com/Masterminds/vcs" - "github.com/pkg/errors" -) - -// unwrapVcsErr recognizes *vcs.LocalError and *vsc.RemoteError, and returns a form -// preserving the actual vcs command output and error, in addition to the message. -// All other types pass through unchanged. -func unwrapVcsErr(err error) error { - var cause error - var out, msg string - - switch t := err.(type) { - case *vcs.LocalError: - cause, out, msg = t.Original(), t.Out(), t.Error() - case *vcs.RemoteError: - cause, out, msg = t.Original(), t.Out(), t.Error() - - default: - return err - } - - if cause == nil { - cause = errors.New(out) - } else { - cause = errors.Wrap(cause, out) - } - return errors.Wrap(cause, msg) -} diff --git a/vendor/github.com/golang/dep/gps/source_manager.go b/vendor/github.com/golang/dep/gps/source_manager.go deleted file mode 100644 index 26683979cc1b66643f7ac9546de1bfcdd8bcf7d8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/source_manager.go +++ /dev/null @@ -1,783 +0,0 @@ -// 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 gps - -import ( - "context" - "fmt" - "io/ioutil" - "log" - "net/url" - "os" - "os/signal" - "path/filepath" - "runtime" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/dep/internal/fs" - "github.com/nightlyone/lockfile" - "github.com/pkg/errors" - "github.com/sdboyer/constext" -) - -// Used to compute a friendly filepath from a URL-shaped input. -var sanitizer = strings.NewReplacer("-", "--", ":", "-", "/", "-", "+", "-") - -// A locker is responsible for preventing multiple instances of dep from -// interfering with one-another. -// -// Currently, anything that can either TryLock(), Unlock(), or GetOwner() -// satisfies that need. -type locker interface { - TryLock() error - Unlock() error - GetOwner() (*os.Process, error) -} - -// A falselocker adheres to the locker interface and its purpose is to quietly -// fail to lock when the DEPNOLOCK environment variable is set. -// -// This allows dep to run on systems where file locking doesn't work -- -// particularly those that use union mount type filesystems that don't -// implement hard links or fnctl() style locking. -type falseLocker struct{} - -// Always returns an error to indicate there's no current ower PID for our -// lock. -func (fl falseLocker) GetOwner() (*os.Process, error) { - return nil, fmt.Errorf("falseLocker always fails") -} - -// Does nothing and returns a nil error so caller believes locking succeeded. -func (fl falseLocker) TryLock() error { - return nil -} - -// Does nothing and returns a nil error so caller believes unlocking succeeded. -func (fl falseLocker) Unlock() error { - return nil -} - -// A SourceManager is responsible for retrieving, managing, and interrogating -// source repositories. Its primary purpose is to serve the needs of a Solver, -// but it is handy for other purposes, as well. -// -// gps's built-in SourceManager, SourceMgr, is intended to be generic and -// sufficient for any purpose. It provides some additional semantics around the -// methods defined here. -type SourceManager interface { - // SourceExists checks if a repository exists, either upstream or in the - // SourceManager's central repository cache. - SourceExists(ProjectIdentifier) (bool, error) - - // SyncSourceFor will attempt to bring all local information about a source - // fully up to date. - SyncSourceFor(ProjectIdentifier) error - - // ListVersions retrieves a list of the available versions for a given - // repository name. - ListVersions(ProjectIdentifier) ([]PairedVersion, error) - - // RevisionPresentIn indicates whether the provided Version is present in - // the given repository. - RevisionPresentIn(ProjectIdentifier, Revision) (bool, error) - - // ListPackages parses the tree of the Go packages at or below root of the - // provided ProjectIdentifier, at the provided version. - ListPackages(ProjectIdentifier, Version) (pkgtree.PackageTree, error) - - // GetManifestAndLock returns manifest and lock information for the provided - // root import path. - // - // gps currently requires that projects be rooted at their repository root, - // necessitating that the ProjectIdentifier's ProjectRoot must also be a - // repository root. - GetManifestAndLock(ProjectIdentifier, Version, ProjectAnalyzer) (Manifest, Lock, error) - - // ExportProject writes out the tree of the provided import path, at the - // provided version, to the provided directory. - ExportProject(context.Context, ProjectIdentifier, Version, string) error - - // DeduceProjectRoot takes an import path and deduces the corresponding - // project/source root. - DeduceProjectRoot(ip string) (ProjectRoot, error) - - // SourceURLsForPath takes an import path and deduces the set of source URLs - // that may refer to a canonical upstream source. - // In general, these URLs differ only by protocol (e.g. https vs. ssh), not path - SourceURLsForPath(ip string) ([]*url.URL, error) - - // Release lets go of any locks held by the SourceManager. Once called, it is - // no longer safe to call methods against it; all method calls will - // immediately result in errors. - Release() - - // InferConstraint tries to puzzle out what kind of version is given in a string - - // semver, a revision, or as a fallback, a plain tag - InferConstraint(s string, pi ProjectIdentifier) (Constraint, error) -} - -// A ProjectAnalyzer is responsible for analyzing a given path for Manifest and -// Lock information. Tools relying on gps must implement one. -type ProjectAnalyzer interface { - // Perform analysis of the filesystem tree rooted at path, with the - // root import path importRoot, to determine the project's constraints, as - // indicated by a Manifest and Lock. - // - // Note that an error will typically cause the solver to treat the analyzed - // version as unusable. As such, an error should generally only be returned - // if the code tree is somehow malformed, but not if the implementor's - // expected files containing Manifest and Lock data are merely absent. - DeriveManifestAndLock(path string, importRoot ProjectRoot) (Manifest, Lock, error) - - // Info reports this project analyzer's info. - Info() ProjectAnalyzerInfo -} - -// ProjectAnalyzerInfo indicates a ProjectAnalyzer's name and version. -type ProjectAnalyzerInfo struct { - Name string - Version int -} - -// String returns a string like: "<name>.<decimal version>" -func (p ProjectAnalyzerInfo) String() string { - return fmt.Sprintf("%s.%d", p.Name, p.Version) -} - -// SourceMgr is the default SourceManager for gps. -// -// There's no (planned) reason why it would need to be reimplemented by other -// tools; control via dependency injection is intended to be sufficient. -type SourceMgr struct { - cachedir string // path to root of cache dir - lf locker // handle for the sm lock file on disk - suprvsr *supervisor // subsystem that supervises running calls/io - cancelAll context.CancelFunc // cancel func to kill all running work - deduceCoord *deductionCoordinator // subsystem that manages import path deduction - srcCoord *sourceCoordinator // subsystem that manages sources - sigmut sync.Mutex // mutex protecting signal handling setup/teardown - qch chan struct{} // quit chan for signal handler - relonce sync.Once // once-er to ensure we only release once - releasing int32 // flag indicating release of sm has begun -} - -var _ SourceManager = &SourceMgr{} - -// ErrSourceManagerIsReleased is the error returned by any SourceManager method -// called after the SourceManager has been released, rendering its methods no -// longer safe to call. -var ErrSourceManagerIsReleased = fmt.Errorf("this SourceManager has been released, its methods can no longer be called") - -// SourceManagerConfig holds configuration information for creating SourceMgrs. -type SourceManagerConfig struct { - Cachedir string // Where to store local instances of upstream sources. - Logger *log.Logger // Optional info/warn logger. Discards if nil. - DisableLocking bool // True if the SourceManager should NOT use a lock file to protect the Cachedir from multiple processes. -} - -// NewSourceManager produces an instance of gps's built-in SourceManager. -// -// The returned SourceManager aggressively caches information wherever possible. -// If tools need to do preliminary work involving upstream repository analysis -// prior to invoking a solve run, it is recommended that they create this -// SourceManager as early as possible and use it to their ends. That way, the -// solver can benefit from any caches that may have already been warmed. -// -// gps's SourceManager is intended to be threadsafe (if it's not, please file a -// bug!). It should be safe to reuse across concurrent solving runs, even on -// unrelated projects. -func NewSourceManager(c SourceManagerConfig) (*SourceMgr, error) { - if c.Logger == nil { - c.Logger = log.New(ioutil.Discard, "", 0) - } - - err := fs.EnsureDir(filepath.Join(c.Cachedir, "sources"), 0777) - if err != nil { - return nil, err - } - - // Fix for #820 - // - // Consult https://godoc.org/github.com/nightlyone/lockfile for the lockfile - // behaviour. It's magic. It deals with stale processes, and if there is - // a process keeping the lock busy, it will pass back a temporary error that - // we can spin on. - - glpath := filepath.Join(c.Cachedir, "sm.lock") - - lockfile, err := func() (locker, error) { - if c.DisableLocking { - return falseLocker{}, nil - } - return lockfile.New(glpath) - }() - - if err != nil { - return nil, CouldNotCreateLockError{ - Path: glpath, - Err: errors.Wrapf(err, "unable to create lock %s", glpath), - } - } - - process, err := lockfile.GetOwner() - if err == nil { - // If we didn't get an error, then the lockfile exists already. We should - // check to see if it's us already: - if process.Pid == os.Getpid() { - return nil, CouldNotCreateLockError{ - Path: glpath, - Err: fmt.Errorf("lockfile %s already locked by this process", glpath), - } - } - - // There is a lockfile, but it's owned by someone else. We'll try to lock - // it anyway. - } - - // If it's a TemporaryError, we retry every second. Otherwise, we fail - // permanently. - // - // TODO: #534 needs to be implemented to provide a better way to log warnings, - // but until then we will just use stderr. - - // Implicit Time of 0. - var lasttime time.Time - err = lockfile.TryLock() - for err != nil { - nowtime := time.Now() - duration := nowtime.Sub(lasttime) - - // The first time this is evaluated, duration will be very large as lasttime is 0. - // Unless time travel is invented and someone travels back to the year 1, we should - // be ok. - if duration > 15*time.Second { - fmt.Fprintf(os.Stderr, "waiting for lockfile %s: %s\n", glpath, err.Error()) - lasttime = nowtime - } - - if t, ok := err.(interface { - Temporary() bool - }); ok && t.Temporary() { - time.Sleep(time.Second * 1) - } else { - return nil, CouldNotCreateLockError{ - Path: glpath, - Err: errors.Wrapf(err, "unable to lock %s", glpath), - } - } - err = lockfile.TryLock() - } - - ctx, cf := context.WithCancel(context.TODO()) - superv := newSupervisor(ctx) - deducer := newDeductionCoordinator(superv) - - sm := &SourceMgr{ - cachedir: c.Cachedir, - lf: lockfile, - suprvsr: superv, - cancelAll: cf, - deduceCoord: deducer, - srcCoord: newSourceCoordinator(superv, deducer, c.Cachedir, c.Logger), - qch: make(chan struct{}), - } - - return sm, nil -} - -// Cachedir returns the location of the cache directory. -func (sm *SourceMgr) Cachedir() string { - return sm.cachedir -} - -// UseDefaultSignalHandling sets up typical os.Interrupt signal handling for a -// SourceMgr. -func (sm *SourceMgr) UseDefaultSignalHandling() { - sigch := make(chan os.Signal, 1) - signal.Notify(sigch, os.Interrupt) - sm.HandleSignals(sigch) -} - -// HandleSignals sets up logic to handle incoming signals with the goal of -// shutting down the SourceMgr safely. -// -// Calling code must provide the signal channel, and is responsible for calling -// signal.Notify() on that channel. -// -// Successive calls to HandleSignals() will deregister the previous handler and -// set up a new one. It is not recommended that the same channel be passed -// multiple times to this method. -// -// SetUpSigHandling() will set up a handler that is appropriate for most -// use cases. -func (sm *SourceMgr) HandleSignals(sigch chan os.Signal) { - sm.sigmut.Lock() - // always start by closing the qch, which will lead to any existing signal - // handler terminating, and deregistering its sigch. - if sm.qch != nil { - close(sm.qch) - } - sm.qch = make(chan struct{}) - - // Run a new goroutine with the input sigch and the fresh qch - go func(sch chan os.Signal, qch <-chan struct{}) { - defer signal.Stop(sch) - select { - case <-sch: - // Set up a timer to uninstall the signal handler after three - // seconds, so that the user can easily force termination with a - // second ctrl-c - time.AfterFunc(3*time.Second, func() { - signal.Stop(sch) - }) - - if opc := sm.suprvsr.count(); opc > 0 { - fmt.Printf("Signal received: waiting for %v ops to complete...\n", opc) - } - - sm.Release() - case <-qch: - // quit channel triggered - deregister our sigch and return - } - }(sigch, sm.qch) - // Try to ensure handler is blocked in for-select before releasing the mutex - runtime.Gosched() - - sm.sigmut.Unlock() -} - -// StopSignalHandling deregisters any signal handler running on this SourceMgr. -// -// It's normally not necessary to call this directly; it will be called as -// needed by Release(). -func (sm *SourceMgr) StopSignalHandling() { - sm.sigmut.Lock() - if sm.qch != nil { - close(sm.qch) - sm.qch = nil - runtime.Gosched() - } - sm.sigmut.Unlock() -} - -// CouldNotCreateLockError describe failure modes in which creating a SourceMgr -// did not succeed because there was an error while attempting to create the -// on-disk lock file. -type CouldNotCreateLockError struct { - Path string - Err error -} - -func (e CouldNotCreateLockError) Error() string { - return e.Err.Error() -} - -// Release lets go of any locks held by the SourceManager. Once called, it is no -// longer safe to call methods against it; all method calls will immediately -// result in errors. -func (sm *SourceMgr) Release() { - atomic.StoreInt32(&sm.releasing, 1) - - sm.relonce.Do(func() { - // Send the signal to the supervisor to cancel all running calls. - sm.cancelAll() - sm.suprvsr.wait() - - // Close the source coordinator. - sm.srcCoord.close() - - // Close the file handle for the lock file and remove it from disk - sm.lf.Unlock() - os.Remove(filepath.Join(sm.cachedir, "sm.lock")) - - // Close the qch, if non-nil, so the signal handlers run out. This will - // also deregister the sig channel, if any has been set up. - if sm.qch != nil { - close(sm.qch) - } - }) -} - -// GetManifestAndLock returns manifest and lock information for the provided -// ProjectIdentifier, at the provided Version. The work of producing the -// manifest and lock is delegated to the provided ProjectAnalyzer's -// DeriveManifestAndLock() method. -func (sm *SourceMgr) GetManifestAndLock(id ProjectIdentifier, v Version, an ProjectAnalyzer) (Manifest, Lock, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return nil, nil, ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - return nil, nil, err - } - - return srcg.getManifestAndLock(context.TODO(), id.ProjectRoot, v, an) -} - -// ListPackages parses the tree of the Go packages at and below the ProjectRoot -// of the given ProjectIdentifier, at the given version. -func (sm *SourceMgr) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return pkgtree.PackageTree{}, ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - return pkgtree.PackageTree{}, err - } - - return srcg.listPackages(context.TODO(), id.ProjectRoot, v) -} - -// ListVersions retrieves a list of the available versions for a given -// repository name. -// -// The list is not sorted; while it may be returned in the order that the -// underlying VCS reports version information, no guarantee is made. It is -// expected that the caller either not care about order, or sort the result -// themselves. -// -// This list is always retrieved from upstream on the first call. Subsequent -// calls will return a cached version of the first call's results. if upstream -// is not accessible (network outage, access issues, or the resource actually -// went away), an error will be returned. -func (sm *SourceMgr) ListVersions(id ProjectIdentifier) ([]PairedVersion, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return nil, ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - // TODO(sdboyer) More-er proper-er errors - return nil, err - } - - return srcg.listVersions(context.TODO()) -} - -// RevisionPresentIn indicates whether the provided Revision is present in the given -// repository. -func (sm *SourceMgr) RevisionPresentIn(id ProjectIdentifier, r Revision) (bool, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return false, ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - // TODO(sdboyer) More-er proper-er errors - return false, err - } - - return srcg.revisionPresentIn(context.TODO(), r) -} - -// SourceExists checks if a repository exists, either upstream or in the cache, -// for the provided ProjectIdentifier. -func (sm *SourceMgr) SourceExists(id ProjectIdentifier) (bool, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return false, ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - return false, err - } - - ctx := context.TODO() - return srcg.existsInCache(ctx) || srcg.existsUpstream(ctx), nil -} - -// SyncSourceFor will ensure that all local caches and information about a -// source are up to date with any network-acccesible information. -// -// The primary use case for this is prefetching. -func (sm *SourceMgr) SyncSourceFor(id ProjectIdentifier) error { - if atomic.LoadInt32(&sm.releasing) == 1 { - return ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), id) - if err != nil { - return err - } - - return srcg.syncLocal(context.TODO()) -} - -// ExportProject writes out the tree of the provided ProjectIdentifier's -// ProjectRoot, at the provided version, to the provided directory. -func (sm *SourceMgr) ExportProject(ctx context.Context, id ProjectIdentifier, v Version, to string) error { - if atomic.LoadInt32(&sm.releasing) == 1 { - return ErrSourceManagerIsReleased - } - - srcg, err := sm.srcCoord.getSourceGatewayFor(ctx, id) - if err != nil { - return err - } - - return srcg.exportVersionTo(ctx, v, to) -} - -// DeduceProjectRoot takes an import path and deduces the corresponding -// project/source root. -// -// Note that some import paths may require network activity to correctly -// determine the root of the path, such as, but not limited to, vanity import -// paths. (A special exception is written for gopkg.in to minimize network -// activity, as its behavior is well-structured) -func (sm *SourceMgr) DeduceProjectRoot(ip string) (ProjectRoot, error) { - if atomic.LoadInt32(&sm.releasing) == 1 { - return "", ErrSourceManagerIsReleased - } - - // TODO(sdboyer) refactor deduceRootPath() so that this validation can move - // back down below a cache point, rather than executing on every call. - if !pathvld.MatchString(ip) { - return "", errors.Errorf("%q is not a valid import path", ip) - } - - pd, err := sm.deduceCoord.deduceRootPath(context.TODO(), ip) - return ProjectRoot(pd.root), err -} - -// InferConstraint tries to puzzle out what kind of version is given in a -// string. Preference is given first for branches, then semver constraints, then -// plain tags, and then revisions. -func (sm *SourceMgr) InferConstraint(s string, pi ProjectIdentifier) (Constraint, error) { - if s == "" { - return Any(), nil - } - - // Lookup the string in the repository - var version PairedVersion - versions, err := sm.ListVersions(pi) - if err != nil { - return nil, errors.Wrapf(err, "list versions for %s", pi) // means repo does not exist - } - SortPairedForUpgrade(versions) - for _, v := range versions { - if s == v.String() { - version = v - break - } - } - - // Branch - if version != nil && version.Type() == IsBranch { - return version.Unpair(), nil - } - - // Semver Constraint - c, err := NewSemverConstraintIC(s) - if c != nil && err == nil { - return c, nil - } - - // Tag - if version != nil { - return version.Unpair(), nil - } - - // Revision, possibly abbreviated - r, err := sm.disambiguateRevision(context.TODO(), pi, Revision(s)) - if err == nil { - return r, nil - } - - return nil, errors.Errorf("%s is not a valid version for the package %s(%s)", s, pi.ProjectRoot, pi.Source) -} - -// SourceURLsForPath takes an import path and deduces the set of source URLs -// that may refer to a canonical upstream source. -// In general, these URLs differ only by protocol (e.g. https vs. ssh), not path -func (sm *SourceMgr) SourceURLsForPath(ip string) ([]*url.URL, error) { - deduced, err := sm.deduceCoord.deduceRootPath(context.TODO(), ip) - if err != nil { - return nil, err - } - - return deduced.mb.possibleURLs(), nil -} - -// disambiguateRevision looks up a revision in the underlying source, spitting -// it back out in an unabbreviated, disambiguated form. -// -// For example, if pi refers to a git-based project, then rev could be an -// abbreviated git commit hash. disambiguateRevision would return the complete -// hash. -func (sm *SourceMgr) disambiguateRevision(ctx context.Context, pi ProjectIdentifier, rev Revision) (Revision, error) { - srcg, err := sm.srcCoord.getSourceGatewayFor(context.TODO(), pi) - if err != nil { - return "", err - } - return srcg.disambiguateRevision(ctx, rev) -} - -type timeCount struct { - count int - start time.Time -} - -type durCount struct { - count int - dur time.Duration -} - -type supervisor struct { - ctx context.Context - mu sync.Mutex // Guards all maps - cond sync.Cond // Wraps mu so callers can wait until all calls end - running map[callInfo]timeCount - ran map[callType]durCount -} - -func newSupervisor(ctx context.Context) *supervisor { - supv := &supervisor{ - ctx: ctx, - running: make(map[callInfo]timeCount), - ran: make(map[callType]durCount), - } - - supv.cond = sync.Cond{L: &supv.mu} - return supv -} - -// do executes the incoming closure using a conjoined context, and keeps -// counters to ensure the sourceMgr can't finish Release()ing until after all -// calls have returned. -func (sup *supervisor) do(inctx context.Context, name string, typ callType, f func(context.Context) error) error { - ci := callInfo{ - name: name, - typ: typ, - } - - octx, err := sup.start(ci) - if err != nil { - return err - } - - cctx, cancelFunc := constext.Cons(inctx, octx) - err = f(cctx) - sup.done(ci) - cancelFunc() - return err -} - -func (sup *supervisor) start(ci callInfo) (context.Context, error) { - sup.mu.Lock() - defer sup.mu.Unlock() - if err := sup.ctx.Err(); err != nil { - // We've already been canceled; error out. - return nil, err - } - - if existingInfo, has := sup.running[ci]; has { - existingInfo.count++ - sup.running[ci] = existingInfo - } else { - sup.running[ci] = timeCount{ - count: 1, - start: time.Now(), - } - } - - return sup.ctx, nil -} - -func (sup *supervisor) count() int { - sup.mu.Lock() - defer sup.mu.Unlock() - return len(sup.running) -} - -func (sup *supervisor) done(ci callInfo) { - sup.mu.Lock() - - existingInfo, has := sup.running[ci] - if !has { - panic(fmt.Sprintf("sourceMgr: tried to complete a call that had not registered via run()")) - } - - if existingInfo.count > 1 { - // If more than one is pending, don't stop the clock yet. - existingInfo.count-- - sup.running[ci] = existingInfo - } else { - // Last one for this particular key; update metrics with info. - durCnt := sup.ran[ci.typ] - durCnt.count++ - durCnt.dur += time.Since(existingInfo.start) - sup.ran[ci.typ] = durCnt - delete(sup.running, ci) - - if len(sup.running) == 0 { - // This is the only place where we signal the cond, as it's the only - // time that the number of running calls could become zero. - sup.cond.Signal() - } - } - sup.mu.Unlock() -} - -// wait until all active calls have terminated. -// -// Assumes something else has already canceled the supervisor via its context. -func (sup *supervisor) wait() { - sup.cond.L.Lock() - for len(sup.running) > 0 { - sup.cond.Wait() - } - sup.cond.L.Unlock() -} - -type callType uint - -const ( - ctHTTPMetadata callType = iota - ctListVersions - ctGetManifestAndLock - ctListPackages - ctSourcePing - ctSourceInit - ctSourceFetch - ctExportTree - ctValidateLocal -) - -func (ct callType) String() string { - switch ct { - case ctHTTPMetadata: - return "Retrieving go get metadata" - case ctListVersions: - return "Retrieving latest version list" - case ctGetManifestAndLock: - return "Reading manifest and lock data" - case ctListPackages: - return "Parsing PackageTree" - case ctSourcePing: - return "Checking for upstream existence" - case ctSourceInit: - return "Initializing local source cache" - case ctSourceFetch: - return "Fetching latest data into local source cache" - case ctExportTree: - return "Writing code tree out to disk" - default: - panic("unknown calltype") - } -} - -// callInfo provides metadata about an ongoing call. -type callInfo struct { - name string - typ callType -} diff --git a/vendor/github.com/golang/dep/gps/strings.go b/vendor/github.com/golang/dep/gps/strings.go deleted file mode 100644 index 6ca7b3d9f475847860d00a86d45ca805906404c2..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/strings.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 gps - -import ( - "bytes" - "unicode" - "unicode/utf8" -) - -// toFold returns a string with the property that strings.EqualFold(s, t) iff -// ToFold(s) == ToFold(t) This lets us test a large set of strings for -// fold-equivalent duplicates without making a quadratic number of calls to -// EqualFold. Note that strings.ToUpper and strings.ToLower do not have the -// desired property in some corner cases. -// -// This is hoisted from toolchain internals: src/cmd/go/internal/str/str.go -func toFold(s string) string { - // Fast path: all ASCII, no upper case. - // Most paths look like this already. - for i := 0; i < len(s); i++ { - c := s[i] - if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' { - goto Slow - } - } - return s - -Slow: - var buf bytes.Buffer - for _, r := range s { - // SimpleFold(x) cycles to the next equivalent rune > x - // or wraps around to smaller values. Iterate until it wraps, - // and we've found the minimum value. - for { - r0 := r - r = unicode.SimpleFold(r0) - if r <= r0 { - break - } - } - // Exception to allow fast path above: A-Z => a-z - if 'A' <= r && r <= 'Z' { - r += 'a' - 'A' - } - buf.WriteRune(r) - } - return buf.String() -} diff --git a/vendor/github.com/golang/dep/gps/trace.go b/vendor/github.com/golang/dep/gps/trace.go deleted file mode 100644 index 4c579d30aadf9fd77eba69fc3fe8efdde595b891..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/trace.go +++ /dev/null @@ -1,205 +0,0 @@ -// 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 gps - -import ( - "fmt" - "strconv" - "strings" - - "github.com/golang/dep/gps/pkgtree" -) - -const ( - successChar = "✓" - successCharSp = successChar + " " - failChar = "✗" - failCharSp = failChar + " " - backChar = "â†" - innerIndent = " " -) - -func (s *solver) traceCheckPkgs(bmi bimodalIdentifier) { - if s.tl == nil { - return - } - - prefix := getprei(len(s.vqs) + 1) - s.tl.Printf("%s\n", tracePrefix(fmt.Sprintf("? revisit %s to add %v pkgs", bmi.id, len(bmi.pl)), prefix, prefix)) -} - -func (s *solver) traceCheckQueue(q *versionQueue, bmi bimodalIdentifier, cont bool, offset int) { - if s.tl == nil { - return - } - - prefix := getprei(len(s.vqs) + offset) - vlen := strconv.Itoa(len(q.pi)) - if !q.allLoaded { - vlen = "at least " + vlen - } - - // TODO(sdboyer) how...to list the packages in the limited space we have? - var verb string - indent := "" - if cont { - // Continue is an "inner" message.. indenting - verb = "continue" - vlen = vlen + " more" - indent = innerIndent - } else { - verb = "attempt" - } - - s.tl.Printf("%s\n", tracePrefix(fmt.Sprintf("%s? %s %s with %v pkgs; %s versions to try", indent, verb, bmi.id, len(bmi.pl), vlen), prefix, prefix)) -} - -// traceStartBacktrack is called with the bmi that first failed, thus initiating -// backtracking -func (s *solver) traceStartBacktrack(bmi bimodalIdentifier, err error, pkgonly bool) { - if s.tl == nil { - return - } - - var msg string - if pkgonly { - msg = fmt.Sprintf("%s%s could not add %v pkgs to %s; begin backtrack", innerIndent, backChar, len(bmi.pl), bmi.id) - } else { - msg = fmt.Sprintf("%s%s no more versions of %s to try; begin backtrack", innerIndent, backChar, bmi.id) - } - - prefix := getprei(len(s.sel.projects)) - s.tl.Printf("%s\n", tracePrefix(msg, prefix, prefix)) -} - -// traceBacktrack is called when a package or project is poppped off during -// backtracking -func (s *solver) traceBacktrack(bmi bimodalIdentifier, pkgonly bool) { - if s.tl == nil { - return - } - - var msg string - if pkgonly { - msg = fmt.Sprintf("%s backtrack: popped %v pkgs from %s", backChar, len(bmi.pl), bmi.id) - } else { - msg = fmt.Sprintf("%s backtrack: no more versions of %s to try", backChar, bmi.id) - } - - prefix := getprei(len(s.sel.projects)) - s.tl.Printf("%s\n", tracePrefix(msg, prefix, prefix)) -} - -// Called just once after solving has finished, whether success or not -func (s *solver) traceFinish(sol solution, err error) { - if s.tl == nil { - return - } - - if err == nil { - var pkgcount int - for _, lp := range sol.Projects() { - pkgcount += len(lp.pkgs) - } - s.tl.Printf("%s%s found solution with %v packages from %v projects", innerIndent, successChar, pkgcount, len(sol.Projects())) - } else { - s.tl.Printf("%s%s solving failed", innerIndent, failChar) - } -} - -// traceSelectRoot is called just once, when the root project is selected -func (s *solver) traceSelectRoot(ptree pkgtree.PackageTree, cdeps []completeDep) { - if s.tl == nil { - return - } - - // This duplicates work a bit, but we're in trace mode and it's only once, - // so who cares - rm, _ := ptree.ToReachMap(true, true, false, s.rd.ir) - - s.tl.Printf("Root project is %q", s.rd.rpt.ImportRoot) - - var expkgs int - for _, cdep := range cdeps { - expkgs += len(cdep.pl) - } - - // TODO(sdboyer) include info on ignored pkgs/imports, etc. - s.tl.Printf(" %v transitively valid internal packages", len(rm)) - s.tl.Printf(" %v external packages imported from %v projects", expkgs, len(cdeps)) - s.tl.Printf("(0) " + successCharSp + "select (root)") -} - -// traceSelect is called when an atom is successfully selected -func (s *solver) traceSelect(awp atomWithPackages, pkgonly bool) { - if s.tl == nil { - return - } - - var msg string - if pkgonly { - msg = fmt.Sprintf("%s%s include %v more pkgs from %s", innerIndent, successChar, len(awp.pl), a2vs(awp.a)) - } else { - msg = fmt.Sprintf("%s select %s w/%v pkgs", successChar, a2vs(awp.a), len(awp.pl)) - } - - prefix := getprei(len(s.sel.projects) - 1) - s.tl.Printf("%s\n", tracePrefix(msg, prefix, prefix)) -} - -func (s *solver) traceInfo(args ...interface{}) { - if s.tl == nil { - return - } - - if len(args) == 0 { - panic("must pass at least one param to traceInfo") - } - - preflen := len(s.sel.projects) - var msg string - switch data := args[0].(type) { - case string: - msg = tracePrefix(innerIndent+fmt.Sprintf(data, args[1:]...), " ", " ") - case traceError: - preflen++ - // We got a special traceError, use its custom method - msg = tracePrefix(innerIndent+data.traceString(), " ", failCharSp) - case error: - // Regular error; still use the x leader but default Error() string - msg = tracePrefix(innerIndent+data.Error(), " ", failCharSp) - default: - // panic here because this can *only* mean a stupid internal bug - panic(fmt.Sprintf("canary - unknown type passed as first param to traceInfo %T", data)) - } - - prefix := getprei(preflen) - s.tl.Printf("%s\n", tracePrefix(msg, prefix, prefix)) -} - -func getprei(i int) string { - var s string - if i < 10 { - s = fmt.Sprintf("(%d) ", i) - } else if i < 100 { - s = fmt.Sprintf("(%d) ", i) - } else { - s = fmt.Sprintf("(%d) ", i) - } - return s -} - -func tracePrefix(msg, sep, fsep string) string { - parts := strings.Split(strings.TrimSuffix(msg, "\n"), "\n") - for k, str := range parts { - if k == 0 { - parts[k] = fsep + str - } else { - parts[k] = sep + str - } - } - - return strings.Join(parts, "\n") -} diff --git a/vendor/github.com/golang/dep/gps/typed_radix.go b/vendor/github.com/golang/dep/gps/typed_radix.go deleted file mode 100644 index 615f297efdc1046a73262a162caae3ae5909687c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/typed_radix.go +++ /dev/null @@ -1,92 +0,0 @@ -// 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 gps - -import ( - "strings" - "sync" - - "github.com/armon/go-radix" -) - -// Typed implementations of radix trees. These are just simple wrappers that let -// us avoid having to type assert anywhere else, cleaning up other code a bit. -// -// Some of the more annoying things to implement (like walks) aren't -// implemented. They can be added if/when we actually need them. -// -// Oh generics, where art thou... - -type deducerTrie struct { - sync.RWMutex - t *radix.Tree -} - -func newDeducerTrie() *deducerTrie { - return &deducerTrie{ - t: radix.New(), - } -} - -// Suppress unused warning. -var _ = (*deducerTrie)(nil).Delete - -// Delete is used to delete a key, returning the previous value and if it was deleted -func (t *deducerTrie) Delete(s string) (pathDeducer, bool) { - t.Lock() - defer t.Unlock() - if d, had := t.t.Delete(s); had { - return d.(pathDeducer), had - } - return nil, false -} - -// Insert is used to add a newentry or update an existing entry. Returns if updated. -func (t *deducerTrie) Insert(s string, d pathDeducer) (pathDeducer, bool) { - t.Lock() - defer t.Unlock() - if d2, had := t.t.Insert(s, d); had { - return d2.(pathDeducer), had - } - return nil, false -} - -// LongestPrefix is like Get, but instead of an exact match, it will return the -// longest prefix match. -func (t *deducerTrie) LongestPrefix(s string) (string, pathDeducer, bool) { - t.RLock() - defer t.RUnlock() - if p, d, has := t.t.LongestPrefix(s); has { - return p, d.(pathDeducer), has - } - return "", nil, false -} - -// isPathPrefixOrEqual is an additional helper check to ensure that the literal -// string prefix returned from a radix tree prefix match is also a path tree -// match. -// -// The radix tree gets it mostly right, but we have to guard against -// possibilities like this: -// -// github.com/sdboyer/foo -// github.com/sdboyer/foobar/baz -// -// The latter would incorrectly be conflated with the former. As we know we're -// operating on strings that describe import paths, guard against this case by -// verifying that either the input is the same length as the match (in which -// case we know they're equal), or that the next character is a "/". (Import -// paths are defined to always use "/", not the OS-specific path separator.) -func isPathPrefixOrEqual(pre, path string) bool { - prflen, pathlen := len(pre), len(path) - if pathlen == prflen+1 { - // this can never be the case - return false - } - - // we assume something else (a trie) has done equality check up to the point - // of the prefix, so we just check len - return prflen == pathlen || strings.Index(path[prflen:], "/") == 0 -} diff --git a/vendor/github.com/golang/dep/gps/vcs_repo.go b/vendor/github.com/golang/dep/gps/vcs_repo.go deleted file mode 100644 index cb500a5a070311127001e4514d036c248df026df..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/vcs_repo.go +++ /dev/null @@ -1,387 +0,0 @@ -// 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 gps - -import ( - "context" - "encoding/xml" - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - "time" - - "github.com/Masterminds/vcs" - "github.com/pkg/errors" -) - -type ctxRepo interface { - vcs.Repo - get(context.Context) error - fetch(context.Context) error - updateVersion(context.Context, string) error - //ping(context.Context) (bool, error) -} - -func newCtxRepo(s vcs.Type, ustr, path string) (ctxRepo, error) { - r, err := getVCSRepo(s, ustr, path) - if err != nil { - // if vcs could not initialize the repo due to a local error - // then the local repo is in an incorrect state. Remove and - // treat it as a new not-yet-cloned repo. - - // TODO(marwan-at-work): warn/give progress of the above comment. - os.RemoveAll(path) - r, err = getVCSRepo(s, ustr, path) - } - - return r, err -} - -func getVCSRepo(s vcs.Type, ustr, path string) (ctxRepo, error) { - switch s { - case vcs.Git: - repo, err := vcs.NewGitRepo(ustr, path) - return &gitRepo{repo}, err - case vcs.Bzr: - repo, err := vcs.NewBzrRepo(ustr, path) - return &bzrRepo{repo}, err - case vcs.Hg: - repo, err := vcs.NewHgRepo(ustr, path) - return &hgRepo{repo}, err - case vcs.Svn: - repo, err := vcs.NewSvnRepo(ustr, path) - return &svnRepo{repo}, err - default: - panic(fmt.Sprintf("Unrecognized format: %v", s)) - } -} - -// original implementation of these methods come from -// https://github.com/Masterminds/vcs - -type gitRepo struct { - *vcs.GitRepo -} - -func newVcsRemoteErrorOr(err error, args []string, out, msg string) error { - if err == context.Canceled || err == context.DeadlineExceeded { - return err - } - return vcs.NewRemoteError(msg, errors.Wrapf(err, "command failed: %v", args), out) -} - -func newVcsLocalErrorOr(err error, args []string, out, msg string) error { - if err == context.Canceled || err == context.DeadlineExceeded { - return err - } - return vcs.NewLocalError(msg, errors.Wrapf(err, "command failed: %v", args), out) -} - -func (r *gitRepo) get(ctx context.Context) error { - cmd := commandContext( - ctx, - "git", - "clone", - "--recursive", - "-v", - "--progress", - r.Remote(), - r.LocalPath(), - ) - // Ensure no prompting for PWs - cmd.SetEnv(append([]string{"GIT_ASKPASS=", "GIT_TERMINAL_PROMPT=0"}, os.Environ()...)) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to get repository") - } - - return nil -} - -func (r *gitRepo) fetch(ctx context.Context) error { - cmd := commandContext( - ctx, - "git", - "fetch", - "--tags", - "--prune", - r.RemoteLocation, - ) - cmd.SetDir(r.LocalPath()) - // Ensure no prompting for PWs - cmd.SetEnv(append([]string{"GIT_ASKPASS=", "GIT_TERMINAL_PROMPT=0"}, os.Environ()...)) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to update repository") - } - return nil -} - -func (r *gitRepo) updateVersion(ctx context.Context, v string) error { - cmd := commandContext(ctx, "git", "checkout", v) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to update checked out version") - } - - return r.defendAgainstSubmodules(ctx) -} - -// defendAgainstSubmodules tries to keep repo state sane in the event of -// submodules. Or nested submodules. What a great idea, submodules. -func (r *gitRepo) defendAgainstSubmodules(ctx context.Context) error { - // First, update them to whatever they should be, if there should happen to be any. - { - cmd := commandContext( - ctx, - "git", - "submodule", - "update", - "--init", - "--recursive", - ) - cmd.SetDir(r.LocalPath()) - // Ensure no prompting for PWs - cmd.SetEnv(append([]string{"GIT_ASKPASS=", "GIT_TERMINAL_PROMPT=0"}, os.Environ()...)) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unexpected error while defensively updating submodules") - } - } - - // Now, do a special extra-aggressive clean in case changing versions caused - // one or more submodules to go away. - { - cmd := commandContext(ctx, "git", "clean", "-x", "-d", "-f", "-f") - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unexpected error while defensively cleaning up after possible derelict submodule directories") - } - } - - // Then, repeat just in case there are any nested submodules that went away. - { - cmd := commandContext( - ctx, - "git", - "submodule", - "foreach", - "--recursive", - "git", - "clean", "-x", "-d", "-f", "-f", - ) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unexpected error while defensively cleaning up after possible derelict nested submodule directories") - } - } - - return nil -} - -type bzrRepo struct { - *vcs.BzrRepo -} - -func (r *bzrRepo) get(ctx context.Context) error { - basePath := filepath.Dir(filepath.FromSlash(r.LocalPath())) - if _, err := os.Stat(basePath); os.IsNotExist(err) { - err = os.MkdirAll(basePath, 0755) - if err != nil { - return newVcsLocalErrorOr(err, nil, "", "unable to create directory") - } - } - - cmd := commandContext(ctx, "bzr", "branch", r.Remote(), r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to get repository") - } - - return nil -} - -func (r *bzrRepo) fetch(ctx context.Context) error { - cmd := commandContext(ctx, "bzr", "pull") - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to update repository") - } - return nil -} - -func (r *bzrRepo) updateVersion(ctx context.Context, version string) error { - cmd := commandContext(ctx, "bzr", "update", "-r", version) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to update checked out version") - } - return nil -} - -type hgRepo struct { - *vcs.HgRepo -} - -func (r *hgRepo) get(ctx context.Context) error { - cmd := commandContext(ctx, "hg", "clone", r.Remote(), r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to get repository") - } - - return nil -} - -func (r *hgRepo) fetch(ctx context.Context) error { - cmd := commandContext(ctx, "hg", "pull") - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to fetch latest changes") - } - return nil -} - -func (r *hgRepo) updateVersion(ctx context.Context, version string) error { - cmd := commandContext(ctx, "hg", "update", version) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to update checked out version") - } - - return nil -} - -type svnRepo struct { - *vcs.SvnRepo -} - -func (r *svnRepo) get(ctx context.Context) error { - remote := r.Remote() - if strings.HasPrefix(remote, "/") { - remote = "file://" + remote - } else if runtime.GOOS == "windows" && filepath.VolumeName(remote) != "" { - remote = "file:///" + remote - } - - cmd := commandContext(ctx, "svn", "checkout", remote, r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to get repository") - } - - return nil -} - -func (r *svnRepo) fetch(ctx context.Context) error { - cmd := commandContext(ctx, "svn", "update") - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to update repository") - } - - return nil -} - -func (r *svnRepo) updateVersion(ctx context.Context, version string) error { - cmd := commandContext(ctx, "svn", "update", "-r", version) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to update checked out version") - } - - return nil -} - -func (r *svnRepo) CommitInfo(id string) (*vcs.CommitInfo, error) { - ctx := context.TODO() - // There are cases where Svn log doesn't return anything for HEAD or BASE. - // svn info does provide details for these but does not have elements like - // the commit message. - if id == "HEAD" || id == "BASE" { - type commit struct { - Revision string `xml:"revision,attr"` - } - - type info struct { - Commit commit `xml:"entry>commit"` - } - - cmd := commandContext(ctx, "svn", "info", "-r", id, "--xml") - cmd.SetDir(r.LocalPath()) - out, err := cmd.CombinedOutput() - if err != nil { - return nil, newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to retrieve commit information") - } - - infos := new(info) - if err := xml.Unmarshal(out, &infos); err != nil { - return nil, newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to retrieve commit information") - } - - id = infos.Commit.Revision - if id == "" { - return nil, vcs.ErrRevisionUnavailable - } - } - - cmd := commandContext(ctx, "svn", "log", "-r", id, "--xml") - cmd.SetDir(r.LocalPath()) - out, err := cmd.CombinedOutput() - if err != nil { - return nil, newVcsRemoteErrorOr(err, cmd.Args(), string(out), - "unable to retrieve commit information") - } - - type logentry struct { - Author string `xml:"author"` - Date string `xml:"date"` - Msg string `xml:"msg"` - } - - type log struct { - XMLName xml.Name `xml:"log"` - Logs []logentry `xml:"logentry"` - } - - logs := new(log) - if err := xml.Unmarshal(out, &logs); err != nil { - return nil, newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to retrieve commit information") - } - - if len(logs.Logs) == 0 { - return nil, vcs.ErrRevisionUnavailable - } - - ci := &vcs.CommitInfo{ - Commit: id, - Author: logs.Logs[0].Author, - Message: logs.Logs[0].Msg, - } - - if len(logs.Logs[0].Date) > 0 { - ci.Date, err = time.Parse(time.RFC3339Nano, logs.Logs[0].Date) - if err != nil { - return nil, newVcsLocalErrorOr(err, cmd.Args(), string(out), - "unable to retrieve commit information") - } - } - - return ci, nil -} diff --git a/vendor/github.com/golang/dep/gps/vcs_source.go b/vendor/github.com/golang/dep/gps/vcs_source.go deleted file mode 100644 index f6b7aef136fc8b98f37952377ebeefd737674ed3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/vcs_source.go +++ /dev/null @@ -1,690 +0,0 @@ -// 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 gps - -import ( - "bytes" - "context" - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/Masterminds/semver" - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -type baseVCSSource struct { - repo ctxRepo -} - -func (bs *baseVCSSource) sourceType() string { - return string(bs.repo.Vcs()) -} - -func (bs *baseVCSSource) existsLocally(ctx context.Context) bool { - return bs.repo.CheckLocal() -} - -// TODO reimpl for git -func (bs *baseVCSSource) existsUpstream(ctx context.Context) bool { - return !bs.repo.Ping() -} - -func (bs *baseVCSSource) upstreamURL() string { - return bs.repo.Remote() -} - -func (bs *baseVCSSource) disambiguateRevision(ctx context.Context, r Revision) (Revision, error) { - ci, err := bs.repo.CommitInfo(string(r)) - if err != nil { - return "", err - } - return Revision(ci.Commit), nil -} - -func (bs *baseVCSSource) getManifestAndLock(ctx context.Context, pr ProjectRoot, r Revision, an ProjectAnalyzer) (Manifest, Lock, error) { - err := bs.repo.updateVersion(ctx, r.String()) - if err != nil { - return nil, nil, unwrapVcsErr(err) - } - - m, l, err := an.DeriveManifestAndLock(bs.repo.LocalPath(), pr) - if err != nil { - return nil, nil, err - } - - if l != nil && l != Lock(nil) { - l = prepLock(l) - } - - return prepManifest(m), l, nil -} - -func (bs *baseVCSSource) revisionPresentIn(r Revision) (bool, error) { - return bs.repo.IsReference(string(r)), nil -} - -// initLocal clones/checks out the upstream repository to disk for the first -// time. -func (bs *baseVCSSource) initLocal(ctx context.Context) error { - err := bs.repo.get(ctx) - - if err != nil { - return unwrapVcsErr(err) - } - return nil -} - -// updateLocal ensures the local data (versions and code) we have about the -// source is fully up to date with that of the canonical upstream source. -func (bs *baseVCSSource) updateLocal(ctx context.Context) error { - err := bs.repo.fetch(ctx) - - if err != nil { - return unwrapVcsErr(err) - } - return nil -} - -func (bs *baseVCSSource) listPackages(ctx context.Context, pr ProjectRoot, r Revision) (ptree pkgtree.PackageTree, err error) { - err = bs.repo.updateVersion(ctx, r.String()) - - if err != nil { - err = unwrapVcsErr(err) - } else { - ptree, err = pkgtree.ListPackages(bs.repo.LocalPath(), string(pr)) - } - - return -} - -func (bs *baseVCSSource) exportRevisionTo(ctx context.Context, r Revision, to string) error { - // Only make the parent dir, as CopyDir will balk on trying to write to an - // empty but existing dir. - if err := os.MkdirAll(filepath.Dir(to), 0777); err != nil { - return err - } - - if err := bs.repo.updateVersion(ctx, r.String()); err != nil { - return unwrapVcsErr(err) - } - - return fs.CopyDir(bs.repo.LocalPath(), to) -} - -var ( - gitHashRE = regexp.MustCompile(`^[a-f0-9]{40}$`) -) - -// gitSource is a generic git repository implementation that should work with -// all standard git remotes. -type gitSource struct { - baseVCSSource -} - -// ensureClean sees to it that a git repository is clean and in working order, -// or returns an error if the adaptive recovery attempts fail. -func (s *gitSource) ensureClean(ctx context.Context) error { - r := s.repo.(*gitRepo) - cmd := commandContext( - ctx, - "git", - "status", - "--porcelain", - ) - cmd.SetDir(r.LocalPath()) - - out, err := cmd.CombinedOutput() - if err != nil { - // An error on simple git status indicates some aggressive repository - // corruption, outside of the purview that we can deal with here. - return err - } - - if len(bytes.TrimSpace(out)) == 0 { - // No output from status indicates a clean tree, without any modified or - // untracked files - we're in good shape. - return nil - } - - // We could be more parsimonious about this, but it's probably not worth it - // - it's a rare case to have to do any cleanup anyway, so when we do, we - // might as well just throw the kitchen sink at it. - cmd = commandContext( - ctx, - "git", - "reset", - "--hard", - ) - cmd.SetDir(r.LocalPath()) - _, err = cmd.CombinedOutput() - if err != nil { - return err - } - - // We also need to git clean -df; just reuse defendAgainstSubmodules here, - // even though it's a bit layer-breaky. - err = r.defendAgainstSubmodules(ctx) - if err != nil { - return err - } - - // Check status one last time. If it's still not clean, give up. - cmd = commandContext( - ctx, - "git", - "status", - "--porcelain", - ) - cmd.SetDir(r.LocalPath()) - - out, err = cmd.CombinedOutput() - if err != nil { - return err - } - - if len(bytes.TrimSpace(out)) != 0 { - return errors.Errorf("failed to clean up git repository at %s - dirty? corrupted? status output: \n%s", r.LocalPath(), string(out)) - } - - return nil -} - -func (s *gitSource) exportRevisionTo(ctx context.Context, rev Revision, to string) error { - r := s.repo - - if err := os.MkdirAll(to, 0777); err != nil { - return err - } - - // Back up original index - idx, bak := filepath.Join(r.LocalPath(), ".git", "index"), filepath.Join(r.LocalPath(), ".git", "origindex") - err := fs.RenameWithFallback(idx, bak) - if err != nil { - return err - } - - // could have an err here...but it's hard to imagine how? - defer fs.RenameWithFallback(bak, idx) - - { - cmd := commandContext(ctx, "git", "read-tree", rev.String()) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return errors.Wrap(err, string(out)) - } - } - - // Ensure we have exactly one trailing slash - to = strings.TrimSuffix(to, string(os.PathSeparator)) + string(os.PathSeparator) - // Checkout from our temporary index to the desired target location on - // disk; now it's git's job to make it fast. - // - // Sadly, this approach *does* also write out vendor dirs. There doesn't - // appear to be a way to make checkout-index respect sparse checkout - // rules (-a supersedes it). The alternative is using plain checkout, - // though we have a bunch of housekeeping to do to set up, then tear - // down, the sparse checkout controls, as well as restore the original - // index and HEAD. - { - cmd := commandContext(ctx, "git", "checkout-index", "-a", "--prefix="+to) - cmd.SetDir(r.LocalPath()) - if out, err := cmd.CombinedOutput(); err != nil { - return errors.Wrap(err, string(out)) - } - } - - return nil -} - -func (s *gitSource) isValidHash(hash []byte) bool { - return gitHashRE.Match(hash) -} - -func (s *gitSource) listVersions(ctx context.Context) (vlist []PairedVersion, err error) { - r := s.repo - - cmd := commandContext(ctx, "git", "ls-remote", r.Remote()) - // We want to invoke from a place where it's not possible for there to be a - // .git file instead of a .git directory, as git ls-remote will choke on the - // former and erroneously quit. However, we can't be sure that the repo - // exists on disk yet at this point; if it doesn't, then instead use the - // parent of the local path, as that's still likely a good bet. - if r.CheckLocal() { - cmd.SetDir(r.LocalPath()) - } else { - cmd.SetDir(filepath.Dir(r.LocalPath())) - } - // Ensure no prompting for PWs - cmd.SetEnv(append([]string{"GIT_ASKPASS=", "GIT_TERMINAL_PROMPT=0"}, os.Environ()...)) - out, err := cmd.CombinedOutput() - if err != nil { - return nil, errors.Wrap(err, string(out)) - } - - all := bytes.Split(bytes.TrimSpace(out), []byte("\n")) - if len(all) == 1 && len(all[0]) == 0 { - return nil, fmt.Errorf("no data returned from ls-remote") - } - - // Pull out the HEAD rev (it's always first) so we know what branches to - // mark as default. This is, perhaps, not the best way to glean this, but it - // was good enough for git itself until 1.8.5. Also, the alternative is - // sniffing data out of the pack protocol, which is a separate request, and - // also waaaay more than we want to do right now. - // - // The cost is that we could potentially have multiple branches marked as - // the default. If that does occur, a later check (again, emulating git - // <1.8.5 behavior) further narrows the failure mode by choosing master as - // the sole default branch if a) master exists and b) master is one of the - // branches marked as a default. - // - // This all reduces the failure mode to a very narrow range of - // circumstances. Nevertheless, if we do end up emitting multiple - // default branches, it is possible that a user could end up following a - // non-default branch, IF: - // - // * Multiple branches match the HEAD rev - // * None of them are master - // * The solver makes it into the branch list in the version queue - // * The user/tool has provided no constraint (so, anyConstraint) - // * A branch that is not actually the default, but happens to share the - // rev, is lexicographically less than the true default branch - // - // If all of those conditions are met, then the user would end up with an - // erroneous non-default branch in their lock file. - var headrev Revision - var onedef, multidef, defmaster bool - - smap := make(map[string]int) - uniq := 0 - vlist = make([]PairedVersion, len(all)) - for _, pair := range all { - var v PairedVersion - // Valid `git ls-remote` output should start with hash, be at least - // 45 chars long and 40th character should be '\t' - // - // See: https://github.com/golang/dep/pull/1160#issuecomment-328843519 - if len(pair) < 45 || pair[40] != '\t' || !s.isValidHash(pair[:40]) { - continue - } - if string(pair[41:]) == "HEAD" { - // If HEAD is present, it's always first - headrev = Revision(pair[:40]) - } else if string(pair[46:51]) == "heads" { - rev := Revision(pair[:40]) - - isdef := rev == headrev - n := string(pair[52:]) - if isdef { - if onedef { - multidef = true - } - onedef = true - if n == "master" { - defmaster = true - } - } - v = branchVersion{ - name: n, - isDefault: isdef, - }.Pair(rev).(PairedVersion) - - vlist[uniq] = v - uniq++ - } else if string(pair[46:50]) == "tags" { - vstr := string(pair[51:]) - if strings.HasSuffix(vstr, "^{}") { - // If the suffix is there, then we *know* this is the rev of - // the underlying commit object that we actually want - vstr = strings.TrimSuffix(vstr, "^{}") - if i, ok := smap[vstr]; ok { - v = NewVersion(vstr).Pair(Revision(pair[:40])) - vlist[i] = v - continue - } - } else if _, ok := smap[vstr]; ok { - // Already saw the deref'd version of this tag, if one - // exists, so skip this. - continue - // Can only hit this branch if we somehow got the deref'd - // version first. Which should be impossible, but this - // covers us in case of weirdness, anyway. - } - v = NewVersion(vstr).Pair(Revision(pair[:40])) - smap[vstr] = uniq - vlist[uniq] = v - uniq++ - } - } - - // Trim off excess from the slice - vlist = vlist[:uniq] - - // There were multiple default branches, but one was master. So, go through - // and strip the default flag from all the non-master branches. - if multidef && defmaster { - for k, v := range vlist { - pv := v.(PairedVersion) - if bv, ok := pv.Unpair().(branchVersion); ok { - if bv.name != "master" && bv.isDefault { - bv.isDefault = false - vlist[k] = bv.Pair(pv.Revision()) - } - } - } - } - - return -} - -// gopkginSource is a specialized git source that performs additional filtering -// according to the input URL. -type gopkginSource struct { - gitSource - major uint64 - unstable bool - // The aliased URL we report as being the one we talk to, even though we're - // actually talking directly to GitHub. - aliasURL string -} - -func (s *gopkginSource) upstreamURL() string { - return s.aliasURL -} - -func (s *gopkginSource) listVersions(ctx context.Context) ([]PairedVersion, error) { - ovlist, err := s.gitSource.listVersions(ctx) - if err != nil { - return nil, err - } - - // Apply gopkg.in's filtering rules - vlist := make([]PairedVersion, len(ovlist)) - k := 0 - var dbranch int // index of branch to be marked default - var bsv semver.Version - var defaultBranch PairedVersion - tryDefaultAsV0 := s.major == 0 - for _, v := range ovlist { - // all git versions will always be paired - pv := v.(versionPair) - switch tv := pv.v.(type) { - case semVersion: - tryDefaultAsV0 = false - if tv.sv.Major() == s.major && !s.unstable { - vlist[k] = v - k++ - } - case branchVersion: - if tv.isDefault && defaultBranch == nil { - defaultBranch = pv - } - - // The semver lib isn't exactly the same as gopkg.in's logic, but - // it's close enough that it's probably fine to use. We can be more - // exact if real problems crop up. - sv, err := semver.NewVersion(tv.name) - if err != nil { - continue - } - tryDefaultAsV0 = false - - if sv.Major() != s.major { - // not the same major version as specified in the import path constraint - continue - } - - // Gopkg.in has a special "-unstable" suffix which we need to handle - // separately. - if s.unstable != strings.HasSuffix(tv.name, gopkgUnstableSuffix) { - continue - } - - // Turn off the default branch marker unconditionally; we can't know - // which one to mark as default until we've seen them all - tv.isDefault = false - // Figure out if this is the current leader for default branch - if bsv == (semver.Version{}) || bsv.LessThan(sv) { - bsv = sv - dbranch = k - } - pv.v = tv - vlist[k] = pv - k++ - } - // The switch skips plainVersions because they cannot possibly meet - // gopkg.in's requirements - } - - vlist = vlist[:k] - if bsv != (semver.Version{}) { - dbv := vlist[dbranch].(versionPair) - vlist[dbranch] = branchVersion{ - name: dbv.v.(branchVersion).name, - isDefault: true, - }.Pair(dbv.r) - } - - // Treat the default branch as v0 only when no other semver branches/tags exist - // See http://labix.org/gopkg.in#VersionZero - if tryDefaultAsV0 && defaultBranch != nil { - vlist = append(vlist, defaultBranch) - } - - return vlist, nil -} - -// bzrSource is a generic bzr repository implementation that should work with -// all standard bazaar remotes. -type bzrSource struct { - baseVCSSource -} - -func (s *bzrSource) exportRevisionTo(ctx context.Context, rev Revision, to string) error { - if err := s.baseVCSSource.exportRevisionTo(ctx, rev, to); err != nil { - return err - } - - return os.RemoveAll(filepath.Join(to, ".bzr")) -} - -func (s *bzrSource) listVersions(ctx context.Context) ([]PairedVersion, error) { - r := s.repo - - // TODO(sdboyer) this should be handled through the gateway's FSM - if !r.CheckLocal() { - err := s.initLocal(ctx) - if err != nil { - return nil, err - } - } - - // Now, list all the tags - tagsCmd := commandContext(ctx, "bzr", "tags", "--show-ids", "-v") - tagsCmd.SetDir(r.LocalPath()) - out, err := tagsCmd.CombinedOutput() - if err != nil { - return nil, errors.Wrap(err, string(out)) - } - - all := bytes.Split(bytes.TrimSpace(out), []byte("\n")) - - viCmd := commandContext(ctx, "bzr", "version-info", "--custom", "--template={revision_id}", "--revision=branch:.") - viCmd.SetDir(r.LocalPath()) - branchrev, err := viCmd.CombinedOutput() - if err != nil { - return nil, errors.Wrap(err, string(branchrev)) - } - - vlist := make([]PairedVersion, 0, len(all)+1) - - // Now, all the tags. - for _, line := range all { - idx := bytes.IndexByte(line, 32) // space - v := NewVersion(string(line[:idx])) - r := Revision(bytes.TrimSpace(line[idx:])) - vlist = append(vlist, v.Pair(r)) - } - - // Last, add the default branch, hardcoding the visual representation of it - // that bzr uses when operating in the workflow mode we're using. - v := newDefaultBranch("(default)") - vlist = append(vlist, v.Pair(Revision(string(branchrev)))) - - return vlist, nil -} - -func (s *bzrSource) disambiguateRevision(ctx context.Context, r Revision) (Revision, error) { - // If we used the default baseVCSSource behavior here, we would return the - // bazaar revision number, which is not a globally unique identifier - it is - // only unique within a branch. This is just the way that - // github.com/Masterminds/vcs chooses to handle bazaar. We want a - // disambiguated unique ID, though, so we need slightly different behavior: - // check whether r doesn't error when we try to look it up. If so, trust that - // it's a revision. - _, err := s.repo.CommitInfo(string(r)) - if err != nil { - return "", err - } - return r, nil -} - -// hgSource is a generic hg repository implementation that should work with -// all standard mercurial servers. -type hgSource struct { - baseVCSSource -} - -func (s *hgSource) exportRevisionTo(ctx context.Context, rev Revision, to string) error { - // TODO: use hg instead of the generic approach in - // baseVCSSource.exportRevisionTo to make it faster. - if err := s.baseVCSSource.exportRevisionTo(ctx, rev, to); err != nil { - return err - } - - return os.RemoveAll(filepath.Join(to, ".hg")) -} - -func (s *hgSource) listVersions(ctx context.Context) ([]PairedVersion, error) { - var vlist []PairedVersion - - r := s.repo - // TODO(sdboyer) this should be handled through the gateway's FSM - if !r.CheckLocal() { - err := s.initLocal(ctx) - if err != nil { - return nil, err - } - } - - // Now, list all the tags - tagsCmd := commandContext(ctx, "hg", "tags", "--debug", "--verbose") - tagsCmd.SetDir(r.LocalPath()) - out, err := tagsCmd.CombinedOutput() - if err != nil { - return nil, errors.Wrap(err, string(out)) - } - - all := bytes.Split(bytes.TrimSpace(out), []byte("\n")) - lbyt := []byte("local") - nulrev := []byte("0000000000000000000000000000000000000000") - for _, line := range all { - if bytes.Equal(lbyt, line[len(line)-len(lbyt):]) { - // Skip local tags - continue - } - - // tip is magic, don't include it - if bytes.HasPrefix(line, []byte("tip")) { - continue - } - - // Split on colon; this gets us the rev and the tag plus local revno - pair := bytes.Split(line, []byte(":")) - if bytes.Equal(nulrev, pair[1]) { - // null rev indicates this tag is marked for deletion - continue - } - - idx := bytes.IndexByte(pair[0], 32) // space - v := NewVersion(string(pair[0][:idx])).Pair(Revision(pair[1])).(PairedVersion) - vlist = append(vlist, v) - } - - // bookmarks next, because the presence of the magic @ bookmark has to - // determine how we handle the branches - var magicAt bool - bookmarksCmd := commandContext(ctx, "hg", "bookmarks", "--debug") - bookmarksCmd.SetDir(r.LocalPath()) - out, err = bookmarksCmd.CombinedOutput() - if err != nil { - // better nothing than partial and misleading - return nil, errors.Wrap(err, string(out)) - } - - out = bytes.TrimSpace(out) - if !bytes.Equal(out, []byte("no bookmarks set")) { - all = bytes.Split(out, []byte("\n")) - for _, line := range all { - // Trim leading spaces, and * marker if present - line = bytes.TrimLeft(line, " *") - pair := bytes.Split(line, []byte(":")) - // if this doesn't split exactly once, we have something weird - if len(pair) != 2 { - continue - } - - // Split on colon; this gets us the rev and the branch plus local revno - idx := bytes.IndexByte(pair[0], 32) // space - // if it's the magic @ marker, make that the default branch - str := string(pair[0][:idx]) - var v PairedVersion - if str == "@" { - magicAt = true - v = newDefaultBranch(str).Pair(Revision(pair[1])).(PairedVersion) - } else { - v = NewBranch(str).Pair(Revision(pair[1])).(PairedVersion) - } - vlist = append(vlist, v) - } - } - - cmd := commandContext(ctx, "hg", "branches", "-c", "--debug") - cmd.SetDir(r.LocalPath()) - out, err = cmd.CombinedOutput() - if err != nil { - // better nothing than partial and misleading - return nil, errors.Wrap(err, string(out)) - } - - all = bytes.Split(bytes.TrimSpace(out), []byte("\n")) - for _, line := range all { - // Trim inactive and closed suffixes, if present; we represent these - // anyway - line = bytes.TrimSuffix(line, []byte(" (inactive)")) - line = bytes.TrimSuffix(line, []byte(" (closed)")) - - // Split on colon; this gets us the rev and the branch plus local revno - pair := bytes.Split(line, []byte(":")) - idx := bytes.IndexByte(pair[0], 32) // space - str := string(pair[0][:idx]) - // if there was no magic @ bookmark, and this is mercurial's magic - // "default" branch, then mark it as default branch - var v PairedVersion - if !magicAt && str == "default" { - v = newDefaultBranch(str).Pair(Revision(pair[1])).(PairedVersion) - } else { - v = NewBranch(str).Pair(Revision(pair[1])).(PairedVersion) - } - vlist = append(vlist, v) - } - - return vlist, nil -} diff --git a/vendor/github.com/golang/dep/gps/vcs_version.go b/vendor/github.com/golang/dep/gps/vcs_version.go deleted file mode 100644 index 1009337d04e98a3ef3284c6f48534ad4fdb6c4d3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/vcs_version.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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 gps - -import ( - "strings" - - "github.com/Masterminds/vcs" - "github.com/pkg/errors" -) - -// VCSVersion returns the current project version for an absolute path. -func VCSVersion(path string) (Version, error) { - repo, err := vcs.NewRepo("", path) - if err != nil { - return nil, errors.Wrapf(err, "creating new repo for root: %s", path) - } - - ver, err := repo.Current() - if err != nil { - return nil, errors.Wrapf(err, "finding current branch/version for root: %s", path) - } - - rev, err := repo.Version() - if err != nil { - return nil, errors.Wrapf(err, "getting repo version for root: %s", path) - } - - // First look through tags. - tags, err := repo.Tags() - if err != nil { - return nil, errors.Wrapf(err, "getting repo tags for root: %s", path) - } - // Try to match the current version to a tag. - if contains(tags, ver) { - // Assume semver if it starts with a v. - if strings.HasPrefix(ver, "v") { - return NewVersion(ver).Pair(Revision(rev)), nil - } - - return nil, errors.Errorf("version for root %s does not start with a v: %q", path, ver) - } - - // Look for the current branch. - branches, err := repo.Branches() - if err != nil { - return nil, errors.Wrapf(err, "getting repo branch for root: %s") - } - // Try to match the current version to a branch. - if contains(branches, ver) { - return NewBranch(ver).Pair(Revision(rev)), nil - } - - return Revision(rev), nil -} - -// contains checks if a array of strings contains a value -func contains(a []string, b string) bool { - for _, v := range a { - if b == v { - return true - } - } - return false -} diff --git a/vendor/github.com/golang/dep/gps/version.go b/vendor/github.com/golang/dep/gps/version.go deleted file mode 100644 index 22f12ef9c0c8ee0f5c8b4a99494133d31d60f0b0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/version.go +++ /dev/null @@ -1,875 +0,0 @@ -// 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 gps - -import ( - "fmt" - "sort" - - "github.com/Masterminds/semver" - "github.com/golang/dep/gps/internal/pb" -) - -// VersionType indicates a type for a Version that conveys some additional -// semantics beyond that which is literally embedded on the Go type. -type VersionType uint8 - -// VersionTypes for the four major classes of version we deal with -const ( - IsRevision VersionType = iota - IsVersion - IsSemver - IsBranch -) - -// Version represents one of the different types of versions used by gps. -// -// Version composes Constraint, because all versions can be used as a constraint -// (where they allow one, and only one, version - themselves), but constraints -// are not necessarily discrete versions. -// -// Version is an interface, but it contains private methods, which restricts it -// to gps's own internal implementations. We do this for the confluence of -// two reasons: the implementation of Versions is complete (there is no case in -// which we'd need other types), and the implementation relies on type magic -// under the hood, which would be unsafe to do if other dynamic types could be -// hiding behind the interface. -type Version interface { - Constraint - - // Indicates the type of version - Revision, Branch, Version, or Semver - Type() VersionType -} - -// PairedVersion represents a normal Version, but paired with its corresponding, -// underlying Revision. -type PairedVersion interface { - Version - - // Revision returns the immutable Revision that identifies this Version. - Revision() Revision - - // Unpair returns the surface-level UnpairedVersion that half of the pair. - // - // It does NOT modify the original PairedVersion - Unpair() UnpairedVersion - - // Ensures it is impossible to be both a PairedVersion and an - // UnpairedVersion - _pair(int) -} - -// UnpairedVersion represents a normal Version, with a method for creating a -// VersionPair by indicating the version's corresponding, underlying Revision. -type UnpairedVersion interface { - Version - // Pair takes the underlying Revision that this UnpairedVersion corresponds - // to and unites them into a PairedVersion. - Pair(Revision) PairedVersion - // Ensures it is impossible to be both a PairedVersion and an - // UnpairedVersion - _pair(bool) -} - -// types are weird -func (branchVersion) _pair(bool) {} -func (plainVersion) _pair(bool) {} -func (semVersion) _pair(bool) {} -func (versionPair) _pair(int) {} - -// NewBranch creates a new Version to represent a floating version (in -// general, a branch). -func NewBranch(body string) UnpairedVersion { - return branchVersion{ - name: body, - // We always set isDefault to false here, because the property is - // specifically designed to be internal-only: only the SourceManager - // gets to mark it. This is OK because nothing that client code is - // responsible for needs to care about has to touch it it. - // - // TODO(sdboyer) ...maybe. this just ugly. - isDefault: false, - } -} - -func newDefaultBranch(body string) UnpairedVersion { - return branchVersion{ - name: body, - isDefault: true, - } -} - -// NewVersion creates a Semver-typed Version if the provided version string is -// valid semver, and a plain/non-semver version if not. -func NewVersion(body string) UnpairedVersion { - sv, err := semver.NewVersion(body) - - if err != nil { - return plainVersion(body) - } - return semVersion{sv: sv} -} - -// A Revision represents an immutable versioning identifier. -type Revision string - -// String converts the Revision back into a string. -func (r Revision) String() string { - return string(r) -} - -// ImpliedCaretString follows the same rules as String(), but in accordance with -// the Constraint interface will always print a leading "=", as all Versions, -// when acting as a Constraint, act as exact matches. -func (r Revision) ImpliedCaretString() string { - return r.String() -} - -func (r Revision) typedString() string { - return "r-" + string(r) -} - -// Type indicates the type of version - for revisions, "revision". -func (r Revision) Type() VersionType { - return IsRevision -} - -// Matches is the Revision acting as a constraint; it checks to see if the provided -// version is the same Revision as itself. -func (r Revision) Matches(v Version) bool { - switch tv := v.(type) { - case versionTypeUnion: - return tv.Matches(r) - case Revision: - return r == tv - case versionPair: - return r == tv.r - } - - return false -} - -// MatchesAny is the Revision acting as a constraint; it checks to see if the provided -// version is the same Revision as itself. -func (r Revision) MatchesAny(c Constraint) bool { - switch tc := c.(type) { - case anyConstraint: - return true - case noneConstraint: - return false - case versionTypeUnion: - return tc.MatchesAny(r) - case Revision: - return r == tc - case versionPair: - return r == tc.r - } - - return false -} - -// Intersect computes the intersection of the Constraint with the provided -// Constraint. For Revisions, this can only be another, exactly equal -// Revision, or a PairedVersion whose underlying Revision is exactly equal. -func (r Revision) Intersect(c Constraint) Constraint { - switch tc := c.(type) { - case anyConstraint: - return r - case noneConstraint: - return none - case versionTypeUnion: - return tc.Intersect(r) - case Revision: - if r == tc { - return r - } - case versionPair: - if r == tc.r { - return r - } - } - - return none -} - -func (r Revision) identical(c Constraint) bool { - r2, ok := c.(Revision) - if !ok { - return false - } - return r == r2 -} - -func (r Revision) copyTo(msg *pb.Constraint) { - msg.Type = pb.Constraint_Revision - msg.Value = string(r) -} - -type branchVersion struct { - name string - isDefault bool -} - -func (v branchVersion) String() string { - return string(v.name) -} - -func (v branchVersion) ImpliedCaretString() string { - return v.String() -} - -func (v branchVersion) typedString() string { - return fmt.Sprintf("b-%s", v.String()) -} - -func (v branchVersion) Type() VersionType { - return IsBranch -} - -func (v branchVersion) Matches(v2 Version) bool { - switch tv := v2.(type) { - case versionTypeUnion: - return tv.Matches(v) - case branchVersion: - return v.name == tv.name - case versionPair: - if tv2, ok := tv.v.(branchVersion); ok { - return tv2.name == v.name - } - } - return false -} - -func (v branchVersion) MatchesAny(c Constraint) bool { - switch tc := c.(type) { - case anyConstraint: - return true - case noneConstraint: - return false - case versionTypeUnion: - return tc.MatchesAny(v) - case branchVersion: - return v.name == tc.name - case versionPair: - if tc2, ok := tc.v.(branchVersion); ok { - return tc2.name == v.name - } - } - - return false -} - -func (v branchVersion) Intersect(c Constraint) Constraint { - switch tc := c.(type) { - case anyConstraint: - return v - case noneConstraint: - return none - case versionTypeUnion: - return tc.Intersect(v) - case branchVersion: - if v.name == tc.name { - return v - } - case versionPair: - if tc2, ok := tc.v.(branchVersion); ok { - if v.name == tc2.name { - return v - } - } - } - - return none -} - -func (v branchVersion) Pair(r Revision) PairedVersion { - return versionPair{ - v: v, - r: r, - } -} - -func (v branchVersion) identical(c Constraint) bool { - v2, ok := c.(branchVersion) - if !ok { - return false - } - return v == v2 -} - -func (v branchVersion) copyTo(msg *pb.Constraint) { - if v.isDefault { - msg.Type = pb.Constraint_DefaultBranch - } else { - msg.Type = pb.Constraint_Branch - } - msg.Value = v.name -} - -type plainVersion string - -func (v plainVersion) String() string { - return string(v) -} - -func (v plainVersion) ImpliedCaretString() string { - return v.String() -} - -func (v plainVersion) typedString() string { - return fmt.Sprintf("pv-%s", v.String()) -} - -func (v plainVersion) Type() VersionType { - return IsVersion -} - -func (v plainVersion) Matches(v2 Version) bool { - switch tv := v2.(type) { - case versionTypeUnion: - return tv.Matches(v) - case plainVersion: - return v == tv - case versionPair: - if tv2, ok := tv.v.(plainVersion); ok { - return tv2 == v - } - } - return false -} - -func (v plainVersion) MatchesAny(c Constraint) bool { - switch tc := c.(type) { - case anyConstraint: - return true - case noneConstraint: - return false - case versionTypeUnion: - return tc.MatchesAny(v) - case plainVersion: - return v == tc - case versionPair: - if tc2, ok := tc.v.(plainVersion); ok { - return tc2 == v - } - } - - return false -} - -func (v plainVersion) Intersect(c Constraint) Constraint { - switch tc := c.(type) { - case anyConstraint: - return v - case noneConstraint: - return none - case versionTypeUnion: - return tc.Intersect(v) - case plainVersion: - if v == tc { - return v - } - case versionPair: - if tc2, ok := tc.v.(plainVersion); ok { - if v == tc2 { - return v - } - } - } - - return none -} - -func (v plainVersion) Pair(r Revision) PairedVersion { - return versionPair{ - v: v, - r: r, - } -} - -func (v plainVersion) identical(c Constraint) bool { - v2, ok := c.(plainVersion) - if !ok { - return false - } - return v == v2 -} - -func (v plainVersion) copyTo(msg *pb.Constraint) { - msg.Type = pb.Constraint_Version - msg.Value = string(v) -} - -type semVersion struct { - sv semver.Version -} - -func (v semVersion) String() string { - str := v.sv.Original() - if str == "" { - str = v.sv.String() - } - return str -} - -func (v semVersion) ImpliedCaretString() string { - return v.sv.ImpliedCaretString() -} - -func (v semVersion) typedString() string { - return fmt.Sprintf("sv-%s", v.String()) -} - -func (v semVersion) Type() VersionType { - return IsSemver -} - -func (v semVersion) Matches(v2 Version) bool { - switch tv := v2.(type) { - case versionTypeUnion: - return tv.Matches(v) - case semVersion: - return v.sv.Equal(tv.sv) - case versionPair: - if tv2, ok := tv.v.(semVersion); ok { - return tv2.sv.Equal(v.sv) - } - } - return false -} - -func (v semVersion) MatchesAny(c Constraint) bool { - switch tc := c.(type) { - case anyConstraint: - return true - case noneConstraint: - return false - case versionTypeUnion: - return tc.MatchesAny(v) - case semVersion: - return v.sv.Equal(tc.sv) - case semverConstraint: - return tc.Intersect(v) != none - case versionPair: - if tc2, ok := tc.v.(semVersion); ok { - return tc2.sv.Equal(v.sv) - } - } - - return false -} - -func (v semVersion) Intersect(c Constraint) Constraint { - switch tc := c.(type) { - case anyConstraint: - return v - case noneConstraint: - return none - case versionTypeUnion: - return tc.Intersect(v) - case semVersion: - if v.sv.Equal(tc.sv) { - return v - } - case semverConstraint: - return tc.Intersect(v) - case versionPair: - if tc2, ok := tc.v.(semVersion); ok { - if v.sv.Equal(tc2.sv) { - return v - } - } - } - - return none -} - -func (v semVersion) Pair(r Revision) PairedVersion { - return versionPair{ - v: v, - r: r, - } -} - -func (v semVersion) identical(c Constraint) bool { - v2, ok := c.(semVersion) - if !ok { - return false - } - return v == v2 -} - -func (v semVersion) copyTo(msg *pb.Constraint) { - msg.Type = pb.Constraint_Semver - msg.Value = v.String() //TODO better encoding which doesn't require re-parsing -} - -type versionPair struct { - v UnpairedVersion - r Revision -} - -func (v versionPair) String() string { - return v.v.String() -} - -func (v versionPair) ImpliedCaretString() string { - return v.v.ImpliedCaretString() -} - -func (v versionPair) typedString() string { - return fmt.Sprintf("%s-%s", v.Unpair().typedString(), v.Revision().typedString()) -} - -func (v versionPair) Type() VersionType { - return v.v.Type() -} - -func (v versionPair) Revision() Revision { - return v.r -} - -func (v versionPair) Unpair() UnpairedVersion { - return v.v -} - -func (v versionPair) Matches(v2 Version) bool { - switch tv2 := v2.(type) { - case versionTypeUnion: - return tv2.Matches(v) - case versionPair: - return v.r == tv2.r - case Revision: - return v.r == tv2 - } - - switch tv := v.v.(type) { - case plainVersion, branchVersion: - if tv.Matches(v2) { - return true - } - case semVersion: - if tv2, ok := v2.(semVersion); ok { - if tv.sv.Equal(tv2.sv) { - return true - } - } - } - - return false -} - -func (v versionPair) MatchesAny(c2 Constraint) bool { - return c2.Matches(v) -} - -func (v versionPair) Intersect(c2 Constraint) Constraint { - switch tc := c2.(type) { - case anyConstraint: - return v - case noneConstraint: - return none - case versionTypeUnion: - return tc.Intersect(v) - case versionPair: - if v.r == tc.r { - return v.r - } - case Revision: - if v.r == tc { - return v.r - } - case semverConstraint: - if tv, ok := v.v.(semVersion); ok { - if tc.Intersect(tv) == v.v { - return v - } - } - // If the semver intersection failed, we know nothing could work - return none - } - - switch tv := v.v.(type) { - case plainVersion, branchVersion: - if c2.Matches(v) { - return v - } - case semVersion: - if tv2, ok := c2.(semVersion); ok { - if tv.sv.Equal(tv2.sv) { - return v - } - } - } - - return none -} - -func (v versionPair) identical(c Constraint) bool { - v2, ok := c.(versionPair) - if !ok { - return false - } - if v.r != v2.r { - return false - } - return v.v.identical(v2.v) -} - -func (v versionPair) copyTo(*pb.Constraint) { - panic("versionPair should never be serialized; it is solver internal-only") -} - -// compareVersionType is a sort func helper that makes a coarse-grained sorting -// decision based on version type. -// -// Make sure that l and r have already been converted from versionPair (if -// applicable). -func compareVersionType(l, r Version) int { - // Big fugly double type switch. No reflect, because this can be smack in a hot loop - switch l.(type) { - case Revision: - switch r.(type) { - case Revision: - return 0 - case branchVersion, plainVersion, semVersion: - return 1 - } - - case plainVersion: - switch r.(type) { - case Revision: - return -1 - case plainVersion: - return 0 - case branchVersion, semVersion: - return 1 - } - - case branchVersion: - switch r.(type) { - case Revision, plainVersion: - return -1 - case branchVersion: - return 0 - case semVersion: - return 1 - } - - case semVersion: - switch r.(type) { - case Revision, branchVersion, plainVersion: - return -1 - case semVersion: - return 0 - } - } - panic("unknown version type") -} - -// SortForUpgrade sorts a slice of []Version in roughly descending order, so -// that presumably newer versions are visited first. The rules are: -// -// - All semver versions come first, and sort mostly according to the semver -// 2.0 spec (as implemented by github.com/Masterminds/semver lib), with one -// exception: -// - Semver versions with a prerelease are after *all* non-prerelease semver. -// Within this subset they are sorted first by their numerical component, then -// lexicographically by their prerelease version. -// - The default branch(es) is next; the exact semantics of that are specific -// to the underlying source. -// - All other branches come next, sorted lexicographically. -// - All non-semver versions (tags) are next, sorted lexicographically. -// - Revisions, if any, are last, sorted lexicographically. Revisions do not -// typically appear in version lists, so the only invariant we maintain is -// determinism - deeper semantics, like chronology or topology, do not matter. -// -// So, given a slice of the following versions: -// -// - Branch: master devel -// - Semver tags: v1.0.0, v1.1.0, v1.1.0-alpha1 -// - Non-semver tags: footag -// - Revision: f6e74e8d -// -// Sorting for upgrade will result in the following slice. -// -// [v1.1.0 v1.0.0 v1.1.0-alpha1 footag devel master f6e74e8d] -func SortForUpgrade(vl []Version) { - sort.Sort(upgradeVersionSorter(vl)) -} - -// SortPairedForUpgrade has the same behavior as SortForUpgrade, but operates on -// []PairedVersion types. -func SortPairedForUpgrade(vl []PairedVersion) { - sort.Sort(pvupgradeVersionSorter(vl)) -} - -// SortForDowngrade sorts a slice of []Version in roughly ascending order, so -// that presumably older versions are visited first. -// -// This is *not* the same as reversing SortForUpgrade (or you could simply -// sort.Reverse()). The type precedence is the same, including the semver vs. -// semver-with-prerelease relation. Lexicographical comparisons within -// non-semver tags, branches, and revisions remains the same as well; because we -// treat these domains as having no ordering relation, there can be no real -// concept of "upgrade" vs "downgrade", so there is no reason to reverse them. -// -// Thus, the only binary relation that is reversed for downgrade is within-type -// comparisons for semver. -// -// So, given a slice of the following versions: -// -// - Branch: master devel -// - Semver tags: v1.0.0, v1.1.0, v1.1.0-alpha1 -// - Non-semver tags: footag -// - Revision: f6e74e8d -// -// Sorting for downgrade will result in the following slice. -// -// [v1.0.0 v1.1.0 v1.1.0-alpha1 footag devel master f6e74e8d] -func SortForDowngrade(vl []Version) { - sort.Sort(downgradeVersionSorter(vl)) -} - -// SortPairedForDowngrade has the same behavior as SortForDowngrade, but -// operates on []PairedVersion types. -func SortPairedForDowngrade(vl []PairedVersion) { - sort.Sort(pvdowngradeVersionSorter(vl)) -} - -type upgradeVersionSorter []Version - -func (vs upgradeVersionSorter) Len() int { - return len(vs) -} - -func (vs upgradeVersionSorter) Swap(i, j int) { - vs[i], vs[j] = vs[j], vs[i] -} - -func (vs upgradeVersionSorter) Less(i, j int) bool { - l, r := vs[i], vs[j] - return vLess(l, r, false) -} - -type pvupgradeVersionSorter []PairedVersion - -func (vs pvupgradeVersionSorter) Len() int { - return len(vs) -} - -func (vs pvupgradeVersionSorter) Swap(i, j int) { - vs[i], vs[j] = vs[j], vs[i] -} -func (vs pvupgradeVersionSorter) Less(i, j int) bool { - l, r := vs[i], vs[j] - return vLess(l, r, false) -} - -type downgradeVersionSorter []Version - -func (vs downgradeVersionSorter) Len() int { - return len(vs) -} - -func (vs downgradeVersionSorter) Swap(i, j int) { - vs[i], vs[j] = vs[j], vs[i] -} - -func (vs downgradeVersionSorter) Less(i, j int) bool { - l, r := vs[i], vs[j] - return vLess(l, r, true) -} - -type pvdowngradeVersionSorter []PairedVersion - -func (vs pvdowngradeVersionSorter) Len() int { - return len(vs) -} - -func (vs pvdowngradeVersionSorter) Swap(i, j int) { - vs[i], vs[j] = vs[j], vs[i] -} -func (vs pvdowngradeVersionSorter) Less(i, j int) bool { - l, r := vs[i], vs[j] - return vLess(l, r, true) -} - -func vLess(l, r Version, down bool) bool { - if tl, ispair := l.(versionPair); ispair { - l = tl.v - } - if tr, ispair := r.(versionPair); ispair { - r = tr.v - } - - switch compareVersionType(l, r) { - case -1: - return true - case 1: - return false - case 0: - break - default: - panic("unreachable") - } - - switch tl := l.(type) { - case branchVersion: - tr := r.(branchVersion) - if tl.isDefault != tr.isDefault { - // If they're not both defaults, then return the left val: if left - // is the default, then it is "less" (true) b/c we want it earlier. - // Else the right is the default, and so the left should be later - // (false). - return tl.isDefault - } - return l.String() < r.String() - case Revision, plainVersion: - // All that we can do now is alpha sort - return l.String() < r.String() - } - - // This ensures that pre-release versions are always sorted after ALL - // full-release versions - lsv, rsv := l.(semVersion).sv, r.(semVersion).sv - lpre, rpre := lsv.Prerelease() == "", rsv.Prerelease() == "" - if (lpre && !rpre) || (!lpre && rpre) { - return lpre - } - - if down { - return lsv.LessThan(rsv) - } - return lsv.GreaterThan(rsv) -} - -func hidePair(pvl []PairedVersion) []Version { - vl := make([]Version, 0, len(pvl)) - for _, v := range pvl { - vl = append(vl, v) - } - return vl -} - -// VersionComponentStrings decomposes a Version into the underlying number, branch and revision -func VersionComponentStrings(v Version) (revision string, branch string, version string) { - switch tv := v.(type) { - case UnpairedVersion: - case Revision: - revision = tv.String() - case PairedVersion: - revision = tv.Revision().String() - } - - switch v.Type() { - case IsBranch: - branch = v.String() - case IsSemver, IsVersion: - version = v.String() - } - - return -} diff --git a/vendor/github.com/golang/dep/gps/version_queue.go b/vendor/github.com/golang/dep/gps/version_queue.go deleted file mode 100644 index 6e23ba4f275dfeadf65c0b48440fbbdbbc124e67..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/version_queue.go +++ /dev/null @@ -1,158 +0,0 @@ -// 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 gps - -import ( - "fmt" - "strings" -) - -type failedVersion struct { - v Version - f error -} - -type versionQueue struct { - id ProjectIdentifier - pi []Version - lockv, prefv Version - fails []failedVersion - b sourceBridge - failed bool - allLoaded bool - adverr error -} - -func newVersionQueue(id ProjectIdentifier, lockv, prefv Version, b sourceBridge) (*versionQueue, error) { - vq := &versionQueue{ - id: id, - b: b, - } - - // Lock goes in first, if present - if lockv != nil { - vq.lockv = lockv - vq.pi = append(vq.pi, lockv) - } - - // Preferred version next - if prefv != nil { - vq.prefv = prefv - vq.pi = append(vq.pi, prefv) - } - - if len(vq.pi) == 0 { - var err error - vq.pi, err = vq.b.listVersions(vq.id) - if err != nil { - // TODO(sdboyer) pushing this error this early entails that we - // unconditionally deep scan (e.g. vendor), as well as hitting the - // network. - return nil, err - } - vq.allLoaded = true - } - - return vq, nil -} - -func (vq *versionQueue) current() Version { - if len(vq.pi) > 0 { - return vq.pi[0] - } - - return nil -} - -// advance moves the versionQueue forward to the next available version, -// recording the failure that eliminated the current version. -func (vq *versionQueue) advance(fail error) error { - // Nothing in the queue means...nothing in the queue, nicely enough - if vq.adverr != nil || len(vq.pi) == 0 { // should be a redundant check, but just in case - return vq.adverr - } - - // Record the fail reason and pop the queue - vq.fails = append(vq.fails, failedVersion{ - v: vq.pi[0], - f: fail, - }) - vq.pi = vq.pi[1:] - - // *now*, if the queue is empty, ensure all versions have been loaded - if len(vq.pi) == 0 { - if vq.allLoaded { - // This branch gets hit when the queue is first fully exhausted, - // after a previous advance() already called ListVersions(). - return nil - } - vq.allLoaded = true - - var vltmp []Version - vltmp, vq.adverr = vq.b.listVersions(vq.id) - if vq.adverr != nil { - return vq.adverr - } - // defensive copy - calling listVersions here means slice contents may - // be modified when removing prefv/lockv. - vq.pi = make([]Version, len(vltmp)) - copy(vq.pi, vltmp) - - // search for and remove lockv and prefv, in a pointer GC-safe manner - // - // could use the version comparator for binary search here to avoid - // O(n) each time...if it matters - var delkeys []int - for k, pi := range vq.pi { - if pi == vq.lockv || pi == vq.prefv { - delkeys = append(delkeys, k) - } - } - - for k, dk := range delkeys { - dk -= k - copy(vq.pi[dk:], vq.pi[dk+1:]) - // write nil to final position for GC safety - vq.pi[len(vq.pi)-1] = nil - vq.pi = vq.pi[:len(vq.pi)-1] - } - - if len(vq.pi) == 0 { - // If listing versions added nothing (new), then return now - return nil - } - } - - // We're finally sure that there's something in the queue. Remove the - // failure marker, as the current version may have failed, but the next one - // hasn't yet - vq.failed = false - - // If all have been loaded and the queue is empty, we're definitely out - // of things to try. Return empty, though, because vq semantics dictate - // that we don't explicitly indicate the end of the queue here. - return nil -} - -// isExhausted indicates whether or not the queue has definitely been exhausted, -// in which case it will return true. -// -// It may return false negatives - suggesting that there is more in the queue -// when a subsequent call to current() will be empty. Plan accordingly. -func (vq *versionQueue) isExhausted() bool { - if !vq.allLoaded { - return false - } - return len(vq.pi) == 0 -} - -func (vq *versionQueue) String() string { - var vs []string - - for _, v := range vq.pi { - vs = append(vs, v.String()) - } - return fmt.Sprintf("[%s]", strings.Join(vs, ", ")) -} diff --git a/vendor/github.com/golang/dep/gps/version_unifier.go b/vendor/github.com/golang/dep/gps/version_unifier.go deleted file mode 100644 index 3698dc7e5dfd2344b92da78380d93f8b0c4a4ec8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/gps/version_unifier.go +++ /dev/null @@ -1,302 +0,0 @@ -// 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 gps - -import "github.com/golang/dep/gps/internal/pb" - -// versionUnifier facilitates cross-type version comparison and set operations. -type versionUnifier struct { - b sourceBridge - mtr *metrics -} - -// pairVersion takes an UnpairedVersion and attempts to pair it with an -// underlying Revision in the context of the provided ProjectIdentifier by -// consulting the canonical version list. -func (vu versionUnifier) pairVersion(id ProjectIdentifier, v UnpairedVersion) PairedVersion { - vl, err := vu.b.listVersions(id) - if err != nil { - return nil - } - - vu.mtr.push("b-pair-version") - // doing it like this is a bit sloppy - for _, v2 := range vl { - if p, ok := v2.(PairedVersion); ok { - if p.Matches(v) { - vu.mtr.pop() - return p - } - } - } - - vu.mtr.pop() - return nil -} - -// pairRevision takes a Revision and attempts to pair it with all possible -// versionsby consulting the canonical version list of the provided -// ProjectIdentifier. -func (vu versionUnifier) pairRevision(id ProjectIdentifier, r Revision) []Version { - vl, err := vu.b.listVersions(id) - if err != nil { - return nil - } - - vu.mtr.push("b-pair-rev") - p := []Version{r} - // doing it like this is a bit sloppy - for _, v2 := range vl { - if pv, ok := v2.(PairedVersion); ok { - if pv.Matches(r) { - p = append(p, pv) - } - } - } - - vu.mtr.pop() - return p -} - -// matches performs a typical match check between the provided version and -// constraint. If that basic check fails and the provided version is incomplete -// (e.g. an unpaired version or bare revision), it will attempt to gather more -// information on one or the other and re-perform the comparison. -func (vu versionUnifier) matches(id ProjectIdentifier, c Constraint, v Version) bool { - if c.Matches(v) { - return true - } - - vu.mtr.push("b-matches") - // This approach is slightly wasteful, but just SO much less verbose, and - // more easily understood. - vtu := vu.createTypeUnion(id, v) - - var uc Constraint - if cv, ok := c.(Version); ok { - uc = vu.createTypeUnion(id, cv) - } else { - uc = c - } - - vu.mtr.pop() - return uc.Matches(vtu) -} - -// matchesAny is the authoritative version of Constraint.MatchesAny. -func (vu versionUnifier) matchesAny(id ProjectIdentifier, c1, c2 Constraint) bool { - if c1.MatchesAny(c2) { - return true - } - - vu.mtr.push("b-matches-any") - // This approach is slightly wasteful, but just SO much less verbose, and - // more easily understood. - var uc1, uc2 Constraint - if v1, ok := c1.(Version); ok { - uc1 = vu.createTypeUnion(id, v1) - } else { - uc1 = c1 - } - - if v2, ok := c2.(Version); ok { - uc2 = vu.createTypeUnion(id, v2) - } else { - uc2 = c2 - } - - vu.mtr.pop() - return uc1.MatchesAny(uc2) -} - -// intersect is the authoritative version of Constraint.Intersect. -func (vu versionUnifier) intersect(id ProjectIdentifier, c1, c2 Constraint) Constraint { - rc := c1.Intersect(c2) - if rc != none { - return rc - } - - vu.mtr.push("b-intersect") - // This approach is slightly wasteful, but just SO much less verbose, and - // more easily understood. - var uc1, uc2 Constraint - if v1, ok := c1.(Version); ok { - uc1 = vu.createTypeUnion(id, v1) - } else { - uc1 = c1 - } - - if v2, ok := c2.(Version); ok { - uc2 = vu.createTypeUnion(id, v2) - } else { - uc2 = c2 - } - - vu.mtr.pop() - return uc1.Intersect(uc2) -} - -// createTypeUnion creates a versionTypeUnion for the provided version. -// -// This union may (and typically will) end up being nothing more than the single -// input version, but creating a versionTypeUnion guarantees that 'local' -// constraint checks (direct method calls) are authoritative. -func (vu versionUnifier) createTypeUnion(id ProjectIdentifier, v Version) versionTypeUnion { - switch tv := v.(type) { - case Revision: - return versionTypeUnion(vu.pairRevision(id, tv)) - case PairedVersion: - return versionTypeUnion(vu.pairRevision(id, tv.Revision())) - case UnpairedVersion: - pv := vu.pairVersion(id, tv) - if pv == nil { - return versionTypeUnion{tv} - } - - return versionTypeUnion(vu.pairRevision(id, pv.Revision())) - } - - return nil -} - -// versionTypeUnion represents a set of versions that are, within the scope of -// this solver run, equivalent. -// -// The simple case here is just a pair - a normal version plus its underlying -// revision - but if a tag or branch point at the same rev, then we consider -// them equivalent. Again, however, this equivalency is short-lived; it must be -// re-assessed during every solver run. -// -// The union members are treated as being OR'd together: all constraint -// operations attempt each member, and will take the most open/optimistic -// answer. -// -// This technically does allow tags to match branches - something we otherwise -// try hard to avoid - but because the original input constraint never actually -// changes (and is never written out in the Solution), there's no harmful case -// of a user suddenly riding a branch when they expected a fixed tag. -type versionTypeUnion []Version - -// This should generally not be called, but is required for the interface. If it -// is called, we have a bigger problem (the type has escaped the solver); thus, -// panic. -func (vtu versionTypeUnion) String() string { - panic("versionTypeUnion should never be turned into a string; it is solver internal-only") -} - -// This should generally not be called, but is required for the interface. If it -// is called, we have a bigger problem (the type has escaped the solver); thus, -// panic. -func (vtu versionTypeUnion) ImpliedCaretString() string { - panic("versionTypeUnion should never be turned into a string; it is solver internal-only") -} - -func (vtu versionTypeUnion) typedString() string { - panic("versionTypeUnion should never be turned into a string; it is solver internal-only") -} - -// This should generally not be called, but is required for the interface. If it -// is called, we have a bigger problem (the type has escaped the solver); thus, -// panic. -func (vtu versionTypeUnion) Type() VersionType { - panic("versionTypeUnion should never need to answer a Type() call; it is solver internal-only") -} - -// Matches takes a version, and returns true if that version matches any version -// contained in the union. -// -// This DOES allow tags to match branches, albeit indirectly through a revision. -func (vtu versionTypeUnion) Matches(v Version) bool { - vtu2, otherIs := v.(versionTypeUnion) - - for _, v1 := range vtu { - if otherIs { - for _, v2 := range vtu2 { - if v1.Matches(v2) { - return true - } - } - } else if v1.Matches(v) { - return true - } - } - - return false -} - -// MatchesAny returns true if any of the contained versions (which are also -// constraints) in the union successfully MatchAny with the provided -// constraint. -func (vtu versionTypeUnion) MatchesAny(c Constraint) bool { - vtu2, otherIs := c.(versionTypeUnion) - - for _, v1 := range vtu { - if otherIs { - for _, v2 := range vtu2 { - if v1.MatchesAny(v2) { - return true - } - } - } else if v1.MatchesAny(c) { - return true - } - } - - return false -} - -// Intersect takes a constraint, and attempts to intersect it with all the -// versions contained in the union until one returns non-none. If that never -// happens, then none is returned. -// -// In order to avoid weird version floating elsewhere in the solver, the union -// always returns the input constraint. (This is probably obviously correct, but -// is still worth noting.) -func (vtu versionTypeUnion) Intersect(c Constraint) Constraint { - vtu2, otherIs := c.(versionTypeUnion) - - for _, v1 := range vtu { - if otherIs { - for _, v2 := range vtu2 { - if rc := v1.Intersect(v2); rc != none { - return rc - } - } - } else if rc := v1.Intersect(c); rc != none { - return rc - } - } - - return none -} - -func (vtu versionTypeUnion) identical(c Constraint) bool { - vtu2, ok := c.(versionTypeUnion) - if !ok { - return false - } - if len(vtu) != len(vtu2) { - return false - } - used := make([]bool, len(vtu)) -outter: - for _, v := range vtu { - for i, v2 := range vtu2 { - if used[i] { - continue - } - if v.identical(v2) { - used[i] = true - continue outter - } - } - return false - } - return true -} - -func (vtu versionTypeUnion) copyTo(*pb.Constraint) { - panic("versionTypeUnion should never be serialized; it is solver internal-only") -} diff --git a/vendor/github.com/golang/dep/hack/build-all.bash b/vendor/github.com/golang/dep/hack/build-all.bash deleted file mode 100755 index 05297508a06024246ccf9bc745db103c36db51ee..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/build-all.bash +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script will build dep and calculate hash for each -# (DEP_BUILD_PLATFORMS, DEP_BUILD_ARCHS) pair. -# DEP_BUILD_PLATFORMS="linux" DEP_BUILD_ARCHS="amd64" ./hack/build-all.sh -# can be called to build only for linux-amd64 - -set -e - -VERSION=$(git describe --tags --dirty) -COMMIT_HASH=$(git rev-parse --short HEAD 2>/dev/null) -DATE=$(date "+%Y-%m-%d") - -GO_BUILD_CMD="go build -a -installsuffix cgo" -GO_BUILD_LDFLAGS="-s -w -X main.commitHash=$COMMIT_HASH -X main.buildDate=$DATE -X main.version=$VERSION" - -if [ -z "$DEP_BUILD_PLATFORMS" ]; then - DEP_BUILD_PLATFORMS="linux windows darwin freebsd" -fi - -if [ -z "$DEP_BUILD_ARCHS" ]; then - DEP_BUILD_ARCHS="amd64 386" -fi - -mkdir -p release - -for OS in ${DEP_BUILD_PLATFORMS[@]}; do - for ARCH in ${DEP_BUILD_ARCHS[@]}; do - NAME="dep-$OS-$ARCH" - if [ "$OS" == "windows" ]; then - NAME="$NAME.exe" - fi - echo "Building for $OS/$ARCH" - GOARCH=$ARCH GOOS=$OS CGO_ENABLED=0 $GO_BUILD_CMD -ldflags "$GO_BUILD_LDFLAGS"\ - -o "release/$NAME" ./cmd/dep/ - shasum -a 256 "release/$NAME" > "release/$NAME".sha256 - done -done diff --git a/vendor/github.com/golang/dep/hack/coverage.bash b/vendor/github.com/golang/dep/hack/coverage.bash deleted file mode 100755 index 6ad89d9f54e847656e916f8b73836be46e644935..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/coverage.bash +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script will generate coverage.txt -set -e - -PKGS=$(go list ./... | grep -v /vendor/) -for pkg in $PKGS; do - go test -race -coverprofile=profile.out -covermode=atomic $pkg - if [[ -f profile.out ]]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel b/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel deleted file mode 100644 index f1194382b165c29f44dab43eb11adfeb75f28947..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") - -go_library( - name = "go_default_library", - srcs = ["main.go"], - importmap = "vendor/github.com/golang/dep/hack/licenseok", - importpath = "github.com/golang/dep/hack/licenseok", - visibility = ["//visibility:private"], -) - -go_binary( - name = "licenseok", - embed = [":go_default_library"], - visibility = ["//visibility:public"], -) diff --git a/vendor/github.com/golang/dep/hack/licenseok/main.go b/vendor/github.com/golang/dep/hack/licenseok/main.go deleted file mode 100644 index f47c7715836a1871bb6eea7d72b373bf7b0acea8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/licenseok/main.go +++ /dev/null @@ -1,201 +0,0 @@ -// 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. - -// Checks if all files have the license header, a lot of this is based off -// https://github.com/google/addlicense. -package main - -import ( - "bytes" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "sync" - "time" -) - -const helpText = `Usage: licenseok [flags] pattern [pattern ...] -This program ensures source code files have copyright license headers -by scanning directory patterns recursively. -The pattern argument can be provided multiple times, and may also refer -to single files. -Flags: -` - -const tmpl = `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.` - -var ( - update bool -) - -type file struct { - path string - mode os.FileMode -} - -func init() { - flag.BoolVar(&update, "u", false, "modifies all source files in place and avoids adding a license header to any file that already has one.") - - flag.Usage = func() { - fmt.Fprintln(os.Stderr, helpText) - flag.PrintDefaults() - } - - flag.Parse() - - if flag.NArg() == 0 { - flag.Usage() - os.Exit(1) - } -} - -func main() { - exitStatus := 0 - - // process at most 1000 files in parallel - ch := make(chan *file, 1000) - done := make(chan struct{}) - go func() { - var wg sync.WaitGroup - for f := range ch { - wg.Add(1) - go func(f *file) { - b, err := ioutil.ReadFile(f.path) - if err != nil { - log.Printf("%s: %v", f.path, err) - exitStatus = 1 - } - - if !hasLicense(b) { - if !update { - fmt.Fprintln(os.Stderr, f.path) - exitStatus = 1 - } else { - fmt.Fprintln(os.Stdout, f.path) - if err := addLicense(b, f.path, f.mode); err != nil { - log.Printf("%s: %v", f.path, err) - exitStatus = 1 - } - } - } - - wg.Done() - }(f) - } - wg.Wait() - close(done) - }() - - for _, d := range flag.Args() { - walk(ch, d) - } - close(ch) - <-done - os.Exit(exitStatus) -} - -func walk(ch chan<- *file, start string) { - filepath.Walk(start, func(path string, fi os.FileInfo, err error) error { - if err != nil { - log.Printf("%s error: %v", path, err) - return nil - } - if fi.IsDir() { - return nil - } - ch <- &file{path, fi.Mode()} - return nil - }) -} - -func addLicense(b []byte, path string, fmode os.FileMode) error { - var lic []byte - var err error - switch filepath.Ext(path) { - default: - return nil - case ".c", ".h": - lic, err = prefix("/*", " * ", " */") - case ".js", ".css": - lic, err = prefix("/**", " * ", " */") - case ".cc", ".cpp", ".cs", ".go", ".hh", ".hpp", ".java", ".m", ".mm", ".proto", ".rs", ".scala", ".swift", ".dart": - lic, err = prefix("", "// ", "") - case ".py", ".sh": - lic, err = prefix("", "# ", "") - case ".el", ".lisp": - lic, err = prefix("", ";; ", "") - case ".erl": - lic, err = prefix("", "% ", "") - case ".hs": - lic, err = prefix("", "-- ", "") - case ".html", ".xml": - lic, err = prefix("<!--", " ", "-->") - case ".php": - lic, err = prefix("<?php", "// ", "?>") - } - if err != nil || lic == nil { - return err - } - - line := hashBang(b) - if len(line) > 0 { - b = b[len(line):] - if line[len(line)-1] != '\n' { - line = append(line, '\n') - } - lic = append(line, lic...) - } - b = append(lic, b...) - return ioutil.WriteFile(path, b, fmode) -} - -func hashBang(b []byte) []byte { - var line []byte - for _, c := range b { - line = append(line, c) - if c == '\n' { - break - } - } - if bytes.HasPrefix(line, []byte("#!")) { - return line - } - return nil -} - -func hasLicense(b []byte) bool { - n := 100 - if len(b) < 100 { - n = len(b) - } - return bytes.Contains(bytes.ToLower(b[:n]), []byte("copyright")) -} - -// prefix will execute a license template and prefix the result with top, middle and bottom. -func prefix(top, mid, bot string) ([]byte, error) { - buf := bytes.NewBufferString(fmt.Sprintf("Copyright %d %s", time.Now().Year(), tmpl)) - var out bytes.Buffer - if top != "" { - out.WriteString(top) - out.WriteRune('\n') - } - out.WriteString(mid) - for _, c := range buf.Bytes() { - out.WriteByte(c) - if c == '\n' { - out.WriteString(mid) - } - } - if bot != "" { - out.WriteRune('\n') - out.WriteString(bot) - } - out.Write([]byte{'\n', '\n'}) - return out.Bytes(), nil -} diff --git a/vendor/github.com/golang/dep/hack/lint.bash b/vendor/github.com/golang/dep/hack/lint.bash deleted file mode 100755 index c474d6b7cc655f975b8fbe6a0d0db7cda655b3dc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/lint.bash +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script will validate code with various linters -set -e - -PKGS=$(go list ./... | grep -vF /vendor/) -go vet $PKGS -golint $PKGS -megacheck -unused.exported -ignore "github.com/golang/dep/internal/test/test.go:U1000 github.com/golang/dep/gps/prune.go:U1000 github.com/golang/dep/manifest.go:U1000" $PKGS diff --git a/vendor/github.com/golang/dep/hack/validate-gofmt.bash b/vendor/github.com/golang/dep/hack/validate-gofmt.bash deleted file mode 100755 index a5ee7fa8bbc02e5e28869ef6ae6982ac1004d37f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/validate-gofmt.bash +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script will validate that `go fmt` has been ran -# and is passing for certain directories in the project. -# -# Here we use `go list` to help determine which packages -# we need to check for `go fmt` -# -# EXIT 0 - The check is successful -# EXIT 1 - The check has failed - -PKGS=$(go list ./... | grep -v /vendor/) -REPO_TLD="github.com/golang/dep" -IGNORE_PKGS=". ./gps" - -for PKG in $PKGS; do - RELATIVE_PATH="${PKG/$REPO_TLD/.}" - i=0 - for IGNORE_PKG in $IGNORE_PKGS; do - if [ "${IGNORE_PKG}" == $RELATIVE_PATH ]; then - i=1 - fi - done; - if [ $i -eq 1 ]; then - continue - fi - - echo "Processing gofmt for: ${PKG}" - gofmt -s -l $RELATIVE_PATH - if [ $? -ne 0 ]; then - echo "GO FMT FAILURE: ${PKG}" - exit 1 - fi -done; -exit 0 diff --git a/vendor/github.com/golang/dep/hack/validate-licence.bash b/vendor/github.com/golang/dep/hack/validate-licence.bash deleted file mode 100755 index dcf1c7edac20f75ffdc0003dce2ce4155affefef..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/validate-licence.bash +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script will build licenseok and run it on all -# source files to check licence -set -e - -go build ./hack/licenseok -find . -path ./vendor -prune -o -regex ".+\.pb\.go$" -prune -o -type f -regex ".*\.\(go\|proto\)$"\ - -printf '%P\n' | xargs ./licenseok diff --git a/vendor/github.com/golang/dep/hack/validate-vendor.bash b/vendor/github.com/golang/dep/hack/validate-vendor.bash deleted file mode 100755 index d6fb2bf5bc1613b6e4c19e507063e1efbf49f5f3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/hack/validate-vendor.bash +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# 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. -# -# This script checks if we changed anything with regard to dependency management -# for our repo and makes sure that it was done in a valid way. - -set -e -o pipefail - -if [ -z "$VALIDATE_UPSTREAM" ]; then - VALIDATE_REPO='https://github.com/golang/dep.git' - VALIDATE_BRANCH='master' - - VALIDATE_HEAD="$(git rev-parse --verify HEAD)" - - git fetch -q "$VALIDATE_REPO" "refs/heads/$VALIDATE_BRANCH" - VALIDATE_UPSTREAM="$(git rev-parse --verify FETCH_HEAD)" - - VALIDATE_COMMIT_DIFF="$VALIDATE_UPSTREAM...$VALIDATE_HEAD" - - validate_diff() { - if [ "$VALIDATE_UPSTREAM" != "$VALIDATE_HEAD" ]; then - git diff "$VALIDATE_COMMIT_DIFF" "$@" - fi - } -fi - -IFS=$'\n' -files=( $(validate_diff --diff-filter=ACMR --name-only -- 'Gopkg.toml' 'Gopkg.lock' 'vendor/' || true) ) -unset IFS - -if [ ${#files[@]} -gt 0 ]; then - go build ./cmd/dep - ./dep ensure -vendor-only - # Let see if the working directory is clean - diffs="$(git status --porcelain -- vendor Gopkg.toml Gopkg.lock 2>/dev/null)" - if [ "$diffs" ]; then - { - echo 'The contents of vendor differ after "dep ensure":' - echo - echo "$diffs" - echo - echo 'Make sure these commands have been run before committing.' - echo - } >&2 - false - else - echo 'Congratulations! All vendoring changes are done the right way.' - fi -else - echo 'No vendor changes in diff.' -fi diff --git a/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel b/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel deleted file mode 100644 index 10a231192ad633adb6101fb572486d4749df5348..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel +++ /dev/null @@ -1,10 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["feedback.go"], - importmap = "vendor/github.com/golang/dep/internal/feedback", - importpath = "github.com/golang/dep/internal/feedback", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = ["//vendor/github.com/golang/dep/gps:go_default_library"], -) diff --git a/vendor/github.com/golang/dep/internal/feedback/feedback.go b/vendor/github.com/golang/dep/internal/feedback/feedback.go deleted file mode 100644 index 7084b9b971e4eee57760575520ff679b76c664e7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/feedback/feedback.go +++ /dev/null @@ -1,117 +0,0 @@ -// 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 feedback - -import ( - "encoding/hex" - "fmt" - "log" - - "github.com/golang/dep/gps" -) - -const ( - // ConsTypeConstraint represents a constraint - ConsTypeConstraint = "constraint" - - // ConsTypeHint represents a constraint type hint - ConsTypeHint = "hint" - - // DepTypeDirect represents a direct dependency - DepTypeDirect = "direct dep" - - // DepTypeTransitive represents a transitive dependency, - // or a dependency of a dependency - DepTypeTransitive = "transitive dep" - - // DepTypeImported represents a dependency imported by an external tool - DepTypeImported = "imported dep" -) - -// ConstraintFeedback holds project constraint feedback data -type ConstraintFeedback struct { - Constraint, LockedVersion, Revision, ConstraintType, DependencyType, ProjectPath string -} - -// NewConstraintFeedback builds a feedback entry for a constraint in the manifest. -func NewConstraintFeedback(pc gps.ProjectConstraint, depType string) *ConstraintFeedback { - cf := &ConstraintFeedback{ - Constraint: pc.Constraint.String(), - ProjectPath: string(pc.Ident.ProjectRoot), - DependencyType: depType, - } - - if _, ok := pc.Constraint.(gps.Revision); ok { - cf.ConstraintType = ConsTypeHint - } else { - cf.ConstraintType = ConsTypeConstraint - } - - return cf -} - -// NewLockedProjectFeedback builds a feedback entry for a project in the lock. -func NewLockedProjectFeedback(lp gps.LockedProject, depType string) *ConstraintFeedback { - cf := &ConstraintFeedback{ - ProjectPath: string(lp.Ident().ProjectRoot), - DependencyType: depType, - } - - switch vt := lp.Version().(type) { - case gps.PairedVersion: - cf.LockedVersion = vt.String() - cf.Revision = vt.Revision().String() - case gps.UnpairedVersion: // Logically this should never occur, but handle for completeness sake - cf.LockedVersion = vt.String() - case gps.Revision: - cf.Revision = vt.String() - } - - return cf -} - -// LogFeedback logs feedback on changes made to the manifest or lock. -func (cf ConstraintFeedback) LogFeedback(logger *log.Logger) { - if cf.Constraint != "" { - logger.Printf(" %v", GetUsingFeedback(cf.Constraint, cf.ConstraintType, cf.DependencyType, cf.ProjectPath)) - } - if cf.Revision != "" { - logger.Printf(" %v", GetLockingFeedback(cf.LockedVersion, cf.Revision, cf.DependencyType, cf.ProjectPath)) - } -} - -// GetUsingFeedback returns a dependency "using" feedback message. For example: -// -// Using ^1.0.0 as constraint for direct dep github.com/foo/bar -// Using 1b8edb3 as hint for direct dep github.com/bar/baz -func GetUsingFeedback(version, consType, depType, projectPath string) string { - if depType == DepTypeImported { - return fmt.Sprintf("Using %s as initial %s for %s %s", version, consType, depType, projectPath) - } - return fmt.Sprintf("Using %s as %s for %s %s", version, consType, depType, projectPath) -} - -// GetLockingFeedback returns a dependency "locking" feedback message. For -// example: -// -// Locking in v1.1.4 (bc29b4f) for direct dep github.com/foo/bar -// Locking in master (436f39d) for transitive dep github.com/baz/qux -func GetLockingFeedback(version, revision, depType, projectPath string) string { - // Check if it's a valid SHA1 digest and trim to 7 characters. - if len(revision) == 40 { - if _, err := hex.DecodeString(revision); err == nil { - // Valid SHA1 digest - revision = revision[0:7] - } - } - - if depType == DepTypeImported { - if version == "" { - version = "*" - } - return fmt.Sprintf("Trying %s (%s) as initial lock for %s %s", version, revision, depType, projectPath) - } - return fmt.Sprintf("Locking in %s (%s) for %s %s", version, revision, depType, projectPath) -} diff --git a/vendor/github.com/golang/dep/internal/fs/BUILD.bazel b/vendor/github.com/golang/dep/internal/fs/BUILD.bazel deleted file mode 100644 index 10e60f08a648cf669b64ce6bd9bfafe06f771ecf..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/BUILD.bazel +++ /dev/null @@ -1,14 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "fs.go", - "rename.go", - "rename_windows.go", - ], - importmap = "vendor/github.com/golang/dep/internal/fs", - importpath = "github.com/golang/dep/internal/fs", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = ["//vendor/github.com/pkg/errors:go_default_library"], -) diff --git a/vendor/github.com/golang/dep/internal/fs/fs.go b/vendor/github.com/golang/dep/internal/fs/fs.go deleted file mode 100644 index 4be512aad81b09a8e617304185031eeb5e8f6d3d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/fs.go +++ /dev/null @@ -1,694 +0,0 @@ -// 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 fs - -import ( - "io" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strings" - "syscall" - "unicode" - - "github.com/pkg/errors" -) - -// HasFilepathPrefix will determine if "path" starts with "prefix" from -// the point of view of a filesystem. -// -// Unlike filepath.HasPrefix, this function is path-aware, meaning that -// it knows that two directories /foo and /foobar are not the same -// thing, and therefore HasFilepathPrefix("/foobar", "/foo") will return -// false. -// -// This function also handles the case where the involved filesystems -// are case-insensitive, meaning /foo/bar and /Foo/Bar correspond to the -// same file. In that situation HasFilepathPrefix("/Foo/Bar", "/foo") -// will return true. The implementation is *not* OS-specific, so a FAT32 -// filesystem mounted on Linux will be handled correctly. -func HasFilepathPrefix(path, prefix string) (bool, error) { - // this function is more convoluted then ideal due to need for special - // handling of volume name/drive letter on Windows. vnPath and vnPrefix - // are first compared, and then used to initialize initial values of p and - // d which will be appended to for incremental checks using - // IsCaseSensitiveFilesystem and then equality. - - // no need to check IsCaseSensitiveFilesystem because VolumeName return - // empty string on all non-Windows machines - vnPath := strings.ToLower(filepath.VolumeName(path)) - vnPrefix := strings.ToLower(filepath.VolumeName(prefix)) - if vnPath != vnPrefix { - return false, nil - } - - // Because filepath.Join("c:","dir") returns "c:dir", we have to manually - // add path separator to drive letters. Also, we need to set the path root - // on *nix systems, since filepath.Join("", "dir") returns a relative path. - vnPath += string(os.PathSeparator) - vnPrefix += string(os.PathSeparator) - - var dn string - - if isDir, err := IsDir(path); err != nil { - return false, errors.Wrap(err, "failed to check filepath prefix") - } else if isDir { - dn = path - } else { - dn = filepath.Dir(path) - } - - dn = strings.TrimSuffix(dn, string(os.PathSeparator)) - prefix = strings.TrimSuffix(prefix, string(os.PathSeparator)) - - // [1:] in the lines below eliminates empty string on *nix and volume name on Windows - dirs := strings.Split(dn, string(os.PathSeparator))[1:] - prefixes := strings.Split(prefix, string(os.PathSeparator))[1:] - - if len(prefixes) > len(dirs) { - return false, nil - } - - // d,p are initialized with "/" on *nix and volume name on Windows - d := vnPath - p := vnPrefix - - for i := range prefixes { - // need to test each component of the path for - // case-sensitiveness because on Unix we could have - // something like ext4 filesystem mounted on FAT - // mountpoint, mounted on ext4 filesystem, i.e. the - // problematic filesystem is not the last one. - caseSensitive, err := IsCaseSensitiveFilesystem(filepath.Join(d, dirs[i])) - if err != nil { - return false, errors.Wrap(err, "failed to check filepath prefix") - } - if caseSensitive { - d = filepath.Join(d, dirs[i]) - p = filepath.Join(p, prefixes[i]) - } else { - d = filepath.Join(d, strings.ToLower(dirs[i])) - p = filepath.Join(p, strings.ToLower(prefixes[i])) - } - - if p != d { - return false, nil - } - } - - return true, nil -} - -// EquivalentPaths compares the paths passed to check if they are equivalent. -// It respects the case-sensitivity of the underlying filesysyems. -func EquivalentPaths(p1, p2 string) (bool, error) { - p1 = filepath.Clean(p1) - p2 = filepath.Clean(p2) - - fi1, err := os.Stat(p1) - if err != nil { - return false, errors.Wrapf(err, "could not check for path equivalence") - } - fi2, err := os.Stat(p2) - if err != nil { - return false, errors.Wrapf(err, "could not check for path equivalence") - } - - p1Filename, p2Filename := "", "" - - if !fi1.IsDir() { - p1, p1Filename = filepath.Split(p1) - } - if !fi2.IsDir() { - p2, p2Filename = filepath.Split(p2) - } - - if isPrefix1, err := HasFilepathPrefix(p1, p2); err != nil { - return false, errors.Wrap(err, "failed to check for path equivalence") - } else if isPrefix2, err := HasFilepathPrefix(p2, p1); err != nil { - return false, errors.Wrap(err, "failed to check for path equivalence") - } else if !isPrefix1 || !isPrefix2 { - return false, nil - } - - if p1Filename != "" || p2Filename != "" { - caseSensitive, err := IsCaseSensitiveFilesystem(filepath.Join(p1, p1Filename)) - if err != nil { - return false, errors.Wrap(err, "could not check for filesystem case-sensitivity") - } - if caseSensitive { - if p1Filename != p2Filename { - return false, nil - } - } else { - if strings.ToLower(p1Filename) != strings.ToLower(p2Filename) { - return false, nil - } - } - } - - return true, nil -} - -// RenameWithFallback attempts to rename a file or directory, but falls back to -// copying in the event of a cross-device link error. If the fallback copy -// succeeds, src is still removed, emulating normal rename behavior. -func RenameWithFallback(src, dst string) error { - _, err := os.Stat(src) - if err != nil { - return errors.Wrapf(err, "cannot stat %s", src) - } - - err = os.Rename(src, dst) - if err == nil { - return nil - } - - return renameFallback(err, src, dst) -} - -// renameByCopy attempts to rename a file or directory by copying it to the -// destination and then removing the src thus emulating the rename behavior. -func renameByCopy(src, dst string) error { - var cerr error - if dir, _ := IsDir(src); dir { - cerr = CopyDir(src, dst) - if cerr != nil { - cerr = errors.Wrap(cerr, "copying directory failed") - } - } else { - cerr = copyFile(src, dst) - if cerr != nil { - cerr = errors.Wrap(cerr, "copying file failed") - } - } - - if cerr != nil { - return errors.Wrapf(cerr, "rename fallback failed: cannot rename %s to %s", src, dst) - } - - return errors.Wrapf(os.RemoveAll(src), "cannot delete %s", src) -} - -// IsCaseSensitiveFilesystem determines if the filesystem where dir -// exists is case sensitive or not. -// -// CAVEAT: this function works by taking the last component of the given -// path and flipping the case of the first letter for which case -// flipping is a reversible operation (/foo/Bar → /foo/bar), then -// testing for the existence of the new filename. There are two -// possibilities: -// -// 1. The alternate filename does not exist. We can conclude that the -// filesystem is case sensitive. -// -// 2. The filename happens to exist. We have to test if the two files -// are the same file (case insensitive file system) or different ones -// (case sensitive filesystem). -// -// If the input directory is such that the last component is composed -// exclusively of case-less codepoints (e.g. numbers), this function will -// return false. -func IsCaseSensitiveFilesystem(dir string) (bool, error) { - alt := filepath.Join(filepath.Dir(dir), genTestFilename(filepath.Base(dir))) - - dInfo, err := os.Stat(dir) - if err != nil { - return false, errors.Wrap(err, "could not determine the case-sensitivity of the filesystem") - } - - aInfo, err := os.Stat(alt) - if err != nil { - // If the file doesn't exists, assume we are on a case-sensitive filesystem. - if os.IsNotExist(err) { - return true, nil - } - - return false, errors.Wrap(err, "could not determine the case-sensitivity of the filesystem") - } - - return !os.SameFile(dInfo, aInfo), nil -} - -// genTestFilename returns a string with at most one rune case-flipped. -// -// The transformation is applied only to the first rune that can be -// reversibly case-flipped, meaning: -// -// * A lowercase rune for which it's true that lower(upper(r)) == r -// * An uppercase rune for which it's true that upper(lower(r)) == r -// -// All the other runes are left intact. -func genTestFilename(str string) string { - flip := true - return strings.Map(func(r rune) rune { - if flip { - if unicode.IsLower(r) { - u := unicode.ToUpper(r) - if unicode.ToLower(u) == r { - r = u - flip = false - } - } else if unicode.IsUpper(r) { - l := unicode.ToLower(r) - if unicode.ToUpper(l) == r { - r = l - flip = false - } - } - } - return r - }, str) -} - -var errPathNotDir = errors.New("given path is not a directory") - -// ReadActualFilenames is used to determine the actual file names in given directory. -// -// On case sensitive file systems like ext4, it will check if those files exist using -// `os.Stat` and return a map with key and value as filenames which exist in the folder. -// -// Otherwise, it reads the contents of the directory and returns a map which has the -// given file name as the key and actual filename as the value(if it was found). -func ReadActualFilenames(dirPath string, names []string) (map[string]string, error) { - actualFilenames := make(map[string]string, len(names)) - if len(names) == 0 { - // This isn't expected to happen for current usage. Adding edge case handling, - // as it may be useful in future. - return actualFilenames, nil - } - // First, check that the given path is valid and it is a directory - dirStat, err := os.Stat(dirPath) - if err != nil { - return nil, errors.Wrap(err, "failed to read actual filenames") - } - - if !dirStat.IsDir() { - return nil, errPathNotDir - } - - // Ideally, we would use `os.Stat` for getting the actual file names but that returns - // the name we passed in as an argument and not the actual filename. So we are forced - // to list the directory contents and check against that. Since this check is costly, - // we do it only if absolutely necessary. - caseSensitive, err := IsCaseSensitiveFilesystem(dirPath) - if err != nil { - return nil, errors.Wrap(err, "failed to read actual filenames") - } - if caseSensitive { - // There will be no difference between actual filename and given filename. So - // just check if those files exist. - for _, name := range names { - _, err := os.Stat(filepath.Join(dirPath, name)) - if err == nil { - actualFilenames[name] = name - } else if !os.IsNotExist(err) { - // Some unexpected err, wrap and return it. - return nil, errors.Wrap(err, "failed to read actual filenames") - } - } - return actualFilenames, nil - } - - dir, err := os.Open(dirPath) - if err != nil { - return nil, errors.Wrap(err, "failed to read actual filenames") - } - defer dir.Close() - - // Pass -1 to read all filenames in directory - filenames, err := dir.Readdirnames(-1) - if err != nil { - return nil, errors.Wrap(err, "failed to read actual filenames") - } - - // namesMap holds the mapping from lowercase name to search name. Using this, we can - // avoid repeatedly looping through names. - namesMap := make(map[string]string, len(names)) - for _, name := range names { - namesMap[strings.ToLower(name)] = name - } - - for _, filename := range filenames { - searchName, ok := namesMap[strings.ToLower(filename)] - if ok { - // We are interested in this file, case insensitive match successful. - actualFilenames[searchName] = filename - if len(actualFilenames) == len(names) { - // We found all that we were looking for. - return actualFilenames, nil - } - } - } - return actualFilenames, nil -} - -var ( - errSrcNotDir = errors.New("source is not a directory") - errDstExist = errors.New("destination already exists") -) - -// CopyDir recursively copies a directory tree, attempting to preserve permissions. -// Source directory must exist, destination directory must *not* exist. -func CopyDir(src, dst string) error { - src = filepath.Clean(src) - dst = filepath.Clean(dst) - - // We use os.Lstat() here to ensure we don't fall in a loop where a symlink - // actually links to a one of its parent directories. - fi, err := os.Lstat(src) - if err != nil { - return err - } - if !fi.IsDir() { - return errSrcNotDir - } - - _, err = os.Stat(dst) - if err != nil && !os.IsNotExist(err) { - return err - } - if err == nil { - return errDstExist - } - - if err = os.MkdirAll(dst, fi.Mode()); err != nil { - return errors.Wrapf(err, "cannot mkdir %s", dst) - } - - entries, err := ioutil.ReadDir(src) - if err != nil { - return errors.Wrapf(err, "cannot read directory %s", dst) - } - - for _, entry := range entries { - srcPath := filepath.Join(src, entry.Name()) - dstPath := filepath.Join(dst, entry.Name()) - - if entry.IsDir() { - if err = CopyDir(srcPath, dstPath); err != nil { - return errors.Wrap(err, "copying directory failed") - } - } else { - // This will include symlinks, which is what we want when - // copying things. - if err = copyFile(srcPath, dstPath); err != nil { - return errors.Wrap(err, "copying file failed") - } - } - } - - return nil -} - -// copyFile copies the contents of the file named src to the file named -// by dst. The file will be created if it does not already exist. If the -// destination file exists, all its contents will be replaced by the contents -// of the source file. The file mode will be copied from the source. -func copyFile(src, dst string) (err error) { - if sym, err := IsSymlink(src); err != nil { - return errors.Wrap(err, "symlink check failed") - } else if sym { - if err := cloneSymlink(src, dst); err != nil { - if runtime.GOOS == "windows" { - // If cloning the symlink fails on Windows because the user - // does not have the required privileges, ignore the error and - // fall back to copying the file contents. - // - // ERROR_PRIVILEGE_NOT_HELD is 1314 (0x522): - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx - if lerr, ok := err.(*os.LinkError); ok && lerr.Err != syscall.Errno(1314) { - return err - } - } else { - return err - } - } else { - return nil - } - } - - in, err := os.Open(src) - if err != nil { - return - } - defer in.Close() - - out, err := os.Create(dst) - if err != nil { - return - } - - if _, err = io.Copy(out, in); err != nil { - out.Close() - return - } - - // Check for write errors on Close - if err = out.Close(); err != nil { - return - } - - si, err := os.Stat(src) - if err != nil { - return - } - - // Temporary fix for Go < 1.9 - // - // See: https://github.com/golang/dep/issues/774 - // and https://github.com/golang/go/issues/20829 - if runtime.GOOS == "windows" { - dst = fixLongPath(dst) - } - err = os.Chmod(dst, si.Mode()) - - return -} - -// cloneSymlink will create a new symlink that points to the resolved path of sl. -// If sl is a relative symlink, dst will also be a relative symlink. -func cloneSymlink(sl, dst string) error { - resolved, err := os.Readlink(sl) - if err != nil { - return err - } - - return os.Symlink(resolved, dst) -} - -// EnsureDir tries to ensure that a directory is present at the given path. It first -// checks if the directory already exists at the given path. If there isn't one, it tries -// to create it with the given permissions. However, it does not try to create the -// directory recursively. -func EnsureDir(path string, perm os.FileMode) error { - _, err := IsDir(path) - - if os.IsNotExist(err) { - err = os.Mkdir(path, perm) - if err != nil { - return errors.Wrapf(err, "failed to ensure directory at %q", path) - } - } - - return err -} - -// IsDir determines is the path given is a directory or not. -func IsDir(name string) (bool, error) { - fi, err := os.Stat(name) - if err != nil { - return false, err - } - if !fi.IsDir() { - return false, errors.Errorf("%q is not a directory", name) - } - return true, nil -} - -// IsNonEmptyDir determines if the path given is a non-empty directory or not. -func IsNonEmptyDir(name string) (bool, error) { - isDir, err := IsDir(name) - if err != nil && !os.IsNotExist(err) { - return false, err - } else if !isDir { - return false, nil - } - - // Get file descriptor - f, err := os.Open(name) - if err != nil { - return false, err - } - defer f.Close() - - // Query only 1 child. EOF if no children. - _, err = f.Readdirnames(1) - switch err { - case io.EOF: - return false, nil - case nil: - return true, nil - default: - return false, err - } -} - -// IsRegular determines if the path given is a regular file or not. -func IsRegular(name string) (bool, error) { - fi, err := os.Stat(name) - if os.IsNotExist(err) { - return false, nil - } - if err != nil { - return false, err - } - mode := fi.Mode() - if mode&os.ModeType != 0 { - return false, errors.Errorf("%q is a %v, expected a file", name, mode) - } - return true, nil -} - -// IsSymlink determines if the given path is a symbolic link. -func IsSymlink(path string) (bool, error) { - l, err := os.Lstat(path) - if err != nil { - return false, err - } - - return l.Mode()&os.ModeSymlink == os.ModeSymlink, nil -} - -// fixLongPath returns the extended-length (\\?\-prefixed) form of -// path when needed, in order to avoid the default 260 character file -// path limit imposed by Windows. If path is not easily converted to -// the extended-length form (for example, if path is a relative path -// or contains .. elements), or is short enough, fixLongPath returns -// path unmodified. -// -// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath -func fixLongPath(path string) string { - // Do nothing (and don't allocate) if the path is "short". - // Empirically (at least on the Windows Server 2013 builder), - // the kernel is arbitrarily okay with < 248 bytes. That - // matches what the docs above say: - // "When using an API to create a directory, the specified - // path cannot be so long that you cannot append an 8.3 file - // name (that is, the directory name cannot exceed MAX_PATH - // minus 12)." Since MAX_PATH is 260, 260 - 12 = 248. - // - // The MSDN docs appear to say that a normal path that is 248 bytes long - // will work; empirically the path must be less then 248 bytes long. - if len(path) < 248 { - // Don't fix. (This is how Go 1.7 and earlier worked, - // not automatically generating the \\?\ form) - return path - } - - // The extended form begins with \\?\, as in - // \\?\c:\windows\foo.txt or \\?\UNC\server\share\foo.txt. - // The extended form disables evaluation of . and .. path - // elements and disables the interpretation of / as equivalent - // to \. The conversion here rewrites / to \ and elides - // . elements as well as trailing or duplicate separators. For - // simplicity it avoids the conversion entirely for relative - // paths or paths containing .. elements. For now, - // \\server\share paths are not converted to - // \\?\UNC\server\share paths because the rules for doing so - // are less well-specified. - if len(path) >= 2 && path[:2] == `\\` { - // Don't canonicalize UNC paths. - return path - } - if !isAbs(path) { - // Relative path - return path - } - - const prefix = `\\?` - - pathbuf := make([]byte, len(prefix)+len(path)+len(`\`)) - copy(pathbuf, prefix) - n := len(path) - r, w := 0, len(prefix) - for r < n { - switch { - case os.IsPathSeparator(path[r]): - // empty block - r++ - case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])): - // /./ - r++ - case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])): - // /../ is currently unhandled - return path - default: - pathbuf[w] = '\\' - w++ - for ; r < n && !os.IsPathSeparator(path[r]); r++ { - pathbuf[w] = path[r] - w++ - } - } - } - // A drive's root directory needs a trailing \ - if w == len(`\\?\c:`) { - pathbuf[w] = '\\' - w++ - } - return string(pathbuf[:w]) -} - -func isAbs(path string) (b bool) { - v := volumeName(path) - if v == "" { - return false - } - path = path[len(v):] - if path == "" { - return false - } - return os.IsPathSeparator(path[0]) -} - -func volumeName(path string) (v string) { - if len(path) < 2 { - return "" - } - // with drive letter - c := path[0] - if path[1] == ':' && - ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || - 'A' <= c && c <= 'Z') { - return path[:2] - } - // is it UNC - if l := len(path); l >= 5 && os.IsPathSeparator(path[0]) && os.IsPathSeparator(path[1]) && - !os.IsPathSeparator(path[2]) && path[2] != '.' { - // first, leading `\\` and next shouldn't be `\`. its server name. - for n := 3; n < l-1; n++ { - // second, next '\' shouldn't be repeated. - if os.IsPathSeparator(path[n]) { - n++ - // third, following something characters. its share name. - if !os.IsPathSeparator(path[n]) { - if path[n] == '.' { - break - } - for ; n < l; n++ { - if os.IsPathSeparator(path[n]) { - break - } - } - return path[:n] - } - break - } - } - } - return "" -} diff --git a/vendor/github.com/golang/dep/internal/fs/rename.go b/vendor/github.com/golang/dep/internal/fs/rename.go deleted file mode 100644 index c48f69f1a0f2ff97ce5c729cd9152f3a6eff664a..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/rename.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - -// +build !windows - -package fs - -import ( - "os" - "syscall" - - "github.com/pkg/errors" -) - -// renameFallback attempts to determine the appropriate fallback to failed rename -// operation depending on the resulting error. -func renameFallback(err error, src, dst string) error { - // Rename may fail if src and dst are on different devices; fall back to - // copy if we detect that case. syscall.EXDEV is the common name for the - // cross device link error which has varying output text across different - // operating systems. - terr, ok := err.(*os.LinkError) - if !ok { - return err - } else if terr.Err != syscall.EXDEV { - return errors.Wrapf(terr, "link error: cannot rename %s to %s", src, dst) - } - - return renameByCopy(src, dst) -} diff --git a/vendor/github.com/golang/dep/internal/fs/rename_windows.go b/vendor/github.com/golang/dep/internal/fs/rename_windows.go deleted file mode 100644 index 50829a5cd0ac4c4c0c482fd0a891ad964eba8f4c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/rename_windows.go +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -// +build windows - -package fs - -import ( - "os" - "syscall" - - "github.com/pkg/errors" -) - -// renameFallback attempts to determine the appropriate fallback to failed rename -// operation depending on the resulting error. -func renameFallback(err error, src, dst string) error { - // Rename may fail if src and dst are on different devices; fall back to - // copy if we detect that case. syscall.EXDEV is the common name for the - // cross device link error which has varying output text across different - // operating systems. - terr, ok := err.(*os.LinkError) - if !ok { - return err - } - - if terr.Err != syscall.EXDEV { - // In windows it can drop down to an operating system call that - // returns an operating system error with a different number and - // message. Checking for that as a fall back. - noerr, ok := terr.Err.(syscall.Errno) - - // 0x11 (ERROR_NOT_SAME_DEVICE) is the windows error. - // See https://msdn.microsoft.com/en-us/library/cc231199.aspx - if ok && noerr != 0x11 { - return errors.Wrapf(terr, "link error: cannot rename %s to %s", src, dst) - } - } - - return renameByCopy(src, dst) -} diff --git a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/file-symlink b/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/file-symlink deleted file mode 120000 index 4c52274de03d033b81624d6e4166dad4ed318305..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/file-symlink +++ /dev/null @@ -1 +0,0 @@ -../test.file \ No newline at end of file diff --git a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/invalid-symlink b/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/invalid-symlink deleted file mode 120000 index 0edf4f301b10b187dc83623bd7355ddabde08b31..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/invalid-symlink +++ /dev/null @@ -1 +0,0 @@ -/non/existing/file \ No newline at end of file diff --git a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/windows-file-symlink b/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/windows-file-symlink deleted file mode 120000 index af1d6c8f573953098bec93dace071d9c84880297..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/fs/testdata/symlinks/windows-file-symlink +++ /dev/null @@ -1 +0,0 @@ -C:/Users/ibrahim/go/src/github.com/golang/dep/internal/fs/testdata/test.file \ No newline at end of file diff --git a/vendor/github.com/golang/dep/internal/fs/testdata/test.file b/vendor/github.com/golang/dep/internal/fs/testdata/test.file deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/internal/importers/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/BUILD.bazel deleted file mode 100644 index 7d4330ccf931e7f74c62cd00aa46394a11c6f2cf..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/BUILD.bazel +++ /dev/null @@ -1,20 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importers.go"], - importmap = "vendor/github.com/golang/dep/internal/importers", - importpath = "github.com/golang/dep/internal/importers", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/glide:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/glock:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/godep:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/govend:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/govendor:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/gvt:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/vndr:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel deleted file mode 100644 index dd342c3138c515f98e89b5d317e4c2a4392e86ee..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/base", - importpath = "github.com/golang/dep/internal/importers/base", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/feedback:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/base/importer.go b/vendor/github.com/golang/dep/internal/importers/base/importer.go deleted file mode 100644 index 82dff70060d0a56a9fc3b221da0a714540ea28d6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/base/importer.go +++ /dev/null @@ -1,333 +0,0 @@ -// 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 base - -import ( - "log" - "strings" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - fb "github.com/golang/dep/internal/feedback" - "github.com/pkg/errors" -) - -// Importer provides a common implementation for importing from other -// dependency managers. -type Importer struct { - SourceManager gps.SourceManager - Logger *log.Logger - Verbose bool - Manifest *dep.Manifest - Lock *dep.Lock -} - -// NewImporter creates a new Importer for embedding in an importer. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{ - Logger: logger, - Verbose: verbose, - Manifest: dep.NewManifest(), - Lock: &dep.Lock{}, - SourceManager: sm, - } -} - -// isTag determines if the specified value is a tag (plain or semver). -func (i *Importer) isTag(pi gps.ProjectIdentifier, value string) (bool, gps.Version, error) { - versions, err := i.SourceManager.ListVersions(pi) - if err != nil { - return false, nil, errors.Wrapf(err, "unable to list versions for %s(%s)", pi.ProjectRoot, pi.Source) - } - - for _, version := range versions { - if version.Type() != gps.IsVersion && version.Type() != gps.IsSemver { - continue - } - - if value == version.String() { - return true, version, nil - } - } - - return false, nil, nil -} - -// lookupVersionForLockedProject figures out the appropriate version for a locked -// project based on the locked revision and the constraint from the manifest. -// First try matching the revision to a version, then try the constraint from the -// manifest, then finally the revision. -func (i *Importer) lookupVersionForLockedProject(pi gps.ProjectIdentifier, c gps.Constraint, rev gps.Revision) (gps.Version, error) { - // Find the version that goes with this revision, if any - versions, err := i.SourceManager.ListVersions(pi) - if err != nil { - return rev, errors.Wrapf(err, "Unable to lookup the version represented by %s in %s(%s). Falling back to locking the revision only.", rev, pi.ProjectRoot, pi.Source) - } - - var branchConstraint gps.PairedVersion - gps.SortPairedForUpgrade(versions) // Sort versions in asc order - matches := []gps.Version{} - for _, v := range versions { - if v.Revision() == rev { - matches = append(matches, v) - } - if c != nil && v.Type() == gps.IsBranch && v.String() == c.String() { - branchConstraint = v - } - } - - // Try to narrow down the matches with the constraint. Otherwise return the first match. - if len(matches) > 0 { - if c != nil { - for _, v := range matches { - if i.testConstraint(c, v) { - return v, nil - } - } - } - return matches[0], nil - } - - // Use branch constraint from the manifest - if branchConstraint != nil { - return branchConstraint.Unpair().Pair(rev), nil - } - - // Give up and lock only to a revision - return rev, nil -} - -// ImportedPackage is a common intermediate representation of a package imported -// from an external tool's configuration. -type ImportedPackage struct { - // Required. The package path, not necessarily the project root. - Name string - - // Required. Text representing a revision or tag. - LockHint string - - // Optional. Alternative source, or fork, for the project. - Source string - - // Optional. Text representing a branch or version. - ConstraintHint string -} - -// importedProject is a consolidated representation of a set of imported packages -// for the same project root. -type importedProject struct { - Root gps.ProjectRoot - ImportedPackage -} - -// loadPackages consolidates all package references into a set of project roots. -func (i *Importer) loadPackages(packages []ImportedPackage) []importedProject { - // preserve the original order of the packages so that messages that - // are printed as they are processed are in a consistent order. - orderedProjects := make([]importedProject, 0, len(packages)) - - projects := make(map[gps.ProjectRoot]*importedProject, len(packages)) - for _, pkg := range packages { - pr, err := i.SourceManager.DeduceProjectRoot(pkg.Name) - if err != nil { - i.Logger.Printf( - " Warning: Skipping project. Cannot determine the project root for %s: %s\n", - pkg.Name, err, - ) - continue - } - pkg.Name = string(pr) - - prj, exists := projects[pr] - if !exists { - prj := importedProject{pr, pkg} - orderedProjects = append(orderedProjects, prj) - projects[pr] = &orderedProjects[len(orderedProjects)-1] - continue - } - - // The config found first "wins", though we allow for incrementally - // setting each field because some importers have a config and lock file. - if prj.Source == "" && pkg.Source != "" { - prj.Source = pkg.Source - } - - if prj.ConstraintHint == "" && pkg.ConstraintHint != "" { - prj.ConstraintHint = pkg.ConstraintHint - } - - if prj.LockHint == "" && pkg.LockHint != "" { - prj.LockHint = pkg.LockHint - } - } - - return orderedProjects -} - -// ImportPackages loads imported packages into the manifest and lock. -// - defaultConstraintFromLock specifies if a constraint should be defaulted -// based on the locked version when there wasn't a constraint hint. -// -// Rules: -// * When a constraint is ignored, default to *. -// * HEAD revisions default to the matching branch. -// * Semantic versions default to ^VERSION. -// * Revision constraints are ignored. -// * Versions that don't satisfy the constraint, drop the constraint. -// * Untagged revisions ignore non-branch constraint hints. -func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintFromLock bool) { - projects := i.loadPackages(packages) - - for _, prj := range projects { - source := prj.Source - if len(source) > 0 { - isDefault, err := i.isDefaultSource(prj.Root, source) - if err != nil { - i.Logger.Printf(" Ignoring imported source %s for %s: %s", source, prj.Root, err.Error()) - source = "" - } else if isDefault { - source = "" - } else if strings.Contains(source, "/vendor/") { - i.Logger.Printf(" Ignoring imported source %s for %s because vendored sources aren't supported", source, prj.Root) - source = "" - } - } - - pc := gps.ProjectConstraint{ - Ident: gps.ProjectIdentifier{ - ProjectRoot: prj.Root, - Source: source, - }, - } - - var err error - pc.Constraint, err = i.SourceManager.InferConstraint(prj.ConstraintHint, pc.Ident) - if err != nil { - pc.Constraint = gps.Any() - } - - var version gps.Version - if prj.LockHint != "" { - var isTag bool - // Determine if the lock hint is a revision or tag - isTag, version, err = i.isTag(pc.Ident, prj.LockHint) - if err != nil { - i.Logger.Printf( - " Warning: Skipping project. Unable to import lock %q for %v: %s\n", - prj.LockHint, pc.Ident, err, - ) - continue - } - // If the hint is a revision, check if it is tagged - if !isTag { - revision := gps.Revision(prj.LockHint) - version, err = i.lookupVersionForLockedProject(pc.Ident, pc.Constraint, revision) - if err != nil { - version = nil - i.Logger.Println(err) - } - } - - // Default the constraint based on the locked version - if defaultConstraintFromLock && prj.ConstraintHint == "" && version != nil { - c := i.convertToConstraint(version) - if c != nil { - pc.Constraint = c - } - } - } - - // Ignore pinned constraints - if i.isConstraintPinned(pc.Constraint) { - if i.Verbose { - i.Logger.Printf(" Ignoring pinned constraint %v for %v.\n", pc.Constraint, pc.Ident) - } - pc.Constraint = gps.Any() - } - - // Ignore constraints which conflict with the locked revision, so that - // solve doesn't later change the revision to satisfy the constraint. - if !i.testConstraint(pc.Constraint, version) { - if i.Verbose { - i.Logger.Printf(" Ignoring constraint %v for %v because it would invalidate the locked version %v.\n", pc.Constraint, pc.Ident, version) - } - pc.Constraint = gps.Any() - } - - // Add constraint to manifest that is not empty (has a branch, version or source) - if !gps.IsAny(pc.Constraint) || pc.Ident.Source != "" { - i.Manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{ - Source: pc.Ident.Source, - Constraint: pc.Constraint, - } - fb.NewConstraintFeedback(pc, fb.DepTypeImported).LogFeedback(i.Logger) - } - - if version != nil { - lp := gps.NewLockedProject(pc.Ident, version, nil) - i.Lock.P = append(i.Lock.P, lp) - fb.NewLockedProjectFeedback(lp, fb.DepTypeImported).LogFeedback(i.Logger) - } - } -} - -// isConstraintPinned returns if a constraint is pinned to a specific revision. -func (i *Importer) isConstraintPinned(c gps.Constraint) bool { - if version, isVersion := c.(gps.Version); isVersion { - switch version.Type() { - case gps.IsRevision, gps.IsVersion: - return true - } - } - return false -} - -// testConstraint verifies that the constraint won't invalidate the locked version. -func (i *Importer) testConstraint(c gps.Constraint, v gps.Version) bool { - // Assume branch constraints are satisfied - if version, isVersion := c.(gps.Version); isVersion { - if version.Type() == gps.IsBranch { - - return true - } - } - - return c.Matches(v) -} - -// convertToConstraint turns a version into a constraint. -// Semver tags are converted to a range with the caret operator. -func (i *Importer) convertToConstraint(v gps.Version) gps.Constraint { - if v.Type() == gps.IsSemver { - c, err := gps.NewSemverConstraintIC(v.String()) - if err != nil { - // This should never fail, because the type is semver. - // If it does fail somehow, don't let that impact the import. - return nil - } - return c - } - return v -} - -func (i *Importer) isDefaultSource(projectRoot gps.ProjectRoot, sourceURL string) (bool, error) { - // this condition is mainly for gopkg.in imports, - // as some importers specify the repository url as https://gopkg.in/..., - // but SourceManager.SourceURLsForPath() returns https://github.com/... urls for gopkg.in - if sourceURL == "https://"+string(projectRoot) { - return true, nil - } - - sourceURLs, err := i.SourceManager.SourceURLsForPath(string(projectRoot)) - if err != nil { - return false, err - } - // The first url in the slice will be the default one (usually https://...) - if len(sourceURLs) > 0 && sourceURL == sourceURLs[0].String() { - return true, nil - } - - return false, nil -} diff --git a/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel deleted file mode 100644 index 68dd5efb0f014d6d76f99c6140c92415746579d1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel +++ /dev/null @@ -1,17 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/glide", - importpath = "github.com/golang/dep/internal/importers/glide", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/go-yaml/yaml:go_default_library", - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/fs:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/glide/importer.go b/vendor/github.com/golang/dep/internal/importers/glide/importer.go deleted file mode 100644 index ebaa3e2d8c62a36bfe6a730fcc4455a618bc32d1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glide/importer.go +++ /dev/null @@ -1,211 +0,0 @@ -// 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 glide - -import ( - "bytes" - "io/ioutil" - "log" - "os" - "path" - "path/filepath" - - "github.com/go-yaml/yaml" - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/fs" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -const glideYamlName = "glide.yaml" -const glideLockName = "glide.lock" - -// Importer imports glide configuration into the dep configuration format. -type Importer struct { - *base.Importer - glideConfig glideYaml - glideLock glideLock - lockFound bool -} - -// NewImporter for glide. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -type glideYaml struct { - Name string `yaml:"package"` - Ignores []string `yaml:"ignore"` - ExcludeDirs []string `yaml:"excludeDirs"` - Imports []glidePackage `yaml:"import"` - TestImports []glidePackage `yaml:"testImport"` -} - -type glideLock struct { - Imports []glideLockedPackage `yaml:"imports"` - TestImports []glideLockedPackage `yaml:"testImports"` -} - -type glidePackage struct { - Name string `yaml:"package"` - Reference string `yaml:"version"` // could contain a semver, tag or branch - Repository string `yaml:"repo"` - - // Unsupported fields that we will warn if used - Subpackages []string `yaml:"subpackages"` - OS string `yaml:"os"` - Arch string `yaml:"arch"` -} - -type glideLockedPackage struct { - Name string `yaml:"name"` - Revision string `yaml:"version"` - Repository string `yaml:"repo"` -} - -// Name of the importer. -func (g *Importer) Name() string { - return "glide" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - // Only require glide.yaml, the lock is optional - y := filepath.Join(dir, glideYamlName) - if _, err := os.Stat(y); err != nil { - return false - } - - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -// load the glide configuration files. Failure to load `glide.yaml` is considered -// unrecoverable and an error is returned for it. But if there is any error while trying -// to load the lock file, only a warning is logged. -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected glide configuration files...") - y := filepath.Join(projectDir, glideYamlName) - if g.Verbose { - g.Logger.Printf(" Loading %s", y) - } - yb, err := ioutil.ReadFile(y) - if err != nil { - return errors.Wrapf(err, "unable to read %s", y) - } - err = yaml.Unmarshal(yb, &g.glideConfig) - if err != nil { - return errors.Wrapf(err, "unable to parse %s", y) - } - - l := filepath.Join(projectDir, glideLockName) - if exists, _ := fs.IsRegular(l); exists { - if g.Verbose { - g.Logger.Printf(" Loading %s", l) - } - lb, err := ioutil.ReadFile(l) - if err != nil { - g.Logger.Printf(" Warning: Ignoring lock file. Unable to read %s: %s\n", l, err) - return nil - } - lock := glideLock{} - err = yaml.Unmarshal(lb, &lock) - if err != nil { - g.Logger.Printf(" Warning: Ignoring lock file. Unable to parse %s: %s\n", l, err) - return nil - } - g.lockFound = true - g.glideLock = lock - } - - return nil -} - -// convert the glide configuration files into dep configuration files. -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - projectName := string(pr) - - task := bytes.NewBufferString("Converting from glide.yaml") - if g.lockFound { - task.WriteString(" and glide.lock") - } - task.WriteString("...") - g.Logger.Println(task) - - numPkgs := len(g.glideConfig.Imports) + len(g.glideConfig.TestImports) + len(g.glideLock.Imports) + len(g.glideLock.TestImports) - packages := make([]base.ImportedPackage, 0, numPkgs) - - // Constraints - for _, pkg := range append(g.glideConfig.Imports, g.glideConfig.TestImports...) { - // Validate - if pkg.Name == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid glide configuration, Name is required", - ) - continue - } - - // Warn - if g.Verbose { - if pkg.OS != "" { - g.Logger.Printf(" The %s package specified an os, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.\n", pkg.Name) - } - if pkg.Arch != "" { - g.Logger.Printf(" The %s package specified an arch, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.\n", pkg.Name) - } - } - - ip := base.ImportedPackage{ - Name: pkg.Name, - Source: pkg.Repository, - ConstraintHint: pkg.Reference, - } - packages = append(packages, ip) - } - - // Locks - for _, pkg := range append(g.glideLock.Imports, g.glideLock.TestImports...) { - // Validate - if pkg.Name == "" { - g.Logger.Println(" Warning: Skipping project. Invalid glide lock, Name is required") - continue - } - - ip := base.ImportedPackage{ - Name: pkg.Name, - Source: pkg.Repository, - LockHint: pkg.Revision, - } - packages = append(packages, ip) - } - - g.ImportPackages(packages, false) - - // Ignores - g.Manifest.Ignored = append(g.Manifest.Ignored, g.glideConfig.Ignores...) - if len(g.glideConfig.ExcludeDirs) > 0 { - if g.glideConfig.Name != "" && g.glideConfig.Name != projectName { - g.Logger.Printf(" Glide thinks the package is '%s' but dep thinks it is '%s', using dep's value.\n", g.glideConfig.Name, projectName) - } - - for _, dir := range g.glideConfig.ExcludeDirs { - pkg := path.Join(projectName, dir) - g.Manifest.Ignored = append(g.Manifest.Ignored, pkg) - } - } - - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.lock b/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.lock deleted file mode 100644 index 0fae06602804c9edcb5132308a926f465bff82ae..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.lock +++ /dev/null @@ -1,12 +0,0 @@ -hash: 16053c82a71f9bd509b05a4523df6bc418aed2083e4b8bd97a870bbc003256f8 -updated: 2017-03-07T17:02:32.214383898-06:00 -imports: -- name: github.com/sdboyer/deptest - repo: https://github.com/sdboyer/deptest.git - vcs: git - version: 3f4c3bea144e112a69bbe5d8d01c1b09a544253f -- name: github.com/sdboyer/deptestdos - version: 5c607206be5decd28e6263ffffdcee067266015e -testImports: -- name: github.com/golang/lint - version: cb00e5669539f047b2f4c53a421a01b0c8e172c6 diff --git a/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.yaml b/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.yaml deleted file mode 100644 index 88a3f2be74d96a91a7f462ca1ae7f9c3d37f6fe7..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glide/testdata/glide.yaml +++ /dev/null @@ -1,20 +0,0 @@ -package: github.com/golang/notexist -homepage: http://example.com -license: MIT -owners: -- name: Sam Boyer - email: sdboyer@example.com - homepage: http://sdboyer.io -ignore: -- github.com/sdboyer/dep-test -excludeDirs: -- samples -import: -- package: github.com/sdboyer/deptest - repo: https://github.com/sdboyer/deptest.git - vcs: git - version: master -- package: github.com/sdboyer/deptestdos - version: v2.0.0 -testImport: -- package: github.com/golang/lint diff --git a/vendor/github.com/golang/dep/internal/importers/glide/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/glide/testdata/golden.txt deleted file mode 100644 index b8a0e65ca8ce52a21ea72bb50c50173daf1b40fc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glide/testdata/golden.txt +++ /dev/null @@ -1,7 +0,0 @@ -Detected glide configuration files... -Converting from glide.yaml and glide.lock... - Using master as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos - Trying * (cb00e56) as initial lock for imported dep github.com/golang/lint diff --git a/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel deleted file mode 100644 index 43742756bfa5bc9dd7e67eefba01dbc4aef1b0dc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/glock", - importpath = "github.com/golang/dep/internal/importers/glock", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/glock/importer.go b/vendor/github.com/golang/dep/internal/importers/glock/importer.go deleted file mode 100644 index 6120d459aaf329d5ec7a1d94d1565bbc9372b940..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glock/importer.go +++ /dev/null @@ -1,150 +0,0 @@ -// 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 glock - -import ( - "bufio" - "fmt" - "log" - "os" - "path/filepath" - "strings" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -const glockfile = "GLOCKFILE" - -// Importer imports glock configuration into the dep configuration format. -type Importer struct { - *base.Importer - - packages []glockPackage -} - -// NewImporter for glock. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -// Name of the importer. -func (g *Importer) Name() string { - return "glock" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - path := filepath.Join(dir, glockfile) - if _, err := os.Stat(path); err != nil { - return false - } - - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -type glockPackage struct { - importPath string - revision string -} - -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected glock configuration files...") - path := filepath.Join(projectDir, glockfile) - if g.Verbose { - g.Logger.Printf(" Loading %s", path) - } - - f, err := os.Open(path) - if err != nil { - return errors.Wrapf(err, "unable to open %s", path) - } - defer f.Close() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - pkg, err := parseGlockLine(scanner.Text()) - if err != nil { - g.Logger.Printf(" Warning: Skipping line. Unable to parse: %s\n", err) - continue - } - if pkg == nil { - continue - } - g.packages = append(g.packages, *pkg) - } - - if err := scanner.Err(); err != nil { - g.Logger.Printf(" Warning: Ignoring errors found while parsing %s: %s\n", path, err) - } - - return nil -} - -func parseGlockLine(line string) (*glockPackage, error) { - fields := strings.Fields(line) - switch len(fields) { - case 2: // Valid. - case 0: // Skip empty lines. - return nil, nil - default: - return nil, fmt.Errorf("invalid glock configuration: %s", line) - } - - // Skip commands. - if fields[0] == "cmd" { - return nil, nil - } - return &glockPackage{ - importPath: fields[0], - revision: fields[1], - }, nil -} - -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - g.Logger.Println("Converting from GLOCKFILE ...") - - packages := make([]base.ImportedPackage, 0, len(g.packages)) - for _, pkg := range g.packages { - // Validate - if pkg.importPath == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid glock configuration, import path is required", - ) - continue - } - - if pkg.revision == "" { - // Do not add 'empty constraints' to the manifest. Solve will add to lock if required. - g.Logger.Printf( - " Warning: Skipping import with empty constraints. "+ - "The solve step will add the dependency to the lock if needed: %q\n", - pkg.importPath, - ) - continue - } - - packages = append(packages, base.ImportedPackage{ - Name: pkg.importPath, - LockHint: pkg.revision, - }) - } - - g.ImportPackages(packages, true) - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/glock/testdata/GLOCKFILE b/vendor/github.com/golang/dep/internal/importers/glock/testdata/GLOCKFILE deleted file mode 100644 index 27f499a4270a7b5c336a74766b23739729d424fd..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glock/testdata/GLOCKFILE +++ /dev/null @@ -1,3 +0,0 @@ -cmd github.com/golang/lint -github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f -github.com/sdboyer/deptestdos 5c607206be5decd28e6263ffffdcee067266015e diff --git a/vendor/github.com/golang/dep/internal/importers/glock/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/glock/testdata/golden.txt deleted file mode 100644 index 3d7781b4f392b1b73a58ad5db874d6894f05528a..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/glock/testdata/golden.txt +++ /dev/null @@ -1,6 +0,0 @@ -Detected glock configuration files... -Converting from GLOCKFILE ... - Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos diff --git a/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel deleted file mode 100644 index 86849a916d4e605a9553e181c7510e4f4c568323..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/godep", - importpath = "github.com/golang/dep/internal/importers/godep", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/godep/importer.go b/vendor/github.com/golang/dep/internal/importers/godep/importer.go deleted file mode 100644 index c3389d8cb5989ef7ce3a268c4d9c4eb939e30c93..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/godep/importer.go +++ /dev/null @@ -1,117 +0,0 @@ -// 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 godep - -import ( - "encoding/json" - "io/ioutil" - "log" - "os" - "path/filepath" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -const godepPath = "Godeps" + string(os.PathSeparator) + "Godeps.json" - -// Importer imports godep configuration into the dep configuration format. -type Importer struct { - *base.Importer - json godepJSON -} - -// NewImporter for godep. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -type godepJSON struct { - Imports []godepPackage `json:"Deps"` -} - -type godepPackage struct { - ImportPath string `json:"ImportPath"` - Rev string `json:"Rev"` - Comment string `json:"Comment"` -} - -// Name of the importer. -func (g *Importer) Name() string { - return "godep" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - y := filepath.Join(dir, godepPath) - if _, err := os.Stat(y); err != nil { - return false - } - - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected godep configuration files...") - j := filepath.Join(projectDir, godepPath) - if g.Verbose { - g.Logger.Printf(" Loading %s", j) - } - jb, err := ioutil.ReadFile(j) - if err != nil { - return errors.Wrapf(err, "unable to read %s", j) - } - err = json.Unmarshal(jb, &g.json) - if err != nil { - return errors.Wrapf(err, "unable to parse %s", j) - } - - return nil -} - -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - g.Logger.Println("Converting from Godeps.json ...") - - packages := make([]base.ImportedPackage, 0, len(g.json.Imports)) - for _, pkg := range g.json.Imports { - // Validate - if pkg.ImportPath == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid godep configuration, ImportPath is required", - ) - continue - } - - if pkg.Rev == "" { - g.Logger.Printf( - " Warning: Invalid godep configuration, Rev not found for ImportPath %q\n", - pkg.ImportPath, - ) - } - - ip := base.ImportedPackage{ - Name: pkg.ImportPath, - LockHint: pkg.Rev, - ConstraintHint: pkg.Comment, - } - packages = append(packages, ip) - } - - g.ImportPackages(packages, true) - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/godep/testdata/Godeps.json b/vendor/github.com/golang/dep/internal/importers/godep/testdata/Godeps.json deleted file mode 100644 index 15126ac12d18c6c02cc0745586161fcebdea6719..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/godep/testdata/Godeps.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ImportPath": "github.com/golang/notexist", - "GoVersion": "go1.8", - "GodepVersion": "vXYZ", - "Deps": [ - { - "ImportPath": "github.com/sdboyer/deptest", - "Rev": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f" - }, - { - "ImportPath": "github.com/sdboyer/deptestdos", - "Comment": "v2.0.0", - "Rev": "5c607206be5decd28e6263ffffdcee067266015e" - } - ] -} diff --git a/vendor/github.com/golang/dep/internal/importers/godep/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/godep/testdata/golden.txt deleted file mode 100644 index 9788b947f795b66ea93963cc8ebff883088de820..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/godep/testdata/golden.txt +++ /dev/null @@ -1,6 +0,0 @@ -Detected godep configuration files... -Converting from Godeps.json ... - Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos diff --git a/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel deleted file mode 100644 index dd3d3b485805eacbc3b011be4f98173da9eff411..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/govend", - importpath = "github.com/golang/dep/internal/importers/govend", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/go-yaml/yaml:go_default_library", - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/govend/importer.go b/vendor/github.com/golang/dep/internal/importers/govend/importer.go deleted file mode 100644 index e4af4368c3d17ed37ab43570c58d5d982b47cd68..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govend/importer.go +++ /dev/null @@ -1,121 +0,0 @@ -// 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 govend - -import ( - "io/ioutil" - "log" - "os" - "path/filepath" - - "github.com/go-yaml/yaml" - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -// ToDo: govend supports json and xml formats as well and we will add support for other formats in next PR - @RaviTezu -// govend don't have a separate lock file. -const govendYAMLName = "vendor.yml" - -// Importer imports govend configuration in to the dep configuration format. -type Importer struct { - *base.Importer - yaml govendYAML -} - -// NewImporter for govend. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -type govendYAML struct { - Imports []govendPackage `yaml:"vendors"` -} - -type govendPackage struct { - Path string `yaml:"path"` - Revision string `yaml:"rev"` -} - -// Name of the importer. -func (g *Importer) Name() string { - return "govend" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - y := filepath.Join(dir, govendYAMLName) - if _, err := os.Stat(y); err != nil { - return false - } - - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -// load the govend configuration files. -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected govend configuration files...") - y := filepath.Join(projectDir, govendYAMLName) - if g.Verbose { - g.Logger.Printf(" Loading %s", y) - } - yb, err := ioutil.ReadFile(y) - if err != nil { - return errors.Wrapf(err, "unable to read %s", y) - } - err = yaml.Unmarshal(yb, &g.yaml) - if err != nil { - return errors.Wrapf(err, "unable to parse %s", y) - } - return nil -} - -// convert the govend configuration files into dep configuration files. -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - g.Logger.Println("Converting from vendor.yaml...") - - packages := make([]base.ImportedPackage, 0, len(g.yaml.Imports)) - for _, pkg := range g.yaml.Imports { - // Path must not be empty - if pkg.Path == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid govend configuration, path is required", - ) - continue - } - - if pkg.Revision == "" { - // Do not add 'empty constraints' to the manifest. Solve will add to lock if required. - g.Logger.Printf( - " Warning: Skipping import with empty constraints. "+ - "The solve step will add the dependency to the lock if needed: %q\n", - pkg.Path, - ) - continue - } - - ip := base.ImportedPackage{ - Name: pkg.Path, - LockHint: pkg.Revision, - } - packages = append(packages, ip) - } - - g.ImportPackages(packages, true) - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/govend/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/govend/testdata/golden.txt deleted file mode 100644 index e77c76ab5f34bb62251c1873005b711a4abef04e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govend/testdata/golden.txt +++ /dev/null @@ -1,6 +0,0 @@ -Detected govend configuration files... -Converting from vendor.yaml... - Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos diff --git a/vendor/github.com/golang/dep/internal/importers/govend/testdata/vendor.yml b/vendor/github.com/golang/dep/internal/importers/govend/testdata/vendor.yml deleted file mode 100644 index 0545b10125a599de1a059d01b140965f24191e10..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govend/testdata/vendor.yml +++ /dev/null @@ -1,6 +0,0 @@ -vendors: -- path: github.com/sdboyer/deptest - rev: 3f4c3bea144e112a69bbe5d8d01c1b09a544253f -- path: github.com/sdboyer/deptestdos - rev: 5c607206be5decd28e6263ffffdcee067266015e - diff --git a/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel deleted file mode 100644 index 26dc082e35140e1a1cadae8d476b2e77dfda74dc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/govendor", - importpath = "github.com/golang/dep/internal/importers/govendor", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/govendor/importer.go b/vendor/github.com/golang/dep/internal/importers/govendor/importer.go deleted file mode 100644 index 09611f49ed6e4f23d961410a47fba3bd67a1557e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govendor/importer.go +++ /dev/null @@ -1,151 +0,0 @@ -// 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 govendor - -import ( - "encoding/json" - "io/ioutil" - "log" - "os" - "path" - "path/filepath" - "strings" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -const govendorDir = "vendor" -const govendorName = "vendor.json" - -// Importer imports govendor configuration into the dep configuration format. -type Importer struct { - *base.Importer - - file govendorFile -} - -// NewImporter for govendor. -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -// File is the structure of the vendor file. -type govendorFile struct { - RootPath string // Import path of vendor folder - Ignore string - Package []*govendorPackage -} - -// Package represents each package. -type govendorPackage struct { - // See the vendor spec for definitions. - Origin string - Path string - Revision string - Version string -} - -// Name of the importer. -func (g *Importer) Name() string { - return "govendor" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - y := filepath.Join(dir, govendorDir, govendorName) - if _, err := os.Stat(y); err != nil { - return false - } - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected govendor configuration file...") - v := filepath.Join(projectDir, govendorDir, govendorName) - if g.Verbose { - g.Logger.Printf(" Loading %s", v) - } - vb, err := ioutil.ReadFile(v) - if err != nil { - return errors.Wrapf(err, "unable to read %s", v) - } - err = json.Unmarshal(vb, &g.file) - if err != nil { - return errors.Wrapf(err, "unable to parse %s", v) - } - return nil -} - -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - g.Logger.Println("Converting from vendor.json...") - - packages := make([]base.ImportedPackage, 0, len(g.file.Package)) - for _, pkg := range g.file.Package { - // Path must not be empty - if pkg.Path == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid govendor configuration, Path is required", - ) - continue - } - - // There are valid govendor configs in the wild that don't have a revision set - // so we are not requiring it to be set during import - - ip := base.ImportedPackage{ - Name: pkg.Path, - Source: pkg.Origin, - LockHint: pkg.Revision, - } - packages = append(packages, ip) - } - - g.ImportPackages(packages, true) - - if len(g.file.Ignore) > 0 { - // Govendor has three use cases here - // 1. 'test' - special case for ignoring test files - // 2. build tags - any string without a slash (/) in it - // 3. path and path prefix - any string with a slash (/) in it. - // The path case could be a full path or just a prefix. - // Dep doesn't support build tags right now: https://github.com/golang/dep/issues/120 - for _, i := range strings.Split(g.file.Ignore, " ") { - if !strings.Contains(i, "/") { - g.Logger.Printf(" Govendor was configured to ignore the %s build tag, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.", i) - continue - } - - var ignorePattern string - _, err := g.SourceManager.DeduceProjectRoot(i) - if err == nil { // external package - ignorePattern = i - } else { // relative package path in the current project - ignorePattern = path.Join(string(pr), i) - } - - // Convert to a a wildcard ignore - ignorePattern = strings.TrimRight(ignorePattern, "/") - ignorePattern += "*" - - g.Manifest.Ignored = append(g.Manifest.Ignored, ignorePattern) - } - } - - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/govendor/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/govendor/testdata/golden.txt deleted file mode 100644 index 51a348f7c9d1497c2b09b3112d11f412c86a42fc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govendor/testdata/golden.txt +++ /dev/null @@ -1,7 +0,0 @@ -Detected govendor configuration file... -Converting from vendor.json... - Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos - Govendor was configured to ignore the test build tag, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291. diff --git a/vendor/github.com/golang/dep/internal/importers/govendor/testdata/vendor.json b/vendor/github.com/golang/dep/internal/importers/govendor/testdata/vendor.json deleted file mode 100644 index 983f15f6192ec19e37ab5a04699dcce583bc0ecc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/govendor/testdata/vendor.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "comment": "", - "ignore": "test github.com/sdboyer/dep-test", - "package": [ - { - "checksumSHA1": "4R6TQcq0/gI/I2kKeUunuO/pEec=", - "origin": "github.com/carolynvs/deptest", - "path": "github.com/sdboyer/deptest", - "revision": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f", - "revisionTime": "2017-02-22T03:31:47Z" - }, - { - "checksumSHA1": "96YwrJjpE07ENey/eDWWnCWKQOw=", - "path": "github.com/sdboyer/deptestdos", - "revision": "5c607206be5decd28e6263ffffdcee067266015e", - "revisionTime": "2017-02-22T03:34:58Z", - "version": "v2", - "versionExact": "v2.0.0" - } - ], - "rootPath": "github.com/golang/notexist" -} diff --git a/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel deleted file mode 100644 index a22b94389803339fef8f522821396691f737b390..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/gvt", - importpath = "github.com/golang/dep/internal/importers/gvt", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/gvt/importer.go b/vendor/github.com/golang/dep/internal/importers/gvt/importer.go deleted file mode 100644 index 97f61a16be034472053aaeb0b47efc8a070350cc..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/gvt/importer.go +++ /dev/null @@ -1,130 +0,0 @@ -// 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 gvt - -import ( - "encoding/json" - "io/ioutil" - "log" - "os" - "path/filepath" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -const gvtPath = "vendor" + string(os.PathSeparator) + "manifest" - -// Importer imports gvt configuration into the dep configuration format. -type Importer struct { - *base.Importer - gvtConfig gvtManifest -} - -// NewImporter for gvt. It handles gb (gb-vendor) too as they share a common manifest file & format -func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(logger, verbose, sm)} -} - -type gvtManifest struct { - Deps []gvtPkg `json:"dependencies"` -} - -type gvtPkg struct { - ImportPath string - Repository string - Revision string - Branch string -} - -// Name of the importer. -func (g *Importer) Name() string { - return "gvt" -} - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (g *Importer) HasDepMetadata(dir string) bool { - y := filepath.Join(dir, gvtPath) - if _, err := os.Stat(y); err != nil { - return false - } - - return true -} - -// Import the config found in the directory. -func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - err := g.load(dir) - if err != nil { - return nil, nil, err - } - - m, l := g.convert(pr) - return m, l, nil -} - -func (g *Importer) load(projectDir string) error { - g.Logger.Println("Detected gb/gvt configuration files...") - j := filepath.Join(projectDir, gvtPath) - if g.Verbose { - g.Logger.Printf(" Loading %s", j) - } - jb, err := ioutil.ReadFile(j) - if err != nil { - return errors.Wrapf(err, "unable to read %s", j) - } - err = json.Unmarshal(jb, &g.gvtConfig) - if err != nil { - return errors.Wrapf(err, "unable to parse %s", j) - } - - return nil -} - -func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - g.Logger.Println("Converting from vendor/manifest ...") - - packages := make([]base.ImportedPackage, 0, len(g.gvtConfig.Deps)) - for _, pkg := range g.gvtConfig.Deps { - // Validate - if pkg.ImportPath == "" { - g.Logger.Println( - " Warning: Skipping project. Invalid gvt configuration, ImportPath is required", - ) - continue - } - - if pkg.Revision == "" { - g.Logger.Printf( - " Warning: Invalid gvt configuration, Revision not found for ImportPath %q\n", - pkg.ImportPath, - ) - } - - var contstraintHint = "" - if pkg.Branch == "HEAD" { - // gb-vendor sets "branch" to "HEAD", if the package was feteched via -tag or -revision, - // we pass the revision as the constraint hint - contstraintHint = pkg.Revision - } else if pkg.Branch != "master" { - // both gvt & gb-vendor set "branch" to "master" unless a different branch was requested. - // so it's not really a constraint unless it's a different branch - contstraintHint = pkg.Branch - } - - ip := base.ImportedPackage{ - Name: pkg.ImportPath, - Source: pkg.Repository, - LockHint: pkg.Revision, - ConstraintHint: contstraintHint, - } - packages = append(packages, ip) - } - - g.ImportPackages(packages, true) - return g.Manifest, g.Lock -} diff --git a/vendor/github.com/golang/dep/internal/importers/gvt/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/gvt/testdata/golden.txt deleted file mode 100644 index 2a079fda7f49d76f025491b409b44d284c0faffe..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/gvt/testdata/golden.txt +++ /dev/null @@ -1,7 +0,0 @@ -Detected gb/gvt configuration files... -Converting from vendor/manifest ... - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos - Using v2 as initial constraint for imported dep github.com/carolynvs/deptest-importers - Trying v2 (b79bc94) as initial lock for imported dep github.com/carolynvs/deptest-importers diff --git a/vendor/github.com/golang/dep/internal/importers/gvt/testdata/manifest b/vendor/github.com/golang/dep/internal/importers/gvt/testdata/manifest deleted file mode 100644 index 36e49d56b1699cc19b7ded3fb750d9c38cf31ac6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/gvt/testdata/manifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "dependencies": [ - { - "importpath": "github.com/sdboyer/deptest", - "revision": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f", - "branch": "HEAD" - }, - { - "importpath": "github.com/sdboyer/deptestdos", - "revision": "5c607206be5decd28e6263ffffdcee067266015e", - "branch": "master" - }, - { - "importpath": "github.com/carolynvs/deptest-importers", - "revision": "b79bc9482da8bb7402cdc3e3fd984db250718dd7", - "branch": "v2" - } - ] -} diff --git a/vendor/github.com/golang/dep/internal/importers/importers.go b/vendor/github.com/golang/dep/internal/importers/importers.go deleted file mode 100644 index d54277c14bac4cb93653fdcc7ff273e51e7740d4..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/importers.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 importers - -import ( - "log" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/glide" - "github.com/golang/dep/internal/importers/glock" - "github.com/golang/dep/internal/importers/godep" - "github.com/golang/dep/internal/importers/govend" - "github.com/golang/dep/internal/importers/govendor" - "github.com/golang/dep/internal/importers/gvt" - "github.com/golang/dep/internal/importers/vndr" -) - -// Importer handles importing configuration from other dependency managers into -// the dep configuration format. -type Importer interface { - // Name of the importer. - Name() string - - // Import the config found in the directory. - Import(path string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) - - // HasDepMetadata checks if a directory contains config that the importer can handle. - HasDepMetadata(dir string) bool -} - -// BuildAll returns a slice of all the importers. -func BuildAll(logger *log.Logger, verbose bool, sm gps.SourceManager) []Importer { - return []Importer{ - glide.NewImporter(logger, verbose, sm), - godep.NewImporter(logger, verbose, sm), - vndr.NewImporter(logger, verbose, sm), - govend.NewImporter(logger, verbose, sm), - gvt.NewImporter(logger, verbose, sm), - govendor.NewImporter(logger, verbose, sm), - glock.NewImporter(logger, verbose, sm), - } -} diff --git a/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel deleted file mode 100644 index e11ed7d2475cc3a5a42a178e33728d2809620c92..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel +++ /dev/null @@ -1,18 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "testcase.go", - "testdata.go", - ], - importmap = "vendor/github.com/golang/dep/internal/importers/importertest", - importpath = "github.com/golang/dep/internal/importers/importertest", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/test:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/importertest/testcase.go b/vendor/github.com/golang/dep/internal/importers/importertest/testcase.go deleted file mode 100644 index 415ed596dc5e10cf2223b26f9771075af33ed79e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/importertest/testcase.go +++ /dev/null @@ -1,185 +0,0 @@ -// 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 importertest - -import ( - "bytes" - "io/ioutil" - "log" - "sort" - "strings" - "testing" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/test" - "github.com/pkg/errors" -) - -// TestCase is a common set of validations applied to the result -// of an importer converting from an external config format to dep's. -type TestCase struct { - DefaultConstraintFromLock bool - WantSourceRepo string - WantConstraint string - WantRevision gps.Revision - WantVersion string - WantIgnored []string - WantWarning string -} - -// NewTestContext creates a unique context with its own GOPATH for a single test. -func NewTestContext(h *test.Helper) *dep.Ctx { - h.TempDir("src") - pwd := h.Path(".") - discardLogger := log.New(ioutil.Discard, "", 0) - - return &dep.Ctx{ - GOPATH: pwd, - Out: discardLogger, - Err: discardLogger, - } -} - -// Execute and validate the test case. -func (tc TestCase) Execute(t *testing.T, convert func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock)) error { - h := test.NewHelper(t) - defer h.Cleanup() - // Disable parallel tests until we can resolve this error on the Windows builds: - // "remote repository at https://github.com/carolynvs/deptest-importers does not exist, or is inaccessible" - //h.Parallel() - - ctx := NewTestContext(h) - sm, err := ctx.SourceManager() - h.Must(err) - defer sm.Release() - - // Capture stderr so we can verify warnings - output := &bytes.Buffer{} - ctx.Err = log.New(output, "", 0) - - manifest, lock := convert(ctx.Err, sm) - return tc.validate(manifest, lock, output) -} - -// validate returns an error if any of the testcase validations failed. -func (tc TestCase) validate(manifest *dep.Manifest, lock *dep.Lock, output *bytes.Buffer) error { - if !equalSlice(manifest.Ignored, tc.WantIgnored) { - return errors.Errorf("unexpected set of ignored projects: \n\t(GOT) %#v \n\t(WNT) %#v", - manifest.Ignored, tc.WantIgnored) - } - - wantConstraintCount := 0 - if tc.WantConstraint != "" { - wantConstraintCount = 1 - } - gotConstraintCount := len(manifest.Constraints) - if gotConstraintCount != wantConstraintCount { - return errors.Errorf("unexpected number of constraints: \n\t(GOT) %v \n\t(WNT) %v", - gotConstraintCount, wantConstraintCount) - } - - if tc.WantConstraint != "" { - d, ok := manifest.Constraints[Project] - if !ok { - return errors.Errorf("Expected the manifest to have a dependency for '%v'", - Project) - } - - gotConstraint := d.Constraint.String() - if gotConstraint != tc.WantConstraint { - return errors.Errorf("unexpected constraint: \n\t(GOT) %v \n\t(WNT) %v", - gotConstraint, tc.WantConstraint) - } - - } - - // Lock checks. - wantLockCount := 0 - if tc.WantRevision != "" { - wantLockCount = 1 - } - gotLockCount := 0 - if lock != nil { - gotLockCount = len(lock.P) - } - if gotLockCount != wantLockCount { - return errors.Errorf("unexpected number of locked projects: \n\t(GOT) %v \n\t(WNT) %v", - gotLockCount, wantLockCount) - } - - if tc.WantRevision != "" { - lp := lock.P[0] - - gotProjectRoot := lp.Ident().ProjectRoot - if gotProjectRoot != Project { - return errors.Errorf("unexpected root project in lock: \n\t(GOT) %v \n\t(WNT) %v", - gotProjectRoot, Project) - } - - gotSource := lp.Ident().Source - if gotSource != tc.WantSourceRepo { - return errors.Errorf("unexpected source repository: \n\t(GOT) %v \n\t(WNT) %v", - gotSource, tc.WantSourceRepo) - } - - // Break down the locked "version" into a version (optional) and revision - var gotVersion string - var gotRevision gps.Revision - if lpv, ok := lp.Version().(gps.PairedVersion); ok { - gotVersion = lpv.String() - gotRevision = lpv.Revision() - } else if lr, ok := lp.Version().(gps.Revision); ok { - gotRevision = lr - } else { - return errors.New("could not determine the type of the locked version") - } - - if gotRevision != tc.WantRevision { - return errors.Errorf("unexpected locked revision: \n\t(GOT) %v \n\t(WNT) %v", - gotRevision, - tc.WantRevision) - } - if gotVersion != tc.WantVersion { - return errors.Errorf("unexpected locked version: \n\t(GOT) %v \n\t(WNT) %v", - gotVersion, - tc.WantVersion) - } - } - - if tc.WantWarning != "" { - gotWarning := output.String() - if !strings.Contains(gotWarning, tc.WantWarning) { - return errors.Errorf("Expected the output to include the warning '%s' but got '%s'\n", tc.WantWarning, gotWarning) - } - } - - return nil -} - -// equalSlice is comparing two string slices for equality. -func equalSlice(a, b []string) bool { - if a == nil && b == nil { - return true - } - - if a == nil || b == nil { - return false - } - - if len(a) != len(b) { - return false - } - - sort.Strings(a) - sort.Strings(b) - for i := range a { - if a[i] != b[i] { - return false - } - } - - return true -} diff --git a/vendor/github.com/golang/dep/internal/importers/importertest/testdata.go b/vendor/github.com/golang/dep/internal/importers/importertest/testdata.go deleted file mode 100644 index fc037ff0dd9890ac0d110926d2f71eed6a0f8894..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/importertest/testdata.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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 importertest - -const ( - // RootProject is the containing project performing the import. - RootProject = "github.com/golang/notexist" - - // Project being imported. - Project = "github.com/carolynvs/deptest-importers" - - // ProjectSrc is an alternate source for the imported project. - ProjectSrc = "https://github.com/carolynvs/deptest-importers.git" - - // UntaggedRev is a revision without any tags. - UntaggedRev = "9b670d143bfb4a00f7461451d5c4a62f80e9d11d" - - // UntaggedRevAbbrv is the result of running `git describe` on UntaggedRev - UntaggedRevAbbrv = "v1.0.0-1-g9b670d1" - - // Beta1Tag is a non-semver tag. - Beta1Tag = "beta1" - - // Beta1Rev is the revision of Beta1Tag - Beta1Rev = "7913ab26988c6fb1e16225f845a178e8849dd254" - - // V2Branch is a branch that could be interpreted as a semver tag (but shouldn't). - V2Branch = "v2" - - // V2Rev is the HEAD revision of V2Branch. - V2Rev = "45dcf5a09c64b48b6e836028a3bc672b19b9d11d" - - // V2PatchTag is a prerelease semver tag on the non-default branch. - V2PatchTag = "v2.0.0-alpha1" - - // V2PatchRev is the revision of V2PatchTag. - V2PatchRev = "347760b50204948ea63e531dd6560e56a9adde8f" - - // V1Tag is a semver tag that matches V1Constraint. - V1Tag = "v1.0.0" - - // V1Rev is the revision of V1Tag. - V1Rev = "d0c29640b17f77426b111f4c1640d716591aa70e" - - // V1PatchTag is a semver tag that matches V1Constraint. - V1PatchTag = "v1.0.2" - - // V1PatchRev is the revision of V1PatchTag - V1PatchRev = "788963efe22e3e6e24c776a11a57468bb2fcd780" - - // V1Constraint is a constraint that matches multiple semver tags. - V1Constraint = "^1.0.0" - - // MultiTaggedRev is a revision with multiple tags. - MultiTaggedRev = "34cf993cc346f65601fe4356dd68bd54d20a1bfe" - - // MultiTaggedSemverTag is a semver tag on MultiTaggedRev. - MultiTaggedSemverTag = "v1.0.4" - - // MultiTaggedPlainTag is a non-semver tag on MultiTaggedRev. - MultiTaggedPlainTag = "stable" - - // NonexistentPrj is a dummy project which does not exist on Github. - NonexistentPrj = "github.com/nonexistent/project" -) diff --git a/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel deleted file mode 100644 index 72cc72322cd432346ce7b4957849265c881b1630..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["importer.go"], - importmap = "vendor/github.com/golang/dep/internal/importers/vndr", - importpath = "github.com/golang/dep/internal/importers/vndr", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep:go_default_library", - "//vendor/github.com/golang/dep/gps:go_default_library", - "//vendor/github.com/golang/dep/internal/importers/base:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/importers/vndr/importer.go b/vendor/github.com/golang/dep/internal/importers/vndr/importer.go deleted file mode 100644 index 60e28e23208c409a8854a6481e13fedba99372f8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/vndr/importer.go +++ /dev/null @@ -1,149 +0,0 @@ -// 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 vndr - -import ( - "bufio" - "log" - "os" - "path/filepath" - "strings" - - "github.com/golang/dep" - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/importers/base" - "github.com/pkg/errors" -) - -func vndrFile(dir string) string { - return filepath.Join(dir, "vendor.conf") -} - -// Importer imports vndr configuration into the dep configuration format. -type Importer struct { - *base.Importer - packages []vndrPackage -} - -// NewImporter for vndr. -func NewImporter(log *log.Logger, verbose bool, sm gps.SourceManager) *Importer { - return &Importer{Importer: base.NewImporter(log, verbose, sm)} -} - -// Name of the importer. -func (v *Importer) Name() string { return "vndr" } - -// HasDepMetadata checks if a directory contains config that the importer can handle. -func (v *Importer) HasDepMetadata(dir string) bool { - _, err := os.Stat(vndrFile(dir)) - return err == nil -} - -// Import the config found in the directory. -func (v *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { - v.Logger.Println("Detected vndr configuration file...") - - err := v.loadVndrFile(dir) - if err != nil { - return nil, nil, errors.Wrapf(err, "unable to load vndr file") - } - - m, l := v.convert(pr) - return m, l, nil -} - -func (v *Importer) loadVndrFile(dir string) error { - v.Logger.Printf("Converting from vendor.conf...") - - path := vndrFile(dir) - f, err := os.Open(path) - if err != nil { - return errors.Wrapf(err, "unable to open %s", path) - } - defer f.Close() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - pkg, err := parseVndrLine(scanner.Text()) - if err != nil { - v.Logger.Printf(" Warning: Skipping line. Unable to parse: %s\n", err) - continue - } - if pkg == nil { - // Could be an empty line or one which is just a comment - continue - } - v.packages = append(v.packages, *pkg) - } - - if err := scanner.Err(); err != nil { - v.Logger.Printf(" Warning: Ignoring errors found while parsing %s: %s\n", path, err) - } - - return nil -} - -func (v *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { - packages := make([]base.ImportedPackage, 0, len(v.packages)) - for _, pkg := range v.packages { - // Validate - if pkg.importPath == "" { - v.Logger.Println( - " Warning: Skipping project. Invalid vndr configuration, import path is required", - ) - continue - } - - if pkg.reference == "" { - v.Logger.Printf( - " Warning: Invalid vndr configuration, reference not found for import path %q\n", - pkg.importPath, - ) - } - - ip := base.ImportedPackage{ - Name: pkg.importPath, - Source: pkg.repository, - LockHint: pkg.reference, - } - packages = append(packages, ip) - } - v.ImportPackages(packages, true) - return v.Manifest, v.Lock -} - -type vndrPackage struct { - importPath string - reference string - repository string -} - -func parseVndrLine(line string) (*vndrPackage, error) { - commentIdx := strings.Index(line, "#") - if commentIdx >= 0 { - line = line[:commentIdx] - } - line = strings.TrimSpace(line) - - if line == "" { - return nil, nil - } - - parts := strings.Fields(line) - - if !(len(parts) == 2 || len(parts) == 3) { - return nil, errors.Errorf("invalid config format: %q", line) - } - - pkg := &vndrPackage{ - importPath: parts[0], - reference: parts[1], - } - if len(parts) == 3 { - pkg.repository = parts[2] - } - - return pkg, nil -} diff --git a/vendor/github.com/golang/dep/internal/importers/vndr/testdata/golden.txt b/vendor/github.com/golang/dep/internal/importers/vndr/testdata/golden.txt deleted file mode 100644 index 3702ae436a186583798636c02256d74a00915a41..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/vndr/testdata/golden.txt +++ /dev/null @@ -1,6 +0,0 @@ -Detected vndr configuration file... -Converting from vendor.conf... - Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest - Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest - Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos - Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos diff --git a/vendor/github.com/golang/dep/internal/importers/vndr/testdata/vendor.conf b/vendor/github.com/golang/dep/internal/importers/vndr/testdata/vendor.conf deleted file mode 100644 index 072166aa57b945b01f1683f85a6539b0333bf900..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/importers/vndr/testdata/vendor.conf +++ /dev/null @@ -1,4 +0,0 @@ -github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f https://github.com/sdboyer/deptest.git # trailing comment -# line comment - -github.com/sdboyer/deptestdos v2.0.0 # trailing comment diff --git a/vendor/github.com/golang/dep/internal/test/BUILD.bazel b/vendor/github.com/golang/dep/internal/test/BUILD.bazel deleted file mode 100644 index b0e3e57fc044d5e118565efaba0f0e073065bda9..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/BUILD.bazel +++ /dev/null @@ -1,13 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "test.go", - "writer.go", - ], - importmap = "vendor/github.com/golang/dep/internal/test", - importpath = "github.com/golang/dep/internal/test", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = ["//vendor/github.com/pkg/errors:go_default_library"], -) diff --git a/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel b/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel deleted file mode 100644 index 928ded317b831494f4d9b5494efa1ef31af64be3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "testcase.go", - "testproj.go", - ], - importmap = "vendor/github.com/golang/dep/internal/test/integration", - importpath = "github.com/golang/dep/internal/test/integration", - visibility = ["//vendor/github.com/golang/dep:__subpackages__"], - deps = [ - "//vendor/github.com/golang/dep/internal/test:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - ], -) diff --git a/vendor/github.com/golang/dep/internal/test/integration/testcase.go b/vendor/github.com/golang/dep/internal/test/integration/testcase.go deleted file mode 100644 index bd772da7d8686674201405dd7474f9a74d45e8c6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/integration/testcase.go +++ /dev/null @@ -1,201 +0,0 @@ -// 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 integration - -import ( - "encoding/json" - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" - "unicode" - - "github.com/golang/dep/internal/test" -) - -// TestCase manages a test case directory structure and content -type TestCase struct { - t *testing.T - name string - rootPath string - initialPath string - finalPath string - Commands [][]string `json:"commands"` - ErrorExpected string `json:"error-expected"` - GopathInitial map[string]string `json:"gopath-initial"` - VendorInitial map[string]string `json:"vendor-initial"` - VendorFinal []string `json:"vendor-final"` - InitPath string `json:"init-path"` -} - -// NewTestCase creates a new TestCase. -func NewTestCase(t *testing.T, dir, name string) *TestCase { - rootPath := filepath.FromSlash(filepath.Join(dir, name)) - n := &TestCase{ - t: t, - name: name, - rootPath: rootPath, - initialPath: filepath.Join(rootPath, "initial"), - finalPath: filepath.Join(rootPath, "final"), - } - j, err := ioutil.ReadFile(filepath.Join(rootPath, "testcase.json")) - if err != nil { - t.Fatal(err) - } - err = json.Unmarshal(j, n) - if err != nil { - t.Fatal(err) - } - return n -} - -// InitialPath represents the initial set of files in a project. -func (tc *TestCase) InitialPath() string { - return tc.initialPath -} - -// UpdateFile updates the golden file with the working result. -func (tc *TestCase) UpdateFile(goldenPath, workingPath string) { - exists, working, err := getFile(workingPath) - if err != nil { - tc.t.Fatalf("Error reading project file %s: %s", goldenPath, err) - } - - golden := filepath.Join(tc.finalPath, goldenPath) - if exists { - if err := tc.WriteFile(golden, working); err != nil { - tc.t.Fatal(err) - } - } else { - err := os.Remove(golden) - if err != nil && !os.IsNotExist(err) { - tc.t.Fatal(err) - } - } -} - -// CompareFile compares the golden file with the working result. -func (tc *TestCase) CompareFile(goldenPath, working string) { - golden := filepath.Join(tc.finalPath, goldenPath) - - gotExists, got, err := getFile(working) - if err != nil { - tc.t.Fatalf("Error reading project file %q: %s", goldenPath, err) - } - wantExists, want, err := getFile(golden) - if err != nil { - tc.t.Fatalf("Error reading testcase file %q: %s", goldenPath, err) - } - - if wantExists && gotExists { - if want != got { - tc.t.Errorf("%s was not as expected\n(WNT):\n%s\n(GOT):\n%s", filepath.Base(goldenPath), want, got) - } - } else if !wantExists && gotExists { - tc.t.Errorf("%q created where none was expected", goldenPath) - } else if wantExists && !gotExists { - tc.t.Errorf("%q not created where one was expected", goldenPath) - } -} - -// UpdateOutput updates the golden file for stdout with the working result. -func (tc *TestCase) UpdateOutput(stdout string) { - stdoutPath := filepath.Join(tc.rootPath, "stdout.txt") - _, err := os.Stat(stdoutPath) - if err != nil { - if os.IsNotExist(err) { - // Don't update the stdout.txt file if it doesn't exist. - return - } - panic(err) - } - - if err := tc.WriteFile(stdoutPath, stdout); err != nil { - tc.t.Fatal(err) - } -} - -// CompareOutput compares expected and actual stdout output. -func (tc *TestCase) CompareOutput(stdout string) { - expected, err := ioutil.ReadFile(filepath.Join(tc.rootPath, "stdout.txt")) - if err != nil { - if os.IsNotExist(err) { - // Nothing to verify - return - } - panic(err) - } - - expStr := normalizeLines(string(expected)) - stdout = normalizeLines(stdout) - - if expStr != stdout { - tc.t.Errorf("stdout was not as expected\n(WNT):\n%s\n(GOT):\n%s\n", expStr, stdout) - } -} - -// normalizeLines returns a version with trailing whitespace stripped from each line. -func normalizeLines(s string) string { - lines := strings.Split(s, "\n") - for i := range lines { - lines[i] = strings.TrimRightFunc(lines[i], unicode.IsSpace) - } - return strings.Join(lines, "\n") -} - -// CompareError compares expected and actual stderr output. -func (tc *TestCase) CompareError(err error, stderr string) { - wantExists, want := tc.ErrorExpected != "", tc.ErrorExpected - gotExists, got := stderr != "" && err != nil, stderr - - if wantExists && gotExists { - switch c := strings.Count(got, want); c { - case 0: - tc.t.Errorf("error did not contain expected string:\n\t(GOT): %s\n\t(WNT): %s", got, want) - case 1: - default: - tc.t.Errorf("expected error %s matches %d times to actual error %s", want, c, got) - } - } else if !wantExists && gotExists { - tc.t.Fatalf("error raised where none was expected: \n%v", stderr) - } else if wantExists && !gotExists { - tc.t.Error("error not raised where one was expected:", want) - } -} - -// CompareVendorPaths validates the vendor directory contents. -func (tc *TestCase) CompareVendorPaths(gotVendorPaths []string) { - if *test.UpdateGolden { - tc.VendorFinal = gotVendorPaths - } else { - wantVendorPaths := tc.VendorFinal - if len(gotVendorPaths) != len(wantVendorPaths) { - tc.t.Fatalf("Wrong number of vendor paths created: want %d got %d", len(wantVendorPaths), len(gotVendorPaths)) - } - for ind := range gotVendorPaths { - if gotVendorPaths[ind] != wantVendorPaths[ind] { - tc.t.Errorf("Mismatch in vendor paths created: want %s got %s", wantVendorPaths, gotVendorPaths) - } - } - } -} - -// WriteFile writes a file using the default file permissions. -func (tc *TestCase) WriteFile(src string, content string) error { - return ioutil.WriteFile(src, []byte(content), 0666) -} - -func getFile(path string) (bool, string, error) { - _, err := os.Stat(path) - if err != nil { - return false, "", nil - } - f, err := ioutil.ReadFile(path) - if err != nil { - return true, "", err - } - return true, string(f), nil -} diff --git a/vendor/github.com/golang/dep/internal/test/integration/testproj.go b/vendor/github.com/golang/dep/internal/test/integration/testproj.go deleted file mode 100644 index 760e1cc52d96ea515e655b261ffc7abf82b1784e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/integration/testproj.go +++ /dev/null @@ -1,310 +0,0 @@ -// 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 integration - -import ( - "bytes" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "sort" - "strings" - "testing" - - "github.com/golang/dep/internal/test" - "github.com/pkg/errors" -) - -const ( - projectRoot string = "src/github.com/golang/notexist" -) - -// RunFunc defines the function signature for an integration test command to execute. -type RunFunc func(prog string, newargs []string, outW, errW io.Writer, dir string, env []string) error - -// TestProject manages the "virtual" test project directory structure -// and content -type TestProject struct { - t *testing.T - preImports []string - tempdir string - env []string - origWd string - stdout bytes.Buffer - stderr bytes.Buffer - run RunFunc -} - -// NewTestProject initializes a new test's project directory. -func NewTestProject(t *testing.T, initPath, wd string, run RunFunc) *TestProject { - new := &TestProject{ - t: t, - origWd: wd, - env: os.Environ(), - run: run, - } - new.makeRootTempDir() - new.TempDir(projectRoot, "vendor") - new.CopyTree(initPath) - - new.Setenv("GOPATH", new.tempdir) - - return new -} - -// Cleanup (remove) the test project's directory. -func (p *TestProject) Cleanup() { - os.RemoveAll(p.tempdir) -} - -// Path to the test project directory. -func (p *TestProject) Path(args ...string) string { - return filepath.Join(p.tempdir, filepath.Join(args...)) -} - -// ProjPath builds an import path for the test project. -func (p *TestProject) ProjPath(args ...string) string { - localPath := append([]string{projectRoot}, args...) - return p.Path(localPath...) -} - -// TempDir creates a temporary directory for the test project. -func (p *TestProject) TempDir(args ...string) { - fullPath := p.Path(args...) - if err := os.MkdirAll(fullPath, 0755); err != nil && !os.IsExist(err) { - p.t.Fatalf("%+v", errors.Errorf("Unable to create temp directory: %s", fullPath)) - } -} - -// TempProjDir builds the path to a package within the test project. -func (p *TestProject) TempProjDir(args ...string) { - localPath := append([]string{projectRoot}, args...) - p.TempDir(localPath...) -} - -// VendorPath lists the contents of the test project's vendor directory. -func (p *TestProject) VendorPath(args ...string) string { - localPath := append([]string{projectRoot, "vendor"}, args...) - p.TempDir(localPath...) - return p.Path(localPath...) -} - -// RunGo runs a go command, and expects it to succeed. -func (p *TestProject) RunGo(args ...string) { - cmd := exec.Command("go", args...) - p.stdout.Reset() - p.stderr.Reset() - cmd.Stdout = &p.stdout - cmd.Stderr = &p.stderr - cmd.Dir = p.tempdir - cmd.Env = p.env - status := cmd.Run() - if p.stdout.Len() > 0 { - p.t.Log("go standard output:") - p.t.Log(p.stdout.String()) - } - if p.stderr.Len() > 0 { - p.t.Log("go standard error:") - p.t.Log(p.stderr.String()) - } - if status != nil { - p.t.Logf("go %v failed unexpectedly: %v", args, status) - p.t.FailNow() - } -} - -// RunGit runs a git command, and expects it to succeed. -func (p *TestProject) RunGit(dir string, args ...string) { - cmd := exec.Command("git", args...) - p.stdout.Reset() - p.stderr.Reset() - cmd.Stdout = &p.stdout - cmd.Stderr = &p.stderr - cmd.Dir = dir - cmd.Env = p.env - status := cmd.Run() - if *test.PrintLogs { - if p.stdout.Len() > 0 { - p.t.Logf("git %v standard output:", args) - p.t.Log(p.stdout.String()) - } - if p.stderr.Len() > 0 { - p.t.Logf("git %v standard error:", args) - p.t.Log(p.stderr.String()) - } - } - if status != nil { - p.t.Logf("git %v failed unexpectedly: %v", args, status) - p.t.FailNow() - } -} - -// GetStdout gets the Stdout output from test run. -func (p *TestProject) GetStdout() string { - return p.stdout.String() -} - -// GetStderr gets the Stderr output from test run. -func (p *TestProject) GetStderr() string { - return p.stderr.String() -} - -// GetVendorGit populates the initial vendor directory for a test project. -func (p *TestProject) GetVendorGit(ip string) { - parse := strings.Split(ip, "/") - gitDir := strings.Join(parse[:len(parse)-1], string(filepath.Separator)) - p.TempProjDir("vendor", gitDir) - p.RunGit(p.ProjPath("vendor", gitDir), "clone", "http://"+ip) -} - -// DoRun executes the integration test command against the test project. -func (p *TestProject) DoRun(args []string) error { - if *test.PrintLogs { - p.t.Logf("running testdep %v", args) - } - prog := filepath.Join(p.origWd, "testdep"+test.ExeSuffix) - newargs := append([]string{args[0], "-v"}, args[1:]...) - - p.stdout.Reset() - p.stderr.Reset() - - status := p.run(prog, newargs, &p.stdout, &p.stderr, p.ProjPath(""), p.env) - - if *test.PrintLogs { - if p.stdout.Len() > 0 { - p.t.Logf("\nstandard output:%s", p.stdout.String()) - } - if p.stderr.Len() > 0 { - p.t.Logf("standard error:\n%s", p.stderr.String()) - } - } - return status -} - -// CopyTree recursively copies a source directory into the test project's directory. -func (p *TestProject) CopyTree(src string) { - filepath.Walk(src, - func(path string, info os.FileInfo, err error) error { - if path != src { - localpath := path[len(src)+1:] - if info.IsDir() { - p.TempDir(projectRoot, localpath) - } else { - destpath := filepath.Join(p.ProjPath(), localpath) - copyFile(destpath, path) - } - } - return nil - }) -} - -func copyFile(dest, src string) { - in, err := os.Open(src) - if err != nil { - panic(err) - } - defer in.Close() - - out, err := os.Create(dest) - if err != nil { - panic(err) - } - defer out.Close() - - io.Copy(out, in) -} - -// GetVendorPaths collects final vendor paths at a depth of three levels. -func (p *TestProject) GetVendorPaths() []string { - vendorPath := p.ProjPath("vendor") - result := make([]string, 0) - filepath.Walk( - vendorPath, - func(path string, info os.FileInfo, err error) error { - if len(path) > len(vendorPath) && info.IsDir() { - parse := strings.Split(path[len(vendorPath)+1:], string(filepath.Separator)) - if len(parse) == 3 { - result = append(result, strings.Join(parse, "/")) - return filepath.SkipDir - } - } - return nil - }, - ) - sort.Strings(result) - return result -} - -// GetImportPaths collect final vendor paths at a depth of three levels. -func (p *TestProject) GetImportPaths() []string { - importPath := p.Path("src") - result := make([]string, 0) - filepath.Walk( - importPath, - func(path string, info os.FileInfo, err error) error { - if len(path) > len(importPath) && info.IsDir() { - parse := strings.Split(path[len(importPath)+1:], string(filepath.Separator)) - if len(parse) == 3 { - result = append(result, strings.Join(parse, "/")) - return filepath.SkipDir - } - } - return nil - }, - ) - sort.Strings(result) - return result -} - -// RecordImportPaths takes a snapshot of the import paths before test is run. -func (p *TestProject) RecordImportPaths() { - p.preImports = p.GetImportPaths() -} - -// CompareImportPaths compares import paths before and after test commands. -func (p *TestProject) CompareImportPaths() { - wantImportPaths := p.preImports - gotImportPaths := p.GetImportPaths() - if len(gotImportPaths) != len(wantImportPaths) { - p.t.Fatalf("Import path count changed during command: pre %d post %d", len(wantImportPaths), len(gotImportPaths)) - } - for ind := range gotImportPaths { - if gotImportPaths[ind] != wantImportPaths[ind] { - p.t.Errorf("Change in import paths during: pre %s post %s", gotImportPaths, wantImportPaths) - } - } -} - -// makeRootTempdir makes a temporary directory for a run of testgo. If -// the temporary directory was already created, this does nothing. -func (p *TestProject) makeRootTempDir() { - if p.tempdir == "" { - var err error - p.tempdir, err = ioutil.TempDir("", "gotest") - p.Must(err) - - // Fix for OSX where the tempdir is a symlink: - if runtime.GOOS == "darwin" { - p.tempdir, err = filepath.EvalSymlinks(p.tempdir) - p.Must(err) - } - } -} - -// Setenv sets an environment variable to use when running the test go -// command. -func (p *TestProject) Setenv(name, val string) { - p.env = append(p.env, name+"="+val) -} - -// Must gives a fatal error if err is not nil. -func (p *TestProject) Must(err error) { - if err != nil { - p.t.Fatalf("%+v", err) - } -} diff --git a/vendor/github.com/golang/dep/internal/test/test.go b/vendor/github.com/golang/dep/internal/test/test.go deleted file mode 100644 index 9a7fbc8d98368a4871b53e4040230d366cb98bd0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/test.go +++ /dev/null @@ -1,625 +0,0 @@ -// 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 test - -import ( - "bytes" - "flag" - "fmt" - "go/format" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strings" - "sync" - "testing" - - "github.com/pkg/errors" -) - -var ( - // ExeSuffix is the suffix of executable files; ".exe" on Windows. - ExeSuffix string - mu sync.Mutex - // PrintLogs controls logging of test commands. - PrintLogs = flag.Bool("logs", false, "log stdin/stdout of test commands") - // UpdateGolden controls updating test fixtures. - UpdateGolden = flag.Bool("update", false, "update golden files") -) - -const ( - manifestName string = "Gopkg.toml" - lockName string = "Gopkg.lock" -) - -func init() { - switch runtime.GOOS { - case "windows": - ExeSuffix = ".exe" - } -} - -// Helper with utilities for testing. -type Helper struct { - t *testing.T - temps []string - wd string - origWd string - env []string - tempdir string - ran bool - inParallel bool - stdout, stderr bytes.Buffer -} - -// NewHelper initializes a new helper for testing. -func NewHelper(t *testing.T) *Helper { - wd, err := os.Getwd() - if err != nil { - panic(err) - } - return &Helper{t: t, origWd: wd} -} - -// Must gives a fatal error if err is not nil. -func (h *Helper) Must(err error) { - if err != nil { - h.t.Fatalf("%+v", err) - } -} - -// check gives a test non-fatal error if err is not nil. -func (h *Helper) check(err error) { - if err != nil { - h.t.Errorf("%+v", err) - } -} - -// Parallel runs the test in parallel by calling t.Parallel. -func (h *Helper) Parallel() { - if h.ran { - h.t.Fatalf("%+v", errors.New("internal testsuite error: call to parallel after run")) - } - if h.wd != "" { - h.t.Fatalf("%+v", errors.New("internal testsuite error: call to parallel after cd")) - } - for _, e := range h.env { - if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { - val := e[strings.Index(e, "=")+1:] - if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") { - h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: call to parallel with testdata in environment (%s)", e)) - } - } - } - h.inParallel = true - h.t.Parallel() -} - -// pwd returns the current directory. -func (h *Helper) pwd() string { - wd, err := os.Getwd() - if err != nil { - h.t.Fatalf("%+v", errors.Wrap(err, "could not get working directory")) - } - return wd -} - -// Cd changes the current directory to the named directory. Note that -// using this means that the test must not be run in parallel with any -// other tests. -func (h *Helper) Cd(dir string) { - if h.inParallel { - h.t.Fatalf("%+v", errors.New("internal testsuite error: changing directory when running in parallel")) - } - if h.wd == "" { - h.wd = h.pwd() - } - abs, err := filepath.Abs(dir) - if err == nil { - h.Setenv("PWD", abs) - } - - err = os.Chdir(dir) - h.Must(errors.Wrapf(err, "Unable to cd to %s", dir)) -} - -// Setenv sets an environment variable to use when running the test go -// command. -func (h *Helper) Setenv(name, val string) { - if h.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) { - h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)) - } - h.unsetenv(name) - h.env = append(h.env, name+"="+val) -} - -// unsetenv removes an environment variable. -func (h *Helper) unsetenv(name string) { - if h.env == nil { - h.env = append([]string(nil), os.Environ()...) - } - for i, v := range h.env { - if strings.HasPrefix(v, name+"=") { - h.env = append(h.env[:i], h.env[i+1:]...) - break - } - } -} - -// DoRun runs the test go command, recording stdout and stderr and -// returning exit status. -func (h *Helper) DoRun(args []string) error { - if h.inParallel { - for _, arg := range args { - if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") { - h.t.Fatalf("%+v", errors.New("internal testsuite error: parallel run using testdata")) - } - } - } - if *PrintLogs { - h.t.Logf("running testdep %v", args) - } - var prog string - if h.wd == "" { - prog = "./testdep" + ExeSuffix - } else { - prog = filepath.Join(h.wd, "testdep"+ExeSuffix) - } - newargs := []string{args[0], "-v"} - newargs = append(newargs, args[1:]...) - cmd := exec.Command(prog, newargs...) - h.stdout.Reset() - h.stderr.Reset() - cmd.Stdout = &h.stdout - cmd.Stderr = &h.stderr - cmd.Env = h.env - status := cmd.Run() - if *PrintLogs { - if h.stdout.Len() > 0 { - h.t.Log("standard output:") - h.t.Log(h.stdout.String()) - } - if h.stderr.Len() > 0 { - h.t.Log("standard error:") - h.t.Log(h.stderr.String()) - } - } - h.ran = true - return errors.Wrapf(status, "Error running %s\n%s", strings.Join(newargs, " "), h.stderr.String()) -} - -// Run runs the test go command, and expects it to succeed. -func (h *Helper) Run(args ...string) { - if runtime.GOOS == "windows" { - mu.Lock() - defer mu.Unlock() - } - if status := h.DoRun(args); status != nil { - h.t.Logf("go %v failed unexpectedly: %v", args, status) - h.t.FailNow() - } -} - -// runFail runs the test go command, and expects it to fail. -func (h *Helper) runFail(args ...string) { - if status := h.DoRun(args); status == nil { - h.t.Fatalf("%+v", errors.New("testgo succeeded unexpectedly")) - } else { - h.t.Log("testgo failed as expected:", status) - } -} - -// RunGo runs a go command, and expects it to succeed. -func (h *Helper) RunGo(args ...string) { - cmd := exec.Command("go", args...) - h.stdout.Reset() - h.stderr.Reset() - cmd.Stdout = &h.stdout - cmd.Stderr = &h.stderr - cmd.Dir = h.wd - cmd.Env = h.env - status := cmd.Run() - if h.stdout.Len() > 0 { - h.t.Log("go standard output:") - h.t.Log(h.stdout.String()) - } - if h.stderr.Len() > 0 { - h.t.Log("go standard error:") - h.t.Log(h.stderr.String()) - } - if status != nil { - h.t.Logf("go %v failed unexpectedly: %v", args, status) - h.t.FailNow() - } -} - -// NeedsExternalNetwork makes sure the tests needing external network will not -// be run when executing tests in short mode. -func NeedsExternalNetwork(t *testing.T) { - if testing.Short() { - t.Skip("skipping test: no external network in -short mode") - } -} - -// NeedsGit will make sure the tests that require git will be skipped if the -// git binary is not available. -func NeedsGit(t *testing.T) { - if _, err := exec.LookPath("git"); err != nil { - t.Skip("skipping because git binary not found") - } -} - -// RunGit runs a git command, and expects it to succeed. -func (h *Helper) RunGit(dir string, args ...string) { - cmd := exec.Command("git", args...) - h.stdout.Reset() - h.stderr.Reset() - cmd.Stdout = &h.stdout - cmd.Stderr = &h.stderr - cmd.Dir = dir - cmd.Env = h.env - status := cmd.Run() - if *PrintLogs { - if h.stdout.Len() > 0 { - h.t.Logf("git %v standard output:", args) - h.t.Log(h.stdout.String()) - } - if h.stderr.Len() > 0 { - h.t.Logf("git %v standard error:", args) - h.t.Log(h.stderr.String()) - } - } - if status != nil { - h.t.Logf("git %v failed unexpectedly: %v", args, status) - h.t.FailNow() - } -} - -// getStdout returns standard output of the testgo run as a string. -func (h *Helper) getStdout() string { - if !h.ran { - h.t.Fatalf("%+v", errors.New("internal testsuite error: stdout called before run")) - } - return h.stdout.String() -} - -// getStderr returns standard error of the testgo run as a string. -func (h *Helper) getStderr() string { - if !h.ran { - h.t.Fatalf("%+v", errors.New("internal testsuite error: stdout called before run")) - } - return h.stderr.String() -} - -// doGrepMatch looks for a regular expression in a buffer, and returns -// whether it is found. The regular expression is matched against -// each line separately, as with the grep command. -func (h *Helper) doGrepMatch(match string, b *bytes.Buffer) bool { - if !h.ran { - h.t.Fatalf("%+v", errors.New("internal testsuite error: grep called before run")) - } - re := regexp.MustCompile(match) - for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { - if re.Match(ln) { - return true - } - } - return false -} - -// doGrep looks for a regular expression in a buffer and fails if it -// is not found. The name argument is the name of the output we are -// searching, "output" or "error". The msg argument is logged on -// failure. -func (h *Helper) doGrep(match string, b *bytes.Buffer, name, msg string) { - if !h.doGrepMatch(match, b) { - h.t.Log(msg) - h.t.Logf("pattern %v not found in standard %s", match, name) - h.t.FailNow() - } -} - -// grepStdout looks for a regular expression in the test run's -// standard output and fails, logging msg, if it is not found. -func (h *Helper) grepStdout(match, msg string) { - h.doGrep(match, &h.stdout, "output", msg) -} - -// grepStderr looks for a regular expression in the test run's -// standard error and fails, logging msg, if it is not found. -func (h *Helper) grepStderr(match, msg string) { - h.doGrep(match, &h.stderr, "error", msg) -} - -// grepBoth looks for a regular expression in the test run's standard -// output or stand error and fails, logging msg, if it is not found. -func (h *Helper) grepBoth(match, msg string) { - if !h.doGrepMatch(match, &h.stdout) && !h.doGrepMatch(match, &h.stderr) { - h.t.Log(msg) - h.t.Logf("pattern %v not found in standard output or standard error", match) - h.t.FailNow() - } -} - -// doGrepNot looks for a regular expression in a buffer and fails if -// it is found. The name and msg arguments are as for doGrep. -func (h *Helper) doGrepNot(match string, b *bytes.Buffer, name, msg string) { - if h.doGrepMatch(match, b) { - h.t.Log(msg) - h.t.Logf("pattern %v found unexpectedly in standard %s", match, name) - h.t.FailNow() - } -} - -// grepStdoutNot looks for a regular expression in the test run's -// standard output and fails, logging msg, if it is found. -func (h *Helper) grepStdoutNot(match, msg string) { - h.doGrepNot(match, &h.stdout, "output", msg) -} - -// grepStderrNot looks for a regular expression in the test run's -// standard error and fails, logging msg, if it is found. -func (h *Helper) grepStderrNot(match, msg string) { - h.doGrepNot(match, &h.stderr, "error", msg) -} - -// grepBothNot looks for a regular expression in the test run's -// standard output or stand error and fails, logging msg, if it is -// found. -func (h *Helper) grepBothNot(match, msg string) { - if h.doGrepMatch(match, &h.stdout) || h.doGrepMatch(match, &h.stderr) { - h.t.Log(msg) - h.t.Fatalf("%+v", errors.Errorf("pattern %v found unexpectedly in standard output or standard error", match)) - } -} - -// doGrepCount counts the number of times a regexp is seen in a buffer. -func (h *Helper) doGrepCount(match string, b *bytes.Buffer) int { - if !h.ran { - h.t.Fatalf("%+v", errors.New("internal testsuite error: doGrepCount called before run")) - } - re := regexp.MustCompile(match) - c := 0 - for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { - if re.Match(ln) { - c++ - } - } - return c -} - -// grepCountBoth returns the number of times a regexp is seen in both -// standard output and standard error. -func (h *Helper) grepCountBoth(match string) int { - return h.doGrepCount(match, &h.stdout) + h.doGrepCount(match, &h.stderr) -} - -// creatingTemp records that the test plans to create a temporary file -// or directory. If the file or directory exists already, it will be -// removed. When the test completes, the file or directory will be -// removed if it exists. -func (h *Helper) creatingTemp(path string) { - if filepath.IsAbs(path) && !strings.HasPrefix(path, h.tempdir) { - h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)) - } - // If we have changed the working directory, make sure we have - // an absolute path, because we are going to change directory - // back before we remove the temporary. - if h.wd != "" && !filepath.IsAbs(path) { - path = filepath.Join(h.pwd(), path) - } - h.Must(os.RemoveAll(path)) - h.temps = append(h.temps, path) -} - -// makeTempdir makes a temporary directory for a run of testgo. If -// the temporary directory was already created, this does nothing. -func (h *Helper) makeTempdir() { - if h.tempdir == "" { - var err error - h.tempdir, err = ioutil.TempDir("", "gotest") - h.Must(err) - } -} - -// TempFile adds a temporary file for a run of testgo. -func (h *Helper) TempFile(path, contents string) { - h.makeTempdir() - h.Must(os.MkdirAll(filepath.Join(h.tempdir, filepath.Dir(path)), 0755)) - bytes := []byte(contents) - if strings.HasSuffix(path, ".go") { - formatted, err := format.Source(bytes) - if err == nil { - bytes = formatted - } - } - h.Must(ioutil.WriteFile(filepath.Join(h.tempdir, path), bytes, 0644)) -} - -// WriteTestFile writes a file to the testdata directory from memory. src is -// relative to ./testdata. -func (h *Helper) WriteTestFile(src string, content string) error { - err := ioutil.WriteFile(filepath.Join(h.origWd, "testdata", src), []byte(content), 0666) - return err -} - -// GetFile reads a file into memory -func (h *Helper) GetFile(path string) io.ReadCloser { - content, err := os.Open(path) - if err != nil { - h.t.Fatalf("%+v", errors.Wrapf(err, "Unable to open file: %s", path)) - } - return content -} - -// GetTestFile reads a file from the testdata directory into memory. src is -// relative to ./testdata. -func (h *Helper) GetTestFile(src string) io.ReadCloser { - fullPath := filepath.Join(h.origWd, "testdata", src) - return h.GetFile(fullPath) -} - -// GetTestFileString reads a file from the testdata directory into memory. src is -// relative to ./testdata. -func (h *Helper) GetTestFileString(src string) string { - srcf := h.GetTestFile(src) - defer srcf.Close() - content, err := ioutil.ReadAll(srcf) - if err != nil { - h.t.Fatalf("%+v", err) - } - return string(content) -} - -// TempCopy copies a temporary file from testdata into the temporary directory. -// dest is relative to the temp directory location, and src is relative to -// ./testdata. -func (h *Helper) TempCopy(dest, src string) { - in := h.GetTestFile(src) - defer in.Close() - h.TempDir(filepath.Dir(dest)) - out, err := os.Create(filepath.Join(h.tempdir, dest)) - if err != nil { - panic(err) - } - defer out.Close() - io.Copy(out, in) -} - -// TempDir adds a temporary directory for a run of testgo. -func (h *Helper) TempDir(path string) { - h.makeTempdir() - fullPath := filepath.Join(h.tempdir, path) - if err := os.MkdirAll(fullPath, 0755); err != nil && !os.IsExist(err) { - h.t.Fatalf("%+v", errors.Errorf("Unable to create temp directory: %s", fullPath)) - } -} - -// Path returns the absolute pathname to file with the temporary -// directory. -func (h *Helper) Path(name string) string { - if h.tempdir == "" { - h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: path(%q) with no tempdir", name)) - } - - var joined string - if name == "." { - joined = h.tempdir - } else { - joined = filepath.Join(h.tempdir, name) - } - - // Ensure it's the absolute, symlink-less path we're returning - abs, err := filepath.EvalSymlinks(joined) - if err != nil { - h.t.Fatalf("%+v", errors.Wrapf(err, "internal testsuite error: could not get absolute path for dir(%q)", joined)) - } - return abs -} - -// MustExist fails if path does not exist. -func (h *Helper) MustExist(path string) { - if err := h.ShouldExist(path); err != nil { - h.t.Fatalf("%+v", err) - } -} - -// ShouldExist returns an error if path does not exist. -func (h *Helper) ShouldExist(path string) error { - if !h.Exist(path) { - return errors.Errorf("%s does not exist but should", path) - } - - return nil -} - -// Exist returns whether or not a path exists -func (h *Helper) Exist(path string) bool { - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - return false - } - h.t.Fatalf("%+v", errors.Wrapf(err, "Error checking if path exists: %s", path)) - } - - return true -} - -// MustNotExist fails if path exists. -func (h *Helper) MustNotExist(path string) { - if err := h.ShouldNotExist(path); err != nil { - h.t.Fatalf("%+v", err) - } -} - -// ShouldNotExist returns an error if path exists. -func (h *Helper) ShouldNotExist(path string) error { - if h.Exist(path) { - return errors.Errorf("%s exists but should not", path) - } - - return nil -} - -// Cleanup cleans up a test that runs testgo. -func (h *Helper) Cleanup() { - if h.wd != "" { - if err := os.Chdir(h.wd); err != nil { - // We are unlikely to be able to continue. - fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err) - os.Exit(2) - } - } - // NOTE(mattn): It seems that sometimes git.exe is not dead - // when cleanup() is called. But we do not know any way to wait for it. - if runtime.GOOS == "windows" { - mu.Lock() - exec.Command(`taskkill`, `/F`, `/IM`, `git.exe`).Run() - mu.Unlock() - } - for _, path := range h.temps { - h.check(os.RemoveAll(path)) - } - if h.tempdir != "" { - h.check(os.RemoveAll(h.tempdir)) - } -} - -// ReadManifest returns the manifest in the current directory. -func (h *Helper) ReadManifest() string { - m := filepath.Join(h.pwd(), manifestName) - h.MustExist(m) - - f, err := ioutil.ReadFile(m) - h.Must(err) - return string(f) -} - -// ReadLock returns the lock in the current directory. -func (h *Helper) ReadLock() string { - l := filepath.Join(h.pwd(), lockName) - h.MustExist(l) - - f, err := ioutil.ReadFile(l) - h.Must(err) - return string(f) -} - -// GetCommit treats repo as a path to a git repository and returns the current -// revision. -func (h *Helper) GetCommit(repo string) string { - repoPath := h.Path("pkg/dep/sources/https---" + strings.Replace(repo, "/", "-", -1)) - cmd := exec.Command("git", "rev-parse", "HEAD") - cmd.Dir = repoPath - out, err := cmd.CombinedOutput() - if err != nil { - h.t.Fatalf("%+v", errors.Wrapf(err, "git commit failed: out -> %s", string(out))) - } - return strings.TrimSpace(string(out)) -} diff --git a/vendor/github.com/golang/dep/internal/test/writer.go b/vendor/github.com/golang/dep/internal/test/writer.go deleted file mode 100644 index 7fd3a4d948f4697e88f6262fc02f028ba2fe2b50..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/internal/test/writer.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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 test - -import ( - "strings" - "testing" - "unicode" -) - -// Writer adapts a testing.TB to the io.Writer interface -type Writer struct { - testing.TB -} - -func (t Writer) Write(b []byte) (n int, err error) { - str := string(b) - if len(str) == 0 { - return 0, nil - } - - for _, part := range strings.Split(str, "\n") { - str := strings.TrimRightFunc(part, unicode.IsSpace) - if len(str) != 0 { - t.Log(str) - } - } - return len(b), err -} diff --git a/vendor/github.com/golang/dep/lock.go b/vendor/github.com/golang/dep/lock.go deleted file mode 100644 index 3f3f563c425f8d04376ff47df2f71fd56832fcf3..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/lock.go +++ /dev/null @@ -1,203 +0,0 @@ -// 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 dep - -import ( - "bytes" - "encoding/hex" - "io" - "sort" - - "github.com/golang/dep/gps" - "github.com/pelletier/go-toml" - "github.com/pkg/errors" -) - -// LockName is the lock file name used by dep. -const LockName = "Gopkg.lock" - -// Lock holds lock file data and implements gps.Lock. -type Lock struct { - SolveMeta SolveMeta - P []gps.LockedProject -} - -// SolveMeta holds solver meta data. -type SolveMeta struct { - InputsDigest []byte - AnalyzerName string - AnalyzerVersion int - SolverName string - SolverVersion int -} - -type rawLock struct { - SolveMeta solveMeta `toml:"solve-meta"` - Projects []rawLockedProject `toml:"projects"` -} - -type solveMeta struct { - InputsDigest string `toml:"inputs-digest"` - AnalyzerName string `toml:"analyzer-name"` - AnalyzerVersion int `toml:"analyzer-version"` - SolverName string `toml:"solver-name"` - SolverVersion int `toml:"solver-version"` -} - -type rawLockedProject struct { - Name string `toml:"name"` - Branch string `toml:"branch,omitempty"` - Revision string `toml:"revision"` - Version string `toml:"version,omitempty"` - Source string `toml:"source,omitempty"` - Packages []string `toml:"packages"` -} - -func readLock(r io.Reader) (*Lock, error) { - buf := &bytes.Buffer{} - _, err := buf.ReadFrom(r) - if err != nil { - return nil, errors.Wrap(err, "Unable to read byte stream") - } - - raw := rawLock{} - err = toml.Unmarshal(buf.Bytes(), &raw) - if err != nil { - return nil, errors.Wrap(err, "Unable to parse the lock as TOML") - } - - return fromRawLock(raw) -} - -func fromRawLock(raw rawLock) (*Lock, error) { - var err error - l := &Lock{ - P: make([]gps.LockedProject, len(raw.Projects)), - } - - l.SolveMeta.InputsDigest, err = hex.DecodeString(raw.SolveMeta.InputsDigest) - if err != nil { - return nil, errors.Errorf("invalid hash digest in lock's memo field") - } - - l.SolveMeta.AnalyzerName = raw.SolveMeta.AnalyzerName - l.SolveMeta.AnalyzerVersion = raw.SolveMeta.AnalyzerVersion - l.SolveMeta.SolverName = raw.SolveMeta.SolverName - l.SolveMeta.SolverVersion = raw.SolveMeta.SolverVersion - - for i, ld := range raw.Projects { - r := gps.Revision(ld.Revision) - - var v gps.Version = r - if ld.Version != "" { - if ld.Branch != "" { - return nil, errors.Errorf("lock file specified both a branch (%s) and version (%s) for %s", ld.Branch, ld.Version, ld.Name) - } - v = gps.NewVersion(ld.Version).Pair(r) - } else if ld.Branch != "" { - v = gps.NewBranch(ld.Branch).Pair(r) - } else if r == "" { - return nil, errors.Errorf("lock file has entry for %s, but specifies no branch or version", ld.Name) - } - - id := gps.ProjectIdentifier{ - ProjectRoot: gps.ProjectRoot(ld.Name), - Source: ld.Source, - } - l.P[i] = gps.NewLockedProject(id, v, ld.Packages) - } - - return l, nil -} - -// InputsDigest returns the hash of inputs which produced this lock data. -func (l *Lock) InputsDigest() []byte { - return l.SolveMeta.InputsDigest -} - -// Projects returns the list of LockedProjects contained in the lock data. -func (l *Lock) Projects() []gps.LockedProject { - return l.P -} - -// HasProjectWithRoot checks if the lock contains a project with the provided -// ProjectRoot. -// -// This check is O(n) in the number of projects. -func (l *Lock) HasProjectWithRoot(root gps.ProjectRoot) bool { - for _, p := range l.P { - if p.Ident().ProjectRoot == root { - return true - } - } - - return false -} - -// toRaw converts the manifest into a representation suitable to write to the lock file -func (l *Lock) toRaw() rawLock { - raw := rawLock{ - SolveMeta: solveMeta{ - InputsDigest: hex.EncodeToString(l.SolveMeta.InputsDigest), - AnalyzerName: l.SolveMeta.AnalyzerName, - AnalyzerVersion: l.SolveMeta.AnalyzerVersion, - SolverName: l.SolveMeta.SolverName, - SolverVersion: l.SolveMeta.SolverVersion, - }, - Projects: make([]rawLockedProject, len(l.P)), - } - - sort.Slice(l.P, func(i, j int) bool { - return l.P[i].Ident().Less(l.P[j].Ident()) - }) - - for k, lp := range l.P { - id := lp.Ident() - ld := rawLockedProject{ - Name: string(id.ProjectRoot), - Source: id.Source, - Packages: lp.Packages(), - } - - v := lp.Version() - ld.Revision, ld.Branch, ld.Version = gps.VersionComponentStrings(v) - - raw.Projects[k] = ld - } - - return raw -} - -// MarshalTOML serializes this lock into TOML via an intermediate raw form. -func (l *Lock) MarshalTOML() ([]byte, error) { - raw := l.toRaw() - var buf bytes.Buffer - enc := toml.NewEncoder(&buf).ArraysWithOneElementPerLine(true) - err := enc.Encode(raw) - return buf.Bytes(), errors.Wrap(err, "Unable to marshal lock to TOML string") -} - -// LockFromSolution converts a gps.Solution to dep's representation of a lock. -// -// Data is defensively copied wherever necessary to ensure the resulting *lock -// shares no memory with the original lock. -func LockFromSolution(in gps.Solution) *Lock { - h, p := in.InputsDigest(), in.Projects() - - l := &Lock{ - SolveMeta: SolveMeta{ - InputsDigest: make([]byte, len(h)), - AnalyzerName: in.AnalyzerName(), - AnalyzerVersion: in.AnalyzerVersion(), - SolverName: in.SolverName(), - SolverVersion: in.SolverVersion(), - }, - P: make([]gps.LockedProject, len(p)), - } - - copy(l.SolveMeta.InputsDigest, h) - copy(l.P, p) - return l -} diff --git a/vendor/github.com/golang/dep/manifest.go b/vendor/github.com/golang/dep/manifest.go deleted file mode 100644 index add9236fdf2c90212d619638ea52476702bc6cef..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/manifest.go +++ /dev/null @@ -1,640 +0,0 @@ -// 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 dep - -import ( - "bytes" - "fmt" - "io" - "reflect" - "regexp" - "sort" - "sync" - - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/pkgtree" - toml "github.com/pelletier/go-toml" - "github.com/pkg/errors" -) - -// ManifestName is the manifest file name used by dep. -const ManifestName = "Gopkg.toml" - -// Errors -var ( - errInvalidConstraint = errors.Errorf("%q must be a TOML array of tables", "constraint") - errInvalidOverride = errors.Errorf("%q must be a TOML array of tables", "override") - errInvalidRequired = errors.Errorf("%q must be a TOML list of strings", "required") - errInvalidIgnored = errors.Errorf("%q must be a TOML list of strings", "ignored") - errInvalidPrune = errors.Errorf("%q must be a TOML table of booleans", "prune") - errInvalidPruneProject = errors.Errorf("%q must be a TOML array of tables", "prune.project") - errInvalidMetadata = errors.New("metadata should be a TOML table") - - errInvalidProjectRoot = errors.New("ProjectRoot name validation failed") - - errInvalidPruneValue = errors.New("prune options values must be booleans") - errPruneSubProject = errors.New("prune projects should not contain sub projects") - - errRootPruneContainsName = errors.Errorf("%q should not include a name", "prune") - errInvalidRootPruneValue = errors.New("root prune options must be omitted instead of being set to false") - errInvalidPruneProjectName = errors.Errorf("%q in %q must be a string", "name", "prune.project") - errNoName = errors.New("no name provided") -) - -// Manifest holds manifest file data and implements gps.RootManifest. -type Manifest struct { - Constraints gps.ProjectConstraints - Ovr gps.ProjectConstraints - - Ignored []string - Required []string - - PruneOptions gps.CascadingPruneOptions -} - -type rawManifest struct { - Constraints []rawProject `toml:"constraint,omitempty"` - Overrides []rawProject `toml:"override,omitempty"` - Ignored []string `toml:"ignored,omitempty"` - Required []string `toml:"required,omitempty"` - PruneOptions rawPruneOptions `toml:"prune,omitempty"` -} - -type rawProject struct { - Name string `toml:"name"` - Branch string `toml:"branch,omitempty"` - Revision string `toml:"revision,omitempty"` - Version string `toml:"version,omitempty"` - Source string `toml:"source,omitempty"` -} - -type rawPruneOptions struct { - UnusedPackages bool `toml:"unused-packages,omitempty"` - NonGoFiles bool `toml:"non-go,omitempty"` - GoTests bool `toml:"go-tests,omitempty"` - - //Projects []map[string]interface{} `toml:"project,omitempty"` - Projects []map[string]interface{} -} - -const ( - pruneOptionUnusedPackages = "unused-packages" - pruneOptionGoTests = "go-tests" - pruneOptionNonGo = "non-go" -) - -// Constants to represents per-project prune uint8 values. -const ( - pvnone uint8 = 0 // No per-project prune value was set in Gopkg.toml. - pvtrue uint8 = 1 // Per-project prune value was explicitly set to true. - pvfalse uint8 = 2 // Per-project prune value was explicitly set to false. -) - -// NewManifest instantites a new manifest. -func NewManifest() *Manifest { - return &Manifest{ - Constraints: make(gps.ProjectConstraints), - Ovr: make(gps.ProjectConstraints), - PruneOptions: gps.CascadingPruneOptions{ - DefaultOptions: gps.PruneNestedVendorDirs, - PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{}, - }, - } -} - -func validateManifest(s string) ([]error, error) { - var warns []error - // Load the TomlTree from string - tree, err := toml.Load(s) - if err != nil { - return warns, errors.Wrap(err, "unable to load TomlTree from string") - } - // Convert tree to a map - manifest := tree.ToMap() - - // match abbreviated git hash (7chars) or hg hash (12chars) - abbrevRevHash := regexp.MustCompile("^[a-f0-9]{7}([a-f0-9]{5})?$") - // Look for unknown fields and collect errors - for prop, val := range manifest { - switch prop { - case "metadata": - // Check if metadata is of Map type - if reflect.TypeOf(val).Kind() != reflect.Map { - warns = append(warns, errInvalidMetadata) - } - case "constraint", "override": - valid := true - // Invalid if type assertion fails. Not a TOML array of tables. - if rawProj, ok := val.([]interface{}); ok { - // Check element type. Must be a map. Checking one element would be - // enough because TOML doesn't allow mixing of types. - if reflect.TypeOf(rawProj[0]).Kind() != reflect.Map { - valid = false - } - - if valid { - // Iterate through each array of tables - for _, v := range rawProj { - ruleProvided := false - props := v.(map[string]interface{}) - // Check the individual field's key to be valid - for key, value := range props { - // Check if the key is valid - switch key { - case "name": - case "branch", "version", "source": - ruleProvided = true - case "revision": - ruleProvided = true - if valueStr, ok := value.(string); ok { - if abbrevRevHash.MatchString(valueStr) { - warns = append(warns, fmt.Errorf("revision %q should not be in abbreviated form", valueStr)) - } - } - case "metadata": - // Check if metadata is of Map type - if reflect.TypeOf(value).Kind() != reflect.Map { - warns = append(warns, fmt.Errorf("metadata in %q should be a TOML table", prop)) - } - default: - // unknown/invalid key - warns = append(warns, fmt.Errorf("invalid key %q in %q", key, prop)) - } - } - if _, ok := props["name"]; !ok { - warns = append(warns, errNoName) - } else if !ruleProvided && prop == "constraint" { - warns = append(warns, fmt.Errorf("branch, version, revision, or source should be provided for %q", props["name"])) - } - } - } - } else { - valid = false - } - - if !valid { - if prop == "constraint" { - return warns, errInvalidConstraint - } - if prop == "override" { - return warns, errInvalidOverride - } - } - case "ignored", "required": - valid := true - if rawList, ok := val.([]interface{}); ok { - // Check element type of the array. TOML doesn't let mixing of types in - // array. Checking one element would be enough. Empty array is valid. - if len(rawList) > 0 && reflect.TypeOf(rawList[0]).Kind() != reflect.String { - valid = false - } - } else { - valid = false - } - - if !valid { - if prop == "ignored" { - return warns, errInvalidIgnored - } - if prop == "required" { - return warns, errInvalidRequired - } - } - case "prune": - pruneWarns, err := validatePruneOptions(val, true) - warns = append(warns, pruneWarns...) - if err != nil { - return warns, err - } - default: - warns = append(warns, fmt.Errorf("unknown field in manifest: %v", prop)) - } - } - - return warns, nil -} - -func validatePruneOptions(val interface{}, root bool) (warns []error, err error) { - if reflect.TypeOf(val).Kind() != reflect.Map { - return warns, errInvalidPrune - } - - for key, value := range val.(map[string]interface{}) { - switch key { - case pruneOptionNonGo, pruneOptionGoTests, pruneOptionUnusedPackages: - if option, ok := value.(bool); !ok { - return warns, errInvalidPruneValue - } else if root && !option { - return warns, errInvalidRootPruneValue - } - case "name": - if root { - warns = append(warns, errRootPruneContainsName) - } else if _, ok := value.(string); !ok { - return warns, errInvalidPruneProjectName - } - case "project": - if !root { - return warns, errPruneSubProject - } - if reflect.TypeOf(value).Kind() != reflect.Slice { - return warns, errInvalidPruneProject - } - - for _, project := range value.([]interface{}) { - projectWarns, err := validatePruneOptions(project, false) - warns = append(warns, projectWarns...) - if err != nil { - return nil, err - } - } - - default: - if root { - warns = append(warns, errors.Errorf("unknown field %q in %q", key, "prune")) - } else { - warns = append(warns, errors.Errorf("unknown field %q in %q", key, "prune.project")) - } - } - } - - return warns, err -} - -func checkRedundantPruneOptions(co gps.CascadingPruneOptions) (warns []error) { - for name, project := range co.PerProjectOptions { - if project.UnusedPackages != pvnone { - if (co.DefaultOptions&gps.PruneUnusedPackages != 0) == (project.UnusedPackages == pvtrue) { - warns = append(warns, errors.Errorf("redundant prune option %q set for %q", pruneOptionUnusedPackages, name)) - } - } - - if project.NonGoFiles != pvnone { - if (co.DefaultOptions&gps.PruneNonGoFiles != 0) == (project.NonGoFiles == pvtrue) { - warns = append(warns, errors.Errorf("redundant prune option %q set for %q", pruneOptionNonGo, name)) - } - } - - if project.GoTests != pvnone { - if (co.DefaultOptions&gps.PruneGoTestFiles != 0) == (project.GoTests == pvtrue) { - warns = append(warns, errors.Errorf("redundant prune option %q set for %q", pruneOptionGoTests, name)) - } - } - } - - return warns -} - -// ValidateProjectRoots validates the project roots present in manifest. -func ValidateProjectRoots(c *Ctx, m *Manifest, sm gps.SourceManager) error { - // Channel to receive all the errors - errorCh := make(chan error, len(m.Constraints)+len(m.Ovr)) - - var wg sync.WaitGroup - - validate := func(pr gps.ProjectRoot) { - defer wg.Done() - origPR, err := sm.DeduceProjectRoot(string(pr)) - if err != nil { - errorCh <- err - } else if origPR != pr { - errorCh <- fmt.Errorf("the name for %q should be changed to %q", pr, origPR) - } - } - - for pr := range m.Constraints { - wg.Add(1) - go validate(pr) - } - for pr := range m.Ovr { - wg.Add(1) - go validate(pr) - } - for pr := range m.PruneOptions.PerProjectOptions { - wg.Add(1) - go validate(pr) - } - - wg.Wait() - close(errorCh) - - var valErr error - if len(errorCh) > 0 { - valErr = errInvalidProjectRoot - c.Err.Printf("The following issues were found in Gopkg.toml:\n\n") - for err := range errorCh { - c.Err.Println(" ✗", err.Error()) - } - c.Err.Println() - } - - return valErr -} - -// readManifest returns a Manifest read from r and a slice of validation warnings. -func readManifest(r io.Reader) (*Manifest, []error, error) { - buf := &bytes.Buffer{} - _, err := buf.ReadFrom(r) - if err != nil { - return nil, nil, errors.Wrap(err, "unable to read byte stream") - } - - warns, err := validateManifest(buf.String()) - if err != nil { - return nil, warns, errors.Wrap(err, "manifest validation failed") - } - - raw := rawManifest{} - err = toml.Unmarshal(buf.Bytes(), &raw) - if err != nil { - return nil, warns, errors.Wrap(err, "unable to parse the manifest as TOML") - } - - m, err := fromRawManifest(raw, buf) - if err != nil { - return nil, warns, err - } - - warns = append(warns, checkRedundantPruneOptions(m.PruneOptions)...) - return m, warns, nil -} - -func fromRawManifest(raw rawManifest, buf *bytes.Buffer) (*Manifest, error) { - m := NewManifest() - - m.Constraints = make(gps.ProjectConstraints, len(raw.Constraints)) - m.Ovr = make(gps.ProjectConstraints, len(raw.Overrides)) - m.Ignored = raw.Ignored - m.Required = raw.Required - - for i := 0; i < len(raw.Constraints); i++ { - name, prj, err := toProject(raw.Constraints[i]) - if err != nil { - return nil, err - } - if _, exists := m.Constraints[name]; exists { - return nil, errors.Errorf("multiple dependencies specified for %s, can only specify one", name) - } - m.Constraints[name] = prj - } - - for i := 0; i < len(raw.Overrides); i++ { - name, prj, err := toProject(raw.Overrides[i]) - if err != nil { - return nil, err - } - if _, exists := m.Ovr[name]; exists { - return nil, errors.Errorf("multiple overrides specified for %s, can only specify one", name) - } - m.Ovr[name] = prj - } - - // TODO(sdboyer) it is awful that we have to do this manual extraction - tree, err := toml.Load(buf.String()) - if err != nil { - return nil, errors.Wrap(err, "unable to load TomlTree from string") - } - - iprunemap := tree.Get("prune") - if iprunemap == nil { - return m, nil - } - // Previous validation already guaranteed that, if it exists, it's this map - // type. - m.PruneOptions = fromRawPruneOptions(iprunemap.(*toml.Tree).ToMap()) - - return m, nil -} - -func fromRawPruneOptions(prunemap map[string]interface{}) gps.CascadingPruneOptions { - opts := gps.CascadingPruneOptions{ - DefaultOptions: gps.PruneNestedVendorDirs, - PerProjectOptions: make(map[gps.ProjectRoot]gps.PruneOptionSet), - } - - if val, has := prunemap[pruneOptionUnusedPackages]; has && val.(bool) { - opts.DefaultOptions |= gps.PruneUnusedPackages - } - if val, has := prunemap[pruneOptionNonGo]; has && val.(bool) { - opts.DefaultOptions |= gps.PruneNonGoFiles - } - if val, has := prunemap[pruneOptionGoTests]; has && val.(bool) { - opts.DefaultOptions |= gps.PruneGoTestFiles - } - - trinary := func(v interface{}) uint8 { - b := v.(bool) - if b { - return pvtrue - } - return pvfalse - } - - if projprunes, has := prunemap["project"]; has { - for _, proj := range projprunes.([]interface{}) { - var pr gps.ProjectRoot - // This should be redundant, but being explicit doesn't hurt. - pos := gps.PruneOptionSet{NestedVendor: pvtrue} - - for key, val := range proj.(map[string]interface{}) { - switch key { - case "name": - pr = gps.ProjectRoot(val.(string)) - case pruneOptionNonGo: - pos.NonGoFiles = trinary(val) - case pruneOptionGoTests: - pos.GoTests = trinary(val) - case pruneOptionUnusedPackages: - pos.UnusedPackages = trinary(val) - } - } - opts.PerProjectOptions[pr] = pos - } - } - - return opts -} - -// toRawPruneOptions converts a gps.RootPruneOption's PruneOptions to rawPruneOptions -// -// Will panic if gps.RootPruneOption includes ProjectPruneOptions -// See https://github.com/golang/dep/pull/1460#discussion_r158128740 for more information -func toRawPruneOptions(co gps.CascadingPruneOptions) rawPruneOptions { - if len(co.PerProjectOptions) != 0 { - panic("toRawPruneOptions cannot convert ProjectOptions to rawPruneOptions") - } - raw := rawPruneOptions{} - - if (co.DefaultOptions & gps.PruneUnusedPackages) != 0 { - raw.UnusedPackages = true - } - - if (co.DefaultOptions & gps.PruneNonGoFiles) != 0 { - raw.NonGoFiles = true - } - - if (co.DefaultOptions & gps.PruneGoTestFiles) != 0 { - raw.GoTests = true - } - return raw -} - -// toProject interprets the string representations of project information held in -// a rawProject, converting them into a proper gps.ProjectProperties. An -// error is returned if the rawProject contains some invalid combination - -// for example, if both a branch and version constraint are specified. -func toProject(raw rawProject) (n gps.ProjectRoot, pp gps.ProjectProperties, err error) { - n = gps.ProjectRoot(raw.Name) - if raw.Branch != "" { - if raw.Version != "" || raw.Revision != "" { - return n, pp, errors.Errorf("multiple constraints specified for %s, can only specify one", n) - } - pp.Constraint = gps.NewBranch(raw.Branch) - } else if raw.Version != "" { - if raw.Revision != "" { - return n, pp, errors.Errorf("multiple constraints specified for %s, can only specify one", n) - } - - // always semver if we can - pp.Constraint, err = gps.NewSemverConstraintIC(raw.Version) - if err != nil { - // but if not, fall back on plain versions - pp.Constraint = gps.NewVersion(raw.Version) - } - } else if raw.Revision != "" { - pp.Constraint = gps.Revision(raw.Revision) - } else { - // If the user specifies nothing, it means an open constraint (accept - // anything). - pp.Constraint = gps.Any() - } - - pp.Source = raw.Source - - return n, pp, nil -} - -// MarshalTOML serializes this manifest into TOML via an intermediate raw form. -func (m *Manifest) MarshalTOML() ([]byte, error) { - raw := m.toRaw() - var buf bytes.Buffer - enc := toml.NewEncoder(&buf).ArraysWithOneElementPerLine(true) - err := enc.Encode(raw) - return buf.Bytes(), errors.Wrap(err, "unable to marshal the lock to a TOML string") -} - -// toRaw converts the manifest into a representation suitable to write to the manifest file -func (m *Manifest) toRaw() rawManifest { - raw := rawManifest{ - Constraints: make([]rawProject, 0, len(m.Constraints)), - Overrides: make([]rawProject, 0, len(m.Ovr)), - Ignored: m.Ignored, - Required: m.Required, - } - - for n, prj := range m.Constraints { - raw.Constraints = append(raw.Constraints, toRawProject(n, prj)) - } - sort.Sort(sortedRawProjects(raw.Constraints)) - - for n, prj := range m.Ovr { - raw.Overrides = append(raw.Overrides, toRawProject(n, prj)) - } - sort.Sort(sortedRawProjects(raw.Overrides)) - - raw.PruneOptions = toRawPruneOptions(m.PruneOptions) - - return raw -} - -type sortedRawProjects []rawProject - -func (s sortedRawProjects) Len() int { return len(s) } -func (s sortedRawProjects) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s sortedRawProjects) Less(i, j int) bool { - l, r := s[i], s[j] - - if l.Name < r.Name { - return true - } - if r.Name < l.Name { - return false - } - - return l.Source < r.Source -} - -func toRawProject(name gps.ProjectRoot, project gps.ProjectProperties) rawProject { - raw := rawProject{ - Name: string(name), - Source: project.Source, - } - - if v, ok := project.Constraint.(gps.Version); ok { - switch v.Type() { - case gps.IsRevision: - raw.Revision = v.String() - case gps.IsBranch: - raw.Branch = v.String() - case gps.IsSemver, gps.IsVersion: - raw.Version = v.ImpliedCaretString() - } - return raw - } - - // We simply don't allow for a case where the user could directly - // express a 'none' constraint, so we can ignore it here. We also ignore - // the 'any' case, because that's the other possibility, and it's what - // we interpret not having any constraint expressions at all to mean. - // if !gps.IsAny(pp.Constraint) && !gps.IsNone(pp.Constraint) { - if !gps.IsAny(project.Constraint) && project.Constraint != nil { - // Has to be a semver range. - raw.Version = project.Constraint.ImpliedCaretString() - } - - return raw -} - -// DependencyConstraints returns a list of project-level constraints. -func (m *Manifest) DependencyConstraints() gps.ProjectConstraints { - return m.Constraints -} - -// Overrides returns a list of project-level override constraints. -func (m *Manifest) Overrides() gps.ProjectConstraints { - return m.Ovr -} - -// IgnoredPackages returns a set of import paths to ignore. -func (m *Manifest) IgnoredPackages() *pkgtree.IgnoredRuleset { - return pkgtree.NewIgnoredRuleset(m.Ignored) -} - -// HasConstraintsOn checks if the manifest contains either constraints or -// overrides on the provided ProjectRoot. -func (m *Manifest) HasConstraintsOn(root gps.ProjectRoot) bool { - if _, has := m.Constraints[root]; has { - return true - } - if _, has := m.Ovr[root]; has { - return true - } - - return false -} - -// RequiredPackages returns a set of import paths to require. -func (m *Manifest) RequiredPackages() map[string]bool { - if len(m.Required) == 0 { - return nil - } - - mp := make(map[string]bool, len(m.Required)) - for _, i := range m.Required { - mp[i] = true - } - - return mp -} diff --git a/vendor/github.com/golang/dep/project.go b/vendor/github.com/golang/dep/project.go deleted file mode 100644 index d2677e88661b2f810996b1a20a844a7bdcd03f08..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/project.go +++ /dev/null @@ -1,276 +0,0 @@ -// 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 dep - -import ( - "fmt" - "os" - "path/filepath" - "sort" - - "github.com/golang/dep/gps" - "github.com/golang/dep/gps/paths" - "github.com/golang/dep/gps/pkgtree" - "github.com/golang/dep/internal/fs" - "github.com/pkg/errors" -) - -var ( - errProjectNotFound = fmt.Errorf("could not find project %s, use dep init to initiate a manifest", ManifestName) - errVendorBackupFailed = fmt.Errorf("failed to create vendor backup. File with same name exists") -) - -// findProjectRoot searches from the starting directory upwards looking for a -// manifest file until we get to the root of the filesystem. -func findProjectRoot(from string) (string, error) { - for { - mp := filepath.Join(from, ManifestName) - - _, err := os.Stat(mp) - if err == nil { - return from, nil - } - if !os.IsNotExist(err) { - // Some err other than non-existence - return that out - return "", err - } - - parent := filepath.Dir(from) - if parent == from { - return "", errProjectNotFound - } - from = parent - } -} - -// checkGopkgFilenames validates filename case for the manifest and lock files. -// -// This is relevant on case-insensitive file systems like the defaults in Windows and -// macOS. -// -// If manifest file is not found, it returns an error indicating the project could not be -// found. If it is found but the case does not match, an error is returned. If a lock -// file is not found, no error is returned as lock file is optional. If it is found but -// the case does not match, an error is returned. -func checkGopkgFilenames(projectRoot string) error { - // ReadActualFilenames is actually costly. Since the check to validate filename case - // for Gopkg filenames is not relevant to case-sensitive filesystems like - // ext4(linux), try for an early return. - caseSensitive, err := fs.IsCaseSensitiveFilesystem(projectRoot) - if err != nil { - return errors.Wrap(err, "could not check validity of configuration filenames") - } - if caseSensitive { - return nil - } - - actualFilenames, err := fs.ReadActualFilenames(projectRoot, []string{ManifestName, LockName}) - - if err != nil { - return errors.Wrap(err, "could not check validity of configuration filenames") - } - - actualMfName, found := actualFilenames[ManifestName] - if !found { - // Ideally this part of the code won't ever be executed if it is called after - // `findProjectRoot`. But be thorough and handle it anyway. - return errProjectNotFound - } - if actualMfName != ManifestName { - return fmt.Errorf("manifest filename %q does not match %q", actualMfName, ManifestName) - } - - // If a file is not found, the string map returned by `fs.ReadActualFilenames` will - // not have an entry for the given filename. Since the lock file is optional, we - // should check for equality only if it was found. - actualLfName, found := actualFilenames[LockName] - if found && actualLfName != LockName { - return fmt.Errorf("lock filename %q does not match %q", actualLfName, LockName) - } - - return nil -} - -// A Project holds a Manifest and optional Lock for a project. -type Project struct { - // AbsRoot is the absolute path to the root directory of the project. - AbsRoot string - // ResolvedAbsRoot is the resolved absolute path to the root directory of the project. - // If AbsRoot is not a symlink, then ResolvedAbsRoot should equal AbsRoot. - ResolvedAbsRoot string - // ImportRoot is the import path of the project's root directory. - ImportRoot gps.ProjectRoot - Manifest *Manifest - Lock *Lock // Optional - RootPackageTree pkgtree.PackageTree -} - -// SetRoot sets the project AbsRoot and ResolvedAbsRoot. If root is not a symlink, ResolvedAbsRoot will be set to root. -func (p *Project) SetRoot(root string) error { - rroot, err := filepath.EvalSymlinks(root) - if err != nil { - return err - } - - p.ResolvedAbsRoot, p.AbsRoot = rroot, root - return nil -} - -// MakeParams is a simple helper to create a gps.SolveParameters without setting -// any nils incorrectly. -func (p *Project) MakeParams() gps.SolveParameters { - params := gps.SolveParameters{ - RootDir: p.AbsRoot, - ProjectAnalyzer: Analyzer{}, - } - - if p.Manifest != nil { - params.Manifest = p.Manifest - } - - if p.Lock != nil { - params.Lock = p.Lock - } - - return params -} - -// ParseRootPackageTree analyzes the root project's disk contents to create a -// PackageTree, trimming out packages that are not relevant for root projects -// along the way. -// -// The resulting tree is cached internally at p.RootPackageTree. -func (p *Project) ParseRootPackageTree() (pkgtree.PackageTree, error) { - if p.RootPackageTree.Packages == nil { - ptree, err := pkgtree.ListPackages(p.ResolvedAbsRoot, string(p.ImportRoot)) - if err != nil { - return pkgtree.PackageTree{}, errors.Wrap(err, "analysis of current project's packages failed") - } - // We don't care about (unreachable) hidden packages for the root project, - // so drop all of those. - var ig *pkgtree.IgnoredRuleset - if p.Manifest != nil { - ig = p.Manifest.IgnoredPackages() - } - p.RootPackageTree = ptree.TrimHiddenPackages(true, true, ig) - } - return p.RootPackageTree, nil -} - -// GetDirectDependencyNames returns the set of unique Project Roots that are the -// direct dependencies of this Project. -// -// A project is considered a direct dependency if at least one of packages in it -// is named in either this Project's required list, or if there is at least one -// non-ignored import statement from a non-ignored package in the current -// project's package tree. -// -// The returned map of Project Roots contains only boolean true values; this -// makes a "false" value always indicate an absent key, which makes conditional -// checks against the map more ergonomic. -// -// This function will correctly utilize ignores and requireds from an existing -// manifest, if one is present, but will also do the right thing without a -// manifest. -func (p *Project) GetDirectDependencyNames(sm gps.SourceManager) (pkgtree.PackageTree, map[gps.ProjectRoot]bool, error) { - ptree, err := p.ParseRootPackageTree() - if err != nil { - return pkgtree.PackageTree{}, nil, err - } - - var ig *pkgtree.IgnoredRuleset - var req map[string]bool - if p.Manifest != nil { - ig = p.Manifest.IgnoredPackages() - req = p.Manifest.RequiredPackages() - } - - rm, _ := ptree.ToReachMap(true, true, false, ig) - reach := rm.FlattenFn(paths.IsStandardImportPath) - - if len(req) > 0 { - // Make a map of imports that are both in the import path list and the - // required list to avoid duplication. - skip := make(map[string]bool, len(req)) - for _, r := range reach { - if req[r] { - skip[r] = true - } - } - - for r := range req { - if !skip[r] { - reach = append(reach, r) - } - } - } - - directDeps := map[gps.ProjectRoot]bool{} - for _, ip := range reach { - pr, err := sm.DeduceProjectRoot(ip) - if err != nil { - return pkgtree.PackageTree{}, nil, err - } - directDeps[pr] = true - } - - return ptree, directDeps, nil -} - -// FindIneffectualConstraints looks for constraint rules expressed in the -// manifest that will have no effect during solving, as they are specified for -// projects that are not direct dependencies of the Project. -// -// "Direct dependency" here is as implemented by GetDirectDependencyNames(); -// it correctly incorporates all "ignored" and "required" rules. -func (p *Project) FindIneffectualConstraints(sm gps.SourceManager) []gps.ProjectRoot { - if p.Manifest == nil { - return nil - } - - _, dd, err := p.GetDirectDependencyNames(sm) - if err != nil { - return nil - } - - var ineff []gps.ProjectRoot - for pr := range p.Manifest.DependencyConstraints() { - if !dd[pr] { - ineff = append(ineff, pr) - } - } - - sort.Slice(ineff, func(i, j int) bool { - return ineff[i] < ineff[j] - }) - return ineff -} - -// BackupVendor looks for existing vendor directory and if it's not empty, -// creates a backup of it to a new directory with the provided suffix. -func BackupVendor(vpath, suffix string) (string, error) { - // Check if there's a non-empty vendor directory - vendorExists, err := fs.IsNonEmptyDir(vpath) - if err != nil && !os.IsNotExist(err) { - return "", err - } - if vendorExists { - // vpath is a full filepath. We need to split it to prefix the backup dir - // with an "_" - vpathDir, name := filepath.Split(vpath) - vendorbak := filepath.Join(vpathDir, "_"+name+"-"+suffix) - // Check if a directory with same name exists - if _, err = os.Stat(vendorbak); os.IsNotExist(err) { - // Copy existing vendor to vendor-{suffix} - if err := fs.CopyDir(vpath, vendorbak); err != nil { - return "", err - } - return vendorbak, nil - } - return "", errVendorBackupFailed - } - - return "", nil -} diff --git a/vendor/github.com/golang/dep/testdata/analyzer/Gopkg.toml b/vendor/github.com/golang/dep/testdata/analyzer/Gopkg.toml deleted file mode 100644 index a86104fe527bd533a1dc1d0bf7e14f081fce9b8f..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/analyzer/Gopkg.toml +++ /dev/null @@ -1,8 +0,0 @@ - -[[constraint]] - name = "github.com/golang/dep" - version = ">=0.12.0, <1.0.0" - -[[constraint]] - name = "github.com/pkg/errors" - version = ">=0.8.0, <1.0.0" diff --git a/vendor/github.com/golang/dep/testdata/lock/error0.toml b/vendor/github.com/golang/dep/testdata/lock/error0.toml deleted file mode 100644 index 80eb22b1be18500fcc927d7ba05c544382aa1ac6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/lock/error0.toml +++ /dev/null @@ -1,9 +0,0 @@ -[solve-meta] - inputs-digest = "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" - -[[projects]] - name = "github.com/golang/dep" - branch = "master" - version = "v0.12.0" - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - packages = ["."] diff --git a/vendor/github.com/golang/dep/testdata/lock/error1.toml b/vendor/github.com/golang/dep/testdata/lock/error1.toml deleted file mode 100644 index 2d83237fc946824116182393da7bf3f8d41d5812..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/lock/error1.toml +++ /dev/null @@ -1,8 +0,0 @@ -[[projects]] - name = "github.com/golang/dep" - branch = "master" - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - packages = ["."] - -[solve-meta] - inputs-digest = "000aaa2a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" diff --git a/vendor/github.com/golang/dep/testdata/lock/error2.toml b/vendor/github.com/golang/dep/testdata/lock/error2.toml deleted file mode 100644 index f692f4d976eb9b143bf4294c1ea76875adc97bda..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/lock/error2.toml +++ /dev/null @@ -1,6 +0,0 @@ -[[projects]] - name = "github.com/golang/dep" - packages = ["."] - -[solve-meta] - inputs-digest = "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" diff --git a/vendor/github.com/golang/dep/testdata/lock/golden0.toml b/vendor/github.com/golang/dep/testdata/lock/golden0.toml deleted file mode 100644 index 2ba4a82d5d76d5cb497fda06d703145e0c8be033..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/lock/golden0.toml +++ /dev/null @@ -1,13 +0,0 @@ - -[[projects]] - branch = "master" - name = "github.com/golang/dep" - packages = ["."] - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - -[solve-meta] - analyzer-name = "" - analyzer-version = 0 - inputs-digest = "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" - solver-name = "" - solver-version = 0 diff --git a/vendor/github.com/golang/dep/testdata/lock/golden1.toml b/vendor/github.com/golang/dep/testdata/lock/golden1.toml deleted file mode 100644 index 1a0e183a476ac78a24b32c40d35636149696095c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/lock/golden1.toml +++ /dev/null @@ -1,13 +0,0 @@ - -[[projects]] - name = "github.com/golang/dep" - packages = ["."] - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - version = "0.12.2" - -[solve-meta] - analyzer-name = "" - analyzer-version = 0 - inputs-digest = "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" - solver-name = "" - solver-version = 0 diff --git a/vendor/github.com/golang/dep/testdata/manifest/error1.toml b/vendor/github.com/golang/dep/testdata/manifest/error1.toml deleted file mode 100644 index fddf02a2b0a3461e8df27430b080f6814fc1de2e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/manifest/error1.toml +++ /dev/null @@ -1,15 +0,0 @@ -ignored = ["github.com/foo/bar"] - -[[constraint]] - name = "github.com/golang/dep" - branch = "master" - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - version = "^v0.12.0" - source = "https://github.com/golang/dep" - -[[override]] - name = "github.com/golang/dep" - branch = "master" - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - version = "^v0.12.0" - source = "https://github.com/golang/dep" diff --git a/vendor/github.com/golang/dep/testdata/manifest/error2.toml b/vendor/github.com/golang/dep/testdata/manifest/error2.toml deleted file mode 100644 index 6b1408362d991a377ffdaec5fb691160441744b6..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/manifest/error2.toml +++ /dev/null @@ -1,9 +0,0 @@ -ignored = ["github.com/foo/bar"] - -[[constraint]] - name = "github.com/golang/dep" - branch = "master" - -[[constraint]] - name = "github.com/golang/dep" - branch = "master" diff --git a/vendor/github.com/golang/dep/testdata/manifest/error3.toml b/vendor/github.com/golang/dep/testdata/manifest/error3.toml deleted file mode 100644 index 4d96624be0477467e72417281cc451100ea293ed..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/manifest/error3.toml +++ /dev/null @@ -1,9 +0,0 @@ -ignored = ["github.com/foo/bar"] - -[[override]] - name = "github.com/golang/dep" - branch = "master" - -[[override]] - name = "github.com/golang/dep" - branch = "master" diff --git a/vendor/github.com/golang/dep/testdata/manifest/golden.toml b/vendor/github.com/golang/dep/testdata/manifest/golden.toml deleted file mode 100644 index 62af53fabb75f18b27423c85a3ad4f6e637cc87c..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/manifest/golden.toml +++ /dev/null @@ -1,17 +0,0 @@ -ignored = ["github.com/foo/bar"] - -[[constraint]] - name = "github.com/babble/brook" - revision = "d05d5aca9f895d19e9265839bffeadd74a2d2ecb" - -[[constraint]] - name = "github.com/golang/dep" - version = "0.12.0" - -[[override]] - branch = "master" - name = "github.com/golang/dep" - source = "https://github.com/golang/dep" - -[prune] - non-go = true diff --git a/vendor/github.com/golang/dep/testdata/rootfind/Gopkg.toml b/vendor/github.com/golang/dep/testdata/rootfind/Gopkg.toml deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/testdata/rootfind/subdir/.gitkeep b/vendor/github.com/golang/dep/testdata/rootfind/subdir/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/badinput_fileroot b/vendor/github.com/golang/dep/testdata/txn_writer/badinput_fileroot deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/expected_diff_output.txt b/vendor/github.com/golang/dep/testdata/txn_writer/expected_diff_output.txt deleted file mode 100644 index bbfe78f82bc727b0324de22864d552c0eaecb0ea..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/txn_writer/expected_diff_output.txt +++ /dev/null @@ -1,31 +0,0 @@ -Memo: 595716d270828e763c811ef79c9c41f85b1d1bfbdfe85280036405c03772206c -> 2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e - -Add: -[[projects]] - name = "github.com/sdboyer/deptest" - packages = ["."] - revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf" - version = "v1.0.0" - -[[projects]] - name = "github.com/stuff/realthing" - packages = ["."] - revision = "1f02e52d6bac308da54ab84a234c58a98ca82347" - version = "2.0.0" - -Remove: -[[projects]] - name = "github.com/stuff/placeholder" - packages = ["."] - revision = "6694017eeb4e20fd277b049bf29dba4895c97234" - version = "2.0.0" - -Modify: -[[projects]] - branch = "- master" - name = "github.com/foo/bar" - packages = ["- placeholder","+ thing"] - revision = "f24338400f072ef18125ae0fbe6b06fe6d1783e7 -> 2a3a211e171803acb82d1d5d42ceb53228f51751" - source = "+ http://github.example.com/foo/bar" - version = "+ 1.2.0" - diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/expected_lock.toml b/vendor/github.com/golang/dep/testdata/txn_writer/expected_lock.toml deleted file mode 100644 index 8c9310fd3be27f28c5036ae2883ab8b26e419be9..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/txn_writer/expected_lock.toml +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/sdboyer/dep-test" - packages = ["."] - revision = "2a3a211e171803acb82d1d5d42ceb53228f51751" - version = "1.0.0" - -[solve-meta] - analyzer-name = "" - analyzer-version = 0 - inputs-digest = "595716d270828e763c811ef79c9c41f85b1d1bfbdfe85280036405c03772206c" - solver-name = "" - solver-version = 0 diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/expected_manifest.toml b/vendor/github.com/golang/dep/testdata/txn_writer/expected_manifest.toml deleted file mode 100644 index bf8ef54e1a10680aa529cef3f0d90ad3aaf7e99e..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/txn_writer/expected_manifest.toml +++ /dev/null @@ -1,30 +0,0 @@ -# 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" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/sdboyer/dep-test" - version = "1.0.0" diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/original_lock.toml b/vendor/github.com/golang/dep/testdata/txn_writer/original_lock.toml deleted file mode 100644 index 26510648739134d6f05e212c6a1b1166508303a8..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/txn_writer/original_lock.toml +++ /dev/null @@ -1,14 +0,0 @@ -[solve-meta] - inputs-digest = "595716d270828e763c811ef79c9c41f85b1d1bfbdfe85280036405c03772206c" - -[[projects]] - name = "github.com/foo/bar" - branch = "master" - revision = "f24338400f072ef18125ae0fbe6b06fe6d1783e7" - packages = ["placeholder", "util"] - -[[projects]] - name = "github.com/stuff/placeholder" - version = "2.0.0" - revision = "6694017eeb4e20fd277b049bf29dba4895c97234" - packages = ["."] diff --git a/vendor/github.com/golang/dep/testdata/txn_writer/updated_lock.toml b/vendor/github.com/golang/dep/testdata/txn_writer/updated_lock.toml deleted file mode 100644 index 81ae83ba349a804edcc56c49f68ed29d1488cbaf..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/testdata/txn_writer/updated_lock.toml +++ /dev/null @@ -1,21 +0,0 @@ -[solve-meta] - inputs-digest = "2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e" - -[[projects]] - name = "github.com/foo/bar" - source = "http://github.example.com/foo/bar" - version = "1.2.0" - revision = "2a3a211e171803acb82d1d5d42ceb53228f51751" - packages = ["thing","util"] - -[[projects]] - name = "github.com/stuff/realthing" - version = "2.0.0" - revision = "1f02e52d6bac308da54ab84a234c58a98ca82347" - packages = ["."] - -[[projects]] - name = "github.com/sdboyer/deptest" - packages = ["."] - revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf" - version = "v1.0.0" diff --git a/vendor/github.com/golang/dep/txn_writer.go b/vendor/github.com/golang/dep/txn_writer.go deleted file mode 100644 index 0cb19706b700a1a71f2fdc8443ae8d2896e15ade..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/txn_writer.go +++ /dev/null @@ -1,481 +0,0 @@ -// 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 dep - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - - "github.com/golang/dep/gps" - "github.com/golang/dep/internal/fs" - "github.com/pelletier/go-toml" - "github.com/pkg/errors" -) - -// Example string to be written to the manifest file -// if no dependencies are found in the project -// during `dep init` -var exampleTOML = []byte(`# 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" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - -`) - -// String added on top of lock file -var lockFileComment = []byte(`# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - -`) - -// SafeWriter transactionalizes writes of manifest, lock, and vendor dir, both -// individually and in any combination, into a pseudo-atomic action with -// transactional rollback. -// -// It is not impervious to errors (writing to disk is hard), but it should -// guard against non-arcane failure conditions. -type SafeWriter struct { - Manifest *Manifest - lock *Lock - lockDiff *gps.LockDiff - writeVendor bool - writeLock bool - pruneOptions gps.CascadingPruneOptions -} - -// NewSafeWriter sets up a SafeWriter to write a set of manifest, lock, and -// vendor tree. -// -// - If manifest is provided, it will be written to the standard manifest file -// name beneath root. -// -// - If newLock is provided, it will be written to the standard lock file -// name beneath root. -// -// - If vendor is VendorAlways, or is VendorOnChanged and the locks are different, -// the vendor directory will be written beneath root based on newLock. -// -// - If oldLock is provided without newLock, error. -// -// - If vendor is VendorAlways without a newLock, error. -func NewSafeWriter(manifest *Manifest, oldLock, newLock *Lock, vendor VendorBehavior, prune gps.CascadingPruneOptions) (*SafeWriter, error) { - sw := &SafeWriter{ - Manifest: manifest, - lock: newLock, - pruneOptions: prune, - } - - if oldLock != nil { - if newLock == nil { - return nil, errors.New("must provide newLock when oldLock is specified") - } - - sw.lockDiff = gps.DiffLocks(oldLock, newLock) - if sw.lockDiff != nil { - sw.writeLock = true - } - } else if newLock != nil { - sw.writeLock = true - } - - switch vendor { - case VendorAlways: - sw.writeVendor = true - case VendorOnChanged: - sw.writeVendor = sw.lockDiff != nil || (newLock != nil && oldLock == nil) - } - - if sw.writeVendor && newLock == nil { - return nil, errors.New("must provide newLock in order to write out vendor") - } - - return sw, nil -} - -// HasLock checks if a Lock is present in the SafeWriter -func (sw *SafeWriter) HasLock() bool { - return sw.lock != nil -} - -// HasManifest checks if a Manifest is present in the SafeWriter -func (sw *SafeWriter) HasManifest() bool { - return sw.Manifest != nil -} - -type rawStringDiff struct { - *gps.StringDiff -} - -// MarshalTOML serializes the diff as a string. -func (diff rawStringDiff) MarshalTOML() ([]byte, error) { - return []byte(diff.String()), nil -} - -type rawLockedProjectDiff struct { - Name gps.ProjectRoot `toml:"name"` - Source *rawStringDiff `toml:"source,omitempty"` - Version *rawStringDiff `toml:"version,omitempty"` - Branch *rawStringDiff `toml:"branch,omitempty"` - Revision *rawStringDiff `toml:"revision,omitempty"` - Packages []rawStringDiff `toml:"packages,omitempty"` -} - -func toRawLockedProjectDiff(diff gps.LockedProjectDiff) rawLockedProjectDiff { - // this is a shallow copy since we aren't modifying the raw diff - raw := rawLockedProjectDiff{Name: diff.Name} - if diff.Source != nil { - raw.Source = &rawStringDiff{diff.Source} - } - if diff.Version != nil { - raw.Version = &rawStringDiff{diff.Version} - } - if diff.Branch != nil { - raw.Branch = &rawStringDiff{diff.Branch} - } - if diff.Revision != nil { - raw.Revision = &rawStringDiff{diff.Revision} - } - raw.Packages = make([]rawStringDiff, len(diff.Packages)) - for i := 0; i < len(diff.Packages); i++ { - raw.Packages[i] = rawStringDiff{&diff.Packages[i]} - } - return raw -} - -type rawLockedProjectDiffs struct { - Projects []rawLockedProjectDiff `toml:"projects"` -} - -func toRawLockedProjectDiffs(diffs []gps.LockedProjectDiff) rawLockedProjectDiffs { - raw := rawLockedProjectDiffs{ - Projects: make([]rawLockedProjectDiff, len(diffs)), - } - - for i := 0; i < len(diffs); i++ { - raw.Projects[i] = toRawLockedProjectDiff(diffs[i]) - } - - return raw -} - -func formatLockDiff(diff gps.LockDiff) (string, error) { - var buf bytes.Buffer - - if diff.HashDiff != nil { - buf.WriteString(fmt.Sprintf("Memo: %s\n\n", diff.HashDiff)) - } - - writeDiffs := func(diffs []gps.LockedProjectDiff) error { - raw := toRawLockedProjectDiffs(diffs) - chunk, err := toml.Marshal(raw) - if err != nil { - return err - } - buf.Write(chunk) - buf.WriteString("\n") - return nil - } - - if len(diff.Add) > 0 { - buf.WriteString("Add:") - err := writeDiffs(diff.Add) - if err != nil { - return "", errors.Wrap(err, "Unable to format LockDiff.Add") - } - } - - if len(diff.Remove) > 0 { - buf.WriteString("Remove:") - err := writeDiffs(diff.Remove) - if err != nil { - return "", errors.Wrap(err, "Unable to format LockDiff.Remove") - } - } - - if len(diff.Modify) > 0 { - buf.WriteString("Modify:") - err := writeDiffs(diff.Modify) - if err != nil { - return "", errors.Wrap(err, "Unable to format LockDiff.Modify") - } - } - - return buf.String(), nil -} - -// VendorBehavior defines when the vendor directory should be written. -type VendorBehavior int - -const ( - // VendorOnChanged indicates that the vendor directory should be written when the lock is new or changed. - VendorOnChanged VendorBehavior = iota - // VendorAlways forces the vendor directory to always be written. - VendorAlways - // VendorNever indicates the vendor directory should never be written. - VendorNever -) - -func (sw SafeWriter) validate(root string, sm gps.SourceManager) error { - if root == "" { - return errors.New("root path must be non-empty") - } - if is, err := fs.IsDir(root); !is { - if err != nil && !os.IsNotExist(err) { - return err - } - return errors.Errorf("root path %q does not exist", root) - } - - if sw.writeVendor && sm == nil { - return errors.New("must provide a SourceManager if writing out a vendor dir") - } - - return nil -} - -// Write saves some combination of config yaml, lock, and a vendor tree. -// root is the absolute path of root dir in which to write. -// sm is only required if vendor is being written. -// -// It first writes to a temp dir, then moves them in place if and only if all the write -// operations succeeded. It also does its best to roll back if any moves fail. -// This mostly guarantees that dep cannot exit with a partial write that would -// leave an undefined state on disk. -func (sw *SafeWriter) Write(root string, sm gps.SourceManager, examples bool, logger *log.Logger) error { - err := sw.validate(root, sm) - if err != nil { - return err - } - - if !sw.HasManifest() && !sw.writeLock && !sw.writeVendor { - // nothing to do - return nil - } - - mpath := filepath.Join(root, ManifestName) - lpath := filepath.Join(root, LockName) - vpath := filepath.Join(root, "vendor") - - td, err := ioutil.TempDir(os.TempDir(), "dep") - if err != nil { - return errors.Wrap(err, "error while creating temp dir for writing manifest/lock/vendor") - } - defer os.RemoveAll(td) - - if sw.HasManifest() { - // Always write the example text to the bottom of the TOML file. - tb, err := sw.Manifest.MarshalTOML() - if err != nil { - return errors.Wrap(err, "failed to marshal manifest to TOML") - } - - var initOutput []byte - - // If examples are enabled, use the example text - if examples { - initOutput = exampleTOML - } - - if err = ioutil.WriteFile(filepath.Join(td, ManifestName), append(initOutput, tb...), 0666); err != nil { - return errors.Wrap(err, "failed to write manifest file to temp dir") - } - } - - if sw.writeLock { - l, err := sw.lock.MarshalTOML() - if err != nil { - return errors.Wrap(err, "failed to marshal lock to TOML") - } - - if err = ioutil.WriteFile(filepath.Join(td, LockName), append(lockFileComment, l...), 0666); err != nil { - return errors.Wrap(err, "failed to write lock file to temp dir") - } - } - - if sw.writeVendor { - err = gps.WriteDepTree(filepath.Join(td, "vendor"), sw.lock, sm, sw.pruneOptions, logger) - if err != nil { - return errors.Wrap(err, "error while writing out vendor tree") - } - } - - // Ensure vendor/.git is preserved if present - if hasDotGit(vpath) { - err = fs.RenameWithFallback(filepath.Join(vpath, ".git"), filepath.Join(td, "vendor/.git")) - if _, ok := err.(*os.LinkError); ok { - return errors.Wrap(err, "failed to preserve vendor/.git") - } - } - - // Move the existing files and dirs to the temp dir while we put the new - // ones in, to provide insurance against errors for as long as possible. - type pathpair struct { - from, to string - } - var restore []pathpair - var failerr error - var vendorbak string - - if sw.HasManifest() { - if _, err := os.Stat(mpath); err == nil { - // Move out the old one. - tmploc := filepath.Join(td, ManifestName+".orig") - failerr = fs.RenameWithFallback(mpath, tmploc) - if failerr != nil { - goto fail - } - restore = append(restore, pathpair{from: tmploc, to: mpath}) - } - - // Move in the new one. - failerr = fs.RenameWithFallback(filepath.Join(td, ManifestName), mpath) - if failerr != nil { - goto fail - } - } - - if sw.writeLock { - if _, err := os.Stat(lpath); err == nil { - // Move out the old one. - tmploc := filepath.Join(td, LockName+".orig") - - failerr = fs.RenameWithFallback(lpath, tmploc) - if failerr != nil { - goto fail - } - restore = append(restore, pathpair{from: tmploc, to: lpath}) - } - - // Move in the new one. - failerr = fs.RenameWithFallback(filepath.Join(td, LockName), lpath) - if failerr != nil { - goto fail - } - } - - if sw.writeVendor { - if _, err := os.Stat(vpath); err == nil { - // Move out the old vendor dir. just do it into an adjacent dir, to - // try to mitigate the possibility of a pointless cross-filesystem - // move with a temp directory. - vendorbak = vpath + ".orig" - if _, err := os.Stat(vendorbak); err == nil { - // If the adjacent dir already exists, bite the bullet and move - // to a proper tempdir. - vendorbak = filepath.Join(td, ".vendor.orig") - } - - failerr = fs.RenameWithFallback(vpath, vendorbak) - if failerr != nil { - goto fail - } - restore = append(restore, pathpair{from: vendorbak, to: vpath}) - } - - // Move in the new one. - failerr = fs.RenameWithFallback(filepath.Join(td, "vendor"), vpath) - if failerr != nil { - goto fail - } - } - - // Renames all went smoothly. The deferred os.RemoveAll will get the temp - // dir, but if we wrote vendor, we have to clean that up directly - if sw.writeVendor { - // Nothing we can really do about an error at this point, so ignore it - os.RemoveAll(vendorbak) - } - - return nil - -fail: - // If we failed at any point, move all the things back into place, then bail. - for _, pair := range restore { - // Nothing we can do on err here, as we're already in recovery mode. - fs.RenameWithFallback(pair.from, pair.to) - } - return failerr -} - -// PrintPreparedActions logs the actions a call to Write would perform. -func (sw *SafeWriter) PrintPreparedActions(output *log.Logger, verbose bool) error { - if sw.HasManifest() { - if verbose { - m, err := sw.Manifest.MarshalTOML() - if err != nil { - return errors.Wrap(err, "ensure DryRun cannot serialize manifest") - } - output.Printf("Would have written the following %s:\n%s\n", ManifestName, string(m)) - } else { - output.Printf("Would have written %s.\n", ManifestName) - } - } - - if sw.writeLock { - if sw.lockDiff == nil { - if verbose { - l, err := sw.lock.MarshalTOML() - if err != nil { - return errors.Wrap(err, "ensure DryRun cannot serialize lock") - } - output.Printf("Would have written the following %s:\n%s\n", LockName, string(l)) - } else { - output.Printf("Would have written %s.\n", LockName) - } - } else { - output.Printf("Would have written the following changes to %s:\n", LockName) - diff, err := formatLockDiff(*sw.lockDiff) - if err != nil { - return errors.Wrap(err, "ensure DryRun cannot serialize the lock diff") - } - output.Println(diff) - } - } - - if sw.writeVendor { - if verbose { - output.Printf("Would have written the following %d projects to the vendor directory:\n", len(sw.lock.Projects())) - lps := sw.lock.Projects() - for i, p := range lps { - output.Printf("(%d/%d) %s@%s\n", i+1, len(lps), p.Ident(), p.Version()) - } - } else { - output.Printf("Would have written %d projects to the vendor directory.\n", len(sw.lock.Projects())) - } - } - - return nil -} - -// hasDotGit checks if a given path has .git file or directory in it. -func hasDotGit(path string) bool { - gitfilepath := filepath.Join(path, ".git") - _, err := os.Stat(gitfilepath) - return err == nil -} diff --git a/vendor/github.com/golang/dep/website/.gitignore b/vendor/github.com/golang/dep/website/.gitignore deleted file mode 100644 index aeedda9bfc3141bee6950e0d73e5b4daf636e6f2..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -node_modules -.DS_Store -lib/core/metadata.js -lib/core/MetadataBlog.js -website/translated_docs -website/build/ -website/yarn.lock -website/node_modules - -website/i18n/* -!website/i18n/en.json diff --git a/vendor/github.com/golang/dep/website/blog/2018-01-23-announce-v0.4.0.md b/vendor/github.com/golang/dep/website/blog/2018-01-23-announce-v0.4.0.md deleted file mode 100644 index bf431031f50224b0503678cc927ff07a59da1464..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/blog/2018-01-23-announce-v0.4.0.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Announcing dep v0.4.0 (with docs!) -author: sam boyer -authorURL: http://twitter.com/sdboyer ---- - -v0.4.0 of dep [has been released](https://github.com/golang/dep/releases/tag/v0.4.0) - and along with it, this site for documentation and announcements about dep! And, being that it's been nearly six months since [the last dep status update](https://sdboyer.io/dep-status/2017-08-17/) (which are now officially discontinued, in favor of this blog), and the roadmap hasn't been substantially updated in even longer, we'll use this release as an excuse to bring a bunch of things up to speed. - -_Note: there was [a significant omission](https://github.com/golang/dep/issues/1561) in v0.4.0's new pruning behavior, so we immediately shipped v0.4.1 with a fix._ - -### A new dep release! - -After three months of work, the next version of dep is stable and ready for public use. The big headline changes are: - -* `dep prune` no longer exists as a separate command. It has been absorbed into `dep ensure`, and its behavior can now be more granularly controlled by [directives in `Gopkg.toml`](https://golang.github.io/dep/docs/Gopkg.toml.html#prune). Calls to `dep prune` will not fail now, but will in future versions, so update your scripts! -* Support for govendor and glock have been added; `dep init` can now read their metadata files and attempt to automatically convert projects managed by those tools. - -Additional information is available in [the release notes](https://github.com/golang/dep/releases/tag/v0.4.0). The other major addition is this documentation site! - -### Docs docs docs - -Dep has had a documentation problem for a while. Having a single-command interface helped us get by with having only an FAQ, but as time wore on, it became increasingly clear that we needed a comprehensive set of documentation if people were to really feel comfortable with the tool. - -This site, which is automatically generated from the [docs directory](https://github.com/golang/dep/tree/master/docs) within the dep repository by [docusaurus](http://docusaurus.io/), is now that comprehensive source of docs. More so than any individual bit of information, it provides some broader benefits: - -* New user guides - reference documentation is not what folks need when starting with a new tool. Step-by-step instructions are. Now [we have that](https://golang.github.io/dep/docs/introduction.html), and it caters to users who are not only new to dep, but also to Go in general. -* Thematic organization of content - up until now, we were somewhat haphazardly flinging information into the FAQ. The body of documentation here is organized from the ground up, which will hopefully make it both more useful and easier to maintain. -* Versioning - docusaurus is capable of snapshotting doc versions on each release, and users will be able to select the version of the docs they want to view (though we've not enabled this just quite yet). Ideally, everyone should always be able to use the latest version, but this at least means you're not penalized if that's not feasible for you/your organization. -* A blog - you're reading it! This is great, as it provides us a canonical place to circulate information about what's happening with the project. - -At the same time, the docs aren't quite comprehensive _yet_. There's more reference material and guides to be written. For example, we're still missing a guide for project maintainers on how to make releases that align well with dep's happy path. - -Also, now that we have this whole docs apparatus, it would be particularly awesome if someone were to step up to help as a [docs maintainer](https://github.com/golang/dep/issues/629#issuecomment-359922251)! (Also also, the CSS on this site is terrible, [please halp](https://github.com/golang/dep/issues/1558)!) - -### The future - -Right now, there's two aspects to the future of dep. One is the roadmap of changes and features that make sense for dep as it exists today, in this standalone context. The other is the roadmap for moving dep into the toolchain. - -For the former, we have a fair bit of work underway that, now that this release is out the door, we can move on quickly. That includes major performance improvements, solver improvements to pick a sane version more of the time with less manual intervention, allowing the `source` field to work the way [most people expect it to](https://github.com/golang/dep/issues/860), and others. The goal is also to move dep towards a more regular release schedule. - -With respect to dep's movement towards the toolchain, discussions have already been ongoing between dep folks and the Go team for months. Movement into the toolchain is not a simple process. Some rules that dep, as a standalone tool, had to accept as law, become negotiable (for example, the semantics of vendor directories). There's also the question of how to best fit dep's commands themselves into the `go` tool. These present both interesting design opportunities and considerable risk. More information and opportunities for comment will be coming as we move into the Go 1.10 cycle. As has always been the plan, though, dep will continue to exist as a standalone tool until the toolchain has evolved sufficiently to supplant it. \ No newline at end of file diff --git a/vendor/github.com/golang/dep/website/core/Footer.js b/vendor/github.com/golang/dep/website/core/Footer.js deleted file mode 100644 index 98956ad5ec7d09c4081ba293906a7e9fde70b663..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/core/Footer.js +++ /dev/null @@ -1,29 +0,0 @@ -const React = require('react'); - -const siteConfig = require(process.cwd() + '/siteConfig.js'); - -class Footer extends React.Component { - render() { - const currentYear = new Date().getFullYear(); - return ( - <footer className="nav-footer" id="footer"> - <section className="copyright"> - {siteConfig.copyright} - </section> - <section className="footer-logo"> - <a href={this.props.config.baseUrl} className="nav-home"> - {this.props.config.footerIcon && ( - <img - src={this.props.config.baseUrl + this.props.config.footerIcon} - alt={this.props.config.title} - width="75" - /> - )} - </a> - </section> - </footer> - ); - } -} - -module.exports = Footer; diff --git a/vendor/github.com/golang/dep/website/i18n/en.json b/vendor/github.com/golang/dep/website/i18n/en.json deleted file mode 100644 index caf77a3dbafcd1c6bf7ce1dc504f5b4a4b4a4c02..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/i18n/en.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "_comment": "This file is auto-generated by write-translations.js", - "localized-strings": { - "next": "Next", - "previous": "Previous", - "tagline": "Dependency management for Go", - "daily-dep": "Daily Dep", - "deduction": "Import Path Deduction", - "ensure-mechanics": "Models and Mechanisms", - "failure-modes": "Failure Modes", - "FAQ": "FAQ", - "glossary": "Glossary", - "Gopkg.lock": "Gopkg.lock", - "Gopkg.toml": "Gopkg.toml", - "installation": "Installation", - "introduction": "Getting Started", - "migrating": "Migrating to Dep", - "new-project": "Creating a New Project", - "the-solver": "The Solver", - "Documentation": "Documentation", - "Blog": "Blog", - "Guides": "Guides", - "References": "References" - }, - "pages-strings": { - "Help Translate|recruit community translators for your project": "Help Translate", - "Edit this Doc|recruitment message asking to edit the doc source": "Edit", - "Translate this Doc|recruitment message asking to translate the docs": "Translate" - } -} diff --git a/vendor/github.com/golang/dep/website/package.json b/vendor/github.com/golang/dep/website/package.json deleted file mode 100644 index ec2e7d746004d6c26958890a8a06958121b380ac..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "scripts": { - "examples": "docusaurus-examples", - "start": "docusaurus-start", - "build": "docusaurus-build", - "publish-gh-pages": "docusaurus-publish", - "write-translations": "docusaurus-write-translations", - "version": "docusaurus-version", - "rename-version": "docusaurus-rename-version" - }, - "devDependencies": { - "docusaurus": "^1.0.5" - } -} diff --git a/vendor/github.com/golang/dep/website/pages/en/help.js b/vendor/github.com/golang/dep/website/pages/en/help.js deleted file mode 100755 index 0a63c19e4990832652c8204501b947e8f852564d..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/pages/en/help.js +++ /dev/null @@ -1,43 +0,0 @@ -const React = require('react'); - -const CompLibrary = require('../../core/CompLibrary.js'); -const Container = CompLibrary.Container; -const GridBlock = CompLibrary.GridBlock; - -const siteConfig = require(process.cwd() + '/siteConfig.js'); - -class Help extends React.Component { - render() { - const supportLinks = [ - { - content: - 'Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)', - title: 'Browse Docs', - }, - { - content: 'Ask questions about the documentation and project', - title: 'Join the community', - }, - { - content: "Find out what's new with this project", - title: 'Stay up to date', - }, - ]; - - return ( - <div className="docMainWrapper wrapper"> - <Container className="mainContainer documentContainer postContainer"> - <div className="post"> - <header className="postHeader"> - <h2>Need help?</h2> - </header> - <p>This project is maintained by a dedicated group of people.</p> - <GridBlock contents={supportLinks} layout="threeColumn" /> - </div> - </Container> - </div> - ); - } -} - -module.exports = Help; diff --git a/vendor/github.com/golang/dep/website/pages/en/index.js b/vendor/github.com/golang/dep/website/pages/en/index.js deleted file mode 100755 index 11437ae9af57df47902e9d0fd1564018fce54cff..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/pages/en/index.js +++ /dev/null @@ -1,92 +0,0 @@ -const React = require('react'); - -const CompLibrary = require('../../core/CompLibrary.js'); -const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */ -const Container = CompLibrary.Container; -const GridBlock = CompLibrary.GridBlock; - -const siteConfig = require(process.cwd() + '/siteConfig.js'); - -class Button extends React.Component { - render() { - return ( - <div className="pluginWrapper buttonWrapper"> - <a className="button" href={this.props.href} target={this.props.target}> - {this.props.children} - </a> - </div> - ); - } -} - -function assetUrl(img) { - return siteConfig.baseUrl + 'docs/assets/' + img; -} - -function docUrl(doc, language) { - return siteConfig.baseUrl + 'docs/' + (language ? language + '/' : '') + doc; -} - -Button.defaultProps = { - target: '_self', -}; - -const SplashContainer = props => ( - <div className="homeContainer"> - <div className="homeSplashFade"> - <div className="wrapper homeWrapper">{props.children}</div> - </div> - </div> -); - -const Logo = props => ( - <div className="projectLogo"> - <img src={props.img_src} /> - </div> -); - -const ProjectTitle = props => ( - <h2 className="projectTitle"> - {siteConfig.title} - <small>{siteConfig.tagline}</small> - </h2> -); - -const PromoSection = props => ( - <div className="section promoSection"> - <div className="promoRow"> - <div className="pluginRowBlock">{props.children}</div> - </div> - </div> -); - -class HomeSplash extends React.Component { - render() { - let language = this.props.language || ''; - return ( - <SplashContainer> - <Logo img_src={assetUrl('DigbyShadows.svg')} /> - <div className="inner"> - <ProjectTitle /> - <PromoSection> - <Button href={docUrl('introduction.html', language)}>Docs</Button> - <Button href={siteConfig.baseUrl + 'blog'}>Blog</Button> - <Button href='https://github.com/golang/dep'>Code</Button> - </PromoSection> - </div> - </SplashContainer> - ); - } -} - -class Index extends React.Component { - render() { - let language = this.props.language || ''; - - return ( - <HomeSplash language={language} /> - ); - } -} - -module.exports = Index; diff --git a/vendor/github.com/golang/dep/website/pages/en/users.js b/vendor/github.com/golang/dep/website/pages/en/users.js deleted file mode 100644 index b94c4bc6e8c7937e6b28c416580184d002cf32c1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/pages/en/users.js +++ /dev/null @@ -1,40 +0,0 @@ -const React = require('react'); - -const CompLibrary = require('../../core/CompLibrary.js'); -const Container = CompLibrary.Container; - -const siteConfig = require(process.cwd() + '/siteConfig.js'); - -class Users extends React.Component { - render() { - const showcase = siteConfig.users.map((user, i) => { - return ( - <a href={user.infoLink} key={i}> - <img src={user.image} title={user.caption} /> - </a> - ); - }); - - return ( - <div className="mainContainer"> - <Container padding={['bottom', 'top']}> - <div className="showcaseSection"> - <div className="prose"> - <h1>Who's Using This?</h1> - <p>This project is used by many folks</p> - </div> - <div className="logos">{showcase}</div> - <p>Are you using this project?</p> - <a - href="https://github.com/golang/dep/edit/master/website/siteConfig.js" - className="button"> - Add your company - </a> - </div> - </Container> - </div> - ); - } -} - -module.exports = Users; diff --git a/vendor/github.com/golang/dep/website/sidebars.json b/vendor/github.com/golang/dep/website/sidebars.json deleted file mode 100644 index 962d2bc62299bf611f29d99d045b96b4b5a0a3ca..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/sidebars.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "docs": { - "Guides": ["introduction", "installation", "new-project", "migrating", "daily-dep"], - "References": ["ensure-mechanics", "failure-modes", "the-solver", "deduction", "Gopkg.toml", "Gopkg.lock", "FAQ", "glossary"] - } -} diff --git a/vendor/github.com/golang/dep/website/siteConfig.js b/vendor/github.com/golang/dep/website/siteConfig.js deleted file mode 100644 index 41acaecab24d785ec96754c23188642bdc5bf8c1..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/siteConfig.js +++ /dev/null @@ -1,46 +0,0 @@ -/* List of projects/orgs using your project for the users page */ -const users = [ -]; - -const siteConfig = { - title: 'dep' /* title for your website */, - tagline: 'Dependency management for Go', - url: 'https://golang.github.io' /* your website url */, - baseUrl: '/dep/' /* base url for your project */, - editUrl: 'https://github.com/golang/dep/edit/master/docs/', - projectName: 'dep', - headerLinks: [ - {doc: 'introduction', label: 'Documentation'}, - {blog: true, label: 'Blog'}, - ], - users, - /* path to images for header/footer */ - headerIcon: 'docs/assets/DigbyFlat.svg', - footerIcon: 'docs/assets/DigbyShadowsScene2.svg', - favicon: 'docs/assets/DigbyScene2Flat.png', - /* colors for website */ - colors: { - secondaryColor: '#E0EBF5', - primaryColor: '#375EAB', - }, - //algolia: { - //apiKey: "f2e26cf744b3d81c7e57499075753104", - //indexName: "dep-docs" - //}, - // This copyright info is used in /core/Footer.js and blog rss/atom feeds. - copyright: - 'Copyright © ' + - new Date().getFullYear() + - ' The Go Authors', - organizationName: 'golang', // or set an env variable ORGANIZATION_NAME - projectName: 'dep', // or set an env variable PROJECT_NAME - highlight: { - // Highlight.js theme to use for syntax highlighting in code blocks - theme: 'default', - }, - scripts: ['https://buttons.github.io/buttons.js'], - // You may provide arbitrary config keys to be used as needed by your template. - repoUrl: 'https://github.com/golang/dep', -}; - -module.exports = siteConfig; diff --git a/vendor/github.com/golang/dep/website/static/css/custom.css b/vendor/github.com/golang/dep/website/static/css/custom.css deleted file mode 100644 index 097e466ac5abc5e42c7bda89f0c4432c1d3fb3a0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/static/css/custom.css +++ /dev/null @@ -1,52 +0,0 @@ -/* your custom css */ - -.homeContainer { - flex: 1 0 auto; - padding-bottom: 1em; -} - -.docMainWrapper { - flex: 1 0 auto; - padding-bottom: 1em; -} - -.homeContainer .homeWrapper .projectLogo { - justify-content: center; - position: relative; - padding: 2em; -} - -.homeContainer .homeWrapper .projectLogo img { - max-height: 360px; -} - -body { - display: flex; - flex-direction: column; -} - -div.navPusher { - display: flex; - flex-direction: column; -} - -.footer-logo { - padding-top: 1em; - display: flex; - justify-content: center; -} - -@media only screen and (min-device-width: 360px) and (max-device-width: 736px) { -} - -@media only screen and (min-width: 1024px) { -} - -@media only screen and (max-width: 1023px) { -} - -@media only screen and (min-width: 1400px) { -} - -@media only screen and (min-width: 1500px) { -} diff --git a/vendor/github.com/golang/dep/website/yarn.lock b/vendor/github.com/golang/dep/website/yarn.lock deleted file mode 100644 index cb5417d7df6ea8bdba56b1bea2a34cccb00c8ef0..0000000000000000000000000000000000000000 --- a/vendor/github.com/golang/dep/website/yarn.lock +++ /dev/null @@ -1,1739 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -accepts@~1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" - dependencies: - mime-types "~2.1.16" - negotiator "0.6.1" - -ajv@^5.1.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" - dependencies: - color-convert "^1.9.0" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -argparse@~0.1.15: - version "0.1.16" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" - dependencies: - underscore "~1.7.0" - underscore.string "~2.4.0" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -autolinker@~0.15.0: - version "0.15.3" - resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.6" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - esutils "^2.0.2" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-flow@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-display-name@^6.23.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-self@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-source@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" - dependencies: - babel-helper-builder-react-jsx "^6.24.1" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-env@^1.6.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-flow@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" - dependencies: - babel-plugin-transform-flow-strip-types "^6.22.0" - -babel-preset-react@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" - dependencies: - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-react-display-name "^6.23.0" - babel-plugin-transform-react-jsx "^6.24.1" - babel-plugin-transform-react-jsx-self "^6.22.0" - babel-plugin-transform-react-jsx-source "^6.22.0" - babel-preset-flow "^6.23.0" - -babel-register@^6.24.1, babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.25.0, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.17.4, babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -body-parser@1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" - dependencies: - bytes "3.0.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.1" - http-errors "~1.6.2" - iconv-lite "0.4.19" - on-finished "~2.3.0" - qs "6.5.1" - raw-body "2.3.2" - type-is "~1.6.15" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -browserslist@^2.1.2: - version "2.11.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" - dependencies: - caniuse-lite "^1.0.30000792" - electron-to-chromium "^1.3.30" - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - -caniuse-lite@^1.0.30000792: - version "1.0.30000792" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz#d0cea981f8118f3961471afbb43c9a1e5bbf0332" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -classnames@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" - dependencies: - color-name "^1.1.1" - -color-name@^1.0.0, color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - -color-string@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@^2.11.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - -convert-source-map@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -create-react-class@^15.6.0: - version "15.6.2" - resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a" - dependencies: - fbjs "^0.8.9" - loose-envify "^1.3.1" - object-assign "^4.1.1" - -crowdin-cli@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/crowdin-cli/-/crowdin-cli-0.3.0.tgz#eac9989a6fe7feaaf33090397afc187c67b46191" - dependencies: - request "^2.53.0" - yamljs "^0.2.1" - yargs "^2.3.0" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug@0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" - -debug@2.6.9, debug@^2.6.8: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -deep-is@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.2.tgz#9ced65ea0bc0b09f42a6d79c1b1903f9d913cc18" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -depd@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" - -depd@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -docusaurus@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/docusaurus/-/docusaurus-1.0.5.tgz#a2d75690e8dde50987a44cc836d6375b6130c8b7" - dependencies: - babel-preset-env "^1.6.0" - babel-preset-react "^6.24.1" - babel-register "^6.24.1" - babel-traverse "^6.25.0" - babylon "^6.17.4" - chalk "^2.1.0" - classnames "^2.2.5" - color "^2.0.1" - commander "^2.11.0" - crowdin-cli "^0.3.0" - escape-string-regexp "^1.0.5" - express "^4.15.3" - feed "^1.1.0" - fs-extra "^5.0.0" - glob "^7.1.2" - highlight.js "^9.12.0" - react "^15.5.4" - react-dom "^15.5.4" - react-dom-factories "^1.0.1" - remarkable "^1.7.1" - request "^2.81.0" - shelljs "^0.7.8" - sitemap "^1.13.0" - tcp-port-used "^0.1.2" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - -electron-to-chromium@^1.3.30: - version "1.3.31" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz#00d832cba9fe2358652b0c48a8816c8e3a037e9f" - -encodeurl@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - dependencies: - iconv-lite "~0.4.13" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - -escape-string-regexp@^1.0.2, 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" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - -express@^4.15.3: - version "4.16.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" - dependencies: - accepts "~1.3.4" - array-flatten "1.1.1" - body-parser "1.18.2" - content-disposition "0.5.2" - content-type "~1.0.4" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.1" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.1.0" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.2" - path-to-regexp "0.1.7" - proxy-addr "~2.0.2" - qs "6.5.1" - range-parser "~1.2.0" - safe-buffer "5.1.1" - send "0.16.1" - serve-static "1.13.1" - setprototypeof "1.1.0" - statuses "~1.3.1" - type-is "~1.6.15" - utils-merge "1.0.1" - vary "~1.1.2" - -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -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" - -fbjs@^0.8.16, fbjs@^0.8.9: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" - 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.9" - -feed@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/feed/-/feed-1.1.1.tgz#914897517e94fa327cc6f73bb585a47c4a9ed321" - dependencies: - xml "^1.0.1" - -finalhandler@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" - dependencies: - debug "2.6.9" - encodeurl "~1.0.1" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.3.1" - unpipe "~1.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - -fs-extra@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - 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" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -highlight.js@^9.12.0: - version "9.12.0" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -http-errors@1.6.2, http-errors@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" - dependencies: - depd "1.1.1" - inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.19, iconv-lite@~0.4.13: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - -invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -ipaddr.js@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" - -is-arrayish@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is2@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/is2/-/is2-0.0.9.tgz#119556d1d1651a41ba105af803267c80b299f629" - dependencies: - deep-is "0.1.2" - -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -lodash@^4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - 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" - -mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - -node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -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" - -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -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" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - dependencies: - ee-first "1.1.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-tmpdir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -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" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -private@^0.1.6, private@^0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - dependencies: - asap "~2.0.3" - -prop-types@^15.5.10: - version "15.6.0" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" - dependencies: - fbjs "^0.8.16" - loose-envify "^1.3.1" - object-assign "^4.1.1" - -proxy-addr@~2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.5.2" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -q@0.9.7: - version "0.9.7" - resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" - -qs@6.5.1, qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -range-parser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - -raw-body@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" - dependencies: - bytes "3.0.0" - http-errors "1.6.2" - iconv-lite "0.4.19" - unpipe "1.0.0" - -react-dom-factories@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0" - -react-dom@^15.5.4: - version "15.6.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730" - dependencies: - fbjs "^0.8.9" - loose-envify "^1.1.0" - object-assign "^4.1.0" - prop-types "^15.5.10" - -react@^15.5.4: - version "15.6.2" - resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72" - dependencies: - create-react-class "^15.6.0" - fbjs "^0.8.9" - loose-envify "^1.1.0" - object-assign "^4.1.0" - prop-types "^15.5.10" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - -regenerate@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remarkable@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6" - dependencies: - argparse "~0.1.15" - autolinker "~0.15.0" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@^2.53.0, request@^2.81.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -resolve@^1.1.6: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" - dependencies: - path-parse "^1.0.5" - -safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -semver@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - -send@0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" - dependencies: - debug "2.6.9" - depd "~1.1.1" - destroy "~1.0.4" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.3.1" - -serve-static@1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" - dependencies: - encodeurl "~1.0.1" - escape-html "~1.0.3" - parseurl "~1.3.2" - send "0.16.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - -setprototypeof@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - -shelljs@^0.7.8: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - dependencies: - is-arrayish "^0.3.1" - -sitemap@^1.13.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-1.13.0.tgz#569cbe2180202926a62a266cd3de09c9ceb43f83" - dependencies: - underscore "^1.7.0" - url-join "^1.1.0" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -"statuses@>= 1.3.1 < 2": - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - -statuses@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" - -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - -tcp-port-used@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-0.1.2.tgz#9450e8768c83b416fd4d1a6a9449eeccbf496c29" - dependencies: - debug "0.7.4" - is2 "0.0.9" - q "0.9.7" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-is@~1.6.15: - version "1.6.15" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.15" - -ua-parser-js@^0.7.9: - version "0.7.17" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" - -underscore.string@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.4.0.tgz#8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b" - -underscore@^1.7.0: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" - -underscore@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" - -universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - -url-join@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - -uuid@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -whatwg-fetch@>=0.10.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - -yamljs@^0.2.1: - version "0.2.10" - resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.10.tgz#481cc7c25ca73af59f591f0c96e3ce56c757a40f" - dependencies: - argparse "^1.0.7" - glob "^7.0.5" - -yargs@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-2.3.0.tgz#e900c87250ec5cd080db6009fe3dd63156f1d7fb" - dependencies: - wordwrap "0.0.2" diff --git a/vendor/github.com/vishvananda/netlink/.travis.yml b/vendor/github.com/vishvananda/netlink/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..f5c0b3eb5f7fdd76268525668e4df1b806c83708 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/.travis.yml @@ -0,0 +1,13 @@ +language: go +before_script: + # make sure we keep path in tact when we sudo + - sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers + # modprobe ip_gre or else the first gre device can't be deleted + - sudo modprobe ip_gre + # modprobe nf_conntrack for the conntrack testing + - sudo modprobe nf_conntrack + - sudo modprobe nf_conntrack_netlink + - sudo modprobe nf_conntrack_ipv4 + - sudo modprobe nf_conntrack_ipv6 +install: + - go get github.com/vishvananda/netns diff --git a/vendor/github.com/vishvananda/netlink/BUILD.bazel b/vendor/github.com/vishvananda/netlink/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..ec1aa1474279966c7225b21f706226d85e4e1ad1 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/BUILD.bazel @@ -0,0 +1,94 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "addr.go", + "addr_linux.go", + "bpf_linux.go", + "bridge_linux.go", + "class.go", + "class_linux.go", + "conntrack_linux.go", + "conntrack_unspecified.go", + "filter.go", + "filter_linux.go", + "fou.go", + "fou_linux.go", + "fou_unspecified.go", + "genetlink_linux.go", + "genetlink_unspecified.go", + "gtp_linux.go", + "handle_linux.go", + "handle_unspecified.go", + "ioctl_linux.go", + "link.go", + "link_linux.go", + "link_tuntap_linux.go", + "neigh.go", + "neigh_linux.go", + "netlink.go", + "netlink_linux.go", + "netlink_unspecified.go", + "order.go", + "protinfo.go", + "protinfo_linux.go", + "qdisc.go", + "qdisc_linux.go", + "route.go", + "route_linux.go", + "route_unspecified.go", + "rule.go", + "rule_linux.go", + "socket.go", + "socket_linux.go", + "xfrm.go", + "xfrm_monitor_linux.go", + "xfrm_policy.go", + "xfrm_policy_linux.go", + "xfrm_state.go", + "xfrm_state_linux.go", + ], + importmap = "vendor/github.com/vishvananda/netlink", + importpath = "github.com/vishvananda/netlink", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/vishvananda/netlink/nl:go_default_library", + "//vendor/golang.org/x/sys/unix:go_default_library", + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:nacl": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + ], + "//conditions:default": [], + }), +) diff --git a/vendor/github.com/vishvananda/netlink/CHANGELOG.md b/vendor/github.com/vishvananda/netlink/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..b11e59ff6a8094ca88877e47c0a313a73ca6f5a1 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 (2018-03-15) + +Initial release tagging \ No newline at end of file diff --git a/vendor/github.com/vishvananda/netlink/LICENSE b/vendor/github.com/vishvananda/netlink/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..9f64db8582cf97fa23685c44b5f8d8d9630da11b --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/LICENSE @@ -0,0 +1,192 @@ + + 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 + + Copyright 2014 Vishvananda Ishaya. + Copyright 2014 Docker, 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/vishvananda/netlink/Makefile b/vendor/github.com/vishvananda/netlink/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a0e68e7a9aaaacabaee2c01e1384c58de99a746a --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/Makefile @@ -0,0 +1,30 @@ +DIRS := \ + . \ + nl + +DEPS = \ + github.com/vishvananda/netns \ + golang.org/x/sys/unix + +uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) +testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go)))) +goroot = $(addprefix ../../../,$(1)) +unroot = $(subst ../../../,,$(1)) +fmt = $(addprefix fmt-,$(1)) + +all: test + +$(call goroot,$(DEPS)): + go get $(call unroot,$@) + +.PHONY: $(call testdirs,$(DIRS)) +$(call testdirs,$(DIRS)): + go test -test.exec sudo -test.parallel 4 -timeout 60s -test.v github.com/vishvananda/netlink/$@ + +$(call fmt,$(call testdirs,$(DIRS))): + ! gofmt -l $(subst fmt-,,$@)/*.go | grep -q . + +.PHONY: fmt +fmt: $(call fmt,$(call testdirs,$(DIRS))) + +test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS)) diff --git a/vendor/github.com/vishvananda/netlink/README.md b/vendor/github.com/vishvananda/netlink/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a88e2f418409b14878f6777b95202f96a37616e9 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/README.md @@ -0,0 +1,92 @@ +# netlink - netlink library for go # + +[](https://travis-ci.org/vishvananda/netlink) [](https://godoc.org/github.com/vishvananda/netlink) + +The netlink package provides a simple netlink library for go. Netlink +is the interface a user-space program in linux uses to communicate with +the kernel. It can be used to add and remove interfaces, set ip addresses +and routes, and configure ipsec. Netlink communication requires elevated +privileges, so in most cases this code needs to be run as root. Since +low-level netlink messages are inscrutable at best, the library attempts +to provide an api that is loosely modeled on the CLI provided by iproute2. +Actions like `ip link add` will be accomplished via a similarly named +function like AddLink(). This library began its life as a fork of the +netlink functionality in +[docker/libcontainer](https://github.com/docker/libcontainer) but was +heavily rewritten to improve testability, performance, and to add new +functionality like ipsec xfrm handling. + +## Local Build and Test ## + +You can use go get command: + + go get github.com/vishvananda/netlink + +Testing dependencies: + + go get github.com/vishvananda/netns + +Testing (requires root): + + sudo -E go test github.com/vishvananda/netlink + +## Examples ## + +Add a new bridge and add eth1 into it: + +```go +package main + +import ( + "fmt" + "github.com/vishvananda/netlink" +) + +func main() { + la := netlink.NewLinkAttrs() + la.Name = "foo" + mybridge := &netlink.Bridge{LinkAttrs: la} + err := netlink.LinkAdd(mybridge) + if err != nil { + fmt.Printf("could not add %s: %v\n", la.Name, err) + } + eth1, _ := netlink.LinkByName("eth1") + netlink.LinkSetMaster(eth1, mybridge) +} + +``` +Note `NewLinkAttrs` constructor, it sets default values in structure. For now +it sets only `TxQLen` to `-1`, so kernel will set default by itself. If you're +using simple initialization(`LinkAttrs{Name: "foo"}`) `TxQLen` will be set to +`0` unless you specify it like `LinkAttrs{Name: "foo", TxQLen: 1000}`. + +Add a new ip address to loopback: + +```go +package main + +import ( + "github.com/vishvananda/netlink" +) + +func main() { + lo, _ := netlink.LinkByName("lo") + addr, _ := netlink.ParseAddr("169.254.169.254/32") + netlink.AddrAdd(lo, addr) +} + +``` + +## Future Work ## + +Many pieces of netlink are not yet fully supported in the high-level +interface. Aspects of virtually all of the high-level objects don't exist. +Many of the underlying primitives are there, so its a matter of putting +the right fields into the high-level objects and making sure that they +are serialized and deserialized correctly in the Add and List methods. + +There are also a few pieces of low level netlink functionality that still +need to be implemented. Routing rules are not in place and some of the +more advanced link types. Hopefully there is decent structure and testing +in place to make these fairly straightforward to add. + diff --git a/vendor/github.com/vishvananda/netlink/addr.go b/vendor/github.com/vishvananda/netlink/addr.go new file mode 100644 index 0000000000000000000000000000000000000000..f08c956969d33186a5e133398dec2e2ea7873abf --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/addr.go @@ -0,0 +1,56 @@ +package netlink + +import ( + "fmt" + "net" + "strings" +) + +// Addr represents an IP address from netlink. Netlink ip addresses +// include a mask, so it stores the address as a net.IPNet. +type Addr struct { + *net.IPNet + Label string + Flags int + Scope int + Peer *net.IPNet + Broadcast net.IP + PreferedLft int + ValidLft int +} + +// String returns $ip/$netmask $label +func (a Addr) String() string { + return strings.TrimSpace(fmt.Sprintf("%s %s", a.IPNet, a.Label)) +} + +// ParseAddr parses the string representation of an address in the +// form $ip/$netmask $label. The label portion is optional +func ParseAddr(s string) (*Addr, error) { + label := "" + parts := strings.Split(s, " ") + if len(parts) > 1 { + s = parts[0] + label = parts[1] + } + m, err := ParseIPNet(s) + if err != nil { + return nil, err + } + return &Addr{IPNet: m, Label: label}, nil +} + +// Equal returns true if both Addrs have the same net.IPNet value. +func (a Addr) Equal(x Addr) bool { + sizea, _ := a.Mask.Size() + sizeb, _ := x.Mask.Size() + // ignore label for comparison + return a.IP.Equal(x.IP) && sizea == sizeb +} + +func (a Addr) PeerEqual(x Addr) bool { + sizea, _ := a.Peer.Mask.Size() + sizeb, _ := x.Peer.Mask.Size() + // ignore label for comparison + return a.Peer.IP.Equal(x.Peer.IP) && sizea == sizeb +} diff --git a/vendor/github.com/vishvananda/netlink/addr_linux.go b/vendor/github.com/vishvananda/netlink/addr_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..d59c3281ec78459b6651acf76d4f2cf72d77ca25 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/addr_linux.go @@ -0,0 +1,354 @@ +package netlink + +import ( + "fmt" + "net" + "strings" + "syscall" + + "github.com/vishvananda/netlink/nl" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +// IFA_FLAGS is a u32 attribute. +const IFA_FLAGS = 0x8 + +// AddrAdd will add an IP address to a link device. +// Equivalent to: `ip addr add $addr dev $link` +func AddrAdd(link Link, addr *Addr) error { + return pkgHandle.AddrAdd(link, addr) +} + +// AddrAdd will add an IP address to a link device. +// Equivalent to: `ip addr add $addr dev $link` +func (h *Handle) AddrAdd(link Link, addr *Addr) error { + req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + return h.addrHandle(link, addr, req) +} + +// AddrReplace will replace (or, if not present, add) an IP address on a link device. +// Equivalent to: `ip addr replace $addr dev $link` +func AddrReplace(link Link, addr *Addr) error { + return pkgHandle.AddrReplace(link, addr) +} + +// AddrReplace will replace (or, if not present, add) an IP address on a link device. +// Equivalent to: `ip addr replace $addr dev $link` +func (h *Handle) AddrReplace(link Link, addr *Addr) error { + req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK) + return h.addrHandle(link, addr, req) +} + +// AddrDel will delete an IP address from a link device. +// Equivalent to: `ip addr del $addr dev $link` +func AddrDel(link Link, addr *Addr) error { + return pkgHandle.AddrDel(link, addr) +} + +// AddrDel will delete an IP address from a link device. +// Equivalent to: `ip addr del $addr dev $link` +func (h *Handle) AddrDel(link Link, addr *Addr) error { + req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK) + return h.addrHandle(link, addr, req) +} + +func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error { + base := link.Attrs() + if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) { + return fmt.Errorf("label must begin with interface name") + } + h.ensureIndex(base) + + family := nl.GetIPFamily(addr.IP) + + msg := nl.NewIfAddrmsg(family) + msg.Index = uint32(base.Index) + msg.Scope = uint8(addr.Scope) + prefixlen, masklen := addr.Mask.Size() + msg.Prefixlen = uint8(prefixlen) + req.AddData(msg) + + var localAddrData []byte + if family == FAMILY_V4 { + localAddrData = addr.IP.To4() + } else { + localAddrData = addr.IP.To16() + } + + localData := nl.NewRtAttr(unix.IFA_LOCAL, localAddrData) + req.AddData(localData) + var peerAddrData []byte + if addr.Peer != nil { + if family == FAMILY_V4 { + peerAddrData = addr.Peer.IP.To4() + } else { + peerAddrData = addr.Peer.IP.To16() + } + } else { + peerAddrData = localAddrData + } + + addressData := nl.NewRtAttr(unix.IFA_ADDRESS, peerAddrData) + req.AddData(addressData) + + if addr.Flags != 0 { + if addr.Flags <= 0xff { + msg.IfAddrmsg.Flags = uint8(addr.Flags) + } else { + b := make([]byte, 4) + native.PutUint32(b, uint32(addr.Flags)) + flagsData := nl.NewRtAttr(IFA_FLAGS, b) + req.AddData(flagsData) + } + } + + if family == FAMILY_V4 { + if addr.Broadcast == nil { + calcBroadcast := make(net.IP, masklen/8) + for i := range localAddrData { + calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i] + } + addr.Broadcast = calcBroadcast + } + req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast)) + + if addr.Label != "" { + labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label)) + req.AddData(labelData) + } + } + + // 0 is the default value for these attributes. However, 0 means "expired", while the least-surprising default + // value should be "forever". To compensate for that, only add the attributes if at least one of the values is + // non-zero, which means the caller has explicitly set them + if addr.ValidLft > 0 || addr.PreferedLft > 0 { + cachedata := nl.IfaCacheInfo{ + IfaValid: uint32(addr.ValidLft), + IfaPrefered: uint32(addr.PreferedLft), + } + req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize())) + } + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// AddrList gets a list of IP addresses in the system. +// Equivalent to: `ip addr show`. +// The list can be filtered by link and ip family. +func AddrList(link Link, family int) ([]Addr, error) { + return pkgHandle.AddrList(link, family) +} + +// AddrList gets a list of IP addresses in the system. +// Equivalent to: `ip addr show`. +// The list can be filtered by link and ip family. +func (h *Handle) AddrList(link Link, family int) ([]Addr, error) { + req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP) + msg := nl.NewIfInfomsg(family) + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR) + if err != nil { + return nil, err + } + + indexFilter := 0 + if link != nil { + base := link.Attrs() + h.ensureIndex(base) + indexFilter = base.Index + } + + var res []Addr + for _, m := range msgs { + addr, msgFamily, ifindex, err := parseAddr(m) + if err != nil { + return res, err + } + + if link != nil && ifindex != indexFilter { + // Ignore messages from other interfaces + continue + } + + if family != FAMILY_ALL && msgFamily != family { + continue + } + + res = append(res, addr) + } + + return res, nil +} + +func parseAddr(m []byte) (addr Addr, family, index int, err error) { + msg := nl.DeserializeIfAddrmsg(m) + + family = -1 + index = -1 + + attrs, err1 := nl.ParseRouteAttr(m[msg.Len():]) + if err1 != nil { + err = err1 + return + } + + family = int(msg.Family) + index = int(msg.Index) + + var local, dst *net.IPNet + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.IFA_ADDRESS: + dst = &net.IPNet{ + IP: attr.Value, + Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), + } + addr.Peer = dst + case unix.IFA_LOCAL: + local = &net.IPNet{ + IP: attr.Value, + Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), + } + addr.IPNet = local + case unix.IFA_BROADCAST: + addr.Broadcast = attr.Value + case unix.IFA_LABEL: + addr.Label = string(attr.Value[:len(attr.Value)-1]) + case IFA_FLAGS: + addr.Flags = int(native.Uint32(attr.Value[0:4])) + case nl.IFA_CACHEINFO: + ci := nl.DeserializeIfaCacheInfo(attr.Value) + addr.PreferedLft = int(ci.IfaPrefered) + addr.ValidLft = int(ci.IfaValid) + } + } + + // IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS + if local != nil { + addr.IPNet = local + } else { + addr.IPNet = dst + } + addr.Scope = int(msg.Scope) + + return +} + +type AddrUpdate struct { + LinkAddress net.IPNet + LinkIndex int + Flags int + Scope int + PreferedLft int + ValidLft int + NewAddr bool // true=added false=deleted +} + +// AddrSubscribe takes a chan down which notifications will be sent +// when addresses change. Close the 'done' chan to stop subscription. +func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error { + return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) +} + +// AddrSubscribeAt works like AddrSubscribe plus it allows the caller +// to choose the network namespace in which to subscribe (ns). +func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error { + return addrSubscribeAt(ns, netns.None(), ch, done, nil, false) +} + +// AddrSubscribeOptions contains a set of options to use with +// AddrSubscribeWithOptions. +type AddrSubscribeOptions struct { + Namespace *netns.NsHandle + ErrorCallback func(error) + ListExisting bool +} + +// AddrSubscribeWithOptions work like AddrSubscribe but enable to +// provide additional options to modify the behavior. Currently, the +// namespace can be provided as well as an error callback. +func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, options AddrSubscribeOptions) error { + if options.Namespace == nil { + none := netns.None() + options.Namespace = &none + } + return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) +} + +func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { + s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR) + if err != nil { + return err + } + if done != nil { + go func() { + <-done + s.Close() + }() + } + if listExisting { + req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR, + unix.NLM_F_DUMP) + infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(infmsg) + if err := s.Send(req); err != nil { + return err + } + } + go func() { + defer close(ch) + for { + msgs, err := s.Receive() + if err != nil { + if cberr != nil { + cberr(err) + } + return + } + for _, m := range msgs { + if m.Header.Type == unix.NLMSG_DONE { + continue + } + if m.Header.Type == unix.NLMSG_ERROR { + native := nl.NativeEndian() + error := int32(native.Uint32(m.Data[0:4])) + if error == 0 { + continue + } + if cberr != nil { + cberr(syscall.Errno(-error)) + } + return + } + msgType := m.Header.Type + if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR { + if cberr != nil { + cberr(fmt.Errorf("bad message type: %d", msgType)) + } + return + } + + addr, _, ifindex, err := parseAddr(m.Data) + if err != nil { + if cberr != nil { + cberr(fmt.Errorf("could not parse address: %v", err)) + } + return + } + + ch <- AddrUpdate{LinkAddress: *addr.IPNet, + LinkIndex: ifindex, + NewAddr: msgType == unix.RTM_NEWADDR, + Flags: addr.Flags, + Scope: addr.Scope, + PreferedLft: addr.PreferedLft, + ValidLft: addr.ValidLft} + } + } + }() + + return nil +} diff --git a/vendor/github.com/vishvananda/netlink/bpf_linux.go b/vendor/github.com/vishvananda/netlink/bpf_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..6631626bfc06a9812e6fc2e2c8e39cb3dc494f11 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/bpf_linux.go @@ -0,0 +1,53 @@ +package netlink + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +type BpfProgType uint32 + +const ( + BPF_PROG_TYPE_UNSPEC BpfProgType = iota + BPF_PROG_TYPE_SOCKET_FILTER + BPF_PROG_TYPE_KPROBE + BPF_PROG_TYPE_SCHED_CLS + BPF_PROG_TYPE_SCHED_ACT + BPF_PROG_TYPE_TRACEPOINT + BPF_PROG_TYPE_XDP +) + +type BPFAttr struct { + ProgType uint32 + InsnCnt uint32 + Insns uintptr + License uintptr + LogLevel uint32 + LogSize uint32 + LogBuf uintptr + KernVersion uint32 +} + +// loadSimpleBpf loads a trivial bpf program for testing purposes. +func loadSimpleBpf(progType BpfProgType, ret uint32) (int, error) { + insns := []uint64{ + 0x00000000000000b7 | (uint64(ret) << 32), + 0x0000000000000095, + } + license := []byte{'A', 'S', 'L', '2', '\x00'} + attr := BPFAttr{ + ProgType: uint32(progType), + InsnCnt: uint32(len(insns)), + Insns: uintptr(unsafe.Pointer(&insns[0])), + License: uintptr(unsafe.Pointer(&license[0])), + } + fd, _, errno := unix.Syscall(unix.SYS_BPF, + 5, /* bpf cmd */ + uintptr(unsafe.Pointer(&attr)), + unsafe.Sizeof(attr)) + if errno != 0 { + return 0, errno + } + return int(fd), nil +} diff --git a/vendor/github.com/vishvananda/netlink/bridge_linux.go b/vendor/github.com/vishvananda/netlink/bridge_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..350ab0db4b01a4e23a5a909c80cab57c1f0d5e3d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/bridge_linux.go @@ -0,0 +1,115 @@ +package netlink + +import ( + "fmt" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +// BridgeVlanList gets a map of device id to bridge vlan infos. +// Equivalent to: `bridge vlan show` +func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { + return pkgHandle.BridgeVlanList() +} + +// BridgeVlanList gets a map of device id to bridge vlan infos. +// Equivalent to: `bridge vlan show` +func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) + msg := nl.NewIfInfomsg(unix.AF_BRIDGE) + req.AddData(msg) + req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN)))) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) + if err != nil { + return nil, err + } + ret := make(map[int32][]*nl.BridgeVlanInfo) + for _, m := range msgs { + msg := nl.DeserializeIfInfomsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.IFLA_AF_SPEC: + //nested attr + nestAttrs, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse nested attr %v", err) + } + for _, nestAttr := range nestAttrs { + switch nestAttr.Attr.Type { + case nl.IFLA_BRIDGE_VLAN_INFO: + vlanInfo := nl.DeserializeBridgeVlanInfo(nestAttr.Value) + ret[msg.Index] = append(ret[msg.Index], vlanInfo) + } + } + } + } + } + return ret, nil +} + +// BridgeVlanAdd adds a new vlan filter entry +// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` +func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { + return pkgHandle.BridgeVlanAdd(link, vid, pvid, untagged, self, master) +} + +// BridgeVlanAdd adds a new vlan filter entry +// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` +func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { + return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master) +} + +// BridgeVlanDel adds a new vlan filter entry +// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` +func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error { + return pkgHandle.BridgeVlanDel(link, vid, pvid, untagged, self, master) +} + +// BridgeVlanDel adds a new vlan filter entry +// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` +func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error { + return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master) +} + +func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_BRIDGE) + msg.Index = int32(base.Index) + req.AddData(msg) + + br := nl.NewRtAttr(unix.IFLA_AF_SPEC, nil) + var flags uint16 + if self { + flags |= nl.BRIDGE_FLAGS_SELF + } + if master { + flags |= nl.BRIDGE_FLAGS_MASTER + } + if flags > 0 { + nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags)) + } + vlanInfo := &nl.BridgeVlanInfo{Vid: vid} + if pvid { + vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID + } + if untagged { + vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED + } + nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) + req.AddData(br) + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/vishvananda/netlink/class.go b/vendor/github.com/vishvananda/netlink/class.go new file mode 100644 index 0000000000000000000000000000000000000000..8ee13af48eb9871a07e920df999ccbc10a2ba4e6 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/class.go @@ -0,0 +1,78 @@ +package netlink + +import ( + "fmt" +) + +type Class interface { + Attrs() *ClassAttrs + Type() string +} + +// ClassAttrs represents a netlink class. A filter is associated with a link, +// has a handle and a parent. The root filter of a device should have a +// parent == HANDLE_ROOT. +type ClassAttrs struct { + LinkIndex int + Handle uint32 + Parent uint32 + Leaf uint32 +} + +func (q ClassAttrs) String() string { + return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf) +} + +type HtbClassAttrs struct { + // TODO handle all attributes + Rate uint64 + Ceil uint64 + Buffer uint32 + Cbuffer uint32 + Quantum uint32 + Level uint32 + Prio uint32 +} + +func (q HtbClassAttrs) String() string { + return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) +} + +// HtbClass represents an Htb class +type HtbClass struct { + ClassAttrs + Rate uint64 + Ceil uint64 + Buffer uint32 + Cbuffer uint32 + Quantum uint32 + Level uint32 + Prio uint32 +} + +func (q HtbClass) String() string { + return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) +} + +func (q *HtbClass) Attrs() *ClassAttrs { + return &q.ClassAttrs +} + +func (q *HtbClass) Type() string { + return "htb" +} + +// GenericClass classes represent types that are not currently understood +// by this netlink library. +type GenericClass struct { + ClassAttrs + ClassType string +} + +func (class *GenericClass) Attrs() *ClassAttrs { + return &class.ClassAttrs +} + +func (class *GenericClass) Type() string { + return class.ClassType +} diff --git a/vendor/github.com/vishvananda/netlink/class_linux.go b/vendor/github.com/vishvananda/netlink/class_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..a4997740e2922f6ec13b7b251dd888417923f326 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/class_linux.go @@ -0,0 +1,255 @@ +package netlink + +import ( + "errors" + "syscall" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +// NOTE: function is in here because it uses other linux functions +func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass { + mtu := 1600 + rate := cattrs.Rate / 8 + ceil := cattrs.Ceil / 8 + buffer := cattrs.Buffer + cbuffer := cattrs.Cbuffer + + if ceil == 0 { + ceil = rate + } + + if buffer == 0 { + buffer = uint32(float64(rate)/Hz() + float64(mtu)) + } + buffer = uint32(Xmittime(rate, buffer)) + + if cbuffer == 0 { + cbuffer = uint32(float64(ceil)/Hz() + float64(mtu)) + } + cbuffer = uint32(Xmittime(ceil, cbuffer)) + + return &HtbClass{ + ClassAttrs: attrs, + Rate: rate, + Ceil: ceil, + Buffer: buffer, + Cbuffer: cbuffer, + Quantum: 10, + Level: 0, + Prio: 0, + } +} + +// ClassDel will delete a class from the system. +// Equivalent to: `tc class del $class` +func ClassDel(class Class) error { + return pkgHandle.ClassDel(class) +} + +// ClassDel will delete a class from the system. +// Equivalent to: `tc class del $class` +func (h *Handle) ClassDel(class Class) error { + return h.classModify(unix.RTM_DELTCLASS, 0, class) +} + +// ClassChange will change a class in place +// Equivalent to: `tc class change $class` +// The parent and handle MUST NOT be changed. +func ClassChange(class Class) error { + return pkgHandle.ClassChange(class) +} + +// ClassChange will change a class in place +// Equivalent to: `tc class change $class` +// The parent and handle MUST NOT be changed. +func (h *Handle) ClassChange(class Class) error { + return h.classModify(unix.RTM_NEWTCLASS, 0, class) +} + +// ClassReplace will replace a class to the system. +// quivalent to: `tc class replace $class` +// The handle MAY be changed. +// If a class already exist with this parent/handle pair, the class is changed. +// If a class does not already exist with this parent/handle, a new class is created. +func ClassReplace(class Class) error { + return pkgHandle.ClassReplace(class) +} + +// ClassReplace will replace a class to the system. +// quivalent to: `tc class replace $class` +// The handle MAY be changed. +// If a class already exist with this parent/handle pair, the class is changed. +// If a class does not already exist with this parent/handle, a new class is created. +func (h *Handle) ClassReplace(class Class) error { + return h.classModify(unix.RTM_NEWTCLASS, unix.NLM_F_CREATE, class) +} + +// ClassAdd will add a class to the system. +// Equivalent to: `tc class add $class` +func ClassAdd(class Class) error { + return pkgHandle.ClassAdd(class) +} + +// ClassAdd will add a class to the system. +// Equivalent to: `tc class add $class` +func (h *Handle) ClassAdd(class Class) error { + return h.classModify( + unix.RTM_NEWTCLASS, + unix.NLM_F_CREATE|unix.NLM_F_EXCL, + class, + ) +} + +func (h *Handle) classModify(cmd, flags int, class Class) error { + req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) + base := class.Attrs() + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Ifindex: int32(base.LinkIndex), + Handle: base.Handle, + Parent: base.Parent, + } + req.AddData(msg) + + if cmd != unix.RTM_DELTCLASS { + if err := classPayload(req, class); err != nil { + return err + } + } + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func classPayload(req *nl.NetlinkRequest, class Class) error { + req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type()))) + + options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) + if htb, ok := class.(*HtbClass); ok { + opt := nl.TcHtbCopt{} + opt.Buffer = htb.Buffer + opt.Cbuffer = htb.Cbuffer + opt.Quantum = htb.Quantum + opt.Level = htb.Level + opt.Prio = htb.Prio + // TODO: Handle Debug properly. For now default to 0 + /* Calculate {R,C}Tab and set Rate and Ceil */ + cellLog := -1 + ccellLog := -1 + linklayer := nl.LINKLAYER_ETHERNET + mtu := 1600 + var rtab [256]uint32 + var ctab [256]uint32 + tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)} + if CalcRtable(&tcrate, rtab[:], cellLog, uint32(mtu), linklayer) < 0 { + return errors.New("HTB: failed to calculate rate table") + } + opt.Rate = tcrate + tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)} + if CalcRtable(&tcceil, ctab[:], ccellLog, uint32(mtu), linklayer) < 0 { + return errors.New("HTB: failed to calculate ceil rate table") + } + opt.Ceil = tcceil + nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize()) + nl.NewRtAttrChild(options, nl.TCA_HTB_RTAB, SerializeRtab(rtab)) + nl.NewRtAttrChild(options, nl.TCA_HTB_CTAB, SerializeRtab(ctab)) + } + req.AddData(options) + return nil +} + +// ClassList gets a list of classes in the system. +// Equivalent to: `tc class show`. +// Generally returns nothing if link and parent are not specified. +func ClassList(link Link, parent uint32) ([]Class, error) { + return pkgHandle.ClassList(link, parent) +} + +// ClassList gets a list of classes in the system. +// Equivalent to: `tc class show`. +// Generally returns nothing if link and parent are not specified. +func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) { + req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP) + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Parent: parent, + } + if link != nil { + base := link.Attrs() + h.ensureIndex(base) + msg.Ifindex = int32(base.Index) + } + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS) + if err != nil { + return nil, err + } + + var res []Class + for _, m := range msgs { + msg := nl.DeserializeTcMsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + base := ClassAttrs{ + LinkIndex: int(msg.Ifindex), + Handle: msg.Handle, + Parent: msg.Parent, + } + + var class Class + classType := "" + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.TCA_KIND: + classType = string(attr.Value[:len(attr.Value)-1]) + switch classType { + case "htb": + class = &HtbClass{} + default: + class = &GenericClass{ClassType: classType} + } + case nl.TCA_OPTIONS: + switch classType { + case "htb": + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + _, err = parseHtbClassData(class, data) + if err != nil { + return nil, err + } + } + } + } + *class.Attrs() = base + res = append(res, class) + } + + return res, nil +} + +func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) { + htb := class.(*HtbClass) + detailed := false + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_HTB_PARMS: + opt := nl.DeserializeTcHtbCopt(datum.Value) + htb.Rate = uint64(opt.Rate.Rate) + htb.Ceil = uint64(opt.Ceil.Rate) + htb.Buffer = opt.Buffer + htb.Cbuffer = opt.Cbuffer + htb.Quantum = opt.Quantum + htb.Level = opt.Level + htb.Prio = opt.Prio + } + } + return detailed, nil +} diff --git a/vendor/github.com/vishvananda/netlink/conntrack_linux.go b/vendor/github.com/vishvananda/netlink/conntrack_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..a0fc74a37224faf5dfb02a38b087990632a00f9b --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/conntrack_linux.go @@ -0,0 +1,371 @@ +package netlink + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +// ConntrackTableType Conntrack table for the netlink operation +type ConntrackTableType uint8 + +const ( + // ConntrackTable Conntrack table + // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK 1 + ConntrackTable = 1 + // ConntrackExpectTable Conntrack expect table + // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2 + ConntrackExpectTable = 2 +) +const ( + // For Parsing Mark + TCP_PROTO = 6 + UDP_PROTO = 17 +) +const ( + // backward compatibility with golang 1.6 which does not have io.SeekCurrent + seekCurrent = 1 +) + +// InetFamily Family type +type InetFamily uint8 + +// -L [table] [options] List conntrack or expectation table +// -G [table] parameters Get conntrack or expectation + +// -I [table] parameters Create a conntrack or expectation +// -U [table] parameters Update a conntrack +// -E [table] [options] Show events + +// -C [table] Show counter +// -S Show statistics + +// ConntrackTableList returns the flow list of a table of a specific family +// conntrack -L [table] [options] List conntrack or expectation table +func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { + return pkgHandle.ConntrackTableList(table, family) +} + +// ConntrackTableFlush flushes all the flows of a specified table +// conntrack -F [table] Flush table +// The flush operation applies to all the family types +func ConntrackTableFlush(table ConntrackTableType) error { + return pkgHandle.ConntrackTableFlush(table) +} + +// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter +// conntrack -D [table] parameters Delete conntrack or expectation +func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) { + return pkgHandle.ConntrackDeleteFilter(table, family, filter) +} + +// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed +// conntrack -L [table] [options] List conntrack or expectation table +func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { + res, err := h.dumpConntrackTable(table, family) + if err != nil { + return nil, err + } + + // Deserialize all the flows + var result []*ConntrackFlow + for _, dataRaw := range res { + result = append(result, parseRawData(dataRaw)) + } + + return result, nil +} + +// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed +// conntrack -F [table] Flush table +// The flush operation applies to all the family types +func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error { + req := h.newConntrackRequest(table, unix.AF_INET, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) + _, err := req.Execute(unix.NETLINK_NETFILTER, 0) + return err +} + +// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed +// conntrack -D [table] parameters Delete conntrack or expectation +func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) { + res, err := h.dumpConntrackTable(table, family) + if err != nil { + return 0, err + } + + var matched uint + for _, dataRaw := range res { + flow := parseRawData(dataRaw) + if match := filter.MatchConntrackFlow(flow); match { + req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) + // skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already + req2.AddRawData(dataRaw[4:]) + req2.Execute(unix.NETLINK_NETFILTER, 0) + matched++ + } + } + + return matched, nil +} + +func (h *Handle) newConntrackRequest(table ConntrackTableType, family InetFamily, operation, flags int) *nl.NetlinkRequest { + // Create the Netlink request object + req := h.newNetlinkRequest((int(table)<<8)|operation, flags) + // Add the netfilter header + msg := &nl.Nfgenmsg{ + NfgenFamily: uint8(family), + Version: nl.NFNETLINK_V0, + ResId: 0, + } + req.AddData(msg) + return req +} + +func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) { + req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, unix.NLM_F_DUMP) + return req.Execute(unix.NETLINK_NETFILTER, 0) +} + +// The full conntrack flow structure is very complicated and can be found in the file: +// http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h +// For the time being, the structure below allows to parse and extract the base information of a flow +type ipTuple struct { + SrcIP net.IP + DstIP net.IP + Protocol uint8 + SrcPort uint16 + DstPort uint16 +} + +type ConntrackFlow struct { + FamilyType uint8 + Forward ipTuple + Reverse ipTuple + Mark uint32 +} + +func (s *ConntrackFlow) String() string { + // conntrack cmd output: + // udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 mark=0 + return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d mark=%d", + nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol, + s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, + s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Mark) +} + +// This method parse the ip tuple structure +// The message structure is the following: +// <len, [CTA_IP_V4_SRC|CTA_IP_V6_SRC], 16 bytes for the IP> +// <len, [CTA_IP_V4_DST|CTA_IP_V6_DST], 16 bytes for the IP> +// <len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO, 1 byte for the protocol, 3 bytes of padding> +// <len, CTA_PROTO_SRC_PORT, 2 bytes for the source port, 2 bytes of padding> +// <len, CTA_PROTO_DST_PORT, 2 bytes for the source port, 2 bytes of padding> +func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 { + for i := 0; i < 2; i++ { + _, t, _, v := parseNfAttrTLV(reader) + switch t { + case nl.CTA_IP_V4_SRC, nl.CTA_IP_V6_SRC: + tpl.SrcIP = v + case nl.CTA_IP_V4_DST, nl.CTA_IP_V6_DST: + tpl.DstIP = v + } + } + // Skip the next 4 bytes nl.NLA_F_NESTED|nl.CTA_TUPLE_PROTO + reader.Seek(4, seekCurrent) + _, t, _, v := parseNfAttrTLV(reader) + if t == nl.CTA_PROTO_NUM { + tpl.Protocol = uint8(v[0]) + } + // Skip some padding 3 bytes + reader.Seek(3, seekCurrent) + for i := 0; i < 2; i++ { + _, t, _ := parseNfAttrTL(reader) + switch t { + case nl.CTA_PROTO_SRC_PORT: + parseBERaw16(reader, &tpl.SrcPort) + case nl.CTA_PROTO_DST_PORT: + parseBERaw16(reader, &tpl.DstPort) + } + // Skip some padding 2 byte + reader.Seek(2, seekCurrent) + } + return tpl.Protocol +} + +func parseNfAttrTLV(r *bytes.Reader) (isNested bool, attrType, len uint16, value []byte) { + isNested, attrType, len = parseNfAttrTL(r) + + value = make([]byte, len) + binary.Read(r, binary.BigEndian, &value) + return isNested, attrType, len, value +} + +func parseNfAttrTL(r *bytes.Reader) (isNested bool, attrType, len uint16) { + binary.Read(r, nl.NativeEndian(), &len) + len -= nl.SizeofNfattr + + binary.Read(r, nl.NativeEndian(), &attrType) + isNested = (attrType & nl.NLA_F_NESTED) == nl.NLA_F_NESTED + attrType = attrType & (nl.NLA_F_NESTED - 1) + + return isNested, attrType, len +} + +func parseBERaw16(r *bytes.Reader, v *uint16) { + binary.Read(r, binary.BigEndian, v) +} + +func parseRawData(data []byte) *ConntrackFlow { + s := &ConntrackFlow{} + var proto uint8 + // First there is the Nfgenmsg header + // consume only the family field + reader := bytes.NewReader(data) + binary.Read(reader, nl.NativeEndian(), &s.FamilyType) + + // skip rest of the Netfilter header + reader.Seek(3, seekCurrent) + // The message structure is the following: + // <len, NLA_F_NESTED|CTA_TUPLE_ORIG> 4 bytes + // <len, NLA_F_NESTED|CTA_TUPLE_IP> 4 bytes + // flow information of the forward flow + // <len, NLA_F_NESTED|CTA_TUPLE_REPLY> 4 bytes + // <len, NLA_F_NESTED|CTA_TUPLE_IP> 4 bytes + // flow information of the reverse flow + for reader.Len() > 0 { + nested, t, l := parseNfAttrTL(reader) + if nested && t == nl.CTA_TUPLE_ORIG { + if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { + proto = parseIpTuple(reader, &s.Forward) + } + } else if nested && t == nl.CTA_TUPLE_REPLY { + if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { + parseIpTuple(reader, &s.Reverse) + + // Got all the useful information stop parsing + break + } else { + // Header not recognized skip it + reader.Seek(int64(l), seekCurrent) + } + } + } + if proto == TCP_PROTO { + reader.Seek(64, seekCurrent) + _, t, _, v := parseNfAttrTLV(reader) + if t == nl.CTA_MARK { + s.Mark = uint32(v[3]) + } + } else if proto == UDP_PROTO { + reader.Seek(16, seekCurrent) + _, t, _, v := parseNfAttrTLV(reader) + if t == nl.CTA_MARK { + s.Mark = uint32(v[3]) + } + } + return s +} + +// Conntrack parameters and options: +// -n, --src-nat ip source NAT ip +// -g, --dst-nat ip destination NAT ip +// -j, --any-nat ip source or destination NAT ip +// -m, --mark mark Set mark +// -c, --secmark secmark Set selinux secmark +// -e, --event-mask eventmask Event mask, eg. NEW,DESTROY +// -z, --zero Zero counters while listing +// -o, --output type[,...] Output format, eg. xml +// -l, --label label[,...] conntrack labels + +// Common parameters and options: +// -s, --src, --orig-src ip Source address from original direction +// -d, --dst, --orig-dst ip Destination address from original direction +// -r, --reply-src ip Source addres from reply direction +// -q, --reply-dst ip Destination address from reply direction +// -p, --protonum proto Layer 4 Protocol, eg. 'tcp' +// -f, --family proto Layer 3 Protocol, eg. 'ipv6' +// -t, --timeout timeout Set timeout +// -u, --status status Set status, eg. ASSURED +// -w, --zone value Set conntrack zone +// --orig-zone value Set zone for original direction +// --reply-zone value Set zone for reply direction +// -b, --buffer-size Netlink socket buffer size +// --mask-src ip Source mask address +// --mask-dst ip Destination mask address + +// Filter types +type ConntrackFilterType uint8 + +const ( + ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction + ConntrackOrigDstIP // -orig-dst ip Destination address from original direction + ConntrackNatSrcIP // -src-nat ip Source NAT ip + ConntrackNatDstIP // -dst-nat ip Destination NAT ip + ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip +) + +type CustomConntrackFilter interface { + // MatchConntrackFlow applies the filter to the flow and returns true if the flow matches + // the filter or false otherwise + MatchConntrackFlow(flow *ConntrackFlow) bool +} + +type ConntrackFilter struct { + ipFilter map[ConntrackFilterType]net.IP +} + +// AddIP adds an IP to the conntrack filter +func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error { + if f.ipFilter == nil { + f.ipFilter = make(map[ConntrackFilterType]net.IP) + } + if _, ok := f.ipFilter[tp]; ok { + return errors.New("Filter attribute already present") + } + f.ipFilter[tp] = ip + return nil +} + +// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches the filter +// false otherwise +func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool { + if len(f.ipFilter) == 0 { + // empty filter always not match + return false + } + + match := true + // -orig-src ip Source address from original direction + if elem, found := f.ipFilter[ConntrackOrigSrcIP]; found { + match = match && elem.Equal(flow.Forward.SrcIP) + } + + // -orig-dst ip Destination address from original direction + if elem, found := f.ipFilter[ConntrackOrigDstIP]; match && found { + match = match && elem.Equal(flow.Forward.DstIP) + } + + // -src-nat ip Source NAT ip + if elem, found := f.ipFilter[ConntrackNatSrcIP]; match && found { + match = match && elem.Equal(flow.Reverse.SrcIP) + } + + // -dst-nat ip Destination NAT ip + if elem, found := f.ipFilter[ConntrackNatDstIP]; match && found { + match = match && elem.Equal(flow.Reverse.DstIP) + } + + // -any-nat ip Source or destination NAT ip + if elem, found := f.ipFilter[ConntrackNatAnyIP]; match && found { + match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP)) + } + + return match +} + +var _ CustomConntrackFilter = (*ConntrackFilter)(nil) diff --git a/vendor/github.com/vishvananda/netlink/conntrack_unspecified.go b/vendor/github.com/vishvananda/netlink/conntrack_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..af7af799e776f7e0e29f1ebf2eac50f732ff58d0 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/conntrack_unspecified.go @@ -0,0 +1,53 @@ +// +build !linux + +package netlink + +// ConntrackTableType Conntrack table for the netlink operation +type ConntrackTableType uint8 + +// InetFamily Family type +type InetFamily uint8 + +// ConntrackFlow placeholder +type ConntrackFlow struct{} + +// ConntrackFilter placeholder +type ConntrackFilter struct{} + +// ConntrackTableList returns the flow list of a table of a specific family +// conntrack -L [table] [options] List conntrack or expectation table +func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { + return nil, ErrNotImplemented +} + +// ConntrackTableFlush flushes all the flows of a specified table +// conntrack -F [table] Flush table +// The flush operation applies to all the family types +func ConntrackTableFlush(table ConntrackTableType) error { + return ErrNotImplemented +} + +// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter +// conntrack -D [table] parameters Delete conntrack or expectation +func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) { + return 0, ErrNotImplemented +} + +// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed +// conntrack -L [table] [options] List conntrack or expectation table +func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { + return nil, ErrNotImplemented +} + +// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed +// conntrack -F [table] Flush table +// The flush operation applies to all the family types +func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error { + return ErrNotImplemented +} + +// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed +// conntrack -D [table] parameters Delete conntrack or expectation +func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) { + return 0, ErrNotImplemented +} diff --git a/vendor/github.com/vishvananda/netlink/filter.go b/vendor/github.com/vishvananda/netlink/filter.go new file mode 100644 index 0000000000000000000000000000000000000000..c2cf8e4dcf516389fb1382dee6fa72212ca56f37 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/filter.go @@ -0,0 +1,288 @@ +package netlink + +import ( + "fmt" +) + +type Filter interface { + Attrs() *FilterAttrs + Type() string +} + +// FilterAttrs represents a netlink filter. A filter is associated with a link, +// has a handle and a parent. The root filter of a device should have a +// parent == HANDLE_ROOT. +type FilterAttrs struct { + LinkIndex int + Handle uint32 + Parent uint32 + Priority uint16 // lower is higher priority + Protocol uint16 // unix.ETH_P_* +} + +func (q FilterAttrs) String() string { + return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol) +} + +type TcAct int32 + +const ( + TC_ACT_UNSPEC TcAct = -1 + TC_ACT_OK TcAct = 0 + TC_ACT_RECLASSIFY TcAct = 1 + TC_ACT_SHOT TcAct = 2 + TC_ACT_PIPE TcAct = 3 + TC_ACT_STOLEN TcAct = 4 + TC_ACT_QUEUED TcAct = 5 + TC_ACT_REPEAT TcAct = 6 + TC_ACT_REDIRECT TcAct = 7 + TC_ACT_JUMP TcAct = 0x10000000 +) + +func (a TcAct) String() string { + switch a { + case TC_ACT_UNSPEC: + return "unspec" + case TC_ACT_OK: + return "ok" + case TC_ACT_RECLASSIFY: + return "reclassify" + case TC_ACT_SHOT: + return "shot" + case TC_ACT_PIPE: + return "pipe" + case TC_ACT_STOLEN: + return "stolen" + case TC_ACT_QUEUED: + return "queued" + case TC_ACT_REPEAT: + return "repeat" + case TC_ACT_REDIRECT: + return "redirect" + case TC_ACT_JUMP: + return "jump" + } + return fmt.Sprintf("0x%x", int32(a)) +} + +type TcPolAct int32 + +const ( + TC_POLICE_UNSPEC TcPolAct = TcPolAct(TC_ACT_UNSPEC) + TC_POLICE_OK TcPolAct = TcPolAct(TC_ACT_OK) + TC_POLICE_RECLASSIFY TcPolAct = TcPolAct(TC_ACT_RECLASSIFY) + TC_POLICE_SHOT TcPolAct = TcPolAct(TC_ACT_SHOT) + TC_POLICE_PIPE TcPolAct = TcPolAct(TC_ACT_PIPE) +) + +func (a TcPolAct) String() string { + switch a { + case TC_POLICE_UNSPEC: + return "unspec" + case TC_POLICE_OK: + return "ok" + case TC_POLICE_RECLASSIFY: + return "reclassify" + case TC_POLICE_SHOT: + return "shot" + case TC_POLICE_PIPE: + return "pipe" + } + return fmt.Sprintf("0x%x", int32(a)) +} + +type ActionAttrs struct { + Index int + Capab int + Action TcAct + Refcnt int + Bindcnt int +} + +func (q ActionAttrs) String() string { + return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt) +} + +// Action represents an action in any supported filter. +type Action interface { + Attrs() *ActionAttrs + Type() string +} + +type GenericAction struct { + ActionAttrs +} + +func (action *GenericAction) Type() string { + return "generic" +} + +func (action *GenericAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + +type BpfAction struct { + ActionAttrs + Fd int + Name string +} + +func (action *BpfAction) Type() string { + return "bpf" +} + +func (action *BpfAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + +type MirredAct uint8 + +func (a MirredAct) String() string { + switch a { + case TCA_EGRESS_REDIR: + return "egress redir" + case TCA_EGRESS_MIRROR: + return "egress mirror" + case TCA_INGRESS_REDIR: + return "ingress redir" + case TCA_INGRESS_MIRROR: + return "ingress mirror" + } + return "unknown" +} + +const ( + TCA_EGRESS_REDIR MirredAct = 1 /* packet redirect to EGRESS*/ + TCA_EGRESS_MIRROR MirredAct = 2 /* mirror packet to EGRESS */ + TCA_INGRESS_REDIR MirredAct = 3 /* packet redirect to INGRESS*/ + TCA_INGRESS_MIRROR MirredAct = 4 /* mirror packet to INGRESS */ +) + +type MirredAction struct { + ActionAttrs + MirredAction MirredAct + Ifindex int +} + +func (action *MirredAction) Type() string { + return "mirred" +} + +func (action *MirredAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + +func NewMirredAction(redirIndex int) *MirredAction { + return &MirredAction{ + ActionAttrs: ActionAttrs{ + Action: TC_ACT_STOLEN, + }, + MirredAction: TCA_EGRESS_REDIR, + Ifindex: redirIndex, + } +} + +// Sel of the U32 filters that contains multiple TcU32Key. This is the copy +// and the frontend representation of nl.TcU32Sel. It is serialized into canonical +// nl.TcU32Sel with the appropriate endianness. +type TcU32Sel struct { + Flags uint8 + Offshift uint8 + Nkeys uint8 + Pad uint8 + Offmask uint16 + Off uint16 + Offoff int16 + Hoff int16 + Hmask uint32 + Keys []TcU32Key +} + +// TcU32Key contained of Sel in the U32 filters. This is the copy and the frontend +// representation of nl.TcU32Key. It is serialized into chanonical nl.TcU32Sel +// with the appropriate endianness. +type TcU32Key struct { + Mask uint32 + Val uint32 + Off int32 + OffMask int32 +} + +// U32 filters on many packet related properties +type U32 struct { + FilterAttrs + ClassId uint32 + RedirIndex int + Sel *TcU32Sel + Actions []Action +} + +func (filter *U32) Attrs() *FilterAttrs { + return &filter.FilterAttrs +} + +func (filter *U32) Type() string { + return "u32" +} + +// MatchAll filters match all packets +type MatchAll struct { + FilterAttrs + ClassId uint32 + Actions []Action +} + +func (filter *MatchAll) Attrs() *FilterAttrs { + return &filter.FilterAttrs +} + +func (filter *MatchAll) Type() string { + return "matchall" +} + +type FilterFwAttrs struct { + ClassId uint32 + InDev string + Mask uint32 + Index uint32 + Buffer uint32 + Mtu uint32 + Mpu uint16 + Rate uint32 + AvRate uint32 + PeakRate uint32 + Action TcPolAct + Overhead uint16 + LinkLayer int +} + +type BpfFilter struct { + FilterAttrs + ClassId uint32 + Fd int + Name string + DirectAction bool +} + +func (filter *BpfFilter) Type() string { + return "bpf" +} + +func (filter *BpfFilter) Attrs() *FilterAttrs { + return &filter.FilterAttrs +} + +// GenericFilter filters represent types that are not currently understood +// by this netlink library. +type GenericFilter struct { + FilterAttrs + FilterType string +} + +func (filter *GenericFilter) Attrs() *FilterAttrs { + return &filter.FilterAttrs +} + +func (filter *GenericFilter) Type() string { + return filter.FilterType +} diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..f0eac6b78cc5c8cd4a8341175792c2edd7dcebaf --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/filter_linux.go @@ -0,0 +1,639 @@ +package netlink + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "syscall" + "unsafe" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +// Constants used in TcU32Sel.Flags. +const ( + TC_U32_TERMINAL = nl.TC_U32_TERMINAL + TC_U32_OFFSET = nl.TC_U32_OFFSET + TC_U32_VAROFFSET = nl.TC_U32_VAROFFSET + TC_U32_EAT = nl.TC_U32_EAT +) + +// Fw filter filters on firewall marks +// NOTE: this is in filter_linux because it refers to nl.TcPolice which +// is defined in nl/tc_linux.go +type Fw struct { + FilterAttrs + ClassId uint32 + // TODO remove nl type from interface + Police nl.TcPolice + InDev string + // TODO Action + Mask uint32 + AvRate uint32 + Rtab [256]uint32 + Ptab [256]uint32 +} + +func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) { + var rtab [256]uint32 + var ptab [256]uint32 + rcellLog := -1 + pcellLog := -1 + avrate := fattrs.AvRate / 8 + police := nl.TcPolice{} + police.Rate.Rate = fattrs.Rate / 8 + police.PeakRate.Rate = fattrs.PeakRate / 8 + buffer := fattrs.Buffer + linklayer := nl.LINKLAYER_ETHERNET + + if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC { + linklayer = fattrs.LinkLayer + } + + police.Action = int32(fattrs.Action) + if police.Rate.Rate != 0 { + police.Rate.Mpu = fattrs.Mpu + police.Rate.Overhead = fattrs.Overhead + if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 { + return nil, errors.New("TBF: failed to calculate rate table") + } + police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer))) + } + police.Mtu = fattrs.Mtu + if police.PeakRate.Rate != 0 { + police.PeakRate.Mpu = fattrs.Mpu + police.PeakRate.Overhead = fattrs.Overhead + if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 { + return nil, errors.New("POLICE: failed to calculate peak rate table") + } + } + + return &Fw{ + FilterAttrs: attrs, + ClassId: fattrs.ClassId, + InDev: fattrs.InDev, + Mask: fattrs.Mask, + Police: police, + AvRate: avrate, + Rtab: rtab, + Ptab: ptab, + }, nil +} + +func (filter *Fw) Attrs() *FilterAttrs { + return &filter.FilterAttrs +} + +func (filter *Fw) Type() string { + return "fw" +} + +// FilterDel will delete a filter from the system. +// Equivalent to: `tc filter del $filter` +func FilterDel(filter Filter) error { + return pkgHandle.FilterDel(filter) +} + +// FilterDel will delete a filter from the system. +// Equivalent to: `tc filter del $filter` +func (h *Handle) FilterDel(filter Filter) error { + req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK) + base := filter.Attrs() + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Ifindex: int32(base.LinkIndex), + Handle: base.Handle, + Parent: base.Parent, + Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)), + } + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// FilterAdd will add a filter to the system. +// Equivalent to: `tc filter add $filter` +func FilterAdd(filter Filter) error { + return pkgHandle.FilterAdd(filter) +} + +// FilterAdd will add a filter to the system. +// Equivalent to: `tc filter add $filter` +func (h *Handle) FilterAdd(filter Filter) error { + native = nl.NativeEndian() + req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + base := filter.Attrs() + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Ifindex: int32(base.LinkIndex), + Handle: base.Handle, + Parent: base.Parent, + Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)), + } + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type()))) + + options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) + + switch filter := filter.(type) { + case *U32: + // Convert TcU32Sel into nl.TcU32Sel as it is without copy. + sel := (*nl.TcU32Sel)(unsafe.Pointer(filter.Sel)) + if sel == nil { + // match all + sel = &nl.TcU32Sel{ + Nkeys: 1, + Flags: nl.TC_U32_TERMINAL, + } + sel.Keys = append(sel.Keys, nl.TcU32Key{}) + } + + if native != networkOrder { + // Copy TcU32Sel. + cSel := *sel + keys := make([]nl.TcU32Key, cap(sel.Keys)) + copy(keys, sel.Keys) + cSel.Keys = keys + sel = &cSel + + // Handle the endianness of attributes + sel.Offmask = native.Uint16(htons(sel.Offmask)) + sel.Hmask = native.Uint32(htonl(sel.Hmask)) + for i, key := range sel.Keys { + sel.Keys[i].Mask = native.Uint32(htonl(key.Mask)) + sel.Keys[i].Val = native.Uint32(htonl(key.Val)) + } + } + sel.Nkeys = uint8(len(sel.Keys)) + nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize()) + if filter.ClassId != 0 { + nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId)) + } + actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil) + // backwards compatibility + if filter.RedirIndex != 0 { + filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...) + } + if err := EncodeActions(actionsAttr, filter.Actions); err != nil { + return err + } + case *Fw: + if filter.Mask != 0 { + b := make([]byte, 4) + native.PutUint32(b, filter.Mask) + nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b) + } + if filter.InDev != "" { + nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev)) + } + if (filter.Police != nl.TcPolice{}) { + + police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil) + nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, filter.Police.Serialize()) + if (filter.Police.Rate != nl.TcRateSpec{}) { + payload := SerializeRtab(filter.Rtab) + nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload) + } + if (filter.Police.PeakRate != nl.TcRateSpec{}) { + payload := SerializeRtab(filter.Ptab) + nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload) + } + } + if filter.ClassId != 0 { + b := make([]byte, 4) + native.PutUint32(b, filter.ClassId) + nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b) + } + case *BpfFilter: + var bpfFlags uint32 + if filter.ClassId != 0 { + nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId)) + } + if filter.Fd >= 0 { + nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd)))) + } + if filter.Name != "" { + nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name)) + } + if filter.DirectAction { + bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT + } + nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags)) + case *MatchAll: + actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil) + if err := EncodeActions(actionsAttr, filter.Actions); err != nil { + return err + } + if filter.ClassId != 0 { + nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId)) + } + } + + req.AddData(options) + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// FilterList gets a list of filters in the system. +// Equivalent to: `tc filter show`. +// Generally returns nothing if link and parent are not specified. +func FilterList(link Link, parent uint32) ([]Filter, error) { + return pkgHandle.FilterList(link, parent) +} + +// FilterList gets a list of filters in the system. +// Equivalent to: `tc filter show`. +// Generally returns nothing if link and parent are not specified. +func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { + req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP) + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Parent: parent, + } + if link != nil { + base := link.Attrs() + h.ensureIndex(base) + msg.Ifindex = int32(base.Index) + } + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER) + if err != nil { + return nil, err + } + + var res []Filter + for _, m := range msgs { + msg := nl.DeserializeTcMsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + base := FilterAttrs{ + LinkIndex: int(msg.Ifindex), + Handle: msg.Handle, + Parent: msg.Parent, + } + base.Priority, base.Protocol = MajorMinor(msg.Info) + base.Protocol = nl.Swap16(base.Protocol) + + var filter Filter + filterType := "" + detailed := false + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.TCA_KIND: + filterType = string(attr.Value[:len(attr.Value)-1]) + switch filterType { + case "u32": + filter = &U32{} + case "fw": + filter = &Fw{} + case "bpf": + filter = &BpfFilter{} + case "matchall": + filter = &MatchAll{} + default: + filter = &GenericFilter{FilterType: filterType} + } + case nl.TCA_OPTIONS: + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + switch filterType { + case "u32": + detailed, err = parseU32Data(filter, data) + if err != nil { + return nil, err + } + case "fw": + detailed, err = parseFwData(filter, data) + if err != nil { + return nil, err + } + case "bpf": + detailed, err = parseBpfData(filter, data) + if err != nil { + return nil, err + } + case "matchall": + detailed, err = parseMatchAllData(filter, data) + if err != nil { + return nil, err + } + default: + detailed = true + } + } + } + // only return the detailed version of the filter + if detailed { + *filter.Attrs() = base + res = append(res, filter) + } + } + + return res, nil +} + +func toTcGen(attrs *ActionAttrs, tcgen *nl.TcGen) { + tcgen.Index = uint32(attrs.Index) + tcgen.Capab = uint32(attrs.Capab) + tcgen.Action = int32(attrs.Action) + tcgen.Refcnt = int32(attrs.Refcnt) + tcgen.Bindcnt = int32(attrs.Bindcnt) +} + +func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) { + attrs.Index = int(tcgen.Index) + attrs.Capab = int(tcgen.Capab) + attrs.Action = TcAct(tcgen.Action) + attrs.Refcnt = int(tcgen.Refcnt) + attrs.Bindcnt = int(tcgen.Bindcnt) +} + +func EncodeActions(attr *nl.RtAttr, actions []Action) error { + tabIndex := int(nl.TCA_ACT_TAB) + + for _, action := range actions { + switch action := action.(type) { + default: + return fmt.Errorf("unknown action type %s", action.Type()) + case *MirredAction: + table := nl.NewRtAttrChild(attr, tabIndex, nil) + tabIndex++ + nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred")) + aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) + mirred := nl.TcMirred{ + Eaction: int32(action.MirredAction), + Ifindex: uint32(action.Ifindex), + } + toTcGen(action.Attrs(), &mirred.TcGen) + nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mirred.Serialize()) + case *BpfAction: + table := nl.NewRtAttrChild(attr, tabIndex, nil) + tabIndex++ + nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf")) + aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) + gen := nl.TcGen{} + toTcGen(action.Attrs(), &gen) + nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_PARMS, gen.Serialize()) + nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd))) + nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name)) + case *GenericAction: + table := nl.NewRtAttrChild(attr, tabIndex, nil) + tabIndex++ + nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("gact")) + aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) + gen := nl.TcGen{} + toTcGen(action.Attrs(), &gen) + nl.NewRtAttrChild(aopts, nl.TCA_GACT_PARMS, gen.Serialize()) + } + } + return nil +} + +func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) { + var actions []Action + for _, table := range tables { + var action Action + var actionType string + aattrs, err := nl.ParseRouteAttr(table.Value) + if err != nil { + return nil, err + } + nextattr: + for _, aattr := range aattrs { + switch aattr.Attr.Type { + case nl.TCA_KIND: + actionType = string(aattr.Value[:len(aattr.Value)-1]) + // only parse if the action is mirred or bpf + switch actionType { + case "mirred": + action = &MirredAction{} + case "bpf": + action = &BpfAction{} + case "gact": + action = &GenericAction{} + default: + break nextattr + } + case nl.TCA_OPTIONS: + adata, err := nl.ParseRouteAttr(aattr.Value) + if err != nil { + return nil, err + } + for _, adatum := range adata { + switch actionType { + case "mirred": + switch adatum.Attr.Type { + case nl.TCA_MIRRED_PARMS: + mirred := *nl.DeserializeTcMirred(adatum.Value) + toAttrs(&mirred.TcGen, action.Attrs()) + action.(*MirredAction).ActionAttrs = ActionAttrs{} + action.(*MirredAction).Ifindex = int(mirred.Ifindex) + action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction) + } + case "bpf": + switch adatum.Attr.Type { + case nl.TCA_ACT_BPF_PARMS: + gen := *nl.DeserializeTcGen(adatum.Value) + toAttrs(&gen, action.Attrs()) + case nl.TCA_ACT_BPF_FD: + action.(*BpfAction).Fd = int(native.Uint32(adatum.Value[0:4])) + case nl.TCA_ACT_BPF_NAME: + action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1]) + } + case "gact": + switch adatum.Attr.Type { + case nl.TCA_GACT_PARMS: + gen := *nl.DeserializeTcGen(adatum.Value) + toAttrs(&gen, action.Attrs()) + } + } + } + } + } + actions = append(actions, action) + } + return actions, nil +} + +func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { + native = nl.NativeEndian() + u32 := filter.(*U32) + detailed := false + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_U32_SEL: + detailed = true + sel := nl.DeserializeTcU32Sel(datum.Value) + u32.Sel = (*TcU32Sel)(unsafe.Pointer(sel)) + if native != networkOrder { + // Handle the endianness of attributes + u32.Sel.Offmask = native.Uint16(htons(sel.Offmask)) + u32.Sel.Hmask = native.Uint32(htonl(sel.Hmask)) + for i, key := range u32.Sel.Keys { + u32.Sel.Keys[i].Mask = native.Uint32(htonl(key.Mask)) + u32.Sel.Keys[i].Val = native.Uint32(htonl(key.Val)) + } + } + case nl.TCA_U32_ACT: + tables, err := nl.ParseRouteAttr(datum.Value) + if err != nil { + return detailed, err + } + u32.Actions, err = parseActions(tables) + if err != nil { + return detailed, err + } + for _, action := range u32.Actions { + if action, ok := action.(*MirredAction); ok { + u32.RedirIndex = int(action.Ifindex) + } + } + case nl.TCA_U32_CLASSID: + u32.ClassId = native.Uint32(datum.Value) + } + } + return detailed, nil +} + +func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { + native = nl.NativeEndian() + fw := filter.(*Fw) + detailed := true + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_FW_MASK: + fw.Mask = native.Uint32(datum.Value[0:4]) + case nl.TCA_FW_CLASSID: + fw.ClassId = native.Uint32(datum.Value[0:4]) + case nl.TCA_FW_INDEV: + fw.InDev = string(datum.Value[:len(datum.Value)-1]) + case nl.TCA_FW_POLICE: + adata, _ := nl.ParseRouteAttr(datum.Value) + for _, aattr := range adata { + switch aattr.Attr.Type { + case nl.TCA_POLICE_TBF: + fw.Police = *nl.DeserializeTcPolice(aattr.Value) + case nl.TCA_POLICE_RATE: + fw.Rtab = DeserializeRtab(aattr.Value) + case nl.TCA_POLICE_PEAKRATE: + fw.Ptab = DeserializeRtab(aattr.Value) + } + } + } + } + return detailed, nil +} + +func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { + native = nl.NativeEndian() + bpf := filter.(*BpfFilter) + detailed := true + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_BPF_FD: + bpf.Fd = int(native.Uint32(datum.Value[0:4])) + case nl.TCA_BPF_NAME: + bpf.Name = string(datum.Value[:len(datum.Value)-1]) + case nl.TCA_BPF_CLASSID: + bpf.ClassId = native.Uint32(datum.Value[0:4]) + case nl.TCA_BPF_FLAGS: + flags := native.Uint32(datum.Value[0:4]) + if (flags & nl.TCA_BPF_FLAG_ACT_DIRECT) != 0 { + bpf.DirectAction = true + } + } + } + return detailed, nil +} + +func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { + native = nl.NativeEndian() + matchall := filter.(*MatchAll) + detailed := true + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_MATCHALL_CLASSID: + matchall.ClassId = native.Uint32(datum.Value[0:4]) + case nl.TCA_MATCHALL_ACT: + tables, err := nl.ParseRouteAttr(datum.Value) + if err != nil { + return detailed, err + } + matchall.Actions, err = parseActions(tables) + if err != nil { + return detailed, err + } + } + } + return detailed, nil +} + +func AlignToAtm(size uint) uint { + var linksize, cells int + cells = int(size / nl.ATM_CELL_PAYLOAD) + if (size % nl.ATM_CELL_PAYLOAD) > 0 { + cells++ + } + linksize = cells * nl.ATM_CELL_SIZE + return uint(linksize) +} + +func AdjustSize(sz uint, mpu uint, linklayer int) uint { + if sz < mpu { + sz = mpu + } + switch linklayer { + case nl.LINKLAYER_ATM: + return AlignToAtm(sz) + default: + return sz + } +} + +func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, linklayer int) int { + bps := rate.Rate + mpu := rate.Mpu + var sz uint + if mtu == 0 { + mtu = 2047 + } + if cellLog < 0 { + cellLog = 0 + for (mtu >> uint(cellLog)) > 255 { + cellLog++ + } + } + for i := 0; i < 256; i++ { + sz = AdjustSize(uint((i+1)<<uint32(cellLog)), uint(mpu), linklayer) + rtab[i] = uint32(Xmittime(uint64(bps), uint32(sz))) + } + rate.CellAlign = -1 + rate.CellLog = uint8(cellLog) + rate.Linklayer = uint8(linklayer & nl.TC_LINKLAYER_MASK) + return cellLog +} + +func DeserializeRtab(b []byte) [256]uint32 { + var rtab [256]uint32 + native := nl.NativeEndian() + r := bytes.NewReader(b) + _ = binary.Read(r, native, &rtab) + return rtab +} + +func SerializeRtab(rtab [256]uint32) []byte { + native := nl.NativeEndian() + var w bytes.Buffer + _ = binary.Write(&w, native, rtab) + return w.Bytes() +} diff --git a/vendor/github.com/vishvananda/netlink/fou.go b/vendor/github.com/vishvananda/netlink/fou.go new file mode 100644 index 0000000000000000000000000000000000000000..71e73c37a0a33753b5df5d0d4e82d40ead8d4864 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/fou.go @@ -0,0 +1,21 @@ +package netlink + +import ( + "errors" +) + +var ( + // ErrAttrHeaderTruncated is returned when a netlink attribute's header is + // truncated. + ErrAttrHeaderTruncated = errors.New("attribute header truncated") + // ErrAttrBodyTruncated is returned when a netlink attribute's body is + // truncated. + ErrAttrBodyTruncated = errors.New("attribute body truncated") +) + +type Fou struct { + Family int + Port int + Protocol int + EncapType int +} diff --git a/vendor/github.com/vishvananda/netlink/fou_linux.go b/vendor/github.com/vishvananda/netlink/fou_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..62d59bd2d0935a442d88fb2da50fc41d45a2b13c --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/fou_linux.go @@ -0,0 +1,215 @@ +// +build linux + +package netlink + +import ( + "encoding/binary" + "errors" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +const ( + FOU_GENL_NAME = "fou" +) + +const ( + FOU_CMD_UNSPEC uint8 = iota + FOU_CMD_ADD + FOU_CMD_DEL + FOU_CMD_GET + FOU_CMD_MAX = FOU_CMD_GET +) + +const ( + FOU_ATTR_UNSPEC = iota + FOU_ATTR_PORT + FOU_ATTR_AF + FOU_ATTR_IPPROTO + FOU_ATTR_TYPE + FOU_ATTR_REMCSUM_NOPARTIAL + FOU_ATTR_MAX = FOU_ATTR_REMCSUM_NOPARTIAL +) + +const ( + FOU_ENCAP_UNSPEC = iota + FOU_ENCAP_DIRECT + FOU_ENCAP_GUE + FOU_ENCAP_MAX = FOU_ENCAP_GUE +) + +var fouFamilyId int + +func FouFamilyId() (int, error) { + if fouFamilyId != 0 { + return fouFamilyId, nil + } + + fam, err := GenlFamilyGet(FOU_GENL_NAME) + if err != nil { + return -1, err + } + + fouFamilyId = int(fam.ID) + return fouFamilyId, nil +} + +func FouAdd(f Fou) error { + return pkgHandle.FouAdd(f) +} + +func (h *Handle) FouAdd(f Fou) error { + fam_id, err := FouFamilyId() + if err != nil { + return err + } + + // setting ip protocol conflicts with encapsulation type GUE + if f.EncapType == FOU_ENCAP_GUE && f.Protocol != 0 { + return errors.New("GUE encapsulation doesn't specify an IP protocol") + } + + req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK) + + // int to byte for port + bp := make([]byte, 2) + binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port)) + + attrs := []*nl.RtAttr{ + nl.NewRtAttr(FOU_ATTR_PORT, bp), + nl.NewRtAttr(FOU_ATTR_TYPE, []byte{uint8(f.EncapType)}), + nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}), + nl.NewRtAttr(FOU_ATTR_IPPROTO, []byte{uint8(f.Protocol)}), + } + raw := []byte{FOU_CMD_ADD, 1, 0, 0} + for _, a := range attrs { + raw = append(raw, a.Serialize()...) + } + + req.AddRawData(raw) + + _, err = req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return err + } + + return nil +} + +func FouDel(f Fou) error { + return pkgHandle.FouDel(f) +} + +func (h *Handle) FouDel(f Fou) error { + fam_id, err := FouFamilyId() + if err != nil { + return err + } + + req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK) + + // int to byte for port + bp := make([]byte, 2) + binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port)) + + attrs := []*nl.RtAttr{ + nl.NewRtAttr(FOU_ATTR_PORT, bp), + nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}), + } + raw := []byte{FOU_CMD_DEL, 1, 0, 0} + for _, a := range attrs { + raw = append(raw, a.Serialize()...) + } + + req.AddRawData(raw) + + _, err = req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return err + } + + return nil +} + +func FouList(fam int) ([]Fou, error) { + return pkgHandle.FouList(fam) +} + +func (h *Handle) FouList(fam int) ([]Fou, error) { + fam_id, err := FouFamilyId() + if err != nil { + return nil, err + } + + req := h.newNetlinkRequest(fam_id, unix.NLM_F_DUMP) + + attrs := []*nl.RtAttr{ + nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(fam)}), + } + raw := []byte{FOU_CMD_GET, 1, 0, 0} + for _, a := range attrs { + raw = append(raw, a.Serialize()...) + } + + req.AddRawData(raw) + + msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return nil, err + } + + fous := make([]Fou, 0, len(msgs)) + for _, m := range msgs { + f, err := deserializeFouMsg(m) + if err != nil { + return fous, err + } + + fous = append(fous, f) + } + + return fous, nil +} + +func deserializeFouMsg(msg []byte) (Fou, error) { + // we'll skip to byte 4 to first attribute + msg = msg[3:] + var shift int + fou := Fou{} + + for { + // attribute header is at least 16 bits + if len(msg) < 4 { + return fou, ErrAttrHeaderTruncated + } + + lgt := int(binary.BigEndian.Uint16(msg[0:2])) + if len(msg) < lgt+4 { + return fou, ErrAttrBodyTruncated + } + attr := binary.BigEndian.Uint16(msg[2:4]) + + shift = lgt + 3 + switch attr { + case FOU_ATTR_AF: + fou.Family = int(msg[5]) + case FOU_ATTR_PORT: + fou.Port = int(binary.BigEndian.Uint16(msg[5:7])) + // port is 2 bytes + shift = lgt + 2 + case FOU_ATTR_IPPROTO: + fou.Protocol = int(msg[5]) + case FOU_ATTR_TYPE: + fou.EncapType = int(msg[5]) + } + + msg = msg[shift:] + + if len(msg) < 4 { + break + } + } + + return fou, nil +} diff --git a/vendor/github.com/vishvananda/netlink/fou_unspecified.go b/vendor/github.com/vishvananda/netlink/fou_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..3a8365bfe6232d22fbbb05b141439c14615193f6 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/fou_unspecified.go @@ -0,0 +1,15 @@ +// +build !linux + +package netlink + +func FouAdd(f Fou) error { + return ErrNotImplemented +} + +func FouDel(f Fou) error { + return ErrNotImplemented +} + +func FouList(fam int) ([]Fou, error) { + return nil, ErrNotImplemented +} diff --git a/vendor/github.com/vishvananda/netlink/genetlink_linux.go b/vendor/github.com/vishvananda/netlink/genetlink_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..ce7969907d4307014dcb851e0669d094682e0324 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/genetlink_linux.go @@ -0,0 +1,168 @@ +package netlink + +import ( + "fmt" + "syscall" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +type GenlOp struct { + ID uint32 + Flags uint32 +} + +type GenlMulticastGroup struct { + ID uint32 + Name string +} + +type GenlFamily struct { + ID uint16 + HdrSize uint32 + Name string + Version uint32 + MaxAttr uint32 + Ops []GenlOp + Groups []GenlMulticastGroup +} + +func parseOps(b []byte) ([]GenlOp, error) { + attrs, err := nl.ParseRouteAttr(b) + if err != nil { + return nil, err + } + ops := make([]GenlOp, 0, len(attrs)) + for _, a := range attrs { + nattrs, err := nl.ParseRouteAttr(a.Value) + if err != nil { + return nil, err + } + var op GenlOp + for _, na := range nattrs { + switch na.Attr.Type { + case nl.GENL_CTRL_ATTR_OP_ID: + op.ID = native.Uint32(na.Value) + case nl.GENL_CTRL_ATTR_OP_FLAGS: + op.Flags = native.Uint32(na.Value) + } + } + ops = append(ops, op) + } + return ops, nil +} + +func parseMulticastGroups(b []byte) ([]GenlMulticastGroup, error) { + attrs, err := nl.ParseRouteAttr(b) + if err != nil { + return nil, err + } + groups := make([]GenlMulticastGroup, 0, len(attrs)) + for _, a := range attrs { + nattrs, err := nl.ParseRouteAttr(a.Value) + if err != nil { + return nil, err + } + var g GenlMulticastGroup + for _, na := range nattrs { + switch na.Attr.Type { + case nl.GENL_CTRL_ATTR_MCAST_GRP_NAME: + g.Name = nl.BytesToString(na.Value) + case nl.GENL_CTRL_ATTR_MCAST_GRP_ID: + g.ID = native.Uint32(na.Value) + } + } + groups = append(groups, g) + } + return groups, nil +} + +func (f *GenlFamily) parseAttributes(attrs []syscall.NetlinkRouteAttr) error { + for _, a := range attrs { + switch a.Attr.Type { + case nl.GENL_CTRL_ATTR_FAMILY_NAME: + f.Name = nl.BytesToString(a.Value) + case nl.GENL_CTRL_ATTR_FAMILY_ID: + f.ID = native.Uint16(a.Value) + case nl.GENL_CTRL_ATTR_VERSION: + f.Version = native.Uint32(a.Value) + case nl.GENL_CTRL_ATTR_HDRSIZE: + f.HdrSize = native.Uint32(a.Value) + case nl.GENL_CTRL_ATTR_MAXATTR: + f.MaxAttr = native.Uint32(a.Value) + case nl.GENL_CTRL_ATTR_OPS: + ops, err := parseOps(a.Value) + if err != nil { + return err + } + f.Ops = ops + case nl.GENL_CTRL_ATTR_MCAST_GROUPS: + groups, err := parseMulticastGroups(a.Value) + if err != nil { + return err + } + f.Groups = groups + } + } + + return nil +} + +func parseFamilies(msgs [][]byte) ([]*GenlFamily, error) { + families := make([]*GenlFamily, 0, len(msgs)) + for _, m := range msgs { + attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) + if err != nil { + return nil, err + } + family := &GenlFamily{} + if err := family.parseAttributes(attrs); err != nil { + return nil, err + } + + families = append(families, family) + } + return families, nil +} + +func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) { + msg := &nl.Genlmsg{ + Command: nl.GENL_CTRL_CMD_GETFAMILY, + Version: nl.GENL_CTRL_VERSION, + } + req := h.newNetlinkRequest(nl.GENL_ID_CTRL, unix.NLM_F_DUMP) + req.AddData(msg) + msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return nil, err + } + return parseFamilies(msgs) +} + +func GenlFamilyList() ([]*GenlFamily, error) { + return pkgHandle.GenlFamilyList() +} + +func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) { + msg := &nl.Genlmsg{ + Command: nl.GENL_CTRL_CMD_GETFAMILY, + Version: nl.GENL_CTRL_VERSION, + } + req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name))) + msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return nil, err + } + families, err := parseFamilies(msgs) + if len(families) != 1 { + return nil, fmt.Errorf("invalid response for GENL_CTRL_CMD_GETFAMILY") + } + return families[0], nil +} + +func GenlFamilyGet(name string) (*GenlFamily, error) { + return pkgHandle.GenlFamilyGet(name) +} diff --git a/vendor/github.com/vishvananda/netlink/genetlink_unspecified.go b/vendor/github.com/vishvananda/netlink/genetlink_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..0192b991e312d83ab725f9b4d9cc2e3f9ab74fe9 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/genetlink_unspecified.go @@ -0,0 +1,25 @@ +// +build !linux + +package netlink + +type GenlOp struct{} + +type GenlMulticastGroup struct{} + +type GenlFamily struct{} + +func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) { + return nil, ErrNotImplemented +} + +func GenlFamilyList() ([]*GenlFamily, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) { + return nil, ErrNotImplemented +} + +func GenlFamilyGet(name string) (*GenlFamily, error) { + return nil, ErrNotImplemented +} diff --git a/vendor/github.com/vishvananda/netlink/gtp_linux.go b/vendor/github.com/vishvananda/netlink/gtp_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..f5e160ba5c0656f3cd974c9d43b0e418d5445ae8 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/gtp_linux.go @@ -0,0 +1,239 @@ +package netlink + +import ( + "fmt" + "net" + "strings" + "syscall" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +type PDP struct { + Version uint32 + TID uint64 + PeerAddress net.IP + MSAddress net.IP + Flow uint16 + NetNSFD uint32 + ITEI uint32 + OTEI uint32 +} + +func (pdp *PDP) String() string { + elems := []string{} + elems = append(elems, fmt.Sprintf("Version: %d", pdp.Version)) + if pdp.Version == 0 { + elems = append(elems, fmt.Sprintf("TID: %d", pdp.TID)) + } else if pdp.Version == 1 { + elems = append(elems, fmt.Sprintf("TEI: %d/%d", pdp.ITEI, pdp.OTEI)) + } + elems = append(elems, fmt.Sprintf("MS-Address: %s", pdp.MSAddress)) + elems = append(elems, fmt.Sprintf("Peer-Address: %s", pdp.PeerAddress)) + return fmt.Sprintf("{%s}", strings.Join(elems, " ")) +} + +func (p *PDP) parseAttributes(attrs []syscall.NetlinkRouteAttr) error { + for _, a := range attrs { + switch a.Attr.Type { + case nl.GENL_GTP_ATTR_VERSION: + p.Version = native.Uint32(a.Value) + case nl.GENL_GTP_ATTR_TID: + p.TID = native.Uint64(a.Value) + case nl.GENL_GTP_ATTR_PEER_ADDRESS: + p.PeerAddress = net.IP(a.Value) + case nl.GENL_GTP_ATTR_MS_ADDRESS: + p.MSAddress = net.IP(a.Value) + case nl.GENL_GTP_ATTR_FLOW: + p.Flow = native.Uint16(a.Value) + case nl.GENL_GTP_ATTR_NET_NS_FD: + p.NetNSFD = native.Uint32(a.Value) + case nl.GENL_GTP_ATTR_I_TEI: + p.ITEI = native.Uint32(a.Value) + case nl.GENL_GTP_ATTR_O_TEI: + p.OTEI = native.Uint32(a.Value) + } + } + return nil +} + +func parsePDP(msgs [][]byte) ([]*PDP, error) { + pdps := make([]*PDP, 0, len(msgs)) + for _, m := range msgs { + attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) + if err != nil { + return nil, err + } + pdp := &PDP{} + if err := pdp.parseAttributes(attrs); err != nil { + return nil, err + } + pdps = append(pdps, pdp) + } + return pdps, nil +} + +func (h *Handle) GTPPDPList() ([]*PDP, error) { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return nil, err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_GETPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_DUMP) + req.AddData(msg) + msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return nil, err + } + return parsePDP(msgs) +} + +func GTPPDPList() ([]*PDP, error) { + return pkgHandle.GTPPDPList() +} + +func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) { + msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) + if err != nil { + return nil, err + } + pdps, err := parsePDP(msgs) + if err != nil { + return nil, err + } + if len(pdps) != 1 { + return nil, fmt.Errorf("invalid reqponse for GENL_GTP_CMD_GETPDP") + } + return pdps[0], nil +} + +func (h *Handle) GTPPDPByTID(link Link, tid int) (*PDP, error) { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return nil, err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_GETPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), 0) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(0))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index)))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(uint64(tid)))) + return gtpPDPGet(req) +} + +func GTPPDPByTID(link Link, tid int) (*PDP, error) { + return pkgHandle.GTPPDPByTID(link, tid) +} + +func (h *Handle) GTPPDPByITEI(link Link, itei int) (*PDP, error) { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return nil, err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_GETPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), 0) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(1))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index)))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(uint32(itei)))) + return gtpPDPGet(req) +} + +func GTPPDPByITEI(link Link, itei int) (*PDP, error) { + return pkgHandle.GTPPDPByITEI(link, itei) +} + +func (h *Handle) GTPPDPByMSAddress(link Link, addr net.IP) (*PDP, error) { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return nil, err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_GETPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), 0) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(0))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index)))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_MS_ADDRESS, []byte(addr.To4()))) + return gtpPDPGet(req) +} + +func GTPPDPByMSAddress(link Link, addr net.IP) (*PDP, error) { + return pkgHandle.GTPPDPByMSAddress(link, addr) +} + +func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_NEWPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index)))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_PEER_ADDRESS, []byte(pdp.PeerAddress.To4()))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_MS_ADDRESS, []byte(pdp.MSAddress.To4()))) + + switch pdp.Version { + case 0: + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(pdp.TID))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_FLOW, nl.Uint16Attr(pdp.Flow))) + case 1: + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(pdp.ITEI))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_O_TEI, nl.Uint32Attr(pdp.OTEI))) + default: + return fmt.Errorf("unsupported GTP version: %d", pdp.Version) + } + _, err = req.Execute(unix.NETLINK_GENERIC, 0) + return err +} + +func GTPPDPAdd(link Link, pdp *PDP) error { + return pkgHandle.GTPPDPAdd(link, pdp) +} + +func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error { + f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME) + if err != nil { + return err + } + msg := &nl.Genlmsg{ + Command: nl.GENL_GTP_CMD_DELPDP, + Version: nl.GENL_GTP_VERSION, + } + req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK) + req.AddData(msg) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version))) + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index)))) + + switch pdp.Version { + case 0: + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(pdp.TID))) + case 1: + req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(pdp.ITEI))) + default: + return fmt.Errorf("unsupported GTP version: %d", pdp.Version) + } + _, err = req.Execute(unix.NETLINK_GENERIC, 0) + return err +} + +func GTPPDPDel(link Link, pdp *PDP) error { + return pkgHandle.GTPPDPDel(link, pdp) +} diff --git a/vendor/github.com/vishvananda/netlink/handle_linux.go b/vendor/github.com/vishvananda/netlink/handle_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..9f6d7fe0fbd1af7bd075fa3d71a86d0b0de0d35d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/handle_linux.go @@ -0,0 +1,144 @@ +package netlink + +import ( + "fmt" + "time" + + "github.com/vishvananda/netlink/nl" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +// Empty handle used by the netlink package methods +var pkgHandle = &Handle{} + +// Handle is an handle for the netlink requests on a +// specific network namespace. All the requests on the +// same netlink family share the same netlink socket, +// which gets released when the handle is deleted. +type Handle struct { + sockets map[int]*nl.SocketHandle + lookupByDump bool +} + +// SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle +func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool { + _, ok := h.sockets[nlFamily] + return ok +} + +// NewHandle returns a netlink handle on the current network namespace. +// Caller may specify the netlink families the handle should support. +// If no families are specified, all the families the netlink package +// supports will be automatically added. +func NewHandle(nlFamilies ...int) (*Handle, error) { + return newHandle(netns.None(), netns.None(), nlFamilies...) +} + +// SetSocketTimeout sets the send and receive timeout for each socket in the +// netlink handle. Although the socket timeout has granularity of one +// microsecond, the effective granularity is floored by the kernel timer tick, +// which default value is four milliseconds. +func (h *Handle) SetSocketTimeout(to time.Duration) error { + if to < time.Microsecond { + return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond) + } + tv := unix.NsecToTimeval(to.Nanoseconds()) + for _, sh := range h.sockets { + if err := sh.Socket.SetSendTimeout(&tv); err != nil { + return err + } + if err := sh.Socket.SetReceiveTimeout(&tv); err != nil { + return err + } + } + return nil +} + +// SetSocketReceiveBufferSize sets the receive buffer size for each +// socket in the netlink handle. The maximum value is capped by +// /proc/sys/net/core/rmem_max. +func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error { + opt := unix.SO_RCVBUF + if force { + opt = unix.SO_RCVBUFFORCE + } + for _, sh := range h.sockets { + fd := sh.Socket.GetFd() + err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, opt, size) + if err != nil { + return err + } + } + return nil +} + +// GetSocketReceiveBufferSize gets the receiver buffer size for each +// socket in the netlink handle. The retrieved value should be the +// double to the one set for SetSocketReceiveBufferSize. +func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) { + results := make([]int, len(h.sockets)) + i := 0 + for _, sh := range h.sockets { + fd := sh.Socket.GetFd() + size, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF) + if err != nil { + return nil, err + } + results[i] = size + i++ + } + return results, nil +} + +// NewHandle returns a netlink handle on the network namespace +// specified by ns. If ns=netns.None(), current network namespace +// will be assumed +func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) { + return newHandle(ns, netns.None(), nlFamilies...) +} + +// NewHandleAtFrom works as NewHandle but allows client to specify the +// new and the origin netns Handle. +func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) { + return newHandle(newNs, curNs) +} + +func newHandle(newNs, curNs netns.NsHandle, nlFamilies ...int) (*Handle, error) { + h := &Handle{sockets: map[int]*nl.SocketHandle{}} + fams := nl.SupportedNlFamilies + if len(nlFamilies) != 0 { + fams = nlFamilies + } + for _, f := range fams { + s, err := nl.GetNetlinkSocketAt(newNs, curNs, f) + if err != nil { + return nil, err + } + h.sockets[f] = &nl.SocketHandle{Socket: s} + } + return h, nil +} + +// Delete releases the resources allocated to this handle +func (h *Handle) Delete() { + for _, sh := range h.sockets { + sh.Close() + } + h.sockets = nil +} + +func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest { + // Do this so that package API still use nl package variable nextSeqNr + if h.sockets == nil { + return nl.NewNetlinkRequest(proto, flags) + } + return &nl.NetlinkRequest{ + NlMsghdr: unix.NlMsghdr{ + Len: uint32(unix.SizeofNlMsghdr), + Type: uint16(proto), + Flags: unix.NLM_F_REQUEST | uint16(flags), + }, + Sockets: h.sockets, + } +} diff --git a/vendor/github.com/vishvananda/netlink/handle_unspecified.go b/vendor/github.com/vishvananda/netlink/handle_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..915b765ded778ccd9ad6f6731063671a4ee2ea9d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/handle_unspecified.go @@ -0,0 +1,258 @@ +// +build !linux + +package netlink + +import ( + "net" + "time" + + "github.com/vishvananda/netns" +) + +type Handle struct{} + +func NewHandle(nlFamilies ...int) (*Handle, error) { + return nil, ErrNotImplemented +} + +func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) { + return nil, ErrNotImplemented +} + +func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) Delete() {} + +func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool { + return false +} + +func (h *Handle) SetSocketTimeout(to time.Duration) error { + return ErrNotImplemented +} + +func (h *Handle) SetPromiscOn(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) SetPromiscOff(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetUp(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetDown(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetMTU(link Link, mtu int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetName(link Link, name string) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetAlias(link Link, name string) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetMaster(link Link, master *Bridge) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetNoMaster(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetNsPid(link Link, nspid int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetNsFd(link Link, fd int) error { + return ErrNotImplemented +} + +func (h *Handle) LinkAdd(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkDel(link Link) error { + return ErrNotImplemented +} + +func (h *Handle) LinkByName(name string) (Link, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) LinkByAlias(alias string) (Link, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) LinkByIndex(index int) (Link, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) LinkList() ([]Link, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) LinkSetHairpin(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetGuard(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetFastLeave(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetLearning(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetRootBlock(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetFlood(link Link, mode bool) error { + return ErrNotImplemented +} + +func (h *Handle) LinkSetTxQLen(link Link, qlen int) error { + return ErrNotImplemented +} + +func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error { + return ErrNotImplemented +} + +func (h *Handle) AddrAdd(link Link, addr *Addr) error { + return ErrNotImplemented +} + +func (h *Handle) AddrDel(link Link, addr *Addr) error { + return ErrNotImplemented +} + +func (h *Handle) AddrList(link Link, family int) ([]Addr, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) ClassDel(class Class) error { + return ErrNotImplemented +} + +func (h *Handle) ClassChange(class Class) error { + return ErrNotImplemented +} + +func (h *Handle) ClassReplace(class Class) error { + return ErrNotImplemented +} + +func (h *Handle) ClassAdd(class Class) error { + return ErrNotImplemented +} + +func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) FilterDel(filter Filter) error { + return ErrNotImplemented +} + +func (h *Handle) FilterAdd(filter Filter) error { + return ErrNotImplemented +} + +func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) NeighAdd(neigh *Neigh) error { + return ErrNotImplemented +} + +func (h *Handle) NeighSet(neigh *Neigh) error { + return ErrNotImplemented +} + +func (h *Handle) NeighAppend(neigh *Neigh) error { + return ErrNotImplemented +} + +func (h *Handle) NeighDel(neigh *Neigh) error { + return ErrNotImplemented +} + +func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) RouteAdd(route *Route) error { + return ErrNotImplemented +} + +func (h *Handle) RouteDel(route *Route) error { + return ErrNotImplemented +} + +func (h *Handle) RouteGet(destination net.IP) ([]Route, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) RouteList(link Link, family int) ([]Route, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { + return nil, ErrNotImplemented +} + +func (h *Handle) RouteReplace(route *Route) error { + return ErrNotImplemented +} + +func (h *Handle) RuleAdd(rule *Rule) error { + return ErrNotImplemented +} + +func (h *Handle) RuleDel(rule *Rule) error { + return ErrNotImplemented +} + +func (h *Handle) RuleList(family int) ([]Rule, error) { + return nil, ErrNotImplemented +} diff --git a/vendor/github.com/vishvananda/netlink/ioctl_linux.go b/vendor/github.com/vishvananda/netlink/ioctl_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..a8503126d56081c798aaaa589b72121892191e76 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/ioctl_linux.go @@ -0,0 +1,98 @@ +package netlink + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +// ioctl for statistics. +const ( + // ETHTOOL_GSSET_INFO gets string set info + ETHTOOL_GSSET_INFO = 0x00000037 + // SIOCETHTOOL is Ethtool interface + SIOCETHTOOL = 0x8946 + // ETHTOOL_GSTRINGS gets specified string set + ETHTOOL_GSTRINGS = 0x0000001b + // ETHTOOL_GSTATS gets NIC-specific statistics + ETHTOOL_GSTATS = 0x0000001d +) + +// string set id. +const ( + // ETH_SS_TEST is self-test result names, for use with %ETHTOOL_TEST + ETH_SS_TEST = iota + // ETH_SS_STATS statistic names, for use with %ETHTOOL_GSTATS + ETH_SS_STATS + // ETH_SS_PRIV_FLAGS are driver private flag names + ETH_SS_PRIV_FLAGS + // _ETH_SS_NTUPLE_FILTERS is deprecated + _ETH_SS_NTUPLE_FILTERS + // ETH_SS_FEATURES are device feature names + ETH_SS_FEATURES + // ETH_SS_RSS_HASH_FUNCS is RSS hush function names + ETH_SS_RSS_HASH_FUNCS +) + +// IfreqSlave is a struct for ioctl bond manipulation syscalls. +// It is used to assign slave to bond interface with Name. +type IfreqSlave struct { + Name [unix.IFNAMSIZ]byte + Slave [unix.IFNAMSIZ]byte +} + +// Ifreq is a struct for ioctl ethernet manipulation syscalls. +type Ifreq struct { + Name [unix.IFNAMSIZ]byte + Data uintptr +} + +// ethtoolSset is a string set information +type ethtoolSset struct { + cmd uint32 + reserved uint32 + mask uint64 + data [1]uint32 +} + +// ethtoolGstrings is string set for data tagging +type ethtoolGstrings struct { + cmd uint32 + stringSet uint32 + length uint32 + data [32]byte +} + +type ethtoolStats struct { + cmd uint32 + nStats uint32 + data [1]uint64 +} + +// newIocltSlaveReq returns filled IfreqSlave with proper interface names +// It is used by ioctl to assign slave to bond master +func newIocltSlaveReq(slave, master string) *IfreqSlave { + ifreq := &IfreqSlave{} + copy(ifreq.Name[:unix.IFNAMSIZ-1], master) + copy(ifreq.Slave[:unix.IFNAMSIZ-1], slave) + return ifreq +} + +// newIocltStringSetReq creates request to get interface string set +func newIocltStringSetReq(linkName string) (*Ifreq, *ethtoolSset) { + e := ðtoolSset{ + cmd: ETHTOOL_GSSET_INFO, + mask: 1 << ETH_SS_STATS, + } + + ifreq := &Ifreq{Data: uintptr(unsafe.Pointer(e))} + copy(ifreq.Name[:unix.IFNAMSIZ-1], linkName) + return ifreq, e +} + +// getSocketUDP returns file descriptor to new UDP socket +// It is used for communication with ioctl interface. +func getSocketUDP() (int, error) { + return syscall.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) +} diff --git a/vendor/github.com/vishvananda/netlink/link.go b/vendor/github.com/vishvananda/netlink/link.go new file mode 100644 index 0000000000000000000000000000000000000000..fe74ffab964081b4c5d90f52ce118e5ee3f1db67 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/link.go @@ -0,0 +1,846 @@ +package netlink + +import ( + "fmt" + "net" + "os" +) + +// Link represents a link device from netlink. Shared link attributes +// like name may be retrieved using the Attrs() method. Unique data +// can be retrieved by casting the object to the proper type. +type Link interface { + Attrs() *LinkAttrs + Type() string +} + +type ( + NsPid int + NsFd int +) + +// LinkAttrs represents data shared by most link types +type LinkAttrs struct { + Index int + MTU int + TxQLen int // Transmit Queue Length + Name string + HardwareAddr net.HardwareAddr + Flags net.Flags + RawFlags uint32 + ParentIndex int // index of the parent link device + MasterIndex int // must be the index of a bridge + Namespace interface{} // nil | NsPid | NsFd + Alias string + Statistics *LinkStatistics + Promisc int + Xdp *LinkXdp + EncapType string + Protinfo *Protinfo + OperState LinkOperState + NetNsID int + NumTxQueues int + NumRxQueues int +} + +// LinkOperState represents the values of the IFLA_OPERSTATE link +// attribute, which contains the RFC2863 state of the interface. +type LinkOperState uint8 + +const ( + OperUnknown = iota // Status can't be determined. + OperNotPresent // Some component is missing. + OperDown // Down. + OperLowerLayerDown // Down due to state of lower layer. + OperTesting // In some test mode. + OperDormant // Not up but pending an external event. + OperUp // Up, ready to send packets. +) + +func (s LinkOperState) String() string { + switch s { + case OperNotPresent: + return "not-present" + case OperDown: + return "down" + case OperLowerLayerDown: + return "lower-layer-down" + case OperTesting: + return "testing" + case OperDormant: + return "dormant" + case OperUp: + return "up" + default: + return "unknown" + } +} + +// NewLinkAttrs returns LinkAttrs structure filled with default values +func NewLinkAttrs() LinkAttrs { + return LinkAttrs{ + TxQLen: -1, + } +} + +type LinkStatistics LinkStatistics64 + +/* +Ref: struct rtnl_link_stats {...} +*/ +type LinkStatistics32 struct { + RxPackets uint32 + TxPackets uint32 + RxBytes uint32 + TxBytes uint32 + RxErrors uint32 + TxErrors uint32 + RxDropped uint32 + TxDropped uint32 + Multicast uint32 + Collisions uint32 + RxLengthErrors uint32 + RxOverErrors uint32 + RxCrcErrors uint32 + RxFrameErrors uint32 + RxFifoErrors uint32 + RxMissedErrors uint32 + TxAbortedErrors uint32 + TxCarrierErrors uint32 + TxFifoErrors uint32 + TxHeartbeatErrors uint32 + TxWindowErrors uint32 + RxCompressed uint32 + TxCompressed uint32 +} + +func (s32 LinkStatistics32) to64() *LinkStatistics64 { + return &LinkStatistics64{ + RxPackets: uint64(s32.RxPackets), + TxPackets: uint64(s32.TxPackets), + RxBytes: uint64(s32.RxBytes), + TxBytes: uint64(s32.TxBytes), + RxErrors: uint64(s32.RxErrors), + TxErrors: uint64(s32.TxErrors), + RxDropped: uint64(s32.RxDropped), + TxDropped: uint64(s32.TxDropped), + Multicast: uint64(s32.Multicast), + Collisions: uint64(s32.Collisions), + RxLengthErrors: uint64(s32.RxLengthErrors), + RxOverErrors: uint64(s32.RxOverErrors), + RxCrcErrors: uint64(s32.RxCrcErrors), + RxFrameErrors: uint64(s32.RxFrameErrors), + RxFifoErrors: uint64(s32.RxFifoErrors), + RxMissedErrors: uint64(s32.RxMissedErrors), + TxAbortedErrors: uint64(s32.TxAbortedErrors), + TxCarrierErrors: uint64(s32.TxCarrierErrors), + TxFifoErrors: uint64(s32.TxFifoErrors), + TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors), + TxWindowErrors: uint64(s32.TxWindowErrors), + RxCompressed: uint64(s32.RxCompressed), + TxCompressed: uint64(s32.TxCompressed), + } +} + +/* +Ref: struct rtnl_link_stats64 {...} +*/ +type LinkStatistics64 struct { + RxPackets uint64 + TxPackets uint64 + RxBytes uint64 + TxBytes uint64 + RxErrors uint64 + TxErrors uint64 + RxDropped uint64 + TxDropped uint64 + Multicast uint64 + Collisions uint64 + RxLengthErrors uint64 + RxOverErrors uint64 + RxCrcErrors uint64 + RxFrameErrors uint64 + RxFifoErrors uint64 + RxMissedErrors uint64 + TxAbortedErrors uint64 + TxCarrierErrors uint64 + TxFifoErrors uint64 + TxHeartbeatErrors uint64 + TxWindowErrors uint64 + RxCompressed uint64 + TxCompressed uint64 +} + +type LinkXdp struct { + Fd int + Attached bool + Flags uint32 + ProgId uint32 +} + +// Device links cannot be created via netlink. These links +// are links created by udev like 'lo' and 'etho0' +type Device struct { + LinkAttrs +} + +func (device *Device) Attrs() *LinkAttrs { + return &device.LinkAttrs +} + +func (device *Device) Type() string { + return "device" +} + +// Dummy links are dummy ethernet devices +type Dummy struct { + LinkAttrs +} + +func (dummy *Dummy) Attrs() *LinkAttrs { + return &dummy.LinkAttrs +} + +func (dummy *Dummy) Type() string { + return "dummy" +} + +// Ifb links are advanced dummy devices for packet filtering +type Ifb struct { + LinkAttrs +} + +func (ifb *Ifb) Attrs() *LinkAttrs { + return &ifb.LinkAttrs +} + +func (ifb *Ifb) Type() string { + return "ifb" +} + +// Bridge links are simple linux bridges +type Bridge struct { + LinkAttrs + MulticastSnooping *bool + HelloTime *uint32 +} + +func (bridge *Bridge) Attrs() *LinkAttrs { + return &bridge.LinkAttrs +} + +func (bridge *Bridge) Type() string { + return "bridge" +} + +// Vlan links have ParentIndex set in their Attrs() +type Vlan struct { + LinkAttrs + VlanId int +} + +func (vlan *Vlan) Attrs() *LinkAttrs { + return &vlan.LinkAttrs +} + +func (vlan *Vlan) Type() string { + return "vlan" +} + +type MacvlanMode uint16 + +const ( + MACVLAN_MODE_DEFAULT MacvlanMode = iota + MACVLAN_MODE_PRIVATE + MACVLAN_MODE_VEPA + MACVLAN_MODE_BRIDGE + MACVLAN_MODE_PASSTHRU + MACVLAN_MODE_SOURCE +) + +// Macvlan links have ParentIndex set in their Attrs() +type Macvlan struct { + LinkAttrs + Mode MacvlanMode + + // MACAddrs is only populated for Macvlan SOURCE links + MACAddrs []net.HardwareAddr +} + +func (macvlan *Macvlan) Attrs() *LinkAttrs { + return &macvlan.LinkAttrs +} + +func (macvlan *Macvlan) Type() string { + return "macvlan" +} + +// Macvtap - macvtap is a virtual interfaces based on macvlan +type Macvtap struct { + Macvlan +} + +func (macvtap Macvtap) Type() string { + return "macvtap" +} + +type TuntapMode uint16 +type TuntapFlag uint16 + +// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink +type Tuntap struct { + LinkAttrs + Mode TuntapMode + Flags TuntapFlag + Queues int + Fds []*os.File +} + +func (tuntap *Tuntap) Attrs() *LinkAttrs { + return &tuntap.LinkAttrs +} + +func (tuntap *Tuntap) Type() string { + return "tuntap" +} + +// Veth devices must specify PeerName on create +type Veth struct { + LinkAttrs + PeerName string // veth on create only +} + +func (veth *Veth) Attrs() *LinkAttrs { + return &veth.LinkAttrs +} + +func (veth *Veth) Type() string { + return "veth" +} + +// GenericLink links represent types that are not currently understood +// by this netlink library. +type GenericLink struct { + LinkAttrs + LinkType string +} + +func (generic *GenericLink) Attrs() *LinkAttrs { + return &generic.LinkAttrs +} + +func (generic *GenericLink) Type() string { + return generic.LinkType +} + +type Vxlan struct { + LinkAttrs + VxlanId int + VtepDevIndex int + SrcAddr net.IP + Group net.IP + TTL int + TOS int + Learning bool + Proxy bool + RSC bool + L2miss bool + L3miss bool + UDPCSum bool + UDP6ZeroCSumTx bool + UDP6ZeroCSumRx bool + NoAge bool + GBP bool + FlowBased bool + Age int + Limit int + Port int + PortLow int + PortHigh int +} + +func (vxlan *Vxlan) Attrs() *LinkAttrs { + return &vxlan.LinkAttrs +} + +func (vxlan *Vxlan) Type() string { + return "vxlan" +} + +type IPVlanMode uint16 + +const ( + IPVLAN_MODE_L2 IPVlanMode = iota + IPVLAN_MODE_L3 + IPVLAN_MODE_L3S + IPVLAN_MODE_MAX +) + +type IPVlan struct { + LinkAttrs + Mode IPVlanMode +} + +func (ipvlan *IPVlan) Attrs() *LinkAttrs { + return &ipvlan.LinkAttrs +} + +func (ipvlan *IPVlan) Type() string { + return "ipvlan" +} + +// BondMode type +type BondMode int + +func (b BondMode) String() string { + s, ok := bondModeToString[b] + if !ok { + return fmt.Sprintf("BondMode(%d)", b) + } + return s +} + +// StringToBondMode returns bond mode, or uknonw is the s is invalid. +func StringToBondMode(s string) BondMode { + mode, ok := StringToBondModeMap[s] + if !ok { + return BOND_MODE_UNKNOWN + } + return mode +} + +// Possible BondMode +const ( + BOND_MODE_BALANCE_RR BondMode = iota + BOND_MODE_ACTIVE_BACKUP + BOND_MODE_BALANCE_XOR + BOND_MODE_BROADCAST + BOND_MODE_802_3AD + BOND_MODE_BALANCE_TLB + BOND_MODE_BALANCE_ALB + BOND_MODE_UNKNOWN +) + +var bondModeToString = map[BondMode]string{ + BOND_MODE_BALANCE_RR: "balance-rr", + BOND_MODE_ACTIVE_BACKUP: "active-backup", + BOND_MODE_BALANCE_XOR: "balance-xor", + BOND_MODE_BROADCAST: "broadcast", + BOND_MODE_802_3AD: "802.3ad", + BOND_MODE_BALANCE_TLB: "balance-tlb", + BOND_MODE_BALANCE_ALB: "balance-alb", +} +var StringToBondModeMap = map[string]BondMode{ + "balance-rr": BOND_MODE_BALANCE_RR, + "active-backup": BOND_MODE_ACTIVE_BACKUP, + "balance-xor": BOND_MODE_BALANCE_XOR, + "broadcast": BOND_MODE_BROADCAST, + "802.3ad": BOND_MODE_802_3AD, + "balance-tlb": BOND_MODE_BALANCE_TLB, + "balance-alb": BOND_MODE_BALANCE_ALB, +} + +// BondArpValidate type +type BondArpValidate int + +// Possible BondArpValidate value +const ( + BOND_ARP_VALIDATE_NONE BondArpValidate = iota + BOND_ARP_VALIDATE_ACTIVE + BOND_ARP_VALIDATE_BACKUP + BOND_ARP_VALIDATE_ALL +) + +// BondPrimaryReselect type +type BondPrimaryReselect int + +// Possible BondPrimaryReselect value +const ( + BOND_PRIMARY_RESELECT_ALWAYS BondPrimaryReselect = iota + BOND_PRIMARY_RESELECT_BETTER + BOND_PRIMARY_RESELECT_FAILURE +) + +// BondArpAllTargets type +type BondArpAllTargets int + +// Possible BondArpAllTargets value +const ( + BOND_ARP_ALL_TARGETS_ANY BondArpAllTargets = iota + BOND_ARP_ALL_TARGETS_ALL +) + +// BondFailOverMac type +type BondFailOverMac int + +// Possible BondFailOverMac value +const ( + BOND_FAIL_OVER_MAC_NONE BondFailOverMac = iota + BOND_FAIL_OVER_MAC_ACTIVE + BOND_FAIL_OVER_MAC_FOLLOW +) + +// BondXmitHashPolicy type +type BondXmitHashPolicy int + +func (b BondXmitHashPolicy) String() string { + s, ok := bondXmitHashPolicyToString[b] + if !ok { + return fmt.Sprintf("XmitHashPolicy(%d)", b) + } + return s +} + +// StringToBondXmitHashPolicy returns bond lacp arte, or uknonw is the s is invalid. +func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy { + lacp, ok := StringToBondXmitHashPolicyMap[s] + if !ok { + return BOND_XMIT_HASH_POLICY_UNKNOWN + } + return lacp +} + +// Possible BondXmitHashPolicy value +const ( + BOND_XMIT_HASH_POLICY_LAYER2 BondXmitHashPolicy = iota + BOND_XMIT_HASH_POLICY_LAYER3_4 + BOND_XMIT_HASH_POLICY_LAYER2_3 + BOND_XMIT_HASH_POLICY_ENCAP2_3 + BOND_XMIT_HASH_POLICY_ENCAP3_4 + BOND_XMIT_HASH_POLICY_UNKNOWN +) + +var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{ + BOND_XMIT_HASH_POLICY_LAYER2: "layer2", + BOND_XMIT_HASH_POLICY_LAYER3_4: "layer3+4", + BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3", + BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3", + BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4", +} +var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{ + "layer2": BOND_XMIT_HASH_POLICY_LAYER2, + "layer3+4": BOND_XMIT_HASH_POLICY_LAYER3_4, + "layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3, + "encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3, + "encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4, +} + +// BondLacpRate type +type BondLacpRate int + +func (b BondLacpRate) String() string { + s, ok := bondLacpRateToString[b] + if !ok { + return fmt.Sprintf("LacpRate(%d)", b) + } + return s +} + +// StringToBondLacpRate returns bond lacp arte, or uknonw is the s is invalid. +func StringToBondLacpRate(s string) BondLacpRate { + lacp, ok := StringToBondLacpRateMap[s] + if !ok { + return BOND_LACP_RATE_UNKNOWN + } + return lacp +} + +// Possible BondLacpRate value +const ( + BOND_LACP_RATE_SLOW BondLacpRate = iota + BOND_LACP_RATE_FAST + BOND_LACP_RATE_UNKNOWN +) + +var bondLacpRateToString = map[BondLacpRate]string{ + BOND_LACP_RATE_SLOW: "slow", + BOND_LACP_RATE_FAST: "fast", +} +var StringToBondLacpRateMap = map[string]BondLacpRate{ + "slow": BOND_LACP_RATE_SLOW, + "fast": BOND_LACP_RATE_FAST, +} + +// BondAdSelect type +type BondAdSelect int + +// Possible BondAdSelect value +const ( + BOND_AD_SELECT_STABLE BondAdSelect = iota + BOND_AD_SELECT_BANDWIDTH + BOND_AD_SELECT_COUNT +) + +// BondAdInfo represents ad info for bond +type BondAdInfo struct { + AggregatorId int + NumPorts int + ActorKey int + PartnerKey int + PartnerMac net.HardwareAddr +} + +// Bond representation +type Bond struct { + LinkAttrs + Mode BondMode + ActiveSlave int + Miimon int + UpDelay int + DownDelay int + UseCarrier int + ArpInterval int + ArpIpTargets []net.IP + ArpValidate BondArpValidate + ArpAllTargets BondArpAllTargets + Primary int + PrimaryReselect BondPrimaryReselect + FailOverMac BondFailOverMac + XmitHashPolicy BondXmitHashPolicy + ResendIgmp int + NumPeerNotif int + AllSlavesActive int + MinLinks int + LpInterval int + PackersPerSlave int + LacpRate BondLacpRate + AdSelect BondAdSelect + // looking at iproute tool AdInfo can only be retrived. It can't be set. + AdInfo *BondAdInfo + AdActorSysPrio int + AdUserPortKey int + AdActorSystem net.HardwareAddr + TlbDynamicLb int +} + +func NewLinkBond(atr LinkAttrs) *Bond { + return &Bond{ + LinkAttrs: atr, + Mode: -1, + ActiveSlave: -1, + Miimon: -1, + UpDelay: -1, + DownDelay: -1, + UseCarrier: -1, + ArpInterval: -1, + ArpIpTargets: nil, + ArpValidate: -1, + ArpAllTargets: -1, + Primary: -1, + PrimaryReselect: -1, + FailOverMac: -1, + XmitHashPolicy: -1, + ResendIgmp: -1, + NumPeerNotif: -1, + AllSlavesActive: -1, + MinLinks: -1, + LpInterval: -1, + PackersPerSlave: -1, + LacpRate: -1, + AdSelect: -1, + AdActorSysPrio: -1, + AdUserPortKey: -1, + AdActorSystem: nil, + TlbDynamicLb: -1, + } +} + +// Flag mask for bond options. Bond.Flagmask must be set to on for option to work. +const ( + BOND_MODE_MASK uint64 = 1 << (1 + iota) + BOND_ACTIVE_SLAVE_MASK + BOND_MIIMON_MASK + BOND_UPDELAY_MASK + BOND_DOWNDELAY_MASK + BOND_USE_CARRIER_MASK + BOND_ARP_INTERVAL_MASK + BOND_ARP_VALIDATE_MASK + BOND_ARP_ALL_TARGETS_MASK + BOND_PRIMARY_MASK + BOND_PRIMARY_RESELECT_MASK + BOND_FAIL_OVER_MAC_MASK + BOND_XMIT_HASH_POLICY_MASK + BOND_RESEND_IGMP_MASK + BOND_NUM_PEER_NOTIF_MASK + BOND_ALL_SLAVES_ACTIVE_MASK + BOND_MIN_LINKS_MASK + BOND_LP_INTERVAL_MASK + BOND_PACKETS_PER_SLAVE_MASK + BOND_LACP_RATE_MASK + BOND_AD_SELECT_MASK +) + +// Attrs implementation. +func (bond *Bond) Attrs() *LinkAttrs { + return &bond.LinkAttrs +} + +// Type implementation fro Vxlan. +func (bond *Bond) Type() string { + return "bond" +} + +// Gretap devices must specify LocalIP and RemoteIP on create +type Gretap struct { + LinkAttrs + IKey uint32 + OKey uint32 + EncapSport uint16 + EncapDport uint16 + Local net.IP + Remote net.IP + IFlags uint16 + OFlags uint16 + PMtuDisc uint8 + Ttl uint8 + Tos uint8 + EncapType uint16 + EncapFlags uint16 + Link uint32 + FlowBased bool +} + +func (gretap *Gretap) Attrs() *LinkAttrs { + return &gretap.LinkAttrs +} + +func (gretap *Gretap) Type() string { + if gretap.Local.To4() == nil { + return "ip6gretap" + } + return "gretap" +} + +type Iptun struct { + LinkAttrs + Ttl uint8 + Tos uint8 + PMtuDisc uint8 + Link uint32 + Local net.IP + Remote net.IP + EncapSport uint16 + EncapDport uint16 + EncapType uint16 + EncapFlags uint16 + FlowBased bool +} + +func (iptun *Iptun) Attrs() *LinkAttrs { + return &iptun.LinkAttrs +} + +func (iptun *Iptun) Type() string { + return "ipip" +} + +type Sittun struct { + LinkAttrs + Link uint32 + Local net.IP + Remote net.IP + Ttl uint8 + Tos uint8 + PMtuDisc uint8 + EncapType uint16 + EncapFlags uint16 + EncapSport uint16 + EncapDport uint16 +} + +func (sittun *Sittun) Attrs() *LinkAttrs { + return &sittun.LinkAttrs +} + +func (sittun *Sittun) Type() string { + return "sit" +} + +type Vti struct { + LinkAttrs + IKey uint32 + OKey uint32 + Link uint32 + Local net.IP + Remote net.IP +} + +func (vti *Vti) Attrs() *LinkAttrs { + return &vti.LinkAttrs +} + +func (iptun *Vti) Type() string { + return "vti" +} + +type Gretun struct { + LinkAttrs + Link uint32 + IFlags uint16 + OFlags uint16 + IKey uint32 + OKey uint32 + Local net.IP + Remote net.IP + Ttl uint8 + Tos uint8 + PMtuDisc uint8 + EncapType uint16 + EncapFlags uint16 + EncapSport uint16 + EncapDport uint16 +} + +func (gretun *Gretun) Attrs() *LinkAttrs { + return &gretun.LinkAttrs +} + +func (gretun *Gretun) Type() string { + if gretun.Local.To4() == nil { + return "ip6gre" + } + return "gre" +} + +type Vrf struct { + LinkAttrs + Table uint32 +} + +func (vrf *Vrf) Attrs() *LinkAttrs { + return &vrf.LinkAttrs +} + +func (vrf *Vrf) Type() string { + return "vrf" +} + +type GTP struct { + LinkAttrs + FD0 int + FD1 int + Role int + PDPHashsize int +} + +func (gtp *GTP) Attrs() *LinkAttrs { + return >p.LinkAttrs +} + +func (gtp *GTP) Type() string { + return "gtp" +} + +// iproute2 supported devices; +// vlan | veth | vcan | dummy | ifb | macvlan | macvtap | +// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | +// gre | gretap | ip6gre | ip6gretap | vti | nlmon | +// bond_slave | ipvlan + +// LinkNotFoundError wraps the various not found errors when +// getting/reading links. This is intended for better error +// handling by dependent code so that "not found error" can +// be distinguished from other errors +type LinkNotFoundError struct { + error +} diff --git a/vendor/github.com/vishvananda/netlink/link_linux.go b/vendor/github.com/vishvananda/netlink/link_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..540191ed843c571d1ad550b67ecfcf2fbdd49324 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/link_linux.go @@ -0,0 +1,2354 @@ +package netlink + +import ( + "bytes" + "encoding/binary" + "fmt" + "net" + "os" + "syscall" + "unsafe" + + "github.com/vishvananda/netlink/nl" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +const ( + SizeofLinkStats32 = 0x5c + SizeofLinkStats64 = 0xd8 +) + +const ( + TUNTAP_MODE_TUN TuntapMode = unix.IFF_TUN + TUNTAP_MODE_TAP TuntapMode = unix.IFF_TAP + TUNTAP_DEFAULTS TuntapFlag = unix.IFF_TUN_EXCL | unix.IFF_ONE_QUEUE + TUNTAP_VNET_HDR TuntapFlag = unix.IFF_VNET_HDR + TUNTAP_TUN_EXCL TuntapFlag = unix.IFF_TUN_EXCL + TUNTAP_NO_PI TuntapFlag = unix.IFF_NO_PI + TUNTAP_ONE_QUEUE TuntapFlag = unix.IFF_ONE_QUEUE + TUNTAP_MULTI_QUEUE TuntapFlag = unix.IFF_MULTI_QUEUE + TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI +) + +var lookupByDump = false + +var macvlanModes = [...]uint32{ + 0, + nl.MACVLAN_MODE_PRIVATE, + nl.MACVLAN_MODE_VEPA, + nl.MACVLAN_MODE_BRIDGE, + nl.MACVLAN_MODE_PASSTHRU, + nl.MACVLAN_MODE_SOURCE, +} + +func ensureIndex(link *LinkAttrs) { + if link != nil && link.Index == 0 { + newlink, _ := LinkByName(link.Name) + if newlink != nil { + link.Index = newlink.Attrs().Index + } + } +} + +func (h *Handle) ensureIndex(link *LinkAttrs) { + if link != nil && link.Index == 0 { + newlink, _ := h.LinkByName(link.Name) + if newlink != nil { + link.Index = newlink.Attrs().Index + } + } +} + +func (h *Handle) LinkSetARPOff(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change |= unix.IFF_NOARP + msg.Flags |= unix.IFF_NOARP + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func LinkSetARPOff(link Link) error { + return pkgHandle.LinkSetARPOff(link) +} + +func (h *Handle) LinkSetARPOn(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change |= unix.IFF_NOARP + msg.Flags &= ^uint32(unix.IFF_NOARP) + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func LinkSetARPOn(link Link) error { + return pkgHandle.LinkSetARPOn(link) +} + +func (h *Handle) SetPromiscOn(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change = unix.IFF_PROMISC + msg.Flags = unix.IFF_PROMISC + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error { + return pkgHandle.MacvlanMACAddrAdd(link, addr) +} + +func (h *Handle) MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error { + return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_ADD) +} + +func MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error { + return pkgHandle.MacvlanMACAddrDel(link, addr) +} + +func (h *Handle) MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error { + return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_DEL) +} + +func MacvlanMACAddrFlush(link Link) error { + return pkgHandle.MacvlanMACAddrFlush(link) +} + +func (h *Handle) MacvlanMACAddrFlush(link Link) error { + return h.macvlanMACAddrChange(link, nil, nl.MACVLAN_MACADDR_FLUSH) +} + +func MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error { + return pkgHandle.MacvlanMACAddrSet(link, addrs) +} + +func (h *Handle) MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error { + return h.macvlanMACAddrChange(link, addrs, nl.MACVLAN_MACADDR_SET) +} + +func (h *Handle) macvlanMACAddrChange(link Link, addrs []net.HardwareAddr, mode uint32) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) + nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) + inner := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + // IFLA_MACVLAN_MACADDR_MODE = mode + b := make([]byte, 4) + native.PutUint32(b, mode) + nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR_MODE, b) + + // populate message with MAC addrs, if necessary + switch mode { + case nl.MACVLAN_MACADDR_ADD, nl.MACVLAN_MACADDR_DEL: + if len(addrs) == 1 { + nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR, []byte(addrs[0])) + } + case nl.MACVLAN_MACADDR_SET: + mad := nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR_DATA, nil) + for _, addr := range addrs { + nl.NewRtAttrChild(mad, nl.IFLA_MACVLAN_MACADDR, []byte(addr)) + } + } + + req.AddData(linkInfo) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func BridgeSetMcastSnoop(link Link, on bool) error { + return pkgHandle.BridgeSetMcastSnoop(link, on) +} + +func (h *Handle) BridgeSetMcastSnoop(link Link, on bool) error { + bridge := link.(*Bridge) + bridge.MulticastSnooping = &on + return h.linkModify(bridge, unix.NLM_F_ACK) +} + +func SetPromiscOn(link Link) error { + return pkgHandle.SetPromiscOn(link) +} + +func (h *Handle) SetPromiscOff(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change = unix.IFF_PROMISC + msg.Flags = 0 & ^unix.IFF_PROMISC + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func SetPromiscOff(link Link) error { + return pkgHandle.SetPromiscOff(link) +} + +// LinkSetUp enables the link device. +// Equivalent to: `ip link set $link up` +func LinkSetUp(link Link) error { + return pkgHandle.LinkSetUp(link) +} + +// LinkSetUp enables the link device. +// Equivalent to: `ip link set $link up` +func (h *Handle) LinkSetUp(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change = unix.IFF_UP + msg.Flags = unix.IFF_UP + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetDown disables link device. +// Equivalent to: `ip link set $link down` +func LinkSetDown(link Link) error { + return pkgHandle.LinkSetDown(link) +} + +// LinkSetDown disables link device. +// Equivalent to: `ip link set $link down` +func (h *Handle) LinkSetDown(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Change = unix.IFF_UP + msg.Flags = 0 & ^unix.IFF_UP + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetMTU sets the mtu of the link device. +// Equivalent to: `ip link set $link mtu $mtu` +func LinkSetMTU(link Link, mtu int) error { + return pkgHandle.LinkSetMTU(link, mtu) +} + +// LinkSetMTU sets the mtu of the link device. +// Equivalent to: `ip link set $link mtu $mtu` +func (h *Handle) LinkSetMTU(link Link, mtu int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + b := make([]byte, 4) + native.PutUint32(b, uint32(mtu)) + + data := nl.NewRtAttr(unix.IFLA_MTU, b) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetName sets the name of the link device. +// Equivalent to: `ip link set $link name $name` +func LinkSetName(link Link, name string) error { + return pkgHandle.LinkSetName(link, name) +} + +// LinkSetName sets the name of the link device. +// Equivalent to: `ip link set $link name $name` +func (h *Handle) LinkSetName(link Link, name string) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_IFNAME, []byte(name)) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetAlias sets the alias of the link device. +// Equivalent to: `ip link set dev $link alias $name` +func LinkSetAlias(link Link, name string) error { + return pkgHandle.LinkSetAlias(link, name) +} + +// LinkSetAlias sets the alias of the link device. +// Equivalent to: `ip link set dev $link alias $name` +func (h *Handle) LinkSetAlias(link Link, name string) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(name)) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetHardwareAddr sets the hardware address of the link device. +// Equivalent to: `ip link set $link address $hwaddr` +func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { + return pkgHandle.LinkSetHardwareAddr(link, hwaddr) +} + +// LinkSetHardwareAddr sets the hardware address of the link device. +// Equivalent to: `ip link set $link address $hwaddr` +func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(hwaddr)) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetVfHardwareAddr sets the hardware address of a vf for the link. +// Equivalent to: `ip link set $link vf $vf mac $hwaddr` +func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { + return pkgHandle.LinkSetVfHardwareAddr(link, vf, hwaddr) +} + +// LinkSetVfHardwareAddr sets the hardware address of a vf for the link. +// Equivalent to: `ip link set $link vf $vf mac $hwaddr` +func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + vfmsg := nl.VfMac{ + Vf: uint32(vf), + } + copy(vfmsg.Mac[:], []byte(hwaddr)) + nl.NewRtAttrChild(info, nl.IFLA_VF_MAC, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetVfVlan sets the vlan of a vf for the link. +// Equivalent to: `ip link set $link vf $vf vlan $vlan` +func LinkSetVfVlan(link Link, vf, vlan int) error { + return pkgHandle.LinkSetVfVlan(link, vf, vlan) +} + +// LinkSetVfVlan sets the vlan of a vf for the link. +// Equivalent to: `ip link set $link vf $vf vlan $vlan` +func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + vfmsg := nl.VfVlan{ + Vf: uint32(vf), + Vlan: uint32(vlan), + } + nl.NewRtAttrChild(info, nl.IFLA_VF_VLAN, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetVfTxRate sets the tx rate of a vf for the link. +// Equivalent to: `ip link set $link vf $vf rate $rate` +func LinkSetVfTxRate(link Link, vf, rate int) error { + return pkgHandle.LinkSetVfTxRate(link, vf, rate) +} + +// LinkSetVfTxRate sets the tx rate of a vf for the link. +// Equivalent to: `ip link set $link vf $vf rate $rate` +func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + vfmsg := nl.VfTxRate{ + Vf: uint32(vf), + Rate: uint32(rate), + } + nl.NewRtAttrChild(info, nl.IFLA_VF_TX_RATE, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link. +// Equivalent to: `ip link set $link vf $vf spoofchk $check` +func LinkSetVfSpoofchk(link Link, vf int, check bool) error { + return pkgHandle.LinkSetVfSpoofchk(link, vf, check) +} + +// LinkSetVfSpookfchk enables/disables spoof check on a vf for the link. +// Equivalent to: `ip link set $link vf $vf spoofchk $check` +func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error { + var setting uint32 + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + if check { + setting = 1 + } + vfmsg := nl.VfSpoofchk{ + Vf: uint32(vf), + Setting: setting, + } + nl.NewRtAttrChild(info, nl.IFLA_VF_SPOOFCHK, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetVfTrust enables/disables trust state on a vf for the link. +// Equivalent to: `ip link set $link vf $vf trust $state` +func LinkSetVfTrust(link Link, vf int, state bool) error { + return pkgHandle.LinkSetVfTrust(link, vf, state) +} + +// LinkSetVfTrust enables/disables trust state on a vf for the link. +// Equivalent to: `ip link set $link vf $vf trust $state` +func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error { + var setting uint32 + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + if state { + setting = 1 + } + vfmsg := nl.VfTrust{ + Vf: uint32(vf), + Setting: setting, + } + nl.NewRtAttrChild(info, nl.IFLA_VF_TRUST, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetMaster sets the master of the link device. +// Equivalent to: `ip link set $link master $master` +func LinkSetMaster(link Link, master *Bridge) error { + return pkgHandle.LinkSetMaster(link, master) +} + +// LinkSetMaster sets the master of the link device. +// Equivalent to: `ip link set $link master $master` +func (h *Handle) LinkSetMaster(link Link, master *Bridge) error { + index := 0 + if master != nil { + masterBase := master.Attrs() + h.ensureIndex(masterBase) + index = masterBase.Index + } + if index <= 0 { + return fmt.Errorf("Device does not exist") + } + return h.LinkSetMasterByIndex(link, index) +} + +// LinkSetNoMaster removes the master of the link device. +// Equivalent to: `ip link set $link nomaster` +func LinkSetNoMaster(link Link) error { + return pkgHandle.LinkSetNoMaster(link) +} + +// LinkSetNoMaster removes the master of the link device. +// Equivalent to: `ip link set $link nomaster` +func (h *Handle) LinkSetNoMaster(link Link) error { + return h.LinkSetMasterByIndex(link, 0) +} + +// LinkSetMasterByIndex sets the master of the link device. +// Equivalent to: `ip link set $link master $master` +func LinkSetMasterByIndex(link Link, masterIndex int) error { + return pkgHandle.LinkSetMasterByIndex(link, masterIndex) +} + +// LinkSetMasterByIndex sets the master of the link device. +// Equivalent to: `ip link set $link master $master` +func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + b := make([]byte, 4) + native.PutUint32(b, uint32(masterIndex)) + + data := nl.NewRtAttr(unix.IFLA_MASTER, b) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetNsPid puts the device into a new network namespace. The +// pid must be a pid of a running process. +// Equivalent to: `ip link set $link netns $pid` +func LinkSetNsPid(link Link, nspid int) error { + return pkgHandle.LinkSetNsPid(link, nspid) +} + +// LinkSetNsPid puts the device into a new network namespace. The +// pid must be a pid of a running process. +// Equivalent to: `ip link set $link netns $pid` +func (h *Handle) LinkSetNsPid(link Link, nspid int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + b := make([]byte, 4) + native.PutUint32(b, uint32(nspid)) + + data := nl.NewRtAttr(unix.IFLA_NET_NS_PID, b) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetNsFd puts the device into a new network namespace. The +// fd must be an open file descriptor to a network namespace. +// Similar to: `ip link set $link netns $ns` +func LinkSetNsFd(link Link, fd int) error { + return pkgHandle.LinkSetNsFd(link, fd) +} + +// LinkSetNsFd puts the device into a new network namespace. The +// fd must be an open file descriptor to a network namespace. +// Similar to: `ip link set $link netns $ns` +func (h *Handle) LinkSetNsFd(link Link, fd int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + b := make([]byte, 4) + native.PutUint32(b, uint32(fd)) + + data := nl.NewRtAttr(unix.IFLA_NET_NS_FD, b) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf +// program loaded with bpf(type=BPF_PROG_TYPE_XDP) +func LinkSetXdpFd(link Link, fd int) error { + return LinkSetXdpFdWithFlags(link, fd, 0) +} + +// LinkSetXdpFdWithFlags adds a bpf function to the driver with the given +// options. The fd must be a bpf program loaded with bpf(type=BPF_PROG_TYPE_XDP) +func LinkSetXdpFdWithFlags(link Link, fd, flags int) error { + base := link.Attrs() + ensureIndex(base) + req := nl.NewNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func boolAttr(val bool) []byte { + var v uint8 + if val { + v = 1 + } + return nl.Uint8Attr(v) +} + +type vxlanPortRange struct { + Lo, Hi uint16 +} + +func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + if vxlan.FlowBased { + vxlan.VxlanId = 0 + } + + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId))) + + if vxlan.VtepDevIndex != 0 { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex))) + } + if vxlan.SrcAddr != nil { + ip := vxlan.SrcAddr.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LOCAL, []byte(ip)) + } else { + ip = vxlan.SrcAddr.To16() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LOCAL6, []byte(ip)) + } + } + } + if vxlan.Group != nil { + group := vxlan.Group.To4() + if group != nil { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GROUP, []byte(group)) + } else { + group = vxlan.Group.To16() + if group != nil { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GROUP6, []byte(group)) + } + } + } + + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_TTL, nl.Uint8Attr(uint8(vxlan.TTL))) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_TOS, nl.Uint8Attr(uint8(vxlan.TOS))) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LEARNING, boolAttr(vxlan.Learning)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PROXY, boolAttr(vxlan.Proxy)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_RSC, boolAttr(vxlan.RSC)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX, boolAttr(vxlan.UDP6ZeroCSumTx)) + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX, boolAttr(vxlan.UDP6ZeroCSumRx)) + + if vxlan.UDPCSum { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_CSUM, boolAttr(vxlan.UDPCSum)) + } + if vxlan.GBP { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, []byte{}) + } + if vxlan.FlowBased { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_FLOWBASED, boolAttr(vxlan.FlowBased)) + } + if vxlan.NoAge { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0)) + } else if vxlan.Age > 0 { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(uint32(vxlan.Age))) + } + if vxlan.Limit > 0 { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LIMIT, nl.Uint32Attr(uint32(vxlan.Limit))) + } + if vxlan.Port > 0 { + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PORT, htons(uint16(vxlan.Port))) + } + if vxlan.PortLow > 0 || vxlan.PortHigh > 0 { + pr := vxlanPortRange{uint16(vxlan.PortLow), uint16(vxlan.PortHigh)} + + buf := new(bytes.Buffer) + binary.Write(buf, binary.BigEndian, &pr) + + nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PORT_RANGE, buf.Bytes()) + } +} + +func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + if bond.Mode >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_MODE, nl.Uint8Attr(uint8(bond.Mode))) + } + if bond.ActiveSlave >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_ACTIVE_SLAVE, nl.Uint32Attr(uint32(bond.ActiveSlave))) + } + if bond.Miimon >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_MIIMON, nl.Uint32Attr(uint32(bond.Miimon))) + } + if bond.UpDelay >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_UPDELAY, nl.Uint32Attr(uint32(bond.UpDelay))) + } + if bond.DownDelay >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_DOWNDELAY, nl.Uint32Attr(uint32(bond.DownDelay))) + } + if bond.UseCarrier >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_USE_CARRIER, nl.Uint8Attr(uint8(bond.UseCarrier))) + } + if bond.ArpInterval >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_INTERVAL, nl.Uint32Attr(uint32(bond.ArpInterval))) + } + if bond.ArpIpTargets != nil { + msg := nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_IP_TARGET, nil) + for i := range bond.ArpIpTargets { + ip := bond.ArpIpTargets[i].To4() + if ip != nil { + nl.NewRtAttrChild(msg, i, []byte(ip)) + continue + } + ip = bond.ArpIpTargets[i].To16() + if ip != nil { + nl.NewRtAttrChild(msg, i, []byte(ip)) + } + } + } + if bond.ArpValidate >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_VALIDATE, nl.Uint32Attr(uint32(bond.ArpValidate))) + } + if bond.ArpAllTargets >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_ALL_TARGETS, nl.Uint32Attr(uint32(bond.ArpAllTargets))) + } + if bond.Primary >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_PRIMARY, nl.Uint32Attr(uint32(bond.Primary))) + } + if bond.PrimaryReselect >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_PRIMARY_RESELECT, nl.Uint8Attr(uint8(bond.PrimaryReselect))) + } + if bond.FailOverMac >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_FAIL_OVER_MAC, nl.Uint8Attr(uint8(bond.FailOverMac))) + } + if bond.XmitHashPolicy >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_XMIT_HASH_POLICY, nl.Uint8Attr(uint8(bond.XmitHashPolicy))) + } + if bond.ResendIgmp >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_RESEND_IGMP, nl.Uint32Attr(uint32(bond.ResendIgmp))) + } + if bond.NumPeerNotif >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_NUM_PEER_NOTIF, nl.Uint8Attr(uint8(bond.NumPeerNotif))) + } + if bond.AllSlavesActive >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_ALL_SLAVES_ACTIVE, nl.Uint8Attr(uint8(bond.AllSlavesActive))) + } + if bond.MinLinks >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_MIN_LINKS, nl.Uint32Attr(uint32(bond.MinLinks))) + } + if bond.LpInterval >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_LP_INTERVAL, nl.Uint32Attr(uint32(bond.LpInterval))) + } + if bond.PackersPerSlave >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PackersPerSlave))) + } + if bond.LacpRate >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_LACP_RATE, nl.Uint8Attr(uint8(bond.LacpRate))) + } + if bond.AdSelect >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_SELECT, nl.Uint8Attr(uint8(bond.AdSelect))) + } + if bond.AdActorSysPrio >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_ACTOR_SYS_PRIO, nl.Uint16Attr(uint16(bond.AdActorSysPrio))) + } + if bond.AdUserPortKey >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_USER_PORT_KEY, nl.Uint16Attr(uint16(bond.AdUserPortKey))) + } + if bond.AdActorSystem != nil { + nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_ACTOR_SYSTEM, []byte(bond.AdActorSystem)) + } + if bond.TlbDynamicLb >= 0 { + nl.NewRtAttrChild(data, nl.IFLA_BOND_TLB_DYNAMIC_LB, nl.Uint8Attr(uint8(bond.TlbDynamicLb))) + } +} + +func cleanupFds(fds []*os.File) { + for _, f := range fds { + f.Close() + } +} + +// LinkAdd adds a new link device. The type and features of the device +// are taken from the parameters in the link object. +// Equivalent to: `ip link add $link` +func LinkAdd(link Link) error { + return pkgHandle.LinkAdd(link) +} + +// LinkAdd adds a new link device. The type and features of the device +// are taken fromt the parameters in the link object. +// Equivalent to: `ip link add $link` +func (h *Handle) LinkAdd(link Link) error { + return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) +} + +func (h *Handle) linkModify(link Link, flags int) error { + // TODO: support extra data for macvlan + base := link.Attrs() + + if base.Name == "" { + return fmt.Errorf("LinkAttrs.Name cannot be empty!") + } + + if tuntap, ok := link.(*Tuntap); ok { + // TODO: support user + // TODO: support group + // TODO: support non- persistent + if tuntap.Mode < unix.IFF_TUN || tuntap.Mode > unix.IFF_TAP { + return fmt.Errorf("Tuntap.Mode %v unknown!", tuntap.Mode) + } + + queues := tuntap.Queues + + var fds []*os.File + var req ifReq + copy(req.Name[:15], base.Name) + + req.Flags = uint16(tuntap.Flags) + + if queues == 0 { //Legacy compatibility + queues = 1 + if tuntap.Flags == 0 { + req.Flags = uint16(TUNTAP_DEFAULTS) + } + } else { + // For best peformance set Flags to TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR + // when a) KVM has support for this ABI and + // b) the value of the flag is queryable using the TUNGETIFF ioctl + if tuntap.Flags == 0 { + req.Flags = uint16(TUNTAP_MULTI_QUEUE_DEFAULTS) + } + } + + req.Flags |= uint16(tuntap.Mode) + + for i := 0; i < queues; i++ { + localReq := req + file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) + if err != nil { + cleanupFds(fds) + return err + } + + fds = append(fds, file) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, file.Fd(), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&localReq))) + if errno != 0 { + cleanupFds(fds) + return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed [%d], errno %v", i, errno) + } + } + + _, _, errno := unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 1) + if errno != 0 { + cleanupFds(fds) + return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno) + } + + h.ensureIndex(base) + + // can't set master during create, so set it afterwards + if base.MasterIndex != 0 { + // TODO: verify MasterIndex is actually a bridge? + err := h.LinkSetMasterByIndex(link, base.MasterIndex) + if err != nil { + _, _, _ = unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 0) + cleanupFds(fds) + return err + } + } + + if tuntap.Queues == 0 { + cleanupFds(fds) + } else { + tuntap.Fds = fds + } + + return nil + } + + req := h.newNetlinkRequest(unix.RTM_NEWLINK, flags) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + // TODO: make it shorter + if base.Flags&net.FlagUp != 0 { + msg.Change = unix.IFF_UP + msg.Flags = unix.IFF_UP + } + if base.Flags&net.FlagBroadcast != 0 { + msg.Change |= unix.IFF_BROADCAST + msg.Flags |= unix.IFF_BROADCAST + } + if base.Flags&net.FlagLoopback != 0 { + msg.Change |= unix.IFF_LOOPBACK + msg.Flags |= unix.IFF_LOOPBACK + } + if base.Flags&net.FlagPointToPoint != 0 { + msg.Change |= unix.IFF_POINTOPOINT + msg.Flags |= unix.IFF_POINTOPOINT + } + if base.Flags&net.FlagMulticast != 0 { + msg.Change |= unix.IFF_MULTICAST + msg.Flags |= unix.IFF_MULTICAST + } + if base.Index != 0 { + msg.Index = int32(base.Index) + } + + req.AddData(msg) + + if base.ParentIndex != 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(base.ParentIndex)) + data := nl.NewRtAttr(unix.IFLA_LINK, b) + req.AddData(data) + } else if link.Type() == "ipvlan" { + return fmt.Errorf("Can't create ipvlan link without ParentIndex") + } + + nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name)) + req.AddData(nameData) + + if base.MTU > 0 { + mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) + req.AddData(mtu) + } + + if base.TxQLen >= 0 { + qlen := nl.NewRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) + req.AddData(qlen) + } + + if base.HardwareAddr != nil { + hwaddr := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(base.HardwareAddr)) + req.AddData(hwaddr) + } + + if base.NumTxQueues > 0 { + txqueues := nl.NewRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues))) + req.AddData(txqueues) + } + + if base.NumRxQueues > 0 { + rxqueues := nl.NewRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues))) + req.AddData(rxqueues) + } + + if base.Namespace != nil { + var attr *nl.RtAttr + switch base.Namespace.(type) { + case NsPid: + val := nl.Uint32Attr(uint32(base.Namespace.(NsPid))) + attr = nl.NewRtAttr(unix.IFLA_NET_NS_PID, val) + case NsFd: + val := nl.Uint32Attr(uint32(base.Namespace.(NsFd))) + attr = nl.NewRtAttr(unix.IFLA_NET_NS_FD, val) + } + + req.AddData(attr) + } + + if base.Xdp != nil { + addXdpAttrs(base.Xdp, req) + } + + linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) + nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) + + switch link := link.(type) { + case *Vlan: + b := make([]byte, 2) + native.PutUint16(b, uint16(link.VlanId)) + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + nl.NewRtAttrChild(data, nl.IFLA_VLAN_ID, b) + case *Veth: + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + peer := nl.NewRtAttrChild(data, nl.VETH_INFO_PEER, nil) + nl.NewIfInfomsgChild(peer, unix.AF_UNSPEC) + nl.NewRtAttrChild(peer, unix.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName)) + if base.TxQLen >= 0 { + nl.NewRtAttrChild(peer, unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) + } + if base.MTU > 0 { + nl.NewRtAttrChild(peer, unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) + } + + case *Vxlan: + addVxlanAttrs(link, linkInfo) + case *Bond: + addBondAttrs(link, linkInfo) + case *IPVlan: + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode))) + case *Macvlan: + if link.Mode != MACVLAN_MODE_DEFAULT { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode])) + } + case *Macvtap: + if link.Mode != MACVLAN_MODE_DEFAULT { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode])) + } + case *Gretap: + addGretapAttrs(link, linkInfo) + case *Iptun: + addIptunAttrs(link, linkInfo) + case *Sittun: + addSittunAttrs(link, linkInfo) + case *Gretun: + addGretunAttrs(link, linkInfo) + case *Vti: + addVtiAttrs(link, linkInfo) + case *Vrf: + addVrfAttrs(link, linkInfo) + case *Bridge: + addBridgeAttrs(link, linkInfo) + case *GTP: + addGTPAttrs(link, linkInfo) + } + + req.AddData(linkInfo) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + if err != nil { + return err + } + + h.ensureIndex(base) + + // can't set master during create, so set it afterwards + if base.MasterIndex != 0 { + // TODO: verify MasterIndex is actually a bridge? + return h.LinkSetMasterByIndex(link, base.MasterIndex) + } + return nil +} + +// LinkDel deletes link device. Either Index or Name must be set in +// the link object for it to be deleted. The other values are ignored. +// Equivalent to: `ip link del $link` +func LinkDel(link Link) error { + return pkgHandle.LinkDel(link) +} + +// LinkDel deletes link device. Either Index or Name must be set in +// the link object for it to be deleted. The other values are ignored. +// Equivalent to: `ip link del $link` +func (h *Handle) LinkDel(link Link) error { + base := link.Attrs() + + h.ensureIndex(base) + + req := h.newNetlinkRequest(unix.RTM_DELLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func (h *Handle) linkByNameDump(name string) (Link, error) { + links, err := h.LinkList() + if err != nil { + return nil, err + } + + for _, link := range links { + if link.Attrs().Name == name { + return link, nil + } + } + return nil, LinkNotFoundError{fmt.Errorf("Link %s not found", name)} +} + +func (h *Handle) linkByAliasDump(alias string) (Link, error) { + links, err := h.LinkList() + if err != nil { + return nil, err + } + + for _, link := range links { + if link.Attrs().Alias == alias { + return link, nil + } + } + return nil, LinkNotFoundError{fmt.Errorf("Link alias %s not found", alias)} +} + +// LinkByName finds a link by name and returns a pointer to the object. +func LinkByName(name string) (Link, error) { + return pkgHandle.LinkByName(name) +} + +// LinkByName finds a link by name and returns a pointer to the object. +func (h *Handle) LinkByName(name string) (Link, error) { + if h.lookupByDump { + return h.linkByNameDump(name) + } + + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(msg) + + nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name)) + req.AddData(nameData) + + link, err := execGetLink(req) + if err == unix.EINVAL { + // older kernels don't support looking up via IFLA_IFNAME + // so fall back to dumping all links + h.lookupByDump = true + return h.linkByNameDump(name) + } + + return link, err +} + +// LinkByAlias finds a link by its alias and returns a pointer to the object. +// If there are multiple links with the alias it returns the first one +func LinkByAlias(alias string) (Link, error) { + return pkgHandle.LinkByAlias(alias) +} + +// LinkByAlias finds a link by its alias and returns a pointer to the object. +// If there are multiple links with the alias it returns the first one +func (h *Handle) LinkByAlias(alias string) (Link, error) { + if h.lookupByDump { + return h.linkByAliasDump(alias) + } + + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(msg) + + nameData := nl.NewRtAttr(unix.IFLA_IFALIAS, nl.ZeroTerminated(alias)) + req.AddData(nameData) + + link, err := execGetLink(req) + if err == unix.EINVAL { + // older kernels don't support looking up via IFLA_IFALIAS + // so fall back to dumping all links + h.lookupByDump = true + return h.linkByAliasDump(alias) + } + + return link, err +} + +// LinkByIndex finds a link by index and returns a pointer to the object. +func LinkByIndex(index int) (Link, error) { + return pkgHandle.LinkByIndex(index) +} + +// LinkByIndex finds a link by index and returns a pointer to the object. +func (h *Handle) LinkByIndex(index int) (Link, error) { + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(index) + req.AddData(msg) + + return execGetLink(req) +} + +func execGetLink(req *nl.NetlinkRequest) (Link, error) { + msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) + if err != nil { + if errno, ok := err.(syscall.Errno); ok { + if errno == unix.ENODEV { + return nil, LinkNotFoundError{fmt.Errorf("Link not found")} + } + } + return nil, err + } + + switch { + case len(msgs) == 0: + return nil, LinkNotFoundError{fmt.Errorf("Link not found")} + + case len(msgs) == 1: + return LinkDeserialize(nil, msgs[0]) + + default: + return nil, fmt.Errorf("More than one link found") + } +} + +// linkDeserialize deserializes a raw message received from netlink into +// a link object. +func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) { + msg := nl.DeserializeIfInfomsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + base := LinkAttrs{Index: int(msg.Index), RawFlags: msg.Flags, Flags: linkFlags(msg.Flags), EncapType: msg.EncapType()} + if msg.Flags&unix.IFF_PROMISC != 0 { + base.Promisc = 1 + } + var ( + link Link + stats32 []byte + stats64 []byte + linkType string + ) + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.IFLA_LINKINFO: + infos, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + for _, info := range infos { + switch info.Attr.Type { + case nl.IFLA_INFO_KIND: + linkType = string(info.Value[:len(info.Value)-1]) + switch linkType { + case "dummy": + link = &Dummy{} + case "ifb": + link = &Ifb{} + case "bridge": + link = &Bridge{} + case "vlan": + link = &Vlan{} + case "veth": + link = &Veth{} + case "vxlan": + link = &Vxlan{} + case "bond": + link = &Bond{} + case "ipvlan": + link = &IPVlan{} + case "macvlan": + link = &Macvlan{} + case "macvtap": + link = &Macvtap{} + case "gretap": + link = &Gretap{} + case "ip6gretap": + link = &Gretap{} + case "ipip": + link = &Iptun{} + case "sit": + link = &Sittun{} + case "gre": + link = &Gretun{} + case "ip6gre": + link = &Gretun{} + case "vti": + link = &Vti{} + case "vrf": + link = &Vrf{} + case "gtp": + link = >P{} + default: + link = &GenericLink{LinkType: linkType} + } + case nl.IFLA_INFO_DATA: + data, err := nl.ParseRouteAttr(info.Value) + if err != nil { + return nil, err + } + switch linkType { + case "vlan": + parseVlanData(link, data) + case "vxlan": + parseVxlanData(link, data) + case "bond": + parseBondData(link, data) + case "ipvlan": + parseIPVlanData(link, data) + case "macvlan": + parseMacvlanData(link, data) + case "macvtap": + parseMacvtapData(link, data) + case "gretap": + parseGretapData(link, data) + case "ip6gretap": + parseGretapData(link, data) + case "ipip": + parseIptunData(link, data) + case "sit": + parseSittunData(link, data) + case "gre": + parseGretunData(link, data) + case "ip6gre": + parseGretunData(link, data) + case "vti": + parseVtiData(link, data) + case "vrf": + parseVrfData(link, data) + case "bridge": + parseBridgeData(link, data) + case "gtp": + parseGTPData(link, data) + } + } + } + case unix.IFLA_ADDRESS: + var nonzero bool + for _, b := range attr.Value { + if b != 0 { + nonzero = true + } + } + if nonzero { + base.HardwareAddr = attr.Value[:] + } + case unix.IFLA_IFNAME: + base.Name = string(attr.Value[:len(attr.Value)-1]) + case unix.IFLA_MTU: + base.MTU = int(native.Uint32(attr.Value[0:4])) + case unix.IFLA_LINK: + base.ParentIndex = int(native.Uint32(attr.Value[0:4])) + case unix.IFLA_MASTER: + base.MasterIndex = int(native.Uint32(attr.Value[0:4])) + case unix.IFLA_TXQLEN: + base.TxQLen = int(native.Uint32(attr.Value[0:4])) + case unix.IFLA_IFALIAS: + base.Alias = string(attr.Value[:len(attr.Value)-1]) + case unix.IFLA_STATS: + stats32 = attr.Value[:] + case unix.IFLA_STATS64: + stats64 = attr.Value[:] + case unix.IFLA_XDP: + xdp, err := parseLinkXdp(attr.Value[:]) + if err != nil { + return nil, err + } + base.Xdp = xdp + case unix.IFLA_PROTINFO | unix.NLA_F_NESTED: + if hdr != nil && hdr.Type == unix.RTM_NEWLINK && + msg.Family == unix.AF_BRIDGE { + attrs, err := nl.ParseRouteAttr(attr.Value[:]) + if err != nil { + return nil, err + } + base.Protinfo = parseProtinfo(attrs) + } + case unix.IFLA_OPERSTATE: + base.OperState = LinkOperState(uint8(attr.Value[0])) + case unix.IFLA_LINK_NETNSID: + base.NetNsID = int(native.Uint32(attr.Value[0:4])) + } + } + + if stats64 != nil { + base.Statistics = parseLinkStats64(stats64) + } else if stats32 != nil { + base.Statistics = parseLinkStats32(stats32) + } + + // Links that don't have IFLA_INFO_KIND are hardware devices + if link == nil { + link = &Device{} + } + *link.Attrs() = base + + return link, nil +} + +// LinkList gets a list of link devices. +// Equivalent to: `ip link show` +func LinkList() ([]Link, error) { + return pkgHandle.LinkList() +} + +// LinkList gets a list of link devices. +// Equivalent to: `ip link show` +func (h *Handle) LinkList() ([]Link, error) { + // NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need + // to get the message ourselves to parse link type. + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) + if err != nil { + return nil, err + } + + var res []Link + for _, m := range msgs { + link, err := LinkDeserialize(nil, m) + if err != nil { + return nil, err + } + res = append(res, link) + } + + return res, nil +} + +// LinkUpdate is used to pass information back from LinkSubscribe() +type LinkUpdate struct { + nl.IfInfomsg + Header unix.NlMsghdr + Link +} + +// LinkSubscribe takes a chan down which notifications will be sent +// when links change. Close the 'done' chan to stop subscription. +func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error { + return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) +} + +// LinkSubscribeAt works like LinkSubscribe plus it allows the caller +// to choose the network namespace in which to subscribe (ns). +func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error { + return linkSubscribeAt(ns, netns.None(), ch, done, nil, false) +} + +// LinkSubscribeOptions contains a set of options to use with +// LinkSubscribeWithOptions. +type LinkSubscribeOptions struct { + Namespace *netns.NsHandle + ErrorCallback func(error) + ListExisting bool +} + +// LinkSubscribeWithOptions work like LinkSubscribe but enable to +// provide additional options to modify the behavior. Currently, the +// namespace can be provided as well as an error callback. +func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, options LinkSubscribeOptions) error { + if options.Namespace == nil { + none := netns.None() + options.Namespace = &none + } + return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) +} + +func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { + s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_LINK) + if err != nil { + return err + } + if done != nil { + go func() { + <-done + s.Close() + }() + } + if listExisting { + req := pkgHandle.newNetlinkRequest(unix.RTM_GETLINK, + unix.NLM_F_DUMP) + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(msg) + if err := s.Send(req); err != nil { + return err + } + } + go func() { + defer close(ch) + for { + msgs, err := s.Receive() + if err != nil { + if cberr != nil { + cberr(err) + } + return + } + for _, m := range msgs { + if m.Header.Type == unix.NLMSG_DONE { + continue + } + if m.Header.Type == unix.NLMSG_ERROR { + native := nl.NativeEndian() + error := int32(native.Uint32(m.Data[0:4])) + if error == 0 { + continue + } + if cberr != nil { + cberr(syscall.Errno(-error)) + } + return + } + ifmsg := nl.DeserializeIfInfomsg(m.Data) + header := unix.NlMsghdr(m.Header) + link, err := LinkDeserialize(&header, m.Data) + if err != nil { + if cberr != nil { + cberr(err) + } + return + } + ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: header, Link: link} + } + } + }() + + return nil +} + +func LinkSetHairpin(link Link, mode bool) error { + return pkgHandle.LinkSetHairpin(link, mode) +} + +func (h *Handle) LinkSetHairpin(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE) +} + +func LinkSetGuard(link Link, mode bool) error { + return pkgHandle.LinkSetGuard(link, mode) +} + +func (h *Handle) LinkSetGuard(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD) +} + +func LinkSetFastLeave(link Link, mode bool) error { + return pkgHandle.LinkSetFastLeave(link, mode) +} + +func (h *Handle) LinkSetFastLeave(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_FAST_LEAVE) +} + +func LinkSetLearning(link Link, mode bool) error { + return pkgHandle.LinkSetLearning(link, mode) +} + +func (h *Handle) LinkSetLearning(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING) +} + +func LinkSetRootBlock(link Link, mode bool) error { + return pkgHandle.LinkSetRootBlock(link, mode) +} + +func (h *Handle) LinkSetRootBlock(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROTECT) +} + +func LinkSetFlood(link Link, mode bool) error { + return pkgHandle.LinkSetFlood(link, mode) +} + +func (h *Handle) LinkSetFlood(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD) +} + +func LinkSetBrProxyArp(link Link, mode bool) error { + return pkgHandle.LinkSetBrProxyArp(link, mode) +} + +func (h *Handle) LinkSetBrProxyArp(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP) +} + +func LinkSetBrProxyArpWiFi(link Link, mode bool) error { + return pkgHandle.LinkSetBrProxyArpWiFi(link, mode) +} + +func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI) +} + +func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_BRIDGE) + msg.Index = int32(base.Index) + req.AddData(msg) + + br := nl.NewRtAttr(unix.IFLA_PROTINFO|unix.NLA_F_NESTED, nil) + nl.NewRtAttrChild(br, attr, boolToByte(mode)) + req.AddData(br) + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + if err != nil { + return err + } + return nil +} + +// LinkSetTxQLen sets the transaction queue length for the link. +// Equivalent to: `ip link set $link txqlen $qlen` +func LinkSetTxQLen(link Link, qlen int) error { + return pkgHandle.LinkSetTxQLen(link, qlen) +} + +// LinkSetTxQLen sets the transaction queue length for the link. +// Equivalent to: `ip link set $link txqlen $qlen` +func (h *Handle) LinkSetTxQLen(link Link, qlen int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) + + msg := nl.NewIfInfomsg(unix.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + b := make([]byte, 4) + native.PutUint32(b, uint32(qlen)) + + data := nl.NewRtAttr(unix.IFLA_TXQLEN, b) + req.AddData(data) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) { + vlan := link.(*Vlan) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_VLAN_ID: + vlan.VlanId = int(native.Uint16(datum.Value[0:2])) + } + } +} + +func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) { + vxlan := link.(*Vxlan) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_VXLAN_ID: + vxlan.VxlanId = int(native.Uint32(datum.Value[0:4])) + case nl.IFLA_VXLAN_LINK: + vxlan.VtepDevIndex = int(native.Uint32(datum.Value[0:4])) + case nl.IFLA_VXLAN_LOCAL: + vxlan.SrcAddr = net.IP(datum.Value[0:4]) + case nl.IFLA_VXLAN_LOCAL6: + vxlan.SrcAddr = net.IP(datum.Value[0:16]) + case nl.IFLA_VXLAN_GROUP: + vxlan.Group = net.IP(datum.Value[0:4]) + case nl.IFLA_VXLAN_GROUP6: + vxlan.Group = net.IP(datum.Value[0:16]) + case nl.IFLA_VXLAN_TTL: + vxlan.TTL = int(datum.Value[0]) + case nl.IFLA_VXLAN_TOS: + vxlan.TOS = int(datum.Value[0]) + case nl.IFLA_VXLAN_LEARNING: + vxlan.Learning = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_PROXY: + vxlan.Proxy = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_RSC: + vxlan.RSC = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_L2MISS: + vxlan.L2miss = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_L3MISS: + vxlan.L3miss = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_UDP_CSUM: + vxlan.UDPCSum = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX: + vxlan.UDP6ZeroCSumTx = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX: + vxlan.UDP6ZeroCSumRx = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_GBP: + vxlan.GBP = true + case nl.IFLA_VXLAN_FLOWBASED: + vxlan.FlowBased = int8(datum.Value[0]) != 0 + case nl.IFLA_VXLAN_AGEING: + vxlan.Age = int(native.Uint32(datum.Value[0:4])) + vxlan.NoAge = vxlan.Age == 0 + case nl.IFLA_VXLAN_LIMIT: + vxlan.Limit = int(native.Uint32(datum.Value[0:4])) + case nl.IFLA_VXLAN_PORT: + vxlan.Port = int(ntohs(datum.Value[0:2])) + case nl.IFLA_VXLAN_PORT_RANGE: + buf := bytes.NewBuffer(datum.Value[0:4]) + var pr vxlanPortRange + if binary.Read(buf, binary.BigEndian, &pr) != nil { + vxlan.PortLow = int(pr.Lo) + vxlan.PortHigh = int(pr.Hi) + } + } + } +} + +func parseBondData(link Link, data []syscall.NetlinkRouteAttr) { + bond := link.(*Bond) + for i := range data { + switch data[i].Attr.Type { + case nl.IFLA_BOND_MODE: + bond.Mode = BondMode(data[i].Value[0]) + case nl.IFLA_BOND_ACTIVE_SLAVE: + bond.ActiveSlave = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_MIIMON: + bond.Miimon = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_UPDELAY: + bond.UpDelay = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_DOWNDELAY: + bond.DownDelay = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_USE_CARRIER: + bond.UseCarrier = int(data[i].Value[0]) + case nl.IFLA_BOND_ARP_INTERVAL: + bond.ArpInterval = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_ARP_IP_TARGET: + // TODO: implement + case nl.IFLA_BOND_ARP_VALIDATE: + bond.ArpValidate = BondArpValidate(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_ARP_ALL_TARGETS: + bond.ArpAllTargets = BondArpAllTargets(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_PRIMARY: + bond.Primary = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_PRIMARY_RESELECT: + bond.PrimaryReselect = BondPrimaryReselect(data[i].Value[0]) + case nl.IFLA_BOND_FAIL_OVER_MAC: + bond.FailOverMac = BondFailOverMac(data[i].Value[0]) + case nl.IFLA_BOND_XMIT_HASH_POLICY: + bond.XmitHashPolicy = BondXmitHashPolicy(data[i].Value[0]) + case nl.IFLA_BOND_RESEND_IGMP: + bond.ResendIgmp = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_NUM_PEER_NOTIF: + bond.NumPeerNotif = int(data[i].Value[0]) + case nl.IFLA_BOND_ALL_SLAVES_ACTIVE: + bond.AllSlavesActive = int(data[i].Value[0]) + case nl.IFLA_BOND_MIN_LINKS: + bond.MinLinks = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_LP_INTERVAL: + bond.LpInterval = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_PACKETS_PER_SLAVE: + bond.PackersPerSlave = int(native.Uint32(data[i].Value[0:4])) + case nl.IFLA_BOND_AD_LACP_RATE: + bond.LacpRate = BondLacpRate(data[i].Value[0]) + case nl.IFLA_BOND_AD_SELECT: + bond.AdSelect = BondAdSelect(data[i].Value[0]) + case nl.IFLA_BOND_AD_INFO: + // TODO: implement + case nl.IFLA_BOND_AD_ACTOR_SYS_PRIO: + bond.AdActorSysPrio = int(native.Uint16(data[i].Value[0:2])) + case nl.IFLA_BOND_AD_USER_PORT_KEY: + bond.AdUserPortKey = int(native.Uint16(data[i].Value[0:2])) + case nl.IFLA_BOND_AD_ACTOR_SYSTEM: + bond.AdActorSystem = net.HardwareAddr(data[i].Value[0:6]) + case nl.IFLA_BOND_TLB_DYNAMIC_LB: + bond.TlbDynamicLb = int(data[i].Value[0]) + } + } +} + +func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) { + ipv := link.(*IPVlan) + for _, datum := range data { + if datum.Attr.Type == nl.IFLA_IPVLAN_MODE { + ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4])) + return + } + } +} + +func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) { + macv := link.(*Macvtap) + parseMacvlanData(&macv.Macvlan, data) +} + +func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) { + macv := link.(*Macvlan) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_MACVLAN_MODE: + switch native.Uint32(datum.Value[0:4]) { + case nl.MACVLAN_MODE_PRIVATE: + macv.Mode = MACVLAN_MODE_PRIVATE + case nl.MACVLAN_MODE_VEPA: + macv.Mode = MACVLAN_MODE_VEPA + case nl.MACVLAN_MODE_BRIDGE: + macv.Mode = MACVLAN_MODE_BRIDGE + case nl.MACVLAN_MODE_PASSTHRU: + macv.Mode = MACVLAN_MODE_PASSTHRU + case nl.MACVLAN_MODE_SOURCE: + macv.Mode = MACVLAN_MODE_SOURCE + } + case nl.IFLA_MACVLAN_MACADDR_COUNT: + macv.MACAddrs = make([]net.HardwareAddr, 0, int(native.Uint32(datum.Value[0:4]))) + case nl.IFLA_MACVLAN_MACADDR_DATA: + macs, err := nl.ParseRouteAttr(datum.Value[:]) + if err != nil { + panic(fmt.Sprintf("failed to ParseRouteAttr for IFLA_MACVLAN_MACADDR_DATA: %v", err)) + } + for _, macDatum := range macs { + macv.MACAddrs = append(macv.MACAddrs, net.HardwareAddr(macDatum.Value[0:6])) + } + } + } +} + +// copied from pkg/net_linux.go +func linkFlags(rawFlags uint32) net.Flags { + var f net.Flags + if rawFlags&unix.IFF_UP != 0 { + f |= net.FlagUp + } + if rawFlags&unix.IFF_BROADCAST != 0 { + f |= net.FlagBroadcast + } + if rawFlags&unix.IFF_LOOPBACK != 0 { + f |= net.FlagLoopback + } + if rawFlags&unix.IFF_POINTOPOINT != 0 { + f |= net.FlagPointToPoint + } + if rawFlags&unix.IFF_MULTICAST != 0 { + f |= net.FlagMulticast + } + return f +} + +func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + if gretap.FlowBased { + // In flow based mode, no other attributes need to be configured + nl.NewRtAttrChild(data, nl.IFLA_GRE_COLLECT_METADATA, boolAttr(gretap.FlowBased)) + return + } + + if ip := gretap.Local; ip != nil { + if ip.To4() != nil { + ip = ip.To4() + } + nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip)) + } + + if ip := gretap.Remote; ip != nil { + if ip.To4() != nil { + ip = ip.To4() + } + nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip)) + } + + if gretap.IKey != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_IKEY, htonl(gretap.IKey)) + gretap.IFlags |= uint16(nl.GRE_KEY) + } + + if gretap.OKey != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_OKEY, htonl(gretap.OKey)) + gretap.OFlags |= uint16(nl.GRE_KEY) + } + + nl.NewRtAttrChild(data, nl.IFLA_GRE_IFLAGS, htons(gretap.IFlags)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_OFLAGS, htons(gretap.OFlags)) + + if gretap.Link != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_LINK, nl.Uint32Attr(gretap.Link)) + } + + nl.NewRtAttrChild(data, nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gretap.PMtuDisc)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_TTL, nl.Uint8Attr(gretap.Ttl)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_TOS, nl.Uint8Attr(gretap.Tos)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gretap.EncapType)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gretap.EncapFlags)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_SPORT, htons(gretap.EncapSport)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_DPORT, htons(gretap.EncapDport)) +} + +func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) { + gre := link.(*Gretap) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_GRE_OKEY: + gre.IKey = ntohl(datum.Value[0:4]) + case nl.IFLA_GRE_IKEY: + gre.OKey = ntohl(datum.Value[0:4]) + case nl.IFLA_GRE_LOCAL: + gre.Local = net.IP(datum.Value[0:16]) + case nl.IFLA_GRE_REMOTE: + gre.Remote = net.IP(datum.Value[0:16]) + case nl.IFLA_GRE_ENCAP_SPORT: + gre.EncapSport = ntohs(datum.Value[0:2]) + case nl.IFLA_GRE_ENCAP_DPORT: + gre.EncapDport = ntohs(datum.Value[0:2]) + case nl.IFLA_GRE_IFLAGS: + gre.IFlags = ntohs(datum.Value[0:2]) + case nl.IFLA_GRE_OFLAGS: + gre.OFlags = ntohs(datum.Value[0:2]) + + case nl.IFLA_GRE_TTL: + gre.Ttl = uint8(datum.Value[0]) + case nl.IFLA_GRE_TOS: + gre.Tos = uint8(datum.Value[0]) + case nl.IFLA_GRE_PMTUDISC: + gre.PMtuDisc = uint8(datum.Value[0]) + case nl.IFLA_GRE_ENCAP_TYPE: + gre.EncapType = native.Uint16(datum.Value[0:2]) + case nl.IFLA_GRE_ENCAP_FLAGS: + gre.EncapFlags = native.Uint16(datum.Value[0:2]) + case nl.IFLA_GRE_COLLECT_METADATA: + if len(datum.Value) > 0 { + gre.FlowBased = int8(datum.Value[0]) != 0 + } + } + } +} + +func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + if ip := gre.Local; ip != nil { + if ip.To4() != nil { + ip = ip.To4() + } + nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip)) + } + + if ip := gre.Remote; ip != nil { + if ip.To4() != nil { + ip = ip.To4() + } + nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip)) + } + + if gre.IKey != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_IKEY, htonl(gre.IKey)) + gre.IFlags |= uint16(nl.GRE_KEY) + } + + if gre.OKey != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_OKEY, htonl(gre.OKey)) + gre.OFlags |= uint16(nl.GRE_KEY) + } + + nl.NewRtAttrChild(data, nl.IFLA_GRE_IFLAGS, htons(gre.IFlags)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_OFLAGS, htons(gre.OFlags)) + + if gre.Link != 0 { + nl.NewRtAttrChild(data, nl.IFLA_GRE_LINK, nl.Uint32Attr(gre.Link)) + } + + nl.NewRtAttrChild(data, nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gre.PMtuDisc)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_TTL, nl.Uint8Attr(gre.Ttl)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_TOS, nl.Uint8Attr(gre.Tos)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gre.EncapType)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gre.EncapFlags)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_SPORT, htons(gre.EncapSport)) + nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_DPORT, htons(gre.EncapDport)) +} + +func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) { + gre := link.(*Gretun) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_GRE_OKEY: + gre.IKey = ntohl(datum.Value[0:4]) + case nl.IFLA_GRE_IKEY: + gre.OKey = ntohl(datum.Value[0:4]) + case nl.IFLA_GRE_LOCAL: + gre.Local = net.IP(datum.Value[0:16]) + case nl.IFLA_GRE_REMOTE: + gre.Remote = net.IP(datum.Value[0:16]) + case nl.IFLA_GRE_IFLAGS: + gre.IFlags = ntohs(datum.Value[0:2]) + case nl.IFLA_GRE_OFLAGS: + gre.OFlags = ntohs(datum.Value[0:2]) + + case nl.IFLA_GRE_TTL: + gre.Ttl = uint8(datum.Value[0]) + case nl.IFLA_GRE_TOS: + gre.Tos = uint8(datum.Value[0]) + case nl.IFLA_GRE_PMTUDISC: + gre.PMtuDisc = uint8(datum.Value[0]) + case nl.IFLA_GRE_ENCAP_TYPE: + gre.EncapType = native.Uint16(datum.Value[0:2]) + case nl.IFLA_GRE_ENCAP_FLAGS: + gre.EncapFlags = native.Uint16(datum.Value[0:2]) + case nl.IFLA_GRE_ENCAP_SPORT: + gre.EncapSport = ntohs(datum.Value[0:2]) + case nl.IFLA_GRE_ENCAP_DPORT: + gre.EncapDport = ntohs(datum.Value[0:2]) + } + } +} + +func parseLinkStats32(data []byte) *LinkStatistics { + return (*LinkStatistics)((*LinkStatistics32)(unsafe.Pointer(&data[0:SizeofLinkStats32][0])).to64()) +} + +func parseLinkStats64(data []byte) *LinkStatistics { + return (*LinkStatistics)((*LinkStatistics64)(unsafe.Pointer(&data[0:SizeofLinkStats64][0]))) +} + +func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) { + attrs := nl.NewRtAttr(unix.IFLA_XDP|unix.NLA_F_NESTED, nil) + b := make([]byte, 4) + native.PutUint32(b, uint32(xdp.Fd)) + nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b) + if xdp.Flags != 0 { + b := make([]byte, 4) + native.PutUint32(b, xdp.Flags) + nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FLAGS, b) + } + req.AddData(attrs) +} + +func parseLinkXdp(data []byte) (*LinkXdp, error) { + attrs, err := nl.ParseRouteAttr(data) + if err != nil { + return nil, err + } + xdp := &LinkXdp{} + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.IFLA_XDP_FD: + xdp.Fd = int(native.Uint32(attr.Value[0:4])) + case nl.IFLA_XDP_ATTACHED: + xdp.Attached = attr.Value[0] != 0 + case nl.IFLA_XDP_FLAGS: + xdp.Flags = native.Uint32(attr.Value[0:4]) + case nl.IFLA_XDP_PROG_ID: + xdp.ProgId = native.Uint32(attr.Value[0:4]) + } + } + return xdp, nil +} + +func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) { + if iptun.FlowBased { + // In flow based mode, no other attributes need to be configured + nl.NewRtAttrChild(linkInfo, nl.IFLA_IPTUN_COLLECT_METADATA, boolAttr(iptun.FlowBased)) + return + } + + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + ip := iptun.Local.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LOCAL, []byte(ip)) + } + + ip = iptun.Remote.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_REMOTE, []byte(ip)) + } + + if iptun.Link != 0 { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LINK, nl.Uint32Attr(iptun.Link)) + } + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(iptun.EncapType)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(iptun.EncapFlags)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_SPORT, htons(iptun.EncapSport)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_DPORT, htons(iptun.EncapDport)) +} + +func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) { + iptun := link.(*Iptun) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_IPTUN_LOCAL: + iptun.Local = net.IP(datum.Value[0:4]) + case nl.IFLA_IPTUN_REMOTE: + iptun.Remote = net.IP(datum.Value[0:4]) + case nl.IFLA_IPTUN_TTL: + iptun.Ttl = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_TOS: + iptun.Tos = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_PMTUDISC: + iptun.PMtuDisc = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_ENCAP_SPORT: + iptun.EncapSport = ntohs(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_DPORT: + iptun.EncapDport = ntohs(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_TYPE: + iptun.EncapType = native.Uint16(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_FLAGS: + iptun.EncapFlags = native.Uint16(datum.Value[0:2]) + case nl.IFLA_IPTUN_COLLECT_METADATA: + iptun.FlowBased = int8(datum.Value[0]) != 0 + } + } +} + +func addSittunAttrs(sittun *Sittun, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + if sittun.Link != 0 { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LINK, nl.Uint32Attr(sittun.Link)) + } + + ip := sittun.Local.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LOCAL, []byte(ip)) + } + + ip = sittun.Remote.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_REMOTE, []byte(ip)) + } + + if sittun.Ttl > 0 { + // Would otherwise fail on 3.10 kernel + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(sittun.Ttl)) + } + + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(sittun.Tos)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(sittun.PMtuDisc)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(sittun.EncapType)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(sittun.EncapFlags)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_SPORT, htons(sittun.EncapSport)) + nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_DPORT, htons(sittun.EncapDport)) +} + +func parseSittunData(link Link, data []syscall.NetlinkRouteAttr) { + sittun := link.(*Sittun) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_IPTUN_LOCAL: + sittun.Local = net.IP(datum.Value[0:4]) + case nl.IFLA_IPTUN_REMOTE: + sittun.Remote = net.IP(datum.Value[0:4]) + case nl.IFLA_IPTUN_TTL: + sittun.Ttl = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_TOS: + sittun.Tos = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_PMTUDISC: + sittun.PMtuDisc = uint8(datum.Value[0]) + case nl.IFLA_IPTUN_ENCAP_TYPE: + sittun.EncapType = native.Uint16(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_FLAGS: + sittun.EncapFlags = native.Uint16(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_SPORT: + sittun.EncapSport = ntohs(datum.Value[0:2]) + case nl.IFLA_IPTUN_ENCAP_DPORT: + sittun.EncapDport = ntohs(datum.Value[0:2]) + } + } +} + +func addVtiAttrs(vti *Vti, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + + ip := vti.Local.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_VTI_LOCAL, []byte(ip)) + } + + ip = vti.Remote.To4() + if ip != nil { + nl.NewRtAttrChild(data, nl.IFLA_VTI_REMOTE, []byte(ip)) + } + + if vti.Link != 0 { + nl.NewRtAttrChild(data, nl.IFLA_VTI_LINK, nl.Uint32Attr(vti.Link)) + } + + nl.NewRtAttrChild(data, nl.IFLA_VTI_IKEY, htonl(vti.IKey)) + nl.NewRtAttrChild(data, nl.IFLA_VTI_OKEY, htonl(vti.OKey)) +} + +func parseVtiData(link Link, data []syscall.NetlinkRouteAttr) { + vti := link.(*Vti) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_VTI_LOCAL: + vti.Local = net.IP(datum.Value[0:4]) + case nl.IFLA_VTI_REMOTE: + vti.Remote = net.IP(datum.Value[0:4]) + case nl.IFLA_VTI_IKEY: + vti.IKey = ntohl(datum.Value[0:4]) + case nl.IFLA_VTI_OKEY: + vti.OKey = ntohl(datum.Value[0:4]) + } + } +} + +func addVrfAttrs(vrf *Vrf, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + b := make([]byte, 4) + native.PutUint32(b, uint32(vrf.Table)) + nl.NewRtAttrChild(data, nl.IFLA_VRF_TABLE, b) +} + +func parseVrfData(link Link, data []syscall.NetlinkRouteAttr) { + vrf := link.(*Vrf) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_VRF_TABLE: + vrf.Table = native.Uint32(datum.Value[0:4]) + } + } +} + +func addBridgeAttrs(bridge *Bridge, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + if bridge.MulticastSnooping != nil { + nl.NewRtAttrChild(data, nl.IFLA_BR_MCAST_SNOOPING, boolToByte(*bridge.MulticastSnooping)) + } + if bridge.HelloTime != nil { + nl.NewRtAttrChild(data, nl.IFLA_BR_HELLO_TIME, nl.Uint32Attr(*bridge.HelloTime)) + } +} + +func parseBridgeData(bridge Link, data []syscall.NetlinkRouteAttr) { + br := bridge.(*Bridge) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_BR_HELLO_TIME: + helloTime := native.Uint32(datum.Value[0:4]) + br.HelloTime = &helloTime + case nl.IFLA_BR_MCAST_SNOOPING: + mcastSnooping := datum.Value[0] == 1 + br.MulticastSnooping = &mcastSnooping + } + } +} + +func addGTPAttrs(gtp *GTP, linkInfo *nl.RtAttr) { + data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) + nl.NewRtAttrChild(data, nl.IFLA_GTP_FD0, nl.Uint32Attr(uint32(gtp.FD0))) + nl.NewRtAttrChild(data, nl.IFLA_GTP_FD1, nl.Uint32Attr(uint32(gtp.FD1))) + nl.NewRtAttrChild(data, nl.IFLA_GTP_PDP_HASHSIZE, nl.Uint32Attr(131072)) + if gtp.Role != nl.GTP_ROLE_GGSN { + nl.NewRtAttrChild(data, nl.IFLA_GTP_ROLE, nl.Uint32Attr(uint32(gtp.Role))) + } +} + +func parseGTPData(link Link, data []syscall.NetlinkRouteAttr) { + gtp := link.(*GTP) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_GTP_FD0: + gtp.FD0 = int(native.Uint32(datum.Value)) + case nl.IFLA_GTP_FD1: + gtp.FD1 = int(native.Uint32(datum.Value)) + case nl.IFLA_GTP_PDP_HASHSIZE: + gtp.PDPHashsize = int(native.Uint32(datum.Value)) + case nl.IFLA_GTP_ROLE: + gtp.Role = int(native.Uint32(datum.Value)) + } + } +} + +// LinkSetBondSlave add slave to bond link via ioctl interface. +func LinkSetBondSlave(link Link, master *Bond) error { + fd, err := getSocketUDP() + if err != nil { + return err + } + defer syscall.Close(fd) + + ifreq := newIocltSlaveReq(link.Attrs().Name, master.Attrs().Name) + + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), unix.SIOCBONDENSLAVE, uintptr(unsafe.Pointer(ifreq))) + if errno != 0 { + return fmt.Errorf("Failed to enslave %q to %q, errno=%v", link.Attrs().Name, master.Attrs().Name, errno) + } + return nil +} + +// VethPeerIndex get veth peer index. +func VethPeerIndex(link *Veth) (int, error) { + fd, err := getSocketUDP() + if err != nil { + return -1, err + } + defer syscall.Close(fd) + + ifreq, sSet := newIocltStringSetReq(link.Name) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) + if errno != 0 { + return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno) + } + + gstrings := ðtoolGstrings{ + cmd: ETHTOOL_GSTRINGS, + stringSet: ETH_SS_STATS, + length: sSet.data[0], + } + ifreq.Data = uintptr(unsafe.Pointer(gstrings)) + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) + if errno != 0 { + return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno) + } + + stats := ðtoolStats{ + cmd: ETHTOOL_GSTATS, + nStats: gstrings.length, + } + ifreq.Data = uintptr(unsafe.Pointer(stats)) + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) + if errno != 0 { + return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno) + } + return int(stats.data[0]), nil +} diff --git a/vendor/github.com/vishvananda/netlink/link_tuntap_linux.go b/vendor/github.com/vishvananda/netlink/link_tuntap_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..310bd33d8d421c339cde5261c8781142fdfa7710 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/link_tuntap_linux.go @@ -0,0 +1,14 @@ +package netlink + +// ideally golang.org/x/sys/unix would define IfReq but it only has +// IFNAMSIZ, hence this minimalistic implementation +const ( + SizeOfIfReq = 40 + IFNAMSIZ = 16 +) + +type ifReq struct { + Name [IFNAMSIZ]byte + Flags uint16 + pad [SizeOfIfReq - IFNAMSIZ - 2]byte +} diff --git a/vendor/github.com/vishvananda/netlink/neigh.go b/vendor/github.com/vishvananda/netlink/neigh.go new file mode 100644 index 0000000000000000000000000000000000000000..3f5cd497a7390e16c28328f3f0f168427f628853 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/neigh.go @@ -0,0 +1,25 @@ +package netlink + +import ( + "fmt" + "net" +) + +// Neigh represents a link layer neighbor from netlink. +type Neigh struct { + LinkIndex int + Family int + State int + Type int + Flags int + IP net.IP + HardwareAddr net.HardwareAddr + LLIPAddr net.IP //Used in the case of NHRP + Vlan int + VNI int +} + +// String returns $ip/$hwaddr $label +func (neigh *Neigh) String() string { + return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr) +} diff --git a/vendor/github.com/vishvananda/netlink/neigh_linux.go b/vendor/github.com/vishvananda/netlink/neigh_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..f75c22649f90428fc94fa98243631978b086bbf3 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/neigh_linux.go @@ -0,0 +1,289 @@ +package netlink + +import ( + "net" + "unsafe" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +const ( + NDA_UNSPEC = iota + NDA_DST + NDA_LLADDR + NDA_CACHEINFO + NDA_PROBES + NDA_VLAN + NDA_PORT + NDA_VNI + NDA_IFINDEX + NDA_MAX = NDA_IFINDEX +) + +// Neighbor Cache Entry States. +const ( + NUD_NONE = 0x00 + NUD_INCOMPLETE = 0x01 + NUD_REACHABLE = 0x02 + NUD_STALE = 0x04 + NUD_DELAY = 0x08 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 +) + +// Neighbor Flags +const ( + NTF_USE = 0x01 + NTF_SELF = 0x02 + NTF_MASTER = 0x04 + NTF_PROXY = 0x08 + NTF_ROUTER = 0x80 +) + +type Ndmsg struct { + Family uint8 + Index uint32 + State uint16 + Flags uint8 + Type uint8 +} + +func deserializeNdmsg(b []byte) *Ndmsg { + var dummy Ndmsg + return (*Ndmsg)(unsafe.Pointer(&b[0:unsafe.Sizeof(dummy)][0])) +} + +func (msg *Ndmsg) Serialize() []byte { + return (*(*[unsafe.Sizeof(*msg)]byte)(unsafe.Pointer(msg)))[:] +} + +func (msg *Ndmsg) Len() int { + return int(unsafe.Sizeof(*msg)) +} + +// NeighAdd will add an IP to MAC mapping to the ARP table +// Equivalent to: `ip neigh add ....` +func NeighAdd(neigh *Neigh) error { + return pkgHandle.NeighAdd(neigh) +} + +// NeighAdd will add an IP to MAC mapping to the ARP table +// Equivalent to: `ip neigh add ....` +func (h *Handle) NeighAdd(neigh *Neigh) error { + return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_EXCL) +} + +// NeighSet will add or replace an IP to MAC mapping to the ARP table +// Equivalent to: `ip neigh replace....` +func NeighSet(neigh *Neigh) error { + return pkgHandle.NeighSet(neigh) +} + +// NeighSet will add or replace an IP to MAC mapping to the ARP table +// Equivalent to: `ip neigh replace....` +func (h *Handle) NeighSet(neigh *Neigh) error { + return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_REPLACE) +} + +// NeighAppend will append an entry to FDB +// Equivalent to: `bridge fdb append...` +func NeighAppend(neigh *Neigh) error { + return pkgHandle.NeighAppend(neigh) +} + +// NeighAppend will append an entry to FDB +// Equivalent to: `bridge fdb append...` +func (h *Handle) NeighAppend(neigh *Neigh) error { + return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_APPEND) +} + +// NeighAppend will append an entry to FDB +// Equivalent to: `bridge fdb append...` +func neighAdd(neigh *Neigh, mode int) error { + return pkgHandle.neighAdd(neigh, mode) +} + +// NeighAppend will append an entry to FDB +// Equivalent to: `bridge fdb append...` +func (h *Handle) neighAdd(neigh *Neigh, mode int) error { + req := h.newNetlinkRequest(unix.RTM_NEWNEIGH, mode|unix.NLM_F_ACK) + return neighHandle(neigh, req) +} + +// NeighDel will delete an IP address from a link device. +// Equivalent to: `ip addr del $addr dev $link` +func NeighDel(neigh *Neigh) error { + return pkgHandle.NeighDel(neigh) +} + +// NeighDel will delete an IP address from a link device. +// Equivalent to: `ip addr del $addr dev $link` +func (h *Handle) NeighDel(neigh *Neigh) error { + req := h.newNetlinkRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK) + return neighHandle(neigh, req) +} + +func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error { + var family int + + if neigh.Family > 0 { + family = neigh.Family + } else { + family = nl.GetIPFamily(neigh.IP) + } + + msg := Ndmsg{ + Family: uint8(family), + Index: uint32(neigh.LinkIndex), + State: uint16(neigh.State), + Type: uint8(neigh.Type), + Flags: uint8(neigh.Flags), + } + req.AddData(&msg) + + ipData := neigh.IP.To4() + if ipData == nil { + ipData = neigh.IP.To16() + } + + dstData := nl.NewRtAttr(NDA_DST, ipData) + req.AddData(dstData) + + if neigh.LLIPAddr != nil { + llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4()) + req.AddData(llIPData) + } else if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil { + hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr)) + req.AddData(hwData) + } + + if neigh.Vlan != 0 { + vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan))) + req.AddData(vlanData) + } + + if neigh.VNI != 0 { + vniData := nl.NewRtAttr(NDA_VNI, nl.Uint32Attr(uint32(neigh.VNI))) + req.AddData(vniData) + } + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// NeighList gets a list of IP-MAC mappings in the system (ARP table). +// Equivalent to: `ip neighbor show`. +// The list can be filtered by link and ip family. +func NeighList(linkIndex, family int) ([]Neigh, error) { + return pkgHandle.NeighList(linkIndex, family) +} + +// NeighProxyList gets a list of neighbor proxies in the system. +// Equivalent to: `ip neighbor show proxy`. +// The list can be filtered by link and ip family. +func NeighProxyList(linkIndex, family int) ([]Neigh, error) { + return pkgHandle.NeighProxyList(linkIndex, family) +} + +// NeighList gets a list of IP-MAC mappings in the system (ARP table). +// Equivalent to: `ip neighbor show`. +// The list can be filtered by link and ip family. +func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) { + return h.neighList(linkIndex, family, 0) +} + +// NeighProxyList gets a list of neighbor proxies in the system. +// Equivalent to: `ip neighbor show proxy`. +// The list can be filtered by link, ip family. +func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) { + return h.neighList(linkIndex, family, NTF_PROXY) +} + +func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) { + req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP) + msg := Ndmsg{ + Family: uint8(family), + Index: uint32(linkIndex), + Flags: uint8(flags), + } + req.AddData(&msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH) + if err != nil { + return nil, err + } + + var res []Neigh + for _, m := range msgs { + ndm := deserializeNdmsg(m) + if linkIndex != 0 && int(ndm.Index) != linkIndex { + // Ignore messages from other interfaces + continue + } + + neigh, err := NeighDeserialize(m) + if err != nil { + continue + } + + res = append(res, *neigh) + } + + return res, nil +} + +func NeighDeserialize(m []byte) (*Neigh, error) { + msg := deserializeNdmsg(m) + + neigh := Neigh{ + LinkIndex: int(msg.Index), + Family: int(msg.Family), + State: int(msg.State), + Type: int(msg.Type), + Flags: int(msg.Flags), + } + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + // This should be cached for perfomance + // once per table dump + link, err := LinkByIndex(neigh.LinkIndex) + if err != nil { + return nil, err + } + encapType := link.Attrs().EncapType + + for _, attr := range attrs { + switch attr.Attr.Type { + case NDA_DST: + neigh.IP = net.IP(attr.Value) + case NDA_LLADDR: + // BUG: Is this a bug in the netlink library? + // #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) + // #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) + attrLen := attr.Attr.Len - unix.SizeofRtAttr + if attrLen == 4 && (encapType == "ipip" || + encapType == "sit" || + encapType == "gre") { + neigh.LLIPAddr = net.IP(attr.Value) + } else if attrLen == 16 && + encapType == "tunnel6" { + neigh.IP = net.IP(attr.Value) + } else { + neigh.HardwareAddr = net.HardwareAddr(attr.Value) + } + case NDA_VLAN: + neigh.Vlan = int(native.Uint16(attr.Value[0:2])) + case NDA_VNI: + neigh.VNI = int(native.Uint32(attr.Value[0:4])) + } + } + + return &neigh, nil +} diff --git a/vendor/github.com/vishvananda/netlink/netlink.go b/vendor/github.com/vishvananda/netlink/netlink.go new file mode 100644 index 0000000000000000000000000000000000000000..fb159526e316ffd5fb03b9b92d9a336eaf6c04d7 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/netlink.go @@ -0,0 +1,39 @@ +// Package netlink provides a simple library for netlink. Netlink is +// the interface a user-space program in linux uses to communicate with +// the kernel. It can be used to add and remove interfaces, set up ip +// addresses and routes, and confiugre ipsec. Netlink communication +// requires elevated privileges, so in most cases this code needs to +// be run as root. The low level primitives for netlink are contained +// in the nl subpackage. This package attempts to provide a high-level +// interface that is loosly modeled on the iproute2 cli. +package netlink + +import ( + "errors" + "net" +) + +var ( + // ErrNotImplemented is returned when a requested feature is not implemented. + ErrNotImplemented = errors.New("not implemented") +) + +// ParseIPNet parses a string in ip/net format and returns a net.IPNet. +// This is valuable because addresses in netlink are often IPNets and +// ParseCIDR returns an IPNet with the IP part set to the base IP of the +// range. +func ParseIPNet(s string) (*net.IPNet, error) { + ip, ipNet, err := net.ParseCIDR(s) + if err != nil { + return nil, err + } + return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil +} + +// NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128. +func NewIPNet(ip net.IP) *net.IPNet { + if ip.To4() != nil { + return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)} + } + return &net.IPNet{IP: ip, Mask: net.CIDRMask(128, 128)} +} diff --git a/vendor/github.com/vishvananda/netlink/netlink_linux.go b/vendor/github.com/vishvananda/netlink/netlink_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..a20d293d870fc8836c3d88dc7f6524e6c1068670 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/netlink_linux.go @@ -0,0 +1,11 @@ +package netlink + +import "github.com/vishvananda/netlink/nl" + +// Family type definitions +const ( + FAMILY_ALL = nl.FAMILY_ALL + FAMILY_V4 = nl.FAMILY_V4 + FAMILY_V6 = nl.FAMILY_V6 + FAMILY_MPLS = nl.FAMILY_MPLS +) diff --git a/vendor/github.com/vishvananda/netlink/netlink_unspecified.go b/vendor/github.com/vishvananda/netlink/netlink_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..86111b92ce167d59f7e73e2c1f17c4bbf8570473 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/netlink_unspecified.go @@ -0,0 +1,225 @@ +// +build !linux + +package netlink + +import "net" + +func LinkSetUp(link Link) error { + return ErrNotImplemented +} + +func LinkSetDown(link Link) error { + return ErrNotImplemented +} + +func LinkSetMTU(link Link, mtu int) error { + return ErrNotImplemented +} + +func LinkSetMaster(link Link, master *Bridge) error { + return ErrNotImplemented +} + +func LinkSetNsPid(link Link, nspid int) error { + return ErrNotImplemented +} + +func LinkSetNsFd(link Link, fd int) error { + return ErrNotImplemented +} + +func LinkSetName(link Link, name string) error { + return ErrNotImplemented +} + +func LinkSetAlias(link Link, name string) error { + return ErrNotImplemented +} + +func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { + return ErrNotImplemented +} + +func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { + return ErrNotImplemented +} + +func LinkSetVfVlan(link Link, vf, vlan int) error { + return ErrNotImplemented +} + +func LinkSetVfTxRate(link Link, vf, rate int) error { + return ErrNotImplemented +} + +func LinkSetNoMaster(link Link) error { + return ErrNotImplemented +} + +func LinkSetMasterByIndex(link Link, masterIndex int) error { + return ErrNotImplemented +} + +func LinkSetXdpFd(link Link, fd int) error { + return ErrNotImplemented +} + +func LinkSetARPOff(link Link) error { + return ErrNotImplemented +} + +func LinkSetARPOn(link Link) error { + return ErrNotImplemented +} + +func LinkByName(name string) (Link, error) { + return nil, ErrNotImplemented +} + +func LinkByAlias(alias string) (Link, error) { + return nil, ErrNotImplemented +} + +func LinkByIndex(index int) (Link, error) { + return nil, ErrNotImplemented +} + +func LinkSetHairpin(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetGuard(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetFastLeave(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetLearning(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetRootBlock(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetFlood(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkSetTxQLen(link Link, qlen int) error { + return ErrNotImplemented +} + +func LinkAdd(link Link) error { + return ErrNotImplemented +} + +func LinkDel(link Link) error { + return ErrNotImplemented +} + +func SetHairpin(link Link, mode bool) error { + return ErrNotImplemented +} + +func SetGuard(link Link, mode bool) error { + return ErrNotImplemented +} + +func SetFastLeave(link Link, mode bool) error { + return ErrNotImplemented +} + +func SetLearning(link Link, mode bool) error { + return ErrNotImplemented +} + +func SetRootBlock(link Link, mode bool) error { + return ErrNotImplemented +} + +func SetFlood(link Link, mode bool) error { + return ErrNotImplemented +} + +func LinkList() ([]Link, error) { + return nil, ErrNotImplemented +} + +func AddrAdd(link Link, addr *Addr) error { + return ErrNotImplemented +} + +func AddrDel(link Link, addr *Addr) error { + return ErrNotImplemented +} + +func AddrList(link Link, family int) ([]Addr, error) { + return nil, ErrNotImplemented +} + +func RouteAdd(route *Route) error { + return ErrNotImplemented +} + +func RouteDel(route *Route) error { + return ErrNotImplemented +} + +func RouteList(link Link, family int) ([]Route, error) { + return nil, ErrNotImplemented +} + +func XfrmPolicyAdd(policy *XfrmPolicy) error { + return ErrNotImplemented +} + +func XfrmPolicyDel(policy *XfrmPolicy) error { + return ErrNotImplemented +} + +func XfrmPolicyList(family int) ([]XfrmPolicy, error) { + return nil, ErrNotImplemented +} + +func XfrmStateAdd(policy *XfrmState) error { + return ErrNotImplemented +} + +func XfrmStateDel(policy *XfrmState) error { + return ErrNotImplemented +} + +func XfrmStateList(family int) ([]XfrmState, error) { + return nil, ErrNotImplemented +} + +func NeighAdd(neigh *Neigh) error { + return ErrNotImplemented +} + +func NeighSet(neigh *Neigh) error { + return ErrNotImplemented +} + +func NeighAppend(neigh *Neigh) error { + return ErrNotImplemented +} + +func NeighDel(neigh *Neigh) error { + return ErrNotImplemented +} + +func NeighList(linkIndex, family int) ([]Neigh, error) { + return nil, ErrNotImplemented +} + +func NeighDeserialize(m []byte) (*Neigh, error) { + return nil, ErrNotImplemented +} + +func SocketGet(local, remote net.Addr) (*Socket, error) { + return nil, ErrNotImplemented +} diff --git a/vendor/github.com/vishvananda/netlink/nl/BUILD.bazel b/vendor/github.com/vishvananda/netlink/nl/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..c40994477bca6e10b5676ceb17e5164aa3e33f36 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/BUILD.bazel @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "addr_linux.go", + "bridge_linux.go", + "conntrack_linux.go", + "genetlink_linux.go", + "link_linux.go", + "mpls_linux.go", + "nl_linux.go", + "nl_unspecified.go", + "route_linux.go", + "seg6_linux.go", + "syscall.go", + "tc_linux.go", + "xfrm_linux.go", + "xfrm_monitor_linux.go", + "xfrm_policy_linux.go", + "xfrm_state_linux.go", + ], + importmap = "vendor/github.com/vishvananda/netlink/nl", + importpath = "github.com/vishvananda/netlink/nl", + visibility = ["//visibility:public"], + deps = select({ + "@io_bazel_rules_go//go/platform:linux": [ + "//vendor/github.com/vishvananda/netns:go_default_library", + "//vendor/golang.org/x/sys/unix:go_default_library", + ], + "//conditions:default": [], + }), +) diff --git a/vendor/github.com/vishvananda/netlink/nl/addr_linux.go b/vendor/github.com/vishvananda/netlink/nl/addr_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..50db3b4cdd87f1bc9d4a1b59e0fdbdd2448a8246 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/addr_linux.go @@ -0,0 +1,77 @@ +package nl + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +type IfAddrmsg struct { + unix.IfAddrmsg +} + +func NewIfAddrmsg(family int) *IfAddrmsg { + return &IfAddrmsg{ + IfAddrmsg: unix.IfAddrmsg{ + Family: uint8(family), + }, + } +} + +// struct ifaddrmsg { +// __u8 ifa_family; +// __u8 ifa_prefixlen; /* The prefix length */ +// __u8 ifa_flags; /* Flags */ +// __u8 ifa_scope; /* Address scope */ +// __u32 ifa_index; /* Link index */ +// }; + +// type IfAddrmsg struct { +// Family uint8 +// Prefixlen uint8 +// Flags uint8 +// Scope uint8 +// Index uint32 +// } +// SizeofIfAddrmsg = 0x8 + +func DeserializeIfAddrmsg(b []byte) *IfAddrmsg { + return (*IfAddrmsg)(unsafe.Pointer(&b[0:unix.SizeofIfAddrmsg][0])) +} + +func (msg *IfAddrmsg) Serialize() []byte { + return (*(*[unix.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:] +} + +func (msg *IfAddrmsg) Len() int { + return unix.SizeofIfAddrmsg +} + +// struct ifa_cacheinfo { +// __u32 ifa_prefered; +// __u32 ifa_valid; +// __u32 cstamp; /* created timestamp, hundredths of seconds */ +// __u32 tstamp; /* updated timestamp, hundredths of seconds */ +// }; + +const IFA_CACHEINFO = 6 +const SizeofIfaCacheInfo = 0x10 + +type IfaCacheInfo struct { + IfaPrefered uint32 + IfaValid uint32 + Cstamp uint32 + Tstamp uint32 +} + +func (msg *IfaCacheInfo) Len() int { + return SizeofIfaCacheInfo +} + +func DeserializeIfaCacheInfo(b []byte) *IfaCacheInfo { + return (*IfaCacheInfo)(unsafe.Pointer(&b[0:SizeofIfaCacheInfo][0])) +} + +func (msg *IfaCacheInfo) Serialize() []byte { + return (*(*[SizeofIfaCacheInfo]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go b/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..6c0d333387d67788f34bfea21b5309d8597098d2 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go @@ -0,0 +1,74 @@ +package nl + +import ( + "fmt" + "unsafe" +) + +const ( + SizeofBridgeVlanInfo = 0x04 +) + +/* Bridge Flags */ +const ( + BRIDGE_FLAGS_MASTER = iota /* Bridge command to/from master */ + BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */ +) + +/* Bridge management nested attributes + * [IFLA_AF_SPEC] = { + * [IFLA_BRIDGE_FLAGS] + * [IFLA_BRIDGE_MODE] + * [IFLA_BRIDGE_VLAN_INFO] + * } + */ +const ( + IFLA_BRIDGE_FLAGS = iota + IFLA_BRIDGE_MODE + IFLA_BRIDGE_VLAN_INFO +) + +const ( + BRIDGE_VLAN_INFO_MASTER = 1 << iota + BRIDGE_VLAN_INFO_PVID + BRIDGE_VLAN_INFO_UNTAGGED + BRIDGE_VLAN_INFO_RANGE_BEGIN + BRIDGE_VLAN_INFO_RANGE_END +) + +// struct bridge_vlan_info { +// __u16 flags; +// __u16 vid; +// }; + +type BridgeVlanInfo struct { + Flags uint16 + Vid uint16 +} + +func (b *BridgeVlanInfo) Serialize() []byte { + return (*(*[SizeofBridgeVlanInfo]byte)(unsafe.Pointer(b)))[:] +} + +func DeserializeBridgeVlanInfo(b []byte) *BridgeVlanInfo { + return (*BridgeVlanInfo)(unsafe.Pointer(&b[0:SizeofBridgeVlanInfo][0])) +} + +func (b *BridgeVlanInfo) PortVID() bool { + return b.Flags&BRIDGE_VLAN_INFO_PVID > 0 +} + +func (b *BridgeVlanInfo) EngressUntag() bool { + return b.Flags&BRIDGE_VLAN_INFO_UNTAGGED > 0 +} + +func (b *BridgeVlanInfo) String() string { + return fmt.Sprintf("%+v", *b) +} + +/* New extended info filters for IFLA_EXT_MASK */ +const ( + RTEXT_FILTER_VF = 1 << iota + RTEXT_FILTER_BRVLAN + RTEXT_FILTER_BRVLAN_COMPRESSED +) diff --git a/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go b/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..380cc5967bfa9168bffbcc708c0068ab5a059ba9 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go @@ -0,0 +1,189 @@ +package nl + +import "unsafe" + +// Track the message sizes for the correct serialization/deserialization +const ( + SizeofNfgenmsg = 4 + SizeofNfattr = 4 + SizeofNfConntrack = 376 + SizeofNfctTupleHead = 52 +) + +var L4ProtoMap = map[uint8]string{ + 6: "tcp", + 17: "udp", +} + +// All the following constants are coming from: +// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink_conntrack.h + +// enum cntl_msg_types { +// IPCTNL_MSG_CT_NEW, +// IPCTNL_MSG_CT_GET, +// IPCTNL_MSG_CT_DELETE, +// IPCTNL_MSG_CT_GET_CTRZERO, +// IPCTNL_MSG_CT_GET_STATS_CPU, +// IPCTNL_MSG_CT_GET_STATS, +// IPCTNL_MSG_CT_GET_DYING, +// IPCTNL_MSG_CT_GET_UNCONFIRMED, +// +// IPCTNL_MSG_MAX +// }; +const ( + IPCTNL_MSG_CT_GET = 1 + IPCTNL_MSG_CT_DELETE = 2 +) + +// #define NFNETLINK_V0 0 +const ( + NFNETLINK_V0 = 0 +) + +// #define NLA_F_NESTED (1 << 15) +const ( + NLA_F_NESTED = (1 << 15) +) + +// enum ctattr_type { +// CTA_UNSPEC, +// CTA_TUPLE_ORIG, +// CTA_TUPLE_REPLY, +// CTA_STATUS, +// CTA_PROTOINFO, +// CTA_HELP, +// CTA_NAT_SRC, +// #define CTA_NAT CTA_NAT_SRC /* backwards compatibility */ +// CTA_TIMEOUT, +// CTA_MARK, +// CTA_COUNTERS_ORIG, +// CTA_COUNTERS_REPLY, +// CTA_USE, +// CTA_ID, +// CTA_NAT_DST, +// CTA_TUPLE_MASTER, +// CTA_SEQ_ADJ_ORIG, +// CTA_NAT_SEQ_ADJ_ORIG = CTA_SEQ_ADJ_ORIG, +// CTA_SEQ_ADJ_REPLY, +// CTA_NAT_SEQ_ADJ_REPLY = CTA_SEQ_ADJ_REPLY, +// CTA_SECMARK, /* obsolete */ +// CTA_ZONE, +// CTA_SECCTX, +// CTA_TIMESTAMP, +// CTA_MARK_MASK, +// CTA_LABELS, +// CTA_LABELS_MASK, +// __CTA_MAX +// }; +const ( + CTA_TUPLE_ORIG = 1 + CTA_TUPLE_REPLY = 2 + CTA_STATUS = 3 + CTA_TIMEOUT = 7 + CTA_MARK = 8 + CTA_PROTOINFO = 4 +) + +// enum ctattr_tuple { +// CTA_TUPLE_UNSPEC, +// CTA_TUPLE_IP, +// CTA_TUPLE_PROTO, +// CTA_TUPLE_ZONE, +// __CTA_TUPLE_MAX +// }; +// #define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1) +const ( + CTA_TUPLE_IP = 1 + CTA_TUPLE_PROTO = 2 +) + +// enum ctattr_ip { +// CTA_IP_UNSPEC, +// CTA_IP_V4_SRC, +// CTA_IP_V4_DST, +// CTA_IP_V6_SRC, +// CTA_IP_V6_DST, +// __CTA_IP_MAX +// }; +// #define CTA_IP_MAX (__CTA_IP_MAX - 1) +const ( + CTA_IP_V4_SRC = 1 + CTA_IP_V4_DST = 2 + CTA_IP_V6_SRC = 3 + CTA_IP_V6_DST = 4 +) + +// enum ctattr_l4proto { +// CTA_PROTO_UNSPEC, +// CTA_PROTO_NUM, +// CTA_PROTO_SRC_PORT, +// CTA_PROTO_DST_PORT, +// CTA_PROTO_ICMP_ID, +// CTA_PROTO_ICMP_TYPE, +// CTA_PROTO_ICMP_CODE, +// CTA_PROTO_ICMPV6_ID, +// CTA_PROTO_ICMPV6_TYPE, +// CTA_PROTO_ICMPV6_CODE, +// __CTA_PROTO_MAX +// }; +// #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1) +const ( + CTA_PROTO_NUM = 1 + CTA_PROTO_SRC_PORT = 2 + CTA_PROTO_DST_PORT = 3 +) + +// enum ctattr_protoinfo { +// CTA_PROTOINFO_UNSPEC, +// CTA_PROTOINFO_TCP, +// CTA_PROTOINFO_DCCP, +// CTA_PROTOINFO_SCTP, +// __CTA_PROTOINFO_MAX +// }; +// #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1) +const ( + CTA_PROTOINFO_TCP = 1 +) + +// enum ctattr_protoinfo_tcp { +// CTA_PROTOINFO_TCP_UNSPEC, +// CTA_PROTOINFO_TCP_STATE, +// CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, +// CTA_PROTOINFO_TCP_WSCALE_REPLY, +// CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, +// CTA_PROTOINFO_TCP_FLAGS_REPLY, +// __CTA_PROTOINFO_TCP_MAX +// }; +// #define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1) +const ( + CTA_PROTOINFO_TCP_STATE = 1 + CTA_PROTOINFO_TCP_WSCALE_ORIGINAL = 2 + CTA_PROTOINFO_TCP_WSCALE_REPLY = 3 + CTA_PROTOINFO_TCP_FLAGS_ORIGINAL = 4 + CTA_PROTOINFO_TCP_FLAGS_REPLY = 5 +) + +// /* General form of address family dependent message. +// */ +// struct nfgenmsg { +// __u8 nfgen_family; /* AF_xxx */ +// __u8 version; /* nfnetlink version */ +// __be16 res_id; /* resource id */ +// }; +type Nfgenmsg struct { + NfgenFamily uint8 + Version uint8 + ResId uint16 // big endian +} + +func (msg *Nfgenmsg) Len() int { + return SizeofNfgenmsg +} + +func DeserializeNfgenmsg(b []byte) *Nfgenmsg { + return (*Nfgenmsg)(unsafe.Pointer(&b[0:SizeofNfgenmsg][0])) +} + +func (msg *Nfgenmsg) Serialize() []byte { + return (*(*[SizeofNfgenmsg]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/genetlink_linux.go b/vendor/github.com/vishvananda/netlink/nl/genetlink_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..81b46f2c79206d212c2daf89b0baab97fbdc36d0 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/genetlink_linux.go @@ -0,0 +1,89 @@ +package nl + +import ( + "unsafe" +) + +const SizeofGenlmsg = 4 + +const ( + GENL_ID_CTRL = 0x10 + GENL_CTRL_VERSION = 2 + GENL_CTRL_NAME = "nlctrl" +) + +const ( + GENL_CTRL_CMD_GETFAMILY = 3 +) + +const ( + GENL_CTRL_ATTR_UNSPEC = iota + GENL_CTRL_ATTR_FAMILY_ID + GENL_CTRL_ATTR_FAMILY_NAME + GENL_CTRL_ATTR_VERSION + GENL_CTRL_ATTR_HDRSIZE + GENL_CTRL_ATTR_MAXATTR + GENL_CTRL_ATTR_OPS + GENL_CTRL_ATTR_MCAST_GROUPS +) + +const ( + GENL_CTRL_ATTR_OP_UNSPEC = iota + GENL_CTRL_ATTR_OP_ID + GENL_CTRL_ATTR_OP_FLAGS +) + +const ( + GENL_ADMIN_PERM = 1 << iota + GENL_CMD_CAP_DO + GENL_CMD_CAP_DUMP + GENL_CMD_CAP_HASPOL +) + +const ( + GENL_CTRL_ATTR_MCAST_GRP_UNSPEC = iota + GENL_CTRL_ATTR_MCAST_GRP_NAME + GENL_CTRL_ATTR_MCAST_GRP_ID +) + +const ( + GENL_GTP_VERSION = 0 + GENL_GTP_NAME = "gtp" +) + +const ( + GENL_GTP_CMD_NEWPDP = iota + GENL_GTP_CMD_DELPDP + GENL_GTP_CMD_GETPDP +) + +const ( + GENL_GTP_ATTR_UNSPEC = iota + GENL_GTP_ATTR_LINK + GENL_GTP_ATTR_VERSION + GENL_GTP_ATTR_TID + GENL_GTP_ATTR_PEER_ADDRESS + GENL_GTP_ATTR_MS_ADDRESS + GENL_GTP_ATTR_FLOW + GENL_GTP_ATTR_NET_NS_FD + GENL_GTP_ATTR_I_TEI + GENL_GTP_ATTR_O_TEI + GENL_GTP_ATTR_PAD +) + +type Genlmsg struct { + Command uint8 + Version uint8 +} + +func (msg *Genlmsg) Len() int { + return SizeofGenlmsg +} + +func DeserializeGenlmsg(b []byte) *Genlmsg { + return (*Genlmsg)(unsafe.Pointer(&b[0:SizeofGenlmsg][0])) +} + +func (msg *Genlmsg) Serialize() []byte { + return (*(*[SizeofGenlmsg]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/link_linux.go b/vendor/github.com/vishvananda/netlink/nl/link_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..84a3498dd3d3515b26ffccfaa68be6c6321ed2bd --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/link_linux.go @@ -0,0 +1,548 @@ +package nl + +import ( + "unsafe" +) + +const ( + DEFAULT_CHANGE = 0xFFFFFFFF +) + +const ( + IFLA_INFO_UNSPEC = iota + IFLA_INFO_KIND + IFLA_INFO_DATA + IFLA_INFO_XSTATS + IFLA_INFO_MAX = IFLA_INFO_XSTATS +) + +const ( + IFLA_VLAN_UNSPEC = iota + IFLA_VLAN_ID + IFLA_VLAN_FLAGS + IFLA_VLAN_EGRESS_QOS + IFLA_VLAN_INGRESS_QOS + IFLA_VLAN_PROTOCOL + IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL +) + +const ( + VETH_INFO_UNSPEC = iota + VETH_INFO_PEER + VETH_INFO_MAX = VETH_INFO_PEER +) + +const ( + IFLA_VXLAN_UNSPEC = iota + IFLA_VXLAN_ID + IFLA_VXLAN_GROUP + IFLA_VXLAN_LINK + IFLA_VXLAN_LOCAL + IFLA_VXLAN_TTL + IFLA_VXLAN_TOS + IFLA_VXLAN_LEARNING + IFLA_VXLAN_AGEING + IFLA_VXLAN_LIMIT + IFLA_VXLAN_PORT_RANGE + IFLA_VXLAN_PROXY + IFLA_VXLAN_RSC + IFLA_VXLAN_L2MISS + IFLA_VXLAN_L3MISS + IFLA_VXLAN_PORT + IFLA_VXLAN_GROUP6 + IFLA_VXLAN_LOCAL6 + IFLA_VXLAN_UDP_CSUM + IFLA_VXLAN_UDP_ZERO_CSUM6_TX + IFLA_VXLAN_UDP_ZERO_CSUM6_RX + IFLA_VXLAN_REMCSUM_TX + IFLA_VXLAN_REMCSUM_RX + IFLA_VXLAN_GBP + IFLA_VXLAN_REMCSUM_NOPARTIAL + IFLA_VXLAN_FLOWBASED + IFLA_VXLAN_MAX = IFLA_VXLAN_FLOWBASED +) + +const ( + BRIDGE_MODE_UNSPEC = iota + BRIDGE_MODE_HAIRPIN +) + +const ( + IFLA_BRPORT_UNSPEC = iota + IFLA_BRPORT_STATE + IFLA_BRPORT_PRIORITY + IFLA_BRPORT_COST + IFLA_BRPORT_MODE + IFLA_BRPORT_GUARD + IFLA_BRPORT_PROTECT + IFLA_BRPORT_FAST_LEAVE + IFLA_BRPORT_LEARNING + IFLA_BRPORT_UNICAST_FLOOD + IFLA_BRPORT_PROXYARP + IFLA_BRPORT_LEARNING_SYNC + IFLA_BRPORT_PROXYARP_WIFI + IFLA_BRPORT_MAX = IFLA_BRPORT_PROXYARP_WIFI +) + +const ( + IFLA_IPVLAN_UNSPEC = iota + IFLA_IPVLAN_MODE + IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE +) + +const ( + IFLA_MACVLAN_UNSPEC = iota + IFLA_MACVLAN_MODE + IFLA_MACVLAN_FLAGS + IFLA_MACVLAN_MACADDR_MODE + IFLA_MACVLAN_MACADDR + IFLA_MACVLAN_MACADDR_DATA + IFLA_MACVLAN_MACADDR_COUNT + IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS +) + +const ( + MACVLAN_MODE_PRIVATE = 1 + MACVLAN_MODE_VEPA = 2 + MACVLAN_MODE_BRIDGE = 4 + MACVLAN_MODE_PASSTHRU = 8 + MACVLAN_MODE_SOURCE = 16 +) + +const ( + MACVLAN_MACADDR_ADD = iota + MACVLAN_MACADDR_DEL + MACVLAN_MACADDR_FLUSH + MACVLAN_MACADDR_SET +) + +const ( + IFLA_BOND_UNSPEC = iota + IFLA_BOND_MODE + IFLA_BOND_ACTIVE_SLAVE + IFLA_BOND_MIIMON + IFLA_BOND_UPDELAY + IFLA_BOND_DOWNDELAY + IFLA_BOND_USE_CARRIER + IFLA_BOND_ARP_INTERVAL + IFLA_BOND_ARP_IP_TARGET + IFLA_BOND_ARP_VALIDATE + IFLA_BOND_ARP_ALL_TARGETS + IFLA_BOND_PRIMARY + IFLA_BOND_PRIMARY_RESELECT + IFLA_BOND_FAIL_OVER_MAC + IFLA_BOND_XMIT_HASH_POLICY + IFLA_BOND_RESEND_IGMP + IFLA_BOND_NUM_PEER_NOTIF + IFLA_BOND_ALL_SLAVES_ACTIVE + IFLA_BOND_MIN_LINKS + IFLA_BOND_LP_INTERVAL + IFLA_BOND_PACKETS_PER_SLAVE + IFLA_BOND_AD_LACP_RATE + IFLA_BOND_AD_SELECT + IFLA_BOND_AD_INFO + IFLA_BOND_AD_ACTOR_SYS_PRIO + IFLA_BOND_AD_USER_PORT_KEY + IFLA_BOND_AD_ACTOR_SYSTEM + IFLA_BOND_TLB_DYNAMIC_LB +) + +const ( + IFLA_BOND_AD_INFO_UNSPEC = iota + IFLA_BOND_AD_INFO_AGGREGATOR + IFLA_BOND_AD_INFO_NUM_PORTS + IFLA_BOND_AD_INFO_ACTOR_KEY + IFLA_BOND_AD_INFO_PARTNER_KEY + IFLA_BOND_AD_INFO_PARTNER_MAC +) + +const ( + IFLA_BOND_SLAVE_UNSPEC = iota + IFLA_BOND_SLAVE_STATE + IFLA_BOND_SLAVE_MII_STATUS + IFLA_BOND_SLAVE_LINK_FAILURE_COUNT + IFLA_BOND_SLAVE_PERM_HWADDR + IFLA_BOND_SLAVE_QUEUE_ID + IFLA_BOND_SLAVE_AD_AGGREGATOR_ID +) + +const ( + IFLA_GRE_UNSPEC = iota + IFLA_GRE_LINK + IFLA_GRE_IFLAGS + IFLA_GRE_OFLAGS + IFLA_GRE_IKEY + IFLA_GRE_OKEY + IFLA_GRE_LOCAL + IFLA_GRE_REMOTE + IFLA_GRE_TTL + IFLA_GRE_TOS + IFLA_GRE_PMTUDISC + IFLA_GRE_ENCAP_LIMIT + IFLA_GRE_FLOWINFO + IFLA_GRE_FLAGS + IFLA_GRE_ENCAP_TYPE + IFLA_GRE_ENCAP_FLAGS + IFLA_GRE_ENCAP_SPORT + IFLA_GRE_ENCAP_DPORT + IFLA_GRE_COLLECT_METADATA + IFLA_GRE_MAX = IFLA_GRE_COLLECT_METADATA +) + +const ( + GRE_CSUM = 0x8000 + GRE_ROUTING = 0x4000 + GRE_KEY = 0x2000 + GRE_SEQ = 0x1000 + GRE_STRICT = 0x0800 + GRE_REC = 0x0700 + GRE_FLAGS = 0x00F8 + GRE_VERSION = 0x0007 +) + +const ( + IFLA_VF_INFO_UNSPEC = iota + IFLA_VF_INFO + IFLA_VF_INFO_MAX = IFLA_VF_INFO +) + +const ( + IFLA_VF_UNSPEC = iota + IFLA_VF_MAC /* Hardware queue specific attributes */ + IFLA_VF_VLAN + IFLA_VF_TX_RATE /* Max TX Bandwidth Allocation */ + IFLA_VF_SPOOFCHK /* Spoof Checking on/off switch */ + IFLA_VF_LINK_STATE /* link state enable/disable/auto switch */ + IFLA_VF_RATE /* Min and Max TX Bandwidth Allocation */ + IFLA_VF_RSS_QUERY_EN /* RSS Redirection Table and Hash Key query + * on/off switch + */ + IFLA_VF_STATS /* network device statistics */ + IFLA_VF_TRUST /* Trust state of VF */ + IFLA_VF_MAX = IFLA_VF_TRUST +) + +const ( + IFLA_VF_LINK_STATE_AUTO = iota /* link state of the uplink */ + IFLA_VF_LINK_STATE_ENABLE /* link always up */ + IFLA_VF_LINK_STATE_DISABLE /* link always down */ + IFLA_VF_LINK_STATE_MAX = IFLA_VF_LINK_STATE_DISABLE +) + +const ( + IFLA_VF_STATS_RX_PACKETS = iota + IFLA_VF_STATS_TX_PACKETS + IFLA_VF_STATS_RX_BYTES + IFLA_VF_STATS_TX_BYTES + IFLA_VF_STATS_BROADCAST + IFLA_VF_STATS_MULTICAST + IFLA_VF_STATS_MAX = IFLA_VF_STATS_MULTICAST +) + +const ( + SizeofVfMac = 0x24 + SizeofVfVlan = 0x0c + SizeofVfTxRate = 0x08 + SizeofVfRate = 0x0c + SizeofVfSpoofchk = 0x08 + SizeofVfLinkState = 0x08 + SizeofVfRssQueryEn = 0x08 + SizeofVfTrust = 0x08 +) + +// struct ifla_vf_mac { +// __u32 vf; +// __u8 mac[32]; /* MAX_ADDR_LEN */ +// }; + +type VfMac struct { + Vf uint32 + Mac [32]byte +} + +func (msg *VfMac) Len() int { + return SizeofVfMac +} + +func DeserializeVfMac(b []byte) *VfMac { + return (*VfMac)(unsafe.Pointer(&b[0:SizeofVfMac][0])) +} + +func (msg *VfMac) Serialize() []byte { + return (*(*[SizeofVfMac]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_vlan { +// __u32 vf; +// __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ +// __u32 qos; +// }; + +type VfVlan struct { + Vf uint32 + Vlan uint32 + Qos uint32 +} + +func (msg *VfVlan) Len() int { + return SizeofVfVlan +} + +func DeserializeVfVlan(b []byte) *VfVlan { + return (*VfVlan)(unsafe.Pointer(&b[0:SizeofVfVlan][0])) +} + +func (msg *VfVlan) Serialize() []byte { + return (*(*[SizeofVfVlan]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_tx_rate { +// __u32 vf; +// __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ +// }; + +type VfTxRate struct { + Vf uint32 + Rate uint32 +} + +func (msg *VfTxRate) Len() int { + return SizeofVfTxRate +} + +func DeserializeVfTxRate(b []byte) *VfTxRate { + return (*VfTxRate)(unsafe.Pointer(&b[0:SizeofVfTxRate][0])) +} + +func (msg *VfTxRate) Serialize() []byte { + return (*(*[SizeofVfTxRate]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_rate { +// __u32 vf; +// __u32 min_tx_rate; /* Min Bandwidth in Mbps */ +// __u32 max_tx_rate; /* Max Bandwidth in Mbps */ +// }; + +type VfRate struct { + Vf uint32 + MinTxRate uint32 + MaxTxRate uint32 +} + +func (msg *VfRate) Len() int { + return SizeofVfRate +} + +func DeserializeVfRate(b []byte) *VfRate { + return (*VfRate)(unsafe.Pointer(&b[0:SizeofVfRate][0])) +} + +func (msg *VfRate) Serialize() []byte { + return (*(*[SizeofVfRate]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_spoofchk { +// __u32 vf; +// __u32 setting; +// }; + +type VfSpoofchk struct { + Vf uint32 + Setting uint32 +} + +func (msg *VfSpoofchk) Len() int { + return SizeofVfSpoofchk +} + +func DeserializeVfSpoofchk(b []byte) *VfSpoofchk { + return (*VfSpoofchk)(unsafe.Pointer(&b[0:SizeofVfSpoofchk][0])) +} + +func (msg *VfSpoofchk) Serialize() []byte { + return (*(*[SizeofVfSpoofchk]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_link_state { +// __u32 vf; +// __u32 link_state; +// }; + +type VfLinkState struct { + Vf uint32 + LinkState uint32 +} + +func (msg *VfLinkState) Len() int { + return SizeofVfLinkState +} + +func DeserializeVfLinkState(b []byte) *VfLinkState { + return (*VfLinkState)(unsafe.Pointer(&b[0:SizeofVfLinkState][0])) +} + +func (msg *VfLinkState) Serialize() []byte { + return (*(*[SizeofVfLinkState]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_rss_query_en { +// __u32 vf; +// __u32 setting; +// }; + +type VfRssQueryEn struct { + Vf uint32 + Setting uint32 +} + +func (msg *VfRssQueryEn) Len() int { + return SizeofVfRssQueryEn +} + +func DeserializeVfRssQueryEn(b []byte) *VfRssQueryEn { + return (*VfRssQueryEn)(unsafe.Pointer(&b[0:SizeofVfRssQueryEn][0])) +} + +func (msg *VfRssQueryEn) Serialize() []byte { + return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:] +} + +// struct ifla_vf_trust { +// __u32 vf; +// __u32 setting; +// }; + +type VfTrust struct { + Vf uint32 + Setting uint32 +} + +func (msg *VfTrust) Len() int { + return SizeofVfTrust +} + +func DeserializeVfTrust(b []byte) *VfTrust { + return (*VfTrust)(unsafe.Pointer(&b[0:SizeofVfTrust][0])) +} + +func (msg *VfTrust) Serialize() []byte { + return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:] +} + +const ( + XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota + XDP_FLAGS_SKB_MODE + XDP_FLAGS_DRV_MODE + XDP_FLAGS_MASK = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE +) + +const ( + IFLA_XDP_UNSPEC = iota + IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */ + IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */ + IFLA_XDP_FLAGS /* xdp prog related flags */ + IFLA_XDP_PROG_ID /* xdp prog id */ + IFLA_XDP_MAX = IFLA_XDP_PROG_ID +) + +const ( + IFLA_IPTUN_UNSPEC = iota + IFLA_IPTUN_LINK + IFLA_IPTUN_LOCAL + IFLA_IPTUN_REMOTE + IFLA_IPTUN_TTL + IFLA_IPTUN_TOS + IFLA_IPTUN_ENCAP_LIMIT + IFLA_IPTUN_FLOWINFO + IFLA_IPTUN_FLAGS + IFLA_IPTUN_PROTO + IFLA_IPTUN_PMTUDISC + IFLA_IPTUN_6RD_PREFIX + IFLA_IPTUN_6RD_RELAY_PREFIX + IFLA_IPTUN_6RD_PREFIXLEN + IFLA_IPTUN_6RD_RELAY_PREFIXLEN + IFLA_IPTUN_ENCAP_TYPE + IFLA_IPTUN_ENCAP_FLAGS + IFLA_IPTUN_ENCAP_SPORT + IFLA_IPTUN_ENCAP_DPORT + IFLA_IPTUN_COLLECT_METADATA + IFLA_IPTUN_MAX = IFLA_IPTUN_COLLECT_METADATA +) + +const ( + IFLA_VTI_UNSPEC = iota + IFLA_VTI_LINK + IFLA_VTI_IKEY + IFLA_VTI_OKEY + IFLA_VTI_LOCAL + IFLA_VTI_REMOTE + IFLA_VTI_MAX = IFLA_VTI_REMOTE +) + +const ( + IFLA_VRF_UNSPEC = iota + IFLA_VRF_TABLE +) + +const ( + IFLA_BR_UNSPEC = iota + IFLA_BR_FORWARD_DELAY + IFLA_BR_HELLO_TIME + IFLA_BR_MAX_AGE + IFLA_BR_AGEING_TIME + IFLA_BR_STP_STATE + IFLA_BR_PRIORITY + IFLA_BR_VLAN_FILTERING + IFLA_BR_VLAN_PROTOCOL + IFLA_BR_GROUP_FWD_MASK + IFLA_BR_ROOT_ID + IFLA_BR_BRIDGE_ID + IFLA_BR_ROOT_PORT + IFLA_BR_ROOT_PATH_COST + IFLA_BR_TOPOLOGY_CHANGE + IFLA_BR_TOPOLOGY_CHANGE_DETECTED + IFLA_BR_HELLO_TIMER + IFLA_BR_TCN_TIMER + IFLA_BR_TOPOLOGY_CHANGE_TIMER + IFLA_BR_GC_TIMER + IFLA_BR_GROUP_ADDR + IFLA_BR_FDB_FLUSH + IFLA_BR_MCAST_ROUTER + IFLA_BR_MCAST_SNOOPING + IFLA_BR_MCAST_QUERY_USE_IFADDR + IFLA_BR_MCAST_QUERIER + IFLA_BR_MCAST_HASH_ELASTICITY + IFLA_BR_MCAST_HASH_MAX + IFLA_BR_MCAST_LAST_MEMBER_CNT + IFLA_BR_MCAST_STARTUP_QUERY_CNT + IFLA_BR_MCAST_LAST_MEMBER_INTVL + IFLA_BR_MCAST_MEMBERSHIP_INTVL + IFLA_BR_MCAST_QUERIER_INTVL + IFLA_BR_MCAST_QUERY_INTVL + IFLA_BR_MCAST_QUERY_RESPONSE_INTVL + IFLA_BR_MCAST_STARTUP_QUERY_INTVL + IFLA_BR_NF_CALL_IPTABLES + IFLA_BR_NF_CALL_IP6TABLES + IFLA_BR_NF_CALL_ARPTABLES + IFLA_BR_VLAN_DEFAULT_PVID + IFLA_BR_PAD + IFLA_BR_VLAN_STATS_ENABLED + IFLA_BR_MCAST_STATS_ENABLED + IFLA_BR_MCAST_IGMP_VERSION + IFLA_BR_MCAST_MLD_VERSION + IFLA_BR_MAX = IFLA_BR_MCAST_MLD_VERSION +) + +const ( + IFLA_GTP_UNSPEC = iota + IFLA_GTP_FD0 + IFLA_GTP_FD1 + IFLA_GTP_PDP_HASHSIZE + IFLA_GTP_ROLE +) + +const ( + GTP_ROLE_GGSN = iota + GTP_ROLE_SGSN +) diff --git a/vendor/github.com/vishvananda/netlink/nl/mpls_linux.go b/vendor/github.com/vishvananda/netlink/nl/mpls_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..3915b7eec44d85a5c47895e7b586d8e834a28e9d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/mpls_linux.go @@ -0,0 +1,36 @@ +package nl + +import "encoding/binary" + +const ( + MPLS_LS_LABEL_SHIFT = 12 + MPLS_LS_S_SHIFT = 8 +) + +func EncodeMPLSStack(labels ...int) []byte { + b := make([]byte, 4*len(labels)) + for idx, label := range labels { + l := label << MPLS_LS_LABEL_SHIFT + if idx == len(labels)-1 { + l |= 1 << MPLS_LS_S_SHIFT + } + binary.BigEndian.PutUint32(b[idx*4:], uint32(l)) + } + return b +} + +func DecodeMPLSStack(buf []byte) []int { + if len(buf)%4 != 0 { + return nil + } + stack := make([]int, 0, len(buf)/4) + for len(buf) > 0 { + l := binary.BigEndian.Uint32(buf[:4]) + buf = buf[4:] + stack = append(stack, int(l)>>MPLS_LS_LABEL_SHIFT) + if (l>>MPLS_LS_S_SHIFT)&1 > 0 { + break + } + } + return stack +} diff --git a/vendor/github.com/vishvananda/netlink/nl/nl_linux.go b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..bc8e82c2cc4d0cbcd71717ddafcadbec0142a7ae --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go @@ -0,0 +1,738 @@ +// Package nl has low level primitives for making Netlink calls. +package nl + +import ( + "bytes" + "encoding/binary" + "fmt" + "net" + "runtime" + "sync" + "sync/atomic" + "syscall" + "unsafe" + + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +const ( + // Family type definitions + FAMILY_ALL = unix.AF_UNSPEC + FAMILY_V4 = unix.AF_INET + FAMILY_V6 = unix.AF_INET6 + FAMILY_MPLS = AF_MPLS +) + +// SupportedNlFamilies contains the list of netlink families this netlink package supports +var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETLINK_NETFILTER} + +var nextSeqNr uint32 + +// GetIPFamily returns the family type of a net.IP. +func GetIPFamily(ip net.IP) int { + if len(ip) <= net.IPv4len { + return FAMILY_V4 + } + if ip.To4() != nil { + return FAMILY_V4 + } + return FAMILY_V6 +} + +var nativeEndian binary.ByteOrder + +// Get native endianness for the system +func NativeEndian() binary.ByteOrder { + if nativeEndian == nil { + var x uint32 = 0x01020304 + if *(*byte)(unsafe.Pointer(&x)) == 0x01 { + nativeEndian = binary.BigEndian + } else { + nativeEndian = binary.LittleEndian + } + } + return nativeEndian +} + +// Byte swap a 16 bit value if we aren't big endian +func Swap16(i uint16) uint16 { + if NativeEndian() == binary.BigEndian { + return i + } + return (i&0xff00)>>8 | (i&0xff)<<8 +} + +// Byte swap a 32 bit value if aren't big endian +func Swap32(i uint32) uint32 { + if NativeEndian() == binary.BigEndian { + return i + } + return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24 +} + +type NetlinkRequestData interface { + Len() int + Serialize() []byte +} + +// IfInfomsg is related to links, but it is used for list requests as well +type IfInfomsg struct { + unix.IfInfomsg +} + +// Create an IfInfomsg with family specified +func NewIfInfomsg(family int) *IfInfomsg { + return &IfInfomsg{ + IfInfomsg: unix.IfInfomsg{ + Family: uint8(family), + }, + } +} + +func DeserializeIfInfomsg(b []byte) *IfInfomsg { + return (*IfInfomsg)(unsafe.Pointer(&b[0:unix.SizeofIfInfomsg][0])) +} + +func (msg *IfInfomsg) Serialize() []byte { + return (*(*[unix.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:] +} + +func (msg *IfInfomsg) Len() int { + return unix.SizeofIfInfomsg +} + +func (msg *IfInfomsg) EncapType() string { + switch msg.Type { + case 0: + return "generic" + case unix.ARPHRD_ETHER: + return "ether" + case unix.ARPHRD_EETHER: + return "eether" + case unix.ARPHRD_AX25: + return "ax25" + case unix.ARPHRD_PRONET: + return "pronet" + case unix.ARPHRD_CHAOS: + return "chaos" + case unix.ARPHRD_IEEE802: + return "ieee802" + case unix.ARPHRD_ARCNET: + return "arcnet" + case unix.ARPHRD_APPLETLK: + return "atalk" + case unix.ARPHRD_DLCI: + return "dlci" + case unix.ARPHRD_ATM: + return "atm" + case unix.ARPHRD_METRICOM: + return "metricom" + case unix.ARPHRD_IEEE1394: + return "ieee1394" + case unix.ARPHRD_INFINIBAND: + return "infiniband" + case unix.ARPHRD_SLIP: + return "slip" + case unix.ARPHRD_CSLIP: + return "cslip" + case unix.ARPHRD_SLIP6: + return "slip6" + case unix.ARPHRD_CSLIP6: + return "cslip6" + case unix.ARPHRD_RSRVD: + return "rsrvd" + case unix.ARPHRD_ADAPT: + return "adapt" + case unix.ARPHRD_ROSE: + return "rose" + case unix.ARPHRD_X25: + return "x25" + case unix.ARPHRD_HWX25: + return "hwx25" + case unix.ARPHRD_PPP: + return "ppp" + case unix.ARPHRD_HDLC: + return "hdlc" + case unix.ARPHRD_LAPB: + return "lapb" + case unix.ARPHRD_DDCMP: + return "ddcmp" + case unix.ARPHRD_RAWHDLC: + return "rawhdlc" + case unix.ARPHRD_TUNNEL: + return "ipip" + case unix.ARPHRD_TUNNEL6: + return "tunnel6" + case unix.ARPHRD_FRAD: + return "frad" + case unix.ARPHRD_SKIP: + return "skip" + case unix.ARPHRD_LOOPBACK: + return "loopback" + case unix.ARPHRD_LOCALTLK: + return "ltalk" + case unix.ARPHRD_FDDI: + return "fddi" + case unix.ARPHRD_BIF: + return "bif" + case unix.ARPHRD_SIT: + return "sit" + case unix.ARPHRD_IPDDP: + return "ip/ddp" + case unix.ARPHRD_IPGRE: + return "gre" + case unix.ARPHRD_PIMREG: + return "pimreg" + case unix.ARPHRD_HIPPI: + return "hippi" + case unix.ARPHRD_ASH: + return "ash" + case unix.ARPHRD_ECONET: + return "econet" + case unix.ARPHRD_IRDA: + return "irda" + case unix.ARPHRD_FCPP: + return "fcpp" + case unix.ARPHRD_FCAL: + return "fcal" + case unix.ARPHRD_FCPL: + return "fcpl" + case unix.ARPHRD_FCFABRIC: + return "fcfb0" + case unix.ARPHRD_FCFABRIC + 1: + return "fcfb1" + case unix.ARPHRD_FCFABRIC + 2: + return "fcfb2" + case unix.ARPHRD_FCFABRIC + 3: + return "fcfb3" + case unix.ARPHRD_FCFABRIC + 4: + return "fcfb4" + case unix.ARPHRD_FCFABRIC + 5: + return "fcfb5" + case unix.ARPHRD_FCFABRIC + 6: + return "fcfb6" + case unix.ARPHRD_FCFABRIC + 7: + return "fcfb7" + case unix.ARPHRD_FCFABRIC + 8: + return "fcfb8" + case unix.ARPHRD_FCFABRIC + 9: + return "fcfb9" + case unix.ARPHRD_FCFABRIC + 10: + return "fcfb10" + case unix.ARPHRD_FCFABRIC + 11: + return "fcfb11" + case unix.ARPHRD_FCFABRIC + 12: + return "fcfb12" + case unix.ARPHRD_IEEE802_TR: + return "tr" + case unix.ARPHRD_IEEE80211: + return "ieee802.11" + case unix.ARPHRD_IEEE80211_PRISM: + return "ieee802.11/prism" + case unix.ARPHRD_IEEE80211_RADIOTAP: + return "ieee802.11/radiotap" + case unix.ARPHRD_IEEE802154: + return "ieee802.15.4" + + case 65534: + return "none" + case 65535: + return "void" + } + return fmt.Sprintf("unknown%d", msg.Type) +} + +func rtaAlignOf(attrlen int) int { + return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1) +} + +func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg { + msg := NewIfInfomsg(family) + parent.children = append(parent.children, msg) + return msg +} + +// Extend RtAttr to handle data and children +type RtAttr struct { + unix.RtAttr + Data []byte + children []NetlinkRequestData +} + +// Create a new Extended RtAttr object +func NewRtAttr(attrType int, data []byte) *RtAttr { + return &RtAttr{ + RtAttr: unix.RtAttr{ + Type: uint16(attrType), + }, + children: []NetlinkRequestData{}, + Data: data, + } +} + +// Create a new RtAttr obj anc add it as a child of an existing object +func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr { + attr := NewRtAttr(attrType, data) + parent.children = append(parent.children, attr) + return attr +} + +// AddChild adds an existing RtAttr as a child. +func (a *RtAttr) AddChild(attr *RtAttr) { + a.children = append(a.children, attr) +} + +func (a *RtAttr) Len() int { + if len(a.children) == 0 { + return (unix.SizeofRtAttr + len(a.Data)) + } + + l := 0 + for _, child := range a.children { + l += rtaAlignOf(child.Len()) + } + l += unix.SizeofRtAttr + return rtaAlignOf(l + len(a.Data)) +} + +// Serialize the RtAttr into a byte array +// This can't just unsafe.cast because it must iterate through children. +func (a *RtAttr) Serialize() []byte { + native := NativeEndian() + + length := a.Len() + buf := make([]byte, rtaAlignOf(length)) + + next := 4 + if a.Data != nil { + copy(buf[next:], a.Data) + next += rtaAlignOf(len(a.Data)) + } + if len(a.children) > 0 { + for _, child := range a.children { + childBuf := child.Serialize() + copy(buf[next:], childBuf) + next += rtaAlignOf(len(childBuf)) + } + } + + if l := uint16(length); l != 0 { + native.PutUint16(buf[0:2], l) + } + native.PutUint16(buf[2:4], a.Type) + return buf +} + +type NetlinkRequest struct { + unix.NlMsghdr + Data []NetlinkRequestData + RawData []byte + Sockets map[int]*SocketHandle +} + +// Serialize the Netlink Request into a byte array +func (req *NetlinkRequest) Serialize() []byte { + length := unix.SizeofNlMsghdr + dataBytes := make([][]byte, len(req.Data)) + for i, data := range req.Data { + dataBytes[i] = data.Serialize() + length = length + len(dataBytes[i]) + } + length += len(req.RawData) + + req.Len = uint32(length) + b := make([]byte, length) + hdr := (*(*[unix.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:] + next := unix.SizeofNlMsghdr + copy(b[0:next], hdr) + for _, data := range dataBytes { + for _, dataByte := range data { + b[next] = dataByte + next = next + 1 + } + } + // Add the raw data if any + if len(req.RawData) > 0 { + copy(b[next:length], req.RawData) + } + return b +} + +func (req *NetlinkRequest) AddData(data NetlinkRequestData) { + if data != nil { + req.Data = append(req.Data, data) + } +} + +// AddRawData adds raw bytes to the end of the NetlinkRequest object during serialization +func (req *NetlinkRequest) AddRawData(data []byte) { + if data != nil { + req.RawData = append(req.RawData, data...) + } +} + +// Execute the request against a the given sockType. +// Returns a list of netlink messages in serialized format, optionally filtered +// by resType. +func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) { + var ( + s *NetlinkSocket + err error + ) + + if req.Sockets != nil { + if sh, ok := req.Sockets[sockType]; ok { + s = sh.Socket + req.Seq = atomic.AddUint32(&sh.Seq, 1) + } + } + sharedSocket := s != nil + + if s == nil { + s, err = getNetlinkSocket(sockType) + if err != nil { + return nil, err + } + defer s.Close() + } else { + s.Lock() + defer s.Unlock() + } + + if err := s.Send(req); err != nil { + return nil, err + } + + pid, err := s.GetPid() + if err != nil { + return nil, err + } + + var res [][]byte + +done: + for { + msgs, err := s.Receive() + if err != nil { + return nil, err + } + for _, m := range msgs { + if m.Header.Seq != req.Seq { + if sharedSocket { + continue + } + return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq) + } + if m.Header.Pid != pid { + return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid) + } + if m.Header.Type == unix.NLMSG_DONE { + break done + } + if m.Header.Type == unix.NLMSG_ERROR { + native := NativeEndian() + error := int32(native.Uint32(m.Data[0:4])) + if error == 0 { + break done + } + return nil, syscall.Errno(-error) + } + if resType != 0 && m.Header.Type != resType { + continue + } + res = append(res, m.Data) + if m.Header.Flags&unix.NLM_F_MULTI == 0 { + break done + } + } + } + return res, nil +} + +// Create a new netlink request from proto and flags +// Note the Len value will be inaccurate once data is added until +// the message is serialized +func NewNetlinkRequest(proto, flags int) *NetlinkRequest { + return &NetlinkRequest{ + NlMsghdr: unix.NlMsghdr{ + Len: uint32(unix.SizeofNlMsghdr), + Type: uint16(proto), + Flags: unix.NLM_F_REQUEST | uint16(flags), + Seq: atomic.AddUint32(&nextSeqNr, 1), + }, + } +} + +type NetlinkSocket struct { + fd int32 + lsa unix.SockaddrNetlink + sync.Mutex +} + +func getNetlinkSocket(protocol int) (*NetlinkSocket, error) { + fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, protocol) + if err != nil { + return nil, err + } + s := &NetlinkSocket{ + fd: int32(fd), + } + s.lsa.Family = unix.AF_NETLINK + if err := unix.Bind(fd, &s.lsa); err != nil { + unix.Close(fd) + return nil, err + } + + return s, nil +} + +// GetNetlinkSocketAt opens a netlink socket in the network namespace newNs +// and positions the thread back into the network namespace specified by curNs, +// when done. If curNs is close, the function derives the current namespace and +// moves back into it when done. If newNs is close, the socket will be opened +// in the current network namespace. +func GetNetlinkSocketAt(newNs, curNs netns.NsHandle, protocol int) (*NetlinkSocket, error) { + c, err := executeInNetns(newNs, curNs) + if err != nil { + return nil, err + } + defer c() + return getNetlinkSocket(protocol) +} + +// executeInNetns sets execution of the code following this call to the +// network namespace newNs, then moves the thread back to curNs if open, +// otherwise to the current netns at the time the function was invoked +// In case of success, the caller is expected to execute the returned function +// at the end of the code that needs to be executed in the network namespace. +// Example: +// func jobAt(...) error { +// d, err := executeInNetns(...) +// if err != nil { return err} +// defer d() +// < code which needs to be executed in specific netns> +// } +// TODO: his function probably belongs to netns pkg. +func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) { + var ( + err error + moveBack func(netns.NsHandle) error + closeNs func() error + unlockThd func() + ) + restore := func() { + // order matters + if moveBack != nil { + moveBack(curNs) + } + if closeNs != nil { + closeNs() + } + if unlockThd != nil { + unlockThd() + } + } + if newNs.IsOpen() { + runtime.LockOSThread() + unlockThd = runtime.UnlockOSThread + if !curNs.IsOpen() { + if curNs, err = netns.Get(); err != nil { + restore() + return nil, fmt.Errorf("could not get current namespace while creating netlink socket: %v", err) + } + closeNs = curNs.Close + } + if err := netns.Set(newNs); err != nil { + restore() + return nil, fmt.Errorf("failed to set into network namespace %d while creating netlink socket: %v", newNs, err) + } + moveBack = netns.Set + } + return restore, nil +} + +// Create a netlink socket with a given protocol (e.g. NETLINK_ROUTE) +// and subscribe it to multicast groups passed in variable argument list. +// Returns the netlink socket on which Receive() method can be called +// to retrieve the messages from the kernel. +func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) { + fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, protocol) + if err != nil { + return nil, err + } + s := &NetlinkSocket{ + fd: int32(fd), + } + s.lsa.Family = unix.AF_NETLINK + + for _, g := range groups { + s.lsa.Groups |= (1 << (g - 1)) + } + + if err := unix.Bind(fd, &s.lsa); err != nil { + unix.Close(fd) + return nil, err + } + + return s, nil +} + +// SubscribeAt works like Subscribe plus let's the caller choose the network +// namespace in which the socket would be opened (newNs). Then control goes back +// to curNs if open, otherwise to the netns at the time this function was called. +func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*NetlinkSocket, error) { + c, err := executeInNetns(newNs, curNs) + if err != nil { + return nil, err + } + defer c() + return Subscribe(protocol, groups...) +} + +func (s *NetlinkSocket) Close() { + fd := int(atomic.SwapInt32(&s.fd, -1)) + unix.Close(fd) +} + +func (s *NetlinkSocket) GetFd() int { + return int(atomic.LoadInt32(&s.fd)) +} + +func (s *NetlinkSocket) Send(request *NetlinkRequest) error { + fd := int(atomic.LoadInt32(&s.fd)) + if fd < 0 { + return fmt.Errorf("Send called on a closed socket") + } + if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil { + return err + } + return nil +} + +func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { + fd := int(atomic.LoadInt32(&s.fd)) + if fd < 0 { + return nil, fmt.Errorf("Receive called on a closed socket") + } + rb := make([]byte, unix.Getpagesize()) + nr, _, err := unix.Recvfrom(fd, rb, 0) + if err != nil { + return nil, err + } + if nr < unix.NLMSG_HDRLEN { + return nil, fmt.Errorf("Got short response from netlink") + } + rb = rb[:nr] + return syscall.ParseNetlinkMessage(rb) +} + +// SetSendTimeout allows to set a send timeout on the socket +func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error { + // Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine + // remains stuck on a send on a closed fd + return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout) +} + +// SetReceiveTimeout allows to set a receive timeout on the socket +func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error { + // Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine + // remains stuck on a recvmsg on a closed fd + return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout) +} + +func (s *NetlinkSocket) GetPid() (uint32, error) { + fd := int(atomic.LoadInt32(&s.fd)) + lsa, err := unix.Getsockname(fd) + if err != nil { + return 0, err + } + switch v := lsa.(type) { + case *unix.SockaddrNetlink: + return v.Pid, nil + } + return 0, fmt.Errorf("Wrong socket type") +} + +func ZeroTerminated(s string) []byte { + bytes := make([]byte, len(s)+1) + for i := 0; i < len(s); i++ { + bytes[i] = s[i] + } + bytes[len(s)] = 0 + return bytes +} + +func NonZeroTerminated(s string) []byte { + bytes := make([]byte, len(s)) + for i := 0; i < len(s); i++ { + bytes[i] = s[i] + } + return bytes +} + +func BytesToString(b []byte) string { + n := bytes.Index(b, []byte{0}) + return string(b[:n]) +} + +func Uint8Attr(v uint8) []byte { + return []byte{byte(v)} +} + +func Uint16Attr(v uint16) []byte { + native := NativeEndian() + bytes := make([]byte, 2) + native.PutUint16(bytes, v) + return bytes +} + +func Uint32Attr(v uint32) []byte { + native := NativeEndian() + bytes := make([]byte, 4) + native.PutUint32(bytes, v) + return bytes +} + +func Uint64Attr(v uint64) []byte { + native := NativeEndian() + bytes := make([]byte, 8) + native.PutUint64(bytes, v) + return bytes +} + +func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) { + var attrs []syscall.NetlinkRouteAttr + for len(b) >= unix.SizeofRtAttr { + a, vbuf, alen, err := netlinkRouteAttrAndValue(b) + if err != nil { + return nil, err + } + ra := syscall.NetlinkRouteAttr{Attr: syscall.RtAttr(*a), Value: vbuf[:int(a.Len)-unix.SizeofRtAttr]} + attrs = append(attrs, ra) + b = b[alen:] + } + return attrs, nil +} + +func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) { + a := (*unix.RtAttr)(unsafe.Pointer(&b[0])) + if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) { + return nil, nil, 0, unix.EINVAL + } + return a, b[unix.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil +} + +// SocketHandle contains the netlink socket and the associated +// sequence counter for a specific netlink family +type SocketHandle struct { + Seq uint32 + Socket *NetlinkSocket +} + +// Close closes the netlink socket +func (sh *SocketHandle) Close() { + if sh.Socket != nil { + sh.Socket.Close() + } +} diff --git a/vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go b/vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..dfc0be6606c240a9bef764648a0849f35d96d2d5 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go @@ -0,0 +1,11 @@ +// +build !linux + +package nl + +import "encoding/binary" + +var SupportedNlFamilies = []int{} + +func NativeEndian() binary.ByteOrder { + return nil +} diff --git a/vendor/github.com/vishvananda/netlink/nl/route_linux.go b/vendor/github.com/vishvananda/netlink/nl/route_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..f6906fcaf7e095c8f253a93a08448f8fd91f1ecd --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/route_linux.go @@ -0,0 +1,81 @@ +package nl + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +type RtMsg struct { + unix.RtMsg +} + +func NewRtMsg() *RtMsg { + return &RtMsg{ + RtMsg: unix.RtMsg{ + Table: unix.RT_TABLE_MAIN, + Scope: unix.RT_SCOPE_UNIVERSE, + Protocol: unix.RTPROT_BOOT, + Type: unix.RTN_UNICAST, + }, + } +} + +func NewRtDelMsg() *RtMsg { + return &RtMsg{ + RtMsg: unix.RtMsg{ + Table: unix.RT_TABLE_MAIN, + Scope: unix.RT_SCOPE_NOWHERE, + }, + } +} + +func (msg *RtMsg) Len() int { + return unix.SizeofRtMsg +} + +func DeserializeRtMsg(b []byte) *RtMsg { + return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0])) +} + +func (msg *RtMsg) Serialize() []byte { + return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] +} + +type RtNexthop struct { + unix.RtNexthop + Children []NetlinkRequestData +} + +func DeserializeRtNexthop(b []byte) *RtNexthop { + return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0])) +} + +func (msg *RtNexthop) Len() int { + if len(msg.Children) == 0 { + return unix.SizeofRtNexthop + } + + l := 0 + for _, child := range msg.Children { + l += rtaAlignOf(child.Len()) + } + l += unix.SizeofRtNexthop + return rtaAlignOf(l) +} + +func (msg *RtNexthop) Serialize() []byte { + length := msg.Len() + msg.RtNexthop.Len = uint16(length) + buf := make([]byte, length) + copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]) + next := rtaAlignOf(unix.SizeofRtNexthop) + if len(msg.Children) > 0 { + for _, child := range msg.Children { + childBuf := child.Serialize() + copy(buf[next:], childBuf) + next += rtaAlignOf(len(childBuf)) + } + } + return buf +} diff --git a/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go b/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..b3425f6b0eccb12fd62cb0fb0757a8b7fcb03096 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go @@ -0,0 +1,111 @@ +package nl + +import ( + "errors" + "fmt" + "net" +) + +type IPv6SrHdr struct { + nextHdr uint8 + hdrLen uint8 + routingType uint8 + segmentsLeft uint8 + firstSegment uint8 + flags uint8 + reserved uint16 + + Segments []net.IP +} + +func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool { + if len(s1.Segments) != len(s2.Segments) { + return false + } + for i := range s1.Segments { + if s1.Segments[i].Equal(s2.Segments[i]) != true { + return false + } + } + return s1.nextHdr == s2.nextHdr && + s1.hdrLen == s2.hdrLen && + s1.routingType == s2.routingType && + s1.segmentsLeft == s2.segmentsLeft && + s1.firstSegment == s2.firstSegment && + s1.flags == s2.flags + // reserved doesn't need to be identical. +} + +// seg6 encap mode +const ( + SEG6_IPTUN_MODE_INLINE = iota + SEG6_IPTUN_MODE_ENCAP +) + +// number of nested RTATTR +// from include/uapi/linux/seg6_iptunnel.h +const ( + SEG6_IPTUNNEL_UNSPEC = iota + SEG6_IPTUNNEL_SRH + __SEG6_IPTUNNEL_MAX +) +const ( + SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1 +) + +func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) { + nsegs := len(segments) // nsegs: number of segments + if nsegs == 0 { + return nil, errors.New("EncodeSEG6Encap: No Segment in srh") + } + b := make([]byte, 12, 12+len(segments)*16) + native := NativeEndian() + native.PutUint32(b, uint32(mode)) + b[4] = 0 // srh.nextHdr (0 when calling netlink) + b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit) + b[6] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA) + b[7] = uint8(nsegs - 1) // srh.segmentsLeft + b[8] = uint8(nsegs - 1) // srh.firstSegment + b[9] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac) + // srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07 + native.PutUint16(b[10:], 0) // srh.reserved + for _, netIP := range segments { + b = append(b, netIP...) // srh.Segments + } + return b, nil +} + +func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) { + native := NativeEndian() + mode := int(native.Uint32(buf)) + srh := IPv6SrHdr{ + nextHdr: buf[4], + hdrLen: buf[5], + routingType: buf[6], + segmentsLeft: buf[7], + firstSegment: buf[8], + flags: buf[9], + reserved: native.Uint16(buf[10:12]), + } + buf = buf[12:] + if len(buf)%16 != 0 { + err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf)) + return mode, nil, err + } + for len(buf) > 0 { + srh.Segments = append(srh.Segments, net.IP(buf[:16])) + buf = buf[16:] + } + return mode, srh.Segments, nil +} + +// Helper functions +func SEG6EncapModeString(mode int) string { + switch mode { + case SEG6_IPTUN_MODE_INLINE: + return "inline" + case SEG6_IPTUN_MODE_ENCAP: + return "encap" + } + return "unknown" +} diff --git a/vendor/github.com/vishvananda/netlink/nl/syscall.go b/vendor/github.com/vishvananda/netlink/nl/syscall.go new file mode 100644 index 0000000000000000000000000000000000000000..fc631e0e505f2cb5cb95da5730de5ebd6bd2cb79 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/syscall.go @@ -0,0 +1,78 @@ +package nl + +// syscall package lack of rule atributes type. +// Thus there are defined below +const ( + FRA_UNSPEC = iota + FRA_DST /* destination address */ + FRA_SRC /* source address */ + FRA_IIFNAME /* interface name */ + FRA_GOTO /* target to jump to (FR_ACT_GOTO) */ + FRA_UNUSED2 + FRA_PRIORITY /* priority/preference */ + FRA_UNUSED3 + FRA_UNUSED4 + FRA_UNUSED5 + FRA_FWMARK /* mark */ + FRA_FLOW /* flow/class id */ + FRA_TUN_ID + FRA_SUPPRESS_IFGROUP + FRA_SUPPRESS_PREFIXLEN + FRA_TABLE /* Extended table id */ + FRA_FWMASK /* mask for netfilter mark */ + FRA_OIFNAME +) + +// ip rule netlink request types +const ( + FR_ACT_UNSPEC = iota + FR_ACT_TO_TBL /* Pass to fixed table */ + FR_ACT_GOTO /* Jump to another rule */ + FR_ACT_NOP /* No operation */ + FR_ACT_RES3 + FR_ACT_RES4 + FR_ACT_BLACKHOLE /* Drop without notification */ + FR_ACT_UNREACHABLE /* Drop with ENETUNREACH */ + FR_ACT_PROHIBIT /* Drop with EACCES */ +) + +// socket diags related +const ( + SOCK_DIAG_BY_FAMILY = 20 /* linux.sock_diag.h */ + TCPDIAG_NOCOOKIE = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/ +) + +const ( + AF_MPLS = 28 +) + +const ( + RTA_NEWDST = 0x13 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 +) + +// RTA_ENCAP subtype +const ( + MPLS_IPTUNNEL_UNSPEC = iota + MPLS_IPTUNNEL_DST +) + +// light weight tunnel encap types +const ( + LWTUNNEL_ENCAP_NONE = iota + LWTUNNEL_ENCAP_MPLS + LWTUNNEL_ENCAP_IP + LWTUNNEL_ENCAP_ILA + LWTUNNEL_ENCAP_IP6 + LWTUNNEL_ENCAP_SEG6 + LWTUNNEL_ENCAP_BPF +) + +// routing header types +const ( + IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed + IPV6_SRCRT_TYPE_0 = 0 // Deprecated; will be removed + IPV6_SRCRT_TYPE_2 = 2 // IPv6 type 2 Routing Header + IPV6_SRCRT_TYPE_4 = 4 // Segment Routing with IPv6 +) diff --git a/vendor/github.com/vishvananda/netlink/nl/tc_linux.go b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..94ebc290a9e31c4426ab08e82543481147b30bc6 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go @@ -0,0 +1,710 @@ +package nl + +import ( + "unsafe" +) + +// LinkLayer +const ( + LINKLAYER_UNSPEC = iota + LINKLAYER_ETHERNET + LINKLAYER_ATM +) + +// ATM +const ( + ATM_CELL_PAYLOAD = 48 + ATM_CELL_SIZE = 53 +) + +const TC_LINKLAYER_MASK = 0x0F + +// Police +const ( + TCA_POLICE_UNSPEC = iota + TCA_POLICE_TBF + TCA_POLICE_RATE + TCA_POLICE_PEAKRATE + TCA_POLICE_AVRATE + TCA_POLICE_RESULT + TCA_POLICE_MAX = TCA_POLICE_RESULT +) + +// Message types +const ( + TCA_UNSPEC = iota + TCA_KIND + TCA_OPTIONS + TCA_STATS + TCA_XSTATS + TCA_RATE + TCA_FCNT + TCA_STATS2 + TCA_STAB + TCA_MAX = TCA_STAB +) + +const ( + TCA_ACT_TAB = 1 + TCAA_MAX = 1 +) + +const ( + TCA_ACT_UNSPEC = iota + TCA_ACT_KIND + TCA_ACT_OPTIONS + TCA_ACT_INDEX + TCA_ACT_STATS + TCA_ACT_MAX +) + +const ( + TCA_PRIO_UNSPEC = iota + TCA_PRIO_MQ + TCA_PRIO_MAX = TCA_PRIO_MQ +) + +const ( + SizeofTcMsg = 0x14 + SizeofTcActionMsg = 0x04 + SizeofTcPrioMap = 0x14 + SizeofTcRateSpec = 0x0c + SizeofTcNetemQopt = 0x18 + SizeofTcNetemCorr = 0x0c + SizeofTcNetemReorder = 0x08 + SizeofTcNetemCorrupt = 0x08 + SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c + SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14 + SizeofTcHtbGlob = 0x14 + SizeofTcU32Key = 0x10 + SizeofTcU32Sel = 0x10 // without keys + SizeofTcGen = 0x14 + SizeofTcMirred = SizeofTcGen + 0x08 + SizeofTcPolice = 2*SizeofTcRateSpec + 0x20 +) + +// struct tcmsg { +// unsigned char tcm_family; +// unsigned char tcm__pad1; +// unsigned short tcm__pad2; +// int tcm_ifindex; +// __u32 tcm_handle; +// __u32 tcm_parent; +// __u32 tcm_info; +// }; + +type TcMsg struct { + Family uint8 + Pad [3]byte + Ifindex int32 + Handle uint32 + Parent uint32 + Info uint32 +} + +func (msg *TcMsg) Len() int { + return SizeofTcMsg +} + +func DeserializeTcMsg(b []byte) *TcMsg { + return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0])) +} + +func (x *TcMsg) Serialize() []byte { + return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:] +} + +// struct tcamsg { +// unsigned char tca_family; +// unsigned char tca__pad1; +// unsigned short tca__pad2; +// }; + +type TcActionMsg struct { + Family uint8 + Pad [3]byte +} + +func (msg *TcActionMsg) Len() int { + return SizeofTcActionMsg +} + +func DeserializeTcActionMsg(b []byte) *TcActionMsg { + return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0])) +} + +func (x *TcActionMsg) Serialize() []byte { + return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:] +} + +const ( + TC_PRIO_MAX = 15 +) + +// struct tc_prio_qopt { +// int bands; /* Number of bands */ +// __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ +// }; + +type TcPrioMap struct { + Bands int32 + Priomap [TC_PRIO_MAX + 1]uint8 +} + +func (msg *TcPrioMap) Len() int { + return SizeofTcPrioMap +} + +func DeserializeTcPrioMap(b []byte) *TcPrioMap { + return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0])) +} + +func (x *TcPrioMap) Serialize() []byte { + return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:] +} + +const ( + TCA_TBF_UNSPEC = iota + TCA_TBF_PARMS + TCA_TBF_RTAB + TCA_TBF_PTAB + TCA_TBF_RATE64 + TCA_TBF_PRATE64 + TCA_TBF_BURST + TCA_TBF_PBURST + TCA_TBF_MAX = TCA_TBF_PBURST +) + +// struct tc_ratespec { +// unsigned char cell_log; +// __u8 linklayer; /* lower 4 bits */ +// unsigned short overhead; +// short cell_align; +// unsigned short mpu; +// __u32 rate; +// }; + +type TcRateSpec struct { + CellLog uint8 + Linklayer uint8 + Overhead uint16 + CellAlign int16 + Mpu uint16 + Rate uint32 +} + +func (msg *TcRateSpec) Len() int { + return SizeofTcRateSpec +} + +func DeserializeTcRateSpec(b []byte) *TcRateSpec { + return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0])) +} + +func (x *TcRateSpec) Serialize() []byte { + return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:] +} + +/** +* NETEM + */ + +const ( + TCA_NETEM_UNSPEC = iota + TCA_NETEM_CORR + TCA_NETEM_DELAY_DIST + TCA_NETEM_REORDER + TCA_NETEM_CORRUPT + TCA_NETEM_LOSS + TCA_NETEM_RATE + TCA_NETEM_ECN + TCA_NETEM_RATE64 + TCA_NETEM_MAX = TCA_NETEM_RATE64 +) + +// struct tc_netem_qopt { +// __u32 latency; /* added delay (us) */ +// __u32 limit; /* fifo limit (packets) */ +// __u32 loss; /* random packet loss (0=none ~0=100%) */ +// __u32 gap; /* re-ordering gap (0 for none) */ +// __u32 duplicate; /* random packet dup (0=none ~0=100%) */ +// __u32 jitter; /* random jitter in latency (us) */ +// }; + +type TcNetemQopt struct { + Latency uint32 + Limit uint32 + Loss uint32 + Gap uint32 + Duplicate uint32 + Jitter uint32 +} + +func (msg *TcNetemQopt) Len() int { + return SizeofTcNetemQopt +} + +func DeserializeTcNetemQopt(b []byte) *TcNetemQopt { + return (*TcNetemQopt)(unsafe.Pointer(&b[0:SizeofTcNetemQopt][0])) +} + +func (x *TcNetemQopt) Serialize() []byte { + return (*(*[SizeofTcNetemQopt]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_netem_corr { +// __u32 delay_corr; /* delay correlation */ +// __u32 loss_corr; /* packet loss correlation */ +// __u32 dup_corr; /* duplicate correlation */ +// }; + +type TcNetemCorr struct { + DelayCorr uint32 + LossCorr uint32 + DupCorr uint32 +} + +func (msg *TcNetemCorr) Len() int { + return SizeofTcNetemCorr +} + +func DeserializeTcNetemCorr(b []byte) *TcNetemCorr { + return (*TcNetemCorr)(unsafe.Pointer(&b[0:SizeofTcNetemCorr][0])) +} + +func (x *TcNetemCorr) Serialize() []byte { + return (*(*[SizeofTcNetemCorr]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_netem_reorder { +// __u32 probability; +// __u32 correlation; +// }; + +type TcNetemReorder struct { + Probability uint32 + Correlation uint32 +} + +func (msg *TcNetemReorder) Len() int { + return SizeofTcNetemReorder +} + +func DeserializeTcNetemReorder(b []byte) *TcNetemReorder { + return (*TcNetemReorder)(unsafe.Pointer(&b[0:SizeofTcNetemReorder][0])) +} + +func (x *TcNetemReorder) Serialize() []byte { + return (*(*[SizeofTcNetemReorder]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_netem_corrupt { +// __u32 probability; +// __u32 correlation; +// }; + +type TcNetemCorrupt struct { + Probability uint32 + Correlation uint32 +} + +func (msg *TcNetemCorrupt) Len() int { + return SizeofTcNetemCorrupt +} + +func DeserializeTcNetemCorrupt(b []byte) *TcNetemCorrupt { + return (*TcNetemCorrupt)(unsafe.Pointer(&b[0:SizeofTcNetemCorrupt][0])) +} + +func (x *TcNetemCorrupt) Serialize() []byte { + return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_tbf_qopt { +// struct tc_ratespec rate; +// struct tc_ratespec peakrate; +// __u32 limit; +// __u32 buffer; +// __u32 mtu; +// }; + +type TcTbfQopt struct { + Rate TcRateSpec + Peakrate TcRateSpec + Limit uint32 + Buffer uint32 + Mtu uint32 +} + +func (msg *TcTbfQopt) Len() int { + return SizeofTcTbfQopt +} + +func DeserializeTcTbfQopt(b []byte) *TcTbfQopt { + return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0])) +} + +func (x *TcTbfQopt) Serialize() []byte { + return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:] +} + +const ( + TCA_HTB_UNSPEC = iota + TCA_HTB_PARMS + TCA_HTB_INIT + TCA_HTB_CTAB + TCA_HTB_RTAB + TCA_HTB_DIRECT_QLEN + TCA_HTB_RATE64 + TCA_HTB_CEIL64 + TCA_HTB_MAX = TCA_HTB_CEIL64 +) + +//struct tc_htb_opt { +// struct tc_ratespec rate; +// struct tc_ratespec ceil; +// __u32 buffer; +// __u32 cbuffer; +// __u32 quantum; +// __u32 level; /* out only */ +// __u32 prio; +//}; + +type TcHtbCopt struct { + Rate TcRateSpec + Ceil TcRateSpec + Buffer uint32 + Cbuffer uint32 + Quantum uint32 + Level uint32 + Prio uint32 +} + +func (msg *TcHtbCopt) Len() int { + return SizeofTcHtbCopt +} + +func DeserializeTcHtbCopt(b []byte) *TcHtbCopt { + return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0])) +} + +func (x *TcHtbCopt) Serialize() []byte { + return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:] +} + +type TcHtbGlob struct { + Version uint32 + Rate2Quantum uint32 + Defcls uint32 + Debug uint32 + DirectPkts uint32 +} + +func (msg *TcHtbGlob) Len() int { + return SizeofTcHtbGlob +} + +func DeserializeTcHtbGlob(b []byte) *TcHtbGlob { + return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0])) +} + +func (x *TcHtbGlob) Serialize() []byte { + return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:] +} + +const ( + TCA_U32_UNSPEC = iota + TCA_U32_CLASSID + TCA_U32_HASH + TCA_U32_LINK + TCA_U32_DIVISOR + TCA_U32_SEL + TCA_U32_POLICE + TCA_U32_ACT + TCA_U32_INDEV + TCA_U32_PCNT + TCA_U32_MARK + TCA_U32_MAX = TCA_U32_MARK +) + +// struct tc_u32_key { +// __be32 mask; +// __be32 val; +// int off; +// int offmask; +// }; + +type TcU32Key struct { + Mask uint32 // big endian + Val uint32 // big endian + Off int32 + OffMask int32 +} + +func (msg *TcU32Key) Len() int { + return SizeofTcU32Key +} + +func DeserializeTcU32Key(b []byte) *TcU32Key { + return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0])) +} + +func (x *TcU32Key) Serialize() []byte { + return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_u32_sel { +// unsigned char flags; +// unsigned char offshift; +// unsigned char nkeys; +// +// __be16 offmask; +// __u16 off; +// short offoff; +// +// short hoff; +// __be32 hmask; +// struct tc_u32_key keys[0]; +// }; + +const ( + TC_U32_TERMINAL = 1 << iota + TC_U32_OFFSET = 1 << iota + TC_U32_VAROFFSET = 1 << iota + TC_U32_EAT = 1 << iota +) + +type TcU32Sel struct { + Flags uint8 + Offshift uint8 + Nkeys uint8 + Pad uint8 + Offmask uint16 // big endian + Off uint16 + Offoff int16 + Hoff int16 + Hmask uint32 // big endian + Keys []TcU32Key +} + +func (msg *TcU32Sel) Len() int { + return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key +} + +func DeserializeTcU32Sel(b []byte) *TcU32Sel { + x := &TcU32Sel{} + copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b) + next := SizeofTcU32Sel + var i uint8 + for i = 0; i < x.Nkeys; i++ { + x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:])) + next += SizeofTcU32Key + } + return x +} + +func (x *TcU32Sel) Serialize() []byte { + // This can't just unsafe.cast because it must iterate through keys. + buf := make([]byte, x.Len()) + copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:]) + next := SizeofTcU32Sel + for _, key := range x.Keys { + keyBuf := key.Serialize() + copy(buf[next:], keyBuf) + next += SizeofTcU32Key + } + return buf +} + +type TcGen struct { + Index uint32 + Capab uint32 + Action int32 + Refcnt int32 + Bindcnt int32 +} + +func (msg *TcGen) Len() int { + return SizeofTcGen +} + +func DeserializeTcGen(b []byte) *TcGen { + return (*TcGen)(unsafe.Pointer(&b[0:SizeofTcGen][0])) +} + +func (x *TcGen) Serialize() []byte { + return (*(*[SizeofTcGen]byte)(unsafe.Pointer(x)))[:] +} + +// #define tc_gen \ +// __u32 index; \ +// __u32 capab; \ +// int action; \ +// int refcnt; \ +// int bindcnt + +const ( + TCA_ACT_GACT = 5 +) + +const ( + TCA_GACT_UNSPEC = iota + TCA_GACT_TM + TCA_GACT_PARMS + TCA_GACT_PROB + TCA_GACT_MAX = TCA_GACT_PROB +) + +type TcGact TcGen + +const ( + TCA_ACT_BPF = 13 +) + +const ( + TCA_ACT_BPF_UNSPEC = iota + TCA_ACT_BPF_TM + TCA_ACT_BPF_PARMS + TCA_ACT_BPF_OPS_LEN + TCA_ACT_BPF_OPS + TCA_ACT_BPF_FD + TCA_ACT_BPF_NAME + TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME +) + +const ( + TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota +) + +const ( + TCA_BPF_UNSPEC = iota + TCA_BPF_ACT + TCA_BPF_POLICE + TCA_BPF_CLASSID + TCA_BPF_OPS_LEN + TCA_BPF_OPS + TCA_BPF_FD + TCA_BPF_NAME + TCA_BPF_FLAGS + TCA_BPF_MAX = TCA_BPF_FLAGS +) + +type TcBpf TcGen + +const ( + TCA_ACT_MIRRED = 8 +) + +const ( + TCA_MIRRED_UNSPEC = iota + TCA_MIRRED_TM + TCA_MIRRED_PARMS + TCA_MIRRED_MAX = TCA_MIRRED_PARMS +) + +// struct tc_mirred { +// tc_gen; +// int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ +// __u32 ifindex; /* ifindex of egress port */ +// }; + +type TcMirred struct { + TcGen + Eaction int32 + Ifindex uint32 +} + +func (msg *TcMirred) Len() int { + return SizeofTcMirred +} + +func DeserializeTcMirred(b []byte) *TcMirred { + return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0])) +} + +func (x *TcMirred) Serialize() []byte { + return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:] +} + +// struct tc_police { +// __u32 index; +// int action; +// __u32 limit; +// __u32 burst; +// __u32 mtu; +// struct tc_ratespec rate; +// struct tc_ratespec peakrate; +// int refcnt; +// int bindcnt; +// __u32 capab; +// }; + +type TcPolice struct { + Index uint32 + Action int32 + Limit uint32 + Burst uint32 + Mtu uint32 + Rate TcRateSpec + PeakRate TcRateSpec + Refcnt int32 + Bindcnt int32 + Capab uint32 +} + +func (msg *TcPolice) Len() int { + return SizeofTcPolice +} + +func DeserializeTcPolice(b []byte) *TcPolice { + return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0])) +} + +func (x *TcPolice) Serialize() []byte { + return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:] +} + +const ( + TCA_FW_UNSPEC = iota + TCA_FW_CLASSID + TCA_FW_POLICE + TCA_FW_INDEV + TCA_FW_ACT + TCA_FW_MASK + TCA_FW_MAX = TCA_FW_MASK +) + +const ( + TCA_MATCHALL_UNSPEC = iota + TCA_MATCHALL_CLASSID + TCA_MATCHALL_ACT + TCA_MATCHALL_FLAGS +) + +const ( + TCA_FQ_UNSPEC = iota + TCA_FQ_PLIMIT // limit of total number of packets in queue + TCA_FQ_FLOW_PLIMIT // limit of packets per flow + TCA_FQ_QUANTUM // RR quantum + TCA_FQ_INITIAL_QUANTUM // RR quantum for new flow + TCA_FQ_RATE_ENABLE // enable/disable rate limiting + TCA_FQ_FLOW_DEFAULT_RATE // obsolete do not use + TCA_FQ_FLOW_MAX_RATE // per flow max rate + TCA_FQ_BUCKETS_LOG // log2(number of buckets) + TCA_FQ_FLOW_REFILL_DELAY // flow credit refill delay in usec + TCA_FQ_ORPHAN_MASK // mask applied to orphaned skb hashes + TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate +) + +const ( + TCA_FQ_CODEL_UNSPEC = iota + TCA_FQ_CODEL_TARGET + TCA_FQ_CODEL_LIMIT + TCA_FQ_CODEL_INTERVAL + TCA_FQ_CODEL_ECN + TCA_FQ_CODEL_FLOWS + TCA_FQ_CODEL_QUANTUM + TCA_FQ_CODEL_CE_THRESHOLD + TCA_FQ_CODEL_DROP_BATCH_SIZE + TCA_FQ_CODEL_MEMORY_LIMIT +) diff --git a/vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go b/vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..09a2ffa10ef798ea70a66c8a64ac9f4ed0ed0f4f --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go @@ -0,0 +1,296 @@ +package nl + +import ( + "bytes" + "net" + "unsafe" +) + +// Infinity for packet and byte counts +const ( + XFRM_INF = ^uint64(0) +) + +type XfrmMsgType uint8 + +type XfrmMsg interface { + Type() XfrmMsgType +} + +// Message Types +const ( + XFRM_MSG_BASE XfrmMsgType = 0x10 + XFRM_MSG_NEWSA = 0x10 + XFRM_MSG_DELSA = 0x11 + XFRM_MSG_GETSA = 0x12 + XFRM_MSG_NEWPOLICY = 0x13 + XFRM_MSG_DELPOLICY = 0x14 + XFRM_MSG_GETPOLICY = 0x15 + XFRM_MSG_ALLOCSPI = 0x16 + XFRM_MSG_ACQUIRE = 0x17 + XFRM_MSG_EXPIRE = 0x18 + XFRM_MSG_UPDPOLICY = 0x19 + XFRM_MSG_UPDSA = 0x1a + XFRM_MSG_POLEXPIRE = 0x1b + XFRM_MSG_FLUSHSA = 0x1c + XFRM_MSG_FLUSHPOLICY = 0x1d + XFRM_MSG_NEWAE = 0x1e + XFRM_MSG_GETAE = 0x1f + XFRM_MSG_REPORT = 0x20 + XFRM_MSG_MIGRATE = 0x21 + XFRM_MSG_NEWSADINFO = 0x22 + XFRM_MSG_GETSADINFO = 0x23 + XFRM_MSG_NEWSPDINFO = 0x24 + XFRM_MSG_GETSPDINFO = 0x25 + XFRM_MSG_MAPPING = 0x26 + XFRM_MSG_MAX = 0x26 + XFRM_NR_MSGTYPES = 0x17 +) + +// Attribute types +const ( + /* Netlink message attributes. */ + XFRMA_UNSPEC = 0x00 + XFRMA_ALG_AUTH = 0x01 /* struct xfrm_algo */ + XFRMA_ALG_CRYPT = 0x02 /* struct xfrm_algo */ + XFRMA_ALG_COMP = 0x03 /* struct xfrm_algo */ + XFRMA_ENCAP = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */ + XFRMA_TMPL = 0x05 /* 1 or more struct xfrm_user_tmpl */ + XFRMA_SA = 0x06 /* struct xfrm_usersa_info */ + XFRMA_POLICY = 0x07 /* struct xfrm_userpolicy_info */ + XFRMA_SEC_CTX = 0x08 /* struct xfrm_sec_ctx */ + XFRMA_LTIME_VAL = 0x09 + XFRMA_REPLAY_VAL = 0x0a + XFRMA_REPLAY_THRESH = 0x0b + XFRMA_ETIMER_THRESH = 0x0c + XFRMA_SRCADDR = 0x0d /* xfrm_address_t */ + XFRMA_COADDR = 0x0e /* xfrm_address_t */ + XFRMA_LASTUSED = 0x0f /* unsigned long */ + XFRMA_POLICY_TYPE = 0x10 /* struct xfrm_userpolicy_type */ + XFRMA_MIGRATE = 0x11 + XFRMA_ALG_AEAD = 0x12 /* struct xfrm_algo_aead */ + XFRMA_KMADDRESS = 0x13 /* struct xfrm_user_kmaddress */ + XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */ + XFRMA_MARK = 0x15 /* struct xfrm_mark */ + XFRMA_TFCPAD = 0x16 /* __u32 */ + XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */ + XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */ + XFRMA_MAX = 0x18 +) + +const ( + SizeofXfrmAddress = 0x10 + SizeofXfrmSelector = 0x38 + SizeofXfrmLifetimeCfg = 0x40 + SizeofXfrmLifetimeCur = 0x20 + SizeofXfrmId = 0x18 + SizeofXfrmMark = 0x08 +) + +// Netlink groups +const ( + XFRMNLGRP_NONE = 0x0 + XFRMNLGRP_ACQUIRE = 0x1 + XFRMNLGRP_EXPIRE = 0x2 + XFRMNLGRP_SA = 0x3 + XFRMNLGRP_POLICY = 0x4 + XFRMNLGRP_AEVENTS = 0x5 + XFRMNLGRP_REPORT = 0x6 + XFRMNLGRP_MIGRATE = 0x7 + XFRMNLGRP_MAPPING = 0x8 + __XFRMNLGRP_MAX = 0x9 +) + +// typedef union { +// __be32 a4; +// __be32 a6[4]; +// } xfrm_address_t; + +type XfrmAddress [SizeofXfrmAddress]byte + +func (x *XfrmAddress) ToIP() net.IP { + var empty = [12]byte{} + ip := make(net.IP, net.IPv6len) + if bytes.Equal(x[4:16], empty[:]) { + ip[10] = 0xff + ip[11] = 0xff + copy(ip[12:16], x[0:4]) + } else { + copy(ip[:], x[:]) + } + return ip +} + +func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet { + ip := x.ToIP() + if GetIPFamily(ip) == FAMILY_V4 { + return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)} + } + return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 128)} +} + +func (x *XfrmAddress) FromIP(ip net.IP) { + var empty = [16]byte{} + if len(ip) < net.IPv4len { + copy(x[4:16], empty[:]) + } else if GetIPFamily(ip) == FAMILY_V4 { + copy(x[0:4], ip.To4()[0:4]) + copy(x[4:16], empty[:12]) + } else { + copy(x[0:16], ip.To16()[0:16]) + } +} + +func DeserializeXfrmAddress(b []byte) *XfrmAddress { + return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0])) +} + +func (x *XfrmAddress) Serialize() []byte { + return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(x)))[:] +} + +// struct xfrm_selector { +// xfrm_address_t daddr; +// xfrm_address_t saddr; +// __be16 dport; +// __be16 dport_mask; +// __be16 sport; +// __be16 sport_mask; +// __u16 family; +// __u8 prefixlen_d; +// __u8 prefixlen_s; +// __u8 proto; +// int ifindex; +// __kernel_uid32_t user; +// }; + +type XfrmSelector struct { + Daddr XfrmAddress + Saddr XfrmAddress + Dport uint16 // big endian + DportMask uint16 // big endian + Sport uint16 // big endian + SportMask uint16 // big endian + Family uint16 + PrefixlenD uint8 + PrefixlenS uint8 + Proto uint8 + Pad [3]byte + Ifindex int32 + User uint32 +} + +func (msg *XfrmSelector) Len() int { + return SizeofXfrmSelector +} + +func DeserializeXfrmSelector(b []byte) *XfrmSelector { + return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0])) +} + +func (msg *XfrmSelector) Serialize() []byte { + return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_lifetime_cfg { +// __u64 soft_byte_limit; +// __u64 hard_byte_limit; +// __u64 soft_packet_limit; +// __u64 hard_packet_limit; +// __u64 soft_add_expires_seconds; +// __u64 hard_add_expires_seconds; +// __u64 soft_use_expires_seconds; +// __u64 hard_use_expires_seconds; +// }; +// + +type XfrmLifetimeCfg struct { + SoftByteLimit uint64 + HardByteLimit uint64 + SoftPacketLimit uint64 + HardPacketLimit uint64 + SoftAddExpiresSeconds uint64 + HardAddExpiresSeconds uint64 + SoftUseExpiresSeconds uint64 + HardUseExpiresSeconds uint64 +} + +func (msg *XfrmLifetimeCfg) Len() int { + return SizeofXfrmLifetimeCfg +} + +func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg { + return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0])) +} + +func (msg *XfrmLifetimeCfg) Serialize() []byte { + return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_lifetime_cur { +// __u64 bytes; +// __u64 packets; +// __u64 add_time; +// __u64 use_time; +// }; + +type XfrmLifetimeCur struct { + Bytes uint64 + Packets uint64 + AddTime uint64 + UseTime uint64 +} + +func (msg *XfrmLifetimeCur) Len() int { + return SizeofXfrmLifetimeCur +} + +func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur { + return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0])) +} + +func (msg *XfrmLifetimeCur) Serialize() []byte { + return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_id { +// xfrm_address_t daddr; +// __be32 spi; +// __u8 proto; +// }; + +type XfrmId struct { + Daddr XfrmAddress + Spi uint32 // big endian + Proto uint8 + Pad [3]byte +} + +func (msg *XfrmId) Len() int { + return SizeofXfrmId +} + +func DeserializeXfrmId(b []byte) *XfrmId { + return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0])) +} + +func (msg *XfrmId) Serialize() []byte { + return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:] +} + +type XfrmMark struct { + Value uint32 + Mask uint32 +} + +func (msg *XfrmMark) Len() int { + return SizeofXfrmMark +} + +func DeserializeXfrmMark(b []byte) *XfrmMark { + return (*XfrmMark)(unsafe.Pointer(&b[0:SizeofXfrmMark][0])) +} + +func (msg *XfrmMark) Serialize() []byte { + return (*(*[SizeofXfrmMark]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go b/vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..715df4cc5f02a515ee5766a0d07bf95553ceadfb --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go @@ -0,0 +1,32 @@ +package nl + +import ( + "unsafe" +) + +const ( + SizeofXfrmUserExpire = 0xe8 +) + +// struct xfrm_user_expire { +// struct xfrm_usersa_info state; +// __u8 hard; +// }; + +type XfrmUserExpire struct { + XfrmUsersaInfo XfrmUsersaInfo + Hard uint8 + Pad [7]byte +} + +func (msg *XfrmUserExpire) Len() int { + return SizeofXfrmUserExpire +} + +func DeserializeXfrmUserExpire(b []byte) *XfrmUserExpire { + return (*XfrmUserExpire)(unsafe.Pointer(&b[0:SizeofXfrmUserExpire][0])) +} + +func (msg *XfrmUserExpire) Serialize() []byte { + return (*(*[SizeofXfrmUserExpire]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go b/vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..66f7e03d2d7f2a73a796eb8013adc018e6aa039f --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go @@ -0,0 +1,119 @@ +package nl + +import ( + "unsafe" +) + +const ( + SizeofXfrmUserpolicyId = 0x40 + SizeofXfrmUserpolicyInfo = 0xa8 + SizeofXfrmUserTmpl = 0x40 +) + +// struct xfrm_userpolicy_id { +// struct xfrm_selector sel; +// __u32 index; +// __u8 dir; +// }; +// + +type XfrmUserpolicyId struct { + Sel XfrmSelector + Index uint32 + Dir uint8 + Pad [3]byte +} + +func (msg *XfrmUserpolicyId) Len() int { + return SizeofXfrmUserpolicyId +} + +func DeserializeXfrmUserpolicyId(b []byte) *XfrmUserpolicyId { + return (*XfrmUserpolicyId)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyId][0])) +} + +func (msg *XfrmUserpolicyId) Serialize() []byte { + return (*(*[SizeofXfrmUserpolicyId]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_userpolicy_info { +// struct xfrm_selector sel; +// struct xfrm_lifetime_cfg lft; +// struct xfrm_lifetime_cur curlft; +// __u32 priority; +// __u32 index; +// __u8 dir; +// __u8 action; +// #define XFRM_POLICY_ALLOW 0 +// #define XFRM_POLICY_BLOCK 1 +// __u8 flags; +// #define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */ +// /* Automatically expand selector to include matching ICMP payloads. */ +// #define XFRM_POLICY_ICMP 2 +// __u8 share; +// }; + +type XfrmUserpolicyInfo struct { + Sel XfrmSelector + Lft XfrmLifetimeCfg + Curlft XfrmLifetimeCur + Priority uint32 + Index uint32 + Dir uint8 + Action uint8 + Flags uint8 + Share uint8 + Pad [4]byte +} + +func (msg *XfrmUserpolicyInfo) Len() int { + return SizeofXfrmUserpolicyInfo +} + +func DeserializeXfrmUserpolicyInfo(b []byte) *XfrmUserpolicyInfo { + return (*XfrmUserpolicyInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyInfo][0])) +} + +func (msg *XfrmUserpolicyInfo) Serialize() []byte { + return (*(*[SizeofXfrmUserpolicyInfo]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_user_tmpl { +// struct xfrm_id id; +// __u16 family; +// xfrm_address_t saddr; +// __u32 reqid; +// __u8 mode; +// __u8 share; +// __u8 optional; +// __u32 aalgos; +// __u32 ealgos; +// __u32 calgos; +// } + +type XfrmUserTmpl struct { + XfrmId XfrmId + Family uint16 + Pad1 [2]byte + Saddr XfrmAddress + Reqid uint32 + Mode uint8 + Share uint8 + Optional uint8 + Pad2 byte + Aalgos uint32 + Ealgos uint32 + Calgos uint32 +} + +func (msg *XfrmUserTmpl) Len() int { + return SizeofXfrmUserTmpl +} + +func DeserializeXfrmUserTmpl(b []byte) *XfrmUserTmpl { + return (*XfrmUserTmpl)(unsafe.Pointer(&b[0:SizeofXfrmUserTmpl][0])) +} + +func (msg *XfrmUserTmpl) Serialize() []byte { + return (*(*[SizeofXfrmUserTmpl]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go b/vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..b6290fd54426f605ac8d8b08388e79cd671c843d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go @@ -0,0 +1,334 @@ +package nl + +import ( + "unsafe" +) + +const ( + SizeofXfrmUsersaId = 0x18 + SizeofXfrmStats = 0x0c + SizeofXfrmUsersaInfo = 0xe0 + SizeofXfrmUserSpiInfo = 0xe8 + SizeofXfrmAlgo = 0x44 + SizeofXfrmAlgoAuth = 0x48 + SizeofXfrmAlgoAEAD = 0x48 + SizeofXfrmEncapTmpl = 0x18 + SizeofXfrmUsersaFlush = 0x8 + SizeofXfrmReplayStateEsn = 0x18 +) + +const ( + XFRM_STATE_NOECN = 1 + XFRM_STATE_DECAP_DSCP = 2 + XFRM_STATE_NOPMTUDISC = 4 + XFRM_STATE_WILDRECV = 8 + XFRM_STATE_ICMP = 16 + XFRM_STATE_AF_UNSPEC = 32 + XFRM_STATE_ALIGN4 = 64 + XFRM_STATE_ESN = 128 +) + +// struct xfrm_usersa_id { +// xfrm_address_t daddr; +// __be32 spi; +// __u16 family; +// __u8 proto; +// }; + +type XfrmUsersaId struct { + Daddr XfrmAddress + Spi uint32 // big endian + Family uint16 + Proto uint8 + Pad byte +} + +func (msg *XfrmUsersaId) Len() int { + return SizeofXfrmUsersaId +} + +func DeserializeXfrmUsersaId(b []byte) *XfrmUsersaId { + return (*XfrmUsersaId)(unsafe.Pointer(&b[0:SizeofXfrmUsersaId][0])) +} + +func (msg *XfrmUsersaId) Serialize() []byte { + return (*(*[SizeofXfrmUsersaId]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_stats { +// __u32 replay_window; +// __u32 replay; +// __u32 integrity_failed; +// }; + +type XfrmStats struct { + ReplayWindow uint32 + Replay uint32 + IntegrityFailed uint32 +} + +func (msg *XfrmStats) Len() int { + return SizeofXfrmStats +} + +func DeserializeXfrmStats(b []byte) *XfrmStats { + return (*XfrmStats)(unsafe.Pointer(&b[0:SizeofXfrmStats][0])) +} + +func (msg *XfrmStats) Serialize() []byte { + return (*(*[SizeofXfrmStats]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_usersa_info { +// struct xfrm_selector sel; +// struct xfrm_id id; +// xfrm_address_t saddr; +// struct xfrm_lifetime_cfg lft; +// struct xfrm_lifetime_cur curlft; +// struct xfrm_stats stats; +// __u32 seq; +// __u32 reqid; +// __u16 family; +// __u8 mode; /* XFRM_MODE_xxx */ +// __u8 replay_window; +// __u8 flags; +// #define XFRM_STATE_NOECN 1 +// #define XFRM_STATE_DECAP_DSCP 2 +// #define XFRM_STATE_NOPMTUDISC 4 +// #define XFRM_STATE_WILDRECV 8 +// #define XFRM_STATE_ICMP 16 +// #define XFRM_STATE_AF_UNSPEC 32 +// #define XFRM_STATE_ALIGN4 64 +// #define XFRM_STATE_ESN 128 +// }; +// +// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1 +// + +type XfrmUsersaInfo struct { + Sel XfrmSelector + Id XfrmId + Saddr XfrmAddress + Lft XfrmLifetimeCfg + Curlft XfrmLifetimeCur + Stats XfrmStats + Seq uint32 + Reqid uint32 + Family uint16 + Mode uint8 + ReplayWindow uint8 + Flags uint8 + Pad [7]byte +} + +func (msg *XfrmUsersaInfo) Len() int { + return SizeofXfrmUsersaInfo +} + +func DeserializeXfrmUsersaInfo(b []byte) *XfrmUsersaInfo { + return (*XfrmUsersaInfo)(unsafe.Pointer(&b[0:SizeofXfrmUsersaInfo][0])) +} + +func (msg *XfrmUsersaInfo) Serialize() []byte { + return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_userspi_info { +// struct xfrm_usersa_info info; +// __u32 min; +// __u32 max; +// }; + +type XfrmUserSpiInfo struct { + XfrmUsersaInfo XfrmUsersaInfo + Min uint32 + Max uint32 +} + +func (msg *XfrmUserSpiInfo) Len() int { + return SizeofXfrmUserSpiInfo +} + +func DeserializeXfrmUserSpiInfo(b []byte) *XfrmUserSpiInfo { + return (*XfrmUserSpiInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserSpiInfo][0])) +} + +func (msg *XfrmUserSpiInfo) Serialize() []byte { + return (*(*[SizeofXfrmUserSpiInfo]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_algo { +// char alg_name[64]; +// unsigned int alg_key_len; /* in bits */ +// char alg_key[0]; +// }; + +type XfrmAlgo struct { + AlgName [64]byte + AlgKeyLen uint32 + AlgKey []byte +} + +func (msg *XfrmAlgo) Len() int { + return SizeofXfrmAlgo + int(msg.AlgKeyLen/8) +} + +func DeserializeXfrmAlgo(b []byte) *XfrmAlgo { + ret := XfrmAlgo{} + copy(ret.AlgName[:], b[0:64]) + ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) + ret.AlgKey = b[68:ret.Len()] + return &ret +} + +func (msg *XfrmAlgo) Serialize() []byte { + b := make([]byte, msg.Len()) + copy(b[0:64], msg.AlgName[:]) + copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) + copy(b[68:msg.Len()], msg.AlgKey[:]) + return b +} + +// struct xfrm_algo_auth { +// char alg_name[64]; +// unsigned int alg_key_len; /* in bits */ +// unsigned int alg_trunc_len; /* in bits */ +// char alg_key[0]; +// }; + +type XfrmAlgoAuth struct { + AlgName [64]byte + AlgKeyLen uint32 + AlgTruncLen uint32 + AlgKey []byte +} + +func (msg *XfrmAlgoAuth) Len() int { + return SizeofXfrmAlgoAuth + int(msg.AlgKeyLen/8) +} + +func DeserializeXfrmAlgoAuth(b []byte) *XfrmAlgoAuth { + ret := XfrmAlgoAuth{} + copy(ret.AlgName[:], b[0:64]) + ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) + ret.AlgTruncLen = *(*uint32)(unsafe.Pointer(&b[68])) + ret.AlgKey = b[72:ret.Len()] + return &ret +} + +func (msg *XfrmAlgoAuth) Serialize() []byte { + b := make([]byte, msg.Len()) + copy(b[0:64], msg.AlgName[:]) + copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) + copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgTruncLen)))[:]) + copy(b[72:msg.Len()], msg.AlgKey[:]) + return b +} + +// struct xfrm_algo_aead { +// char alg_name[64]; +// unsigned int alg_key_len; /* in bits */ +// unsigned int alg_icv_len; /* in bits */ +// char alg_key[0]; +// } + +type XfrmAlgoAEAD struct { + AlgName [64]byte + AlgKeyLen uint32 + AlgICVLen uint32 + AlgKey []byte +} + +func (msg *XfrmAlgoAEAD) Len() int { + return SizeofXfrmAlgoAEAD + int(msg.AlgKeyLen/8) +} + +func DeserializeXfrmAlgoAEAD(b []byte) *XfrmAlgoAEAD { + ret := XfrmAlgoAEAD{} + copy(ret.AlgName[:], b[0:64]) + ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) + ret.AlgICVLen = *(*uint32)(unsafe.Pointer(&b[68])) + ret.AlgKey = b[72:ret.Len()] + return &ret +} + +func (msg *XfrmAlgoAEAD) Serialize() []byte { + b := make([]byte, msg.Len()) + copy(b[0:64], msg.AlgName[:]) + copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) + copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgICVLen)))[:]) + copy(b[72:msg.Len()], msg.AlgKey[:]) + return b +} + +// struct xfrm_encap_tmpl { +// __u16 encap_type; +// __be16 encap_sport; +// __be16 encap_dport; +// xfrm_address_t encap_oa; +// }; + +type XfrmEncapTmpl struct { + EncapType uint16 + EncapSport uint16 // big endian + EncapDport uint16 // big endian + Pad [2]byte + EncapOa XfrmAddress +} + +func (msg *XfrmEncapTmpl) Len() int { + return SizeofXfrmEncapTmpl +} + +func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl { + return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0])) +} + +func (msg *XfrmEncapTmpl) Serialize() []byte { + return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_usersa_flush { +// __u8 proto; +// }; + +type XfrmUsersaFlush struct { + Proto uint8 +} + +func (msg *XfrmUsersaFlush) Len() int { + return SizeofXfrmUsersaFlush +} + +func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush { + return (*XfrmUsersaFlush)(unsafe.Pointer(&b[0:SizeofXfrmUsersaFlush][0])) +} + +func (msg *XfrmUsersaFlush) Serialize() []byte { + return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:] +} + +// struct xfrm_replay_state_esn { +// unsigned int bmp_len; +// __u32 oseq; +// __u32 seq; +// __u32 oseq_hi; +// __u32 seq_hi; +// __u32 replay_window; +// __u32 bmp[0]; +// }; + +type XfrmReplayStateEsn struct { + BmpLen uint32 + OSeq uint32 + Seq uint32 + OSeqHi uint32 + SeqHi uint32 + ReplayWindow uint32 + Bmp []uint32 +} + +func (msg *XfrmReplayStateEsn) Serialize() []byte { + // We deliberately do not pass Bmp, as it gets set by the kernel. + return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:] +} diff --git a/vendor/github.com/vishvananda/netlink/order.go b/vendor/github.com/vishvananda/netlink/order.go new file mode 100644 index 0000000000000000000000000000000000000000..e28e153a1bf03892b5db18db7ffc3345de78e0cb --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/order.go @@ -0,0 +1,32 @@ +package netlink + +import ( + "encoding/binary" + + "github.com/vishvananda/netlink/nl" +) + +var ( + native = nl.NativeEndian() + networkOrder = binary.BigEndian +) + +func htonl(val uint32) []byte { + bytes := make([]byte, 4) + binary.BigEndian.PutUint32(bytes, val) + return bytes +} + +func htons(val uint16) []byte { + bytes := make([]byte, 2) + binary.BigEndian.PutUint16(bytes, val) + return bytes +} + +func ntohl(buf []byte) uint32 { + return binary.BigEndian.Uint32(buf) +} + +func ntohs(buf []byte) uint16 { + return binary.BigEndian.Uint16(buf) +} diff --git a/vendor/github.com/vishvananda/netlink/protinfo.go b/vendor/github.com/vishvananda/netlink/protinfo.go new file mode 100644 index 0000000000000000000000000000000000000000..0087c4438bc263dc13f5ed80a88dc0db5a2c570e --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/protinfo.go @@ -0,0 +1,58 @@ +package netlink + +import ( + "strings" +) + +// Protinfo represents bridge flags from netlink. +type Protinfo struct { + Hairpin bool + Guard bool + FastLeave bool + RootBlock bool + Learning bool + Flood bool + ProxyArp bool + ProxyArpWiFi bool +} + +// String returns a list of enabled flags +func (prot *Protinfo) String() string { + var boolStrings []string + if prot.Hairpin { + boolStrings = append(boolStrings, "Hairpin") + } + if prot.Guard { + boolStrings = append(boolStrings, "Guard") + } + if prot.FastLeave { + boolStrings = append(boolStrings, "FastLeave") + } + if prot.RootBlock { + boolStrings = append(boolStrings, "RootBlock") + } + if prot.Learning { + boolStrings = append(boolStrings, "Learning") + } + if prot.Flood { + boolStrings = append(boolStrings, "Flood") + } + if prot.ProxyArp { + boolStrings = append(boolStrings, "ProxyArp") + } + if prot.ProxyArpWiFi { + boolStrings = append(boolStrings, "ProxyArpWiFi") + } + return strings.Join(boolStrings, " ") +} + +func boolToByte(x bool) []byte { + if x { + return []byte{1} + } + return []byte{0} +} + +func byteToBool(x byte) bool { + return uint8(x) != 0 +} diff --git a/vendor/github.com/vishvananda/netlink/protinfo_linux.go b/vendor/github.com/vishvananda/netlink/protinfo_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..43c465f05758fc92a839b71faf1386fa022d6d88 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/protinfo_linux.go @@ -0,0 +1,75 @@ +package netlink + +import ( + "fmt" + "syscall" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +func LinkGetProtinfo(link Link) (Protinfo, error) { + return pkgHandle.LinkGetProtinfo(link) +} + +func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) { + base := link.Attrs() + h.ensureIndex(base) + var pi Protinfo + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) + msg := nl.NewIfInfomsg(unix.AF_BRIDGE) + req.AddData(msg) + msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) + if err != nil { + return pi, err + } + + for _, m := range msgs { + ans := nl.DeserializeIfInfomsg(m) + if int(ans.Index) != base.Index { + continue + } + attrs, err := nl.ParseRouteAttr(m[ans.Len():]) + if err != nil { + return pi, err + } + for _, attr := range attrs { + if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED { + continue + } + infos, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return pi, err + } + pi = *parseProtinfo(infos) + + return pi, nil + } + } + return pi, fmt.Errorf("Device with index %d not found", base.Index) +} + +func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo { + var pi Protinfo + for _, info := range infos { + switch info.Attr.Type { + case nl.IFLA_BRPORT_MODE: + pi.Hairpin = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_GUARD: + pi.Guard = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_FAST_LEAVE: + pi.FastLeave = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_PROTECT: + pi.RootBlock = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_LEARNING: + pi.Learning = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_UNICAST_FLOOD: + pi.Flood = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_PROXYARP: + pi.ProxyArp = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_PROXYARP_WIFI: + pi.ProxyArpWiFi = byteToBool(info.Value[0]) + } + } + return &pi +} diff --git a/vendor/github.com/vishvananda/netlink/qdisc.go b/vendor/github.com/vishvananda/netlink/qdisc.go new file mode 100644 index 0000000000000000000000000000000000000000..3df4b5c291cc0ccac89347901b5463d6faea5c13 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/qdisc.go @@ -0,0 +1,292 @@ +package netlink + +import ( + "fmt" + "math" +) + +const ( + HANDLE_NONE = 0 + HANDLE_INGRESS = 0xFFFFFFF1 + HANDLE_CLSACT = HANDLE_INGRESS + HANDLE_ROOT = 0xFFFFFFFF + PRIORITY_MAP_LEN = 16 +) +const ( + HANDLE_MIN_INGRESS = 0xFFFFFFF2 + HANDLE_MIN_EGRESS = 0xFFFFFFF3 +) + +type Qdisc interface { + Attrs() *QdiscAttrs + Type() string +} + +// QdiscAttrs represents a netlink qdisc. A qdisc is associated with a link, +// has a handle, a parent and a refcnt. The root qdisc of a device should +// have parent == HANDLE_ROOT. +type QdiscAttrs struct { + LinkIndex int + Handle uint32 + Parent uint32 + Refcnt uint32 // read only +} + +func (q QdiscAttrs) String() string { + return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt) +} + +func MakeHandle(major, minor uint16) uint32 { + return (uint32(major) << 16) | uint32(minor) +} + +func MajorMinor(handle uint32) (uint16, uint16) { + return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF) +} + +func HandleStr(handle uint32) string { + switch handle { + case HANDLE_NONE: + return "none" + case HANDLE_INGRESS: + return "ingress" + case HANDLE_ROOT: + return "root" + default: + major, minor := MajorMinor(handle) + return fmt.Sprintf("%x:%x", major, minor) + } +} + +func Percentage2u32(percentage float32) uint32 { + // FIXME this is most likely not the best way to convert from % to uint32 + if percentage == 100 { + return math.MaxUint32 + } + return uint32(math.MaxUint32 * (percentage / 100)) +} + +// PfifoFast is the default qdisc created by the kernel if one has not +// been defined for the interface +type PfifoFast struct { + QdiscAttrs + Bands uint8 + PriorityMap [PRIORITY_MAP_LEN]uint8 +} + +func (qdisc *PfifoFast) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *PfifoFast) Type() string { + return "pfifo_fast" +} + +// Prio is a basic qdisc that works just like PfifoFast +type Prio struct { + QdiscAttrs + Bands uint8 + PriorityMap [PRIORITY_MAP_LEN]uint8 +} + +func NewPrio(attrs QdiscAttrs) *Prio { + return &Prio{ + QdiscAttrs: attrs, + Bands: 3, + PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + } +} + +func (qdisc *Prio) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Prio) Type() string { + return "prio" +} + +// Htb is a classful qdisc that rate limits based on tokens +type Htb struct { + QdiscAttrs + Version uint32 + Rate2Quantum uint32 + Defcls uint32 + Debug uint32 + DirectPkts uint32 +} + +func NewHtb(attrs QdiscAttrs) *Htb { + return &Htb{ + QdiscAttrs: attrs, + Version: 3, + Defcls: 0, + Rate2Quantum: 10, + Debug: 0, + DirectPkts: 0, + } +} + +func (qdisc *Htb) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Htb) Type() string { + return "htb" +} + +// Netem is a classless qdisc that rate limits based on tokens + +type NetemQdiscAttrs struct { + Latency uint32 // in us + DelayCorr float32 // in % + Limit uint32 + Loss float32 // in % + LossCorr float32 // in % + Gap uint32 + Duplicate float32 // in % + DuplicateCorr float32 // in % + Jitter uint32 // in us + ReorderProb float32 // in % + ReorderCorr float32 // in % + CorruptProb float32 // in % + CorruptCorr float32 // in % +} + +func (q NetemQdiscAttrs) String() string { + return fmt.Sprintf( + "{Latency: %d, Limit: %d, Loss: %f, Gap: %d, Duplicate: %f, Jitter: %d}", + q.Latency, q.Limit, q.Loss, q.Gap, q.Duplicate, q.Jitter, + ) +} + +type Netem struct { + QdiscAttrs + Latency uint32 + DelayCorr uint32 + Limit uint32 + Loss uint32 + LossCorr uint32 + Gap uint32 + Duplicate uint32 + DuplicateCorr uint32 + Jitter uint32 + ReorderProb uint32 + ReorderCorr uint32 + CorruptProb uint32 + CorruptCorr uint32 +} + +func (qdisc *Netem) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Netem) Type() string { + return "netem" +} + +// Tbf is a classless qdisc that rate limits based on tokens +type Tbf struct { + QdiscAttrs + Rate uint64 + Limit uint32 + Buffer uint32 + Peakrate uint64 + Minburst uint32 + // TODO: handle other settings +} + +func (qdisc *Tbf) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Tbf) Type() string { + return "tbf" +} + +// Ingress is a qdisc for adding ingress filters +type Ingress struct { + QdiscAttrs +} + +func (qdisc *Ingress) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Ingress) Type() string { + return "ingress" +} + +// GenericQdisc qdiscs represent types that are not currently understood +// by this netlink library. +type GenericQdisc struct { + QdiscAttrs + QdiscType string +} + +func (qdisc *GenericQdisc) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *GenericQdisc) Type() string { + return qdisc.QdiscType +} + +// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic. +type Fq struct { + QdiscAttrs + PacketLimit uint32 + FlowPacketLimit uint32 + // In bytes + Quantum uint32 + InitialQuantum uint32 + // called RateEnable under the hood + Pacing uint32 + FlowDefaultRate uint32 + FlowMaxRate uint32 + // called BucketsLog under the hood + Buckets uint32 + FlowRefillDelay uint32 + LowRateThreshold uint32 +} + +func NewFq(attrs QdiscAttrs) *Fq { + return &Fq{ + QdiscAttrs: attrs, + Pacing: 1, + } +} + +func (qdisc *Fq) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *Fq) Type() string { + return "fq" +} + +// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme. +type FqCodel struct { + QdiscAttrs + Target uint32 + Limit uint32 + Interval uint32 + ECN uint32 + Flows uint32 + Quantum uint32 + // There are some more attributes here, but support for them seems not ubiquitous +} + +func NewFqCodel(attrs QdiscAttrs) *FqCodel { + return &FqCodel{ + QdiscAttrs: attrs, + ECN: 1, + } +} + +func (qdisc *FqCodel) Attrs() *QdiscAttrs { + return &qdisc.QdiscAttrs +} + +func (qdisc *FqCodel) Type() string { + return "fq_codel" +} diff --git a/vendor/github.com/vishvananda/netlink/qdisc_linux.go b/vendor/github.com/vishvananda/netlink/qdisc_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..3794ac18a83fe39e9374419dfdacadc29adef2d0 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/qdisc_linux.go @@ -0,0 +1,647 @@ +package netlink + +import ( + "fmt" + "io/ioutil" + "strconv" + "strings" + "syscall" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +// NOTE function is here because it uses other linux functions +func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem { + var limit uint32 = 1000 + var lossCorr, delayCorr, duplicateCorr uint32 + var reorderProb, reorderCorr uint32 + var corruptProb, corruptCorr uint32 + + latency := nattrs.Latency + loss := Percentage2u32(nattrs.Loss) + gap := nattrs.Gap + duplicate := Percentage2u32(nattrs.Duplicate) + jitter := nattrs.Jitter + + // Correlation + if latency > 0 && jitter > 0 { + delayCorr = Percentage2u32(nattrs.DelayCorr) + } + if loss > 0 { + lossCorr = Percentage2u32(nattrs.LossCorr) + } + if duplicate > 0 { + duplicateCorr = Percentage2u32(nattrs.DuplicateCorr) + } + // FIXME should validate values(like loss/duplicate are percentages...) + latency = time2Tick(latency) + + if nattrs.Limit != 0 { + limit = nattrs.Limit + } + // Jitter is only value if latency is > 0 + if latency > 0 { + jitter = time2Tick(jitter) + } + + reorderProb = Percentage2u32(nattrs.ReorderProb) + reorderCorr = Percentage2u32(nattrs.ReorderCorr) + + if reorderProb > 0 { + // ERROR if lantency == 0 + if gap == 0 { + gap = 1 + } + } + + corruptProb = Percentage2u32(nattrs.CorruptProb) + corruptCorr = Percentage2u32(nattrs.CorruptCorr) + + return &Netem{ + QdiscAttrs: attrs, + Latency: latency, + DelayCorr: delayCorr, + Limit: limit, + Loss: loss, + LossCorr: lossCorr, + Gap: gap, + Duplicate: duplicate, + DuplicateCorr: duplicateCorr, + Jitter: jitter, + ReorderProb: reorderProb, + ReorderCorr: reorderCorr, + CorruptProb: corruptProb, + CorruptCorr: corruptCorr, + } +} + +// QdiscDel will delete a qdisc from the system. +// Equivalent to: `tc qdisc del $qdisc` +func QdiscDel(qdisc Qdisc) error { + return pkgHandle.QdiscDel(qdisc) +} + +// QdiscDel will delete a qdisc from the system. +// Equivalent to: `tc qdisc del $qdisc` +func (h *Handle) QdiscDel(qdisc Qdisc) error { + return h.qdiscModify(unix.RTM_DELQDISC, 0, qdisc) +} + +// QdiscChange will change a qdisc in place +// Equivalent to: `tc qdisc change $qdisc` +// The parent and handle MUST NOT be changed. +func QdiscChange(qdisc Qdisc) error { + return pkgHandle.QdiscChange(qdisc) +} + +// QdiscChange will change a qdisc in place +// Equivalent to: `tc qdisc change $qdisc` +// The parent and handle MUST NOT be changed. +func (h *Handle) QdiscChange(qdisc Qdisc) error { + return h.qdiscModify(unix.RTM_NEWQDISC, 0, qdisc) +} + +// QdiscReplace will replace a qdisc to the system. +// Equivalent to: `tc qdisc replace $qdisc` +// The handle MUST change. +func QdiscReplace(qdisc Qdisc) error { + return pkgHandle.QdiscReplace(qdisc) +} + +// QdiscReplace will replace a qdisc to the system. +// Equivalent to: `tc qdisc replace $qdisc` +// The handle MUST change. +func (h *Handle) QdiscReplace(qdisc Qdisc) error { + return h.qdiscModify( + unix.RTM_NEWQDISC, + unix.NLM_F_CREATE|unix.NLM_F_REPLACE, + qdisc) +} + +// QdiscAdd will add a qdisc to the system. +// Equivalent to: `tc qdisc add $qdisc` +func QdiscAdd(qdisc Qdisc) error { + return pkgHandle.QdiscAdd(qdisc) +} + +// QdiscAdd will add a qdisc to the system. +// Equivalent to: `tc qdisc add $qdisc` +func (h *Handle) QdiscAdd(qdisc Qdisc) error { + return h.qdiscModify( + unix.RTM_NEWQDISC, + unix.NLM_F_CREATE|unix.NLM_F_EXCL, + qdisc) +} + +func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error { + req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) + base := qdisc.Attrs() + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Ifindex: int32(base.LinkIndex), + Handle: base.Handle, + Parent: base.Parent, + } + req.AddData(msg) + + // When deleting don't bother building the rest of the netlink payload + if cmd != unix.RTM_DELQDISC { + if err := qdiscPayload(req, qdisc); err != nil { + return err + } + } + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error { + + req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type()))) + + options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) + + switch qdisc := qdisc.(type) { + case *Prio: + tcmap := nl.TcPrioMap{ + Bands: int32(qdisc.Bands), + Priomap: qdisc.PriorityMap, + } + options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize()) + case *Tbf: + opt := nl.TcTbfQopt{} + opt.Rate.Rate = uint32(qdisc.Rate) + opt.Peakrate.Rate = uint32(qdisc.Peakrate) + opt.Limit = qdisc.Limit + opt.Buffer = qdisc.Buffer + nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize()) + if qdisc.Rate >= uint64(1<<32) { + nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate)) + } + if qdisc.Peakrate >= uint64(1<<32) { + nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate)) + } + if qdisc.Peakrate > 0 { + nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst)) + } + case *Htb: + opt := nl.TcHtbGlob{} + opt.Version = qdisc.Version + opt.Rate2Quantum = qdisc.Rate2Quantum + opt.Defcls = qdisc.Defcls + // TODO: Handle Debug properly. For now default to 0 + opt.Debug = qdisc.Debug + opt.DirectPkts = qdisc.DirectPkts + nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize()) + // nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize()) + case *Netem: + opt := nl.TcNetemQopt{} + opt.Latency = qdisc.Latency + opt.Limit = qdisc.Limit + opt.Loss = qdisc.Loss + opt.Gap = qdisc.Gap + opt.Duplicate = qdisc.Duplicate + opt.Jitter = qdisc.Jitter + options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize()) + // Correlation + corr := nl.TcNetemCorr{} + corr.DelayCorr = qdisc.DelayCorr + corr.LossCorr = qdisc.LossCorr + corr.DupCorr = qdisc.DuplicateCorr + + if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 { + nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize()) + } + // Corruption + corruption := nl.TcNetemCorrupt{} + corruption.Probability = qdisc.CorruptProb + corruption.Correlation = qdisc.CorruptCorr + if corruption.Probability > 0 { + nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize()) + } + // Reorder + reorder := nl.TcNetemReorder{} + reorder.Probability = qdisc.ReorderProb + reorder.Correlation = qdisc.ReorderCorr + if reorder.Probability > 0 { + nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize()) + } + case *Ingress: + // ingress filters must use the proper handle + if qdisc.Attrs().Parent != HANDLE_INGRESS { + return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS") + } + case *FqCodel: + nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN)))) + if qdisc.Limit > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit)))) + } + if qdisc.Interval > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval)))) + } + if qdisc.Flows > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows)))) + } + if qdisc.Quantum > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) + } + + case *Fq: + nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing)))) + + if qdisc.Buckets > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets)))) + } + if qdisc.LowRateThreshold > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold)))) + } + if qdisc.Quantum > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) + } + if qdisc.InitialQuantum > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum)))) + } + if qdisc.FlowRefillDelay > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay)))) + } + if qdisc.FlowPacketLimit > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit)))) + } + if qdisc.FlowMaxRate > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate)))) + } + if qdisc.FlowDefaultRate > 0 { + nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate)))) + } + } + + req.AddData(options) + return nil +} + +// QdiscList gets a list of qdiscs in the system. +// Equivalent to: `tc qdisc show`. +// The list can be filtered by link. +func QdiscList(link Link) ([]Qdisc, error) { + return pkgHandle.QdiscList(link) +} + +// QdiscList gets a list of qdiscs in the system. +// Equivalent to: `tc qdisc show`. +// The list can be filtered by link. +func (h *Handle) QdiscList(link Link) ([]Qdisc, error) { + req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP) + index := int32(0) + if link != nil { + base := link.Attrs() + h.ensureIndex(base) + index = int32(base.Index) + } + msg := &nl.TcMsg{ + Family: nl.FAMILY_ALL, + Ifindex: index, + } + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC) + if err != nil { + return nil, err + } + + var res []Qdisc + for _, m := range msgs { + msg := nl.DeserializeTcMsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + // skip qdiscs from other interfaces + if link != nil && msg.Ifindex != index { + continue + } + + base := QdiscAttrs{ + LinkIndex: int(msg.Ifindex), + Handle: msg.Handle, + Parent: msg.Parent, + Refcnt: msg.Info, + } + var qdisc Qdisc + qdiscType := "" + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.TCA_KIND: + qdiscType = string(attr.Value[:len(attr.Value)-1]) + switch qdiscType { + case "pfifo_fast": + qdisc = &PfifoFast{} + case "prio": + qdisc = &Prio{} + case "tbf": + qdisc = &Tbf{} + case "ingress": + qdisc = &Ingress{} + case "htb": + qdisc = &Htb{} + case "fq": + qdisc = &Fq{} + case "fq_codel": + qdisc = &FqCodel{} + case "netem": + qdisc = &Netem{} + default: + qdisc = &GenericQdisc{QdiscType: qdiscType} + } + case nl.TCA_OPTIONS: + switch qdiscType { + case "pfifo_fast": + // pfifo returns TcPrioMap directly without wrapping it in rtattr + if err := parsePfifoFastData(qdisc, attr.Value); err != nil { + return nil, err + } + case "prio": + // prio returns TcPrioMap directly without wrapping it in rtattr + if err := parsePrioData(qdisc, attr.Value); err != nil { + return nil, err + } + case "tbf": + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + if err := parseTbfData(qdisc, data); err != nil { + return nil, err + } + case "htb": + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + if err := parseHtbData(qdisc, data); err != nil { + return nil, err + } + case "fq": + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + if err := parseFqData(qdisc, data); err != nil { + return nil, err + } + case "fq_codel": + data, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, err + } + if err := parseFqCodelData(qdisc, data); err != nil { + return nil, err + } + case "netem": + if err := parseNetemData(qdisc, attr.Value); err != nil { + return nil, err + } + + // no options for ingress + } + } + } + *qdisc.Attrs() = base + res = append(res, qdisc) + } + + return res, nil +} + +func parsePfifoFastData(qdisc Qdisc, value []byte) error { + pfifo := qdisc.(*PfifoFast) + tcmap := nl.DeserializeTcPrioMap(value) + pfifo.PriorityMap = tcmap.Priomap + pfifo.Bands = uint8(tcmap.Bands) + return nil +} + +func parsePrioData(qdisc Qdisc, value []byte) error { + prio := qdisc.(*Prio) + tcmap := nl.DeserializeTcPrioMap(value) + prio.PriorityMap = tcmap.Priomap + prio.Bands = uint8(tcmap.Bands) + return nil +} + +func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { + native = nl.NativeEndian() + htb := qdisc.(*Htb) + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_HTB_INIT: + opt := nl.DeserializeTcHtbGlob(datum.Value) + htb.Version = opt.Version + htb.Rate2Quantum = opt.Rate2Quantum + htb.Defcls = opt.Defcls + htb.Debug = opt.Debug + htb.DirectPkts = opt.DirectPkts + case nl.TCA_HTB_DIRECT_QLEN: + // TODO + //htb.DirectQlen = native.uint32(datum.Value) + } + } + return nil +} + +func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { + native = nl.NativeEndian() + fqCodel := qdisc.(*FqCodel) + for _, datum := range data { + + switch datum.Attr.Type { + case nl.TCA_FQ_CODEL_TARGET: + fqCodel.Target = native.Uint32(datum.Value) + case nl.TCA_FQ_CODEL_LIMIT: + fqCodel.Limit = native.Uint32(datum.Value) + case nl.TCA_FQ_CODEL_INTERVAL: + fqCodel.Interval = native.Uint32(datum.Value) + case nl.TCA_FQ_CODEL_ECN: + fqCodel.ECN = native.Uint32(datum.Value) + case nl.TCA_FQ_CODEL_FLOWS: + fqCodel.Flows = native.Uint32(datum.Value) + case nl.TCA_FQ_CODEL_QUANTUM: + fqCodel.Quantum = native.Uint32(datum.Value) + } + } + return nil +} + +func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { + native = nl.NativeEndian() + fq := qdisc.(*Fq) + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_FQ_BUCKETS_LOG: + fq.Buckets = native.Uint32(datum.Value) + case nl.TCA_FQ_LOW_RATE_THRESHOLD: + fq.LowRateThreshold = native.Uint32(datum.Value) + case nl.TCA_FQ_QUANTUM: + fq.Quantum = native.Uint32(datum.Value) + case nl.TCA_FQ_RATE_ENABLE: + fq.Pacing = native.Uint32(datum.Value) + case nl.TCA_FQ_INITIAL_QUANTUM: + fq.InitialQuantum = native.Uint32(datum.Value) + case nl.TCA_FQ_ORPHAN_MASK: + // TODO + case nl.TCA_FQ_FLOW_REFILL_DELAY: + fq.FlowRefillDelay = native.Uint32(datum.Value) + case nl.TCA_FQ_FLOW_PLIMIT: + fq.FlowPacketLimit = native.Uint32(datum.Value) + case nl.TCA_FQ_PLIMIT: + fq.PacketLimit = native.Uint32(datum.Value) + case nl.TCA_FQ_FLOW_MAX_RATE: + fq.FlowMaxRate = native.Uint32(datum.Value) + case nl.TCA_FQ_FLOW_DEFAULT_RATE: + fq.FlowDefaultRate = native.Uint32(datum.Value) + } + } + return nil +} + +func parseNetemData(qdisc Qdisc, value []byte) error { + netem := qdisc.(*Netem) + opt := nl.DeserializeTcNetemQopt(value) + netem.Latency = opt.Latency + netem.Limit = opt.Limit + netem.Loss = opt.Loss + netem.Gap = opt.Gap + netem.Duplicate = opt.Duplicate + netem.Jitter = opt.Jitter + data, err := nl.ParseRouteAttr(value[nl.SizeofTcNetemQopt:]) + if err != nil { + return err + } + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_NETEM_CORR: + opt := nl.DeserializeTcNetemCorr(datum.Value) + netem.DelayCorr = opt.DelayCorr + netem.LossCorr = opt.LossCorr + netem.DuplicateCorr = opt.DupCorr + case nl.TCA_NETEM_CORRUPT: + opt := nl.DeserializeTcNetemCorrupt(datum.Value) + netem.CorruptProb = opt.Probability + netem.CorruptCorr = opt.Correlation + case nl.TCA_NETEM_REORDER: + opt := nl.DeserializeTcNetemReorder(datum.Value) + netem.ReorderProb = opt.Probability + netem.ReorderCorr = opt.Correlation + } + } + return nil +} + +func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { + native = nl.NativeEndian() + tbf := qdisc.(*Tbf) + for _, datum := range data { + switch datum.Attr.Type { + case nl.TCA_TBF_PARMS: + opt := nl.DeserializeTcTbfQopt(datum.Value) + tbf.Rate = uint64(opt.Rate.Rate) + tbf.Peakrate = uint64(opt.Peakrate.Rate) + tbf.Limit = opt.Limit + tbf.Buffer = opt.Buffer + case nl.TCA_TBF_RATE64: + tbf.Rate = native.Uint64(datum.Value[0:8]) + case nl.TCA_TBF_PRATE64: + tbf.Peakrate = native.Uint64(datum.Value[0:8]) + case nl.TCA_TBF_PBURST: + tbf.Minburst = native.Uint32(datum.Value[0:4]) + } + } + return nil +} + +const ( + TIME_UNITS_PER_SEC = 1000000 +) + +var ( + tickInUsec float64 + clockFactor float64 + hz float64 +) + +func initClock() { + data, err := ioutil.ReadFile("/proc/net/psched") + if err != nil { + return + } + parts := strings.Split(strings.TrimSpace(string(data)), " ") + if len(parts) < 3 { + return + } + var vals [3]uint64 + for i := range vals { + val, err := strconv.ParseUint(parts[i], 16, 32) + if err != nil { + return + } + vals[i] = val + } + // compatibility + if vals[2] == 1000000000 { + vals[0] = vals[1] + } + clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC + tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor + hz = float64(vals[0]) +} + +func TickInUsec() float64 { + if tickInUsec == 0.0 { + initClock() + } + return tickInUsec +} + +func ClockFactor() float64 { + if clockFactor == 0.0 { + initClock() + } + return clockFactor +} + +func Hz() float64 { + if hz == 0.0 { + initClock() + } + return hz +} + +func time2Tick(time uint32) uint32 { + return uint32(float64(time) * TickInUsec()) +} + +func tick2Time(tick uint32) uint32 { + return uint32(float64(tick) / TickInUsec()) +} + +func time2Ktime(time uint32) uint32 { + return uint32(float64(time) * ClockFactor()) +} + +func ktime2Time(ktime uint32) uint32 { + return uint32(float64(ktime) / ClockFactor()) +} + +func burst(rate uint64, buffer uint32) uint32 { + return uint32(float64(rate) * float64(tick2Time(buffer)) / TIME_UNITS_PER_SEC) +} + +func latency(rate uint64, limit, buffer uint32) float64 { + return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer)) +} + +func Xmittime(rate uint64, size uint32) float64 { + return TickInUsec() * TIME_UNITS_PER_SEC * (float64(size) / float64(rate)) +} diff --git a/vendor/github.com/vishvananda/netlink/route.go b/vendor/github.com/vishvananda/netlink/route.go new file mode 100644 index 0000000000000000000000000000000000000000..2cd58ee33424b48341f4bed41d4043ac764c3c2f --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/route.go @@ -0,0 +1,178 @@ +package netlink + +import ( + "fmt" + "net" + "strings" +) + +// Scope is an enum representing a route scope. +type Scope uint8 + +type NextHopFlag int + +type Destination interface { + Family() int + Decode([]byte) error + Encode() ([]byte, error) + String() string + Equal(Destination) bool +} + +type Encap interface { + Type() int + Decode([]byte) error + Encode() ([]byte, error) + String() string + Equal(Encap) bool +} + +// Route represents a netlink route. +type Route struct { + LinkIndex int + ILinkIndex int + Scope Scope + Dst *net.IPNet + Src net.IP + Gw net.IP + MultiPath []*NexthopInfo + Protocol int + Priority int + Table int + Type int + Tos int + Flags int + MPLSDst *int + NewDst Destination + Encap Encap + MTU int + AdvMSS int +} + +func (r Route) String() string { + elems := []string{} + if len(r.MultiPath) == 0 { + elems = append(elems, fmt.Sprintf("Ifindex: %d", r.LinkIndex)) + } + if r.MPLSDst != nil { + elems = append(elems, fmt.Sprintf("Dst: %d", r.MPLSDst)) + } else { + elems = append(elems, fmt.Sprintf("Dst: %s", r.Dst)) + } + if r.NewDst != nil { + elems = append(elems, fmt.Sprintf("NewDst: %s", r.NewDst)) + } + if r.Encap != nil { + elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap)) + } + elems = append(elems, fmt.Sprintf("Src: %s", r.Src)) + if len(r.MultiPath) > 0 { + elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath)) + } else { + elems = append(elems, fmt.Sprintf("Gw: %s", r.Gw)) + } + elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags())) + elems = append(elems, fmt.Sprintf("Table: %d", r.Table)) + return fmt.Sprintf("{%s}", strings.Join(elems, " ")) +} + +func (r Route) Equal(x Route) bool { + return r.LinkIndex == x.LinkIndex && + r.ILinkIndex == x.ILinkIndex && + r.Scope == x.Scope && + ipNetEqual(r.Dst, x.Dst) && + r.Src.Equal(x.Src) && + r.Gw.Equal(x.Gw) && + nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) && + r.Protocol == x.Protocol && + r.Priority == x.Priority && + r.Table == x.Table && + r.Type == x.Type && + r.Tos == x.Tos && + r.Flags == x.Flags && + (r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) && + (r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) && + (r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap))) +} + +func (r *Route) SetFlag(flag NextHopFlag) { + r.Flags |= int(flag) +} + +func (r *Route) ClearFlag(flag NextHopFlag) { + r.Flags &^= int(flag) +} + +type flagString struct { + f NextHopFlag + s string +} + +// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE +type RouteUpdate struct { + Type uint16 + Route +} + +type NexthopInfo struct { + LinkIndex int + Hops int + Gw net.IP + Flags int + NewDst Destination + Encap Encap +} + +func (n *NexthopInfo) String() string { + elems := []string{} + elems = append(elems, fmt.Sprintf("Ifindex: %d", n.LinkIndex)) + if n.NewDst != nil { + elems = append(elems, fmt.Sprintf("NewDst: %s", n.NewDst)) + } + if n.Encap != nil { + elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap)) + } + elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1)) + elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw)) + elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags())) + return fmt.Sprintf("{%s}", strings.Join(elems, " ")) +} + +func (n NexthopInfo) Equal(x NexthopInfo) bool { + return n.LinkIndex == x.LinkIndex && + n.Hops == x.Hops && + n.Gw.Equal(x.Gw) && + n.Flags == x.Flags && + (n.NewDst == x.NewDst || (n.NewDst != nil && n.NewDst.Equal(x.NewDst))) && + (n.Encap == x.Encap || (n.Encap != nil && n.Encap.Equal(x.Encap))) +} + +type nexthopInfoSlice []*NexthopInfo + +func (n nexthopInfoSlice) Equal(x []*NexthopInfo) bool { + if len(n) != len(x) { + return false + } + for i := range n { + if n[i] == nil || x[i] == nil { + return false + } + if !n[i].Equal(*x[i]) { + return false + } + } + return true +} + +// ipNetEqual returns true iff both IPNet are equal +func ipNetEqual(ipn1 *net.IPNet, ipn2 *net.IPNet) bool { + if ipn1 == ipn2 { + return true + } + if ipn1 == nil || ipn2 == nil { + return false + } + m1, _ := ipn1.Mask.Size() + m2, _ := ipn2.Mask.Size() + return m1 == m2 && ipn1.IP.Equal(ipn2.IP) +} diff --git a/vendor/github.com/vishvananda/netlink/route_linux.go b/vendor/github.com/vishvananda/netlink/route_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..3f856711f3ce8bec5196fc023117d29bfffe38c7 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/route_linux.go @@ -0,0 +1,878 @@ +package netlink + +import ( + "fmt" + "net" + "strings" + "syscall" + + "github.com/vishvananda/netlink/nl" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +// RtAttr is shared so it is in netlink_linux.go + +const ( + SCOPE_UNIVERSE Scope = unix.RT_SCOPE_UNIVERSE + SCOPE_SITE Scope = unix.RT_SCOPE_SITE + SCOPE_LINK Scope = unix.RT_SCOPE_LINK + SCOPE_HOST Scope = unix.RT_SCOPE_HOST + SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE +) + +const ( + RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota) + RT_FILTER_SCOPE + RT_FILTER_TYPE + RT_FILTER_TOS + RT_FILTER_IIF + RT_FILTER_OIF + RT_FILTER_DST + RT_FILTER_SRC + RT_FILTER_GW + RT_FILTER_TABLE +) + +const ( + FLAG_ONLINK NextHopFlag = unix.RTNH_F_ONLINK + FLAG_PERVASIVE NextHopFlag = unix.RTNH_F_PERVASIVE +) + +var testFlags = []flagString{ + {f: FLAG_ONLINK, s: "onlink"}, + {f: FLAG_PERVASIVE, s: "pervasive"}, +} + +func listFlags(flag int) []string { + var flags []string + for _, tf := range testFlags { + if flag&int(tf.f) != 0 { + flags = append(flags, tf.s) + } + } + return flags +} + +func (r *Route) ListFlags() []string { + return listFlags(r.Flags) +} + +func (n *NexthopInfo) ListFlags() []string { + return listFlags(n.Flags) +} + +type MPLSDestination struct { + Labels []int +} + +func (d *MPLSDestination) Family() int { + return nl.FAMILY_MPLS +} + +func (d *MPLSDestination) Decode(buf []byte) error { + d.Labels = nl.DecodeMPLSStack(buf) + return nil +} + +func (d *MPLSDestination) Encode() ([]byte, error) { + return nl.EncodeMPLSStack(d.Labels...), nil +} + +func (d *MPLSDestination) String() string { + s := make([]string, 0, len(d.Labels)) + for _, l := range d.Labels { + s = append(s, fmt.Sprintf("%d", l)) + } + return strings.Join(s, "/") +} + +func (d *MPLSDestination) Equal(x Destination) bool { + o, ok := x.(*MPLSDestination) + if !ok { + return false + } + if d == nil && o == nil { + return true + } + if d == nil || o == nil { + return false + } + if d.Labels == nil && o.Labels == nil { + return true + } + if d.Labels == nil || o.Labels == nil { + return false + } + if len(d.Labels) != len(o.Labels) { + return false + } + for i := range d.Labels { + if d.Labels[i] != o.Labels[i] { + return false + } + } + return true +} + +type MPLSEncap struct { + Labels []int +} + +func (e *MPLSEncap) Type() int { + return nl.LWTUNNEL_ENCAP_MPLS +} + +func (e *MPLSEncap) Decode(buf []byte) error { + if len(buf) < 4 { + return fmt.Errorf("lack of bytes") + } + native := nl.NativeEndian() + l := native.Uint16(buf) + if len(buf) < int(l) { + return fmt.Errorf("lack of bytes") + } + buf = buf[:l] + typ := native.Uint16(buf[2:]) + if typ != nl.MPLS_IPTUNNEL_DST { + return fmt.Errorf("unknown MPLS Encap Type: %d", typ) + } + e.Labels = nl.DecodeMPLSStack(buf[4:]) + return nil +} + +func (e *MPLSEncap) Encode() ([]byte, error) { + s := nl.EncodeMPLSStack(e.Labels...) + native := nl.NativeEndian() + hdr := make([]byte, 4) + native.PutUint16(hdr, uint16(len(s)+4)) + native.PutUint16(hdr[2:], nl.MPLS_IPTUNNEL_DST) + return append(hdr, s...), nil +} + +func (e *MPLSEncap) String() string { + s := make([]string, 0, len(e.Labels)) + for _, l := range e.Labels { + s = append(s, fmt.Sprintf("%d", l)) + } + return strings.Join(s, "/") +} + +func (e *MPLSEncap) Equal(x Encap) bool { + o, ok := x.(*MPLSEncap) + if !ok { + return false + } + if e == nil && o == nil { + return true + } + if e == nil || o == nil { + return false + } + if e.Labels == nil && o.Labels == nil { + return true + } + if e.Labels == nil || o.Labels == nil { + return false + } + if len(e.Labels) != len(o.Labels) { + return false + } + for i := range e.Labels { + if e.Labels[i] != o.Labels[i] { + return false + } + } + return true +} + +// SEG6 definitions +type SEG6Encap struct { + Mode int + Segments []net.IP +} + +func (e *SEG6Encap) Type() int { + return nl.LWTUNNEL_ENCAP_SEG6 +} +func (e *SEG6Encap) Decode(buf []byte) error { + if len(buf) < 4 { + return fmt.Errorf("lack of bytes") + } + native := nl.NativeEndian() + // Get Length(l) & Type(typ) : 2 + 2 bytes + l := native.Uint16(buf) + if len(buf) < int(l) { + return fmt.Errorf("lack of bytes") + } + buf = buf[:l] // make sure buf size upper limit is Length + typ := native.Uint16(buf[2:]) + if typ != nl.SEG6_IPTUNNEL_SRH { + return fmt.Errorf("unknown SEG6 Type: %d", typ) + } + + var err error + e.Mode, e.Segments, err = nl.DecodeSEG6Encap(buf[4:]) + + return err +} +func (e *SEG6Encap) Encode() ([]byte, error) { + s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments) + native := nl.NativeEndian() + hdr := make([]byte, 4) + native.PutUint16(hdr, uint16(len(s)+4)) + native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH) + return append(hdr, s...), err +} +func (e *SEG6Encap) String() string { + segs := make([]string, 0, len(e.Segments)) + // append segment backwards (from n to 0) since seg#0 is the last segment. + for i := len(e.Segments); i > 0; i-- { + segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1])) + } + str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode), + len(e.Segments), strings.Join(segs, " ")) + return str +} +func (e *SEG6Encap) Equal(x Encap) bool { + o, ok := x.(*SEG6Encap) + if !ok { + return false + } + if e == o { + return true + } + if e == nil || o == nil { + return false + } + if e.Mode != o.Mode { + return false + } + if len(e.Segments) != len(o.Segments) { + return false + } + for i := range e.Segments { + if !e.Segments[i].Equal(o.Segments[i]) { + return false + } + } + return true +} + +// RouteAdd will add a route to the system. +// Equivalent to: `ip route add $route` +func RouteAdd(route *Route) error { + return pkgHandle.RouteAdd(route) +} + +// RouteAdd will add a route to the system. +// Equivalent to: `ip route add $route` +func (h *Handle) RouteAdd(route *Route) error { + flags := unix.NLM_F_CREATE | unix.NLM_F_EXCL | unix.NLM_F_ACK + req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) + return h.routeHandle(route, req, nl.NewRtMsg()) +} + +// RouteReplace will add a route to the system. +// Equivalent to: `ip route replace $route` +func RouteReplace(route *Route) error { + return pkgHandle.RouteReplace(route) +} + +// RouteReplace will add a route to the system. +// Equivalent to: `ip route replace $route` +func (h *Handle) RouteReplace(route *Route) error { + flags := unix.NLM_F_CREATE | unix.NLM_F_REPLACE | unix.NLM_F_ACK + req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) + return h.routeHandle(route, req, nl.NewRtMsg()) +} + +// RouteDel will delete a route from the system. +// Equivalent to: `ip route del $route` +func RouteDel(route *Route) error { + return pkgHandle.RouteDel(route) +} + +// RouteDel will delete a route from the system. +// Equivalent to: `ip route del $route` +func (h *Handle) RouteDel(route *Route) error { + req := h.newNetlinkRequest(unix.RTM_DELROUTE, unix.NLM_F_ACK) + return h.routeHandle(route, req, nl.NewRtDelMsg()) +} + +func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error { + if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil && route.MPLSDst == nil { + return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil") + } + + family := -1 + var rtAttrs []*nl.RtAttr + + if route.Dst != nil && route.Dst.IP != nil { + dstLen, _ := route.Dst.Mask.Size() + msg.Dst_len = uint8(dstLen) + dstFamily := nl.GetIPFamily(route.Dst.IP) + family = dstFamily + var dstData []byte + if dstFamily == FAMILY_V4 { + dstData = route.Dst.IP.To4() + } else { + dstData = route.Dst.IP.To16() + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) + } else if route.MPLSDst != nil { + family = nl.FAMILY_MPLS + msg.Dst_len = uint8(20) + msg.Type = unix.RTN_UNICAST + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst))) + } + + if route.NewDst != nil { + if family != -1 && family != route.NewDst.Family() { + return fmt.Errorf("new destination and destination are not the same address family") + } + buf, err := route.NewDst.Encode() + if err != nil { + return err + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_NEWDST, buf)) + } + + if route.Encap != nil { + buf := make([]byte, 2) + native.PutUint16(buf, uint16(route.Encap.Type())) + rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf)) + buf, err := route.Encap.Encode() + if err != nil { + return err + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP, buf)) + } + + if route.Src != nil { + srcFamily := nl.GetIPFamily(route.Src) + if family != -1 && family != srcFamily { + return fmt.Errorf("source and destination ip are not the same IP family") + } + family = srcFamily + var srcData []byte + if srcFamily == FAMILY_V4 { + srcData = route.Src.To4() + } else { + srcData = route.Src.To16() + } + // The commonly used src ip for routes is actually PREFSRC + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PREFSRC, srcData)) + } + + if route.Gw != nil { + gwFamily := nl.GetIPFamily(route.Gw) + if family != -1 && family != gwFamily { + return fmt.Errorf("gateway, source, and destination ip are not the same IP family") + } + family = gwFamily + var gwData []byte + if gwFamily == FAMILY_V4 { + gwData = route.Gw.To4() + } else { + gwData = route.Gw.To16() + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData)) + } + + if len(route.MultiPath) > 0 { + buf := []byte{} + for _, nh := range route.MultiPath { + rtnh := &nl.RtNexthop{ + RtNexthop: unix.RtNexthop{ + Hops: uint8(nh.Hops), + Ifindex: int32(nh.LinkIndex), + Flags: uint8(nh.Flags), + }, + } + children := []nl.NetlinkRequestData{} + if nh.Gw != nil { + gwFamily := nl.GetIPFamily(nh.Gw) + if family != -1 && family != gwFamily { + return fmt.Errorf("gateway, source, and destination ip are not the same IP family") + } + if gwFamily == FAMILY_V4 { + children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To4()))) + } else { + children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To16()))) + } + } + if nh.NewDst != nil { + if family != -1 && family != nh.NewDst.Family() { + return fmt.Errorf("new destination and destination are not the same address family") + } + buf, err := nh.NewDst.Encode() + if err != nil { + return err + } + children = append(children, nl.NewRtAttr(nl.RTA_NEWDST, buf)) + } + if nh.Encap != nil { + buf := make([]byte, 2) + native.PutUint16(buf, uint16(nh.Encap.Type())) + rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf)) + buf, err := nh.Encap.Encode() + if err != nil { + return err + } + children = append(children, nl.NewRtAttr(nl.RTA_ENCAP, buf)) + } + rtnh.Children = children + buf = append(buf, rtnh.Serialize()...) + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_MULTIPATH, buf)) + } + + if route.Table > 0 { + if route.Table >= 256 { + msg.Table = unix.RT_TABLE_UNSPEC + b := make([]byte, 4) + native.PutUint32(b, uint32(route.Table)) + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_TABLE, b)) + } else { + msg.Table = uint8(route.Table) + } + } + + if route.Priority > 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(route.Priority)) + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b)) + } + if route.Tos > 0 { + msg.Tos = uint8(route.Tos) + } + if route.Protocol > 0 { + msg.Protocol = uint8(route.Protocol) + } + if route.Type > 0 { + msg.Type = uint8(route.Type) + } + + var metrics []*nl.RtAttr + // TODO: support other rta_metric values + if route.MTU > 0 { + b := nl.Uint32Attr(uint32(route.MTU)) + metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b)) + } + if route.AdvMSS > 0 { + b := nl.Uint32Attr(uint32(route.AdvMSS)) + metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b)) + } + + if metrics != nil { + attr := nl.NewRtAttr(unix.RTA_METRICS, nil) + for _, metric := range metrics { + attr.AddChild(metric) + } + rtAttrs = append(rtAttrs, attr) + } + + msg.Flags = uint32(route.Flags) + msg.Scope = uint8(route.Scope) + msg.Family = uint8(family) + req.AddData(msg) + for _, attr := range rtAttrs { + req.AddData(attr) + } + + var ( + b = make([]byte, 4) + native = nl.NativeEndian() + ) + native.PutUint32(b, uint32(route.LinkIndex)) + + req.AddData(nl.NewRtAttr(unix.RTA_OIF, b)) + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// RouteList gets a list of routes in the system. +// Equivalent to: `ip route show`. +// The list can be filtered by link and ip family. +func RouteList(link Link, family int) ([]Route, error) { + return pkgHandle.RouteList(link, family) +} + +// RouteList gets a list of routes in the system. +// Equivalent to: `ip route show`. +// The list can be filtered by link and ip family. +func (h *Handle) RouteList(link Link, family int) ([]Route, error) { + var routeFilter *Route + if link != nil { + routeFilter = &Route{ + LinkIndex: link.Attrs().Index, + } + } + return h.RouteListFiltered(family, routeFilter, RT_FILTER_OIF) +} + +// RouteListFiltered gets a list of routes in the system filtered with specified rules. +// All rules must be defined in RouteFilter struct +func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { + return pkgHandle.RouteListFiltered(family, filter, filterMask) +} + +// RouteListFiltered gets a list of routes in the system filtered with specified rules. +// All rules must be defined in RouteFilter struct +func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { + req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP) + infmsg := nl.NewIfInfomsg(family) + req.AddData(infmsg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) + if err != nil { + return nil, err + } + + var res []Route + for _, m := range msgs { + msg := nl.DeserializeRtMsg(m) + if msg.Flags&unix.RTM_F_CLONED != 0 { + // Ignore cloned routes + continue + } + if msg.Table != unix.RT_TABLE_MAIN { + if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 { + // Ignore non-main tables + continue + } + } + route, err := deserializeRoute(m) + if err != nil { + return nil, err + } + if filter != nil { + switch { + case filterMask&RT_FILTER_TABLE != 0 && filter.Table != unix.RT_TABLE_UNSPEC && route.Table != filter.Table: + continue + case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol: + continue + case filterMask&RT_FILTER_SCOPE != 0 && route.Scope != filter.Scope: + continue + case filterMask&RT_FILTER_TYPE != 0 && route.Type != filter.Type: + continue + case filterMask&RT_FILTER_TOS != 0 && route.Tos != filter.Tos: + continue + case filterMask&RT_FILTER_OIF != 0 && route.LinkIndex != filter.LinkIndex: + continue + case filterMask&RT_FILTER_IIF != 0 && route.ILinkIndex != filter.ILinkIndex: + continue + case filterMask&RT_FILTER_GW != 0 && !route.Gw.Equal(filter.Gw): + continue + case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src): + continue + case filterMask&RT_FILTER_DST != 0: + if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) { + if !ipNetEqual(route.Dst, filter.Dst) { + continue + } + } + } + } + res = append(res, route) + } + return res, nil +} + +// deserializeRoute decodes a binary netlink message into a Route struct +func deserializeRoute(m []byte) (Route, error) { + msg := nl.DeserializeRtMsg(m) + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return Route{}, err + } + route := Route{ + Scope: Scope(msg.Scope), + Protocol: int(msg.Protocol), + Table: int(msg.Table), + Type: int(msg.Type), + Tos: int(msg.Tos), + Flags: int(msg.Flags), + } + + native := nl.NativeEndian() + var encap, encapType syscall.NetlinkRouteAttr + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.RTA_GATEWAY: + route.Gw = net.IP(attr.Value) + case unix.RTA_PREFSRC: + route.Src = net.IP(attr.Value) + case unix.RTA_DST: + if msg.Family == nl.FAMILY_MPLS { + stack := nl.DecodeMPLSStack(attr.Value) + if len(stack) == 0 || len(stack) > 1 { + return route, fmt.Errorf("invalid MPLS RTA_DST") + } + route.MPLSDst = &stack[0] + } else { + route.Dst = &net.IPNet{ + IP: attr.Value, + Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), + } + } + case unix.RTA_OIF: + route.LinkIndex = int(native.Uint32(attr.Value[0:4])) + case unix.RTA_IIF: + route.ILinkIndex = int(native.Uint32(attr.Value[0:4])) + case unix.RTA_PRIORITY: + route.Priority = int(native.Uint32(attr.Value[0:4])) + case unix.RTA_TABLE: + route.Table = int(native.Uint32(attr.Value[0:4])) + case unix.RTA_MULTIPATH: + parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) { + if len(value) < unix.SizeofRtNexthop { + return nil, nil, fmt.Errorf("lack of bytes") + } + nh := nl.DeserializeRtNexthop(value) + if len(value) < int(nh.RtNexthop.Len) { + return nil, nil, fmt.Errorf("lack of bytes") + } + info := &NexthopInfo{ + LinkIndex: int(nh.RtNexthop.Ifindex), + Hops: int(nh.RtNexthop.Hops), + Flags: int(nh.RtNexthop.Flags), + } + attrs, err := nl.ParseRouteAttr(value[unix.SizeofRtNexthop:int(nh.RtNexthop.Len)]) + if err != nil { + return nil, nil, err + } + var encap, encapType syscall.NetlinkRouteAttr + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.RTA_GATEWAY: + info.Gw = net.IP(attr.Value) + case nl.RTA_NEWDST: + var d Destination + switch msg.Family { + case nl.FAMILY_MPLS: + d = &MPLSDestination{} + } + if err := d.Decode(attr.Value); err != nil { + return nil, nil, err + } + info.NewDst = d + case nl.RTA_ENCAP_TYPE: + encapType = attr + case nl.RTA_ENCAP: + encap = attr + } + } + + if len(encap.Value) != 0 && len(encapType.Value) != 0 { + typ := int(native.Uint16(encapType.Value[0:2])) + var e Encap + switch typ { + case nl.LWTUNNEL_ENCAP_MPLS: + e = &MPLSEncap{} + if err := e.Decode(encap.Value); err != nil { + return nil, nil, err + } + } + info.Encap = e + } + + return info, value[int(nh.RtNexthop.Len):], nil + } + rest := attr.Value + for len(rest) > 0 { + info, buf, err := parseRtNexthop(rest) + if err != nil { + return route, err + } + route.MultiPath = append(route.MultiPath, info) + rest = buf + } + case nl.RTA_NEWDST: + var d Destination + switch msg.Family { + case nl.FAMILY_MPLS: + d = &MPLSDestination{} + } + if err := d.Decode(attr.Value); err != nil { + return route, err + } + route.NewDst = d + case nl.RTA_ENCAP_TYPE: + encapType = attr + case nl.RTA_ENCAP: + encap = attr + case unix.RTA_METRICS: + metrics, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return route, err + } + for _, metric := range metrics { + switch metric.Attr.Type { + case unix.RTAX_MTU: + route.MTU = int(native.Uint32(metric.Value[0:4])) + case unix.RTAX_ADVMSS: + route.AdvMSS = int(native.Uint32(metric.Value[0:4])) + } + } + } + } + + if len(encap.Value) != 0 && len(encapType.Value) != 0 { + typ := int(native.Uint16(encapType.Value[0:2])) + var e Encap + switch typ { + case nl.LWTUNNEL_ENCAP_MPLS: + e = &MPLSEncap{} + if err := e.Decode(encap.Value); err != nil { + return route, err + } + case nl.LWTUNNEL_ENCAP_SEG6: + e = &SEG6Encap{} + if err := e.Decode(encap.Value); err != nil { + return route, err + } + } + route.Encap = e + } + + return route, nil +} + +// RouteGet gets a route to a specific destination from the host system. +// Equivalent to: 'ip route get'. +func RouteGet(destination net.IP) ([]Route, error) { + return pkgHandle.RouteGet(destination) +} + +// RouteGet gets a route to a specific destination from the host system. +// Equivalent to: 'ip route get'. +func (h *Handle) RouteGet(destination net.IP) ([]Route, error) { + req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST) + family := nl.GetIPFamily(destination) + var destinationData []byte + var bitlen uint8 + if family == FAMILY_V4 { + destinationData = destination.To4() + bitlen = 32 + } else { + destinationData = destination.To16() + bitlen = 128 + } + msg := &nl.RtMsg{} + msg.Family = uint8(family) + msg.Dst_len = bitlen + req.AddData(msg) + + rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData) + req.AddData(rtaDst) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) + if err != nil { + return nil, err + } + + var res []Route + for _, m := range msgs { + route, err := deserializeRoute(m) + if err != nil { + return nil, err + } + res = append(res, route) + } + return res, nil + +} + +// RouteSubscribe takes a chan down which notifications will be sent +// when routes are added or deleted. Close the 'done' chan to stop subscription. +func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error { + return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) +} + +// RouteSubscribeAt works like RouteSubscribe plus it allows the caller +// to choose the network namespace in which to subscribe (ns). +func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error { + return routeSubscribeAt(ns, netns.None(), ch, done, nil, false) +} + +// RouteSubscribeOptions contains a set of options to use with +// RouteSubscribeWithOptions. +type RouteSubscribeOptions struct { + Namespace *netns.NsHandle + ErrorCallback func(error) + ListExisting bool +} + +// RouteSubscribeWithOptions work like RouteSubscribe but enable to +// provide additional options to modify the behavior. Currently, the +// namespace can be provided as well as an error callback. +func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, options RouteSubscribeOptions) error { + if options.Namespace == nil { + none := netns.None() + options.Namespace = &none + } + return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) +} + +func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { + s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_ROUTE, unix.RTNLGRP_IPV6_ROUTE) + if err != nil { + return err + } + if done != nil { + go func() { + <-done + s.Close() + }() + } + if listExisting { + req := pkgHandle.newNetlinkRequest(unix.RTM_GETROUTE, + unix.NLM_F_DUMP) + infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) + req.AddData(infmsg) + if err := s.Send(req); err != nil { + return err + } + } + go func() { + defer close(ch) + for { + msgs, err := s.Receive() + if err != nil { + if cberr != nil { + cberr(err) + } + return + } + for _, m := range msgs { + if m.Header.Type == unix.NLMSG_DONE { + continue + } + if m.Header.Type == unix.NLMSG_ERROR { + native := nl.NativeEndian() + error := int32(native.Uint32(m.Data[0:4])) + if error == 0 { + continue + } + if cberr != nil { + cberr(syscall.Errno(-error)) + } + return + } + route, err := deserializeRoute(m.Data) + if err != nil { + if cberr != nil { + cberr(err) + } + return + } + ch <- RouteUpdate{Type: m.Header.Type, Route: route} + } + } + }() + + return nil +} diff --git a/vendor/github.com/vishvananda/netlink/route_unspecified.go b/vendor/github.com/vishvananda/netlink/route_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..2701862b4b96186ac6762d920ecb1907610bd4cc --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/route_unspecified.go @@ -0,0 +1,11 @@ +// +build !linux + +package netlink + +func (r *Route) ListFlags() []string { + return []string{} +} + +func (n *NexthopInfo) ListFlags() []string { + return []string{} +} diff --git a/vendor/github.com/vishvananda/netlink/rule.go b/vendor/github.com/vishvananda/netlink/rule.go new file mode 100644 index 0000000000000000000000000000000000000000..7fc8ae5df15e903fdd847204d07be6d572a6d2fc --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/rule.go @@ -0,0 +1,42 @@ +package netlink + +import ( + "fmt" + "net" +) + +// Rule represents a netlink rule. +type Rule struct { + Priority int + Family int + Table int + Mark int + Mask int + TunID uint + Goto int + Src *net.IPNet + Dst *net.IPNet + Flow int + IifName string + OifName string + SuppressIfgroup int + SuppressPrefixlen int + Invert bool +} + +func (r Rule) String() string { + return fmt.Sprintf("ip rule %d: from %s table %d", r.Priority, r.Src, r.Table) +} + +// NewRule return empty rules. +func NewRule() *Rule { + return &Rule{ + SuppressIfgroup: -1, + SuppressPrefixlen: -1, + Priority: -1, + Mark: -1, + Mask: -1, + Goto: -1, + Flow: -1, + } +} diff --git a/vendor/github.com/vishvananda/netlink/rule_linux.go b/vendor/github.com/vishvananda/netlink/rule_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..6238ae45864280eac07c95c50058f852cd50ca12 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/rule_linux.go @@ -0,0 +1,234 @@ +package netlink + +import ( + "fmt" + "net" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +const FibRuleInvert = 0x2 + +// RuleAdd adds a rule to the system. +// Equivalent to: ip rule add +func RuleAdd(rule *Rule) error { + return pkgHandle.RuleAdd(rule) +} + +// RuleAdd adds a rule to the system. +// Equivalent to: ip rule add +func (h *Handle) RuleAdd(rule *Rule) error { + req := h.newNetlinkRequest(unix.RTM_NEWRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + return ruleHandle(rule, req) +} + +// RuleDel deletes a rule from the system. +// Equivalent to: ip rule del +func RuleDel(rule *Rule) error { + return pkgHandle.RuleDel(rule) +} + +// RuleDel deletes a rule from the system. +// Equivalent to: ip rule del +func (h *Handle) RuleDel(rule *Rule) error { + req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK) + return ruleHandle(rule, req) +} + +func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { + msg := nl.NewRtMsg() + msg.Family = unix.AF_INET + msg.Protocol = unix.RTPROT_BOOT + msg.Scope = unix.RT_SCOPE_UNIVERSE + msg.Table = unix.RT_TABLE_UNSPEC + msg.Type = unix.RTN_UNSPEC + if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 { + msg.Type = unix.RTN_UNICAST + } + if rule.Invert { + msg.Flags |= FibRuleInvert + } + if rule.Family != 0 { + msg.Family = uint8(rule.Family) + } + if rule.Table >= 0 && rule.Table < 256 { + msg.Table = uint8(rule.Table) + } + + var dstFamily uint8 + var rtAttrs []*nl.RtAttr + if rule.Dst != nil && rule.Dst.IP != nil { + dstLen, _ := rule.Dst.Mask.Size() + msg.Dst_len = uint8(dstLen) + msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP)) + dstFamily = msg.Family + var dstData []byte + if msg.Family == unix.AF_INET { + dstData = rule.Dst.IP.To4() + } else { + dstData = rule.Dst.IP.To16() + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) + } + + if rule.Src != nil && rule.Src.IP != nil { + msg.Family = uint8(nl.GetIPFamily(rule.Src.IP)) + if dstFamily != 0 && dstFamily != msg.Family { + return fmt.Errorf("source and destination ip are not the same IP family") + } + srcLen, _ := rule.Src.Mask.Size() + msg.Src_len = uint8(srcLen) + var srcData []byte + if msg.Family == unix.AF_INET { + srcData = rule.Src.IP.To4() + } else { + srcData = rule.Src.IP.To16() + } + rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData)) + } + + req.AddData(msg) + for i := range rtAttrs { + req.AddData(rtAttrs[i]) + } + + native := nl.NativeEndian() + + if rule.Priority >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Priority)) + req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b)) + } + if rule.Mark >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Mark)) + req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b)) + } + if rule.Mask >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Mask)) + req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b)) + } + if rule.Flow >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Flow)) + req.AddData(nl.NewRtAttr(nl.FRA_FLOW, b)) + } + if rule.TunID > 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.TunID)) + req.AddData(nl.NewRtAttr(nl.FRA_TUN_ID, b)) + } + if rule.Table >= 256 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Table)) + req.AddData(nl.NewRtAttr(nl.FRA_TABLE, b)) + } + if msg.Table > 0 { + if rule.SuppressPrefixlen >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.SuppressPrefixlen)) + req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_PREFIXLEN, b)) + } + if rule.SuppressIfgroup >= 0 { + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.SuppressIfgroup)) + req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_IFGROUP, b)) + } + } + if rule.IifName != "" { + req.AddData(nl.NewRtAttr(nl.FRA_IIFNAME, []byte(rule.IifName))) + } + if rule.OifName != "" { + req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName))) + } + if rule.Goto >= 0 { + msg.Type = nl.FR_ACT_NOP + b := make([]byte, 4) + native.PutUint32(b, uint32(rule.Goto)) + req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b)) + } + + _, err := req.Execute(unix.NETLINK_ROUTE, 0) + return err +} + +// RuleList lists rules in the system. +// Equivalent to: ip rule list +func RuleList(family int) ([]Rule, error) { + return pkgHandle.RuleList(family) +} + +// RuleList lists rules in the system. +// Equivalent to: ip rule list +func (h *Handle) RuleList(family int) ([]Rule, error) { + req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST) + msg := nl.NewIfInfomsg(family) + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE) + if err != nil { + return nil, err + } + + native := nl.NativeEndian() + var res = make([]Rule, 0) + for i := range msgs { + msg := nl.DeserializeRtMsg(msgs[i]) + attrs, err := nl.ParseRouteAttr(msgs[i][msg.Len():]) + if err != nil { + return nil, err + } + + rule := NewRule() + + rule.Invert = msg.Flags&FibRuleInvert > 0 + + for j := range attrs { + switch attrs[j].Attr.Type { + case unix.RTA_TABLE: + rule.Table = int(native.Uint32(attrs[j].Value[0:4])) + case nl.FRA_SRC: + rule.Src = &net.IPNet{ + IP: attrs[j].Value, + Mask: net.CIDRMask(int(msg.Src_len), 8*len(attrs[j].Value)), + } + case nl.FRA_DST: + rule.Dst = &net.IPNet{ + IP: attrs[j].Value, + Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attrs[j].Value)), + } + case nl.FRA_FWMARK: + rule.Mark = int(native.Uint32(attrs[j].Value[0:4])) + case nl.FRA_FWMASK: + rule.Mask = int(native.Uint32(attrs[j].Value[0:4])) + case nl.FRA_TUN_ID: + rule.TunID = uint(native.Uint64(attrs[j].Value[0:4])) + case nl.FRA_IIFNAME: + rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) + case nl.FRA_OIFNAME: + rule.OifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) + case nl.FRA_SUPPRESS_PREFIXLEN: + i := native.Uint32(attrs[j].Value[0:4]) + if i != 0xffffffff { + rule.SuppressPrefixlen = int(i) + } + case nl.FRA_SUPPRESS_IFGROUP: + i := native.Uint32(attrs[j].Value[0:4]) + if i != 0xffffffff { + rule.SuppressIfgroup = int(i) + } + case nl.FRA_FLOW: + rule.Flow = int(native.Uint32(attrs[j].Value[0:4])) + case nl.FRA_GOTO: + rule.Goto = int(native.Uint32(attrs[j].Value[0:4])) + case nl.FRA_PRIORITY: + rule.Priority = int(native.Uint32(attrs[j].Value[0:4])) + } + } + res = append(res, *rule) + } + + return res, nil +} diff --git a/vendor/github.com/vishvananda/netlink/socket.go b/vendor/github.com/vishvananda/netlink/socket.go new file mode 100644 index 0000000000000000000000000000000000000000..41aa726245bc086cd4942c928038f8f9e682ddc3 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/socket.go @@ -0,0 +1,27 @@ +package netlink + +import "net" + +// SocketID identifies a single socket. +type SocketID struct { + SourcePort uint16 + DestinationPort uint16 + Source net.IP + Destination net.IP + Interface uint32 + Cookie [2]uint32 +} + +// Socket represents a netlink socket. +type Socket struct { + Family uint8 + State uint8 + Timer uint8 + Retrans uint8 + ID SocketID + Expires uint32 + RQueue uint32 + WQueue uint32 + UID uint32 + INode uint32 +} diff --git a/vendor/github.com/vishvananda/netlink/socket_linux.go b/vendor/github.com/vishvananda/netlink/socket_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..99e9fb4d8979f1efc30af4bad1c508a31628a12d --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/socket_linux.go @@ -0,0 +1,159 @@ +package netlink + +import ( + "errors" + "fmt" + "net" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +const ( + sizeofSocketID = 0x30 + sizeofSocketRequest = sizeofSocketID + 0x8 + sizeofSocket = sizeofSocketID + 0x18 +) + +type socketRequest struct { + Family uint8 + Protocol uint8 + Ext uint8 + pad uint8 + States uint32 + ID SocketID +} + +type writeBuffer struct { + Bytes []byte + pos int +} + +func (b *writeBuffer) Write(c byte) { + b.Bytes[b.pos] = c + b.pos++ +} + +func (b *writeBuffer) Next(n int) []byte { + s := b.Bytes[b.pos : b.pos+n] + b.pos += n + return s +} + +func (r *socketRequest) Serialize() []byte { + b := writeBuffer{Bytes: make([]byte, sizeofSocketRequest)} + b.Write(r.Family) + b.Write(r.Protocol) + b.Write(r.Ext) + b.Write(r.pad) + native.PutUint32(b.Next(4), r.States) + networkOrder.PutUint16(b.Next(2), r.ID.SourcePort) + networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort) + copy(b.Next(4), r.ID.Source.To4()) + b.Next(12) + copy(b.Next(4), r.ID.Destination.To4()) + b.Next(12) + native.PutUint32(b.Next(4), r.ID.Interface) + native.PutUint32(b.Next(4), r.ID.Cookie[0]) + native.PutUint32(b.Next(4), r.ID.Cookie[1]) + return b.Bytes +} + +func (r *socketRequest) Len() int { return sizeofSocketRequest } + +type readBuffer struct { + Bytes []byte + pos int +} + +func (b *readBuffer) Read() byte { + c := b.Bytes[b.pos] + b.pos++ + return c +} + +func (b *readBuffer) Next(n int) []byte { + s := b.Bytes[b.pos : b.pos+n] + b.pos += n + return s +} + +func (s *Socket) deserialize(b []byte) error { + if len(b) < sizeofSocket { + return fmt.Errorf("socket data short read (%d); want %d", len(b), sizeofSocket) + } + rb := readBuffer{Bytes: b} + s.Family = rb.Read() + s.State = rb.Read() + s.Timer = rb.Read() + s.Retrans = rb.Read() + s.ID.SourcePort = networkOrder.Uint16(rb.Next(2)) + s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2)) + s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read()) + rb.Next(12) + s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read()) + rb.Next(12) + s.ID.Interface = native.Uint32(rb.Next(4)) + s.ID.Cookie[0] = native.Uint32(rb.Next(4)) + s.ID.Cookie[1] = native.Uint32(rb.Next(4)) + s.Expires = native.Uint32(rb.Next(4)) + s.RQueue = native.Uint32(rb.Next(4)) + s.WQueue = native.Uint32(rb.Next(4)) + s.UID = native.Uint32(rb.Next(4)) + s.INode = native.Uint32(rb.Next(4)) + return nil +} + +// SocketGet returns the Socket identified by its local and remote addresses. +func SocketGet(local, remote net.Addr) (*Socket, error) { + localTCP, ok := local.(*net.TCPAddr) + if !ok { + return nil, ErrNotImplemented + } + remoteTCP, ok := remote.(*net.TCPAddr) + if !ok { + return nil, ErrNotImplemented + } + localIP := localTCP.IP.To4() + if localIP == nil { + return nil, ErrNotImplemented + } + remoteIP := remoteTCP.IP.To4() + if remoteIP == nil { + return nil, ErrNotImplemented + } + + s, err := nl.Subscribe(unix.NETLINK_INET_DIAG) + if err != nil { + return nil, err + } + defer s.Close() + req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0) + req.AddData(&socketRequest{ + Family: unix.AF_INET, + Protocol: unix.IPPROTO_TCP, + ID: SocketID{ + SourcePort: uint16(localTCP.Port), + DestinationPort: uint16(remoteTCP.Port), + Source: localIP, + Destination: remoteIP, + Cookie: [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE}, + }, + }) + s.Send(req) + msgs, err := s.Receive() + if err != nil { + return nil, err + } + if len(msgs) == 0 { + return nil, errors.New("no message nor error from netlink") + } + if len(msgs) > 2 { + return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs)) + } + sock := &Socket{} + if err := sock.deserialize(msgs[0].Data); err != nil { + return nil, err + } + return sock, nil +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm.go b/vendor/github.com/vishvananda/netlink/xfrm.go new file mode 100644 index 0000000000000000000000000000000000000000..02b41842e1022275aa8f0a10ad94f809210f719e --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm.go @@ -0,0 +1,75 @@ +package netlink + +import ( + "fmt" + + "golang.org/x/sys/unix" +) + +// Proto is an enum representing an ipsec protocol. +type Proto uint8 + +const ( + XFRM_PROTO_ROUTE2 Proto = unix.IPPROTO_ROUTING + XFRM_PROTO_ESP Proto = unix.IPPROTO_ESP + XFRM_PROTO_AH Proto = unix.IPPROTO_AH + XFRM_PROTO_HAO Proto = unix.IPPROTO_DSTOPTS + XFRM_PROTO_COMP Proto = 0x6c // NOTE not defined on darwin + XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW +) + +func (p Proto) String() string { + switch p { + case XFRM_PROTO_ROUTE2: + return "route2" + case XFRM_PROTO_ESP: + return "esp" + case XFRM_PROTO_AH: + return "ah" + case XFRM_PROTO_HAO: + return "hao" + case XFRM_PROTO_COMP: + return "comp" + case XFRM_PROTO_IPSEC_ANY: + return "ipsec-any" + } + return fmt.Sprintf("%d", p) +} + +// Mode is an enum representing an ipsec transport. +type Mode uint8 + +const ( + XFRM_MODE_TRANSPORT Mode = iota + XFRM_MODE_TUNNEL + XFRM_MODE_ROUTEOPTIMIZATION + XFRM_MODE_IN_TRIGGER + XFRM_MODE_BEET + XFRM_MODE_MAX +) + +func (m Mode) String() string { + switch m { + case XFRM_MODE_TRANSPORT: + return "transport" + case XFRM_MODE_TUNNEL: + return "tunnel" + case XFRM_MODE_ROUTEOPTIMIZATION: + return "ro" + case XFRM_MODE_IN_TRIGGER: + return "in_trigger" + case XFRM_MODE_BEET: + return "beet" + } + return fmt.Sprintf("%d", m) +} + +// XfrmMark represents the mark associated to the state or policy +type XfrmMark struct { + Value uint32 + Mask uint32 +} + +func (m *XfrmMark) String() string { + return fmt.Sprintf("(0x%x,0x%x)", m.Value, m.Mask) +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..efe72ddf29cebcccded5c2aca849ea557bf78358 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go @@ -0,0 +1,97 @@ +package netlink + +import ( + "fmt" + + "github.com/vishvananda/netlink/nl" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" +) + +type XfrmMsg interface { + Type() nl.XfrmMsgType +} + +type XfrmMsgExpire struct { + XfrmState *XfrmState + Hard bool +} + +func (ue *XfrmMsgExpire) Type() nl.XfrmMsgType { + return nl.XFRM_MSG_EXPIRE +} + +func parseXfrmMsgExpire(b []byte) *XfrmMsgExpire { + var e XfrmMsgExpire + + msg := nl.DeserializeXfrmUserExpire(b) + e.XfrmState = xfrmStateFromXfrmUsersaInfo(&msg.XfrmUsersaInfo) + e.Hard = msg.Hard == 1 + + return &e +} + +func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error, + types ...nl.XfrmMsgType) error { + + groups, err := xfrmMcastGroups(types) + if err != nil { + return nil + } + s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_XFRM, groups...) + if err != nil { + return err + } + + if done != nil { + go func() { + <-done + s.Close() + }() + + } + + go func() { + defer close(ch) + for { + msgs, err := s.Receive() + if err != nil { + errorChan <- err + return + } + for _, m := range msgs { + switch m.Header.Type { + case nl.XFRM_MSG_EXPIRE: + ch <- parseXfrmMsgExpire(m.Data) + default: + errorChan <- fmt.Errorf("unsupported msg type: %x", m.Header.Type) + } + } + } + }() + + return nil +} + +func xfrmMcastGroups(types []nl.XfrmMsgType) ([]uint, error) { + groups := make([]uint, 0) + + if len(types) == 0 { + return nil, fmt.Errorf("no xfrm msg type specified") + } + + for _, t := range types { + var group uint + + switch t { + case nl.XFRM_MSG_EXPIRE: + group = nl.XFRMNLGRP_EXPIRE + default: + return nil, fmt.Errorf("unsupported group: %x", t) + } + + groups = append(groups, group) + } + + return groups, nil +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm_policy.go b/vendor/github.com/vishvananda/netlink/xfrm_policy.go new file mode 100644 index 0000000000000000000000000000000000000000..c97ec43a25309dee6a6441803f266d61cacc9277 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm_policy.go @@ -0,0 +1,74 @@ +package netlink + +import ( + "fmt" + "net" +) + +// Dir is an enum representing an ipsec template direction. +type Dir uint8 + +const ( + XFRM_DIR_IN Dir = iota + XFRM_DIR_OUT + XFRM_DIR_FWD + XFRM_SOCKET_IN + XFRM_SOCKET_OUT + XFRM_SOCKET_FWD +) + +func (d Dir) String() string { + switch d { + case XFRM_DIR_IN: + return "dir in" + case XFRM_DIR_OUT: + return "dir out" + case XFRM_DIR_FWD: + return "dir fwd" + case XFRM_SOCKET_IN: + return "socket in" + case XFRM_SOCKET_OUT: + return "socket out" + case XFRM_SOCKET_FWD: + return "socket fwd" + } + return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN) +} + +// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec +// policy. These rules are matched with XfrmState to determine encryption +// and authentication algorithms. +type XfrmPolicyTmpl struct { + Dst net.IP + Src net.IP + Proto Proto + Mode Mode + Spi int + Reqid int +} + +func (t XfrmPolicyTmpl) String() string { + return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Spi: 0x%x, Reqid: 0x%x}", + t.Dst, t.Src, t.Proto, t.Mode, t.Spi, t.Reqid) +} + +// XfrmPolicy represents an ipsec policy. It represents the overlay network +// and has a list of XfrmPolicyTmpls representing the base addresses of +// the policy. +type XfrmPolicy struct { + Dst *net.IPNet + Src *net.IPNet + Proto Proto + DstPort int + SrcPort int + Dir Dir + Priority int + Index int + Mark *XfrmMark + Tmpls []XfrmPolicyTmpl +} + +func (p XfrmPolicy) String() string { + return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Mark: %s, Tmpls: %s}", + p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Mark, p.Tmpls) +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..fde0c2ca5ad0e8f5e6872da273aa0a7c6ac4207c --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go @@ -0,0 +1,256 @@ +package netlink + +import ( + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) { + sel.Family = uint16(nl.FAMILY_V4) + if policy.Dst != nil { + sel.Family = uint16(nl.GetIPFamily(policy.Dst.IP)) + sel.Daddr.FromIP(policy.Dst.IP) + prefixlenD, _ := policy.Dst.Mask.Size() + sel.PrefixlenD = uint8(prefixlenD) + } + if policy.Src != nil { + sel.Saddr.FromIP(policy.Src.IP) + prefixlenS, _ := policy.Src.Mask.Size() + sel.PrefixlenS = uint8(prefixlenS) + } + sel.Proto = uint8(policy.Proto) + sel.Dport = nl.Swap16(uint16(policy.DstPort)) + sel.Sport = nl.Swap16(uint16(policy.SrcPort)) + if sel.Dport != 0 { + sel.DportMask = ^uint16(0) + } + if sel.Sport != 0 { + sel.SportMask = ^uint16(0) + } +} + +// XfrmPolicyAdd will add an xfrm policy to the system. +// Equivalent to: `ip xfrm policy add $policy` +func XfrmPolicyAdd(policy *XfrmPolicy) error { + return pkgHandle.XfrmPolicyAdd(policy) +} + +// XfrmPolicyAdd will add an xfrm policy to the system. +// Equivalent to: `ip xfrm policy add $policy` +func (h *Handle) XfrmPolicyAdd(policy *XfrmPolicy) error { + return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_NEWPOLICY) +} + +// XfrmPolicyUpdate will update an xfrm policy to the system. +// Equivalent to: `ip xfrm policy update $policy` +func XfrmPolicyUpdate(policy *XfrmPolicy) error { + return pkgHandle.XfrmPolicyUpdate(policy) +} + +// XfrmPolicyUpdate will update an xfrm policy to the system. +// Equivalent to: `ip xfrm policy update $policy` +func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error { + return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_UPDPOLICY) +} + +func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error { + req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + + msg := &nl.XfrmUserpolicyInfo{} + selFromPolicy(&msg.Sel, policy) + msg.Priority = uint32(policy.Priority) + msg.Index = uint32(policy.Index) + msg.Dir = uint8(policy.Dir) + msg.Lft.SoftByteLimit = nl.XFRM_INF + msg.Lft.HardByteLimit = nl.XFRM_INF + msg.Lft.SoftPacketLimit = nl.XFRM_INF + msg.Lft.HardPacketLimit = nl.XFRM_INF + req.AddData(msg) + + tmplData := make([]byte, nl.SizeofXfrmUserTmpl*len(policy.Tmpls)) + for i, tmpl := range policy.Tmpls { + start := i * nl.SizeofXfrmUserTmpl + userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl]) + userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst) + userTmpl.Saddr.FromIP(tmpl.Src) + userTmpl.XfrmId.Proto = uint8(tmpl.Proto) + userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi)) + userTmpl.Mode = uint8(tmpl.Mode) + userTmpl.Reqid = uint32(tmpl.Reqid) + userTmpl.Aalgos = ^uint32(0) + userTmpl.Ealgos = ^uint32(0) + userTmpl.Calgos = ^uint32(0) + } + if len(tmplData) > 0 { + tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData) + req.AddData(tmpls) + } + if policy.Mark != nil { + out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark)) + req.AddData(out) + } + + _, err := req.Execute(unix.NETLINK_XFRM, 0) + return err +} + +// XfrmPolicyDel will delete an xfrm policy from the system. Note that +// the Tmpls are ignored when matching the policy to delete. +// Equivalent to: `ip xfrm policy del $policy` +func XfrmPolicyDel(policy *XfrmPolicy) error { + return pkgHandle.XfrmPolicyDel(policy) +} + +// XfrmPolicyDel will delete an xfrm policy from the system. Note that +// the Tmpls are ignored when matching the policy to delete. +// Equivalent to: `ip xfrm policy del $policy` +func (h *Handle) XfrmPolicyDel(policy *XfrmPolicy) error { + _, err := h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_DELPOLICY) + return err +} + +// XfrmPolicyList gets a list of xfrm policies in the system. +// Equivalent to: `ip xfrm policy show`. +// The list can be filtered by ip family. +func XfrmPolicyList(family int) ([]XfrmPolicy, error) { + return pkgHandle.XfrmPolicyList(family) +} + +// XfrmPolicyList gets a list of xfrm policies in the system. +// Equivalent to: `ip xfrm policy show`. +// The list can be filtered by ip family. +func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) { + req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP) + + msg := nl.NewIfInfomsg(family) + req.AddData(msg) + + msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY) + if err != nil { + return nil, err + } + + var res []XfrmPolicy + for _, m := range msgs { + if policy, err := parseXfrmPolicy(m, family); err == nil { + res = append(res, *policy) + } else if err == familyError { + continue + } else { + return nil, err + } + } + return res, nil +} + +// XfrmPolicyGet gets a the policy described by the index or selector, if found. +// Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`. +func XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) { + return pkgHandle.XfrmPolicyGet(policy) +} + +// XfrmPolicyGet gets a the policy described by the index or selector, if found. +// Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`. +func (h *Handle) XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) { + return h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_GETPOLICY) +} + +// XfrmPolicyFlush will flush the policies on the system. +// Equivalent to: `ip xfrm policy flush` +func XfrmPolicyFlush() error { + return pkgHandle.XfrmPolicyFlush() +} + +// XfrmPolicyFlush will flush the policies on the system. +// Equivalent to: `ip xfrm policy flush` +func (h *Handle) XfrmPolicyFlush() error { + req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK) + _, err := req.Execute(unix.NETLINK_XFRM, 0) + return err +} + +func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) { + req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) + + msg := &nl.XfrmUserpolicyId{} + selFromPolicy(&msg.Sel, policy) + msg.Index = uint32(policy.Index) + msg.Dir = uint8(policy.Dir) + req.AddData(msg) + + if policy.Mark != nil { + out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark)) + req.AddData(out) + } + + resType := nl.XFRM_MSG_NEWPOLICY + if nlProto == nl.XFRM_MSG_DELPOLICY { + resType = 0 + } + + msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) + if err != nil { + return nil, err + } + + if nlProto == nl.XFRM_MSG_DELPOLICY { + return nil, err + } + + p, err := parseXfrmPolicy(msgs[0], FAMILY_ALL) + if err != nil { + return nil, err + } + + return p, nil +} + +func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) { + msg := nl.DeserializeXfrmUserpolicyInfo(m) + + // This is mainly for the policy dump + if family != FAMILY_ALL && family != int(msg.Sel.Family) { + return nil, familyError + } + + var policy XfrmPolicy + + policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD) + policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS) + policy.Proto = Proto(msg.Sel.Proto) + policy.DstPort = int(nl.Swap16(msg.Sel.Dport)) + policy.SrcPort = int(nl.Swap16(msg.Sel.Sport)) + policy.Priority = int(msg.Priority) + policy.Index = int(msg.Index) + policy.Dir = Dir(msg.Dir) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.XFRMA_TMPL: + max := len(attr.Value) + for i := 0; i < max; i += nl.SizeofXfrmUserTmpl { + var resTmpl XfrmPolicyTmpl + tmpl := nl.DeserializeXfrmUserTmpl(attr.Value[i : i+nl.SizeofXfrmUserTmpl]) + resTmpl.Dst = tmpl.XfrmId.Daddr.ToIP() + resTmpl.Src = tmpl.Saddr.ToIP() + resTmpl.Proto = Proto(tmpl.XfrmId.Proto) + resTmpl.Mode = Mode(tmpl.Mode) + resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi)) + resTmpl.Reqid = int(tmpl.Reqid) + policy.Tmpls = append(policy.Tmpls, resTmpl) + } + case nl.XFRMA_MARK: + mark := nl.DeserializeXfrmMark(attr.Value[:]) + policy.Mark = new(XfrmMark) + policy.Mark.Value = mark.Value + policy.Mark.Mask = mark.Mask + } + } + + return &policy, nil +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm_state.go b/vendor/github.com/vishvananda/netlink/xfrm_state.go new file mode 100644 index 0000000000000000000000000000000000000000..d14740dc55b362544de5ff4d145b5448e231bfee --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm_state.go @@ -0,0 +1,129 @@ +package netlink + +import ( + "fmt" + "net" + "time" +) + +// XfrmStateAlgo represents the algorithm to use for the ipsec encryption. +type XfrmStateAlgo struct { + Name string + Key []byte + TruncateLen int // Auth only + ICVLen int // AEAD only +} + +func (a XfrmStateAlgo) String() string { + base := fmt.Sprintf("{Name: %s, Key: 0x%x", a.Name, a.Key) + if a.TruncateLen != 0 { + base = fmt.Sprintf("%s, Truncate length: %d", base, a.TruncateLen) + } + if a.ICVLen != 0 { + base = fmt.Sprintf("%s, ICV length: %d", base, a.ICVLen) + } + return fmt.Sprintf("%s}", base) +} + +// EncapType is an enum representing the optional packet encapsulation. +type EncapType uint8 + +const ( + XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1 + XFRM_ENCAP_ESPINUDP +) + +func (e EncapType) String() string { + switch e { + case XFRM_ENCAP_ESPINUDP_NONIKE: + return "espinudp-non-ike" + case XFRM_ENCAP_ESPINUDP: + return "espinudp" + } + return "unknown" +} + +// XfrmStateEncap represents the encapsulation to use for the ipsec encryption. +type XfrmStateEncap struct { + Type EncapType + SrcPort int + DstPort int + OriginalAddress net.IP +} + +func (e XfrmStateEncap) String() string { + return fmt.Sprintf("{Type: %s, Srcport: %d, DstPort: %d, OriginalAddress: %v}", + e.Type, e.SrcPort, e.DstPort, e.OriginalAddress) +} + +// XfrmStateLimits represents the configured limits for the state. +type XfrmStateLimits struct { + ByteSoft uint64 + ByteHard uint64 + PacketSoft uint64 + PacketHard uint64 + TimeSoft uint64 + TimeHard uint64 + TimeUseSoft uint64 + TimeUseHard uint64 +} + +// XfrmStateStats represents the current number of bytes/packets +// processed by this State, the State's installation and first use +// time and the replay window counters. +type XfrmStateStats struct { + ReplayWindow uint32 + Replay uint32 + Failed uint32 + Bytes uint64 + Packets uint64 + AddTime uint64 + UseTime uint64 +} + +// XfrmState represents the state of an ipsec policy. It optionally +// contains an XfrmStateAlgo for encryption and one for authentication. +type XfrmState struct { + Dst net.IP + Src net.IP + Proto Proto + Mode Mode + Spi int + Reqid int + ReplayWindow int + Limits XfrmStateLimits + Statistics XfrmStateStats + Mark *XfrmMark + Auth *XfrmStateAlgo + Crypt *XfrmStateAlgo + Aead *XfrmStateAlgo + Encap *XfrmStateEncap + ESN bool +} + +func (sa XfrmState) String() string { + return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t", + sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN) +} +func (sa XfrmState) Print(stats bool) string { + if !stats { + return sa.String() + } + at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate) + ut := "-" + if sa.Statistics.UseTime > 0 { + ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate) + } + return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+ + "AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d", + sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard), + sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut, + sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed) +} + +func printLimit(lmt uint64) string { + if lmt == ^uint64(0) { + return "(INF)" + } + return fmt.Sprintf("%d", lmt) +} diff --git a/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..5dfdb33e4499b92240bbd6de3854797cc720f473 --- /dev/null +++ b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go @@ -0,0 +1,457 @@ +package netlink + +import ( + "fmt" + "unsafe" + + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" +) + +func writeStateAlgo(a *XfrmStateAlgo) []byte { + algo := nl.XfrmAlgo{ + AlgKeyLen: uint32(len(a.Key) * 8), + AlgKey: a.Key, + } + end := len(a.Name) + if end > 64 { + end = 64 + } + copy(algo.AlgName[:end], a.Name) + return algo.Serialize() +} + +func writeStateAlgoAuth(a *XfrmStateAlgo) []byte { + algo := nl.XfrmAlgoAuth{ + AlgKeyLen: uint32(len(a.Key) * 8), + AlgTruncLen: uint32(a.TruncateLen), + AlgKey: a.Key, + } + end := len(a.Name) + if end > 64 { + end = 64 + } + copy(algo.AlgName[:end], a.Name) + return algo.Serialize() +} + +func writeStateAlgoAead(a *XfrmStateAlgo) []byte { + algo := nl.XfrmAlgoAEAD{ + AlgKeyLen: uint32(len(a.Key) * 8), + AlgICVLen: uint32(a.ICVLen), + AlgKey: a.Key, + } + end := len(a.Name) + if end > 64 { + end = 64 + } + copy(algo.AlgName[:end], a.Name) + return algo.Serialize() +} + +func writeMark(m *XfrmMark) []byte { + mark := &nl.XfrmMark{ + Value: m.Value, + Mask: m.Mask, + } + if mark.Mask == 0 { + mark.Mask = ^uint32(0) + } + return mark.Serialize() +} + +func writeReplayEsn(replayWindow int) []byte { + replayEsn := &nl.XfrmReplayStateEsn{ + OSeq: 0, + Seq: 0, + OSeqHi: 0, + SeqHi: 0, + ReplayWindow: uint32(replayWindow), + } + + // Linux stores the bitmap to identify the already received sequence packets in blocks of uint32 elements. + // Therefore bitmap length is the minimum number of uint32 elements needed. The following is a ceiling operation. + bytesPerElem := int(unsafe.Sizeof(replayEsn.BmpLen)) // Any uint32 variable is good for this + replayEsn.BmpLen = uint32((replayWindow + (bytesPerElem * 8) - 1) / (bytesPerElem * 8)) + + return replayEsn.Serialize() +} + +// XfrmStateAdd will add an xfrm state to the system. +// Equivalent to: `ip xfrm state add $state` +func XfrmStateAdd(state *XfrmState) error { + return pkgHandle.XfrmStateAdd(state) +} + +// XfrmStateAdd will add an xfrm state to the system. +// Equivalent to: `ip xfrm state add $state` +func (h *Handle) XfrmStateAdd(state *XfrmState) error { + return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA) +} + +// XfrmStateAllocSpi will allocate an xfrm state in the system. +// Equivalent to: `ip xfrm state allocspi` +func XfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) { + return pkgHandle.xfrmStateAllocSpi(state) +} + +// XfrmStateUpdate will update an xfrm state to the system. +// Equivalent to: `ip xfrm state update $state` +func XfrmStateUpdate(state *XfrmState) error { + return pkgHandle.XfrmStateUpdate(state) +} + +// XfrmStateUpdate will update an xfrm state to the system. +// Equivalent to: `ip xfrm state update $state` +func (h *Handle) XfrmStateUpdate(state *XfrmState) error { + return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_UPDSA) +} + +func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error { + + // A state with spi 0 can't be deleted so don't allow it to be set + if state.Spi == 0 { + return fmt.Errorf("Spi must be set when adding xfrm state.") + } + req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + + msg := xfrmUsersaInfoFromXfrmState(state) + + if state.ESN { + if state.ReplayWindow == 0 { + return fmt.Errorf("ESN flag set without ReplayWindow") + } + msg.Flags |= nl.XFRM_STATE_ESN + msg.ReplayWindow = 0 + } + + limitsToLft(state.Limits, &msg.Lft) + req.AddData(msg) + + if state.Auth != nil { + out := nl.NewRtAttr(nl.XFRMA_ALG_AUTH_TRUNC, writeStateAlgoAuth(state.Auth)) + req.AddData(out) + } + if state.Crypt != nil { + out := nl.NewRtAttr(nl.XFRMA_ALG_CRYPT, writeStateAlgo(state.Crypt)) + req.AddData(out) + } + if state.Aead != nil { + out := nl.NewRtAttr(nl.XFRMA_ALG_AEAD, writeStateAlgoAead(state.Aead)) + req.AddData(out) + } + if state.Encap != nil { + encapData := make([]byte, nl.SizeofXfrmEncapTmpl) + encap := nl.DeserializeXfrmEncapTmpl(encapData) + encap.EncapType = uint16(state.Encap.Type) + encap.EncapSport = nl.Swap16(uint16(state.Encap.SrcPort)) + encap.EncapDport = nl.Swap16(uint16(state.Encap.DstPort)) + encap.EncapOa.FromIP(state.Encap.OriginalAddress) + out := nl.NewRtAttr(nl.XFRMA_ENCAP, encapData) + req.AddData(out) + } + if state.Mark != nil { + out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) + req.AddData(out) + } + if state.ESN { + out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow)) + req.AddData(out) + } + + _, err := req.Execute(unix.NETLINK_XFRM, 0) + return err +} + +func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) { + req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI, + unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) + + msg := &nl.XfrmUserSpiInfo{} + msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state)) + // 1-255 is reserved by IANA for future use + msg.Min = 0x100 + msg.Max = 0xffffffff + req.AddData(msg) + + if state.Mark != nil { + out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) + req.AddData(out) + } + + msgs, err := req.Execute(unix.NETLINK_XFRM, 0) + if err != nil { + return nil, err + } + + s, err := parseXfrmState(msgs[0], FAMILY_ALL) + if err != nil { + return nil, err + } + + return s, err +} + +// XfrmStateDel will delete an xfrm state from the system. Note that +// the Algos are ignored when matching the state to delete. +// Equivalent to: `ip xfrm state del $state` +func XfrmStateDel(state *XfrmState) error { + return pkgHandle.XfrmStateDel(state) +} + +// XfrmStateDel will delete an xfrm state from the system. Note that +// the Algos are ignored when matching the state to delete. +// Equivalent to: `ip xfrm state del $state` +func (h *Handle) XfrmStateDel(state *XfrmState) error { + _, err := h.xfrmStateGetOrDelete(state, nl.XFRM_MSG_DELSA) + return err +} + +// XfrmStateList gets a list of xfrm states in the system. +// Equivalent to: `ip [-4|-6] xfrm state show`. +// The list can be filtered by ip family. +func XfrmStateList(family int) ([]XfrmState, error) { + return pkgHandle.XfrmStateList(family) +} + +// XfrmStateList gets a list of xfrm states in the system. +// Equivalent to: `ip xfrm state show`. +// The list can be filtered by ip family. +func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) { + req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP) + + msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA) + if err != nil { + return nil, err + } + + var res []XfrmState + for _, m := range msgs { + if state, err := parseXfrmState(m, family); err == nil { + res = append(res, *state) + } else if err == familyError { + continue + } else { + return nil, err + } + } + return res, nil +} + +// XfrmStateGet gets the xfrm state described by the ID, if found. +// Equivalent to: `ip xfrm state get ID [ mark MARK [ mask MASK ] ]`. +// Only the fields which constitue the SA ID must be filled in: +// ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ] +// mark is optional +func XfrmStateGet(state *XfrmState) (*XfrmState, error) { + return pkgHandle.XfrmStateGet(state) +} + +// XfrmStateGet gets the xfrm state described by the ID, if found. +// Equivalent to: `ip xfrm state get ID [ mark MARK [ mask MASK ] ]`. +// Only the fields which constitue the SA ID must be filled in: +// ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ] +// mark is optional +func (h *Handle) XfrmStateGet(state *XfrmState) (*XfrmState, error) { + return h.xfrmStateGetOrDelete(state, nl.XFRM_MSG_GETSA) +} + +func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) { + req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) + + msg := &nl.XfrmUsersaId{} + msg.Family = uint16(nl.GetIPFamily(state.Dst)) + msg.Daddr.FromIP(state.Dst) + msg.Proto = uint8(state.Proto) + msg.Spi = nl.Swap32(uint32(state.Spi)) + req.AddData(msg) + + if state.Mark != nil { + out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) + req.AddData(out) + } + if state.Src != nil { + out := nl.NewRtAttr(nl.XFRMA_SRCADDR, state.Src.To16()) + req.AddData(out) + } + + resType := nl.XFRM_MSG_NEWSA + if nlProto == nl.XFRM_MSG_DELSA { + resType = 0 + } + + msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) + if err != nil { + return nil, err + } + + if nlProto == nl.XFRM_MSG_DELSA { + return nil, nil + } + + s, err := parseXfrmState(msgs[0], FAMILY_ALL) + if err != nil { + return nil, err + } + + return s, nil +} + +var familyError = fmt.Errorf("family error") + +func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState { + var state XfrmState + + state.Dst = msg.Id.Daddr.ToIP() + state.Src = msg.Saddr.ToIP() + state.Proto = Proto(msg.Id.Proto) + state.Mode = Mode(msg.Mode) + state.Spi = int(nl.Swap32(msg.Id.Spi)) + state.Reqid = int(msg.Reqid) + state.ReplayWindow = int(msg.ReplayWindow) + lftToLimits(&msg.Lft, &state.Limits) + curToStats(&msg.Curlft, &msg.Stats, &state.Statistics) + + return &state +} + +func parseXfrmState(m []byte, family int) (*XfrmState, error) { + msg := nl.DeserializeXfrmUsersaInfo(m) + + // This is mainly for the state dump + if family != FAMILY_ALL && family != int(msg.Family) { + return nil, familyError + } + + state := xfrmStateFromXfrmUsersaInfo(msg) + + attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:]) + if err != nil { + return nil, err + } + + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.XFRMA_ALG_AUTH, nl.XFRMA_ALG_CRYPT: + var resAlgo *XfrmStateAlgo + if attr.Attr.Type == nl.XFRMA_ALG_AUTH { + if state.Auth == nil { + state.Auth = new(XfrmStateAlgo) + } + resAlgo = state.Auth + } else { + state.Crypt = new(XfrmStateAlgo) + resAlgo = state.Crypt + } + algo := nl.DeserializeXfrmAlgo(attr.Value[:]) + (*resAlgo).Name = nl.BytesToString(algo.AlgName[:]) + (*resAlgo).Key = algo.AlgKey + case nl.XFRMA_ALG_AUTH_TRUNC: + if state.Auth == nil { + state.Auth = new(XfrmStateAlgo) + } + algo := nl.DeserializeXfrmAlgoAuth(attr.Value[:]) + state.Auth.Name = nl.BytesToString(algo.AlgName[:]) + state.Auth.Key = algo.AlgKey + state.Auth.TruncateLen = int(algo.AlgTruncLen) + case nl.XFRMA_ALG_AEAD: + state.Aead = new(XfrmStateAlgo) + algo := nl.DeserializeXfrmAlgoAEAD(attr.Value[:]) + state.Aead.Name = nl.BytesToString(algo.AlgName[:]) + state.Aead.Key = algo.AlgKey + state.Aead.ICVLen = int(algo.AlgICVLen) + case nl.XFRMA_ENCAP: + encap := nl.DeserializeXfrmEncapTmpl(attr.Value[:]) + state.Encap = new(XfrmStateEncap) + state.Encap.Type = EncapType(encap.EncapType) + state.Encap.SrcPort = int(nl.Swap16(encap.EncapSport)) + state.Encap.DstPort = int(nl.Swap16(encap.EncapDport)) + state.Encap.OriginalAddress = encap.EncapOa.ToIP() + case nl.XFRMA_MARK: + mark := nl.DeserializeXfrmMark(attr.Value[:]) + state.Mark = new(XfrmMark) + state.Mark.Value = mark.Value + state.Mark.Mask = mark.Mask + } + } + + return state, nil +} + +// XfrmStateFlush will flush the xfrm state on the system. +// proto = 0 means any transformation protocols +// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]` +func XfrmStateFlush(proto Proto) error { + return pkgHandle.XfrmStateFlush(proto) +} + +// XfrmStateFlush will flush the xfrm state on the system. +// proto = 0 means any transformation protocols +// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]` +func (h *Handle) XfrmStateFlush(proto Proto) error { + req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, unix.NLM_F_ACK) + + req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)}) + + _, err := req.Execute(unix.NETLINK_XFRM, 0) + if err != nil { + return err + } + + return nil +} + +func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) { + if lmts.ByteSoft != 0 { + lft.SoftByteLimit = lmts.ByteSoft + } else { + lft.SoftByteLimit = nl.XFRM_INF + } + if lmts.ByteHard != 0 { + lft.HardByteLimit = lmts.ByteHard + } else { + lft.HardByteLimit = nl.XFRM_INF + } + if lmts.PacketSoft != 0 { + lft.SoftPacketLimit = lmts.PacketSoft + } else { + lft.SoftPacketLimit = nl.XFRM_INF + } + if lmts.PacketHard != 0 { + lft.HardPacketLimit = lmts.PacketHard + } else { + lft.HardPacketLimit = nl.XFRM_INF + } + lft.SoftAddExpiresSeconds = lmts.TimeSoft + lft.HardAddExpiresSeconds = lmts.TimeHard + lft.SoftUseExpiresSeconds = lmts.TimeUseSoft + lft.HardUseExpiresSeconds = lmts.TimeUseHard +} + +func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) { + *lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft)) +} + +func curToStats(cur *nl.XfrmLifetimeCur, wstats *nl.XfrmStats, stats *XfrmStateStats) { + stats.Bytes = cur.Bytes + stats.Packets = cur.Packets + stats.AddTime = cur.AddTime + stats.UseTime = cur.UseTime + stats.ReplayWindow = wstats.ReplayWindow + stats.Replay = wstats.Replay + stats.Failed = wstats.IntegrityFailed +} + +func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo { + msg := &nl.XfrmUsersaInfo{} + msg.Family = uint16(nl.GetIPFamily(state.Dst)) + msg.Id.Daddr.FromIP(state.Dst) + msg.Saddr.FromIP(state.Src) + msg.Id.Proto = uint8(state.Proto) + msg.Mode = uint8(state.Mode) + msg.Id.Spi = nl.Swap32(uint32(state.Spi)) + msg.Reqid = uint32(state.Reqid) + msg.ReplayWindow = uint8(state.ReplayWindow) + + return msg +} diff --git a/vendor/github.com/vishvananda/netns/BUILD.bazel b/vendor/github.com/vishvananda/netns/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..a77cd9225eb1a2a3ae469a17deacd244ecc1ee37 --- /dev/null +++ b/vendor/github.com/vishvananda/netns/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "netns.go", + "netns_linux.go", + "netns_unspecified.go", + ], + importmap = "vendor/github.com/vishvananda/netns", + importpath = "github.com/vishvananda/netns", + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/vishvananda/netns/LICENSE b/vendor/github.com/vishvananda/netns/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..9f64db8582cf97fa23685c44b5f8d8d9630da11b --- /dev/null +++ b/vendor/github.com/vishvananda/netns/LICENSE @@ -0,0 +1,192 @@ + + 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 + + Copyright 2014 Vishvananda Ishaya. + Copyright 2014 Docker, 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/vishvananda/netns/README.md b/vendor/github.com/vishvananda/netns/README.md new file mode 100644 index 0000000000000000000000000000000000000000..66a5f7258ba1e6374b7aee4ac94cddece22be91f --- /dev/null +++ b/vendor/github.com/vishvananda/netns/README.md @@ -0,0 +1,51 @@ +# netns - network namespaces in go # + +The netns package provides an ultra-simple interface for handling +network namespaces in go. Changing namespaces requires elevated +privileges, so in most cases this code needs to be run as root. + +## Local Build and Test ## + +You can use go get command: + + go get github.com/vishvananda/netns + +Testing (requires root): + + sudo -E go test github.com/vishvananda/netns + +## Example ## + +```go +package main + +import ( + "fmt" + "net" + "runtime" + "github.com/vishvananda/netns" +) + +func main() { + // Lock the OS Thread so we don't accidentally switch namespaces + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + // Save the current network namespace + origns, _ := netns.Get() + defer origns.Close() + + // Create a new network namespace + newns, _ := netns.New() + netns.Set(newns) + defer newns.Close() + + // Do something with the network namespace + ifaces, _ := net.Interfaces() + fmt.Printf("Interfaces: %v\n", ifaces) + + // Switch back to the original namespace + netns.Set(origns) +} + +``` diff --git a/vendor/github.com/vishvananda/netns/netns.go b/vendor/github.com/vishvananda/netns/netns.go new file mode 100644 index 0000000000000000000000000000000000000000..dd2f21570a482806df2af9505356d11b2cf743b0 --- /dev/null +++ b/vendor/github.com/vishvananda/netns/netns.go @@ -0,0 +1,80 @@ +// Package netns allows ultra-simple network namespace handling. NsHandles +// can be retrieved and set. Note that the current namespace is thread +// local so actions that set and reset namespaces should use LockOSThread +// to make sure the namespace doesn't change due to a goroutine switch. +// It is best to close NsHandles when you are done with them. This can be +// accomplished via a `defer ns.Close()` on the handle. Changing namespaces +// requires elevated privileges, so in most cases this code needs to be run +// as root. +package netns + +import ( + "fmt" + "syscall" +) + +// NsHandle is a handle to a network namespace. It can be cast directly +// to an int and used as a file descriptor. +type NsHandle int + +// Equal determines if two network handles refer to the same network +// namespace. This is done by comparing the device and inode that the +// file descriptors point to. +func (ns NsHandle) Equal(other NsHandle) bool { + if ns == other { + return true + } + var s1, s2 syscall.Stat_t + if err := syscall.Fstat(int(ns), &s1); err != nil { + return false + } + if err := syscall.Fstat(int(other), &s2); err != nil { + return false + } + return (s1.Dev == s2.Dev) && (s1.Ino == s2.Ino) +} + +// String shows the file descriptor number and its dev and inode. +func (ns NsHandle) String() string { + var s syscall.Stat_t + if ns == -1 { + return "NS(None)" + } + if err := syscall.Fstat(int(ns), &s); err != nil { + return fmt.Sprintf("NS(%d: unknown)", ns) + } + return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino) +} + +// UniqueId returns a string which uniquely identifies the namespace +// associated with the network handle. +func (ns NsHandle) UniqueId() string { + var s syscall.Stat_t + if ns == -1 { + return "NS(none)" + } + if err := syscall.Fstat(int(ns), &s); err != nil { + return "NS(unknown)" + } + return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino) +} + +// IsOpen returns true if Close() has not been called. +func (ns NsHandle) IsOpen() bool { + return ns != -1 +} + +// Close closes the NsHandle and resets its file descriptor to -1. +// It is not safe to use an NsHandle after Close() is called. +func (ns *NsHandle) Close() error { + if err := syscall.Close(int(*ns)); err != nil { + return err + } + (*ns) = -1 + return nil +} + +// None gets an empty (closed) NsHandle. +func None() NsHandle { + return NsHandle(-1) +} diff --git a/vendor/github.com/vishvananda/netns/netns_linux.go b/vendor/github.com/vishvananda/netns/netns_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..e665ef4499832785a341cbff952d5b0f9ef2759e --- /dev/null +++ b/vendor/github.com/vishvananda/netns/netns_linux.go @@ -0,0 +1,230 @@ +// +build linux + +package netns + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + "syscall" +) + +// SYS_SETNS syscall allows changing the namespace of the current process. +var SYS_SETNS = map[string]uintptr{ + "386": 346, + "amd64": 308, + "arm64": 268, + "arm": 375, + "mips": 4344, + "mipsle": 4344, + "ppc64": 350, + "ppc64le": 350, + "s390x": 339, +}[runtime.GOARCH] + +// Deprecated: use syscall pkg instead (go >= 1.5 needed). +const ( + CLONE_NEWUTS = 0x04000000 /* New utsname group? */ + CLONE_NEWIPC = 0x08000000 /* New ipcs */ + CLONE_NEWUSER = 0x10000000 /* New user namespace */ + CLONE_NEWPID = 0x20000000 /* New pid namespace */ + CLONE_NEWNET = 0x40000000 /* New network namespace */ + CLONE_IO = 0x80000000 /* Get io context */ +) + +// Setns sets namespace using syscall. Note that this should be a method +// in syscall but it has not been added. +func Setns(ns NsHandle, nstype int) (err error) { + _, _, e1 := syscall.Syscall(SYS_SETNS, uintptr(ns), uintptr(nstype), 0) + if e1 != 0 { + err = e1 + } + return +} + +// Set sets the current network namespace to the namespace represented +// by NsHandle. +func Set(ns NsHandle) (err error) { + return Setns(ns, CLONE_NEWNET) +} + +// New creates a new network namespace and returns a handle to it. +func New() (ns NsHandle, err error) { + if err := syscall.Unshare(CLONE_NEWNET); err != nil { + return -1, err + } + return Get() +} + +// Get gets a handle to the current threads network namespace. +func Get() (NsHandle, error) { + return GetFromThread(os.Getpid(), syscall.Gettid()) +} + +// GetFromPath gets a handle to a network namespace +// identified by the path +func GetFromPath(path string) (NsHandle, error) { + fd, err := syscall.Open(path, syscall.O_RDONLY, 0) + if err != nil { + return -1, err + } + return NsHandle(fd), nil +} + +// GetFromName gets a handle to a named network namespace such as one +// created by `ip netns add`. +func GetFromName(name string) (NsHandle, error) { + return GetFromPath(fmt.Sprintf("/var/run/netns/%s", name)) +} + +// GetFromPid gets a handle to the network namespace of a given pid. +func GetFromPid(pid int) (NsHandle, error) { + return GetFromPath(fmt.Sprintf("/proc/%d/ns/net", pid)) +} + +// GetFromThread gets a handle to the network namespace of a given pid and tid. +func GetFromThread(pid, tid int) (NsHandle, error) { + return GetFromPath(fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid)) +} + +// GetFromDocker gets a handle to the network namespace of a docker container. +// Id is prefixed matched against the running docker containers, so a short +// identifier can be used as long as it isn't ambiguous. +func GetFromDocker(id string) (NsHandle, error) { + pid, err := getPidForContainer(id) + if err != nil { + return -1, err + } + return GetFromPid(pid) +} + +// borrowed from docker/utils/utils.go +func findCgroupMountpoint(cgroupType string) (string, error) { + output, err := ioutil.ReadFile("/proc/mounts") + if err != nil { + return "", err + } + + // /proc/mounts has 6 fields per line, one mount per line, e.g. + // cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0 + for _, line := range strings.Split(string(output), "\n") { + parts := strings.Split(line, " ") + if len(parts) == 6 && parts[2] == "cgroup" { + for _, opt := range strings.Split(parts[3], ",") { + if opt == cgroupType { + return parts[1], nil + } + } + } + } + + return "", fmt.Errorf("cgroup mountpoint not found for %s", cgroupType) +} + +// Returns the relative path to the cgroup docker is running in. +// borrowed from docker/utils/utils.go +// modified to get the docker pid instead of using /proc/self +func getThisCgroup(cgroupType string) (string, error) { + dockerpid, err := ioutil.ReadFile("/var/run/docker.pid") + if err != nil { + return "", err + } + result := strings.Split(string(dockerpid), "\n") + if len(result) == 0 || len(result[0]) == 0 { + return "", fmt.Errorf("docker pid not found in /var/run/docker.pid") + } + pid, err := strconv.Atoi(result[0]) + if err != nil { + return "", err + } + output, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) + if err != nil { + return "", err + } + for _, line := range strings.Split(string(output), "\n") { + parts := strings.Split(line, ":") + // any type used by docker should work + if parts[1] == cgroupType { + return parts[2], nil + } + } + return "", fmt.Errorf("cgroup '%s' not found in /proc/%d/cgroup", cgroupType, pid) +} + +// Returns the first pid in a container. +// borrowed from docker/utils/utils.go +// modified to only return the first pid +// modified to glob with id +// modified to search for newer docker containers +func getPidForContainer(id string) (int, error) { + pid := 0 + + // memory is chosen randomly, any cgroup used by docker works + cgroupType := "memory" + + cgroupRoot, err := findCgroupMountpoint(cgroupType) + if err != nil { + return pid, err + } + + cgroupThis, err := getThisCgroup(cgroupType) + if err != nil { + return pid, err + } + + id += "*" + + attempts := []string{ + filepath.Join(cgroupRoot, cgroupThis, id, "tasks"), + // With more recent lxc versions use, cgroup will be in lxc/ + filepath.Join(cgroupRoot, cgroupThis, "lxc", id, "tasks"), + // With more recent docker, cgroup will be in docker/ + filepath.Join(cgroupRoot, cgroupThis, "docker", id, "tasks"), + // Even more recent docker versions under systemd use docker-<id>.scope/ + filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", "tasks"), + // Even more recent docker versions under cgroup/systemd/docker/<id>/ + filepath.Join(cgroupRoot, "..", "systemd", "docker", id, "tasks"), + // Kubernetes with docker and CNI is even more different + filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, "tasks"), + // Another flavor of containers location in recent kubernetes 1.11+ + filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"), + // When runs inside of a container with recent kubernetes 1.11+ + filepath.Join(cgroupRoot, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"), + } + + var filename string + for _, attempt := range attempts { + filenames, _ := filepath.Glob(attempt) + if len(filenames) > 1 { + return pid, fmt.Errorf("Ambiguous id supplied: %v", filenames) + } else if len(filenames) == 1 { + filename = filenames[0] + break + } + } + + if filename == "" { + return pid, fmt.Errorf("Unable to find container: %v", id[:len(id)-1]) + } + + output, err := ioutil.ReadFile(filename) + if err != nil { + return pid, err + } + + result := strings.Split(string(output), "\n") + if len(result) == 0 || len(result[0]) == 0 { + return pid, fmt.Errorf("No pid found for container") + } + + pid, err = strconv.Atoi(result[0]) + if err != nil { + return pid, fmt.Errorf("Invalid pid '%s': %s", result[0], err) + } + + return pid, nil +} diff --git a/vendor/github.com/vishvananda/netns/netns_unspecified.go b/vendor/github.com/vishvananda/netns/netns_unspecified.go new file mode 100644 index 0000000000000000000000000000000000000000..d06af62b68ad208de2d508380bcc66f96169bbbc --- /dev/null +++ b/vendor/github.com/vishvananda/netns/netns_unspecified.go @@ -0,0 +1,43 @@ +// +build !linux + +package netns + +import ( + "errors" +) + +var ( + ErrNotImplemented = errors.New("not implemented") +) + +func Set(ns NsHandle) (err error) { + return ErrNotImplemented +} + +func New() (ns NsHandle, err error) { + return -1, ErrNotImplemented +} + +func Get() (NsHandle, error) { + return -1, ErrNotImplemented +} + +func GetFromPath(path string) (NsHandle, error) { + return -1, ErrNotImplemented +} + +func GetFromName(name string) (NsHandle, error) { + return -1, ErrNotImplemented +} + +func GetFromPid(pid int) (NsHandle, error) { + return -1, ErrNotImplemented +} + +func GetFromThread(pid, tid int) (NsHandle, error) { + return -1, ErrNotImplemented +} + +func GetFromDocker(id string) (NsHandle, error) { + return -1, ErrNotImplemented +}