util-0.5.0/0000755000175000017500000000000014142163707012024 5ustar nileshnileshutil-0.5.0/go.sum0000644000175000017500000016221414142163707013165 0ustar nileshnileshcloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shenwei356/breader v0.3.1 h1:OjgfeHhpNGQPkS1+lgsl4eNuuO//Y16N6TkqG5oxO5U= github.com/shenwei356/breader v0.3.1/go.mod h1:UR11JJCxU9s7eUdU4xn3L/VodxoXzWhjJPh8WZbb+us= github.com/shenwei356/natsort v0.0.0-20190418160752-600d539c017d h1:eeXLHcXyGEr72V1SOSEI7vSzUOTJvHutwF7Ykm+hscQ= github.com/shenwei356/natsort v0.0.0-20190418160752-600d539c017d/go.mod h1:SiiGiRFyRtV7S9RamOrmQR5gpGIRhWJM1w0EtmuQ1io= github.com/shenwei356/xopen v0.1.0 h1:PizY52rLA7A6EdkwKZ6A8h8/a+c9DCBXqfLtwVzsWnM= github.com/shenwei356/xopen v0.1.0/go.mod h1:6EQUa6I7Zsl2GQKqcL9qGLrTzVE+oZyly+uhzovQYSk= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/twotwotwo/sorts v0.0.0-20160814051341-bf5c1f2b8553 h1:DRC1ubdb3ZmyyIeCSTxjZIQAnpLPfKVgYrLETQuOPjo= github.com/twotwotwo/sorts v0.0.0-20160814051341-bf5c1f2b8553/go.mod h1:Rj7Csq/tZ/egz+Ltc2IVpsA5309AmSMEswjkTZmq2Xc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= util-0.5.0/exec/0000755000175000017500000000000014142163707012750 5ustar nileshnileshutil-0.5.0/exec/exec.go0000644000175000017500000000710514142163707014226 0ustar nileshnilesh// Package exec runs external commands. It wraps os.exec to // allow using full command string as arguments, // and provides functions // of providing (stdin, stdout, stderr) channel for // (stdin, stdout, stderr) pipe. // // Attention, this package is experimental. package exec import ( "bufio" "errors" "io" "os/exec" "strings" ) type Cmd struct { *exec.Cmd } // Command returns the Cmd struct to execute the command. // No need to split the path and arguments. // The error may be caused by unclosed quote. func Command(name string) (*Cmd, error) { path, argv, err := parseCommandName(name) if err != nil { return nil, err } return &Cmd{exec.Command(path, argv...)}, nil } // StdoutChannel returns a channel that will be connected to // the command's standard error when the command starts. // It closes when StdoutPipe closed. func (c *Cmd) StdoutChannel() (chan string, error) { ch := make(chan string, 100) pipe, err := c.StdoutPipe() if err != nil { return nil, err } reader := bufio.NewReader(pipe) go func() { for { str, err := reader.ReadString('\n') if err != nil { if err == io.EOF { if str != "" { ch <- str } } close(ch) return } if str != "" { ch <- str } } }() return ch, nil } // StderrChannel returns a channel that will be connected to // the command's standard error when the command starts. // It closes when StderrPipe closed. func (c *Cmd) StderrChannel() (chan string, error) { ch := make(chan string, 100) pipe, err := c.StderrPipe() if err != nil { return nil, err } reader := bufio.NewReader(pipe) go func() { for { str, err := reader.ReadString('\n') if err != nil { if err == io.EOF { if str != "" { ch <- str } } close(ch) return } if str != "" { ch <- str } } }() return ch, nil } // StdinChannel returns a channel that will be connected to // the command's standard error when the command starts. func (c *Cmd) StdinChannel() (chan string, error) { ch := make(chan string, 100) pipe, err := c.StdinPipe() if err != nil { return nil, err } writer := bufio.NewWriter(pipe) go func() { for { select { case str := <-ch: writer.WriteString(str) } } }() return ch, nil } // parseCommandName split the full command into path and arguments. func parseCommandName(name string) (string, []string, error) { if len(strings.Trim(name, " ")) == 0 { return "", nil, errors.New("no command given") } var ( quoted bool = false quotation rune tmp []rune = make([]rune, 0) argv []string = make([]string, 0) ) for _, b := range name { switch b { case ' ': if quoted { tmp = append(tmp, b) } else { if len(strings.Trim(string(tmp), " ")) > 0 { argv = append(argv, string(tmp)) } tmp = make([]rune, 0) } case '"': if quoted { if quotation == '"' { quoted, quotation = false, '_' argv = append(argv, string(tmp)) tmp = make([]rune, 0) } else { tmp = append(tmp, b) } } else { quoted, quotation = true, '"' } case '\'': if quoted { if quotation == '\'' { quoted, quotation = false, '_' argv = append(argv, string(tmp)) tmp = make([]rune, 0) } else { tmp = append(tmp, b) } } else { quoted, quotation = true, '\'' } default: tmp = append(tmp, b) } } if len(strings.Trim(string(tmp), " ")) > 0 { argv = append(argv, string(tmp)) } path := argv[0] var arg []string if len(argv) > 1 { arg = argv[1:] } if quoted { return path, arg, errors.New("unclosed quote") } return path, arg, nil } util-0.5.0/exec/README.md0000644000175000017500000000057114142163707014232 0ustar nileshnileshexec ======== Package exec runs external commands. It wraps os.exec to allow using full command string as arguments, and provides functions of providing (stdin, stdout, stderr) channel for (stdin, stdout, stderr) pipe. ***Attention, this package is experimental***. This package is imported by [crun of go edition](https://github.com/shenwei356/crun/blob/master/go/crun.go) util-0.5.0/exec/LICENSE0000644000175000017500000000210314142163707013751 0ustar nileshnileshCopyright (c) 2013 Wei Shen (shenwei356@gmail.com) The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.util-0.5.0/numbers/0000755000175000017500000000000014142163707013477 5ustar nileshnileshutil-0.5.0/numbers/uniq.go0000644000175000017500000000171714142163707015010 0ustar nileshnileshpackage numbers import "sort" // Uniq removes duplicated elements in the list, and returns a new one. func Uniq(list *[]uint64) *[]uint64 { if len(*list) == 0 { return &[]uint64{} } else if len(*list) == 1 { return &[]uint64{(*list)[0]} } sort.Sort(Uint64Slice(*list)) s := make([]uint64, 0, len(*list)) p := (*list)[0] s = append(s, p) for _, v := range (*list)[1:] { if v != p { s = append(s, v) } p = v } return &s } // UniqInplace is faster than Uniq for short slice (<1000). func UniqInplace(list *[]uint64) { if len(*list) == 0 || len(*list) == 1 { return } sort.Sort(Uint64Slice(*list)) var i, j int var p, v uint64 var flag bool p = (*list)[0] for i = 1; i < len(*list); i++ { v = (*list)[i] if v == p { if !flag { j = i // mark insertion position flag = true } continue } if flag { // need to insert to previous position (*list)[j] = v j++ } p = v } if j > 0 { *list = (*list)[:j] } } util-0.5.0/numbers/base.go0000644000175000017500000000110614142163707014736 0ustar nileshnileshpackage numbers type Uint64Slice []uint64 func (s Uint64Slice) Len() int { return len(s) } func (s Uint64Slice) Less(i, j int) bool { return s[i] < s[j] } func (s Uint64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s *Uint64Slice) Push(x interface{}) { *s = append(*s, x.(uint64)) } func (s *Uint64Slice) Pop() interface{} { old := *s n := len(old) x := old[n-1] *s = old[0 : n-1] return x } func Equal(s, t []uint64) bool { if len(s) != len(t) { return false } for i, v := range s { if v != t[i] { return false } } return true } util-0.5.0/numbers/uniq_test.go0000644000175000017500000000250014142163707016036 0ustar nileshnileshpackage numbers import ( "math/rand" "testing" ) var data []*[]uint64 var data2 []*[]uint64 func init() { N := 100000 // N lists n := 300 // n elements for a list data = make([]*[]uint64, N) data2 = make([]*[]uint64, N) for i := 0; i < N; i++ { _n := rand.Intn(n) if _n < 0 { _n = -_n } _data := make([]uint64, _n) for j := 0; j < _n; j++ { _data[j] = uint64(float64(rand.Intn(_n)) / float64(1)) } _data2 := make([]uint64, _n) copy(_data2, _data) data[i] = &_data data2[i] = &_data2 } } func TestUniq(t *testing.T) { for _, _data := range data { u1 := Uniq(_data) c := make([]uint64, len(*_data)) copy(c, *_data) UniqInplace(&c) // fmt.Printf("original: %v\n", _data) // fmt.Printf(" Inplace: %v\n", c) // fmt.Printf(" uniq: %v\n", *u1) if !Equal(*u1, c) { // fmt.Printf("original: %v\n", _data) // fmt.Printf(" Inplace: %v\n", c) // fmt.Printf(" uniq: %v\n", *u1) t.Error("error") } } } var result *[]uint64 func BenchmarkUniq(b *testing.B) { var _result *[]uint64 // for i := 0; i < b.N; i++ { for _, _data := range data { _result = Uniq(_data) } // } result = _result } func BenchmarkUniqInplace(b *testing.B) { var _result *[]uint64 // for i := 0; i < b.N; i++ { for _, _data := range data2 { UniqInplace(_data) } // } result = _result } util-0.5.0/README.md0000644000175000017500000000121514142163707013302 0ustar nileshnilesh# util [![GoDoc](https://godoc.org/github.com/shenwei356/util?status.svg)](https://godoc.org/github.com/shenwei356/util) [![Go Report Card](https://goreportcard.com/badge/github.com/shenwei356/util)](https://goreportcard.com/report/github.com/shenwei356/util) Utility packges ## Install This package is "go-gettable", just: go get -u github.com/shenwei356/util Copyright (c) 2013-2020, Wei Shen (shenwei356@gmail.com) ## More See the README of sub package. ## Documentation [See documentation on godoc for more detail](https://godoc.org/github.com/shenwei356/util). [MIT License](https://github.com/shenwei356/util/blob/master/LICENSE) util-0.5.0/cliutil/0000755000175000017500000000000014142163707013471 5ustar nileshnileshutil-0.5.0/cliutil/cobra.go0000644000175000017500000000730514142163707015113 0ustar nileshnileshpackage cliutil import ( "fmt" "os" "strconv" "github.com/shenwei356/util/stringutil" "github.com/spf13/cobra" ) func isStdin(file string) bool { return file == "-" } func CheckError(err error) { if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(-1) } } func GetFlagInt(cmd *cobra.Command, flag string) int { value, err := cmd.Flags().GetInt(flag) CheckError(err) return value } func GetFlagUint8(cmd *cobra.Command, flag string) uint8 { value, err := cmd.Flags().GetUint8(flag) CheckError(err) return value } func GetFlagUint32(cmd *cobra.Command, flag string) uint32 { value, err := cmd.Flags().GetUint32(flag) CheckError(err) return value } func GetFlagUint64(cmd *cobra.Command, flag string) uint64 { value, err := cmd.Flags().GetUint64(flag) CheckError(err) return value } func GetFlagPositiveInt(cmd *cobra.Command, flag string) int { value, err := cmd.Flags().GetInt(flag) CheckError(err) if value <= 0 { CheckError(fmt.Errorf("value of flag --%s should be greater than 0", flag)) } return value } func GetFlagPositiveFloat64(cmd *cobra.Command, flag string) float64 { value, err := cmd.Flags().GetFloat64(flag) CheckError(err) if value <= 0 { CheckError(fmt.Errorf("value of flag --%s should be greater than 0", flag)) } return value } func GetFlagNonNegativeInt(cmd *cobra.Command, flag string) int { value, err := cmd.Flags().GetInt(flag) CheckError(err) if value < 0 { CheckError(fmt.Errorf("value of flag --%s should be greater than or equal to 0", flag)) } return value } func GetFlagNonNegativeFloat64(cmd *cobra.Command, flag string) float64 { value, err := cmd.Flags().GetFloat64(flag) CheckError(err) if value < 0 { CheckError(fmt.Errorf("value of flag --%s should be greater than or equal to ", flag)) } return value } func GetFlagBool(cmd *cobra.Command, flag string) bool { value, err := cmd.Flags().GetBool(flag) CheckError(err) return value } func GetFlagString(cmd *cobra.Command, flag string) string { value, err := cmd.Flags().GetString(flag) CheckError(err) return value } func GetFlagNonEmptyString(cmd *cobra.Command, flag string) string { value, err := cmd.Flags().GetString(flag) CheckError(err) if value == "" { CheckError(fmt.Errorf("value of flag --%s should not be empty", flag)) } return value } func GetFlagCommaSeparatedStrings(cmd *cobra.Command, flag string) []string { value, err := cmd.Flags().GetString(flag) CheckError(err) return stringutil.Split(value, ",") } func GetFlagSemicolonSeparatedStrings(cmd *cobra.Command, flag string) []string { value, err := cmd.Flags().GetString(flag) CheckError(err) return stringutil.Split(value, ";") } func GetFlagCommaSeparatedInts(cmd *cobra.Command, flag string) []int { filedsStrList := GetFlagCommaSeparatedStrings(cmd, flag) fields := make([]int, len(filedsStrList)) for i, value := range filedsStrList { v, err := strconv.Atoi(value) if err != nil { CheckError(fmt.Errorf("value of flag --%s should be comma separated integers", flag)) } fields[i] = v } return fields } func GetFlagRune(cmd *cobra.Command, flag string) rune { value, err := cmd.Flags().GetString(flag) CheckError(err) if len(value) > 1 { CheckError(fmt.Errorf("value of flag --%s should has length of 1", flag)) } var v rune for _, r := range value { v = r break } return v } func GetFlagFloat64(cmd *cobra.Command, flag string) float64 { value, err := cmd.Flags().GetFloat64(flag) CheckError(err) return value } func GetFlagInt64(cmd *cobra.Command, flag string) int64 { value, err := cmd.Flags().GetInt64(flag) CheckError(err) return value } func GetFlagStringSlice(cmd *cobra.Command, flag string) []string { value, err := cmd.Flags().GetStringSlice(flag) CheckError(err) return value } util-0.5.0/cliutil/others.go0000644000175000017500000000500714142163707015326 0ustar nileshnileshpackage cliutil import ( "bufio" "fmt" "os" "strings" "github.com/pkg/errors" "github.com/shenwei356/breader" ) // ReadKVs parse two-column (key\tvalue) tab-delimited file(s). func ReadKVs(file string, ignoreCase bool) (map[string]string, error) { type KV [2]string fn := func(line string) (interface{}, bool, error) { if len(line) > 0 && line[len(line)-1] == '\n' { line = line[:len(line)-1] } if len(line) > 0 && line[len(line)-1] == '\r' { line = line[:len(line)-1] } if len(line) == 0 { return nil, false, nil } items := strings.Split(line, "\t") if len(items) < 2 { return nil, false, nil } if ignoreCase { return KV([2]string{strings.ToLower(items[0]), items[1]}), true, nil } return KV([2]string{items[0], items[1]}), true, nil } kvs := make(map[string]string) reader, err := breader.NewBufferedReader(file, 4, 100, fn) if err != nil { return kvs, err } var items KV var data interface{} for chunk := range reader.Ch { if chunk.Err != nil { return kvs, err } for _, data = range chunk.Data { items = data.(KV) kvs[items[0]] = items[1] } } return kvs, nil } // DropCR removes last "\r" if it is. func DropCR(data []byte) []byte { if len(data) > 0 && data[len(data)-1] == '\r' { return data[0 : len(data)-1] } return data } // DropLF removes "\n" func DropLF(data []byte) []byte { if len(data) > 0 && data[len(data)-1] == '\n' { return data[0 : len(data)-1] } return data } func GetFileList(args []string, checkFile bool) []string { files := make([]string, 0, 1000) if len(args) == 0 { files = append(files, "-") } else { for _, file := range args { if isStdin(file) { continue } if !checkFile { continue } if _, err := os.Stat(file); os.IsNotExist(err) { CheckError(errors.Wrap(err, file)) } } files = args } return files } func GetFileListFromFile(file string, checkFile bool) ([]string, error) { fh, err := os.Open(file) if err != nil { return nil, fmt.Errorf("read file list from '%s': %s", file, err) } var _file string lists := make([]string, 0, 1000) scanner := bufio.NewScanner(fh) for scanner.Scan() { _file = scanner.Text() if strings.TrimSpace(_file) == "" { continue } if checkFile && !isStdin(_file) { if _, err = os.Stat(_file); os.IsNotExist(err) { return lists, fmt.Errorf("check file '%s': %s", _file, err) } } lists = append(lists, _file) } if err = scanner.Err(); err != nil { return nil, fmt.Errorf("read file list from '%s': %s", file, err) } return lists, nil } util-0.5.0/stringutil/0000755000175000017500000000000014142163707014230 5ustar nileshnileshutil-0.5.0/stringutil/StringCount.go0000644000175000017500000000334414142163707017042 0ustar nileshnileshpackage stringutil import "sort" // StringCount is a struct store count of Key type StringCount struct { Key string Count int } // StringCountList is slice of Keycount type StringCountList []StringCount func (b StringCountList) Len() int { return len(b) } func (b StringCountList) Less(i, j int) bool { // return b[i].Count < b[j].Count // This will return unwanted result: return b[i].Count < b[j].Count || b[i].Key < b[j].Key if b[i].Count < b[j].Count { return true } if b[i].Count == b[j].Count { if b[i].Key < b[j].Key { return true } return false } return false } func (b StringCountList) Swap(i, j int) { b[i], b[j] = b[j], b[i] } // ReversedStringCountList is Reversed StringCountList type ReversedStringCountList struct { StringCountList } // Less is different from the Less of StringCountList func (b ReversedStringCountList) Less(i, j int) bool { // return b.StringCountList[i].Count > b.StringCountList[j].Count if b.StringCountList[i].Count > b.StringCountList[j].Count { return true } if b.StringCountList[i].Count == b.StringCountList[j].Count { if b.StringCountList[i].Key < b.StringCountList[j].Key { return true } return false } return false } // CountOfString returns the count of Key for a Key slice func CountOfString(s []string) map[string]int { count := make(map[string]int) for _, b := range s { count[b]++ } return count } // SortCountOfString sorts count of Key func SortCountOfString(count map[string]int, reverse bool) StringCountList { countList := make(StringCountList, len(count)) i := 0 for b, c := range count { countList[i] = StringCount{b, c} i++ } if reverse { sort.Sort(ReversedStringCountList{countList}) } else { sort.Sort(countList) } return countList } util-0.5.0/stringutil/util.go0000644000175000017500000000354214142163707015540 0ustar nileshnileshpackage stringutil import ( "bytes" "regexp" "unsafe" "github.com/shenwei356/util/byteutil" ) // Split splits a byte slice by given letters func Split(slice string, letters string) []string { result := byteutil.Split([]byte(slice), []byte(letters)) result2 := []string{} for _, s := range result { result2 = append(result2, string(s)) } return result2 } // Str2Bytes convert string to byte slice. Warning: it's unsafe!!! func Str2Bytes(s string) []byte { x := (*[2]uintptr)(unsafe.Pointer(&s)) h := [3]uintptr{x[0], x[1], x[1]} return *(*[]byte)(unsafe.Pointer(&h)) } // ReverseStringSlice reverses StringSlice func ReverseStringSlice(s []string) []string { // make a copy of s l := len(s) t := make([]string, l) for i := 0; i < l; i++ { t[i] = s[i] } // reverse for i, j := 0, l-1; i < j; i, j = i+1, j-1 { t[i], t[j] = t[j], t[i] } return t } // ReverseStringSliceInplace reverses StringSlice func ReverseStringSliceInplace(s []string) { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } } // EscapeSymbols escape custom symbols func EscapeSymbols(s, symbols string) string { m := make(map[rune]struct{}) for _, c := range symbols { m[c] = struct{}{} } var buf bytes.Buffer var ok bool for _, c := range s { if _, ok = m[c]; ok { buf.WriteByte('\\') } buf.WriteRune(c) } return buf.String() } // UnEscaper returns a function for unescaping string func UnEscaper() func(s string) string { var re = regexp.MustCompile(`\\([abfnrtv'"?])`) var m = map[string]string{ `\a`: "\a", `\b`: "\b", `\f`: "\f", `\n`: "\n", `\r`: "\r", `\t`: "\t", `\v`: "\v", `\\`: "\\", `\'`: "'", `\"`: "\"", `\?`: "?", } var mapping = func(key string) string { if v, ok := m[key]; ok { return v } return key } return func(s string) string { return re.ReplaceAllStringFunc(s, mapping) } } util-0.5.0/stringutil/multiKeySort.go0000644000175000017500000000532514142163707017237 0ustar nileshnileshpackage stringutil import ( "strconv" "strings" "github.com/shenwei356/natsort" ) // SortType defines the sort type type SortType struct { Index int IgnoreCase bool Natural bool // natural order Number bool UserDefined bool Reverse bool Levels map[string]int } // MultiKeyStringSlice sort [][]string by multiple keys type MultiKeyStringSlice struct { SortTypes *[]SortType Value []string } // MultiKeyStringSliceList is slice of MultiKeyStringSlice type MultiKeyStringSliceList []MultiKeyStringSlice func (list MultiKeyStringSliceList) Len() int { return len(list) } func (list MultiKeyStringSliceList) Swap(i, j int) { list[i], list[j] = list[j], list[i] } func (list MultiKeyStringSliceList) Less(i, j int) bool { var err error var v int for _, t := range *list[i].SortTypes { if t.Natural { if t.IgnoreCase { v = strings.Compare(strings.ToLower(list[i].Value[t.Index]), strings.ToLower(list[j].Value[t.Index])) } else { v = strings.Compare(list[i].Value[t.Index], list[j].Value[t.Index]) } if v == 0 { continue } if natsort.Compare(list[i].Value[t.Index], list[j].Value[t.Index], t.IgnoreCase) { v = -1 } else { v = 1 } } else if t.Number { var a, b float64 a, err = strconv.ParseFloat(removeComma(list[i].Value[t.Index]), 64) if err != nil { a = 0 } b, err = strconv.ParseFloat(removeComma(list[j].Value[t.Index]), 64) if err != nil { b = 0 } if a < b { v = -1 } else if a == b { v = 0 } else { v = 1 } } else if t.UserDefined { var a, b int var okA, okB bool if t.IgnoreCase { a, okA = t.Levels[strings.ToLower(list[i].Value[t.Index])] b, okB = t.Levels[strings.ToLower(list[j].Value[t.Index])] } else { a, okA = t.Levels[list[i].Value[t.Index]] b, okB = t.Levels[list[j].Value[t.Index]] } if okA { if okB { if a < b { v = -1 } else if a == b { v = 0 } else { v = 1 } } else { v = -1 } } else if okB { v = 1 } else { v = strings.Compare(list[i].Value[t.Index], list[j].Value[t.Index]) } } else { if t.IgnoreCase { v = strings.Compare(strings.ToLower(list[i].Value[t.Index]), strings.ToLower(list[j].Value[t.Index])) } else { v = strings.Compare(list[i].Value[t.Index], list[j].Value[t.Index]) } } if v == 0 { } else if v < 0 { if t.Reverse { return false } return true } else { if t.Reverse { return true } return false } } return true } func removeComma(s string) string { newSlice := []byte{} for i := 0; i < len(s); i++ { switch s[i] { case ',': default: newSlice = append(newSlice, s[i]) } } return string(newSlice) } util-0.5.0/stringutil/String2ByteSlice.go0000644000175000017500000000333114142163707017713 0ustar nileshnileshpackage stringutil import ( "bytes" "github.com/shenwei356/natsort" ) // String2ByteSlice is for sortint of string-[]byte pairs type String2ByteSlice struct { Key string Value []byte } // String2ByteSliceList is list of string2ByteSlice type String2ByteSliceList []String2ByteSlice // NaturalOrder is the global variable for sorting String2ByteSlice var NaturalOrder = false // IgnoreCase for ignoring case when sorting in natural order var IgnoreCase = false func (list String2ByteSliceList) Len() int { return len(list) } func (list String2ByteSliceList) Less(i, j int) bool { if NaturalOrder { return natsort.Compare(list[i].Key, list[j].Key, IgnoreCase) } return list[i].Key < list[j].Key } func (list String2ByteSliceList) Swap(i, j int) { list[i], list[j] = list[j], list[i] } // ReversedString2ByteSliceList is reversed String2ByteSliceList type ReversedString2ByteSliceList struct { String2ByteSliceList } // Less ... func (list ReversedString2ByteSliceList) Less(i, j int) bool { if NaturalOrder { return !natsort.Compare(list.String2ByteSliceList[i].Key, list.String2ByteSliceList[j].Key, IgnoreCase) } return list.String2ByteSliceList[i].Key > list.String2ByteSliceList[j].Key } // ByValue ... type ByValue struct { String2ByteSliceList } // Less ... func (list ByValue) Less(i, j int) bool { c := bytes.Compare(list.String2ByteSliceList[i].Value, list.String2ByteSliceList[j].Value) if c == -1 { return true } return false } // ReversedByValue ... type ReversedByValue struct { String2ByteSliceList } // Less ... func (list ReversedByValue) Less(i, j int) bool { c := bytes.Compare(list.String2ByteSliceList[j].Value, list.String2ByteSliceList[i].Value) if c == -1 { return true } return false } util-0.5.0/go.mod0000644000175000017500000000110514142163707013127 0ustar nileshnileshmodule github.com/shenwei356/util go 1.17 require ( github.com/montanaflynn/stats v0.6.6 github.com/pkg/errors v0.9.1 github.com/shenwei356/breader v0.3.1 github.com/shenwei356/natsort v0.0.0-20190418160752-600d539c017d github.com/spf13/cobra v1.2.1 github.com/twotwotwo/sorts v0.0.0-20160814051341-bf5c1f2b8553 ) require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/shenwei356/xopen v0.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect ) util-0.5.0/struct/0000755000175000017500000000000014142163707013350 5ustar nileshnileshutil-0.5.0/struct/sa/0000755000175000017500000000000014142163707013753 5ustar nileshnileshutil-0.5.0/struct/sa/sa.go0000644000175000017500000000073014142163707014705 0ustar nileshnileshpackage sa import "sort" // SuffixArray returns the suffix array of s func SuffixArray(s []byte) []int { n := len(s) suffixMap := make(map[string]int, n) for i := 0; i < n; i++ { suffixMap[string(s[i:])] = i } suffixes := make([]string, n) i := 0 for suffix := range suffixMap { suffixes[i] = suffix i++ } indice := make([]int, n) i = 0 sort.Strings(suffixes) for _, suffix := range suffixes { indice[i] = suffixMap[suffix] i++ } return indice } util-0.5.0/struct/sa/sa_test.go0000644000175000017500000000035114142163707015743 0ustar nileshnileshpackage sa import ( "reflect" "testing" ) func TestSuffixArray(t *testing.T) { s := []byte("banana$") sa := SuffixArray(s) if !reflect.DeepEqual(sa, []int{6, 5, 3, 1, 0, 4, 2}) { t.Error("Test failed: TestSuffixArray") } } util-0.5.0/struct/stack/0000755000175000017500000000000014142163707014455 5ustar nileshnileshutil-0.5.0/struct/stack/stack.go0000644000175000017500000000127114142163707016112 0ustar nileshnileshpackage stack // Stack struct type Stack []interface{} // Empty tell if it is empty func (s Stack) Empty() bool { return len(s) == 0 } // Peek return the last element func (s Stack) Peek() interface{} { return s[len(s)-1] } // Put puts element to stack func (s *Stack) Put(i interface{}) { (*s) = append((*s), i) } // Pop pops element from the stack func (s *Stack) Pop() interface{} { d := (*s)[len(*s)-1] (*s) = (*s)[:len(*s)-1] return d } /* func main() { var s stack for i := 0; i < 3; i++ { s.Put(i) fmt.Printf("len=%d\n", len(s)) fmt.Printf("peek=%d\n", s.Peek()) } for !s.Empty() { i := s.Pop() fmt.Printf("len=%d\n", len(s)) fmt.Printf("pop=%d\n", i) } } */ util-0.5.0/math/0000755000175000017500000000000014142163707012755 5ustar nileshnileshutil-0.5.0/math/float.go0000644000175000017500000000102214142163707014404 0ustar nileshnileshpackage math import "math" // Round returns round of float64 func Round(f float64, n int) float64 { pow10N := math.Pow10(n) return math.Trunc((f+0.5/pow10N)*pow10N) / pow10N } const MaxUint = ^uint(0) const MinUint = 0 const MaxInt = int(MaxUint >> 1) const MinInt = -MaxInt - 1 func MinInts(a int, vals ...int) int { min := a for _, v := range vals { if v < min { min = v } } return min } func MaxInts(a int, vals ...int) int { max := a for _, v := range vals { if v > max { max = v } } return max } util-0.5.0/randutil/0000755000175000017500000000000014142163707013646 5ustar nileshnileshutil-0.5.0/randutil/shuffle.go0000644000175000017500000000025414142163707015632 0ustar nileshnileshpackage randutil import "math/rand" // Shuffle shuffles a slice of int func Shuffle(s []int) { for i := range s { j := rand.Intn(i + 1) s[i], s[j] = s[j], s[i] } } util-0.5.0/pathutil/0000755000175000017500000000000014142163707013656 5ustar nileshnileshutil-0.5.0/pathutil/path.go0000644000175000017500000000325114142163707015142 0ustar nileshnileshpackage pathutil import ( "fmt" "os" "regexp" ) // Exists checks if a file or directory exists. func Exists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } // LinkExists checks if link exists. func LinkExists(path string) (bool, error) { _, err := os.Lstat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } // DirExists checks if a path exists and is a directory. func DirExists(path string) (bool, error) { fi, err := os.Stat(path) if err == nil && fi.IsDir() { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } // IsEmpty checks if a given path is empty. func IsEmpty(path string) (bool, error) { if b, _ := Exists(path); !b { return false, fmt.Errorf("%q path does not exist", path) } fi, err := os.Stat(path) if err != nil { return false, err } if fi.IsDir() { f, err := os.Open(path) defer f.Close() if err != nil { return false, err } list, err := f.Readdir(-1) // f.Close() - see bug fix above return len(list) == 0, nil } return fi.Size() == 0, nil } // IsDir checks if a given path is a directory. func IsDir(path string) (bool, error) { fi, err := os.Stat(path) if err != nil { return false, err } return fi.IsDir(), nil } // ReInvalidPathChars is used to remove invalid path characters var ReInvalidPathChars = regexp.MustCompile(`[<>:"/\\\|?\*]+`) // RemoveInvalidPathChars removes invalid characters for path func RemoveInvalidPathChars(s string, repl string) string { return ReInvalidPathChars.ReplaceAllString(s, repl) } util-0.5.0/.gitignore0000755000175000017500000000041114142163707014013 0ustar nileshnilesh# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.directory util-0.5.0/bytesize/0000755000175000017500000000000014142163707013662 5ustar nileshnileshutil-0.5.0/bytesize/README.md0000644000175000017500000000220114142163707015134 0ustar nileshnileshbytesize ======== Package for providing a way to show readable values of byte sizes by reediting the code from http://golang.org/doc/effective_go.html. It could also parsing byte size text to ByteSize object. Usage ------- fmt.Printf("1024 bytes\t%v\n", bytesize.ByteSize(1024)) fmt.Printf("13146111 bytes\t%v\n", bytesize.ByteSize(13146111)) // parsing size, err := bytesize.Parse([]byte("1.5 KB")) if err != nil { fmt.Println(err) } fmt.Printf("\n%.0f bytes\n", size) Result: 1024 bytes 1.00 KB 13146111 bytes 12.54 MB 1536 bytes REGEXP for ByteSize Text ---------------------------- (?i)^\s*([\-\d\.]+)\s*([KMGTPEZY]?B|[BKMGTPEZY]|)\s*$ Example: data["1234.2 kb"] = 1263820.80 lower case data["-1234.2 kb"] = -1263820.80 lower case data[" 1234.2 kb "] = 1263820.80 space data["1234.2 k"] = 1263820.80 simple unit data["1234.2 "] = 1234.2 no unit data[" kb "] = -1 illegal value data["- kb"] = -1 illegal value data["1234.2 aB"] = -1 illegal unit data["1234.2 Packages"] = -1 illegal unit util-0.5.0/bytesize/.directory0000755000175000017500000000007414142163707015673 0ustar nileshnilesh[Dolphin] Timestamp=2016,11,15,20,4,27 Version=3 ViewMode=1 util-0.5.0/bytesize/bytesize.go0000644000175000017500000001103014142163707016042 0ustar nileshnilesh// Copyright 2014 Wei Shen (shenwei356@gmail.com). All rights reserved. // Use of this source code is governed by a MIT-license // that can be found in the LICENSE file. // Package bytesize provides a way to show readable values of byte size // by reediting the code from http://golang.org/doc/effective_go.html. // It could also parsing byte size text to ByteSize object. package bytesize import ( "errors" "fmt" "regexp" "strconv" "strings" ) // ByteSize stands for byte size. Division operation is needed, so it uses float64 instead of uint64 type ByteSize float64 // const for bytesize. B is also specified. const ( B ByteSize = 1 << (10 * iota) KB MB GB TB PB EB ZB YB ) // FullUnit decides output "10 GB" (true) or "10 G" (false). var FullUnit = true // Print readable values of byte size func (b ByteSize) String() string { if FullUnit { switch { case b >= YB: return fmt.Sprintf("%.2f YB", b/YB) case b >= ZB: return fmt.Sprintf("%.2f ZB", b/ZB) case b >= EB: return fmt.Sprintf("%.2f EB", b/EB) case b >= PB: return fmt.Sprintf("%.2f PB", b/PB) case b >= TB: return fmt.Sprintf("%.2f TB", b/TB) case b >= GB: return fmt.Sprintf("%.2f GB", b/GB) case b >= MB: return fmt.Sprintf("%.2f MB", b/MB) case b >= KB: return fmt.Sprintf("%.2f KB", b/KB) } return fmt.Sprintf("%.2f B", b) } switch { case b >= YB: return fmt.Sprintf("%.2f Y", b/YB) case b >= ZB: return fmt.Sprintf("%.2f Z", b/ZB) case b >= EB: return fmt.Sprintf("%.2f E", b/EB) case b >= PB: return fmt.Sprintf("%.2f P", b/PB) case b >= TB: return fmt.Sprintf("%.2f T", b/TB) case b >= GB: return fmt.Sprintf("%.2f G", b/GB) case b >= MB: return fmt.Sprintf("%.2f M", b/MB) case b >= KB: return fmt.Sprintf("%.2f K", b/KB) } return fmt.Sprintf("%.2f", b) } // BytesizeRegexp is the regexp object for ByteSize Text. The REGEXP is: // // (?i)^\s*([\-?[\d\.]+)\s*([KMGTPEZY]?B|[BKMGTPEZY]|)\s?$ // // Example: // // data["1234.2 kb"] = 1263820.80 // lower case // data["-1234.2 kb"] = -1263820.80 // lower case // data[" 1234.2 kb "] = 1263820.80 // space // data["1234.2 k"] = 1263820.80 // simple unit // data["1234.2 "] = 1234.2 // no unit // data[" kb "] = -1 // illegal value // data["- kb"] = -1 // illegal value // data["1234.2 aB"] = -1 // illegal unit // data["1234.2 Packages"] = -1 // illegal unit // var BytesizeRegexp = regexp.MustCompile(`(?i)^\s*(\-?[\d\.]+)\s*([KMGTPEZY]?B|[BKMGTPEZY]|)\s*$`) // ErrText is error information for Illegal byte size text var ErrText = "illegal bytesize text" // Parse parses ByteSize Text to ByteSize object // // Example // // size, err := bytesize.Parse([]byte("1.5 KB")) // if err != nil { // fmt.Println(err) // } // fmt.Printf("%.0f bytes\n", size) // func Parse(sizeText []byte) (ByteSize, error) { if !BytesizeRegexp.Match(sizeText) { return 0, errors.New(ErrText) } // parse value and unit subs := BytesizeRegexp.FindSubmatch(sizeText) // no need to check ParseFloat error. BytesizeRegexp could ensure this size, _ := strconv.ParseFloat(string(subs[1]), 64) unit := strings.ToUpper(string(subs[2])) switch unit { case "B", "": size = size * float64(B) case "KB", "K": size = size * float64(KB) case "MB", "M": size = size * float64(MB) case "GB", "G": size = size * float64(GB) case "TB", "T": size = size * float64(TB) case "PB", "P": size = size * float64(PB) case "EB", "E": size = size * float64(EB) case "ZB", "Z": size = size * float64(ZB) case "YB", "Y": size = size * float64(YB) } // fmt.Printf("%s\t=%.2f=\t=%s=\n", sizeText, size, unit) return ByteSize(size), nil } // ParseByteSize parses byte size from string. func ParseByteSize(val string) (int, error) { val = strings.Trim(val, " \t\r\n") if val == "" { return 0, nil } var u int64 var noUnit bool switch val[len(val)-1] { case 'B', 'b': u = 1 case 'K', 'k': u = 1 << 10 case 'M', 'm': u = 1 << 20 case 'G', 'g': u = 1 << 30 default: noUnit = true u = 1 } var size float64 var err error if noUnit { size, err = strconv.ParseFloat(val, 10) if err != nil { return 0, fmt.Errorf("invalid byte size: %s", val) } if size < 0 { size = 0 } return int(size), nil } if len(val) == 1 { // no value return 0, nil } size, err = strconv.ParseFloat(strings.Trim(val[0:len(val)-1], " \t\r\n"), 10) if err != nil { return 0, fmt.Errorf("invalid byte size: %s", val) } if size < 0 { size = 0 } return int(size * float64(u)), nil } util-0.5.0/bytesize/bytesize_test.go0000644000175000017500000000271214142163707017110 0ustar nileshnileshpackage bytesize import ( // "fmt" "testing" ) // test Right cases func Test1(t *testing.T) { bytes := []ByteSize{3, 1000, 1024, 1203, 132434, 41234134, 132413241324, 13e15} data := make(map[ByteSize]string) for _, b := range bytes { // 132434 : "129.33 KB" data[b] = b.String() } for _, s := range data { // size == 132433.92 size, err := Parse([]byte(s)) if err != nil && err.Error() != ErrText { t.Error("UNKNOWN ERROR TYPE") } // size == "129.33 KB" if s != size.String() { t.Error("FAILED") } } } // test more func Test2(t *testing.T) { data := make(map[string]ByteSize) data["1234.2 kb"] = 1263820.80 // lower case data["-1234.2 kb"] = -1263820.80 // lower case data[" 1234.2 kb "] = 1263820.80 // space data["1234.2 k"] = 1263820.80 // simple unit data["1234.2 "] = 1234.2 // no unit data[" kb "] = -1 // illegal value data["- kb"] = -1 // illegal value data["1234.2 aB"] = -1 // illegal unit data["1234.2 Packages"] = -1 // illegal unit data["1234.2 P."] = -1 // illegal unit for s, info := range data { size, err := Parse([]byte(s)) if err != nil { // fmt.Printf("%s\t%s\n", s, err) if err.Error() != ErrText || info != -1 { t.Error("unknown error type or test sample error") } } else { // check value if size != info { t.Error("value error") } } // fmt.Printf("%s\t%.2f\t%.2f\n", s, info, size) } } util-0.5.0/bytesize/LICENSE0000644000175000017500000000210314142163707014663 0ustar nileshnileshCopyright (c) 2013 Wei Shen (shenwei356@gmail.com) The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.util-0.5.0/.gitattributes0000755000175000017500000000074314142163707014726 0ustar nileshnilesh# Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp *.sln merge=union *.csproj merge=union *.vbproj merge=union *.fsproj merge=union *.dbproj merge=union # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain util-0.5.0/LICENSE0000644000175000017500000000210314142163707013025 0ustar nileshnileshCopyright (c) 2013 Wei Shen (shenwei356@gmail.com) The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.util-0.5.0/stats/0000755000175000017500000000000014142163707013162 5ustar nileshnileshutil-0.5.0/stats/quantile_test.go0000644000175000017500000000543614142163707016402 0ustar nileshnileshpackage stats import ( "math" "math/rand" "testing" stats2 "github.com/montanaflynn/stats" ) type testCase struct { data []float64 q1, median, q3 float64 min, max float64 } var cases = []testCase{ { data: []float64{}, median: 0, q1: 0, q3: 0, min: 0, max: 0, }, { data: []float64{2}, median: 2, q1: 1, q3: 1, min: 2, max: 2, }, { data: []float64{1, 2}, median: 1.5, q1: 1, q3: 2, min: 1, max: 2, }, { data: []float64{1, 2, 3}, median: 2, q1: 1.5, q3: 2.5, min: 1, max: 3, }, { data: []float64{1, 2, 3, 4}, median: 2.5, q1: 1.5, q3: 3.5, min: 1, max: 4, }, { data: []float64{2, 3, 4, 5, 6, 7, 8, 9}, median: 5.5, q1: 3.5, q3: 7.5, min: 2, max: 9, }, { data: []float64{0.5, 0.6, 0.7, 0.8, 0.8, 0.85, 0.9}, median: 0.8, q1: 0.65, q3: 0.825, min: 0.5, max: 0.9, }, { data: []float64{1, 0.8, 0.8, 0.85, 0.9}, median: 0.85, q1: 0.8, q3: 0.9, min: 0.8, max: 1, }, } func Test(t *testing.T) { for i, _case := range cases { rand.Shuffle(len(_case.data), func(i, j int) { _case.data[i], _case.data[j] = _case.data[j], _case.data[i] }) stats := NewQuantiler() for _, l := range _case.data { stats.Add(l) } if stats.Count() != uint64(len(_case.data)) { t.Errorf("case %d: count mismatch", i) } min := stats.Min() if min != _case.min { t.Errorf("case %d: min mismatch: %f != %f", i, min, _case.min) } max := stats.Max() if max != _case.max { t.Errorf("case %d: max mismatch: %f != %f", i, max, _case.max) } median := stats.Median() if math.Abs(median-_case.median) > 0.001 { t.Errorf("case %d: median mismatch: %f != %f", i, median, _case.median) } q1 := stats.Q1() if math.Abs(q1-_case.q1) > 0.001 { t.Errorf("case %d: q1 mismatch: %f != %f", i, q1, _case.q1) } q3 := stats.Q3() if math.Abs(q3-_case.q3) > 0.001 { t.Errorf("case %d: q3 mismatch: %f != %f", i, q3, _case.q3) } } } var cases2 = []testCase{ { data: []float64{}, }, { data: []float64{0.8}, }, { data: []float64{1, 2}, }, { data: []float64{1, 2, 3}, }, { data: []float64{1, 2, 3, 3, 4, 5, 6, 7, 5}, }, { data: []float64{0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 7, 4, 2, 1, 4, 5, 6, 6, 4, 2, 2, 4, 10}, }, } func Test2(t *testing.T) { for i, _case := range cases2 { rand.Shuffle(len(_case.data), func(i, j int) { _case.data[i], _case.data[j] = _case.data[j], _case.data[i] }) stats := NewQuantiler() for _, l := range _case.data { stats.Add(l) } p90 := stats.Percentile(90) pp90, _ := stats2.Percentile(_case.data, 90) if math.Abs(p90-pp90) > 0.001 { t.Errorf("case %d: p90 mismatch: %f != %f", i, p90, pp90) } } } util-0.5.0/stats/quantile.go0000644000175000017500000001176114142163707015341 0ustar nileshnileshpackage stats import ( "math" "github.com/twotwotwo/sorts" ) type valueCount struct { Value, Count float64 } type valueCounts []valueCount func (c valueCounts) Len() int { return len(c) } func (c valueCounts) Less(i, j int) bool { return c[i].Value < c[j].Value } func (c valueCounts) Swap(i, j int) { c[i], c[j] = c[j], c[i] } type Quantiler struct { count map[float64]float64 // value -> count n uint64 // n min, max, sum float64 // sum // for sorting counts []valueCount // value, count accCounts []valueCount // value, accumulative count sorted bool } // NewQuantiler initializes a Quantiler func NewQuantiler() *Quantiler { return &Quantiler{count: make(map[float64]float64, 1024), min: math.MaxFloat64} } // Add adds a new element func (stats *Quantiler) Add(value float64) { stats.n++ stats.sum += value stats.count[value]++ if value > stats.max { stats.max = value } if value < stats.min { stats.min = value } stats.sorted = false } func (stats *Quantiler) sort() { stats.counts = make([]valueCount, 0, len(stats.count)) for value, count := range stats.count { stats.counts = append(stats.counts, valueCount{value, count}) } sorts.Quicksort(valueCounts(stats.counts)) stats.accCounts = make([]valueCount, len(stats.count)) for i, data := range stats.counts { if i == 0 { stats.accCounts[i] = valueCount{data.Value, data.Count} } else { stats.accCounts[i] = valueCount{data.Value, data.Count + stats.accCounts[i-1].Count} } } stats.sorted = true } // Count returns number of elements func (stats *Quantiler) Count() uint64 { return stats.n } // Min returns the minimum value func (stats *Quantiler) Min() float64 { if stats.n == 0 { return 0 } return stats.min } // Max returns the maxinimum length func (stats *Quantiler) Max() float64 { return stats.max } // Sum returns the sum func (stats *Quantiler) Sum() float64 { return stats.sum } // Mean returns mean func (stats *Quantiler) Mean() float64 { return float64(stats.sum) / float64(stats.n) } // Q2 returns Q2 func (stats *Quantiler) Q2() float64 { return stats.Median() } // Median returns median func (stats *Quantiler) Median() float64 { if !stats.sorted { stats.sort() } if len(stats.counts) == 0 { return 0 } if len(stats.counts) == 1 { return float64(stats.counts[0].Value) } even := stats.n&1 == 0 // %2 == 0 var iMedianL, iMedianR uint64 // 0-based if even { iMedianL = uint64(stats.n/2) - 1 // 3 iMedianR = uint64(stats.n / 2) // 4 } else { iMedianL = uint64(stats.n / 2) } return stats.getValue(even, iMedianL, iMedianR) } // Q1 returns Q1 func (stats *Quantiler) Q1() float64 { if !stats.sorted { stats.sort() } if len(stats.counts) == 0 { return 0 } if len(stats.counts) == 1 { return float64(stats.counts[0].Value) / 2 } even := stats.n&1 == 0 // %2 == 0 var iMedianL, iMedianR uint64 // 0-based var n uint64 if even { n = stats.n / 2 } else { n = (stats.n + 1) / 2 } even = n%2 == 0 if even { iMedianL = uint64(n/2) - 1 iMedianR = uint64(n / 2) } else { iMedianL = uint64(n / 2) } return stats.getValue(even, iMedianL, iMedianR) } // Q3 returns Q3 func (stats *Quantiler) Q3() float64 { if !stats.sorted { stats.sort() } if len(stats.counts) == 0 { return 0 } if len(stats.counts) == 1 { return float64(stats.counts[0].Value) / 2 } even := stats.n&1 == 0 // %2 == 0 var iMedianL, iMedianR uint64 // 0-based var mean, n uint64 if even { n = stats.n / 2 mean = n } else { n = (stats.n + 1) / 2 mean = stats.n / 2 } even = n%2 == 0 if even { iMedianL = uint64(n/2) - 1 + mean iMedianR = uint64(n/2) + mean } else { iMedianL = uint64(n/2) + mean } return stats.getValue(even, iMedianL, iMedianR) } func (stats *Quantiler) getValue(even bool, iMedianL uint64, iMedianR uint64) float64 { var accCount float64 var flag bool var prev float64 for _, data := range stats.accCounts { accCount = data.Count if flag { // the middle two having different value. // example: 1, 2, 3, 4 or 1, 2 return (data.Value + prev) / 2 } if accCount >= float64(iMedianL+1) { if even { if accCount >= float64(iMedianR+1) { // having >=2 of same value in the middle. // example: 2, 2, 2, 3, 3, 4, 8, 8 return data.Value } flag = true prev = data.Value } else { // right here return data.Value } } } // never happen // panic("should never happen") return 0 } func (stats *Quantiler) Percentile(percent float64) float64 { if percent <= 0 || percent > 100 { panic("invalid percentile") } if !stats.sorted { stats.sort() } if len(stats.counts) == 0 { return 0 } if len(stats.counts) == 1 { return float64(stats.counts[0].Value) } i0 := float64(stats.n) * percent / 100 i := math.Floor(i0) even := math.Abs(i0-i) > 0.001 var iMedianL, iMedianR uint64 // 0-based if even { iMedianL = uint64(i) - 1 iMedianR = uint64(i) } else { iMedianL = uint64(i - 1) } return stats.getValue(even, iMedianL, iMedianR) } util-0.5.0/byteutil/0000755000175000017500000000000014142163707013665 5ustar nileshnileshutil-0.5.0/byteutil/struct.go0000644000175000017500000000111714142163707015540 0ustar nileshnileshpackage byteutil import "bytes" // SliceOfByteSlice is [][]byte type SliceOfByteSlice [][]byte func (s SliceOfByteSlice) Len() int { return len(s) } func (s SliceOfByteSlice) Less(i, j int) bool { c := bytes.Compare(s[i], s[j]) if c == -1 { return true } return false } func (s SliceOfByteSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // ByteSlice is []byte type ByteSlice []byte func (bs ByteSlice) Len() int { return len(bs) } func (bs ByteSlice) Less(i, j int) bool { return bs[i] < bs[j] } func (bs ByteSlice) Swap(i, j int) { bs[i], bs[j] = bs[j], bs[i] } util-0.5.0/byteutil/alphabet.go0000644000175000017500000000106214142163707015773 0ustar nileshnileshpackage byteutil import "sort" // Alphabet returns the alphabet of a byte slice func Alphabet(s []byte) []byte { count := CountOfByte(s) letters := make([]byte, len(count)) i := 0 for b := range count { letters[i] = b i++ } sort.Sort(ByteSlice(letters)) return letters } // AlphabetFromCountOfByte returns the alphabet of a byte slice from count func AlphabetFromCountOfByte(count map[byte]int) []byte { letters := make([]byte, len(count)) i := 0 for b := range count { letters[i] = b i++ } sort.Sort(ByteSlice(letters)) return letters } util-0.5.0/byteutil/byte_coder_test.go0000644000175000017500000000076614142163707017403 0ustar nileshnileshpackage byteutil import ( "testing" ) func TestByteCoder(t *testing.T) { coder, err := NewByteCoder([]byte("acgtryswkmbdhvACGTRYSWKMBDHV")) if err != nil { t.Error(err) } dna2int, err := coder.Encode([]byte("Jj")) if err != ErrInvalideLetter { t.Error(err) } dna2int, err = coder.Encode([]byte("acTg")) if err != nil { t.Error(err) } int2dna, err := coder.Decode(dna2int) if err != nil { t.Error(err) } if string(int2dna) != "acTg" { t.Errorf("ByteCoder test error") } } util-0.5.0/byteutil/byte_coder.go0000644000175000017500000000411214142163707016331 0ustar nileshnileshpackage byteutil import ( "fmt" "sort" ) var ( // ErrInvalideLetter means invalid letter ErrInvalideLetter = fmt.Errorf("ByteCoder: invalid letter") // ErrInvalideCode means invalid code ErrInvalideCode = fmt.Errorf("ByteCoder: invalid code") ) // ByteCoder is used to convert betweeen byte and int type ByteCoder struct { Alphabet []byte alphabetQuerySlice []byte bytes2int []int int2bytes []byte } // NewByteCoder Create a ByteCoder type func NewByteCoder(alphabet []byte) (*ByteCoder, error) { if len(alphabet) == 0 { return nil, fmt.Errorf("ByteCoder: alphabet should not be empty") } m := make(map[byte]struct{}, len(alphabet)) for _, a := range alphabet { m[a] = struct{}{} } max := -1 var b int for a := range m { b = int(a) if max < b { max = b } } alphabet2 := make([]byte, len(m)) slice := make([]byte, max+1) i := 0 for a := range m { slice[a-'\x00'] = a alphabet2[i] = a i++ } sort.Sort(ByteSlice(alphabet2)) bytes2int := make([]int, max+1) int2bytes := make([]byte, len(m)) for i, a := range alphabet2 { bytes2int[a-'\x00'] = i int2bytes[i] = a } return &ByteCoder{Alphabet: alphabet2, alphabetQuerySlice: slice, bytes2int: bytes2int, int2bytes: int2bytes}, nil } func (coder *ByteCoder) String() string { return fmt.Sprintf(`ByteCoder: alphabet:"%s" num:%d`, coder.Alphabet, len(coder.Alphabet)) } // Encode converts []byte to []int func (coder *ByteCoder) Encode(s []byte) ([]int, error) { code := make([]int, len(s)) for i, b := range s { if int(b) > len(coder.alphabetQuerySlice) { return nil, ErrInvalideLetter } v := coder.alphabetQuerySlice[b-'\x00'] if v == 0 { return nil, ErrInvalideLetter } code[i] = coder.bytes2int[v] } return code, nil } // Decode convert []int to []byte func (coder *ByteCoder) Decode(code []int) ([]byte, error) { bytes := make([]byte, len(code)) for i, b := range code { if b >= len(coder.int2bytes) { return nil, ErrInvalideCode } v := coder.int2bytes[b] if v == 0 { return nil, ErrInvalideCode } bytes[i] = v } return bytes, nil } util-0.5.0/byteutil/count_test.go0000644000175000017500000000152714142163707016410 0ustar nileshnileshpackage byteutil import "testing" func TestCountOfByteAndAlphabet(t *testing.T) { s := []byte("abcdefadfwefasdga") count := CountOfByte(s) alphabet := Alphabet(s) sum := 0 for _, letter := range alphabet { sum += count[letter] } if sum != len(s) { t.Error("Test failed: TestCountOfByteAndAlphabet") } } func TestSortCountOfByte(t *testing.T) { s := []byte("cccaaadd") countList := SortCountOfByte(CountOfByte(s), true) // fmt.Println(countList) // if !(countList[0].Count == 3 && (countList[0].Key == 'a' || countList[0].Key == 'c')) { if !(countList[0].Count == 3 && countList[0].Key == 'a') { t.Error("Test failed: TestSortCountOfByte") } countList = SortCountOfByte(CountOfByte(s), false) // fmt.Println(countList) if !(countList[0].Key == 'd' && countList[0].Count == 2) { t.Error("Test failed: TestSortCountOfByte") } } util-0.5.0/byteutil/util_test.go0000644000175000017500000000073614142163707016236 0ustar nileshnileshpackage byteutil import "testing" func TestSubSlice(t *testing.T) { s := []byte("0123456789") if true && string(SubSlice(s, 0, 0)) == "0123456789" && string(SubSlice(s, 0, 1)) == "0" && string(SubSlice(s, 1, 2)) == "1" && string(SubSlice(s, -2, -1)) == "8" && string(SubSlice(s, len(s)-1, len(s))) == "9" && string(SubSlice(s, -1, 0)) == "9" && // different from python string(SubSlice(s, 7, -1)) == "78" && true { } else { t.Error("SubSlice error") } } util-0.5.0/byteutil/util.go0000644000175000017500000001042314142163707015171 0ustar nileshnileshpackage byteutil import ( "bytes" // "fmt" "unsafe" ) // ReverseByteSlice reverses a byte slice func ReverseByteSlice(s []byte) []byte { // make a copy of s l := len(s) t := make([]byte, l) for i := 0; i < l; i++ { t[i] = s[i] } // reverse for i, j := 0, l-1; i < j; i, j = i+1, j-1 { t[i], t[j] = t[j], t[i] } return t } // ReverseByteSliceInplace reverses a byte slice func ReverseByteSliceInplace(s []byte) { // reverse for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } } var _newline = []byte{'\n'} // WrapByteSlice wraps byte slice func WrapByteSlice(s []byte, width int) []byte { if width < 1 { return s } l := len(s) if l == 0 { return s } var lines int if l%width == 0 { lines = l/width - 1 } else { lines = int(l / width) } // var buffer bytes.Buffer buffer := bytes.NewBuffer(make([]byte, 0, l+lines)) var start, end int for i := 0; i <= lines; i++ { start = i * width end = (i + 1) * width if end > l { end = l } buffer.Write(s[start:end]) if i < lines { // buffer.WriteString("\n") buffer.Write(_newline) } } return buffer.Bytes() } // WrapByteSlice2 wraps byte slice, it reuses the bytes.Buffer func WrapByteSlice2(s []byte, width int, buffer *bytes.Buffer) ([]byte, *bytes.Buffer) { if width < 1 { return s, buffer } l := len(s) if l == 0 { return s, buffer } var lines int if l%width == 0 { lines = l/width - 1 } else { lines = int(l / width) } if buffer == nil { buffer = bytes.NewBuffer(make([]byte, 0, l+lines)) } else { buffer.Reset() } var start, end int for i := 0; i <= lines; i++ { start = i * width end = (i + 1) * width if end > l { end = l } buffer.Write(s[start:end]) if i < lines { buffer.Write(_newline) } } return buffer.Bytes(), buffer } // SubSlice provides similar slice indexing as python with one exception // that end could be equal to 0. // So we could get the last element by SubSlice(s, -1, 0) // or get the whole element by SubSlice(s, 0, 0) func SubSlice(slice []byte, start int, end int) []byte { if start == 0 && end == 0 { return slice } if start == end || (start < 0 && end > 0) { return []byte{} } l := len(slice) s, e := start, end if s < 0 { s = l + s if s < 1 { s = 0 } } if e < 0 { e = l + e if e < 0 { e = 0 } } if e == 0 || e > l { e = l } return slice[s:e] } // ByteToLower lowers a byte func ByteToLower(b byte) byte { if b <= '\u007F' { if 'A' <= b && b <= 'Z' { b += 'a' - 'A' } return b } return b } // ByteToUpper upper a byte func ByteToUpper(b byte) byte { if b <= '\u007F' { if 'a' <= b && b <= 'z' { b -= 'a' - 'A' } return b } return b } // MakeQuerySlice is used to replace map. // see: http://blog.shenwei.me/map-is-not-the-fastest-in-go/ func MakeQuerySlice(letters []byte) []byte { max := -1 for i := 0; i < len(letters); i++ { j := int(letters[i]) if max < j { max = j } } querySlice := make([]byte, max+1) for i := 0; i < len(letters); i++ { querySlice[int(letters[i])] = letters[i] } return querySlice } // Split splits a byte slice by giveen letters. // It's much faster than regexp.Split func Split(slice []byte, letters []byte) [][]byte { querySlice := MakeQuerySlice(letters) results := [][]byte{} tmp := []byte{} var j int var value byte var sliceSize = len(querySlice) for _, b := range slice { j = int(b) if j >= sliceSize { // not delimiter byte tmp = append(tmp, b) continue } value = querySlice[j] if value == 0 { // not delimiter byte tmp = append(tmp, b) continue } else { if len(tmp) > 0 { results = append(results, tmp) tmp = []byte{} } } } if len(tmp) > 0 { results = append(results, tmp) } return results } // Bytes2Str convert byte slice to string without GC. Warning: it's unsafe!!! func Bytes2Str(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } // CountBytes counts given ASCII characters in a byte slice func CountBytes(seq, letters []byte) int { if len(letters) == 0 || len(seq) == 0 { return 0 } // do not use map querySlice := make([]byte, 256) for i := 0; i < len(letters); i++ { querySlice[int(letters[i])] = letters[i] } var g byte var n int for i := 0; i < len(seq); i++ { g = querySlice[int(seq[i])] if g > 0 { // not gap n++ } } return n } util-0.5.0/byteutil/count.go0000644000175000017500000000324114142163707015344 0ustar nileshnileshpackage byteutil import "sort" // ByteCount is a struct store count of byte type ByteCount struct { Key byte Count int } // ByteCountList is slice of ByteCount type ByteCountList []ByteCount func (b ByteCountList) Len() int { return len(b) } func (b ByteCountList) Less(i, j int) bool { // return b[i].Count < b[j].Count // This will return unwanted result: return b[i].Count < b[j].Count || b[i].Key < b[j].Key if b[i].Count < b[j].Count { return true } if b[i].Count == b[j].Count { if b[i].Key < b[j].Key { return true } return false } return false } func (b ByteCountList) Swap(i, j int) { b[i], b[j] = b[j], b[i] } // ReversedByteCountList is Reversed ByteCountList type ReversedByteCountList struct { ByteCountList } // Less is different from the Less of ByteCountList func (b ReversedByteCountList) Less(i, j int) bool { // return b.ByteCountList[i].Count > b.ByteCountList[j].Count if b.ByteCountList[i].Count > b.ByteCountList[j].Count { return true } if b.ByteCountList[i].Count == b.ByteCountList[j].Count { if b.ByteCountList[i].Key < b.ByteCountList[j].Key { return true } return false } return false } // CountOfByte returns the count of byte for a byte slice func CountOfByte(s []byte) map[byte]int { count := make(map[byte]int) for _, b := range s { count[b]++ } return count } // SortCountOfByte sorts count of byte func SortCountOfByte(count map[byte]int, reverse bool) ByteCountList { countList := make(ByteCountList, len(count)) i := 0 for b, c := range count { countList[i] = ByteCount{b, c} i++ } if reverse { sort.Sort(ReversedByteCountList{countList}) } else { sort.Sort(countList) } return countList }