Skip to content

Commit ad3a106

Browse files
authored
fix(cog): update cog containing fix for regex patterns in CRDs (#1314)
## What Changed? Why? Discovered by @bcotton in [slack msg](https://raintank-corp.slack.com/archives/C04RVCAG9B5/p1774968715493699) > It would seem that the grafana-app-sdk v0.5.2 removes the code-generation for regex validation in CRDs — e.g. [this regex](https://github.com/grafana/service-model/blob/main/kinds/common.cue#L5) used [like this](https://github.com/grafana/service-model/blob/main/kinds/domain.cue#L35) is now removing the pattern section from the CRD [like here](https://github.com/grafana/service-model/pull/237/changes#diff-670d330021c6f871837270d20f1ffdca1174bb4640e1cc08e0b8a58bc503c0d3) Applies and tests a change in cog: - grafana/cog#1053 ### How was it tested? Codegen test files
1 parent bf0433f commit ad3a106

File tree

13 files changed

+102
-81
lines changed

13 files changed

+102
-81
lines changed

codegen/cuekind/testing/testkind.cue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ testKind: {
8181
"v1": {
8282
schema: {
8383
spec: {
84-
stringField: string
84+
stringField: string & =~"^[a-zA-Z_][a-zA-Z0-9_-]*$"
8585
}
8686
}
8787
}

codegen/testing/golden_generated/crd/testkind.testapp.ext.grafana.com.json.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"spec": {
1818
"properties": {
1919
"stringField": {
20+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_-]*$",
2021
"type": "string"
2122
}
2223
},

codegen/testing/golden_generated/crd/testkind.testapp.ext.grafana.com.yaml.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ spec:
2323
spec:
2424
properties:
2525
stringField:
26+
pattern: ^[a-zA-Z_][a-zA-Z0-9_-]*$
2627
type: string
2728
required:
2829
- stringField

codegen/testing/golden_generated/go/groupbygroup/manifestdata/testapp_manifest.go.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
)
2323

2424
var (
25-
rawSchemaTestKindv1 = []byte(`{"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":true,"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"TestKind":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"stringField":{"type":"string"}},"required":["stringField"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":true,"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
25+
rawSchemaTestKindv1 = []byte(`{"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":true,"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"TestKind":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"stringField":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_-]*$","type":"string"}},"required":["stringField"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":true,"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
2626
versionSchemaTestKindv1 app.VersionSchema
2727
_ = json.Unmarshal(rawSchemaTestKindv1, &versionSchemaTestKindv1)
2828
rawSchemaTestKind2v1 = []byte(`{"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":true,"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"TestKind2":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"testField":{"type":"string"}},"required":["testField"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":true,"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)

codegen/testing/golden_generated/manifest/test-app-manifest.json.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"spec": {
3030
"properties": {
3131
"stringField": {
32+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_-]*$",
3233
"type": "string"
3334
}
3435
},

codegen/testing/golden_generated/manifest/test-app-manifest.yaml.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ spec:
4747
spec:
4848
properties:
4949
stringField:
50+
pattern: ^[a-zA-Z_][a-zA-Z0-9_-]*$
5051
type: string
5152
required:
5253
- stringField

examples/apiserver/go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ require (
9999
go.uber.org/zap v1.27.1 // indirect
100100
go.yaml.in/yaml/v2 v2.4.3 // indirect
101101
go.yaml.in/yaml/v3 v3.0.4 // indirect
102-
golang.org/x/crypto v0.48.0 // indirect
102+
golang.org/x/crypto v0.49.0 // indirect
103103
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
104-
golang.org/x/net v0.51.0 // indirect
104+
golang.org/x/net v0.52.0 // indirect
105105
golang.org/x/oauth2 v0.35.0 // indirect
106-
golang.org/x/sync v0.19.0 // indirect
107-
golang.org/x/sys v0.41.0 // indirect
108-
golang.org/x/term v0.40.0 // indirect
109-
golang.org/x/text v0.34.0 // indirect
106+
golang.org/x/sync v0.20.0 // indirect
107+
golang.org/x/sys v0.42.0 // indirect
108+
golang.org/x/term v0.41.0 // indirect
109+
golang.org/x/text v0.35.0 // indirect
110110
golang.org/x/time v0.14.0 // indirect
111111
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
112112
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect

examples/apiserver/go.sum

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -263,46 +263,46 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
263263
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
264264
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
265265
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
266-
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
267-
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
266+
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
267+
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
268268
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM=
269269
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
270270
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
271271
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
272-
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
273-
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
272+
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
273+
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
274274
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
275275
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
276276
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
277277
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
278-
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
279-
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
278+
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
279+
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
280280
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
281281
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
282282
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
283283
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
284284
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
285-
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
286-
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
285+
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
286+
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
287287
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
288288
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
289289
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
290-
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
291-
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
292-
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
293-
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
290+
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
291+
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
292+
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
293+
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
294294
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
295295
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
296-
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
297-
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
296+
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
297+
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
298298
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
299299
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
300300
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
301301
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
302302
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
303303
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
304-
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
305-
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
304+
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
305+
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
306306
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
307307
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
308308
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

go.mod

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/emicklei/go-restful/v3 v3.13.0
1717
github.com/getkin/kin-openapi v0.133.0
1818
github.com/grafana/codejen v0.0.4-0.20250428224353-8764ced07770
19-
github.com/grafana/cog v0.0.57
19+
github.com/grafana/cog v0.1.5
2020
github.com/grafana/grafana-app-sdk/logging v0.50.4
2121
github.com/hashicorp/go-multierror v1.1.1
2222
github.com/prometheus/client_golang v1.23.2
@@ -31,8 +31,8 @@ require (
3131
go.opentelemetry.io/otel/sdk v1.40.0
3232
go.opentelemetry.io/otel/trace v1.42.0
3333
go.uber.org/goleak v1.3.0
34-
golang.org/x/sync v0.19.0
35-
golang.org/x/tools v0.42.0
34+
golang.org/x/sync v0.20.0
35+
golang.org/x/tools v0.43.0
3636
gomodules.xyz/jsonpatch/v2 v2.5.0
3737
google.golang.org/grpc v1.79.3
3838
gopkg.in/yaml.v3 v3.0.1
@@ -62,6 +62,7 @@ require (
6262
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
6363
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
6464
github.com/emicklei/proto v1.14.2 // indirect
65+
github.com/fatih/color v1.19.0 // indirect
6566
github.com/felixge/httpsnoop v1.0.4 // indirect
6667
github.com/fsnotify/fsnotify v1.9.0 // indirect
6768
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
@@ -101,6 +102,8 @@ require (
101102
github.com/klauspost/compress v1.18.2 // indirect
102103
github.com/kylelemons/godebug v1.1.0 // indirect
103104
github.com/mailru/easyjson v0.9.1 // indirect
105+
github.com/mattn/go-colorable v0.1.14 // indirect
106+
github.com/mattn/go-isatty v0.0.20 // indirect
104107
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
105108
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
106109
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
@@ -117,7 +120,7 @@ require (
117120
github.com/prometheus/procfs v0.19.2 // indirect
118121
github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b // indirect
119122
github.com/rogpeppe/go-internal v1.14.1 // indirect
120-
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
123+
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
121124
github.com/stoewer/go-strcase v1.3.1 // indirect
122125
github.com/stretchr/objx v0.5.2 // indirect
123126
github.com/ugorji/go/codec v1.2.11 // indirect
@@ -137,14 +140,14 @@ require (
137140
go.uber.org/zap v1.27.1 // indirect
138141
go.yaml.in/yaml/v2 v2.4.3 // indirect
139142
go.yaml.in/yaml/v3 v3.0.4 // indirect
140-
golang.org/x/crypto v0.48.0 // indirect
143+
golang.org/x/crypto v0.49.0 // indirect
141144
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
142-
golang.org/x/mod v0.33.0 // indirect
143-
golang.org/x/net v0.51.0 // indirect
145+
golang.org/x/mod v0.34.0 // indirect
146+
golang.org/x/net v0.52.0 // indirect
144147
golang.org/x/oauth2 v0.35.0 // indirect
145-
golang.org/x/sys v0.41.0 // indirect
146-
golang.org/x/term v0.40.0 // indirect
147-
golang.org/x/text v0.34.0 // indirect
148+
golang.org/x/sys v0.42.0 // indirect
149+
golang.org/x/term v0.41.0 // indirect
150+
golang.org/x/text v0.35.0 // indirect
148151
golang.org/x/time v0.14.0 // indirect
149152
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect
150153
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect

0 commit comments

Comments
 (0)