Tjz
z2Bjk+Ub9TzT(Z$!`+w1f9a{SYn?h^$U$mDJKK^KOurlxGlhf8coXvjW^}bgt-rFjD
znHJ|Xo9Wew;}%JlW_Kjsthc+chb^XXpU3LOdy_KCS4OTntgUFd?YsGkV{8gPCrIUU
z7xZ1<|6Oe5g44&3J$ODp>G5YKW=00a#V!U;2J*mEAgjzGVIbBZvce&_^W7!+r|T*d
zavIkkZ(n>dQ`LY6q(GR3)qt6i@xOr}h$qOxWx&zImXe>Fn2DZTf#J-^uui3sYst!#
z{ImS~I{#0uS#WDz%!i-3yIxOGkACKhN$DyM2L{LbrkL@xJCpY3crHP)J~LHEx;nsZlX$z1Na++S~*x&F8L
zSHsIX`Pf;-7fz4f$yxWfRV}c$Te2$X#22gkrUlwjtNp9{IiD}~zjo}z)1J=iJoj~z
zPFk$n)~eK8B%5+0@w1g$N8H(l+-H4!LOMmyS_+%b`$^TD`}g=z?!9=Gts-l=GE2@y
HTP6bly#{pd
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..d2817641bafb022339926786ab85b545f40ac665
GIT binary patch
literal 1147
zcmXqLVktLhVvb+H%*4pVB*OPMYW498DSV5WgVNVW|Jr8oCgimNFB_*;n@8JsUPeZ4
zRtAH{c0+ChPB!LH7B*p~&|nycgNMo4(NM@h03^fC!x>zfmseSqn3HNKV890w6yxnyM_06xZQcZ?W@M4y!->Y40>Qzg1y0
z&gNQpqF{|c>D+ZZ(rFIKEL_n{%!~|-iyLnkG+s4m+z3nvvdS!tD-9Z#Eo|&v(%3b4
zVzNoZ_g%=<^$R1;>=M3fAjvH2AGv2jo&gWY$-*qG2F#3%{|y8|JV6#N1CA!Pl>FSp
z%sk}C2j(GQ()!XwH^ngbB~t_{rh@w&h5|n>_#Tt3odjy
zuPCdY_u)fF^#8=jc^^+Q{aqN5`$@Gm({I-q6VU_LtQOD6naL>j(`V|D&;QI6%^$Dc
z@$uH$=blqSKTV1FFaEpmVP=>@vvi*Y`l|mqO|ORNA0oIS8nOI
z?NiA8%5=ljL@D29-OKpueEYz|zv5rHb554&taa#n7142tpUKWU?R-O_r^0)6j>G3Y
aOB;Xxy<$H9NT-Uzt(mu6i*GEf3IzZ)c%0q<
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..d8c3710c85f9ff41ddfc709924c866350a727a4f
GIT binary patch
literal 1013
zcmXqLV*Y5*#B_53GZP~dlZa+?pWMd9xVH0Kw4Tf@Xyh=ks1AdSQHxGwPW?5!&W`3Tbn1KjLh?$4C*eEf+B(=CCJ~_3h#8ApW0&YDg
zqZoHZWt9UE>m}#s8pw(B8W|aw8XFoJ7#JIxMv3#90J%nHQ0^ddX%nLoaxgNoGB7tW
z@-rATF>*0AF)}hdZr#y6M}F(|x(>G^%gcAlKWcTb*S((Se#vIyuMojqJ6T@W9G$-N
zZ|C3aC}V-ru$PA$a>||`V5!;WvLO9;#Z4xLTYkS~Q%%)mH+DGbsA<2rr@8F$Psyk!
zC02_czBy5RY)XCG=Yl1DX=(>VSrdJ-C#|hK7^zn?b35awX)f$Ntvf$$
zcUg9sL1fPSDbXqWt6$VVZu~MYZrj`2y}fI?80UuXsujC8ao09pzReSEFH3&Hjk;!&j?yPw^7|NHlfMLseyY=TyHB}&&4U!T;kt&%Ic
z-@@f=`1w!pGyVU%zJI$PWGYXZ;?Bg($iTQb*dWkA7MKcT`B=nQL{>NicfPwM|8!l2
zLQdoQtUFt($qvv(cdI=i6tz3tUW`|a0C
z&5N-8^H(H$?psgMz!}=eS*uc^;s&
z=?+d?)Hkg%emvc~QLj+DwRvTMu)Tl4_m}{_7kTC1{xNsF-p9krsM-B)Ge_#Kiu#~{
zd67^5U(N6lVcaug+5}Tw2V+f_-BCNQyG;7WAZ_<^`6QjCrOhu7&ztq4tdo7t^%&>)
zTR0VF*I2Sr
HHQW{e5x{wf
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..dae619c097512f20d09d2054c63fc0f715d7be24
GIT binary patch
literal 998
zcmXqLVt!=M#B^!_GZP~dlZZk6mxvepr#-!NVoqOL*`yn*LOZ7#@Un4gwRyCC=VfH%
zW@RvFY&YaK;ACSCWnmL$3Jr#FICz+x9SwyH1VA$EJeHTH8JZfJT11KSnjmurkxQExm5_sxk(GhDiIJbd
zpox)-sfm%1VO{t`EzVyWX$3+}`kJnrGQY>^=jnZyz4d%;|IQeuB_Gcfo1a{_>B5Fg
zXYbI=4K*7QZdjc*51-)~EjRzyir2SPA5Z@zcTLeXV*g^*2f0P(7p>c
z?c<>#uh>H(ryKBq6bQ4h8Za|5{x=W=@dR183^XGxLzc8JJvw;mpWjp+5Pu
z!*lq#5Sb^i@`a>klJNjzx%iu)2*?h3yy-gEL(;p^g~mZo#n!wzh9Qua5C+wfRd
ztarh_l9E{Oro7&WNVTl@3-~vy&EDU;)-f|r-8<&mQ>C=;``&D2+5V0(pW(g3o1}Sj
z^gY793Mi&+ntK1`1tm%ENt=U{rb%k1PtbRHEhYTylqR?8HqOeuvA1fBY>pc~NUFTR
KZE!sDzAgX``fm0B
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..ce7f8d31d6802c7e68c188af8797c3a063894857
GIT binary patch
literal 1147
zcmXqLVktLhVvb+H%*4pVB%&$)xidhT`$ARBi)~L`p2_`@+!*`b5acj4ER7|Ts-W~
z`MCv&d6kBO2K*oqZXOPo%(Bel%=|nTUzhK>3dC_Z(le%bCn$9moio9jI@8{
zd;5%c{XT!(ig$;5K+$bpwI6ChVmse+UV1r`!RY5*U#A%ppFJxS>PX#w$sz7*X_R~A
zg!|$g&z66XI$)aW-TrxDio@fp!U^sS#+*GdHMB|H?BTf!^g~J_=D$Y-Ot{~xpTg~G+{k6
Zdr{DieczoQDL-a%Ib3(Tsv+bGCjf+Ap-TV&
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..04b0d73600b72f80a03943d41973b279db9e8b32
GIT binary patch
literal 1013
zcmXqLV*Y5*#B_53GZP~dlZb{E^N!s~snriRh?%)HJiGKl>CAisUN%mxHjlRNyo`+8
ztPBQ??S|Y2oNUaYENsF|p}{Z?2M?38qoI(207!`V#>K<#
zoS$2em{(~iXuuB=;pX9R$t=q(&dkp<6f+P32{H5V78@nTm!uY##3!c~l^9AHNWiV<
zWEA7BsH}1TV!h=2Tmw0AULzv|Q)5FT0|N^q(aL-(RkWjuO*nCZC(^b4{cp%V+e53*PfoZW)2DU5BJN^Jypf0+
z%dyqB7eAAEDfH_&Z*6C3aP8^9M)sYbgC^`~v;4F5#oepTLYl5+2bdY(i!-?My>4G)
z&8u+L`?_9LxQB1$HP?fpd*5i(-|SJJ!`sZHa8UZu(QeP3Dc(Yr8?G#iY20z>);Fh$
zMQ>DZHkC%KUBdEb&cYv;1sHCx@Vv~#%*epFIM^W2Ko*z^WcgUcSVVXxICA%7?w=9J
zwOIRjXviz}kjUu<@*rtt76}8f2J8wz2}@R(k?}tZs{u2RLJoFd>IDWnBZI}4y?mP{
zW+WALO{`uTY0T-O8uy=9`&z_;*e^$wYu3!Wz-Re-&a7vV%g_8h++q8CMf&zxTFdl~
zp5i+{-R9L&+mdUFEBoKr@u=5M->UQ>MNWJ7BRi)4^M4~B*uKhe`J%yAbG&-Thr?bk
zCap+`USuL4V}qf=6kBV_EFAN
zmIn*31Qb`P{oxd|=2o5l$|&AdTJ_-*k&5oDQvTTOiN8OjczyHyta?pWMd9xVH0Kw4Tf@Xyh=ks1AdSQHxGwPW?5!&W`3Tbn1KjLh?$4C*eEf+B(=CCJ~_3h#8ApW0&YDg
zqZoHZWt9UE>m}#s8pw(B8W|aw8XFoJ7#JIxMv3#90J%nHQ0^ddX%nLoaxgNoGB7tW
z@-rATF>*0AF)}hdZr#y6M}F(|x(>G^%gcAlKWcTb*S((Se#vIyuMojqJ6T@W9G$-N
zZ|C3aC}V-ru$PA$a>||`V5!;WvLO9;#Z4xLTYkS~Q%%)mH+DGbsA<2rr@8F$Psyk!
zC02_czBy5RY)XCG=Yl1DX=(>VSrdJ-C#|hK7^zn?b35awX)f$Ntvf$$
zcUg9sL1fPSDbXqWt6$VVZu~MYZrj`2y}fI?80UuXsujC8ao09pzReSEFH3&Hjk;!&j?yPw^7|NHlfMLseyY=TyHB}&&4U!T;kt&%Ic
z-@@f=`1w!pGyVU%zJI$PWGYXZ;?Bg($iTQb*dWkA7MKcT`B=nQL{>NicfPwM|8!l2
zLQdoQtUFt($qvv(cdI=i6tz3tUW`|a0C
z&5N-8^H(H$?psgMz!}=eS*uc^;s&
z=?+d?)Hkg%emvc~QLj+DwRvTMu)Tl4_m}{_7kTC1{xNsF-p9krsM-B)Ge_#Kiu#~{
zd67^5U(N6lVcaug+5}Tw2V+f_-BCNQyG;7WAZ_<^`6QjCrOhu7&ztq4tdo7t^%&>)
zTR0VF*I2Sr
HHQW{e5x{wf
literal 0
HcmV?d00001
diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..04b0d73600b72f80a03943d41973b279db9e8b32
GIT binary patch
literal 1013
zcmXqLV*Y5*#B_53GZP~dlZb{E^N!s~snriRh?%)HJiGKl>CAisUN%mxHjlRNyo`+8
ztPBQ??S|Y2oNUaYENsF|p}{Z?2M?38qoI(207!`V#>K<#
zoS$2em{(~iXuuB=;pX9R$t=q(&dkp<6f+P32{H5V78@nTm!uY##3!c~l^9AHNWiV<
zWEA7BsH}1TV!h=2Tmw0AULzv|Q)5FT0|N^q(aL-(RkWjuO*nCZC(^b4{cp%V+e53*PfoZW)2DU5BJN^Jypf0+
z%dyqB7eAAEDfH_&Z*6C3aP8^9M)sYbgC^`~v;4F5#oepTLYl5+2bdY(i!-?My>4G)
z&8u+L`?_9LxQB1$HP?fpd*5i(-|SJJ!`sZHa8UZu(QeP3Dc(Yr8?G#iY20z>);Fh$
zMQ>DZHkC%KUBdEb&cYv;1sHCx@Vv~#%*epFIM^W2Ko*z^WcgUcSVVXxICA%7?w=9J
zwOIRjXviz}kjUu<@*rtt76}8f2J8wz2}@R(k?}tZs{u2RLJoFd>IDWnBZI}4y?mP{
zW+WALO{`uTY0T-O8uy=9`&z_;*e^$wYu3!Wz-Re-&a7vV%g_8h++q8CMf&zxTFdl~
zp5i+{-R9L&+mdUFEBoKr@u=5M->UQ>MNWJ7BRi)4^M4~B*uKhe`J%yAbG&-Thr?bk
zCap+`USuL4V}qf=6kBV_EFAN
zmIn*31Qb`P{oxd|=2o5l$|&AdTJ_-*k&5oDQvTTOiN8OjczyHyta 0 {
+ cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream)
+ if cert.PrivateKey == nil {
+ return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
+ }
+ }
+
+ minVersion, maxVersion, err := getTLSMinMaxVersionsClient(tlsConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ // Create mTLS credentials for client.
+ config := &tls.Config{
+ VerifyPeerCertificate: certverifier.VerifyServerCertificateChain(serverHostname, verificationMode, s2AStream, serverAuthorizationPolicy),
+ ServerName: serverHostname,
+ InsecureSkipVerify: true, // NOLINT
+ ClientSessionCache: nil,
+ SessionTicketsDisabled: true,
+ MinVersion: minVersion,
+ MaxVersion: maxVersion,
+ NextProtos: []string{h2},
+ }
+ if len(tlsConfig.CertificateChain) > 0 {
+ config.Certificates = []tls.Certificate{cert}
+ }
+ return config, nil
+}
+
+// GetTLSConfigurationForServer returns a tls.Config instance for use by a server application.
+func GetTLSConfigurationForServer(s2AStream stream.S2AStream, tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (*tls.Config, error) {
+ return &tls.Config{
+ GetConfigForClient: ClientConfig(tokenManager, localIdentities, verificationMode, s2AStream),
+ }, nil
+}
+
+// ClientConfig builds a TLS config for a server to establish a secure
+// connection with a client, based on SNI communicated during ClientHello.
+// Ensures that server presents the correct certificate to establish a TLS
+// connection.
+func ClientConfig(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream) func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
+ return func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
+ tlsConfig, err := getServerConfigFromS2Av2(tokenManager, localIdentities, chi.ServerName, s2AStream)
+ if err != nil {
+ return nil, err
+ }
+
+ var cert tls.Certificate
+ for i, v := range tlsConfig.CertificateChain {
+ // Populate Certificates field.
+ block, _ := pem.Decode([]byte(v))
+ if block == nil {
+ return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty")
+ }
+ x509Cert, err := x509.ParseCertificate(block.Bytes)
+ if err != nil {
+ return nil, err
+ }
+ cert.Certificate = append(cert.Certificate, x509Cert.Raw)
+ if i == 0 {
+ cert.Leaf = x509Cert
+ }
+ }
+
+ cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream)
+ if cert.PrivateKey == nil {
+ return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
+ }
+
+ minVersion, maxVersion, err := getTLSMinMaxVersionsServer(tlsConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ clientAuth := getTLSClientAuthType(tlsConfig)
+
+ var cipherSuites []uint16
+ cipherSuites = getCipherSuites(tlsConfig.Ciphersuites)
+
+ // Create mTLS credentials for server.
+ return &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ VerifyPeerCertificate: certverifier.VerifyClientCertificateChain(verificationMode, s2AStream),
+ ClientAuth: clientAuth,
+ CipherSuites: cipherSuites,
+ SessionTicketsDisabled: true,
+ MinVersion: minVersion,
+ MaxVersion: maxVersion,
+ NextProtos: []string{h2},
+ }, nil
+ }
+}
+
+func getCipherSuites(tlsConfigCipherSuites []commonpb.Ciphersuite) []uint16 {
+ var tlsGoCipherSuites []uint16
+ for _, v := range tlsConfigCipherSuites {
+ s := getTLSCipherSuite(v)
+ if s != 0xffff {
+ tlsGoCipherSuites = append(tlsGoCipherSuites, s)
+ }
+ }
+ return tlsGoCipherSuites
+}
+
+func getTLSCipherSuite(tlsCipherSuite commonpb.Ciphersuite) uint16 {
+ switch tlsCipherSuite {
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ return tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ return tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ return tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ return tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ default:
+ return 0xffff
+ }
+}
+
+func getServerConfigFromS2Av2(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, sni string, s2AStream stream.S2AStream) (*s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration, error) {
+ authMechanisms := getAuthMechanisms(tokenManager, localIdentities)
+ var locID *commonpbv1.Identity
+ if localIdentities != nil {
+ locID = localIdentities[0]
+ }
+
+ if err := s2AStream.Send(&s2av2pb.SessionReq{
+ LocalIdentity: locID,
+ AuthenticationMechanisms: authMechanisms,
+ ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{
+ GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{
+ ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_SERVER,
+ Sni: sni,
+ },
+ },
+ }); err != nil {
+ return nil, err
+ }
+
+ resp, err := s2AStream.Recv()
+ if err != nil {
+ return nil, err
+ }
+
+ // TODO(rmehta19): Add unit test for this if statement.
+ if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+ return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+ }
+
+ return resp.GetGetTlsConfigurationResp().GetServerTlsConfiguration(), nil
+}
+
+func getTLSClientAuthType(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) tls.ClientAuthType {
+ var clientAuth tls.ClientAuthType
+ switch x := tlsConfig.RequestClientCertificate; x {
+ case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE:
+ clientAuth = tls.NoClientCert
+ case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ clientAuth = tls.RequestClientCert
+ case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+ // This case actually maps to tls.VerifyClientCertIfGiven. However this
+ // mapping triggers normal verification, followed by custom verification,
+ // specified in VerifyPeerCertificate. To bypass normal verification, and
+ // only do custom verification we set clientAuth to RequireAnyClientCert or
+ // RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
+ // discussion.
+ clientAuth = tls.RequireAnyClientCert
+ case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ clientAuth = tls.RequireAnyClientCert
+ case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+ // This case actually maps to tls.RequireAndVerifyClientCert. However this
+ // mapping triggers normal verification, followed by custom verification,
+ // specified in VerifyPeerCertificate. To bypass normal verification, and
+ // only do custom verification we set clientAuth to RequireAnyClientCert or
+ // RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
+ // discussion.
+ clientAuth = tls.RequireAnyClientCert
+ default:
+ clientAuth = tls.RequireAnyClientCert
+ }
+ return clientAuth
+}
+
+func getAuthMechanisms(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity) []*s2av2pb.AuthenticationMechanism {
+ if tokenManager == nil {
+ return nil
+ }
+ if len(localIdentities) == 0 {
+ token, err := tokenManager.DefaultToken()
+ if err != nil {
+ grpclog.Infof("Unable to get token for empty local identity: %v", err)
+ return nil
+ }
+ return []*s2av2pb.AuthenticationMechanism{
+ {
+ MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+ Token: token,
+ },
+ },
+ }
+ }
+ var authMechanisms []*s2av2pb.AuthenticationMechanism
+ for _, localIdentity := range localIdentities {
+ if localIdentity == nil {
+ token, err := tokenManager.DefaultToken()
+ if err != nil {
+ grpclog.Infof("Unable to get default token for local identity %v: %v", localIdentity, err)
+ continue
+ }
+ authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
+ Identity: localIdentity,
+ MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+ Token: token,
+ },
+ })
+ } else {
+ token, err := tokenManager.Token(localIdentity)
+ if err != nil {
+ grpclog.Infof("Unable to get token for local identity %v: %v", localIdentity, err)
+ continue
+ }
+ authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
+ Identity: localIdentity,
+ MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+ Token: token,
+ },
+ })
+ }
+ }
+ return authMechanisms
+}
+
+// TODO(rmehta19): refactor switch statements into a helper function.
+func getTLSMinMaxVersionsClient(tlsConfig *s2av2pb.GetTlsConfigurationResp_ClientTlsConfiguration) (uint16, uint16, error) {
+ // Map S2Av2 TLSVersion to consts defined in tls package.
+ var minVersion uint16
+ var maxVersion uint16
+ switch x := tlsConfig.MinTlsVersion; x {
+ case commonpb.TLSVersion_TLS_VERSION_1_0:
+ minVersion = tls.VersionTLS10
+ case commonpb.TLSVersion_TLS_VERSION_1_1:
+ minVersion = tls.VersionTLS11
+ case commonpb.TLSVersion_TLS_VERSION_1_2:
+ minVersion = tls.VersionTLS12
+ case commonpb.TLSVersion_TLS_VERSION_1_3:
+ minVersion = tls.VersionTLS13
+ default:
+ return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
+ }
+
+ switch x := tlsConfig.MaxTlsVersion; x {
+ case commonpb.TLSVersion_TLS_VERSION_1_0:
+ maxVersion = tls.VersionTLS10
+ case commonpb.TLSVersion_TLS_VERSION_1_1:
+ maxVersion = tls.VersionTLS11
+ case commonpb.TLSVersion_TLS_VERSION_1_2:
+ maxVersion = tls.VersionTLS12
+ case commonpb.TLSVersion_TLS_VERSION_1_3:
+ maxVersion = tls.VersionTLS13
+ default:
+ return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
+ }
+ if minVersion > maxVersion {
+ return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
+ }
+ return minVersion, maxVersion, nil
+}
+
+func getTLSMinMaxVersionsServer(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) (uint16, uint16, error) {
+ // Map S2Av2 TLSVersion to consts defined in tls package.
+ var minVersion uint16
+ var maxVersion uint16
+ switch x := tlsConfig.MinTlsVersion; x {
+ case commonpb.TLSVersion_TLS_VERSION_1_0:
+ minVersion = tls.VersionTLS10
+ case commonpb.TLSVersion_TLS_VERSION_1_1:
+ minVersion = tls.VersionTLS11
+ case commonpb.TLSVersion_TLS_VERSION_1_2:
+ minVersion = tls.VersionTLS12
+ case commonpb.TLSVersion_TLS_VERSION_1_3:
+ minVersion = tls.VersionTLS13
+ default:
+ return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
+ }
+
+ switch x := tlsConfig.MaxTlsVersion; x {
+ case commonpb.TLSVersion_TLS_VERSION_1_0:
+ maxVersion = tls.VersionTLS10
+ case commonpb.TLSVersion_TLS_VERSION_1_1:
+ maxVersion = tls.VersionTLS11
+ case commonpb.TLSVersion_TLS_VERSION_1_2:
+ maxVersion = tls.VersionTLS12
+ case commonpb.TLSVersion_TLS_VERSION_1_3:
+ maxVersion = tls.VersionTLS13
+ default:
+ return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
+ }
+ if minVersion > maxVersion {
+ return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
+ }
+ return minVersion, maxVersion, nil
+}
diff --git a/vendor/github.com/google/s2a-go/s2a.go b/vendor/github.com/google/s2a-go/s2a.go
new file mode 100644
index 00000000..1c1349de
--- /dev/null
+++ b/vendor/github.com/google/s2a-go/s2a.go
@@ -0,0 +1,412 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package s2a provides the S2A transport credentials used by a gRPC
+// application.
+package s2a
+
+import (
+ "context"
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/google/s2a-go/fallback"
+ "github.com/google/s2a-go/internal/handshaker"
+ "github.com/google/s2a-go/internal/handshaker/service"
+ "github.com/google/s2a-go/internal/tokenmanager"
+ "github.com/google/s2a-go/internal/v2"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/grpclog"
+
+ commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+ s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+const (
+ s2aSecurityProtocol = "tls"
+ // defaultTimeout specifies the default server handshake timeout.
+ defaultTimeout = 30.0 * time.Second
+)
+
+// s2aTransportCreds are the transport credentials required for establishing
+// a secure connection using the S2A. They implement the
+// credentials.TransportCredentials interface.
+type s2aTransportCreds struct {
+ info *credentials.ProtocolInfo
+ minTLSVersion commonpb.TLSVersion
+ maxTLSVersion commonpb.TLSVersion
+ // tlsCiphersuites contains the ciphersuites used in the S2A connection.
+ // Note that these are currently unconfigurable.
+ tlsCiphersuites []commonpb.Ciphersuite
+ // localIdentity should only be used by the client.
+ localIdentity *commonpb.Identity
+ // localIdentities should only be used by the server.
+ localIdentities []*commonpb.Identity
+ // targetIdentities should only be used by the client.
+ targetIdentities []*commonpb.Identity
+ isClient bool
+ s2aAddr string
+ ensureProcessSessionTickets *sync.WaitGroup
+}
+
+// NewClientCreds returns a client-side transport credentials object that uses
+// the S2A to establish a secure connection with a server.
+func NewClientCreds(opts *ClientOptions) (credentials.TransportCredentials, error) {
+ if opts == nil {
+ return nil, errors.New("nil client options")
+ }
+ var targetIdentities []*commonpb.Identity
+ for _, targetIdentity := range opts.TargetIdentities {
+ protoTargetIdentity, err := toProtoIdentity(targetIdentity)
+ if err != nil {
+ return nil, err
+ }
+ targetIdentities = append(targetIdentities, protoTargetIdentity)
+ }
+ localIdentity, err := toProtoIdentity(opts.LocalIdentity)
+ if err != nil {
+ return nil, err
+ }
+ if opts.EnableLegacyMode {
+ return &s2aTransportCreds{
+ info: &credentials.ProtocolInfo{
+ SecurityProtocol: s2aSecurityProtocol,
+ },
+ minTLSVersion: commonpb.TLSVersion_TLS1_3,
+ maxTLSVersion: commonpb.TLSVersion_TLS1_3,
+ tlsCiphersuites: []commonpb.Ciphersuite{
+ commonpb.Ciphersuite_AES_128_GCM_SHA256,
+ commonpb.Ciphersuite_AES_256_GCM_SHA384,
+ commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
+ },
+ localIdentity: localIdentity,
+ targetIdentities: targetIdentities,
+ isClient: true,
+ s2aAddr: opts.S2AAddress,
+ ensureProcessSessionTickets: opts.EnsureProcessSessionTickets,
+ }, nil
+ }
+ verificationMode := getVerificationMode(opts.VerificationMode)
+ var fallbackFunc fallback.ClientHandshake
+ if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackClientHandshakeFunc != nil {
+ fallbackFunc = opts.FallbackOpts.FallbackClientHandshakeFunc
+ }
+ return v2.NewClientCreds(opts.S2AAddress, localIdentity, verificationMode, fallbackFunc, opts.getS2AStream, opts.serverAuthorizationPolicy)
+}
+
+// NewServerCreds returns a server-side transport credentials object that uses
+// the S2A to establish a secure connection with a client.
+func NewServerCreds(opts *ServerOptions) (credentials.TransportCredentials, error) {
+ if opts == nil {
+ return nil, errors.New("nil server options")
+ }
+ var localIdentities []*commonpb.Identity
+ for _, localIdentity := range opts.LocalIdentities {
+ protoLocalIdentity, err := toProtoIdentity(localIdentity)
+ if err != nil {
+ return nil, err
+ }
+ localIdentities = append(localIdentities, protoLocalIdentity)
+ }
+ if opts.EnableLegacyMode {
+ return &s2aTransportCreds{
+ info: &credentials.ProtocolInfo{
+ SecurityProtocol: s2aSecurityProtocol,
+ },
+ minTLSVersion: commonpb.TLSVersion_TLS1_3,
+ maxTLSVersion: commonpb.TLSVersion_TLS1_3,
+ tlsCiphersuites: []commonpb.Ciphersuite{
+ commonpb.Ciphersuite_AES_128_GCM_SHA256,
+ commonpb.Ciphersuite_AES_256_GCM_SHA384,
+ commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
+ },
+ localIdentities: localIdentities,
+ isClient: false,
+ s2aAddr: opts.S2AAddress,
+ }, nil
+ }
+ verificationMode := getVerificationMode(opts.VerificationMode)
+ return v2.NewServerCreds(opts.S2AAddress, localIdentities, verificationMode, opts.getS2AStream)
+}
+
+// ClientHandshake initiates a client-side TLS handshake using the S2A.
+func (c *s2aTransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+ if !c.isClient {
+ return nil, nil, errors.New("client handshake called using server transport credentials")
+ }
+
+ // Connect to the S2A.
+ hsConn, err := service.Dial(c.s2aAddr)
+ if err != nil {
+ grpclog.Infof("Failed to connect to S2A: %v", err)
+ return nil, nil, err
+ }
+
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithCancel(ctx)
+ defer cancel()
+
+ opts := &handshaker.ClientHandshakerOptions{
+ MinTLSVersion: c.minTLSVersion,
+ MaxTLSVersion: c.maxTLSVersion,
+ TLSCiphersuites: c.tlsCiphersuites,
+ TargetIdentities: c.targetIdentities,
+ LocalIdentity: c.localIdentity,
+ TargetName: serverAuthority,
+ EnsureProcessSessionTickets: c.ensureProcessSessionTickets,
+ }
+ chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
+ if err != nil {
+ grpclog.Infof("Call to handshaker.NewClientHandshaker failed: %v", err)
+ return nil, nil, err
+ }
+ defer func() {
+ if err != nil {
+ if closeErr := chs.Close(); closeErr != nil {
+ grpclog.Infof("Close failed unexpectedly: %v", err)
+ err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
+ }
+ }
+ }()
+
+ secConn, authInfo, err := chs.ClientHandshake(context.Background())
+ if err != nil {
+ grpclog.Infof("Handshake failed: %v", err)
+ return nil, nil, err
+ }
+ return secConn, authInfo, nil
+}
+
+// ServerHandshake initiates a server-side TLS handshake using the S2A.
+func (c *s2aTransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+ if c.isClient {
+ return nil, nil, errors.New("server handshake called using client transport credentials")
+ }
+
+ // Connect to the S2A.
+ hsConn, err := service.Dial(c.s2aAddr)
+ if err != nil {
+ grpclog.Infof("Failed to connect to S2A: %v", err)
+ return nil, nil, err
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
+ defer cancel()
+
+ opts := &handshaker.ServerHandshakerOptions{
+ MinTLSVersion: c.minTLSVersion,
+ MaxTLSVersion: c.maxTLSVersion,
+ TLSCiphersuites: c.tlsCiphersuites,
+ LocalIdentities: c.localIdentities,
+ }
+ shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
+ if err != nil {
+ grpclog.Infof("Call to handshaker.NewServerHandshaker failed: %v", err)
+ return nil, nil, err
+ }
+ defer func() {
+ if err != nil {
+ if closeErr := shs.Close(); closeErr != nil {
+ grpclog.Infof("Close failed unexpectedly: %v", err)
+ err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
+ }
+ }
+ }()
+
+ secConn, authInfo, err := shs.ServerHandshake(context.Background())
+ if err != nil {
+ grpclog.Infof("Handshake failed: %v", err)
+ return nil, nil, err
+ }
+ return secConn, authInfo, nil
+}
+
+func (c *s2aTransportCreds) Info() credentials.ProtocolInfo {
+ return *c.info
+}
+
+func (c *s2aTransportCreds) Clone() credentials.TransportCredentials {
+ info := *c.info
+ var localIdentity *commonpb.Identity
+ if c.localIdentity != nil {
+ localIdentity = proto.Clone(c.localIdentity).(*commonpb.Identity)
+ }
+ var localIdentities []*commonpb.Identity
+ if c.localIdentities != nil {
+ localIdentities = make([]*commonpb.Identity, len(c.localIdentities))
+ for i, localIdentity := range c.localIdentities {
+ localIdentities[i] = proto.Clone(localIdentity).(*commonpb.Identity)
+ }
+ }
+ var targetIdentities []*commonpb.Identity
+ if c.targetIdentities != nil {
+ targetIdentities = make([]*commonpb.Identity, len(c.targetIdentities))
+ for i, targetIdentity := range c.targetIdentities {
+ targetIdentities[i] = proto.Clone(targetIdentity).(*commonpb.Identity)
+ }
+ }
+ return &s2aTransportCreds{
+ info: &info,
+ minTLSVersion: c.minTLSVersion,
+ maxTLSVersion: c.maxTLSVersion,
+ tlsCiphersuites: c.tlsCiphersuites,
+ localIdentity: localIdentity,
+ localIdentities: localIdentities,
+ targetIdentities: targetIdentities,
+ isClient: c.isClient,
+ s2aAddr: c.s2aAddr,
+ }
+}
+
+func (c *s2aTransportCreds) OverrideServerName(serverNameOverride string) error {
+ c.info.ServerName = serverNameOverride
+ return nil
+}
+
+// TLSClientConfigOptions specifies parameters for creating client TLS config.
+type TLSClientConfigOptions struct {
+ // ServerName is required by s2a as the expected name when verifying the hostname found in server's certificate.
+ // tlsConfig, _ := factory.Build(ctx, &s2a.TLSClientConfigOptions{
+ // ServerName: "example.com",
+ // })
+ ServerName string
+}
+
+// TLSClientConfigFactory defines the interface for a client TLS config factory.
+type TLSClientConfigFactory interface {
+ Build(ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error)
+}
+
+// NewTLSClientConfigFactory returns an instance of s2aTLSClientConfigFactory.
+func NewTLSClientConfigFactory(opts *ClientOptions) (TLSClientConfigFactory, error) {
+ if opts == nil {
+ return nil, fmt.Errorf("opts must be non-nil")
+ }
+ if opts.EnableLegacyMode {
+ return nil, fmt.Errorf("NewTLSClientConfigFactory only supports S2Av2")
+ }
+ tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+ if err != nil {
+ // The only possible error is: access token not set in the environment,
+ // which is okay in environments other than serverless.
+ grpclog.Infof("Access token manager not initialized: %v", err)
+ return &s2aTLSClientConfigFactory{
+ s2av2Address: opts.S2AAddress,
+ tokenManager: nil,
+ verificationMode: getVerificationMode(opts.VerificationMode),
+ serverAuthorizationPolicy: opts.serverAuthorizationPolicy,
+ }, nil
+ }
+ return &s2aTLSClientConfigFactory{
+ s2av2Address: opts.S2AAddress,
+ tokenManager: tokenManager,
+ verificationMode: getVerificationMode(opts.VerificationMode),
+ serverAuthorizationPolicy: opts.serverAuthorizationPolicy,
+ }, nil
+}
+
+type s2aTLSClientConfigFactory struct {
+ s2av2Address string
+ tokenManager tokenmanager.AccessTokenManager
+ verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode
+ serverAuthorizationPolicy []byte
+}
+
+func (f *s2aTLSClientConfigFactory) Build(
+ ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error) {
+ serverName := ""
+ if opts != nil && opts.ServerName != "" {
+ serverName = opts.ServerName
+ }
+ return v2.NewClientTLSConfig(ctx, f.s2av2Address, f.tokenManager, f.verificationMode, serverName, f.serverAuthorizationPolicy)
+}
+
+func getVerificationMode(verificationMode VerificationModeType) s2av2pb.ValidatePeerCertificateChainReq_VerificationMode {
+ switch verificationMode {
+ case ConnectToGoogle:
+ return s2av2pb.ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE
+ case Spiffe:
+ return s2av2pb.ValidatePeerCertificateChainReq_SPIFFE
+ default:
+ return s2av2pb.ValidatePeerCertificateChainReq_UNSPECIFIED
+ }
+}
+
+// NewS2ADialTLSContextFunc returns a dialer which establishes an MTLS connection using S2A.
+// Example use with http.RoundTripper:
+//
+// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
+// S2AAddress: s2aAddress, // required
+// })
+// transport := http.DefaultTransport
+// transport.DialTLSContext = dialTLSContext
+func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, network, addr string) (net.Conn, error) {
+
+ return func(ctx context.Context, network, addr string) (net.Conn, error) {
+
+ fallback := func(err error) (net.Conn, error) {
+ if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackDialer != nil &&
+ opts.FallbackOpts.FallbackDialer.Dialer != nil && opts.FallbackOpts.FallbackDialer.ServerAddr != "" {
+ fbDialer := opts.FallbackOpts.FallbackDialer
+ grpclog.Infof("fall back to dial: %s", fbDialer.ServerAddr)
+ fbConn, fbErr := fbDialer.Dialer.DialContext(ctx, network, fbDialer.ServerAddr)
+ if fbErr != nil {
+ return nil, fmt.Errorf("error fallback to %s: %v; S2A error: %w", fbDialer.ServerAddr, fbErr, err)
+ }
+ return fbConn, nil
+ }
+ return nil, err
+ }
+
+ factory, err := NewTLSClientConfigFactory(opts)
+ if err != nil {
+ grpclog.Infof("error creating S2A client config factory: %v", err)
+ return fallback(err)
+ }
+
+ serverName, _, err := net.SplitHostPort(addr)
+ if err != nil {
+ serverName = addr
+ }
+ timeoutCtx, cancel := context.WithTimeout(ctx, v2.GetS2ATimeout())
+ defer cancel()
+ s2aTLSConfig, err := factory.Build(timeoutCtx, &TLSClientConfigOptions{
+ ServerName: serverName,
+ })
+ if err != nil {
+ grpclog.Infof("error building S2A TLS config: %v", err)
+ return fallback(err)
+ }
+
+ s2aDialer := &tls.Dialer{
+ Config: s2aTLSConfig,
+ }
+ c, err := s2aDialer.DialContext(ctx, network, addr)
+ if err != nil {
+ grpclog.Infof("error dialing with S2A to %s: %v", addr, err)
+ return fallback(err)
+ }
+ grpclog.Infof("success dialing MTLS to %s with S2A", addr)
+ return c, nil
+ }
+}
diff --git a/vendor/github.com/google/s2a-go/s2a_options.go b/vendor/github.com/google/s2a-go/s2a_options.go
new file mode 100644
index 00000000..94feafb9
--- /dev/null
+++ b/vendor/github.com/google/s2a-go/s2a_options.go
@@ -0,0 +1,208 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package s2a
+
+import (
+ "context"
+ "crypto/tls"
+ "errors"
+ "sync"
+
+ "github.com/google/s2a-go/fallback"
+ "github.com/google/s2a-go/stream"
+
+ s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
+)
+
+// Identity is the interface for S2A identities.
+type Identity interface {
+ // Name returns the name of the identity.
+ Name() string
+}
+
+type spiffeID struct {
+ spiffeID string
+}
+
+func (s *spiffeID) Name() string { return s.spiffeID }
+
+// NewSpiffeID creates a SPIFFE ID from id.
+func NewSpiffeID(id string) Identity {
+ return &spiffeID{spiffeID: id}
+}
+
+type hostname struct {
+ hostname string
+}
+
+func (h *hostname) Name() string { return h.hostname }
+
+// NewHostname creates a hostname from name.
+func NewHostname(name string) Identity {
+ return &hostname{hostname: name}
+}
+
+type uid struct {
+ uid string
+}
+
+func (h *uid) Name() string { return h.uid }
+
+// NewUID creates a UID from name.
+func NewUID(name string) Identity {
+ return &uid{uid: name}
+}
+
+// VerificationModeType specifies the mode that S2A must use to verify the peer
+// certificate chain.
+type VerificationModeType int
+
+// Three types of verification modes.
+const (
+ Unspecified = iota
+ ConnectToGoogle
+ Spiffe
+)
+
+// ClientOptions contains the client-side options used to establish a secure
+// channel using the S2A handshaker service.
+type ClientOptions struct {
+ // TargetIdentities contains a list of allowed server identities. One of the
+ // target identities should match the peer identity in the handshake
+ // result; otherwise, the handshake fails.
+ TargetIdentities []Identity
+ // LocalIdentity is the local identity of the client application. If none is
+ // provided, then the S2A will choose the default identity, if one exists.
+ LocalIdentity Identity
+ // S2AAddress is the address of the S2A.
+ S2AAddress string
+ // EnsureProcessSessionTickets waits for all session tickets to be sent to
+ // S2A before a process completes.
+ //
+ // This functionality is crucial for processes that complete very soon after
+ // using S2A to establish a TLS connection, but it can be ignored for longer
+ // lived processes.
+ //
+ // Usage example:
+ // func main() {
+ // var ensureProcessSessionTickets sync.WaitGroup
+ // clientOpts := &s2a.ClientOptions{
+ // EnsureProcessSessionTickets: &ensureProcessSessionTickets,
+ // // Set other members.
+ // }
+ // creds, _ := s2a.NewClientCreds(clientOpts)
+ // conn, _ := grpc.Dial(serverAddr, grpc.WithTransportCredentials(creds))
+ // defer conn.Close()
+ //
+ // // Make RPC call.
+ //
+ // // The process terminates right after the RPC call ends.
+ // // ensureProcessSessionTickets can be used to ensure resumption
+ // // tickets are fully processed. If the process is long-lived, using
+ // // ensureProcessSessionTickets is not necessary.
+ // ensureProcessSessionTickets.Wait()
+ // }
+ EnsureProcessSessionTickets *sync.WaitGroup
+ // If true, enables the use of legacy S2Av1.
+ EnableLegacyMode bool
+ // VerificationMode specifies the mode that S2A must use to verify the
+ // peer certificate chain.
+ VerificationMode VerificationModeType
+
+ // Optional fallback after dialing with S2A fails.
+ FallbackOpts *FallbackOptions
+
+ // Generates an S2AStream interface for talking to the S2A server.
+ getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)
+
+ // Serialized user specified policy for server authorization.
+ serverAuthorizationPolicy []byte
+}
+
+// FallbackOptions prescribes the fallback logic that should be taken if the application fails to connect with S2A.
+type FallbackOptions struct {
+ // FallbackClientHandshakeFunc is used to specify fallback behavior when calling s2a.NewClientCreds().
+ // It will be called by ClientHandshake function, after handshake with S2A fails.
+ // s2a.NewClientCreds() ignores the other FallbackDialer field.
+ FallbackClientHandshakeFunc fallback.ClientHandshake
+
+ // FallbackDialer is used to specify fallback behavior when calling s2a.NewS2aDialTLSContextFunc().
+ // It passes in a custom fallback dialer and server address to use after dialing with S2A fails.
+ // s2a.NewS2aDialTLSContextFunc() ignores the other FallbackClientHandshakeFunc field.
+ FallbackDialer *FallbackDialer
+}
+
+// FallbackDialer contains a fallback tls.Dialer and a server address to connect to.
+type FallbackDialer struct {
+ // Dialer specifies a fallback tls.Dialer.
+ Dialer *tls.Dialer
+ // ServerAddr is used by Dialer to establish fallback connection.
+ ServerAddr string
+}
+
+// DefaultClientOptions returns the default client options.
+func DefaultClientOptions(s2aAddress string) *ClientOptions {
+ return &ClientOptions{
+ S2AAddress: s2aAddress,
+ VerificationMode: ConnectToGoogle,
+ }
+}
+
+// ServerOptions contains the server-side options used to establish a secure
+// channel using the S2A handshaker service.
+type ServerOptions struct {
+ // LocalIdentities is the list of local identities that may be assumed by
+ // the server. If no local identity is specified, then the S2A chooses a
+ // default local identity, if one exists.
+ LocalIdentities []Identity
+ // S2AAddress is the address of the S2A.
+ S2AAddress string
+ // If true, enables the use of legacy S2Av1.
+ EnableLegacyMode bool
+ // VerificationMode specifies the mode that S2A must use to verify the
+ // peer certificate chain.
+ VerificationMode VerificationModeType
+
+ // Generates an S2AStream interface for talking to the S2A server.
+ getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)
+}
+
+// DefaultServerOptions returns the default server options.
+func DefaultServerOptions(s2aAddress string) *ServerOptions {
+ return &ServerOptions{
+ S2AAddress: s2aAddress,
+ VerificationMode: ConnectToGoogle,
+ }
+}
+
+func toProtoIdentity(identity Identity) (*s2apb.Identity, error) {
+ if identity == nil {
+ return nil, nil
+ }
+ switch id := identity.(type) {
+ case *spiffeID:
+ return &s2apb.Identity{IdentityOneof: &s2apb.Identity_SpiffeId{SpiffeId: id.Name()}}, nil
+ case *hostname:
+ return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Hostname{Hostname: id.Name()}}, nil
+ case *uid:
+ return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Uid{Uid: id.Name()}}, nil
+ default:
+ return nil, errors.New("unrecognized identity type")
+ }
+}
diff --git a/vendor/github.com/google/s2a-go/s2a_utils.go b/vendor/github.com/google/s2a-go/s2a_utils.go
new file mode 100644
index 00000000..d649cc46
--- /dev/null
+++ b/vendor/github.com/google/s2a-go/s2a_utils.go
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package s2a
+
+import (
+ "context"
+ "errors"
+
+ commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/peer"
+)
+
+// AuthInfo exposes security information from the S2A to the application.
+type AuthInfo interface {
+ // AuthType returns the authentication type.
+ AuthType() string
+ // ApplicationProtocol returns the application protocol, e.g. "grpc".
+ ApplicationProtocol() string
+ // TLSVersion returns the TLS version negotiated during the handshake.
+ TLSVersion() commonpb.TLSVersion
+ // Ciphersuite returns the ciphersuite negotiated during the handshake.
+ Ciphersuite() commonpb.Ciphersuite
+ // PeerIdentity returns the authenticated identity of the peer.
+ PeerIdentity() *commonpb.Identity
+ // LocalIdentity returns the local identity of the application used during
+ // session setup.
+ LocalIdentity() *commonpb.Identity
+ // PeerCertFingerprint returns the SHA256 hash of the peer certificate used in
+ // the S2A handshake.
+ PeerCertFingerprint() []byte
+ // LocalCertFingerprint returns the SHA256 hash of the local certificate used
+ // in the S2A handshake.
+ LocalCertFingerprint() []byte
+ // IsHandshakeResumed returns true if a cached session was used to resume
+ // the handshake.
+ IsHandshakeResumed() bool
+ // SecurityLevel returns the security level of the connection.
+ SecurityLevel() credentials.SecurityLevel
+}
+
+// AuthInfoFromPeer extracts the authinfo.S2AAuthInfo object from the given
+// peer, if it exists. This API should be used by gRPC clients after
+// obtaining a peer object using the grpc.Peer() CallOption.
+func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
+ s2aAuthInfo, ok := p.AuthInfo.(AuthInfo)
+ if !ok {
+ return nil, errors.New("no S2AAuthInfo found in Peer")
+ }
+ return s2aAuthInfo, nil
+}
+
+// AuthInfoFromContext extracts the authinfo.S2AAuthInfo object from the given
+// context, if it exists. This API should be used by gRPC server RPC handlers
+// to get information about the peer. On the client-side, use the grpc.Peer()
+// CallOption and the AuthInfoFromPeer function.
+func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {
+ p, ok := peer.FromContext(ctx)
+ if !ok {
+ return nil, errors.New("no Peer found in Context")
+ }
+ return AuthInfoFromPeer(p)
+}
diff --git a/vendor/github.com/google/s2a-go/stream/s2a_stream.go b/vendor/github.com/google/s2a-go/stream/s2a_stream.go
new file mode 100644
index 00000000..584bf32b
--- /dev/null
+++ b/vendor/github.com/google/s2a-go/stream/s2a_stream.go
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package stream provides an interface for bidirectional streaming to the S2A server.
+package stream
+
+import (
+ s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+// S2AStream defines the operation for communicating with the S2A server over a bidirectional stream.
+type S2AStream interface {
+ // Send sends the message to the S2A server.
+ Send(*s2av2pb.SessionReq) error
+ // Recv receives the message from the S2A server.
+ Recv() (*s2av2pb.SessionResp, error)
+ // Closes the channel to the S2A server.
+ CloseSend() error
+}
diff --git a/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json b/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
index d88960b7..91d60a80 100644
--- a/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
+++ b/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- "v2": "2.7.0"
+ "v2": "2.11.0"
}
diff --git a/vendor/github.com/googleapis/gax-go/v2/CHANGES.md b/vendor/github.com/googleapis/gax-go/v2/CHANGES.md
index b75170f2..e17b196f 100644
--- a/vendor/github.com/googleapis/gax-go/v2/CHANGES.md
+++ b/vendor/github.com/googleapis/gax-go/v2/CHANGES.md
@@ -1,5 +1,57 @@
# Changelog
+## [2.11.0](https://github.com/googleapis/gax-go/compare/v2.10.0...v2.11.0) (2023-06-13)
+
+
+### Features
+
+* **v2:** add GoVersion package variable ([#283](https://github.com/googleapis/gax-go/issues/283)) ([26553cc](https://github.com/googleapis/gax-go/commit/26553ccadb4016b189881f52e6c253b68bb3e3d5))
+
+
+### Bug Fixes
+
+* **v2:** handle space in non-devel go version ([#288](https://github.com/googleapis/gax-go/issues/288)) ([fd7bca0](https://github.com/googleapis/gax-go/commit/fd7bca029a1c5e63def8f0a5fd1ec3f725d92f75))
+
+## [2.10.0](https://github.com/googleapis/gax-go/compare/v2.9.1...v2.10.0) (2023-05-30)
+
+
+### Features
+
+* update dependencies ([#280](https://github.com/googleapis/gax-go/issues/280)) ([4514281](https://github.com/googleapis/gax-go/commit/4514281058590f3637c36bfd49baa65c4d3cfb21))
+
+## [2.9.1](https://github.com/googleapis/gax-go/compare/v2.9.0...v2.9.1) (2023-05-23)
+
+
+### Bug Fixes
+
+* **v2:** drop cloud lro test dep ([#276](https://github.com/googleapis/gax-go/issues/276)) ([c67eeba](https://github.com/googleapis/gax-go/commit/c67eeba0f10a3294b1d93c1b8fbe40211a55ae5f)), refs [#270](https://github.com/googleapis/gax-go/issues/270)
+
+## [2.9.0](https://github.com/googleapis/gax-go/compare/v2.8.0...v2.9.0) (2023-05-22)
+
+
+### Features
+
+* **apierror:** add method to return HTTP status code conditionally ([#274](https://github.com/googleapis/gax-go/issues/274)) ([5874431](https://github.com/googleapis/gax-go/commit/587443169acd10f7f86d1989dc8aaf189e645e98)), refs [#229](https://github.com/googleapis/gax-go/issues/229)
+
+
+### Documentation
+
+* add ref to usage with clients ([#272](https://github.com/googleapis/gax-go/issues/272)) ([ea4d72d](https://github.com/googleapis/gax-go/commit/ea4d72d514beba4de450868b5fb028601a29164e)), refs [#228](https://github.com/googleapis/gax-go/issues/228)
+
+## [2.8.0](https://github.com/googleapis/gax-go/compare/v2.7.1...v2.8.0) (2023-03-15)
+
+
+### Features
+
+* **v2:** add WithTimeout option ([#259](https://github.com/googleapis/gax-go/issues/259)) ([9a8da43](https://github.com/googleapis/gax-go/commit/9a8da43693002448b1e8758023699387481866d1))
+
+## [2.7.1](https://github.com/googleapis/gax-go/compare/v2.7.0...v2.7.1) (2023-03-06)
+
+
+### Bug Fixes
+
+* **v2/apierror:** return Unknown GRPCStatus when err source is HTTP ([#260](https://github.com/googleapis/gax-go/issues/260)) ([043b734](https://github.com/googleapis/gax-go/commit/043b73437a240a91229207fb3ee52a9935a36f23)), refs [#254](https://github.com/googleapis/gax-go/issues/254)
+
## [2.7.0](https://github.com/googleapis/gax-go/compare/v2.6.0...v2.7.0) (2022-11-02)
diff --git a/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go b/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
index aa6be130..d785a065 100644
--- a/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
+++ b/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
@@ -29,6 +29,10 @@
// Package apierror implements a wrapper error for parsing error details from
// API calls. Both HTTP & gRPC status errors are supported.
+//
+// For examples of how to use [APIError] with client libraries please reference
+// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors)
+// in the client library documentation.
package apierror
import (
@@ -39,6 +43,7 @@ import (
jsonerror "github.com/googleapis/gax-go/v2/apierror/internal/proto"
"google.golang.org/api/googleapi"
"google.golang.org/genproto/googleapis/rpc/errdetails"
+ "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
@@ -197,12 +202,12 @@ func (a *APIError) Unwrap() error {
// Error returns a readable representation of the APIError.
func (a *APIError) Error() string {
var msg string
- if a.status != nil {
- msg = a.err.Error()
- } else if a.httpErr != nil {
+ if a.httpErr != nil {
// Truncate the googleapi.Error message because it dumps the Details in
// an ugly way.
msg = fmt.Sprintf("googleapi: Error %d: %s", a.httpErr.Code, a.httpErr.Message)
+ } else if a.status != nil {
+ msg = a.err.Error()
}
return strings.TrimSpace(fmt.Sprintf("%s\n%s", msg, a.details))
}
@@ -236,6 +241,9 @@ func (a *APIError) Metadata() map[string]string {
// setDetailsFromError parses a Status error or a googleapi.Error
// and sets status and details or httpErr and details, respectively.
// It returns false if neither Status nor googleapi.Error can be parsed.
+// When err is a googleapi.Error, the status of the returned error will
+// be set to an Unknown error, rather than nil, since a nil code is
+// interpreted as OK in the gRPC status package.
func (a *APIError) setDetailsFromError(err error) bool {
st, isStatus := status.FromError(err)
var herr *googleapi.Error
@@ -248,6 +256,7 @@ func (a *APIError) setDetailsFromError(err error) bool {
case isHTTPErr:
a.httpErr = herr
a.details = parseHTTPDetails(herr)
+ a.status = status.New(codes.Unknown, herr.Message)
default:
return false
}
@@ -340,3 +349,13 @@ func parseHTTPDetails(gae *googleapi.Error) ErrDetails {
return parseDetails(details)
}
+
+// HTTPCode returns the underlying HTTP response status code. This method returns
+// `-1` if the underlying error is a [google.golang.org/grpc/status.Status]. To
+// check gRPC error codes use [google.golang.org/grpc/status.Code].
+func (a *APIError) HTTPCode() int {
+ if a.httpErr == nil {
+ return -1
+ }
+ return a.httpErr.Code
+}
diff --git a/vendor/github.com/googleapis/gax-go/v2/call_option.go b/vendor/github.com/googleapis/gax-go/v2/call_option.go
index e0920055..c52e03f6 100644
--- a/vendor/github.com/googleapis/gax-go/v2/call_option.go
+++ b/vendor/github.com/googleapis/gax-go/v2/call_option.go
@@ -218,6 +218,14 @@ func (p pathOpt) Resolve(s *CallSettings) {
s.Path = p.p
}
+type timeoutOpt struct {
+ t time.Duration
+}
+
+func (t timeoutOpt) Resolve(s *CallSettings) {
+ s.timeout = t.t
+}
+
// WithPath applies a Path override to the HTTP-based APICall.
//
// This is for internal use only.
@@ -230,6 +238,15 @@ func WithGRPCOptions(opt ...grpc.CallOption) CallOption {
return grpcOpt(append([]grpc.CallOption(nil), opt...))
}
+// WithTimeout is a convenience option for setting a context.WithTimeout on the
+// singular context.Context used for **all** APICall attempts. Calculated from
+// the start of the first APICall attempt.
+// If the context.Context provided to Invoke already has a Deadline set, that
+// will always be respected over the deadline calculated using this option.
+func WithTimeout(t time.Duration) CallOption {
+ return &timeoutOpt{t: t}
+}
+
// CallSettings allow fine-grained control over how calls are made.
type CallSettings struct {
// Retry returns a Retryer to be used to control retry logic of a method call.
@@ -241,4 +258,8 @@ type CallSettings struct {
// Path is an HTTP override for an APICall.
Path string
+
+ // Timeout defines the amount of time that Invoke has to complete.
+ // Unexported so it cannot be changed by the code in an APICall.
+ timeout time.Duration
}
diff --git a/vendor/github.com/googleapis/gax-go/v2/header.go b/vendor/github.com/googleapis/gax-go/v2/header.go
index 139371a0..6488461f 100644
--- a/vendor/github.com/googleapis/gax-go/v2/header.go
+++ b/vendor/github.com/googleapis/gax-go/v2/header.go
@@ -29,7 +29,73 @@
package gax
-import "bytes"
+import (
+ "bytes"
+ "runtime"
+ "strings"
+ "unicode"
+)
+
+var (
+ // GoVersion is a header-safe representation of the current runtime
+ // environment's Go version. This is for GAX consumers that need to
+ // report the Go runtime version in API calls.
+ GoVersion string
+ // version is a package internal global variable for testing purposes.
+ version = runtime.Version
+)
+
+// versionUnknown is only used when the runtime version cannot be determined.
+const versionUnknown = "UNKNOWN"
+
+func init() {
+ GoVersion = goVersion()
+}
+
+// goVersion returns a Go runtime version derived from the runtime environment
+// that is modified to be suitable for reporting in a header, meaning it has no
+// whitespace. If it is unable to determine the Go runtime version, it returns
+// versionUnknown.
+func goVersion() string {
+ const develPrefix = "devel +"
+
+ s := version()
+ if strings.HasPrefix(s, develPrefix) {
+ s = s[len(develPrefix):]
+ if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+ s = s[:p]
+ }
+ return s
+ } else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+ s = s[:p]
+ }
+
+ notSemverRune := func(r rune) bool {
+ return !strings.ContainsRune("0123456789.", r)
+ }
+
+ if strings.HasPrefix(s, "go1") {
+ s = s[2:]
+ var prerelease string
+ if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
+ s, prerelease = s[:p], s[p:]
+ }
+ if strings.HasSuffix(s, ".") {
+ s += "0"
+ } else if strings.Count(s, ".") < 2 {
+ s += ".0"
+ }
+ if prerelease != "" {
+ // Some release candidates already have a dash in them.
+ if !strings.HasPrefix(prerelease, "-") {
+ prerelease = "-" + prerelease
+ }
+ s += prerelease
+ }
+ return s
+ }
+ return "UNKNOWN"
+}
// XGoogHeader is for use by the Google Cloud Libraries only.
//
diff --git a/vendor/github.com/googleapis/gax-go/v2/internal/version.go b/vendor/github.com/googleapis/gax-go/v2/internal/version.go
index 0ba5da1d..374dcdb1 100644
--- a/vendor/github.com/googleapis/gax-go/v2/internal/version.go
+++ b/vendor/github.com/googleapis/gax-go/v2/internal/version.go
@@ -30,4 +30,4 @@
package internal
// Version is the current tagged release of the library.
-const Version = "2.7.0"
+const Version = "2.11.0"
diff --git a/vendor/github.com/googleapis/gax-go/v2/invoke.go b/vendor/github.com/googleapis/gax-go/v2/invoke.go
index 9fcc2995..721d1af5 100644
--- a/vendor/github.com/googleapis/gax-go/v2/invoke.go
+++ b/vendor/github.com/googleapis/gax-go/v2/invoke.go
@@ -68,6 +68,16 @@ type sleeper func(ctx context.Context, d time.Duration) error
// invoke implements Invoke, taking an additional sleeper argument for testing.
func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error {
var retryer Retryer
+
+ // Only use the value provided via WithTimeout if the context doesn't
+ // already have a deadline. This is important for backwards compatibility if
+ // the user already set a deadline on the context given to Invoke.
+ if _, ok := ctx.Deadline(); !ok && settings.timeout != 0 {
+ c, cc := context.WithTimeout(ctx, settings.timeout)
+ defer cc()
+ ctx = c
+ }
+
for {
err := call(ctx, settings)
if err == nil {
diff --git a/vendor/github.com/gookit/color/README.md b/vendor/github.com/gookit/color/README.md
index 718b11b5..77d50ca3 100644
--- a/vendor/github.com/gookit/color/README.md
+++ b/vendor/github.com/gookit/color/README.md
@@ -570,6 +570,7 @@ Check out these projects, which use https://github.com/gookit/color :
- [xo/terminfo](https://github.com/xo/terminfo)
- [beego/bee](https://github.com/beego/bee)
- [issue9/term](https://github.com/issue9/term)
+ - [muesli/termenv](https://github.com/muesli/termenv)
- [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code)
- [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map)
- [Terminal Colors](https://gist.github.com/XVilka/8346728)
diff --git a/vendor/github.com/gookit/color/README.zh-CN.md b/vendor/github.com/gookit/color/README.zh-CN.md
index 1b144058..192a89c5 100644
--- a/vendor/github.com/gookit/color/README.zh-CN.md
+++ b/vendor/github.com/gookit/color/README.zh-CN.md
@@ -578,6 +578,7 @@ const (
## 参考项目
- [inhere/console](https://github.com/inhere/php-console)
+ - [muesli/termenv](https://github.com/muesli/termenv)
- [xo/terminfo](https://github.com/xo/terminfo)
- [beego/bee](https://github.com/beego/bee)
- [issue9/term](https://github.com/issue9/term)
diff --git a/vendor/github.com/gookit/color/any.go b/vendor/github.com/gookit/color/any.go
new file mode 100644
index 00000000..8bf31c18
--- /dev/null
+++ b/vendor/github.com/gookit/color/any.go
@@ -0,0 +1,6 @@
+//go:build !go1.18
+// +build !go1.18
+
+package color
+
+type any = interface{}
diff --git a/vendor/github.com/gookit/color/color.go b/vendor/github.com/gookit/color/color.go
index 59e0b0b6..22de1b04 100644
--- a/vendor/github.com/gookit/color/color.go
+++ b/vendor/github.com/gookit/color/color.go
@@ -183,7 +183,7 @@ func InnerErrs() []error {
// Usage:
//
// msg := RenderCode("3;32;45", "some", "message")
-func RenderCode(code string, args ...interface{}) string {
+func RenderCode(code string, args ...any) string {
var message string
if ln := len(args); ln == 0 {
return ""
@@ -205,7 +205,7 @@ func RenderCode(code string, args ...interface{}) string {
// RenderWithSpaces Render code with spaces.
// If the number of args is > 1, a space will be added between the args
-func RenderWithSpaces(code string, args ...interface{}) string {
+func RenderWithSpaces(code string, args ...any) string {
msg := formatArgsForPrintln(args)
if len(code) == 0 {
return msg
diff --git a/vendor/github.com/gookit/color/color_16.go b/vendor/github.com/gookit/color/color_16.go
index 3551521c..eda226a1 100644
--- a/vendor/github.com/gookit/color/color_16.go
+++ b/vendor/github.com/gookit/color/color_16.go
@@ -41,15 +41,27 @@ func (o Opts) String() string {
* Basic 16 color definition
*************************************************************/
-// Base value for foreground/background color
-// base: fg 30~37, bg 40~47
-// light: fg 90~97, bg 100~107
+const (
+ // OptMax max option value. range: 0 - 9
+ OptMax = 10
+ // DiffFgBg diff foreground and background color
+ DiffFgBg = 10
+)
+
+// Boundary value for foreground/background color 16
+//
+// - base: fg 30~37, bg 40~47
+// - light: fg 90~97, bg 100~107
const (
FgBase uint8 = 30
+ FgMax uint8 = 37
BgBase uint8 = 40
+ BgMax uint8 = 47
HiFgBase uint8 = 90
+ HiFgMax uint8 = 97
HiBgBase uint8 = 100
+ HiBgMax uint8 = 107
)
// Foreground colors. basic foreground colors 30 - 37
@@ -94,7 +106,7 @@ const (
BgDefault Color = 49
)
-// Extra background color 100 - 107(非标准)
+// Extra background color 100 - 107 (non-standard)
const (
BgDarkGray Color = iota + 100
BgLightRed
@@ -108,7 +120,7 @@ const (
BgGray Color = 100
)
-// Option settings
+// Option settings. range: 0 - 9
const (
OpReset Color = iota // 0 重置所有设置
OpBold // 1 加粗
@@ -188,61 +200,69 @@ func (c Color) Text(message string) string { return RenderString(c.String(), mes
// Render messages by color setting
//
// Usage:
-// green := color.FgGreen.Render
-// fmt.Println(green("message"))
-func (c Color) Render(a ...interface{}) string { return RenderCode(c.String(), a...) }
+//
+// green := color.FgGreen.Render
+// fmt.Println(green("message"))
+func (c Color) Render(a ...any) string { return RenderCode(c.String(), a...) }
// Renderln messages by color setting.
// like Println, will add spaces for each argument
//
// Usage:
-// green := color.FgGreen.Renderln
-// fmt.Println(green("message"))
-func (c Color) Renderln(a ...interface{}) string { return RenderWithSpaces(c.String(), a...) }
+//
+// green := color.FgGreen.Renderln
+// fmt.Println(green("message"))
+func (c Color) Renderln(a ...any) string { return RenderWithSpaces(c.String(), a...) }
// Sprint render messages by color setting. is alias of the Render()
-func (c Color) Sprint(a ...interface{}) string { return RenderCode(c.String(), a...) }
+func (c Color) Sprint(a ...any) string { return RenderCode(c.String(), a...) }
// Sprintf format and render message.
//
// Usage:
-// green := color.Green.Sprintf
-// colored := green("message")
-func (c Color) Sprintf(format string, args ...interface{}) string {
+//
+// green := color.Green.Sprintf
+// colored := green("message")
+func (c Color) Sprintf(format string, args ...any) string {
return RenderString(c.String(), fmt.Sprintf(format, args...))
}
// Print messages.
//
// Usage:
-// color.Green.Print("message")
+//
+// color.Green.Print("message")
+//
// OR:
-// green := color.FgGreen.Print
-// green("message")
-func (c Color) Print(args ...interface{}) {
+//
+// green := color.FgGreen.Print
+// green("message")
+func (c Color) Print(args ...any) {
doPrintV2(c.Code(), fmt.Sprint(args...))
}
// Printf format and print messages.
//
// Usage:
-// color.Cyan.Printf("string %s", "arg0")
-func (c Color) Printf(format string, a ...interface{}) {
+//
+// color.Cyan.Printf("string %s", "arg0")
+func (c Color) Printf(format string, a ...any) {
doPrintV2(c.Code(), fmt.Sprintf(format, a...))
}
// Println messages with new line
-func (c Color) Println(a ...interface{}) { doPrintlnV2(c.String(), a) }
+func (c Color) Println(a ...any) { doPrintlnV2(c.String(), a) }
// Light current color. eg: 36(FgCyan) -> 96(FgLightCyan).
//
// Usage:
-// lightCyan := Cyan.Light()
-// lightCyan.Print("message")
+//
+// lightCyan := Cyan.Light()
+// lightCyan.Print("message")
func (c Color) Light() Color {
- val := int(c)
+ val := uint8(c)
if val >= 30 && val <= 47 {
- return Color(uint8(c) + 60)
+ return Color(val + 60)
}
// don't change
@@ -252,12 +272,13 @@ func (c Color) Light() Color {
// Darken current color. eg. 96(FgLightCyan) -> 36(FgCyan)
//
// Usage:
-// cyan := LightCyan.Darken()
-// cyan.Print("message")
+//
+// cyan := LightCyan.Darken()
+// cyan.Print("message")
func (c Color) Darken() Color {
- val := int(c)
+ val := uint8(c)
if val >= 90 && val <= 107 {
- return Color(uint8(c) - 60)
+ return Color(val - 60)
}
// don't change
@@ -315,7 +336,7 @@ func (c Color) RGB() RGBColor {
return emptyRGBColor
}
- return HEX(Basic2hex(val))
+ return HEX(Basic2hex(val), c.IsBg())
}
// Code convert to code string. eg "35"
@@ -328,8 +349,23 @@ func (c Color) String() string {
return strconv.FormatInt(int64(c), 10)
}
+// IsBg check is background color
+func (c Color) IsBg() bool {
+ val := uint8(c)
+ return val >= BgBase && val <= BgMax || val >= HiBgBase && val <= HiBgMax
+}
+
+// IsFg check is foreground color
+func (c Color) IsFg() bool {
+ val := uint8(c)
+ return val >= FgBase && val <= FgMax || val >= HiFgBase && val <= HiFgMax
+}
+
+// IsOption check is option code: 0-9
+func (c Color) IsOption() bool { return uint8(c) < OptMax }
+
// IsValid color value
-func (c Color) IsValid() bool { return c < 107 }
+func (c Color) IsValid() bool { return uint8(c) < HiBgMax }
/*************************************************************
* basic color maps
@@ -461,9 +497,7 @@ func Fg2Bg(val uint8) uint8 {
}
// Basic2nameMap data
-func Basic2nameMap() map[uint8]string {
- return basic2nameMap
-}
+func Basic2nameMap() map[uint8]string { return basic2nameMap }
// func initName2basicMap() map[string]uint8 {
// n2b := make(map[string]uint8, len(basic2nameMap))
diff --git a/vendor/github.com/gookit/color/color_256.go b/vendor/github.com/gookit/color/color_256.go
index c95c0f7b..79ae5f8d 100644
--- a/vendor/github.com/gookit/color/color_256.go
+++ b/vendor/github.com/gookit/color/color_256.go
@@ -19,16 +19,19 @@ from wikipedia, 256 color:
// tpl for 8 bit 256 color(`2^8`)
//
// format:
-// ESC[ … 38;5; … m // 选择前景色
-// ESC[ … 48;5; … m // 选择背景色
+//
+// ESC[ … 38;5; … m // 选择前景色
+// ESC[ … 48;5; … m // 选择背景色
//
// example:
-// fg "\x1b[38;5;242m"
-// bg "\x1b[48;5;208m"
-// both "\x1b[38;5;242;48;5;208m"
+//
+// fg "\x1b[38;5;242m"
+// bg "\x1b[48;5;208m"
+// both "\x1b[38;5;242;48;5;208m"
//
// links:
-// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位
+//
+// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位
const (
TplFg256 = "38;5;%d"
TplBg256 = "48;5;%d"
@@ -40,19 +43,21 @@ const (
* 8bit(256) Color: Bit8Color Color256
*************************************************************/
-// Color256 256 color (8 bit), uint8 range at 0 - 255
+// Color256 256 color (8 bit), uint8 range at 0 - 255.
+// Support 256 color on windows CMD, PowerShell
//
// 颜色值使用10进制和16进制都可 0x98 = 152
//
// The color consists of two uint8:
-// 0: color value
-// 1: color type; Fg=0, Bg=1, >1: unset value
+//
+// 0: color value
+// 1: color type; Fg=0, Bg=1, >1: unset value
//
// example:
-// fg color: [152, 0]
-// bg color: [152, 1]
//
-// NOTICE: now support 256 color on windows CMD, PowerShell
+// fg color: [152, 0]
+// bg color: [152, 1]
+//
// lint warn - Name starts with package name
type Color256 [2]uint8
type Bit8Color = Color256 // alias
@@ -87,27 +92,27 @@ func (c Color256) Reset() error {
}
// Print print message
-func (c Color256) Print(a ...interface{}) {
+func (c Color256) Print(a ...any) {
doPrintV2(c.String(), fmt.Sprint(a...))
}
// Printf format and print message
-func (c Color256) Printf(format string, a ...interface{}) {
+func (c Color256) Printf(format string, a ...any) {
doPrintV2(c.String(), fmt.Sprintf(format, a...))
}
// Println print message with newline
-func (c Color256) Println(a ...interface{}) {
+func (c Color256) Println(a ...any) {
doPrintlnV2(c.String(), a)
}
// Sprint returns rendered message
-func (c Color256) Sprint(a ...interface{}) string {
+func (c Color256) Sprint(a ...any) string {
return RenderCode(c.String(), a...)
}
// Sprintf returns format and rendered message
-func (c Color256) Sprintf(format string, a ...interface{}) string {
+func (c Color256) Sprintf(format string, a ...any) string {
return RenderString(c.String(), fmt.Sprintf(format, a...))
}
@@ -159,9 +164,7 @@ func (c Color256) String() string {
}
// IsFg color
-func (c Color256) IsFg() bool {
- return c[1] == AsFg
-}
+func (c Color256) IsFg() bool { return c[1] == AsFg }
// ToFg 256 color
func (c Color256) ToFg() Color256 {
@@ -170,9 +173,7 @@ func (c Color256) ToFg() Color256 {
}
// IsBg color
-func (c Color256) IsBg() bool {
- return c[1] == AsBg
-}
+func (c Color256) IsBg() bool { return c[1] == AsBg }
// ToBg 256 color
func (c Color256) ToBg() Color256 {
@@ -181,9 +182,7 @@ func (c Color256) ToBg() Color256 {
}
// IsEmpty value
-func (c Color256) IsEmpty() bool {
- return c[1] > 1
-}
+func (c Color256) IsEmpty() bool { return c[1] > 1 }
/*************************************************************
* 8bit(256) Style
@@ -206,9 +205,10 @@ type Style256 struct {
// S256 create a color256 style
//
// Usage:
-// s := color.S256()
-// s := color.S256(132) // fg
-// s := color.S256(132, 203) // fg and bg
+//
+// s := color.S256()
+// s := color.S256(132) // fg
+// s := color.S256(132, 203) // fg and bg
func S256(fgAndBg ...uint8) *Style256 {
s := &Style256{}
vl := len(fgAndBg)
@@ -256,27 +256,27 @@ func (s *Style256) AddOpts(opts ...Color) *Style256 {
}
// Print message
-func (s *Style256) Print(a ...interface{}) {
+func (s *Style256) Print(a ...any) {
doPrintV2(s.String(), fmt.Sprint(a...))
}
// Printf format and print message
-func (s *Style256) Printf(format string, a ...interface{}) {
+func (s *Style256) Printf(format string, a ...any) {
doPrintV2(s.String(), fmt.Sprintf(format, a...))
}
// Println print message with newline
-func (s *Style256) Println(a ...interface{}) {
+func (s *Style256) Println(a ...any) {
doPrintlnV2(s.String(), a)
}
// Sprint returns rendered message
-func (s *Style256) Sprint(a ...interface{}) string {
+func (s *Style256) Sprint(a ...any) string {
return RenderCode(s.Code(), a...)
}
// Sprintf returns format and rendered message
-func (s *Style256) Sprintf(format string, a ...interface{}) string {
+func (s *Style256) Sprintf(format string, a ...any) string {
return RenderString(s.Code(), fmt.Sprintf(format, a...))
}
diff --git a/vendor/github.com/gookit/color/color_rgb.go b/vendor/github.com/gookit/color/color_rgb.go
index ff3c1bb0..bc129b71 100644
--- a/vendor/github.com/gookit/color/color_rgb.go
+++ b/vendor/github.com/gookit/color/color_rgb.go
@@ -8,20 +8,24 @@ import (
// 24 bit RGB color
// RGB:
-// R 0-255 G 0-255 B 0-255
-// R 00-FF G 00-FF B 00-FF (16进制)
+//
+// R 0-255 G 0-255 B 0-255
+// R 00-FF G 00-FF B 00-FF (16进制)
//
// Format:
-// ESC[ … 38;2;;; … m // Select RGB foreground color
-// ESC[ … 48;2;;; … m // Choose RGB background color
+//
+// ESC[ … 38;2;;; … m // Select RGB foreground color
+// ESC[ … 48;2;;; … m // Choose RGB background color
//
// links:
-// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#24位
+//
+// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#24位
//
// example:
-// fg: \x1b[38;2;30;144;255mMESSAGE\x1b[0m
-// bg: \x1b[48;2;30;144;255mMESSAGE\x1b[0m
-// both: \x1b[38;2;233;90;203;48;2;30;144;255mMESSAGE\x1b[0m
+//
+// fg: \x1b[38;2;30;144;255mMESSAGE\x1b[0m
+// bg: \x1b[48;2;30;144;255mMESSAGE\x1b[0m
+// both: \x1b[38;2;233;90;203;48;2;30;144;255mMESSAGE\x1b[0m
const (
TplFgRGB = "38;2;%d;%d;%d"
TplBgRGB = "48;2;%d;%d;%d"
@@ -40,17 +44,17 @@ const (
*************************************************************/
// RGBColor definition.
+// Support RGB color on Windows CMD, PowerShell
//
// The first to third digits represent the color value.
// The last digit represents the foreground(0), background(1), >1 is unset value
//
// Usage:
-// // 0, 1, 2 is R,G,B.
-// // 3rd: Fg=0, Bg=1, >1: unset value
-// RGBColor{30,144,255, 0}
-// RGBColor{30,144,255, 1}
//
-// NOTICE: now support RGB color on Windows CMD, PowerShell
+// // 0, 1, 2 is R,G,B.
+// // 3rd: Fg=0, Bg=1, >1: unset value
+// RGBColor{30,144,255, 0}
+// RGBColor{30,144,255, 1}
type RGBColor [4]uint8
// create an empty RGBColor
@@ -59,9 +63,10 @@ var emptyRGBColor = RGBColor{3: 99}
// RGB color create.
//
// Usage:
-// c := RGB(30,144,255)
-// c := RGB(30,144,255, true)
-// c.Print("message")
+//
+// c := RGB(30,144,255)
+// c := RGB(30,144,255, true)
+// c.Print("message")
func RGB(r, g, b uint8, isBg ...bool) RGBColor {
rgb := RGBColor{r, g, b}
if len(isBg) > 0 && isBg[0] {
@@ -90,11 +95,12 @@ func RgbFromInts(rgb []int, isBg ...bool) RGBColor {
// HEX create RGB color from a HEX color string.
//
// Usage:
-// c := HEX("ccc") // rgb: [204 204 204]
-// c := HEX("aabbcc") // rgb: [170 187 204]
-// c := HEX("#aabbcc")
-// c := HEX("0xaabbcc")
-// c.Print("message")
+//
+// c := HEX("ccc") // rgb: [204 204 204]
+// c := HEX("aabbcc") // rgb: [170 187 204]
+// c := HEX("#aabbcc")
+// c := HEX("0xaabbcc")
+// c.Print("message")
func HEX(hex string, isBg ...bool) RGBColor {
if rgb := HexToRgb(hex); len(rgb) > 0 {
return RGB(uint8(rgb[0]), uint8(rgb[1]), uint8(rgb[2]), isBg...)
@@ -139,11 +145,12 @@ func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor {
// Support use color name in the {namedRgbMap}
//
// Usage:
-// c := RGBFromString("170,187,204")
-// c.Print("message")
//
-// c := RGBFromString("brown")
-// c.Print("message with color brown")
+// c := RGBFromString("170,187,204")
+// c.Print("message")
+//
+// c := RGBFromString("brown")
+// c.Print("message with color brown")
func RGBFromString(rgb string, isBg ...bool) RGBColor {
// use color name in the {namedRgbMap}
if rgbVal, ok := namedRgbMap[rgb]; ok {
@@ -180,27 +187,27 @@ func (c RGBColor) Reset() error {
}
// Print print message
-func (c RGBColor) Print(a ...interface{}) {
+func (c RGBColor) Print(a ...any) {
doPrintV2(c.String(), fmt.Sprint(a...))
}
// Printf format and print message
-func (c RGBColor) Printf(format string, a ...interface{}) {
+func (c RGBColor) Printf(format string, a ...any) {
doPrintV2(c.String(), fmt.Sprintf(format, a...))
}
// Println print message with newline
-func (c RGBColor) Println(a ...interface{}) {
+func (c RGBColor) Println(a ...any) {
doPrintlnV2(c.String(), a)
}
// Sprint returns rendered message
-func (c RGBColor) Sprint(a ...interface{}) string {
+func (c RGBColor) Sprint(a ...any) string {
return RenderCode(c.String(), a...)
}
// Sprintf returns format and rendered message
-func (c RGBColor) Sprintf(format string, a ...interface{}) string {
+func (c RGBColor) Sprintf(format string, a ...any) string {
return RenderString(c.String(), fmt.Sprintf(format, a...))
}
@@ -243,6 +250,18 @@ func (c RGBColor) String() string {
return ""
}
+// ToBg convert to background color
+func (c RGBColor) ToBg() RGBColor {
+ c[3] = AsBg
+ return c
+}
+
+// ToFg convert to foreground color
+func (c RGBColor) ToFg() RGBColor {
+ c[3] = AsFg
+ return c
+}
+
// IsEmpty value
func (c RGBColor) IsEmpty() bool {
return c[3] > AsBg
@@ -279,8 +298,8 @@ func (c RGBColor) C16() Color { return c.Basic() }
// All are composed of 4 digits uint8, the first three digits are the color value;
// The last bit is different from RGBColor, here it indicates whether the value is set.
//
-// 1 Has been set
-// ^1 Not set
+// 1 Has been set
+// ^1 Not set
type RGBStyle struct {
// Name of the style
Name string
@@ -303,8 +322,9 @@ func NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle {
// HEXStyle create a RGBStyle from HEX color string.
//
// Usage:
-// s := HEXStyle("aabbcc", "eee")
-// s.Print("message")
+//
+// s := HEXStyle("aabbcc", "eee")
+// s.Print("message")
func HEXStyle(fg string, bg ...string) *RGBStyle {
s := &RGBStyle{}
if len(bg) > 0 {
@@ -320,8 +340,9 @@ func HEXStyle(fg string, bg ...string) *RGBStyle {
// RGBStyleFromString create a RGBStyle from color value string.
//
// Usage:
-// s := RGBStyleFromString("170,187,204", "70,87,4")
-// s.Print("message")
+//
+// s := RGBStyleFromString("170,187,204", "70,87,4")
+// s.Print("message")
func RGBStyleFromString(fg string, bg ...string) *RGBStyle {
s := &RGBStyle{}
if len(bg) > 0 {
@@ -363,27 +384,27 @@ func (s *RGBStyle) AddOpts(opts ...Color) *RGBStyle {
}
// Print print message
-func (s *RGBStyle) Print(a ...interface{}) {
+func (s *RGBStyle) Print(a ...any) {
doPrintV2(s.String(), fmt.Sprint(a...))
}
// Printf format and print message
-func (s *RGBStyle) Printf(format string, a ...interface{}) {
+func (s *RGBStyle) Printf(format string, a ...any) {
doPrintV2(s.String(), fmt.Sprintf(format, a...))
}
// Println print message with newline
-func (s *RGBStyle) Println(a ...interface{}) {
+func (s *RGBStyle) Println(a ...any) {
doPrintlnV2(s.String(), a)
}
// Sprint returns rendered message
-func (s *RGBStyle) Sprint(a ...interface{}) string {
+func (s *RGBStyle) Sprint(a ...any) string {
return RenderCode(s.String(), a...)
}
// Sprintf returns format and rendered message
-func (s *RGBStyle) Sprintf(format string, a ...interface{}) string {
+func (s *RGBStyle) Sprintf(format string, a ...any) string {
return RenderString(s.String(), fmt.Sprintf(format, a...))
}
diff --git a/vendor/github.com/gookit/color/color_tag.go b/vendor/github.com/gookit/color/color_tag.go
index 4f6fed93..1d2b9d3f 100644
--- a/vendor/github.com/gookit/color/color_tag.go
+++ b/vendor/github.com/gookit/color/color_tag.go
@@ -41,7 +41,8 @@ var (
// There are internal defined fg color tags
//
// Usage:
-// content text>
+//
+// content text>
//
// @notice 加 0 在前面是为了防止之前的影响到现在的设置
var colorTags = map[string]string{
@@ -324,15 +325,17 @@ func (tp *TagParser) ParseByEnv(str string) string {
return tp.Parse(str)
}
-// Parse parse given string, replace color tag and return rendered string
+// Parse given string, replace color tag and return rendered string
//
// Use built in tags:
-// CONTENT>
-// // e.g: `message>`
+//
+// CONTENT>
+// // e.g: `message>`
//
// Custom tag attributes:
-// `CONTENT>`
-// // e.g: `wel>`
+//
+// `CONTENT>`
+// // e.g: `wel>`
func (tp *TagParser) Parse(str string) string {
// not contains color tag
if !strings.Contains(str, ">") {
@@ -376,26 +379,30 @@ func ReplaceTag(str string) string {
// ParseCodeFromAttr parse color attributes.
//
// attr format:
-// // VALUE please see var: FgColors, BgColors, AllOptions
-// "fg=VALUE;bg=VALUE;op=VALUE"
+//
+// // VALUE please see var: FgColors, BgColors, AllOptions
+// "fg=VALUE;bg=VALUE;op=VALUE"
//
// 16 color:
-// "fg=yellow"
-// "bg=red"
-// "op=bold,underscore" // option is allow multi value
-// "fg=white;bg=blue;op=bold"
-// "fg=white;op=bold,underscore"
+//
+// "fg=yellow"
+// "bg=red"
+// "op=bold,underscore" // option is allow multi value
+// "fg=white;bg=blue;op=bold"
+// "fg=white;op=bold,underscore"
//
// 256 color:
+//
// "fg=167"
// "fg=167;bg=23"
// "fg=167;bg=23;op=bold"
//
// True color:
-// // hex
+//
+// // hex
// "fg=fc1cac"
// "fg=fc1cac;bg=c2c3c4"
-// // r,g,b
+// // r,g,b
// "fg=23,45,214"
// "fg=23,45,214;bg=109,99,88"
func ParseCodeFromAttr(attr string) (code string) {
@@ -476,12 +483,10 @@ func ClearTag(s string) string {
*************************************************************/
// GetTagCode get color code by tag name
-func GetTagCode(name string) string {
- return colorTags[name]
-}
+func GetTagCode(name string) string { return colorTags[name] }
// ApplyTag for messages
-func ApplyTag(tag string, a ...interface{}) string {
+func ApplyTag(tag string, a ...any) string {
return RenderCode(GetTagCode(tag), a...)
}
@@ -510,11 +515,12 @@ func IsDefinedTag(name string) bool {
// Tag value is a defined style name
// Usage:
-// Tag("info").Println("message")
+//
+// Tag("info").Println("message")
type Tag string
// Print messages
-func (tg Tag) Print(a ...interface{}) {
+func (tg Tag) Print(a ...any) {
name := string(tg)
str := fmt.Sprint(a...)
@@ -526,7 +532,7 @@ func (tg Tag) Print(a ...interface{}) {
}
// Printf format and print messages
-func (tg Tag) Printf(format string, a ...interface{}) {
+func (tg Tag) Printf(format string, a ...any) {
name := string(tg)
str := fmt.Sprintf(format, a...)
@@ -538,7 +544,7 @@ func (tg Tag) Printf(format string, a ...interface{}) {
}
// Println messages line
-func (tg Tag) Println(a ...interface{}) {
+func (tg Tag) Println(a ...any) {
name := string(tg)
if stl := GetStyle(name); !stl.IsEmpty() {
stl.Println(a...)
@@ -548,12 +554,12 @@ func (tg Tag) Println(a ...interface{}) {
}
// Sprint render messages
-func (tg Tag) Sprint(a ...interface{}) string {
+func (tg Tag) Sprint(a ...any) string {
return RenderCode(GetTagCode(string(tg)), a...)
}
// Sprintf format and render messages
-func (tg Tag) Sprintf(format string, a ...interface{}) string {
+func (tg Tag) Sprintf(format string, a ...any) string {
tag := string(tg)
str := fmt.Sprintf(format, a...)
diff --git a/vendor/github.com/gookit/color/convert.go b/vendor/github.com/gookit/color/convert.go
index 39aac7d2..c7103536 100644
--- a/vendor/github.com/gookit/color/convert.go
+++ b/vendor/github.com/gookit/color/convert.go
@@ -52,6 +52,7 @@ var (
// ---------- basic(16) <=> RGB color convert ----------
// refer from Hyper app
+ // Tip: only keep foreground color, background color need convert to foreground color for convert to RGB
basic2hexMap = map[uint8]string{
30: "000000", // black
31: "c51e14", // red
@@ -61,7 +62,7 @@ var (
35: "c839c5", // magenta
36: "20c5c6", // cyan
37: "c7c7c7", // white
- // - don't add bg color
+ // - don't add bg color, convert to fg color for convert to RGB
// 40: "000000", // black
// 41: "c51e14", // red
// 42: "1dc121", // green
@@ -428,10 +429,11 @@ func HexToRGB(hex string) []int { return HexToRgb(hex) }
// HexToRgb convert hex color string to RGB numbers
//
// Usage:
-// rgb := HexToRgb("ccc") // rgb: [204 204 204]
-// rgb := HexToRgb("aabbcc") // rgb: [170 187 204]
-// rgb := HexToRgb("#aabbcc") // rgb: [170 187 204]
-// rgb := HexToRgb("0xad99c0") // rgb: [170 187 204]
+//
+// rgb := HexToRgb("ccc") // rgb: [204 204 204]
+// rgb := HexToRgb("aabbcc") // rgb: [170 187 204]
+// rgb := HexToRgb("#aabbcc") // rgb: [170 187 204]
+// rgb := HexToRgb("0xad99c0") // rgb: [170 187 204]
func HexToRgb(hex string) (rgb []int) {
hex = strings.TrimSpace(hex)
if hex == "" {
@@ -474,6 +476,7 @@ func Rgb2hex(rgb []int) string { return RgbToHex(rgb) }
// RgbToHex convert RGB-code to hex-code
//
// Usage:
+//
// hex := RgbToHex([]int{170, 187, 204}) // hex: "aabbcc"
func RgbToHex(rgb []int) string {
hexNodes := make([]string, len(rgb))
@@ -488,10 +491,15 @@ func RgbToHex(rgb []int) string {
* 4bit(16) color <=> RGB/True color
*************************************************************/
+// BasicToHex convert basic color to hex string.
+func BasicToHex(val uint8) string {
+ val = Bg2Fg(val)
+ return basic2hexMap[val]
+}
+
// Basic2hex convert basic color to hex string.
func Basic2hex(val uint8) string {
- val = Fg2Bg(val)
- return basic2hexMap[val]
+ return BasicToHex(val)
}
// Hex2basic convert hex string to basic color code.
@@ -663,6 +671,7 @@ func C256ToRgbV1(val uint8) (rgb []uint8) {
// returns r, g, and b in the set [0, 255].
//
// Usage:
+//
// HslIntToRgb(0, 100, 50) // red
// HslIntToRgb(120, 100, 50) // lime
// HslIntToRgb(120, 100, 25) // dark green
@@ -677,6 +686,7 @@ func HslIntToRgb(h, s, l int) (rgb []uint8) {
// returns r, g, and b in the set [0, 255].
//
// Usage:
+//
// rgbVals := HslToRgb(0, 1, 0.5) // red
func HslToRgb(h, s, l float64) (rgb []uint8) {
var r, g, b float64
diff --git a/vendor/github.com/gookit/color/printer.go b/vendor/github.com/gookit/color/printer.go
index 326aabc0..985a0b62 100644
--- a/vendor/github.com/gookit/color/printer.go
+++ b/vendor/github.com/gookit/color/printer.go
@@ -9,18 +9,19 @@ import "fmt"
// PrinterFace interface
type PrinterFace interface {
fmt.Stringer
- Sprint(a ...interface{}) string
- Sprintf(format string, a ...interface{}) string
- Print(a ...interface{})
- Printf(format string, a ...interface{})
- Println(a ...interface{})
+ Sprint(a ...any) string
+ Sprintf(format string, a ...any) string
+ Print(a ...any)
+ Printf(format string, a ...any)
+ Println(a ...any)
}
// Printer a generic color message printer.
//
// Usage:
-// p := &Printer{Code: "32;45;3"}
-// p.Print("message")
+//
+// p := &Printer{Code: "32;45;3"}
+// p.Print("message")
type Printer struct {
// NoColor disable color.
NoColor bool
@@ -40,27 +41,27 @@ func (p *Printer) String() string {
}
// Sprint returns rendering colored messages
-func (p *Printer) Sprint(a ...interface{}) string {
+func (p *Printer) Sprint(a ...any) string {
return RenderCode(p.String(), a...)
}
// Sprintf returns format and rendering colored messages
-func (p *Printer) Sprintf(format string, a ...interface{}) string {
+func (p *Printer) Sprintf(format string, a ...any) string {
return RenderString(p.String(), fmt.Sprintf(format, a...))
}
// Print rendering colored messages
-func (p *Printer) Print(a ...interface{}) {
+func (p *Printer) Print(a ...any) {
doPrintV2(p.String(), fmt.Sprint(a...))
}
// Printf format and rendering colored messages
-func (p *Printer) Printf(format string, a ...interface{}) {
+func (p *Printer) Printf(format string, a ...any) {
doPrintV2(p.String(), fmt.Sprintf(format, a...))
}
// Println rendering colored messages with newline
-func (p *Printer) Println(a ...interface{}) {
+func (p *Printer) Println(a ...any) {
doPrintlnV2(p.Code, a)
}
@@ -77,46 +78,56 @@ func (p *Printer) IsEmpty() bool {
type SimplePrinter struct{}
// Print message
-func (s *SimplePrinter) Print(v ...interface{}) {
+func (s *SimplePrinter) Print(v ...any) {
Print(v...)
}
// Printf message
-func (s *SimplePrinter) Printf(format string, v ...interface{}) {
+func (s *SimplePrinter) Printf(format string, v ...any) {
Printf(format, v...)
}
// Println message
-func (s *SimplePrinter) Println(v ...interface{}) {
+func (s *SimplePrinter) Println(v ...any) {
Println(v...)
}
+// Successf message
+func (s *SimplePrinter) Successf(format string, a ...any) {
+ Success.Printf(format, a...)
+}
+
+// Successln message
+func (s *SimplePrinter) Successln(a ...any) {
+ Success.Println(a...)
+}
+
// Infof message
-func (s *SimplePrinter) Infof(format string, a ...interface{}) {
+func (s *SimplePrinter) Infof(format string, a ...any) {
Info.Printf(format, a...)
}
// Infoln message
-func (s *SimplePrinter) Infoln(a ...interface{}) {
+func (s *SimplePrinter) Infoln(a ...any) {
Info.Println(a...)
}
// Warnf message
-func (s *SimplePrinter) Warnf(format string, a ...interface{}) {
+func (s *SimplePrinter) Warnf(format string, a ...any) {
Warn.Printf(format, a...)
}
// Warnln message
-func (s *SimplePrinter) Warnln(a ...interface{}) {
+func (s *SimplePrinter) Warnln(a ...any) {
Warn.Println(a...)
}
// Errorf message
-func (s *SimplePrinter) Errorf(format string, a ...interface{}) {
+func (s *SimplePrinter) Errorf(format string, a ...any) {
Error.Printf(format, a...)
}
// Errorln message
-func (s *SimplePrinter) Errorln(a ...interface{}) {
+func (s *SimplePrinter) Errorln(a ...any) {
Error.Println(a...)
}
diff --git a/vendor/github.com/gookit/color/quickstart.go b/vendor/github.com/gookit/color/quickstart.go
index 4dbd1a43..b368b8a1 100644
--- a/vendor/github.com/gookit/color/quickstart.go
+++ b/vendor/github.com/gookit/color/quickstart.go
@@ -5,104 +5,104 @@ package color
*************************************************************/
// Redp print message with Red color
-func Redp(a ...interface{}) { Red.Print(a...) }
+func Redp(a ...any) { Red.Print(a...) }
// Redf print message with Red color
-func Redf(format string, a ...interface{}) { Red.Printf(format, a...) }
+func Redf(format string, a ...any) { Red.Printf(format, a...) }
// Redln print message line with Red color
-func Redln(a ...interface{}) { Red.Println(a...) }
+func Redln(a ...any) { Red.Println(a...) }
// Bluep print message with Blue color
-func Bluep(a ...interface{}) { Blue.Print(a...) }
+func Bluep(a ...any) { Blue.Print(a...) }
// Bluef print message with Blue color
-func Bluef(format string, a ...interface{}) { Blue.Printf(format, a...) }
+func Bluef(format string, a ...any) { Blue.Printf(format, a...) }
// Blueln print message line with Blue color
-func Blueln(a ...interface{}) { Blue.Println(a...) }
+func Blueln(a ...any) { Blue.Println(a...) }
// Cyanp print message with Cyan color
-func Cyanp(a ...interface{}) { Cyan.Print(a...) }
+func Cyanp(a ...any) { Cyan.Print(a...) }
// Cyanf print message with Cyan color
-func Cyanf(format string, a ...interface{}) { Cyan.Printf(format, a...) }
+func Cyanf(format string, a ...any) { Cyan.Printf(format, a...) }
// Cyanln print message line with Cyan color
-func Cyanln(a ...interface{}) { Cyan.Println(a...) }
+func Cyanln(a ...any) { Cyan.Println(a...) }
// Grayp print message with Gray color
-func Grayp(a ...interface{}) { Gray.Print(a...) }
+func Grayp(a ...any) { Gray.Print(a...) }
// Grayf print message with Gray color
-func Grayf(format string, a ...interface{}) { Gray.Printf(format, a...) }
+func Grayf(format string, a ...any) { Gray.Printf(format, a...) }
// Grayln print message line with Gray color
-func Grayln(a ...interface{}) { Gray.Println(a...) }
+func Grayln(a ...any) { Gray.Println(a...) }
// Greenp print message with Green color
-func Greenp(a ...interface{}) { Green.Print(a...) }
+func Greenp(a ...any) { Green.Print(a...) }
// Greenf print message with Green color
-func Greenf(format string, a ...interface{}) { Green.Printf(format, a...) }
+func Greenf(format string, a ...any) { Green.Printf(format, a...) }
// Greenln print message line with Green color
-func Greenln(a ...interface{}) { Green.Println(a...) }
+func Greenln(a ...any) { Green.Println(a...) }
// Yellowp print message with Yellow color
-func Yellowp(a ...interface{}) { Yellow.Print(a...) }
+func Yellowp(a ...any) { Yellow.Print(a...) }
// Yellowf print message with Yellow color
-func Yellowf(format string, a ...interface{}) { Yellow.Printf(format, a...) }
+func Yellowf(format string, a ...any) { Yellow.Printf(format, a...) }
// Yellowln print message line with Yellow color
-func Yellowln(a ...interface{}) { Yellow.Println(a...) }
+func Yellowln(a ...any) { Yellow.Println(a...) }
// Magentap print message with Magenta color
-func Magentap(a ...interface{}) { Magenta.Print(a...) }
+func Magentap(a ...any) { Magenta.Print(a...) }
// Magentaf print message with Magenta color
-func Magentaf(format string, a ...interface{}) { Magenta.Printf(format, a...) }
+func Magentaf(format string, a ...any) { Magenta.Printf(format, a...) }
// Magentaln print message line with Magenta color
-func Magentaln(a ...interface{}) { Magenta.Println(a...) }
+func Magentaln(a ...any) { Magenta.Println(a...) }
/*************************************************************
* quick use style print message
*************************************************************/
// Infop print message with Info color
-func Infop(a ...interface{}) { Info.Print(a...) }
+func Infop(a ...any) { Info.Print(a...) }
// Infof print message with Info style
-func Infof(format string, a ...interface{}) { Info.Printf(format, a...) }
+func Infof(format string, a ...any) { Info.Printf(format, a...) }
// Infoln print message with Info style
-func Infoln(a ...interface{}) { Info.Println(a...) }
+func Infoln(a ...any) { Info.Println(a...) }
// Successp print message with success color
-func Successp(a ...interface{}) { Success.Print(a...) }
+func Successp(a ...any) { Success.Print(a...) }
// Successf print message with success style
-func Successf(format string, a ...interface{}) { Success.Printf(format, a...) }
+func Successf(format string, a ...any) { Success.Printf(format, a...) }
// Successln print message with success style
-func Successln(a ...interface{}) { Success.Println(a...) }
+func Successln(a ...any) { Success.Println(a...) }
// Errorp print message with Error color
-func Errorp(a ...interface{}) { Error.Print(a...) }
+func Errorp(a ...any) { Error.Print(a...) }
// Errorf print message with Error style
-func Errorf(format string, a ...interface{}) { Error.Printf(format, a...) }
+func Errorf(format string, a ...any) { Error.Printf(format, a...) }
// Errorln print message with Error style
-func Errorln(a ...interface{}) { Error.Println(a...) }
+func Errorln(a ...any) { Error.Println(a...) }
// Warnp print message with Warn color
-func Warnp(a ...interface{}) { Warn.Print(a...) }
+func Warnp(a ...any) { Warn.Print(a...) }
// Warnf print message with Warn style
-func Warnf(format string, a ...interface{}) { Warn.Printf(format, a...) }
+func Warnf(format string, a ...any) { Warn.Printf(format, a...) }
// Warnln print message with Warn style
-func Warnln(a ...interface{}) { Warn.Println(a...) }
+func Warnln(a ...any) { Warn.Println(a...) }
diff --git a/vendor/github.com/gookit/color/style.go b/vendor/github.com/gookit/color/style.go
index fad76fb3..353d39f1 100644
--- a/vendor/github.com/gookit/color/style.go
+++ b/vendor/github.com/gookit/color/style.go
@@ -12,12 +12,14 @@ import (
// Style a 16 color style. can add: fg color, bg color, color options
//
// Example:
-// color.Style{color.FgGreen}.Print("message")
+//
+// color.Style{color.FgGreen}.Print("message")
type Style []Color
// New create a custom style
//
// Usage:
+//
// color.New(color.FgGreen).Print("message")
// equals to:
// color.Style{color.FgGreen}.Print("message")
@@ -35,45 +37,49 @@ func (s *Style) Add(cs ...Color) {
*s = append(*s, cs...)
}
-// Render render text
+// Render colored text
+//
// Usage:
-// color.New(color.FgGreen).Render("text")
-// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text")
-func (s Style) Render(a ...interface{}) string {
+//
+// color.New(color.FgGreen).Render("text")
+// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text")
+func (s Style) Render(a ...any) string {
return RenderCode(s.String(), a...)
}
-// Renderln render text line.
+// Renderln render text with newline.
// like Println, will add spaces for each argument
+//
// Usage:
-// color.New(color.FgGreen).Renderln("text", "more")
-// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text", "more")
-func (s Style) Renderln(a ...interface{}) string {
+//
+// color.New(color.FgGreen).Renderln("text", "more")
+// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text", "more")
+func (s Style) Renderln(a ...any) string {
return RenderWithSpaces(s.String(), a...)
}
// Sprint is alias of the 'Render'
-func (s Style) Sprint(a ...interface{}) string {
+func (s Style) Sprint(a ...any) string {
return RenderCode(s.String(), a...)
}
// Sprintf format and render message.
-func (s Style) Sprintf(format string, a ...interface{}) string {
+func (s Style) Sprintf(format string, a ...any) string {
return RenderString(s.String(), fmt.Sprintf(format, a...))
}
// Print render and Print text
-func (s Style) Print(a ...interface{}) {
+func (s Style) Print(a ...any) {
doPrintV2(s.String(), fmt.Sprint(a...))
}
// Printf render and print text
-func (s Style) Printf(format string, a ...interface{}) {
+func (s Style) Printf(format string, a ...any) {
doPrintV2(s.Code(), fmt.Sprintf(format, a...))
}
// Println render and print text line
-func (s Style) Println(a ...interface{}) {
+func (s Style) Println(a ...any) {
doPrintlnV2(s.String(), a)
}
@@ -115,20 +121,20 @@ func (t *Theme) Save() {
}
// Tips use name as title, only apply style for name
-func (t *Theme) Tips(format string, a ...interface{}) {
+func (t *Theme) Tips(format string, a ...any) {
// only apply style for name
t.Print(strings.ToUpper(t.Name) + ": ")
Printf(format+"\n", a...)
}
// Prompt use name as title, and apply style for message
-func (t *Theme) Prompt(format string, a ...interface{}) {
+func (t *Theme) Prompt(format string, a ...any) {
title := strings.ToUpper(t.Name) + ":"
t.Println(title, fmt.Sprintf(format, a...))
}
// Block like Prompt, but will wrap a empty line
-func (t *Theme) Block(format string, a ...interface{}) {
+func (t *Theme) Block(format string, a ...any) {
title := strings.ToUpper(t.Name) + ":\n"
t.Println(title, fmt.Sprintf(format, a...))
@@ -140,10 +146,11 @@ func (t *Theme) Block(format string, a ...interface{}) {
// internal themes(like bootstrap style)
// Usage:
-// color.Info.Print("message")
-// color.Info.Printf("a %s message", "test")
-// color.Warn.Println("message")
-// color.Error.Println("message")
+//
+// color.Info.Print("message")
+// color.Info.Printf("a %s message", "test")
+// color.Warn.Println("message")
+// color.Error.Println("message")
var (
// Info color style
Info = &Theme{"info", Style{OpReset, FgGreen}}
@@ -175,7 +182,8 @@ var (
// Themes internal defined themes.
// Usage:
-// color.Themes["info"].Println("message")
+//
+// color.Themes["info"].Println("message")
var Themes = map[string]*Theme{
"info": Info,
"note": Note,
@@ -211,7 +219,8 @@ func GetTheme(name string) *Theme {
// Styles internal defined styles, like bootstrap styles.
// Usage:
-// color.Styles["info"].Println("message")
+//
+// color.Styles["info"].Println("message")
var Styles = map[string]Style{
"info": {OpReset, FgGreen},
"note": {OpBold, FgLightCyan},
@@ -285,31 +294,31 @@ func (s *Scheme) Style(name string) Style {
}
// Infof message print
-func (s *Scheme) Infof(format string, a ...interface{}) {
+func (s *Scheme) Infof(format string, a ...any) {
s.Styles["info"].Printf(format, a...)
}
// Infoln message print
-func (s *Scheme) Infoln(v ...interface{}) {
+func (s *Scheme) Infoln(v ...any) {
s.Styles["info"].Println(v...)
}
// Warnf message print
-func (s *Scheme) Warnf(format string, a ...interface{}) {
+func (s *Scheme) Warnf(format string, a ...any) {
s.Styles["warn"].Printf(format, a...)
}
// Warnln message print
-func (s *Scheme) Warnln(v ...interface{}) {
+func (s *Scheme) Warnln(v ...any) {
s.Styles["warn"].Println(v...)
}
// Errorf message print
-func (s *Scheme) Errorf(format string, a ...interface{}) {
+func (s *Scheme) Errorf(format string, a ...any) {
s.Styles["error"].Printf(format, a...)
}
// Errorln message print
-func (s *Scheme) Errorln(v ...interface{}) {
+func (s *Scheme) Errorln(v ...any) {
s.Styles["error"].Println(v...)
}
diff --git a/vendor/github.com/gookit/color/utils.go b/vendor/github.com/gookit/color/utils.go
index 4554b27e..b6920f6d 100644
--- a/vendor/github.com/gookit/color/utils.go
+++ b/vendor/github.com/gookit/color/utils.go
@@ -32,39 +32,31 @@ func ResetTerminal() error {
*************************************************************/
// Print render color tag and print messages
-func Print(a ...interface{}) {
+func Print(a ...any) {
Fprint(output, a...)
}
// Printf format and print messages
-func Printf(format string, a ...interface{}) {
+func Printf(format string, a ...any) {
Fprintf(output, format, a...)
}
// Println messages with new line
-func Println(a ...interface{}) {
+func Println(a ...any) {
Fprintln(output, a...)
}
// Fprint print rendered messages to writer
//
// Notice: will ignore print error
-func Fprint(w io.Writer, a ...interface{}) {
+func Fprint(w io.Writer, a ...any) {
_, err := fmt.Fprint(w, Render(a...))
saveInternalError(err)
-
- // if isLikeInCmd {
- // renderColorCodeOnCmd(func() {
- // _, _ = fmt.Fprint(w, Render(a...))
- // })
- // } else {
- // _, _ = fmt.Fprint(w, Render(a...))
- // }
}
// Fprintf print format and rendered messages to writer.
// Notice: will ignore print error
-func Fprintf(w io.Writer, format string, a ...interface{}) {
+func Fprintf(w io.Writer, format string, a ...any) {
str := fmt.Sprintf(format, a...)
_, err := fmt.Fprint(w, ReplaceTag(str))
saveInternalError(err)
@@ -72,7 +64,7 @@ func Fprintf(w io.Writer, format string, a ...interface{}) {
// Fprintln print rendered messages line to writer
// Notice: will ignore print error
-func Fprintln(w io.Writer, a ...interface{}) {
+func Fprintln(w io.Writer, a ...any) {
str := formatArgsForPrintln(a)
_, err := fmt.Fprintln(w, ReplaceTag(str))
saveInternalError(err)
@@ -80,7 +72,7 @@ func Fprintln(w io.Writer, a ...interface{}) {
// Lprint passes colored messages to a log.Logger for printing.
// Notice: should be goroutine safe
-func Lprint(l *log.Logger, a ...interface{}) {
+func Lprint(l *log.Logger, a ...any) {
l.Print(Render(a...))
}
@@ -90,7 +82,7 @@ func Lprint(l *log.Logger, a ...interface{}) {
//
// text := Render("hello> world>!")
// fmt.Println(text)
-func Render(a ...interface{}) string {
+func Render(a ...any) string {
if len(a) == 0 {
return ""
}
@@ -98,28 +90,23 @@ func Render(a ...interface{}) string {
}
// Sprint parse color tags, return rendered string
-func Sprint(a ...interface{}) string {
+func Sprint(a ...any) string {
if len(a) == 0 {
return ""
}
-
return ReplaceTag(fmt.Sprint(a...))
}
// Sprintf format and return rendered string
-func Sprintf(format string, a ...interface{}) string {
+func Sprintf(format string, a ...any) string {
return ReplaceTag(fmt.Sprintf(format, a...))
}
// String alias of the ReplaceTag
-func String(s string) string {
- return ReplaceTag(s)
-}
+func String(s string) string { return ReplaceTag(s) }
// Text alias of the ReplaceTag
-func Text(s string) string {
- return ReplaceTag(s)
-}
+func Text(s string) string { return ReplaceTag(s) }
// Uint8sToInts convert []uint8 to []int
// func Uint8sToInts(u8s []uint8 ) []int {
@@ -138,25 +125,17 @@ func Text(s string) string {
func doPrintV2(code, str string) {
_, err := fmt.Fprint(output, RenderString(code, str))
saveInternalError(err)
-
- // if isLikeInCmd {
- // renderColorCodeOnCmd(func() {
- // _, _ = fmt.Fprint(output, RenderString(code, str))
- // })
- // } else {
- // _, _ = fmt.Fprint(output, RenderString(code, str))
- // }
}
// new implementation, support render full color code on pwsh.exe, cmd.exe
-func doPrintlnV2(code string, args []interface{}) {
+func doPrintlnV2(code string, args []any) {
str := formatArgsForPrintln(args)
_, err := fmt.Fprintln(output, RenderString(code, str))
saveInternalError(err)
}
// use Println, will add spaces for each arg
-func formatArgsForPrintln(args []interface{}) (message string) {
+func formatArgsForPrintln(args []any) (message string) {
if ln := len(args); ln == 0 {
message = ""
} else if ln == 1 {
@@ -178,7 +157,7 @@ func formatArgsForPrintln(args []interface{}) (message string) {
// return debugMode == "on"
// }
-func debugf(f string, v ...interface{}) {
+func debugf(f string, v ...any) {
if debugMode {
fmt.Print("COLOR_DEBUG: ")
fmt.Printf(f, v...)
diff --git a/vendor/github.com/itchyny/gojq/CHANGELOG.md b/vendor/github.com/itchyny/gojq/CHANGELOG.md
index cee2ce33..65e605fb 100644
--- a/vendor/github.com/itchyny/gojq/CHANGELOG.md
+++ b/vendor/github.com/itchyny/gojq/CHANGELOG.md
@@ -1,4 +1,51 @@
# Changelog
+## [v0.12.12](https://github.com/itchyny/gojq/compare/v0.12.11..v0.12.12) (2023-03-01)
+* fix assignment operator (`=`) with overlapping paths and multiple values (`[[]] | .. = ..`)
+* fix crash on multiplying large numbers to an empty string (`9223372036854775807 * ""`)
+* improve zsh completion file
+
+## [v0.12.11](https://github.com/itchyny/gojq/compare/v0.12.10..v0.12.11) (2022-12-24)
+* fix crash on assignment operator (`=`) with multiple values (`. = (0,0)`)
+* fix `isnormal` and `normals` functions against subnormal numbers
+
+## [v0.12.10](https://github.com/itchyny/gojq/compare/v0.12.9..v0.12.10) (2022-12-01)
+* fix `break` in `try`-`catch` query (`label $x | try break $x catch .`)
+* fix path value validation for `getpath` function (`path(getpath([[0]][0]))`)
+* fix path value validation for custom iterator functions
+* fix `walk` function with argument emitting multiple values (`[1],{x:1} | walk(.,0)`)
+* fix `@csv`, `@tsv`, `@sh` to escape the null character (`["\u0000"] | @csv,@tsv,@sh`)
+* improve performance of assignment operator (`=`), update-assignment operator (`|=`),
+ `map_values`, `del`, `delpaths`, `walk`, `ascii_downcase`, and `ascii_upcase` functions
+
+## [v0.12.9](https://github.com/itchyny/gojq/compare/v0.12.8..v0.12.9) (2022-09-01)
+* fix `fromjson` to emit error on unexpected trailing string
+* fix path analyzer on variable argument evaluation (`def f($x): .y; path(f(.x))`)
+* fix raw input option `--raw-input` (`-R`) to keep carriage returns and support 64KiB+ lines
+
+## [v0.12.8](https://github.com/itchyny/gojq/compare/v0.12.7..v0.12.8) (2022-06-01)
+* implement `gojq.Compare` for comparing values in custom internal functions
+* implement `gojq.TypeOf` for obtaining type name of values in custom internal functions
+* implement `gojq.Preview` for previewing values for error messages of custom internal functions
+* fix query lexer to parse string literals as JSON to support surrogate pairs (`"\ud83d\ude04"`)
+* fix priority bug of declared and builtin functions (`def empty: .; null | select(.)`)
+* fix string indexing by index out of bounds to emit `null` (`"abc" | .[3]`)
+* fix array binding pattern not to match against strings (`"abc" as [$a] ?// $a | $a`)
+* fix `sub` and `gsub` functions to emit results in the same order of jq
+* fix `fromjson` to keep integer precision (`"10000000000000000" | fromjson + 1`)
+* fix stream option to raise error against incomplete JSON input
+* improve array updating index and string repetition to increase limitations
+* improve `mktime` to support nanoseconds, just like `gmtime` and `now`
+* improve query lexer to report unterminated string literals
+* improve performance of string indexing and slicing by reducing allocations
+* improve performance of object and array indexing, slicing, and iteration,
+ by validating path values by comparing data addresses. This change improves jq
+ compatibility of path value validation (`{} | {}.x = 0`, `[0] | [.[]][] = 1`).
+ Also optimize constant indexing and slicing by specialized instruction
+* improve performance of `add` (on array of strings), `flatten`, `min`, `max`,
+ `sort`, `unique`, `join`, `to_entries`, `from_entries`, `indices`, `index`,
+ `rindex`, `startswith`, `endswith`, `ltrimstr`, `rtrimstr`, `explode`,
+ `capture`, `sub`, and `gsub` functions
+
## [v0.12.7](https://github.com/itchyny/gojq/compare/v0.12.6..v0.12.7) (2022-03-01)
* fix precedence of try expression against operators (`try 0 * error(0)`)
* fix iterator suffix with optional operator (`0 | .x[]?`)
@@ -187,7 +234,7 @@
## [v0.7.0](https://github.com/itchyny/gojq/compare/v0.6.0..v0.7.0) (2019-12-22)
* implement YAML input (`--yaml-input`) and output (`--yaml-output`)
* fix pipe in object value
-* fix precedence of if, try, reduce and foreach expressions
+* fix precedence of `if`, `try`, `reduce` and `foreach` expressions
* release from GitHub Actions
## [v0.6.0](https://github.com/itchyny/gojq/compare/v0.5.0..v0.6.0) (2019-08-26)
diff --git a/vendor/github.com/itchyny/gojq/Dockerfile b/vendor/github.com/itchyny/gojq/Dockerfile
index 7beaf4ed..284ece77 100644
--- a/vendor/github.com/itchyny/gojq/Dockerfile
+++ b/vendor/github.com/itchyny/gojq/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.17 AS builder
+FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
diff --git a/vendor/github.com/itchyny/gojq/LICENSE b/vendor/github.com/itchyny/gojq/LICENSE
index e3fc027c..3f4fcb26 100644
--- a/vendor/github.com/itchyny/gojq/LICENSE
+++ b/vendor/github.com/itchyny/gojq/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2019-2022 itchyny
+Copyright (c) 2019-2023 itchyny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/itchyny/gojq/Makefile b/vendor/github.com/itchyny/gojq/Makefile
index b5de9126..b7cdb400 100644
--- a/vendor/github.com/itchyny/gojq/Makefile
+++ b/vendor/github.com/itchyny/gojq/Makefile
@@ -1,8 +1,8 @@
BIN := gojq
VERSION := $$(make -s show-version)
VERSION_PATH := cli
-CURRENT_REVISION := $(shell git rev-parse --short HEAD)
-BUILD_LDFLAGS := "-s -w -X github.com/itchyny/$(BIN)/cli.revision=$(CURRENT_REVISION)"
+CURRENT_REVISION = $(shell git rev-parse --short HEAD)
+BUILD_LDFLAGS = "-s -w -X github.com/itchyny/$(BIN)/cli.revision=$(CURRENT_REVISION)"
GOBIN ?= $(shell go env GOPATH)/bin
SHELL := /bin/bash
@@ -19,7 +19,7 @@ build-dev: parser.go builtin.go
.PHONY: build-debug
build-debug: parser.go builtin.go
- go build -tags debug -ldflags=$(BUILD_LDFLAGS) -o $(BIN) ./cmd/$(BIN)
+ go build -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) -o $(BIN) ./cmd/$(BIN)
builtin.go: builtin.jq parser.go.y parser.go query.go operator.go _tools/*
GOOS= GOARCH= go generate
@@ -33,26 +33,26 @@ $(GOBIN)/goyacc:
.PHONY: install
install:
- go install -ldflags=$(BUILD_LDFLAGS) ./...
+ go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
.PHONY: install-dev
install-dev: parser.go builtin.go
- go install -ldflags=$(BUILD_LDFLAGS) ./...
+ go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
.PHONY: install-debug
install-debug: parser.go builtin.go
- go install -tags debug -ldflags=$(BUILD_LDFLAGS) ./...
+ go install -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
.PHONY: show-version
show-version: $(GOBIN)/gobump
- @gobump show -r $(VERSION_PATH)
+ @gobump show -r "$(VERSION_PATH)"
$(GOBIN)/gobump:
@go install github.com/x-motemen/gobump/cmd/gobump@latest
.PHONY: cross
cross: $(GOBIN)/goxz CREDITS
- goxz -n $(BIN) -pv=v$(VERSION) -include _$(BIN) -arch=amd64,arm64 \
+ goxz -n $(BIN) -pv=v$(VERSION) -include _$(BIN) \
-build-ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
$(GOBIN)/goxz:
@@ -72,7 +72,7 @@ test: build
.PHONY: lint
lint: $(GOBIN)/staticcheck
go vet ./...
- staticcheck -checks all,-ST1000 -tags debug ./...
+ staticcheck -checks all -tags gojq_debug ./...
$(GOBIN)/staticcheck:
go install honnef.co/go/tools/cmd/staticcheck@latest
@@ -89,27 +89,15 @@ clean:
.PHONY: update
update: export GOPROXY=direct
update:
- rm -f go.sum && go get -u -d ./... && go get -d github.com/mattn/go-runewidth@v0.0.9 && go mod tidy
- sed -i.bak '/require (/,/)/d' go.dev.mod && rm -f go.dev.{sum,mod.bak}
+ go get -u -d ./... && go mod tidy
+ go mod edit -modfile=go.dev.mod -droprequire=github.com/itchyny/{astgen,timefmt}-go
go get -u -d -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate
.PHONY: bump
bump: $(GOBIN)/gobump
-ifneq ($(shell git status --porcelain),)
- $(error git workspace is dirty)
-endif
-ifneq ($(shell git rev-parse --abbrev-ref HEAD),main)
- $(error current branch is not main)
-endif
+ test -z "$$(git status --porcelain || echo .)"
+ test "$$(git branch --show-current)" = "main"
@gobump up -w "$(VERSION_PATH)"
git commit -am "bump up version to $(VERSION)"
git tag "v$(VERSION)"
- git push origin main
- git push origin "refs/tags/v$(VERSION)"
-
-.PHONY: upload
-upload: $(GOBIN)/ghr
- ghr "v$(VERSION)" goxz
-
-$(GOBIN)/ghr:
- go install github.com/tcnksm/ghr@latest
+ git push --atomic origin main tag "v$(VERSION)"
diff --git a/vendor/github.com/itchyny/gojq/README.md b/vendor/github.com/itchyny/gojq/README.md
index baba061f..6370e440 100644
--- a/vendor/github.com/itchyny/gojq/README.md
+++ b/vendor/github.com/itchyny/gojq/README.md
@@ -75,11 +75,11 @@ docker run -i --rm ghcr.io/itchyny/gojq
## Difference to jq
- gojq is purely implemented with Go language and is completely portable. jq depends on the C standard library so the availability of math functions depends on the library. jq also depends on the regular expression library and it makes build scripts complex.
- gojq implements nice error messages for invalid query and JSON input. The error message of jq is sometimes difficult to tell where to fix the query.
-- gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have `keys_unsorted` function and `--sort-keys` (`-S`) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated. Also, gojq assumes only valid JSON input while jq deals with some JSON extensions; `NaN`, `Infinity` and `[000]`.
-- gojq supports arbitrary-precision integer calculation while jq does not. This is important to keep the precision of numeric IDs or nanosecond values. You can also use gojq to solve some mathematical problems which require big integers. Note that mathematical functions convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo operation, and division (when divisible) keep integer precisions. When you want to calculate floor division of big integers, use `def intdiv($x; $y): ($x - $x % $y) / $y;`, instead of `$x / $y`.
-- gojq fixes various bugs of jq. gojq correctly deletes elements of arrays by `|= empty` ([jq#2051](https://github.com/stedolan/jq/issues/2051)). gojq fixes `try`/`catch` handling ([jq#1859](https://github.com/stedolan/jq/issues/1859), [jq#1885](https://github.com/stedolan/jq/issues/1885), [jq#2140](https://github.com/stedolan/jq/issues/2140)). gojq fixes `nth/2` to output nothing when the count is equal to or larger than the stream size ([jq#1867](https://github.com/stedolan/jq/issues/1867)). gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/stedolan/jq/issues/1430), [jq#1624](https://github.com/stedolan/jq/issues/1624)), and supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/stedolan/jq/issues/1520)). gojq accepts indexing query `.e0` ([jq#1526](https://github.com/stedolan/jq/issues/1526), [jq#1651](https://github.com/stedolan/jq/issues/1651)), and allows `gsub` to handle patterns including `"^"` ([jq#2148](https://github.com/stedolan/jq/issues/2148)). gojq improves variable lexer to allow using keywords for variable names, especially in binding patterns, also disallows spaces after `$` ([jq#526](https://github.com/stedolan/jq/issues/526)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/stedolan/jq/issues/2374)).
-- gojq implements `@uri` to escape all the reserved characters defined in RFC 3986, Sec. 2.2 ([jq#1506](https://github.com/stedolan/jq/issues/1506)), and fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/stedolan/jq/issues/1931)). gojq improves time formatting and parsing, deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/stedolan/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/stedolan/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/stedolan/jq/issues/929), [jq#2195](https://github.com/stedolan/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/stedolan/jq/issues/1912)).
-- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue), `recurse_down` (deprecated in jq). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]interface{}` does not keep the order), `--unbuffered` (unbuffered by default). gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support some regular expression flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (declaration of `def true: .;` is a confusing query).
+- gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have `keys_unsorted` function and `--sort-keys` (`-S`) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated.
+- gojq supports arbitrary-precision integer calculation while jq does not; jq loses the precision of large integers when calculation is involved. Note that even with gojq, all mathematical functions, including `floor` and `round`, convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo, and division operators (when divisible) keep the integer precision. To calculate floor division of integers without losing the precision, use `def idivide($n): (. - . % $n) / $n;`. To round down floating-point numbers to integers, use `def ifloor: floor | tostring | tonumber;`, but note that this function does not work with large floating-point numbers and also loses the precision of large integers.
+- gojq fixes various bugs of jq. gojq correctly deletes elements of arrays by `|= empty` ([jq#2051](https://github.com/stedolan/jq/issues/2051)). gojq fixes `try`/`catch` handling ([jq#1859](https://github.com/stedolan/jq/issues/1859), [jq#1885](https://github.com/stedolan/jq/issues/1885), [jq#2140](https://github.com/stedolan/jq/issues/2140)). gojq fixes `nth/2` to output nothing when the count is equal to or larger than the stream size ([jq#1867](https://github.com/stedolan/jq/issues/1867)). gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/stedolan/jq/issues/1430), [jq#1624](https://github.com/stedolan/jq/issues/1624)). gojq handles overlapping occurrence differently in `rindex` and `indices`; `"ababa" | [rindex("aba"), indices("aba")]` results in `[2,[0,2]]` ([jq#2433](https://github.com/stedolan/jq/issues/2433)). gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/stedolan/jq/issues/1520)). gojq accepts indexing query `.e0` ([jq#1526](https://github.com/stedolan/jq/issues/1526), [jq#1651](https://github.com/stedolan/jq/issues/1651)), and allows `gsub` to handle patterns including `"^"` ([jq#2148](https://github.com/stedolan/jq/issues/2148)). gojq improves variable lexer to allow using keywords for variable names, especially in binding patterns, also disallows spaces after `$` ([jq#526](https://github.com/stedolan/jq/issues/526)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/stedolan/jq/issues/2374)).
+- gojq truncates down floating-point numbers on indexing (`[0] | .[0.5]` results in `0` not `null`), and slicing (`[0,1,2] | .[0.5:1.5]` results in `[0]` not `[0,1]`). gojq parses unary operators with higher precedence than variable binding (`[-1 as $x | 1,$x]` results in `[1,-1]` not `[-1,-1]`). gojq implements `@uri` to escape all the reserved characters defined in RFC 3986, Sec. 2.2 ([jq#1506](https://github.com/stedolan/jq/issues/1506)), and fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/stedolan/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/stedolan/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/stedolan/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/stedolan/jq/issues/929), [jq#2195](https://github.com/stedolan/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/stedolan/jq/issues/1912)). gojq supports nanoseconds in date and time functions.
+- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue), `recurse_down` (deprecated in jq). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]any` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support or behaves differently with some regular expression metacharacters and flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (`def true: .; true` is a confusing query), and module name prefixes in function declarations (using module prefixes like `def m::f: .;` is undocumented).
- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`).
### Color configuration
@@ -109,7 +109,7 @@ func main() {
if err != nil {
log.Fatalln(err)
}
- input := map[string]interface{}{"foo": []interface{}{1, 2, 3}}
+ input := map[string]any{"foo": []any{1, 2, 3}}
iter := query.Run(input) // or query.RunWithContext
for {
v, ok := iter.Next()
@@ -127,10 +127,10 @@ func main() {
- Firstly, use [`gojq.Parse(string) (*Query, error)`](https://pkg.go.dev/github.com/itchyny/gojq#Parse) to get the query from a string.
- Secondly, get the result iterator
- using [`query.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Query.Run) or [`query.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Query.RunWithContext)
- - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query.
- - In either case, you cannot use custom type values as the query input. The type should be `[]interface{}` for an array and `map[string]interface{}` for a map (just like decoded to an `interface{}` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `interface{}` and use it as the query input.
-- Thirdly, iterate through the results using [`iter.Next() (interface{}, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates.
- - The return type is not `(interface{}, error)` because iterators can emit multiple errors and you can continue after an error. It is difficult for the iterator to tell the termination in this situation.
+ - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. But for arguments of `code.Run`, do not give values sharing same data between multiple calls.
+ - In either case, you cannot use custom type values as the query input. The type should be `[]any` for an array and `map[string]any` for a map (just like decoded to an `any` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `any` and use it as the query input.
+- Thirdly, iterate through the results using [`iter.Next() (any, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates.
+ - The return type is not `(any, error)` because iterators can emit multiple errors and you can continue after an error. It is difficult for the iterator to tell the termination in this situation.
- Note that the result iterator may emit infinite number of values; `repeat(0)` and `range(infinite)`. It may stuck with no output value; `def f: f; f`. Use `RunWithContext` when you want to limit the execution time.
[`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) allows to configure the following compiler options.
diff --git a/vendor/github.com/itchyny/gojq/_gojq b/vendor/github.com/itchyny/gojq/_gojq
index 4c94718a..d403a314 100644
--- a/vendor/github.com/itchyny/gojq/_gojq
+++ b/vendor/github.com/itchyny/gojq/_gojq
@@ -2,31 +2,42 @@
_gojq()
{
- _arguments -C \
- '(-c --compact-output)'{-c,--compact-output}'[compact output]' \
- '(-r --raw-output)'{-r,--raw-output}'[output raw strings]' \
- '(-j --join-output)'{-j,--join-output}'[stop printing a newline after each output]' \
- '(-0 --nul-output)'{-0,--nul-output}'[print NUL after each output]' \
- '(-C --color-output)'{-C,--color-output}'[colorize output even if piped]' \
- '(-M --monochrome-output)'{-M,--monochrome-output}'[stop colorizing output]' \
- '(--yaml-output)'--yaml-output'[output by YAML]' \
- '(--indent)'--indent'[number of spaces for indentation]:indentation count' \
- '(--tab)'--tab'[use tabs for indentation]' \
+ _arguments -s -S \
+ '(-r --raw-output -j --join-output -0 --nul-output)'{-r,--raw-output}'[output raw strings]' \
+ '(-r --raw-output -j --join-output -0 --nul-output)'{-j,--join-output}'[output without newlines]' \
+ '(-r --raw-output -j --join-output -0 --nul-output)'{-0,--nul-output}'[output with NUL character]' \
+ '(-c --compact-output --indent --tab --yaml-output)'{-c,--compact-output}'[output without pretty-printing]' \
+ '(-c --compact-output --tab --yaml-output)--indent=[number of spaces for indentation]:indentation count:(2 4 8)' \
+ '(-c --compact-output --indent --yaml-output)--tab[use tabs for indentation]' \
+ '(-c --compact-output --indent --tab )--yaml-output[output in YAML format]' \
+ '(-C --color-output -M --monochrome-output)'{-C,--color-output}'[output with colors even if piped]' \
+ '(-C --color-output -M --monochrome-output)'{-M,--monochrome-output}'[output without colors]' \
'(-n --null-input)'{-n,--null-input}'[use null as input value]' \
- '(-R --raw-input)'{-R,--raw-input}'[read input as raw strings]' \
+ '(-R --raw-input --stream --yaml-input)'{-R,--raw-input}'[read input as raw strings]' \
+ '(-R --raw-input --yaml-input)--stream[parse input in stream fashion]' \
+ '(-R --raw-input --stream )--yaml-input[read input as YAML format]' \
'(-s --slurp)'{-s,--slurp}'[read all inputs into an array]' \
- '(--stream)'--stream'[parse input in stream fashion]' \
- '(--yaml-input)'--yaml-input'[read input as YAML]' \
- '(-f --from-file)'{-f,--from-file}'[load query from file]:filename of jq query:_files' \
- '(-L)'-L'[directory to search modules from]:module directory:_directories' \
- '(--arg)'--arg'[set variable to string value]:variable name:' \
- '(--argjson)'--argjson'[set variable to JSON value]:variable name:' \
- '(--slurpfile)'--slurpfile'[set variable to the JSON contents of the file]:variable name:' \
- '(--rawfile)'--rawfile'[set variable to the contents of the file]:variable name:' \
- '(--args)'--args'[consume remaining arguments as positional string values]' \
- '(--jsonargs)'--jsonargs'[consume remaining arguments as positional JSON values]' \
+ '(-f --from-file 1)'{-f,--from-file}='[load query from file]:filename of jq query:_files' \
+ '*-L=[directory to search modules from]:module directory:_directories' \
+ '*--arg[set a string value to a variable]:variable name: :string value' \
+ '*--argjson[set a JSON value to a variable]:variable name: :JSON value' \
+ '*--slurpfile[set the JSON contents of a file to a variable]:variable name: :JSON file:_files' \
+ '*--rawfile[set the contents of a file to a variable]:variable name: :file:_files' \
+ '*--args[consume remaining arguments as positional string values]' \
+ '*--jsonargs[consume remaining arguments as positional JSON values]' \
'(-e --exit-status)'{-e,--exit-status}'[exit 1 when the last value is false or null]' \
- '(-v --version)'{-v,--version}'[print version]' \
- '(-h --help)'{-h,--help}'[print help]' \
- && ret=0
+ '(- 1 *)'{-v,--version}'[display version information]' \
+ '(- 1 *)'{-h,--help}'[display help information]' \
+ '1: :_guard "^-([[:alpha:]0]#|-*)" "jq query"' \
+ '*: :_gojq_args'
+}
+
+_gojq_args() {
+ if (($words[(I)--args] > $words[(I)--jsonargs])); then
+ _message 'string value'
+ elif (($words[(I)--args] < $words[(I)--jsonargs])); then
+ _message 'JSON value'
+ else
+ _arguments '*:input file:_files'
+ fi
}
diff --git a/vendor/github.com/itchyny/gojq/builtin.go b/vendor/github.com/itchyny/gojq/builtin.go
index 65f9e234..ccf31358 100644
--- a/vendor/github.com/itchyny/gojq/builtin.go
+++ b/vendor/github.com/itchyny/gojq/builtin.go
@@ -7,78 +7,61 @@ func init() {
"IN": []*FuncDef{&FuncDef{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Left: &Query{Func: "s"}, Op: OpEq, Right: &Query{Func: "."}}, &Query{Func: "."}}}}}}, &FuncDef{Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Left: &Query{Func: "src"}, Op: OpEq, Right: &Query{Func: "s"}}, &Query{Func: "."}}}}}}},
"INDEX": []*FuncDef{&FuncDef{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$row"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "idx_expr"}, Op: OpPipe, Right: &Query{Func: "tostring"}}}}}}, Op: OpAssign, Right: &Query{Func: "$row"}}}}}}, &FuncDef{Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "idx_expr"}}}}}}},
"JOIN": []*FuncDef{&FuncDef{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}}}}, &FuncDef{Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}, &FuncDef{Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "join_expr"}}}}},
- "all": []*FuncDef{&FuncDef{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "."}}}}}}, &FuncDef{Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "y"}, Op: OpAnd, Right: &Query{Func: "empty"}}}}}}}}},
- "any": []*FuncDef{&FuncDef{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "."}}}}}}, &FuncDef{Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "y"}, Op: OpOr, Right: &Query{Func: "empty"}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}},
+ "_assign": []*FuncDef{},
+ "_modify": []*FuncDef{},
+ "all": []*FuncDef{&FuncDef{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Func: "."}}}}}}, &FuncDef{Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "y"}, Op: OpPipe, Right: &Query{Func: "not"}}}}}}}}}}}}},
+ "any": []*FuncDef{&FuncDef{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Func: "."}}}}}}, &FuncDef{Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, &Query{Func: "y"}}}}}}, &FuncDef{Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{&Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "y"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}},
"arrays": []*FuncDef{&FuncDef{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}}}}}}},
- "ascii_downcase": []*FuncDef{&FuncDef{Name: "ascii_downcase", Body: &Query{Left: &Query{Func: "explode"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeNumber, Number: "65"}}, Op: OpLe, Right: &Query{Func: "."}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "90"}}}}, Then: &Query{Left: &Query{Func: "."}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "32"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "implode"}}}}},
- "ascii_upcase": []*FuncDef{&FuncDef{Name: "ascii_upcase", Body: &Query{Left: &Query{Func: "explode"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeNumber, Number: "97"}}, Op: OpLe, Right: &Query{Func: "."}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "122"}}}}, Then: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "32"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "implode"}}}}},
- "assign": []*FuncDef{&FuncDef{Name: "_assign", Args: []string{"ps", "$v"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "ps"}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Func: "."}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Func: "$p"}, &Query{Func: "$v"}}}}}}}}}},
"booleans": []*FuncDef{&FuncDef{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}}}}}}}},
- "capture": []*FuncDef{&FuncDef{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Op: OpNe, Right: &Query{Func: "null"}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{KeyQuery: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "add"}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}}}}}},
- "combinations": []*FuncDef{&FuncDef{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "combinations"}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$y"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Func: "$y"}}}}}}}}}}}}}}}}}, &FuncDef{Name: "combinations", Args: []string{"n"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$dot"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "range", Args: []*Query{&Query{Func: "n"}}}}}, Op: OpPipe, Right: &Query{Func: "$dot"}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}},
+ "capture": []*FuncDef{&FuncDef{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Func: "_capture"}}}},
+ "combinations": []*FuncDef{&FuncDef{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}}}}}}}, &FuncDef{Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{&Query{Func: "n"}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{&Query{Func: "."}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}},
"del": []*FuncDef{&FuncDef{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "f"}}}}}}}}}}}}}},
- "endswith": []*FuncDef{&FuncDef{Name: "endswith", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}, Then: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Func: "length"}}}}}}, IsSlice: true}}}, Op: OpEq, Right: &Query{Func: "$x"}}, Else: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_type_error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "endswith"}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_type_error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "endswith"}}}}}}}}}}}},
"finites": []*FuncDef{&FuncDef{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "isfinite"}}}}}}},
"first": []*FuncDef{&FuncDef{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, &FuncDef{Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}},
- "flatten": []*FuncDef{&FuncDef{Name: "_flatten", Args: []string{"$x"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "$x"}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_flatten", Args: []*Query{&Query{Left: &Query{Func: "$x"}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "."}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "add"}}}, &FuncDef{Name: "flatten", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$x"}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "flatten depth must not be negative"}}}}}}}, Else: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_flatten", Args: []*Query{&Query{Func: "$x"}}}}}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}, &FuncDef{Name: "flatten", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_flatten", Args: []*Query{&Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}},
- "from_entries": []*FuncDef{&FuncDef{Name: "from_entries", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{KeyQuery: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "key"}}}, Op: OpAlt, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Key"}}}, Op: OpAlt, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Name"}}}}}}, Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "value"}}}}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "value"}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Value"}}}}}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "add"}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}}}}},
"fromdate": []*FuncDef{&FuncDef{Name: "fromdate", Body: &Query{Func: "fromdateiso8601"}}},
"fromdateiso8601": []*FuncDef{&FuncDef{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Op: OpPipe, Right: &Query{Func: "mktime"}}}},
- "fromstream": []*FuncDef{&FuncDef{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "x", Val: &ObjectVal{Queries: []*Query{&Query{Func: "null"}}}}, &ObjectKeyVal{Key: "e", Val: &ObjectVal{Queries: []*Query{&Query{Func: "false"}}}}}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$init"}}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}, Pattern: &Pattern{Name: "$i"}, Start: &Query{Func: "$init"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "$init"}, Else: &Query{Func: "."}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$i"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "x"}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "x"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}},
+ "fromstream": []*FuncDef{&FuncDef{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "x", Val: &ObjectVal{Queries: []*Query{&Query{Func: "null"}}}}, &ObjectKeyVal{Key: "e", Val: &ObjectVal{Queries: []*Query{&Query{Func: "false"}}}}}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$init"}}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}, Pattern: &Pattern{Name: "$i"}, Start: &Query{Func: "$init"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "$init"}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$i"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "x"}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "x"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}},
"group_by": []*FuncDef{&FuncDef{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
"gsub": []*FuncDef{&FuncDef{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, &FuncDef{Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}}},
"in": []*FuncDef{&FuncDef{Name: "in", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{&Query{Func: "$x"}}}}}}}}}}}}},
- "index": []*FuncDef{&FuncDef{Name: "index", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_lindex", Args: []*Query{&Query{Func: "$x"}}}}}}},
- "indices": []*FuncDef{&FuncDef{Name: "indices", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_indices", Args: []*Query{&Query{Func: "$x"}}}}}}},
"inputs": []*FuncDef{&FuncDef{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{&Query{Func: "input"}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}}, Then: &Query{Func: "empty"}, Else: &Query{Func: "error"}}}}}}}}},
"inside": []*FuncDef{&FuncDef{Name: "inside", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "contains", Args: []*Query{&Query{Func: "$x"}}}}}}}}}}}}},
"isempty": []*FuncDef{&FuncDef{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "false"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}, Op: OpComma, Right: &Query{Func: "true"}}}}}}},
"iterables": []*FuncDef{&FuncDef{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}},
- "join": []*FuncDef{&FuncDef{Name: "join", Args: []string{"$x"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_join", Args: []*Query{&Query{Func: "$x"}}}}}}}},
"last": []*FuncDef{&FuncDef{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}, &FuncDef{Name: "last", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "null"}, Update: &Query{Func: "$item"}}}}}},
"leaf_paths": []*FuncDef{&FuncDef{Name: "leaf_paths", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "paths", Args: []*Query{&Query{Func: "scalars"}}}}}}},
"limit": []*FuncDef{&FuncDef{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Func: "empty"}}}}}}}}}}}, Elif: []*IfElif{&IfElif{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "empty"}}}, Else: &Query{Func: "g"}}}}}},
- "ltrimstr": []*FuncDef{&FuncDef{Name: "ltrimstr", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}, Op: OpAnd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}, Op: OpAnd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "startswith", Args: []*Query{&Query{Func: "$x"}}}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Func: "length"}}, IsSlice: true}}}}}}}},
"map": []*FuncDef{&FuncDef{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}},
"map_values": []*FuncDef{&FuncDef{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Op: OpModify, Right: &Query{Func: "f"}}}},
- "match": []*FuncDef{&FuncDef{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}, &Query{Func: "false"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}}},
- "max": []*FuncDef{&FuncDef{Name: "max", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "max_by", Args: []*Query{&Query{Func: "."}}}}}}},
+ "match": []*FuncDef{&FuncDef{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}, &Query{Func: "false"}}}, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}},
"max_by": []*FuncDef{&FuncDef{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
- "min": []*FuncDef{&FuncDef{Name: "min", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "min_by", Args: []*Query{&Query{Func: "."}}}}}}},
"min_by": []*FuncDef{&FuncDef{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
- "modify": []*FuncDef{&FuncDef{Name: "_modify", Args: []string{"ps", "f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: "ps"}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}, Update: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpAdd, Right: &Query{Func: "$p"}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$q"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Func: "$q"}, &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$q"}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}}}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}, &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$p"}}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}}}}}}}}},
"normals": []*FuncDef{&FuncDef{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "isnormal"}}}}}}},
"not": []*FuncDef{&FuncDef{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "."}, Then: &Query{Func: "false"}, Else: &Query{Func: "true"}}}}}},
- "nth": []*FuncDef{&FuncDef{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, &FuncDef{Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative indices"}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Op: OpOr, Right: &Query{Func: "empty"}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}}}}}}},
+ "nth": []*FuncDef{&FuncDef{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, &FuncDef{Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative indices"}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Left: &Query{Func: "$n"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}}},
"nulls": []*FuncDef{&FuncDef{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Func: "null"}}}}}}}},
"numbers": []*FuncDef{&FuncDef{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}}}}}}}},
"objects": []*FuncDef{&FuncDef{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}},
- "paths": []*FuncDef{&FuncDef{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{&Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}, Then: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}}, &FuncDef{Name: "paths", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Left: &Query{Func: "paths"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$p"}}, Body: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}}}}}}}}}}}}}}},
+ "paths": []*FuncDef{&FuncDef{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Func: ".."}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}, &FuncDef{Name: "paths", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "paths"}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}, Op: OpPipe, Right: &Query{Func: "$p"}}}}}}}}},
"range": []*FuncDef{&FuncDef{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, &Query{Func: "$end"}, &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, &FuncDef{Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Func: "$start"}, &Query{Func: "$end"}, &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, &FuncDef{Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{&Query{Func: "$start"}, &Query{Func: "$end"}, &Query{Func: "$step"}}}}}}},
"recurse": []*FuncDef{&FuncDef{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}}}}}}, &FuncDef{Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}, Func: "r"}}, &FuncDef{Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Func: "cond"}}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}}, Func: "r"}}},
"repeat": []*FuncDef{&FuncDef{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_repeat", Body: &Query{Left: &Query{Func: "f"}, Op: OpComma, Right: &Query{Func: "_repeat"}}}}, Func: "_repeat"}}},
- "rindex": []*FuncDef{&FuncDef{Name: "rindex", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_rindex", Args: []*Query{&Query{Func: "$x"}}}}}}},
- "rtrimstr": []*FuncDef{&FuncDef{Name: "rtrimstr", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Left: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}, Op: OpAnd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}, Op: OpAnd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "endswith", Args: []*Query{&Query{Func: "$x"}}}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Func: "length"}}}}}}, IsSlice: true}}}}}}}},
"scalars": []*FuncDef{&FuncDef{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}},
- "scan": []*FuncDef{&FuncDef{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Left: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}, Op: OpAdd, Right: &Query{Func: "$flags"}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Index: &Index{Name: "string"}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}},
+ "scan": []*FuncDef{&FuncDef{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Index: &Index{Name: "string"}}}}}}}}}}}}}},
"select": []*FuncDef{&FuncDef{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "f"}, Then: &Query{Func: "."}, Else: &Query{Func: "empty"}}}}}},
- "sort": []*FuncDef{&FuncDef{Name: "sort", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sort_by", Args: []*Query{&Query{Func: "."}}}}}}},
"sort_by": []*FuncDef{&FuncDef{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
- "splits": []*FuncDef{&FuncDef{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}}},
- "startswith": []*FuncDef{&FuncDef{Name: "startswith", Args: []string{"$x"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}, Then: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{End: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Func: "length"}}, IsSlice: true}}}, Op: OpEq, Right: &Query{Func: "$x"}}, Else: &Query{Left: &Query{Func: "$x"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_type_error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "startswith"}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_type_error", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "startswith"}}}}}}}}}}}},
+ "splits": []*FuncDef{&FuncDef{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}, SuffixList: []*Suffix{&Suffix{Iter: true}}}}}},
"strings": []*FuncDef{&FuncDef{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}}},
- "sub": []*FuncDef{&FuncDef{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$in"}}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, Then: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$x"}}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "captures"}}, &Suffix{Iter: true}}}}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Op: OpNe, Right: &Query{Func: "null"}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{KeyQuery: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "add"}, Op: OpAlt, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "string"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$in"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}, End: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Func: "str"}}}}}}}, &ObjectKeyVal{Key: "offset", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "length"}}}}}}}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "matches"}}, &Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}}}}}}, Else: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$in"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{}}}}}}, &ObjectKeyVal{Key: "offset", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}},
+ "sub": []*FuncDef{&FuncDef{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "str"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$str"}}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{&Suffix{Index: &Index{End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$r"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "_capture"}, Op: OpPipe, Right: &Query{Func: "str"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "length"}}}}}}, End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}, &ObjectKeyVal{Key: "offset", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Name: "offset"}}}}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{&Suffix{Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}, IsSlice: true}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "string", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{}}}}}}, &ObjectKeyVal{Key: "matches", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}},
"test": []*FuncDef{&FuncDef{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "null"}}}}}}, &FuncDef{Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{&Query{Func: "$re"}, &Query{Func: "$flags"}, &Query{Func: "true"}}}}}}},
- "to_entries": []*FuncDef{&FuncDef{Name: "to_entries", Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "keys"}, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$k"}}, Body: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{&ObjectKeyVal{Key: "key", Val: &ObjectVal{Queries: []*Query{&Query{Func: "$k"}}}}, &ObjectKeyVal{Key: "value", Val: &ObjectVal{Queries: []*Query{&Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$k"}}}}}}}}}}}}}}}}}}}}},
"todate": []*FuncDef{&FuncDef{Name: "todate", Body: &Query{Func: "todateiso8601"}}},
"todateiso8601": []*FuncDef{&FuncDef{Name: "todateiso8601", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strftime", Args: []*Query{&Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%SZ"}}}}}}}}},
"tostream": []*FuncDef{&FuncDef{Name: "tostream", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{FuncDefs: []*FuncDef{&FuncDef{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}, Op: OpComma, Right: &Query{Func: "."}}}}, Func: "r"}}}, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{&Query{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{&Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Iter: true}, &Suffix{Optional: true}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpComma, Right: &Query{Func: "."}}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpAdd, Right: &Query{Func: "$q"}}}}}}}}}}}}}}}},
- "truncate_stream": []*FuncDef{&FuncDef{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$input"}}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Func: "length"}}}}, Op: OpGt, Right: &Query{Func: "$n"}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$input"}, SuffixList: []*Suffix{&Suffix{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}, &Suffix{Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}}}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}}}}}},
- "unique": []*FuncDef{&FuncDef{Name: "unique", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "unique_by", Args: []*Query{&Query{Func: "."}}}}}}},
+ "truncate_stream": []*FuncDef{&FuncDef{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{&Suffix{Bind: &Bind{Patterns: []*Pattern{&Pattern{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Func: "$n"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpModify, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}},
"unique_by": []*FuncDef{&FuncDef{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
"until": []*FuncDef{&FuncDef{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Func: "."}, Else: &Query{Left: &Query{Func: "next"}, Op: OpPipe, Right: &Query{Func: "_until"}}}}}}}, Func: "_until"}}},
"values": []*FuncDef{&FuncDef{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{&Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Func: "null"}}}}}}}},
- "walk": []*FuncDef{&FuncDef{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{&Query{Func: "_walk"}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}},
+ "walk": []*FuncDef{&FuncDef{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Func: "_walk"}}}}}, Elif: []*IfElif{&IfElif{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{&Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "last", Args: []*Query{&Query{Func: "_walk"}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}},
"while": []*FuncDef{&FuncDef{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{&FuncDef{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "update"}, Op: OpPipe, Right: &Query{Func: "_while"}}}}}, Else: &Query{Func: "empty"}}}}}}, Func: "_while"}}},
"with_entries": []*FuncDef{&FuncDef{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Func: "to_entries"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{&Query{Func: "f"}}}}}, Op: OpPipe, Right: &Query{Func: "from_entries"}}}}},
}
diff --git a/vendor/github.com/itchyny/gojq/builtin.jq b/vendor/github.com/itchyny/gojq/builtin.jq
index b6a9e1d8..66d63073 100644
--- a/vendor/github.com/itchyny/gojq/builtin.jq
+++ b/vendor/github.com/itchyny/gojq/builtin.jq
@@ -1,10 +1,6 @@
def not: if . then false else true end;
def in(xs): . as $x | xs | has($x);
def map(f): [.[] | f];
-def to_entries: [keys[] as $k | {key: $k, value: .[$k]}];
-def from_entries:
- map({ (.key // .Key // .name // .Name): (if has("value") then .value else .Value end) })
- | add // {};
def with_entries(f): to_entries | map(f) | from_entries;
def select(f): if f then . else empty end;
def recurse: recurse(.[]?);
@@ -24,21 +20,10 @@ def range($end): _range(0; $end; 1);
def range($start; $end): _range($start; $end; 1);
def range($start; $end; $step): _range($start; $end; $step);
-def _flatten($x):
- map(if type == "array" and $x != 0 then _flatten($x - 1) else [.] end) | add;
-def flatten($x):
- if $x < 0
- then error("flatten depth must not be negative")
- else _flatten($x) // [] end;
-def flatten: _flatten(-1) // [];
-def min: min_by(.);
def min_by(f): _min_by(map([f]));
-def max: max_by(.);
def max_by(f): _max_by(map([f]));
-def sort: sort_by(.);
def sort_by(f): _sort_by(map([f]));
def group_by(f): _group_by(map([f]));
-def unique: unique_by(.);
def unique_by(f): _unique_by(map([f]));
def arrays: select(type == "array");
@@ -54,55 +39,21 @@ def values: select(. != null);
def scalars: select(type | . != "array" and . != "object");
def leaf_paths: paths(scalars);
-def indices($x): _indices($x);
-def index($x): _lindex($x);
-def rindex($x): _rindex($x);
def inside(xs): . as $x | xs | contains($x);
-def startswith($x):
- if type == "string" then
- if $x|type == "string" then
- .[:$x | length] == $x
- else
- $x | _type_error("startswith")
- end
- else
- _type_error("startswith")
- end;
-def endswith($x):
- if type == "string" then
- if $x|type == "string" then
- .[- ($x | length):] == $x
- else
- $x | _type_error("endswith")
- end
- else
- _type_error("endswith")
- end;
-def ltrimstr($x):
- if type == "string" and ($x|type == "string") and startswith($x) then
- .[$x | length:]
- end;
-def rtrimstr($x):
- if type == "string" and ($x|type == "string") and endswith($x) then
- .[:- ($x | length)]
- end;
-
def combinations:
if length == 0 then
[]
else
- .[0][] as $x | .[1:] | combinations as $y | [$x] + $y
+ .[0][] as $x | [$x] + (.[1:] | combinations)
end;
-def combinations(n):
- . as $dot | [range(n) | $dot] | combinations;
-def join($x):
- if type != "array" then [.[]] end | _join($x);
-def ascii_downcase:
- explode | map(if 65 <= . and . <= 90 then . + 32 end) | implode;
-def ascii_upcase:
- explode | map(if 97 <= . and . <= 122 then . - 32 end) | implode;
+def combinations(n): [limit(n; repeat(.))] | combinations;
def walk(f):
- def _walk: if type | . == "array" or . == "object" then map_values(_walk) end | f;
+ def _walk:
+ if type == "array" then
+ map(_walk)
+ elif type == "object" then
+ map_values(last(_walk))
+ end | f;
_walk;
def first: .[0];
@@ -110,17 +61,20 @@ def first(g): label $out | g | ., break $out;
def last: .[-1];
def last(g): reduce g as $item (null; $item);
def isempty(g): label $out | (g | false, break $out), true;
-def all: all(.[]; .);
+def all: all(.);
def all(y): all(.[]; y);
-def all(g; y): isempty(g|y and empty);
-def any: any(.[]; .);
+def all(g; y): isempty(g | select(y | not));
+def any: any(.);
def any(y): any(.[]; y);
-def any(g; y): isempty(g|y or empty) | not;
+def any(g; y): isempty(g | select(y)) | not;
def limit($n; g):
if $n > 0 then
- label $out
- | foreach g as $item
- ($n; .-1; $item, if . <= 0 then break $out else empty end)
+ label $out |
+ foreach g as $item (
+ $n;
+ . - 1;
+ $item, if . <= 0 then break $out else empty end
+ )
elif $n == 0 then
empty
else
@@ -131,41 +85,39 @@ def nth($n; g):
if $n < 0 then
error("nth doesn't support negative indices")
else
- label $out
- | foreach g as $item
- ($n; .-1; . < 0 or empty | $item, break $out)
+ label $out |
+ foreach g as $item (
+ $n + 1;
+ . - 1;
+ if . <= 0 then $item, break $out else empty end
+ )
end;
def truncate_stream(f):
- . as $n | null | f | . as $input
- | if (.[0] | length) > $n then setpath([0]; $input[0][$n:]) else empty end;
+ . as $n | null | f |
+ if .[0] | length > $n then .[0] |= .[$n:] else empty end;
def fromstream(f):
- { x: null, e: false } as $init
- | foreach f as $i
- ( $init;
- if .e then $init else . end
- | if $i | length == 2
- then setpath(["e"]; $i[0] | length==0) | setpath(["x"] + $i[0]; $i[1])
- else setpath(["e"]; $i[0] | length==1) end;
- if .e then .x else empty end);
+ { x: null, e: false } as $init |
+ foreach f as $i (
+ $init;
+ if .e then $init end |
+ if $i | length == 2 then
+ setpath(["e"]; $i[0] | length == 0) |
+ setpath(["x"] + $i[0]; $i[1])
+ else
+ setpath(["e"]; $i[0] | length == 1)
+ end;
+ if .e then .x else empty end
+ );
def tostream:
- path(def r: (.[]? | r), .; r) as $p
- | getpath($p)
- | reduce path(.[]?) as $q ([$p, .]; [$p + $q]);
+ path(def r: (.[]? | r), .; r) as $p |
+ getpath($p) |
+ reduce path(.[]?) as $q ([$p, .]; [$p + $q]);
-def _assign(ps; $v):
- reduce path(ps) as $p (.; setpath($p; $v));
-def _modify(ps; f):
- reduce path(ps) as $p
- ([., []]; label $out | (([0] + $p) as $q | setpath($q; getpath($q) | f) | ., break $out), setpath([1]; .[1] + [$p]))
- | . as $x | $x[0] | delpaths($x[1]);
def map_values(f): .[] |= f;
def del(f): delpaths([path(f)]);
-def paths:
- path(recurse(if type | . == "array" or . == "object" then .[] else empty end))
- | select(length > 0);
-def paths(f):
- . as $x | paths | select(. as $p | $x | getpath($p) | f);
+def paths: path(..) | select(. != []);
+def paths(f): paths as $p | select(getpath($p) | f) | $p;
def fromdateiso8601: strptime("%Y-%m-%dT%H:%M:%S%z") | mktime;
def todateiso8601: strftime("%Y-%m-%dT%H:%M:%SZ");
@@ -173,39 +125,37 @@ def fromdate: fromdateiso8601;
def todate: todateiso8601;
def match($re): match($re; null);
-def match($re; $flags): _match($re; $flags; false) | .[];
+def match($re; $flags): _match($re; $flags; false)[];
def test($re): test($re; null);
def test($re; $flags): _match($re; $flags; true);
def capture($re): capture($re; null);
-def capture($re; $flags):
- match($re; $flags)
- | [.captures[] | select(.name != null) | { (.name): .string }]
- | add // {};
+def capture($re; $flags): match($re; $flags) | _capture;
def scan($re): scan($re; null);
def scan($re; $flags):
- match($re; "g" + $flags)
- | if .captures|length > 0 then [.captures[].string] else .string end;
+ match($re; $flags + "g") |
+ if .captures == [] then
+ .string
+ else
+ [.captures[].string]
+ end;
def splits($re): splits($re; null);
-def splits($re; $flags): split($re; $flags) | .[];
+def splits($re; $flags): split($re; $flags)[];
def sub($re; str): sub($re; str; null);
def sub($re; str; $flags):
- . as $in
- | def _sub:
- if .matches|length > 0
- then
- . as $x | .matches[0] as $r
- | [$r.captures[] | select(.name != null) | { (.name): .string }]
- | add // {}
- | {
- string: ($x.string + $in[$x.offset:$r.offset] + str),
- offset: ($r.offset + $r.length),
- matches: $x.matches[1:]
- }
- | _sub
- else
- .string + $in[.offset:]
- end;
- { string: "", offset: 0, matches: [match($re; $flags)] } | _sub;
+ . as $str |
+ def _sub:
+ if .matches == [] then
+ $str[:.offset] + .string
+ else
+ .matches[-1] as $r |
+ {
+ string: (($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string),
+ offset: $r.offset,
+ matches: .matches[:-1],
+ } |
+ _sub
+ end;
+ { string: "", matches: [match($re; $flags)] } | _sub;
def gsub($re; str): sub($re; str; "g");
def gsub($re; str; $flags): sub($re; str; $flags + "g");
@@ -216,8 +166,9 @@ def inputs:
if . == "break" then empty else error end;
def INDEX(stream; idx_expr):
- reduce stream as $row ({}; .[$row|idx_expr|tostring] = $row);
-def INDEX(idx_expr): INDEX(.[]; idx_expr);
+ reduce stream as $row ({}; .[$row | idx_expr | tostring] = $row);
+def INDEX(idx_expr):
+ INDEX(.[]; idx_expr);
def JOIN($idx; idx_expr):
[.[] | [., $idx[idx_expr]]];
def JOIN($idx; stream; idx_expr):
diff --git a/vendor/github.com/itchyny/gojq/code.go b/vendor/github.com/itchyny/gojq/code.go
index f1935d84..33505bde 100644
--- a/vendor/github.com/itchyny/gojq/code.go
+++ b/vendor/github.com/itchyny/gojq/code.go
@@ -1,7 +1,7 @@
package gojq
type code struct {
- v interface{}
+ v any
op opcode
}
@@ -25,13 +25,15 @@ const (
opbacktrack
opjump
opjumpifnot
+ opindex
+ opindexarray
opcall
opcallrec
oppushpc
opcallpc
opscope
opret
- opeach
+ opiter
opexpbegin
opexpend
oppathbegin
@@ -74,6 +76,10 @@ func (op opcode) String() string {
return "jump"
case opjumpifnot:
return "jumpifnot"
+ case opindex:
+ return "index"
+ case opindexarray:
+ return "indexarray"
case opcall:
return "call"
case opcallrec:
@@ -86,8 +92,8 @@ func (op opcode) String() string {
return "scope"
case opret:
return "ret"
- case opeach:
- return "each"
+ case opiter:
+ return "iter"
case opexpbegin:
return "expbegin"
case opexpend:
diff --git a/vendor/github.com/itchyny/gojq/compare.go b/vendor/github.com/itchyny/gojq/compare.go
index 9f0d5338..e70c1fbb 100644
--- a/vendor/github.com/itchyny/gojq/compare.go
+++ b/vendor/github.com/itchyny/gojq/compare.go
@@ -5,19 +5,17 @@ import (
"math/big"
)
-func compare(l, r interface{}) int {
+// Compare l and r, and returns jq-flavored comparison value.
+// The result will be 0 if l == r, -1 if l < r, and +1 if l > r.
+// This comparison is used by built-in operators and functions.
+func Compare(l, r any) int {
+ return compare(l, r)
+}
+
+func compare(l, r any) int {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} {
- switch {
- case l < r:
- return -1
- case l == r:
- return 0
- default:
- return 1
- }
- },
- func(l, r float64) interface{} {
+ compareInt,
+ func(l, r float64) any {
switch {
case l < r || math.IsNaN(l):
return -1
@@ -27,10 +25,10 @@ func compare(l, r interface{}) int {
return 1
}
},
- func(l, r *big.Int) interface{} {
+ func(l, r *big.Int) any {
return l.Cmp(r)
},
- func(l, r string) interface{} {
+ func(l, r string) any {
switch {
case l < r:
return -1
@@ -40,66 +38,63 @@ func compare(l, r interface{}) int {
return 1
}
},
- func(l, r []interface{}) interface{} {
- for i := 0; ; i++ {
- if i >= len(l) {
- if i >= len(r) {
- return 0
- }
- return -1
- }
- if i >= len(r) {
- return 1
- }
+ func(l, r []any) any {
+ n := len(l)
+ if len(r) < n {
+ n = len(r)
+ }
+ for i := 0; i < n; i++ {
if cmp := compare(l[i], r[i]); cmp != 0 {
return cmp
}
}
+ return compareInt(len(l), len(r))
},
- func(l, r map[string]interface{}) interface{} {
+ func(l, r map[string]any) any {
lk, rk := funcKeys(l), funcKeys(r)
if cmp := compare(lk, rk); cmp != 0 {
return cmp
}
- for _, k := range lk.([]interface{}) {
+ for _, k := range lk.([]any) {
if cmp := compare(l[k.(string)], r[k.(string)]); cmp != 0 {
return cmp
}
}
return 0
},
- func(l, r interface{}) interface{} {
- ln, rn := getTypeOrdNum(l), getTypeOrdNum(r)
- switch {
- case ln < rn:
- return -1
- case ln == rn:
- return 0
- default:
- return 1
- }
+ func(l, r any) any {
+ return compareInt(typeIndex(l), typeIndex(r))
},
).(int)
}
-func getTypeOrdNum(v interface{}) int {
+func compareInt(l, r int) any {
+ switch {
+ case l < r:
+ return -1
+ case l == r:
+ return 0
+ default:
+ return 1
+ }
+}
+
+func typeIndex(v any) int {
switch v := v.(type) {
- case nil:
+ default:
return 0
case bool:
- if v {
- return 2
+ if !v {
+ return 1
}
- return 1
+ return 2
case int, float64, *big.Int:
return 3
case string:
return 4
- case []interface{}:
+ case []any:
return 5
- case map[string]interface{}:
+ case map[string]any:
return 6
- default:
- return -1
}
}
diff --git a/vendor/github.com/itchyny/gojq/compiler.go b/vendor/github.com/itchyny/gojq/compiler.go
index 00daa04c..135387fa 100644
--- a/vendor/github.com/itchyny/gojq/compiler.go
+++ b/vendor/github.com/itchyny/gojq/compiler.go
@@ -2,7 +2,6 @@ package gojq
import (
"context"
- "encoding/json"
"errors"
"fmt"
"sort"
@@ -18,6 +17,7 @@ type compiler struct {
inputIter Iter
codes []*code
codeinfos []codeinfo
+ builtinScope *scopeinfo
scopes []*scopeinfo
scopecnt int
}
@@ -30,16 +30,17 @@ type Code struct {
}
// Run runs the code with the variable values (which should be in the
-// same order as the given variables using WithVariables) and returns
+// same order as the given variables using [WithVariables]) and returns
// a result iterator.
//
-// It is safe to call this method of a *Code in multiple goroutines.
-func (c *Code) Run(v interface{}, values ...interface{}) Iter {
+// It is safe to call this method in goroutines, to reuse a compiled [*Code].
+// But for arguments, do not give values sharing same data between goroutines.
+func (c *Code) Run(v any, values ...any) Iter {
return c.RunWithContext(context.Background(), v, values...)
}
// RunWithContext runs the code with context.
-func (c *Code) RunWithContext(ctx context.Context, v interface{}, values ...interface{}) Iter {
+func (c *Code) RunWithContext(ctx context.Context, v any, values ...any) Iter {
if len(values) > len(c.variables) {
return NewIter(&tooManyVariableValuesError{})
} else if len(values) < len(c.variables) {
@@ -51,16 +52,6 @@ func (c *Code) RunWithContext(ctx context.Context, v interface{}, values ...inte
return newEnv(ctx).execute(c, normalizeNumbers(v), values...)
}
-// ModuleLoader is an interface for loading modules.
-//
-// Implement following optional methods. Use NewModuleLoader to load local modules.
-// LoadModule(string) (*Query, error)
-// LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
-// LoadInitModules() ([]*Query, error)
-// LoadJSON(string) (interface{}, error)
-// LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error)
-type ModuleLoader interface{}
-
type scopeinfo struct {
variables []*varinfo
funcs []*funcinfo
@@ -87,6 +78,7 @@ func Compile(q *Query, options ...CompilerOption) (*Code, error) {
for _, opt := range options {
opt(c)
}
+ c.builtinScope = c.newScope()
scope := c.newScope()
c.scopes = []*scopeinfo{scope}
setscope := c.lazy(func() *code {
@@ -152,15 +144,15 @@ func (c *compiler) compileImport(i *Import) error {
return fmt.Errorf("cannot load module: %q", path)
}
if strings.HasPrefix(alias, "$") {
- var vals interface{}
+ var vals any
if moduleLoader, ok := c.moduleLoader.(interface {
- LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error)
+ LoadJSONWithMeta(string, map[string]any) (any, error)
}); ok {
if vals, err = moduleLoader.LoadJSONWithMeta(path, i.Meta.ToValue()); err != nil {
return err
}
} else if moduleLoader, ok := c.moduleLoader.(interface {
- LoadJSON(string) (interface{}, error)
+ LoadJSON(string) (any, error)
}); ok {
if vals, err = moduleLoader.LoadJSON(path); err != nil {
return err
@@ -177,7 +169,7 @@ func (c *compiler) compileImport(i *Import) error {
}
var q *Query
if moduleLoader, ok := c.moduleLoader.(interface {
- LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
+ LoadModuleWithMeta(string, map[string]any) (*Query, error)
}); ok {
if q, err = moduleLoader.LoadModuleWithMeta(path, i.Meta.ToValue()); err != nil {
return err
@@ -190,8 +182,11 @@ func (c *compiler) compileImport(i *Import) error {
}
}
c.appendCodeInfo("module " + path)
- defer c.appendCodeInfo("end of module " + path)
- return c.compileModule(q, alias)
+ if err = c.compileModule(q, alias); err != nil {
+ return err
+ }
+ c.appendCodeInfo("end of module " + path)
+ return nil
}
func (c *compiler) compileModule(q *Query, alias string) error {
@@ -274,6 +269,31 @@ func (c *compiler) lookupFuncOrVariable(name string) (*funcinfo, *varinfo) {
return nil, nil
}
+func (c *compiler) lookupBuiltin(name string, argcnt int) *funcinfo {
+ s := c.builtinScope
+ for i := len(s.funcs) - 1; i >= 0; i-- {
+ if f := s.funcs[i]; f.name == name && f.argcnt == argcnt {
+ return f
+ }
+ }
+ return nil
+}
+
+func (c *compiler) appendBuiltin(name string, argcnt int) func() {
+ setjump := c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })
+ c.appendCodeInfo(name)
+ c.builtinScope.funcs = append(
+ c.builtinScope.funcs,
+ &funcinfo{name, len(c.codes), argcnt},
+ )
+ return func() {
+ setjump()
+ c.appendCodeInfo("end of " + name)
+ }
+}
+
func (c *compiler) newScope() *scopeinfo {
i := c.scopecnt // do not use len(c.scopes) because it pops
c.scopecnt++
@@ -294,29 +314,22 @@ func (c *compiler) newScopeDepth() func() {
func (c *compiler) compileFuncDef(e *FuncDef, builtin bool) error {
var scope *scopeinfo
if builtin {
- scope = c.scopes[0]
- for i := len(scope.funcs) - 1; i >= 0; i-- {
- if f := scope.funcs[i]; f.name == e.Name && f.argcnt == len(e.Args) {
- return nil
- }
- }
+ scope = c.builtinScope
} else {
scope = c.scopes[len(c.scopes)-1]
}
defer c.lazy(func() *code {
- return &code{op: opjump, v: c.pc()}
+ return &code{op: opjump, v: len(c.codes)}
})()
c.appendCodeInfo(e.Name)
- defer c.appendCodeInfo("end of " + e.Name)
- pc := c.pc()
- scope.funcs = append(scope.funcs, &funcinfo{e.Name, pc, len(e.Args)})
+ scope.funcs = append(scope.funcs, &funcinfo{e.Name, len(c.codes), len(e.Args)})
defer func(scopes []*scopeinfo, variables []string) {
c.scopes, c.variables = scopes, variables
}(c.scopes, c.variables)
c.variables = c.variables[len(c.variables):]
scope = c.newScope()
if builtin {
- c.scopes = []*scopeinfo{c.scopes[0], scope}
+ c.scopes = []*scopeinfo{c.builtinScope, scope}
} else {
c.scopes = append(c.scopes, scope)
}
@@ -344,14 +357,20 @@ func (c *compiler) compileFuncDef(e *FuncDef, builtin bool) error {
}
for _, w := range vis {
c.append(&code{op: opload, v: v})
+ c.append(&code{op: opexpbegin})
c.append(&code{op: opload, v: w.index})
c.append(&code{op: opcallpc})
c.appendCodeInfo(w.name)
c.append(&code{op: opstore, v: c.pushVariable(w.name)})
+ c.append(&code{op: opexpend})
}
c.append(&code{op: opload, v: v})
}
- return c.compile(e.Body)
+ if err := c.compile(e.Body); err != nil {
+ return err
+ }
+ c.appendCodeInfo("end of " + e.Name)
+ return nil
}
func (c *compiler) compileQuery(e *Query) error {
@@ -425,15 +444,15 @@ func (c *compiler) compileQuery(e *Query) error {
func (c *compiler) compileComma(l, r *Query) error {
setfork := c.lazy(func() *code {
- return &code{op: opfork, v: c.pc() + 1}
+ return &code{op: opfork, v: len(c.codes)}
})
if err := c.compileQuery(l); err != nil {
return err
}
- setfork()
defer c.lazy(func() *code {
- return &code{op: opjump, v: c.pc()}
+ return &code{op: opjump, v: len(c.codes)}
})()
+ setfork()
return c.compileQuery(r)
}
@@ -442,23 +461,23 @@ func (c *compiler) compileAlt(l, r *Query) error {
found := c.newVariable()
c.append(&code{op: opstore, v: found})
setfork := c.lazy(func() *code {
- return &code{op: opfork, v: c.pc()} // opload found
+ return &code{op: opfork, v: len(c.codes)} // opload found
})
if err := c.compileQuery(l); err != nil {
return err
}
c.append(&code{op: opdup})
- c.append(&code{op: opjumpifnot, v: c.pc() + 4}) // oppop
- c.append(&code{op: oppush, v: true}) // found some value
+ c.append(&code{op: opjumpifnot, v: len(c.codes) + 4}) // oppop
+ c.append(&code{op: oppush, v: true}) // found some value
c.append(&code{op: opstore, v: found})
defer c.lazy(func() *code {
- return &code{op: opjump, v: c.pc()} // ret
+ return &code{op: opjump, v: len(c.codes)}
})()
c.append(&code{op: oppop})
c.append(&code{op: opbacktrack})
setfork()
c.append(&code{op: opload, v: found})
- c.append(&code{op: opjumpifnot, v: c.pc() + 3})
+ c.append(&code{op: opjumpifnot, v: len(c.codes) + 3})
c.append(&code{op: opbacktrack}) // if found, backtrack
c.append(&code{op: oppop})
return c.compileQuery(r)
@@ -467,8 +486,9 @@ func (c *compiler) compileAlt(l, r *Query) error {
func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error {
switch op {
case OpAssign:
- // .foo.bar = f => setpath(["foo", "bar"]; f)
- if xs := l.toIndices(); xs != nil {
+ // optimize assignment operator with constant indexing and slicing
+ // .foo.[0].[1:2] = f => setpath(["foo",0,{"start":1,"end":2}]; f)
+ if xs := l.toIndices(nil); xs != nil {
// ref: compileCall
v := c.newVariable()
c.append(&code{op: opstore, v: v})
@@ -478,7 +498,7 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error {
}
c.append(&code{op: oppush, v: xs})
c.append(&code{op: opload, v: v})
- c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["setpath"].callback, 2, "setpath"}})
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["setpath"].callback, 2, "setpath"}})
return nil
}
fallthrough
@@ -517,7 +537,12 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error {
}
}
-func (c *compiler) compileBind(b *Bind) error {
+func (c *compiler) compileBind(e *Term, b *Bind) error {
+ c.append(&code{op: opdup})
+ c.append(&code{op: opexpbegin})
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
var pc int
var vs [][2]int
for i, p := range b.Patterns {
@@ -534,97 +559,86 @@ func (c *compiler) compileBind(b *Bind) error {
c.append(&code{op: opstore, v: v})
}
}
- vs, err = c.compilePattern(p)
- if err != nil {
+ if vs, err = c.compilePattern(vs[:0], p); err != nil {
return err
}
if i < len(b.Patterns)-1 {
defer c.lazy(func() *code {
return &code{op: opjump, v: pc}
})()
- pcc = c.pc()
+ pcc = len(c.codes)
}
}
if len(b.Patterns) > 1 {
- pc = c.pc()
+ pc = len(c.codes)
}
if len(b.Patterns) == 1 && c.codes[len(c.codes)-2].op == opexpbegin {
c.codes[len(c.codes)-2].op = opnop
} else {
- c.append(&code{op: opexpend}) // ref: compileTermSuffix
+ c.append(&code{op: opexpend})
}
return c.compileQuery(b.Body)
}
-func (c *compiler) compilePattern(p *Pattern) ([][2]int, error) {
+func (c *compiler) compilePattern(vs [][2]int, p *Pattern) ([][2]int, error) {
+ var err error
c.appendCodeInfo(p)
if p.Name != "" {
v := c.pushVariable(p.Name)
c.append(&code{op: opstore, v: v})
- return [][2]int{v}, nil
+ return append(vs, v), nil
} else if len(p.Array) > 0 {
- var vs [][2]int
v := c.newVariable()
c.append(&code{op: opstore, v: v})
for i, p := range p.Array {
- c.append(&code{op: oppush, v: i})
- c.append(&code{op: opload, v: v})
c.append(&code{op: opload, v: v})
- // ref: compileCall
- c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
- ns, err := c.compilePattern(p)
- if err != nil {
+ c.append(&code{op: opindexarray, v: i})
+ if vs, err = c.compilePattern(vs, p); err != nil {
return nil, err
}
- vs = append(vs, ns...)
}
return vs, nil
} else if len(p.Object) > 0 {
- var vs [][2]int
v := c.newVariable()
c.append(&code{op: opstore, v: v})
for _, kv := range p.Object {
var key, name string
- if kv.KeyOnly != "" {
- key, name = kv.KeyOnly[1:], kv.KeyOnly
- c.append(&code{op: oppush, v: key})
- } else if kv.Key != "" {
- key = kv.Key
- if key != "" && key[0] == '$' {
+ c.append(&code{op: opload, v: v})
+ if key = kv.Key; key != "" {
+ if key[0] == '$' {
key, name = key[1:], key
}
- c.append(&code{op: oppush, v: key})
} else if kv.KeyString != nil {
- c.append(&code{op: opload, v: v})
- if err := c.compileString(kv.KeyString, nil); err != nil {
- return nil, err
+ if key = kv.KeyString.Str; key == "" {
+ if err := c.compileString(kv.KeyString, nil); err != nil {
+ return nil, err
+ }
}
} else if kv.KeyQuery != nil {
- c.append(&code{op: opload, v: v})
if err := c.compileQuery(kv.KeyQuery); err != nil {
return nil, err
}
}
- c.append(&code{op: opload, v: v})
- c.append(&code{op: opload, v: v})
- // ref: compileCall
- c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
+ if key != "" {
+ c.append(&code{op: opindex, v: key})
+ } else {
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: oppush, v: nil})
+ // ref: compileCall
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}})
+ }
if name != "" {
if kv.Val != nil {
c.append(&code{op: opdup})
}
- ns, err := c.compilePattern(&Pattern{Name: name})
- if err != nil {
+ if vs, err = c.compilePattern(vs, &Pattern{Name: name}); err != nil {
return nil, err
}
- vs = append(vs, ns...)
}
if kv.Val != nil {
- ns, err := c.compilePattern(kv.Val)
- if err != nil {
+ if vs, err = c.compilePattern(vs, kv.Val); err != nil {
return nil, err
}
- vs = append(vs, ns...)
}
}
return vs, nil
@@ -650,17 +664,17 @@ func (c *compiler) compileIf(e *If) error {
}
pcc := len(c.codes)
setjumpifnot := c.lazy(func() *code {
- return &code{op: opjumpifnot, v: c.pc() + 1} // if falsy, skip then clause
+ return &code{op: opjumpifnot, v: len(c.codes)} // skip then clause
})
f = c.newScopeDepth()
if err := c.compileQuery(e.Then); err != nil {
return err
}
f()
- setjumpifnot()
defer c.lazy(func() *code {
- return &code{op: opjump, v: c.pc()} // jump to ret after else clause
+ return &code{op: opjump, v: len(c.codes)}
})()
+ setjumpifnot()
if len(e.Elif) > 0 {
return c.compileIf(&If{e.Elif[0].Cond, e.Elif[0].Then, e.Elif[1:], e.Else})
}
@@ -686,7 +700,7 @@ func (c *compiler) compileIf(e *If) error {
func (c *compiler) compileTry(e *Try) error {
c.appendCodeInfo(e)
setforktrybegin := c.lazy(func() *code {
- return &code{op: opforktrybegin, v: c.pc()}
+ return &code{op: opforktrybegin, v: len(c.codes)}
})
f := c.newScopeDepth()
if err := c.compileQuery(e.Body); err != nil {
@@ -695,7 +709,7 @@ func (c *compiler) compileTry(e *Try) error {
f()
c.append(&code{op: opforktryend})
defer c.lazy(func() *code {
- return &code{op: opjump, v: c.pc()}
+ return &code{op: opjump, v: len(c.codes)}
})()
setforktrybegin()
if e.Catch != nil {
@@ -709,9 +723,9 @@ func (c *compiler) compileTry(e *Try) error {
func (c *compiler) compileReduce(e *Reduce) error {
c.appendCodeInfo(e)
defer c.newScopeDepth()()
- defer c.lazy(func() *code {
- return &code{op: opfork, v: c.pc() - 2}
- })()
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)}
+ })
c.append(&code{op: opdup})
v := c.newVariable()
f := c.newScopeDepth()
@@ -723,7 +737,7 @@ func (c *compiler) compileReduce(e *Reduce) error {
if err := c.compileTerm(e.Term); err != nil {
return err
}
- if _, err := c.compilePattern(e.Pattern); err != nil {
+ if _, err := c.compilePattern(nil, e.Pattern); err != nil {
return err
}
c.append(&code{op: opload, v: v})
@@ -734,6 +748,7 @@ func (c *compiler) compileReduce(e *Reduce) error {
f()
c.append(&code{op: opstore, v: v})
c.append(&code{op: opbacktrack})
+ setfork()
c.append(&code{op: oppop})
c.append(&code{op: opload, v: v})
return nil
@@ -753,7 +768,7 @@ func (c *compiler) compileForeach(e *Foreach) error {
if err := c.compileTerm(e.Term); err != nil {
return err
}
- if _, err := c.compilePattern(e.Pattern); err != nil {
+ if _, err := c.compilePattern(nil, e.Pattern); err != nil {
return err
}
c.append(&code{op: opload, v: v})
@@ -774,9 +789,7 @@ func (c *compiler) compileForeach(e *Foreach) error {
func (c *compiler) compileLabel(e *Label) error {
c.appendCodeInfo(e)
v := c.pushVariable("$%" + e.Ident[1:])
- defer c.lazy(func() *code {
- return &code{op: opforklabel, v: v}
- })()
+ c.append(&code{op: opforklabel, v: v})
return c.compileQuery(e.Body)
}
@@ -787,21 +800,21 @@ func (c *compiler) compileBreak(label string) error {
}
c.append(&code{op: oppop})
c.append(&code{op: opload, v: v})
- c.append(&code{op: opcall, v: [3]interface{}{
- func(v interface{}, _ []interface{}) interface{} {
- return &breakError{label, v}
- },
- 0,
- "_break",
- }})
+ c.append(&code{op: opcall, v: [3]any{funcBreak(label), 0, "_break"}})
return nil
}
+func funcBreak(label string) func(any, []any) any {
+ return func(v any, _ []any) any {
+ return &breakError{label, v}
+ }
+}
+
func (c *compiler) compileTerm(e *Term) error {
if len(e.SuffixList) > 0 {
s := e.SuffixList[len(e.SuffixList)-1]
t := *e // clone without changing e
- (&t).SuffixList = t.SuffixList[:len(e.SuffixList)-1]
+ t.SuffixList = t.SuffixList[:len(e.SuffixList)-1]
return c.compileTermSuffix(&t, s)
}
switch e.Type {
@@ -827,11 +840,7 @@ func (c *compiler) compileTerm(e *Term) error {
case TermTypeArray:
return c.compileArray(e.Array)
case TermTypeNumber:
- v := normalizeNumber(json.Number(e.Number))
- if err, ok := v.(error); ok {
- return err
- }
- c.append(&code{op: opconst, v: v})
+ c.append(&code{op: opconst, v: toNumber(e.Number)})
return nil
case TermTypeUnary:
return c.compileUnary(e.Unary)
@@ -860,10 +869,15 @@ func (c *compiler) compileTerm(e *Term) error {
}
func (c *compiler) compileIndex(e *Term, x *Index) error {
- c.appendCodeInfo(x)
- if x.Name != "" {
- return c.compileCall("_index", []*Query{{Term: e}, {Term: &Term{Type: TermTypeString, Str: &String{Str: x.Name}}}})
+ if k := x.toIndexKey(); k != nil {
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
+ c.appendCodeInfo(x)
+ c.append(&code{op: opindex, v: k})
+ return nil
}
+ c.appendCodeInfo(x)
if x.Str != nil {
return c.compileCall("_index", []*Query{{Term: e}, {Term: &Term{Type: TermTypeString, Str: x.Str}}})
}
@@ -880,12 +894,11 @@ func (c *compiler) compileIndex(e *Term, x *Index) error {
}
func (c *compiler) compileFunc(e *Func) error {
- name := e.Name
if len(e.Args) == 0 {
- if f, v := c.lookupFuncOrVariable(name); f != nil {
+ if f, v := c.lookupFuncOrVariable(e.Name); f != nil {
return c.compileCallPc(f, e.Args)
} else if v != nil {
- if name[0] == '$' {
+ if e.Name[0] == '$' {
c.append(&code{op: oppop})
c.append(&code{op: opload, v: v.index})
} else {
@@ -893,8 +906,8 @@ func (c *compiler) compileFunc(e *Func) error {
c.append(&code{op: opcallpc})
}
return nil
- } else if name == "$ENV" || name == "env" {
- env := make(map[string]interface{})
+ } else if e.Name == "$ENV" || e.Name == "env" {
+ env := make(map[string]any)
if c.environLoader != nil {
for _, kv := range c.environLoader() {
if i := strings.IndexByte(kv, '='); i > 0 {
@@ -904,36 +917,42 @@ func (c *compiler) compileFunc(e *Func) error {
}
c.append(&code{op: opconst, v: env})
return nil
- } else if name[0] == '$' {
- return &variableNotFoundError{name}
+ } else if e.Name[0] == '$' {
+ return &variableNotFoundError{e.Name}
}
} else {
for i := len(c.scopes) - 1; i >= 0; i-- {
s := c.scopes[i]
for j := len(s.funcs) - 1; j >= 0; j-- {
- if f := s.funcs[j]; f.name == name && f.argcnt == len(e.Args) {
+ if f := s.funcs[j]; f.name == e.Name && f.argcnt == len(e.Args) {
return c.compileCallPc(f, e.Args)
}
}
}
}
- if name[0] == '_' {
- name = name[1:]
+ if f := c.lookupBuiltin(e.Name, len(e.Args)); f != nil {
+ return c.compileCallPc(f, e.Args)
}
- if fds, ok := builtinFuncDefs[name]; ok {
+ if fds, ok := builtinFuncDefs[e.Name]; ok {
for _, fd := range fds {
if len(fd.Args) == len(e.Args) {
if err := c.compileFuncDef(fd, true); err != nil {
return err
}
+ break
}
}
- s := c.scopes[0]
- for i := len(s.funcs) - 1; i >= 0; i-- {
- if f := s.funcs[i]; f.name == e.Name && f.argcnt == len(e.Args) {
- return c.compileCallPc(f, e.Args)
+ if len(fds) == 0 {
+ switch e.Name {
+ case "_assign":
+ c.compileAssign()
+ case "_modify":
+ c.compileModify()
}
}
+ if f := c.lookupBuiltin(e.Name, len(e.Args)); f != nil {
+ return c.compileCallPc(f, e.Args)
+ }
}
if fn, ok := internalFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
switch e.Name {
@@ -949,27 +968,27 @@ func (c *compiler) compileFunc(e *Func) error {
return nil
case "builtins":
return c.compileCallInternal(
- [3]interface{}{c.funcBuiltins, 0, e.Name},
+ [3]any{c.funcBuiltins, 0, e.Name},
e.Args,
true,
- false,
+ -1,
)
case "input":
if c.inputIter == nil {
return &inputNotAllowedError{}
}
return c.compileCallInternal(
- [3]interface{}{c.funcInput, 0, e.Name},
+ [3]any{c.funcInput, 0, e.Name},
e.Args,
true,
- false,
+ -1,
)
case "modulemeta":
return c.compileCallInternal(
- [3]interface{}{c.funcModulemeta, 0, e.Name},
+ [3]any{c.funcModulemeta, 0, e.Name},
e.Args,
true,
- false,
+ -1,
)
default:
return c.compileCall(e.Name, e.Args)
@@ -977,22 +996,130 @@ func (c *compiler) compileFunc(e *Func) error {
}
if fn, ok := c.customFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
if err := c.compileCallInternal(
- [3]interface{}{fn.callback, len(e.Args), e.Name},
+ [3]any{fn.callback, len(e.Args), e.Name},
e.Args,
true,
- false,
+ -1,
); err != nil {
return err
}
if fn.iter {
- c.append(&code{op: opeach})
+ c.append(&code{op: opiter})
}
return nil
}
return &funcNotFoundError{e}
}
-func (c *compiler) funcBuiltins(interface{}, []interface{}) interface{} {
+// Appends the compiled code for the assignment operator (`=`) to maximize
+// performance. Originally the operator was implemented as follows.
+//
+// def _assign(p; $x): reduce path(p) as $q (.; setpath($q; $x));
+//
+// To overcome the difficulty of reducing allocations on `setpath`, we use the
+// `allocator` type and track the allocated addresses during the reduction.
+func (c *compiler) compileAssign() {
+ defer c.appendBuiltin("_assign", 2)()
+ scope := c.newScope()
+ v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1}
+ x, a := [2]int{scope.id, 2}, [2]int{scope.id, 3}
+ // Cannot reuse v, p due to backtracking in x.
+ w, q := [2]int{scope.id, 4}, [2]int{scope.id, 5}
+ c.appends(
+ &code{op: opscope, v: [3]int{scope.id, 6, 2}},
+ &code{op: opstore, v: v}, // def _assign(p; $x):
+ &code{op: opstore, v: p},
+ &code{op: opstore, v: x},
+ &code{op: opload, v: v},
+ &code{op: opexpbegin},
+ &code{op: opload, v: x},
+ &code{op: opcallpc},
+ &code{op: opstore, v: x},
+ &code{op: opexpend},
+ &code{op: oppush, v: nil},
+ &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
+ &code{op: opstore, v: a},
+ &code{op: opload, v: v},
+ &code{op: opfork, v: len(c.codes) + 30}, // reduce [L1]
+ &code{op: opdup},
+ &code{op: opstore, v: w},
+ &code{op: oppathbegin}, // path(p)
+ &code{op: opload, v: p},
+ &code{op: opcallpc},
+ &code{op: opload, v: w},
+ &code{op: oppathend},
+ &code{op: opstore, v: q}, // as $q (.;
+ &code{op: opload, v: a}, // setpath($q; $x)
+ &code{op: opload, v: x},
+ &code{op: opload, v: q},
+ &code{op: opload, v: w},
+ &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
+ &code{op: opstore, v: w},
+ &code{op: opbacktrack}, // );
+ &code{op: oppop}, // [L1]
+ &code{op: opload, v: w},
+ &code{op: opret},
+ )
+}
+
+// Appends the compiled code for the update-assignment operator (`|=`) to
+// maximize performance. We use the `allocator` type, just like `_assign/2`.
+func (c *compiler) compileModify() {
+ defer c.appendBuiltin("_modify", 2)()
+ scope := c.newScope()
+ v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1}
+ f, d := [2]int{scope.id, 2}, [2]int{scope.id, 3}
+ a, l := [2]int{scope.id, 4}, [2]int{scope.id, 5}
+ c.appends(
+ &code{op: opscope, v: [3]int{scope.id, 6, 2}},
+ &code{op: opstore, v: v}, // def _modify(p; f):
+ &code{op: opstore, v: p},
+ &code{op: opstore, v: f},
+ &code{op: oppush, v: []any{}},
+ &code{op: opstore, v: d},
+ &code{op: oppush, v: nil},
+ &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
+ &code{op: opstore, v: a},
+ &code{op: opload, v: v},
+ &code{op: opfork, v: len(c.codes) + 39}, // reduce [L1]
+ &code{op: oppathbegin}, // path(p)
+ &code{op: opload, v: p},
+ &code{op: opcallpc},
+ &code{op: opload, v: v},
+ &code{op: oppathend},
+ &code{op: opstore, v: p}, // as $p (.;
+ &code{op: opforklabel, v: l}, // label $l |
+ &code{op: opload, v: v}, //
+ &code{op: opfork, v: len(c.codes) + 36}, // [L2]
+ &code{op: oppop}, // (getpath($p) |
+ &code{op: opload, v: a},
+ &code{op: opload, v: p},
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{internalFuncs["getpath"].callback, 1, "getpath"}},
+ &code{op: opload, v: f}, // f)
+ &code{op: opcallpc},
+ &code{op: opload, v: p}, // setpath($p; ...)
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
+ &code{op: opstore, v: v},
+ &code{op: opload, v: v}, // ., break $l
+ &code{op: opfork, v: len(c.codes) + 34}, // [L4]
+ &code{op: opjump, v: len(c.codes) + 38}, // [L3]
+ &code{op: opload, v: l}, // [L4]
+ &code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}},
+ &code{op: opload, v: p}, // append $p to $d [L2]
+ &code{op: opappend, v: d}, //
+ &code{op: opbacktrack}, // ) | [L3]
+ &code{op: oppop}, // delpaths($d); [L1]
+ &code{op: opload, v: a},
+ &code{op: opload, v: d},
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{funcDelpathsWithAllocator, 2, "_delpaths"}},
+ &code{op: opret},
+ )
+}
+
+func (c *compiler) funcBuiltins(any, []any) any {
type funcNameArity struct {
name string
arity int
@@ -1027,14 +1154,14 @@ func (c *compiler) funcBuiltins(interface{}, []interface{}) interface{} {
return xs[i].name < xs[j].name ||
xs[i].name == xs[j].name && xs[i].arity < xs[j].arity
})
- ys := make([]interface{}, len(xs))
+ ys := make([]any, len(xs))
for i, x := range xs {
ys[i] = x.name + "/" + strconv.Itoa(x.arity)
}
return ys
}
-func (c *compiler) funcInput(interface{}, []interface{}) interface{} {
+func (c *compiler) funcInput(any, []any) any {
v, ok := c.inputIter.Next()
if !ok {
return errors.New("break")
@@ -1042,7 +1169,7 @@ func (c *compiler) funcInput(interface{}, []interface{}) interface{} {
return normalizeNumbers(v)
}
-func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} {
+func (c *compiler) funcModulemeta(v any, _ []any) any {
s, ok := v.(string)
if !ok {
return &funcTypeError{"modulemeta", v}
@@ -1053,7 +1180,7 @@ func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} {
var q *Query
var err error
if moduleLoader, ok := c.moduleLoader.(interface {
- LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
+ LoadModuleWithMeta(string, map[string]any) (*Query, error)
}); ok {
if q, err = moduleLoader.LoadModuleWithMeta(s, nil); err != nil {
return err
@@ -1067,13 +1194,13 @@ func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} {
}
meta := q.Meta.ToValue()
if meta == nil {
- meta = make(map[string]interface{})
+ meta = make(map[string]any)
}
- var deps []interface{}
+ var deps []any
for _, i := range q.Imports {
v := i.Meta.ToValue()
if v == nil {
- v = make(map[string]interface{})
+ v = make(map[string]any)
} else {
for k := range v {
// dirty hack to remove the internal fields
@@ -1103,7 +1230,7 @@ func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} {
func (c *compiler) compileObject(e *Object) error {
c.appendCodeInfo(e)
if len(e.KeyVals) == 0 {
- c.append(&code{op: opconst, v: map[string]interface{}{}})
+ c.append(&code{op: opconst, v: map[string]any{}})
return nil
}
defer c.newScopeDepth()()
@@ -1128,7 +1255,7 @@ func (c *compiler) compileObject(e *Object) error {
return nil
}
}
- w := make(map[string]interface{}, l)
+ w := make(map[string]any, l)
for i := 0; i < l; i++ {
w[c.codes[pc+i*3].v.(string)] = c.codes[pc+i*3+2].v
}
@@ -1138,61 +1265,57 @@ func (c *compiler) compileObject(e *Object) error {
}
func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error {
- if kv.KeyOnly != "" {
- if kv.KeyOnly[0] == '$' {
- c.append(&code{op: oppush, v: kv.KeyOnly[1:]})
- c.append(&code{op: opload, v: v})
- return c.compileFunc(&Func{Name: kv.KeyOnly})
- }
- c.append(&code{op: oppush, v: kv.KeyOnly})
- c.append(&code{op: opload, v: v})
- return c.compileIndex(&Term{Type: TermTypeIdentity}, &Index{Name: kv.KeyOnly})
- } else if kv.KeyOnlyString != nil {
- c.append(&code{op: opload, v: v})
- if err := c.compileString(kv.KeyOnlyString, nil); err != nil {
- return err
- }
- c.append(&code{op: opdup})
- c.append(&code{op: opload, v: v})
- c.append(&code{op: opload, v: v})
- // ref: compileCall
- c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
- return nil
- } else {
- if kv.KeyQuery != nil {
- c.append(&code{op: opload, v: v})
- f := c.newScopeDepth()
- if err := c.compileQuery(kv.KeyQuery); err != nil {
- return err
+ if key := kv.Key; key != "" {
+ if key[0] == '$' {
+ if kv.Val == nil { // {$foo} == {foo:$foo}
+ c.append(&code{op: oppush, v: key[1:]})
}
- f()
- } else if kv.KeyString != nil {
c.append(&code{op: opload, v: v})
- if err := c.compileString(kv.KeyString, nil); err != nil {
+ if err := c.compileFunc(&Func{Name: key}); err != nil {
return err
}
- if d := c.codes[len(c.codes)-1]; d.op == opconst {
- c.codes[len(c.codes)-2] = &code{op: oppush, v: d.v}
- c.codes = c.codes[:len(c.codes)-1]
+ } else {
+ c.append(&code{op: oppush, v: key})
+ if kv.Val == nil { // {foo} == {foo:.foo}
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opindex, v: key})
}
- } else if kv.Key[0] == '$' {
+ }
+ } else if key := kv.KeyString; key != nil {
+ if key.Queries == nil {
+ c.append(&code{op: oppush, v: key.Str})
+ if kv.Val == nil { // {"foo"} == {"foo":.["foo"]}
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opindex, v: key.Str})
+ }
+ } else {
c.append(&code{op: opload, v: v})
- if err := c.compileFunc(&Func{Name: kv.Key}); err != nil {
+ if err := c.compileString(key, nil); err != nil {
return err
}
- } else {
- c.append(&code{op: oppush, v: kv.Key})
+ if kv.Val == nil {
+ c.append(&code{op: opdup})
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: oppush, v: nil})
+ // ref: compileCall
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}})
+ }
}
+ } else if kv.KeyQuery != nil {
c.append(&code{op: opload, v: v})
- return c.compileObjectVal(kv.Val)
- }
-}
-
-func (c *compiler) compileObjectVal(e *ObjectVal) error {
- for _, e := range e.Queries {
- if err := c.compileQuery(e); err != nil {
+ f := c.newScopeDepth()
+ if err := c.compileQuery(kv.KeyQuery); err != nil {
return err
}
+ f()
+ }
+ if kv.Val != nil {
+ c.append(&code{op: opload, v: v})
+ for _, e := range kv.Val.Queries {
+ if err := c.compileQuery(e); err != nil {
+ return err
+ }
+ }
}
return nil
}
@@ -1200,25 +1323,23 @@ func (c *compiler) compileObjectVal(e *ObjectVal) error {
func (c *compiler) compileArray(e *Array) error {
c.appendCodeInfo(e)
if e.Query == nil {
- c.append(&code{op: opconst, v: []interface{}{}})
+ c.append(&code{op: opconst, v: []any{}})
return nil
}
- c.append(&code{op: oppush, v: []interface{}{}})
+ c.append(&code{op: oppush, v: []any{}})
arr := c.newVariable()
c.append(&code{op: opstore, v: arr})
pc := len(c.codes)
- c.append(&code{op: opfork})
- defer func() {
- if pc < len(c.codes) {
- c.codes[pc].v = c.pc() - 2
- }
- }()
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)}
+ })
defer c.newScopeDepth()()
if err := c.compileQuery(e.Query); err != nil {
return err
}
c.append(&code{op: opappend, v: arr})
c.append(&code{op: opbacktrack})
+ setfork()
c.append(&code{op: oppop})
c.append(&code{op: opload, v: arr})
if e.Query.Op == OpPipe {
@@ -1236,7 +1357,7 @@ func (c *compiler) compileArray(e *Array) error {
return nil
}
}
- v := make([]interface{}, l)
+ v := make([]any, l)
for i := 0; i < l; i++ {
v[i] = c.codes[pc+i*2+l].v
}
@@ -1247,6 +1368,10 @@ func (c *compiler) compileArray(e *Array) error {
func (c *compiler) compileUnary(e *Unary) error {
c.appendCodeInfo(e)
+ if v := e.toNumber(); v != nil {
+ c.append(&code{op: opconst, v: v})
+ return nil
+ }
if err := c.compileTerm(e.Term); err != nil {
return err
}
@@ -1260,12 +1385,12 @@ func (c *compiler) compileUnary(e *Unary) error {
}
}
-func (c *compiler) compileFormat(fmt string, str *String) error {
- f := formatToFunc(fmt)
+func (c *compiler) compileFormat(format string, str *String) error {
+ f := formatToFunc(format)
if f == nil {
f = &Func{
Name: "format",
- Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: fmt[1:]}}}},
+ Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: format[1:]}}}},
}
}
if str == nil {
@@ -1274,8 +1399,8 @@ func (c *compiler) compileFormat(fmt string, str *String) error {
return c.compileString(str, f)
}
-func formatToFunc(fmt string) *Func {
- switch fmt {
+func formatToFunc(format string) *Func {
+ switch format {
case "@text":
return &Func{Name: "tostring"}
case "@json":
@@ -1328,14 +1453,14 @@ func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error {
if err := c.compileTerm(e); err != nil {
return err
}
- c.append(&code{op: opeach})
+ c.append(&code{op: opiter})
return nil
} else if s.Optional {
if len(e.SuffixList) > 0 {
- if u, ok := e.SuffixList[len(e.SuffixList)-1].toTerm(); ok {
- t := *e // clone without changing e
- (&t).SuffixList = t.SuffixList[:len(e.SuffixList)-1]
- if err := c.compileTerm(&t); err != nil {
+ if u := e.SuffixList[len(e.SuffixList)-1].toTerm(); u != nil {
+ // no need to clone (ref: compileTerm)
+ e.SuffixList = e.SuffixList[:len(e.SuffixList)-1]
+ if err := c.compileTerm(e); err != nil {
return err
}
e = u
@@ -1343,12 +1468,7 @@ func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error {
}
return c.compileTry(&Try{Body: &Query{Term: e}})
} else if s.Bind != nil {
- c.append(&code{op: opdup})
- c.append(&code{op: opexpbegin})
- if err := c.compileTerm(e); err != nil {
- return err
- }
- return c.compileBind(s.Bind)
+ return c.compileBind(e, s.Bind)
} else {
return fmt.Errorf("invalid suffix: %s", s)
}
@@ -1356,46 +1476,56 @@ func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error {
func (c *compiler) compileCall(name string, args []*Query) error {
fn := internalFuncs[name]
+ var indexing int
+ switch name {
+ case "_index", "_slice":
+ indexing = 1
+ case "getpath":
+ indexing = 0
+ default:
+ indexing = -1
+ }
if err := c.compileCallInternal(
- [3]interface{}{fn.callback, len(args), name},
+ [3]any{fn.callback, len(args), name},
args,
true,
- name == "_index" || name == "_slice",
+ indexing,
); err != nil {
return err
}
if fn.iter {
- c.append(&code{op: opeach})
+ c.append(&code{op: opiter})
}
return nil
}
func (c *compiler) compileCallPc(fn *funcinfo, args []*Query) error {
- return c.compileCallInternal(fn.pc, args, false, false)
+ return c.compileCallInternal(fn.pc, args, false, -1)
}
func (c *compiler) compileCallInternal(
- fn interface{}, args []*Query, internal, indexing bool) error {
+ fn any, args []*Query, internal bool, indexing int,
+) error {
if len(args) == 0 {
c.append(&code{op: opcall, v: fn})
return nil
}
- idx := c.newVariable()
- c.append(&code{op: opstore, v: idx})
- if indexing && len(args) > 1 {
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ if indexing >= 0 {
c.append(&code{op: opexpbegin})
}
for i := len(args) - 1; i >= 0; i-- {
- pc := c.pc() + 1 // skip opjump (ref: compileFuncDef)
+ pc := len(c.codes) + 1 // skip opjump (ref: compileFuncDef)
name := "lambda:" + strconv.Itoa(pc)
if err := c.compileFuncDef(&FuncDef{Name: name, Body: args[i]}, false); err != nil {
return err
}
if internal {
- switch c.pc() - pc {
+ switch len(c.codes) - pc {
case 2: // optimize identity argument (opscope, opret)
j := len(c.codes) - 3
- c.codes[j] = &code{op: opload, v: idx}
+ c.codes[j] = &code{op: opload, v: v}
c.codes = c.codes[:j+1]
s := c.scopes[len(c.scopes)-1]
s.funcs = s.funcs[:len(s.funcs)-1]
@@ -1406,7 +1536,7 @@ func (c *compiler) compileCallInternal(
c.codes[j] = &code{op: oppush, v: c.codes[j+2].v}
c.codes = c.codes[:j+1]
} else {
- c.codes[j] = &code{op: opload, v: idx}
+ c.codes[j] = &code{op: opload, v: v}
c.codes[j+1] = c.codes[j+2]
c.codes = c.codes[:j+2]
}
@@ -1414,14 +1544,14 @@ func (c *compiler) compileCallInternal(
s.funcs = s.funcs[:len(s.funcs)-1]
c.deleteCodeInfo(name)
default:
- c.append(&code{op: opload, v: idx})
+ c.append(&code{op: opload, v: v})
c.append(&code{op: oppushpc, v: pc})
c.append(&code{op: opcallpc})
}
} else {
c.append(&code{op: oppushpc, v: pc})
}
- if indexing && i == 1 {
+ if i == indexing {
if c.codes[len(c.codes)-2].op == opexpbegin {
c.codes[len(c.codes)-2] = c.codes[len(c.codes)-1]
c.codes = c.codes[:len(c.codes)-1]
@@ -1430,7 +1560,11 @@ func (c *compiler) compileCallInternal(
}
}
}
- c.append(&code{op: opload, v: idx})
+ if indexing > 0 {
+ c.append(&code{op: oppush, v: nil})
+ } else {
+ c.append(&code{op: opload, v: v})
+ }
c.append(&code{op: opcall, v: fn})
return nil
}
@@ -1439,8 +1573,8 @@ func (c *compiler) append(code *code) {
c.codes = append(c.codes, code)
}
-func (c *compiler) pc() int {
- return len(c.codes)
+func (c *compiler) appends(codes ...*code) {
+ c.codes = append(c.codes, codes...)
}
func (c *compiler) lazy(f func() *code) func() {
diff --git a/vendor/github.com/itchyny/gojq/debug.go b/vendor/github.com/itchyny/gojq/debug.go
index 4a346fb2..ad3d7216 100644
--- a/vendor/github.com/itchyny/gojq/debug.go
+++ b/vendor/github.com/itchyny/gojq/debug.go
@@ -1,5 +1,5 @@
-//go:build debug
-// +build debug
+//go:build gojq_debug
+// +build gojq_debug
package gojq
@@ -32,7 +32,7 @@ type codeinfo struct {
pc int
}
-func (c *compiler) appendCodeInfo(x interface{}) {
+func (c *compiler) appendCodeInfo(x any) {
if !debug {
return
}
@@ -47,7 +47,7 @@ func (c *compiler) appendCodeInfo(x interface{}) {
if c.codes[len(c.codes)-1] != nil && c.codes[len(c.codes)-1].op == opret && strings.HasPrefix(name, "end of ") {
diff = -1
}
- c.codeinfos = append(c.codeinfos, codeinfo{name, c.pc() + diff})
+ c.codeinfos = append(c.codeinfos, codeinfo{name, len(c.codes) + diff})
}
func (c *compiler) deleteCodeInfo(name string) {
@@ -182,7 +182,7 @@ func debugOperand(c *code) string {
switch v := c.v.(type) {
case int:
return strconv.Itoa(v)
- case [3]interface{}:
+ case [3]any:
return fmt.Sprintf("%s/%d", v[2], v[1])
default:
panic(c)
@@ -192,17 +192,21 @@ func debugOperand(c *code) string {
}
}
-func debugValue(v interface{}) string {
+func debugValue(v any) string {
switch v := v.(type) {
case Iter:
return fmt.Sprintf("gojq.Iter(%#v)", v)
+ case []pathValue:
+ return fmt.Sprintf("[]gojq.pathValue(%v)", v)
case [2]int:
return fmt.Sprintf("[%d,%d]", v[0], v[1])
case [3]int:
return fmt.Sprintf("[%d,%d,%d]", v[0], v[1], v[2])
- case [3]interface{}:
+ case [3]any:
return fmt.Sprintf("[%v,%v,%v]", v[0], v[1], v[2])
+ case allocator:
+ return fmt.Sprintf("%v", v)
default:
- return previewValue(v)
+ return Preview(v)
}
}
diff --git a/vendor/github.com/itchyny/gojq/deepequal.go b/vendor/github.com/itchyny/gojq/deepequal.go
deleted file mode 100644
index 37c56e42..00000000
--- a/vendor/github.com/itchyny/gojq/deepequal.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package gojq
-
-import (
- "math"
- "math/big"
-)
-
-func deepEqual(l, r interface{}) bool {
- return binopTypeSwitch(l, r,
- func(l, r int) interface{} {
- return l == r
- },
- func(l, r float64) interface{} {
- return l == r || math.IsNaN(l) && math.IsNaN(r)
- },
- func(l, r *big.Int) interface{} {
- return l.Cmp(r) == 0
- },
- func(l, r string) interface{} {
- return l == r
- },
- func(l, r []interface{}) interface{} {
- if len(l) != len(r) {
- return false
- }
- for i, v := range l {
- if !deepEqual(v, r[i]) {
- return false
- }
- }
- return true
- },
- func(l, r map[string]interface{}) interface{} {
- if len(l) != len(r) {
- return false
- }
- for k, v := range l {
- if !deepEqual(v, r[k]) {
- return false
- }
- }
- return true
- },
- func(l, r interface{}) interface{} {
- return l == r
- },
- ).(bool)
-}
diff --git a/vendor/github.com/itchyny/gojq/encoder.go b/vendor/github.com/itchyny/gojq/encoder.go
index c7905f96..3233e8a9 100644
--- a/vendor/github.com/itchyny/gojq/encoder.go
+++ b/vendor/github.com/itchyny/gojq/encoder.go
@@ -14,25 +14,29 @@ import (
// Marshal returns the jq-flavored JSON encoding of v.
//
-// This method only accepts limited types (nil, bool, int, float64, *big.Int,
-// string, []interface{} and map[string]interface{}) because these are the
-// possible types a gojq iterator can emit. This method marshals NaN to null,
-// truncates infinities to (+|-) math.MaxFloat64, uses \b and \f in strings,
-// and does not escape '<' and '>' for embedding in HTML. These behaviors are
-// based on the marshaler of jq command and different from Go standard library
-// method json.Marshal.
-func Marshal(v interface{}) ([]byte, error) {
+// This method accepts only limited types (nil, bool, int, float64, *big.Int,
+// string, []any, and map[string]any) because these are the possible types a
+// gojq iterator can emit. This method marshals NaN to null, truncates
+// infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, and does not
+// escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors are based on
+// the marshaler of jq command, and different from json.Marshal in the Go
+// standard library. Note that the result is not safe to embed in HTML.
+func Marshal(v any) ([]byte, error) {
var b bytes.Buffer
(&encoder{w: &b}).encode(v)
return b.Bytes(), nil
}
-func jsonMarshal(v interface{}) string {
+func jsonMarshal(v any) string {
var sb strings.Builder
(&encoder{w: &sb}).encode(v)
return sb.String()
}
+func jsonEncodeString(sb *strings.Builder, v string) {
+ (&encoder{w: sb}).encodeString(v)
+}
+
type encoder struct {
w interface {
io.Writer
@@ -42,7 +46,7 @@ type encoder struct {
buf [64]byte
}
-func (e *encoder) encode(v interface{}) {
+func (e *encoder) encode(v any) {
switch v := v.(type) {
case nil:
e.w.WriteString("null")
@@ -60,12 +64,12 @@ func (e *encoder) encode(v interface{}) {
e.w.Write(v.Append(e.buf[:0], 10))
case string:
e.encodeString(v)
- case []interface{}:
+ case []any:
e.encodeArray(v)
- case map[string]interface{}:
- e.encodeMap(v)
+ case map[string]any:
+ e.encodeObject(v)
default:
- panic(fmt.Sprintf("invalid value: %v", v))
+ panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v))
}
}
@@ -80,12 +84,12 @@ func (e *encoder) encodeFloat64(f float64) {
} else if f <= -math.MaxFloat64 {
f = -math.MaxFloat64
}
- fmt := byte('f')
+ format := byte('f')
if x := math.Abs(f); x != 0 && x < 1e-6 || x >= 1e21 {
- fmt = 'e'
+ format = 'e'
}
- buf := strconv.AppendFloat(e.buf[:0], f, fmt, -1, 64)
- if fmt == 'e' {
+ buf := strconv.AppendFloat(e.buf[:0], f, format, -1, 64)
+ if format == 'e' {
// clean up e-09 to e-9
if n := len(buf); n >= 4 && buf[n-4] == 'e' && buf[n-3] == '-' && buf[n-2] == '0' {
buf[n-2] = buf[n-1]
@@ -101,30 +105,31 @@ func (e *encoder) encodeString(s string) {
start := 0
for i := 0; i < len(s); {
if b := s[i]; b < utf8.RuneSelf {
- if ']' <= b && b <= '~' || '#' <= b && b <= '[' || b == ' ' || b == '!' {
+ if ' ' <= b && b <= '~' && b != '"' && b != '\\' {
i++
continue
}
if start < i {
e.w.WriteString(s[start:i])
}
- e.w.WriteByte('\\')
switch b {
- case '\\', '"':
- e.w.WriteByte(b)
+ case '"':
+ e.w.WriteString(`\"`)
+ case '\\':
+ e.w.WriteString(`\\`)
case '\b':
- e.w.WriteByte('b')
+ e.w.WriteString(`\b`)
case '\f':
- e.w.WriteByte('f')
+ e.w.WriteString(`\f`)
case '\n':
- e.w.WriteByte('n')
+ e.w.WriteString(`\n`)
case '\r':
- e.w.WriteByte('r')
+ e.w.WriteString(`\r`)
case '\t':
- e.w.WriteByte('t')
+ e.w.WriteString(`\t`)
default:
const hex = "0123456789abcdef"
- e.w.WriteString("u00")
+ e.w.WriteString(`\u00`)
e.w.WriteByte(hex[b>>4])
e.w.WriteByte(hex[b&0xF])
}
@@ -150,7 +155,7 @@ func (e *encoder) encodeString(s string) {
e.w.WriteByte('"')
}
-func (e *encoder) encodeArray(vs []interface{}) {
+func (e *encoder) encodeArray(vs []any) {
e.w.WriteByte('[')
for i, v := range vs {
if i > 0 {
@@ -161,11 +166,11 @@ func (e *encoder) encodeArray(vs []interface{}) {
e.w.WriteByte(']')
}
-func (e *encoder) encodeMap(vs map[string]interface{}) {
+func (e *encoder) encodeObject(vs map[string]any) {
e.w.WriteByte('{')
type keyVal struct {
key string
- val interface{}
+ val any
}
kvs := make([]keyVal, len(vs))
var i int
diff --git a/vendor/github.com/itchyny/gojq/env.go b/vendor/github.com/itchyny/gojq/env.go
index dd1859c4..bf058eda 100644
--- a/vendor/github.com/itchyny/gojq/env.go
+++ b/vendor/github.com/itchyny/gojq/env.go
@@ -7,7 +7,7 @@ type env struct {
stack *stack
paths *stack
scopes *scopeStack
- values []interface{}
+ values []any
codes []*code
codeinfos []codeinfo
forks []fork
@@ -15,7 +15,7 @@ type env struct {
offset int
expdepth int
label int
- args [32]interface{} // len(env.args) > maxarity
+ args [32]any // len(env.args) > maxarity
ctx context.Context
}
diff --git a/vendor/github.com/itchyny/gojq/error.go b/vendor/github.com/itchyny/gojq/error.go
index c13e9777..695463f3 100644
--- a/vendor/github.com/itchyny/gojq/error.go
+++ b/vendor/github.com/itchyny/gojq/error.go
@@ -1,23 +1,18 @@
package gojq
-import (
- "fmt"
- "math/big"
- "strconv"
- "strings"
-)
+import "strconv"
// ValueError is an interface for errors with a value for internal function.
// Return an error implementing this interface when you want to catch error
// values (not error messages) by try-catch, just like built-in error function.
-// Refer to WithFunction to add a custom internal function.
+// Refer to [WithFunction] to add a custom internal function.
type ValueError interface {
error
- Value() interface{}
+ Value() any
}
type expectedObjectError struct {
- v interface{}
+ v any
}
func (err *expectedObjectError) Error() string {
@@ -25,7 +20,7 @@ func (err *expectedObjectError) Error() string {
}
type expectedArrayError struct {
- v interface{}
+ v any
}
func (err *expectedArrayError) Error() string {
@@ -33,7 +28,7 @@ func (err *expectedArrayError) Error() string {
}
type expectedStringError struct {
- v interface{}
+ v any
}
func (err *expectedStringError) Error() string {
@@ -41,7 +36,7 @@ func (err *expectedStringError) Error() string {
}
type iteratorError struct {
- v interface{}
+ v any
}
func (err *iteratorError) Error() string {
@@ -49,15 +44,15 @@ func (err *iteratorError) Error() string {
}
type arrayIndexTooLargeError struct {
- v interface{}
+ v any
}
func (err *arrayIndexTooLargeError) Error() string {
- return "array index too large: " + previewValue(err.v)
+ return "array index too large: " + Preview(err.v)
}
type objectKeyNotStringError struct {
- v interface{}
+ v any
}
func (err *objectKeyNotStringError) Error() string {
@@ -65,15 +60,23 @@ func (err *objectKeyNotStringError) Error() string {
}
type arrayIndexNotNumberError struct {
- v interface{}
+ v any
}
func (err *arrayIndexNotNumberError) Error() string {
return "expected a number for indexing an array but got: " + typeErrorPreview(err.v)
}
+type stringIndexNotNumberError struct {
+ v any
+}
+
+func (err *stringIndexNotNumberError) Error() string {
+ return "expected a number for indexing a string but got: " + typeErrorPreview(err.v)
+}
+
type expectedStartEndError struct {
- v interface{}
+ v any
}
func (err *expectedStartEndError) Error() string {
@@ -82,7 +85,7 @@ func (err *expectedStartEndError) Error() string {
type lengthMismatchError struct {
name string
- v, x []interface{}
+ v, x []any
}
func (err *lengthMismatchError) Error() string {
@@ -105,7 +108,7 @@ func (err *funcNotFoundError) Error() string {
type funcTypeError struct {
name string
- v interface{}
+ v any
}
func (err *funcTypeError) Error() string {
@@ -113,7 +116,7 @@ func (err *funcTypeError) Error() string {
}
type exitCodeError struct {
- value interface{}
+ value any
code int
halt bool
}
@@ -129,7 +132,7 @@ func (err *exitCodeError) IsEmptyError() bool {
return err.value == nil
}
-func (err *exitCodeError) Value() interface{} {
+func (err *exitCodeError) Value() any {
return err.value
}
@@ -141,25 +144,41 @@ func (err *exitCodeError) IsHaltError() bool {
return err.halt
}
-type funcContainsError struct {
- l, r interface{}
+type containsTypeError struct {
+ l, r any
}
-func (err *funcContainsError) Error() string {
- return "cannot check contains(" + previewValue(err.r) + "): " + typeErrorPreview(err.l)
+func (err *containsTypeError) Error() string {
+ return "cannot check contains(" + Preview(err.r) + "): " + typeErrorPreview(err.l)
}
type hasKeyTypeError struct {
- l, r interface{}
+ l, r any
}
func (err *hasKeyTypeError) Error() string {
return "cannot check whether " + typeErrorPreview(err.l) + " has a key: " + typeErrorPreview(err.r)
}
+type flattenDepthError struct {
+ v float64
+}
+
+func (err *flattenDepthError) Error() string {
+ return "flatten depth must not be negative: " + typeErrorPreview(err.v)
+}
+
+type joinTypeError struct {
+ v any
+}
+
+func (err *joinTypeError) Error() string {
+ return "cannot join: " + typeErrorPreview(err.v)
+}
+
type unaryTypeError struct {
name string
- v interface{}
+ v any
}
func (err *unaryTypeError) Error() string {
@@ -168,7 +187,7 @@ func (err *unaryTypeError) Error() string {
type binopTypeError struct {
name string
- l, r interface{}
+ l, r any
}
func (err *binopTypeError) Error() string {
@@ -176,7 +195,7 @@ func (err *binopTypeError) Error() string {
}
type zeroDivisionError struct {
- l, r interface{}
+ l, r any
}
func (err *zeroDivisionError) Error() string {
@@ -184,11 +203,11 @@ func (err *zeroDivisionError) Error() string {
}
type zeroModuloError struct {
- l, r interface{}
+ l, r any
}
func (err *zeroModuloError) Error() string {
- return "cannot modulo " + typeErrorPreview(err.l) + " by: " + typeErrorPreview(err.r) + ""
+ return "cannot modulo " + typeErrorPreview(err.l) + " by: " + typeErrorPreview(err.r)
}
type formatNotFoundError struct {
@@ -199,21 +218,13 @@ func (err *formatNotFoundError) Error() string {
return "format not defined: " + err.n
}
-type formatCsvTsvRowError struct {
+type formatRowError struct {
typ string
- v interface{}
+ v any
}
-func (err *formatCsvTsvRowError) Error() string {
- return "invalid " + err.typ + " row: " + typeErrorPreview(err.v)
-}
-
-type formatShError struct {
- v interface{}
-}
-
-func (err *formatShError) Error() string {
- return "cannot escape for shell: " + typeErrorPreview(err.v)
+func (err *formatRowError) Error() string {
+ return "@" + err.typ + " cannot format an array including: " + typeErrorPreview(err.v)
}
type tooManyVariableValuesError struct{}
@@ -248,7 +259,7 @@ func (err *variableNameError) Error() string {
type breakError struct {
n string
- v interface{}
+ v any
}
func (err *breakError) Error() string {
@@ -268,7 +279,7 @@ func (err *tryEndError) Error() string {
}
type invalidPathError struct {
- v interface{}
+ v any
}
func (err *invalidPathError) Error() string {
@@ -276,7 +287,7 @@ func (err *invalidPathError) Error() string {
}
type invalidPathIterError struct {
- v interface{}
+ v any
}
func (err *invalidPathIterError) Error() string {
@@ -284,24 +295,24 @@ func (err *invalidPathIterError) Error() string {
}
type getpathError struct {
- v, path interface{}
+ v, path any
}
func (err *getpathError) Error() string {
- return "cannot getpath with " + previewValue(err.path) + " against: " + typeErrorPreview(err.v) + ""
+ return "cannot getpath with " + Preview(err.path) + " against: " + typeErrorPreview(err.v)
}
type queryParseError struct {
- typ, fname, contents string
- err error
+ fname, contents string
+ err error
}
-func (err *queryParseError) QueryParseError() (string, string, string, error) {
- return err.typ, err.fname, err.contents, err.err
+func (err *queryParseError) QueryParseError() (string, string, error) {
+ return err.fname, err.contents, err.err
}
func (err *queryParseError) Error() string {
- return "invalid " + err.typ + ": " + err.fname + ": " + err.err.Error()
+ return "invalid query: " + err.fname + ": " + err.err.Error()
}
type jsonParseError struct {
@@ -317,113 +328,13 @@ func (err *jsonParseError) Error() string {
return "invalid json: " + err.fname + ": " + err.err.Error()
}
-func typeErrorPreview(v interface{}) string {
- if _, ok := v.(Iter); ok {
- return "gojq.Iter"
- }
- p := preview(v)
- if p != "" {
- p = " (" + p + ")"
- }
- return typeof(v) + p
-}
-
-func typeof(v interface{}) string {
- switch v := v.(type) {
+func typeErrorPreview(v any) string {
+ switch v.(type) {
case nil:
return "null"
- case bool:
- return "boolean"
- case int, float64, *big.Int:
- return "number"
- case string:
- return "string"
- case []interface{}:
- return "array"
- case map[string]interface{}:
- return "object"
+ case Iter:
+ return "gojq.Iter"
default:
- panic(fmt.Sprintf("invalid value: %v", v))
- }
-}
-
-type limitedWriter struct {
- buf []byte
- off int
-}
-
-func (w *limitedWriter) Write(bs []byte) (int, error) {
- n := copy(w.buf[w.off:], bs)
- if w.off += n; w.off == len(w.buf) {
- panic(nil)
- }
- return n, nil
-}
-
-func (w *limitedWriter) WriteByte(b byte) error {
- w.buf[w.off] = b
- if w.off++; w.off == len(w.buf) {
- panic(nil)
- }
- return nil
-}
-
-func (w *limitedWriter) WriteString(s string) (int, error) {
- n := copy(w.buf[w.off:], s)
- if w.off += n; w.off == len(w.buf) {
- panic(nil)
- }
- return n, nil
-}
-
-func (w *limitedWriter) String() string {
- return string(w.buf[:w.off])
-}
-
-func jsonLimitedMarshal(v interface{}, n int) (s string) {
- w := &limitedWriter{buf: make([]byte, n)}
- defer func() {
- recover()
- s = w.String()
- }()
- (&encoder{w: w}).encode(v)
- return
-}
-
-func preview(v interface{}) string {
- if v == nil {
- return ""
- }
- s := jsonLimitedMarshal(v, 32)
- if l := 30; len(s) > l {
- var trailing string
- switch v.(type) {
- case string:
- trailing = ` ..."`
- case []interface{}:
- trailing = " ...]"
- case map[string]interface{}:
- trailing = " ...}"
- default:
- trailing = " ..."
- }
- var sb strings.Builder
- sb.Grow(l + 5)
- for _, c := range s {
- sb.WriteRune(c)
- if sb.Len() >= l-len(trailing) {
- sb.WriteString(trailing)
- break
- }
- }
- s = sb.String()
- }
- return s
-}
-
-func previewValue(v interface{}) string {
- if v == nil {
- return "null"
+ return TypeOf(v) + " (" + Preview(v) + ")"
}
- return preview(v)
}
diff --git a/vendor/github.com/itchyny/gojq/execute.go b/vendor/github.com/itchyny/gojq/execute.go
index d861c628..d43ef3e9 100644
--- a/vendor/github.com/itchyny/gojq/execute.go
+++ b/vendor/github.com/itchyny/gojq/execute.go
@@ -2,11 +2,12 @@ package gojq
import (
"context"
- "fmt"
+ "math"
+ "reflect"
"sort"
)
-func (env *env) execute(bc *Code, v interface{}, vars ...interface{}) Iter {
+func (env *env) execute(bc *Code, v any, vars ...any) Iter {
env.codes = bc.codes
env.codeinfos = bc.codeinfos
env.push(v)
@@ -17,7 +18,7 @@ func (env *env) execute(bc *Code, v interface{}, vars ...interface{}) Iter {
return env
}
-func (env *env) Next() (interface{}, bool) {
+func (env *env) Next() (any, bool) {
var err error
pc, callpc, index := env.pc, len(env.codes)-1, -1
backtrack, hasCtx := env.backtrack, env.ctx != context.Background()
@@ -42,9 +43,9 @@ loop:
case oppop:
env.pop()
case opdup:
- x := env.pop()
- env.push(x)
- env.push(x)
+ v := env.pop()
+ env.push(v)
+ env.push(v)
case opconst:
env.pop()
env.push(code.v)
@@ -57,7 +58,7 @@ loop:
break loop
}
n := code.v.(int)
- m := make(map[string]interface{}, n)
+ m := make(map[string]any, n)
for i := 0; i < n; i++ {
v, k := env.pop(), env.pop()
s, ok := k.(string)
@@ -70,7 +71,7 @@ loop:
env.push(m)
case opappend:
i := env.index(code.v.([2]int))
- env.values[i] = append(env.values[i].([]interface{}), env.pop())
+ env.values[i] = append(env.values[i].([]any), env.pop())
case opfork:
if backtrack {
if err != nil {
@@ -78,9 +79,8 @@ loop:
}
pc, backtrack = code.v.(int), false
goto loop
- } else {
- env.pushfork(pc)
}
+ env.pushfork(pc)
case opforktrybegin:
if backtrack {
if err == nil {
@@ -90,6 +90,8 @@ loop:
case *tryEndError:
err = er.err
break loop
+ case *breakError:
+ break loop
case ValueError:
if er, ok := er.(*exitCodeError); ok && er.halt {
break loop
@@ -107,18 +109,16 @@ loop:
}
pc, backtrack, err = code.v.(int), false, nil
goto loop
- } else {
- env.pushfork(pc)
}
+ env.pushfork(pc)
case opforktryend:
if backtrack {
if err != nil {
err = &tryEndError{err}
}
break loop
- } else {
- env.pushfork(pc)
}
+ env.pushfork(pc)
case opforkalt:
if backtrack {
if err == nil {
@@ -126,9 +126,8 @@ loop:
}
pc, backtrack, err = code.v.(int), false, nil
goto loop
- } else {
- env.pushfork(pc)
}
+ env.pushfork(pc)
case opforklabel:
if backtrack {
label := env.pop()
@@ -136,13 +135,12 @@ loop:
err = nil
}
break loop
- } else {
- env.push(env.label)
- env.pushfork(pc)
- env.pop()
- env.values[env.index(code.v.([2]int))] = env.label
- env.label++
}
+ env.push(env.label)
+ env.pushfork(pc)
+ env.pop()
+ env.values[env.index(code.v.([2]int))] = env.label
+ env.label++
case opbacktrack:
break loop
case opjump:
@@ -153,6 +151,30 @@ loop:
pc = code.v.(int)
goto loop
}
+ case opindex, opindexarray:
+ if backtrack {
+ break loop
+ }
+ p, v := code.v, env.pop()
+ if code.op == opindexarray && v != nil {
+ if _, ok := v.([]any); !ok {
+ err = &expectedArrayError{v}
+ break loop
+ }
+ }
+ w := funcIndex2(nil, v, p)
+ if e, ok := w.(error); ok {
+ err = e
+ break loop
+ }
+ env.push(w)
+ if !env.paths.empty() && env.expdepth == 0 {
+ if !env.pathIntact(v) {
+ err = &invalidPathError{v}
+ break loop
+ }
+ env.paths.push(pathValue{path: p, value: w})
+ }
case opcall:
if backtrack {
break loop
@@ -161,13 +183,13 @@ loop:
case int:
pc, callpc, index = v, pc, env.scopes.index
goto loop
- case [3]interface{}:
+ case [3]any:
argcnt := v[1].(int)
x, args := env.pop(), env.args[:argcnt]
for i := 0; i < argcnt; i++ {
args[i] = env.pop()
}
- w := v[0].(func(interface{}, []interface{}) interface{})(x, args)
+ w := v[0].(func(any, []any) any)(x, args)
if e, ok := w.(error); ok {
if er, ok := e.(*exitCodeError); !ok || er.value != nil || er.halt {
err = e
@@ -175,14 +197,31 @@ loop:
break loop
}
env.push(w)
- if !env.paths.empty() {
- var ps []interface{}
- ps, err = env.pathEntries(v[2].(string), x, args)
- if err != nil {
- break loop
- }
- for _, p := range ps {
- env.paths.push(pathValue{path: p, value: w})
+ if !env.paths.empty() && env.expdepth == 0 {
+ switch v[2].(string) {
+ case "_index":
+ if x = args[0]; !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ env.paths.push(pathValue{path: args[1], value: w})
+ case "_slice":
+ if x = args[0]; !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ env.paths.push(pathValue{
+ path: map[string]any{"start": args[2], "end": args[1]},
+ value: w,
+ })
+ case "getpath":
+ if !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ for _, p := range args[0].([]any) {
+ env.paths.push(pathValue{path: p, value: w})
+ }
}
}
default:
@@ -199,7 +238,7 @@ loop:
goto loop
case opscope:
xs := code.v.([3]int)
- var saveindex, outerindex, limit int
+ var saveindex, outerindex int
if index == env.scopes.index {
if callpc >= 0 {
saveindex = index
@@ -207,7 +246,7 @@ loop:
callpc, saveindex = env.popscope()
}
} else {
- env.scopes.save(&saveindex, &limit)
+ saveindex, _ = env.scopes.save()
env.scopes.index = index
}
if outerindex = index; outerindex >= 0 {
@@ -218,7 +257,7 @@ loop:
env.scopes.push(scope{xs[0], env.offset, callpc, saveindex, outerindex})
env.offset += xs[1]
if env.offset > len(env.values) {
- vs := make([]interface{}, env.offset*2)
+ vs := make([]any, env.offset*2)
copy(vs, env.values)
env.values = vs
}
@@ -230,7 +269,7 @@ loop:
if env.scopes.empty() {
return env.pop(), true
}
- case opeach:
+ case opiter:
if err != nil {
break loop
}
@@ -239,9 +278,8 @@ loop:
switch v := env.pop().(type) {
case []pathValue:
xs = v
- case []interface{}:
- if !env.paths.empty() && env.expdepth == 0 &&
- !deepEqual(v, env.paths.top().(pathValue).value) {
+ case []any:
+ if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) {
err = &invalidPathIterError{v}
break loop
}
@@ -252,9 +290,8 @@ loop:
for i, v := range v {
xs[i] = pathValue{path: i, value: v}
}
- case map[string]interface{}:
- if !env.paths.empty() && env.expdepth == 0 &&
- !deepEqual(v, env.paths.top().(pathValue).value) {
+ case map[string]any:
+ if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) {
err = &invalidPathIterError{v}
break loop
}
@@ -271,10 +308,6 @@ loop:
return xs[i].path.(string) < xs[j].path.(string)
})
case Iter:
- if !env.paths.empty() && env.expdepth == 0 {
- err = &invalidPathIterError{v}
- break loop
- }
if w, ok := v.Next(); ok {
env.push(v)
env.pushfork(pc)
@@ -289,6 +322,7 @@ loop:
break loop
default:
err = &iteratorError{v}
+ env.push(emptyIter{})
break loop
}
if len(xs) > 1 {
@@ -312,18 +346,13 @@ loop:
if backtrack {
break loop
}
- if env.expdepth > 0 {
- panic(fmt.Sprintf("unexpected expdepth: %d", env.expdepth))
- }
env.pop()
- x := env.pop()
- if deepEqual(x, env.paths.top().(pathValue).value) {
- env.push(env.poppaths())
- env.expdepth = env.paths.pop().(int)
- } else {
- err = &invalidPathError{x}
+ if v := env.pop(); !env.pathIntact(v) {
+ err = &invalidPathError{v}
break loop
}
+ env.push(env.poppaths())
+ env.expdepth = env.paths.pop().(int)
default:
panic(code.op)
}
@@ -338,11 +367,11 @@ loop:
return nil, false
}
-func (env *env) push(v interface{}) {
+func (env *env) push(v any) {
env.stack.push(v)
}
-func (env *env) pop() interface{} {
+func (env *env) pop() any {
return env.stack.pop()
}
@@ -357,9 +386,9 @@ func (env *env) popscope() (int, int) {
func (env *env) pushfork(pc int) {
f := fork{pc: pc, expdepth: env.expdepth}
- env.stack.save(&f.stackindex, &f.stacklimit)
- env.scopes.save(&f.scopeindex, &f.scopelimit)
- env.paths.save(&f.pathindex, &f.pathlimit)
+ f.stackindex, f.stacklimit = env.stack.save()
+ f.scopeindex, f.scopelimit = env.scopes.save()
+ f.pathindex, f.pathlimit = env.paths.save()
env.forks = append(env.forks, f)
env.debugForks(pc, ">>>")
}
@@ -386,39 +415,28 @@ func (env *env) index(v [2]int) int {
}
type pathValue struct {
- path, value interface{}
+ path, value any
}
-func (env *env) pathEntries(name string, x interface{}, args []interface{}) ([]interface{}, error) {
- switch name {
- case "_index":
- if env.expdepth > 0 {
- return nil, nil
- } else if !deepEqual(args[0], env.paths.top().(pathValue).value) {
- return nil, &invalidPathError{x}
- }
- return []interface{}{args[1]}, nil
- case "_slice":
- if env.expdepth > 0 {
- return nil, nil
- } else if !deepEqual(args[0], env.paths.top().(pathValue).value) {
- return nil, &invalidPathError{x}
+func (env *env) pathIntact(v any) bool {
+ w := env.paths.top().(pathValue).value
+ switch v := v.(type) {
+ case []any, map[string]any:
+ switch w.(type) {
+ case []any, map[string]any:
+ v, w := reflect.ValueOf(v), reflect.ValueOf(w)
+ return v.Pointer() == w.Pointer() && v.Len() == w.Len()
}
- return []interface{}{map[string]interface{}{"start": args[2], "end": args[1]}}, nil
- case "getpath":
- if env.expdepth > 0 {
- return nil, nil
- } else if !deepEqual(x, env.paths.top().(pathValue).value) {
- return nil, &invalidPathError{x}
+ case float64:
+ if w, ok := w.(float64); ok {
+ return v == w || math.IsNaN(v) && math.IsNaN(w)
}
- return args[0].([]interface{}), nil
- default:
- return nil, nil
}
+ return v == w
}
-func (env *env) poppaths() []interface{} {
- var xs []interface{}
+func (env *env) poppaths() []any {
+ var xs []any
for {
p := env.paths.pop().(pathValue)
if p.path == nil {
diff --git a/vendor/github.com/itchyny/gojq/func.go b/vendor/github.com/itchyny/gojq/func.go
index ca4caa69..d94a7a47 100644
--- a/vendor/github.com/itchyny/gojq/func.go
+++ b/vendor/github.com/itchyny/gojq/func.go
@@ -4,9 +4,11 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
+ "io"
"math"
"math/big"
"net/url"
+ "reflect"
"regexp"
"sort"
"strconv"
@@ -30,7 +32,7 @@ const (
type function struct {
argcount int
iter bool
- callback func(interface{}, []interface{}) interface{}
+ callback func(any, []any) any
}
func (fn function) accept(cnt int) bool {
@@ -51,15 +53,26 @@ func init() {
"utf8bytelength": argFunc0(funcUtf8ByteLength),
"keys": argFunc0(funcKeys),
"has": argFunc1(funcHas),
+ "to_entries": argFunc0(funcToEntries),
+ "from_entries": argFunc0(funcFromEntries),
"add": argFunc0(funcAdd),
"tonumber": argFunc0(funcToNumber),
"tostring": argFunc0(funcToString),
"type": argFunc0(funcType),
"reverse": argFunc0(funcReverse),
"contains": argFunc1(funcContains),
+ "indices": argFunc1(funcIndices),
+ "index": argFunc1(funcIndex),
+ "rindex": argFunc1(funcRindex),
+ "startswith": argFunc1(funcStartsWith),
+ "endswith": argFunc1(funcEndsWith),
+ "ltrimstr": argFunc1(funcLtrimstr),
+ "rtrimstr": argFunc1(funcRtrimstr),
"explode": argFunc0(funcExplode),
"implode": argFunc0(funcImplode),
"split": {argcount1 | argcount2, false, funcSplit},
+ "ascii_downcase": argFunc0(funcASCIIDowncase),
+ "ascii_upcase": argFunc0(funcASCIIUpcase),
"tojson": argFunc0(funcToJSON),
"fromjson": argFunc0(funcFromJSON),
"format": argFunc1(funcFormat),
@@ -70,11 +83,8 @@ func init() {
"_tosh": argFunc0(funcToSh),
"_tobase64": argFunc0(funcToBase64),
"_tobase64d": argFunc0(funcToBase64d),
- "_index": argFunc2(funcIndex),
+ "_index": argFunc2(funcIndex2),
"_slice": argFunc3(funcSlice),
- "_indices": argFunc1(funcIndices),
- "_lindex": argFunc1(funcLindex),
- "_rindex": argFunc1(funcRindex),
"_plus": argFunc0(funcOpPlus),
"_negate": argFunc0(funcOpNegate),
"_add": argFunc2(funcOpAdd),
@@ -89,13 +99,18 @@ func init() {
"_less": argFunc2(funcOpLt),
"_greatereq": argFunc2(funcOpGe),
"_lesseq": argFunc2(funcOpLe),
+ "flatten": {argcount0 | argcount1, false, funcFlatten},
"_range": {argcount3, true, funcRange},
+ "min": argFunc0(funcMin),
"_min_by": argFunc1(funcMinBy),
+ "max": argFunc0(funcMax),
"_max_by": argFunc1(funcMaxBy),
+ "sort": argFunc0(funcSort),
"_sort_by": argFunc1(funcSortBy),
"_group_by": argFunc1(funcGroupBy),
+ "unique": argFunc0(funcUnique),
"_unique_by": argFunc1(funcUniqueBy),
- "_join": argFunc1(funcJoin),
+ "join": argFunc1(funcJoin),
"sin": mathFunc("sin", math.Sin),
"cos": mathFunc("cos", math.Cos),
"tan": mathFunc("tan", math.Tan),
@@ -176,47 +191,47 @@ func init() {
"strptime": argFunc1(funcStrptime),
"now": argFunc0(funcNow),
"_match": argFunc3(funcMatch),
+ "_capture": argFunc0(funcCapture),
"error": {argcount0 | argcount1, false, funcError},
"halt": argFunc0(funcHalt),
"halt_error": {argcount0 | argcount1, false, funcHaltError},
- "_type_error": argFunc1(internalfuncTypeError),
}
}
-func argFunc0(fn func(interface{}) interface{}) function {
+func argFunc0(f func(any) any) function {
return function{
- argcount0, false, func(v interface{}, _ []interface{}) interface{} {
- return fn(v)
+ argcount0, false, func(v any, _ []any) any {
+ return f(v)
},
}
}
-func argFunc1(fn func(_, _ interface{}) interface{}) function {
+func argFunc1(f func(_, _ any) any) function {
return function{
- argcount1, false, func(v interface{}, args []interface{}) interface{} {
- return fn(v, args[0])
+ argcount1, false, func(v any, args []any) any {
+ return f(v, args[0])
},
}
}
-func argFunc2(fn func(_, _, _ interface{}) interface{}) function {
+func argFunc2(f func(_, _, _ any) any) function {
return function{
- argcount2, false, func(v interface{}, args []interface{}) interface{} {
- return fn(v, args[0], args[1])
+ argcount2, false, func(v any, args []any) any {
+ return f(v, args[0], args[1])
},
}
}
-func argFunc3(fn func(_, _, _, _ interface{}) interface{}) function {
+func argFunc3(f func(_, _, _, _ any) any) function {
return function{
- argcount3, false, func(v interface{}, args []interface{}) interface{} {
- return fn(v, args[0], args[1], args[2])
+ argcount3, false, func(v any, args []any) any {
+ return f(v, args[0], args[1], args[2])
},
}
}
func mathFunc(name string, f func(float64) float64) function {
- return argFunc0(func(v interface{}) interface{} {
+ return argFunc0(func(v any) any {
x, ok := toFloat(v)
if !ok {
return &funcTypeError{name, v}
@@ -226,7 +241,7 @@ func mathFunc(name string, f func(float64) float64) function {
}
func mathFunc2(name string, f func(_, _ float64) float64) function {
- return argFunc2(func(_, x, y interface{}) interface{} {
+ return argFunc2(func(_, x, y any) any {
l, ok := toFloat(x)
if !ok {
return &funcTypeError{name, x}
@@ -240,7 +255,7 @@ func mathFunc2(name string, f func(_, _ float64) float64) function {
}
func mathFunc3(name string, f func(_, _, _ float64) float64) function {
- return argFunc3(func(_, a, b, c interface{}) interface{} {
+ return argFunc3(func(_, a, b, c any) any {
x, ok := toFloat(a)
if !ok {
return &funcTypeError{name, a}
@@ -257,14 +272,10 @@ func mathFunc3(name string, f func(_, _, _ float64) float64) function {
})
}
-func funcLength(v interface{}) interface{} {
+func funcLength(v any) any {
switch v := v.(type) {
- case []interface{}:
- return len(v)
- case map[string]interface{}:
- return len(v)
- case string:
- return len([]rune(v))
+ case nil:
+ return 0
case int:
if v >= 0 {
return v
@@ -277,128 +288,207 @@ func funcLength(v interface{}) interface{} {
return v
}
return new(big.Int).Abs(v)
- case nil:
- return 0
+ case string:
+ return len([]rune(v))
+ case []any:
+ return len(v)
+ case map[string]any:
+ return len(v)
default:
return &funcTypeError{"length", v}
}
}
-func funcUtf8ByteLength(v interface{}) interface{} {
- switch v := v.(type) {
- case string:
- return len(v)
- default:
+func funcUtf8ByteLength(v any) any {
+ s, ok := v.(string)
+ if !ok {
return &funcTypeError{"utf8bytelength", v}
}
+ return len(s)
}
-func funcKeys(v interface{}) interface{} {
+func funcKeys(v any) any {
switch v := v.(type) {
- case []interface{}:
- w := make([]interface{}, len(v))
+ case []any:
+ w := make([]any, len(v))
for i := range v {
w[i] = i
}
return w
- case map[string]interface{}:
- w := make([]string, len(v))
- var i int
- for k := range v {
+ case map[string]any:
+ w := make([]any, len(v))
+ for i, k := range keys(v) {
w[i] = k
- i++
}
- sort.Strings(w)
- u := make([]interface{}, len(v))
- for i, x := range w {
- u[i] = x
- }
- return u
+ return w
default:
return &funcTypeError{"keys", v}
}
}
-func funcHas(v, x interface{}) interface{} {
+func keys(v map[string]any) []string {
+ w := make([]string, len(v))
+ var i int
+ for k := range v {
+ w[i] = k
+ i++
+ }
+ sort.Strings(w)
+ return w
+}
+
+func values(v any) ([]any, bool) {
+ switch v := v.(type) {
+ case []any:
+ return v, true
+ case map[string]any:
+ vs := make([]any, len(v))
+ for i, k := range keys(v) {
+ vs[i] = v[k]
+ }
+ return vs, true
+ default:
+ return nil, false
+ }
+}
+
+func funcHas(v, x any) any {
switch v := v.(type) {
- case []interface{}:
+ case []any:
if x, ok := toInt(x); ok {
return 0 <= x && x < len(v)
}
- return &hasKeyTypeError{v, x}
- case map[string]interface{}:
- switch x := x.(type) {
- case string:
+ case map[string]any:
+ if x, ok := x.(string); ok {
_, ok := v[x]
return ok
- default:
- return &hasKeyTypeError{v, x}
}
case nil:
return false
- default:
- return &hasKeyTypeError{v, x}
}
+ return &hasKeyTypeError{v, x}
}
-func funcAdd(v interface{}) interface{} {
- if vs, ok := v.(map[string]interface{}); ok {
- xs := make([]string, len(vs))
- var i int
- for k := range vs {
- xs[i] = k
- i++
+func funcToEntries(v any) any {
+ switch v := v.(type) {
+ case []any:
+ w := make([]any, len(v))
+ for i, x := range v {
+ w[i] = map[string]any{"key": i, "value": x}
+ }
+ return w
+ case map[string]any:
+ w := make([]any, len(v))
+ for i, k := range keys(v) {
+ w[i] = map[string]any{"key": k, "value": v[k]}
}
- sort.Strings(xs)
- us := make([]interface{}, len(vs))
- for i, x := range xs {
- us[i] = vs[x]
+ return w
+ default:
+ return &funcTypeError{"to_entries", v}
+ }
+}
+
+func funcFromEntries(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &funcTypeError{"from_entries", v}
+ }
+ w := make(map[string]any, len(vs))
+ for _, v := range vs {
+ switch v := v.(type) {
+ case map[string]any:
+ var (
+ key string
+ value any
+ ok bool
+ )
+ for _, k := range [4]string{"key", "Key", "name", "Name"} {
+ if k := v[k]; k != nil && k != false {
+ if key, ok = k.(string); !ok {
+ return &objectKeyNotStringError{k}
+ }
+ break
+ }
+ }
+ if !ok {
+ return &objectKeyNotStringError{nil}
+ }
+ for _, k := range [2]string{"value", "Value"} {
+ if value, ok = v[k]; ok {
+ break
+ }
+ }
+ w[key] = value
+ default:
+ return &funcTypeError{"from_entries", v}
}
- v = us
}
- vs, ok := v.([]interface{})
+ return w
+}
+
+func funcAdd(v any) any {
+ vs, ok := values(v)
if !ok {
return &funcTypeError{"add", v}
}
v = nil
for _, x := range vs {
- switch y := x.(type) {
- case map[string]interface{}:
+ switch x := x.(type) {
+ case nil:
+ continue
+ case string:
switch w := v.(type) {
case nil:
- m := make(map[string]interface{}, len(y))
- for k, e := range y {
- m[k] = e
- }
- v = m
+ var sb strings.Builder
+ sb.WriteString(x)
+ v = &sb
continue
- case map[string]interface{}:
- for k, e := range y {
- w[k] = e
- }
+ case *strings.Builder:
+ w.WriteString(x)
continue
}
- case []interface{}:
+ case []any:
switch w := v.(type) {
case nil:
- s := make([]interface{}, len(y))
- copy(s, y)
+ s := make([]any, len(x))
+ copy(s, x)
v = s
continue
- case []interface{}:
- v = append(w, y...)
+ case []any:
+ v = append(w, x...)
+ continue
+ }
+ case map[string]any:
+ switch w := v.(type) {
+ case nil:
+ m := make(map[string]any, len(x))
+ for k, e := range x {
+ m[k] = e
+ }
+ v = m
+ continue
+ case map[string]any:
+ for k, e := range x {
+ w[k] = e
+ }
continue
}
}
+ if sb, ok := v.(*strings.Builder); ok {
+ v = sb.String()
+ }
v = funcOpAdd(nil, v, x)
if err, ok := v.(error); ok {
return err
}
}
+ if sb, ok := v.(*strings.Builder); ok {
+ v = sb.String()
+ }
return v
}
-func funcToNumber(v interface{}) interface{} {
+func funcToNumber(v any) any {
switch v := v.(type) {
case int, float64, *big.Int:
return v
@@ -406,130 +496,227 @@ func funcToNumber(v interface{}) interface{} {
if !newLexer(v).validNumber() {
return fmt.Errorf("invalid number: %q", v)
}
- return normalizeNumber(json.Number(v))
+ return toNumber(v)
default:
return &funcTypeError{"tonumber", v}
}
}
-func funcToString(v interface{}) interface{} {
+func toNumber(v string) any {
+ return normalizeNumber(json.Number(v))
+}
+
+func funcToString(v any) any {
if s, ok := v.(string); ok {
return s
}
return funcToJSON(v)
}
-func funcType(v interface{}) interface{} {
- return typeof(v)
+func funcType(v any) any {
+ return TypeOf(v)
}
-func funcReverse(v interface{}) interface{} {
- vs, ok := v.([]interface{})
+func funcReverse(v any) any {
+ vs, ok := v.([]any)
if !ok {
- return &expectedArrayError{v}
+ return &funcTypeError{"reverse", v}
}
- ws := make([]interface{}, len(vs))
+ ws := make([]any, len(vs))
for i, v := range vs {
ws[len(ws)-i-1] = v
}
return ws
}
-func funcContains(v, x interface{}) interface{} {
- switch v := v.(type) {
- case nil:
- if x == nil {
- return true
- }
- case bool:
- switch x := x.(type) {
- case bool:
- if v == x {
- return true
- }
- }
- }
+func funcContains(v, x any) any {
return binopTypeSwitch(v, x,
- func(l, r int) interface{} { return l == r },
- func(l, r float64) interface{} { return l == r },
- func(l, r *big.Int) interface{} { return l.Cmp(r) == 0 },
- func(l, r string) interface{} { return strings.Contains(l, r) },
- func(l, r []interface{}) interface{} {
- for _, x := range r {
- var found bool
- for _, y := range l {
- if funcContains(y, x) == true {
- found = true
- break
+ func(l, r int) any { return l == r },
+ func(l, r float64) any { return l == r },
+ func(l, r *big.Int) any { return l.Cmp(r) == 0 },
+ func(l, r string) any { return strings.Contains(l, r) },
+ func(l, r []any) any {
+ R:
+ for _, r := range r {
+ for _, l := range l {
+ if funcContains(l, r) == true {
+ continue R
}
}
- if !found {
- return false
- }
+ return false
}
return true
},
- func(l, r map[string]interface{}) interface{} {
- for k, rk := range r {
- lk, ok := l[k]
- if !ok {
- return false
- }
- c := funcContains(lk, rk)
- if _, ok := c.(error); ok {
- return false
- }
- if c == false {
+ func(l, r map[string]any) any {
+ if len(l) < len(r) {
+ return false
+ }
+ for k, r := range r {
+ if l, ok := l[k]; !ok || funcContains(l, r) != true {
return false
}
}
return true
},
- func(l, r interface{}) interface{} { return &funcContainsError{l, r} },
+ func(l, r any) any {
+ if l == r {
+ return true
+ }
+ return &containsTypeError{l, r}
+ },
)
}
-func funcExplode(v interface{}) interface{} {
+func funcIndices(v, x any) any {
+ return indexFunc(v, x, indices)
+}
+
+func indices(vs, xs []any) any {
+ var rs []any
+ if len(xs) == 0 {
+ return rs
+ }
+ for i := 0; i <= len(vs)-len(xs); i++ {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ rs = append(rs, i)
+ }
+ }
+ return rs
+}
+
+func funcIndex(v, x any) any {
+ return indexFunc(v, x, func(vs, xs []any) any {
+ if len(xs) == 0 {
+ return nil
+ }
+ for i := 0; i <= len(vs)-len(xs); i++ {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ return i
+ }
+ }
+ return nil
+ })
+}
+
+func funcRindex(v, x any) any {
+ return indexFunc(v, x, func(vs, xs []any) any {
+ if len(xs) == 0 {
+ return nil
+ }
+ for i := len(vs) - len(xs); i >= 0; i-- {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ return i
+ }
+ }
+ return nil
+ })
+}
+
+func indexFunc(v, x any, f func(_, _ []any) any) any {
switch v := v.(type) {
+ case nil:
+ return nil
+ case []any:
+ switch x := x.(type) {
+ case []any:
+ return f(v, x)
+ default:
+ return f(v, []any{x})
+ }
case string:
- return explode(v)
+ if x, ok := x.(string); ok {
+ return f(explode(v), explode(x))
+ }
+ return &expectedStringError{x}
default:
+ return &expectedArrayError{v}
+ }
+}
+
+func funcStartsWith(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &funcTypeError{"startswith", v}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &funcTypeError{"startswith", x}
+ }
+ return strings.HasPrefix(s, t)
+}
+
+func funcEndsWith(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &funcTypeError{"endswith", v}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &funcTypeError{"endswith", x}
+ }
+ return strings.HasSuffix(s, t)
+}
+
+func funcLtrimstr(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return v
+ }
+ t, ok := x.(string)
+ if !ok {
+ return v
+ }
+ return strings.TrimPrefix(s, t)
+}
+
+func funcRtrimstr(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return v
+ }
+ t, ok := x.(string)
+ if !ok {
+ return v
+ }
+ return strings.TrimSuffix(s, t)
+}
+
+func funcExplode(v any) any {
+ s, ok := v.(string)
+ if !ok {
return &funcTypeError{"explode", v}
}
+ return explode(s)
}
-func explode(s string) []interface{} {
- rs := []int32(s)
- xs := make([]interface{}, len(rs))
- for i, r := range rs {
+func explode(s string) []any {
+ xs := make([]any, len([]rune(s)))
+ var i int
+ for _, r := range s {
xs[i] = int(r)
+ i++
}
return xs
}
-func funcImplode(v interface{}) interface{} {
- switch v := v.(type) {
- case []interface{}:
- return implode(v)
- default:
+func funcImplode(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
return &funcTypeError{"implode", v}
}
-}
-
-func implode(v []interface{}) interface{} {
var sb strings.Builder
- sb.Grow(len(v))
- for _, r := range v {
- if r, ok := toInt(r); ok && 0 <= r && r <= utf8.MaxRune {
+ sb.Grow(len(vs))
+ for _, v := range vs {
+ if r, ok := toInt(v); ok && 0 <= r && r <= utf8.MaxRune {
sb.WriteRune(rune(r))
} else {
- return &funcTypeError{"implode", v}
+ return &funcTypeError{"implode", vs}
}
}
return sb.String()
}
-func funcSplit(v interface{}, args []interface{}) interface{} {
+func funcSplit(v any, args []any) any {
s, ok := v.(string)
if !ok {
return &funcTypeError{"split", v}
@@ -556,43 +743,71 @@ func funcSplit(v interface{}, args []interface{}) interface{} {
}
ss = r.Split(s, -1)
}
- xs := make([]interface{}, len(ss))
+ xs := make([]any, len(ss))
for i, s := range ss {
xs[i] = s
}
return xs
}
-func funcToJSON(v interface{}) interface{} {
- return jsonMarshal(v)
+func funcASCIIDowncase(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &funcTypeError{"ascii_downcase", v}
+ }
+ return strings.Map(func(r rune) rune {
+ if 'A' <= r && r <= 'Z' {
+ return r + ('a' - 'A')
+ }
+ return r
+ }, s)
}
-func funcFromJSON(v interface{}) interface{} {
- switch v := v.(type) {
- case string:
- var w interface{}
- err := json.Unmarshal([]byte(v), &w)
- if err != nil {
- return err
+func funcASCIIUpcase(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &funcTypeError{"ascii_upcase", v}
+ }
+ return strings.Map(func(r rune) rune {
+ if 'a' <= r && r <= 'z' {
+ return r - ('a' - 'A')
}
- return w
- default:
+ return r
+ }, s)
+}
+
+func funcToJSON(v any) any {
+ return jsonMarshal(v)
+}
+
+func funcFromJSON(v any) any {
+ s, ok := v.(string)
+ if !ok {
return &funcTypeError{"fromjson", v}
}
+ var w any
+ dec := json.NewDecoder(strings.NewReader(s))
+ dec.UseNumber()
+ if err := dec.Decode(&w); err != nil {
+ return err
+ }
+ if _, err := dec.Token(); err != io.EOF {
+ return &funcTypeError{"fromjson", v}
+ }
+ return normalizeNumbers(w)
}
-func funcFormat(v, x interface{}) interface{} {
- switch x := x.(type) {
- case string:
- fmt := "@" + x
- f := formatToFunc(fmt)
- if f == nil {
- return &formatNotFoundError{fmt}
- }
- return internalFuncs[f.Name].callback(v, nil)
- default:
+func funcFormat(v, x any) any {
+ s, ok := x.(string)
+ if !ok {
return &funcTypeError{"format", x}
}
+ format := "@" + s
+ f := formatToFunc(format)
+ if f == nil {
+ return &formatNotFoundError{format}
+ }
+ return internalFuncs[f.Name].callback(v, nil)
}
var htmlEscaper = strings.NewReplacer(
@@ -603,7 +818,7 @@ var htmlEscaper = strings.NewReplacer(
`"`, """,
)
-func funcToHTML(v interface{}) interface{} {
+func funcToHTML(v any) any {
switch x := funcToString(v).(type) {
case string:
return htmlEscaper.Replace(x)
@@ -612,7 +827,7 @@ func funcToHTML(v interface{}) interface{} {
}
}
-func funcToURI(v interface{}) interface{} {
+func funcToURI(v any) any {
switch x := funcToString(v).(type) {
case string:
return url.QueryEscape(x)
@@ -621,9 +836,14 @@ func funcToURI(v interface{}) interface{} {
}
}
-func funcToCSV(v interface{}) interface{} {
- return funcToCSVTSV("csv", v, ",", func(s string) string {
- return `"` + strings.ReplaceAll(s, `"`, `""`) + `"`
+var csvEscaper = strings.NewReplacer(
+ `"`, `""`,
+ "\x00", `\0`,
+)
+
+func funcToCSV(v any) any {
+ return formatJoin("csv", v, ",", func(s string) string {
+ return `"` + csvEscaper.Replace(s) + `"`
})
}
@@ -632,72 +852,49 @@ var tsvEscaper = strings.NewReplacer(
"\r", `\r`,
"\n", `\n`,
"\\", `\\`,
+ "\x00", `\0`,
)
-func funcToTSV(v interface{}) interface{} {
- return funcToCSVTSV("tsv", v, "\t", func(s string) string {
- return tsvEscaper.Replace(s)
- })
+func funcToTSV(v any) any {
+ return formatJoin("tsv", v, "\t", tsvEscaper.Replace)
}
-func funcToCSVTSV(typ string, v interface{}, sep string, escape func(string) string) interface{} {
- switch xs := v.(type) {
- case []interface{}:
- ys := make([]string, len(xs))
- for i, x := range xs {
- y, err := toCSVTSV(typ, x, escape)
- if err != nil {
- return err
- }
- ys[i] = y
- }
- return strings.Join(ys, sep)
- default:
- return &expectedArrayError{v}
- }
-}
+var shEscaper = strings.NewReplacer(
+ "'", `'\''`,
+ "\x00", `\0`,
+)
-func toCSVTSV(typ string, v interface{}, escape func(string) string) (string, error) {
- switch v := v.(type) {
- case map[string]interface{}, []interface{}:
- return "", &formatCsvTsvRowError{typ, v}
- case string:
- return escape(v), nil
- default:
- if s := jsonMarshal(v); s != "null" {
- return s, nil
- }
- return "", nil
+func funcToSh(v any) any {
+ if _, ok := v.([]any); !ok {
+ v = []any{v}
}
+ return formatJoin("sh", v, " ", func(s string) string {
+ return "'" + shEscaper.Replace(s) + "'"
+ })
}
-func funcToSh(v interface{}) interface{} {
- var xs []interface{}
- if w, ok := v.([]interface{}); ok {
- xs = w
- } else {
- xs = []interface{}{v}
+func formatJoin(typ string, v any, sep string, escape func(string) string) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &funcTypeError{"@" + typ, v}
}
- var s strings.Builder
- for i, x := range xs {
- if i > 0 {
- s.WriteByte(' ')
- }
- switch x := x.(type) {
- case map[string]interface{}, []interface{}:
- return &formatShError{x}
+ ss := make([]string, len(vs))
+ for i, v := range vs {
+ switch v := v.(type) {
+ case []any, map[string]any:
+ return &formatRowError{typ, v}
case string:
- s.WriteByte('\'')
- s.WriteString(strings.ReplaceAll(x, "'", `'\''`))
- s.WriteByte('\'')
+ ss[i] = escape(v)
default:
- s.WriteString(jsonMarshal(x))
+ if s := jsonMarshal(v); s != "null" || typ == "sh" {
+ ss[i] = s
+ }
}
}
- return s.String()
+ return strings.Join(ss, sep)
}
-func funcToBase64(v interface{}) interface{} {
+func funcToBase64(v any) any {
switch x := funcToString(v).(type) {
case string:
return base64.StdEncoding.EncodeToString([]byte(x))
@@ -706,7 +903,7 @@ func funcToBase64(v interface{}) interface{} {
}
}
-func funcToBase64d(v interface{}) interface{} {
+func funcToBase64d(v any) any {
switch x := funcToString(v).(type) {
case string:
if i := strings.IndexRune(x, base64.StdPadding); i >= 0 {
@@ -722,48 +919,39 @@ func funcToBase64d(v interface{}) interface{} {
}
}
-func funcIndex(_, v, x interface{}) interface{} {
+func funcIndex2(_, v, x any) any {
switch x := x.(type) {
case string:
switch v := v.(type) {
case nil:
return nil
- case map[string]interface{}:
+ case map[string]any:
return v[x]
default:
return &expectedObjectError{v}
}
case int, float64, *big.Int:
- idx, _ := toInt(x)
+ i, _ := toInt(x)
switch v := v.(type) {
case nil:
return nil
- case []interface{}:
- return funcIndexSlice(nil, nil, &idx, v)
+ case []any:
+ return index(v, i)
case string:
- switch v := funcIndexSlice(nil, nil, &idx, explode(v)).(type) {
- case []interface{}:
- return implode(v)
- case int:
- return implode([]interface{}{v})
- case nil:
- return ""
- default:
- panic(v)
- }
+ return indexString(v, i)
default:
return &expectedArrayError{v}
}
- case []interface{}:
+ case []any:
switch v := v.(type) {
case nil:
return nil
- case []interface{}:
+ case []any:
return indices(v, x)
default:
return &expectedArrayError{v}
}
- case map[string]interface{}:
+ case map[string]any:
if v == nil {
return nil
}
@@ -777,192 +965,163 @@ func funcIndex(_, v, x interface{}) interface{} {
}
return funcSlice(nil, v, end, start)
default:
- return &objectKeyNotStringError{x}
+ switch v.(type) {
+ case []any:
+ return &arrayIndexNotNumberError{x}
+ case string:
+ return &stringIndexNotNumberError{x}
+ default:
+ return &objectKeyNotStringError{x}
+ }
}
}
-func indices(vs, xs []interface{}) interface{} {
- var rs []interface{}
- if len(xs) == 0 {
- return rs
+func index(vs []any, i int) any {
+ i = clampIndex(i, -1, len(vs))
+ if 0 <= i && i < len(vs) {
+ return vs[i]
}
- for i := 0; i < len(vs) && i < len(vs)-len(xs)+1; i++ {
- var neq bool
- for j, y := range xs {
- if neq = compare(vs[i+j], y) != 0; neq {
- break
+ return nil
+}
+
+func indexString(s string, i int) any {
+ l := len([]rune(s))
+ i = clampIndex(i, -1, l)
+ if 0 <= i && i < l {
+ for _, r := range s {
+ if i--; i < 0 {
+ return string(r)
}
}
- if !neq {
- rs = append(rs, i)
- }
}
- return rs
+ return nil
}
-func funcSlice(_, v, end, start interface{}) (r interface{}) {
- if w, ok := v.(string); ok {
- v = explode(w)
- defer func() {
- switch s := r.(type) {
- case []interface{}:
- r = implode(s)
- case int:
- r = implode([]interface{}{s})
- case nil:
- r = ""
- case error:
- default:
- panic(r)
- }
- }()
- }
+func funcSlice(_, v, e, s any) (r any) {
switch v := v.(type) {
case nil:
return nil
- case []interface{}:
- if start != nil {
- if start, ok := toInt(start); ok {
- if end != nil {
- if end, ok := toInt(end); ok {
- return funcIndexSlice(&start, &end, nil, v)
- }
- return &arrayIndexNotNumberError{end}
- }
- return funcIndexSlice(&start, nil, nil, v)
- }
- return &arrayIndexNotNumberError{start}
- }
- if end != nil {
- if end, ok := toInt(end); ok {
- return funcIndexSlice(nil, &end, nil, v)
- }
- return &arrayIndexNotNumberError{end}
- }
- return v
+ case []any:
+ return slice(v, e, s)
+ case string:
+ return sliceString(v, e, s)
default:
return &expectedArrayError{v}
}
}
-func funcIndexSlice(start, end, index *int, a []interface{}) interface{} {
- aa := a
- if index != nil {
- i := toIndex(aa, *index)
- if i < 0 {
- return nil
+func slice(vs []any, e, s any) any {
+ var start, end int
+ if s != nil {
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, len(vs))
+ } else {
+ return &arrayIndexNotNumberError{s}
}
- return a[i]
}
- if end != nil {
- i := toIndex(aa, *end)
- if i == -1 {
- i = len(a)
- } else if i == -2 {
- i = 0
+ if e != nil {
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, len(vs))
+ } else {
+ return &arrayIndexNotNumberError{e}
+ }
+ } else {
+ end = len(vs)
+ }
+ return vs[start:end]
+}
+
+func sliceString(v string, e, s any) any {
+ var start, end int
+ l := len([]rune(v))
+ if s != nil {
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, l)
+ } else {
+ return &stringIndexNotNumberError{s}
+ }
+ }
+ if e != nil {
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, l)
+ } else {
+ return &stringIndexNotNumberError{e}
+ }
+ } else {
+ end = l
+ }
+ if start < l {
+ for i := range v {
+ if start--; start < 0 {
+ start = i
+ break
+ }
}
- a = a[:i]
+ } else {
+ start = len(v)
}
- if start != nil {
- i := toIndex(aa, *start)
- if i == -1 || len(a) < i {
- i = len(a)
- } else if i == -2 {
- i = 0
+ if end < l {
+ for i := range v {
+ if end--; end < 0 {
+ end = i
+ break
+ }
}
- a = a[i:]
+ } else {
+ end = len(v)
}
- return a
+ return v[start:end]
}
-func toIndex(a []interface{}, i int) int {
- l := len(a)
- switch {
- case i < -l:
- return -2
- case i < 0:
- return l + i
- case i < l:
+func clampIndex(i, min, max int) int {
+ if i < 0 {
+ i += max
+ }
+ if i < min {
+ return min
+ } else if i < max {
return i
- default:
- return -1
+ } else {
+ return max
}
}
-func funcIndices(v, x interface{}) interface{} {
- return indexFunc(v, x, indices)
-}
-
-func funcLindex(v, x interface{}) interface{} {
- return indexFunc(v, x, func(vs, xs []interface{}) interface{} {
- if len(xs) == 0 {
- return nil
- }
- for i := 0; i < len(vs) && i < len(vs)-len(xs)+1; i++ {
- var neq bool
- for j, y := range xs {
- if neq = compare(vs[i+j], y) != 0; neq {
- break
- }
- }
- if !neq {
- return i
- }
- }
- return nil
- })
-}
-
-func funcRindex(v, x interface{}) interface{} {
- return indexFunc(v, x, func(vs, xs []interface{}) interface{} {
- if len(xs) == 0 {
- return nil
- }
- i := len(vs) - 1
- if j := len(vs) - len(xs); j < i {
- i = j
+func funcFlatten(v any, args []any) any {
+ vs, ok := values(v)
+ if !ok {
+ return &funcTypeError{"flatten", v}
+ }
+ var depth float64
+ if len(args) == 0 {
+ depth = -1
+ } else {
+ depth, ok = toFloat(args[0])
+ if !ok {
+ return &funcTypeError{"flatten", args[0]}
}
- for ; i >= 0; i-- {
- var neq bool
- for j, y := range xs {
- if neq = compare(vs[i+j], y) != 0; neq {
- break
- }
- }
- if !neq {
- return i
- }
+ if depth < 0 {
+ return &flattenDepthError{depth}
}
- return nil
- })
+ }
+ return flatten(nil, vs, depth)
}
-func indexFunc(v, x interface{}, f func(_, _ []interface{}) interface{}) interface{} {
- switch v := v.(type) {
- case nil:
- return nil
- case []interface{}:
- switch x := x.(type) {
- case []interface{}:
- return f(v, x)
- default:
- return f(v, []interface{}{x})
- }
- case string:
- if x, ok := x.(string); ok {
- return f(explode(v), explode(x))
+func flatten(xs, vs []any, depth float64) []any {
+ for _, v := range vs {
+ if vs, ok := v.([]any); ok && depth != 0 {
+ xs = flatten(xs, vs, depth-1)
+ } else {
+ xs = append(xs, v)
}
- return &expectedStringError{x}
- default:
- return &expectedArrayError{v}
}
+ return xs
}
type rangeIter struct {
- value, end, step interface{}
+ value, end, step any
}
-func (iter *rangeIter) Next() (interface{}, bool) {
+func (iter *rangeIter) Next() (any, bool) {
if compare(iter.step, 0)*compare(iter.value, iter.end) >= 0 {
return nil, false
}
@@ -971,7 +1130,7 @@ func (iter *rangeIter) Next() (interface{}, bool) {
return v, true
}
-func funcRange(_ interface{}, xs []interface{}) interface{} {
+func funcRange(_ any, xs []any) any {
for _, x := range xs {
switch x.(type) {
case int, float64, *big.Int:
@@ -982,43 +1141,59 @@ func funcRange(_ interface{}, xs []interface{}) interface{} {
return &rangeIter{xs[0], xs[1], xs[2]}
}
-func funcMinBy(v, x interface{}) interface{} {
- vs, ok := v.([]interface{})
+func funcMin(v any) any {
+ vs, ok := v.([]any)
if !ok {
- return &expectedArrayError{v}
+ return &funcTypeError{"min", v}
}
- xs, ok := x.([]interface{})
+ return minMaxBy(vs, vs, true)
+}
+
+func funcMinBy(v, x any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &funcTypeError{"min_by", v}
+ }
+ xs, ok := x.([]any)
if !ok {
- return &expectedArrayError{x}
+ return &funcTypeError{"min_by", x}
}
if len(vs) != len(xs) {
return &lengthMismatchError{"min_by", vs, xs}
}
- return funcMinMaxBy(vs, xs, true)
+ return minMaxBy(vs, xs, true)
}
-func funcMaxBy(v, x interface{}) interface{} {
- vs, ok := v.([]interface{})
+func funcMax(v any) any {
+ vs, ok := v.([]any)
if !ok {
- return &expectedArrayError{v}
+ return &funcTypeError{"max", v}
+ }
+ return minMaxBy(vs, vs, false)
+}
+
+func funcMaxBy(v, x any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &funcTypeError{"max_by", v}
}
- xs, ok := x.([]interface{})
+ xs, ok := x.([]any)
if !ok {
- return &expectedArrayError{x}
+ return &funcTypeError{"max_by", x}
}
if len(vs) != len(xs) {
return &lengthMismatchError{"max_by", vs, xs}
}
- return funcMinMaxBy(vs, xs, false)
+ return minMaxBy(vs, xs, false)
}
-func funcMinMaxBy(vs, xs []interface{}, isMin bool) interface{} {
+func minMaxBy(vs, xs []any, isMin bool) any {
if len(vs) == 0 {
return nil
}
i, j, x := 0, 0, xs[0]
for i++; i < len(xs); i++ {
- if (compare(x, xs[i]) > 0) == isMin {
+ if compare(x, xs[i]) > 0 == isMin {
j, x = i, xs[i]
}
}
@@ -1026,45 +1201,83 @@ func funcMinMaxBy(vs, xs []interface{}, isMin bool) interface{} {
}
type sortItem struct {
- value, key interface{}
+ value, key any
+}
+
+func sortItems(name string, v, x any) ([]*sortItem, error) {
+ vs, ok := v.([]any)
+ if !ok {
+ return nil, &funcTypeError{name, v}
+ }
+ xs, ok := x.([]any)
+ if !ok {
+ return nil, &funcTypeError{name, x}
+ }
+ if len(vs) != len(xs) {
+ return nil, &lengthMismatchError{name, vs, xs}
+ }
+ items := make([]*sortItem, len(vs))
+ for i, v := range vs {
+ items[i] = &sortItem{v, xs[i]}
+ }
+ sort.SliceStable(items, func(i, j int) bool {
+ return compare(items[i].key, items[j].key) < 0
+ })
+ return items, nil
+}
+
+func funcSort(v any) any {
+ return sortBy("sort", v, v)
}
-func funcSortBy(v, x interface{}) interface{} {
- items, err := sortItems("sort_by", v, x)
+func funcSortBy(v, x any) any {
+ return sortBy("sort_by", v, x)
+}
+
+func sortBy(name string, v, x any) any {
+ items, err := sortItems(name, v, x)
if err != nil {
return err
}
- rs := make([]interface{}, len(items))
+ rs := make([]any, len(items))
for i, x := range items {
rs[i] = x.value
}
return rs
}
-func funcGroupBy(v, x interface{}) interface{} {
+func funcGroupBy(v, x any) any {
items, err := sortItems("group_by", v, x)
if err != nil {
return err
}
- var rs []interface{}
- var last interface{}
+ var rs []any
+ var last any
for i, r := range items {
if i == 0 || compare(last, r.key) != 0 {
- rs, last = append(rs, []interface{}{r.value}), r.key
+ rs, last = append(rs, []any{r.value}), r.key
} else {
- rs[len(rs)-1] = append(rs[len(rs)-1].([]interface{}), r.value)
+ rs[len(rs)-1] = append(rs[len(rs)-1].([]any), r.value)
}
}
return rs
}
-func funcUniqueBy(v, x interface{}) interface{} {
- items, err := sortItems("unique_by", v, x)
+func funcUnique(v any) any {
+ return uniqueBy("unique", v, v)
+}
+
+func funcUniqueBy(v, x any) any {
+ return uniqueBy("unique_by", v, x)
+}
+
+func uniqueBy(name string, v, x any) any {
+ items, err := sortItems(name, v, x)
if err != nil {
return err
}
- var rs []interface{}
- var last interface{}
+ var rs []any
+ var last any
for i, r := range items {
if i == 0 || compare(last, r.key) != 0 {
rs, last = append(rs, r.value), r.key
@@ -1073,10 +1286,10 @@ func funcUniqueBy(v, x interface{}) interface{} {
return rs
}
-func funcJoin(v, x interface{}) interface{} {
- vs, ok := v.([]interface{})
+func funcJoin(v, x any) any {
+ vs, ok := values(v)
if !ok {
- return &expectedArrayError{v}
+ return &funcTypeError{"join", v}
}
if len(vs) == 0 {
return ""
@@ -1086,48 +1299,26 @@ func funcJoin(v, x interface{}) interface{} {
return &funcTypeError{"join", x}
}
ss := make([]string, len(vs))
- for i, e := range vs {
- switch e := e.(type) {
+ for i, v := range vs {
+ switch v := v.(type) {
case nil:
case string:
- ss[i] = e
+ ss[i] = v
case bool:
- if e {
+ if v {
ss[i] = "true"
} else {
ss[i] = "false"
}
case int, float64, *big.Int:
- ss[i] = jsonMarshal(e)
+ ss[i] = jsonMarshal(v)
default:
- return &unaryTypeError{"join", e}
+ return &joinTypeError{v}
}
}
return strings.Join(ss, sep)
}
-func sortItems(name string, v, x interface{}) ([]*sortItem, error) {
- vs, ok := v.([]interface{})
- if !ok {
- return nil, &expectedArrayError{v}
- }
- xs, ok := x.([]interface{})
- if !ok {
- return nil, &expectedArrayError{x}
- }
- if len(vs) != len(xs) {
- return nil, &lengthMismatchError{name, vs, xs}
- }
- items := make([]*sortItem, len(vs))
- for i, v := range vs {
- items[i] = &sortItem{v, xs[i]}
- }
- sort.SliceStable(items, func(i, j int) bool {
- return compare(items[i].key, items[j].key) < 0
- })
- return items, nil
-}
-
func funcSignificand(v float64) float64 {
if math.IsNaN(v) || math.IsInf(v, 0) || v == 0.0 {
return v
@@ -1139,22 +1330,22 @@ func funcExp10(v float64) float64 {
return math.Pow(10, v)
}
-func funcFrexp(v interface{}) interface{} {
+func funcFrexp(v any) any {
x, ok := toFloat(v)
if !ok {
return &funcTypeError{"frexp", v}
}
f, e := math.Frexp(x)
- return []interface{}{f, e}
+ return []any{f, e}
}
-func funcModf(v interface{}) interface{} {
+func funcModf(v any) any {
x, ok := toFloat(v)
if !ok {
return &funcTypeError{"modf", v}
}
i, f := math.Modf(x)
- return []interface{}{f, i}
+ return []any{f, i}
}
func funcLgamma(v float64) float64 {
@@ -1190,25 +1381,25 @@ func funcYn(l, r float64) float64 {
return math.Yn(int(l), r)
}
-func funcInfinite(interface{}) interface{} {
+func funcInfinite(any) any {
return math.Inf(1)
}
-func funcIsfinite(v interface{}) interface{} {
+func funcIsfinite(v any) any {
x, ok := toFloat(v)
return ok && !math.IsInf(x, 0)
}
-func funcIsinfinite(v interface{}) interface{} {
+func funcIsinfinite(v any) any {
x, ok := toFloat(v)
return ok && math.IsInf(x, 0)
}
-func funcNan(interface{}) interface{} {
+func funcNan(any) any {
return math.NaN()
}
-func funcIsnan(v interface{}) interface{} {
+func funcIsnan(v any) any {
x, ok := toFloat(v)
if !ok {
if v == nil {
@@ -1219,18 +1410,65 @@ func funcIsnan(v interface{}) interface{} {
return math.IsNaN(x)
}
-func funcIsnormal(v interface{}) interface{} {
- x, ok := toFloat(v)
- return ok && !math.IsNaN(x) && !math.IsInf(x, 0) && x != 0.0
+func funcIsnormal(v any) any {
+ if v, ok := toFloat(v); ok {
+ e := math.Float64bits(v) & 0x7ff0000000000000 >> 52
+ return 0 < e && e < 0x7ff
+ }
+ return false
+}
+
+// An `allocator` creates new maps and slices, stores the allocated addresses.
+// This allocator is used to reduce allocations on assignment operator (`=`),
+// update-assignment operator (`|=`), and the `map_values`, `del`, `delpaths`
+// functions.
+type allocator map[uintptr]struct{}
+
+func funcAllocator(any, []any) any {
+ return allocator{}
+}
+
+func (a allocator) allocated(v any) bool {
+ _, ok := a[reflect.ValueOf(v).Pointer()]
+ return ok
+}
+
+func (a allocator) makeObject(l int) map[string]any {
+ v := make(map[string]any, l)
+ if a != nil {
+ a[reflect.ValueOf(v).Pointer()] = struct{}{}
+ }
+ return v
+}
+
+func (a allocator) makeArray(l, c int) []any {
+ if c < l {
+ c = l
+ }
+ v := make([]any, l, c)
+ if a != nil {
+ a[reflect.ValueOf(v).Pointer()] = struct{}{}
+ }
+ return v
+}
+
+func funcSetpath(v, p, n any) any {
+ // There is no need to use an allocator on a single update.
+ return setpath(v, p, n, nil)
+}
+
+// Used in compiler#compileAssign and compiler#compileModify.
+func funcSetpathWithAllocator(v any, args []any) any {
+ return setpath(v, args[0], args[1], args[2].(allocator))
}
-func funcSetpath(v, p, w interface{}) interface{} {
- path, ok := p.([]interface{})
+func setpath(v, p, n any, a allocator) any {
+ path, ok := p.([]any)
if !ok {
return &funcTypeError{"setpath", p}
}
var err error
- if v, err = updatePaths(v, path, w, false); err != nil {
+ if v, err = update(v, path, n, a); err != nil {
if err, ok := err.(*funcTypeError); ok {
err.name = "setpath"
}
@@ -1239,188 +1477,74 @@ func funcSetpath(v, p, w interface{}) interface{} {
return v
}
-func funcDelpaths(v, p interface{}) interface{} {
- paths, ok := p.([]interface{})
+func funcDelpaths(v, p any) any {
+ return delpaths(v, p, allocator{})
+}
+
+// Used in compiler#compileAssign and compiler#compileModify.
+func funcDelpathsWithAllocator(v any, args []any) any {
+ return delpaths(v, args[0], args[1].(allocator))
+}
+
+func delpaths(v, p any, a allocator) any {
+ paths, ok := p.([]any)
if !ok {
return &funcTypeError{"delpaths", p}
}
+ if len(paths) == 0 {
+ return v
+ }
// Fills the paths with an empty value and then delete them. We cannot delete
// in each loop because array indices should not change. For example,
// jq -n "[0, 1, 2, 3] | delpaths([[1], [2]])" #=> [0, 3].
var empty struct{}
var err error
for _, p := range paths {
- path, ok := p.([]interface{})
+ path, ok := p.([]any)
if !ok {
return &funcTypeError{"delpaths", p}
}
- if v, err = updatePaths(v, path, empty, true); err != nil {
+ if v, err = update(v, path, empty, a); err != nil {
return err
}
}
return deleteEmpty(v)
}
-func updatePaths(v interface{}, path []interface{}, w interface{}, delpaths bool) (interface{}, error) {
+func update(v any, path []any, n any, a allocator) (any, error) {
if len(path) == 0 {
- return w, nil
+ return n, nil
}
- switch x := path[0].(type) {
+ switch p := path[0].(type) {
case string:
- if v == nil {
- if delpaths {
- return v, nil
- }
- v = make(map[string]interface{})
- }
- switch uu := v.(type) {
- case map[string]interface{}:
- if _, ok := uu[x]; !ok && delpaths {
- return v, nil
- }
- u, err := updatePaths(uu[x], path[1:], w, delpaths)
- if err != nil {
- return nil, err
- }
- vs := make(map[string]interface{}, len(uu))
- for k, v := range uu {
- vs[k] = v
- }
- vs[x] = u
- return vs, nil
+ switch v := v.(type) {
+ case nil:
+ return updateObject(nil, p, path[1:], n, a)
+ case map[string]any:
+ return updateObject(v, p, path[1:], n, a)
case struct{}:
return v, nil
default:
return nil, &expectedObjectError{v}
}
case int, float64, *big.Int:
- if v == nil {
- if delpaths {
- return v, nil
- }
- v = []interface{}{}
- }
- switch uu := v.(type) {
- case []interface{}:
- y, _ := toInt(x)
- l := len(uu)
- var copied bool
- if copied = y >= l; copied {
- if delpaths {
- return v, nil
- }
- if y > 0x3ffffff {
- return nil, &arrayIndexTooLargeError{y}
- }
- l = y + 1
- ys := make([]interface{}, l)
- copy(ys, uu)
- uu = ys
- } else if y < -l {
- if delpaths {
- return v, nil
- }
- return nil, &funcTypeError{v: y}
- } else if y < 0 {
- y += l
- }
- u, err := updatePaths(uu[y], path[1:], w, delpaths)
- if err != nil {
- return nil, err
- }
- if copied {
- uu[y] = u
- return uu, nil
- }
- vs := make([]interface{}, l)
- copy(vs, uu)
- vs[y] = u
- return vs, nil
+ i, _ := toInt(p)
+ switch v := v.(type) {
+ case nil:
+ return updateArrayIndex(nil, i, path[1:], n, a)
+ case []any:
+ return updateArrayIndex(v, i, path[1:], n, a)
case struct{}:
return v, nil
default:
return nil, &expectedArrayError{v}
}
- case map[string]interface{}:
- if len(x) == 0 {
- switch v.(type) {
- case []interface{}:
- return nil, &arrayIndexNotNumberError{x}
- default:
- return nil, &objectKeyNotStringError{x}
- }
- }
- if v == nil {
- v = []interface{}{}
- }
- switch uu := v.(type) {
- case []interface{}:
- var start, end int
- if x, ok := toInt(x["start"]); ok {
- x := toIndex(uu, x)
- if x > len(uu) || x == -1 {
- start = len(uu)
- } else if x == -2 {
- start = 0
- } else {
- start = x
- }
- }
- if x, ok := toInt(x["end"]); ok {
- x := toIndex(uu, x)
- if x == -1 {
- end = len(uu)
- } else if x < start {
- end = start
- } else {
- end = x
- }
- } else {
- end = len(uu)
- }
- if delpaths {
- if start >= end {
- return uu, nil
- }
- if len(path) > 1 {
- u, err := updatePaths(uu[start:end], path[1:], w, delpaths)
- if err != nil {
- return nil, err
- }
- switch us := u.(type) {
- case []interface{}:
- vs := make([]interface{}, len(uu))
- copy(vs, uu)
- copy(vs[start:end], us)
- return vs, nil
- default:
- return nil, &expectedArrayError{u}
- }
- }
- vs := make([]interface{}, len(uu))
- copy(vs, uu)
- for y := start; y < end; y++ {
- vs[y] = w
- }
- return vs, nil
- }
- if len(path) > 1 {
- u, err := updatePaths(uu[start:end], path[1:], w, delpaths)
- if err != nil {
- return nil, err
- }
- w = u
- }
- switch v := w.(type) {
- case []interface{}:
- vs := make([]interface{}, start+len(v)+len(uu)-end)
- copy(vs, uu[:start])
- copy(vs[start:], v)
- copy(vs[start+len(v):], uu[end:])
- return vs, nil
- default:
- return nil, &expectedArrayError{v}
- }
+ case map[string]any:
+ switch v := v.(type) {
+ case nil:
+ return updateArraySlice(nil, p, path[1:], n, a)
+ case []any:
+ return updateArraySlice(v, p, path[1:], n, a)
case struct{}:
return v, nil
default:
@@ -1428,47 +1552,192 @@ func updatePaths(v interface{}, path []interface{}, w interface{}, delpaths bool
}
default:
switch v.(type) {
- case []interface{}:
- return nil, &arrayIndexNotNumberError{x}
+ case []any:
+ return nil, &arrayIndexNotNumberError{p}
default:
- return nil, &objectKeyNotStringError{x}
+ return nil, &objectKeyNotStringError{p}
+ }
+ }
+}
+
+func updateObject(v map[string]any, k string, path []any, n any, a allocator) (any, error) {
+ x, ok := v[k]
+ if !ok && n == struct{}{} {
+ return v, nil
+ }
+ u, err := update(x, path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ if a.allocated(v) {
+ v[k] = u
+ return v, nil
+ }
+ w := a.makeObject(len(v) + 1)
+ for k, v := range v {
+ w[k] = v
+ }
+ w[k] = u
+ return w, nil
+}
+
+func updateArrayIndex(v []any, i int, path []any, n any, a allocator) (any, error) {
+ var x any
+ if j := clampIndex(i, -1, len(v)); j < 0 {
+ if n == struct{}{} {
+ return v, nil
+ }
+ return nil, &funcTypeError{v: i}
+ } else if j < len(v) {
+ i = j
+ x = v[i]
+ } else {
+ if n == struct{}{} {
+ return v, nil
}
+ if i >= 0x8000000 {
+ return nil, &arrayIndexTooLargeError{i}
+ }
+ }
+ u, err := update(x, path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ l, c := len(v), cap(v)
+ if a.allocated(v) {
+ if i < c {
+ if i >= l {
+ v = v[:i+1]
+ }
+ v[i] = u
+ return v, nil
+ }
+ c *= 2
+ }
+ if i >= l {
+ l = i + 1
+ }
+ w := a.makeArray(l, c)
+ copy(w, v)
+ w[i] = u
+ return w, nil
+}
+
+func updateArraySlice(v []any, m map[string]any, path []any, n any, a allocator) (any, error) {
+ s, ok := m["start"]
+ if !ok {
+ return nil, &expectedStartEndError{m}
+ }
+ e, ok := m["end"]
+ if !ok {
+ return nil, &expectedStartEndError{m}
+ }
+ var start, end int
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, len(v))
+ }
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, len(v))
+ } else {
+ end = len(v)
+ }
+ if start == end && n == struct{}{} {
+ return v, nil
+ }
+ u, err := update(v[start:end], path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ switch u := u.(type) {
+ case []any:
+ var w []any
+ if len(u) == end-start && a.allocated(v) {
+ w = v
+ } else {
+ w = a.makeArray(len(v)-(end-start)+len(u), 0)
+ copy(w, v[:start])
+ copy(w[start+len(u):], v[end:])
+ }
+ copy(w[start:], u)
+ return w, nil
+ case struct{}:
+ var w []any
+ if a.allocated(v) {
+ w = v
+ } else {
+ w = a.makeArray(len(v), 0)
+ copy(w, v)
+ }
+ for i := start; i < end; i++ {
+ w[i] = u
+ }
+ return w, nil
+ default:
+ return nil, &expectedArrayError{u}
+ }
+}
+
+func deleteEmpty(v any) any {
+ switch v := v.(type) {
+ case struct{}:
+ return nil
+ case map[string]any:
+ for k, w := range v {
+ if w == struct{}{} {
+ delete(v, k)
+ } else {
+ v[k] = deleteEmpty(w)
+ }
+ }
+ return v
+ case []any:
+ var j int
+ for _, w := range v {
+ if w != struct{}{} {
+ v[j] = deleteEmpty(w)
+ j++
+ }
+ }
+ for i := j; i < len(v); i++ {
+ v[i] = nil
+ }
+ return v[:j]
+ default:
+ return v
}
}
-func funcGetpath(v, p interface{}) interface{} {
- keys, ok := p.([]interface{})
+func funcGetpath(v, p any) any {
+ keys, ok := p.([]any)
if !ok {
return &funcTypeError{"getpath", p}
}
u := v
for _, x := range keys {
switch v.(type) {
- case map[string]interface{}:
- case []interface{}:
- case nil:
+ case nil, []any, map[string]any:
+ v = funcIndex2(nil, v, x)
+ if _, ok := v.(error); ok {
+ return &getpathError{u, p}
+ }
default:
return &getpathError{u, p}
}
- v = funcIndex(nil, v, x)
- if _, ok := v.(error); ok {
- return &getpathError{u, p}
- }
}
return v
}
-func funcTranspose(v interface{}) interface{} {
- vss, ok := v.([]interface{})
+func funcTranspose(v any) any {
+ vss, ok := v.([]any)
if !ok {
return &funcTypeError{"transpose", v}
}
if len(vss) == 0 {
- return []interface{}{}
+ return []any{}
}
var l int
for _, vs := range vss {
- vs, ok := vs.([]interface{})
+ vs, ok := vs.([]any)
if !ok {
return &funcTypeError{"transpose", v}
}
@@ -1476,23 +1745,23 @@ func funcTranspose(v interface{}) interface{} {
l = k
}
}
- wss := make([][]interface{}, l)
- xs := make([]interface{}, l)
+ wss := make([][]any, l)
+ xs := make([]any, l)
for i, k := 0, len(vss); i < l; i++ {
- s := make([]interface{}, k)
+ s := make([]any, k)
wss[i] = s
xs[i] = s
}
for i, vs := range vss {
- for j, v := range vs.([]interface{}) {
+ for j, v := range vs.([]any) {
wss[j][i] = v
}
}
return xs
}
-func funcBsearch(v, t interface{}) interface{} {
- vs, ok := v.([]interface{})
+func funcBsearch(v, t any) any {
+ vs, ok := v.([]any)
if !ok {
return &funcTypeError{"bsearch", v}
}
@@ -1505,23 +1774,23 @@ func funcBsearch(v, t interface{}) interface{} {
return -i - 1
}
-func funcGmtime(v interface{}) interface{} {
+func funcGmtime(v any) any {
if v, ok := toFloat(v); ok {
return epochToArray(v, time.UTC)
}
return &funcTypeError{"gmtime", v}
}
-func funcLocaltime(v interface{}) interface{} {
+func funcLocaltime(v any) any {
if v, ok := toFloat(v); ok {
return epochToArray(v, time.Local)
}
return &funcTypeError{"localtime", v}
}
-func epochToArray(v float64, loc *time.Location) []interface{} {
+func epochToArray(v float64, loc *time.Location) []any {
t := time.Unix(int64(v), int64((v-math.Floor(v))*1e9)).In(loc)
- return []interface{}{
+ return []any{
t.Year(),
int(t.Month()) - 1,
t.Day(),
@@ -1533,22 +1802,26 @@ func epochToArray(v float64, loc *time.Location) []interface{} {
}
}
-func funcMktime(v interface{}) interface{} {
- if a, ok := v.([]interface{}); ok {
+func funcMktime(v any) any {
+ if a, ok := v.([]any); ok {
t, err := arrayToTime("mktime", a, time.UTC)
if err != nil {
return err
}
- return float64(t.Unix())
+ return timeToEpoch(t)
}
return &funcTypeError{"mktime", v}
}
-func funcStrftime(v, x interface{}) interface{} {
+func timeToEpoch(t time.Time) float64 {
+ return float64(t.Unix()) + float64(t.Nanosecond())/1e9
+}
+
+func funcStrftime(v, x any) any {
if w, ok := toFloat(v); ok {
v = epochToArray(w, time.UTC)
}
- if a, ok := v.([]interface{}); ok {
+ if a, ok := v.([]any); ok {
if format, ok := x.(string); ok {
t, err := arrayToTime("strftime", a, time.UTC)
if err != nil {
@@ -1561,11 +1834,11 @@ func funcStrftime(v, x interface{}) interface{} {
return &funcTypeError{"strftime", v}
}
-func funcStrflocaltime(v, x interface{}) interface{} {
+func funcStrflocaltime(v, x any) any {
if w, ok := toFloat(v); ok {
v = epochToArray(w, time.Local)
}
- if a, ok := v.([]interface{}); ok {
+ if a, ok := v.([]any); ok {
if format, ok := x.(string); ok {
t, err := arrayToTime("strflocaltime", a, time.Local)
if err != nil {
@@ -1578,7 +1851,7 @@ func funcStrflocaltime(v, x interface{}) interface{} {
return &funcTypeError{"strflocaltime", v}
}
-func funcStrptime(v, x interface{}) interface{} {
+func funcStrptime(v, x any) any {
if v, ok := v.(string); ok {
if format, ok := x.(string); ok {
t, err := timefmt.Parse(v, format)
@@ -1589,14 +1862,14 @@ func funcStrptime(v, x interface{}) interface{} {
if t == s {
return &funcTypeError{"strptime", v}
}
- return epochToArray(float64(t.Unix())+float64(t.Nanosecond())/1e9, time.UTC)
+ return epochToArray(timeToEpoch(t), time.UTC)
}
return &funcTypeError{"strptime", x}
}
return &funcTypeError{"strptime", v}
}
-func arrayToTime(name string, a []interface{}, loc *time.Location) (time.Time, error) {
+func arrayToTime(name string, a []any, loc *time.Location) (time.Time, error) {
var t time.Time
if len(a) != 8 {
return t, &funcTypeError{name, a}
@@ -1636,12 +1909,11 @@ func arrayToTime(name string, a []interface{}, loc *time.Location) (time.Time, e
return time.Date(y, time.Month(m), d, h, min, sec, nsec, loc), nil
}
-func funcNow(interface{}) interface{} {
- t := time.Now()
- return float64(t.Unix()) + float64(t.Nanosecond())/1e9
+func funcNow(any) any {
+ return timeToEpoch(time.Now())
}
-func funcMatch(v, re, fs, testing interface{}) interface{} {
+func funcMatch(v, re, fs, testing any) any {
var flags string
if fs != nil {
v, ok := fs.(string)
@@ -1674,16 +1946,16 @@ func funcMatch(v, re, fs, testing interface{}) interface{} {
xs = [][]int{got}
}
}
- res, names := make([]interface{}, len(xs)), r.SubexpNames()
+ res, names := make([]any, len(xs)), r.SubexpNames()
for i, x := range xs {
- captures := make([]interface{}, (len(x)-2)/2)
+ captures := make([]any, (len(x)-2)/2)
for j := 1; j < len(x)/2; j++ {
- var name interface{}
+ var name any
if n := names[j]; n != "" {
name = n
}
if x[j*2] < 0 {
- captures[j-1] = map[string]interface{}{
+ captures[j-1] = map[string]any{
"name": name,
"offset": -1,
"length": 0,
@@ -1691,14 +1963,14 @@ func funcMatch(v, re, fs, testing interface{}) interface{} {
}
continue
}
- captures[j-1] = map[string]interface{}{
+ captures[j-1] = map[string]any{
"name": name,
"offset": len([]rune(s[:x[j*2]])),
"length": len([]rune(s[:x[j*2+1]])) - len([]rune(s[:x[j*2]])),
"string": s[x[j*2]:x[j*2+1]],
}
}
- res[i] = map[string]interface{}{
+ res[i] = map[string]any{
"offset": len([]rune(s[:x[0]])),
"length": len([]rune(s[:x[1]])) - len([]rune(s[:x[0]])),
"string": s[x[0]:x[1]],
@@ -1728,7 +2000,28 @@ func compileRegexp(re, flags string) (*regexp.Regexp, error) {
return r, nil
}
-func funcError(v interface{}, args []interface{}) interface{} {
+func funcCapture(v any) any {
+ vs, ok := v.(map[string]any)
+ if !ok {
+ return &expectedObjectError{v}
+ }
+ v = vs["captures"]
+ captures, ok := v.([]any)
+ if !ok {
+ return &expectedArrayError{v}
+ }
+ w := make(map[string]any, len(captures))
+ for _, capture := range captures {
+ if capture, ok := capture.(map[string]any); ok {
+ if name, ok := capture["name"].(string); ok {
+ w[name] = capture["string"]
+ }
+ }
+ }
+ return w
+}
+
+func funcError(v any, args []any) any {
if len(args) > 0 {
v = args[0]
}
@@ -1739,11 +2032,11 @@ func funcError(v interface{}, args []interface{}) interface{} {
return &exitCodeError{v, code, false}
}
-func funcHalt(interface{}) interface{} {
+func funcHalt(any) any {
return &exitCodeError{nil, 0, true}
}
-func funcHaltError(v interface{}, args []interface{}) interface{} {
+func funcHaltError(v any, args []any) any {
code := 5
if len(args) > 0 {
var ok bool
@@ -1754,14 +2047,7 @@ func funcHaltError(v interface{}, args []interface{}) interface{} {
return &exitCodeError{v, code, true}
}
-func internalfuncTypeError(v, x interface{}) interface{} {
- if x, ok := x.(string); ok {
- return &funcTypeError{x, v}
- }
- return &funcTypeError{"_type_error", v}
-}
-
-func toInt(x interface{}) (int, bool) {
+func toInt(x any) (int, bool) {
switch x := x.(type) {
case int:
return x, true
@@ -1769,30 +2055,30 @@ func toInt(x interface{}) (int, bool) {
return floatToInt(x), true
case *big.Int:
if x.IsInt64() {
- if i := x.Int64(); minInt <= i && i <= maxInt {
+ if i := x.Int64(); math.MinInt <= i && i <= math.MaxInt {
return int(i), true
}
}
if x.Sign() > 0 {
- return maxInt, true
+ return math.MaxInt, true
}
- return minInt, true
+ return math.MinInt, true
default:
return 0, false
}
}
func floatToInt(x float64) int {
- if minInt <= x && x <= maxInt {
+ if math.MinInt <= x && x <= math.MaxInt {
return int(x)
}
if x > 0 {
- return maxInt
+ return math.MaxInt
}
- return minInt
+ return math.MinInt
}
-func toFloat(x interface{}) (float64, bool) {
+func toFloat(x any) (float64, bool) {
switch x := x.(type) {
case int:
return float64(x), true
diff --git a/vendor/github.com/itchyny/gojq/go.dev.mod b/vendor/github.com/itchyny/gojq/go.dev.mod
index 46e652e2..9a0579ca 100644
--- a/vendor/github.com/itchyny/gojq/go.dev.mod
+++ b/vendor/github.com/itchyny/gojq/go.dev.mod
@@ -1,8 +1,8 @@
module github.com/itchyny/gojq
-go 1.16
+go 1.18
require (
github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972 // indirect
- github.com/itchyny/timefmt-go v0.1.3 // indirect
+ github.com/itchyny/timefmt-go v0.1.5 // indirect
)
diff --git a/vendor/github.com/itchyny/gojq/go.dev.sum b/vendor/github.com/itchyny/gojq/go.dev.sum
index 467aa0b9..66aee6c5 100644
--- a/vendor/github.com/itchyny/gojq/go.dev.sum
+++ b/vendor/github.com/itchyny/gojq/go.dev.sum
@@ -1,4 +1,4 @@
github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972 h1:XYWolmPDLTY9B1O5o/Ad811/mtVkaHWMiZdbPLm/nDA=
github.com/itchyny/astgen-go v0.0.0-20210914105503-cc8fccf6f972/go.mod h1:jTXcxGeQMJfFN3wWjtzb4aAaWDDN+QbezE0HjH1XfNk=
-github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
-github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
+github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
+github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
diff --git a/vendor/github.com/itchyny/gojq/gojq.go b/vendor/github.com/itchyny/gojq/gojq.go
index 8f53b356..e078c809 100644
--- a/vendor/github.com/itchyny/gojq/gojq.go
+++ b/vendor/github.com/itchyny/gojq/gojq.go
@@ -1,5 +1,5 @@
-// Package gojq provides the parser and interpreter of gojq.
+// Package gojq provides the parser and the interpreter of gojq.
+// Please refer to [Usage as a library] for introduction.
//
-// Please refer to https://github.com/itchyny/gojq#usage-as-a-library for
-// introduction of the usage as a library.
+// [Usage as a library]: https://github.com/itchyny/gojq#usage-as-a-library
package gojq
diff --git a/vendor/github.com/itchyny/gojq/iter.go b/vendor/github.com/itchyny/gojq/iter.go
index 0cee25ba..d0bed960 100644
--- a/vendor/github.com/itchyny/gojq/iter.go
+++ b/vendor/github.com/itchyny/gojq/iter.go
@@ -2,11 +2,11 @@ package gojq
// Iter is an interface for an iterator.
type Iter interface {
- Next() (interface{}, bool)
+ Next() (any, bool)
}
-// NewIter creates a new Iter from values.
-func NewIter(values ...interface{}) Iter {
+// NewIter creates a new [Iter] from values.
+func NewIter(values ...any) Iter {
switch len(values) {
case 0:
return emptyIter{}
@@ -20,16 +20,16 @@ func NewIter(values ...interface{}) Iter {
type emptyIter struct{}
-func (emptyIter) Next() (interface{}, bool) {
+func (emptyIter) Next() (any, bool) {
return nil, false
}
type unitIter struct {
- value interface{}
+ value any
done bool
}
-func (iter *unitIter) Next() (interface{}, bool) {
+func (iter *unitIter) Next() (any, bool) {
if iter.done {
return nil, false
}
@@ -37,9 +37,9 @@ func (iter *unitIter) Next() (interface{}, bool) {
return iter.value, true
}
-type sliceIter []interface{}
+type sliceIter []any
-func (iter *sliceIter) Next() (interface{}, bool) {
+func (iter *sliceIter) Next() (any, bool) {
if len(*iter) == 0 {
return nil, false
}
diff --git a/vendor/github.com/itchyny/gojq/lexer.go b/vendor/github.com/itchyny/gojq/lexer.go
index d36a6838..82bb2b6b 100644
--- a/vendor/github.com/itchyny/gojq/lexer.go
+++ b/vendor/github.com/itchyny/gojq/lexer.go
@@ -1,8 +1,7 @@
package gojq
import (
- "strconv"
- "strings"
+ "encoding/json"
"unicode/utf8"
)
@@ -235,9 +234,9 @@ func (l *lexer) Lex(lval *yySymType) (tokenType int) {
return tok
default:
if ch >= utf8.RuneSelf {
- r, _ := utf8.DecodeRuneInString(l.source[l.offset-1:])
+ r, size := utf8.DecodeRuneInString(l.source[l.offset-1:])
+ l.offset += size
l.token = string(r)
- l.offset += len(l.token)
}
}
return int(ch)
@@ -381,82 +380,129 @@ func (l *lexer) validNumber() bool {
}
func (l *lexer) scanString(start int) (int, string) {
- var quote, newline bool
+ var decode bool
+ var controls int
unquote := func(src string, quote bool) (string, error) {
- if quote {
- src = "\"" + src + "\""
+ if !decode {
+ if quote {
+ return src, nil
+ }
+ return src[1 : len(src)-1], nil
}
- if newline {
- src = strings.ReplaceAll(src, "\n", "\\n")
+ var buf []byte
+ if !quote && controls == 0 {
+ buf = []byte(src)
+ } else {
+ buf = quoteAndEscape(src, quote, controls)
}
- return strconv.Unquote(src)
+ if err := json.Unmarshal(buf, &src); err != nil {
+ return "", err
+ }
+ return src, nil
}
- for i, m := l.offset, len(l.source); i < m; i++ {
+ for i := l.offset; i < len(l.source); i++ {
ch := l.source[i]
switch ch {
case '\\':
- quote = !quote
- case '\n':
- newline = true
- case '"':
- if !quote {
- if !l.inString {
- l.offset = i + 1
- l.token = l.source[start:l.offset]
- str, err := unquote(l.token, false)
- if err != nil {
- return tokInvalid, ""
+ if i++; i >= len(l.source) {
+ break
+ }
+ switch l.source[i] {
+ case 'u':
+ for j := 1; j <= 4; j++ {
+ if i+j >= len(l.source) || !isHex(l.source[i+j]) {
+ l.offset = i + j
+ l.token = l.source[i-1 : l.offset]
+ return tokInvalidEscapeSequence, ""
}
- return tokString, str
}
- if i > l.offset {
- l.offset = i
- l.token = l.source[start:l.offset]
- str, err := unquote(l.token, true)
- if err != nil {
- return tokInvalid, ""
- }
- return tokString, str
+ i += 4
+ fallthrough
+ case '"', '/', '\\', 'b', 'f', 'n', 'r', 't':
+ decode = true
+ case '(':
+ if !l.inString {
+ l.inString = true
+ return tokStringStart, ""
}
- l.inString = false
- l.offset = i + 1
- return tokStringEnd, ""
- }
- quote = false
- case '(':
- if quote {
- if l.inString {
- if i > l.offset+1 {
- l.offset = i - 1
- l.token = l.source[start:l.offset]
- str, err := unquote(l.token, true)
- if err != nil {
- return tokInvalid, ""
- }
- return tokString, str
- }
- l.offset = i + 1
+ if i == l.offset+1 {
+ l.offset += 2
l.inString = false
return tokStringQuery, ""
}
- l.inString = true
- return tokStringStart, ""
+ l.offset = i - 1
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, true)
+ if err != nil {
+ return tokInvalid, ""
+ }
+ return tokString, str
+ default:
+ l.offset = i + 1
+ l.token = l.source[l.offset-2 : l.offset]
+ return tokInvalidEscapeSequence, ""
}
- default:
- if quote {
- if !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' ||
- '0' <= ch && ch <= '9' || ch == '\'' || ch == '"') {
- l.offset = i + 1
- l.token = l.source[l.offset-2 : l.offset]
+ case '"':
+ if !l.inString {
+ l.offset = i + 1
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, false)
+ if err != nil {
return tokInvalid, ""
}
- quote = false
+ return tokString, str
+ }
+ if i > l.offset {
+ l.offset = i
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, true)
+ if err != nil {
+ return tokInvalid, ""
+ }
+ return tokString, str
+ }
+ l.inString = false
+ l.offset = i + 1
+ return tokStringEnd, ""
+ default:
+ if !decode {
+ decode = ch > '~'
+ }
+ if ch < ' ' { // ref: unquoteBytes in encoding/json
+ controls++
}
}
}
l.offset = len(l.source)
- l.token = l.source[start:l.offset]
- return tokInvalid, ""
+ l.token = ""
+ return tokUnterminatedString, ""
+}
+
+func quoteAndEscape(src string, quote bool, controls int) []byte {
+ size := len(src) + controls*5
+ if quote {
+ size += 2
+ }
+ buf := make([]byte, size)
+ var j int
+ if quote {
+ buf[0] = '"'
+ buf[len(buf)-1] = '"'
+ j++
+ }
+ for i := 0; i < len(src); i++ {
+ if ch := src[i]; ch < ' ' {
+ const hex = "0123456789abcdef"
+ copy(buf[j:], `\u00`)
+ buf[j+4] = hex[ch>>4]
+ buf[j+5] = hex[ch&0xF]
+ j += 6
+ } else {
+ buf[j] = ch
+ j++
+ }
+ }
+ return buf
}
type parseError struct {
@@ -466,24 +512,18 @@ type parseError struct {
}
func (err *parseError) Error() string {
- var message string
- prefix := "unexpected"
- switch {
- case err.tokenType == eof:
- message = ""
- case err.tokenType == tokInvalid:
- prefix = "invalid"
- fallthrough
- case err.tokenType >= utf8.RuneSelf:
- if strings.HasPrefix(err.token, "\"") {
- message = err.token
- } else {
- message = "\"" + err.token + "\""
- }
+ switch err.tokenType {
+ case eof:
+ return "unexpected EOF"
+ case tokInvalid:
+ return "invalid token " + jsonMarshal(err.token)
+ case tokInvalidEscapeSequence:
+ return `invalid escape sequence "` + err.token + `" in string literal`
+ case tokUnterminatedString:
+ return "unterminated string literal"
default:
- message = strconv.Quote(string(rune(err.tokenType)))
+ return "unexpected token " + jsonMarshal(err.token)
}
- return prefix + " token " + message
}
func (err *parseError) Token() (string, int) {
@@ -492,12 +532,7 @@ func (err *parseError) Token() (string, int) {
func (l *lexer) Error(string) {
offset, token := l.offset, l.token
- switch {
- case l.tokenType == eof:
- offset++
- case l.tokenType >= utf8.RuneSelf:
- offset -= len(token) - 1
- default:
+ if l.tokenType != eof && l.tokenType < utf8.RuneSelf {
token = string(rune(l.tokenType))
}
l.err = &parseError{offset, token, l.tokenType}
@@ -518,6 +553,12 @@ func isIdent(ch byte, tail bool) bool {
tail && isNumber(ch)
}
+func isHex(ch byte) bool {
+ return 'a' <= ch && ch <= 'f' ||
+ 'A' <= ch && ch <= 'F' ||
+ isNumber(ch)
+}
+
func isNumber(ch byte) bool {
return '0' <= ch && ch <= '9'
}
diff --git a/vendor/github.com/itchyny/gojq/math.go b/vendor/github.com/itchyny/gojq/math.go
deleted file mode 100644
index 55d64765..00000000
--- a/vendor/github.com/itchyny/gojq/math.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package gojq
-
-import "math/bits"
-
-const (
- maxInt = 1<<(bits.UintSize-1) - 1 // math.MaxInt64 or math.MaxInt32
- minInt = -maxInt - 1 // math.MinInt64 or math.MinInt32
- maxHalfInt = 1<<(bits.UintSize/2-1) - 1 // math.MaxInt32 or math.MaxInt16
- minHalfInt = -maxHalfInt - 1 // math.MinInt32 or math.MinInt16
-)
diff --git a/vendor/github.com/itchyny/gojq/module_loader.go b/vendor/github.com/itchyny/gojq/module_loader.go
index b6cebca9..6e9ba48c 100644
--- a/vendor/github.com/itchyny/gojq/module_loader.go
+++ b/vendor/github.com/itchyny/gojq/module_loader.go
@@ -9,15 +9,26 @@ import (
"strings"
)
-type moduleLoader struct {
- paths []string
-}
+// ModuleLoader is the interface for loading modules.
+//
+// Implement following optional methods. Use [NewModuleLoader] to load local modules.
+//
+// LoadModule(string) (*Query, error)
+// LoadModuleWithMeta(string, map[string]any) (*Query, error)
+// LoadInitModules() ([]*Query, error)
+// LoadJSON(string) (any, error)
+// LoadJSONWithMeta(string, map[string]any) (any, error)
+type ModuleLoader any
-// NewModuleLoader creates a new ModuleLoader reading local modules in the paths.
+// NewModuleLoader creates a new [ModuleLoader] reading local modules in the paths.
func NewModuleLoader(paths []string) ModuleLoader {
return &moduleLoader{expandHomeDir(paths)}
}
+type moduleLoader struct {
+ paths []string
+}
+
func (l *moduleLoader) LoadInitModules() ([]*Query, error) {
var qs []*Query
for _, path := range l.paths {
@@ -40,14 +51,14 @@ func (l *moduleLoader) LoadInitModules() ([]*Query, error) {
}
q, err := parseModule(path, string(cnt))
if err != nil {
- return nil, &queryParseError{"query in module", path, string(cnt), err}
+ return nil, &queryParseError{path, string(cnt), err}
}
qs = append(qs, q)
}
return qs, nil
}
-func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]interface{}) (*Query, error) {
+func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]any) (*Query, error) {
path, err := l.lookupModule(name, ".jq", meta)
if err != nil {
return nil, err
@@ -58,12 +69,12 @@ func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]interface
}
q, err := parseModule(path, string(cnt))
if err != nil {
- return nil, &queryParseError{"query in module", path, string(cnt), err}
+ return nil, &queryParseError{path, string(cnt), err}
}
return q, nil
}
-func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{}) (interface{}, error) {
+func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]any) (any, error) {
path, err := l.lookupModule(name, ".json", meta)
if err != nil {
return nil, err
@@ -73,11 +84,11 @@ func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{}
return nil, err
}
defer f.Close()
- var vals []interface{}
+ var vals []any
dec := json.NewDecoder(f)
dec.UseNumber()
for {
- var val interface{}
+ var val any
if err := dec.Decode(&val); err != nil {
if err == io.EOF {
break
@@ -96,7 +107,7 @@ func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]interface{}
return vals, nil
}
-func (l *moduleLoader) lookupModule(name, extension string, meta map[string]interface{}) (string, error) {
+func (l *moduleLoader) lookupModule(name, extension string, meta map[string]any) (string, error) {
paths := l.paths
if path := searchPath(meta); path != "" {
paths = append([]string{path}, paths...)
@@ -135,7 +146,7 @@ func parseModule(path, cnt string) (*Query, error) {
return q, nil
}
-func searchPath(meta map[string]interface{}) string {
+func searchPath(meta map[string]any) string {
x, ok := meta["search"]
if !ok {
return ""
diff --git a/vendor/github.com/itchyny/gojq/normalize.go b/vendor/github.com/itchyny/gojq/normalize.go
index afca122b..2bfcd215 100644
--- a/vendor/github.com/itchyny/gojq/normalize.go
+++ b/vendor/github.com/itchyny/gojq/normalize.go
@@ -7,8 +7,8 @@ import (
"strings"
)
-func normalizeNumber(v json.Number) interface{} {
- if i, err := v.Int64(); err == nil && minInt <= i && i <= maxInt {
+func normalizeNumber(v json.Number) any {
+ if i, err := v.Int64(); err == nil && math.MinInt <= i && i <= math.MaxInt {
return int(i)
}
if strings.ContainsAny(v.String(), ".eE") {
@@ -25,22 +25,22 @@ func normalizeNumber(v json.Number) interface{} {
return math.Inf(1)
}
-func normalizeNumbers(v interface{}) interface{} {
+func normalizeNumbers(v any) any {
switch v := v.(type) {
case json.Number:
return normalizeNumber(v)
case *big.Int:
if v.IsInt64() {
- if i := v.Int64(); minInt <= i && i <= maxInt {
+ if i := v.Int64(); math.MinInt <= i && i <= math.MaxInt {
return int(i)
}
}
return v
case int64:
- if v > maxInt || v < minInt {
- return new(big.Int).SetInt64(v)
+ if math.MinInt <= v && v <= math.MaxInt {
+ return int(v)
}
- return int(v)
+ return big.NewInt(v)
case int32:
return int(v)
case int16:
@@ -48,68 +48,36 @@ func normalizeNumbers(v interface{}) interface{} {
case int8:
return int(v)
case uint:
- if v > maxInt {
- return new(big.Int).SetUint64(uint64(v))
+ if v <= math.MaxInt {
+ return int(v)
}
- return int(v)
+ return new(big.Int).SetUint64(uint64(v))
case uint64:
- if v > maxInt {
- return new(big.Int).SetUint64(v)
+ if v <= math.MaxInt {
+ return int(v)
}
- return int(v)
+ return new(big.Int).SetUint64(v)
case uint32:
- if uint64(v) > maxInt {
- return new(big.Int).SetUint64(uint64(v))
+ if uint64(v) <= math.MaxInt {
+ return int(v)
}
- return int(v)
+ return new(big.Int).SetUint64(uint64(v))
case uint16:
return int(v)
case uint8:
return int(v)
case float32:
return float64(v)
- case map[string]interface{}:
- for k, x := range v {
- v[k] = normalizeNumbers(x)
- }
- return v
- case []interface{}:
+ case []any:
for i, x := range v {
v[i] = normalizeNumbers(x)
}
return v
- default:
- return v
- }
-}
-
-// It's ok to delete destructively because this function is used right after
-// updatePaths, where it shallow-copies maps or slices on updates.
-func deleteEmpty(v interface{}) interface{} {
- switch v := v.(type) {
- case struct{}:
- return nil
- case map[string]interface{}:
- for k, w := range v {
- if w == struct{}{} {
- delete(v, k)
- } else {
- v[k] = deleteEmpty(w)
- }
+ case map[string]any:
+ for k, x := range v {
+ v[k] = normalizeNumbers(x)
}
return v
- case []interface{}:
- var j int
- for _, w := range v {
- if w != struct{}{} {
- v[j] = deleteEmpty(w)
- j++
- }
- }
- for i := j; i < len(v); i++ {
- v[i] = nil
- }
- return v[:j]
default:
return v
}
diff --git a/vendor/github.com/itchyny/gojq/operator.go b/vendor/github.com/itchyny/gojq/operator.go
index 80e13ef9..73a548e0 100644
--- a/vendor/github.com/itchyny/gojq/operator.go
+++ b/vendor/github.com/itchyny/gojq/operator.go
@@ -37,7 +37,7 @@ const (
OpUpdateAlt
)
-// String implements Stringer.
+// String implements [fmt.Stringer].
func (op Operator) String() string {
switch op {
case OpPipe:
@@ -93,7 +93,7 @@ func (op Operator) String() string {
}
}
-// GoString implements GoStringer.
+// GoString implements [fmt.GoStringer].
func (op Operator) GoString() (str string) {
defer func() { str = "gojq." + str }()
switch op {
@@ -208,23 +208,19 @@ func (op Operator) getFunc() string {
}
func binopTypeSwitch(
- l, r interface{},
- callbackInts func(_, _ int) interface{},
- callbackFloats func(_, _ float64) interface{},
- callbackBigInts func(_, _ *big.Int) interface{},
- callbackStrings func(_, _ string) interface{},
- callbackArrays func(_, _ []interface{}) interface{},
- callbackMaps func(_, _ map[string]interface{}) interface{},
- fallback func(_, _ interface{}) interface{}) interface{} {
+ l, r any,
+ callbackInts func(_, _ int) any,
+ callbackFloats func(_, _ float64) any,
+ callbackBigInts func(_, _ *big.Int) any,
+ callbackStrings func(_, _ string) any,
+ callbackArrays func(_, _ []any) any,
+ callbackMaps func(_, _ map[string]any) any,
+ fallback func(_, _ any) any) any {
switch l := l.(type) {
case int:
switch r := r.(type) {
case int:
- if minHalfInt <= l && l <= maxHalfInt &&
- minHalfInt <= r && r <= maxHalfInt {
- return callbackInts(l, r)
- }
- return callbackBigInts(big.NewInt(int64(l)), big.NewInt(int64(r)))
+ return callbackInts(l, r)
case float64:
return callbackFloats(float64(l), r)
case *big.Int:
@@ -261,16 +257,16 @@ func binopTypeSwitch(
default:
return fallback(l, r)
}
- case []interface{}:
+ case []any:
switch r := r.(type) {
- case []interface{}:
+ case []any:
return callbackArrays(l, r)
default:
return fallback(l, r)
}
- case map[string]interface{}:
+ case map[string]any:
switch r := r.(type) {
- case map[string]interface{}:
+ case map[string]any:
return callbackMaps(l, r)
default:
return fallback(l, r)
@@ -280,7 +276,7 @@ func binopTypeSwitch(
}
}
-func funcOpPlus(v interface{}) interface{} {
+func funcOpPlus(v any) any {
switch v := v.(type) {
case int:
return v
@@ -293,7 +289,7 @@ func funcOpPlus(v interface{}) interface{} {
}
}
-func funcOpNegate(v interface{}) interface{} {
+func funcOpNegate(v any) any {
switch v := v.(type) {
case int:
return -v
@@ -306,28 +302,38 @@ func funcOpNegate(v interface{}) interface{} {
}
}
-func funcOpAdd(_, l, r interface{}) interface{} {
- if l == nil {
- return r
- } else if r == nil {
- return l
- }
+func funcOpAdd(_, l, r any) any {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} { return l + r },
- func(l, r float64) interface{} { return l + r },
- func(l, r *big.Int) interface{} { return new(big.Int).Add(l, r) },
- func(l, r string) interface{} { return l + r },
- func(l, r []interface{}) interface{} {
+ func(l, r int) any {
+ if v := l + r; (v >= l) == (r >= 0) {
+ return v
+ }
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Add(x, y)
+ },
+ func(l, r float64) any { return l + r },
+ func(l, r *big.Int) any { return new(big.Int).Add(l, r) },
+ func(l, r string) any { return l + r },
+ func(l, r []any) any {
+ if len(l) == 0 {
+ return r
+ }
if len(r) == 0 {
return l
- } else if len(l) == 0 {
- return r
}
- v := make([]interface{}, 0, len(l)+len(r))
- return append(append(v, l...), r...)
+ v := make([]any, len(l)+len(r))
+ copy(v, l)
+ copy(v[len(l):], r)
+ return v
},
- func(l, r map[string]interface{}) interface{} {
- m := make(map[string]interface{}, len(l)+len(r))
+ func(l, r map[string]any) any {
+ if len(l) == 0 {
+ return r
+ }
+ if len(r) == 0 {
+ return l
+ }
+ m := make(map[string]any, len(l)+len(r))
for k, v := range l {
m[k] = v
}
@@ -336,63 +342,71 @@ func funcOpAdd(_, l, r interface{}) interface{} {
}
return m
},
- func(l, r interface{}) interface{} { return &binopTypeError{"add", l, r} },
+ func(l, r any) any {
+ if l == nil {
+ return r
+ }
+ if r == nil {
+ return l
+ }
+ return &binopTypeError{"add", l, r}
+ },
)
}
-func funcOpSub(_, l, r interface{}) interface{} {
+func funcOpSub(_, l, r any) any {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} { return l - r },
- func(l, r float64) interface{} { return l - r },
- func(l, r *big.Int) interface{} { return new(big.Int).Sub(l, r) },
- func(l, r string) interface{} { return &binopTypeError{"subtract", l, r} },
- func(l, r []interface{}) interface{} {
- a := make([]interface{}, 0, len(l))
- for _, v := range l {
- var found bool
- for _, w := range r {
- if compare(v, w) == 0 {
- found = true
- break
+ func(l, r int) any {
+ if v := l - r; (v <= l) == (r >= 0) {
+ return v
+ }
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Sub(x, y)
+ },
+ func(l, r float64) any { return l - r },
+ func(l, r *big.Int) any { return new(big.Int).Sub(l, r) },
+ func(l, r string) any { return &binopTypeError{"subtract", l, r} },
+ func(l, r []any) any {
+ v := make([]any, 0, len(l))
+ L:
+ for _, l := range l {
+ for _, r := range r {
+ if compare(l, r) == 0 {
+ continue L
}
}
- if !found {
- a = append(a, v)
- }
+ v = append(v, l)
}
- return a
+ return v
},
- func(l, r map[string]interface{}) interface{} { return &binopTypeError{"subtract", l, r} },
- func(l, r interface{}) interface{} { return &binopTypeError{"subtract", l, r} },
+ func(l, r map[string]any) any { return &binopTypeError{"subtract", l, r} },
+ func(l, r any) any { return &binopTypeError{"subtract", l, r} },
)
}
-func funcOpMul(_, l, r interface{}) interface{} {
+func funcOpMul(_, l, r any) any {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} { return l * r },
- func(l, r float64) interface{} { return l * r },
- func(l, r *big.Int) interface{} { return new(big.Int).Mul(l, r) },
- func(l, r string) interface{} { return &binopTypeError{"multiply", l, r} },
- func(l, r []interface{}) interface{} { return &binopTypeError{"multiply", l, r} },
- deepMergeObjects,
- func(l, r interface{}) interface{} {
- multiplyString := func(s string, cnt float64) interface{} {
- if cnt <= 0.0 || cnt > float64(maxHalfInt/(16*(len(s)+1))) || math.IsNaN(cnt) {
- return nil
- }
- if cnt < 1.0 {
- return s
- }
- return strings.Repeat(s, int(cnt))
+ func(l, r int) any {
+ if v := l * r; r == 0 || v/r == l {
+ return v
}
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Mul(x, y)
+ },
+ func(l, r float64) any { return l * r },
+ func(l, r *big.Int) any { return new(big.Int).Mul(l, r) },
+ func(l, r string) any { return &binopTypeError{"multiply", l, r} },
+ func(l, r []any) any { return &binopTypeError{"multiply", l, r} },
+ deepMergeObjects,
+ func(l, r any) any {
if l, ok := l.(string); ok {
- if f, ok := toFloat(r); ok {
- return multiplyString(l, f)
+ if r, ok := toFloat(r); ok {
+ return repeatString(l, r)
}
}
if r, ok := r.(string); ok {
- if f, ok := toFloat(l); ok {
- return multiplyString(r, f)
+ if l, ok := toFloat(l); ok {
+ return repeatString(r, l)
}
}
return &binopTypeError{"multiply", l, r}
@@ -400,15 +414,15 @@ func funcOpMul(_, l, r interface{}) interface{} {
)
}
-func deepMergeObjects(l, r map[string]interface{}) interface{} {
- m := make(map[string]interface{}, len(l)+len(r))
+func deepMergeObjects(l, r map[string]any) any {
+ m := make(map[string]any, len(l)+len(r))
for k, v := range l {
m[k] = v
}
for k, v := range r {
if mk, ok := m[k]; ok {
- if mk, ok := mk.(map[string]interface{}); ok {
- if w, ok := v.(map[string]interface{}); ok {
+ if mk, ok := mk.(map[string]any); ok {
+ if w, ok := v.(map[string]any); ok {
v = deepMergeObjects(mk, w)
}
}
@@ -418,9 +432,19 @@ func deepMergeObjects(l, r map[string]interface{}) interface{} {
return m
}
-func funcOpDiv(_, l, r interface{}) interface{} {
+func repeatString(s string, n float64) any {
+ if n <= 0.0 || len(s) > 0 && n > float64(0x10000000/len(s)) || math.IsNaN(n) {
+ return nil
+ }
+ if int(n) < 1 {
+ return s
+ }
+ return strings.Repeat(s, int(n))
+}
+
+func funcOpDiv(_, l, r any) any {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} {
+ func(l, r int) any {
if r == 0 {
if l == 0 {
return math.NaN()
@@ -432,7 +456,7 @@ func funcOpDiv(_, l, r interface{}) interface{} {
}
return float64(l) / float64(r)
},
- func(l, r float64) interface{} {
+ func(l, r float64) any {
if r == 0.0 {
if l == 0.0 {
return math.NaN()
@@ -441,7 +465,7 @@ func funcOpDiv(_, l, r interface{}) interface{} {
}
return l / r
},
- func(l, r *big.Int) interface{} {
+ func(l, r *big.Int) any {
if r.Sign() == 0 {
if l.Sign() == 0 {
return math.NaN()
@@ -454,78 +478,78 @@ func funcOpDiv(_, l, r interface{}) interface{} {
}
return bigToFloat(l) / bigToFloat(r)
},
- func(l, r string) interface{} {
+ func(l, r string) any {
if l == "" {
- return []interface{}{}
+ return []any{}
}
xs := strings.Split(l, r)
- vs := make([]interface{}, len(xs))
+ vs := make([]any, len(xs))
for i, x := range xs {
vs[i] = x
}
return vs
},
- func(l, r []interface{}) interface{} { return &binopTypeError{"divide", l, r} },
- func(l, r map[string]interface{}) interface{} { return &binopTypeError{"divide", l, r} },
- func(l, r interface{}) interface{} { return &binopTypeError{"divide", l, r} },
+ func(l, r []any) any { return &binopTypeError{"divide", l, r} },
+ func(l, r map[string]any) any { return &binopTypeError{"divide", l, r} },
+ func(l, r any) any { return &binopTypeError{"divide", l, r} },
)
}
-func funcOpMod(_, l, r interface{}) interface{} {
+func funcOpMod(_, l, r any) any {
return binopTypeSwitch(l, r,
- func(l, r int) interface{} {
+ func(l, r int) any {
if r == 0 {
return &zeroModuloError{l, r}
}
return l % r
},
- func(l, r float64) interface{} {
+ func(l, r float64) any {
ri := floatToInt(r)
if ri == 0 {
return &zeroModuloError{l, r}
}
return floatToInt(l) % ri
},
- func(l, r *big.Int) interface{} {
+ func(l, r *big.Int) any {
if r.Sign() == 0 {
return &zeroModuloError{l, r}
}
return new(big.Int).Rem(l, r)
},
- func(l, r string) interface{} { return &binopTypeError{"modulo", l, r} },
- func(l, r []interface{}) interface{} { return &binopTypeError{"modulo", l, r} },
- func(l, r map[string]interface{}) interface{} { return &binopTypeError{"modulo", l, r} },
- func(l, r interface{}) interface{} { return &binopTypeError{"modulo", l, r} },
+ func(l, r string) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r []any) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r map[string]any) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r any) any { return &binopTypeError{"modulo", l, r} },
)
}
-func funcOpAlt(_, l, r interface{}) interface{} {
+func funcOpAlt(_, l, r any) any {
if l == nil || l == false {
return r
}
return l
}
-func funcOpEq(_, l, r interface{}) interface{} {
+func funcOpEq(_, l, r any) any {
return compare(l, r) == 0
}
-func funcOpNe(_, l, r interface{}) interface{} {
+func funcOpNe(_, l, r any) any {
return compare(l, r) != 0
}
-func funcOpGt(_, l, r interface{}) interface{} {
+func funcOpGt(_, l, r any) any {
return compare(l, r) > 0
}
-func funcOpLt(_, l, r interface{}) interface{} {
+func funcOpLt(_, l, r any) any {
return compare(l, r) < 0
}
-func funcOpGe(_, l, r interface{}) interface{} {
+func funcOpGe(_, l, r any) any {
return compare(l, r) >= 0
}
-func funcOpLe(_, l, r interface{}) interface{} {
+func funcOpLe(_, l, r any) any {
return compare(l, r) <= 0
}
diff --git a/vendor/github.com/itchyny/gojq/option.go b/vendor/github.com/itchyny/gojq/option.go
index 5eb771cc..f1a110fa 100644
--- a/vendor/github.com/itchyny/gojq/option.go
+++ b/vendor/github.com/itchyny/gojq/option.go
@@ -6,7 +6,7 @@ import "fmt"
type CompilerOption func(*compiler)
// WithModuleLoader is a compiler option for module loader.
-// If you want to load modules from the filesystem, use NewModuleLoader.
+// If you want to load modules from the filesystem, use [NewModuleLoader].
func WithModuleLoader(moduleLoader ModuleLoader) CompilerOption {
return func(c *compiler) {
c.moduleLoader = moduleLoader
@@ -15,7 +15,7 @@ func WithModuleLoader(moduleLoader ModuleLoader) CompilerOption {
// WithEnvironLoader is a compiler option for environment variables loader.
// The OS environment variables are not accessible by default due to security
-// reason. You can pass os.Environ if you allow to access it.
+// reasons. You can specify [os.Environ] as argument if you allow to access.
func WithEnvironLoader(environLoader func() []string) CompilerOption {
return func(c *compiler) {
c.environLoader = environLoader
@@ -23,7 +23,7 @@ func WithEnvironLoader(environLoader func() []string) CompilerOption {
}
// WithVariables is a compiler option for variable names. The variables can be
-// used in the query. You have to give the values to code.Run in the same order.
+// used in the query. You have to give the values to [*Code.Run] in the same order.
func WithVariables(variables []string) CompilerOption {
return func(c *compiler) {
c.variables = variables
@@ -35,31 +35,28 @@ func WithVariables(variables []string) CompilerOption {
// values should satisfy 0 <= minarity <= maxarity <= 30, otherwise panics.
// On handling numbers, you should take account to int, float64 and *big.Int.
// These are the number types you are allowed to return, so do not return int64.
-// Refer to ValueError to return a value error just like built-in error function.
-// If you want to emit multiple values, call the empty function, accept a filter
-// for its argument, or call another built-in function, then use LoadInitModules
-// of the module loader.
-func WithFunction(name string, minarity, maxarity int,
- f func(interface{}, []interface{}) interface{}) CompilerOption {
+// Refer to [ValueError] to return a value error just like built-in error
+// function. If you want to emit multiple values, call the empty function,
+// accept a filter for its argument, or call another built-in function, then
+// use LoadInitModules of the module loader.
+func WithFunction(name string, minarity, maxarity int, f func(any, []any) any) CompilerOption {
return withFunction(name, minarity, maxarity, false, f)
}
// WithIterFunction is a compiler option for adding a custom iterator function.
-// This is like the WithFunction option, but you can add a function which
+// This is like the [WithFunction] option, but you can add a function which
// returns an Iter to emit multiple values. You cannot define both iterator and
// non-iterator functions of the same name (with possibly different arities).
-// See also NewIter, which can be used to convert values or an error to an Iter.
-func WithIterFunction(name string, minarity, maxarity int,
- f func(interface{}, []interface{}) Iter) CompilerOption {
+// See also [NewIter], which can be used to convert values or an error to an Iter.
+func WithIterFunction(name string, minarity, maxarity int, f func(any, []any) Iter) CompilerOption {
return withFunction(name, minarity, maxarity, true,
- func(v interface{}, args []interface{}) interface{} {
+ func(v any, args []any) any {
return f(v, args)
},
)
}
-func withFunction(name string, minarity, maxarity int, iter bool,
- f func(interface{}, []interface{}) interface{}) CompilerOption {
+func withFunction(name string, minarity, maxarity int, iter bool, f func(any, []any) any) CompilerOption {
if !(0 <= minarity && minarity <= maxarity && maxarity <= 30) {
panic(fmt.Sprintf("invalid arity for %q: %d, %d", name, minarity, maxarity))
}
@@ -74,7 +71,7 @@ func withFunction(name string, minarity, maxarity int, iter bool,
}
c.customFuncs[name] = function{
argcount | fn.argcount, iter,
- func(x interface{}, xs []interface{}) interface{} {
+ func(x any, xs []any) any {
if argcount&(1< 0 {
@@ -30,10 +35,10 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef {
return xs
}
-//line parser.go.y:28
+//line parser.go.y:33
type yySymType struct {
yys int
- value interface{}
+ value any
token string
operator Operator
}
@@ -61,24 +66,26 @@ const tokModuleVariable = 57365
const tokIndex = 57366
const tokNumber = 57367
const tokFormat = 57368
-const tokInvalid = 57369
-const tokString = 57370
-const tokStringStart = 57371
-const tokStringQuery = 57372
-const tokStringEnd = 57373
-const tokIf = 57374
-const tokThen = 57375
-const tokElif = 57376
-const tokElse = 57377
-const tokEnd = 57378
-const tokTry = 57379
-const tokCatch = 57380
-const tokReduce = 57381
-const tokForeach = 57382
-const tokRecurse = 57383
-const tokFuncDefPost = 57384
-const tokTermPost = 57385
-const tokEmptyCatch = 57386
+const tokString = 57369
+const tokStringStart = 57370
+const tokStringQuery = 57371
+const tokStringEnd = 57372
+const tokIf = 57373
+const tokThen = 57374
+const tokElif = 57375
+const tokElse = 57376
+const tokEnd = 57377
+const tokTry = 57378
+const tokCatch = 57379
+const tokReduce = 57380
+const tokForeach = 57381
+const tokRecurse = 57382
+const tokFuncDefPost = 57383
+const tokTermPost = 57384
+const tokEmptyCatch = 57385
+const tokInvalid = 57386
+const tokInvalidEscapeSequence = 57387
+const tokUnterminatedString = 57388
var yyToknames = [...]string{
"$end",
@@ -107,7 +114,6 @@ var yyToknames = [...]string{
"tokIndex",
"tokNumber",
"tokFormat",
- "tokInvalid",
"tokString",
"tokStringStart",
"tokStringQuery",
@@ -125,6 +131,9 @@ var yyToknames = [...]string{
"tokFuncDefPost",
"tokTermPost",
"tokEmptyCatch",
+ "tokInvalid",
+ "tokInvalidEscapeSequence",
+ "tokUnterminatedString",
"'|'",
"','",
"'+'",
@@ -150,15 +159,15 @@ const yyEofCode = 1
const yyErrCode = 2
const yyInitialStackSize = 16
-//line parser.go.y:687
+//line parser.go.y:693
//line yacctab:1
-var yyExca = [...]int{
+var yyExca = [...]int16{
-1, 1,
1, -1,
-2, 0,
-1, 97,
- 53, 0,
+ 55, 0,
-2, 104,
-1, 130,
5, 0,
@@ -167,167 +176,170 @@ var yyExca = [...]int{
9, 0,
-2, 35,
-1, 194,
- 56, 114,
+ 58, 114,
-2, 54,
}
const yyPrivate = 57344
-const yyLast = 1094
+const yyLast = 1127
-var yyAct = [...]int{
+var yyAct = [...]int16{
86, 214, 174, 112, 12, 203, 9, 175, 111, 31,
190, 6, 156, 140, 117, 47, 95, 97, 93, 94,
- 89, 227, 49, 75, 76, 7, 77, 78, 79, 240,
- 235, 103, 239, 106, 164, 123, 226, 119, 107, 108,
- 105, 234, 102, 75, 76, 113, 77, 78, 79, 163,
- 122, 104, 211, 75, 76, 210, 77, 78, 79, 158,
- 159, 264, 259, 243, 72, 74, 80, 81, 82, 83,
- 84, 229, 73, 127, 275, 128, 129, 130, 131, 132,
- 133, 134, 135, 136, 137, 138, 80, 81, 82, 83,
- 84, 228, 73, 147, 72, 74, 80, 81, 82, 83,
- 84, 145, 73, 141, 278, 161, 246, 277, 157, 225,
- 166, 165, 144, 126, 125, 167, 88, 42, 43, 245,
- 124, 258, 224, 206, 179, 180, 181, 44, 183, 184,
- 73, 242, 177, 154, 153, 178, 142, 186, 49, 173,
- 267, 100, 143, 92, 91, 90, 92, 191, 99, 197,
- 150, 120, 200, 192, 201, 202, 188, 256, 257, 207,
- 88, 182, 98, 198, 199, 209, 219, 7, 216, 101,
- 215, 215, 218, 213, 113, 155, 185, 75, 76, 3,
- 77, 78, 79, 42, 43, 221, 222, 28, 91, 90,
- 92, 179, 180, 181, 230, 204, 205, 232, 8, 177,
- 223, 27, 178, 80, 81, 82, 83, 84, 220, 73,
- 85, 157, 241, 176, 46, 149, 237, 110, 72, 74,
- 80, 81, 82, 83, 84, 88, 73, 152, 182, 196,
- 79, 191, 195, 255, 7, 253, 254, 192, 248, 247,
- 236, 160, 249, 250, 96, 262, 260, 261, 215, 263,
- 11, 121, 189, 91, 90, 92, 11, 268, 269, 187,
- 270, 82, 83, 84, 139, 73, 272, 273, 80, 81,
- 82, 83, 84, 208, 73, 279, 10, 5, 271, 280,
- 51, 52, 4, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 115, 116, 170, 2, 171, 169, 1,
- 0, 42, 43, 0, 0, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 0, 0, 20, 0, 17, 37,
- 24, 25, 26, 38, 40, 39, 41, 23, 29, 30,
- 114, 42, 43, 0, 212, 15, 0, 0, 0, 0,
- 16, 0, 13, 14, 22, 0, 0, 0, 0, 0,
- 33, 34, 0, 0, 0, 21, 0, 36, 0, 148,
- 32, 0, 146, 35, 51, 52, 0, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 115, 116, 0,
+ 89, 141, 49, 7, 179, 180, 181, 240, 246, 264,
+ 239, 103, 177, 106, 178, 227, 164, 119, 107, 108,
+ 105, 245, 102, 75, 76, 113, 77, 78, 79, 123,
+ 226, 163, 211, 225, 259, 210, 142, 179, 180, 181,
+ 158, 159, 143, 182, 122, 177, 224, 178, 219, 7,
+ 235, 234, 104, 127, 243, 128, 129, 130, 131, 132,
+ 133, 134, 135, 136, 137, 138, 72, 74, 80, 81,
+ 82, 83, 84, 147, 73, 88, 182, 196, 73, 229,
+ 195, 145, 7, 150, 228, 161, 166, 165, 157, 126,
+ 125, 124, 144, 88, 258, 167, 80, 81, 82, 83,
+ 84, 206, 73, 44, 242, 91, 90, 92, 183, 184,
+ 82, 83, 84, 154, 73, 153, 267, 186, 49, 173,
+ 42, 43, 100, 91, 90, 92, 99, 191, 120, 197,
+ 256, 257, 200, 192, 201, 202, 188, 75, 76, 207,
+ 77, 78, 79, 198, 199, 209, 42, 43, 216, 92,
+ 215, 215, 218, 213, 113, 98, 75, 76, 185, 77,
+ 78, 79, 204, 205, 101, 221, 222, 170, 155, 171,
+ 169, 3, 28, 27, 230, 96, 220, 232, 176, 46,
+ 223, 11, 80, 81, 82, 83, 84, 11, 73, 78,
+ 79, 157, 241, 110, 8, 152, 237, 255, 236, 72,
+ 74, 80, 81, 82, 83, 84, 85, 73, 79, 278,
+ 160, 191, 277, 121, 189, 253, 254, 192, 248, 247,
+ 187, 139, 249, 250, 208, 262, 260, 261, 215, 263,
+ 80, 81, 82, 83, 84, 149, 73, 268, 269, 10,
+ 270, 5, 4, 2, 1, 88, 272, 273, 80, 81,
+ 82, 83, 84, 0, 73, 279, 0, 0, 271, 280,
+ 51, 52, 0, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 115, 116, 91, 90, 92, 0, 0,
+ 42, 43, 0, 87, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 88, 0, 20, 0, 17, 37, 24,
+ 25, 26, 38, 40, 39, 41, 23, 29, 30, 42,
+ 43, 0, 114, 15, 0, 0, 212, 0, 16, 0,
+ 13, 14, 22, 91, 90, 92, 0, 0, 0, 0,
+ 0, 33, 34, 0, 0, 0, 21, 0, 36, 0,
+ 148, 32, 0, 146, 35, 51, 52, 0, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 115, 116,
0, 0, 0, 0, 0, 42, 43, 0, 0, 63,
64, 65, 66, 67, 68, 69, 70, 71, 18, 19,
20, 0, 17, 37, 24, 25, 26, 38, 40, 39,
- 41, 23, 29, 30, 114, 42, 43, 0, 109, 15,
- 0, 0, 0, 0, 16, 0, 13, 14, 22, 0,
+ 41, 23, 29, 30, 42, 43, 0, 114, 15, 0,
+ 0, 109, 0, 16, 0, 13, 14, 22, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33, 34, 0, 0,
+ 0, 21, 0, 36, 0, 0, 32, 0, 20, 35,
+ 17, 37, 24, 25, 26, 38, 40, 39, 41, 23,
+ 29, 30, 42, 43, 0, 0, 15, 0, 0, 0,
+ 0, 16, 0, 13, 14, 22, 0, 0, 0, 0,
0, 0, 0, 0, 33, 34, 0, 0, 0, 21,
- 0, 36, 0, 0, 32, 0, 20, 35, 17, 37,
- 24, 25, 26, 38, 40, 39, 41, 23, 29, 30,
- 0, 42, 43, 0, 0, 15, 0, 0, 0, 0,
- 16, 0, 13, 14, 22, 0, 87, 0, 0, 0,
- 33, 34, 0, 0, 0, 21, 88, 36, 0, 0,
- 32, 0, 231, 35, 20, 0, 17, 37, 24, 25,
- 26, 38, 40, 39, 41, 23, 29, 30, 0, 42,
- 43, 0, 0, 15, 91, 90, 92, 0, 16, 0,
- 13, 14, 22, 0, 0, 0, 0, 0, 33, 34,
- 0, 0, 0, 21, 0, 36, 0, 0, 32, 0,
- 118, 35, 20, 0, 17, 37, 24, 25, 26, 38,
- 40, 39, 41, 23, 29, 30, 0, 42, 43, 0,
- 0, 15, 0, 77, 78, 79, 16, 0, 13, 14,
- 22, 0, 0, 0, 0, 0, 33, 34, 0, 0,
- 0, 21, 0, 36, 0, 0, 32, 51, 52, 35,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 48, 0, 0, 80, 81, 82, 83, 84, 50, 73,
- 0, 0, 63, 64, 65, 66, 67, 68, 69, 70,
+ 0, 36, 0, 0, 32, 0, 231, 35, 20, 0,
+ 17, 37, 24, 25, 26, 38, 40, 39, 41, 23,
+ 29, 30, 42, 43, 0, 0, 15, 0, 0, 0,
+ 0, 16, 0, 13, 14, 22, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 34, 0, 0, 0, 21,
+ 0, 36, 0, 0, 32, 0, 118, 35, 20, 0,
+ 17, 37, 24, 25, 26, 38, 40, 39, 41, 23,
+ 29, 30, 42, 43, 0, 0, 15, 0, 77, 78,
+ 79, 16, 0, 13, 14, 22, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 34, 0, 0, 0, 21,
+ 0, 36, 0, 0, 32, 51, 52, 35, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 48, 0,
+ 80, 81, 82, 83, 84, 50, 73, 0, 0, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 51, 52,
+ 0, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 48, 0, 0, 0, 0, 0, 0, 50, 0,
+ 0, 172, 63, 64, 65, 66, 67, 68, 69, 70,
71, 51, 52, 0, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 62, 48, 0, 0, 0, 0, 0,
- 0, 172, 50, 0, 0, 0, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 51, 52, 0, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 115, 194,
- 78, 79, 0, 0, 0, 45, 42, 43, 0, 0,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 37,
- 24, 25, 26, 38, 40, 39, 41, 23, 29, 30,
- 0, 42, 43, 75, 76, 193, 77, 78, 79, 80,
- 81, 82, 83, 84, 22, 73, 0, 0, 0, 0,
- 33, 34, 0, 0, 0, 21, 0, 36, 0, 0,
- 32, 75, 76, 35, 77, 78, 79, 0, 0, 0,
- 0, 0, 0, 0, 72, 74, 80, 81, 82, 83,
- 84, 0, 73, 0, 0, 0, 75, 76, 252, 77,
- 78, 79, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 72, 74, 80, 81, 82, 83, 84, 0,
- 73, 0, 0, 0, 75, 76, 233, 77, 78, 79,
- 0, 0, 0, 0, 0, 0, 0, 72, 74, 80,
- 81, 82, 83, 84, 0, 73, 0, 0, 0, 75,
- 76, 168, 77, 78, 79, 0, 0, 0, 0, 0,
+ 59, 60, 61, 62, 115, 194, 0, 0, 0, 0,
+ 0, 42, 43, 0, 45, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 37, 24, 25, 26, 38, 40,
+ 39, 41, 23, 29, 30, 42, 43, 75, 76, 0,
+ 77, 78, 79, 193, 0, 0, 0, 0, 22, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 34, 0,
+ 0, 0, 21, 0, 36, 0, 0, 32, 75, 76,
+ 35, 77, 78, 79, 0, 0, 0, 0, 0, 0,
+ 72, 74, 80, 81, 82, 83, 84, 0, 73, 0,
+ 0, 0, 75, 76, 252, 77, 78, 79, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 72, 74, 80, 81, 82, 83, 84, 0, 73,
+ 0, 0, 0, 75, 76, 233, 77, 78, 79, 0,
0, 0, 0, 0, 0, 72, 74, 80, 81, 82,
- 83, 84, 0, 73, 0, 0, 75, 76, 281, 77,
- 78, 79, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83, 84, 0, 73, 0, 0, 0, 75, 76, 168,
+ 77, 78, 79, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 72, 74, 80, 81,
+ 82, 83, 84, 0, 73, 0, 0, 75, 76, 281,
+ 77, 78, 79, 0, 0, 0, 0, 0, 0, 0,
72, 74, 80, 81, 82, 83, 84, 0, 73, 0,
0, 75, 76, 276, 77, 78, 79, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 72, 74, 80,
- 81, 82, 83, 84, 0, 73, 0, 0, 75, 76,
- 251, 77, 78, 79, 0, 0, 0, 0, 0, 0,
- 0, 0, 72, 74, 80, 81, 82, 83, 84, 0,
- 73, 0, 0, 75, 76, 244, 77, 78, 79, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
- 74, 80, 81, 82, 83, 84, 0, 73, 0, 0,
- 75, 76, 217, 77, 78, 79, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72, 74, 80, 81, 82, 83, 84, 0, 73, 0,
+ 0, 75, 76, 251, 77, 78, 79, 0, 0, 0,
0, 0, 0, 0, 72, 74, 80, 81, 82, 83,
- 84, 0, 73, 0, 0, 75, 76, 162, 77, 78,
+ 84, 0, 73, 0, 0, 75, 76, 244, 77, 78,
79, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 72, 74, 80, 81, 82, 83, 84, 0, 73,
- 0, 266, 75, 76, 0, 77, 78, 79, 0, 0,
- 0, 0, 0, 0, 0, 0, 72, 74, 80, 81,
- 82, 83, 84, 0, 73, 0, 265, 75, 76, 0,
- 77, 78, 79, 0, 0, 0, 75, 76, 0, 77,
- 78, 79, 0, 72, 74, 80, 81, 82, 83, 84,
- 0, 73, 0, 238, 75, 76, 274, 77, 78, 79,
- 0, 0, 0, 0, 0, 151, 0, 0, 72, 74,
- 80, 81, 82, 83, 84, 0, 73, 72, 74, 80,
- 81, 82, 83, 84, 0, 73, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 72, 74, 80, 81, 82,
- 83, 84, 0, 73,
+ 0, 0, 0, 0, 72, 74, 80, 81, 82, 83,
+ 84, 0, 73, 0, 0, 75, 76, 217, 77, 78,
+ 79, 0, 0, 0, 0, 0, 0, 0, 72, 74,
+ 80, 81, 82, 83, 84, 0, 73, 0, 0, 75,
+ 76, 162, 77, 78, 79, 0, 0, 0, 0, 0,
+ 75, 76, 0, 77, 78, 79, 0, 0, 72, 74,
+ 80, 81, 82, 83, 84, 0, 73, 0, 275, 75,
+ 76, 0, 77, 78, 79, 0, 0, 0, 0, 0,
+ 0, 0, 72, 74, 80, 81, 82, 83, 84, 0,
+ 73, 0, 266, 72, 74, 80, 81, 82, 83, 84,
+ 0, 73, 0, 265, 75, 76, 0, 77, 78, 79,
+ 0, 0, 72, 74, 80, 81, 82, 83, 84, 0,
+ 73, 0, 238, 0, 0, 0, 75, 76, 0, 77,
+ 78, 79, 274, 0, 0, 75, 76, 0, 77, 78,
+ 79, 0, 0, 0, 0, 0, 0, 72, 74, 80,
+ 81, 82, 83, 84, 151, 73, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
+ 74, 80, 81, 82, 83, 84, 0, 73, 72, 74,
+ 80, 81, 82, 83, 84, 0, 73,
}
-var yyPact = [...]int{
- 169, -1000, -1000, -35, -1000, 387, 72, 614, -1000, 1040,
- -1000, 529, 462, 673, 673, 529, 529, 141, 120, 113,
- 149, 89, -1000, -1000, -1000, -1000, -1000, -6, -1000, -1000,
- 155, -1000, 529, 673, 673, 357, 481, 130, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -11, -1000, 64, 58,
- 57, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+var yyPact = [...]int16{
+ 181, -1000, -1000, -39, -1000, 387, 66, 621, -1000, 1071,
+ -1000, 535, 289, 678, 678, 535, 535, 154, 119, 115,
+ 164, 113, -1000, -1000, -1000, -1000, -1000, 13, -1000, -1000,
+ 139, -1000, 535, 678, 678, 358, 485, 127, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, 1, -1000, 53, 52,
+ 51, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, 529, -1000, 529, 529, 529, 529, 529, 529,
- 529, 529, 529, 529, 529, -1000, 1040, 82, -1000, -1000,
- -1000, 89, 303, 201, 136, 1022, 529, 96, 88, 161,
- -35, 3, -1000, -1000, 529, -1000, 909, 92, 92, -1000,
- -12, -1000, 55, 54, 529, -1000, -1000, -1000, -1000, 752,
- -1000, 267, -1000, 580, 174, 174, 174, 1040, 39, 39,
- 556, 662, 221, 156, 212, 212, 77, 77, 77, 131,
- -1000, -1000, 82, 648, -1000, -1000, -1000, 173, 529, 82,
- 82, 529, -1000, 529, 529, 175, 68, -1000, 529, 175,
- -3, 1040, -1000, -1000, 273, 673, 673, 884, -1000, -1000,
- -1000, 529, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, 107, -1000, -1000, 529, 82, 63, -1000, -25,
- -1000, 35, 15, 529, -1000, -1000, 433, 727, -16, -27,
- 1040, -1000, 1040, -35, -1000, -1000, -1000, 988, -26, -1000,
- -1000, 529, -1000, -1000, 86, 92, 86, 7, 857, -1000,
- 60, -1000, 1040, -1000, -1000, 82, -1000, 648, 82, 82,
- 832, -1000, 699, -1000, 529, 529, 123, 66, -1000, 6,
- 175, 1040, 673, 673, -1000, -1000, 174, -1000, -1000, -1000,
- -1000, 5, -1000, 961, 936, 104, 529, 529, -1000, 529,
- -1000, 92, 86, -1000, 82, 529, 529, -1000, 1013, 1040,
- 19, -1000, 805, 49, 529, -1000, -1000, -1000, 529, 1040,
- 780, -1000,
+ -1000, -1000, 535, -1000, 535, 535, 535, 535, 535, 535,
+ 535, 535, 535, 535, 535, -1000, 1071, 0, -1000, -1000,
+ -1000, 113, 302, 241, 89, 1062, 535, 98, 86, 174,
+ -39, 2, -1000, -1000, 535, -1000, 921, 71, 71, -1000,
+ -12, -1000, 49, 48, 535, -1000, -1000, -1000, -1000, 758,
+ -1000, 160, -1000, 588, 40, 40, 40, 1071, 153, 153,
+ 561, 201, 219, 67, 79, 79, 43, 43, 43, 131,
+ -1000, -1000, 0, 654, -1000, -1000, -1000, 39, 535, 0,
+ 0, 535, -1000, 535, 535, 162, 64, -1000, 535, 162,
+ -5, 1071, -1000, -1000, 273, 678, 678, 897, -1000, -1000,
+ -1000, 535, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, 7, -1000, -1000, 535, 0, 5, -1000, -13,
+ -1000, 46, 41, 535, -1000, -1000, 435, 734, 12, 11,
+ 1071, -1000, 1071, -39, -1000, -1000, -1000, 1005, -30, -1000,
+ -1000, 535, -1000, -1000, 77, 71, 77, 16, 867, -1000,
+ -20, -1000, 1071, -1000, -1000, 0, -1000, 654, 0, 0,
+ 843, -1000, 703, -1000, 535, 535, 117, 57, -1000, -4,
+ 162, 1071, 678, 678, -1000, -1000, 40, -1000, -1000, -1000,
+ -1000, -29, -1000, 986, 975, 101, 535, 535, -1000, 535,
+ -1000, 71, 77, -1000, 0, 535, 535, -1000, 1040, 1071,
+ 951, -1000, 813, 172, 535, -1000, -1000, -1000, 535, 1071,
+ 789, -1000,
}
-var yyPgo = [...]int{
- 0, 299, 296, 282, 277, 276, 12, 198, 244, 273,
- 0, 264, 13, 259, 252, 10, 4, 9, 251, 20,
- 241, 240, 233, 227, 217, 8, 1, 2, 7, 214,
- 15, 213, 208, 5, 201, 187, 14, 3,
+var yyPgo = [...]int16{
+ 0, 264, 263, 262, 261, 259, 12, 214, 195, 244,
+ 0, 241, 13, 240, 234, 10, 4, 9, 233, 20,
+ 230, 218, 217, 215, 213, 8, 1, 2, 7, 199,
+ 15, 198, 196, 5, 193, 192, 14, 3,
}
-var yyR1 = [...]int{
+var yyR1 = [...]int8{
0, 1, 2, 2, 3, 3, 4, 4, 5, 5,
6, 6, 7, 7, 8, 8, 9, 9, 33, 33,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
@@ -346,7 +358,7 @@ var yyR1 = [...]int{
36, 36, 36, 36, 36, 36, 36, 36,
}
-var yyR2 = [...]int{
+var yyR2 = [...]int8{
0, 2, 0, 3, 2, 2, 0, 2, 6, 4,
0, 1, 0, 2, 5, 8, 1, 3, 1, 1,
2, 3, 5, 9, 9, 11, 7, 3, 4, 2,
@@ -365,39 +377,39 @@ var yyR2 = [...]int{
1, 1, 1, 1, 1, 1, 1, 1,
}
-var yyChk = [...]int{
- -1000, -1, -2, 10, -3, -4, -28, 60, -7, -10,
- -5, -8, -16, 39, 40, 32, 37, 15, 11, 12,
- 13, 52, 41, 24, 17, 18, 19, -34, -35, 25,
- 26, -17, 57, 47, 48, 60, 54, 16, 20, 22,
- 21, 23, 28, 29, 55, 61, -29, -30, 20, -36,
- 28, 7, 8, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 45, 53, 46, 4, 5, 7, 8, 9,
- 47, 48, 49, 50, 51, -7, -10, 14, 24, -19,
- 53, 52, 54, -16, -16, -10, -8, -10, 21, 28,
- 28, 20, -19, -17, 57, -17, -10, -16, -16, 61,
- -24, -25, -37, -17, 57, 20, 21, -36, 59, -10,
- 21, -18, 61, 46, 56, 56, 56, -10, -10, -10,
+var yyChk = [...]int16{
+ -1000, -1, -2, 10, -3, -4, -28, 62, -7, -10,
+ -5, -8, -16, 38, 39, 31, 36, 15, 11, 12,
+ 13, 54, 40, 24, 17, 18, 19, -34, -35, 25,
+ 26, -17, 59, 49, 50, 62, 56, 16, 20, 22,
+ 21, 23, 27, 28, 57, 63, -29, -30, 20, -36,
+ 27, 7, 8, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 47, 55, 48, 4, 5, 7, 8, 9,
+ 49, 50, 51, 52, 53, -7, -10, 14, 24, -19,
+ 55, 54, 56, -16, -16, -10, -8, -10, 21, 27,
+ 27, 20, -19, -17, 59, -17, -10, -16, -16, 63,
+ -24, -25, -37, -17, 59, 20, 21, -36, 61, -10,
+ 21, -18, 63, 48, 58, 58, 58, -10, -10, -10,
-10, -10, -10, -10, -10, -10, -10, -10, -10, -11,
- -12, 21, 54, 60, -19, -17, 59, -10, 56, 14,
- 14, 33, -23, 38, 45, 14, -6, -28, 56, 57,
- -20, -10, 58, 61, 46, 56, 56, -10, 59, 31,
- 28, 30, 61, -30, -27, -28, -31, 25, 28, 17,
- 18, 19, 54, -27, -27, 45, 6, -13, -12, -14,
- -15, -37, -17, 57, 21, 59, 56, -10, -12, -12,
- -10, -10, -10, -33, 20, 21, 55, -10, -9, -33,
- 58, 55, 61, -25, -26, -16, -26, 58, -10, 59,
- -32, -27, -10, -12, 59, 46, 61, 46, 56, 56,
- -10, 59, -10, 59, 57, 57, -21, -6, 55, 58,
- 55, -10, 45, 56, 58, 59, 46, -12, -15, -12,
- -12, 58, 59, -10, -10, -22, 34, 35, 55, 56,
- -33, -16, -26, -27, 56, 55, 55, 36, -10, -10,
- -10, -12, -10, -10, 33, 55, 58, 58, 55, -10,
- -10, 58,
+ -12, 21, 56, 62, -19, -17, 61, -10, 58, 14,
+ 14, 32, -23, 37, 47, 14, -6, -28, 58, 59,
+ -20, -10, 60, 63, 48, 58, 58, -10, 61, 30,
+ 27, 29, 63, -30, -27, -28, -31, 25, 27, 17,
+ 18, 19, 56, -27, -27, 47, 6, -13, -12, -14,
+ -15, -37, -17, 59, 21, 61, 58, -10, -12, -12,
+ -10, -10, -10, -33, 20, 21, 57, -10, -9, -33,
+ 60, 57, 63, -25, -26, -16, -26, 60, -10, 61,
+ -32, -27, -10, -12, 61, 48, 63, 48, 58, 58,
+ -10, 61, -10, 61, 59, 59, -21, -6, 57, 60,
+ 57, -10, 47, 58, 60, 61, 48, -12, -15, -12,
+ -12, 60, 61, -10, -10, -22, 33, 34, 57, 58,
+ -33, -16, -26, -27, 58, 57, 57, 35, -10, -10,
+ -10, -12, -10, -10, 32, 57, 60, 60, 57, -10,
+ -10, 60,
}
-var yyDef = [...]int{
+var yyDef = [...]int16{
2, -2, 6, 0, 1, 12, 0, 0, 4, 5,
7, 12, 41, 0, 0, 0, 0, 0, 0, 0,
0, 55, 56, 57, 60, 61, 62, 63, 65, 66,
@@ -429,31 +441,31 @@ var yyDef = [...]int{
0, 25,
}
-var yyTok1 = [...]int{
+var yyTok1 = [...]int8{
1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 51, 3, 3,
- 57, 58, 49, 47, 46, 48, 52, 50, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 56, 55,
- 3, 3, 3, 53, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 53, 3, 3,
+ 59, 60, 51, 49, 48, 50, 54, 52, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 58, 57,
+ 3, 3, 3, 55, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 54, 3, 59, 3, 3, 3, 3, 3, 3,
+ 3, 56, 3, 61, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 60, 45, 61,
+ 3, 3, 3, 62, 47, 63,
}
-var yyTok2 = [...]int{
+var yyTok2 = [...]int8{
2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44,
+ 42, 43, 44, 45, 46,
}
-var yyTok3 = [...]int{
+var yyTok3 = [...]int8{
0,
}
@@ -535,9 +547,9 @@ func yyErrorMessage(state, lookAhead int) string {
expected := make([]int, 0, 4)
// Look for shiftable tokens.
- base := yyPact[state]
+ base := int(yyPact[state])
for tok := TOKSTART; tok-1 < len(yyToknames); tok++ {
- if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok {
+ if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok {
if len(expected) == cap(expected) {
return res
}
@@ -547,13 +559,13 @@ func yyErrorMessage(state, lookAhead int) string {
if yyDef[state] == -2 {
i := 0
- for yyExca[i] != -1 || yyExca[i+1] != state {
+ for yyExca[i] != -1 || int(yyExca[i+1]) != state {
i += 2
}
// Look for tokens that we accept or reduce.
for i += 2; yyExca[i] >= 0; i += 2 {
- tok := yyExca[i]
+ tok := int(yyExca[i])
if tok < TOKSTART || yyExca[i+1] == 0 {
continue
}
@@ -584,30 +596,30 @@ func yylex1(lex yyLexer, lval *yySymType) (char, token int) {
token = 0
char = lex.Lex(lval)
if char <= 0 {
- token = yyTok1[0]
+ token = int(yyTok1[0])
goto out
}
if char < len(yyTok1) {
- token = yyTok1[char]
+ token = int(yyTok1[char])
goto out
}
if char >= yyPrivate {
if char < yyPrivate+len(yyTok2) {
- token = yyTok2[char-yyPrivate]
+ token = int(yyTok2[char-yyPrivate])
goto out
}
}
for i := 0; i < len(yyTok3); i += 2 {
- token = yyTok3[i+0]
+ token = int(yyTok3[i+0])
if token == char {
- token = yyTok3[i+1]
+ token = int(yyTok3[i+1])
goto out
}
}
out:
if token == 0 {
- token = yyTok2[1] /* unknown char */
+ token = int(yyTok2[1]) /* unknown char */
}
if yyDebug >= 3 {
__yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char))
@@ -662,7 +674,7 @@ yystack:
yyS[yyp].yys = yystate
yynewstate:
- yyn = yyPact[yystate]
+ yyn = int(yyPact[yystate])
if yyn <= yyFlag {
goto yydefault /* simple state */
}
@@ -673,8 +685,8 @@ yynewstate:
if yyn < 0 || yyn >= yyLast {
goto yydefault
}
- yyn = yyAct[yyn]
- if yyChk[yyn] == yytoken { /* valid shift */
+ yyn = int(yyAct[yyn])
+ if int(yyChk[yyn]) == yytoken { /* valid shift */
yyrcvr.char = -1
yytoken = -1
yyVAL = yyrcvr.lval
@@ -687,7 +699,7 @@ yynewstate:
yydefault:
/* default state action */
- yyn = yyDef[yystate]
+ yyn = int(yyDef[yystate])
if yyn == -2 {
if yyrcvr.char < 0 {
yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
@@ -696,18 +708,18 @@ yydefault:
/* look through exception table */
xi := 0
for {
- if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
+ if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate {
break
}
xi += 2
}
for xi += 2; ; xi += 2 {
- yyn = yyExca[xi+0]
+ yyn = int(yyExca[xi+0])
if yyn < 0 || yyn == yytoken {
break
}
}
- yyn = yyExca[xi+1]
+ yyn = int(yyExca[xi+1])
if yyn < 0 {
goto ret0
}
@@ -729,10 +741,10 @@ yydefault:
/* find a state where "error" is a legal shift action */
for yyp >= 0 {
- yyn = yyPact[yyS[yyp].yys] + yyErrCode
+ yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode
if yyn >= 0 && yyn < yyLast {
- yystate = yyAct[yyn] /* simulate a shift of "error" */
- if yyChk[yystate] == yyErrCode {
+ yystate = int(yyAct[yyn]) /* simulate a shift of "error" */
+ if int(yyChk[yystate]) == yyErrCode {
goto yystack
}
}
@@ -768,7 +780,7 @@ yydefault:
yypt := yyp
_ = yypt // guard against "declared and not used"
- yyp -= yyR2[yyn]
+ yyp -= int(yyR2[yyn])
// yyp is now the index of $0. Perform the default action. Iff the
// reduced production is ε, $1 is possibly out of range.
if yyp+1 >= len(yyS) {
@@ -779,16 +791,16 @@ yydefault:
yyVAL = yyS[yyp+1]
/* consult goto table to find next state */
- yyn = yyR1[yyn]
- yyg := yyPgo[yyn]
+ yyn = int(yyR1[yyn])
+ yyg := int(yyPgo[yyn])
yyj := yyg + yyS[yyp].yys + 1
if yyj >= yyLast {
- yystate = yyAct[yyg]
+ yystate = int(yyAct[yyg])
} else {
- yystate = yyAct[yyj]
- if yyChk[yystate] != -yyn {
- yystate = yyAct[yyg]
+ yystate = int(yyAct[yyj])
+ if int(yyChk[yystate]) != -yyn {
+ yystate = int(yyAct[yyg])
}
}
// dummy call; replaced with literal code
@@ -796,7 +808,7 @@ yydefault:
case 1:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:67
+//line parser.go.y:73
{
if yyDollar[1].value != nil {
yyDollar[2].value.(*Query).Meta = yyDollar[1].value.(*ConstObject)
@@ -805,25 +817,25 @@ yydefault:
}
case 2:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:74
+//line parser.go.y:80
{
yyVAL.value = nil
}
case 3:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:78
+//line parser.go.y:84
{
yyVAL.value = yyDollar[2].value
}
case 4:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:84
+//line parser.go.y:90
{
yyVAL.value = &Query{Imports: yyDollar[1].value.([]*Import), FuncDefs: reverseFuncDef(yyDollar[2].value.([]*FuncDef)), Term: &Term{Type: TermTypeIdentity}}
}
case 5:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:88
+//line parser.go.y:94
{
if yyDollar[1].value != nil {
yyDollar[2].value.(*Query).Imports = yyDollar[1].value.([]*Import)
@@ -832,144 +844,144 @@ yydefault:
}
case 6:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:95
+//line parser.go.y:101
{
yyVAL.value = []*Import(nil)
}
case 7:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:99
+//line parser.go.y:105
{
yyVAL.value = append(yyDollar[1].value.([]*Import), yyDollar[2].value.(*Import))
}
case 8:
yyDollar = yyS[yypt-6 : yypt+1]
-//line parser.go.y:105
+//line parser.go.y:111
{
yyVAL.value = &Import{ImportPath: yyDollar[2].token, ImportAlias: yyDollar[4].token, Meta: yyDollar[5].value.(*ConstObject)}
}
case 9:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:109
+//line parser.go.y:115
{
yyVAL.value = &Import{IncludePath: yyDollar[2].token, Meta: yyDollar[3].value.(*ConstObject)}
}
case 10:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:115
+//line parser.go.y:121
{
yyVAL.value = (*ConstObject)(nil)
}
case 11:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:118
+//line parser.go.y:124
{
}
case 12:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:122
+//line parser.go.y:128
{
yyVAL.value = []*FuncDef(nil)
}
case 13:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:126
+//line parser.go.y:132
{
yyVAL.value = append(yyDollar[2].value.([]*FuncDef), yyDollar[1].value.(*FuncDef))
}
case 14:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:132
+//line parser.go.y:138
{
yyVAL.value = &FuncDef{Name: yyDollar[2].token, Body: yyDollar[4].value.(*Query)}
}
case 15:
yyDollar = yyS[yypt-8 : yypt+1]
-//line parser.go.y:136
+//line parser.go.y:142
{
yyVAL.value = &FuncDef{yyDollar[2].token, yyDollar[4].value.([]string), yyDollar[7].value.(*Query)}
}
case 16:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:142
+//line parser.go.y:148
{
yyVAL.value = []string{yyDollar[1].token}
}
case 17:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:146
+//line parser.go.y:152
{
yyVAL.value = append(yyDollar[1].value.([]string), yyDollar[3].token)
}
case 18:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:151
+//line parser.go.y:157
{
}
case 19:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:152
+//line parser.go.y:158
{
}
case 20:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:156
+//line parser.go.y:162
{
yyDollar[2].value.(*Query).FuncDefs = prependFuncDef(yyDollar[2].value.(*Query).FuncDefs, yyDollar[1].value.(*FuncDef))
yyVAL.value = yyDollar[2].value
}
case 21:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:161
+//line parser.go.y:167
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[3].value.(*Query)}
}
case 22:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:165
+//line parser.go.y:171
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Bind: &Bind{yyDollar[3].value.([]*Pattern), yyDollar[5].value.(*Query)}})
yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)}
}
case 23:
yyDollar = yyS[yypt-9 : yypt+1]
-//line parser.go.y:170
+//line parser.go.y:176
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query)}}}
}
case 24:
yyDollar = yyS[yypt-9 : yypt+1]
-//line parser.go.y:174
+//line parser.go.y:180
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), nil}}}
}
case 25:
yyDollar = yyS[yypt-11 : yypt+1]
-//line parser.go.y:178
+//line parser.go.y:184
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), yyDollar[10].value.(*Query)}}}
}
case 26:
yyDollar = yyS[yypt-7 : yypt+1]
-//line parser.go.y:182
+//line parser.go.y:188
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeIf, If: &If{yyDollar[2].value.(*Query), yyDollar[4].value.(*Query), yyDollar[5].value.([]*IfElif), yyDollar[6].value.(*Query)}}}
}
case 27:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:186
+//line parser.go.y:192
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeTry, Try: &Try{yyDollar[2].value.(*Query), yyDollar[3].value.(*Query)}}}
}
case 28:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:190
+//line parser.go.y:196
{
yyVAL.value = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{yyDollar[2].token, yyDollar[4].value.(*Query)}}}
}
case 29:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:194
+//line parser.go.y:200
{
if t := yyDollar[1].value.(*Query).Term; t != nil {
t.SuffixList = append(t.SuffixList, &Suffix{Optional: true})
@@ -979,175 +991,175 @@ yydefault:
}
case 30:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:202
+//line parser.go.y:208
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpComma, Right: yyDollar[3].value.(*Query)}
}
case 31:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:206
+//line parser.go.y:212
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
}
case 32:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:210
+//line parser.go.y:216
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
}
case 33:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:214
+//line parser.go.y:220
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpOr, Right: yyDollar[3].value.(*Query)}
}
case 34:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:218
+//line parser.go.y:224
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAnd, Right: yyDollar[3].value.(*Query)}
}
case 35:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:222
+//line parser.go.y:228
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
}
case 36:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:226
+//line parser.go.y:232
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAdd, Right: yyDollar[3].value.(*Query)}
}
case 37:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:230
+//line parser.go.y:236
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpSub, Right: yyDollar[3].value.(*Query)}
}
case 38:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:234
+//line parser.go.y:240
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMul, Right: yyDollar[3].value.(*Query)}
}
case 39:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:238
+//line parser.go.y:244
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpDiv, Right: yyDollar[3].value.(*Query)}
}
case 40:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:242
+//line parser.go.y:248
{
yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMod, Right: yyDollar[3].value.(*Query)}
}
case 41:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:246
+//line parser.go.y:252
{
yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)}
}
case 42:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:252
+//line parser.go.y:258
{
yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)}
}
case 43:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:256
+//line parser.go.y:262
{
yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern))
}
case 44:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:262
+//line parser.go.y:268
{
yyVAL.value = &Pattern{Name: yyDollar[1].token}
}
case 45:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:266
+//line parser.go.y:272
{
yyVAL.value = &Pattern{Array: yyDollar[2].value.([]*Pattern)}
}
case 46:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:270
+//line parser.go.y:276
{
yyVAL.value = &Pattern{Object: yyDollar[2].value.([]*PatternObject)}
}
case 47:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:276
+//line parser.go.y:282
{
yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)}
}
case 48:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:280
+//line parser.go.y:286
{
yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern))
}
case 49:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:286
+//line parser.go.y:292
{
yyVAL.value = []*PatternObject{yyDollar[1].value.(*PatternObject)}
}
case 50:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:290
+//line parser.go.y:296
{
yyVAL.value = append(yyDollar[1].value.([]*PatternObject), yyDollar[3].value.(*PatternObject))
}
case 51:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:296
+//line parser.go.y:302
{
yyVAL.value = &PatternObject{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Pattern)}
}
case 52:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:300
+//line parser.go.y:306
{
yyVAL.value = &PatternObject{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Pattern)}
}
case 53:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:304
+//line parser.go.y:310
{
yyVAL.value = &PatternObject{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Pattern)}
}
case 54:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:308
+//line parser.go.y:314
{
- yyVAL.value = &PatternObject{KeyOnly: yyDollar[1].token}
+ yyVAL.value = &PatternObject{Key: yyDollar[1].token}
}
case 55:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:314
+//line parser.go.y:320
{
yyVAL.value = &Term{Type: TermTypeIdentity}
}
case 56:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:318
+//line parser.go.y:324
{
yyVAL.value = &Term{Type: TermTypeRecurse}
}
case 57:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:322
+//line parser.go.y:328
{
yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Name: yyDollar[1].token}}
}
case 58:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:326
+//line parser.go.y:332
{
if yyDollar[2].value.(*Suffix).Iter {
yyVAL.value = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{yyDollar[2].value.(*Suffix)}}
@@ -1157,569 +1169,569 @@ yydefault:
}
case 59:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:334
+//line parser.go.y:340
{
yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Str: yyDollar[2].value.(*String)}}
}
case 60:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:338
+//line parser.go.y:344
{
yyVAL.value = &Term{Type: TermTypeNull}
}
case 61:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:342
+//line parser.go.y:348
{
yyVAL.value = &Term{Type: TermTypeTrue}
}
case 62:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:346
+//line parser.go.y:352
{
yyVAL.value = &Term{Type: TermTypeFalse}
}
case 63:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:350
+//line parser.go.y:356
{
yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}}
}
case 64:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:354
+//line parser.go.y:360
{
yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token, Args: yyDollar[3].value.([]*Query)}}
}
case 65:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:358
+//line parser.go.y:364
{
yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}}
}
case 66:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:362
+//line parser.go.y:368
{
yyVAL.value = &Term{Type: TermTypeNumber, Number: yyDollar[1].token}
}
case 67:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:366
+//line parser.go.y:372
{
yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token}
}
case 68:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:370
+//line parser.go.y:376
{
yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token, Str: yyDollar[2].value.(*String)}
}
case 69:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:374
+//line parser.go.y:380
{
yyVAL.value = &Term{Type: TermTypeString, Str: yyDollar[1].value.(*String)}
}
case 70:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:378
+//line parser.go.y:384
{
yyVAL.value = &Term{Type: TermTypeQuery, Query: yyDollar[2].value.(*Query)}
}
case 71:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:382
+//line parser.go.y:388
{
yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, yyDollar[2].value.(*Term)}}
}
case 72:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:386
+//line parser.go.y:392
{
yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, yyDollar[2].value.(*Term)}}
}
case 73:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:390
+//line parser.go.y:396
{
yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{}}
}
case 74:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:394
+//line parser.go.y:400
{
yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}}
}
case 75:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:398
+//line parser.go.y:404
{
yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}}
}
case 76:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:402
+//line parser.go.y:408
{
yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{}}
}
case 77:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:406
+//line parser.go.y:412
{
yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{yyDollar[2].value.(*Query)}}
}
case 78:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:410
+//line parser.go.y:416
{
yyVAL.value = &Term{Type: TermTypeBreak, Break: yyDollar[2].token}
}
case 79:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:414
+//line parser.go.y:420
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Name: yyDollar[2].token}})
}
case 80:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:418
+//line parser.go.y:424
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[2].value.(*Suffix))
}
case 81:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:422
+//line parser.go.y:428
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Optional: true})
}
case 82:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:426
+//line parser.go.y:432
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[3].value.(*Suffix))
}
case 83:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:430
+//line parser.go.y:436
{
yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Str: yyDollar[3].value.(*String)}})
}
case 84:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:436
+//line parser.go.y:442
{
yyVAL.value = &String{Str: yyDollar[1].token}
}
case 85:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:440
+//line parser.go.y:446
{
yyVAL.value = &String{Queries: yyDollar[2].value.([]*Query)}
}
case 86:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:446
+//line parser.go.y:452
{
yyVAL.value = []*Query{}
}
case 87:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:450
+//line parser.go.y:456
{
yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: yyDollar[2].token}}})
}
case 88:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:454
+//line parser.go.y:460
{
yylex.(*lexer).inString = true
yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeQuery, Query: yyDollar[3].value.(*Query)}})
}
case 89:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:460
+//line parser.go.y:466
{
}
case 90:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:461
+//line parser.go.y:467
{
}
case 91:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:464
+//line parser.go.y:470
{
}
case 92:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:465
+//line parser.go.y:471
{
}
case 93:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:469
+//line parser.go.y:475
{
yyVAL.value = &Suffix{Iter: true}
}
case 94:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:473
+//line parser.go.y:479
{
yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query)}}
}
case 95:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:477
+//line parser.go.y:483
{
yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), IsSlice: true}}
}
case 96:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:481
+//line parser.go.y:487
{
yyVAL.value = &Suffix{Index: &Index{End: yyDollar[3].value.(*Query), IsSlice: true}}
}
case 97:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:485
+//line parser.go.y:491
{
yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), End: yyDollar[4].value.(*Query), IsSlice: true}}
}
case 98:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:491
+//line parser.go.y:497
{
yyVAL.value = []*Query{yyDollar[1].value.(*Query)}
}
case 99:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:495
+//line parser.go.y:501
{
yyVAL.value = append(yyDollar[1].value.([]*Query), yyDollar[3].value.(*Query))
}
case 100:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:501
+//line parser.go.y:507
{
yyVAL.value = []*IfElif(nil)
}
case 101:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:505
+//line parser.go.y:511
{
yyVAL.value = append(yyDollar[1].value.([]*IfElif), &IfElif{yyDollar[3].value.(*Query), yyDollar[5].value.(*Query)})
}
case 102:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:511
+//line parser.go.y:517
{
yyVAL.value = (*Query)(nil)
}
case 103:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:515
+//line parser.go.y:521
{
yyVAL.value = yyDollar[2].value
}
case 104:
yyDollar = yyS[yypt-0 : yypt+1]
-//line parser.go.y:521
+//line parser.go.y:527
{
yyVAL.value = (*Query)(nil)
}
case 105:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:525
+//line parser.go.y:531
{
yyVAL.value = yyDollar[2].value
}
case 106:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:531
+//line parser.go.y:537
{
yyVAL.value = []*ObjectKeyVal{yyDollar[1].value.(*ObjectKeyVal)}
}
case 107:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:535
+//line parser.go.y:541
{
yyVAL.value = append(yyDollar[1].value.([]*ObjectKeyVal), yyDollar[3].value.(*ObjectKeyVal))
}
case 108:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:541
+//line parser.go.y:547
{
yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ObjectVal)}
}
case 109:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:545
+//line parser.go.y:551
{
yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*ObjectVal)}
}
case 110:
yyDollar = yyS[yypt-5 : yypt+1]
-//line parser.go.y:549
+//line parser.go.y:555
{
yyVAL.value = &ObjectKeyVal{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*ObjectVal)}
}
case 111:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:553
+//line parser.go.y:559
{
- yyVAL.value = &ObjectKeyVal{KeyOnly: yyDollar[1].token}
+ yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token}
}
case 112:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:557
+//line parser.go.y:563
{
- yyVAL.value = &ObjectKeyVal{KeyOnlyString: yyDollar[1].value.(*String)}
+ yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String)}
}
case 113:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:562
+//line parser.go.y:568
{
}
case 114:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:563
+//line parser.go.y:569
{
}
case 115:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:564
+//line parser.go.y:570
{
}
case 116:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:568
+//line parser.go.y:574
{
yyVAL.value = &ObjectVal{[]*Query{{Term: yyDollar[1].value.(*Term)}}}
}
case 117:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:572
+//line parser.go.y:578
{
yyVAL.value = &ObjectVal{append(yyDollar[1].value.(*ObjectVal).Queries, &Query{Term: yyDollar[3].value.(*Term)})}
}
case 118:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:578
+//line parser.go.y:584
{
yyVAL.value = &ConstTerm{Object: yyDollar[1].value.(*ConstObject)}
}
case 119:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:582
+//line parser.go.y:588
{
yyVAL.value = &ConstTerm{Array: yyDollar[1].value.(*ConstArray)}
}
case 120:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:586
+//line parser.go.y:592
{
yyVAL.value = &ConstTerm{Number: yyDollar[1].token}
}
case 121:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:590
+//line parser.go.y:596
{
yyVAL.value = &ConstTerm{Str: yyDollar[1].token}
}
case 122:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:594
+//line parser.go.y:600
{
yyVAL.value = &ConstTerm{Null: true}
}
case 123:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:598
+//line parser.go.y:604
{
yyVAL.value = &ConstTerm{True: true}
}
case 124:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:602
+//line parser.go.y:608
{
yyVAL.value = &ConstTerm{False: true}
}
case 125:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:608
+//line parser.go.y:614
{
yyVAL.value = &ConstObject{}
}
case 126:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:612
+//line parser.go.y:618
{
yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)}
}
case 127:
yyDollar = yyS[yypt-4 : yypt+1]
-//line parser.go.y:616
+//line parser.go.y:622
{
yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)}
}
case 128:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:622
+//line parser.go.y:628
{
yyVAL.value = []*ConstObjectKeyVal{yyDollar[1].value.(*ConstObjectKeyVal)}
}
case 129:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:626
+//line parser.go.y:632
{
yyVAL.value = append(yyDollar[1].value.([]*ConstObjectKeyVal), yyDollar[3].value.(*ConstObjectKeyVal))
}
case 130:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:632
+//line parser.go.y:638
{
yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
}
case 131:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:636
+//line parser.go.y:642
{
yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
}
case 132:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:640
+//line parser.go.y:646
{
yyVAL.value = &ConstObjectKeyVal{KeyString: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
}
case 133:
yyDollar = yyS[yypt-2 : yypt+1]
-//line parser.go.y:646
+//line parser.go.y:652
{
yyVAL.value = &ConstArray{}
}
case 134:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:650
+//line parser.go.y:656
{
yyVAL.value = &ConstArray{yyDollar[2].value.([]*ConstTerm)}
}
case 135:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:656
+//line parser.go.y:662
{
yyVAL.value = []*ConstTerm{yyDollar[1].value.(*ConstTerm)}
}
case 136:
yyDollar = yyS[yypt-3 : yypt+1]
-//line parser.go.y:660
+//line parser.go.y:666
{
yyVAL.value = append(yyDollar[1].value.([]*ConstTerm), yyDollar[3].value.(*ConstTerm))
}
case 137:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:665
+//line parser.go.y:671
{
}
case 138:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:666
+//line parser.go.y:672
{
}
case 139:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:667
+//line parser.go.y:673
{
}
case 140:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:668
+//line parser.go.y:674
{
}
case 141:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:669
+//line parser.go.y:675
{
}
case 142:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:670
+//line parser.go.y:676
{
}
case 143:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:671
+//line parser.go.y:677
{
}
case 144:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:672
+//line parser.go.y:678
{
}
case 145:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:673
+//line parser.go.y:679
{
}
case 146:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:674
+//line parser.go.y:680
{
}
case 147:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:675
+//line parser.go.y:681
{
}
case 148:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:676
+//line parser.go.y:682
{
}
case 149:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:677
+//line parser.go.y:683
{
}
case 150:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:678
+//line parser.go.y:684
{
}
case 151:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:679
+//line parser.go.y:685
{
}
case 152:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:680
+//line parser.go.y:686
{
}
case 153:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:681
+//line parser.go.y:687
{
}
case 154:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:682
+//line parser.go.y:688
{
}
case 155:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:683
+//line parser.go.y:689
{
}
case 156:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:684
+//line parser.go.y:690
{
}
case 157:
yyDollar = yyS[yypt-1 : yypt+1]
-//line parser.go.y:685
+//line parser.go.y:691
{
}
}
diff --git a/vendor/github.com/itchyny/gojq/parser.go.y b/vendor/github.com/itchyny/gojq/parser.go.y
index 5e2bc081..380c3cf6 100644
--- a/vendor/github.com/itchyny/gojq/parser.go.y
+++ b/vendor/github.com/itchyny/gojq/parser.go.y
@@ -1,7 +1,12 @@
%{
package gojq
-// Parse parses a query.
+// Parse a query string, and returns the query struct.
+//
+// If parsing failed, the returned error has the method Token() (string, int),
+// which reports the invalid token and the byte offset in the query string. The
+// token is empty if the error occurred after scanning the entire query string.
+// The byte offset is the scanned bytes when the error occurred.
func Parse(src string) (*Query, error) {
l := newLexer(src)
if yyParse(l) > 0 {
@@ -26,7 +31,7 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef {
%}
%union {
- value interface{}
+ value any
token string
operator Operator
}
@@ -41,11 +46,12 @@ func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef {
%token tokModule tokImport tokInclude tokDef tokAs tokLabel tokBreak
%token tokNull tokTrue tokFalse
%token tokIdent tokVariable tokModuleIdent tokModuleVariable
-%token tokIndex tokNumber tokFormat tokInvalid
+%token tokIndex tokNumber tokFormat
%token tokString tokStringStart tokStringQuery tokStringEnd
%token tokIf tokThen tokElif tokElse tokEnd
%token tokTry tokCatch tokReduce tokForeach
%token tokRecurse tokFuncDefPost tokTermPost tokEmptyCatch
+%token tokInvalid tokInvalidEscapeSequence tokUnterminatedString
%nonassoc tokFuncDefPost tokTermPost
%right '|'
@@ -306,7 +312,7 @@ objectpattern
}
| tokVariable
{
- $$ = &PatternObject{KeyOnly: $1}
+ $$ = &PatternObject{Key: $1}
}
term
@@ -551,11 +557,11 @@ objectkeyval
}
| objectkey
{
- $$ = &ObjectKeyVal{KeyOnly: $1}
+ $$ = &ObjectKeyVal{Key: $1}
}
| string
{
- $$ = &ObjectKeyVal{KeyOnlyString: $1.(*String)}
+ $$ = &ObjectKeyVal{KeyString: $1.(*String)}
}
objectkey
diff --git a/vendor/github.com/itchyny/gojq/preview.go b/vendor/github.com/itchyny/gojq/preview.go
new file mode 100644
index 00000000..e082eb56
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/preview.go
@@ -0,0 +1,77 @@
+package gojq
+
+import "unicode/utf8"
+
+// Preview returns the preview string of v. The preview string is basically the
+// same as the jq-flavored JSON encoding returned by [Marshal], but is truncated
+// by 30 bytes, and more efficient than truncating the result of [Marshal].
+//
+// This method is used by error messages of built-in operators and functions,
+// and accepts only limited types (nil, bool, int, float64, *big.Int, string,
+// []any, and map[string]any). Note that the maximum width and trailing strings
+// on truncation may be changed in the future.
+func Preview(v any) string {
+ bs := jsonLimitedMarshal(v, 32)
+ if l := 30; len(bs) > l {
+ var trailing string
+ switch v.(type) {
+ case string:
+ trailing = ` ..."`
+ case []any:
+ trailing = " ...]"
+ case map[string]any:
+ trailing = " ...}"
+ default:
+ trailing = " ..."
+ }
+ for len(bs) > l-len(trailing) {
+ _, size := utf8.DecodeLastRune(bs)
+ bs = bs[:len(bs)-size]
+ }
+ bs = append(bs, trailing...)
+ }
+ return string(bs)
+}
+
+func jsonLimitedMarshal(v any, n int) (bs []byte) {
+ w := &limitedWriter{buf: make([]byte, n)}
+ defer func() {
+ _ = recover()
+ bs = w.Bytes()
+ }()
+ (&encoder{w: w}).encode(v)
+ return
+}
+
+type limitedWriter struct {
+ buf []byte
+ off int
+}
+
+func (w *limitedWriter) Write(bs []byte) (int, error) {
+ n := copy(w.buf[w.off:], bs)
+ if w.off += n; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return n, nil
+}
+
+func (w *limitedWriter) WriteByte(b byte) error {
+ w.buf[w.off] = b
+ if w.off++; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return nil
+}
+
+func (w *limitedWriter) WriteString(s string) (int, error) {
+ n := copy(w.buf[w.off:], s)
+ if w.off += n; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return n, nil
+}
+
+func (w *limitedWriter) Bytes() []byte {
+ return w.buf[:w.off]
+}
diff --git a/vendor/github.com/itchyny/gojq/query.go b/vendor/github.com/itchyny/gojq/query.go
index 98b65027..5f20b4ff 100644
--- a/vendor/github.com/itchyny/gojq/query.go
+++ b/vendor/github.com/itchyny/gojq/query.go
@@ -2,8 +2,6 @@ package gojq
import (
"context"
- "encoding/json"
- "strconv"
"strings"
)
@@ -21,13 +19,14 @@ type Query struct {
// Run the query.
//
-// It is safe to call this method of a *Query in multiple goroutines.
-func (e *Query) Run(v interface{}) Iter {
+// It is safe to call this method in goroutines, to reuse a parsed [*Query].
+// But for arguments, do not give values sharing same data between goroutines.
+func (e *Query) Run(v any) Iter {
return e.RunWithContext(context.Background(), v)
}
// RunWithContext runs the query with context.
-func (e *Query) RunWithContext(ctx context.Context, v interface{}) Iter {
+func (e *Query) RunWithContext(ctx context.Context, v any) Iter {
code, err := Compile(e)
if err != nil {
return NewIter(err)
@@ -93,11 +92,18 @@ func (e *Query) minify() {
}
}
-func (e *Query) toIndices() []interface{} {
- if e.FuncDefs != nil || e.Right != nil || e.Term == nil {
+func (e *Query) toIndexKey() any {
+ if e.Term == nil {
return nil
}
- return e.Term.toIndices()
+ return e.Term.toIndexKey()
+}
+
+func (e *Query) toIndices(xs []any) []any {
+ if e.Term == nil {
+ return nil
+ }
+ return e.Term.toIndices(xs)
}
// Import ...
@@ -117,12 +123,12 @@ func (e *Import) String() string {
func (e *Import) writeTo(s *strings.Builder) {
if e.ImportPath != "" {
s.WriteString("import ")
- s.WriteString(strconv.Quote(e.ImportPath))
+ jsonEncodeString(s, e.ImportPath)
s.WriteString(" as ")
s.WriteString(e.ImportAlias)
} else {
s.WriteString("include ")
- s.WriteString(strconv.Quote(e.IncludePath))
+ jsonEncodeString(s, e.IncludePath)
}
if e.Meta != nil {
s.WriteByte(' ')
@@ -308,25 +314,48 @@ func (e *Term) toFunc() string {
}
}
-func (e *Term) toIndices() []interface{} {
- if e.Index != nil {
- xs := e.Index.toIndices()
- if xs == nil {
+func (e *Term) toIndexKey() any {
+ switch e.Type {
+ case TermTypeNumber:
+ return toNumber(e.Number)
+ case TermTypeUnary:
+ return e.Unary.toNumber()
+ case TermTypeString:
+ if e.Str.Queries == nil {
+ return e.Str.Str
+ }
+ return nil
+ default:
+ return nil
+ }
+}
+
+func (e *Term) toIndices(xs []any) []any {
+ switch e.Type {
+ case TermTypeIndex:
+ if xs = e.Index.toIndices(xs); xs == nil {
return nil
}
- for _, s := range e.SuffixList {
- x := s.toIndices()
- if x == nil {
- return nil
- }
- xs = append(xs, x...)
+ case TermTypeQuery:
+ if xs = e.Query.toIndices(xs); xs == nil {
+ return nil
}
- return xs
- } else if e.Query != nil && len(e.SuffixList) == 0 {
- return e.Query.toIndices()
- } else {
+ default:
return nil
}
+ for _, s := range e.SuffixList {
+ if xs = s.toIndices(xs); xs == nil {
+ return nil
+ }
+ }
+ return xs
+}
+
+func (e *Term) toNumber() any {
+ if e.Type == TermTypeNumber {
+ return toNumber(e.Number)
+ }
+ return nil
}
// Unary ...
@@ -350,6 +379,14 @@ func (e *Unary) minify() {
e.Term.minify()
}
+func (e *Unary) toNumber() any {
+ v := e.Term.toNumber()
+ if v != nil && e.Op == OpSub {
+ v = funcOpNegate(v)
+ }
+ return v
+}
+
// Pattern ...
type Pattern struct {
Name string
@@ -393,7 +430,6 @@ type PatternObject struct {
KeyString *String
KeyQuery *Query
Val *Pattern
- KeyOnly string
}
func (e *PatternObject) String() string {
@@ -416,9 +452,6 @@ func (e *PatternObject) writeTo(s *strings.Builder) {
s.WriteString(": ")
e.Val.writeTo(s)
}
- if e.KeyOnly != "" {
- s.WriteString(e.KeyOnly)
- }
}
// Index ...
@@ -450,24 +483,22 @@ func (e *Index) writeTo(s *strings.Builder) {
func (e *Index) writeSuffixTo(s *strings.Builder) {
if e.Name != "" {
s.WriteString(e.Name)
+ } else if e.Str != nil {
+ e.Str.writeTo(s)
} else {
- if e.Str != nil {
- e.Str.writeTo(s)
- } else {
- s.WriteByte('[')
- if e.IsSlice {
- if e.Start != nil {
- e.Start.writeTo(s)
- }
- s.WriteByte(':')
- if e.End != nil {
- e.End.writeTo(s)
- }
- } else {
+ s.WriteByte('[')
+ if e.IsSlice {
+ if e.Start != nil {
e.Start.writeTo(s)
}
- s.WriteByte(']')
+ s.WriteByte(':')
+ if e.End != nil {
+ e.End.writeTo(s)
+ }
+ } else {
+ e.Start.writeTo(s)
}
+ s.WriteByte(']')
}
}
@@ -483,11 +514,38 @@ func (e *Index) minify() {
}
}
-func (e *Index) toIndices() []interface{} {
- if e.Name == "" {
- return nil
+func (e *Index) toIndexKey() any {
+ if e.Name != "" {
+ return e.Name
+ } else if e.Str != nil {
+ if e.Str.Queries == nil {
+ return e.Str.Str
+ }
+ } else if !e.IsSlice {
+ return e.Start.toIndexKey()
+ } else {
+ var start, end any
+ ok := true
+ if e.Start != nil {
+ start = e.Start.toIndexKey()
+ ok = start != nil
+ }
+ if e.End != nil && ok {
+ end = e.End.toIndexKey()
+ ok = end != nil
+ }
+ if ok {
+ return map[string]any{"start": start, "end": end}
+ }
+ }
+ return nil
+}
+
+func (e *Index) toIndices(xs []any) []any {
+ if k := e.toIndexKey(); k != nil {
+ return append(xs, k)
}
- return []interface{}{e.Name}
+ return nil
}
// Func ...
@@ -543,7 +601,7 @@ func (e *String) String() string {
func (e *String) writeTo(s *strings.Builder) {
if e.Queries == nil {
- s.WriteString(strconv.Quote(e.Str))
+ jsonEncodeString(s, e.Str)
return
}
s.WriteByte('"')
@@ -599,12 +657,10 @@ func (e *Object) minify() {
// ObjectKeyVal ...
type ObjectKeyVal struct {
- Key string
- KeyString *String
- KeyQuery *Query
- Val *ObjectVal
- KeyOnly string
- KeyOnlyString *String
+ Key string
+ KeyString *String
+ KeyQuery *Query
+ Val *ObjectVal
}
func (e *ObjectKeyVal) String() string {
@@ -627,11 +683,6 @@ func (e *ObjectKeyVal) writeTo(s *strings.Builder) {
s.WriteString(": ")
e.Val.writeTo(s)
}
- if e.KeyOnly != "" {
- s.WriteString(e.KeyOnly)
- } else if e.KeyOnlyString != nil {
- e.KeyOnlyString.writeTo(s)
- }
}
func (e *ObjectKeyVal) minify() {
@@ -643,9 +694,6 @@ func (e *ObjectKeyVal) minify() {
if e.Val != nil {
e.Val.minify()
}
- if e.KeyOnlyString != nil {
- e.KeyOnlyString.minify()
- }
}
// ObjectVal ...
@@ -737,21 +785,21 @@ func (e *Suffix) minify() {
}
}
-func (e *Suffix) toTerm() (*Term, bool) {
+func (e *Suffix) toTerm() *Term {
if e.Index != nil {
- return &Term{Type: TermTypeIndex, Index: e.Index}, true
+ return &Term{Type: TermTypeIndex, Index: e.Index}
} else if e.Iter {
- return &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}, true
+ return &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}
} else {
- return nil, false
+ return nil
}
}
-func (e *Suffix) toIndices() []interface{} {
+func (e *Suffix) toIndices(xs []any) []any {
if e.Index == nil {
return nil
}
- return e.Index.toIndices()
+ return e.Index.toIndices(xs)
}
// Bind ...
@@ -1005,17 +1053,17 @@ func (e *ConstTerm) writeTo(s *strings.Builder) {
} else if e.False {
s.WriteString("false")
} else {
- s.WriteString(strconv.Quote(e.Str))
+ jsonEncodeString(s, e.Str)
}
}
-func (e *ConstTerm) toValue() interface{} {
+func (e *ConstTerm) toValue() any {
if e.Object != nil {
return e.Object.ToValue()
} else if e.Array != nil {
return e.Array.toValue()
} else if e.Number != "" {
- return normalizeNumber(json.Number(e.Number))
+ return toNumber(e.Number)
} else if e.Null {
return nil
} else if e.True {
@@ -1053,12 +1101,12 @@ func (e *ConstObject) writeTo(s *strings.Builder) {
s.WriteString(" }")
}
-// ToValue converts the object to map[string]interface{}.
-func (e *ConstObject) ToValue() map[string]interface{} {
+// ToValue converts the object to map[string]any.
+func (e *ConstObject) ToValue() map[string]any {
if e == nil {
return nil
}
- v := make(map[string]interface{}, len(e.KeyVals))
+ v := make(map[string]any, len(e.KeyVals))
for _, e := range e.KeyVals {
key := e.Key
if key == "" {
@@ -1114,8 +1162,8 @@ func (e *ConstArray) writeTo(s *strings.Builder) {
s.WriteByte(']')
}
-func (e *ConstArray) toValue() []interface{} {
- v := make([]interface{}, len(e.Elems))
+func (e *ConstArray) toValue() []any {
+ v := make([]any, len(e.Elems))
for i, e := range e.Elems {
v[i] = e.toValue()
}
diff --git a/vendor/github.com/itchyny/gojq/release.go b/vendor/github.com/itchyny/gojq/release.go
index 196fb772..c34dfb45 100644
--- a/vendor/github.com/itchyny/gojq/release.go
+++ b/vendor/github.com/itchyny/gojq/release.go
@@ -1,11 +1,11 @@
-//go:build !debug
-// +build !debug
+//go:build !gojq_debug
+// +build !gojq_debug
package gojq
type codeinfo struct{}
-func (c *compiler) appendCodeInfo(interface{}) {}
+func (c *compiler) appendCodeInfo(any) {}
func (c *compiler) deleteCodeInfo(string) {}
diff --git a/vendor/github.com/itchyny/gojq/scope_stack.go b/vendor/github.com/itchyny/gojq/scope_stack.go
index 82d620be..e140ca15 100644
--- a/vendor/github.com/itchyny/gojq/scope_stack.go
+++ b/vendor/github.com/itchyny/gojq/scope_stack.go
@@ -39,11 +39,12 @@ func (s *scopeStack) empty() bool {
return s.index < 0
}
-func (s *scopeStack) save(index, limit *int) {
- *index, *limit = s.index, s.limit
+func (s *scopeStack) save() (index, limit int) {
+ index, limit = s.index, s.limit
if s.index > s.limit {
s.limit = s.index
}
+ return
}
func (s *scopeStack) restore(index, limit int) {
diff --git a/vendor/github.com/itchyny/gojq/stack.go b/vendor/github.com/itchyny/gojq/stack.go
index f629d28e..a0e265c8 100644
--- a/vendor/github.com/itchyny/gojq/stack.go
+++ b/vendor/github.com/itchyny/gojq/stack.go
@@ -7,7 +7,7 @@ type stack struct {
}
type block struct {
- value interface{}
+ value any
next int
}
@@ -15,7 +15,7 @@ func newStack() *stack {
return &stack{index: -1, limit: -1}
}
-func (s *stack) push(v interface{}) {
+func (s *stack) push(v any) {
b := block{v, s.index}
i := s.index + 1
if i <= s.limit {
@@ -29,13 +29,13 @@ func (s *stack) push(v interface{}) {
}
}
-func (s *stack) pop() interface{} {
+func (s *stack) pop() any {
b := s.data[s.index]
s.index = b.next
return b.value
}
-func (s *stack) top() interface{} {
+func (s *stack) top() any {
return s.data[s.index].value
}
@@ -43,11 +43,12 @@ func (s *stack) empty() bool {
return s.index < 0
}
-func (s *stack) save(index, limit *int) {
- *index, *limit = s.index, s.limit
+func (s *stack) save() (index, limit int) {
+ index, limit = s.index, s.limit
if s.index > s.limit {
s.limit = s.index
}
+ return
}
func (s *stack) restore(index, limit int) {
diff --git a/vendor/github.com/itchyny/gojq/term_type.go b/vendor/github.com/itchyny/gojq/term_type.go
index 1670948c..941e7ba9 100644
--- a/vendor/github.com/itchyny/gojq/term_type.go
+++ b/vendor/github.com/itchyny/gojq/term_type.go
@@ -1,6 +1,6 @@
package gojq
-// TermType represents the type of Term.
+// TermType represents the type of [Term].
type TermType int
// TermType list.
@@ -27,7 +27,7 @@ const (
TermTypeQuery
)
-// GoString implements GoStringer.
+// GoString implements [fmt.GoStringer].
func (termType TermType) GoString() (str string) {
defer func() { str = "gojq." + str }()
switch termType {
diff --git a/vendor/github.com/itchyny/gojq/type.go b/vendor/github.com/itchyny/gojq/type.go
new file mode 100644
index 00000000..bb388e20
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/type.go
@@ -0,0 +1,29 @@
+package gojq
+
+import (
+ "fmt"
+ "math/big"
+)
+
+// TypeOf returns the jq-flavored type name of v.
+//
+// This method is used by built-in type/0 function, and accepts only limited
+// types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any).
+func TypeOf(v any) string {
+ switch v.(type) {
+ case nil:
+ return "null"
+ case bool:
+ return "boolean"
+ case int, float64, *big.Int:
+ return "number"
+ case string:
+ return "string"
+ case []any:
+ return "array"
+ case map[string]any:
+ return "object"
+ default:
+ panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v))
+ }
+}
diff --git a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md
index 52b37d05..61a4e9dc 100644
--- a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md
+++ b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md
@@ -1,4 +1,11 @@
# Changelog
+## [v0.1.5](https://github.com/itchyny/timefmt-go/compare/v0.1.4..v0.1.5) (2022-12-01)
+* support parsing time zone offset with name using both `%z` and `%Z`
+
+## [v0.1.4](https://github.com/itchyny/timefmt-go/compare/v0.1.3..v0.1.4) (2022-09-01)
+* improve documents
+* drop support for Go 1.16
+
## [v0.1.3](https://github.com/itchyny/timefmt-go/compare/v0.1.2..v0.1.3) (2021-04-14)
* implement `ParseInLocation` for configuring the default location
diff --git a/vendor/github.com/itchyny/timefmt-go/LICENSE b/vendor/github.com/itchyny/timefmt-go/LICENSE
index 4d650fa8..84d6cb03 100644
--- a/vendor/github.com/itchyny/timefmt-go/LICENSE
+++ b/vendor/github.com/itchyny/timefmt-go/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020,2021 itchyny
+Copyright (c) 2020-2022 itchyny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/itchyny/timefmt-go/Makefile b/vendor/github.com/itchyny/timefmt-go/Makefile
index bacef7bf..a87cb286 100644
--- a/vendor/github.com/itchyny/timefmt-go/Makefile
+++ b/vendor/github.com/itchyny/timefmt-go/Makefile
@@ -1,20 +1,19 @@
GOBIN ?= $(shell go env GOPATH)/bin
-export GO111MODULE=on
.PHONY: all
all: test
.PHONY: test
test:
- go test -v ./...
+ go test -v -race ./...
.PHONY: lint
-lint: $(GOBIN)/golint
+lint: $(GOBIN)/staticcheck
go vet ./...
- golint -set_exit_status ./...
+ staticcheck -checks all,-ST1000 ./...
-$(GOBIN)/golint:
- cd && go get golang.org/x/lint/golint
+$(GOBIN)/staticcheck:
+ go install honnef.co/go/tools/cmd/staticcheck@latest
.PHONY: clean
clean:
diff --git a/vendor/github.com/itchyny/timefmt-go/README.md b/vendor/github.com/itchyny/timefmt-go/README.md
index 078b1e1a..f01af961 100644
--- a/vendor/github.com/itchyny/timefmt-go/README.md
+++ b/vendor/github.com/itchyny/timefmt-go/README.md
@@ -1,7 +1,7 @@
# timefmt-go
[![CI Status](https://github.com/itchyny/timefmt-go/workflows/CI/badge.svg)](https://github.com/itchyny/timefmt-go/actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/timefmt-go)](https://goreportcard.com/report/github.com/itchyny/timefmt-go)
-[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE)
+[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE)
[![release](https://img.shields.io/github/release/itchyny/timefmt-go/all.svg)](https://github.com/itchyny/timefmt-go/releases)
[![pkg.go.dev](https://pkg.go.dev/badge/github.com/itchyny/timefmt-go)](https://pkg.go.dev/github.com/itchyny/timefmt-go)
@@ -35,14 +35,15 @@ func main() {
Please refer to [`man 3 strftime`](https://linux.die.net/man/3/strftime) and
[`man 3 strptime`](https://linux.die.net/man/3/strptime) for formatters.
+As an extension, `%f` directive is supported for zero-padded microseconds, which originates from Python.
Note that `E` and `O` modifier characters are not supported.
## Comparison to other libraries
- This library
- provides both formatting and parsing functions in pure Go language,
- - depends only on the Go standard libraries not to grows up the module file.
+ - depends only on the Go standard libraries not to grow up dependency.
- `Format` (`strftime`) implements glibc extensions including
- - width specifier like `%10A, %10B %2k:%M`,
+ - width specifier like `%6Y %10B %4Z` (limited to 1024 bytes),
- omitting padding modifier like `%-y-%-m-%-d`,
- space padding modifier like `%_y-%_m-%_d`,
- upper case modifier like `%^a %^b`,
diff --git a/vendor/github.com/itchyny/timefmt-go/format.go b/vendor/github.com/itchyny/timefmt-go/format.go
index 1d9b3672..eea976ee 100644
--- a/vendor/github.com/itchyny/timefmt-go/format.go
+++ b/vendor/github.com/itchyny/timefmt-go/format.go
@@ -1,6 +1,7 @@
package timefmt
import (
+ "math"
"strconv"
"time"
)
@@ -10,8 +11,7 @@ func Format(t time.Time, format string) string {
return string(AppendFormat(make([]byte, 0, 64), t, format))
}
-// AppendFormat appends formatted time to the bytes.
-// You can use this method to reduce allocations.
+// AppendFormat appends formatted time string to the buffer.
func AppendFormat(buf []byte, t time.Time, format string) []byte {
year, month, day := t.Date()
hour, min, sec := t.Clock()
@@ -74,7 +74,7 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte {
b = format[i]
if b <= '9' && '0' <= b {
width = width*10 + int(b&0x0F)
- if width >= int((^uint(0)>>1)/10) {
+ if width >= math.MaxInt/10 {
width = maxWidth
}
} else {
diff --git a/vendor/github.com/itchyny/timefmt-go/parse.go b/vendor/github.com/itchyny/timefmt-go/parse.go
index 2d2b5f4d..83b0df2c 100644
--- a/vendor/github.com/itchyny/timefmt-go/parse.go
+++ b/vendor/github.com/itchyny/timefmt-go/parse.go
@@ -25,7 +25,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
}
}()
var j, century, yday, colons int
- var pm bool
+ var pm, hasZoneName, hasZoneOffset bool
var pending string
for i, l := 0, len(source); i < len(format); i++ {
if b := format[i]; b == '%' {
@@ -158,14 +158,14 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
hour, min, sec = t.Clock()
month = int(mon)
case 'f':
- var msec, k, d int
- if msec, k, err = parseNumber(source, j, 6, 'f'); err != nil {
+ var usec, k, d int
+ if usec, k, err = parseNumber(source, j, 6, 'f'); err != nil {
return
}
- nsec = msec * 1000
for j, d = k, k-j; d < 6; d++ {
- nsec *= 10
+ usec *= 10
}
+ nsec = usec * 1000
case 'Z':
k := j
for ; k < l; k++ {
@@ -178,7 +178,14 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
err = fmt.Errorf(`cannot parse %q with "%%Z"`, source[j:k])
return
}
- loc = t.Location()
+ if hasZoneOffset {
+ name, _ := t.Zone()
+ _, offset := locationZone(loc)
+ loc = time.FixedZone(name, offset)
+ } else {
+ loc = t.Location()
+ }
+ hasZoneName = true
j = k
case 'z':
if j >= l {
@@ -231,7 +238,12 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
j = k
}
}
- loc, colons = time.FixedZone("", sign*((hour*60+min)*60+sec)), 0
+ var name string
+ if hasZoneName {
+ name, _ = locationZone(loc)
+ }
+ loc, colons = time.FixedZone(name, sign*((hour*60+min)*60+sec)), 0
+ hasZoneOffset = true
case 'Z':
loc, colons, j = time.UTC, 0, j+1
default:
@@ -328,6 +340,10 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc), nil
}
+func locationZone(loc *time.Location) (name string, offset int) {
+ return time.Date(2000, time.January, 1, 0, 0, 0, 0, loc).Zone()
+}
+
type parseFormatError byte
func (err parseFormatError) Error() string {
diff --git a/vendor/github.com/itchyny/timefmt-go/timefmt.go b/vendor/github.com/itchyny/timefmt-go/timefmt.go
new file mode 100644
index 00000000..45bf6ae9
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/timefmt.go
@@ -0,0 +1,2 @@
+// Package timefmt provides functions for formatting and parsing date time strings.
+package timefmt
diff --git a/vendor/github.com/lithammer/fuzzysearch/fuzzy/fuzzy.go b/vendor/github.com/lithammer/fuzzysearch/fuzzy/fuzzy.go
index 7ae7091f..88908773 100644
--- a/vendor/github.com/lithammer/fuzzysearch/fuzzy/fuzzy.go
+++ b/vendor/github.com/lithammer/fuzzysearch/fuzzy/fuzzy.go
@@ -3,7 +3,6 @@
package fuzzy
import (
- "bytes"
"unicode"
"unicode/utf8"
@@ -53,9 +52,12 @@ func MatchNormalizedFold(source, target string) bool {
}
func match(source, target string, transformer transform.Transformer) bool {
- source = stringTransform(source, transformer)
- target = stringTransform(target, transformer)
+ sourceT := stringTransform(source, transformer)
+ targetT := stringTransform(target, transformer)
+ return matchTransformed(sourceT, targetT)
+}
+func matchTransformed(source, target string) bool {
lenDiff := len(target) - len(source)
if lenDiff < 0 {
@@ -101,10 +103,13 @@ func FindNormalizedFold(source string, targets []string) []string {
}
func find(source string, targets []string, transformer transform.Transformer) []string {
+ sourceT := stringTransform(source, transformer)
+
var matches []string
for _, target := range targets {
- if match(source, target, transformer) {
+ targetT := stringTransform(target, transformer)
+ if matchTransformed(sourceT, targetT) {
matches = append(matches, target)
}
}
@@ -194,10 +199,13 @@ func RankFindNormalizedFold(source string, targets []string) Ranks {
}
func rankFind(source string, targets []string, transformer transform.Transformer) Ranks {
+ sourceT := stringTransform(source, transformer)
+
var r Ranks
for index, target := range targets {
- if match(source, target, transformer) {
+ targetT := stringTransform(target, transformer)
+ if matchTransformed(sourceT, targetT) {
distance := LevenshteinDistance(source, target)
r = append(r, Rank{source, target, distance, index})
}
@@ -251,19 +259,30 @@ func stringTransform(s string, t transform.Transformer) (transformed string) {
type unicodeFoldTransformer struct{ transform.NopResetter }
func (unicodeFoldTransformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
- runes := bytes.Runes(src)
- var lowerRunes []rune
- for _, r := range runes {
- lowerRunes = append(lowerRunes, unicode.ToLower(r))
- }
-
- srcBytes := []byte(string(lowerRunes))
- n := copy(dst, srcBytes)
- if n < len(srcBytes) {
- err = transform.ErrShortDst
+ // Converting src to a string allocates.
+ // In theory, it need not; see https://go.dev/issue/27148.
+ // It is possible to write this loop using utf8.DecodeRune
+ // and thereby avoid allocations, but it is noticeably slower.
+ // So just let's wait for the compiler to get smarter.
+ for _, r := range string(src) {
+ if r == utf8.RuneError {
+ // Go spec for ranging over a string says:
+ // If the iteration encounters an invalid UTF-8 sequence,
+ // the second value will be 0xFFFD, the Unicode replacement character,
+ // and the next iteration will advance a single byte in the string.
+ nSrc++
+ } else {
+ nSrc += utf8.RuneLen(r)
+ }
+ r = unicode.ToLower(r)
+ x := utf8.RuneLen(r)
+ if x > len(dst[nDst:]) {
+ err = transform.ErrShortDst
+ break
+ }
+ nDst += utf8.EncodeRune(dst[nDst:], r)
}
-
- return n, n, err
+ return nDst, nSrc, err
}
type nopTransformer struct{ transform.NopResetter }
diff --git a/vendor/github.com/lithammer/fuzzysearch/fuzzy/levenshtein.go b/vendor/github.com/lithammer/fuzzysearch/fuzzy/levenshtein.go
index 4fb5838c..c0fc1910 100644
--- a/vendor/github.com/lithammer/fuzzysearch/fuzzy/levenshtein.go
+++ b/vendor/github.com/lithammer/fuzzysearch/fuzzy/levenshtein.go
@@ -33,11 +33,13 @@ func LevenshteinDistance(s, t string) int {
return column[len(r1)]
}
-func min(a, b, c int) int {
- if a < b && a < c {
+func min2(a, b int) int {
+ if a < b {
return a
- } else if b < c {
- return b
}
- return c
+ return b
+}
+
+func min(a, b, c int) int {
+ return min2(min2(a, b), c)
}
diff --git a/vendor/github.com/logrusorgru/aurora/.gitignore b/vendor/github.com/logrusorgru/aurora/.gitignore
deleted file mode 100644
index dbcb7cc7..00000000
--- a/vendor/github.com/logrusorgru/aurora/.gitignore
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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
-*.out
-
-# coverage
-
-cover.html
-
-# benchcmp
-
-*.cmp
-
diff --git a/vendor/github.com/logrusorgru/aurora/.travis.yml b/vendor/github.com/logrusorgru/aurora/.travis.yml
deleted file mode 100644
index 570e361b..00000000
--- a/vendor/github.com/logrusorgru/aurora/.travis.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-language: go
-go:
- - tip
-before_install:
- - go get github.com/axw/gocov/gocov
- - go get github.com/mattn/goveralls
- - go get golang.org/x/tools/cmd/cover
-script:
- - $HOME/gopath/bin/goveralls -service=travis-ci
diff --git a/vendor/github.com/logrusorgru/aurora/AUTHORS.md b/vendor/github.com/logrusorgru/aurora/AUTHORS.md
deleted file mode 100644
index 0ee9e3eb..00000000
--- a/vendor/github.com/logrusorgru/aurora/AUTHORS.md
+++ /dev/null
@@ -1,8 +0,0 @@
-AUTHORS
-=======
-
-- Konstantin Ivanov @logrusorgru
-- Mattias Eriksson @snaggen
-- Ousmane Traore @otraore
-- Simon Legner @simon04
-- Sevenate @sevenate
diff --git a/vendor/github.com/logrusorgru/aurora/CHANGELOG.md b/vendor/github.com/logrusorgru/aurora/CHANGELOG.md
deleted file mode 100644
index ad0a2025..00000000
--- a/vendor/github.com/logrusorgru/aurora/CHANGELOG.md
+++ /dev/null
@@ -1,59 +0,0 @@
-Changes
-=======
-
----
-16:05:02
-Thursday, July 2, 2020
-
-Change license from the WTFPL to the Unlicense due to pkg.go.dev restriction.
-
----
-15:39:40
-Wednesday, April 17, 2019
-
-- Bright background and foreground colors
-- 8-bit indexed colors `Index`, `BgIndex`
-- 24 grayscale colors `Gray`, `BgGray`
-- `Yellow` and `BgYellow` methods, mark Brow and BgBrown as deprecated
- Following specifications, correct name of the colors are yellow, but
- by historical reason they are called brown. Both, the `Yellow` and the
- `Brown` methods (including `Bg+`) represents the same colors. The Brown
- are leaved for backward compatibility until Go modules production release.
-- Additional formats
- + `Faint` that is opposite to the `Bold`
- + `DoublyUnderline`
- + `Fraktur`
- + `Italic`
- + `Underline`
- + `SlowBlink` with `Blink` alias
- + `RapidBlink`
- + `Reverse` that is alias for the `Inverse`
- + `Conceal` with `Hidden` alias
- + `CrossedOut` with `StrikeThrough` alias
- + `Framed`
- + `Encircled`
- + `Overlined`
-- Add AUTHORS.md file and change all copyright notices.
-- `Reset` method to create clear value. `Reset` method that replaces
- `Bleach` method. The `Bleach` method was marked as deprecated.
-
----
-
-14:25:49
-Friday, August 18, 2017
-
-- LICENSE.md changed to LICENSE
-- fix email in README.md
-- add "no warranty" to README.md
-- set proper copyright date
-
----
-
-16:59:28
-Tuesday, November 8, 2016
-
-- Rid out off sync.Pool
-- Little optimizations (very little)
-- Improved benchmarks
-
----
diff --git a/vendor/github.com/logrusorgru/aurora/LICENSE b/vendor/github.com/logrusorgru/aurora/LICENSE
deleted file mode 100644
index 68a49daa..00000000
--- a/vendor/github.com/logrusorgru/aurora/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
-
-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 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.
-
-For more information, please refer to
diff --git a/vendor/github.com/logrusorgru/aurora/README.md b/vendor/github.com/logrusorgru/aurora/README.md
deleted file mode 100644
index e0afce1c..00000000
--- a/vendor/github.com/logrusorgru/aurora/README.md
+++ /dev/null
@@ -1,314 +0,0 @@
-Aurora
-======
-
-[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/logrusorgru/aurora?tab=doc)
-[![Unlicense](https://img.shields.io/badge/license-unlicense-blue.svg)](http://unlicense.org/)
-[![Build Status](https://travis-ci.org/logrusorgru/aurora.svg)](https://travis-ci.org/logrusorgru/aurora)
-[![Coverage Status](https://coveralls.io/repos/logrusorgru/aurora/badge.svg?branch=master)](https://coveralls.io/r/logrusorgru/aurora?branch=master)
-[![GoReportCard](https://goreportcard.com/badge/logrusorgru/aurora)](https://goreportcard.com/report/logrusorgru/aurora)
-[![Gitter](https://img.shields.io/badge/chat-on_gitter-46bc99.svg?logo=data:image%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTQiIHdpZHRoPSIxNCI%2BPGcgZmlsbD0iI2ZmZiI%2BPHJlY3QgeD0iMCIgeT0iMyIgd2lkdGg9IjEiIGhlaWdodD0iNSIvPjxyZWN0IHg9IjIiIHk9IjQiIHdpZHRoPSIxIiBoZWlnaHQ9IjciLz48cmVjdCB4PSI0IiB5PSI0IiB3aWR0aD0iMSIgaGVpZ2h0PSI3Ii8%2BPHJlY3QgeD0iNiIgeT0iNCIgd2lkdGg9IjEiIGhlaWdodD0iNCIvPjwvZz48L3N2Zz4%3D&logoWidth=10)](https://gitter.im/logrusorgru/aurora)
-
-Ultimate ANSI colors for Golang. The package supports Printf/Sprintf etc.
-
-
-![aurora logo](https://github.com/logrusorgru/aurora/blob/master/gopher_aurora.png)
-
-# TOC
-
-- [Installation](#installation)
-- [Usage](#usage)
- + [Simple](#simple)
- + [Printf](#printf)
- + [aurora.Sprintf](#aurorasprintf)
- + [Enable/Disable colors](#enabledisable-colors)
-- [Chains](#chains)
-- [Colorize](#colorize)
-- [Grayscale](#grayscale)
-- [8-bit colors](#8-bit-colors)
-- [Supported Colors & Formats](#supported-colors--formats)
- + [All colors](#all-colors)
- + [Standard and bright colors](#standard-and-bright-colors)
- + [Formats are likely supported](#formats-are-likely-supported)
- + [Formats are likely unsupported](#formats-are-likely-unsupported)
-- [Limitations](#limitations)
- + [Windows](#windows)
- + [TTY](#tty)
-- [Licensing](#licensing)
-
-# Installation
-
-Get
-```
-go get -u github.com/logrusorgru/aurora
-```
-Test
-```
-go test -cover github.com/logrusorgru/aurora
-```
-
-# Usage
-
-### Simple
-
-```go
-package main
-
-import (
- "fmt"
-
- . "github.com/logrusorgru/aurora"
-)
-
-func main() {
- fmt.Println("Hello,", Magenta("Aurora"))
- fmt.Println(Bold(Cyan("Cya!")))
-}
-
-```
-
-![simple png](https://github.com/logrusorgru/aurora/blob/master/simple.png)
-
-### Printf
-
-```go
-package main
-
-import (
- "fmt"
-
- . "github.com/logrusorgru/aurora"
-)
-
-func main() {
- fmt.Printf("Got it %d times\n", Green(1240))
- fmt.Printf("PI is %+1.2e\n", Cyan(3.14))
-}
-
-```
-
-![printf png](https://github.com/logrusorgru/aurora/blob/master/printf.png)
-
-### aurora.Sprintf
-
-```go
-package main
-
-import (
- "fmt"
-
- . "github.com/logrusorgru/aurora"
-)
-
-func main() {
- fmt.Println(Sprintf(Magenta("Got it %d times"), Green(1240)))
-}
-
-```
-
-![sprintf png](https://github.com/logrusorgru/aurora/blob/master/sprintf.png)
-
-### Enable/Disable colors
-
-```go
-package main
-
-import (
- "fmt"
- "flag"
-
- "github.com/logrusorgru/aurora"
-)
-
-// colorizer
-var au aurora.Aurora
-
-var colors = flag.Bool("colors", false, "enable or disable colors")
-
-func init() {
- flag.Parse()
- au = aurora.NewAurora(*colors)
-}
-
-func main() {
- // use colorizer
- fmt.Println(au.Green("Hello"))
-}
-
-```
-Without flags:
-![disable png](https://github.com/logrusorgru/aurora/blob/master/disable.png)
-
-With `-colors` flag:
-![enable png](https://github.com/logrusorgru/aurora/blob/master/enable.png)
-
-# Chains
-
-The following samples are equal
-
-```go
-x := BgMagenta(Bold(Red("x")))
-```
-
-```go
-x := Red("x").Bold().BgMagenta()
-```
-
-The second is more readable
-
-# Colorize
-
-There is `Colorize` function that allows to choose some colors and
-format from a side
-
-```go
-
-func getColors() Color {
- // some stuff that returns appropriate colors and format
-}
-
-// [...]
-
-func main() {
- fmt.Println(Colorize("Greeting", getColors()))
-}
-
-```
-Less complicated example
-
-```go
-x := Colorize("Greeting", GreenFg|GrayBg|BoldFm)
-```
-
-Unlike other color functions and methods (such as Red/BgBlue etc)
-a `Colorize` clears previous colors
-
-```go
-x := Red("x").Colorize(BgGreen) // will be with green background only
-```
-
-# Grayscale
-
-```go
-fmt.Println(" ",
- Gray(1-1, " 00-23 ").BgGray(24-1),
- Gray(4-1, " 03-19 ").BgGray(20-1),
- Gray(8-1, " 07-15 ").BgGray(16-1),
- Gray(12-1, " 11-11 ").BgGray(12-1),
- Gray(16-1, " 15-07 ").BgGray(8-1),
- Gray(20-1, " 19-03 ").BgGray(4-1),
- Gray(24-1, " 23-00 ").BgGray(1-1),
-)
-```
-
-![grayscale png](https://github.com/logrusorgru/aurora/blob/master/aurora_grayscale.png)
-
-# 8-bit colors
-
-Methods `Index` and `BgIndex` implements 8-bit colors.
-
-| Index/BgIndex | Meaning | Foreground | Background |
-| -------------- | --------------- | ---------- | ---------- |
-| 0- 7 | standard colors | 30- 37 | 40- 47 |
-| 8- 15 | bright colors | 90- 97 | 100-107 |
-| 16-231 | 216 colors | 38;5;n | 48;5;n |
-| 232-255 | 24 grayscale | 38;5;n | 48;5;n |
-
-
-# Supported colors & formats
-
-- formats
- + bold (1)
- + faint (2)
- + doubly-underline (21)
- + fraktur (20)
- + italic (3)
- + underline (4)
- + slow blink (5)
- + rapid blink (6)
- + reverse video (7)
- + conceal (8)
- + crossed out (9)
- + framed (51)
- + encircled (52)
- + overlined (53)
-- background and foreground colors, including bright
- + black
- + red
- + green
- + yellow (brown)
- + blue
- + magenta
- + cyan
- + white
- + 24 grayscale colors
- + 216 8-bit colors
-
-### All colors
-
-![linux png](https://github.com/logrusorgru/aurora/blob/master/aurora_colors_black.png)
-![white png](https://github.com/logrusorgru/aurora/blob/master/aurora_colors_white.png)
-
-### Standard and bright colors
-
-![linux black standard png](https://github.com/logrusorgru/aurora/blob/master/aurora_black_standard.png)
-![linux white standard png](https://github.com/logrusorgru/aurora/blob/master/aurora_white_standard.png)
-
-### Formats are likely supported
-
-![formats supported gif](https://github.com/logrusorgru/aurora/blob/master/aurora_formats.gif)
-
-### Formats are likely unsupported
-
-![formats rarely supported png](https://github.com/logrusorgru/aurora/blob/master/aurora_rarely_supported.png)
-
-# Limitations
-
-There is no way to represent `%T` and `%p` with colors using
-a standard approach
-
-```go
-package main
-
-import (
- "fmt"
-
- . "github.com/logrusorgru/aurora"
-)
-
-func main() {
- r := Red("red")
- var i int
- fmt.Printf("%T %p\n", r, Green(&i))
-}
-```
-
-Output will be without colors
-
-```
-aurora.value %!p(aurora.value={0xc42000a310 768 0})
-```
-
-The obvious workaround is `Red(fmt.Sprintf("%T", some))`
-
-### Windows
-
-The Aurora provides ANSI colors only, so there is no support for Windows. That said, there are workarounds available.
-Check out these comments to learn more:
-
-- [Using go-colorable](https://github.com/logrusorgru/aurora/issues/2#issuecomment-299014211).
-- [Using registry for Windows 10](https://github.com/logrusorgru/aurora/issues/10#issue-476361247).
-
-### TTY
-
-The Aurora has no internal TTY detectors by design. Take a look
- [this comment](https://github.com/logrusorgru/aurora/issues/2#issuecomment-299030108) if you want turn
-on colors for a terminal only, and turn them off for a file.
-
-### Licensing
-
-Copyright © 2016-2020 The Aurora Authors. This work is free.
-It comes without any warranty, to the extent permitted by applicable
-law. You can redistribute it and/or modify it under the terms of the
-the Unlicense. See the LICENSE file for more details.
-
-
diff --git a/vendor/github.com/logrusorgru/aurora/aurora.go b/vendor/github.com/logrusorgru/aurora/aurora.go
deleted file mode 100644
index 3b302305..00000000
--- a/vendor/github.com/logrusorgru/aurora/aurora.go
+++ /dev/null
@@ -1,725 +0,0 @@
-//
-// Copyright (c) 2016-2020 The Aurora Authors. All rights reserved.
-// This program is free software. It comes without any warranty,
-// to the extent permitted by applicable law. You can redistribute
-// it and/or modify it under the terms of the Unlicense. See LICENSE
-// file for more details or see below.
-//
-
-//
-// This is free and unencumbered software released into the public domain.
-//
-// Anyone is free to copy, modify, publish, use, compile, sell, or
-// distribute this software, either in source code form or as a compiled
-// binary, for any purpose, commercial or non-commercial, and by any
-// means.
-//
-// In jurisdictions that recognize copyright laws, the author or authors
-// of this software dedicate any and all copyright interest in the
-// software to the public domain. We make this dedication for the benefit
-// of the public at large and to the detriment of our heirs and
-// successors. We intend this dedication to be an overt act of
-// relinquishment in perpetuity of all present and future rights to this
-// software under copyright law.
-//
-// 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 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.
-//
-// For more information, please refer to
-//
-
-// Package aurora implements ANSI-colors
-package aurora
-
-import (
- "fmt"
-)
-
-// An Aurora implements colorizer interface.
-// It also can be a non-colorizer
-type Aurora interface {
-
- // Reset wraps given argument returning Value
- // without formats and colors.
- Reset(arg interface{}) Value
-
- //
- // Formats
- //
- //
- // Bold or increased intensity (1).
- Bold(arg interface{}) Value
- // Faint, decreased intensity (2).
- Faint(arg interface{}) Value
- //
- // DoublyUnderline or Bold off, double-underline
- // per ECMA-48 (21).
- DoublyUnderline(arg interface{}) Value
- // Fraktur, rarely supported (20).
- Fraktur(arg interface{}) Value
- //
- // Italic, not widely supported, sometimes
- // treated as inverse (3).
- Italic(arg interface{}) Value
- // Underline (4).
- Underline(arg interface{}) Value
- //
- // SlowBlink, blinking less than 150
- // per minute (5).
- SlowBlink(arg interface{}) Value
- // RapidBlink, blinking 150+ per minute,
- // not widely supported (6).
- RapidBlink(arg interface{}) Value
- // Blink is alias for the SlowBlink.
- Blink(arg interface{}) Value
- //
- // Reverse video, swap foreground and
- // background colors (7).
- Reverse(arg interface{}) Value
- // Inverse is alias for the Reverse
- Inverse(arg interface{}) Value
- //
- // Conceal, hidden, not widely supported (8).
- Conceal(arg interface{}) Value
- // Hidden is alias for the Conceal
- Hidden(arg interface{}) Value
- //
- // CrossedOut, characters legible, but
- // marked for deletion (9).
- CrossedOut(arg interface{}) Value
- // StrikeThrough is alias for the CrossedOut.
- StrikeThrough(arg interface{}) Value
- //
- // Framed (51).
- Framed(arg interface{}) Value
- // Encircled (52).
- Encircled(arg interface{}) Value
- //
- // Overlined (53).
- Overlined(arg interface{}) Value
-
- //
- // Foreground colors
- //
- //
- // Black foreground color (30)
- Black(arg interface{}) Value
- // Red foreground color (31)
- Red(arg interface{}) Value
- // Green foreground color (32)
- Green(arg interface{}) Value
- // Yellow foreground color (33)
- Yellow(arg interface{}) Value
- // Brown foreground color (33)
- //
- // Deprecated: use Yellow instead, following specification
- Brown(arg interface{}) Value
- // Blue foreground color (34)
- Blue(arg interface{}) Value
- // Magenta foreground color (35)
- Magenta(arg interface{}) Value
- // Cyan foreground color (36)
- Cyan(arg interface{}) Value
- // White foreground color (37)
- White(arg interface{}) Value
- //
- // Bright foreground colors
- //
- // BrightBlack foreground color (90)
- BrightBlack(arg interface{}) Value
- // BrightRed foreground color (91)
- BrightRed(arg interface{}) Value
- // BrightGreen foreground color (92)
- BrightGreen(arg interface{}) Value
- // BrightYellow foreground color (93)
- BrightYellow(arg interface{}) Value
- // BrightBlue foreground color (94)
- BrightBlue(arg interface{}) Value
- // BrightMagenta foreground color (95)
- BrightMagenta(arg interface{}) Value
- // BrightCyan foreground color (96)
- BrightCyan(arg interface{}) Value
- // BrightWhite foreground color (97)
- BrightWhite(arg interface{}) Value
- //
- // Other
- //
- // Index of pre-defined 8-bit foreground color
- // from 0 to 255 (38;5;n).
- //
- // 0- 7: standard colors (as in ESC [ 30–37 m)
- // 8- 15: high intensity colors (as in ESC [ 90–97 m)
- // 16-231: 6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
- // 232-255: grayscale from black to white in 24 steps
- //
- Index(n uint8, arg interface{}) Value
- // Gray from 0 to 23.
- Gray(n uint8, arg interface{}) Value
-
- //
- // Background colors
- //
- //
- // BgBlack background color (40)
- BgBlack(arg interface{}) Value
- // BgRed background color (41)
- BgRed(arg interface{}) Value
- // BgGreen background color (42)
- BgGreen(arg interface{}) Value
- // BgYellow background color (43)
- BgYellow(arg interface{}) Value
- // BgBrown background color (43)
- //
- // Deprecated: use BgYellow instead, following specification
- BgBrown(arg interface{}) Value
- // BgBlue background color (44)
- BgBlue(arg interface{}) Value
- // BgMagenta background color (45)
- BgMagenta(arg interface{}) Value
- // BgCyan background color (46)
- BgCyan(arg interface{}) Value
- // BgWhite background color (47)
- BgWhite(arg interface{}) Value
- //
- // Bright background colors
- //
- // BgBrightBlack background color (100)
- BgBrightBlack(arg interface{}) Value
- // BgBrightRed background color (101)
- BgBrightRed(arg interface{}) Value
- // BgBrightGreen background color (102)
- BgBrightGreen(arg interface{}) Value
- // BgBrightYellow background color (103)
- BgBrightYellow(arg interface{}) Value
- // BgBrightBlue background color (104)
- BgBrightBlue(arg interface{}) Value
- // BgBrightMagenta background color (105)
- BgBrightMagenta(arg interface{}) Value
- // BgBrightCyan background color (106)
- BgBrightCyan(arg interface{}) Value
- // BgBrightWhite background color (107)
- BgBrightWhite(arg interface{}) Value
- //
- // Other
- //
- // BgIndex of 8-bit pre-defined background color
- // from 0 to 255 (48;5;n).
- //
- // 0- 7: standard colors (as in ESC [ 40–47 m)
- // 8- 15: high intensity colors (as in ESC [100–107 m)
- // 16-231: 6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
- // 232-255: grayscale from black to white in 24 steps
- //
- BgIndex(n uint8, arg interface{}) Value
- // BgGray from 0 to 23.
- BgGray(n uint8, arg interface{}) Value
-
- //
- // Special
- //
- // Colorize removes existing colors and
- // formats of the argument and applies given.
- Colorize(arg interface{}, color Color) Value
-
- //
- // Support methods
- //
- // Sprintf allows to use colored format.
- Sprintf(format interface{}, args ...interface{}) string
-}
-
-// NewAurora returns a new Aurora interface that
-// will support or not support colors depending
-// the enableColors argument
-func NewAurora(enableColors bool) Aurora {
- if enableColors {
- return aurora{}
- }
- return auroraClear{}
-}
-
-// no colors
-
-type auroraClear struct{}
-
-func (auroraClear) Reset(arg interface{}) Value { return valueClear{arg} }
-
-func (auroraClear) Bold(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Faint(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) DoublyUnderline(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Fraktur(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Italic(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Underline(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) SlowBlink(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) RapidBlink(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Blink(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Reverse(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Inverse(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Conceal(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Hidden(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) CrossedOut(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) StrikeThrough(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Framed(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Encircled(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Overlined(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Black(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Red(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Green(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Yellow(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Brown(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Blue(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Magenta(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Cyan(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) White(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightBlack(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightRed(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightGreen(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightYellow(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightBlue(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightMagenta(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightCyan(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BrightWhite(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Index(_ uint8, arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Gray(_ uint8, arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBlack(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgRed(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgGreen(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgYellow(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrown(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBlue(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgMagenta(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgCyan(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgWhite(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightBlack(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightRed(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightGreen(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightYellow(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightBlue(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightMagenta(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightCyan(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgBrightWhite(arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgIndex(_ uint8, arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) BgGray(_ uint8, arg interface{}) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Colorize(arg interface{}, _ Color) Value {
- return valueClear{arg}
-}
-
-func (auroraClear) Sprintf(format interface{}, args ...interface{}) string {
- if str, ok := format.(string); ok {
- return fmt.Sprintf(str, args...)
- }
- return fmt.Sprintf(fmt.Sprint(format), args...)
-}
-
-// colorized
-
-type aurora struct{}
-
-func (aurora) Reset(arg interface{}) Value {
- return Reset(arg)
-}
-
-func (aurora) Bold(arg interface{}) Value {
- return Bold(arg)
-}
-
-func (aurora) Faint(arg interface{}) Value {
- return Faint(arg)
-}
-
-func (aurora) DoublyUnderline(arg interface{}) Value {
- return DoublyUnderline(arg)
-}
-
-func (aurora) Fraktur(arg interface{}) Value {
- return Fraktur(arg)
-}
-
-func (aurora) Italic(arg interface{}) Value {
- return Italic(arg)
-}
-
-func (aurora) Underline(arg interface{}) Value {
- return Underline(arg)
-}
-
-func (aurora) SlowBlink(arg interface{}) Value {
- return SlowBlink(arg)
-}
-
-func (aurora) RapidBlink(arg interface{}) Value {
- return RapidBlink(arg)
-}
-
-func (aurora) Blink(arg interface{}) Value {
- return Blink(arg)
-}
-
-func (aurora) Reverse(arg interface{}) Value {
- return Reverse(arg)
-}
-
-func (aurora) Inverse(arg interface{}) Value {
- return Inverse(arg)
-}
-
-func (aurora) Conceal(arg interface{}) Value {
- return Conceal(arg)
-}
-
-func (aurora) Hidden(arg interface{}) Value {
- return Hidden(arg)
-}
-
-func (aurora) CrossedOut(arg interface{}) Value {
- return CrossedOut(arg)
-}
-
-func (aurora) StrikeThrough(arg interface{}) Value {
- return StrikeThrough(arg)
-}
-
-func (aurora) Framed(arg interface{}) Value {
- return Framed(arg)
-}
-
-func (aurora) Encircled(arg interface{}) Value {
- return Encircled(arg)
-}
-
-func (aurora) Overlined(arg interface{}) Value {
- return Overlined(arg)
-}
-
-func (aurora) Black(arg interface{}) Value {
- return Black(arg)
-}
-
-func (aurora) Red(arg interface{}) Value {
- return Red(arg)
-}
-
-func (aurora) Green(arg interface{}) Value {
- return Green(arg)
-}
-
-func (aurora) Yellow(arg interface{}) Value {
- return Yellow(arg)
-}
-
-func (aurora) Brown(arg interface{}) Value {
- return Brown(arg)
-}
-
-func (aurora) Blue(arg interface{}) Value {
- return Blue(arg)
-}
-
-func (aurora) Magenta(arg interface{}) Value {
- return Magenta(arg)
-}
-
-func (aurora) Cyan(arg interface{}) Value {
- return Cyan(arg)
-}
-
-func (aurora) White(arg interface{}) Value {
- return White(arg)
-}
-
-func (aurora) BrightBlack(arg interface{}) Value {
- return BrightBlack(arg)
-}
-
-func (aurora) BrightRed(arg interface{}) Value {
- return BrightRed(arg)
-}
-
-func (aurora) BrightGreen(arg interface{}) Value {
- return BrightGreen(arg)
-}
-
-func (aurora) BrightYellow(arg interface{}) Value {
- return BrightYellow(arg)
-}
-
-func (aurora) BrightBlue(arg interface{}) Value {
- return BrightBlue(arg)
-}
-
-func (aurora) BrightMagenta(arg interface{}) Value {
- return BrightMagenta(arg)
-}
-
-func (aurora) BrightCyan(arg interface{}) Value {
- return BrightCyan(arg)
-}
-
-func (aurora) BrightWhite(arg interface{}) Value {
- return BrightWhite(arg)
-}
-
-func (aurora) Index(index uint8, arg interface{}) Value {
- return Index(index, arg)
-}
-
-func (aurora) Gray(n uint8, arg interface{}) Value {
- return Gray(n, arg)
-}
-
-func (aurora) BgBlack(arg interface{}) Value {
- return BgBlack(arg)
-}
-
-func (aurora) BgRed(arg interface{}) Value {
- return BgRed(arg)
-}
-
-func (aurora) BgGreen(arg interface{}) Value {
- return BgGreen(arg)
-}
-
-func (aurora) BgYellow(arg interface{}) Value {
- return BgYellow(arg)
-}
-
-func (aurora) BgBrown(arg interface{}) Value {
- return BgBrown(arg)
-}
-
-func (aurora) BgBlue(arg interface{}) Value {
- return BgBlue(arg)
-}
-
-func (aurora) BgMagenta(arg interface{}) Value {
- return BgMagenta(arg)
-}
-
-func (aurora) BgCyan(arg interface{}) Value {
- return BgCyan(arg)
-}
-
-func (aurora) BgWhite(arg interface{}) Value {
- return BgWhite(arg)
-}
-
-func (aurora) BgBrightBlack(arg interface{}) Value {
- return BgBrightBlack(arg)
-}
-
-func (aurora) BgBrightRed(arg interface{}) Value {
- return BgBrightRed(arg)
-}
-
-func (aurora) BgBrightGreen(arg interface{}) Value {
- return BgBrightGreen(arg)
-}
-
-func (aurora) BgBrightYellow(arg interface{}) Value {
- return BgBrightYellow(arg)
-}
-
-func (aurora) BgBrightBlue(arg interface{}) Value {
- return BgBrightBlue(arg)
-}
-
-func (aurora) BgBrightMagenta(arg interface{}) Value {
- return BgBrightMagenta(arg)
-}
-
-func (aurora) BgBrightCyan(arg interface{}) Value {
- return BgBrightCyan(arg)
-}
-
-func (aurora) BgBrightWhite(arg interface{}) Value {
- return BgBrightWhite(arg)
-}
-
-func (aurora) BgIndex(n uint8, arg interface{}) Value {
- return BgIndex(n, arg)
-}
-
-func (aurora) BgGray(n uint8, arg interface{}) Value {
- return BgGray(n, arg)
-}
-
-func (aurora) Colorize(arg interface{}, color Color) Value {
- return Colorize(arg, color)
-}
-
-func (aurora) Sprintf(format interface{}, args ...interface{}) string {
- return Sprintf(format, args...)
-}
diff --git a/vendor/github.com/logrusorgru/aurora/aurora_black_standard.png b/vendor/github.com/logrusorgru/aurora/aurora_black_standard.png
deleted file mode 100644
index 83658d60950ceb262d7f8595fa1a4380997fd216..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 37415
zcmZs?bx<8o&@PO-yX(On65QRL;O_2n(BK-}-GaM2!66Xb-Q8UeAHVm#x9a}!)z;M3
z_Rh}KOm9zjKl4navZ53+0s#UT7#OmQw74o57&z)zk%EKylJo+`guZStCUR2ZV4we8
z`Q4>SUlMpHX>C_9Fx0yL3iyeCcK4SM)=fr10(K7y9TA7}F53V0ON8$xq2(s#Xm4-s
z;07kB3BFlbk(*T`e6yO)PY8$k
zdcK{`7YUXm`Fb%uDi-|zD*=907NJD_@8kbd=l_xH7l;JI{Nn$w!T(d||B?Jp7d1Gv
zf3BKsrl(h@n@J~?sDCT>_QrcRx2tJG1pB*iYzV9nRj9B;>8qNtP;YQ2>_EQGaS4Pp
zbPp}-Dhz2-ms}yg12{%OUGxx|-h{RrdIQesvl(7zPOEgtpV%U#4nE(dTv{7}nsk#m
zNbCz9Azl1sop?lK63+kTd$@o2PKp?gpW`me5paizv<&$sT-gf(=ZQ_mQ=?4_%@m6jip4LXS89m~zUC|JM_AO9bx{x7
zVp;8mjNKBJDg~poS3=<%yI)M~KigAjVi)9cHVY^0M(Y-QTsK8Mr%uUqvhoJ
zwqjfGV#fr8u@WpvZX;88@Mw(tm7an$wfK*D(d{&T6>`gs&H_HM
zeoFipB_SmDS4+Vt&Oea)qZ`-S)KM$Zpi-|G}o+avNAeD;tE%DlQI|B&kO
zv^oI?FfN5yqc^@vMFibR`_K06C!aEg_2E88TPGMXt2xVW1L04*$FREPsv@zIX77XY
zqZ<>Mj&VEv;^N8j&1Y|`)}rD!-R%x;>ae5faDBzZ#&VK`3v7A-dmxHTKKDCQlUPT`l13rcL!XJrCp7v=eu*y`i6FZ*B
zDqI-kI7zs3t*XoUPw@N5RNa(@V=iLs_ey>iU}a(|2p
zQ$&DdVD>ikji7LhfGe!#FZm+KlkL;so^(^cxp%B`{c0ew@zcxC4#`FZJ#ZfUUgn!#
zy@13W|F`Tl!*~Ed#s;|+#%B_y<+q~g`9I=oukLxA8q0r|nK*}#P!N%ane%pU4{U=H
z&$KU`Y4l3Lz4@&=O7XEys=7xb1h{e975&aIMGLofoc8?UWoO>h`g}1_af|U+SYHO)
zHcMW_rCYC~5&xit=`+hEQE2B%N1~_*pF1*V+A+Qag)dzWJrf3ueToN4^2z0+#!N+@$W4P&c8CGJt|_(Rw1Z>*1^)YC<&gREf<@wVkz
zpDe#B+~Tov*AOuIlZ+lgx%o_vb5P!Vxw*Scw?6AM|4XGcR$P?H_w}vuC}irslk~D4
zzLUcr9)mn%Vg&;c+A)`A!ii>X2r*f6@FG78n?HA=eT7v2{8CFBi!Z063Dfo?*{XVu
z3XZi{J^pJteh84f&;45!2%g;xtMxX66Pr8d51BJOVImF-4ZzPq!aQ_?-r1W@`!v>9
z;o<9D5!;_;Tb~u{*LP1RCgl8+K93owdEoJ*27xu-(Qx>oE+1ErNCW7ro9MavF1NX4
zh|Y1qD~VcWu`;aMrKzeZqRUjYqe>14RpEF;U%tlAiaLja8Xd;-{*@)~J%o^IC+IOm
zjaw^Esu3I}x3E&UHWNlkMDIX`0=A$l*Ua>@a4Fm9zxAFQGNc+bxQaQSL(_l;WZG#ECOcIVSNSGVC#^-g!*AT64BbI5Y%oM+ow@UCOM
zAqA=)3)DY9yFp7fK(M@j8EPV)chtVL{pbjR=k1q`R~C2C_iWoyK^*jBp+{S
zP&G8@5Mkh8AhDp$8%!AQ7Y9%bgFR;#Ow4O|La^{pAxTo#&KaL7k%`r2+4>2FtEmNy
zDgOK@B}`jXOhco0cc2L;LS|7!U3EQ9S`V`>ARm2>@9(U4{}~J0+vsX)!OJCy*QYyK
zyJ&AwAV;RFstvSws--MK_Bu6m^hy7sQ)#iiC@`DSb$jQLedTJ^lh8O2iswd_rjMwvi2Av(CW^1J0=QDiO39wB@{8PDN)GA?PeZV(eD~6Z
z(C6Ml(rV}M6AnR!?E=rT;ZCM~@0k<0G9R1fBYAUiSu3Mo9|f-a*!Xv2y1#-W&w2ba
z+TE0Vp)`gkvKU3XYhidO*pPALbxf0A8#Dj-T5{EazPO`aE>=N~Jia%hN~1DEb=y+a
z0_Tnq1BwB7ezpJzNRl$xrfp0Mh`1a;onhh=Au7!nyT0=qWlYHA{TavGpQXDP-(kZf
z#KiFxTlK6vq=IEs)j)a)%nY~^{+Ki0P+XKOW*@IQSYze^(k8|R;&51tpl-c_-^YAE
z8*^WM=_f6w#xp9N>ytD#DpnB@onlQA?HQk>4~Rd_&s*@oZ6~-f>>re(?IjY#p1MEr
zvXnn?`s8kL*cw%9rdfxT!SPLLj1K*-SmEn{qP~=uhzcJy=h+InVdMTAt$l)C2I9p@
zS;RC&9$MW86%F|So0?)NT7%tz;acTkb6iyikXog!?A5kXuN|?sD%A+8P_Al}E7^@%
zT$RK`?rT~(Sp&01M4xGRL5vbka&O8W`{s93HZ)R13tb6*5&v{*+uV%hs;Cm5{$WHx
zJqXgUEb=bXfN4v?N>DH`rg{!!;*rZFkFhrt$I~LpLY_J+NtA)dBEZe9o+cjfZ?3ci
zzPLlkEG7}nB?vv>4>Ra4IeTjFwJ`4(wO+il7x2o6+S7l`(ZUpSj%n{Nu5s5e(*|(|
zv(Nm?Jp}N&5rhd~yETZLFNjz;u1|4^{6UjcijJ+<-Yfsd@7$|G<4QXiQKfZkh7fP+
zO4=&*usU`p60^v`j0~J_vwz>j&$qP#G#-!*^
zyDgo>)G4UZ{gV@yh-q`uoyP;lgLKfhD64zY$n-NQ{`wXa>(2ieoG!b42ZTfOSOt~-
z=4U1cLM@Q}1{WIg;PWf2UblX{EoO+QfT2Z_y;lWP@CVMFo5Q)NryLiKN<$I0{FLL}
zrJAfB%HJ^=Vx#?K!i!7tf*6J1c_Y4-z(|}Wow79&Sj3m%J}nvjjz_MXFrCv!);lFp
z)1CU!`NZz*1{0t}XDS+)l;4|cmzJwS9f?u8H-D8(yx;DQ1jj*6>RJeq*e5Cl$=wv|
z^fd<*$A=11KbxlOhC|Bo7MMxlQ=JYok&2Jq+}QE(?b+t!9B8+;Q4%fcU2+V_RcAQ*
zZAwa0YdebdDHsRk8-_$(thgyv*}d3hOa^8UDs)U+qK^OQFUpdvwgpBKwq94h|HY{$
z1&8a%!9pKP_CN>V|7t@1j_%JJ*QY-L`DS~vCeTPuPJgNuuPHOa><26mW5hQ$zK@mJ
zkF6<>VF$AzmXjsAmpL2DQNh9Zm$1G{sUWv(C_7a|_g9~D6E*UXvoccO-QlmkJ3o2V
zM2k49VFDaNib-B{E5X(XiOb?m1<_=+3fly>h(~+&`x34sUv)KeLXok>=AW~4ShxZc
z&!tB8Bi&0DtMteNSG1|YO-!%a926NUdbv+DW+-n!{lm0EK79J2?
zX?J=jr=591Cy*LJi4E0qq=D5B5bgs_*NDyPb78PpUh2&Y4c!SW*^titXEk;DPXY_e
z&N%zH&s86`Zmf`U+qJQ^;b*wGm{zlZC8B5e{o#r6o)`J?cJzDjdpmuRh@SL-j9_`H
z>amEIchQOz%Y<-UQ
zd$nRmC}FcoEhz>SS?xvlOY2XBY}!y4M+adk!;{=^do9G4idJ5a6FAc$Fpz?h$=54Ly|N5W*DC?xB_g9$NFC
z-kj{{j6XM4i0I}i?#DCvizf@j1_E0|+hhTgV!oMMc%X@}l%&LU(vb1b1?$m$*
z@IL?y#z|t+5%FuLO2j%k$=MVYDV6^EPWPHQlbH@4j_e1RjzdcX8b9}8Q{)Av1U(m-iy&G
zSE>IaDMF8cg#t#-vWJFBeXxs^!32cHEU%A6u4`U!R)Ogfd|s|hEgspXIS^W2NwJTY
z!@7w_wF@GqlV|%!tBKU#K_&v|BBq-tZvc~_6&sK^e^covT8iqulkMJB9aKJYFI*yP
z-}y|WkRRxbPQWgbXzf7`NMi4ZWQ&b7Sk5ODW|2PW8P0pR_oCVmnPth9Wd!lNJ;3a
zdBUO<$7o)Y=W9#xj_?4h;dy2O>ac9fJQ7H4BA&xrULJ2$=&yIiCbNM(6z0lhtj)-n
zH*qM~OPWYHV;9A)X=gQd&fpICj`Oq@u4q={wDo0kA`%bXVmgVSY~w6`7;v9
zQc@VbjDaEMH{x4WZ-Kpgx;6tjgyPMWP%aS2Yq{70hmqdzau;o`L1h}?U7zmTH-xMY
zYLoh#qoIM{QS@Hu$>1Cwx9?7-X>8AMv(l8{sO&G)OMFT=Hn>u5frcf!AAVmhh}wlRnE7i3h9N&Nn%KS&l(B^<9e*O&}iQ)a!)LHjmJ9eMu}OWIrDuz>ia-3d>-ajAZ9Zus2tkH|*Poohc;&OKxxQUQdGnz>(~U))8A
zUN8Y*JAsWrXYf-ktk)4hK)}p83X}7Nd}G!r8L=wI5Tanc%ltPpQ~BnOvHUcsh9!-
z!!5`2D)~6wK!}@sN9$tbIKj5kaF+0@VDx7SbEUPgPGm2
zlFl=1&Y=VQ?Qc|AM(+$z-S5cLrkd7s51l-HZLE$XqRiE}F>u5^6XePJMg<>|Hp{nE
z?>L7#6g1C^DjLh}!;^sgd1pvmdfCDZT=siL05Aq4jp}wYX&Sje!>P;S6;cIZm(Gl7
zPHNQr`iQ=EfRsrPc0g{`-S&3HeY1!)+XjhuxeK0;do~;Zb;lD|3Pn8R1>3uAE6SG3
zr-73EVM?*Pw$`7G3u=Z{G&R*BmDA1@3LUP=XU(llxYJxgZCkFU{@=3UvWSnuz$!H2
z1Pe3rP+y&y?u&HYWT6~5O{E~#)D->Ds-KJ@;}wAjmnB;Z6yzYX{Yy7u8LRtg+HT!Trv&lfCq)K@c*t!-uBRaV(p3qs(3pv15C|(dD%eRB
zA-DUX#2&B|TNdkWmPfkOLm%7K76*B?GCf(a_&<>I|9}86$U+#m@sv#OJ1t&<@7fUK
z4#-8}>kTf*X|Rl#-fDX5S&>XwklqDG1mmD^6Jc3z%f)1cKFoBPeA=X)*VGi-edkj@(c|E~MXfk|#b
zF`og&uSPqL-&ZKLD{Zqgj^^kO9gVBubWITnF3@33)*AL%$6(1XNHEfqd(Q!?Gb|Bc
z#aQb@3d@-KINlBn*2{WkQ)!Id7Kn5C#XpG{)ZdN5d8{yTOv|;>XJw|NMBLfJvr=n5
z$Q)3{jI(*qW1XWpQ~l(9*tJ_Yg$e29Tv8x$Q~~88=k?r5wXYw-nTBbCzi?q@tNz&4
z6h~Ds#{Z3DKcsq*+uzTS){sAA+}j@d_JFVjt~QN|5AuHWThi?Feh4!TOnVOFn3
ztMiE`n2Fg(<`=ABN;7<;T+w1rTA-?Vx<5@03;VQCce_9YYBVfR(}82pA3q+RgzUzf
z;|qn(qE^1jmGs*YK6JAx9dj
zrpT~@M}sKWCp36J<+WL#D`z1Y%5v>z1y45xdT(e&p_;L>Ge)*nSfasAkZt1)RK<7iU9Rk2F2vmS$be08~@TYV5DvfgegMZy-(0$>o;
za)}3X8_K=(lDO;Wg9-TbY(LJ{2z6^*ok3H
zrh2-3dA|O;>cDn=K7(A+p;lC11)DVuq&9P*N?C$aMS<+8w&PEe9Chht?q`Br_BtBM~W|BU)xS@P>siw53mi@%lr)ZNKLU1solDg2x!-^YsX
zMqP=`J?_Jg-AD@&HwFXjkTELM27zJVWK97gCneWf(Zd3^*5Q`y*mA{#^aS6++p~GPce8JHcGv)LhQB7Jbcw=e
zm<(I)471!m-Zz{dm_V$v(Qm#EUP+^?ex8XIwuo
zu2}sS=y=BCJ&RDgjX(JFH7>TVz9K!v9Ae?eNFnNJG0j<%koP0d0S|hXJo_DFMxo?*A=NlIVYN&`E@zSr&wZ=EH
zqaDK$7?_eB<+&TsLN#M&h0ih%&?tf@_(Q>d!HjQ%Vhc}SvFi-EJcX?m;}wdvNr*w=
z1S2J87g>(fP{r3AnAxkLiXuC;p@d1C(J~;SWmFi&&L{2OH&%(7s3+#edlN@Kfc7?L
z7IN>rEH7aWxuU?SP%lRFa8UMAR?gZwzXpDJhXpx%0+^@PLAEKvi(dtJrgn}DJFlpH
zkC>yx+<;)q`TKc!^!rV+Zr_@VMNe0J>=ZB2Y)1dra8wl5;)E$B!4
zscOG8s`K?#x5DYLrRfrQWEO`Q&;75Q5W)etD;&wg1YU#XioHj4bS;;G6SulpJ5mB5
z8H61-);7(Cubl&XJe4p8Jz-Cch02QzJZGNw477>BcW`=kcekj8g4#!yCfSmj@LXmU
zUh!YBOg7e|zE_NAR*3wWxJ%}rm4{IjS%nu`Smf{ffDuYg{W?OMoDAL6jcqwfNf#9Y
zkgJYY$HMAvkEZ#Gs7^rQ6{o<0KeHQ?1I{dT{ChH%p*jRYmEem~kadr`A+i3kFqa
z?2o)Ei14$OGg+#laENe%@=-KNi;nF-vV5Bmp&tns_-W?UKK25aVhBDayzErt6M>HY
zzTOxg7!CayYeT}a#j%Q!l9HAgC)l$HQ%^oGX1%goJ;r*3rD*sSrbeHv
zH5&ZBiKOCCko#-y_qLRyl~`!^Nt(5#N{RVpItz;@kkahNkrs(bOaM;=%fWS|+-&-K
zW8hHa^_{3iWfjW$LUUp`wWHDQKGXZ@foyDx(>#=14pyXe$vT#ZYD_{)Idy;5fL$Oj
zPM5OGNcih*|3$r7arlgn6@@2%_TRGOA7y+#JS-n`0}lbCW*z~Ekr(|LAbA!GLRp}7
zIpKn>sig{3lH~JB3nf^OcMA!UWj|cXx!qP=&8PmYr`W;UnU|?Nk!r(Rjcptx>Aa3GVIFjpri#f$IIM^>5HXTd_VHgyNf92
zcqQ2S`DQ64RdtYkC`3paF`vdNN=rS*(Fl*bbwBm0y9_g3$**V68LgW*IvisMEJ${7
zi3r#wMReFBDfsRmQki)1Fvz9Bf|UP3NSl_Ed!_9!Hg@M@s2CI>Y5q&Gfy58TzW%aL
z8aI8>Z(gqgYu2bWi~q}1_&;D02zS3AOICf|XOPBMUi3T%uZgpbqCigTPYAqY{Bq(D
z*sT%!FdzQ>ruU8BMI9`jho8WlW!XgfHAemFJrHES-l6_2b#&Q>5VaYHY`v^+z-!~m
z*z?jss}EmGQelX_I9@8E(FWN`yN^4r023FDg{vt~`NAuwvz*pD>U^EWxs~h>GH-8T
zv6f!;KwI%;ahw;zQ5Zhfo32G~UH2cZyq=%4mtxdU^O^6rEA+#kD+WQ7$!
z0v@!4r}jbV4?nQ9VW9eMd8(F^msrdG&5h!L@Q4dn$$_3OW}o~XIG2=VF~x83X)>|$
z1I2Ubd_2O2KeuV@^x1yxS}e0nVsrk|{bgf%TT%J_)=D2Q9$Ac)_P1BJlrEJ-Q93DLRz0};(!Z;Mr2C{aL<)q_
z{EELWV$W%Y=O*C(RaXK_Z=>nSH3B5N
zVM)!c4hqjw!`0d4d7O7_{XmC{(NJ1f?u2n@%VD*Z>|GoNaL}9qO1IX
z9Yc;3(X@)Mgp!;@ZvHJD96(&w-gf%=b6|@=?kBGaXX%b72+OmmbjO`}$kZDmi4CE(
zQit#gmk84hVBeOb2$o3Fl{K~{m;u?Wu?gyO`Cq7Q~
z^&_`^CwDQp{Yk&n+2kp!ymV<5P(md=UI*O1%CAn4Om-ldktCa5`1g0~;@9wc;2F#G
zja8f?n=zcOu4zvt8Z8#(WP|s_!D7nxcbF>eCP
zbk09lgWMv(*tGhq6dam@=Qr58B~otZa3>5n0@lCPR-Z4TTRBeADbH09C1$zL3Jr>J
z8~_~dLLdol7?@36vT%`(Jee}oD_11z)6mYx?N^%Qrf|ptUpAul$%+!NU7S%PN%&k1
zK`N-p?BNq!YE?NU8AWd*dVX{+x#sD7#D%6wM&~p|kb%wUZD!xgiryj1e~N
zS9b`e7(*^D!oh^gWTV9pQ3~apWKkfR+h&rkt|t>6((odETXitoUY7Ct_`V#sIglFc
zqsw_M9(R(mt%|O>3963)&n~U*r(vB{?1?qKyR|Y66E(!f(#W}
zJ5o#~_$U03lfWVxbg!Q$M^|joGo-;pi8Y?zIDC8vn;V3;_+E@NT$(LQ$@Ck%+E(8|
ztyJRP%!w&{hvu$YbI3`kSe#%nB#s;yfZ=f2a9Tj7fY%4Pn!KJ)VqH<{Y{|^=T>u+I
zR<_`!vuxL&6BoS#Xdd6yvW7qY1x57x7vUN6AO8d?`T69*_vfIYv-p5fq4F^0~o(6i-skT2dCAzrB@W-M=7y46ldpZww@4Z^fJX
zhDS(FjcGe^oDDVJpLT?(q_V0T!ngcg8taigVp3QZ?_~aGo=yF#uuM}UBa0Ii0wyyW
zCO>2D)!kNe1oj2K6i0$vPdo9B?wCfJGf^Fceq$U%FYAGv=hGYIP5L1s)bcoAAv{3k
z>a5?+jZA5k6(6JsAtOUpc)?NJdgEMW7hYoUX&UV`gY#nBX2y!X2;yO%bENo-5m~jk
z(@=dRy=h8ByAtPt((%8XzyJ1u{)g5#Kovq|3_gUpX=H*p^wR+E%1qlw;rO6}5>-Md
zd@D+&i4^B1n`)QkK4)ZSRc}{`q
zmg8-Cmcyqdwx9P~t@o6ehW+TP;^6mrjDn8Xkc!7~`Xpw$jT85lV8vRC2ooF!MH+hz
z%ML%DFrF8x`;(Rs+%?JOW4)B0ANnMlZzMom@*?VRBvbX}6McdO&0iQZStzPvpV3hh
z6tkLsGpH(#Om6}5Ru6{xFmkkMdgH@#estfi`DjnsTu!=eB
za+K^ow@rJC*jx$agwDFxjZZ~m%=*b>q~Uxw)7pwWkUgs0nkP(a+J)%Y=V5zH+wH-}
zKRlpLCVq9}uH4X(A6nn5_0L3_^tiw01hhrp$OvR$196KUWW;6I1$NV%g?>KA;xgo#
z=UB!1Y4X0$x8L#1)0VhSgQQ*oN~Sti80_Drca$33e}=;Lj_(XlY&n}2;Z4^rZu}8V
zi?Vy+VW{;Bv_+N#Z1tw!pAZT1$sk#|#6eFeT`KW)V<$0El3yoJ71)2}cxJi7(F3G=
zEoC0Gn>k;E4w5IF%Yo{c{S$H)S1B_B8D8Q68dxtxvS;|#+VtT!;pyf)UsqCg>`}zy
zu?YDiBYhMBf;U60K_bxfheJ)=sVrf4-tBA3yZw^Ddvixif!~zHR#EGqAqdl8-A{<+hbHBIUl;46d-8g(sSF4?so#X{`RQiMV)c_WfaAP#{V;Q}1M7q6
zM(2KG_p&T)$gZ0rKPMgk1NTPlY;JdJ=Oct9r0O0MQ^8NdQa?N52XCaxPHiNriA7{A
zvhJ>U@`-aj_akm$UKO0oDZnAp->?gPQA$hXCnLs$Qgpz`yKKw?O$6=loKXZn*)Gf{
zKIdu*cxhZ$Qy~n}ApzWuIcha%A=4}*~U0!>Mh0GiBgM=5GUO-}r>4%$Rfy&-}P5P5%$l;EbS
zpNa8FMNiFyg}Gl6kS3veTUvP7!8N##mJ|QrH;7quURd`ej?P3G4;zg;{1);>Zrf$C
zZxn}BqhTvNJ1R6e)ww~8_I>B+C_56roR1r-ekJuU{W72g*9+U-g&m)vciJ3bS=_jo
zbw-1UXI1t4EXEkJ(B_w(FB4b7LrS4fwjR+~vu+(0-inru
zS2ohVZu@Bi7hWYk*ON{zZJ*6{8-f|7nGq+_4cnF3Z(3Sv(kWN8uoa%J_r=z1w2HW8
z1jnR8P*N`xKfEEzK*Wsn8)7ldm_M9NnE7F@-Wqt0{5Pv6
zkILS_DqZu;t)0Gorll{ZLn`yAKLctP7cd6pW)eQ@sF!`;rX04gNm_*CDFVnjVu<14
zi)T3F<-j9pdX!HFVy4TH*a5~85-FmQ7LKMva--5^3PUCYk&0lW7bp4YqX@cxIu!xDv46W0**@d1AeVbGG
z*9Q6hJ_l4*4(eZ4GE}ru@c_SH6yFB~{XD&Os$%}p=eK-itSY5P%F=eGr10@qv{s3x
zH@hlXj-M+Rox5X@U7%ofo!R38rM`nt2wX}6xx@_g8&=aGM6Z@tIfQw#D1Xjc@n(C*
zr-Y;NArlhG)a(I|nLy*=mSnHSau@&raJr)W$r`PQ0f`Vn5LEnqR%)AnZ@_iM^ZOsE
zYKF9INwyrwhZR~CiLN}}$dSJ|s)%F|P?Ks%$DL9CLP|IK)8iGYknZ_V3`fc%Pdn2r?~1iBTd=c=EjAzWlqw?
z<9Dnw=P;hks?Ty-qa%sP^hE`Bmn9moC
z7k|3>SMdP;aFDu=gC$ScYL8{ca%M_rN9b>
zyyh&93*F-e8WPwZHnB@r$F~Y8~SoS;+Q__-#O(Yz0OEeAWOOin#Y*x0MTf;YOMr^43b(X<(N7c3SYiBVQaBY3fPv95dW`*9A
z4x@<$v^x-LSzfCz%^YiQ@xKjv;OtkM8pO2%`|jWnZ5d|pRgbafatni&p6Q*8AD6fW
zdKmKfuboB>MTN(xYEORRyuJKs$$m6Oy+v&l*EixIUH*he7gLN6FDsJF?3*ftA$gMI
z53B_?KT0e@Yy8!}1B$K>+l>cLXv#xLU=Q_70V||C
zk=y@|%EK+tlt_hS|LV)wvmb}nn|C~LzJHmo7tWp2qcl!Q?U54;mw5~HguxpeVcgb^
zna@9P-_(D04_wC7?vMfNH<}&hOypb|C58U@0qgE8_q{iRKe@B~Cdr_oxi}R0$6fW)
z>c%i6|7iAa{#^o=K|^^_zb$Q04JwTcP+Fz|B_uOW{4x=S5i9X>^6KVZcKtbR`)F+~_;bNP{
zh*YdDns3QPy(QT@N&F}kYSU>{`rlJ6#?k+sd$HOt*x424G6u(t+9I2o4MIJEO;Xu5
zn`Tr%I+mIl#yu!k5vW`Dg)HgOSEfKRVi@Rs=v_9@6%!u!Ht31S8kydO9wY=OM-$}R
z?B7uD`oLPb>mA$(YC${M0)j<1!+}M@&mfXU1il8MM9@z0)pRqi%$*SKUhG1o^=5uLT}V2e
zI-C8FoiQsC4*m-Y+wsnt_^>9>q+yM+1S^2yb>d{RPI#JM)y=R~Nxtc2P+kL@10pbN
z{3gMQGz_d#T1%OtdAkqHAmcmnxT>6~W5^bNspjk{pb9i!yU5c7s*3d8$%
z0zZx~0Atf%K3z==`Z$#R9vuA*#L-VgV;$VvJSK*KUb3SUnSjkF{>5W55mp^eGKnb?
zkI`)u2B1pg3?Bo~Ia$Th_mjl!sX=n`75o|eX2zL!<>}c^VbZem@N`vi$B)(e@?L(0
ztjC0~mOV=He2>45zjMf?ueo8=qXsZj^DIVvahL|(iv6b|onzx9-ma748i^RZ(}06z
z;k@!c;0x0v*1)kJ7v|NTX-lXMNAC@6p{GD@VGuE3A6cx6x#{_B^Q1=
z;>QFR4A;^4QbOoCHIY~tlEyv2gmkAwKPv|LDaZo&V@3yv(2+?jxIIt_(Li0`$OC+_
z10)+Q-}Sl8dba8#am|A6P1+B%D(;ZCMy4|73zd5sqThcqJ)IBuz=Zn#8SdTv&R1Hr
z7Bs8e$K*|HS)6o>3qKL0*-O)t``0x_w7d!c7T~IbZUhmyaCfT(qb}Aq+LRDvB(CpG
zgjI^d(X^T)ZX3Y*TY`5{AB~Pz;Xj^Uuw=Hi-*q4T>oAuR#MFD9*$+06D111@
zQ{nhp1VT#<1GcwB#yX+Jx7dl*Os6!%~>tyswV5
zC3Tu2^N=j$0vMk7hd`M96MuIl{@4DoXduW}EZg
zL;6tK2Ov9AdP?8;)xDe1lb^^)MueyD3lKK7zD4_Fx^TF4%ZFFK(+m?yKL0l#Xhs!u*&`WVfPA8}MN8=ue;!
zo~P9R{BekaE}Xrj%Ypjc&|XsL5@&bU9W7I&^F+VC*5D0tO5)*Va_TV?Lob%KDhG3_
z4OL>FrQo>pvZ=EkQFW9oad~%Ab=BHBF8UU{A3nc
zra1T7(hvGn@UoiAk_)3#pYy})^44v|APIL
zKmyqABG>AB)&-PwvUkprD}asUq59ucXbu2nr~R?glQw_BU`-vK>wZ{u+;-(%
zK6H!80i-eicv~s+u
z6bX`_w4jjHtyQ>>F*C-eI59T4hz^(cN`s;9_8aOqk9EF7be@U0vzreZi=03HM77K`
zyEU+p8MFl?n=y9}0sX;ZO{pDbJyt%df}@nb$^HKXm~kCUDOx@Wq0EU}+#|6jJ`Wqe
zZV|ymq5ns(TK^CDTgPf)tf%aZ-C+}uJ`BS&;R_6oUSR`yM9F1Zo35BNkP^w{jVy71
zSRD9aalZIflCzyzcOaDnWmLW_4r5
zY&e;;wm3racz&eRX{NGXlHgxmn(x2w8fdu`EwW60+hqBmf(K4qNxYxkg@}}PQ*_(Z
zq+1sn&ImgHOExPQ{q;dcujZz$%TkjiBs`i{_lbX0gEe>iNpFIr(|KKl0h!p(`Y1=)
zc0=f^b9r~_Y{Nc`F|H#k$Y3WQggBoGIe*j{&r~9}{AnVSK99OI>sfwdec=KG$WK8R
zVe?QBY+SF^yD|KE0Ol@2XeLGLrblzQK-rI!{zu!QL31A9C|0_2wi}9#4#=(N$&7#I
z4EfwwawBdC7OQm>TVuPSgx4*O$%|Zm`efMMdX0u7%*=21*W572Fm5!!7(gMyRO=RG
z+b|%nS$i)y2D)+;bYeL?9`{Dypwy;&m^HQ?mc*{6h9MG9S(ylb#aV6V1OJ0M?mHVO
z&t`NQ(Z$7bd%7?dPjxfuJtMw`SpB*;4KeSBh>G6&Uoeu^so~rt61;i)<;c8OlH^DZ
zY2)Q2D0F?}?3v?sKN@mw3H_*ixlTZ
zk{$Rvs$+k1rR$7<=KQ|8#sz!8lVV^T9LiAAmj*~-5Uad>uJB!5w^eX_23+P)C?r*F
zRxWG+#$86B2~B0mhC?to;o}*NWl{lIP|JW`s=7bafN>1C5HtvI3{jSnbdx;;^OaPp
z%H>n{`R}t>|Ew$~uj266Ttp~w+c&T7B1Vo+yRX`xx{d^{-Zou(!Y4251JWLv9QF@1
zIcGeA1h7<>0VULx$uoi^*PJ)I|Juzg%o8-dpgjfWCSqW>w#Ntulup+%JRgLB+qku^
zPDFx3tT=gMWcHbV|CNDPPV1I`PA>=~)FwDmOtj2#
z=ucGA`#Uu=lK|y>YwXnWGdw{3cyu&I3TA$e#6;=fs=e^q=iS^E5+@u|Zh&t+WB1IR
z=YmA=48Q*Z+pEKH|I`!`+?{<%0EDkW{IQ%((j`h3f;%$Oib=lH7*~wV|8gMWO)RFB
z*>bbQM^gYf&2regbX8h@i^_=dLJ)A~yywyBth=?xX-eb%;E_mE;8(?`n_lq&H=O)DK;>cATtwFjA
zM1IpxdWogh495e4xp`&~!r%yU9rDZzQ0n?P{fyu{`W<~7!OeCs96ng-C`ex;5Qa^$
z68?X=025Mtds4d#y;}?x*+$S6^k*J7rCb42I45zAV&@B=Oa^|BG$z`LRd8|g7|>h-
zj0V65O%s`7Q5>vesVGqH^ZXA=kS7$r@_T>y(Bb69F1ZkXy!WbD;ruFN#S%zjorh0D
zTyijaoo7z`oy|s96BBAD@+*fTSTcF^_xRQw=ZNhVuZsBtt
z2Mix=!hO=TC~#{#YCIU_&qQ8S^-N?!Vp
zRN$Sn;gt@BokC&?MrqMNyGsU7LZK1tuTU0SadLTA5|%kNNkf#7CzqK+P;#N`uwS08
zG6Xq%m&w&{>503n%yA_5w_Xan@b$DgrpqSEz$JJeCDYQD_6)x3uEEq@AIxdMufjN{
zu709wJQE8Gn6hzkAf62M=awrkZxBFo4yNlP&)d_{8+?<`R@LrD$z}SYdTtFdcxICe
z|B}Mj)R`N{R^a9b@X}ZG$ix6w2x{SJjp5~R-P^*Z+7OuJZ_?z9D+W61#>=|M{%ylR
ztBEupU6fjB`sL^v2*t%7SiawYW>spXNu2f`>=<#
z1J{JA#Q~co)s05mgVKqYJ^FAd5TUE
z&hW+bDNz}h(c*y<>X(-8o9Sz!Z=Fal?OMNZ!l_bh6@U}E@n+1u=EzY1NAb*b`(;RZ>x1s
z8d4UUX*Rq>5HTv3XU~dGKza_HauR(#aIGxhx`Q6X3}tCF2i<=?-vGB6j8n-{yTVHQ
zZO+TQzL-|?PWC3->G!{E3Hbjo@0{5m8?6tyisyvaW-_h!XD|tbr0V+juNf5ZKH%x3
zvIpj7(szX9k%;L*Fw-v1!kdJ4MuySzsgRMk@$jVh!ke2(<|~g%*84!s@iWBuccwwx
zZ}e$n=ohtjr;Vuz>@q4taxqQdvSDJB&n~L_oj-nz)+HGb%t|^4-c#;u+{?K<@HON{Io)=3`vk
zA99%NuP@o>M@7vh6{vX0lSfu0A5eEHcJH6ZBXwVmyS!h~=Mob~(^UuN@M_HdNL6@5
zPyVuiiIgE>V@p|xrlEVg`nsK2RTqfFSgQKBlQ}!p>mDadwoA(&
z*5A{J@ASEQ0&QD!pm9SAUC-^OJFf#$nuO%1C%7MmoXg%*Fj_nUifiefoKa9M8Iw
zqA3i#tp1;zNL@NIcQMbmFGRUJ3GdzG^^L@b#cfR5qRiXg@5GOfj|*zod%@866p`o_qsJ`YO76ucL@n3l`-datv9a-ra?7Hk
zz3UH|x0U6~h^J+boh}Bc*BZG64)yxi7$U`d&<@)Lb|}L$z3Db_h8=_RGKzBH31gjo
zlvZHT*|5x}zTNKFyL-}e51!3tdlbXASJ3t0xub4zW7(Lw^x^S^4_vGciJt8SL+-bI
z^aN-kxOU^?xXm5KdGlgZptO}B3{@=H3%fsNIj%9lt@l+7+MWj(S=1iw(&Fib%DJNf
zCdzB0Q)5G3g;|~TW8TJ8&M}SYQk`6cJokb{qPUeer(
znTFSL>l#_qsw~*}OMD!q@){~`#r@|B
zuQ+gz_q#Zs6Y0B{dP*b^4D$E=ckTZz{{OZ5Z)Xlpim`9%4%qJ7zAbmCQ^vf{8_v=P
z|LL2;mg^ls{*61Xye(aa_V4HO}67QuH$t_Ss0!6+8Iu50iC|v2X2;X
zzFQglU)0}XM!yd*tI_nKDvEIpzr{tJCeFAU7Aq>$0!{eVdTNwQ$QcRqho3S9;~qDI
zM9jM2FoDaLJ#(50r)$fv>+K~EUJCkK>mU5xZ&U9Ox=(o@KsVF)93_h+>NX!ZrB50$
zkIhzm@Q20)MYZM0cx>}ml$$kg3tPx6cO703oQ4Jm^y|_^U#Cl~B`>$CY6%REoDweS
z$^8jom%5`{XwS-};3_5*o=0n+>)7{~<=A#lpLqj==0m3OA03nXV7vLI3QTO642e}@
zL>bb0@}U2o9xp732>oA0TI!mVbou0GMHD$vC?iuHZMye(Sl5+OcSq0UT`2@!|-1>fGaA+bD?#{X@?W8dCBF&fEA
zkrLKmOtc2M5A?mTuiH}+i&tZf96$!|wTis?@z;nppe1RpiJ~#)@D&`Pe1^Q9IVm#N
zfL!BpkZVOuWYF*IJq&3*nVl{)y9&LK>O^th%wk6N@e0_8ltY{zHBwSe{5$Y2XT(8o
zb^FE7HlZ=(c+%WU6rRVuWmk;U=eGNHpKFuX^SU3MXTJ5YU|3`BhEu@P4oiK%9^@_%
z!GFZAz;#$a^GlhG?=Nzx?|s?EegFCDbCJK|F{taB^yhZ)kDc+f*X^`FCuGS3=m@Tz
zd+9tE^RpIKDgM8rqv2W5tvgmeqTl-A?(a0z*KV
zl`N%LQ?JdOEAV{#OyDTxjPlK?5Ml`tZMH{xVY%qiP4mrcN0}_)LDz|3at*PXV}mcM
zaZN^wC`eiIXjJA-R$T%>L7l!6eEgm(X!_l$=F17&XOM{FKIH4hQ|Y`sxX|^h-|UM+(wfvb8iAtm1Uh
ztA$D?68XE)l@zy*1k|U(<6rHSiz81e59E#u8~vp#BRwhb+Iycjf7%i@lxb|od?7CX
zFEx+9Hhl`~Gpek`#c?z{>F23bjw=NXNFu~vKiqLQCF5H#W;D|NTbGoXQ*;<83tJ*$
zKJhp!*}HIG5WXgi#)tQUuD9shBZI*%Wom2a~_PUnC#shQr|k0J&q@DPZRk26&Az=_Py~
zyv(?-vb^0tZZ<07DEU}oRv5vxq=-!rdXPlYQ>Y^?tHDzAlP|NYW!-RSq%wfdPr6)<=
z=hl-2d#b*Iw5e58eN02Q3O7Uwd|c@NyKmp#e~Tww%w1@s&@;s{R6l0L
zM`f%l@NOn;dS{trImv0gEbZ#hQgX!7Rb`%kx$HR{hIicbiIcv6W=Z(Hfm>a@^JTR$
zY}W83l9TN6WGu|;^!B!L$?7A=SbJbw5BohW#p#Xklls36Zm7)q7iLT1XG+SSy@IRD
zWEeQitF4X&j4zWm$xF;cln+_C7G)tz$D6#4o%F9S3z~}Y^iE|=jO9g}TGL#L?4ddk
zCc^o8u+GjBDxOAU`25_?t}eW@F9E~%$?)3f1IG0Lm&Bp
zCz;Dqv|SOCPaHPml@%2BePPj$sryT>e{BpYTx0Jwxw2^-ARDO^)n2U$4l4aCi)wTC
zAI_uVpW6Jobp*C6ib
z9|i=?9xAlEffh5iu*?D2E=9?uuyoDN1J$af?
zFuOyuDhi`nakqVEh!FWsPxFKc!>LeyMmc%_BE3U`IKs;##F$wrgnILbi;!RYU(e+Tmdqj@AzCY~lWHF`N
zOhe`_%}TmBy$chobYqV@jqDBf+H8EFdHQlby+);?<6Tcuij8!z4)a~+1n=DMNh!I@%
zn&D2!H}+~JUy>hln5dAWJj`4XwSsIJ{s?wMqD`^dc)!*;|K)&~6JA!7g1C=wi4%8GrCLD41j-
zbpxBP{|W~T!){L2UXs03G2i$Zjlz6=a>}X)-}KFZEL?@TZ---+kTPGvOqsloak;#@
zXGrB5Ha7Ews_bha7CK+W=|)gygpji}z@~
zqkJj&ej;e4#U5>X#P5dKOddRhFhYK^rvXFZR|H=8LlLGLh_8vZ!5L_Y?4PR|^@+s{bLYp&GEa8#D3e+im+X79p1hE@d9VY>8!Kyn|hDX}k
zk^H{_7U;lpDBnYWU*`8Txo?mjhkZuT<${-F{ial5T%pArb>x61f}4?>)jg;Oq5uzR
zUrlC+?LS~BA;1{G%NSr;mOFKRe*%{jdG!D$^l*f!l#mudfgSXwCCNZf**SiVtwz!~
zl`doI1wr2uy7F5~Rd3KUTiByKFd7GW3Gtl=1omhH3bOO&MrB7fi0BKTl^4D|CWx&N
z|KWuQO-|h3*KQC9spkRVwa9pE)_Uyb@t}E2>G4kDGdk}X))*-O`#bRlE;7f)dE-LdNal{vjfE%p9T7!_wB{D
z2uj2piQ{+V6UBo6#SpN?H*)~W1&LYKN7c=VYU$I3i@5=>B4TKaJ@GrRX+9(POtkld`@1bCZ_L1)Us*-!HRtn2HDbW`5A63$
zm{D$`Sa)?~l^%m63hS{bvicL@=%*x^hd<7(ri_KuLV|~&g0&V*0mixHX+0^Eq>~he
z?I=s~h_Q`*2a=xO8pnzn_lOQi%NK;+8^MKhkn|mf2+~(4XPCZ7*!UMXrc_sV^($De
z79_nO5mG|0!@9AMmLsm-rf@8(d-~QZ&
z=tWIpRn)auxVz;miarDjDn^5a88&aoyeZzhXTq3hAuIqb8at3tJPPRGU0eVPpbwOB
zBs8w_d`R!T;D}vPmwZQ{%Y-x4F8G6(IuR1Dcn%`
z!`(E^5pD0ckV70?u;Ra?FjalUW&Pw&kRQ$S7GJ);_Fnb&A|TXhNm)I_e7nO^K{25^
zP#hoy<&4~ZqFI%wV}9?NkPOM4`7Dldx#Ip|A}IMu1YzSx0Cyc8UK+RwRZ`P?TrGj*
zrj3-2w>$Z~^NXX`)U>t$9^ZDRD3}q}%S%4K&|O5IaUiVE@5|K}9Xt7_O4*?TIdWo%
zV1DJQl-rn-n{Hmj(&4~Leefv;u*goDhtz-VCl>{fsx2-gBwpS}&P|g^!;2B~x?q0|
zC)u=_@w|sPaXe_Wv_Kn)yYkT^rye6%PDH<)aQ3MCFPkBJBK?@N?rZ
zo<1B5XRG2)3~SVxevL&wJ45GdP3VtorPmE1w
zXvAr=2GT4}eHBu|Aq?a(VCrd-NkQ{e`1575;RWti1R@noMj3u)5*d-`)))YjCn;h9
z{qI~l(gl`0F3I3}N4o`+-k%PQn5oioQxFQjaPYARCZwp=&<@T1ez|JSBi7&lEHM$UTQ5Y|hfMojS
z{A8v>`Zwe7r#Mcn0~J0Y@IJx|TcHGsNkk6g0z$$b?4CiF+h059YOnil8nfE%c
z8_wVF=