diff --git a/go.mod b/go.mod
index 290a65187..231de7eb1 100644
--- a/go.mod
+++ b/go.mod
@@ -3,17 +3,14 @@ module github.com/xiaomi/naftis
go 1.12
require (
- github.com/Azure/go-autorest v12.2.0+incompatible // indirect
github.com/cenkalti/backoff v2.1.1+incompatible // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dvwright/xss-mw v0.0.0-20170109072128-5b2fd362dcaf
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
github.com/ghodss/yaml v1.0.0
- github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 // indirect
- github.com/gin-gonic/gin v1.3.0
+ github.com/gin-gonic/gin v1.7.7
github.com/gorilla/websocket v1.4.1
github.com/hashicorp/go-multierror v1.0.0
- github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect
github.com/jinzhu/gorm v1.9.1
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
github.com/jinzhu/now v1.0.0 // indirect
@@ -25,9 +22,6 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.5.1
- gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
- gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
- gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
istio.io/istio v0.0.0-20200708154433-f508fdd78eb0
k8s.io/api v0.18.1
k8s.io/apimachinery v0.18.1
diff --git a/go.sum b/go.sum
index 4149534d0..d4e36b3cb 100644
--- a/go.sum
+++ b/go.sum
@@ -1,8 +1,6 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.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.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
-cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
@@ -24,7 +22,6 @@ fortio.org/fortio v1.3.1/go.mod h1:Go0fRqoPJ1xy5JOWcS23jyF58byVZxFyEePYsGmCR0k=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
-github.com/Azure/go-autorest v12.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.9.4/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
@@ -46,12 +43,10 @@ github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YH
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/Masterminds/sprig v2.14.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig v2.20.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA=
github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
-github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -69,12 +64,9 @@ github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4Rq
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
-github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
-github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
github.com/antlr/antlr4 v0.0.0-20190819145818-b43a4c3a8015/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
-github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -86,7 +78,6 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -114,7 +105,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.4/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533 h1:8wZizuKuZVu5COB7EsBYxBQz8nRcXXn5d4Gt91eJLvU=
github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -147,6 +137,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
+github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -155,8 +146,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
-github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02 h1:PS3xfVPa8N84AzoWZHFCbA0+ikz4f4skktfjQoNMsgk=
-github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY=
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@@ -198,7 +188,6 @@ github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
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 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.5-0.20200326174812-e8bd2869ff56 h1:SX76iRBhEsRqbtli8FMEbotrLPVGkzxd9lssASy0fko=
github.com/envoyproxy/go-control-plane v0.9.5-0.20200326174812-e8bd2869ff56/go.mod h1:OXl5to++W0ctG+EHWTFUjiypVxC/Y4VLc/KFU+al13s=
@@ -207,6 +196,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
@@ -217,14 +207,13 @@ github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
-github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
-github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
-github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
-github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
+github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -281,8 +270,15 @@ github.com/go-openapi/swag v0.19.6/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfT
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
+github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -297,39 +293,32 @@ github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kE
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
-github.com/gogo/googleapis v1.0.0 h1:7wwW6yQ5xmZE42/QWNC87xHgnHxIh7pWvtc1BhI/0DU=
-github.com/gogo/googleapis v1.0.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
-github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE=
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/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/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
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.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
@@ -343,23 +332,14 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//
github.com/gomodule/redigo v1.8.0/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
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/cel-go v0.2.0/go.mod h1:fTCVOuSN/Vn6d49zvRpr3fDAKFyfpLViE0gU+9Vtm7g=
github.com/google/cel-go v0.4.1/go.mod h1:F0UncVAXNlNjl/4C8hqGdoV6APmuFpetoMJSLIQLBPU=
-github.com/google/cel-spec v0.2.0/go.mod h1:MjQm800JAGhOZXI7vatnVpmIaFTR6L8FHcKk+piiKpI=
github.com/google/cel-spec v0.3.0/go.mod h1:MjQm800JAGhOZXI7vatnVpmIaFTR6L8FHcKk+piiKpI=
-github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
-github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
-github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
-github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
-github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -368,28 +348,24 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
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/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
-github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
-github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
-github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -407,8 +383,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20171214222146-0e7658f8ee99/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/consul v1.3.1/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357 h1:Rem2+U35z1QtPQc6r+WolF7yXiefXqDKyk+lN2pE164=
-github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
@@ -419,8 +393,6 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
-github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0 h1:j30noezaCfvNLcdMYSvHLv81DxYRSt1grlpseG67vhU=
-github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
@@ -434,13 +406,10 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
-github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
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/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
-github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
@@ -452,17 +421,11 @@ github.com/hashicorp/vault/sdk v0.1.12/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
-github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
-github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.2.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/imdario/mergo v0.0.0-20141206190957-6633656539c1 h1:FeeCi0I2Fu8kA8IXrdVPtGzym+mW9bzfj9f26EaES9k=
-github.com/imdario/mergo v0.0.0-20141206190957-6633656539c1/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
-github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
@@ -480,8 +443,6 @@ github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhB
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE=
-github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -507,16 +468,16 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
-github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -529,7 +490,6 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -541,10 +501,8 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
-github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do=
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
github.com/microcosm-cc/bluemonday v1.0.0 h1:dr58SIfmOwOVr+m4Ye1xLWv8Dk9OFwXAtYnbJSmJ65k=
@@ -558,8 +516,6 @@ github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699 h1:KXZJFdun9knAVAR8tg/aHJEr5DgtcbqyvzacK+CDCaI=
-github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
@@ -570,7 +526,6 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -579,8 +534,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/natefinch/lumberjack v0.0.0-20170531160350-a96e63847dc3 h1:BDvcX7oM8ZWOS08LQXaW8ucGblfoSG4srpoW6pKhvqs=
-github.com/natefinch/lumberjack v0.0.0-20170531160350-a96e63847dc3/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
@@ -596,14 +549,15 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/open-policy-agent/opa v0.8.2/go.mod h1:rlfeSeHuZmMEpmrcGla42AjkOUjP4rGIpS96H12un3o=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -622,7 +576,6 @@ github.com/openzipkin/zipkin-go v0.1.7/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
-github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.3.0 h1:e5+lF2E4Y2WCIxBefVowBuB0iHrUH4HZ8q+6mGF7fJc=
github.com/pelletier/go-toml v1.3.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
@@ -634,8 +587,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
github.com/pierrec/lz4 v2.2.7+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -647,7 +600,6 @@ github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prY
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
-github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM=
@@ -655,9 +607,7 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -666,7 +616,6 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -675,7 +624,6 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -715,37 +663,26 @@ github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
-github.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I=
-github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
-github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
-github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=
-github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
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.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=
-github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
@@ -754,10 +691,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
@@ -769,8 +704,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
-github.com/ugorji/go v1.1.1 h1:gmervu+jDMvXTbcHQ0pd2wee85nEoE0BsVyEuzkfK8w=
-github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
@@ -792,7 +725,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
github.com/yashtewari/glob-intersection v0.0.0-20180206001645-7af743e8ec84/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co=
github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 h1:lkoOjizoHqOcEFsvYGE5c8Ykdijjnd0R3r1yDYHzLno=
github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268/go.mod h1:mq0zhomp/G6rRTb0dvHWXRHr/2+Qgeq5hMXfJ670+i4=
-github.com/yuin/gopher-lua v0.0.0-20180316054350-84ea3a3c79b3/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
@@ -812,7 +744,6 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -820,8 +751,6 @@ go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.9.0 h1:WciNIN5xKjsLnAkg/+UngCXim8pdyhP/4QwycrDzQlQ=
-go.uber.org/zap v1.9.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -832,7 +761,6 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/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=
@@ -841,12 +769,12 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/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-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+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-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -881,7 +809,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/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 h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -901,7 +828,6 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -909,9 +835,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
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-20190412183630-56d357773e84 h1:IqXQ59gzdXv58Jmm2xn0tSOR9i6HqroaOFRQ3wR/dJQ=
-golang.org/x/sync v0.0.0-20190412183630-56d357773e84/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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -928,7 +853,6 @@ golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -957,18 +881,14 @@ golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w=
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1002,6 +922,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
@@ -1016,9 +937,7 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
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/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
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=
@@ -1027,10 +946,7 @@ google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpC
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190227213309-4f5b463f9597/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/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=
@@ -1046,7 +962,6 @@ google.golang.org/genproto v0.0.0-20191223191004-3caeed10a8bf/go.mod h1:n3cpQtvx
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
-google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1056,7 +971,6 @@ google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
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.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
@@ -1064,21 +978,18 @@ google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0=
gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
-gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
-gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
-gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
-gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -1088,21 +999,19 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
-gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
helm.sh/helm/v3 v3.2.0/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1111,77 +1020,44 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
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=
-istio.io/api v0.0.0-20180730173215-123b0a79a4db h1:tJr6kUSwplvWjubZo77W8r641oE186qSqdnfxfF+PY8=
-istio.io/api v0.0.0-20180730173215-123b0a79a4db/go.mod h1:hhLFQmpHia8zgaM37vb2ml9iS5NfNfqZGRt1pS9aVEo=
istio.io/api v0.0.0-20190515205759-982e5c3888c6/go.mod h1:hhLFQmpHia8zgaM37vb2ml9iS5NfNfqZGRt1pS9aVEo=
-istio.io/api v0.0.0-20200227213531-891bf31f3c32 h1:Kbv2woZ1iw8s4JSz/WgcLEUVmBjQDneL/EB3k5jhU+A=
-istio.io/api v0.0.0-20200227213531-891bf31f3c32/go.mod h1:bcY3prusO/6vA6zGHz4PNG2v79clPyTw06Xx3fprJSQ=
istio.io/api v0.0.0-20200708135631-b736e804afd1 h1:GvIZ4goWRTAW/NUjtCVF61C1wnb4Ky2MvF+votyjFvM=
istio.io/api v0.0.0-20200708135631-b736e804afd1/go.mod h1:kyq3g5w42zl/AKlbzDGppYpGMQYMYMyZKeq0/eexML8=
istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
-istio.io/gogo-genproto v0.0.0-20200130224810-a0338448499a h1:WQLbIB0tZSOwAILzqBG9/A7rq+wwTA8a1nqfTmQQSU8=
-istio.io/gogo-genproto v0.0.0-20200130224810-a0338448499a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
istio.io/gogo-genproto v0.0.0-20200511213158-02f1fd1746e5 h1:+jL9OzDdbpqHghV6i1dDy2jV+FtC7wz+CuKi2UxZoSs=
istio.io/gogo-genproto v0.0.0-20200511213158-02f1fd1746e5/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
-istio.io/istio v0.0.0-20180723195305-a66a221bfe4c h1:PlzTB39zApeF0TkISdSO64Mwib+ce+Qeyh8b7pW7s1Q=
-istio.io/istio v0.0.0-20180723195305-a66a221bfe4c/go.mod h1:OWBySrQjjk549IhxWCt7DTl9ZSsXdvbgm+SmgGVRsGA=
-istio.io/istio v0.0.0-20200304114959-c3c353285578 h1:hP6FZr8yk1mEYskTKuriab9VdjvxSD57nlZWNLTOrMc=
-istio.io/istio v0.0.0-20200304114959-c3c353285578/go.mod h1:CiQvu6hLKkn0J9S0vaCwT+JLPL3ls1O5wL4WrPoGtTM=
istio.io/istio v0.0.0-20200708154433-f508fdd78eb0 h1:YU5kd/z1QIcpjgFIF782KRYRY/1Ox8APeenEBBAuc+o=
istio.io/istio v0.0.0-20200708154433-f508fdd78eb0/go.mod h1:9LOBG72wGBsM3L++suW2dDmomc5E25UpvzGoBe7e950=
-istio.io/pkg v0.0.0-20200204185554-47b6d38ec784 h1:jAQeN+aokzbSL1TsIwXcxy4fIwDoVK/epvGZ92X9qmI=
-istio.io/pkg v0.0.0-20200204185554-47b6d38ec784/go.mod h1:pwGaxLUDLobzL/WvWV94z72LvBbB1dr2UUUyPuasfIU=
istio.io/pkg v0.0.0-20200511212725-7bfbbf968c23 h1:1GMOTQs9yVdNEBmVKxDlq6ios80gIAOMO1WfKYKYjZo=
istio.io/pkg v0.0.0-20200511212725-7bfbbf968c23/go.mod h1:pwGaxLUDLobzL/WvWV94z72LvBbB1dr2UUUyPuasfIU=
-k8s.io/api v0.0.0-20180601181742-8b7507fac302 h1:Qt1IyBlZWyVK+Xa3yoHb0G7sW6E3+7Zem32d4siDB1M=
-k8s.io/api v0.0.0-20180601181742-8b7507fac302/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
-k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc=
-k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
k8s.io/api v0.18.1 h1:pnHr0LH69kvL29eHldoepUDKTuiOejNZI2A1gaxve3Q=
k8s.io/api v0.18.1/go.mod h1:3My4jorQWzSs5a+l7Ge6JBbIxChLnY8HnuT58ZWolss=
-k8s.io/apiextensions-apiserver v0.0.0-20180601203502-8e7f43002fec h1:4IEgYOmlFYZPBdm6KW6UO6mxqTAoAaSuighdxs9sO38=
-k8s.io/apiextensions-apiserver v0.0.0-20180601203502-8e7f43002fec/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=
-k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6Kolpss=
-k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs=
k8s.io/apiextensions-apiserver v0.18.0 h1:HN4/P8vpGZFvB5SOMuPPH2Wt9Y/ryX+KRvIyAkchu1Q=
k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo=
-k8s.io/apimachinery v0.0.0-20180601181227-17529ec7eadb h1:wNISiSgK+4mXexgcfqVaOQgIAOwVzlUGizWC9XCNEQA=
-k8s.io/apimachinery v0.0.0-20180601181227-17529ec7eadb/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4=
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
-k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
-k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.1 h1:hKPYcQRPLQoG2e7fKkVl0YCvm9TBefXTfGILa9vjVVk=
k8s.io/apimachinery v0.18.1/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
-k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw=
-k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ=
-k8s.io/client-go v0.0.0-20180619232744-a312bfe35c40 h1:FgAFNLxLkmzw2L7Z0Ql7bBJJjlBt+oYgd3cybjAqlTs=
-k8s.io/client-go v0.0.0-20180619232744-a312bfe35c40/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
-k8s.io/client-go v0.17.2 h1:ndIfkfXEGrNhLIgkr0+qhRguSD3u6DCmonepn1O6NYc=
-k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE=
k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
-k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA=
-k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs=
k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/helm v2.14.3+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
@@ -1191,13 +1067,10 @@ k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKf
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
-k8s.io/kubectl v0.17.2/go.mod h1:y4rfLV0n6aPmvbRCqZQjvOp3ezxsFgpqL+zF5jH/lxk=
k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
-k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw=
k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
-k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
@@ -1218,12 +1091,10 @@ sigs.k8s.io/service-apis v0.0.0-20200227172328-b9010cfacdbe/go.mod h1:fkpFab5voE
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
-sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
-sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/vendor/github.com/gin-contrib/sse/.travis.yml b/vendor/github.com/gin-contrib/sse/.travis.yml
index a556ac09e..d0e8fcf99 100644
--- a/vendor/github.com/gin-contrib/sse/.travis.yml
+++ b/vendor/github.com/gin-contrib/sse/.travis.yml
@@ -1,15 +1,26 @@
language: go
sudo: false
go:
- - 1.6.4
- - 1.7.4
- - tip
+ - 1.8.x
+ - 1.9.x
+ - 1.10.x
+ - 1.11.x
+ - 1.12.x
+ - master
git:
- depth: 3
+ depth: 10
+
+matrix:
+ fast_finish: true
+ include:
+ - go: 1.11.x
+ env: GO111MODULE=on
+ - go: 1.12.x
+ env: GO111MODULE=on
script:
- go test -v -covermode=count -coverprofile=coverage.out
after_success:
- - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/gin-contrib/sse/go.mod b/vendor/github.com/gin-contrib/sse/go.mod
new file mode 100644
index 000000000..b9c03f47d
--- /dev/null
+++ b/vendor/github.com/gin-contrib/sse/go.mod
@@ -0,0 +1,5 @@
+module github.com/gin-contrib/sse
+
+go 1.12
+
+require github.com/stretchr/testify v1.3.0
diff --git a/vendor/github.com/gin-contrib/sse/go.sum b/vendor/github.com/gin-contrib/sse/go.sum
new file mode 100644
index 000000000..4347755af
--- /dev/null
+++ b/vendor/github.com/gin-contrib/sse/go.sum
@@ -0,0 +1,7 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/vendor/github.com/gin-gonic/gin/.gitignore b/vendor/github.com/gin-gonic/gin/.gitignore
index 14dc8f20d..bdd50c95c 100644
--- a/vendor/github.com/gin-gonic/gin/.gitignore
+++ b/vendor/github.com/gin-gonic/gin/.gitignore
@@ -3,3 +3,5 @@ vendor/*
coverage.out
count.out
test
+profile.out
+tmp.out
diff --git a/vendor/github.com/gin-gonic/gin/.travis.yml b/vendor/github.com/gin-gonic/gin/.travis.yml
index e91015685..bcc21414d 100644
--- a/vendor/github.com/gin-gonic/gin/.travis.yml
+++ b/vendor/github.com/gin-gonic/gin/.travis.yml
@@ -1,25 +1,38 @@
language: go
-sudo: false
-go:
- - 1.6.x
- - 1.7.x
- - 1.8.x
- - 1.9.x
- - 1.10.x
- - master
+
+matrix:
+ fast_finish: true
+ include:
+ - go: 1.13.x
+ - go: 1.13.x
+ env:
+ - TESTTAGS=nomsgpack
+ - go: 1.14.x
+ - go: 1.14.x
+ env:
+ - TESTTAGS=nomsgpack
+ - go: 1.15.x
+ - go: 1.15.x
+ env:
+ - TESTTAGS=nomsgpack
+ - go: master
git:
depth: 10
+before_install:
+ - if [[ "${GO111MODULE}" = "on" ]]; then mkdir "${HOME}/go"; export GOPATH="${HOME}/go"; fi
+
install:
- - make install
+ - if [[ "${GO111MODULE}" = "on" ]]; then go mod download; fi
+ - if [[ "${GO111MODULE}" = "on" ]]; then export PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}"; fi
+ - if [[ "${GO111MODULE}" = "on" ]]; then make tools; fi
go_import_path: github.com/gin-gonic/gin
script:
- make vet
- make fmt-check
- - make embedmd
- make misspell-check
- make test
diff --git a/vendor/github.com/gin-gonic/gin/AUTHORS.md b/vendor/github.com/gin-gonic/gin/AUTHORS.md
index dda19bcf3..c634e6be0 100644
--- a/vendor/github.com/gin-gonic/gin/AUTHORS.md
+++ b/vendor/github.com/gin-gonic/gin/AUTHORS.md
@@ -156,7 +156,7 @@ People and companies, who have contributed, in alphabetical order.
- Fix variadic parameter in the flexible render API
- Fix Corrupted plain render
- Add Pluggable View Renderer Example
-
+
**@msemenistyi (Mykyta Semenistyi)**
- update Readme.md. Add code to String method
@@ -190,6 +190,8 @@ People and companies, who have contributed, in alphabetical order.
**@rogierlommers (Rogier Lommers)**
- Add updated static serve example
+**@rw-access (Ross Wolf)**
+- Added support to mix exact and param routes
**@se77en (Damon Zhao)**
- Improve color logging
diff --git a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md
index 9a7df86a3..c11ee99ae 100644
--- a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md
+++ b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md
@@ -1,604 +1,666 @@
-## Benchmark System
+# Benchmark System
-**VM HOST:** DigitalOcean
-**Machine:** 4 CPU, 8 GB RAM. Ubuntu 16.04.2 x64
-**Date:** July 19th, 2017
-**Go Version:** 1.8.3 linux/amd64
-**Source:** [Go HTTP Router Benchmark](https://github.com/julienschmidt/go-http-routing-benchmark)
+**VM HOST:** Travis
+**Machine:** Ubuntu 16.04.6 LTS x64
+**Date:** May 04th, 2020
+**Version:** Gin v1.6.3
+**Go Version:** 1.14.2 linux/amd64
+**Source:** [Go HTTP Router Benchmark](https://github.com/gin-gonic/go-http-routing-benchmark)
+**Result:** [See the gist](https://gist.github.com/appleboy/b5f2ecfaf50824ae9c64dcfb9165ae5e) or [Travis result](https://travis-ci.org/github/gin-gonic/go-http-routing-benchmark/jobs/682947061)
## Static Routes: 157
-```
-Gin: 30512 Bytes
+```sh
+Gin: 34936 Bytes
-HttpServeMux: 17344 Bytes
-Ace: 30080 Bytes
-Bear: 30472 Bytes
-Beego: 96408 Bytes
-Bone: 37904 Bytes
-Denco: 10464 Bytes
-Echo: 73680 Bytes
-GocraftWeb: 55720 Bytes
-Goji: 27200 Bytes
-Gojiv2: 104464 Bytes
-GoJsonRest: 136472 Bytes
-GoRestful: 914904 Bytes
-GorillaMux: 675568 Bytes
-HttpRouter: 21128 Bytes
-HttpTreeMux: 73448 Bytes
-Kocha: 115072 Bytes
-LARS: 30120 Bytes
-Macaron: 37984 Bytes
-Martini: 310832 Bytes
-Pat: 20464 Bytes
-Possum: 91328 Bytes
-R2router: 23712 Bytes
-Rivet: 23880 Bytes
-Tango: 28008 Bytes
-TigerTonic: 80368 Bytes
-Traffic: 626480 Bytes
-Vulcan: 369064 Bytes
+HttpServeMux: 14512 Bytes
+Ace: 30680 Bytes
+Aero: 34536 Bytes
+Bear: 30456 Bytes
+Beego: 98456 Bytes
+Bone: 40224 Bytes
+Chi: 83608 Bytes
+Denco: 10216 Bytes
+Echo: 80328 Bytes
+GocraftWeb: 55288 Bytes
+Goji: 29744 Bytes
+Gojiv2: 105840 Bytes
+GoJsonRest: 137496 Bytes
+GoRestful: 816936 Bytes
+GorillaMux: 585632 Bytes
+GowwwRouter: 24968 Bytes
+HttpRouter: 21712 Bytes
+HttpTreeMux: 73448 Bytes
+Kocha: 115472 Bytes
+LARS: 30640 Bytes
+Macaron: 38592 Bytes
+Martini: 310864 Bytes
+Pat: 19696 Bytes
+Possum: 89920 Bytes
+R2router: 23712 Bytes
+Rivet: 24608 Bytes
+Tango: 28264 Bytes
+TigerTonic: 78768 Bytes
+Traffic: 538976 Bytes
+Vulcan: 369960 Bytes
```
## GithubAPI Routes: 203
-```
-Gin: 52672 Bytes
+```sh
+Gin: 58512 Bytes
-Ace: 48992 Bytes
-Bear: 161592 Bytes
-Beego: 147992 Bytes
-Bone: 97728 Bytes
-Denco: 36440 Bytes
-Echo: 95672 Bytes
-GocraftWeb: 95640 Bytes
-Goji: 86088 Bytes
-Gojiv2: 144392 Bytes
-GoJsonRest: 134648 Bytes
-GoRestful: 1410760 Bytes
-GorillaMux: 1509488 Bytes
-HttpRouter: 37464 Bytes
-HttpTreeMux: 78800 Bytes
-Kocha: 785408 Bytes
-LARS: 49032 Bytes
-Macaron: 132712 Bytes
-Martini: 564352 Bytes
-Pat: 21200 Bytes
-Possum: 83888 Bytes
-R2router: 47104 Bytes
-Rivet: 42840 Bytes
-Tango: 54584 Bytes
-TigerTonic: 96384 Bytes
-Traffic: 1061920 Bytes
-Vulcan: 465296 Bytes
+Ace: 48688 Bytes
+Aero: 318568 Bytes
+Bear: 84248 Bytes
+Beego: 150936 Bytes
+Bone: 100976 Bytes
+Chi: 95112 Bytes
+Denco: 36736 Bytes
+Echo: 100296 Bytes
+GocraftWeb: 95432 Bytes
+Goji: 49680 Bytes
+Gojiv2: 104704 Bytes
+GoJsonRest: 141976 Bytes
+GoRestful: 1241656 Bytes
+GorillaMux: 1322784 Bytes
+GowwwRouter: 80008 Bytes
+HttpRouter: 37144 Bytes
+HttpTreeMux: 78800 Bytes
+Kocha: 785120 Bytes
+LARS: 48600 Bytes
+Macaron: 92784 Bytes
+Martini: 485264 Bytes
+Pat: 21200 Bytes
+Possum: 85312 Bytes
+R2router: 47104 Bytes
+Rivet: 42840 Bytes
+Tango: 54840 Bytes
+TigerTonic: 95264 Bytes
+Traffic: 921744 Bytes
+Vulcan: 425992 Bytes
```
## GPlusAPI Routes: 13
-```
-Gin: 3968 Bytes
+```sh
+Gin: 4384 Bytes
-Ace: 3600 Bytes
-Bear: 7112 Bytes
-Beego: 10048 Bytes
-Bone: 6480 Bytes
-Denco: 3256 Bytes
-Echo: 9000 Bytes
-GocraftWeb: 7496 Bytes
-Goji: 2912 Bytes
-Gojiv2: 7376 Bytes
-GoJsonRest: 11544 Bytes
-GoRestful: 88776 Bytes
-GorillaMux: 71488 Bytes
-HttpRouter: 2712 Bytes
-HttpTreeMux: 7440 Bytes
-Kocha: 128880 Bytes
-LARS: 3640 Bytes
-Macaron: 8656 Bytes
-Martini: 23936 Bytes
-Pat: 1856 Bytes
-Possum: 7248 Bytes
-R2router: 3928 Bytes
-Rivet: 3064 Bytes
-Tango: 4912 Bytes
-TigerTonic: 9408 Bytes
-Traffic: 49472 Bytes
-Vulcan: 25496 Bytes
+Ace: 3712 Bytes
+Aero: 26056 Bytes
+Bear: 7112 Bytes
+Beego: 10272 Bytes
+Bone: 6688 Bytes
+Chi: 8024 Bytes
+Denco: 3264 Bytes
+Echo: 9688 Bytes
+GocraftWeb: 7496 Bytes
+Goji: 3152 Bytes
+Gojiv2: 7376 Bytes
+GoJsonRest: 11400 Bytes
+GoRestful: 74328 Bytes
+GorillaMux: 66208 Bytes
+GowwwRouter: 5744 Bytes
+HttpRouter: 2808 Bytes
+HttpTreeMux: 7440 Bytes
+Kocha: 128880 Bytes
+LARS: 3656 Bytes
+Macaron: 8656 Bytes
+Martini: 23920 Bytes
+Pat: 1856 Bytes
+Possum: 7248 Bytes
+R2router: 3928 Bytes
+Rivet: 3064 Bytes
+Tango: 5168 Bytes
+TigerTonic: 9408 Bytes
+Traffic: 46400 Bytes
+Vulcan: 25544 Bytes
```
## ParseAPI Routes: 26
-```
-Gin: 6928 Bytes
+```sh
+Gin: 7776 Bytes
-Ace: 6592 Bytes
-Bear: 12320 Bytes
-Beego: 18960 Bytes
-Bone: 11024 Bytes
-Denco: 4184 Bytes
-Echo: 11168 Bytes
-GocraftWeb: 12800 Bytes
-Goji: 5232 Bytes
-Gojiv2: 14464 Bytes
-GoJsonRest: 14216 Bytes
-GoRestful: 127368 Bytes
-GorillaMux: 123016 Bytes
-HttpRouter: 4976 Bytes
-HttpTreeMux: 7848 Bytes
-Kocha: 181712 Bytes
-LARS: 6632 Bytes
-Macaron: 13648 Bytes
-Martini: 45952 Bytes
-Pat: 2560 Bytes
-Possum: 9200 Bytes
-R2router: 7056 Bytes
-Rivet: 5680 Bytes
-Tango: 8664 Bytes
-TigerTonic: 9840 Bytes
-Traffic: 93480 Bytes
-Vulcan: 44504 Bytes
+Ace: 6704 Bytes
+Aero: 28488 Bytes
+Bear: 12320 Bytes
+Beego: 19280 Bytes
+Bone: 11440 Bytes
+Chi: 9744 Bytes
+Denco: 4192 Bytes
+Echo: 11664 Bytes
+GocraftWeb: 12800 Bytes
+Goji: 5680 Bytes
+Gojiv2: 14464 Bytes
+GoJsonRest: 14072 Bytes
+GoRestful: 116264 Bytes
+GorillaMux: 105880 Bytes
+GowwwRouter: 9344 Bytes
+HttpRouter: 5072 Bytes
+HttpTreeMux: 7848 Bytes
+Kocha: 181712 Bytes
+LARS: 6632 Bytes
+Macaron: 13648 Bytes
+Martini: 45888 Bytes
+Pat: 2560 Bytes
+Possum: 9200 Bytes
+R2router: 7056 Bytes
+Rivet: 5680 Bytes
+Tango: 8920 Bytes
+TigerTonic: 9840 Bytes
+Traffic: 79096 Bytes
+Vulcan: 44504 Bytes
```
## Static Routes
-```
-BenchmarkGin_StaticAll 50000 34506 ns/op 0 B/op 0 allocs/op
+```sh
+BenchmarkGin_StaticAll 62169 19319 ns/op 0 B/op 0 allocs/op
-BenchmarkAce_StaticAll 30000 49657 ns/op 0 B/op 0 allocs/op
-BenchmarkHttpServeMux_StaticAll 2000 1183737 ns/op 96 B/op 8 allocs/op
-BenchmarkBeego_StaticAll 5000 412621 ns/op 57776 B/op 628 allocs/op
-BenchmarkBear_StaticAll 10000 149242 ns/op 20336 B/op 461 allocs/op
-BenchmarkBone_StaticAll 10000 118583 ns/op 0 B/op 0 allocs/op
-BenchmarkDenco_StaticAll 100000 13247 ns/op 0 B/op 0 allocs/op
-BenchmarkEcho_StaticAll 20000 79914 ns/op 5024 B/op 157 allocs/op
-BenchmarkGocraftWeb_StaticAll 10000 211823 ns/op 46440 B/op 785 allocs/op
-BenchmarkGoji_StaticAll 10000 109390 ns/op 0 B/op 0 allocs/op
-BenchmarkGojiv2_StaticAll 3000 415533 ns/op 145696 B/op 1099 allocs/op
-BenchmarkGoJsonRest_StaticAll 5000 364403 ns/op 51653 B/op 1727 allocs/op
-BenchmarkGoRestful_StaticAll 500 2578579 ns/op 314936 B/op 3144 allocs/op
-BenchmarkGorillaMux_StaticAll 500 2704856 ns/op 115648 B/op 1578 allocs/op
-BenchmarkHttpRouter_StaticAll 100000 18541 ns/op 0 B/op 0 allocs/op
-BenchmarkHttpTreeMux_StaticAll 100000 22332 ns/op 0 B/op 0 allocs/op
-BenchmarkKocha_StaticAll 50000 31176 ns/op 0 B/op 0 allocs/op
-BenchmarkLARS_StaticAll 50000 40840 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_StaticAll 5000 517656 ns/op 120576 B/op 1413 allocs/op
-BenchmarkMartini_StaticAll 300 4462289 ns/op 125442 B/op 1717 allocs/op
-BenchmarkPat_StaticAll 500 2157275 ns/op 533904 B/op 11123 allocs/op
-BenchmarkPossum_StaticAll 10000 254701 ns/op 65312 B/op 471 allocs/op
-BenchmarkR2router_StaticAll 10000 133956 ns/op 22608 B/op 628 allocs/op
-BenchmarkRivet_StaticAll 30000 46812 ns/op 0 B/op 0 allocs/op
-BenchmarkTango_StaticAll 5000 390613 ns/op 39225 B/op 1256 allocs/op
-BenchmarkTigerTonic_StaticAll 20000 88060 ns/op 7504 B/op 157 allocs/op
-BenchmarkTraffic_StaticAll 500 2910236 ns/op 729736 B/op 14287 allocs/op
-BenchmarkVulcan_StaticAll 5000 277366 ns/op 15386 B/op 471 allocs/op
+BenchmarkAce_StaticAll 65428 18313 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_StaticAll 121132 9632 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpServeMux_StaticAll 52626 22758 ns/op 0 B/op 0 allocs/op
+BenchmarkBeego_StaticAll 9962 179058 ns/op 55264 B/op 471 allocs/op
+BenchmarkBear_StaticAll 14894 80966 ns/op 20272 B/op 469 allocs/op
+BenchmarkBone_StaticAll 18718 64065 ns/op 0 B/op 0 allocs/op
+BenchmarkChi_StaticAll 10000 149827 ns/op 67824 B/op 471 allocs/op
+BenchmarkDenco_StaticAll 211393 5680 ns/op 0 B/op 0 allocs/op
+BenchmarkEcho_StaticAll 49341 24343 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_StaticAll 10000 126209 ns/op 46312 B/op 785 allocs/op
+BenchmarkGoji_StaticAll 27956 43174 ns/op 0 B/op 0 allocs/op
+BenchmarkGojiv2_StaticAll 3430 370718 ns/op 205984 B/op 1570 allocs/op
+BenchmarkGoJsonRest_StaticAll 9134 188888 ns/op 51653 B/op 1727 allocs/op
+BenchmarkGoRestful_StaticAll 706 1703330 ns/op 613280 B/op 2053 allocs/op
+BenchmarkGorillaMux_StaticAll 1268 924083 ns/op 153233 B/op 1413 allocs/op
+BenchmarkGowwwRouter_StaticAll 63374 18935 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpRouter_StaticAll 109938 10902 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_StaticAll 109166 10861 ns/op 0 B/op 0 allocs/op
+BenchmarkKocha_StaticAll 92258 12992 ns/op 0 B/op 0 allocs/op
+BenchmarkLARS_StaticAll 65200 18387 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_StaticAll 5671 291501 ns/op 115553 B/op 1256 allocs/op
+BenchmarkMartini_StaticAll 807 1460498 ns/op 125444 B/op 1717 allocs/op
+BenchmarkPat_StaticAll 513 2342396 ns/op 602832 B/op 12559 allocs/op
+BenchmarkPossum_StaticAll 10000 128270 ns/op 65312 B/op 471 allocs/op
+BenchmarkR2router_StaticAll 16726 71760 ns/op 22608 B/op 628 allocs/op
+BenchmarkRivet_StaticAll 41722 28723 ns/op 0 B/op 0 allocs/op
+BenchmarkTango_StaticAll 7606 205082 ns/op 39209 B/op 1256 allocs/op
+BenchmarkTigerTonic_StaticAll 26247 45806 ns/op 7376 B/op 157 allocs/op
+BenchmarkTraffic_StaticAll 550 2284518 ns/op 754864 B/op 14601 allocs/op
+BenchmarkVulcan_StaticAll 10000 131343 ns/op 15386 B/op 471 allocs/op
```
## Micro Benchmarks
-```
-BenchmarkGin_Param 20000000 113 ns/op 0 B/op 0 allocs/op
+```sh
+BenchmarkGin_Param 18785022 63.9 ns/op 0 B/op 0 allocs/op
-BenchmarkAce_Param 5000000 375 ns/op 32 B/op 1 allocs/op
-BenchmarkBear_Param 1000000 1709 ns/op 456 B/op 5 allocs/op
-BenchmarkBeego_Param 1000000 2484 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_Param 1000000 2391 ns/op 688 B/op 5 allocs/op
-BenchmarkDenco_Param 10000000 240 ns/op 32 B/op 1 allocs/op
-BenchmarkEcho_Param 5000000 366 ns/op 32 B/op 1 allocs/op
-BenchmarkGocraftWeb_Param 1000000 2343 ns/op 648 B/op 8 allocs/op
-BenchmarkGoji_Param 1000000 1197 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_Param 1000000 2771 ns/op 944 B/op 8 allocs/op
-BenchmarkGoJsonRest_Param 1000000 2993 ns/op 649 B/op 13 allocs/op
-BenchmarkGoRestful_Param 200000 8860 ns/op 2296 B/op 21 allocs/op
-BenchmarkGorillaMux_Param 500000 4461 ns/op 1056 B/op 11 allocs/op
-BenchmarkHttpRouter_Param 10000000 175 ns/op 32 B/op 1 allocs/op
-BenchmarkHttpTreeMux_Param 1000000 1167 ns/op 352 B/op 3 allocs/op
-BenchmarkKocha_Param 3000000 429 ns/op 56 B/op 3 allocs/op
-BenchmarkLARS_Param 10000000 134 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_Param 500000 4635 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_Param 200000 9933 ns/op 1072 B/op 10 allocs/op
-BenchmarkPat_Param 1000000 2929 ns/op 648 B/op 12 allocs/op
-BenchmarkPossum_Param 1000000 2503 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_Param 1000000 1507 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_Param 5000000 297 ns/op 48 B/op 1 allocs/op
-BenchmarkTango_Param 1000000 1862 ns/op 248 B/op 8 allocs/op
-BenchmarkTigerTonic_Param 500000 5660 ns/op 992 B/op 17 allocs/op
-BenchmarkTraffic_Param 200000 8408 ns/op 1960 B/op 21 allocs/op
-BenchmarkVulcan_Param 2000000 963 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_Param5 2000000 740 ns/op 160 B/op 1 allocs/op
-BenchmarkBear_Param5 1000000 2777 ns/op 501 B/op 5 allocs/op
-BenchmarkBeego_Param5 1000000 3740 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_Param5 1000000 2950 ns/op 736 B/op 5 allocs/op
-BenchmarkDenco_Param5 2000000 644 ns/op 160 B/op 1 allocs/op
-BenchmarkEcho_Param5 3000000 558 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_Param5 10000000 198 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_Param5 500000 3870 ns/op 920 B/op 11 allocs/op
-BenchmarkGoji_Param5 1000000 1746 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_Param5 1000000 3214 ns/op 1008 B/op 8 allocs/op
-BenchmarkGoJsonRest_Param5 500000 5509 ns/op 1097 B/op 16 allocs/op
-BenchmarkGoRestful_Param5 200000 11232 ns/op 2392 B/op 21 allocs/op
-BenchmarkGorillaMux_Param5 300000 7777 ns/op 1184 B/op 11 allocs/op
-BenchmarkHttpRouter_Param5 3000000 631 ns/op 160 B/op 1 allocs/op
-BenchmarkHttpTreeMux_Param5 1000000 2800 ns/op 576 B/op 6 allocs/op
-BenchmarkKocha_Param5 1000000 2053 ns/op 440 B/op 10 allocs/op
-BenchmarkLARS_Param5 10000000 232 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_Param5 500000 5888 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_Param5 200000 12807 ns/op 1232 B/op 11 allocs/op
-BenchmarkPat_Param5 300000 7320 ns/op 964 B/op 32 allocs/op
-BenchmarkPossum_Param5 1000000 2495 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_Param5 1000000 1844 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_Param5 2000000 935 ns/op 240 B/op 1 allocs/op
-BenchmarkTango_Param5 1000000 2327 ns/op 360 B/op 8 allocs/op
-BenchmarkTigerTonic_Param5 100000 18514 ns/op 2551 B/op 43 allocs/op
-BenchmarkTraffic_Param5 200000 11997 ns/op 2248 B/op 25 allocs/op
-BenchmarkVulcan_Param5 1000000 1333 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_Param20 1000000 2031 ns/op 640 B/op 1 allocs/op
-BenchmarkBear_Param20 200000 7285 ns/op 1664 B/op 5 allocs/op
-BenchmarkBeego_Param20 300000 6224 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_Param20 200000 8023 ns/op 1903 B/op 5 allocs/op
-BenchmarkDenco_Param20 1000000 2262 ns/op 640 B/op 1 allocs/op
-BenchmarkEcho_Param20 1000000 1387 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_Param20 3000000 503 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_Param20 100000 14408 ns/op 3795 B/op 15 allocs/op
-BenchmarkGoji_Param20 500000 5272 ns/op 1247 B/op 2 allocs/op
-BenchmarkGojiv2_Param20 1000000 4163 ns/op 1248 B/op 8 allocs/op
-BenchmarkGoJsonRest_Param20 100000 17866 ns/op 4485 B/op 20 allocs/op
-BenchmarkGoRestful_Param20 100000 21022 ns/op 4724 B/op 23 allocs/op
-BenchmarkGorillaMux_Param20 100000 17055 ns/op 3547 B/op 13 allocs/op
-BenchmarkHttpRouter_Param20 1000000 1748 ns/op 640 B/op 1 allocs/op
-BenchmarkHttpTreeMux_Param20 200000 12246 ns/op 3196 B/op 10 allocs/op
-BenchmarkKocha_Param20 300000 6861 ns/op 1808 B/op 27 allocs/op
-BenchmarkLARS_Param20 3000000 526 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_Param20 100000 13069 ns/op 2906 B/op 12 allocs/op
-BenchmarkMartini_Param20 100000 23602 ns/op 3597 B/op 13 allocs/op
-BenchmarkPat_Param20 50000 32143 ns/op 4688 B/op 111 allocs/op
-BenchmarkPossum_Param20 1000000 2396 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_Param20 200000 8907 ns/op 2283 B/op 7 allocs/op
-BenchmarkRivet_Param20 1000000 3280 ns/op 1024 B/op 1 allocs/op
-BenchmarkTango_Param20 500000 4640 ns/op 856 B/op 8 allocs/op
-BenchmarkTigerTonic_Param20 20000 67581 ns/op 10532 B/op 138 allocs/op
-BenchmarkTraffic_Param20 50000 40313 ns/op 7941 B/op 45 allocs/op
-BenchmarkVulcan_Param20 1000000 2264 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_ParamWrite 3000000 532 ns/op 40 B/op 2 allocs/op
-BenchmarkBear_ParamWrite 1000000 1778 ns/op 456 B/op 5 allocs/op
-BenchmarkBeego_ParamWrite 1000000 2596 ns/op 376 B/op 5 allocs/op
-BenchmarkBone_ParamWrite 1000000 2519 ns/op 688 B/op 5 allocs/op
-BenchmarkDenco_ParamWrite 5000000 411 ns/op 32 B/op 1 allocs/op
-BenchmarkEcho_ParamWrite 2000000 718 ns/op 40 B/op 2 allocs/op
-BenchmarkGin_ParamWrite 5000000 283 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_ParamWrite 1000000 2561 ns/op 656 B/op 9 allocs/op
-BenchmarkGoji_ParamWrite 1000000 1378 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_ParamWrite 1000000 3128 ns/op 976 B/op 10 allocs/op
-BenchmarkGoJsonRest_ParamWrite 500000 4446 ns/op 1128 B/op 18 allocs/op
-BenchmarkGoRestful_ParamWrite 200000 10291 ns/op 2304 B/op 22 allocs/op
-BenchmarkGorillaMux_ParamWrite 500000 5153 ns/op 1064 B/op 12 allocs/op
-BenchmarkHttpRouter_ParamWrite 5000000 263 ns/op 32 B/op 1 allocs/op
-BenchmarkHttpTreeMux_ParamWrite 1000000 1351 ns/op 352 B/op 3 allocs/op
-BenchmarkKocha_ParamWrite 3000000 538 ns/op 56 B/op 3 allocs/op
-BenchmarkLARS_ParamWrite 5000000 316 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_ParamWrite 500000 5756 ns/op 1160 B/op 14 allocs/op
-BenchmarkMartini_ParamWrite 200000 13097 ns/op 1176 B/op 14 allocs/op
-BenchmarkPat_ParamWrite 500000 4954 ns/op 1072 B/op 17 allocs/op
-BenchmarkPossum_ParamWrite 1000000 2499 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_ParamWrite 1000000 1531 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_ParamWrite 3000000 570 ns/op 112 B/op 2 allocs/op
-BenchmarkTango_ParamWrite 2000000 957 ns/op 136 B/op 4 allocs/op
-BenchmarkTigerTonic_ParamWrite 200000 7025 ns/op 1424 B/op 23 allocs/op
-BenchmarkTraffic_ParamWrite 200000 10112 ns/op 2384 B/op 25 allocs/op
-BenchmarkVulcan_ParamWrite 1000000 1006 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_Param 14689765 81.5 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_Param 23094770 51.2 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_Param 1417045 845 ns/op 456 B/op 5 allocs/op
+BenchmarkBeego_Param 1000000 1080 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_Param 1000000 1463 ns/op 816 B/op 6 allocs/op
+BenchmarkChi_Param 1378756 885 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_Param 8557899 143 ns/op 32 B/op 1 allocs/op
+BenchmarkEcho_Param 16433347 75.5 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_Param 1000000 1218 ns/op 648 B/op 8 allocs/op
+BenchmarkGoji_Param 1921248 617 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_Param 561848 2156 ns/op 1328 B/op 11 allocs/op
+BenchmarkGoJsonRest_Param 1000000 1358 ns/op 649 B/op 13 allocs/op
+BenchmarkGoRestful_Param 224857 5307 ns/op 4192 B/op 14 allocs/op
+BenchmarkGorillaMux_Param 498313 2459 ns/op 1280 B/op 10 allocs/op
+BenchmarkGowwwRouter_Param 1864354 654 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_Param 26269074 47.7 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_Param 2109829 557 ns/op 352 B/op 3 allocs/op
+BenchmarkKocha_Param 5050216 243 ns/op 56 B/op 3 allocs/op
+BenchmarkLARS_Param 19811712 59.9 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_Param 662746 2329 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_Param 279902 4260 ns/op 1072 B/op 10 allocs/op
+BenchmarkPat_Param 1000000 1382 ns/op 536 B/op 11 allocs/op
+BenchmarkPossum_Param 1000000 1014 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_Param 1712559 707 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_Param 6648086 182 ns/op 48 B/op 1 allocs/op
+BenchmarkTango_Param 1221504 994 ns/op 248 B/op 8 allocs/op
+BenchmarkTigerTonic_Param 891661 2261 ns/op 776 B/op 16 allocs/op
+BenchmarkTraffic_Param 350059 3598 ns/op 1856 B/op 21 allocs/op
+BenchmarkVulcan_Param 2517823 472 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_Param5 9214365 130 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_Param5 15369013 77.9 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_Param5 1000000 1113 ns/op 501 B/op 5 allocs/op
+BenchmarkBeego_Param5 1000000 1269 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_Param5 986820 1873 ns/op 864 B/op 6 allocs/op
+BenchmarkChi_Param5 1000000 1156 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_Param5 3036331 400 ns/op 160 B/op 1 allocs/op
+BenchmarkEcho_Param5 6447133 186 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_Param5 10786068 110 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_Param5 844820 1944 ns/op 920 B/op 11 allocs/op
+BenchmarkGoji_Param5 1474965 827 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_Param5 442820 2516 ns/op 1392 B/op 11 allocs/op
+BenchmarkGoJsonRest_Param5 507555 2711 ns/op 1097 B/op 16 allocs/op
+BenchmarkGoRestful_Param5 216481 6093 ns/op 4288 B/op 14 allocs/op
+BenchmarkGorillaMux_Param5 314402 3628 ns/op 1344 B/op 10 allocs/op
+BenchmarkGowwwRouter_Param5 1624660 733 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_Param5 13167324 92.0 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_Param5 1000000 1295 ns/op 576 B/op 6 allocs/op
+BenchmarkKocha_Param5 1000000 1138 ns/op 440 B/op 10 allocs/op
+BenchmarkLARS_Param5 11580613 105 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_Param5 473596 2755 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_Param5 230756 5111 ns/op 1232 B/op 11 allocs/op
+BenchmarkPat_Param5 469190 3370 ns/op 888 B/op 29 allocs/op
+BenchmarkPossum_Param5 1000000 1002 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_Param5 1422129 844 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_Param5 2263789 539 ns/op 240 B/op 1 allocs/op
+BenchmarkTango_Param5 1000000 1256 ns/op 360 B/op 8 allocs/op
+BenchmarkTigerTonic_Param5 175500 7492 ns/op 2279 B/op 39 allocs/op
+BenchmarkTraffic_Param5 233631 5816 ns/op 2208 B/op 27 allocs/op
+BenchmarkVulcan_Param5 1923416 629 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_Param20 4321266 281 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_Param20 31501641 35.2 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_Param20 335204 3489 ns/op 1665 B/op 5 allocs/op
+BenchmarkBeego_Param20 503674 2860 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_Param20 298922 4741 ns/op 2031 B/op 6 allocs/op
+BenchmarkChi_Param20 878181 1957 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_Param20 1000000 1360 ns/op 640 B/op 1 allocs/op
+BenchmarkEcho_Param20 2104946 580 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_Param20 4167204 290 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_Param20 173064 7514 ns/op 3796 B/op 15 allocs/op
+BenchmarkGoji_Param20 458778 2651 ns/op 1247 B/op 2 allocs/op
+BenchmarkGojiv2_Param20 364862 3178 ns/op 1632 B/op 11 allocs/op
+BenchmarkGoJsonRest_Param20 125514 9760 ns/op 4485 B/op 20 allocs/op
+BenchmarkGoRestful_Param20 101217 11964 ns/op 6715 B/op 18 allocs/op
+BenchmarkGorillaMux_Param20 147654 8132 ns/op 3452 B/op 12 allocs/op
+BenchmarkGowwwRouter_Param20 1000000 1225 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_Param20 4920895 247 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_Param20 173202 6605 ns/op 3196 B/op 10 allocs/op
+BenchmarkKocha_Param20 345988 3620 ns/op 1808 B/op 27 allocs/op
+BenchmarkLARS_Param20 4592326 262 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_Param20 166492 7286 ns/op 2924 B/op 12 allocs/op
+BenchmarkMartini_Param20 122162 10653 ns/op 3595 B/op 13 allocs/op
+BenchmarkPat_Param20 78630 15239 ns/op 4424 B/op 93 allocs/op
+BenchmarkPossum_Param20 1000000 1008 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_Param20 294981 4587 ns/op 2284 B/op 7 allocs/op
+BenchmarkRivet_Param20 691798 2090 ns/op 1024 B/op 1 allocs/op
+BenchmarkTango_Param20 842440 2505 ns/op 856 B/op 8 allocs/op
+BenchmarkTigerTonic_Param20 38614 31509 ns/op 9870 B/op 119 allocs/op
+BenchmarkTraffic_Param20 57633 21107 ns/op 7853 B/op 47 allocs/op
+BenchmarkVulcan_Param20 1000000 1178 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_ParamWrite 7330743 180 ns/op 8 B/op 1 allocs/op
+BenchmarkAero_ParamWrite 13833598 86.7 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_ParamWrite 1363321 867 ns/op 456 B/op 5 allocs/op
+BenchmarkBeego_ParamWrite 1000000 1104 ns/op 360 B/op 4 allocs/op
+BenchmarkBone_ParamWrite 1000000 1475 ns/op 816 B/op 6 allocs/op
+BenchmarkChi_ParamWrite 1320590 892 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_ParamWrite 7093605 172 ns/op 32 B/op 1 allocs/op
+BenchmarkEcho_ParamWrite 8434424 161 ns/op 8 B/op 1 allocs/op
+BenchmarkGin_ParamWrite 10377034 118 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_ParamWrite 1000000 1266 ns/op 656 B/op 9 allocs/op
+BenchmarkGoji_ParamWrite 1874168 654 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_ParamWrite 459032 2352 ns/op 1360 B/op 13 allocs/op
+BenchmarkGoJsonRest_ParamWrite 499434 2145 ns/op 1128 B/op 18 allocs/op
+BenchmarkGoRestful_ParamWrite 241087 5470 ns/op 4200 B/op 15 allocs/op
+BenchmarkGorillaMux_ParamWrite 425686 2522 ns/op 1280 B/op 10 allocs/op
+BenchmarkGowwwRouter_ParamWrite 922172 1778 ns/op 976 B/op 8 allocs/op
+BenchmarkHttpRouter_ParamWrite 15392049 77.7 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_ParamWrite 1973385 597 ns/op 352 B/op 3 allocs/op
+BenchmarkKocha_ParamWrite 4262500 281 ns/op 56 B/op 3 allocs/op
+BenchmarkLARS_ParamWrite 10764410 113 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_ParamWrite 486769 2726 ns/op 1176 B/op 14 allocs/op
+BenchmarkMartini_ParamWrite 264804 4842 ns/op 1176 B/op 14 allocs/op
+BenchmarkPat_ParamWrite 735116 2047 ns/op 960 B/op 15 allocs/op
+BenchmarkPossum_ParamWrite 1000000 1004 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_ParamWrite 1592136 768 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_ParamWrite 3582051 339 ns/op 112 B/op 2 allocs/op
+BenchmarkTango_ParamWrite 2237337 534 ns/op 136 B/op 4 allocs/op
+BenchmarkTigerTonic_ParamWrite 439608 3136 ns/op 1216 B/op 21 allocs/op
+BenchmarkTraffic_ParamWrite 306979 4328 ns/op 2280 B/op 25 allocs/op
+BenchmarkVulcan_ParamWrite 2529973 472 ns/op 98 B/op 3 allocs/op
```
## GitHub
-```
-BenchmarkGin_GithubStatic 10000000 156 ns/op 0 B/op 0 allocs/op
+```sh
+BenchmarkGin_GithubStatic 15629472 76.7 ns/op 0 B/op 0 allocs/op
-BenchmarkAce_GithubStatic 5000000 294 ns/op 0 B/op 0 allocs/op
-BenchmarkBear_GithubStatic 2000000 893 ns/op 120 B/op 3 allocs/op
-BenchmarkBeego_GithubStatic 1000000 2491 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_GithubStatic 50000 25300 ns/op 2880 B/op 60 allocs/op
-BenchmarkDenco_GithubStatic 20000000 76.0 ns/op 0 B/op 0 allocs/op
-BenchmarkEcho_GithubStatic 2000000 516 ns/op 32 B/op 1 allocs/op
-BenchmarkGocraftWeb_GithubStatic 1000000 1448 ns/op 296 B/op 5 allocs/op
-BenchmarkGoji_GithubStatic 3000000 496 ns/op 0 B/op 0 allocs/op
-BenchmarkGojiv2_GithubStatic 1000000 2941 ns/op 928 B/op 7 allocs/op
-BenchmarkGoRestful_GithubStatic 100000 27256 ns/op 3224 B/op 22 allocs/op
-BenchmarkGoJsonRest_GithubStatic 1000000 2196 ns/op 329 B/op 11 allocs/op
-BenchmarkGorillaMux_GithubStatic 50000 31617 ns/op 736 B/op 10 allocs/op
-BenchmarkHttpRouter_GithubStatic 20000000 88.4 ns/op 0 B/op 0 allocs/op
-BenchmarkHttpTreeMux_GithubStatic 10000000 134 ns/op 0 B/op 0 allocs/op
-BenchmarkKocha_GithubStatic 20000000 113 ns/op 0 B/op 0 allocs/op
-BenchmarkLARS_GithubStatic 10000000 195 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GithubStatic 500000 3740 ns/op 768 B/op 9 allocs/op
-BenchmarkMartini_GithubStatic 50000 27673 ns/op 768 B/op 9 allocs/op
-BenchmarkPat_GithubStatic 100000 19470 ns/op 3648 B/op 76 allocs/op
-BenchmarkPossum_GithubStatic 1000000 1729 ns/op 416 B/op 3 allocs/op
-BenchmarkR2router_GithubStatic 2000000 879 ns/op 144 B/op 4 allocs/op
-BenchmarkRivet_GithubStatic 10000000 231 ns/op 0 B/op 0 allocs/op
-BenchmarkTango_GithubStatic 1000000 2325 ns/op 248 B/op 8 allocs/op
-BenchmarkTigerTonic_GithubStatic 3000000 610 ns/op 48 B/op 1 allocs/op
-BenchmarkTraffic_GithubStatic 20000 62973 ns/op 18904 B/op 148 allocs/op
-BenchmarkVulcan_GithubStatic 1000000 1447 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_GithubParam 2000000 686 ns/op 96 B/op 1 allocs/op
-BenchmarkBear_GithubParam 1000000 2155 ns/op 496 B/op 5 allocs/op
-BenchmarkBeego_GithubParam 1000000 2713 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_GithubParam 100000 15088 ns/op 1760 B/op 18 allocs/op
-BenchmarkDenco_GithubParam 2000000 629 ns/op 128 B/op 1 allocs/op
-BenchmarkEcho_GithubParam 2000000 653 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_GithubParam 5000000 255 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_GithubParam 1000000 3145 ns/op 712 B/op 9 allocs/op
-BenchmarkGoji_GithubParam 1000000 1916 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_GithubParam 1000000 3975 ns/op 1024 B/op 10 allocs/op
-BenchmarkGoJsonRest_GithubParam 300000 4134 ns/op 713 B/op 14 allocs/op
-BenchmarkGoRestful_GithubParam 50000 30782 ns/op 2360 B/op 21 allocs/op
-BenchmarkGorillaMux_GithubParam 100000 17148 ns/op 1088 B/op 11 allocs/op
-BenchmarkHttpRouter_GithubParam 3000000 523 ns/op 96 B/op 1 allocs/op
-BenchmarkHttpTreeMux_GithubParam 1000000 1671 ns/op 384 B/op 4 allocs/op
-BenchmarkKocha_GithubParam 1000000 1021 ns/op 128 B/op 5 allocs/op
-BenchmarkLARS_GithubParam 5000000 283 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GithubParam 500000 4270 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_GithubParam 100000 21728 ns/op 1152 B/op 11 allocs/op
-BenchmarkPat_GithubParam 200000 11208 ns/op 2464 B/op 48 allocs/op
-BenchmarkPossum_GithubParam 1000000 2334 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_GithubParam 1000000 1487 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_GithubParam 2000000 782 ns/op 96 B/op 1 allocs/op
-BenchmarkTango_GithubParam 1000000 2653 ns/op 344 B/op 8 allocs/op
-BenchmarkTigerTonic_GithubParam 300000 14073 ns/op 1440 B/op 24 allocs/op
-BenchmarkTraffic_GithubParam 50000 29164 ns/op 5992 B/op 52 allocs/op
-BenchmarkVulcan_GithubParam 1000000 2529 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_GithubAll 10000 134059 ns/op 13792 B/op 167 allocs/op
-BenchmarkBear_GithubAll 5000 534445 ns/op 86448 B/op 943 allocs/op
-BenchmarkBeego_GithubAll 3000 592444 ns/op 74705 B/op 812 allocs/op
-BenchmarkBone_GithubAll 200 6957308 ns/op 698784 B/op 8453 allocs/op
-BenchmarkDenco_GithubAll 10000 158819 ns/op 20224 B/op 167 allocs/op
-BenchmarkEcho_GithubAll 10000 154700 ns/op 6496 B/op 203 allocs/op
-BenchmarkGin_GithubAll 30000 48375 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_GithubAll 3000 570806 ns/op 131656 B/op 1686 allocs/op
-BenchmarkGoji_GithubAll 2000 818034 ns/op 56112 B/op 334 allocs/op
-BenchmarkGojiv2_GithubAll 2000 1213973 ns/op 274768 B/op 3712 allocs/op
-BenchmarkGoJsonRest_GithubAll 2000 785796 ns/op 134371 B/op 2737 allocs/op
-BenchmarkGoRestful_GithubAll 300 5238188 ns/op 689672 B/op 4519 allocs/op
-BenchmarkGorillaMux_GithubAll 100 10257726 ns/op 211840 B/op 2272 allocs/op
-BenchmarkHttpRouter_GithubAll 20000 105414 ns/op 13792 B/op 167 allocs/op
-BenchmarkHttpTreeMux_GithubAll 10000 319934 ns/op 65856 B/op 671 allocs/op
-BenchmarkKocha_GithubAll 10000 209442 ns/op 23304 B/op 843 allocs/op
-BenchmarkLARS_GithubAll 20000 62565 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GithubAll 2000 1161270 ns/op 204194 B/op 2000 allocs/op
-BenchmarkMartini_GithubAll 200 9991713 ns/op 226549 B/op 2325 allocs/op
-BenchmarkPat_GithubAll 200 5590793 ns/op 1499568 B/op 27435 allocs/op
-BenchmarkPossum_GithubAll 10000 319768 ns/op 84448 B/op 609 allocs/op
-BenchmarkR2router_GithubAll 10000 305134 ns/op 77328 B/op 979 allocs/op
-BenchmarkRivet_GithubAll 10000 132134 ns/op 16272 B/op 167 allocs/op
-BenchmarkTango_GithubAll 3000 552754 ns/op 63826 B/op 1618 allocs/op
-BenchmarkTigerTonic_GithubAll 1000 1439483 ns/op 239104 B/op 5374 allocs/op
-BenchmarkTraffic_GithubAll 100 11383067 ns/op 2659329 B/op 21848 allocs/op
-BenchmarkVulcan_GithubAll 5000 394253 ns/op 19894 B/op 609 allocs/op
+BenchmarkAce_GithubStatic 15542612 75.9 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GithubStatic 24777151 48.5 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GithubStatic 2788894 435 ns/op 120 B/op 3 allocs/op
+BenchmarkBeego_GithubStatic 1000000 1064 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_GithubStatic 93507 12838 ns/op 2880 B/op 60 allocs/op
+BenchmarkChi_GithubStatic 1387743 860 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_GithubStatic 39384996 30.4 ns/op 0 B/op 0 allocs/op
+BenchmarkEcho_GithubStatic 12076382 99.1 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GithubStatic 1596495 756 ns/op 296 B/op 5 allocs/op
+BenchmarkGoji_GithubStatic 6364876 189 ns/op 0 B/op 0 allocs/op
+BenchmarkGojiv2_GithubStatic 550202 2098 ns/op 1312 B/op 10 allocs/op
+BenchmarkGoRestful_GithubStatic 102183 12552 ns/op 4256 B/op 13 allocs/op
+BenchmarkGoJsonRest_GithubStatic 1000000 1029 ns/op 329 B/op 11 allocs/op
+BenchmarkGorillaMux_GithubStatic 255552 5190 ns/op 976 B/op 9 allocs/op
+BenchmarkGowwwRouter_GithubStatic 15531916 77.1 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpRouter_GithubStatic 27920724 43.1 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GithubStatic 21448953 55.8 ns/op 0 B/op 0 allocs/op
+BenchmarkKocha_GithubStatic 21405310 56.0 ns/op 0 B/op 0 allocs/op
+BenchmarkLARS_GithubStatic 13625156 89.0 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GithubStatic 1000000 1747 ns/op 736 B/op 8 allocs/op
+BenchmarkMartini_GithubStatic 187186 7326 ns/op 768 B/op 9 allocs/op
+BenchmarkPat_GithubStatic 109143 11563 ns/op 3648 B/op 76 allocs/op
+BenchmarkPossum_GithubStatic 1575898 770 ns/op 416 B/op 3 allocs/op
+BenchmarkR2router_GithubStatic 3046231 404 ns/op 144 B/op 4 allocs/op
+BenchmarkRivet_GithubStatic 11484826 105 ns/op 0 B/op 0 allocs/op
+BenchmarkTango_GithubStatic 1000000 1153 ns/op 248 B/op 8 allocs/op
+BenchmarkTigerTonic_GithubStatic 4929780 249 ns/op 48 B/op 1 allocs/op
+BenchmarkTraffic_GithubStatic 106351 11819 ns/op 4664 B/op 90 allocs/op
+BenchmarkVulcan_GithubStatic 1613271 722 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_GithubParam 8386032 143 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GithubParam 11816200 102 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GithubParam 1000000 1012 ns/op 496 B/op 5 allocs/op
+BenchmarkBeego_GithubParam 1000000 1157 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_GithubParam 184653 6912 ns/op 1888 B/op 19 allocs/op
+BenchmarkChi_GithubParam 1000000 1102 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_GithubParam 3484798 352 ns/op 128 B/op 1 allocs/op
+BenchmarkEcho_GithubParam 6337380 189 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_GithubParam 9132032 131 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GithubParam 1000000 1446 ns/op 712 B/op 9 allocs/op
+BenchmarkGoji_GithubParam 1248640 977 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_GithubParam 383233 2784 ns/op 1408 B/op 13 allocs/op
+BenchmarkGoJsonRest_GithubParam 1000000 1991 ns/op 713 B/op 14 allocs/op
+BenchmarkGoRestful_GithubParam 76414 16015 ns/op 4352 B/op 16 allocs/op
+BenchmarkGorillaMux_GithubParam 150026 7663 ns/op 1296 B/op 10 allocs/op
+BenchmarkGowwwRouter_GithubParam 1592044 751 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_GithubParam 10420628 115 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GithubParam 1403755 835 ns/op 384 B/op 4 allocs/op
+BenchmarkKocha_GithubParam 2286170 533 ns/op 128 B/op 5 allocs/op
+BenchmarkLARS_GithubParam 9540374 129 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GithubParam 533154 2742 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_GithubParam 119397 9638 ns/op 1152 B/op 11 allocs/op
+BenchmarkPat_GithubParam 150675 8858 ns/op 2408 B/op 48 allocs/op
+BenchmarkPossum_GithubParam 1000000 1001 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_GithubParam 1602886 761 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_GithubParam 2986579 409 ns/op 96 B/op 1 allocs/op
+BenchmarkTango_GithubParam 1000000 1356 ns/op 344 B/op 8 allocs/op
+BenchmarkTigerTonic_GithubParam 388899 3429 ns/op 1176 B/op 22 allocs/op
+BenchmarkTraffic_GithubParam 123160 9734 ns/op 2816 B/op 40 allocs/op
+BenchmarkVulcan_GithubParam 1000000 1138 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_GithubAll 40543 29670 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GithubAll 57632 20648 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GithubAll 9234 216179 ns/op 86448 B/op 943 allocs/op
+BenchmarkBeego_GithubAll 7407 243496 ns/op 71456 B/op 609 allocs/op
+BenchmarkBone_GithubAll 420 2922835 ns/op 720160 B/op 8620 allocs/op
+BenchmarkChi_GithubAll 7620 238331 ns/op 87696 B/op 609 allocs/op
+BenchmarkDenco_GithubAll 18355 64494 ns/op 20224 B/op 167 allocs/op
+BenchmarkEcho_GithubAll 31251 38479 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_GithubAll 43550 27364 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GithubAll 4117 300062 ns/op 131656 B/op 1686 allocs/op
+BenchmarkGoji_GithubAll 3274 416158 ns/op 56112 B/op 334 allocs/op
+BenchmarkGojiv2_GithubAll 1402 870518 ns/op 352720 B/op 4321 allocs/op
+BenchmarkGoJsonRest_GithubAll 2976 401507 ns/op 134371 B/op 2737 allocs/op
+BenchmarkGoRestful_GithubAll 410 2913158 ns/op 910144 B/op 2938 allocs/op
+BenchmarkGorillaMux_GithubAll 346 3384987 ns/op 251650 B/op 1994 allocs/op
+BenchmarkGowwwRouter_GithubAll 10000 143025 ns/op 72144 B/op 501 allocs/op
+BenchmarkHttpRouter_GithubAll 55938 21360 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GithubAll 10000 153944 ns/op 65856 B/op 671 allocs/op
+BenchmarkKocha_GithubAll 10000 106315 ns/op 23304 B/op 843 allocs/op
+BenchmarkLARS_GithubAll 47779 25084 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GithubAll 3266 371907 ns/op 149409 B/op 1624 allocs/op
+BenchmarkMartini_GithubAll 331 3444706 ns/op 226551 B/op 2325 allocs/op
+BenchmarkPat_GithubAll 273 4381818 ns/op 1483152 B/op 26963 allocs/op
+BenchmarkPossum_GithubAll 10000 164367 ns/op 84448 B/op 609 allocs/op
+BenchmarkR2router_GithubAll 10000 160220 ns/op 77328 B/op 979 allocs/op
+BenchmarkRivet_GithubAll 14625 82453 ns/op 16272 B/op 167 allocs/op
+BenchmarkTango_GithubAll 6255 279611 ns/op 63826 B/op 1618 allocs/op
+BenchmarkTigerTonic_GithubAll 2008 687874 ns/op 193856 B/op 4474 allocs/op
+BenchmarkTraffic_GithubAll 355 3478508 ns/op 820744 B/op 14114 allocs/op
+BenchmarkVulcan_GithubAll 6885 193333 ns/op 19894 B/op 609 allocs/op
```
## Google+
-```
-BenchmarkGin_GPlusStatic 10000000 183 ns/op 0 B/op 0 allocs/op
+```sh
+BenchmarkGin_GPlusStatic 19247326 62.2 ns/op 0 B/op 0 allocs/op
-BenchmarkAce_GPlusStatic 5000000 276 ns/op 0 B/op 0 allocs/op
-BenchmarkBear_GPlusStatic 2000000 652 ns/op 104 B/op 3 allocs/op
-BenchmarkBeego_GPlusStatic 1000000 2239 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_GPlusStatic 5000000 380 ns/op 32 B/op 1 allocs/op
-BenchmarkDenco_GPlusStatic 30000000 45.8 ns/op 0 B/op 0 allocs/op
-BenchmarkEcho_GPlusStatic 5000000 338 ns/op 32 B/op 1 allocs/op
-BenchmarkGocraftWeb_GPlusStatic 1000000 1158 ns/op 280 B/op 5 allocs/op
-BenchmarkGoji_GPlusStatic 5000000 331 ns/op 0 B/op 0 allocs/op
-BenchmarkGojiv2_GPlusStatic 1000000 2106 ns/op 928 B/op 7 allocs/op
-BenchmarkGoJsonRest_GPlusStatic 1000000 1626 ns/op 329 B/op 11 allocs/op
-BenchmarkGoRestful_GPlusStatic 300000 7598 ns/op 1976 B/op 20 allocs/op
-BenchmarkGorillaMux_GPlusStatic 1000000 2629 ns/op 736 B/op 10 allocs/op
-BenchmarkHttpRouter_GPlusStatic 30000000 52.5 ns/op 0 B/op 0 allocs/op
-BenchmarkHttpTreeMux_GPlusStatic 20000000 85.8 ns/op 0 B/op 0 allocs/op
-BenchmarkKocha_GPlusStatic 20000000 89.2 ns/op 0 B/op 0 allocs/op
-BenchmarkLARS_GPlusStatic 10000000 162 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GPlusStatic 500000 3479 ns/op 768 B/op 9 allocs/op
-BenchmarkMartini_GPlusStatic 200000 9092 ns/op 768 B/op 9 allocs/op
-BenchmarkPat_GPlusStatic 3000000 493 ns/op 96 B/op 2 allocs/op
-BenchmarkPossum_GPlusStatic 1000000 1467 ns/op 416 B/op 3 allocs/op
-BenchmarkR2router_GPlusStatic 2000000 788 ns/op 144 B/op 4 allocs/op
-BenchmarkRivet_GPlusStatic 20000000 114 ns/op 0 B/op 0 allocs/op
-BenchmarkTango_GPlusStatic 1000000 1534 ns/op 200 B/op 8 allocs/op
-BenchmarkTigerTonic_GPlusStatic 5000000 282 ns/op 32 B/op 1 allocs/op
-BenchmarkTraffic_GPlusStatic 500000 3798 ns/op 1192 B/op 15 allocs/op
-BenchmarkVulcan_GPlusStatic 2000000 1125 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_GPlusParam 3000000 528 ns/op 64 B/op 1 allocs/op
-BenchmarkBear_GPlusParam 1000000 1570 ns/op 480 B/op 5 allocs/op
-BenchmarkBeego_GPlusParam 1000000 2369 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_GPlusParam 1000000 2028 ns/op 688 B/op 5 allocs/op
-BenchmarkDenco_GPlusParam 5000000 385 ns/op 64 B/op 1 allocs/op
-BenchmarkEcho_GPlusParam 3000000 441 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_GPlusParam 10000000 174 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_GPlusParam 1000000 2033 ns/op 648 B/op 8 allocs/op
-BenchmarkGoji_GPlusParam 1000000 1399 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_GPlusParam 1000000 2641 ns/op 944 B/op 8 allocs/op
-BenchmarkGoJsonRest_GPlusParam 1000000 2824 ns/op 649 B/op 13 allocs/op
-BenchmarkGoRestful_GPlusParam 200000 8875 ns/op 2296 B/op 21 allocs/op
-BenchmarkGorillaMux_GPlusParam 200000 6291 ns/op 1056 B/op 11 allocs/op
-BenchmarkHttpRouter_GPlusParam 5000000 316 ns/op 64 B/op 1 allocs/op
-BenchmarkHttpTreeMux_GPlusParam 1000000 1129 ns/op 352 B/op 3 allocs/op
-BenchmarkKocha_GPlusParam 3000000 538 ns/op 56 B/op 3 allocs/op
-BenchmarkLARS_GPlusParam 10000000 198 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GPlusParam 500000 3554 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_GPlusParam 200000 9831 ns/op 1072 B/op 10 allocs/op
-BenchmarkPat_GPlusParam 1000000 2706 ns/op 688 B/op 12 allocs/op
-BenchmarkPossum_GPlusParam 1000000 2297 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_GPlusParam 1000000 1318 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_GPlusParam 5000000 399 ns/op 48 B/op 1 allocs/op
-BenchmarkTango_GPlusParam 1000000 2070 ns/op 264 B/op 8 allocs/op
-BenchmarkTigerTonic_GPlusParam 500000 4853 ns/op 1056 B/op 17 allocs/op
-BenchmarkTraffic_GPlusParam 200000 8278 ns/op 1976 B/op 21 allocs/op
-BenchmarkVulcan_GPlusParam 1000000 1243 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_GPlus2Params 3000000 549 ns/op 64 B/op 1 allocs/op
-BenchmarkBear_GPlus2Params 1000000 2112 ns/op 496 B/op 5 allocs/op
-BenchmarkBeego_GPlus2Params 500000 2750 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_GPlus2Params 300000 7032 ns/op 1040 B/op 9 allocs/op
-BenchmarkDenco_GPlus2Params 3000000 502 ns/op 64 B/op 1 allocs/op
-BenchmarkEcho_GPlus2Params 3000000 641 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_GPlus2Params 5000000 250 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_GPlus2Params 1000000 2681 ns/op 712 B/op 9 allocs/op
-BenchmarkGoji_GPlus2Params 1000000 1926 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_GPlus2Params 500000 3996 ns/op 1024 B/op 11 allocs/op
-BenchmarkGoJsonRest_GPlus2Params 500000 3886 ns/op 713 B/op 14 allocs/op
-BenchmarkGoRestful_GPlus2Params 200000 10376 ns/op 2360 B/op 21 allocs/op
-BenchmarkGorillaMux_GPlus2Params 100000 14162 ns/op 1088 B/op 11 allocs/op
-BenchmarkHttpRouter_GPlus2Params 5000000 336 ns/op 64 B/op 1 allocs/op
-BenchmarkHttpTreeMux_GPlus2Params 1000000 1523 ns/op 384 B/op 4 allocs/op
-BenchmarkKocha_GPlus2Params 2000000 970 ns/op 128 B/op 5 allocs/op
-BenchmarkLARS_GPlus2Params 5000000 238 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GPlus2Params 500000 4016 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_GPlus2Params 100000 21253 ns/op 1200 B/op 13 allocs/op
-BenchmarkPat_GPlus2Params 200000 8632 ns/op 2256 B/op 34 allocs/op
-BenchmarkPossum_GPlus2Params 1000000 2171 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_GPlus2Params 1000000 1340 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_GPlus2Params 3000000 557 ns/op 96 B/op 1 allocs/op
-BenchmarkTango_GPlus2Params 1000000 2186 ns/op 344 B/op 8 allocs/op
-BenchmarkTigerTonic_GPlus2Params 200000 9060 ns/op 1488 B/op 24 allocs/op
-BenchmarkTraffic_GPlus2Params 100000 20324 ns/op 3272 B/op 31 allocs/op
-BenchmarkVulcan_GPlus2Params 1000000 2039 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_GPlusAll 300000 6603 ns/op 640 B/op 11 allocs/op
-BenchmarkBear_GPlusAll 100000 22363 ns/op 5488 B/op 61 allocs/op
-BenchmarkBeego_GPlusAll 50000 38757 ns/op 4784 B/op 52 allocs/op
-BenchmarkBone_GPlusAll 20000 54916 ns/op 10336 B/op 98 allocs/op
-BenchmarkDenco_GPlusAll 300000 4959 ns/op 672 B/op 11 allocs/op
-BenchmarkEcho_GPlusAll 200000 6558 ns/op 416 B/op 13 allocs/op
-BenchmarkGin_GPlusAll 500000 2757 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_GPlusAll 50000 34615 ns/op 8040 B/op 103 allocs/op
-BenchmarkGoji_GPlusAll 100000 16002 ns/op 3696 B/op 22 allocs/op
-BenchmarkGojiv2_GPlusAll 50000 35060 ns/op 12624 B/op 115 allocs/op
-BenchmarkGoJsonRest_GPlusAll 50000 41479 ns/op 8117 B/op 170 allocs/op
-BenchmarkGoRestful_GPlusAll 10000 131653 ns/op 32024 B/op 275 allocs/op
-BenchmarkGorillaMux_GPlusAll 10000 101380 ns/op 13296 B/op 142 allocs/op
-BenchmarkHttpRouter_GPlusAll 500000 3711 ns/op 640 B/op 11 allocs/op
-BenchmarkHttpTreeMux_GPlusAll 100000 14438 ns/op 4032 B/op 38 allocs/op
-BenchmarkKocha_GPlusAll 200000 8039 ns/op 976 B/op 43 allocs/op
-BenchmarkLARS_GPlusAll 500000 2630 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_GPlusAll 30000 51123 ns/op 13152 B/op 128 allocs/op
-BenchmarkMartini_GPlusAll 10000 176157 ns/op 14016 B/op 145 allocs/op
-BenchmarkPat_GPlusAll 20000 69911 ns/op 16576 B/op 298 allocs/op
-BenchmarkPossum_GPlusAll 100000 20716 ns/op 5408 B/op 39 allocs/op
-BenchmarkR2router_GPlusAll 100000 17463 ns/op 5040 B/op 63 allocs/op
-BenchmarkRivet_GPlusAll 300000 5142 ns/op 768 B/op 11 allocs/op
-BenchmarkTango_GPlusAll 50000 27321 ns/op 3656 B/op 104 allocs/op
-BenchmarkTigerTonic_GPlusAll 20000 77597 ns/op 14512 B/op 288 allocs/op
-BenchmarkTraffic_GPlusAll 10000 151406 ns/op 37360 B/op 392 allocs/op
-BenchmarkVulcan_GPlusAll 100000 18555 ns/op 1274 B/op 39 allocs/op
+BenchmarkAce_GPlusStatic 20235060 59.2 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GPlusStatic 31978935 37.6 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GPlusStatic 3516523 341 ns/op 104 B/op 3 allocs/op
+BenchmarkBeego_GPlusStatic 1212036 991 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_GPlusStatic 6736242 183 ns/op 32 B/op 1 allocs/op
+BenchmarkChi_GPlusStatic 1490640 814 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_GPlusStatic 55006856 21.8 ns/op 0 B/op 0 allocs/op
+BenchmarkEcho_GPlusStatic 17688258 67.9 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GPlusStatic 1829181 666 ns/op 280 B/op 5 allocs/op
+BenchmarkGoji_GPlusStatic 9147451 130 ns/op 0 B/op 0 allocs/op
+BenchmarkGojiv2_GPlusStatic 594015 2063 ns/op 1312 B/op 10 allocs/op
+BenchmarkGoJsonRest_GPlusStatic 1264906 950 ns/op 329 B/op 11 allocs/op
+BenchmarkGoRestful_GPlusStatic 231558 5341 ns/op 3872 B/op 13 allocs/op
+BenchmarkGorillaMux_GPlusStatic 908418 1809 ns/op 976 B/op 9 allocs/op
+BenchmarkGowwwRouter_GPlusStatic 40684604 29.5 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpRouter_GPlusStatic 46742804 25.7 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GPlusStatic 32567161 36.9 ns/op 0 B/op 0 allocs/op
+BenchmarkKocha_GPlusStatic 33800060 35.3 ns/op 0 B/op 0 allocs/op
+BenchmarkLARS_GPlusStatic 20431858 60.0 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GPlusStatic 1000000 1745 ns/op 736 B/op 8 allocs/op
+BenchmarkMartini_GPlusStatic 442248 3619 ns/op 768 B/op 9 allocs/op
+BenchmarkPat_GPlusStatic 4328004 292 ns/op 96 B/op 2 allocs/op
+BenchmarkPossum_GPlusStatic 1570753 763 ns/op 416 B/op 3 allocs/op
+BenchmarkR2router_GPlusStatic 3339474 355 ns/op 144 B/op 4 allocs/op
+BenchmarkRivet_GPlusStatic 18570961 64.7 ns/op 0 B/op 0 allocs/op
+BenchmarkTango_GPlusStatic 1388702 860 ns/op 200 B/op 8 allocs/op
+BenchmarkTigerTonic_GPlusStatic 7803543 159 ns/op 32 B/op 1 allocs/op
+BenchmarkTraffic_GPlusStatic 878605 2171 ns/op 1112 B/op 16 allocs/op
+BenchmarkVulcan_GPlusStatic 2742446 437 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_GPlusParam 11626975 105 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GPlusParam 16914322 71.6 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GPlusParam 1405173 832 ns/op 480 B/op 5 allocs/op
+BenchmarkBeego_GPlusParam 1000000 1075 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_GPlusParam 1000000 1557 ns/op 816 B/op 6 allocs/op
+BenchmarkChi_GPlusParam 1347926 894 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_GPlusParam 5513000 212 ns/op 64 B/op 1 allocs/op
+BenchmarkEcho_GPlusParam 11884383 101 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_GPlusParam 12898952 93.1 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GPlusParam 1000000 1194 ns/op 648 B/op 8 allocs/op
+BenchmarkGoji_GPlusParam 1857229 645 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_GPlusParam 520939 2322 ns/op 1328 B/op 11 allocs/op
+BenchmarkGoJsonRest_GPlusParam 1000000 1536 ns/op 649 B/op 13 allocs/op
+BenchmarkGoRestful_GPlusParam 205449 5800 ns/op 4192 B/op 14 allocs/op
+BenchmarkGorillaMux_GPlusParam 395310 3188 ns/op 1280 B/op 10 allocs/op
+BenchmarkGowwwRouter_GPlusParam 1851798 667 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_GPlusParam 18420789 65.2 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GPlusParam 1878463 629 ns/op 352 B/op 3 allocs/op
+BenchmarkKocha_GPlusParam 4495610 273 ns/op 56 B/op 3 allocs/op
+BenchmarkLARS_GPlusParam 14615976 83.2 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GPlusParam 584145 2549 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_GPlusParam 250501 4583 ns/op 1072 B/op 10 allocs/op
+BenchmarkPat_GPlusParam 1000000 1645 ns/op 576 B/op 11 allocs/op
+BenchmarkPossum_GPlusParam 1000000 1008 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_GPlusParam 1708191 688 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_GPlusParam 5795014 211 ns/op 48 B/op 1 allocs/op
+BenchmarkTango_GPlusParam 1000000 1091 ns/op 264 B/op 8 allocs/op
+BenchmarkTigerTonic_GPlusParam 760221 2489 ns/op 856 B/op 16 allocs/op
+BenchmarkTraffic_GPlusParam 309774 4039 ns/op 1872 B/op 21 allocs/op
+BenchmarkVulcan_GPlusParam 1935730 623 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_GPlus2Params 9158314 134 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GPlus2Params 11300517 107 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GPlus2Params 1239238 961 ns/op 496 B/op 5 allocs/op
+BenchmarkBeego_GPlus2Params 1000000 1202 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_GPlus2Params 335576 3725 ns/op 1168 B/op 10 allocs/op
+BenchmarkChi_GPlus2Params 1000000 1014 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_GPlus2Params 4394598 280 ns/op 64 B/op 1 allocs/op
+BenchmarkEcho_GPlus2Params 7851861 154 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_GPlus2Params 9958588 120 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GPlus2Params 1000000 1433 ns/op 712 B/op 9 allocs/op
+BenchmarkGoji_GPlus2Params 1325134 909 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_GPlus2Params 405955 2870 ns/op 1408 B/op 14 allocs/op
+BenchmarkGoJsonRest_GPlus2Params 977038 1987 ns/op 713 B/op 14 allocs/op
+BenchmarkGoRestful_GPlus2Params 205018 6142 ns/op 4384 B/op 16 allocs/op
+BenchmarkGorillaMux_GPlus2Params 205641 6015 ns/op 1296 B/op 10 allocs/op
+BenchmarkGowwwRouter_GPlus2Params 1748542 684 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_GPlus2Params 14047102 87.7 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GPlus2Params 1418673 828 ns/op 384 B/op 4 allocs/op
+BenchmarkKocha_GPlus2Params 2334562 520 ns/op 128 B/op 5 allocs/op
+BenchmarkLARS_GPlus2Params 11954094 101 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GPlus2Params 491552 2890 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_GPlus2Params 120532 9545 ns/op 1200 B/op 13 allocs/op
+BenchmarkPat_GPlus2Params 194739 6766 ns/op 2168 B/op 33 allocs/op
+BenchmarkPossum_GPlus2Params 1201224 1009 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_GPlus2Params 1575535 756 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_GPlus2Params 3698930 325 ns/op 96 B/op 1 allocs/op
+BenchmarkTango_GPlus2Params 1000000 1212 ns/op 344 B/op 8 allocs/op
+BenchmarkTigerTonic_GPlus2Params 349350 3660 ns/op 1200 B/op 22 allocs/op
+BenchmarkTraffic_GPlus2Params 169714 7862 ns/op 2248 B/op 28 allocs/op
+BenchmarkVulcan_GPlus2Params 1222288 974 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_GPlusAll 845606 1398 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_GPlusAll 1000000 1009 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_GPlusAll 103830 11386 ns/op 5488 B/op 61 allocs/op
+BenchmarkBeego_GPlusAll 82653 14784 ns/op 4576 B/op 39 allocs/op
+BenchmarkBone_GPlusAll 36601 33123 ns/op 11744 B/op 109 allocs/op
+BenchmarkChi_GPlusAll 95264 12831 ns/op 5616 B/op 39 allocs/op
+BenchmarkDenco_GPlusAll 567681 2950 ns/op 672 B/op 11 allocs/op
+BenchmarkEcho_GPlusAll 720366 1665 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_GPlusAll 1000000 1185 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_GPlusAll 71575 16365 ns/op 8040 B/op 103 allocs/op
+BenchmarkGoji_GPlusAll 136352 9191 ns/op 3696 B/op 22 allocs/op
+BenchmarkGojiv2_GPlusAll 38006 31802 ns/op 17616 B/op 154 allocs/op
+BenchmarkGoJsonRest_GPlusAll 57238 21561 ns/op 8117 B/op 170 allocs/op
+BenchmarkGoRestful_GPlusAll 15147 79276 ns/op 55520 B/op 192 allocs/op
+BenchmarkGorillaMux_GPlusAll 24446 48410 ns/op 16112 B/op 128 allocs/op
+BenchmarkGowwwRouter_GPlusAll 150112 7770 ns/op 4752 B/op 33 allocs/op
+BenchmarkHttpRouter_GPlusAll 1367820 878 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_GPlusAll 166628 8004 ns/op 4032 B/op 38 allocs/op
+BenchmarkKocha_GPlusAll 265694 4570 ns/op 976 B/op 43 allocs/op
+BenchmarkLARS_GPlusAll 1000000 1068 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_GPlusAll 54564 23305 ns/op 9568 B/op 104 allocs/op
+BenchmarkMartini_GPlusAll 16274 73845 ns/op 14016 B/op 145 allocs/op
+BenchmarkPat_GPlusAll 27181 44478 ns/op 15264 B/op 271 allocs/op
+BenchmarkPossum_GPlusAll 122587 10277 ns/op 5408 B/op 39 allocs/op
+BenchmarkR2router_GPlusAll 130137 9297 ns/op 5040 B/op 63 allocs/op
+BenchmarkRivet_GPlusAll 532438 3323 ns/op 768 B/op 11 allocs/op
+BenchmarkTango_GPlusAll 86054 14531 ns/op 3656 B/op 104 allocs/op
+BenchmarkTigerTonic_GPlusAll 33936 35356 ns/op 11600 B/op 242 allocs/op
+BenchmarkTraffic_GPlusAll 17833 68181 ns/op 26248 B/op 341 allocs/op
+BenchmarkVulcan_GPlusAll 120109 9861 ns/op 1274 B/op 39 allocs/op
```
## Parse.com
-```
-BenchmarkGin_ParseStatic 10000000 133 ns/op 0 B/op 0 allocs/op
+```sh
+BenchmarkGin_ParseStatic 18877833 63.5 ns/op 0 B/op 0 allocs/op
-BenchmarkAce_ParseStatic 5000000 241 ns/op 0 B/op 0 allocs/op
-BenchmarkBear_ParseStatic 2000000 728 ns/op 120 B/op 3 allocs/op
-BenchmarkBeego_ParseStatic 1000000 2623 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_ParseStatic 1000000 1285 ns/op 144 B/op 3 allocs/op
-BenchmarkDenco_ParseStatic 30000000 57.8 ns/op 0 B/op 0 allocs/op
-BenchmarkEcho_ParseStatic 5000000 342 ns/op 32 B/op 1 allocs/op
-BenchmarkGocraftWeb_ParseStatic 1000000 1478 ns/op 296 B/op 5 allocs/op
-BenchmarkGoji_ParseStatic 3000000 415 ns/op 0 B/op 0 allocs/op
-BenchmarkGojiv2_ParseStatic 1000000 2087 ns/op 928 B/op 7 allocs/op
-BenchmarkGoJsonRest_ParseStatic 1000000 1712 ns/op 329 B/op 11 allocs/op
-BenchmarkGoRestful_ParseStatic 200000 11072 ns/op 3224 B/op 22 allocs/op
-BenchmarkGorillaMux_ParseStatic 500000 4129 ns/op 752 B/op 11 allocs/op
-BenchmarkHttpRouter_ParseStatic 30000000 52.4 ns/op 0 B/op 0 allocs/op
-BenchmarkHttpTreeMux_ParseStatic 20000000 109 ns/op 0 B/op 0 allocs/op
-BenchmarkKocha_ParseStatic 20000000 81.8 ns/op 0 B/op 0 allocs/op
-BenchmarkLARS_ParseStatic 10000000 150 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_ParseStatic 1000000 3288 ns/op 768 B/op 9 allocs/op
-BenchmarkMartini_ParseStatic 200000 9110 ns/op 768 B/op 9 allocs/op
-BenchmarkPat_ParseStatic 1000000 1135 ns/op 240 B/op 5 allocs/op
-BenchmarkPossum_ParseStatic 1000000 1557 ns/op 416 B/op 3 allocs/op
-BenchmarkR2router_ParseStatic 2000000 730 ns/op 144 B/op 4 allocs/op
-BenchmarkRivet_ParseStatic 10000000 121 ns/op 0 B/op 0 allocs/op
-BenchmarkTango_ParseStatic 1000000 1688 ns/op 248 B/op 8 allocs/op
-BenchmarkTigerTonic_ParseStatic 3000000 427 ns/op 48 B/op 1 allocs/op
-BenchmarkTraffic_ParseStatic 500000 5962 ns/op 1816 B/op 20 allocs/op
-BenchmarkVulcan_ParseStatic 2000000 969 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_ParseParam 3000000 497 ns/op 64 B/op 1 allocs/op
-BenchmarkBear_ParseParam 1000000 1473 ns/op 467 B/op 5 allocs/op
-BenchmarkBeego_ParseParam 1000000 2384 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_ParseParam 1000000 2513 ns/op 768 B/op 6 allocs/op
-BenchmarkDenco_ParseParam 5000000 364 ns/op 64 B/op 1 allocs/op
-BenchmarkEcho_ParseParam 5000000 418 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_ParseParam 10000000 163 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_ParseParam 1000000 2361 ns/op 664 B/op 8 allocs/op
-BenchmarkGoji_ParseParam 1000000 1590 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_ParseParam 1000000 2851 ns/op 976 B/op 9 allocs/op
-BenchmarkGoJsonRest_ParseParam 1000000 2965 ns/op 649 B/op 13 allocs/op
-BenchmarkGoRestful_ParseParam 200000 12207 ns/op 3544 B/op 23 allocs/op
-BenchmarkGorillaMux_ParseParam 500000 5187 ns/op 1088 B/op 12 allocs/op
-BenchmarkHttpRouter_ParseParam 5000000 275 ns/op 64 B/op 1 allocs/op
-BenchmarkHttpTreeMux_ParseParam 1000000 1108 ns/op 352 B/op 3 allocs/op
-BenchmarkKocha_ParseParam 3000000 495 ns/op 56 B/op 3 allocs/op
-BenchmarkLARS_ParseParam 10000000 192 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_ParseParam 500000 4103 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_ParseParam 200000 9878 ns/op 1072 B/op 10 allocs/op
-BenchmarkPat_ParseParam 500000 3657 ns/op 1120 B/op 17 allocs/op
-BenchmarkPossum_ParseParam 1000000 2084 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_ParseParam 1000000 1251 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_ParseParam 5000000 335 ns/op 48 B/op 1 allocs/op
-BenchmarkTango_ParseParam 1000000 1854 ns/op 280 B/op 8 allocs/op
-BenchmarkTigerTonic_ParseParam 500000 4582 ns/op 1008 B/op 17 allocs/op
-BenchmarkTraffic_ParseParam 200000 8125 ns/op 2248 B/op 23 allocs/op
-BenchmarkVulcan_ParseParam 1000000 1148 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_Parse2Params 3000000 539 ns/op 64 B/op 1 allocs/op
-BenchmarkBear_Parse2Params 1000000 1778 ns/op 496 B/op 5 allocs/op
-BenchmarkBeego_Parse2Params 1000000 2519 ns/op 368 B/op 4 allocs/op
-BenchmarkBone_Parse2Params 1000000 2596 ns/op 720 B/op 5 allocs/op
-BenchmarkDenco_Parse2Params 3000000 492 ns/op 64 B/op 1 allocs/op
-BenchmarkEcho_Parse2Params 3000000 484 ns/op 32 B/op 1 allocs/op
-BenchmarkGin_Parse2Params 10000000 193 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_Parse2Params 1000000 2575 ns/op 712 B/op 9 allocs/op
-BenchmarkGoji_Parse2Params 1000000 1373 ns/op 336 B/op 2 allocs/op
-BenchmarkGojiv2_Parse2Params 500000 2416 ns/op 960 B/op 8 allocs/op
-BenchmarkGoJsonRest_Parse2Params 300000 3452 ns/op 713 B/op 14 allocs/op
-BenchmarkGoRestful_Parse2Params 100000 17719 ns/op 6008 B/op 25 allocs/op
-BenchmarkGorillaMux_Parse2Params 300000 5102 ns/op 1088 B/op 11 allocs/op
-BenchmarkHttpRouter_Parse2Params 5000000 303 ns/op 64 B/op 1 allocs/op
-BenchmarkHttpTreeMux_Parse2Params 1000000 1372 ns/op 384 B/op 4 allocs/op
-BenchmarkKocha_Parse2Params 2000000 874 ns/op 128 B/op 5 allocs/op
-BenchmarkLARS_Parse2Params 10000000 192 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_Parse2Params 500000 3871 ns/op 1056 B/op 10 allocs/op
-BenchmarkMartini_Parse2Params 200000 9954 ns/op 1152 B/op 11 allocs/op
-BenchmarkPat_Parse2Params 500000 4194 ns/op 832 B/op 17 allocs/op
-BenchmarkPossum_Parse2Params 1000000 2121 ns/op 560 B/op 6 allocs/op
-BenchmarkR2router_Parse2Params 1000000 1415 ns/op 432 B/op 5 allocs/op
-BenchmarkRivet_Parse2Params 3000000 457 ns/op 96 B/op 1 allocs/op
-BenchmarkTango_Parse2Params 1000000 1914 ns/op 312 B/op 8 allocs/op
-BenchmarkTigerTonic_Parse2Params 300000 6895 ns/op 1408 B/op 24 allocs/op
-BenchmarkTraffic_Parse2Params 200000 8317 ns/op 2040 B/op 22 allocs/op
-BenchmarkVulcan_Parse2Params 1000000 1274 ns/op 98 B/op 3 allocs/op
-BenchmarkAce_ParseAll 200000 10401 ns/op 640 B/op 16 allocs/op
-BenchmarkBear_ParseAll 50000 37743 ns/op 8928 B/op 110 allocs/op
-BenchmarkBeego_ParseAll 20000 63193 ns/op 9568 B/op 104 allocs/op
-BenchmarkBone_ParseAll 20000 61767 ns/op 14160 B/op 131 allocs/op
-BenchmarkDenco_ParseAll 300000 7036 ns/op 928 B/op 16 allocs/op
-BenchmarkEcho_ParseAll 200000 11824 ns/op 832 B/op 26 allocs/op
-BenchmarkGin_ParseAll 300000 4199 ns/op 0 B/op 0 allocs/op
-BenchmarkGocraftWeb_ParseAll 30000 51758 ns/op 13728 B/op 181 allocs/op
-BenchmarkGoji_ParseAll 50000 29614 ns/op 5376 B/op 32 allocs/op
-BenchmarkGojiv2_ParseAll 20000 68676 ns/op 24464 B/op 199 allocs/op
-BenchmarkGoJsonRest_ParseAll 20000 76135 ns/op 13866 B/op 321 allocs/op
-BenchmarkGoRestful_ParseAll 5000 389487 ns/op 110928 B/op 600 allocs/op
-BenchmarkGorillaMux_ParseAll 10000 221250 ns/op 24864 B/op 292 allocs/op
-BenchmarkHttpRouter_ParseAll 200000 6444 ns/op 640 B/op 16 allocs/op
-BenchmarkHttpTreeMux_ParseAll 50000 30702 ns/op 5728 B/op 51 allocs/op
-BenchmarkKocha_ParseAll 200000 13712 ns/op 1112 B/op 54 allocs/op
-BenchmarkLARS_ParseAll 300000 6925 ns/op 0 B/op 0 allocs/op
-BenchmarkMacaron_ParseAll 20000 96278 ns/op 24576 B/op 250 allocs/op
-BenchmarkMartini_ParseAll 5000 271352 ns/op 25072 B/op 253 allocs/op
-BenchmarkPat_ParseAll 20000 74941 ns/op 17264 B/op 343 allocs/op
-BenchmarkPossum_ParseAll 50000 39947 ns/op 10816 B/op 78 allocs/op
-BenchmarkR2router_ParseAll 50000 42479 ns/op 8352 B/op 120 allocs/op
-BenchmarkRivet_ParseAll 200000 7726 ns/op 912 B/op 16 allocs/op
-BenchmarkTango_ParseAll 30000 50014 ns/op 7168 B/op 208 allocs/op
-BenchmarkTigerTonic_ParseAll 10000 106550 ns/op 19728 B/op 379 allocs/op
-BenchmarkTraffic_ParseAll 10000 216037 ns/op 57776 B/op 642 allocs/op
-BenchmarkVulcan_ParseAll 50000 34379 ns/op 2548 B/op 78 allocs/op
+BenchmarkAce_ParseStatic 19663731 60.8 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_ParseStatic 28967341 41.5 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_ParseStatic 3006984 402 ns/op 120 B/op 3 allocs/op
+BenchmarkBeego_ParseStatic 1000000 1031 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_ParseStatic 1782482 675 ns/op 144 B/op 3 allocs/op
+BenchmarkChi_ParseStatic 1453261 819 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_ParseStatic 45023595 26.5 ns/op 0 B/op 0 allocs/op
+BenchmarkEcho_ParseStatic 17330470 69.3 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_ParseStatic 1644006 731 ns/op 296 B/op 5 allocs/op
+BenchmarkGoji_ParseStatic 7026930 170 ns/op 0 B/op 0 allocs/op
+BenchmarkGojiv2_ParseStatic 517618 2037 ns/op 1312 B/op 10 allocs/op
+BenchmarkGoJsonRest_ParseStatic 1227080 975 ns/op 329 B/op 11 allocs/op
+BenchmarkGoRestful_ParseStatic 192458 6659 ns/op 4256 B/op 13 allocs/op
+BenchmarkGorillaMux_ParseStatic 744062 2109 ns/op 976 B/op 9 allocs/op
+BenchmarkGowwwRouter_ParseStatic 37781062 31.8 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpRouter_ParseStatic 45311223 26.5 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_ParseStatic 21383475 56.1 ns/op 0 B/op 0 allocs/op
+BenchmarkKocha_ParseStatic 29953290 40.1 ns/op 0 B/op 0 allocs/op
+BenchmarkLARS_ParseStatic 20036196 62.7 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_ParseStatic 1000000 1740 ns/op 736 B/op 8 allocs/op
+BenchmarkMartini_ParseStatic 404156 3801 ns/op 768 B/op 9 allocs/op
+BenchmarkPat_ParseStatic 1547180 772 ns/op 240 B/op 5 allocs/op
+BenchmarkPossum_ParseStatic 1608991 757 ns/op 416 B/op 3 allocs/op
+BenchmarkR2router_ParseStatic 3177936 385 ns/op 144 B/op 4 allocs/op
+BenchmarkRivet_ParseStatic 17783205 67.4 ns/op 0 B/op 0 allocs/op
+BenchmarkTango_ParseStatic 1210777 990 ns/op 248 B/op 8 allocs/op
+BenchmarkTigerTonic_ParseStatic 5316440 231 ns/op 48 B/op 1 allocs/op
+BenchmarkTraffic_ParseStatic 496050 2539 ns/op 1256 B/op 19 allocs/op
+BenchmarkVulcan_ParseStatic 2462798 488 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_ParseParam 13393669 89.6 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_ParseParam 19836619 60.4 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_ParseParam 1405954 864 ns/op 467 B/op 5 allocs/op
+BenchmarkBeego_ParseParam 1000000 1065 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_ParseParam 1000000 1698 ns/op 896 B/op 7 allocs/op
+BenchmarkChi_ParseParam 1356037 873 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_ParseParam 6241392 204 ns/op 64 B/op 1 allocs/op
+BenchmarkEcho_ParseParam 14088100 85.1 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_ParseParam 17426064 68.9 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_ParseParam 1000000 1254 ns/op 664 B/op 8 allocs/op
+BenchmarkGoji_ParseParam 1682574 713 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_ParseParam 502224 2333 ns/op 1360 B/op 12 allocs/op
+BenchmarkGoJsonRest_ParseParam 1000000 1401 ns/op 649 B/op 13 allocs/op
+BenchmarkGoRestful_ParseParam 182623 7097 ns/op 4576 B/op 14 allocs/op
+BenchmarkGorillaMux_ParseParam 482332 2477 ns/op 1280 B/op 10 allocs/op
+BenchmarkGowwwRouter_ParseParam 1834873 657 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_ParseParam 23593393 51.0 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_ParseParam 2100160 574 ns/op 352 B/op 3 allocs/op
+BenchmarkKocha_ParseParam 4837220 252 ns/op 56 B/op 3 allocs/op
+BenchmarkLARS_ParseParam 18411192 66.2 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_ParseParam 571870 2398 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_ParseParam 286262 4268 ns/op 1072 B/op 10 allocs/op
+BenchmarkPat_ParseParam 692906 2157 ns/op 992 B/op 15 allocs/op
+BenchmarkPossum_ParseParam 1000000 1011 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_ParseParam 1722735 697 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_ParseParam 6058054 203 ns/op 48 B/op 1 allocs/op
+BenchmarkTango_ParseParam 1000000 1061 ns/op 280 B/op 8 allocs/op
+BenchmarkTigerTonic_ParseParam 890275 2277 ns/op 784 B/op 15 allocs/op
+BenchmarkTraffic_ParseParam 351322 3543 ns/op 1896 B/op 21 allocs/op
+BenchmarkVulcan_ParseParam 2076544 572 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_Parse2Params 11718074 101 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_Parse2Params 16264988 73.4 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_Parse2Params 1238322 973 ns/op 496 B/op 5 allocs/op
+BenchmarkBeego_Parse2Params 1000000 1120 ns/op 352 B/op 3 allocs/op
+BenchmarkBone_Parse2Params 1000000 1632 ns/op 848 B/op 6 allocs/op
+BenchmarkChi_Parse2Params 1239477 955 ns/op 432 B/op 3 allocs/op
+BenchmarkDenco_Parse2Params 4944133 245 ns/op 64 B/op 1 allocs/op
+BenchmarkEcho_Parse2Params 10518286 114 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_Parse2Params 14505195 82.7 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_Parse2Params 1000000 1437 ns/op 712 B/op 9 allocs/op
+BenchmarkGoji_Parse2Params 1689883 707 ns/op 336 B/op 2 allocs/op
+BenchmarkGojiv2_Parse2Params 502334 2308 ns/op 1344 B/op 11 allocs/op
+BenchmarkGoJsonRest_Parse2Params 1000000 1771 ns/op 713 B/op 14 allocs/op
+BenchmarkGoRestful_Parse2Params 159092 7583 ns/op 4928 B/op 14 allocs/op
+BenchmarkGorillaMux_Parse2Params 417548 2980 ns/op 1296 B/op 10 allocs/op
+BenchmarkGowwwRouter_Parse2Params 1751737 686 ns/op 432 B/op 3 allocs/op
+BenchmarkHttpRouter_Parse2Params 18089204 66.3 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_Parse2Params 1556986 777 ns/op 384 B/op 4 allocs/op
+BenchmarkKocha_Parse2Params 2493082 485 ns/op 128 B/op 5 allocs/op
+BenchmarkLARS_Parse2Params 15350108 78.5 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_Parse2Params 530974 2605 ns/op 1072 B/op 10 allocs/op
+BenchmarkMartini_Parse2Params 247069 4673 ns/op 1152 B/op 11 allocs/op
+BenchmarkPat_Parse2Params 816295 2126 ns/op 752 B/op 16 allocs/op
+BenchmarkPossum_Parse2Params 1000000 1002 ns/op 496 B/op 5 allocs/op
+BenchmarkR2router_Parse2Params 1569771 733 ns/op 432 B/op 5 allocs/op
+BenchmarkRivet_Parse2Params 4080546 295 ns/op 96 B/op 1 allocs/op
+BenchmarkTango_Parse2Params 1000000 1121 ns/op 312 B/op 8 allocs/op
+BenchmarkTigerTonic_Parse2Params 399556 3470 ns/op 1168 B/op 22 allocs/op
+BenchmarkTraffic_Parse2Params 314194 4159 ns/op 1944 B/op 22 allocs/op
+BenchmarkVulcan_Parse2Params 1827559 664 ns/op 98 B/op 3 allocs/op
+BenchmarkAce_ParseAll 478395 2503 ns/op 0 B/op 0 allocs/op
+BenchmarkAero_ParseAll 715392 1658 ns/op 0 B/op 0 allocs/op
+BenchmarkBear_ParseAll 59191 20124 ns/op 8928 B/op 110 allocs/op
+BenchmarkBeego_ParseAll 45507 27266 ns/op 9152 B/op 78 allocs/op
+BenchmarkBone_ParseAll 29328 41459 ns/op 16208 B/op 147 allocs/op
+BenchmarkChi_ParseAll 48531 25053 ns/op 11232 B/op 78 allocs/op
+BenchmarkDenco_ParseAll 325532 4284 ns/op 928 B/op 16 allocs/op
+BenchmarkEcho_ParseAll 433771 2759 ns/op 0 B/op 0 allocs/op
+BenchmarkGin_ParseAll 576316 2082 ns/op 0 B/op 0 allocs/op
+BenchmarkGocraftWeb_ParseAll 41500 29692 ns/op 13728 B/op 181 allocs/op
+BenchmarkGoji_ParseAll 80833 15563 ns/op 5376 B/op 32 allocs/op
+BenchmarkGojiv2_ParseAll 19836 60335 ns/op 34448 B/op 277 allocs/op
+BenchmarkGoJsonRest_ParseAll 32210 38027 ns/op 13866 B/op 321 allocs/op
+BenchmarkGoRestful_ParseAll 6644 190842 ns/op 117600 B/op 354 allocs/op
+BenchmarkGorillaMux_ParseAll 12634 95894 ns/op 30288 B/op 250 allocs/op
+BenchmarkGowwwRouter_ParseAll 98152 12159 ns/op 6912 B/op 48 allocs/op
+BenchmarkHttpRouter_ParseAll 933208 1273 ns/op 0 B/op 0 allocs/op
+BenchmarkHttpTreeMux_ParseAll 107191 11554 ns/op 5728 B/op 51 allocs/op
+BenchmarkKocha_ParseAll 184862 6225 ns/op 1112 B/op 54 allocs/op
+BenchmarkLARS_ParseAll 644546 1858 ns/op 0 B/op 0 allocs/op
+BenchmarkMacaron_ParseAll 26145 46484 ns/op 19136 B/op 208 allocs/op
+BenchmarkMartini_ParseAll 10000 121838 ns/op 25072 B/op 253 allocs/op
+BenchmarkPat_ParseAll 25417 47196 ns/op 15216 B/op 308 allocs/op
+BenchmarkPossum_ParseAll 58550 20735 ns/op 10816 B/op 78 allocs/op
+BenchmarkR2router_ParseAll 72732 16584 ns/op 8352 B/op 120 allocs/op
+BenchmarkRivet_ParseAll 281365 4968 ns/op 912 B/op 16 allocs/op
+BenchmarkTango_ParseAll 42831 28668 ns/op 7168 B/op 208 allocs/op
+BenchmarkTigerTonic_ParseAll 23774 49972 ns/op 16048 B/op 332 allocs/op
+BenchmarkTraffic_ParseAll 10000 104679 ns/op 45520 B/op 605 allocs/op
+BenchmarkVulcan_ParseAll 64810 18108 ns/op 2548 B/op 78 allocs/op
```
diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
index e6a108ca3..4c806a5a7 100644
--- a/vendor/github.com/gin-gonic/gin/CHANGELOG.md
+++ b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
@@ -1,6 +1,247 @@
-# CHANGELOG
+# Gin ChangeLog
-### Gin 1.3.0
+## Gin v1.7.7
+
+### BUGFIXES
+
+* Fixed X-Forwarded-For unsafe handling of CVE-2020-28483 [#2844](https://github.com/gin-gonic/gin/pull/2844), closed issue [#2862](https://github.com/gin-gonic/gin/issues/2862).
+* Tree: updated the code logic for `latestNode` [#2897](https://github.com/gin-gonic/gin/pull/2897), closed issue [#2894](https://github.com/gin-gonic/gin/issues/2894) [#2878](https://github.com/gin-gonic/gin/issues/2878).
+* Tree: fixed the misplacement of adding slashes [#2847](https://github.com/gin-gonic/gin/pull/2847), closed issue [#2843](https://github.com/gin-gonic/gin/issues/2843).
+* Tree: fixed tsr with mixed static and wildcard paths [#2924](https://github.com/gin-gonic/gin/pull/2924), closed issue [#2918](https://github.com/gin-gonic/gin/issues/2918).
+
+### ENHANCEMENTS
+
+* TrustedProxies: make it backward-compatible [#2887](https://github.com/gin-gonic/gin/pull/2887), closed issue [#2819](https://github.com/gin-gonic/gin/issues/2819).
+* TrustedPlatform: provide custom options for another CDN services [#2906](https://github.com/gin-gonic/gin/pull/2906).
+
+### DOCS
+
+* NoMethod: added usage annotation ([#2832](https://github.com/gin-gonic/gin/pull/2832#issuecomment-929954463)).
+
+## Gin v1.7.6
+
+### BUGFIXES
+
+* bump new release to fix v1.7.5 release error by using v1.7.4 codes.
+
+## Gin v1.7.4
+
+### BUGFIXES
+
+* bump new release to fix checksum mismatch
+
+## Gin v1.7.3
+
+### BUGFIXES
+
+* fix level 1 router match [#2767](https://github.com/gin-gonic/gin/issues/2767), [#2796](https://github.com/gin-gonic/gin/issues/2796)
+
+## Gin v1.7.2
+
+### BUGFIXES
+
+* Fix conflict between param and exact path [#2706](https://github.com/gin-gonic/gin/issues/2706). Close issue [#2682](https://github.com/gin-gonic/gin/issues/2682) [#2696](https://github.com/gin-gonic/gin/issues/2696).
+
+## Gin v1.7.1
+
+### BUGFIXES
+
+* fix: data race with trustedCIDRs from [#2674](https://github.com/gin-gonic/gin/issues/2674)([#2675](https://github.com/gin-gonic/gin/pull/2675))
+
+## Gin v1.7.0
+
+### BUGFIXES
+
+* fix compile error from [#2572](https://github.com/gin-gonic/gin/pull/2572) ([#2600](https://github.com/gin-gonic/gin/pull/2600))
+* fix: print headers without Authorization header on broken pipe ([#2528](https://github.com/gin-gonic/gin/pull/2528))
+* fix(tree): reassign fullpath when register new node ([#2366](https://github.com/gin-gonic/gin/pull/2366))
+
+### ENHANCEMENTS
+
+* Support params and exact routes without creating conflicts ([#2663](https://github.com/gin-gonic/gin/pull/2663))
+* chore: improve render string performance ([#2365](https://github.com/gin-gonic/gin/pull/2365))
+* Sync route tree to httprouter latest code ([#2368](https://github.com/gin-gonic/gin/pull/2368))
+* chore: rename getQueryCache/getFormCache to initQueryCache/initFormCa ([#2375](https://github.com/gin-gonic/gin/pull/2375))
+* chore(performance): improve countParams ([#2378](https://github.com/gin-gonic/gin/pull/2378))
+* Remove some functions that have the same effect as the bytes package ([#2387](https://github.com/gin-gonic/gin/pull/2387))
+* update:SetMode function ([#2321](https://github.com/gin-gonic/gin/pull/2321))
+* remove a unused type SecureJSONPrefix ([#2391](https://github.com/gin-gonic/gin/pull/2391))
+* Add a redirect sample for POST method ([#2389](https://github.com/gin-gonic/gin/pull/2389))
+* Add CustomRecovery builtin middleware ([#2322](https://github.com/gin-gonic/gin/pull/2322))
+* binding: avoid 2038 problem on 32-bit architectures ([#2450](https://github.com/gin-gonic/gin/pull/2450))
+* Prevent panic in Context.GetQuery() when there is no Request ([#2412](https://github.com/gin-gonic/gin/pull/2412))
+* Add GetUint and GetUint64 method on gin.context ([#2487](https://github.com/gin-gonic/gin/pull/2487))
+* update content-disposition header to MIME-style ([#2512](https://github.com/gin-gonic/gin/pull/2512))
+* reduce allocs and improve the render `WriteString` ([#2508](https://github.com/gin-gonic/gin/pull/2508))
+* implement ".Unwrap() error" on Error type ([#2525](https://github.com/gin-gonic/gin/pull/2525)) ([#2526](https://github.com/gin-gonic/gin/pull/2526))
+* Allow bind with a map[string]string ([#2484](https://github.com/gin-gonic/gin/pull/2484))
+* chore: update tree ([#2371](https://github.com/gin-gonic/gin/pull/2371))
+* Support binding for slice/array obj [Rewrite] ([#2302](https://github.com/gin-gonic/gin/pull/2302))
+* basic auth: fix timing oracle ([#2609](https://github.com/gin-gonic/gin/pull/2609))
+* Add mixed param and non-param paths (port of httprouter[#329](https://github.com/gin-gonic/gin/pull/329)) ([#2663](https://github.com/gin-gonic/gin/pull/2663))
+* feat(engine): add trustedproxies and remoteIP ([#2632](https://github.com/gin-gonic/gin/pull/2632))
+
+## Gin v1.6.3
+
+### ENHANCEMENTS
+
+ * Improve performance: Change `*sync.RWMutex` to `sync.RWMutex` in context. [#2351](https://github.com/gin-gonic/gin/pull/2351)
+
+## Gin v1.6.2
+
+### BUGFIXES
+ * fix missing initial sync.RWMutex [#2305](https://github.com/gin-gonic/gin/pull/2305)
+### ENHANCEMENTS
+ * Add set samesite in cookie. [#2306](https://github.com/gin-gonic/gin/pull/2306)
+
+## Gin v1.6.1
+
+### BUGFIXES
+ * Revert "fix accept incoming network connections" [#2294](https://github.com/gin-gonic/gin/pull/2294)
+
+## Gin v1.6.0
+
+### BREAKING
+ * chore(performance): Improve performance for adding RemoveExtraSlash flag [#2159](https://github.com/gin-gonic/gin/pull/2159)
+ * drop support govendor [#2148](https://github.com/gin-gonic/gin/pull/2148)
+ * Added support for SameSite cookie flag [#1615](https://github.com/gin-gonic/gin/pull/1615)
+### FEATURES
+ * add yaml negotiation [#2220](https://github.com/gin-gonic/gin/pull/2220)
+ * FileFromFS [#2112](https://github.com/gin-gonic/gin/pull/2112)
+### BUGFIXES
+ * Unix Socket Handling [#2280](https://github.com/gin-gonic/gin/pull/2280)
+ * Use json marshall in context json to fix breaking new line issue. Fixes #2209 [#2228](https://github.com/gin-gonic/gin/pull/2228)
+ * fix accept incoming network connections [#2216](https://github.com/gin-gonic/gin/pull/2216)
+ * Fixed a bug in the calculation of the maximum number of parameters [#2166](https://github.com/gin-gonic/gin/pull/2166)
+ * [FIX] allow empty headers on DataFromReader [#2121](https://github.com/gin-gonic/gin/pull/2121)
+ * Add mutex for protect Context.Keys map [#1391](https://github.com/gin-gonic/gin/pull/1391)
+### ENHANCEMENTS
+ * Add mitigation for log injection [#2277](https://github.com/gin-gonic/gin/pull/2277)
+ * tree: range over nodes values [#2229](https://github.com/gin-gonic/gin/pull/2229)
+ * tree: remove duplicate assignment [#2222](https://github.com/gin-gonic/gin/pull/2222)
+ * chore: upgrade go-isatty and json-iterator/go [#2215](https://github.com/gin-gonic/gin/pull/2215)
+ * path: sync code with httprouter [#2212](https://github.com/gin-gonic/gin/pull/2212)
+ * Use zero-copy approach to convert types between string and byte slice [#2206](https://github.com/gin-gonic/gin/pull/2206)
+ * Reuse bytes when cleaning the URL paths [#2179](https://github.com/gin-gonic/gin/pull/2179)
+ * tree: remove one else statement [#2177](https://github.com/gin-gonic/gin/pull/2177)
+ * tree: sync httprouter update (#2173) (#2172) [#2171](https://github.com/gin-gonic/gin/pull/2171)
+ * tree: sync part httprouter codes and reduce if/else [#2163](https://github.com/gin-gonic/gin/pull/2163)
+ * use http method constant [#2155](https://github.com/gin-gonic/gin/pull/2155)
+ * upgrade go-validator to v10 [#2149](https://github.com/gin-gonic/gin/pull/2149)
+ * Refactor redirect request in gin.go [#1970](https://github.com/gin-gonic/gin/pull/1970)
+ * Add build tag nomsgpack [#1852](https://github.com/gin-gonic/gin/pull/1852)
+### DOCS
+ * docs(path): improve comments [#2223](https://github.com/gin-gonic/gin/pull/2223)
+ * Renew README to fit the modification of SetCookie method [#2217](https://github.com/gin-gonic/gin/pull/2217)
+ * Fix spelling [#2202](https://github.com/gin-gonic/gin/pull/2202)
+ * Remove broken link from README. [#2198](https://github.com/gin-gonic/gin/pull/2198)
+ * Update docs on Context.Done(), Context.Deadline() and Context.Err() [#2196](https://github.com/gin-gonic/gin/pull/2196)
+ * Update validator to v10 [#2190](https://github.com/gin-gonic/gin/pull/2190)
+ * upgrade go-validator to v10 for README [#2189](https://github.com/gin-gonic/gin/pull/2189)
+ * Update to currently output [#2188](https://github.com/gin-gonic/gin/pull/2188)
+ * Fix "Custom Validators" example [#2186](https://github.com/gin-gonic/gin/pull/2186)
+ * Add project to README [#2165](https://github.com/gin-gonic/gin/pull/2165)
+ * docs(benchmarks): for gin v1.5 [#2153](https://github.com/gin-gonic/gin/pull/2153)
+ * Changed wording for clarity in README.md [#2122](https://github.com/gin-gonic/gin/pull/2122)
+### MISC
+ * ci support go1.14 [#2262](https://github.com/gin-gonic/gin/pull/2262)
+ * chore: upgrade depend version [#2231](https://github.com/gin-gonic/gin/pull/2231)
+ * Drop support go1.10 [#2147](https://github.com/gin-gonic/gin/pull/2147)
+ * fix comment in `mode.go` [#2129](https://github.com/gin-gonic/gin/pull/2129)
+
+## Gin v1.5.0
+
+- [FIX] Use DefaultWriter and DefaultErrorWriter for debug messages [#1891](https://github.com/gin-gonic/gin/pull/1891)
+- [NEW] Now you can parse the inline lowercase start structure [#1893](https://github.com/gin-gonic/gin/pull/1893)
+- [FIX] Some code improvements [#1909](https://github.com/gin-gonic/gin/pull/1909)
+- [FIX] Use encode replace json marshal increase json encoder speed [#1546](https://github.com/gin-gonic/gin/pull/1546)
+- [NEW] Hold matched route full path in the Context [#1826](https://github.com/gin-gonic/gin/pull/1826)
+- [FIX] Fix context.Params race condition on Copy() [#1841](https://github.com/gin-gonic/gin/pull/1841)
+- [NEW] Add context param query cache [#1450](https://github.com/gin-gonic/gin/pull/1450)
+- [FIX] Improve GetQueryMap performance [#1918](https://github.com/gin-gonic/gin/pull/1918)
+- [FIX] Improve get post data [#1920](https://github.com/gin-gonic/gin/pull/1920)
+- [FIX] Use context instead of x/net/context [#1922](https://github.com/gin-gonic/gin/pull/1922)
+- [FIX] Attempt to fix PostForm cache bug [#1931](https://github.com/gin-gonic/gin/pull/1931)
+- [NEW] Add support of multipart multi files [#1949](https://github.com/gin-gonic/gin/pull/1949)
+- [NEW] Support bind http header param [#1957](https://github.com/gin-gonic/gin/pull/1957)
+- [FIX] Drop support for go1.8 and go1.9 [#1933](https://github.com/gin-gonic/gin/pull/1933)
+- [FIX] Bugfix for the FullPath feature [#1919](https://github.com/gin-gonic/gin/pull/1919)
+- [FIX] Gin1.5 bytes.Buffer to strings.Builder [#1939](https://github.com/gin-gonic/gin/pull/1939)
+- [FIX] Upgrade github.com/ugorji/go/codec [#1969](https://github.com/gin-gonic/gin/pull/1969)
+- [NEW] Support bind unix time [#1980](https://github.com/gin-gonic/gin/pull/1980)
+- [FIX] Simplify code [#2004](https://github.com/gin-gonic/gin/pull/2004)
+- [NEW] Support negative Content-Length in DataFromReader [#1981](https://github.com/gin-gonic/gin/pull/1981)
+- [FIX] Identify terminal on a RISC-V architecture for auto-colored logs [#2019](https://github.com/gin-gonic/gin/pull/2019)
+- [BREAKING] `Context.JSONP()` now expects a semicolon (`;`) at the end [#2007](https://github.com/gin-gonic/gin/pull/2007)
+- [BREAKING] Upgrade default `binding.Validator` to v9 (see [its changelog](https://github.com/go-playground/validator/releases/tag/v9.0.0)) [#1015](https://github.com/gin-gonic/gin/pull/1015)
+- [NEW] Add `DisallowUnknownFields()` in `Context.BindJSON()` [#2028](https://github.com/gin-gonic/gin/pull/2028)
+- [NEW] Use specific `net.Listener` with `Engine.RunListener()` [#2023](https://github.com/gin-gonic/gin/pull/2023)
+- [FIX] Fix some typo [#2079](https://github.com/gin-gonic/gin/pull/2079) [#2080](https://github.com/gin-gonic/gin/pull/2080)
+- [FIX] Relocate binding body tests [#2086](https://github.com/gin-gonic/gin/pull/2086)
+- [FIX] Use Writer in Context.Status [#1606](https://github.com/gin-gonic/gin/pull/1606)
+- [FIX] `Engine.RunUnix()` now returns the error if it can't change the file mode [#2093](https://github.com/gin-gonic/gin/pull/2093)
+- [FIX] `RouterGroup.StaticFS()` leaked files. Now it closes them. [#2118](https://github.com/gin-gonic/gin/pull/2118)
+- [FIX] `Context.Request.FormFile` leaked file. Now it closes it. [#2114](https://github.com/gin-gonic/gin/pull/2114)
+- [FIX] Ignore walking on `form:"-"` mapping [#1943](https://github.com/gin-gonic/gin/pull/1943)
+
+### Gin v1.4.0
+
+- [NEW] Support for [Go Modules](https://github.com/golang/go/wiki/Modules) [#1569](https://github.com/gin-gonic/gin/pull/1569)
+- [NEW] Refactor of form mapping multipart request [#1829](https://github.com/gin-gonic/gin/pull/1829)
+- [FIX] Truncate Latency precision in long running request [#1830](https://github.com/gin-gonic/gin/pull/1830)
+- [FIX] IsTerm flag should not be affected by DisableConsoleColor method. [#1802](https://github.com/gin-gonic/gin/pull/1802)
+- [NEW] Supporting file binding [#1264](https://github.com/gin-gonic/gin/pull/1264)
+- [NEW] Add support for mapping arrays [#1797](https://github.com/gin-gonic/gin/pull/1797)
+- [FIX] Readme updates [#1793](https://github.com/gin-gonic/gin/pull/1793) [#1788](https://github.com/gin-gonic/gin/pull/1788) [1789](https://github.com/gin-gonic/gin/pull/1789)
+- [FIX] StaticFS: Fixed Logging two log lines on 404. [#1805](https://github.com/gin-gonic/gin/pull/1805), [#1804](https://github.com/gin-gonic/gin/pull/1804)
+- [NEW] Make context.Keys available as LogFormatterParams [#1779](https://github.com/gin-gonic/gin/pull/1779)
+- [NEW] Use internal/json for Marshal/Unmarshal [#1791](https://github.com/gin-gonic/gin/pull/1791)
+- [NEW] Support mapping time.Duration [#1794](https://github.com/gin-gonic/gin/pull/1794)
+- [NEW] Refactor form mappings [#1749](https://github.com/gin-gonic/gin/pull/1749)
+- [NEW] Added flag to context.Stream indicates if client disconnected in middle of stream [#1252](https://github.com/gin-gonic/gin/pull/1252)
+- [FIX] Moved [examples](https://github.com/gin-gonic/examples) to stand alone Repo [#1775](https://github.com/gin-gonic/gin/pull/1775)
+- [NEW] Extend context.File to allow for the content-disposition attachments via a new method context.Attachment [#1260](https://github.com/gin-gonic/gin/pull/1260)
+- [FIX] Support HTTP content negotiation wildcards [#1112](https://github.com/gin-gonic/gin/pull/1112)
+- [NEW] Add prefix from X-Forwarded-Prefix in redirectTrailingSlash [#1238](https://github.com/gin-gonic/gin/pull/1238)
+- [FIX] context.Copy() race condition [#1020](https://github.com/gin-gonic/gin/pull/1020)
+- [NEW] Add context.HandlerNames() [#1729](https://github.com/gin-gonic/gin/pull/1729)
+- [FIX] Change color methods to public in the defaultLogger. [#1771](https://github.com/gin-gonic/gin/pull/1771)
+- [FIX] Update writeHeaders method to use http.Header.Set [#1722](https://github.com/gin-gonic/gin/pull/1722)
+- [NEW] Add response size to LogFormatterParams [#1752](https://github.com/gin-gonic/gin/pull/1752)
+- [NEW] Allow ignoring field on form mapping [#1733](https://github.com/gin-gonic/gin/pull/1733)
+- [NEW] Add a function to force color in console output. [#1724](https://github.com/gin-gonic/gin/pull/1724)
+- [FIX] Context.Next() - recheck len of handlers on every iteration. [#1745](https://github.com/gin-gonic/gin/pull/1745)
+- [FIX] Fix all errcheck warnings [#1739](https://github.com/gin-gonic/gin/pull/1739) [#1653](https://github.com/gin-gonic/gin/pull/1653)
+- [NEW] context: inherits context cancellation and deadline from http.Request context for Go>=1.7 [#1690](https://github.com/gin-gonic/gin/pull/1690)
+- [NEW] Binding for URL Params [#1694](https://github.com/gin-gonic/gin/pull/1694)
+- [NEW] Add LoggerWithFormatter method [#1677](https://github.com/gin-gonic/gin/pull/1677)
+- [FIX] CI testing updates [#1671](https://github.com/gin-gonic/gin/pull/1671) [#1670](https://github.com/gin-gonic/gin/pull/1670) [#1682](https://github.com/gin-gonic/gin/pull/1682) [#1669](https://github.com/gin-gonic/gin/pull/1669)
+- [FIX] StaticFS(): Send 404 when path does not exist [#1663](https://github.com/gin-gonic/gin/pull/1663)
+- [FIX] Handle nil body for JSON binding [#1638](https://github.com/gin-gonic/gin/pull/1638)
+- [FIX] Support bind uri param [#1612](https://github.com/gin-gonic/gin/pull/1612)
+- [FIX] recovery: fix issue with syscall import on google app engine [#1640](https://github.com/gin-gonic/gin/pull/1640)
+- [FIX] Make sure the debug log contains line breaks [#1650](https://github.com/gin-gonic/gin/pull/1650)
+- [FIX] Panic stack trace being printed during recovery of broken pipe [#1089](https://github.com/gin-gonic/gin/pull/1089) [#1259](https://github.com/gin-gonic/gin/pull/1259)
+- [NEW] RunFd method to run http.Server through a file descriptor [#1609](https://github.com/gin-gonic/gin/pull/1609)
+- [NEW] Yaml binding support [#1618](https://github.com/gin-gonic/gin/pull/1618)
+- [FIX] Pass MaxMultipartMemory when FormFile is called [#1600](https://github.com/gin-gonic/gin/pull/1600)
+- [FIX] LoadHTML* tests [#1559](https://github.com/gin-gonic/gin/pull/1559)
+- [FIX] Removed use of sync.pool from HandleContext [#1565](https://github.com/gin-gonic/gin/pull/1565)
+- [FIX] Format output log to os.Stderr [#1571](https://github.com/gin-gonic/gin/pull/1571)
+- [FIX] Make logger use a yellow background and a darkgray text for legibility [#1570](https://github.com/gin-gonic/gin/pull/1570)
+- [FIX] Remove sensitive request information from panic log. [#1370](https://github.com/gin-gonic/gin/pull/1370)
+- [FIX] log.Println() does not print timestamp [#829](https://github.com/gin-gonic/gin/pull/829) [#1560](https://github.com/gin-gonic/gin/pull/1560)
+- [NEW] Add PureJSON renderer [#694](https://github.com/gin-gonic/gin/pull/694)
+- [FIX] Add missing copyright and update if/else [#1497](https://github.com/gin-gonic/gin/pull/1497)
+- [FIX] Update msgpack usage [#1498](https://github.com/gin-gonic/gin/pull/1498)
+- [FIX] Use protobuf on render [#1496](https://github.com/gin-gonic/gin/pull/1496)
+- [FIX] Add support for Protobuf format response [#1479](https://github.com/gin-gonic/gin/pull/1479)
+- [NEW] Set default time format in form binding [#1487](https://github.com/gin-gonic/gin/pull/1487)
+- [FIX] Add BindXML and ShouldBindXML [#1485](https://github.com/gin-gonic/gin/pull/1485)
+- [NEW] Upgrade dependency libraries [#1491](https://github.com/gin-gonic/gin/pull/1491)
+
+
+## Gin v1.3.0
- [NEW] Add [`func (*Context) QueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.QueryMap), [`func (*Context) GetQueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetQueryMap), [`func (*Context) PostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.PostFormMap) and [`func (*Context) GetPostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetPostFormMap) to support `type map[string]string` as query string or form parameters, see [#1383](https://github.com/gin-gonic/gin/pull/1383)
- [NEW] Add [`func (*Context) AsciiJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.AsciiJSON), see [#1358](https://github.com/gin-gonic/gin/pull/1358)
@@ -22,7 +263,7 @@
- [FIX] Gin Mode `""` when calling [`func Mode`](https://godoc.org/github.com/gin-gonic/gin#Mode) now returns `const DebugMode`, see [#1250](https://github.com/gin-gonic/gin/pull/1250)
- [FIX] `Flush()` now doesn't overwrite `responseWriter` status code, see [#1460](https://github.com/gin-gonic/gin/pull/1460)
-### Gin 1.2.0
+## Gin 1.2.0
- [NEW] Switch from godeps to govendor
- [NEW] Add support for Let's Encrypt via gin-gonic/autotls
@@ -45,25 +286,25 @@
- [FIX] Use X-Forwarded-For before X-Real-Ip
- [FIX] time.Time binding (#904)
-### Gin 1.1.4
+## Gin 1.1.4
- [NEW] Support google appengine for IsTerminal func
-### Gin 1.1.3
+## Gin 1.1.3
- [FIX] Reverted Logger: skip ANSI color commands
-### Gin 1.1
+## Gin 1.1
-- [NEW] Implement QueryArray and PostArray methods
-- [NEW] Refactor GetQuery and GetPostForm
-- [NEW] Add contribution guide
+- [NEW] Implement QueryArray and PostArray methods
+- [NEW] Refactor GetQuery and GetPostForm
+- [NEW] Add contribution guide
- [FIX] Corrected typos in README
-- [FIX] Removed additional Iota
-- [FIX] Changed imports to gopkg instead of github in README (#733)
+- [FIX] Removed additional Iota
+- [FIX] Changed imports to gopkg instead of github in README (#733)
- [FIX] Logger: skip ANSI color commands if output is not a tty
-### Gin 1.0rc2 (...)
+## Gin 1.0rc2 (...)
- [PERFORMANCE] Fast path for writing Content-Type.
- [PERFORMANCE] Much faster 404 routing
@@ -98,7 +339,7 @@
- [FIX] MIT license in every file
-### Gin 1.0rc1 (May 22, 2015)
+## Gin 1.0rc1 (May 22, 2015)
- [PERFORMANCE] Zero allocation router
- [PERFORMANCE] Faster JSON, XML and text rendering
@@ -106,7 +347,7 @@
- [PERFORMANCE] Misc code optimizations. Inlining, tail call optimizations
- [NEW] Built-in support for golang.org/x/net/context
- [NEW] Any(path, handler). Create a route that matches any path
-- [NEW] Refactored rendering pipeline (faster and static typeded)
+- [NEW] Refactored rendering pipeline (faster and static typed)
- [NEW] Refactored errors API
- [NEW] IndentedJSON() prints pretty JSON
- [NEW] Added gin.DefaultWriter
@@ -142,7 +383,7 @@
- [FIX] Better support for Google App Engine (using log instead of fmt)
-### Gin 0.6 (Mar 9, 2015)
+## Gin 0.6 (Mar 9, 2015)
- [NEW] Support multipart/form-data
- [NEW] NoMethod handler
@@ -152,14 +393,14 @@
- [FIX] Improve color logger
-### Gin 0.5 (Feb 7, 2015)
+## Gin 0.5 (Feb 7, 2015)
- [NEW] Content Negotiation
- [FIX] Solved security bug that allow a client to spoof ip
- [FIX] Fix unexported/ignored fields in binding
-### Gin 0.4 (Aug 21, 2014)
+## Gin 0.4 (Aug 21, 2014)
- [NEW] Development mode
- [NEW] Unit tests
@@ -168,14 +409,14 @@
- [FIX] Improved documentation for model binding
-### Gin 0.3 (Jul 18, 2014)
+## Gin 0.3 (Jul 18, 2014)
- [PERFORMANCE] Normal log and error log are printed in the same call.
- [PERFORMANCE] Improve performance of NoRouter()
- [PERFORMANCE] Improve context's memory locality, reduce CPU cache faults.
- [NEW] Flexible rendering API
- [NEW] Add Context.File()
-- [NEW] Add shorcut RunTLS() for http.ListenAndServeTLS
+- [NEW] Add shortcut RunTLS() for http.ListenAndServeTLS
- [FIX] Rename NotFound404() to NoRoute()
- [FIX] Errors in context are purged
- [FIX] Adds HEAD method in Static file serving
@@ -186,7 +427,7 @@
- [FIX] Check application/x-www-form-urlencoded when parsing form
-### Gin 0.2b (Jul 08, 2014)
+## Gin 0.2b (Jul 08, 2014)
- [PERFORMANCE] Using sync.Pool to allocatio/gc overhead
- [NEW] Travis CI integration
- [NEW] Completely new logger
@@ -198,14 +439,14 @@
- [NEW] New Bind() and BindWith() methods for parsing request body.
- [NEW] Add Content.Copy()
- [NEW] Add context.LastError()
-- [NEW] Add shorcut for OPTIONS HTTP method
+- [NEW] Add shortcut for OPTIONS HTTP method
- [FIX] Tons of README fixes
- [FIX] Header is written before body
- [FIX] BasicAuth() and changes API a little bit
- [FIX] Recovery() middleware only prints panics
- [FIX] Context.Get() does not panic anymore. Use MustGet() instead.
- [FIX] Multiple http.WriteHeader() in NotFound handlers
-- [FIX] Engine.Run() panics if http server can't be setted up
+- [FIX] Engine.Run() panics if http server can't be set up
- [FIX] Crash when route path doesn't start with '/'
- [FIX] Do not update header when status code is negative
- [FIX] Setting response headers before calling WriteHeader in context.String()
diff --git a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
index 547b777a1..97daa808f 100644
--- a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
+++ b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
@@ -1,4 +1,4 @@
-## Contributing
+## Contributing
- With issues:
- Use the search tool before opening a new issue.
@@ -8,6 +8,6 @@
- With pull requests:
- Open your pull request against `master`
- Your pull request should have no more than two commits, if not you should squash them.
- - It should pass all tests in the available continuous integrations systems such as TravisCI.
+ - It should pass all tests in the available continuous integration systems such as TravisCI.
- You should add/modify tests to cover your proposed code changes.
- If your pull request contains a new feature, please document it on the README.
diff --git a/vendor/github.com/gin-gonic/gin/Makefile b/vendor/github.com/gin-gonic/gin/Makefile
index 51b9969fd..1a9919395 100644
--- a/vendor/github.com/gin-gonic/gin/Makefile
+++ b/vendor/github.com/gin-gonic/gin/Makefile
@@ -1,16 +1,32 @@
+GO ?= go
GOFMT ?= gofmt "-s"
-PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
-VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
-GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
-
-all: install
-
-install: deps
- govendor sync
+PACKAGES ?= $(shell $(GO) list ./...)
+VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
+GOFILES := $(shell find . -name "*.go")
+TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
+TESTTAGS ?= ""
.PHONY: test
test:
- sh coverage.sh
+ echo "mode: count" > coverage.out
+ for d in $(TESTFOLDER); do \
+ $(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
+ cat tmp.out; \
+ if grep -q "^--- FAIL" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ elif grep -q "build failed" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ elif grep -q "setup failed" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ fi; \
+ if [ -f profile.out ]; then \
+ cat profile.out | grep -v "mode:" >> coverage.out; \
+ rm profile.out; \
+ fi; \
+ done
.PHONY: fmt
fmt:
@@ -18,7 +34,6 @@ fmt:
.PHONY: fmt-check
fmt-check:
- # get all go files and run go fmt on them
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
@@ -27,36 +42,30 @@ fmt-check:
fi;
vet:
- go vet $(VETPACKAGES)
-
-deps:
- @hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/kardianos/govendor; \
- fi
- @hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/campoy/embedmd; \
- fi
-
-embedmd:
- embedmd -d *.md
+ $(GO) vet $(VETPACKAGES)
.PHONY: lint
lint:
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/golang/lint/golint; \
+ $(GO) get -u golang.org/x/lint/golint; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
.PHONY: misspell-check
misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/client9/misspell/cmd/misspell; \
+ $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -error $(GOFILES)
.PHONY: misspell
misspell:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/client9/misspell/cmd/misspell; \
+ $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -w $(GOFILES)
+
+.PHONY: tools
+tools:
+ go install golang.org/x/lint/golint; \
+ go install github.com/client9/misspell/cmd/misspell;
diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md
index 28598baf5..9bf459b09 100644
--- a/vendor/github.com/gin-gonic/gin/README.md
+++ b/vendor/github.com/gin-gonic/gin/README.md
@@ -5,46 +5,61 @@
[](https://travis-ci.org/gin-gonic/gin)
[](https://codecov.io/gh/gin-gonic/gin)
[](https://goreportcard.com/report/github.com/gin-gonic/gin)
-[](https://godoc.org/github.com/gin-gonic/gin)
+[](https://pkg.go.dev/github.com/gin-gonic/gin?tab=doc)
[](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://sourcegraph.com/github.com/gin-gonic/gin?badge)
[](https://www.codetriage.com/gin-gonic/gin)
+[](https://github.com/gin-gonic/gin/releases)
+[](https://www.tickgit.com/browse?repo=github.com/gin-gonic/gin)
-Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
+Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
-
## Contents
-- [Installation](#installation)
-- [Prerequisite](#prerequisite)
-- [Quick start](#quick-start)
-- [Benchmarks](#benchmarks)
-- [Gin v1.stable](#gin-v1-stable)
-- [Build with jsoniter](#build-with-jsoniter)
-- [API Examples](#api-examples)
- - [Using GET,POST,PUT,PATCH,DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options)
+- [Gin Web Framework](#gin-web-framework)
+ - [Contents](#contents)
+ - [Installation](#installation)
+ - [Quick start](#quick-start)
+ - [Benchmarks](#benchmarks)
+ - [Gin v1. stable](#gin-v1-stable)
+ - [Build with jsoniter](#build-with-jsoniter)
+ - [API Examples](#api-examples)
+ - [Using GET, POST, PUT, PATCH, DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options)
- [Parameters in path](#parameters-in-path)
- [Querystring parameters](#querystring-parameters)
- [Multipart/Urlencoded Form](#multiparturlencoded-form)
- [Another example: query + post form](#another-example-query--post-form)
- [Map as querystring or postform parameters](#map-as-querystring-or-postform-parameters)
- [Upload files](#upload-files)
+ - [Single file](#single-file)
+ - [Multiple files](#multiple-files)
- [Grouping routes](#grouping-routes)
- [Blank Gin without middleware by default](#blank-gin-without-middleware-by-default)
- [Using middleware](#using-middleware)
- [How to write log file](#how-to-write-log-file)
+ - [Custom Log Format](#custom-log-format)
+ - [Controlling Log output coloring](#controlling-log-output-coloring)
- [Model binding and validation](#model-binding-and-validation)
- [Custom Validators](#custom-validators)
- [Only Bind Query String](#only-bind-query-string)
- [Bind Query String or Post Data](#bind-query-string-or-post-data)
+ - [Bind Uri](#bind-uri)
+ - [Bind Header](#bind-header)
- [Bind HTML checkboxes](#bind-html-checkboxes)
- [Multipart/Urlencoded binding](#multiparturlencoded-binding)
- - [XML, JSON and YAML rendering](#xml-json-and-yaml-rendering)
- - [JSONP rendering](#jsonp)
+ - [XML, JSON, YAML and ProtoBuf rendering](#xml-json-yaml-and-protobuf-rendering)
+ - [SecureJSON](#securejson)
+ - [JSONP](#jsonp)
+ - [AsciiJSON](#asciijson)
+ - [PureJSON](#purejson)
- [Serving static files](#serving-static-files)
+ - [Serving data from file](#serving-data-from-file)
- [Serving data from reader](#serving-data-from-reader)
- [HTML rendering](#html-rendering)
+ - [Custom Template renderer](#custom-template-renderer)
+ - [Custom Delimiters](#custom-delimiters)
+ - [Custom Template Funcs](#custom-template-funcs)
- [Multitemplate](#multitemplate)
- [Redirects](#redirects)
- [Custom Middleware](#custom-middleware)
@@ -53,19 +68,24 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [Custom HTTP configuration](#custom-http-configuration)
- [Support Let's Encrypt](#support-lets-encrypt)
- [Run multiple service using Gin](#run-multiple-service-using-gin)
- - [Graceful restart or stop](#graceful-restart-or-stop)
+ - [Graceful shutdown or restart](#graceful-shutdown-or-restart)
+ - [Third-party packages](#third-party-packages)
+ - [Manually](#manually)
- [Build a single binary with templates](#build-a-single-binary-with-templates)
- [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
- [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
- [http2 server push](#http2-server-push)
-- [Testing](#testing)
-- [Users](#users--)
+ - [Define format for the log of routes](#define-format-for-the-log-of-routes)
+ - [Set and get a cookie](#set-and-get-a-cookie)
+ - [Don't trust all proxies](#don't-trust-all-proxies)
+ - [Testing](#testing)
+ - [Users](#users)
## Installation
To install Gin package, you need to install Go and set your Go workspace first.
-1. Download and install it:
+1. The first need [Go](https://golang.org/) installed (**version 1.13+ is required**), then you can use the below Go command to install Gin.
```sh
$ go get -u github.com/gin-gonic/gin
@@ -83,44 +103,8 @@ import "github.com/gin-gonic/gin"
import "net/http"
```
-### Use a vendor tool like [Govendor](https://github.com/kardianos/govendor)
-
-1. `go get` govendor
-
-```sh
-$ go get github.com/kardianos/govendor
-```
-2. Create your project folder and `cd` inside
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-3. Vendor init your project and add gin
-
-```sh
-$ govendor init
-$ govendor fetch github.com/gin-gonic/gin@v1.2
-```
-
-4. Copy a starting template inside your project
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go
-```
-
-5. Run your project
-
-```sh
-$ go run main.go
-```
-
-## Prerequisite
-
-Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
-
## Quick start
-
+
```sh
# assume the following codes in example.go file
$ cat example.go
@@ -138,12 +122,12 @@ func main() {
"message": "pong",
})
})
- r.Run() // listen and serve on 0.0.0.0:8080
+ r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
```
```
-# run example.go and visit 0.0.0.0:8080/ping on browser
+# run example.go and visit 0.0.0.0:8080/ping (for windows "localhost:8080/ping") on browser
$ go run example.go
```
@@ -153,35 +137,38 @@ Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httpr
[See all benchmarks](/BENCHMARKS.md)
-Benchmark name | (1) | (2) | (3) | (4)
---------------------------------------------|-----------:|------------:|-----------:|---------:
-**BenchmarkGin_GithubAll** | **30000** | **48375** | **0** | **0**
-BenchmarkAce_GithubAll | 10000 | 134059 | 13792 | 167
-BenchmarkBear_GithubAll | 5000 | 534445 | 86448 | 943
-BenchmarkBeego_GithubAll | 3000 | 592444 | 74705 | 812
-BenchmarkBone_GithubAll | 200 | 6957308 | 698784 | 8453
-BenchmarkDenco_GithubAll | 10000 | 158819 | 20224 | 167
-BenchmarkEcho_GithubAll | 10000 | 154700 | 6496 | 203
-BenchmarkGocraftWeb_GithubAll | 3000 | 570806 | 131656 | 1686
-BenchmarkGoji_GithubAll | 2000 | 818034 | 56112 | 334
-BenchmarkGojiv2_GithubAll | 2000 | 1213973 | 274768 | 3712
-BenchmarkGoJsonRest_GithubAll | 2000 | 785796 | 134371 | 2737
-BenchmarkGoRestful_GithubAll | 300 | 5238188 | 689672 | 4519
-BenchmarkGorillaMux_GithubAll | 100 | 10257726 | 211840 | 2272
-BenchmarkHttpRouter_GithubAll | 20000 | 105414 | 13792 | 167
-BenchmarkHttpTreeMux_GithubAll | 10000 | 319934 | 65856 | 671
-BenchmarkKocha_GithubAll | 10000 | 209442 | 23304 | 843
-BenchmarkLARS_GithubAll | 20000 | 62565 | 0 | 0
-BenchmarkMacaron_GithubAll | 2000 | 1161270 | 204194 | 2000
-BenchmarkMartini_GithubAll | 200 | 9991713 | 226549 | 2325
-BenchmarkPat_GithubAll | 200 | 5590793 | 1499568 | 27435
-BenchmarkPossum_GithubAll | 10000 | 319768 | 84448 | 609
-BenchmarkR2router_GithubAll | 10000 | 305134 | 77328 | 979
-BenchmarkRivet_GithubAll | 10000 | 132134 | 16272 | 167
-BenchmarkTango_GithubAll | 3000 | 552754 | 63826 | 1618
-BenchmarkTigerTonic_GithubAll | 1000 | 1439483 | 239104 | 5374
-BenchmarkTraffic_GithubAll | 100 | 11383067 | 2659329 | 21848
-BenchmarkVulcan_GithubAll | 5000 | 394253 | 19894 | 609
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
- (1): Total Repetitions achieved in constant time, higher means more confident result
- (2): Single Repetition Duration (ns/op), lower is better
@@ -192,13 +179,13 @@ BenchmarkVulcan_GithubAll | 5000 | 394253 | 19894
- [x] Zero allocation router.
- [x] Still the fastest http router and framework. From routing to writing.
-- [x] Complete suite of unit tests
-- [x] Battle tested
+- [x] Complete suite of unit tests.
+- [x] Battle tested.
- [x] API frozen, new releases will not break your code.
## Build with [jsoniter](https://github.com/json-iterator/go)
-Gin use `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
```sh
$ go build -tags=jsoniter .
@@ -206,13 +193,12 @@ $ go build -tags=jsoniter .
## API Examples
+You can find a number of ready-to-run examples at [Gin examples repository](https://github.com/gin-gonic/examples).
+
### Using GET, POST, PUT, PATCH, DELETE and OPTIONS
```go
func main() {
- // Disable Console Color
- // gin.DisableConsoleColor()
-
// Creates a gin router with default middleware:
// logger and recovery (crash-free) middleware
router := gin.Default()
@@ -253,6 +239,18 @@ func main() {
c.String(http.StatusOK, message)
})
+ // For each matched request Context will hold the route definition
+ router.POST("/user/:name/*action", func(c *gin.Context) {
+ c.FullPath() == "/user/:name/*action" // true
+ })
+
+ // This handler will add a new router for /user/groups.
+ // Exact routes are resolved before param routes, regardless of the order they were defined.
+ // Routes starting with /user/groups are never interpreted as /user/:name/... routes
+ router.GET("/user/groups", func(c *gin.Context) {
+ c.String(http.StatusOK, "The available groups are [...]", name)
+ })
+
router.Run(":8080")
}
```
@@ -350,27 +348,31 @@ func main() {
```
```
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+ids: map[b:hello a:1234]; names: map[second:tianou first:thinkerou]
```
### Upload files
#### Single file
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single).
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
```go
func main() {
router := gin.Default()
// Set a lower memory limit for multipart forms (default is 32 MiB)
- // router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// single file
file, _ := c.FormFile("file")
log.Println(file.Filename)
// Upload the file to specific dst.
- // c.SaveUploadedFile(file, dst)
+ c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
@@ -388,13 +390,13 @@ curl -X POST http://localhost:8080/upload \
#### Multiple files
-See the detail [example code](examples/upload-file/multiple).
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
```go
func main() {
router := gin.Default()
// Set a lower memory limit for multipart forms (default is 32 MiB)
- // router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// Multipart form
form, _ := c.MultipartForm()
@@ -404,7 +406,7 @@ func main() {
log.Println(file.Filename)
// Upload the file to specific dst.
- // c.SaveUploadedFile(file, dst)
+ c.SaveUploadedFile(file, dst)
}
c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
})
@@ -502,6 +504,39 @@ func main() {
}
```
+### Custom Recovery behavior
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
+ if err, ok := recovered.(string); ok {
+ c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
+ }
+ c.AbortWithStatus(http.StatusInternalServerError)
+ }))
+
+ r.GET("/panic", func(c *gin.Context) {
+ // panic with a string -- the custom middleware could save this to a database or report it to the user
+ panic("foo")
+ })
+
+ r.GET("/", func(c *gin.Context) {
+ c.String(http.StatusOK, "ohai")
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
### How to write log file
```go
func main() {
@@ -524,20 +559,99 @@ func main() {
}
```
+### Custom Log Format
+```go
+func main() {
+ router := gin.New()
+
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+**Sample Output**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
+
+### Controlling Log output coloring
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
### Model binding and validation
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz).
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
-Gin uses [**go-playground/validator.v8**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags).
+Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://godoc.org/github.com/go-playground/validator#hdr-Baked_In_Validators_and_Tags).
Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
Also, Gin provides two sets of methods for binding:
- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindQuery`
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindQuery`
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
@@ -547,8 +661,8 @@ You can also specify that specific fields are required. If a field is decorated
```go
// Binding from JSON
type Login struct {
- User string `form:"user" json:"user" binding:"required"`
- Password string `form:"password" json:"password" binding:"required"`
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
func main() {
@@ -557,30 +671,55 @@ func main() {
// Example for binding JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
- if err := c.ShouldBindJSON(&json); err == nil {
- if json.User == "manu" && json.Password == "123" {
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- }
- } else {
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //

+[](https://travis-ci.org/go-playground/locales)
+[](https://goreportcard.com/report/github.com/go-playground/locales)
+[](https://godoc.org/github.com/go-playground/locales)
+
+[](https://gitter.im/go-playground/locales?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within
+an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator).
+
+Features
+--------
+- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v31.0.1
+- [x] Contains Cardinal, Ordinal and Range Plural Rules
+- [x] Contains Month, Weekday and Timezone translations built in
+- [x] Contains Date & Time formatting functions
+- [x] Contains Number, Currency, Accounting and Percent formatting functions
+- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
+
+Full Tests
+--------------------
+I could sure use your help adding tests for every locale, it is a huge undertaking and I just don't have the free time to do it all at the moment;
+any help would be **greatly appreciated!!!!** please see [issue](https://github.com/go-playground/locales/issues/1) for details.
+
+Installation
+-----------
+
+Use go get
+
+```shell
+go get github.com/go-playground/locales
+```
+
+NOTES
+--------
+You'll notice most return types are []byte, this is because most of the time the results will be concatenated with a larger body
+of text and can avoid some allocations if already appending to a byte array, otherwise just cast as string.
+
+Usage
+-------
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/go-playground/locales/currency"
+ "github.com/go-playground/locales/en_CA"
+)
+
+func main() {
+
+ loc, _ := time.LoadLocation("America/Toronto")
+ datetime := time.Date(2016, 02, 03, 9, 0, 1, 0, loc)
+
+ l := en_CA.New()
+
+ // Dates
+ fmt.Println(l.FmtDateFull(datetime))
+ fmt.Println(l.FmtDateLong(datetime))
+ fmt.Println(l.FmtDateMedium(datetime))
+ fmt.Println(l.FmtDateShort(datetime))
+
+ // Times
+ fmt.Println(l.FmtTimeFull(datetime))
+ fmt.Println(l.FmtTimeLong(datetime))
+ fmt.Println(l.FmtTimeMedium(datetime))
+ fmt.Println(l.FmtTimeShort(datetime))
+
+ // Months Wide
+ fmt.Println(l.MonthWide(time.January))
+ fmt.Println(l.MonthWide(time.February))
+ fmt.Println(l.MonthWide(time.March))
+ // ...
+
+ // Months Abbreviated
+ fmt.Println(l.MonthAbbreviated(time.January))
+ fmt.Println(l.MonthAbbreviated(time.February))
+ fmt.Println(l.MonthAbbreviated(time.March))
+ // ...
+
+ // Months Narrow
+ fmt.Println(l.MonthNarrow(time.January))
+ fmt.Println(l.MonthNarrow(time.February))
+ fmt.Println(l.MonthNarrow(time.March))
+ // ...
+
+ // Weekdays Wide
+ fmt.Println(l.WeekdayWide(time.Sunday))
+ fmt.Println(l.WeekdayWide(time.Monday))
+ fmt.Println(l.WeekdayWide(time.Tuesday))
+ // ...
+
+ // Weekdays Abbreviated
+ fmt.Println(l.WeekdayAbbreviated(time.Sunday))
+ fmt.Println(l.WeekdayAbbreviated(time.Monday))
+ fmt.Println(l.WeekdayAbbreviated(time.Tuesday))
+ // ...
+
+ // Weekdays Short
+ fmt.Println(l.WeekdayShort(time.Sunday))
+ fmt.Println(l.WeekdayShort(time.Monday))
+ fmt.Println(l.WeekdayShort(time.Tuesday))
+ // ...
+
+ // Weekdays Narrow
+ fmt.Println(l.WeekdayNarrow(time.Sunday))
+ fmt.Println(l.WeekdayNarrow(time.Monday))
+ fmt.Println(l.WeekdayNarrow(time.Tuesday))
+ // ...
+
+ var f64 float64
+
+ f64 = -10356.4523
+
+ // Number
+ fmt.Println(l.FmtNumber(f64, 2))
+
+ // Currency
+ fmt.Println(l.FmtCurrency(f64, 2, currency.CAD))
+ fmt.Println(l.FmtCurrency(f64, 2, currency.USD))
+
+ // Accounting
+ fmt.Println(l.FmtAccounting(f64, 2, currency.CAD))
+ fmt.Println(l.FmtAccounting(f64, 2, currency.USD))
+
+ f64 = 78.12
+
+ // Percent
+ fmt.Println(l.FmtPercent(f64, 0))
+
+ // Plural Rules for locale, so you know what rules you must cover
+ fmt.Println(l.PluralsCardinal())
+ fmt.Println(l.PluralsOrdinal())
+
+ // Cardinal Plural Rules
+ fmt.Println(l.CardinalPluralRule(1, 0))
+ fmt.Println(l.CardinalPluralRule(1.0, 0))
+ fmt.Println(l.CardinalPluralRule(1.0, 1))
+ fmt.Println(l.CardinalPluralRule(3, 0))
+
+ // Ordinal Plural Rules
+ fmt.Println(l.OrdinalPluralRule(21, 0)) // 21st
+ fmt.Println(l.OrdinalPluralRule(22, 0)) // 22nd
+ fmt.Println(l.OrdinalPluralRule(33, 0)) // 33rd
+ fmt.Println(l.OrdinalPluralRule(34, 0)) // 34th
+
+ // Range Plural Rules
+ fmt.Println(l.RangePluralRule(1, 0, 1, 0)) // 1-1
+ fmt.Println(l.RangePluralRule(1, 0, 2, 0)) // 1-2
+ fmt.Println(l.RangePluralRule(5, 0, 8, 0)) // 5-8
+}
+```
+
+NOTES:
+-------
+These rules were generated from the [Unicode CLDR Project](http://cldr.unicode.org/), if you encounter any issues
+I strongly encourage contributing to the CLDR project to get the locale information corrected and the next time
+these locales are regenerated the fix will come with.
+
+I do however realize that time constraints are often important and so there are two options:
+
+1. Create your own locale, copy, paste and modify, and ensure it complies with the `Translator` interface.
+2. Add an exception in the locale generation code directly and once regenerated, fix will be in place.
+
+Please to not make fixes inside the locale files, they WILL get overwritten when the locales are regenerated.
+
+License
+------
+Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/locales/currency/currency.go b/vendor/github.com/go-playground/locales/currency/currency.go
new file mode 100644
index 000000000..cdaba596b
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/currency/currency.go
@@ -0,0 +1,308 @@
+package currency
+
+// Type is the currency type associated with the locales currency enum
+type Type int
+
+// locale currencies
+const (
+ ADP Type = iota
+ AED
+ AFA
+ AFN
+ ALK
+ ALL
+ AMD
+ ANG
+ AOA
+ AOK
+ AON
+ AOR
+ ARA
+ ARL
+ ARM
+ ARP
+ ARS
+ ATS
+ AUD
+ AWG
+ AZM
+ AZN
+ BAD
+ BAM
+ BAN
+ BBD
+ BDT
+ BEC
+ BEF
+ BEL
+ BGL
+ BGM
+ BGN
+ BGO
+ BHD
+ BIF
+ BMD
+ BND
+ BOB
+ BOL
+ BOP
+ BOV
+ BRB
+ BRC
+ BRE
+ BRL
+ BRN
+ BRR
+ BRZ
+ BSD
+ BTN
+ BUK
+ BWP
+ BYB
+ BYN
+ BYR
+ BZD
+ CAD
+ CDF
+ CHE
+ CHF
+ CHW
+ CLE
+ CLF
+ CLP
+ CNH
+ CNX
+ CNY
+ COP
+ COU
+ CRC
+ CSD
+ CSK
+ CUC
+ CUP
+ CVE
+ CYP
+ CZK
+ DDM
+ DEM
+ DJF
+ DKK
+ DOP
+ DZD
+ ECS
+ ECV
+ EEK
+ EGP
+ ERN
+ ESA
+ ESB
+ ESP
+ ETB
+ EUR
+ FIM
+ FJD
+ FKP
+ FRF
+ GBP
+ GEK
+ GEL
+ GHC
+ GHS
+ GIP
+ GMD
+ GNF
+ GNS
+ GQE
+ GRD
+ GTQ
+ GWE
+ GWP
+ GYD
+ HKD
+ HNL
+ HRD
+ HRK
+ HTG
+ HUF
+ IDR
+ IEP
+ ILP
+ ILR
+ ILS
+ INR
+ IQD
+ IRR
+ ISJ
+ ISK
+ ITL
+ JMD
+ JOD
+ JPY
+ KES
+ KGS
+ KHR
+ KMF
+ KPW
+ KRH
+ KRO
+ KRW
+ KWD
+ KYD
+ KZT
+ LAK
+ LBP
+ LKR
+ LRD
+ LSL
+ LTL
+ LTT
+ LUC
+ LUF
+ LUL
+ LVL
+ LVR
+ LYD
+ MAD
+ MAF
+ MCF
+ MDC
+ MDL
+ MGA
+ MGF
+ MKD
+ MKN
+ MLF
+ MMK
+ MNT
+ MOP
+ MRO
+ MTL
+ MTP
+ MUR
+ MVP
+ MVR
+ MWK
+ MXN
+ MXP
+ MXV
+ MYR
+ MZE
+ MZM
+ MZN
+ NAD
+ NGN
+ NIC
+ NIO
+ NLG
+ NOK
+ NPR
+ NZD
+ OMR
+ PAB
+ PEI
+ PEN
+ PES
+ PGK
+ PHP
+ PKR
+ PLN
+ PLZ
+ PTE
+ PYG
+ QAR
+ RHD
+ ROL
+ RON
+ RSD
+ RUB
+ RUR
+ RWF
+ SAR
+ SBD
+ SCR
+ SDD
+ SDG
+ SDP
+ SEK
+ SGD
+ SHP
+ SIT
+ SKK
+ SLL
+ SOS
+ SRD
+ SRG
+ SSP
+ STD
+ STN
+ SUR
+ SVC
+ SYP
+ SZL
+ THB
+ TJR
+ TJS
+ TMM
+ TMT
+ TND
+ TOP
+ TPE
+ TRL
+ TRY
+ TTD
+ TWD
+ TZS
+ UAH
+ UAK
+ UGS
+ UGX
+ USD
+ USN
+ USS
+ UYI
+ UYP
+ UYU
+ UZS
+ VEB
+ VEF
+ VND
+ VNN
+ VUV
+ WST
+ XAF
+ XAG
+ XAU
+ XBA
+ XBB
+ XBC
+ XBD
+ XCD
+ XDR
+ XEU
+ XFO
+ XFU
+ XOF
+ XPD
+ XPF
+ XPT
+ XRE
+ XSU
+ XTS
+ XUA
+ XXX
+ YDD
+ YER
+ YUD
+ YUM
+ YUN
+ YUR
+ ZAL
+ ZAR
+ ZMK
+ ZMW
+ ZRN
+ ZRZ
+ ZWD
+ ZWL
+ ZWR
+)
diff --git a/vendor/github.com/go-playground/locales/go.mod b/vendor/github.com/go-playground/locales/go.mod
new file mode 100644
index 000000000..34ab6f238
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/go.mod
@@ -0,0 +1,5 @@
+module github.com/go-playground/locales
+
+go 1.13
+
+require golang.org/x/text v0.3.2
diff --git a/vendor/github.com/go-playground/locales/go.sum b/vendor/github.com/go-playground/locales/go.sum
new file mode 100644
index 000000000..63c9200f5
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/go.sum
@@ -0,0 +1,3 @@
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/vendor/github.com/go-playground/locales/logo.png b/vendor/github.com/go-playground/locales/logo.png
new file mode 100644
index 000000000..3038276e6
Binary files /dev/null and b/vendor/github.com/go-playground/locales/logo.png differ
diff --git a/vendor/github.com/go-playground/locales/rules.go b/vendor/github.com/go-playground/locales/rules.go
new file mode 100644
index 000000000..920290014
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/rules.go
@@ -0,0 +1,293 @@
+package locales
+
+import (
+ "strconv"
+ "time"
+
+ "github.com/go-playground/locales/currency"
+)
+
+// // ErrBadNumberValue is returned when the number passed for
+// // plural rule determination cannot be parsed
+// type ErrBadNumberValue struct {
+// NumberValue string
+// InnerError error
+// }
+
+// // Error returns ErrBadNumberValue error string
+// func (e *ErrBadNumberValue) Error() string {
+// return fmt.Sprintf("Invalid Number Value '%s' %s", e.NumberValue, e.InnerError)
+// }
+
+// var _ error = new(ErrBadNumberValue)
+
+// PluralRule denotes the type of plural rules
+type PluralRule int
+
+// PluralRule's
+const (
+ PluralRuleUnknown PluralRule = iota
+ PluralRuleZero // zero
+ PluralRuleOne // one - singular
+ PluralRuleTwo // two - dual
+ PluralRuleFew // few - paucal
+ PluralRuleMany // many - also used for fractions if they have a separate class
+ PluralRuleOther // other - required—general plural form—also used if the language only has a single form
+)
+
+const (
+ pluralsString = "UnknownZeroOneTwoFewManyOther"
+)
+
+// Translator encapsulates an instance of a locale
+// NOTE: some values are returned as a []byte just in case the caller
+// wishes to add more and can help avoid allocations; otherwise just cast as string
+type Translator interface {
+
+ // The following Functions are for overriding, debugging or developing
+ // with a Translator Locale
+
+ // Locale returns the string value of the translator
+ Locale() string
+
+ // returns an array of cardinal plural rules associated
+ // with this translator
+ PluralsCardinal() []PluralRule
+
+ // returns an array of ordinal plural rules associated
+ // with this translator
+ PluralsOrdinal() []PluralRule
+
+ // returns an array of range plural rules associated
+ // with this translator
+ PluralsRange() []PluralRule
+
+ // returns the cardinal PluralRule given 'num' and digits/precision of 'v' for locale
+ CardinalPluralRule(num float64, v uint64) PluralRule
+
+ // returns the ordinal PluralRule given 'num' and digits/precision of 'v' for locale
+ OrdinalPluralRule(num float64, v uint64) PluralRule
+
+ // returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for locale
+ RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) PluralRule
+
+ // returns the locales abbreviated month given the 'month' provided
+ MonthAbbreviated(month time.Month) string
+
+ // returns the locales abbreviated months
+ MonthsAbbreviated() []string
+
+ // returns the locales narrow month given the 'month' provided
+ MonthNarrow(month time.Month) string
+
+ // returns the locales narrow months
+ MonthsNarrow() []string
+
+ // returns the locales wide month given the 'month' provided
+ MonthWide(month time.Month) string
+
+ // returns the locales wide months
+ MonthsWide() []string
+
+ // returns the locales abbreviated weekday given the 'weekday' provided
+ WeekdayAbbreviated(weekday time.Weekday) string
+
+ // returns the locales abbreviated weekdays
+ WeekdaysAbbreviated() []string
+
+ // returns the locales narrow weekday given the 'weekday' provided
+ WeekdayNarrow(weekday time.Weekday) string
+
+ // WeekdaysNarrowreturns the locales narrow weekdays
+ WeekdaysNarrow() []string
+
+ // returns the locales short weekday given the 'weekday' provided
+ WeekdayShort(weekday time.Weekday) string
+
+ // returns the locales short weekdays
+ WeekdaysShort() []string
+
+ // returns the locales wide weekday given the 'weekday' provided
+ WeekdayWide(weekday time.Weekday) string
+
+ // returns the locales wide weekdays
+ WeekdaysWide() []string
+
+ // The following Functions are common Formatting functionsfor the Translator's Locale
+
+ // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
+ FmtNumber(num float64, v uint64) string
+
+ // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
+ // NOTE: 'num' passed into FmtPercent is assumed to be in percent already
+ FmtPercent(num float64, v uint64) string
+
+ // returns the currency representation of 'num' with digits/precision of 'v' for locale
+ FmtCurrency(num float64, v uint64, currency currency.Type) string
+
+ // returns the currency representation of 'num' with digits/precision of 'v' for locale
+ // in accounting notation.
+ FmtAccounting(num float64, v uint64, currency currency.Type) string
+
+ // returns the short date representation of 't' for locale
+ FmtDateShort(t time.Time) string
+
+ // returns the medium date representation of 't' for locale
+ FmtDateMedium(t time.Time) string
+
+ // returns the long date representation of 't' for locale
+ FmtDateLong(t time.Time) string
+
+ // returns the full date representation of 't' for locale
+ FmtDateFull(t time.Time) string
+
+ // returns the short time representation of 't' for locale
+ FmtTimeShort(t time.Time) string
+
+ // returns the medium time representation of 't' for locale
+ FmtTimeMedium(t time.Time) string
+
+ // returns the long time representation of 't' for locale
+ FmtTimeLong(t time.Time) string
+
+ // returns the full time representation of 't' for locale
+ FmtTimeFull(t time.Time) string
+}
+
+// String returns the string value of PluralRule
+func (p PluralRule) String() string {
+
+ switch p {
+ case PluralRuleZero:
+ return pluralsString[7:11]
+ case PluralRuleOne:
+ return pluralsString[11:14]
+ case PluralRuleTwo:
+ return pluralsString[14:17]
+ case PluralRuleFew:
+ return pluralsString[17:20]
+ case PluralRuleMany:
+ return pluralsString[20:24]
+ case PluralRuleOther:
+ return pluralsString[24:]
+ default:
+ return pluralsString[:7]
+ }
+}
+
+//
+// Precision Notes:
+//
+// must specify a precision >= 0, and here is why https://play.golang.org/p/LyL90U0Vyh
+//
+// v := float64(3.141)
+// i := float64(int64(v))
+//
+// fmt.Println(v - i)
+//
+// or
+//
+// s := strconv.FormatFloat(v-i, 'f', -1, 64)
+// fmt.Println(s)
+//
+// these will not print what you'd expect: 0.14100000000000001
+// and so this library requires a precision to be specified, or
+// inaccurate plural rules could be applied.
+//
+//
+//
+// n - absolute value of the source number (integer and decimals).
+// i - integer digits of n.
+// v - number of visible fraction digits in n, with trailing zeros.
+// w - number of visible fraction digits in n, without trailing zeros.
+// f - visible fractional digits in n, with trailing zeros.
+// t - visible fractional digits in n, without trailing zeros.
+//
+//
+// Func(num float64, v uint64) // v = digits/precision and prevents -1 as a special case as this can lead to very unexpected behaviour, see precision note's above.
+//
+// n := math.Abs(num)
+// i := int64(n)
+// v := v
+//
+//
+// w := strconv.FormatFloat(num-float64(i), 'f', int(v), 64) // then parse backwards on string until no more zero's....
+// f := strconv.FormatFloat(n, 'f', int(v), 64) // then turn everything after decimal into an int64
+// t := strconv.FormatFloat(n, 'f', int(v), 64) // then parse backwards on string until no more zero's....
+//
+//
+//
+// General Inclusion Rules
+// - v will always be available inherently
+// - all require n
+// - w requires i
+//
+
+// W returns the number of visible fraction digits in N, without trailing zeros.
+func W(n float64, v uint64) (w int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then w will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ s = s[2:]
+ end := len(s) + 1
+
+ for i := end; i >= 0; i-- {
+ if s[i] != '0' {
+ end = i + 1
+ break
+ }
+ }
+
+ w = int64(len(s[:end]))
+ }
+
+ return
+}
+
+// F returns the visible fractional digits in N, with trailing zeros.
+func F(n float64, v uint64) (f int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then f will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ // ignoring error, because it can't fail as we generated
+ // the string internally from a real number
+ f, _ = strconv.ParseInt(s[2:], 10, 64)
+ }
+
+ return
+}
+
+// T returns the visible fractional digits in N, without trailing zeros.
+func T(n float64, v uint64) (t int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then t will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ s = s[2:]
+ end := len(s) + 1
+
+ for i := end; i >= 0; i-- {
+ if s[i] != '0' {
+ end = i + 1
+ break
+ }
+ }
+
+ // ignoring error, because it can't fail as we generated
+ // the string internally from a real number
+ t, _ = strconv.ParseInt(s[:end], 10, 64)
+ }
+
+ return
+}
diff --git a/vendor/github.com/go-playground/universal-translator/.gitignore b/vendor/github.com/go-playground/universal-translator/.gitignore
new file mode 100644
index 000000000..bc4e07f34
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/.gitignore
@@ -0,0 +1,25 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+*.coverprofile
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/.travis.yml b/vendor/github.com/go-playground/universal-translator/.travis.yml
new file mode 100644
index 000000000..39b8b923e
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/.travis.yml
@@ -0,0 +1,27 @@
+language: go
+go:
+ - 1.13.4
+ - tip
+matrix:
+ allow_failures:
+ - go: tip
+
+notifications:
+ email:
+ recipients: dean.karn@gmail.com
+ on_success: change
+ on_failure: always
+
+before_install:
+ - go install github.com/mattn/goveralls
+
+# Only clone the most recent commit.
+git:
+ depth: 1
+
+script:
+ - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
+
+after_success: |
+ [ $TRAVIS_GO_VERSION = 1.13.4 ] &&
+ goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/LICENSE b/vendor/github.com/go-playground/universal-translator/LICENSE
new file mode 100644
index 000000000..8d8aba15b
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Go Playground
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-playground/universal-translator/README.md b/vendor/github.com/go-playground/universal-translator/README.md
new file mode 100644
index 000000000..071f33ab2
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/README.md
@@ -0,0 +1,89 @@
+## universal-translator
+

+[](https://travis-ci.org/go-playground/universal-translator)
+[](https://coveralls.io/github/go-playground/universal-translator)
+[](https://goreportcard.com/report/github.com/go-playground/universal-translator)
+[](https://godoc.org/github.com/go-playground/universal-translator)
+
+[](https://gitter.im/go-playground/universal-translator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
+
+Why another i18n library?
+--------------------------
+Because none of the plural rules seem to be correct out there, including the previous implementation of this package,
+so I took it upon myself to create [locales](https://github.com/go-playground/locales) for everyone to use; this package
+is a thin wrapper around [locales](https://github.com/go-playground/locales) in order to store and translate text for
+use in your applications.
+
+Features
+--------
+- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v30.0.3
+- [x] Contains Cardinal, Ordinal and Range Plural Rules
+- [x] Contains Month, Weekday and Timezone translations built in
+- [x] Contains Date & Time formatting functions
+- [x] Contains Number, Currency, Accounting and Percent formatting functions
+- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
+- [x] Support loading translations from files
+- [x] Exporting translations to file(s), mainly for getting them professionally translated
+- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
+- [ ] Tests for all languages, I need help with this, please see [here](https://github.com/go-playground/locales/issues/1)
+
+Installation
+-----------
+
+Use go get
+
+```shell
+go get github.com/go-playground/universal-translator
+```
+
+Usage & Documentation
+-------
+
+Please see https://godoc.org/github.com/go-playground/universal-translator for usage docs
+
+##### Examples:
+
+- [Basic](https://github.com/go-playground/universal-translator/tree/master/_examples/basic)
+- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-no-files)
+- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-with-files)
+
+File formatting
+--------------
+All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained withing the same file(s);
+they are only separated for easy viewing.
+
+##### Examples:
+
+- [Formats](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
+
+##### Basic Makeup
+NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
+```json
+{
+ "locale": "en",
+ "key": "days-left",
+ "trans": "You have {0} day left.",
+ "type": "Cardinal",
+ "rule": "One",
+ "override": false
+}
+```
+|Field|Description|
+|---|---|
+|locale|The locale for which the translation is for.|
+|key|The translation key that will be used to store and lookup each translation; normally it is a string or integer.|
+|trans|The actual translation text.|
+|type|The type of translation Cardinal, Ordinal, Range or "" for a plain substitution(not required to be defined if plain used)|
+|rule|The plural rule for which the translation is for eg. One, Two, Few, Many or Other.(not required to be defined if plain used)|
+|override|If you wish to override an existing translation that has already been registered, set this to 'true'. 99% of the time there is no need to define it.|
+
+Help With Tests
+---------------
+To anyone interesting in helping or contributing, I sure could use some help creating tests for each language.
+Please see issue [here](https://github.com/go-playground/locales/issues/1) for details.
+
+License
+------
+Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/universal-translator/errors.go b/vendor/github.com/go-playground/universal-translator/errors.go
new file mode 100644
index 000000000..38b163b62
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/errors.go
@@ -0,0 +1,148 @@
+package ut
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/go-playground/locales"
+)
+
+var (
+ // ErrUnknowTranslation indicates the translation could not be found
+ ErrUnknowTranslation = errors.New("Unknown Translation")
+)
+
+var _ error = new(ErrConflictingTranslation)
+var _ error = new(ErrRangeTranslation)
+var _ error = new(ErrOrdinalTranslation)
+var _ error = new(ErrCardinalTranslation)
+var _ error = new(ErrMissingPluralTranslation)
+var _ error = new(ErrExistingTranslator)
+
+// ErrExistingTranslator is the error representing a conflicting translator
+type ErrExistingTranslator struct {
+ locale string
+}
+
+// Error returns ErrExistingTranslator's internal error text
+func (e *ErrExistingTranslator) Error() string {
+ return fmt.Sprintf("error: conflicting translator for locale '%s'", e.locale)
+}
+
+// ErrConflictingTranslation is the error representing a conflicting translation
+type ErrConflictingTranslation struct {
+ locale string
+ key interface{}
+ rule locales.PluralRule
+ text string
+}
+
+// Error returns ErrConflictingTranslation's internal error text
+func (e *ErrConflictingTranslation) Error() string {
+
+ if _, ok := e.key.(string); !ok {
+ return fmt.Sprintf("error: conflicting key '%#v' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
+ }
+
+ return fmt.Sprintf("error: conflicting key '%s' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
+}
+
+// ErrRangeTranslation is the error representing a range translation error
+type ErrRangeTranslation struct {
+ text string
+}
+
+// Error returns ErrRangeTranslation's internal error text
+func (e *ErrRangeTranslation) Error() string {
+ return e.text
+}
+
+// ErrOrdinalTranslation is the error representing an ordinal translation error
+type ErrOrdinalTranslation struct {
+ text string
+}
+
+// Error returns ErrOrdinalTranslation's internal error text
+func (e *ErrOrdinalTranslation) Error() string {
+ return e.text
+}
+
+// ErrCardinalTranslation is the error representing a cardinal translation error
+type ErrCardinalTranslation struct {
+ text string
+}
+
+// Error returns ErrCardinalTranslation's internal error text
+func (e *ErrCardinalTranslation) Error() string {
+ return e.text
+}
+
+// ErrMissingPluralTranslation is the error signifying a missing translation given
+// the locales plural rules.
+type ErrMissingPluralTranslation struct {
+ locale string
+ key interface{}
+ rule locales.PluralRule
+ translationType string
+}
+
+// Error returns ErrMissingPluralTranslation's internal error text
+func (e *ErrMissingPluralTranslation) Error() string {
+
+ if _, ok := e.key.(string); !ok {
+ return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%#v' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
+ }
+
+ return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%s' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
+}
+
+// ErrMissingBracket is the error representing a missing bracket in a translation
+// eg. This is a {0 <-- missing ending '}'
+type ErrMissingBracket struct {
+ locale string
+ key interface{}
+ text string
+}
+
+// Error returns ErrMissingBracket error message
+func (e *ErrMissingBracket) Error() string {
+ return fmt.Sprintf("error: missing bracket '{}', in translation. locale: '%s' key: '%v' text: '%s'", e.locale, e.key, e.text)
+}
+
+// ErrBadParamSyntax is the error representing a bad parameter definition in a translation
+// eg. This is a {must-be-int}
+type ErrBadParamSyntax struct {
+ locale string
+ param string
+ key interface{}
+ text string
+}
+
+// Error returns ErrBadParamSyntax error message
+func (e *ErrBadParamSyntax) Error() string {
+ return fmt.Sprintf("error: bad parameter syntax, missing parameter '%s' in translation. locale: '%s' key: '%v' text: '%s'", e.param, e.locale, e.key, e.text)
+}
+
+// import/export errors
+
+// ErrMissingLocale is the error representing an expected locale that could
+// not be found aka locale not registered with the UniversalTranslator Instance
+type ErrMissingLocale struct {
+ locale string
+}
+
+// Error returns ErrMissingLocale's internal error text
+func (e *ErrMissingLocale) Error() string {
+ return fmt.Sprintf("error: locale '%s' not registered.", e.locale)
+}
+
+// ErrBadPluralDefinition is the error representing an incorrect plural definition
+// usually found within translations defined within files during the import process.
+type ErrBadPluralDefinition struct {
+ tl translation
+}
+
+// Error returns ErrBadPluralDefinition's internal error text
+func (e *ErrBadPluralDefinition) Error() string {
+ return fmt.Sprintf("error: bad plural definition '%#v'", e.tl)
+}
diff --git a/vendor/github.com/go-playground/universal-translator/go.mod b/vendor/github.com/go-playground/universal-translator/go.mod
new file mode 100644
index 000000000..8079590fe
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/go.mod
@@ -0,0 +1,5 @@
+module github.com/go-playground/universal-translator
+
+go 1.13
+
+require github.com/go-playground/locales v0.13.0
diff --git a/vendor/github.com/go-playground/universal-translator/go.sum b/vendor/github.com/go-playground/universal-translator/go.sum
new file mode 100644
index 000000000..cbbf32416
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/go.sum
@@ -0,0 +1,4 @@
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/vendor/github.com/go-playground/universal-translator/import_export.go b/vendor/github.com/go-playground/universal-translator/import_export.go
new file mode 100644
index 000000000..7bd76f26b
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/import_export.go
@@ -0,0 +1,274 @@
+package ut
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ "io"
+
+ "github.com/go-playground/locales"
+)
+
+type translation struct {
+ Locale string `json:"locale"`
+ Key interface{} `json:"key"` // either string or integer
+ Translation string `json:"trans"`
+ PluralType string `json:"type,omitempty"`
+ PluralRule string `json:"rule,omitempty"`
+ OverrideExisting bool `json:"override,omitempty"`
+}
+
+const (
+ cardinalType = "Cardinal"
+ ordinalType = "Ordinal"
+ rangeType = "Range"
+)
+
+// ImportExportFormat is the format of the file import or export
+type ImportExportFormat uint8
+
+// supported Export Formats
+const (
+ FormatJSON ImportExportFormat = iota
+)
+
+// Export writes the translations out to a file on disk.
+//
+// NOTE: this currently only works with string or int translations keys.
+func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error {
+
+ _, err := os.Stat(dirname)
+ fmt.Println(dirname, err, os.IsNotExist(err))
+ if err != nil {
+
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ if err = os.MkdirAll(dirname, 0744); err != nil {
+ return err
+ }
+ }
+
+ // build up translations
+ var trans []translation
+ var b []byte
+ var ext string
+
+ for _, locale := range t.translators {
+
+ for k, v := range locale.(*translator).translations {
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k,
+ Translation: v.text,
+ })
+ }
+
+ for k, pluralTrans := range locale.(*translator).cardinalTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: cardinalType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ for k, pluralTrans := range locale.(*translator).ordinalTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: ordinalType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ for k, pluralTrans := range locale.(*translator).rangeTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: rangeType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ switch format {
+ case FormatJSON:
+ b, err = json.MarshalIndent(trans, "", " ")
+ ext = ".json"
+ }
+
+ if err != nil {
+ return err
+ }
+
+ err = ioutil.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
+ if err != nil {
+ return err
+ }
+
+ trans = trans[0:0]
+ }
+
+ return nil
+}
+
+// Import reads the translations out of a file or directory on disk.
+//
+// NOTE: this currently only works with string or int translations keys.
+func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilename string) error {
+
+ fi, err := os.Stat(dirnameOrFilename)
+ if err != nil {
+ return err
+ }
+
+ processFn := func(filename string) error {
+
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ return t.ImportByReader(format, f)
+ }
+
+ if !fi.IsDir() {
+ return processFn(dirnameOrFilename)
+ }
+
+ // recursively go through directory
+ walker := func(path string, info os.FileInfo, err error) error {
+
+ if info.IsDir() {
+ return nil
+ }
+
+ switch format {
+ case FormatJSON:
+ // skip non JSON files
+ if filepath.Ext(info.Name()) != ".json" {
+ return nil
+ }
+ }
+
+ return processFn(path)
+ }
+
+ return filepath.Walk(dirnameOrFilename, walker)
+}
+
+// ImportByReader imports the the translations found within the contents read from the supplied reader.
+//
+// NOTE: generally used when assets have been embedded into the binary and are already in memory.
+func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error {
+
+ b, err := ioutil.ReadAll(reader)
+ if err != nil {
+ return err
+ }
+
+ var trans []translation
+
+ switch format {
+ case FormatJSON:
+ err = json.Unmarshal(b, &trans)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ for _, tl := range trans {
+
+ locale, found := t.FindTranslator(tl.Locale)
+ if !found {
+ return &ErrMissingLocale{locale: tl.Locale}
+ }
+
+ pr := stringToPR(tl.PluralRule)
+
+ if pr == locales.PluralRuleUnknown {
+
+ err = locale.Add(tl.Key, tl.Translation, tl.OverrideExisting)
+ if err != nil {
+ return err
+ }
+
+ continue
+ }
+
+ switch tl.PluralType {
+ case cardinalType:
+ err = locale.AddCardinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ case ordinalType:
+ err = locale.AddOrdinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ case rangeType:
+ err = locale.AddRange(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ default:
+ return &ErrBadPluralDefinition{tl: tl}
+ }
+
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func stringToPR(s string) locales.PluralRule {
+
+ switch s {
+ case "One":
+ return locales.PluralRuleOne
+ case "Two":
+ return locales.PluralRuleTwo
+ case "Few":
+ return locales.PluralRuleFew
+ case "Many":
+ return locales.PluralRuleMany
+ case "Other":
+ return locales.PluralRuleOther
+ default:
+ return locales.PluralRuleUnknown
+ }
+
+}
diff --git a/vendor/github.com/go-playground/universal-translator/logo.png b/vendor/github.com/go-playground/universal-translator/logo.png
new file mode 100644
index 000000000..a37aa8c0c
Binary files /dev/null and b/vendor/github.com/go-playground/universal-translator/logo.png differ
diff --git a/vendor/github.com/go-playground/universal-translator/translator.go b/vendor/github.com/go-playground/universal-translator/translator.go
new file mode 100644
index 000000000..cfafce8a0
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/translator.go
@@ -0,0 +1,420 @@
+package ut
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/go-playground/locales"
+)
+
+const (
+ paramZero = "{0}"
+ paramOne = "{1}"
+ unknownTranslation = ""
+)
+
+// Translator is universal translators
+// translator instance which is a thin wrapper
+// around locales.Translator instance providing
+// some extra functionality
+type Translator interface {
+ locales.Translator
+
+ // adds a normal translation for a particular language/locale
+ // {#} is the only replacement type accepted and are ad infinitum
+ // eg. one: '{0} day left' other: '{0} days left'
+ Add(key interface{}, text string, override bool) error
+
+ // adds a cardinal plural translation for a particular language/locale
+ // {0} is the only replacement type accepted and only one variable is accepted as
+ // multiple cannot be used for a plural rule determination, unless it is a range;
+ // see AddRange below.
+ // eg. in locale 'en' one: '{0} day left' other: '{0} days left'
+ AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // adds an ordinal plural translation for a particular language/locale
+ // {0} is the only replacement type accepted and only one variable is accepted as
+ // multiple cannot be used for a plural rule determination, unless it is a range;
+ // see AddRange below.
+ // eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring'
+ // - 1st, 2nd, 3rd...
+ AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // adds a range plural translation for a particular language/locale
+ // {0} and {1} are the only replacement types accepted and only these are accepted.
+ // eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
+ AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // creates the translation for the locale given the 'key' and params passed in
+ T(key interface{}, params ...string) (string, error)
+
+ // creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments
+ // and param passed in
+ C(key interface{}, num float64, digits uint64, param string) (string, error)
+
+ // creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments
+ // and param passed in
+ O(key interface{}, num float64, digits uint64, param string) (string, error)
+
+ // creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and
+ // 'digit2' arguments and 'param1' and 'param2' passed in
+ R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error)
+
+ // VerifyTranslations checks to ensures that no plural rules have been
+ // missed within the translations.
+ VerifyTranslations() error
+}
+
+var _ Translator = new(translator)
+var _ locales.Translator = new(translator)
+
+type translator struct {
+ locales.Translator
+ translations map[interface{}]*transText
+ cardinalTanslations map[interface{}][]*transText // array index is mapped to locales.PluralRule index + the locales.PluralRuleUnknown
+ ordinalTanslations map[interface{}][]*transText
+ rangeTanslations map[interface{}][]*transText
+}
+
+type transText struct {
+ text string
+ indexes []int
+}
+
+func newTranslator(trans locales.Translator) Translator {
+ return &translator{
+ Translator: trans,
+ translations: make(map[interface{}]*transText), // translation text broken up by byte index
+ cardinalTanslations: make(map[interface{}][]*transText),
+ ordinalTanslations: make(map[interface{}][]*transText),
+ rangeTanslations: make(map[interface{}][]*transText),
+ }
+}
+
+// Add adds a normal translation for a particular language/locale
+// {#} is the only replacement type accepted and are ad infinitum
+// eg. one: '{0} day left' other: '{0} days left'
+func (t *translator) Add(key interface{}, text string, override bool) error {
+
+ if _, ok := t.translations[key]; ok && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, text: text}
+ }
+
+ lb := strings.Count(text, "{")
+ rb := strings.Count(text, "}")
+
+ if lb != rb {
+ return &ErrMissingBracket{locale: t.Locale(), key: key, text: text}
+ }
+
+ trans := &transText{
+ text: text,
+ }
+
+ var idx int
+
+ for i := 0; i < lb; i++ {
+ s := "{" + strconv.Itoa(i) + "}"
+ idx = strings.Index(text, s)
+ if idx == -1 {
+ return &ErrBadParamSyntax{locale: t.Locale(), param: s, key: key, text: text}
+ }
+
+ trans.indexes = append(trans.indexes, idx)
+ trans.indexes = append(trans.indexes, idx+len(s))
+ }
+
+ t.translations[key] = trans
+
+ return nil
+}
+
+// AddCardinal adds a cardinal plural translation for a particular language/locale
+// {0} is the only replacement type accepted and only one variable is accepted as
+// multiple cannot be used for a plural rule determination, unless it is a range;
+// see AddRange below.
+// eg. in locale 'en' one: '{0} day left' other: '{0} days left'
+func (t *translator) AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsCardinal() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrCardinalTranslation{text: fmt.Sprintf("error: cardinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.cardinalTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7, 7)
+ t.cardinalTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 2, 2),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrCardinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddCardinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ return nil
+}
+
+// AddOrdinal adds an ordinal plural translation for a particular language/locale
+// {0} is the only replacement type accepted and only one variable is accepted as
+// multiple cannot be used for a plural rule determination, unless it is a range;
+// see AddRange below.
+// eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring' - 1st, 2nd, 3rd...
+func (t *translator) AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsOrdinal() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrOrdinalTranslation{text: fmt.Sprintf("error: ordinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.ordinalTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7, 7)
+ t.ordinalTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 2, 2),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrOrdinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddOrdinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ return nil
+}
+
+// AddRange adds a range plural translation for a particular language/locale
+// {0} and {1} are the only replacement types accepted and only these are accepted.
+// eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
+func (t *translator) AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsRange() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: range plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.rangeTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7, 7)
+ t.rangeTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 4, 4),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, are you sure you're adding a Range Translation? locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ idx = strings.Index(text, paramOne)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, a Range Translation requires two parameters. locale: '%s' key: '%v' text: '%s'", paramOne, t.Locale(), key, text)}
+ }
+
+ trans.indexes[2] = idx
+ trans.indexes[3] = idx + len(paramOne)
+
+ return nil
+}
+
+// T creates the translation for the locale given the 'key' and params passed in
+func (t *translator) T(key interface{}, params ...string) (string, error) {
+
+ trans, ok := t.translations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ b := make([]byte, 0, 64)
+
+ var start, end, count int
+
+ for i := 0; i < len(trans.indexes); i++ {
+ end = trans.indexes[i]
+ b = append(b, trans.text[start:end]...)
+ b = append(b, params[count]...)
+ i++
+ start = trans.indexes[i]
+ count++
+ }
+
+ b = append(b, trans.text[start:]...)
+
+ return string(b), nil
+}
+
+// C creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
+func (t *translator) C(key interface{}, num float64, digits uint64, param string) (string, error) {
+
+ tarr, ok := t.cardinalTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.CardinalPluralRule(num, digits)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param...)
+ b = append(b, trans.text[trans.indexes[1]:]...)
+
+ return string(b), nil
+}
+
+// O creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
+func (t *translator) O(key interface{}, num float64, digits uint64, param string) (string, error) {
+
+ tarr, ok := t.ordinalTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.OrdinalPluralRule(num, digits)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param...)
+ b = append(b, trans.text[trans.indexes[1]:]...)
+
+ return string(b), nil
+}
+
+// R creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and 'digit2' arguments
+// and 'param1' and 'param2' passed in
+func (t *translator) R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error) {
+
+ tarr, ok := t.rangeTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.RangePluralRule(num1, digits1, num2, digits2)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param1...)
+ b = append(b, trans.text[trans.indexes[1]:trans.indexes[2]]...)
+ b = append(b, param2...)
+ b = append(b, trans.text[trans.indexes[3]:]...)
+
+ return string(b), nil
+}
+
+// VerifyTranslations checks to ensures that no plural rules have been
+// missed within the translations.
+func (t *translator) VerifyTranslations() error {
+
+ for k, v := range t.cardinalTanslations {
+
+ for _, rule := range t.PluralsCardinal() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "plural", rule: rule, key: k}
+ }
+ }
+ }
+
+ for k, v := range t.ordinalTanslations {
+
+ for _, rule := range t.PluralsOrdinal() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "ordinal", rule: rule, key: k}
+ }
+ }
+ }
+
+ for k, v := range t.rangeTanslations {
+
+ for _, rule := range t.PluralsRange() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "range", rule: rule, key: k}
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-playground/universal-translator/universal_translator.go b/vendor/github.com/go-playground/universal-translator/universal_translator.go
new file mode 100644
index 000000000..dbf707f5c
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/universal_translator.go
@@ -0,0 +1,113 @@
+package ut
+
+import (
+ "strings"
+
+ "github.com/go-playground/locales"
+)
+
+// UniversalTranslator holds all locale & translation data
+type UniversalTranslator struct {
+ translators map[string]Translator
+ fallback Translator
+}
+
+// New returns a new UniversalTranslator instance set with
+// the fallback locale and locales it should support
+func New(fallback locales.Translator, supportedLocales ...locales.Translator) *UniversalTranslator {
+
+ t := &UniversalTranslator{
+ translators: make(map[string]Translator),
+ }
+
+ for _, v := range supportedLocales {
+
+ trans := newTranslator(v)
+ t.translators[strings.ToLower(trans.Locale())] = trans
+
+ if fallback.Locale() == v.Locale() {
+ t.fallback = trans
+ }
+ }
+
+ if t.fallback == nil && fallback != nil {
+ t.fallback = newTranslator(fallback)
+ }
+
+ return t
+}
+
+// FindTranslator trys to find a Translator based on an array of locales
+// and returns the first one it can find, otherwise returns the
+// fallback translator.
+func (t *UniversalTranslator) FindTranslator(locales ...string) (trans Translator, found bool) {
+
+ for _, locale := range locales {
+
+ if trans, found = t.translators[strings.ToLower(locale)]; found {
+ return
+ }
+ }
+
+ return t.fallback, false
+}
+
+// GetTranslator returns the specified translator for the given locale,
+// or fallback if not found
+func (t *UniversalTranslator) GetTranslator(locale string) (trans Translator, found bool) {
+
+ if trans, found = t.translators[strings.ToLower(locale)]; found {
+ return
+ }
+
+ return t.fallback, false
+}
+
+// GetFallback returns the fallback locale
+func (t *UniversalTranslator) GetFallback() Translator {
+ return t.fallback
+}
+
+// AddTranslator adds the supplied translator, if it already exists the override param
+// will be checked and if false an error will be returned, otherwise the translator will be
+// overridden; if the fallback matches the supplied translator it will be overridden as well
+// NOTE: this is normally only used when translator is embedded within a library
+func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error {
+
+ lc := strings.ToLower(translator.Locale())
+ _, ok := t.translators[lc]
+ if ok && !override {
+ return &ErrExistingTranslator{locale: translator.Locale()}
+ }
+
+ trans := newTranslator(translator)
+
+ if t.fallback.Locale() == translator.Locale() {
+
+ // because it's optional to have a fallback, I don't impose that limitation
+ // don't know why you wouldn't but...
+ if !override {
+ return &ErrExistingTranslator{locale: translator.Locale()}
+ }
+
+ t.fallback = trans
+ }
+
+ t.translators[lc] = trans
+
+ return nil
+}
+
+// VerifyTranslations runs through all locales and identifies any issues
+// eg. missing plural rules for a locale
+func (t *UniversalTranslator) VerifyTranslations() (err error) {
+
+ for _, trans := range t.translators {
+ err = trans.VerifyTranslations()
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
diff --git a/vendor/gopkg.in/go-playground/validator.v8/.gitignore b/vendor/github.com/go-playground/validator/v10/.gitignore
similarity index 94%
rename from vendor/gopkg.in/go-playground/validator.v8/.gitignore
rename to vendor/github.com/go-playground/validator/v10/.gitignore
index 792ca00d2..6e43fac0d 100644
--- a/vendor/gopkg.in/go-playground/validator.v8/.gitignore
+++ b/vendor/github.com/go-playground/validator/v10/.gitignore
@@ -6,6 +6,7 @@
# Folders
_obj
_test
+bin
# Architecture specific extensions/prefixes
*.[568vq]
@@ -26,4 +27,4 @@ _testmain.go
*.out
*.txt
cover.html
-README.html
\ No newline at end of file
+README.html
diff --git a/vendor/github.com/go-playground/validator/v10/.travis.yml b/vendor/github.com/go-playground/validator/v10/.travis.yml
new file mode 100644
index 000000000..85a7be34b
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/.travis.yml
@@ -0,0 +1,29 @@
+language: go
+go:
+ - 1.15.2
+ - tip
+matrix:
+ allow_failures:
+ - go: tip
+
+notifications:
+ email:
+ recipients: dean.karn@gmail.com
+ on_success: change
+ on_failure: always
+
+before_install:
+ - go install github.com/mattn/goveralls
+ - mkdir -p $GOPATH/src/gopkg.in
+ - ln -s $GOPATH/src/github.com/$TRAVIS_REPO_SLUG $GOPATH/src/gopkg.in/validator.v9
+
+# Only clone the most recent commit.
+git:
+ depth: 1
+
+script:
+ - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
+
+after_success: |
+ [ $TRAVIS_GO_VERSION = 1.15.2 ] &&
+ goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN
diff --git a/vendor/gopkg.in/go-playground/validator.v8/LICENSE b/vendor/github.com/go-playground/validator/v10/LICENSE
similarity index 100%
rename from vendor/gopkg.in/go-playground/validator.v8/LICENSE
rename to vendor/github.com/go-playground/validator/v10/LICENSE
diff --git a/vendor/github.com/go-playground/validator/v10/Makefile b/vendor/github.com/go-playground/validator/v10/Makefile
new file mode 100644
index 000000000..19c91ed73
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/Makefile
@@ -0,0 +1,18 @@
+GOCMD=GO111MODULE=on go
+
+linters-install:
+ @golangci-lint --version >/dev/null 2>&1 || { \
+ echo "installing linting tools..."; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.21.0; \
+ }
+
+lint: linters-install
+ $(PWD)/bin/golangci-lint run
+
+test:
+ $(GOCMD) test -cover -race ./...
+
+bench:
+ $(GOCMD) test -bench=. -benchmem ./...
+
+.PHONY: test lint linters-install
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md
new file mode 100644
index 000000000..04fbb3c86
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/README.md
@@ -0,0 +1,299 @@
+Package validator
+================
+
[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+[](https://travis-ci.org/go-playground/validator)
+[](https://coveralls.io/github/go-playground/validator?branch=master)
+[](https://goreportcard.com/report/github.com/go-playground/validator)
+[](https://pkg.go.dev/github.com/go-playground/validator/v10)
+
+
+Package validator implements value validations for structs and individual fields based on tags.
+
+It has the following **unique** features:
+
+- Cross Field and Cross Struct validations by using validation tags or custom validators.
+- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
+- Ability to dive into both map keys and values for validation
+- Handles type interface by determining it's underlying type prior to validation.
+- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
+- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
+- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
+- Customizable i18n aware error messages.
+- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding)
+
+Installation
+------------
+
+Use go get.
+
+ go get github.com/go-playground/validator/v10
+
+Then import the validator package into your own code.
+
+ import "github.com/go-playground/validator/v10"
+
+Error Return Value
+-------
+
+Validation functions return type error
+
+They return type error to avoid the issue discussed in the following, where err is always != nil:
+
+* http://stackoverflow.com/a/29138676/3158232
+* https://github.com/go-playground/validator/issues/134
+
+Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
+
+```go
+err := validate.Struct(mystruct)
+validationErrors := err.(validator.ValidationErrors)
+ ```
+
+Usage and documentation
+------
+
+Please see https://godoc.org/github.com/go-playground/validator for detailed usage docs.
+
+##### Examples:
+
+- [Simple](https://github.com/go-playground/validator/blob/master/_examples/simple/main.go)
+- [Custom Field Types](https://github.com/go-playground/validator/blob/master/_examples/custom/main.go)
+- [Struct Level](https://github.com/go-playground/validator/blob/master/_examples/struct-level/main.go)
+- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/master/_examples/translations/main.go)
+- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
+- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
+
+Baked-in Validations
+------
+
+### Fields:
+
+| Tag | Description |
+| - | - |
+| eqcsfield | Field Equals Another Field (relative)|
+| eqfield | Field Equals Another Field |
+| fieldcontains | NOT DOCUMENTED IN doc.go |
+| fieldexcludes | NOT DOCUMENTED IN doc.go |
+| gtcsfield | Field Greater Than Another Relative Field |
+| gtecsfield | Field Greater Than or Equal To Another Relative Field |
+| gtefield | Field Greater Than or Equal To Another Field |
+| gtfield | Field Greater Than Another Field |
+| ltcsfield | Less Than Another Relative Field |
+| ltecsfield | Less Than or Equal To Another Relative Field |
+| ltefield | Less Than or Equal To Another Field |
+| ltfield | Less Than Another Field |
+| necsfield | Field Does Not Equal Another Field (relative) |
+| nefield | Field Does Not Equal Another Field |
+
+### Network:
+
+| Tag | Description |
+| - | - |
+| cidr | Classless Inter-Domain Routing CIDR |
+| cidrv4 | Classless Inter-Domain Routing CIDRv4 |
+| cidrv6 | Classless Inter-Domain Routing CIDRv6 |
+| datauri | Data URL |
+| fqdn | Full Qualified Domain Name (FQDN) |
+| hostname | Hostname RFC 952 |
+| hostname_port | HostPort |
+| hostname_rfc1123 | Hostname RFC 1123 |
+| ip | Internet Protocol Address IP |
+| ip4_addr | Internet Protocol Address IPv4 |
+| ip6_addr |Internet Protocol Address IPv6 |
+| ip_addr | Internet Protocol Address IP |
+| ipv4 | Internet Protocol Address IPv4 |
+| ipv6 | Internet Protocol Address IPv6 |
+| mac | Media Access Control Address MAC |
+| tcp4_addr | Transmission Control Protocol Address TCPv4 |
+| tcp6_addr | Transmission Control Protocol Address TCPv6 |
+| tcp_addr | Transmission Control Protocol Address TCP |
+| udp4_addr | User Datagram Protocol Address UDPv4 |
+| udp6_addr | User Datagram Protocol Address UDPv6 |
+| udp_addr | User Datagram Protocol Address UDP |
+| unix_addr | Unix domain socket end point Address |
+| uri | URI String |
+| url | URL String |
+| url_encoded | URL Encoded |
+| urn_rfc2141 | Urn RFC 2141 String |
+
+### Strings:
+
+| Tag | Description |
+| - | - |
+| alpha | Alpha Only |
+| alphanum | Alphanumeric |
+| alphanumunicode | Alphanumeric Unicode |
+| alphaunicode | Alpha Unicode |
+| ascii | ASCII |
+| contains | Contains |
+| containsany | Contains Any |
+| containsrune | Contains Rune |
+| endswith | Ends With |
+| lowercase | Lowercase |
+| multibyte | Multi-Byte Characters |
+| number | NOT DOCUMENTED IN doc.go |
+| numeric | Numeric |
+| printascii | Printable ASCII |
+| startswith | Starts With |
+| uppercase | Uppercase |
+
+### Format:
+| Tag | Description |
+| - | - |
+| base64 | Base64 String |
+| base64url | Base64URL String |
+| btc_addr | Bitcoin Address |
+| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
+| datetime | Datetime |
+| e164 | e164 formatted phone number |
+| email | E-mail String
+| eth_addr | Ethereum Address |
+| hexadecimal | Hexadecimal String |
+| hexcolor | Hexcolor String |
+| hsl | HSL String |
+| hsla | HSLA String |
+| html | HTML Tags |
+| html_encoded | HTML Encoded |
+| isbn | International Standard Book Number |
+| isbn10 | International Standard Book Number 10 |
+| isbn13 | International Standard Book Number 13 |
+| json | JSON |
+| latitude | Latitude |
+| longitude | Longitude |
+| rgb | RGB String |
+| rgba | RGBA String |
+| ssn | Social Security Number SSN |
+| uuid | Universally Unique Identifier UUID |
+| uuid3 | Universally Unique Identifier UUID v3 |
+| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
+| uuid4 | Universally Unique Identifier UUID v4 |
+| uuid4_rfc4122 | Universally Unique Identifier UUID v4 RFC4122 |
+| uuid5 | Universally Unique Identifier UUID v5 |
+| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
+| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
+
+### Comparisons:
+| Tag | Description |
+| - | - |
+| eq | Equals |
+| gt | Greater than|
+| gte |Greater than or equal |
+| lt | Less Than |
+| lte | Less Than or Equal |
+| ne | Not Equal |
+
+### Other:
+| Tag | Description |
+| - | - |
+| dir | Directory |
+| endswith | Ends With |
+| excludes | Excludes |
+| excludesall | Excludes All |
+| excludesrune | Excludes Rune |
+| file | File path |
+| isdefault | Is Default |
+| len | Length |
+| max | Maximum |
+| min | Minimum |
+| oneof | One Of |
+| required | Required |
+| required_if | Required If |
+| required_unless | Required Unless |
+| required_with | Required With |
+| required_with_all | Required With All |
+| required_without | Required Without |
+| required_without_all | Required Without All |
+| excluded_with | Excluded With |
+| excluded_with_all | Excluded With All |
+| excluded_without | Excluded Without |
+| excluded_without_all | Excluded Without All |
+| unique | Unique |
+
+Benchmarks
+------
+###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
+```go
+goos: darwin
+goarch: amd64
+pkg: github.com/go-playground/validator
+BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op
+BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op
+BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op
+BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op
+BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op
+BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op
+BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op
+BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op
+BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op
+BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op
+BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op
+BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op
+BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op
+BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op
+BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op
+BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op
+BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op
+BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op
+BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op
+BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op
+BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op
+BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op
+BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op
+BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op
+BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op
+BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op
+BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op
+BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op
+BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op
+BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op
+BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op
+BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op
+BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op
+BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op
+BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op
+BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op
+BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op
+BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op
+BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op
+BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op
+BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op
+BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op
+BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op
+BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op
+BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op
+BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op
+```
+
+Complementary Software
+----------------------
+
+Here is a list of software that complements using this library either pre or post validation.
+
+* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
+* [mold](https://github.com/go-playground/mold) - A general library to help modify or set data within data structures and other objects
+
+How to Contribute
+------
+
+Make a pull request...
+
+License
+------
+Distributed under MIT License, please see license file within the code for more details.
diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go
new file mode 100644
index 000000000..6ce762d15
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/baked_in.go
@@ -0,0 +1,2285 @@
+package validator
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "net"
+ "net/url"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/crypto/sha3"
+
+ urn "github.com/leodido/go-urn"
+)
+
+// Func accepts a FieldLevel interface for all validation needs. The return
+// value should be true when validation succeeds.
+type Func func(fl FieldLevel) bool
+
+// FuncCtx accepts a context.Context and FieldLevel interface for all
+// validation needs. The return value should be true when validation succeeds.
+type FuncCtx func(ctx context.Context, fl FieldLevel) bool
+
+// wrapFunc wraps noramal Func makes it compatible with FuncCtx
+func wrapFunc(fn Func) FuncCtx {
+ if fn == nil {
+ return nil // be sure not to wrap a bad function.
+ }
+ return func(ctx context.Context, fl FieldLevel) bool {
+ return fn(fl)
+ }
+}
+
+var (
+ restrictedTags = map[string]struct{}{
+ diveTag: {},
+ keysTag: {},
+ endKeysTag: {},
+ structOnlyTag: {},
+ omitempty: {},
+ skipValidationTag: {},
+ utf8HexComma: {},
+ utf8Pipe: {},
+ noStructLevelTag: {},
+ requiredTag: {},
+ isdefault: {},
+ }
+
+ // BakedInAliasValidators is a default mapping of a single validation tag that
+ // defines a common or complex set of validation(s) to simplify
+ // adding validation to structs.
+ bakedInAliases = map[string]string{
+ "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
+ "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+ }
+
+ // BakedInValidators is the default map of ValidationFunc
+ // you can add, remove or even replace items to suite your needs,
+ // or even disregard and use your own map if so desired.
+ bakedInValidators = map[string]Func{
+ "required": hasValue,
+ "required_if": requiredIf,
+ "required_unless": requiredUnless,
+ "required_with": requiredWith,
+ "required_with_all": requiredWithAll,
+ "required_without": requiredWithout,
+ "required_without_all": requiredWithoutAll,
+ "excluded_with": excludedWith,
+ "excluded_with_all": excludedWithAll,
+ "excluded_without": excludedWithout,
+ "excluded_without_all": excludedWithoutAll,
+ "isdefault": isDefault,
+ "len": hasLengthOf,
+ "min": hasMinOf,
+ "max": hasMaxOf,
+ "eq": isEq,
+ "ne": isNe,
+ "lt": isLt,
+ "lte": isLte,
+ "gt": isGt,
+ "gte": isGte,
+ "eqfield": isEqField,
+ "eqcsfield": isEqCrossStructField,
+ "necsfield": isNeCrossStructField,
+ "gtcsfield": isGtCrossStructField,
+ "gtecsfield": isGteCrossStructField,
+ "ltcsfield": isLtCrossStructField,
+ "ltecsfield": isLteCrossStructField,
+ "nefield": isNeField,
+ "gtefield": isGteField,
+ "gtfield": isGtField,
+ "ltefield": isLteField,
+ "ltfield": isLtField,
+ "fieldcontains": fieldContains,
+ "fieldexcludes": fieldExcludes,
+ "alpha": isAlpha,
+ "alphanum": isAlphanum,
+ "alphaunicode": isAlphaUnicode,
+ "alphanumunicode": isAlphanumUnicode,
+ "numeric": isNumeric,
+ "number": isNumber,
+ "hexadecimal": isHexadecimal,
+ "hexcolor": isHEXColor,
+ "rgb": isRGB,
+ "rgba": isRGBA,
+ "hsl": isHSL,
+ "hsla": isHSLA,
+ "e164": isE164,
+ "email": isEmail,
+ "url": isURL,
+ "uri": isURI,
+ "urn_rfc2141": isUrnRFC2141, // RFC 2141
+ "file": isFile,
+ "base64": isBase64,
+ "base64url": isBase64URL,
+ "contains": contains,
+ "containsany": containsAny,
+ "containsrune": containsRune,
+ "excludes": excludes,
+ "excludesall": excludesAll,
+ "excludesrune": excludesRune,
+ "startswith": startsWith,
+ "endswith": endsWith,
+ "startsnotwith": startsNotWith,
+ "endsnotwith": endsNotWith,
+ "isbn": isISBN,
+ "isbn10": isISBN10,
+ "isbn13": isISBN13,
+ "eth_addr": isEthereumAddress,
+ "btc_addr": isBitcoinAddress,
+ "btc_addr_bech32": isBitcoinBech32Address,
+ "uuid": isUUID,
+ "uuid3": isUUID3,
+ "uuid4": isUUID4,
+ "uuid5": isUUID5,
+ "uuid_rfc4122": isUUIDRFC4122,
+ "uuid3_rfc4122": isUUID3RFC4122,
+ "uuid4_rfc4122": isUUID4RFC4122,
+ "uuid5_rfc4122": isUUID5RFC4122,
+ "ascii": isASCII,
+ "printascii": isPrintableASCII,
+ "multibyte": hasMultiByteCharacter,
+ "datauri": isDataURI,
+ "latitude": isLatitude,
+ "longitude": isLongitude,
+ "ssn": isSSN,
+ "ipv4": isIPv4,
+ "ipv6": isIPv6,
+ "ip": isIP,
+ "cidrv4": isCIDRv4,
+ "cidrv6": isCIDRv6,
+ "cidr": isCIDR,
+ "tcp4_addr": isTCP4AddrResolvable,
+ "tcp6_addr": isTCP6AddrResolvable,
+ "tcp_addr": isTCPAddrResolvable,
+ "udp4_addr": isUDP4AddrResolvable,
+ "udp6_addr": isUDP6AddrResolvable,
+ "udp_addr": isUDPAddrResolvable,
+ "ip4_addr": isIP4AddrResolvable,
+ "ip6_addr": isIP6AddrResolvable,
+ "ip_addr": isIPAddrResolvable,
+ "unix_addr": isUnixAddrResolvable,
+ "mac": isMAC,
+ "hostname": isHostnameRFC952, // RFC 952
+ "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
+ "fqdn": isFQDN,
+ "unique": isUnique,
+ "oneof": isOneOf,
+ "html": isHTML,
+ "html_encoded": isHTMLEncoded,
+ "url_encoded": isURLEncoded,
+ "dir": isDir,
+ "json": isJSON,
+ "hostname_port": isHostnamePort,
+ "lowercase": isLowercase,
+ "uppercase": isUppercase,
+ "datetime": isDatetime,
+ "timezone": isTimeZone,
+ "iso3166_1_alpha2": isIso3166Alpha2,
+ "iso3166_1_alpha3": isIso3166Alpha3,
+ "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
+ }
+)
+
+var oneofValsCache = map[string][]string{}
+var oneofValsCacheRWLock = sync.RWMutex{}
+
+func parseOneOfParam2(s string) []string {
+ oneofValsCacheRWLock.RLock()
+ vals, ok := oneofValsCache[s]
+ oneofValsCacheRWLock.RUnlock()
+ if !ok {
+ oneofValsCacheRWLock.Lock()
+ vals = splitParamsRegex.FindAllString(s, -1)
+ for i := 0; i < len(vals); i++ {
+ vals[i] = strings.Replace(vals[i], "'", "", -1)
+ }
+ oneofValsCache[s] = vals
+ oneofValsCacheRWLock.Unlock()
+ }
+ return vals
+}
+
+func isURLEncoded(fl FieldLevel) bool {
+ return uRLEncodedRegex.MatchString(fl.Field().String())
+}
+
+func isHTMLEncoded(fl FieldLevel) bool {
+ return hTMLEncodedRegex.MatchString(fl.Field().String())
+}
+
+func isHTML(fl FieldLevel) bool {
+ return hTMLRegex.MatchString(fl.Field().String())
+}
+
+func isOneOf(fl FieldLevel) bool {
+ vals := parseOneOfParam2(fl.Param())
+
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+ for i := 0; i < len(vals); i++ {
+ if vals[i] == v {
+ return true
+ }
+ }
+ return false
+}
+
+// isUnique is the validation function for validating if each array|slice|map value is unique
+func isUnique(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+ v := reflect.ValueOf(struct{}{})
+
+ switch field.Kind() {
+ case reflect.Slice, reflect.Array:
+ elem := field.Type().Elem()
+ if elem.Kind() == reflect.Ptr {
+ elem = elem.Elem()
+ }
+
+ if param == "" {
+ m := reflect.MakeMap(reflect.MapOf(elem, v.Type()))
+
+ for i := 0; i < field.Len(); i++ {
+ m.SetMapIndex(reflect.Indirect(field.Index(i)), v)
+ }
+ return field.Len() == m.Len()
+ }
+
+ sf, ok := elem.FieldByName(param)
+ if !ok {
+ panic(fmt.Sprintf("Bad field name %s", param))
+ }
+
+ sfTyp := sf.Type
+ if sfTyp.Kind() == reflect.Ptr {
+ sfTyp = sfTyp.Elem()
+ }
+
+ m := reflect.MakeMap(reflect.MapOf(sfTyp, v.Type()))
+ for i := 0; i < field.Len(); i++ {
+ m.SetMapIndex(reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param)), v)
+ }
+ return field.Len() == m.Len()
+ case reflect.Map:
+ m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
+
+ for _, k := range field.MapKeys() {
+ m.SetMapIndex(field.MapIndex(k), v)
+ }
+ return field.Len() == m.Len()
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+}
+
+// IsMAC is the validation function for validating if the field's value is a valid MAC address.
+func isMAC(fl FieldLevel) bool {
+
+ _, err := net.ParseMAC(fl.Field().String())
+
+ return err == nil
+}
+
+// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
+func isCIDRv4(fl FieldLevel) bool {
+
+ ip, _, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil && ip.To4() != nil
+}
+
+// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
+func isCIDRv6(fl FieldLevel) bool {
+
+ ip, _, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil && ip.To4() == nil
+}
+
+// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
+func isCIDR(fl FieldLevel) bool {
+
+ _, _, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil
+}
+
+// IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
+func isIPv4(fl FieldLevel) bool {
+
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil && ip.To4() != nil
+}
+
+// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
+func isIPv6(fl FieldLevel) bool {
+
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil && ip.To4() == nil
+}
+
+// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
+func isIP(fl FieldLevel) bool {
+
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil
+}
+
+// IsSSN is the validation function for validating if the field's value is a valid SSN.
+func isSSN(fl FieldLevel) bool {
+
+ field := fl.Field()
+
+ if field.Len() != 11 {
+ return false
+ }
+
+ return sSNRegex.MatchString(field.String())
+}
+
+// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
+func isLongitude(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ case reflect.Float32:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
+ case reflect.Float64:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+
+ return longitudeRegex.MatchString(v)
+}
+
+// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
+func isLatitude(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ case reflect.Float32:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
+ case reflect.Float64:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+
+ return latitudeRegex.MatchString(v)
+}
+
+// IsDataURI is the validation function for validating if the field's value is a valid data URI.
+func isDataURI(fl FieldLevel) bool {
+
+ uri := strings.SplitN(fl.Field().String(), ",", 2)
+
+ if len(uri) != 2 {
+ return false
+ }
+
+ if !dataURIRegex.MatchString(uri[0]) {
+ return false
+ }
+
+ return base64Regex.MatchString(uri[1])
+}
+
+// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
+func hasMultiByteCharacter(fl FieldLevel) bool {
+
+ field := fl.Field()
+
+ if field.Len() == 0 {
+ return true
+ }
+
+ return multibyteRegex.MatchString(field.String())
+}
+
+// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
+func isPrintableASCII(fl FieldLevel) bool {
+ return printableASCIIRegex.MatchString(fl.Field().String())
+}
+
+// IsASCII is the validation function for validating if the field's value is a valid ASCII character.
+func isASCII(fl FieldLevel) bool {
+ return aSCIIRegex.MatchString(fl.Field().String())
+}
+
+// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
+func isUUID5(fl FieldLevel) bool {
+ return uUID5Regex.MatchString(fl.Field().String())
+}
+
+// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
+func isUUID4(fl FieldLevel) bool {
+ return uUID4Regex.MatchString(fl.Field().String())
+}
+
+// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
+func isUUID3(fl FieldLevel) bool {
+ return uUID3Regex.MatchString(fl.Field().String())
+}
+
+// IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
+func isUUID(fl FieldLevel) bool {
+ return uUIDRegex.MatchString(fl.Field().String())
+}
+
+// IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
+func isUUID5RFC4122(fl FieldLevel) bool {
+ return uUID5RFC4122Regex.MatchString(fl.Field().String())
+}
+
+// IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
+func isUUID4RFC4122(fl FieldLevel) bool {
+ return uUID4RFC4122Regex.MatchString(fl.Field().String())
+}
+
+// IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
+func isUUID3RFC4122(fl FieldLevel) bool {
+ return uUID3RFC4122Regex.MatchString(fl.Field().String())
+}
+
+// IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
+func isUUIDRFC4122(fl FieldLevel) bool {
+ return uUIDRFC4122Regex.MatchString(fl.Field().String())
+}
+
+// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
+func isISBN(fl FieldLevel) bool {
+ return isISBN10(fl) || isISBN13(fl)
+}
+
+// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
+func isISBN13(fl FieldLevel) bool {
+
+ s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
+
+ if !iSBN13Regex.MatchString(s) {
+ return false
+ }
+
+ var checksum int32
+ var i int32
+
+ factor := []int32{1, 3}
+
+ for i = 0; i < 12; i++ {
+ checksum += factor[i%2] * int32(s[i]-'0')
+ }
+
+ return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
+}
+
+// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
+func isISBN10(fl FieldLevel) bool {
+
+ s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
+
+ if !iSBN10Regex.MatchString(s) {
+ return false
+ }
+
+ var checksum int32
+ var i int32
+
+ for i = 0; i < 9; i++ {
+ checksum += (i + 1) * int32(s[i]-'0')
+ }
+
+ if s[9] == 'X' {
+ checksum += 10 * 10
+ } else {
+ checksum += 10 * int32(s[9]-'0')
+ }
+
+ return checksum%11 == 0
+}
+
+// IsEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
+func isEthereumAddress(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !ethAddressRegex.MatchString(address) {
+ return false
+ }
+
+ if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
+ return true
+ }
+
+ // Checksum validation. Reference: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
+ address = address[2:] // Skip "0x" prefix.
+ h := sha3.NewLegacyKeccak256()
+ // hash.Hash's io.Writer implementation says it never returns an error. https://golang.org/pkg/hash/#Hash
+ _, _ = h.Write([]byte(strings.ToLower(address)))
+ hash := hex.EncodeToString(h.Sum(nil))
+
+ for i := 0; i < len(address); i++ {
+ if address[i] <= '9' { // Skip 0-9 digits: they don't have upper/lower-case.
+ continue
+ }
+ if hash[i] > '7' && address[i] >= 'a' || hash[i] <= '7' && address[i] <= 'F' {
+ return false
+ }
+ }
+
+ return true
+}
+
+// IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address
+func isBitcoinAddress(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !btcAddressRegex.MatchString(address) {
+ return false
+ }
+
+ alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
+
+ decode := [25]byte{}
+
+ for _, n := range []byte(address) {
+ d := bytes.IndexByte(alphabet, n)
+
+ for i := 24; i >= 0; i-- {
+ d += 58 * int(decode[i])
+ decode[i] = byte(d % 256)
+ d /= 256
+ }
+ }
+
+ h := sha256.New()
+ _, _ = h.Write(decode[:21])
+ d := h.Sum([]byte{})
+ h = sha256.New()
+ _, _ = h.Write(d)
+
+ validchecksum := [4]byte{}
+ computedchecksum := [4]byte{}
+
+ copy(computedchecksum[:], h.Sum(d[:0]))
+ copy(validchecksum[:], decode[21:])
+
+ return validchecksum == computedchecksum
+}
+
+// IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
+func isBitcoinBech32Address(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) {
+ return false
+ }
+
+ am := len(address) % 8
+
+ if am == 0 || am == 3 || am == 5 {
+ return false
+ }
+
+ address = strings.ToLower(address)
+
+ alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+
+ hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
+ addr := address[3:]
+ dp := make([]int, 0, len(addr))
+
+ for _, c := range addr {
+ dp = append(dp, strings.IndexRune(alphabet, c))
+ }
+
+ ver := dp[0]
+
+ if ver < 0 || ver > 16 {
+ return false
+ }
+
+ if ver == 0 {
+ if len(address) != 42 && len(address) != 62 {
+ return false
+ }
+ }
+
+ values := append(hr, dp...)
+
+ GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
+
+ p := 1
+
+ for _, v := range values {
+ b := p >> 25
+ p = (p&0x1ffffff)<<5 ^ v
+
+ for i := 0; i < 5; i++ {
+ if (b>>uint(i))&1 == 1 {
+ p ^= GEN[i]
+ }
+ }
+ }
+
+ if p != 1 {
+ return false
+ }
+
+ b := uint(0)
+ acc := 0
+ mv := (1 << 5) - 1
+ var sw []int
+
+ for _, v := range dp[1 : len(dp)-6] {
+ acc = (acc << 5) | v
+ b += 5
+ for b >= 8 {
+ b -= 8
+ sw = append(sw, (acc>>b)&mv)
+ }
+ }
+
+ if len(sw) < 2 || len(sw) > 40 {
+ return false
+ }
+
+ return true
+}
+
+// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
+func excludesRune(fl FieldLevel) bool {
+ return !containsRune(fl)
+}
+
+// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
+func excludesAll(fl FieldLevel) bool {
+ return !containsAny(fl)
+}
+
+// Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
+func excludes(fl FieldLevel) bool {
+ return !contains(fl)
+}
+
+// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
+func containsRune(fl FieldLevel) bool {
+
+ r, _ := utf8.DecodeRuneInString(fl.Param())
+
+ return strings.ContainsRune(fl.Field().String(), r)
+}
+
+// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
+func containsAny(fl FieldLevel) bool {
+ return strings.ContainsAny(fl.Field().String(), fl.Param())
+}
+
+// Contains is the validation function for validating that the field's value contains the text specified within the param.
+func contains(fl FieldLevel) bool {
+ return strings.Contains(fl.Field().String(), fl.Param())
+}
+
+// StartsWith is the validation function for validating that the field's value starts with the text specified within the param.
+func startsWith(fl FieldLevel) bool {
+ return strings.HasPrefix(fl.Field().String(), fl.Param())
+}
+
+// EndsWith is the validation function for validating that the field's value ends with the text specified within the param.
+func endsWith(fl FieldLevel) bool {
+ return strings.HasSuffix(fl.Field().String(), fl.Param())
+}
+
+// StartsNotWith is the validation function for validating that the field's value does not start with the text specified within the param.
+func startsNotWith(fl FieldLevel) bool {
+ return !startsWith(fl)
+}
+
+// EndsNotWith is the validation function for validating that the field's value does not end with the text specified within the param.
+func endsNotWith(fl FieldLevel) bool {
+ return !endsWith(fl)
+}
+
+// FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
+func fieldContains(fl FieldLevel) bool {
+ field := fl.Field()
+
+ currentField, _, ok := fl.GetStructFieldOK()
+
+ if !ok {
+ return false
+ }
+
+ return strings.Contains(field.String(), currentField.String())
+}
+
+// FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
+func fieldExcludes(fl FieldLevel) bool {
+ field := fl.Field()
+
+ currentField, _, ok := fl.GetStructFieldOK()
+ if !ok {
+ return true
+ }
+
+ return !strings.Contains(field.String(), currentField.String())
+}
+
+// IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
+func isNeField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+
+ if !ok || currentKind != kind {
+ return true
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() != currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() != currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() != currentField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) != int64(currentField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return true
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return !fieldTime.Equal(t)
+ }
+
+ }
+
+ // default reflect.String:
+ return field.String() != currentField.String()
+}
+
+// IsNe is the validation function for validating that the field's value does not equal the provided param value.
+func isNe(fl FieldLevel) bool {
+ return !isEq(fl)
+}
+
+// IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
+func isLteCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() <= topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() <= topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() <= topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) <= int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ fieldTime := field.Interface().(time.Time)
+ topTime := topField.Interface().(time.Time)
+
+ return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
+ }
+ }
+
+ // default reflect.String:
+ return field.String() <= topField.String()
+}
+
+// IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
+// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
+func isLtCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() < topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() < topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() < topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) < int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ fieldTime := field.Interface().(time.Time)
+ topTime := topField.Interface().(time.Time)
+
+ return fieldTime.Before(topTime)
+ }
+ }
+
+ // default reflect.String:
+ return field.String() < topField.String()
+}
+
+// IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
+func isGteCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() >= topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() >= topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() >= topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) >= int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ fieldTime := field.Interface().(time.Time)
+ topTime := topField.Interface().(time.Time)
+
+ return fieldTime.After(topTime) || fieldTime.Equal(topTime)
+ }
+ }
+
+ // default reflect.String:
+ return field.String() >= topField.String()
+}
+
+// IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
+func isGtCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() > topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() > topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() > topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) > int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ fieldTime := field.Interface().(time.Time)
+ topTime := topField.Interface().(time.Time)
+
+ return fieldTime.After(topTime)
+ }
+ }
+
+ // default reflect.String:
+ return field.String() > topField.String()
+}
+
+// IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
+func isNeCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return true
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return topField.Int() != field.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return topField.Uint() != field.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return topField.Float() != field.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(topField.Len()) != int64(field.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return true
+ }
+
+ if fieldType == timeType {
+
+ t := field.Interface().(time.Time)
+ fieldTime := topField.Interface().(time.Time)
+
+ return !fieldTime.Equal(t)
+ }
+ }
+
+ // default reflect.String:
+ return topField.String() != field.String()
+}
+
+// IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
+func isEqCrossStructField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return topField.Int() == field.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return topField.Uint() == field.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return topField.Float() == field.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(topField.Len()) == int64(field.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := field.Interface().(time.Time)
+ fieldTime := topField.Interface().(time.Time)
+
+ return fieldTime.Equal(t)
+ }
+ }
+
+ // default reflect.String:
+ return topField.String() == field.String()
+}
+
+// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
+func isEqField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() == currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() == currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() == currentField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) == int64(currentField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return fieldTime.Equal(t)
+ }
+
+ }
+
+ // default reflect.String:
+ return field.String() == currentField.String()
+}
+
+// IsEq is the validation function for validating if the current field's value is equal to the param's value.
+func isEq(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ return field.String() == param
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) == p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() == p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() == p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() == p
+
+ case reflect.Bool:
+ p := asBool(param)
+
+ return field.Bool() == p
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
+func isBase64(fl FieldLevel) bool {
+ return base64Regex.MatchString(fl.Field().String())
+}
+
+// IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
+func isBase64URL(fl FieldLevel) bool {
+ return base64URLRegex.MatchString(fl.Field().String())
+}
+
+// IsURI is the validation function for validating if the current field's value is a valid URI.
+func isURI(fl FieldLevel) bool {
+
+ field := fl.Field()
+
+ switch field.Kind() {
+
+ case reflect.String:
+
+ s := field.String()
+
+ // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
+ // emulate browser and strip the '#' suffix prior to validation. see issue-#237
+ if i := strings.Index(s, "#"); i > -1 {
+ s = s[:i]
+ }
+
+ if len(s) == 0 {
+ return false
+ }
+
+ _, err := url.ParseRequestURI(s)
+
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsURL is the validation function for validating if the current field's value is a valid URL.
+func isURL(fl FieldLevel) bool {
+
+ field := fl.Field()
+
+ switch field.Kind() {
+
+ case reflect.String:
+
+ var i int
+ s := field.String()
+
+ // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
+ // emulate browser and strip the '#' suffix prior to validation. see issue-#237
+ if i = strings.Index(s, "#"); i > -1 {
+ s = s[:i]
+ }
+
+ if len(s) == 0 {
+ return false
+ }
+
+ url, err := url.ParseRequestURI(s)
+
+ if err != nil || url.Scheme == "" {
+ return false
+ }
+
+ return true
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
+func isUrnRFC2141(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+
+ case reflect.String:
+
+ str := field.String()
+
+ _, match := urn.Parse([]byte(str))
+
+ return match
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsFile is the validation function for validating if the current field's value is a valid file path.
+func isFile(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+ fileInfo, err := os.Stat(field.String())
+ if err != nil {
+ return false
+ }
+
+ return !fileInfo.IsDir()
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number.
+func isE164(fl FieldLevel) bool {
+ return e164Regex.MatchString(fl.Field().String())
+}
+
+// IsEmail is the validation function for validating if the current field's value is a valid email address.
+func isEmail(fl FieldLevel) bool {
+ return emailRegex.MatchString(fl.Field().String())
+}
+
+// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
+func isHSLA(fl FieldLevel) bool {
+ return hslaRegex.MatchString(fl.Field().String())
+}
+
+// IsHSL is the validation function for validating if the current field's value is a valid HSL color.
+func isHSL(fl FieldLevel) bool {
+ return hslRegex.MatchString(fl.Field().String())
+}
+
+// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
+func isRGBA(fl FieldLevel) bool {
+ return rgbaRegex.MatchString(fl.Field().String())
+}
+
+// IsRGB is the validation function for validating if the current field's value is a valid RGB color.
+func isRGB(fl FieldLevel) bool {
+ return rgbRegex.MatchString(fl.Field().String())
+}
+
+// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
+func isHEXColor(fl FieldLevel) bool {
+ return hexcolorRegex.MatchString(fl.Field().String())
+}
+
+// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
+func isHexadecimal(fl FieldLevel) bool {
+ return hexadecimalRegex.MatchString(fl.Field().String())
+}
+
+// IsNumber is the validation function for validating if the current field's value is a valid number.
+func isNumber(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
+ return true
+ default:
+ return numberRegex.MatchString(fl.Field().String())
+ }
+}
+
+// IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
+func isNumeric(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
+ return true
+ default:
+ return numericRegex.MatchString(fl.Field().String())
+ }
+}
+
+// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
+func isAlphanum(fl FieldLevel) bool {
+ return alphaNumericRegex.MatchString(fl.Field().String())
+}
+
+// IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
+func isAlpha(fl FieldLevel) bool {
+ return alphaRegex.MatchString(fl.Field().String())
+}
+
+// IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
+func isAlphanumUnicode(fl FieldLevel) bool {
+ return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
+}
+
+// IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
+func isAlphaUnicode(fl FieldLevel) bool {
+ return alphaUnicodeRegex.MatchString(fl.Field().String())
+}
+
+// isDefault is the opposite of required aka hasValue
+func isDefault(fl FieldLevel) bool {
+ return !hasValue(fl)
+}
+
+// HasValue is the validation function for validating if the current field's value is not the default static value.
+func hasValue(fl FieldLevel) bool {
+ field := fl.Field()
+ switch field.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ return !field.IsNil()
+ default:
+ if fl.(*validate).fldIsPointer && field.Interface() != nil {
+ return true
+ }
+ return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
+ }
+}
+
+// requireCheckField is a func for check field kind
+func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool {
+ field := fl.Field()
+ kind := field.Kind()
+ var nullable, found bool
+ if len(param) > 0 {
+ field, kind, nullable, found = fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
+ if !found {
+ return defaultNotFoundValue
+ }
+ }
+ switch kind {
+ case reflect.Invalid:
+ return defaultNotFoundValue
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ return field.IsNil()
+ default:
+ if nullable && field.Interface() != nil {
+ return false
+ }
+ return field.IsValid() && field.Interface() == reflect.Zero(field.Type()).Interface()
+ }
+}
+
+// requireCheckFieldValue is a func for check field value
+func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool {
+ field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
+ if !found {
+ return defaultNotFoundValue
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() == asInt(value)
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() == asUint(value)
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() == asFloat(value)
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) == asInt(value)
+ }
+
+ // default reflect.String:
+ return field.String() == value
+}
+
+// requiredIf is the validation function
+// The field under validation must be present and not empty only if all the other specified fields are equal to the value following with the specified field.
+func requiredIf(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for required_if %s", fl.FieldName()))
+ }
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// requiredUnless is the validation function
+// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
+func requiredUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for required_unless %s", fl.FieldName()))
+ }
+
+ for i := 0; i < len(params); i += 2 {
+ if requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// ExcludedWith is the validation function
+// The field under validation must not be present or is empty if any of the other specified fields are present.
+func excludedWith(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return !hasValue(fl)
+ }
+ }
+ return true
+}
+
+// RequiredWith is the validation function
+// The field under validation must be present and not empty only if any of the other specified fields are present.
+func requiredWith(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return hasValue(fl)
+ }
+ }
+ return true
+}
+
+// ExcludedWithAll is the validation function
+// The field under validation must not be present or is empty if all of the other specified fields are present.
+func excludedWithAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
+// RequiredWithAll is the validation function
+// The field under validation must be present and not empty only if all of the other specified fields are present.
+func requiredWithAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// ExcludedWithout is the validation function
+// The field under validation must not be present or is empty when any of the other specified fields are not present.
+func excludedWithout(fl FieldLevel) bool {
+ if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
+ return !hasValue(fl)
+ }
+ return true
+}
+
+// RequiredWithout is the validation function
+// The field under validation must be present and not empty only when any of the other specified fields are not present.
+func requiredWithout(fl FieldLevel) bool {
+ if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
+ return hasValue(fl)
+ }
+ return true
+}
+
+// RequiredWithoutAll is the validation function
+// The field under validation must not be present or is empty when all of the other specified fields are not present.
+func excludedWithoutAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
+// RequiredWithoutAll is the validation function
+// The field under validation must be present and not empty only when all of the other specified fields are not present.
+func requiredWithoutAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
+func isGteField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() >= currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() >= currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() >= currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return fieldTime.After(t) || fieldTime.Equal(t)
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) >= len(currentField.String())
+}
+
+// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
+func isGtField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() > currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() > currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() > currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return fieldTime.After(t)
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) > len(currentField.String())
+}
+
+// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
+func isGte(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) >= p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) >= p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() >= p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() >= p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() >= p
+
+ case reflect.Struct:
+
+ if field.Type() == timeType {
+
+ now := time.Now().UTC()
+ t := field.Interface().(time.Time)
+
+ return t.After(now) || t.Equal(now)
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsGt is the validation function for validating if the current field's value is greater than the param's value.
+func isGt(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) > p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) > p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() > p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() > p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() > p
+ case reflect.Struct:
+
+ if field.Type() == timeType {
+
+ return field.Interface().(time.Time).After(time.Now().UTC())
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
+func hasLengthOf(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) == p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) == p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() == p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() == p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() == p
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
+func hasMinOf(fl FieldLevel) bool {
+ return isGte(fl)
+}
+
+// IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
+func isLteField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() <= currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() <= currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() <= currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return fieldTime.Before(t) || fieldTime.Equal(t)
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) <= len(currentField.String())
+}
+
+// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
+func isLtField(fl FieldLevel) bool {
+
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() < currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() < currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() < currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+
+ if fieldType == timeType {
+
+ t := currentField.Interface().(time.Time)
+ fieldTime := field.Interface().(time.Time)
+
+ return fieldTime.Before(t)
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) < len(currentField.String())
+}
+
+// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
+func isLte(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) <= p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) <= p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() <= p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() <= p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() <= p
+
+ case reflect.Struct:
+
+ if field.Type() == timeType {
+
+ now := time.Now().UTC()
+ t := field.Interface().(time.Time)
+
+ return t.Before(now) || t.Equal(now)
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// IsLt is the validation function for validating if the current field's value is less than the param's value.
+func isLt(fl FieldLevel) bool {
+
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) < p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) < p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() < p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() < p
+
+ case reflect.Float32, reflect.Float64:
+ p := asFloat(param)
+
+ return field.Float() < p
+
+ case reflect.Struct:
+
+ if field.Type() == timeType {
+
+ return field.Interface().(time.Time).Before(time.Now().UTC())
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
+func hasMaxOf(fl FieldLevel) bool {
+ return isLte(fl)
+}
+
+// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
+func isTCP4AddrResolvable(fl FieldLevel) bool {
+
+ if !isIP4Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
+ return err == nil
+}
+
+// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
+func isTCP6AddrResolvable(fl FieldLevel) bool {
+
+ if !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
+
+ return err == nil
+}
+
+// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
+func isTCPAddrResolvable(fl FieldLevel) bool {
+
+ if !isIP4Addr(fl) && !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
+
+ return err == nil
+}
+
+// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
+func isUDP4AddrResolvable(fl FieldLevel) bool {
+
+ if !isIP4Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
+
+ return err == nil
+}
+
+// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
+func isUDP6AddrResolvable(fl FieldLevel) bool {
+
+ if !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
+
+ return err == nil
+}
+
+// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
+func isUDPAddrResolvable(fl FieldLevel) bool {
+
+ if !isIP4Addr(fl) && !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp", fl.Field().String())
+
+ return err == nil
+}
+
+// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
+func isIP4AddrResolvable(fl FieldLevel) bool {
+
+ if !isIPv4(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip4", fl.Field().String())
+
+ return err == nil
+}
+
+// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
+func isIP6AddrResolvable(fl FieldLevel) bool {
+
+ if !isIPv6(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip6", fl.Field().String())
+
+ return err == nil
+}
+
+// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
+func isIPAddrResolvable(fl FieldLevel) bool {
+
+ if !isIP(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip", fl.Field().String())
+
+ return err == nil
+}
+
+// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
+func isUnixAddrResolvable(fl FieldLevel) bool {
+
+ _, err := net.ResolveUnixAddr("unix", fl.Field().String())
+
+ return err == nil
+}
+
+func isIP4Addr(fl FieldLevel) bool {
+
+ val := fl.Field().String()
+
+ if idx := strings.LastIndex(val, ":"); idx != -1 {
+ val = val[0:idx]
+ }
+
+ ip := net.ParseIP(val)
+
+ return ip != nil && ip.To4() != nil
+}
+
+func isIP6Addr(fl FieldLevel) bool {
+
+ val := fl.Field().String()
+
+ if idx := strings.LastIndex(val, ":"); idx != -1 {
+ if idx != 0 && val[idx-1:idx] == "]" {
+ val = val[1 : idx-1]
+ }
+ }
+
+ ip := net.ParseIP(val)
+
+ return ip != nil && ip.To4() == nil
+}
+
+func isHostnameRFC952(fl FieldLevel) bool {
+ return hostnameRegexRFC952.MatchString(fl.Field().String())
+}
+
+func isHostnameRFC1123(fl FieldLevel) bool {
+ return hostnameRegexRFC1123.MatchString(fl.Field().String())
+}
+
+func isFQDN(fl FieldLevel) bool {
+ val := fl.Field().String()
+
+ if val == "" {
+ return false
+ }
+
+ return fqdnRegexRFC1123.MatchString(val)
+}
+
+// IsDir is the validation function for validating if the current field's value is a valid directory.
+func isDir(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ fileInfo, err := os.Stat(field.String())
+ if err != nil {
+ return false
+ }
+
+ return fileInfo.IsDir()
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isJSON is the validation function for validating if the current field's value is a valid json string.
+func isJSON(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ val := field.String()
+ return json.Valid([]byte(val))
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isHostnamePort validates a
[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-[](https://semaphoreci.com/joeybloggs/validator)
-[](https://coveralls.io/github/go-playground/validator?branch=v8)
-[](https://goreportcard.com/report/github.com/go-playground/validator)
-[](https://godoc.org/gopkg.in/go-playground/validator.v8)
-
-
-Package validator implements value validations for structs and individual fields based on tags.
-
-It has the following **unique** features:
-
-- Cross Field and Cross Struct validations by using validation tags or custom validators.
-- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
-- Handles type interface by determining it's underlying type prior to validation.
-- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
-- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
-- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
-
-Installation
-------------
-
-Use go get.
-
- go get gopkg.in/go-playground/validator.v8
-
-or to update
-
- go get -u gopkg.in/go-playground/validator.v8
-
-Then import the validator package into your own code.
-
- import "gopkg.in/go-playground/validator.v8"
-
-Error Return Value
--------
-
-Validation functions return type error
-
-They return type error to avoid the issue discussed in the following, where err is always != nil:
-
-* http://stackoverflow.com/a/29138676/3158232
-* https://github.com/go-playground/validator/issues/134
-
-validator only returns nil or ValidationErrors as type error; so in you code all you need to do
-is check if the error returned is not nil, and if it's not type cast it to type ValidationErrors
-like so:
-
-```go
-err := validate.Struct(mystruct)
-validationErrors := err.(validator.ValidationErrors)
- ```
-
-Usage and documentation
-------
-
-Please see http://godoc.org/gopkg.in/go-playground/validator.v8 for detailed usage docs.
-
-##### Examples:
-
-Struct & Field validation
-```go
-package main
-
-import (
- "fmt"
-
- "gopkg.in/go-playground/validator.v8"
-)
-
-// User contains user information
-type User struct {
- FirstName string `validate:"required"`
- LastName string `validate:"required"`
- Age uint8 `validate:"gte=0,lte=130"`
- Email string `validate:"required,email"`
- FavouriteColor string `validate:"hexcolor|rgb|rgba"`
- Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
-}
-
-// Address houses a users address information
-type Address struct {
- Street string `validate:"required"`
- City string `validate:"required"`
- Planet string `validate:"required"`
- Phone string `validate:"required"`
-}
-
-var validate *validator.Validate
-
-func main() {
-
- config := &validator.Config{TagName: "validate"}
-
- validate = validator.New(config)
-
- validateStruct()
- validateField()
-}
-
-func validateStruct() {
-
- address := &Address{
- Street: "Eavesdown Docks",
- Planet: "Persphone",
- Phone: "none",
- }
-
- user := &User{
- FirstName: "Badger",
- LastName: "Smith",
- Age: 135,
- Email: "Badger.Smith@gmail.com",
- FavouriteColor: "#000",
- Addresses: []*Address{address},
- }
-
- // returns nil or ValidationErrors ( map[string]*FieldError )
- errs := validate.Struct(user)
-
- if errs != nil {
-
- fmt.Println(errs) // output: Key: "User.Age" Error:Field validation for "Age" failed on the "lte" tag
- // Key: "User.Addresses[0].City" Error:Field validation for "City" failed on the "required" tag
- err := errs.(validator.ValidationErrors)["User.Addresses[0].City"]
- fmt.Println(err.Field) // output: City
- fmt.Println(err.Tag) // output: required
- fmt.Println(err.Kind) // output: string
- fmt.Println(err.Type) // output: string
- fmt.Println(err.Param) // output:
- fmt.Println(err.Value) // output:
-
- // from here you can create your own error messages in whatever language you wish
- return
- }
-
- // save user to database
-}
-
-func validateField() {
- myEmail := "joeybloggs.gmail.com"
-
- errs := validate.Field(myEmail, "required,email")
-
- if errs != nil {
- fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag
- return
- }
-
- // email ok, move on
-}
-```
-
-Custom Field Type
-```go
-package main
-
-import (
- "database/sql"
- "database/sql/driver"
- "fmt"
- "reflect"
-
- "gopkg.in/go-playground/validator.v8"
-)
-
-// DbBackedUser User struct
-type DbBackedUser struct {
- Name sql.NullString `validate:"required"`
- Age sql.NullInt64 `validate:"required"`
-}
-
-func main() {
-
- config := &validator.Config{TagName: "validate"}
-
- validate := validator.New(config)
-
- // register all sql.Null* types to use the ValidateValuer CustomTypeFunc
- validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
-
- x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}
- errs := validate.Struct(x)
-
- if len(errs.(validator.ValidationErrors)) > 0 {
- fmt.Printf("Errs:\n%+v\n", errs)
- }
-}
-
-// ValidateValuer implements validator.CustomTypeFunc
-func ValidateValuer(field reflect.Value) interface{} {
- if valuer, ok := field.Interface().(driver.Valuer); ok {
- val, err := valuer.Value()
- if err == nil {
- return val
- }
- // handle the error how you want
- }
- return nil
-}
-```
-
-Struct Level Validation
-```go
-package main
-
-import (
- "fmt"
- "reflect"
-
- "gopkg.in/go-playground/validator.v8"
-)
-
-// User contains user information
-type User struct {
- FirstName string `json:"fname"`
- LastName string `json:"lname"`
- Age uint8 `validate:"gte=0,lte=130"`
- Email string `validate:"required,email"`
- FavouriteColor string `validate:"hexcolor|rgb|rgba"`
- Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
-}
-
-// Address houses a users address information
-type Address struct {
- Street string `validate:"required"`
- City string `validate:"required"`
- Planet string `validate:"required"`
- Phone string `validate:"required"`
-}
-
-var validate *validator.Validate
-
-func main() {
-
- config := &validator.Config{TagName: "validate"}
-
- validate = validator.New(config)
- validate.RegisterStructValidation(UserStructLevelValidation, User{})
-
- validateStruct()
-}
-
-// UserStructLevelValidation contains custom struct level validations that don't always
-// make sense at the field validation level. For Example this function validates that either
-// FirstName or LastName exist; could have done that with a custom field validation but then
-// would have had to add it to both fields duplicating the logic + overhead, this way it's
-// only validated once.
-//
-// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way
-// hooks right into validator and you can combine with validation tags and still have a
-// common error output format.
-func UserStructLevelValidation(v *validator.Validate, structLevel *validator.StructLevel) {
-
- user := structLevel.CurrentStruct.Interface().(User)
-
- if len(user.FirstName) == 0 && len(user.LastName) == 0 {
- structLevel.ReportError(reflect.ValueOf(user.FirstName), "FirstName", "fname", "fnameorlname")
- structLevel.ReportError(reflect.ValueOf(user.LastName), "LastName", "lname", "fnameorlname")
- }
-
- // plus can to more, even with different tag than "fnameorlname"
-}
-
-func validateStruct() {
-
- address := &Address{
- Street: "Eavesdown Docks",
- Planet: "Persphone",
- Phone: "none",
- City: "Unknown",
- }
-
- user := &User{
- FirstName: "",
- LastName: "",
- Age: 45,
- Email: "Badger.Smith@gmail.com",
- FavouriteColor: "#000",
- Addresses: []*Address{address},
- }
-
- // returns nil or ValidationErrors ( map[string]*FieldError )
- errs := validate.Struct(user)
-
- if errs != nil {
-
- fmt.Println(errs) // output: Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'fnameorlname' tag
- // Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'fnameorlname' tag
- err := errs.(validator.ValidationErrors)["User.FirstName"]
- fmt.Println(err.Field) // output: FirstName
- fmt.Println(err.Tag) // output: fnameorlname
- fmt.Println(err.Kind) // output: string
- fmt.Println(err.Type) // output: string
- fmt.Println(err.Param) // output:
- fmt.Println(err.Value) // output:
-
- // from here you can create your own error messages in whatever language you wish
- return
- }
-
- // save user to database
-}
-```
-
-Benchmarks
-------
-###### Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.5.3 darwin/amd64
-```go
-PASS
-BenchmarkFieldSuccess-8 20000000 118 ns/op 0 B/op 0 allocs/op
-BenchmarkFieldFailure-8 2000000 758 ns/op 432 B/op 4 allocs/op
-BenchmarkFieldDiveSuccess-8 500000 2471 ns/op 464 B/op 28 allocs/op
-BenchmarkFieldDiveFailure-8 500000 3172 ns/op 896 B/op 32 allocs/op
-BenchmarkFieldCustomTypeSuccess-8 5000000 300 ns/op 32 B/op 2 allocs/op
-BenchmarkFieldCustomTypeFailure-8 2000000 775 ns/op 432 B/op 4 allocs/op
-BenchmarkFieldOrTagSuccess-8 1000000 1122 ns/op 4 B/op 1 allocs/op
-BenchmarkFieldOrTagFailure-8 1000000 1167 ns/op 448 B/op 6 allocs/op
-BenchmarkStructLevelValidationSuccess-8 3000000 548 ns/op 160 B/op 5 allocs/op
-BenchmarkStructLevelValidationFailure-8 3000000 558 ns/op 160 B/op 5 allocs/op
-BenchmarkStructSimpleCustomTypeSuccess-8 2000000 623 ns/op 36 B/op 3 allocs/op
-BenchmarkStructSimpleCustomTypeFailure-8 1000000 1381 ns/op 640 B/op 9 allocs/op
-BenchmarkStructPartialSuccess-8 1000000 1036 ns/op 272 B/op 9 allocs/op
-BenchmarkStructPartialFailure-8 1000000 1734 ns/op 730 B/op 14 allocs/op
-BenchmarkStructExceptSuccess-8 2000000 888 ns/op 250 B/op 7 allocs/op
-BenchmarkStructExceptFailure-8 1000000 1036 ns/op 272 B/op 9 allocs/op
-BenchmarkStructSimpleCrossFieldSuccess-8 2000000 773 ns/op 80 B/op 4 allocs/op
-BenchmarkStructSimpleCrossFieldFailure-8 1000000 1487 ns/op 536 B/op 9 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 1000000 1261 ns/op 112 B/op 7 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldFailure-8 1000000 2055 ns/op 576 B/op 12 allocs/op
-BenchmarkStructSimpleSuccess-8 3000000 519 ns/op 4 B/op 1 allocs/op
-BenchmarkStructSimpleFailure-8 1000000 1429 ns/op 640 B/op 9 allocs/op
-BenchmarkStructSimpleSuccessParallel-8 10000000 146 ns/op 4 B/op 1 allocs/op
-BenchmarkStructSimpleFailureParallel-8 2000000 551 ns/op 640 B/op 9 allocs/op
-BenchmarkStructComplexSuccess-8 500000 3269 ns/op 244 B/op 15 allocs/op
-BenchmarkStructComplexFailure-8 200000 8436 ns/op 3609 B/op 60 allocs/op
-BenchmarkStructComplexSuccessParallel-8 1000000 1024 ns/op 244 B/op 15 allocs/op
-BenchmarkStructComplexFailureParallel-8 500000 3536 ns/op 3609 B/op 60 allocs/op
-```
-
-Complimentary Software
-----------------------
-
-Here is a list of software that compliments using this library either pre or post validation.
-
-* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
-* [Conform](https://github.com/leebenson/conform) - Trims, sanitizes & scrubs data based on struct tags.
-
-How to Contribute
-------
-
-There will always be a development branch for each version i.e. `v1-development`. In order to contribute,
-please make your pull requests against those branches.
-
-If the changes being proposed or requested are breaking changes, please create an issue, for discussion
-or create a pull request against the highest development branch for example this package has a
-v1 and v1-development branch however, there will also be a v2-development branch even though v2 doesn't exist yet.
-
-I strongly encourage everyone whom creates a custom validation function to contribute them and
-help make this package even better.
-
-License
-------
-Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/gopkg.in/go-playground/validator.v8/baked_in.go b/vendor/gopkg.in/go-playground/validator.v8/baked_in.go
deleted file mode 100644
index 44aaa0851..000000000
--- a/vendor/gopkg.in/go-playground/validator.v8/baked_in.go
+++ /dev/null
@@ -1,1410 +0,0 @@
-package validator
-
-import (
- "fmt"
- "net"
- "net/url"
- "reflect"
- "strings"
- "time"
- "unicode/utf8"
-)
-
-// BakedInAliasValidators is a default mapping of a single validationstag that
-// defines a common or complex set of validation(s) to simplify
-// adding validation to structs. i.e. set key "_ageok" and the tags
-// are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60"
-var bakedInAliasValidators = map[string]string{
- "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
-}
-
-// BakedInValidators is the default map of ValidationFunc
-// you can add, remove or even replace items to suite your needs,
-// or even disregard and use your own map if so desired.
-var bakedInValidators = map[string]Func{
- "required": HasValue,
- "len": HasLengthOf,
- "min": HasMinOf,
- "max": HasMaxOf,
- "eq": IsEq,
- "ne": IsNe,
- "lt": IsLt,
- "lte": IsLte,
- "gt": IsGt,
- "gte": IsGte,
- "eqfield": IsEqField,
- "eqcsfield": IsEqCrossStructField,
- "necsfield": IsNeCrossStructField,
- "gtcsfield": IsGtCrossStructField,
- "gtecsfield": IsGteCrossStructField,
- "ltcsfield": IsLtCrossStructField,
- "ltecsfield": IsLteCrossStructField,
- "nefield": IsNeField,
- "gtefield": IsGteField,
- "gtfield": IsGtField,
- "ltefield": IsLteField,
- "ltfield": IsLtField,
- "alpha": IsAlpha,
- "alphanum": IsAlphanum,
- "numeric": IsNumeric,
- "number": IsNumber,
- "hexadecimal": IsHexadecimal,
- "hexcolor": IsHEXColor,
- "rgb": IsRGB,
- "rgba": IsRGBA,
- "hsl": IsHSL,
- "hsla": IsHSLA,
- "email": IsEmail,
- "url": IsURL,
- "uri": IsURI,
- "base64": IsBase64,
- "contains": Contains,
- "containsany": ContainsAny,
- "containsrune": ContainsRune,
- "excludes": Excludes,
- "excludesall": ExcludesAll,
- "excludesrune": ExcludesRune,
- "isbn": IsISBN,
- "isbn10": IsISBN10,
- "isbn13": IsISBN13,
- "uuid": IsUUID,
- "uuid3": IsUUID3,
- "uuid4": IsUUID4,
- "uuid5": IsUUID5,
- "ascii": IsASCII,
- "printascii": IsPrintableASCII,
- "multibyte": HasMultiByteCharacter,
- "datauri": IsDataURI,
- "latitude": IsLatitude,
- "longitude": IsLongitude,
- "ssn": IsSSN,
- "ipv4": IsIPv4,
- "ipv6": IsIPv6,
- "ip": IsIP,
- "cidrv4": IsCIDRv4,
- "cidrv6": IsCIDRv6,
- "cidr": IsCIDR,
- "tcp4_addr": IsTCP4AddrResolvable,
- "tcp6_addr": IsTCP6AddrResolvable,
- "tcp_addr": IsTCPAddrResolvable,
- "udp4_addr": IsUDP4AddrResolvable,
- "udp6_addr": IsUDP6AddrResolvable,
- "udp_addr": IsUDPAddrResolvable,
- "ip4_addr": IsIP4AddrResolvable,
- "ip6_addr": IsIP6AddrResolvable,
- "ip_addr": IsIPAddrResolvable,
- "unix_addr": IsUnixAddrResolvable,
- "mac": IsMAC,
-}
-
-// IsMAC is the validation function for validating if the field's value is a valid MAC address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsMAC(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- _, err := net.ParseMAC(field.String())
- return err == nil
-}
-
-// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsCIDRv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- ip, _, err := net.ParseCIDR(field.String())
-
- return err == nil && ip.To4() != nil
-}
-
-// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsCIDRv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- ip, _, err := net.ParseCIDR(field.String())
-
- return err == nil && ip.To4() == nil
-}
-
-// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsCIDR(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- _, _, err := net.ParseCIDR(field.String())
-
- return err == nil
-}
-
-// IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIPv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- ip := net.ParseIP(field.String())
-
- return ip != nil && ip.To4() != nil
-}
-
-// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIPv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- ip := net.ParseIP(field.String())
-
- return ip != nil && ip.To4() == nil
-}
-
-// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIP(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- ip := net.ParseIP(field.String())
-
- return ip != nil
-}
-
-// IsSSN is the validation function for validating if the field's value is a valid SSN.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsSSN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if field.Len() != 11 {
- return false
- }
-
- return sSNRegex.MatchString(field.String())
-}
-
-// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLongitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return longitudeRegex.MatchString(field.String())
-}
-
-// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLatitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return latitudeRegex.MatchString(field.String())
-}
-
-// IsDataURI is the validation function for validating if the field's value is a valid data URI.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsDataURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- uri := strings.SplitN(field.String(), ",", 2)
-
- if len(uri) != 2 {
- return false
- }
-
- if !dataURIRegex.MatchString(uri[0]) {
- return false
- }
-
- fld := reflect.ValueOf(uri[1])
-
- return IsBase64(v, topStruct, currentStructOrField, fld, fld.Type(), fld.Kind(), param)
-}
-
-// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func HasMultiByteCharacter(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if field.Len() == 0 {
- return true
- }
-
- return multibyteRegex.MatchString(field.String())
-}
-
-// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsPrintableASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return printableASCIIRegex.MatchString(field.String())
-}
-
-// IsASCII is the validation function for validating if the field's value is a valid ASCII character.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return aSCIIRegex.MatchString(field.String())
-}
-
-// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUUID5(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return uUID5Regex.MatchString(field.String())
-}
-
-// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUUID4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return uUID4Regex.MatchString(field.String())
-}
-
-// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUUID3(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return uUID3Regex.MatchString(field.String())
-}
-
-// IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUUID(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return uUIDRegex.MatchString(field.String())
-}
-
-// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsISBN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return IsISBN10(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) || IsISBN13(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsISBN13(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- s := strings.Replace(strings.Replace(field.String(), "-", "", 4), " ", "", 4)
-
- if !iSBN13Regex.MatchString(s) {
- return false
- }
-
- var checksum int32
- var i int32
-
- factor := []int32{1, 3}
-
- for i = 0; i < 12; i++ {
- checksum += factor[i%2] * int32(s[i]-'0')
- }
-
- return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
-}
-
-// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsISBN10(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- s := strings.Replace(strings.Replace(field.String(), "-", "", 3), " ", "", 3)
-
- if !iSBN10Regex.MatchString(s) {
- return false
- }
-
- var checksum int32
- var i int32
-
- for i = 0; i < 9; i++ {
- checksum += (i + 1) * int32(s[i]-'0')
- }
-
- if s[9] == 'X' {
- checksum += 10 * 10
- } else {
- checksum += 10 * int32(s[9]-'0')
- }
-
- return checksum%11 == 0
-}
-
-// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func ExcludesRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return !ContainsRune(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func ExcludesAll(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return !ContainsAny(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func Excludes(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return !Contains(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func ContainsRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- r, _ := utf8.DecodeRuneInString(param)
-
- return strings.ContainsRune(field.String(), r)
-}
-
-// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func ContainsAny(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return strings.ContainsAny(field.String(), param)
-}
-
-// Contains is the validation function for validating that the field's value contains the text specified within the param.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func Contains(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return strings.Contains(field.String(), param)
-}
-
-// IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsNeField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
-
- if !ok || currentKind != fieldKind {
- return true
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() != currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() != currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() != currentField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) != int64(currentField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return true
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return !fieldTime.Equal(t)
- }
-
- }
-
- // default reflect.String:
- return field.String() != currentField.String()
-}
-
-// IsNe is the validation function for validating that the field's value does not equal the provided param value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsNe(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return !IsEq(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || topKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() <= topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() <= topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() <= topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) <= int64(topField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() <= topField.String()
-}
-
-// IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || topKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() < topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() < topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() < topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) < int64(topField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() < topField.String()
-}
-
-// IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || topKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() >= topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() >= topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() >= topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) >= int64(topField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime) || fieldTime.Equal(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() >= topField.String()
-}
-
-// IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || topKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() > topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() > topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() > topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) > int64(topField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() > topField.String()
-}
-
-// IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, currentKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || currentKind != fieldKind {
- return true
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return topField.Int() != field.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return topField.Uint() != field.Uint()
-
- case reflect.Float32, reflect.Float64:
- return topField.Float() != field.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(topField.Len()) != int64(field.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return true
- }
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return !fieldTime.Equal(t)
- }
- }
-
- // default reflect.String:
- return topField.String() != field.String()
-}
-
-// IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
- if !ok || topKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return topField.Int() == field.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return topField.Uint() == field.Uint()
-
- case reflect.Float32, reflect.Float64:
- return topField.Float() == field.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(topField.Len()) == int64(field.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return fieldTime.Equal(t)
- }
- }
-
- // default reflect.String:
- return topField.String() == field.String()
-}
-
-// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsEqField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
- if !ok || currentKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() == currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() == currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() == currentField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) == int64(currentField.Len())
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Equal(t)
- }
-
- }
-
- // default reflect.String:
- return field.String() == currentField.String()
-}
-
-// IsEq is the validation function for validating if the current field's value is equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsEq(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- return field.String() == param
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) == p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() == p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() == p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() == p
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsBase64(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return base64Regex.MatchString(field.String())
-}
-
-// IsURI is the validation function for validating if the current field's value is a valid URI.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
-
- s := field.String()
-
- // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
- // emulate browser and strip the '#' suffix prior to validation. see issue-#237
- if i := strings.Index(s, "#"); i > -1 {
- s = s[:i]
- }
-
- if s == blank {
- return false
- }
-
- _, err := url.ParseRequestURI(s)
-
- return err == nil
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsURL is the validation function for validating if the current field's value is a valid URL.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsURL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
-
- var i int
- s := field.String()
-
- // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
- // emulate browser and strip the '#' suffix prior to validation. see issue-#237
- if i = strings.Index(s, "#"); i > -1 {
- s = s[:i]
- }
-
- if s == blank {
- return false
- }
-
- url, err := url.ParseRequestURI(s)
-
- if err != nil || url.Scheme == blank {
- return false
- }
-
- return err == nil
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsEmail is the validation function for validating if the current field's value is a valid email address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsEmail(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return emailRegex.MatchString(field.String())
-}
-
-// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsHSLA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return hslaRegex.MatchString(field.String())
-}
-
-// IsHSL is the validation function for validating if the current field's value is a valid HSL color.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsHSL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return hslRegex.MatchString(field.String())
-}
-
-// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsRGBA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return rgbaRegex.MatchString(field.String())
-}
-
-// IsRGB is the validation function for validating if the current field's value is a valid RGB color.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsRGB(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return rgbRegex.MatchString(field.String())
-}
-
-// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsHEXColor(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return hexcolorRegex.MatchString(field.String())
-}
-
-// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsHexadecimal(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return hexadecimalRegex.MatchString(field.String())
-}
-
-// IsNumber is the validation function for validating if the current field's value is a valid number.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsNumber(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return numberRegex.MatchString(field.String())
-}
-
-// IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsNumeric(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return numericRegex.MatchString(field.String())
-}
-
-// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsAlphanum(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return alphaNumericRegex.MatchString(field.String())
-}
-
-// IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsAlpha(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return alphaRegex.MatchString(field.String())
-}
-
-// HasValue is the validation function for validating if the current field's value is not the default static value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func HasValue(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
- case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
- return !field.IsNil()
- default:
- return field.IsValid() && field.Interface() != reflect.Zero(fieldType).Interface()
- }
-}
-
-// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
- if !ok || currentKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() >= currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() >= currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() >= currentField.Float()
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t) || fieldTime.Equal(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) >= len(currentField.String())
-}
-
-// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
- if !ok || currentKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() > currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() > currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() > currentField.Float()
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) > len(currentField.String())
-}
-
-// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) >= p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) >= p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() >= p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() >= p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() >= p
-
- case reflect.Struct:
-
- if fieldType == timeType || fieldType == timePtrType {
-
- now := time.Now().UTC()
- t := field.Interface().(time.Time)
-
- return t.After(now) || t.Equal(now)
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsGt is the validation function for validating if the current field's value is greater than the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsGt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) > p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) > p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() > p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() > p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() > p
- case reflect.Struct:
-
- if fieldType == timeType || fieldType == timePtrType {
-
- return field.Interface().(time.Time).After(time.Now().UTC())
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func HasLengthOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) == p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) == p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() == p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() == p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() == p
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func HasMinOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- return IsGte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
- if !ok || currentKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() <= currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() <= currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() <= currentField.Float()
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t) || fieldTime.Equal(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) <= len(currentField.String())
-}
-
-// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
- if !ok || currentKind != fieldKind {
- return false
- }
-
- switch fieldKind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() < currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() < currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() < currentField.Float()
-
- case reflect.Struct:
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) < len(currentField.String())
-}
-
-// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) <= p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) <= p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() <= p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() <= p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() <= p
-
- case reflect.Struct:
-
- if fieldType == timeType || fieldType == timePtrType {
-
- now := time.Now().UTC()
- t := field.Interface().(time.Time)
-
- return t.Before(now) || t.Equal(now)
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsLt is the validation function for validating if the current field's value is less than the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsLt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- switch fieldKind {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) < p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) < p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() < p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() < p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() < p
-
- case reflect.Struct:
-
- if fieldType == timeType || fieldType == timePtrType {
-
- return field.Interface().(time.Time).Before(time.Now().UTC())
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func HasMaxOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- return IsLte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
-}
-
-// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsTCP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp4", field.String())
- return err == nil
-}
-
-// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsTCP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp6", field.String())
- return err == nil
-}
-
-// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsTCPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
- !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp", field.String())
- return err == nil
-}
-
-// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUDP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp4", field.String())
- return err == nil
-}
-
-// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUDP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp6", field.String())
- return err == nil
-}
-
-// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUDPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
- !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp", field.String())
- return err == nil
-}
-
-// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !IsIPv4(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip4", field.String())
- return err == nil
-}
-
-// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !IsIPv6(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip6", field.String())
- return err == nil
-}
-
-// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsIPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
-
- if !IsIP(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip", field.String())
- return err == nil
-}
-
-// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func IsUnixAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- _, err := net.ResolveUnixAddr("unix", field.String())
- return err == nil
-}
-
-func isIP4Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- val := field.String()
-
- if idx := strings.LastIndex(val, ":"); idx != -1 {
- val = val[0:idx]
- }
-
- if !IsIPv4(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
- return false
- }
-
- return true
-}
-
-func isIP6Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
- val := field.String()
-
- if idx := strings.LastIndex(val, ":"); idx != -1 {
- if idx != 0 && val[idx-1:idx] == "]" {
- val = val[1 : idx-1]
- }
- }
-
- if !IsIPv6(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
- return false
- }
-
- return true
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v8/regexes.go b/vendor/gopkg.in/go-playground/validator.v8/regexes.go
deleted file mode 100644
index 83ae1982a..000000000
--- a/vendor/gopkg.in/go-playground/validator.v8/regexes.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package validator
-
-import "regexp"
-
-const (
- alphaRegexString = "^[a-zA-Z]+$"
- alphaNumericRegexString = "^[a-zA-Z0-9]+$"
- numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
- numberRegexString = "^[0-9]+$"
- hexadecimalRegexString = "^[0-9a-fA-F]+$"
- hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
- rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$"
- rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
- hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$"
- hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
- emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:\\(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22)))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
- base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
- iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
- iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
- uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
- uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
- aSCIIRegexString = "^[\x00-\x7F]*$"
- printableASCIIRegexString = "^[\x20-\x7E]*$"
- multibyteRegexString = "[^\x00-\x7F]"
- dataURIRegexString = "^data:.+\\/(.+);base64$"
- latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
- longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
- sSNRegexString = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
-)
-
-var (
- alphaRegex = regexp.MustCompile(alphaRegexString)
- alphaNumericRegex = regexp.MustCompile(alphaNumericRegexString)
- numericRegex = regexp.MustCompile(numericRegexString)
- numberRegex = regexp.MustCompile(numberRegexString)
- hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
- hexcolorRegex = regexp.MustCompile(hexcolorRegexString)
- rgbRegex = regexp.MustCompile(rgbRegexString)
- rgbaRegex = regexp.MustCompile(rgbaRegexString)
- hslRegex = regexp.MustCompile(hslRegexString)
- hslaRegex = regexp.MustCompile(hslaRegexString)
- emailRegex = regexp.MustCompile(emailRegexString)
- base64Regex = regexp.MustCompile(base64RegexString)
- iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
- iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
- uUID3Regex = regexp.MustCompile(uUID3RegexString)
- uUID4Regex = regexp.MustCompile(uUID4RegexString)
- uUID5Regex = regexp.MustCompile(uUID5RegexString)
- uUIDRegex = regexp.MustCompile(uUIDRegexString)
- aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
- printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
- multibyteRegex = regexp.MustCompile(multibyteRegexString)
- dataURIRegex = regexp.MustCompile(dataURIRegexString)
- latitudeRegex = regexp.MustCompile(latitudeRegexString)
- longitudeRegex = regexp.MustCompile(longitudeRegexString)
- sSNRegex = regexp.MustCompile(sSNRegexString)
-)
diff --git a/vendor/gopkg.in/go-playground/validator.v8/validator.go b/vendor/gopkg.in/go-playground/validator.v8/validator.go
deleted file mode 100644
index 2b1d7164d..000000000
--- a/vendor/gopkg.in/go-playground/validator.v8/validator.go
+++ /dev/null
@@ -1,782 +0,0 @@
-/**
- * Package validator
- *
- * MISC:
- * - anonymous structs - they don't have names so expect the Struct name within StructErrors to be blank
- *
- */
-
-package validator
-
-import (
- "bytes"
- "errors"
- "fmt"
- "reflect"
- "strings"
- "sync"
- "time"
-)
-
-const (
- utf8HexComma = "0x2C"
- utf8Pipe = "0x7C"
- tagSeparator = ","
- orSeparator = "|"
- tagKeySeparator = "="
- structOnlyTag = "structonly"
- noStructLevelTag = "nostructlevel"
- omitempty = "omitempty"
- skipValidationTag = "-"
- diveTag = "dive"
- existsTag = "exists"
- fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
- arrayIndexFieldName = "%s" + leftBracket + "%d" + rightBracket
- mapIndexFieldName = "%s" + leftBracket + "%v" + rightBracket
- invalidValidation = "Invalid validation tag on field %s"
- undefinedValidation = "Undefined validation function on field %s"
- validatorNotInitialized = "Validator instance not initialized"
- fieldNameRequired = "Field Name Required"
- tagRequired = "Tag Required"
-)
-
-var (
- timeType = reflect.TypeOf(time.Time{})
- timePtrType = reflect.TypeOf(&time.Time{})
- defaultCField = new(cField)
-)
-
-// StructLevel contains all of the information and helper methods
-// for reporting errors during struct level validation
-type StructLevel struct {
- TopStruct reflect.Value
- CurrentStruct reflect.Value
- errPrefix string
- nsPrefix string
- errs ValidationErrors
- v *Validate
-}
-
-// ReportValidationErrors accepts the key relative to the top level struct and validatin errors.
-// Example: had a triple nested struct User, ContactInfo, Country and ran errs := validate.Struct(country)
-// from within a User struct level validation would call this method like so:
-// ReportValidationErrors("ContactInfo.", errs)
-// NOTE: relativeKey can contain both the Field Relative and Custom name relative paths
-// i.e. ReportValidationErrors("ContactInfo.|cInfo", errs) where cInfo represents say the JSON name of
-// the relative path; this will be split into 2 variables in the next valiator version.
-func (sl *StructLevel) ReportValidationErrors(relativeKey string, errs ValidationErrors) {
- for _, e := range errs {
-
- idx := strings.Index(relativeKey, "|")
- var rel string
- var cRel string
-
- if idx != -1 {
- rel = relativeKey[:idx]
- cRel = relativeKey[idx+1:]
- } else {
- rel = relativeKey
- }
-
- key := sl.errPrefix + rel + e.Field
-
- e.FieldNamespace = key
- e.NameNamespace = sl.nsPrefix + cRel + e.Name
-
- sl.errs[key] = e
- }
-}
-
-// ReportError reports an error just by passing the field and tag information
-// NOTE: tag can be an existing validation tag or just something you make up
-// and precess on the flip side it's up to you.
-func (sl *StructLevel) ReportError(field reflect.Value, fieldName string, customName string, tag string) {
-
- field, kind := sl.v.ExtractType(field)
-
- if fieldName == blank {
- panic(fieldNameRequired)
- }
-
- if customName == blank {
- customName = fieldName
- }
-
- if tag == blank {
- panic(tagRequired)
- }
-
- ns := sl.errPrefix + fieldName
-
- switch kind {
- case reflect.Invalid:
- sl.errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: sl.nsPrefix + customName,
- Name: customName,
- Field: fieldName,
- Tag: tag,
- ActualTag: tag,
- Param: blank,
- Kind: kind,
- }
- default:
- sl.errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: sl.nsPrefix + customName,
- Name: customName,
- Field: fieldName,
- Tag: tag,
- ActualTag: tag,
- Param: blank,
- Value: field.Interface(),
- Kind: kind,
- Type: field.Type(),
- }
- }
-}
-
-// Validate contains the validator settings passed in using the Config struct
-type Validate struct {
- tagName string
- fieldNameTag string
- validationFuncs map[string]Func
- structLevelFuncs map[reflect.Type]StructLevelFunc
- customTypeFuncs map[reflect.Type]CustomTypeFunc
- aliasValidators map[string]string
- hasCustomFuncs bool
- hasAliasValidators bool
- hasStructLevelFuncs bool
- tagCache *tagCache
- structCache *structCache
- errsPool *sync.Pool
-}
-
-func (v *Validate) initCheck() {
- if v == nil {
- panic(validatorNotInitialized)
- }
-}
-
-// Config contains the options that a Validator instance will use.
-// It is passed to the New() function
-type Config struct {
- TagName string
- FieldNameTag string
-}
-
-// CustomTypeFunc allows for overriding or adding custom field type handler functions
-// field = field value of the type to return a value to be validated
-// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29
-type CustomTypeFunc func(field reflect.Value) interface{}
-
-// Func accepts all values needed for file and cross field validation
-// v = validator instance, needed but some built in functions for it's custom types
-// topStruct = top level struct when validating by struct otherwise nil
-// currentStruct = current level struct when validating by struct otherwise optional comparison value
-// field = field value for validation
-// param = parameter used in validation i.e. gt=0 param would be 0
-type Func func(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldtype reflect.Type, fieldKind reflect.Kind, param string) bool
-
-// StructLevelFunc accepts all values needed for struct level validation
-type StructLevelFunc func(v *Validate, structLevel *StructLevel)
-
-// ValidationErrors is a type of map[string]*FieldError
-// it exists to allow for multiple errors to be passed from this library
-// and yet still subscribe to the error interface
-type ValidationErrors map[string]*FieldError
-
-// Error is intended for use in development + debugging and not intended to be a production error message.
-// It allows ValidationErrors to subscribe to the Error interface.
-// All information to create an error message specific to your application is contained within
-// the FieldError found within the ValidationErrors map
-func (ve ValidationErrors) Error() string {
-
- buff := bytes.NewBufferString(blank)
-
- for key, err := range ve {
- buff.WriteString(fmt.Sprintf(fieldErrMsg, key, err.Field, err.Tag))
- buff.WriteString("\n")
- }
-
- return strings.TrimSpace(buff.String())
-}
-
-// FieldError contains a single field's validation error along
-// with other properties that may be needed for error message creation
-type FieldError struct {
- FieldNamespace string
- NameNamespace string
- Field string
- Name string
- Tag string
- ActualTag string
- Kind reflect.Kind
- Type reflect.Type
- Param string
- Value interface{}
-}
-
-// New creates a new Validate instance for use.
-func New(config *Config) *Validate {
-
- tc := new(tagCache)
- tc.m.Store(make(map[string]*cTag))
-
- sc := new(structCache)
- sc.m.Store(make(map[reflect.Type]*cStruct))
-
- v := &Validate{
- tagName: config.TagName,
- fieldNameTag: config.FieldNameTag,
- tagCache: tc,
- structCache: sc,
- errsPool: &sync.Pool{New: func() interface{} {
- return ValidationErrors{}
- }}}
-
- if len(v.aliasValidators) == 0 {
- // must copy alias validators for separate validations to be used in each validator instance
- v.aliasValidators = map[string]string{}
- for k, val := range bakedInAliasValidators {
- v.RegisterAliasValidation(k, val)
- }
- }
-
- if len(v.validationFuncs) == 0 {
- // must copy validators for separate validations to be used in each instance
- v.validationFuncs = map[string]Func{}
- for k, val := range bakedInValidators {
- v.RegisterValidation(k, val)
- }
- }
-
- return v
-}
-
-// RegisterStructValidation registers a StructLevelFunc against a number of types
-// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) {
- v.initCheck()
-
- if v.structLevelFuncs == nil {
- v.structLevelFuncs = map[reflect.Type]StructLevelFunc{}
- }
-
- for _, t := range types {
- v.structLevelFuncs[reflect.TypeOf(t)] = fn
- }
-
- v.hasStructLevelFuncs = true
-}
-
-// RegisterValidation adds a validation Func to a Validate's map of validators denoted by the key
-// NOTE: if the key already exists, the previous validation function will be replaced.
-// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterValidation(key string, fn Func) error {
- v.initCheck()
-
- if key == blank {
- return errors.New("Function Key cannot be empty")
- }
-
- if fn == nil {
- return errors.New("Function cannot be empty")
- }
-
- _, ok := restrictedTags[key]
-
- if ok || strings.ContainsAny(key, restrictedTagChars) {
- panic(fmt.Sprintf(restrictedTagErr, key))
- }
-
- v.validationFuncs[key] = fn
-
- return nil
-}
-
-// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
-// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
- v.initCheck()
-
- if v.customTypeFuncs == nil {
- v.customTypeFuncs = map[reflect.Type]CustomTypeFunc{}
- }
-
- for _, t := range types {
- v.customTypeFuncs[reflect.TypeOf(t)] = fn
- }
-
- v.hasCustomFuncs = true
-}
-
-// RegisterAliasValidation registers a mapping of a single validationstag that
-// defines a common or complex set of validation(s) to simplify adding validation
-// to structs. NOTE: when returning an error the tag returned in FieldError will be
-// the alias tag unless the dive tag is part of the alias; everything after the
-// dive tag is not reported as the alias tag. Also the ActualTag in the before case
-// will be the actual tag within the alias that failed.
-// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterAliasValidation(alias, tags string) {
- v.initCheck()
-
- _, ok := restrictedTags[alias]
-
- if ok || strings.ContainsAny(alias, restrictedTagChars) {
- panic(fmt.Sprintf(restrictedAliasErr, alias))
- }
-
- v.aliasValidators[alias] = tags
- v.hasAliasValidators = true
-}
-
-// Field validates a single field using tag style validation and returns nil or ValidationErrors as type error.
-// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
-// NOTE: it returns ValidationErrors instead of a single FieldError because this can also
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) Field(field interface{}, tag string) error {
- v.initCheck()
-
- if len(tag) == 0 || tag == skipValidationTag {
- return nil
- }
-
- errs := v.errsPool.Get().(ValidationErrors)
- fieldVal := reflect.ValueOf(field)
-
- ctag, ok := v.tagCache.Get(tag)
- if !ok {
- v.tagCache.lock.Lock()
- defer v.tagCache.lock.Unlock()
-
- // could have been multiple trying to access, but once first is done this ensures tag
- // isn't parsed again.
- ctag, ok = v.tagCache.Get(tag)
- if !ok {
- ctag, _ = v.parseFieldTagsRecursive(tag, blank, blank, false)
- v.tagCache.Set(tag, ctag)
- }
- }
-
- v.traverseField(fieldVal, fieldVal, fieldVal, blank, blank, errs, false, false, nil, nil, defaultCField, ctag)
-
- if len(errs) == 0 {
- v.errsPool.Put(errs)
- return nil
- }
-
- return errs
-}
-
-// FieldWithValue validates a single field, against another fields value using tag style validation and returns nil or ValidationErrors.
-// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
-// NOTE: it returns ValidationErrors instead of a single FieldError because this can also
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) error {
- v.initCheck()
-
- if len(tag) == 0 || tag == skipValidationTag {
- return nil
- }
-
- errs := v.errsPool.Get().(ValidationErrors)
- topVal := reflect.ValueOf(val)
-
- ctag, ok := v.tagCache.Get(tag)
- if !ok {
- v.tagCache.lock.Lock()
- defer v.tagCache.lock.Unlock()
-
- // could have been multiple trying to access, but once first is done this ensures tag
- // isn't parsed again.
- ctag, ok = v.tagCache.Get(tag)
- if !ok {
- ctag, _ = v.parseFieldTagsRecursive(tag, blank, blank, false)
- v.tagCache.Set(tag, ctag)
- }
- }
-
- v.traverseField(topVal, topVal, reflect.ValueOf(field), blank, blank, errs, false, false, nil, nil, defaultCField, ctag)
-
- if len(errs) == 0 {
- v.errsPool.Put(errs)
- return nil
- }
-
- return errs
-}
-
-// StructPartial validates the fields passed in only, ignoring all others.
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name and returns nil or ValidationErrors as error
-// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
-func (v *Validate) StructPartial(current interface{}, fields ...string) error {
- v.initCheck()
-
- sv, _ := v.ExtractType(reflect.ValueOf(current))
- name := sv.Type().Name()
- m := map[string]struct{}{}
-
- if fields != nil {
- for _, k := range fields {
-
- flds := strings.Split(k, namespaceSeparator)
- if len(flds) > 0 {
-
- key := name + namespaceSeparator
- for _, s := range flds {
-
- idx := strings.Index(s, leftBracket)
-
- if idx != -1 {
- for idx != -1 {
- key += s[:idx]
- m[key] = struct{}{}
-
- idx2 := strings.Index(s, rightBracket)
- idx2++
- key += s[idx:idx2]
- m[key] = struct{}{}
- s = s[idx2:]
- idx = strings.Index(s, leftBracket)
- }
- } else {
-
- key += s
- m[key] = struct{}{}
- }
-
- key += namespaceSeparator
- }
- }
- }
- }
-
- errs := v.errsPool.Get().(ValidationErrors)
-
- v.ensureValidStruct(sv, sv, sv, blank, blank, errs, true, len(m) != 0, false, m, false)
-
- if len(errs) == 0 {
- v.errsPool.Put(errs)
- return nil
- }
-
- return errs
-}
-
-// StructExcept validates all fields except the ones passed in.
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name and returns nil or ValidationErrors as error
-// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
-func (v *Validate) StructExcept(current interface{}, fields ...string) error {
- v.initCheck()
-
- sv, _ := v.ExtractType(reflect.ValueOf(current))
- name := sv.Type().Name()
- m := map[string]struct{}{}
-
- for _, key := range fields {
- m[name+namespaceSeparator+key] = struct{}{}
- }
-
- errs := v.errsPool.Get().(ValidationErrors)
-
- v.ensureValidStruct(sv, sv, sv, blank, blank, errs, true, len(m) != 0, true, m, false)
-
- if len(errs) == 0 {
- v.errsPool.Put(errs)
- return nil
- }
-
- return errs
-}
-
-// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
-// it returns nil or ValidationErrors as error.
-// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
-func (v *Validate) Struct(current interface{}) error {
- v.initCheck()
-
- errs := v.errsPool.Get().(ValidationErrors)
- sv := reflect.ValueOf(current)
-
- v.ensureValidStruct(sv, sv, sv, blank, blank, errs, true, false, false, nil, false)
-
- if len(errs) == 0 {
- v.errsPool.Put(errs)
- return nil
- }
-
- return errs
-}
-
-func (v *Validate) ensureValidStruct(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, useStructName bool, partial bool, exclude bool, includeExclude map[string]struct{}, isStructOnly bool) {
-
- if current.Kind() == reflect.Ptr && !current.IsNil() {
- current = current.Elem()
- }
-
- if current.Kind() != reflect.Struct && current.Kind() != reflect.Interface {
- panic("value passed for validation is not a struct")
- }
-
- v.tranverseStruct(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, useStructName, partial, exclude, includeExclude, nil, nil)
-}
-
-// tranverseStruct traverses a structs fields and then passes them to be validated by traverseField
-func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, useStructName bool, partial bool, exclude bool, includeExclude map[string]struct{}, cs *cStruct, ct *cTag) {
-
- var ok bool
- first := len(nsPrefix) == 0
- typ := current.Type()
-
- cs, ok = v.structCache.Get(typ)
- if !ok {
- cs = v.extractStructCache(current, typ.Name())
- }
-
- if useStructName {
- errPrefix += cs.Name + namespaceSeparator
-
- if len(v.fieldNameTag) != 0 {
- nsPrefix += cs.Name + namespaceSeparator
- }
- }
-
- // structonly tag present don't tranverseFields
- // but must still check and run below struct level validation
- // if present
- if first || ct == nil || ct.typeof != typeStructOnly {
-
- for _, f := range cs.fields {
-
- if partial {
-
- _, ok = includeExclude[errPrefix+f.Name]
-
- if (ok && exclude) || (!ok && !exclude) {
- continue
- }
- }
-
- v.traverseField(topStruct, currentStruct, current.Field(f.Idx), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, f, f.cTags)
- }
- }
-
- // check if any struct level validations, after all field validations already checked.
- if cs.fn != nil {
- cs.fn(v, &StructLevel{v: v, TopStruct: topStruct, CurrentStruct: current, errPrefix: errPrefix, nsPrefix: nsPrefix, errs: errs})
- }
-}
-
-// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
-func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, partial bool, exclude bool, includeExclude map[string]struct{}, cs *cStruct, cf *cField, ct *cTag) {
-
- current, kind, nullable := v.extractTypeInternal(current, false)
- var typ reflect.Type
-
- switch kind {
- case reflect.Ptr, reflect.Interface, reflect.Invalid:
-
- if ct == nil {
- return
- }
-
- if ct.typeof == typeOmitEmpty {
- return
- }
-
- if ct.hasTag {
-
- ns := errPrefix + cf.Name
-
- if kind == reflect.Invalid {
- errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: nsPrefix + cf.AltName,
- Name: cf.AltName,
- Field: cf.Name,
- Tag: ct.aliasTag,
- ActualTag: ct.tag,
- Param: ct.param,
- Kind: kind,
- }
- return
- }
-
- errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: nsPrefix + cf.AltName,
- Name: cf.AltName,
- Field: cf.Name,
- Tag: ct.aliasTag,
- ActualTag: ct.tag,
- Param: ct.param,
- Value: current.Interface(),
- Kind: kind,
- Type: current.Type(),
- }
-
- return
- }
-
- case reflect.Struct:
- typ = current.Type()
-
- if typ != timeType {
-
- if ct != nil {
- ct = ct.next
- }
-
- if ct != nil && ct.typeof == typeNoStructLevel {
- return
- }
-
- v.tranverseStruct(topStruct, current, current, errPrefix+cf.Name+namespaceSeparator, nsPrefix+cf.AltName+namespaceSeparator, errs, false, partial, exclude, includeExclude, cs, ct)
- return
- }
- }
-
- if !ct.hasTag {
- return
- }
-
- typ = current.Type()
-
-OUTER:
- for {
- if ct == nil {
- return
- }
-
- switch ct.typeof {
-
- case typeExists:
- ct = ct.next
- continue
-
- case typeOmitEmpty:
-
- if !nullable && !HasValue(v, topStruct, currentStruct, current, typ, kind, blank) {
- return
- }
-
- ct = ct.next
- continue
-
- case typeDive:
-
- ct = ct.next
-
- // traverse slice or map here
- // or panic ;)
- switch kind {
- case reflect.Slice, reflect.Array:
-
- for i := 0; i < current.Len(); i++ {
- v.traverseField(topStruct, currentStruct, current.Index(i), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, &cField{Name: fmt.Sprintf(arrayIndexFieldName, cf.Name, i), AltName: fmt.Sprintf(arrayIndexFieldName, cf.AltName, i)}, ct)
- }
-
- case reflect.Map:
- for _, key := range current.MapKeys() {
- v.traverseField(topStruct, currentStruct, current.MapIndex(key), errPrefix, nsPrefix, errs, partial, exclude, includeExclude, cs, &cField{Name: fmt.Sprintf(mapIndexFieldName, cf.Name, key.Interface()), AltName: fmt.Sprintf(mapIndexFieldName, cf.AltName, key.Interface())}, ct)
- }
-
- default:
- // throw error, if not a slice or map then should not have gotten here
- // bad dive tag
- panic("dive error! can't dive on a non slice or map")
- }
-
- return
-
- case typeOr:
-
- errTag := blank
-
- for {
-
- if ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) {
-
- // drain rest of the 'or' values, then continue or leave
- for {
-
- ct = ct.next
-
- if ct == nil {
- return
- }
-
- if ct.typeof != typeOr {
- continue OUTER
- }
- }
- }
-
- errTag += orSeparator + ct.tag
-
- if ct.next == nil {
- // if we get here, no valid 'or' value and no more tags
-
- ns := errPrefix + cf.Name
-
- if ct.hasAlias {
- errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: nsPrefix + cf.AltName,
- Name: cf.AltName,
- Field: cf.Name,
- Tag: ct.aliasTag,
- ActualTag: ct.actualAliasTag,
- Value: current.Interface(),
- Type: typ,
- Kind: kind,
- }
- } else {
- errs[errPrefix+cf.Name] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: nsPrefix + cf.AltName,
- Name: cf.AltName,
- Field: cf.Name,
- Tag: errTag[1:],
- ActualTag: errTag[1:],
- Value: current.Interface(),
- Type: typ,
- Kind: kind,
- }
- }
-
- return
- }
-
- ct = ct.next
- }
-
- default:
- if !ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) {
-
- ns := errPrefix + cf.Name
-
- errs[ns] = &FieldError{
- FieldNamespace: ns,
- NameNamespace: nsPrefix + cf.AltName,
- Name: cf.AltName,
- Field: cf.Name,
- Tag: ct.aliasTag,
- ActualTag: ct.tag,
- Value: current.Interface(),
- Param: ct.param,
- Type: typ,
- Kind: kind,
- }
-
- return
-
- }
-
- ct = ct.next
- }
- }
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index a836b0692..0b4b4806c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -251,13 +251,21 @@ github.com/envoyproxy/protoc-gen-validate/validate
github.com/fsnotify/fsnotify
# github.com/ghodss/yaml v1.0.0
github.com/ghodss/yaml
-# github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7
+# github.com/gin-contrib/sse v0.1.0
github.com/gin-contrib/sse
-# github.com/gin-gonic/gin v1.3.0
+# github.com/gin-gonic/gin v1.7.7
github.com/gin-gonic/gin
github.com/gin-gonic/gin/binding
-github.com/gin-gonic/gin/json
+github.com/gin-gonic/gin/internal/bytesconv
+github.com/gin-gonic/gin/internal/json
github.com/gin-gonic/gin/render
+# github.com/go-playground/locales v0.13.0
+github.com/go-playground/locales
+github.com/go-playground/locales/currency
+# github.com/go-playground/universal-translator v0.17.0
+github.com/go-playground/universal-translator
+# github.com/go-playground/validator/v10 v10.4.1
+github.com/go-playground/validator/v10
# github.com/go-sql-driver/mysql v1.4.1
github.com/go-sql-driver/mysql
# github.com/gogo/protobuf v1.3.1
@@ -321,6 +329,8 @@ github.com/jinzhu/gorm/dialects/mysql
github.com/jinzhu/inflection
# github.com/json-iterator/go v1.1.9
github.com/json-iterator/go
+# github.com/leodido/go-urn v1.2.0
+github.com/leodido/go-urn
# github.com/magiconair/properties v1.8.1
github.com/magiconair/properties
# github.com/mattn/go-isatty v0.0.12
@@ -395,7 +405,8 @@ go.uber.org/zap/internal/color
go.uber.org/zap/internal/exit
go.uber.org/zap/zapcore
go.uber.org/zap/zapgrpc
-# golang.org/x/crypto v0.0.0-20200414173820-0848c9571904
+# golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
+golang.org/x/crypto/sha3
golang.org/x/crypto/ssh/terminal
# golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
golang.org/x/net/context
@@ -415,6 +426,7 @@ golang.org/x/oauth2/internal
golang.org/x/oauth2/jws
golang.org/x/oauth2/jwt
# golang.org/x/sys v0.0.0-20200116001909-b77594299b42
+golang.org/x/sys/cpu
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/text v0.3.2
@@ -479,8 +491,6 @@ google.golang.org/grpc/serviceconfig
google.golang.org/grpc/stats
google.golang.org/grpc/status
google.golang.org/grpc/tap
-# gopkg.in/go-playground/validator.v8 v8.18.2
-gopkg.in/go-playground/validator.v8
# gopkg.in/inf.v0 v0.9.1
gopkg.in/inf.v0
# gopkg.in/yaml.v2 v2.2.8