diff --git a/README.md b/README.md
index 7d97fee5..1280a37c 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
# protovalidate-es
-[Protovalidate][protovalidate] provides standard annotations to validate common constraints on messages and fields, as well as the ability to use [CEL][cel] to write custom constraints. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf.
+[Protovalidate][protovalidate] provides standard annotations to validate common rules on messages and fields, as well as the ability to use [CEL][cel] to write custom rules. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf.
With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules:
diff --git a/packages/protovalidate-testing/expected-failures.yaml b/packages/protovalidate-testing/expected-failures.yaml
index 9e8df5e7..80b84976 100644
--- a/packages/protovalidate-testing/expected-failures.yaml
+++ b/packages/protovalidate-testing/expected-failures.yaml
@@ -1,224 +1,454 @@
-custom_constraints:
+custom_rules:
- compilation/incorrect_type
- # input: [type.googleapis.com/buf.validate.conformance.cases.custom_constraints.IncorrectType]:{a:123}
+ # input: [type.googleapis.com/buf.validate.conformance.cases.custom_rules.IncorrectType]:{a:123}
# want: compilation err: expression incorrectly treats an int32 field as a string
# got: runtime error: RuntimeError: found no matching overload for 'startsWith' applied to '(int, string)'
- compilation/missing_field
- # input: [type.googleapis.com/buf.validate.conformance.cases.custom_constraints.MissingField]:{a:123}
+ # input: [type.googleapis.com/buf.validate.conformance.cases.custom_rules.MissingField]:{a:123}
# want: compilation err: expression references a non-existent field b
- # got: runtime error: RuntimeError: field not found: b in a
+ # got: runtime error: RuntimeError: field not found: b in message buf.validate.conformance.cases.custom_rules.MissingField
kitchen_sink:
- field/embedded/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.KitchenSinkMessage]:{val:{another:{}}}
# want: validation error (14 violations)
- # 1. constraint_id: "bytes.const"
+ # 1. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.another.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 2. constraint_id: "bytes.const"
+ # 2. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 3. constraint_id: "double.in"
+ # 3. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.another.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 4. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 5. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.another.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 6. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 7. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.another.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 8. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 9. rule_id: "required"
+ # message: "value is required"
+ # field: "val.another.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 10. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.another.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 11. rule_id: "required"
+ # message: "value is required"
+ # field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 12. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 13. rule_id: "string.const"
+ # message: "value must equal `abcd`"
+ # field: "val.another.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # 14. rule_id: "string.const"
+ # message: "value must equal `abcd`"
+ # field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # got: validation error (14 violations)
+ # 1. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.another.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 2. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 3. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.another.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 4. constraint_id: "double.in"
+ # 4. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 5. constraint_id: "enum.const"
+ # 5. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.another.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 6. constraint_id: "enum.const"
+ # 6. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 7. constraint_id: "int32.const"
+ # 7. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.another.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 8. constraint_id: "int32.const"
+ # 8. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 9. constraint_id: "required"
+ # 9. rule_id: "required"
# message: "value is required"
# field: "val.another.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 10. constraint_id: "required"
+ # 10. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.another.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 11. constraint_id: "required"
+ # for_key: false
+ # 11. rule_id: "required"
# message: "value is required"
# field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 12. constraint_id: "required"
+ # 12. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 13. constraint_id: "string.const"
+ # for_key: false
+ # 13. rule_id: "string.const"
# message: "value must equal `abcd`"
# field: "val.another.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"another" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # for_key: false
# rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # 14. constraint_id: "string.const"
+ # 14. rule_id: "string.const"
# message: "value must equal `abcd`"
# field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # for_key: false
# rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- field/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.KitchenSinkMessage]:{val:{}}
# want: validation error (7 violations)
- # 1. constraint_id: "bytes.const"
+ # 1. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 2. constraint_id: "double.in"
+ # 2. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 3. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 4. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 5. rule_id: "required"
+ # message: "value is required"
+ # field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 6. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 7. rule_id: "string.const"
+ # message: "value must equal `abcd`"
+ # field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # got: validation error (7 violations)
+ # 1. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 2. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 3. constraint_id: "enum.const"
+ # 3. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 4. constraint_id: "int32.const"
+ # 4. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 5. constraint_id: "required"
+ # 5. rule_id: "required"
# message: "value is required"
# field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 6. constraint_id: "required"
+ # 6. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 7. constraint_id: "string.const"
+ # for_key: false
+ # 7. rule_id: "string.const"
# message: "value must equal `abcd`"
# field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # for_key: false
# rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- field/transitive/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.KitchenSinkMessage]:{val:{const:"abcd" nested:{} bool_const:true}}
# want: validation error (14 violations)
- # 1. constraint_id: "bool.const"
+ # 1. rule_id: "bool.const"
# message: "value must equal false"
# field: "val.bool_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"bool_const" field_type:TYPE_BOOL}
# rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # 2. constraint_id: "bytes.const"
+ # 2. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 3. constraint_id: "bytes.const"
+ # 3. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.nested.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 4. constraint_id: "double.in"
+ # 4. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 5. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.nested.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 6. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 7. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.nested.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 8. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 9. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.nested.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 10. rule_id: "required"
+ # message: "value is required"
+ # field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 11. rule_id: "required"
+ # message: "value is required"
+ # field: "val.nested.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 12. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.nested.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 13. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 14. rule_id: "string.const"
+ # message: "value must equal `abcd`"
+ # field: "val.nested.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # got: validation error (14 violations)
+ # 1. rule_id: "bool.const"
+ # message: "value must equal false"
+ # field: "val.bool_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"bool_const" field_type:TYPE_BOOL}
+ # for_key: false
+ # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
+ # 2. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 3. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.nested.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 4. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 5. constraint_id: "double.in"
+ # 5. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.nested.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 6. constraint_id: "enum.const"
+ # 6. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 7. constraint_id: "enum.const"
+ # 7. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.nested.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 8. constraint_id: "int32.const"
+ # 8. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 9. constraint_id: "int32.const"
+ # 9. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.nested.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 10. constraint_id: "required"
+ # 10. rule_id: "required"
# message: "value is required"
# field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 11. constraint_id: "required"
+ # 11. rule_id: "required"
# message: "value is required"
# field: "val.nested.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 12. constraint_id: "required"
+ # 12. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.nested.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 13. constraint_id: "required"
+ # for_key: false
+ # 13. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 14. constraint_id: "string.const"
+ # for_key: false
+ # 14. rule_id: "string.const"
# message: "value must equal `abcd`"
# field: "val.nested.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # for_key: false
# rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - field/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.KitchenSinkMessage]:{val:{const:"abcd" int_const:5 float_val:{value:1} dur_val:{seconds:3} ts_val:{seconds:17} float_const:7 double_in:123 enum_const:COMPLEX_TEST_ENUM_TWO any_val:{[type.googleapis.com/google.protobuf.Duration]:{}} rep_ts_val:{seconds:3} map_val:{key:-2 value:"b"} map_val:{key:-1 value:"a"} bytes_val:"\x00\x99" x:"foobar"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- many/all-non-message-fields/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.KitchenSinkMessage]:{val:{bool_const:true float_val:{} ts_val:{} float_const:8 any_val:{type_url:"asdf"} rep_ts_val:{nanos:1}}}
# want: validation error (13 violations)
- # 1. constraint_id: "any.in"
+ # 1. rule_id: "any.in"
# message: "type URL must be in the allow list"
# field: "val.any_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:12 field_name:"any_val" field_type:TYPE_MESSAGE}
# rule: "any.in" elements:{field_number:20 field_name:"any" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"in" field_type:TYPE_STRING}
- # 2. constraint_id: "bool.const"
+ # 2. rule_id: "bool.const"
# message: "value must equal false"
# field: "val.bool_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"bool_const" field_type:TYPE_BOOL}
# rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # 3. constraint_id: "bytes.const"
+ # 3. rule_id: "bytes.const"
# message: "value must be 0099"
# field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
# rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # 4. constraint_id: "double.in"
+ # 4. rule_id: "double.in"
+ # message: "value must be in list [456.789, 123]"
+ # field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
+ # 5. rule_id: "enum.const"
+ # message: "value must equal 2"
+ # field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 6. rule_id: "float.gt"
+ # message: "value must be greater than 0"
+ # field: "val.float_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"float_val" field_type:TYPE_MESSAGE}
+ # rule: "float.gt" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"gt" field_type:TYPE_FLOAT}
+ # 7. rule_id: "float.lt"
+ # message: "value must be less than 8"
+ # field: "val.float_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:9 field_name:"float_const" field_type:TYPE_FLOAT}
+ # rule: "float.lt" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"lt" field_type:TYPE_FLOAT}
+ # 8. rule_id: "int32.const"
+ # message: "value must equal 5"
+ # field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
+ # 9. rule_id: "required"
+ # message: "value is required"
+ # field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
+ # 10. rule_id: "required"
+ # message: "exactly one field is required in oneof"
+ # field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
+ # 11. rule_id: "string.const"
+ # message: "value must equal `abcd`"
+ # field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # 12. rule_id: "timestamp.gt"
+ # message: "value must be greater than 1970-01-01T00:00:07Z"
+ # field: "val.ts_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:7 field_name:"ts_val" field_type:TYPE_MESSAGE}
+ # rule: "timestamp.gt" elements:{field_number:22 field_name:"timestamp" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"gt" field_type:TYPE_MESSAGE}
+ # 13. rule_id: "timestamp.gte"
+ # message: "value must be greater than or equal to 1970-01-01T00:00:00.001Z"
+ # field: "val.rep_ts_val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:13 field_name:"rep_ts_val" field_type:TYPE_MESSAGE index:0}
+ # rule: "repeated.items.timestamp.gte" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:22 field_name:"timestamp" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"gte" field_type:TYPE_MESSAGE}
+ # got: validation error (13 violations)
+ # 1. rule_id: "any.in"
+ # message: "type URL must be in the allow list"
+ # field: "val.any_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:12 field_name:"any_val" field_type:TYPE_MESSAGE}
+ # for_key: false
+ # rule: "any.in" elements:{field_number:20 field_name:"any" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"in" field_type:TYPE_STRING}
+ # 2. rule_id: "bool.const"
+ # message: "value must equal false"
+ # field: "val.bool_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"bool_const" field_type:TYPE_BOOL}
+ # for_key: false
+ # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
+ # 3. rule_id: "bytes.const"
+ # message: "value must be 099"
+ # field: "val.bytes_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes_val" field_type:TYPE_BYTES}
+ # for_key: false
+ # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
+ # 4. rule_id: "double.in"
# message: "value must be in list [456.789000, 123.000000]"
# field: "val.double_in" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"double_in" field_type:TYPE_DOUBLE}
+ # for_key: false
# rule: "double.in" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"in" field_type:TYPE_DOUBLE}
- # 5. constraint_id: "enum.const"
+ # 5. rule_id: "enum.const"
# message: "value must equal 2"
# field: "val.enum_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"enum_const" field_type:TYPE_ENUM}
+ # for_key: false
# rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 6. constraint_id: "float.gt"
+ # 6. rule_id: "float.gt"
# message: "value must be greater than 0"
# field: "val.float_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"float_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "float.gt" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"gt" field_type:TYPE_FLOAT}
- # 7. constraint_id: "float.lt"
+ # 7. rule_id: "float.lt"
# message: "value must be less than 8"
# field: "val.float_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:9 field_name:"float_const" field_type:TYPE_FLOAT}
+ # for_key: false
# rule: "float.lt" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"lt" field_type:TYPE_FLOAT}
- # 8. constraint_id: "int32.const"
+ # 8. rule_id: "int32.const"
# message: "value must equal 5"
# field: "val.int_const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:3 field_name:"int_const" field_type:TYPE_INT32}
+ # for_key: false
# rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # 9. constraint_id: "required"
+ # 9. rule_id: "required"
# message: "value is required"
# field: "val.dur_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"dur_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "required" elements:{field_number:25 field_name:"required" field_type:TYPE_BOOL}
- # 10. constraint_id: "required"
+ # 10. rule_id: "required"
# message: "exactly one field is required in oneof"
# field: "val.o" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_name:"o"}
- # 11. constraint_id: "string.const"
+ # for_key: false
+ # 11. rule_id: "string.const"
# message: "value must equal `abcd`"
# field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
+ # for_key: false
# rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # 12. constraint_id: "timestamp.gt"
+ # 12. rule_id: "timestamp.gt"
# message: "value must be greater than 1970-01-01T00:00:07Z"
# field: "val.ts_val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:7 field_name:"ts_val" field_type:TYPE_MESSAGE}
+ # for_key: false
# rule: "timestamp.gt" elements:{field_number:22 field_name:"timestamp" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"gt" field_type:TYPE_MESSAGE}
- # 13. constraint_id: "timestamp.gte"
+ # 13. rule_id: "timestamp.gte"
# message: "value must be greater than or equal to 1970-01-01T00:00:00.001Z"
# field: "val.rep_ts_val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:13 field_name:"rep_ts_val" field_type:TYPE_MESSAGE index:0}
+ # for_key: false
# rule: "repeated.items.timestamp.gte" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:22 field_name:"timestamp" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"gte" field_type:TYPE_MESSAGE}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
-predefined_constraints:
+predefined_rules:
- proto/2023/fixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed32RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed32.even.edition_2023"
+ # 1. rule_id: "fixed32.even.edition_2023"
# message: "fixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED32}
# rule: "fixed32.[buf.validate.conformance.cases.fixed32_even_edition_2023]" elements:{field_number:9 field_name:"fixed32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.fixed32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -230,7 +460,7 @@ predefined_constraints:
- proto/2023/fixed64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed64RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed64.even.edition_2023"
+ # 1. rule_id: "fixed64.even.edition_2023"
# message: "fixed64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED64}
# rule: "fixed64.[buf.validate.conformance.cases.fixed64_even_edition_2023]" elements:{field_number:10 field_name:"fixed64" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.fixed64_even_edition_2023]" field_type:TYPE_BOOL}
@@ -242,7 +472,7 @@ predefined_constraints:
- proto/2023/map/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedMapRuleEdition2023]:{val:{key:1 value:1} val:{key:2 value:2} val:{key:3 value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.at_least_five.edition_2023"
+ # 1. rule_id: "map.at_least_five.edition_2023"
# message: "map must have at least five pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.[buf.validate.conformance.cases.map_at_least_five_edition_2023]" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.map_at_least_five_edition_2023]" field_type:TYPE_BOOL}
@@ -254,23 +484,23 @@ predefined_constraints:
- proto/2023/predefined_and_custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedAndCustomRuleEdition2023]:{a:-1 b:{c:-1}}
# want: validation error (5 violations)
- # 1. constraint_id: "predefined_and_custom_rule_embedded_edition_2023"
+ # 1. rule_id: "predefined_and_custom_rule_embedded_edition_2023"
# message: "b.c must be a multiple of 3"
# field: "b" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 2. constraint_id: "predefined_and_custom_rule_nested_edition_2023"
+ # 2. rule_id: "predefined_and_custom_rule_nested_edition_2023"
# message: "c must be positive"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 3. constraint_id: "predefined_and_custom_rule_scalar_edition_2023"
+ # 3. rule_id: "predefined_and_custom_rule_scalar_edition_2023"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 4. constraint_id: "sint32.even.edition_2023"
+ # 4. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
- # 5. constraint_id: "sint32.even.edition_2023"
+ # 5. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -282,7 +512,7 @@ predefined_constraints:
- proto/2023/repeated/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedBytesRuleEdition2023]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.edition_2023"
+ # 1. rule_id: "bytes.valid_path.edition_2023"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.bytes.[buf.validate.conformance.cases.bytes_valid_path_edition_2023]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.bytes_valid_path_edition_2023]" field_type:TYPE_BOOL}
@@ -290,7 +520,7 @@ predefined_constraints:
- proto/2023/repeated/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedStringRuleEdition2023]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.edition_2023"
+ # 1. rule_id: "string.valid_path.edition_2023"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.string.[buf.validate.conformance.cases.string_valid_path_edition_2023]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.string_valid_path_edition_2023]" field_type:TYPE_BOOL}
@@ -298,7 +528,7 @@ predefined_constraints:
- proto/2023/repeated/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt32RuleEdition2023]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.edition_2023"
+ # 1. rule_id: "uint32.even.edition_2023"
# message: "uint32 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint32.[buf.validate.conformance.cases.uint32_even_edition_2023]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -310,7 +540,7 @@ predefined_constraints:
- proto/2023/repeated/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt64RuleEdition2023]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.edition_2023"
+ # 1. rule_id: "uint64.even.edition_2023"
# message: "uint64 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint64.[buf.validate.conformance.cases.uint64_even_edition_2023]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint64_even_edition_2023]" field_type:TYPE_BOOL}
@@ -322,7 +552,7 @@ predefined_constraints:
- proto/2023/sfixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSFixed32RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sfixed32.even.edition_2023"
+ # 1. rule_id: "sfixed32.even.edition_2023"
# message: "sfixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SFIXED32}
# rule: "sfixed32.[buf.validate.conformance.cases.sfixed32_even_edition_2023]" elements:{field_number:11 field_name:"sfixed32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sfixed32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -334,7 +564,7 @@ predefined_constraints:
- proto/2023/sint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSInt32RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.edition_2023"
+ # 1. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -346,7 +576,7 @@ predefined_constraints:
- proto/2023/standard_predefined_custom/custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleEdition2023]:{a:24}
# want: validation error (1 violation)
- # 1. constraint_id: "standard_predefined_and_custom_rule_scalar_edition_2023"
+ # 1. rule_id: "standard_predefined_and_custom_rule_scalar_edition_2023"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
@@ -354,7 +584,7 @@ predefined_constraints:
- proto/2023/standard_predefined_custom/predefined/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleEdition2023]:{a:27}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.edition_2023"
+ # 1. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -362,7 +592,7 @@ predefined_constraints:
- proto/2023/standard_predefined_custom/standard/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleEdition2023]:{a:28}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.lt"
+ # 1. rule_id: "sint32.lt"
# message: "value must be less than 28"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.lt" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"lt" field_type:TYPE_SINT32}
@@ -374,7 +604,7 @@ predefined_constraints:
- proto/2023/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt32RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.edition_2023"
+ # 1. rule_id: "uint32.even.edition_2023"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT32}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_edition_2023]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -386,7 +616,7 @@ predefined_constraints:
- proto/2023/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt64RuleEdition2023]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.edition_2023"
+ # 1. rule_id: "uint64.even.edition_2023"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT64}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_edition_2023]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint64_even_edition_2023]" field_type:TYPE_BOOL}
@@ -398,7 +628,7 @@ predefined_constraints:
- proto/2023/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedBytesRuleEdition2023]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.edition_2023"
+ # 1. rule_id: "bytes.valid_path.edition_2023"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "bytes.[buf.validate.conformance.cases.bytes_valid_path_edition_2023]" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.bytes_valid_path_edition_2023]" field_type:TYPE_BOOL}
@@ -406,7 +636,7 @@ predefined_constraints:
- proto/2023/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedStringRuleEdition2023]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.edition_2023"
+ # 1. rule_id: "string.valid_path.edition_2023"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "string.[buf.validate.conformance.cases.string_valid_path_edition_2023]" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.string_valid_path_edition_2023]" field_type:TYPE_BOOL}
@@ -414,7 +644,7 @@ predefined_constraints:
- proto/2023/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt32RuleEdition2023]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.edition_2023"
+ # 1. rule_id: "uint32.even.edition_2023"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_edition_2023]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -426,7 +656,7 @@ predefined_constraints:
- proto/2023/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt64RuleEdition2023]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.edition_2023"
+ # 1. rule_id: "uint64.even.edition_2023"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_edition_2023]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.uint64_even_edition_2023]" field_type:TYPE_BOOL}
@@ -438,7 +668,7 @@ predefined_constraints:
- proto2/fixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed32RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed32.even.proto2"
+ # 1. rule_id: "fixed32.even.proto2"
# message: "fixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED32}
# rule: "fixed32.[buf.validate.conformance.cases.fixed32_even_proto2]" elements:{field_number:9 field_name:"fixed32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.fixed32_even_proto2]" field_type:TYPE_BOOL}
@@ -450,7 +680,7 @@ predefined_constraints:
- proto2/fixed64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed64RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed64.even.proto2"
+ # 1. rule_id: "fixed64.even.proto2"
# message: "fixed64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED64}
# rule: "fixed64.[buf.validate.conformance.cases.fixed64_even_proto2]" elements:{field_number:10 field_name:"fixed64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.fixed64_even_proto2]" field_type:TYPE_BOOL}
@@ -462,23 +692,23 @@ predefined_constraints:
- proto2/predefined_and_custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedAndCustomRuleProto2]:{a:-1 b:{c:-1}}
# want: validation error (5 violations)
- # 1. constraint_id: "predefined_and_custom_rule_embedded_proto2"
+ # 1. rule_id: "predefined_and_custom_rule_embedded_proto2"
# message: "b.c must be a multiple of 3"
# field: "b" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 2. constraint_id: "predefined_and_custom_rule_nested_proto2"
+ # 2. rule_id: "predefined_and_custom_rule_nested_proto2"
# message: "c must be positive"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 3. constraint_id: "predefined_and_custom_rule_scalar_proto2"
+ # 3. rule_id: "predefined_and_custom_rule_scalar_proto2"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 4. constraint_id: "sint32.even.proto2"
+ # 4. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
- # 5. constraint_id: "sint32.even.proto2"
+ # 5. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
@@ -490,7 +720,7 @@ predefined_constraints:
- proto2/repeated/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedBytesRuleProto2]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.proto2"
+ # 1. rule_id: "bytes.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.bytes.[buf.validate.conformance.cases.bytes_valid_path_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.bytes_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -498,7 +728,7 @@ predefined_constraints:
- proto2/repeated/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedStringRuleProto2]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.proto2"
+ # 1. rule_id: "string.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.string.[buf.validate.conformance.cases.string_valid_path_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.string_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -506,7 +736,7 @@ predefined_constraints:
- proto2/repeated/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt32RuleProto2]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -518,7 +748,7 @@ predefined_constraints:
- proto2/repeated/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt64RuleProto2]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -530,7 +760,7 @@ predefined_constraints:
- proto2/sfixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSFixed32RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sfixed32.even.proto2"
+ # 1. rule_id: "sfixed32.even.proto2"
# message: "sfixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SFIXED32}
# rule: "sfixed32.[buf.validate.conformance.cases.sfixed32_even_proto2]" elements:{field_number:11 field_name:"sfixed32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sfixed32_even_proto2]" field_type:TYPE_BOOL}
@@ -542,7 +772,7 @@ predefined_constraints:
- proto2/sint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSInt32RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.proto2"
+ # 1. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
@@ -554,7 +784,7 @@ predefined_constraints:
- proto2/standard_predefined_custom/custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto2]:{a:24}
# want: validation error (1 violation)
- # 1. constraint_id: "standard_predefined_and_custom_rule_scalar_proto2"
+ # 1. rule_id: "standard_predefined_and_custom_rule_scalar_proto2"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
@@ -562,7 +792,7 @@ predefined_constraints:
- proto2/standard_predefined_custom/predefined/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto2]:{a:27}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.proto2"
+ # 1. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
@@ -570,7 +800,7 @@ predefined_constraints:
- proto2/standard_predefined_custom/standard/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto2]:{a:28}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.lt"
+ # 1. rule_id: "sint32.lt"
# message: "value must be less than 28"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.lt" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"lt" field_type:TYPE_SINT32}
@@ -582,7 +812,7 @@ predefined_constraints:
- proto2/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt32RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT32}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -594,7 +824,7 @@ predefined_constraints:
- proto2/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt64RuleProto2]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT64}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -606,7 +836,7 @@ predefined_constraints:
- proto2/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedBytesRuleProto2]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.proto2"
+ # 1. rule_id: "bytes.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "bytes.[buf.validate.conformance.cases.bytes_valid_path_proto2]" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.bytes_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -614,7 +844,7 @@ predefined_constraints:
- proto2/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedStringRuleProto2]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.proto2"
+ # 1. rule_id: "string.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "string.[buf.validate.conformance.cases.string_valid_path_proto2]" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.string_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -622,7 +852,7 @@ predefined_constraints:
- proto2/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt32RuleProto2]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -634,7 +864,7 @@ predefined_constraints:
- proto2/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt64RuleProto2]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -646,7 +876,7 @@ predefined_constraints:
- proto3/fixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed32RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed32.even.proto2"
+ # 1. rule_id: "fixed32.even.proto2"
# message: "fixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED32}
# rule: "fixed32.[buf.validate.conformance.cases.fixed32_even_proto2]" elements:{field_number:9 field_name:"fixed32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.fixed32_even_proto2]" field_type:TYPE_BOOL}
@@ -658,7 +888,7 @@ predefined_constraints:
- proto3/fixed64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedFixed64RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "fixed64.even.proto2"
+ # 1. rule_id: "fixed64.even.proto2"
# message: "fixed64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED64}
# rule: "fixed64.[buf.validate.conformance.cases.fixed64_even_proto2]" elements:{field_number:10 field_name:"fixed64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.fixed64_even_proto2]" field_type:TYPE_BOOL}
@@ -670,7 +900,7 @@ predefined_constraints:
- proto3/map/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedMapRuleProto3]:{val:{key:1 value:1} val:{key:2 value:2} val:{key:3 value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.at_least_five.edition_2023"
+ # 1. rule_id: "map.at_least_five.edition_2023"
# message: "map must have at least five pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.[buf.validate.conformance.cases.map_at_least_five_edition_2023]" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.map_at_least_five_edition_2023]" field_type:TYPE_BOOL}
@@ -682,23 +912,23 @@ predefined_constraints:
- proto3/predefined_and_custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedAndCustomRuleProto3]:{a:-1 b:{c:-1}}
# want: validation error (5 violations)
- # 1. constraint_id: "predefined_and_custom_rule_embedded_proto3"
+ # 1. rule_id: "predefined_and_custom_rule_embedded_proto3"
# message: "b.c must be a multiple of 3"
# field: "b" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 2. constraint_id: "predefined_and_custom_rule_nested_proto3"
+ # 2. rule_id: "predefined_and_custom_rule_nested_proto3"
# message: "c must be positive"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 3. constraint_id: "predefined_and_custom_rule_scalar_proto3"
+ # 3. rule_id: "predefined_and_custom_rule_scalar_proto3"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
- # 4. constraint_id: "sint32.even.edition_2023"
+ # 4. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
- # 5. constraint_id: "sint32.even.edition_2023"
+ # 5. rule_id: "sint32.even.edition_2023"
# message: "sint32 value is not even"
# field: "b.c" elements:{field_number:2 field_name:"b" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"c" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_edition_2023]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1162 field_name:"[buf.validate.conformance.cases.sint32_even_edition_2023]" field_type:TYPE_BOOL}
@@ -710,7 +940,7 @@ predefined_constraints:
- proto3/repeated/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedBytesRuleProto3]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.proto2"
+ # 1. rule_id: "bytes.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.bytes.[buf.validate.conformance.cases.bytes_valid_path_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.bytes_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -718,7 +948,7 @@ predefined_constraints:
- proto3/repeated/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedStringRuleProto3]:{val:{value:"valid/file.proto"} val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.proto2"
+ # 1. rule_id: "string.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.string.[buf.validate.conformance.cases.string_valid_path_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.string_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -726,7 +956,7 @@ predefined_constraints:
- proto3/repeated/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt32RuleProto3]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -738,7 +968,7 @@ predefined_constraints:
- proto3/repeated/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedRepeatedWrappedUInt64RuleProto3]:{val:{value:2} val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val[1]" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE index:1}
# rule: "repeated.items.uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -750,7 +980,7 @@ predefined_constraints:
- proto3/sfixed32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSFixed32RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sfixed32.even.proto2"
+ # 1. rule_id: "sfixed32.even.proto2"
# message: "sfixed32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SFIXED32}
# rule: "sfixed32.[buf.validate.conformance.cases.sfixed32_even_proto2]" elements:{field_number:11 field_name:"sfixed32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sfixed32_even_proto2]" field_type:TYPE_BOOL}
@@ -762,7 +992,7 @@ predefined_constraints:
- proto3/sint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedSInt32RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.proto2"
+ # 1. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
@@ -774,7 +1004,7 @@ predefined_constraints:
- proto3/standard_predefined_custom/custom/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto3]:{a:24}
# want: validation error (1 violation)
- # 1. constraint_id: "standard_predefined_and_custom_rule_scalar_proto3"
+ # 1. rule_id: "standard_predefined_and_custom_rule_scalar_proto3"
# message: "a must be greater than 24"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "cel[0]" elements:{field_number:23 field_name:"cel" field_type:TYPE_MESSAGE index:0}
@@ -782,7 +1012,7 @@ predefined_constraints:
- proto3/standard_predefined_custom/predefined/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto3]:{a:27}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.even.proto2"
+ # 1. rule_id: "sint32.even.proto2"
# message: "sint32 value is not even"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.[buf.validate.conformance.cases.sint32_even_proto2]" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.sint32_even_proto2]" field_type:TYPE_BOOL}
@@ -790,7 +1020,7 @@ predefined_constraints:
- proto3/standard_predefined_custom/standard/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.StandardPredefinedAndCustomRuleProto3]:{a:28}
# want: validation error (1 violation)
- # 1. constraint_id: "sint32.lt"
+ # 1. rule_id: "sint32.lt"
# message: "value must be less than 28"
# field: "a" elements:{field_number:1 field_name:"a" field_type:TYPE_SINT32}
# rule: "sint32.lt" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"lt" field_type:TYPE_SINT32}
@@ -802,7 +1032,7 @@ predefined_constraints:
- proto3/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt32RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT32}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -814,7 +1044,7 @@ predefined_constraints:
- proto3/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedUInt64RuleProto3]:{val:3}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT64}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -826,7 +1056,7 @@ predefined_constraints:
- proto3/wrapped/bytes/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedBytesRuleProto3]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.valid_path.proto2"
+ # 1. rule_id: "bytes.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "bytes.[buf.validate.conformance.cases.bytes_valid_path_proto2]" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.bytes_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -834,7 +1064,7 @@ predefined_constraints:
- proto3/wrapped/string/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedStringRuleProto3]:{val:{value:"../invalid/path"}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.valid_path.proto2"
+ # 1. rule_id: "string.valid_path.proto2"
# message: "not a valid path: `../invalid/path`"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "string.[buf.validate.conformance.cases.string_valid_path_proto2]" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.string_valid_path_proto2]" field_type:TYPE_BOOL}
@@ -842,7 +1072,7 @@ predefined_constraints:
- proto3/wrapped/uint32/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt32RuleProto3]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint32.even.proto2"
+ # 1. rule_id: "uint32.even.proto2"
# message: "uint32 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint32.[buf.validate.conformance.cases.uint32_even_proto2]" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint32_even_proto2]" field_type:TYPE_BOOL}
@@ -854,7 +1084,7 @@ predefined_constraints:
- proto3/wrapped/uint64/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt64RuleProto3]:{val:{value:3}}
# want: validation error (1 violation)
- # 1. constraint_id: "uint64.even.proto2"
+ # 1. rule_id: "uint64.even.proto2"
# message: "uint64 value is not even"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "uint64.[buf.validate.conformance.cases.uint64_even_proto2]" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1161 field_name:"[buf.validate.conformance.cases.uint64_even_proto2]" field_type:TYPE_BOOL}
@@ -863,45 +1093,11 @@ predefined_constraints:
# input: [type.googleapis.com/buf.validate.conformance.cases.PredefinedWrappedUInt64RuleProto3]:{val:{value:2}}
# want: valid
# got: runtime error: RuntimeError: found no matching overload for '_%_' applied to '(wrapper(uint), uint)'
-standard_constraints/bool:
- - const/false/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BoolConstFalse]:{val:true}
- # want: validation error (1 violation)
- # 1. constraint_id: "bool.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BOOL}
- # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - const/false/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BoolConstFalse]:{}
- # want: valid
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - const/true/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BoolConstTrue]:{}
- # want: validation error (1 violation)
- # 1. constraint_id: "bool.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BOOL}
- # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - const/true/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BoolConstTrue]:{val:true}
- # want: valid
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
-standard_constraints/bytes:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BytesConst]:{val:"bar"}
- # want: validation error (1 violation)
- # 1. constraint_id: "bytes.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
- # rule: "bytes.const" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BYTES}
- # got: compilation err: CompilationError: failed to compile bytes.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.BytesConst]:{val:"foo"}
- # want: valid
- # got: compilation err: CompilationError: failed to compile bytes.const: parse error: :1:15: reserved identifier
+standard_rules/bytes:
- contains/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.BytesContains]:{val:"candy bazs"}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.contains"
+ # 1. rule_id: "bytes.contains"
# message: "value does not contain 626172"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
# rule: "bytes.contains" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:7 field_name:"contains" field_type:TYPE_BYTES}
@@ -917,7 +1113,7 @@ standard_constraints/bytes:
- prefix/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.BytesPrefix]:{val:"bar"}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.prefix"
+ # 1. rule_id: "bytes.prefix"
# message: "value does not have prefix 99"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
# rule: "bytes.prefix" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:5 field_name:"prefix" field_type:TYPE_BYTES}
@@ -933,7 +1129,7 @@ standard_constraints/bytes:
- suffix/case_sensitive/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.BytesSuffix]:{val:"FooBaz"}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.suffix"
+ # 1. rule_id: "bytes.suffix"
# message: "value does not have suffix 62757a7a"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
# rule: "bytes.suffix" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"suffix" field_type:TYPE_BYTES}
@@ -941,7 +1137,7 @@ standard_constraints/bytes:
- suffix/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.BytesSuffix]:{val:"foobar"}
# want: validation error (1 violation)
- # 1. constraint_id: "bytes.suffix"
+ # 1. rule_id: "bytes.suffix"
# message: "value does not have suffix 62757a7a"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_BYTES}
# rule: "bytes.suffix" elements:{field_number:15 field_name:"bytes" field_type:TYPE_MESSAGE} elements:{field_number:6 field_name:"suffix" field_type:TYPE_BYTES}
@@ -954,96 +1150,11 @@ standard_constraints/bytes:
# input: [type.googleapis.com/buf.validate.conformance.cases.BytesSuffix]:{val:"buzz"}
# want: valid
# got: runtime error: RuntimeError: found no matching overload for 'endsWith' applied to '(bytes, bytes)'
-standard_constraints/double:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.DoubleConst]:{val:4.56}
- # want: validation error (1 violation)
- # 1. constraint_id: "double.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_DOUBLE}
- # rule: "double.const" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_DOUBLE}
- # got: compilation err: CompilationError: failed to compile double.const: parse error: :1:15: reserved identifier
- - const/invalid_nan
- # input: [type.googleapis.com/buf.validate.conformance.cases.DoubleConst]:{val:nan}
- # want: validation error (1 violation)
- # 1. constraint_id: "double.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_DOUBLE}
- # rule: "double.const" elements:{field_number:2 field_name:"double" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_DOUBLE}
- # got: compilation err: CompilationError: failed to compile double.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.DoubleConst]:{val:1.23}
- # want: valid
- # got: compilation err: CompilationError: failed to compile double.const: parse error: :1:15: reserved identifier
-standard_constraints/enum:
- - alias/const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.EnumAliasConst]:{val:TEST_ENUM_ALIAS_C}
- # want: validation error (1 violation)
- # 1. constraint_id: "enum.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_ENUM}
- # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # got: compilation err: CompilationError: failed to compile enum.const: parse error: :1:15: reserved identifier
- - alias/const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.EnumAliasConst]:{val:TEST_ENUM_ALIAS_B}
- # want: valid
- # got: compilation err: CompilationError: failed to compile enum.const: parse error: :1:15: reserved identifier
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.EnumConst]:{val:TEST_ENUM_ONE}
- # want: validation error (1 violation)
- # 1. constraint_id: "enum.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_ENUM}
- # rule: "enum.const" elements:{field_number:16 field_name:"enum" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # got: compilation err: CompilationError: failed to compile enum.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.EnumConst]:{val:TEST_ENUM_TWO}
- # want: valid
- # got: compilation err: CompilationError: failed to compile enum.const: parse error: :1:15: reserved identifier
-standard_constraints/fixed32:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Fixed32Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "fixed32.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED32}
- # rule: "fixed32.const" elements:{field_number:9 field_name:"fixed32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_FIXED32}
- # got: compilation err: CompilationError: failed to compile fixed32.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Fixed32Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile fixed32.const: parse error: :1:15: reserved identifier
-standard_constraints/fixed64:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Fixed64Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "fixed64.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FIXED64}
- # rule: "fixed64.const" elements:{field_number:10 field_name:"fixed64" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_FIXED64}
- # got: compilation err: CompilationError: failed to compile fixed64.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Fixed64Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile fixed64.const: parse error: :1:15: reserved identifier
-standard_constraints/float:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.FloatConst]:{val:4.56}
- # want: validation error (1 violation)
- # 1. constraint_id: "float.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FLOAT}
- # rule: "float.const" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_FLOAT}
- # got: compilation err: CompilationError: failed to compile float.const: parse error: :1:15: reserved identifier
- - const/nan
- # input: [type.googleapis.com/buf.validate.conformance.cases.FloatConst]:{val:nan}
- # want: validation error (1 violation)
- # 1. constraint_id: "float.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_FLOAT}
- # rule: "float.const" elements:{field_number:1 field_name:"float" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_FLOAT}
- # got: compilation err: CompilationError: failed to compile float.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.FloatConst]:{val:1.23}
- # want: valid
- # got: compilation err: CompilationError: failed to compile float.const: parse error: :1:15: reserved identifier
-standard_constraints/ignore:
+standard_rules/ignore:
- proto/2023/map/ignore_default/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.EditionsMapIgnoreDefault]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1054,7 +1165,7 @@ standard_constraints/ignore:
- proto/2023/map/ignore_empty/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.EditionsMapIgnoreEmpty]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1065,7 +1176,7 @@ standard_constraints/ignore:
- proto/2023/map/ignore_unspecified/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.EditionsMapIgnoreUnspecified]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1076,7 +1187,7 @@ standard_constraints/ignore:
- proto2/map/ignore_default/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto2MapIgnoreDefault]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1087,7 +1198,7 @@ standard_constraints/ignore:
- proto2/map/ignore_empty/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto2MapIgnoreEmpty]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1098,7 +1209,7 @@ standard_constraints/ignore:
- proto2/map/ignore_unspecified/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto2MapIgnoreUnspecified]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1109,7 +1220,7 @@ standard_constraints/ignore:
- proto3/map/ignore_default/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto3MapIgnoreDefault]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1120,7 +1231,7 @@ standard_constraints/ignore:
- proto3/map/ignore_empty/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto3MapIgnoreEmpty]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1131,7 +1242,7 @@ standard_constraints/ignore:
- proto3/map/ignore_unspecified/invalid/populated
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto3MapIgnoreUnspecified]:{val:{key:1 value:1}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1139,11 +1250,11 @@ standard_constraints/ignore:
# input: [type.googleapis.com/buf.validate.conformance.cases.Proto3MapIgnoreUnspecified]:{val:{key:1 value:1} val:{key:2 value:2} val:{key:3 value:3}}
# want: valid
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
-standard_constraints/ignore_empty:
+standard_rules/ignore_empty:
- proto/2023/map/nonempty/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.IgnoreEmptyEditionsMap]:{val:{key:0 value:0}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1154,7 +1265,7 @@ standard_constraints/ignore_empty:
- proto2/map/nonempty/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.IgnoreEmptyProto2Map]:{val:{key:0 value:0}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1165,7 +1276,7 @@ standard_constraints/ignore_empty:
- proto3/map/nonempty/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.IgnoreEmptyProto3Map]:{val:{key:0 value:0}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
@@ -1173,39 +1284,11 @@ standard_constraints/ignore_empty:
# input: [type.googleapis.com/buf.validate.conformance.cases.IgnoreEmptyProto3Map]:{val:{key:1 value:2} val:{key:3 value:4} val:{key:5 value:6}}
# want: valid
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
-standard_constraints/int32:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Int32Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "int32.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_INT32}
- # rule: "int32.const" elements:{field_number:3 field_name:"int32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT32}
- # got: compilation err: CompilationError: failed to compile int32.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Int32Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile int32.const: parse error: :1:15: reserved identifier
-standard_constraints/int64:
- - big_constraints/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Int64BigConstraints]:{lt_pos:-5666777888 lt_neg:-5666777888 gt_pos:5666777888 gt_neg:5666777888 lte_pos:-5666777888 lte_neg:-5666777888 gte_pos:5666777888 gte_neg:5666777888 constant_pos:5444333222 constant_neg:-5444333222 in:5444333222 notin:5666777888}
- # want: valid
- # got: compilation err: CompilationError: failed to compile int64.const: parse error: :1:15: reserved identifier
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Int64Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "int64.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_INT64}
- # rule: "int64.const" elements:{field_number:4 field_name:"int64" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_INT64}
- # got: compilation err: CompilationError: failed to compile int64.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Int64Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile int64.const: parse error: :1:15: reserved identifier
-standard_constraints/map:
+standard_rules/map:
- exact/above/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.MapExact]:{val:{key:1 value:"a"} val:{key:2 value:"b"} val:{key:3 value:"c"} val:{key:4 value:"d"}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.max_pairs"
+ # 1. rule_id: "map.max_pairs"
# message: "map must be at most 3 entries"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.max_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"max_pairs" field_type:TYPE_UINT64}
@@ -1213,7 +1296,7 @@ standard_constraints/map:
- exact/below/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.MapExact]:{val:{key:1 value:"a"} val:{key:2 value:"b"}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# message: "map must be at least 3 entries"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
@@ -1229,7 +1312,7 @@ standard_constraints/map:
- max_pairs/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.MapMax]:{val:{key:1 value:2} val:{key:3 value:4} val:{key:5 value:6} val:{key:7 value:8}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.max_pairs"
+ # 1. rule_id: "map.max_pairs"
# message: "map must be at most 3 entries"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.max_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"max_pairs" field_type:TYPE_UINT64}
@@ -1241,7 +1324,7 @@ standard_constraints/map:
- min/max/above/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.MapMinMax]:{val:{key:"a" value:true} val:{key:"b" value:false} val:{key:"c" value:true} val:{key:"d" value:false} val:{key:"e" value:true}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.max_pairs"
+ # 1. rule_id: "map.max_pairs"
# message: "map must be at most 4 entries"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.max_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"max_pairs" field_type:TYPE_UINT64}
@@ -1265,7 +1348,7 @@ standard_constraints/map:
- min_pairs/invalid
# input: [type.googleapis.com/buf.validate.conformance.cases.MapMin]:{val:{key:1 value:2}}
# want: validation error (1 violation)
- # 1. constraint_id: "map.min_pairs"
+ # 1. rule_id: "map.min_pairs"
# message: "map must be at least 2 entries"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
# rule: "map.min_pairs" elements:{field_number:19 field_name:"map" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"min_pairs" field_type:TYPE_UINT64}
@@ -1274,197 +1357,57 @@ standard_constraints/map:
# input: [type.googleapis.com/buf.validate.conformance.cases.MapMin]:{val:{key:1 value:2} val:{key:3 value:4} val:{key:5 value:6}}
# want: valid
# got: runtime error: RuntimeError: found no matching overload for 'size' applied to '(map)'
-standard_constraints/message:
- - field/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Message]:{val:{}}
- # want: validation error (1 violation)
- # 1. constraint_id: "string.const"
- # message: "value must equal `foo`"
- # field: "val.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - field/transitive/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Message]:{val:{const:"foo" nested:{}}}
- # want: validation error (1 violation)
- # 1. constraint_id: "string.const"
- # message: "value must equal `foo`"
- # field: "val.nested.const" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"nested" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - field/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Message]:{val:{const:"foo"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - optional/required/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.MessageRequiredButOptional]:{val:{const:"foo"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - required/oneof/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.MessageRequiredOneof]:{val:{const:"foo"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - required/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.MessageRequired]:{val:{const:"foo"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
-standard_constraints/oneof:
- - field/Z/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Oneof]:{z:{val:true}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - filed/Z/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.Oneof]:{z:{}}
- # want: validation error (1 violation)
- # 1. constraint_id: "bool.const"
- # field: "z.val" elements:{field_number:3 field_name:"z" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"val" field_type:TYPE_BOOL}
- # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
-standard_constraints/repeated:
-standard_constraints/sfixed32:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SFixed32Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "sfixed32.const"
- # message: "value must equal 1"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SFIXED32}
- # rule: "sfixed32.const" elements:{field_number:11 field_name:"sfixed32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_SFIXED32}
- # got: compilation err: CompilationError: failed to compile sfixed32.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SFixed32Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile sfixed32.const: parse error: :1:15: reserved identifier
-standard_constraints/sfixed64:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SFixed64Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "sfixed64.const"
- # message: "value must equal 1"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SFIXED64}
- # rule: "sfixed64.const" elements:{field_number:12 field_name:"sfixed64" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_SFIXED64}
- # got: compilation err: CompilationError: failed to compile sfixed64.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SFixed64Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile sfixed64.const: parse error: :1:15: reserved identifier
-standard_constraints/sint32:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SInt32Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "sint32.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SINT32}
- # rule: "sint32.const" elements:{field_number:7 field_name:"sint32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_SINT32}
- # got: compilation err: CompilationError: failed to compile sint32.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SInt32Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile sint32.const: parse error: :1:15: reserved identifier
-standard_constraints/sint64:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SInt64Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "sint64.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_SINT64}
- # rule: "sint64.const" elements:{field_number:8 field_name:"sint64" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_SINT64}
- # got: compilation err: CompilationError: failed to compile sint64.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.SInt64Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile sint64.const: parse error: :1:15: reserved identifier
-standard_constraints/string:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.StringConst]:{val:"bar"}
- # want: validation error (1 violation)
- # 1. constraint_id: "string.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_STRING}
- # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.StringConst]:{val:"foo"}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
-standard_constraints/uint32:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.UInt32Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "uint32.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT32}
- # rule: "uint32.const" elements:{field_number:5 field_name:"uint32" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_UINT32}
- # got: compilation err: CompilationError: failed to compile uint32.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.UInt32Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile uint32.const: parse error: :1:15: reserved identifier
-standard_constraints/uint64:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.UInt64Const]:{val:2}
- # want: validation error (1 violation)
- # 1. constraint_id: "uint64.const"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_UINT64}
- # rule: "uint64.const" elements:{field_number:6 field_name:"uint64" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_UINT64}
- # got: compilation err: CompilationError: failed to compile uint64.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.UInt64Const]:{val:1}
- # want: valid
- # got: compilation err: CompilationError: failed to compile uint64.const: parse error: :1:15: reserved identifier
-standard_constraints/well_known_types/duration:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.DurationConst]:{val:{nanos:3}}
- # want: validation error (1 violation)
- # 1. constraint_id: "duration.const"
- # message: "value must equal 3s"
- # field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
- # rule: "duration.const" elements:{field_number:21 field_name:"duration" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"const" field_type:TYPE_MESSAGE}
- # got: compilation err: CompilationError: failed to compile duration.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.DurationConst]:{val:{seconds:3}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile duration.const: parse error: :1:15: reserved identifier
-standard_constraints/well_known_types/timestamp:
- - const/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.TimestampConst]:{val:{nanos:3}}
- # want: validation error (1 violation)
- # 1. constraint_id: "timestamp.const"
+standard_rules/repeated:
+ - items/in/invalid
+ # input: [type.googleapis.com/buf.validate.conformance.cases.RepeatedItemIn]:{val:"baz"}
+ # want: validation error (1 violation)
+ # 1. rule_id: "string.in"
+ # message: "value must be in list [foo, bar]"
+ # field: "val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_STRING index:0}
+ # rule: "repeated.items.string.in" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"in" field_type:TYPE_STRING}
+ # got: validation error (1 violation)
+ # 1. rule_id: "string.in"
+ # message: "value must be in list [\"foo\", \"bar\"]"
+ # field: "val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_STRING index:0}
+ # for_key: false
+ # rule: "repeated.items.string.in" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:10 field_name:"in" field_type:TYPE_STRING}
+ - items/not_in/invalid
+ # input: [type.googleapis.com/buf.validate.conformance.cases.RepeatedItemNotIn]:{val:"foo"}
+ # want: validation error (1 violation)
+ # 1. rule_id: "string.not_in"
+ # message: "value must not be in list [foo, bar]"
+ # field: "val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_STRING index:0}
+ # rule: "repeated.items.string.not_in" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"not_in" field_type:TYPE_STRING}
+ # got: validation error (1 violation)
+ # 1. rule_id: "string.not_in"
+ # message: "value must not be in list [\"foo\", \"bar\"]"
+ # field: "val[0]" elements:{field_number:1 field_name:"val" field_type:TYPE_STRING index:0}
+ # for_key: false
+ # rule: "repeated.items.string.not_in" elements:{field_number:18 field_name:"repeated" field_type:TYPE_MESSAGE} elements:{field_number:4 field_name:"items" field_type:TYPE_MESSAGE} elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:11 field_name:"not_in" field_type:TYPE_STRING}
+standard_rules/well_known_types/duration:
+ - in/invalid
+ # input: [type.googleapis.com/buf.validate.conformance.cases.DurationIn]:{val:{}}
+ # want: validation error (1 violation)
+ # 1. rule_id: "duration.in"
+ # message: "value must be in list [1s, 0.000001s]"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
- # rule: "timestamp.const" elements:{field_number:22 field_name:"timestamp" field_type:TYPE_MESSAGE} elements:{field_number:2 field_name:"const" field_type:TYPE_MESSAGE}
- # got: compilation err: CompilationError: failed to compile timestamp.const: parse error: :1:15: reserved identifier
- - const/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.TimestampConst]:{val:{seconds:3}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile timestamp.const: parse error: :1:15: reserved identifier
-standard_constraints/well_known_types/wrapper:
- - bool/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperBool]:{val:{}}
- # want: validation error (1 violation)
- # 1. constraint_id: "bool.const"
- # message: "value must equal true"
+ # rule: "duration.in" elements:{field_number:21 field_name:"duration" field_type:TYPE_MESSAGE} elements:{field_number:7 field_name:"in" field_type:TYPE_MESSAGE}
+ # got: validation error (1 violation)
+ # 1. rule_id: "duration.in"
+ # message: "value must be in list [duration(\"1s\"), duration(\"0.000001s\")]"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
- # rule: "bool.const" elements:{field_number:13 field_name:"bool" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_BOOL}
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - bool/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperBool]:{val:{value:true}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile bool.const: parse error: :1:15: reserved identifier
- - required/empty/string/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperRequiredEmptyString]:{val:{value:"foo"}}
+ # for_key: false
+ # rule: "duration.in" elements:{field_number:21 field_name:"duration" field_type:TYPE_MESSAGE} elements:{field_number:7 field_name:"in" field_type:TYPE_MESSAGE}
+ - not in/invalid
+ # input: [type.googleapis.com/buf.validate.conformance.cases.DurationNotIn]:{val:{}}
# want: validation error (1 violation)
- # 1. constraint_id: "string.const"
- # message: "value must equal ``"
+ # 1. rule_id: "duration.not_in"
+ # message: "value must not be in list [0s]"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
- # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - required/empty/string/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperRequiredEmptyString]:{val:{}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - required/string/invalid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperRequiredString]:{val:{value:"foo"}}
- # want: validation error (1 violation)
- # 1. constraint_id: "string.const"
- # message: "value must equal `bar`"
+ # rule: "duration.not_in" elements:{field_number:21 field_name:"duration" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"not_in" field_type:TYPE_MESSAGE}
+ # got: validation error (1 violation)
+ # 1. rule_id: "duration.not_in"
+ # message: "value must not be in list [duration(\"0s\")]"
# field: "val" elements:{field_number:1 field_name:"val" field_type:TYPE_MESSAGE}
- # rule: "string.const" elements:{field_number:14 field_name:"string" field_type:TYPE_MESSAGE} elements:{field_number:1 field_name:"const" field_type:TYPE_STRING}
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
- - required/string/valid
- # input: [type.googleapis.com/buf.validate.conformance.cases.WrapperRequiredString]:{val:{value:"bar"}}
- # want: valid
- # got: compilation err: CompilationError: failed to compile string.const: parse error: :1:15: reserved identifier
+ # for_key: false
+ # rule: "duration.not_in" elements:{field_number:21 field_name:"duration" field_type:TYPE_MESSAGE} elements:{field_number:8 field_name:"not_in" field_type:TYPE_MESSAGE}
diff --git a/packages/protovalidate-testing/package.json b/packages/protovalidate-testing/package.json
index bb6adf4f..aca7eac7 100644
--- a/packages/protovalidate-testing/package.json
+++ b/packages/protovalidate-testing/package.json
@@ -6,7 +6,7 @@
},
"scripts": {
"install-protovalidate-conformance": "node scripts/install-protovalidate-conformance.js",
- "generate": "buf generate buf.build/bufbuild/protovalidate-testing:v0.10.4",
+ "generate": "buf generate buf.build/bufbuild/protovalidate-testing:v0.11.0",
"postgenerate": "license-header src/gen",
"test": "protovalidate-conformance --strict_message --strict_error --expected_failures=expected-failures.yaml -- tsx src/executor.ts",
"format": "prettier --write --ignore-unknown '.' '!dist' '!src/gen'",
diff --git a/packages/protovalidate-testing/scripts/failure-list.js b/packages/protovalidate-testing/scripts/failure-list.js
index 5623ae91..6beef0da 100644
--- a/packages/protovalidate-testing/scripts/failure-list.js
+++ b/packages/protovalidate-testing/scripts/failure-list.js
@@ -23,7 +23,7 @@ const suites = [];
let suite;
let kase;
for (const line of lines) {
- // --- FAIL: standard_constraints/map (failed: 18, skipped: 0, passed: 11, total: 29)
+ // --- FAIL: standard_rules/map (failed: 18, skipped: 0, passed: 11, total: 29)
const mSuite =
/^--- FAIL: (.+) \(failed: \d+, skipped: \d+, passed: \d+, total: \d+\)$/.exec(
line,
diff --git a/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_constraints/custom_constraints_pb.ts b/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_constraints/custom_constraints_pb.ts
deleted file mode 100644
index 5fa8e3ca..00000000
--- a/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_constraints/custom_constraints_pb.ts
+++ /dev/null
@@ -1,630 +0,0 @@
-// Copyright 2024-2025 Buf Technologies, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// @generated by protoc-gen-es v2.2.5 with parameter "target=ts,import_extension=.js,ts_nocheck=false"
-// @generated from file buf/validate/conformance/cases/custom_constraints/custom_constraints.proto (package buf.validate.conformance.cases.custom_constraints, syntax proto3)
-/* eslint-disable */
-
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
-import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
-import { file_buf_validate_validate } from "../../../validate_pb.js";
-import type { Message } from "@bufbuild/protobuf";
-
-/**
- * Describes the file buf/validate/conformance/cases/custom_constraints/custom_constraints.proto.
- */
-export const file_buf_validate_conformance_cases_custom_constraints_custom_constraints: GenFile = /*@__PURE__*/
- fileDesc("CkpidWYvdmFsaWRhdGUvY29uZm9ybWFuY2UvY2FzZXMvY3VzdG9tX2NvbnN0cmFpbnRzL2N1c3RvbV9jb25zdHJhaW50cy5wcm90bxIxYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cyK8AQoNTm9FeHByZXNzaW9ucxIJCgFhGAEgASgFEkIKAWIYAiABKA4yNy5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkVudW0SUgoBYxgDIAEoCzJHLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuTm9FeHByZXNzaW9ucy5OZXN0ZWQaCAoGTmVzdGVkIqsFChJNZXNzYWdlRXhwcmVzc2lvbnMSCQoBYRgBIAEoBRIJCgFiGAIgASgFEkIKAWMYAyABKA4yNy5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkVudW0SQgoBZBgEIAEoDjI3LmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRW51bRJXCgFlGAUgASgLMkwuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5NZXNzYWdlRXhwcmVzc2lvbnMuTmVzdGVkElcKAWYYBiABKAsyTC5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLk1lc3NhZ2VFeHByZXNzaW9ucy5OZXN0ZWQacgoGTmVzdGVkEgkKAWEYASABKAUSCQoBYhgCIAEoBTpSukhPGk0KGW1lc3NhZ2VfZXhwcmVzc2lvbl9uZXN0ZWQaMHRoaXMuYSA+IHRoaXMuYiA/ICcnOiAnYSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBiJzrQAbpIzAEaQwoZbWVzc2FnZV9leHByZXNzaW9uX3NjYWxhchIVYSBtdXN0IGJlIGxlc3MgdGhhbiBiGg90aGlzLmEgPCB0aGlzLmIaPwoXbWVzc2FnZV9leHByZXNzaW9uX2VudW0SEmMgbXVzdCBub3QgZXF1YWwgZBoQdGhpcy5jICE9IHRoaXMuZBpEChhtZXNzYWdlX2V4cHJlc3Npb25fZW1iZWQSEmUuYSBtdXN0IGVxdWFsIGYuYRoUdGhpcy5lLmEgPT0gdGhpcy5mLmEiTwoMTWlzc2luZ0ZpZWxkEgkKAWEYASABKAU6NLpIMRovCg1taXNzaW5nX2ZpZWxkEhJiIG11c3QgYmUgcG9zaXRpdmUaCnRoaXMuYiA+IDAiZAoNSW5jb3JyZWN0VHlwZRIJCgFhGAEgASgFOki6SEUaQwoOaW5jb3JyZWN0X3R5cGUSF2EgbXVzdCBzdGFydCB3aXRoICdmb28nGhh0aGlzLmEuc3RhcnRzV2l0aCgnZm9vJykiegoPRHluUnVudGltZUVycm9yEgkKAWEYASABKAU6XLpIWRpXCg9keW5fcnVudGltZV9lcnISLmR5bmFtaWMgdHlwZSB0cmllcyB0byB1c2UgYSBub24tZXhpc3RlbnQgZmllbGQaFGR5bih0aGlzKS5iID09ICdmb28nIlwKDE5vd0VxdWFsc05vdzpMukhJGkcKDm5vd19lcXVhbHNfbm93Eilub3cgc2hvdWxkIGVxdWFsIG5vdyB3aXRoaW4gYW4gZXhwcmVzc2lvbhoKbm93ID09IG5vdyLaAgodRmllbGRFeHByZXNzaW9uTXVsdGlwbGVTY2FsYXISuAIKA3ZhbBgBIAEoBUKqArpIpgK6AV8KImZpZWxkX2V4cHJlc3Npb24ubXVsdGlwbGUuc2NhbGFyLjESL3Rlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm11bHRpcGxlLnNjYWxhci4xGgh0aGlzID4gMLoBXwoiZmllbGRfZXhwcmVzc2lvbi5tdWx0aXBsZS5zY2FsYXIuMhIvdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubXVsdGlwbGUuc2NhbGFyLjIaCHRoaXMgPiAxugFfCiJmaWVsZF9leHByZXNzaW9uLm11bHRpcGxlLnNjYWxhci4zEi90ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tdWx0aXBsZS5zY2FsYXIuMxoIdGhpcyA+IDIidwobRmllbGRFeHByZXNzaW9uTmVzdGVkU2NhbGFyElgKBm5lc3RlZBgBIAEoCzJILmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRmllbGRFeHByZXNzaW9uU2NhbGFyIp0BCh1GaWVsZEV4cHJlc3Npb25PcHRpb25hbFNjYWxhchJ0CgN2YWwYASABKAVCYrpIX7oBXAogZmllbGRfZXhwcmVzc2lvbi5vcHRpb25hbC5zY2FsYXISLXRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm9wdGlvbmFsLnNjYWxhchoJdGhpcyA9PSAxSACIAQFCBgoEX3ZhbCJ2ChVGaWVsZEV4cHJlc3Npb25TY2FsYXISXQoDdmFsGAEgASgFQlC6SE26AUoKF2ZpZWxkX2V4cHJlc3Npb24uc2NhbGFyEiR0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5zY2FsYXIaCXRoaXMgPT0gMSKqAQoTRmllbGRFeHByZXNzaW9uRW51bRKSAQoDdmFsGAEgASgOMjcuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5FbnVtQky6SEm6AUYKFWZpZWxkX2V4cHJlc3Npb24uZW51bRIidGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24uZW51bRoJdGhpcyA9PSAxIt0BChZGaWVsZEV4cHJlc3Npb25NZXNzYWdlErABCgN2YWwYASABKAsyTS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvbk1lc3NhZ2UuTXNnQlS6SFG6AU4KGGZpZWxkX2V4cHJlc3Npb24ubWVzc2FnZRIldGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWVzc2FnZRoLdGhpcy5hID09IDEaEAoDTXNnEgkKAWEYASABKAUilAIKGEZpZWxkRXhwcmVzc2lvbk1hcFNjYWxhchLLAQoDdmFsGAEgAygLMlQuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5GaWVsZEV4cHJlc3Npb25NYXBTY2FsYXIuVmFsRW50cnlCaLpIZboBYgobZmllbGRfZXhwcmVzc2lvbi5tYXAuc2NhbGFyEih0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tYXAuc2NhbGFyGhl0aGlzLmFsbChrLCB0aGlzW2tdID09IDEpGioKCFZhbEVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoBToCOAEixQIKFkZpZWxkRXhwcmVzc2lvbk1hcEVudW0SxQEKA3ZhbBgBIAMoCzJSLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRmllbGRFeHByZXNzaW9uTWFwRW51bS5WYWxFbnRyeUJkukhhugFeChlmaWVsZF9leHByZXNzaW9uLm1hcC5lbnVtEiZ0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tYXAuZW51bRoZdGhpcy5hbGwoaywgdGhpc1trXSA9PSAxKRpjCghWYWxFbnRyeRILCgNrZXkYASABKAUSRgoFdmFsdWUYAiABKA4yNy5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkVudW06AjgBIv4CChlGaWVsZEV4cHJlc3Npb25NYXBNZXNzYWdlEtABCgN2YWwYASADKAsyVS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2UuVmFsRW50cnlCbLpIaboBZgocZmllbGRfZXhwcmVzc2lvbi5tYXAubWVzc2FnZRIpdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWFwLm1lc3NhZ2UaG3RoaXMuYWxsKGssIHRoaXNba10uYSA9PSAxKRp8CghWYWxFbnRyeRILCgNrZXkYASABKAUSXwoFdmFsdWUYAiABKAsyUC5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2UuTXNnOgI4ARoQCgNNc2cSCQoBYRgBIAEoBSKOAgoWRmllbGRFeHByZXNzaW9uTWFwS2V5cxLHAQoDdmFsGAEgAygLMlIuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5GaWVsZEV4cHJlc3Npb25NYXBLZXlzLlZhbEVudHJ5Qma6SGOaAWAiXroBWwoZZmllbGRfZXhwcmVzc2lvbi5tYXAua2V5cxImdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWFwLmtleXMaFnRoaXMgPT0gNCB8fCB0aGlzID09IDgaKgoIVmFsRW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgFOgI4ASKjAgoeRmllbGRFeHByZXNzaW9uTWFwU2NhbGFyVmFsdWVzEtQBCgN2YWwYASADKAsyWi5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvbk1hcFNjYWxhclZhbHVlcy5WYWxFbnRyeUJrukhomgFlKmO6AWAKImZpZWxkX2V4cHJlc3Npb24ubWFwLnNjYWxhci52YWx1ZXMSL3Rlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm1hcC5zY2FsYXIudmFsdWVzGgl0aGlzID09IDEaKgoIVmFsRW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgFOgI4ASLUAgocRmllbGRFeHByZXNzaW9uTWFwRW51bVZhbHVlcxLOAQoDdmFsGAEgAygLMlguYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5GaWVsZEV4cHJlc3Npb25NYXBFbnVtVmFsdWVzLlZhbEVudHJ5Qme6SGSaAWEqX7oBXAogZmllbGRfZXhwcmVzc2lvbi5tYXAuZW51bS52YWx1ZXMSLXRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm1hcC5lbnVtLnZhbHVlcxoJdGhpcyA9PSAxGmMKCFZhbEVudHJ5EgsKA2tleRgBIAEoBRJGCgV2YWx1ZRgCIAEoDjI3LmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRW51bToCOAEilAMKH0ZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2VWYWx1ZXMS2QEKA3ZhbBgBIAMoCzJbLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRmllbGRFeHByZXNzaW9uTWFwTWVzc2FnZVZhbHVlcy5WYWxFbnRyeUJvukhsmgFpKme6AWQKI2ZpZWxkX2V4cHJlc3Npb24ubWFwLm1lc3NhZ2UudmFsdWVzEjB0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tYXAubWVzc2FnZS52YWx1ZXMaC3RoaXMuYSA9PSAxGoIBCghWYWxFbnRyeRILCgNrZXkYASABKAUSZQoFdmFsdWUYAiABKAsyVi5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2VWYWx1ZXMuTXNnOgI4ARoQCgNNc2cSCQoBYRgBIAEoBSKaAQodRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRTY2FsYXISeQoDdmFsGAEgAygFQmy6SGm6AWYKIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuc2NhbGFyEi10ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5zY2FsYXIaE3RoaXMuYWxsKGUsIGUgPT0gMSkizgEKG0ZpZWxkRXhwcmVzc2lvblJlcGVhdGVkRW51bRKuAQoDdmFsGAEgAygOMjcuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5FbnVtQmi6SGW6AWIKHmZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bRIrdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bRoTdGhpcy5hbGwoZSwgZSA9PSAxKSKJAgoeRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRNZXNzYWdlEtQBCgN2YWwYASADKAsyVS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX2NvbnN0cmFpbnRzLkZpZWxkRXhwcmVzc2lvblJlcGVhdGVkTWVzc2FnZS5Nc2dCcLpIbboBagohZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5tZXNzYWdlEi50ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5tZXNzYWdlGhV0aGlzLmFsbChlLCBlLmEgPT0gMSkaEAoDTXNnEgkKAWEYASABKAUipwEKIkZpZWxkRXhwcmVzc2lvblJlcGVhdGVkU2NhbGFySXRlbXMSgAEKA3ZhbBgBIAMoBUJzukhwkgFtImu6AWgKJmZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuc2NhbGFyLml0ZW1zEjN0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5zY2FsYXIuaXRlbXMaCXRoaXMgPT0gMSLaAQogRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRFbnVtSXRlbXMStQEKA3ZhbBgBIAMoDjI3LmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fY29uc3RyYWludHMuRW51bUJvukhskgFpIme6AWQKJGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bS5pdGVtcxIxdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bS5pdGVtcxoJdGhpcyA9PSAxIpoCCiNGaWVsZEV4cHJlc3Npb25SZXBlYXRlZE1lc3NhZ2VJdGVtcxLgAQoDdmFsGAEgAygLMlouYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9jb25zdHJhaW50cy5GaWVsZEV4cHJlc3Npb25SZXBlYXRlZE1lc3NhZ2VJdGVtcy5Nc2dCd7pIdJIBcSJvugFsCidmaWVsZF9leHByZXNzaW9uLnJlcGVhdGVkLm1lc3NhZ2UuaXRlbXMSNHRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLnJlcGVhdGVkLm1lc3NhZ2UuaXRlbXMaC3RoaXMuYSA9PSAxGhAKA01zZxIJCgFhGAEgASgFKioKBEVudW0SFAoQRU5VTV9VTlNQRUNJRklFRBAAEgwKCEVOVU1fT05FEAFiBnByb3RvMw", [file_buf_validate_validate]);
-
-/**
- * A message that does not contain any expressions
- *
- * @generated from message buf.validate.conformance.cases.custom_constraints.NoExpressions
- */
-export type NoExpressions = Message<"buf.validate.conformance.cases.custom_constraints.NoExpressions"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.Enum b = 2;
- */
- b: Enum;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.NoExpressions.Nested c = 3;
- */
- c?: NoExpressions_Nested;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.NoExpressions.
- * Use `create(NoExpressionsSchema)` to create a new message.
- */
-export const NoExpressionsSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.NoExpressions.Nested
- */
-export type NoExpressions_Nested = Message<"buf.validate.conformance.cases.custom_constraints.NoExpressions.Nested"> & {
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.NoExpressions.Nested.
- * Use `create(NoExpressions_NestedSchema)` to create a new message.
- */
-export const NoExpressions_NestedSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 0, 0);
-
-/**
- * A message with message-level custom expressions
- *
- * @generated from message buf.validate.conformance.cases.custom_constraints.MessageExpressions
- */
-export type MessageExpressions = Message<"buf.validate.conformance.cases.custom_constraints.MessageExpressions"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-
- /**
- * @generated from field: int32 b = 2;
- */
- b: number;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.Enum c = 3;
- */
- c: Enum;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.Enum d = 4;
- */
- d: Enum;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.MessageExpressions.Nested e = 5;
- */
- e?: MessageExpressions_Nested;
-
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.MessageExpressions.Nested f = 6;
- */
- f?: MessageExpressions_Nested;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.MessageExpressions.
- * Use `create(MessageExpressionsSchema)` to create a new message.
- */
-export const MessageExpressionsSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 1);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.MessageExpressions.Nested
- */
-export type MessageExpressions_Nested = Message<"buf.validate.conformance.cases.custom_constraints.MessageExpressions.Nested"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-
- /**
- * @generated from field: int32 b = 2;
- */
- b: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.MessageExpressions.Nested.
- * Use `create(MessageExpressions_NestedSchema)` to create a new message.
- */
-export const MessageExpressions_NestedSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 1, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.MissingField
- */
-export type MissingField = Message<"buf.validate.conformance.cases.custom_constraints.MissingField"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.MissingField.
- * Use `create(MissingFieldSchema)` to create a new message.
- */
-export const MissingFieldSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 2);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.IncorrectType
- */
-export type IncorrectType = Message<"buf.validate.conformance.cases.custom_constraints.IncorrectType"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.IncorrectType.
- * Use `create(IncorrectTypeSchema)` to create a new message.
- */
-export const IncorrectTypeSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 3);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.DynRuntimeError
- */
-export type DynRuntimeError = Message<"buf.validate.conformance.cases.custom_constraints.DynRuntimeError"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.DynRuntimeError.
- * Use `create(DynRuntimeErrorSchema)` to create a new message.
- */
-export const DynRuntimeErrorSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 4);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.NowEqualsNow
- */
-export type NowEqualsNow = Message<"buf.validate.conformance.cases.custom_constraints.NowEqualsNow"> & {
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.NowEqualsNow.
- * Use `create(NowEqualsNowSchema)` to create a new message.
- */
-export const NowEqualsNowSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 5);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMultipleScalar
- */
-export type FieldExpressionMultipleScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMultipleScalar"> & {
- /**
- * @generated from field: int32 val = 1;
- */
- val: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMultipleScalar.
- * Use `create(FieldExpressionMultipleScalarSchema)` to create a new message.
- */
-export const FieldExpressionMultipleScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 6);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionNestedScalar
- */
-export type FieldExpressionNestedScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionNestedScalar"> & {
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.FieldExpressionScalar nested = 1;
- */
- nested?: FieldExpressionScalar;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionNestedScalar.
- * Use `create(FieldExpressionNestedScalarSchema)` to create a new message.
- */
-export const FieldExpressionNestedScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 7);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionOptionalScalar
- */
-export type FieldExpressionOptionalScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionOptionalScalar"> & {
- /**
- * @generated from field: optional int32 val = 1;
- */
- val?: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionOptionalScalar.
- * Use `create(FieldExpressionOptionalScalarSchema)` to create a new message.
- */
-export const FieldExpressionOptionalScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 8);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionScalar
- */
-export type FieldExpressionScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionScalar"> & {
- /**
- * @generated from field: int32 val = 1;
- */
- val: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionScalar.
- * Use `create(FieldExpressionScalarSchema)` to create a new message.
- */
-export const FieldExpressionScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 9);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionEnum
- */
-export type FieldExpressionEnum = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionEnum"> & {
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.Enum val = 1;
- */
- val: Enum;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionEnum.
- * Use `create(FieldExpressionEnumSchema)` to create a new message.
- */
-export const FieldExpressionEnumSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 10);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage
- */
-export type FieldExpressionMessage = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage"> & {
- /**
- * @generated from field: buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage.Msg val = 1;
- */
- val?: FieldExpressionMessage_Msg;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage.
- * Use `create(FieldExpressionMessageSchema)` to create a new message.
- */
-export const FieldExpressionMessageSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 11);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage.Msg
- */
-export type FieldExpressionMessage_Msg = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage.Msg"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMessage.Msg.
- * Use `create(FieldExpressionMessage_MsgSchema)` to create a new message.
- */
-export const FieldExpressionMessage_MsgSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 11, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalar
- */
-export type FieldExpressionMapScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalar"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: number };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalar.
- * Use `create(FieldExpressionMapScalarSchema)` to create a new message.
- */
-export const FieldExpressionMapScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 12);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnum
- */
-export type FieldExpressionMapEnum = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnum"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: Enum };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnum.
- * Use `create(FieldExpressionMapEnumSchema)` to create a new message.
- */
-export const FieldExpressionMapEnumSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 13);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage
- */
-export type FieldExpressionMapMessage = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: FieldExpressionMapMessage_Msg };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage.
- * Use `create(FieldExpressionMapMessageSchema)` to create a new message.
- */
-export const FieldExpressionMapMessageSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 14);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage.Msg
- */
-export type FieldExpressionMapMessage_Msg = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage.Msg"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessage.Msg.
- * Use `create(FieldExpressionMapMessage_MsgSchema)` to create a new message.
- */
-export const FieldExpressionMapMessage_MsgSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 14, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapKeys
- */
-export type FieldExpressionMapKeys = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapKeys"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: number };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapKeys.
- * Use `create(FieldExpressionMapKeysSchema)` to create a new message.
- */
-export const FieldExpressionMapKeysSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 15);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalarValues
- */
-export type FieldExpressionMapScalarValues = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalarValues"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: number };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapScalarValues.
- * Use `create(FieldExpressionMapScalarValuesSchema)` to create a new message.
- */
-export const FieldExpressionMapScalarValuesSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 16);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnumValues
- */
-export type FieldExpressionMapEnumValues = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnumValues"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: Enum };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapEnumValues.
- * Use `create(FieldExpressionMapEnumValuesSchema)` to create a new message.
- */
-export const FieldExpressionMapEnumValuesSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 17);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues
- */
-export type FieldExpressionMapMessageValues = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues"> & {
- /**
- * @generated from field: map val = 1;
- */
- val: { [key: number]: FieldExpressionMapMessageValues_Msg };
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues.
- * Use `create(FieldExpressionMapMessageValuesSchema)` to create a new message.
- */
-export const FieldExpressionMapMessageValuesSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 18);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues.Msg
- */
-export type FieldExpressionMapMessageValues_Msg = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues.Msg"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionMapMessageValues.Msg.
- * Use `create(FieldExpressionMapMessageValues_MsgSchema)` to create a new message.
- */
-export const FieldExpressionMapMessageValues_MsgSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 18, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalar
- */
-export type FieldExpressionRepeatedScalar = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalar"> & {
- /**
- * @generated from field: repeated int32 val = 1;
- */
- val: number[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalar.
- * Use `create(FieldExpressionRepeatedScalarSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedScalarSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 19);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnum
- */
-export type FieldExpressionRepeatedEnum = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnum"> & {
- /**
- * @generated from field: repeated buf.validate.conformance.cases.custom_constraints.Enum val = 1;
- */
- val: Enum[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnum.
- * Use `create(FieldExpressionRepeatedEnumSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedEnumSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 20);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage
- */
-export type FieldExpressionRepeatedMessage = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage"> & {
- /**
- * @generated from field: repeated buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage.Msg val = 1;
- */
- val: FieldExpressionRepeatedMessage_Msg[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage.
- * Use `create(FieldExpressionRepeatedMessageSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedMessageSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 21);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage.Msg
- */
-export type FieldExpressionRepeatedMessage_Msg = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage.Msg"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessage.Msg.
- * Use `create(FieldExpressionRepeatedMessage_MsgSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedMessage_MsgSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 21, 0);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalarItems
- */
-export type FieldExpressionRepeatedScalarItems = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalarItems"> & {
- /**
- * @generated from field: repeated int32 val = 1;
- */
- val: number[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedScalarItems.
- * Use `create(FieldExpressionRepeatedScalarItemsSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedScalarItemsSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 22);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnumItems
- */
-export type FieldExpressionRepeatedEnumItems = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnumItems"> & {
- /**
- * @generated from field: repeated buf.validate.conformance.cases.custom_constraints.Enum val = 1;
- */
- val: Enum[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedEnumItems.
- * Use `create(FieldExpressionRepeatedEnumItemsSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedEnumItemsSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 23);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems
- */
-export type FieldExpressionRepeatedMessageItems = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems"> & {
- /**
- * @generated from field: repeated buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems.Msg val = 1;
- */
- val: FieldExpressionRepeatedMessageItems_Msg[];
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems.
- * Use `create(FieldExpressionRepeatedMessageItemsSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedMessageItemsSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 24);
-
-/**
- * @generated from message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems.Msg
- */
-export type FieldExpressionRepeatedMessageItems_Msg = Message<"buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems.Msg"> & {
- /**
- * @generated from field: int32 a = 1;
- */
- a: number;
-};
-
-/**
- * Describes the message buf.validate.conformance.cases.custom_constraints.FieldExpressionRepeatedMessageItems.Msg.
- * Use `create(FieldExpressionRepeatedMessageItems_MsgSchema)` to create a new message.
- */
-export const FieldExpressionRepeatedMessageItems_MsgSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 24, 0);
-
-/**
- * @generated from enum buf.validate.conformance.cases.custom_constraints.Enum
- */
-export enum Enum {
- /**
- * @generated from enum value: ENUM_UNSPECIFIED = 0;
- */
- UNSPECIFIED = 0,
-
- /**
- * @generated from enum value: ENUM_ONE = 1;
- */
- ONE = 1,
-}
-
-/**
- * Describes the enum buf.validate.conformance.cases.custom_constraints.Enum.
- */
-export const EnumSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_buf_validate_conformance_cases_custom_constraints_custom_constraints, 0);
-
diff --git a/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_rules/custom_rules_pb.ts b/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_rules/custom_rules_pb.ts
new file mode 100644
index 00000000..90b76fbc
--- /dev/null
+++ b/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_rules/custom_rules_pb.ts
@@ -0,0 +1,715 @@
+// Copyright 2024-2025 Buf Technologies, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// @generated by protoc-gen-es v2.2.5 with parameter "target=ts,import_extension=.js,ts_nocheck=false"
+// @generated from file buf/validate/conformance/cases/custom_rules/custom_rules.proto (package buf.validate.conformance.cases.custom_rules, syntax proto3)
+/* eslint-disable */
+
+import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
+import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
+import { file_buf_validate_validate } from "../../../validate_pb.js";
+import type { Message } from "@bufbuild/protobuf";
+
+/**
+ * Describes the file buf/validate/conformance/cases/custom_rules/custom_rules.proto.
+ */
+export const file_buf_validate_conformance_cases_custom_rules_custom_rules: GenFile = /*@__PURE__*/
+ fileDesc("Cj5idWYvdmFsaWRhdGUvY29uZm9ybWFuY2UvY2FzZXMvY3VzdG9tX3J1bGVzL2N1c3RvbV9ydWxlcy5wcm90bxIrYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcyKwAQoNTm9FeHByZXNzaW9ucxIJCgFhGAEgASgFEjwKAWIYAiABKA4yMS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkVudW0STAoBYxgDIAEoCzJBLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuTm9FeHByZXNzaW9ucy5OZXN0ZWQaCAoGTmVzdGVkIpMFChJNZXNzYWdlRXhwcmVzc2lvbnMSCQoBYRgBIAEoBRIJCgFiGAIgASgFEjwKAWMYAyABKA4yMS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkVudW0SPAoBZBgEIAEoDjIxLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRW51bRJRCgFlGAUgASgLMkYuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5NZXNzYWdlRXhwcmVzc2lvbnMuTmVzdGVkElEKAWYYBiABKAsyRi5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLk1lc3NhZ2VFeHByZXNzaW9ucy5OZXN0ZWQacgoGTmVzdGVkEgkKAWEYASABKAUSCQoBYhgCIAEoBTpSukhPGk0KGW1lc3NhZ2VfZXhwcmVzc2lvbl9uZXN0ZWQaMHRoaXMuYSA+IHRoaXMuYiA/ICcnOiAnYSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBiJzrQAbpIzAEaQwoZbWVzc2FnZV9leHByZXNzaW9uX3NjYWxhchIVYSBtdXN0IGJlIGxlc3MgdGhhbiBiGg90aGlzLmEgPCB0aGlzLmIaPwoXbWVzc2FnZV9leHByZXNzaW9uX2VudW0SEmMgbXVzdCBub3QgZXF1YWwgZBoQdGhpcy5jICE9IHRoaXMuZBpEChhtZXNzYWdlX2V4cHJlc3Npb25fZW1iZWQSEmUuYSBtdXN0IGVxdWFsIGYuYRoUdGhpcy5lLmEgPT0gdGhpcy5mLmEiTwoMTWlzc2luZ0ZpZWxkEgkKAWEYASABKAU6NLpIMRovCg1taXNzaW5nX2ZpZWxkEhJiIG11c3QgYmUgcG9zaXRpdmUaCnRoaXMuYiA+IDAiZAoNSW5jb3JyZWN0VHlwZRIJCgFhGAEgASgFOki6SEUaQwoOaW5jb3JyZWN0X3R5cGUSF2EgbXVzdCBzdGFydCB3aXRoICdmb28nGhh0aGlzLmEuc3RhcnRzV2l0aCgnZm9vJykiegoPRHluUnVudGltZUVycm9yEgkKAWEYASABKAU6XLpIWRpXCg9keW5fcnVudGltZV9lcnISLmR5bmFtaWMgdHlwZSB0cmllcyB0byB1c2UgYSBub24tZXhpc3RlbnQgZmllbGQaFGR5bih0aGlzKS5iID09ICdmb28nIlwKDE5vd0VxdWFsc05vdzpMukhJGkcKDm5vd19lcXVhbHNfbm93Eilub3cgc2hvdWxkIGVxdWFsIG5vdyB3aXRoaW4gYW4gZXhwcmVzc2lvbhoKbm93ID09IG5vdyLaAgodRmllbGRFeHByZXNzaW9uTXVsdGlwbGVTY2FsYXISuAIKA3ZhbBgBIAEoBUKqArpIpgK6AV8KImZpZWxkX2V4cHJlc3Npb24ubXVsdGlwbGUuc2NhbGFyLjESL3Rlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm11bHRpcGxlLnNjYWxhci4xGgh0aGlzID4gMLoBXwoiZmllbGRfZXhwcmVzc2lvbi5tdWx0aXBsZS5zY2FsYXIuMhIvdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubXVsdGlwbGUuc2NhbGFyLjIaCHRoaXMgPiAxugFfCiJmaWVsZF9leHByZXNzaW9uLm11bHRpcGxlLnNjYWxhci4zEi90ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tdWx0aXBsZS5zY2FsYXIuMxoIdGhpcyA+IDIicQobRmllbGRFeHByZXNzaW9uTmVzdGVkU2NhbGFyElIKBm5lc3RlZBgBIAEoCzJCLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRmllbGRFeHByZXNzaW9uU2NhbGFyIp0BCh1GaWVsZEV4cHJlc3Npb25PcHRpb25hbFNjYWxhchJ0CgN2YWwYASABKAVCYrpIX7oBXAogZmllbGRfZXhwcmVzc2lvbi5vcHRpb25hbC5zY2FsYXISLXRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm9wdGlvbmFsLnNjYWxhchoJdGhpcyA9PSAxSACIAQFCBgoEX3ZhbCJ2ChVGaWVsZEV4cHJlc3Npb25TY2FsYXISXQoDdmFsGAEgASgFQlC6SE26AUoKF2ZpZWxkX2V4cHJlc3Npb24uc2NhbGFyEiR0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5zY2FsYXIaCXRoaXMgPT0gMSKkAQoTRmllbGRFeHByZXNzaW9uRW51bRKMAQoDdmFsGAEgASgOMjEuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5FbnVtQky6SEm6AUYKFWZpZWxkX2V4cHJlc3Npb24uZW51bRIidGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24uZW51bRoJdGhpcyA9PSAxItcBChZGaWVsZEV4cHJlc3Npb25NZXNzYWdlEqoBCgN2YWwYASABKAsyRy5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvbk1lc3NhZ2UuTXNnQlS6SFG6AU4KGGZpZWxkX2V4cHJlc3Npb24ubWVzc2FnZRIldGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWVzc2FnZRoLdGhpcy5hID09IDEaEAoDTXNnEgkKAWEYASABKAUi/gEKF0ZpZWxkRXhwcmVzc2lvbk1hcEludDMyErYBCgN2YWwYASADKAsyTS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvbk1hcEludDMyLlZhbEVudHJ5Qlq6SFe6AVQKGmZpZWxkX2V4cHJlc3Npb24ubWFwLmludDMyEhthbGwgbWFwIHZhbHVlcyBtdXN0IGVxdWFsIDEaGXRoaXMuYWxsKGssIHRoaXNba10gPT0gMSkaKgoIVmFsRW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgFOgI4ASL+AQoXRmllbGRFeHByZXNzaW9uTWFwSW50NjQStgEKA3ZhbBgBIAMoCzJNLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRmllbGRFeHByZXNzaW9uTWFwSW50NjQuVmFsRW50cnlCWrpIV7oBVAoaZmllbGRfZXhwcmVzc2lvbi5tYXAuaW50NjQSG2FsbCBtYXAgdmFsdWVzIG11c3QgZXF1YWwgMRoZdGhpcy5hbGwoaywgdGhpc1trXSA9PSAxKRoqCghWYWxFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgBIocCChhGaWVsZEV4cHJlc3Npb25NYXBVaW50MzISvgEKA3ZhbBgBIAMoCzJOLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRmllbGRFeHByZXNzaW9uTWFwVWludDMyLlZhbEVudHJ5QmG6SF66AVsKG2ZpZWxkX2V4cHJlc3Npb24ubWFwLnVpbnQzMhIbYWxsIG1hcCB2YWx1ZXMgbXVzdCBlcXVhbCAxGh90aGlzLmFsbChrLCB0aGlzW2tdID09IHVpbnQoMSkpGioKCFZhbEVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1ZRgCIAEoDToCOAEihwIKGEZpZWxkRXhwcmVzc2lvbk1hcFVpbnQ2NBK+AQoDdmFsGAEgAygLMk4uYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBVaW50NjQuVmFsRW50cnlCYbpIXroBWwobZmllbGRfZXhwcmVzc2lvbi5tYXAudWludDY0EhthbGwgbWFwIHZhbHVlcyBtdXN0IGVxdWFsIDEaH3RoaXMuYWxsKGssIHRoaXNba10gPT0gdWludCgxKSkaKgoIVmFsRW50cnkSCwoDa2V5GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ASKDAgoWRmllbGRFeHByZXNzaW9uTWFwQm9vbBK8AQoDdmFsGAEgAygLMkwuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBCb29sLlZhbEVudHJ5QmG6SF66AVsKGWZpZWxkX2V4cHJlc3Npb24ubWFwLmJvb2wSH2FsbCBtYXAgdmFsdWVzIG11c3QgZXF1YWwgZmFsc2UaHXRoaXMuYWxsKGssIHRoaXNba10gPT0gZmFsc2UpGioKCFZhbEVudHJ5EgsKA2tleRgBIAEoCBINCgV2YWx1ZRgCIAEoCDoCOAEiiQIKGEZpZWxkRXhwcmVzc2lvbk1hcFN0cmluZxLAAQoDdmFsGAEgAygLMk4uYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBTdHJpbmcuVmFsRW50cnlCY7pIYLoBXQobZmllbGRfZXhwcmVzc2lvbi5tYXAuc3RyaW5nEh9hbGwgbWFwIHZhbHVlcyBtdXN0IGVxdWFsICdmb28nGh10aGlzLmFsbChrLCB0aGlzW2tdID09ICdmb28nKRoqCghWYWxFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrkCChZGaWVsZEV4cHJlc3Npb25NYXBFbnVtEr8BCgN2YWwYASADKAsyTC5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvbk1hcEVudW0uVmFsRW50cnlCZLpIYboBXgoZZmllbGRfZXhwcmVzc2lvbi5tYXAuZW51bRImdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWFwLmVudW0aGXRoaXMuYWxsKGssIHRoaXNba10gPT0gMSkaXQoIVmFsRW50cnkSCwoDa2V5GAEgASgFEkAKBXZhbHVlGAIgASgOMjEuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5FbnVtOgI4ASLyAgoZRmllbGRFeHByZXNzaW9uTWFwTWVzc2FnZRLKAQoDdmFsGAEgAygLMk8uYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBNZXNzYWdlLlZhbEVudHJ5Qmy6SGm6AWYKHGZpZWxkX2V4cHJlc3Npb24ubWFwLm1lc3NhZ2USKXRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm1hcC5tZXNzYWdlGht0aGlzLmFsbChrLCB0aGlzW2tdLmEgPT0gMSkadgoIVmFsRW50cnkSCwoDa2V5GAEgASgFElkKBXZhbHVlGAIgASgLMkouYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBNZXNzYWdlLk1zZzoCOAEaEAoDTXNnEgkKAWEYASABKAUiiAIKFkZpZWxkRXhwcmVzc2lvbk1hcEtleXMSwQEKA3ZhbBgBIAMoCzJMLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRmllbGRFeHByZXNzaW9uTWFwS2V5cy5WYWxFbnRyeUJmukhjmgFgIl66AVsKGWZpZWxkX2V4cHJlc3Npb24ubWFwLmtleXMSJnRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLm1hcC5rZXlzGhZ0aGlzID09IDQgfHwgdGhpcyA9PSA4GioKCFZhbEVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoBToCOAEinQIKHkZpZWxkRXhwcmVzc2lvbk1hcFNjYWxhclZhbHVlcxLOAQoDdmFsGAEgAygLMlQuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25NYXBTY2FsYXJWYWx1ZXMuVmFsRW50cnlCa7pIaJoBZSpjugFgCiJmaWVsZF9leHByZXNzaW9uLm1hcC5zY2FsYXIudmFsdWVzEi90ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tYXAuc2NhbGFyLnZhbHVlcxoJdGhpcyA9PSAxGioKCFZhbEVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoBToCOAEiyAIKHEZpZWxkRXhwcmVzc2lvbk1hcEVudW1WYWx1ZXMSyAEKA3ZhbBgBIAMoCzJSLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRmllbGRFeHByZXNzaW9uTWFwRW51bVZhbHVlcy5WYWxFbnRyeUJnukhkmgFhKl+6AVwKIGZpZWxkX2V4cHJlc3Npb24ubWFwLmVudW0udmFsdWVzEi10ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5tYXAuZW51bS52YWx1ZXMaCXRoaXMgPT0gMRpdCghWYWxFbnRyeRILCgNrZXkYASABKAUSQAoFdmFsdWUYAiABKA4yMS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkVudW06AjgBIocDCh9GaWVsZEV4cHJlc3Npb25NYXBNZXNzYWdlVmFsdWVzEtMBCgN2YWwYASADKAsyVS5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2VWYWx1ZXMuVmFsRW50cnlCb7pIbJoBaSpnugFkCiNmaWVsZF9leHByZXNzaW9uLm1hcC5tZXNzYWdlLnZhbHVlcxIwdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ubWFwLm1lc3NhZ2UudmFsdWVzGgt0aGlzLmEgPT0gMRp8CghWYWxFbnRyeRILCgNrZXkYASABKAUSXwoFdmFsdWUYAiABKAsyUC5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvbk1hcE1lc3NhZ2VWYWx1ZXMuTXNnOgI4ARoQCgNNc2cSCQoBYRgBIAEoBSKaAQodRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRTY2FsYXISeQoDdmFsGAEgAygFQmy6SGm6AWYKIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuc2NhbGFyEi10ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5zY2FsYXIaE3RoaXMuYWxsKGUsIGUgPT0gMSkiyAEKG0ZpZWxkRXhwcmVzc2lvblJlcGVhdGVkRW51bRKoAQoDdmFsGAEgAygOMjEuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5FbnVtQmi6SGW6AWIKHmZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bRIrdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bRoTdGhpcy5hbGwoZSwgZSA9PSAxKSKDAgoeRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRNZXNzYWdlEs4BCgN2YWwYASADKAsyTy5idWYudmFsaWRhdGUuY29uZm9ybWFuY2UuY2FzZXMuY3VzdG9tX3J1bGVzLkZpZWxkRXhwcmVzc2lvblJlcGVhdGVkTWVzc2FnZS5Nc2dCcLpIbboBagohZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5tZXNzYWdlEi50ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5tZXNzYWdlGhV0aGlzLmFsbChlLCBlLmEgPT0gMSkaEAoDTXNnEgkKAWEYASABKAUipwEKIkZpZWxkRXhwcmVzc2lvblJlcGVhdGVkU2NhbGFySXRlbXMSgAEKA3ZhbBgBIAMoBUJzukhwkgFtImu6AWgKJmZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuc2NhbGFyLml0ZW1zEjN0ZXN0IG1lc3NhZ2UgZmllbGRfZXhwcmVzc2lvbi5yZXBlYXRlZC5zY2FsYXIuaXRlbXMaCXRoaXMgPT0gMSLUAQogRmllbGRFeHByZXNzaW9uUmVwZWF0ZWRFbnVtSXRlbXMSrwEKA3ZhbBgBIAMoDjIxLmJ1Zi52YWxpZGF0ZS5jb25mb3JtYW5jZS5jYXNlcy5jdXN0b21fcnVsZXMuRW51bUJvukhskgFpIme6AWQKJGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bS5pdGVtcxIxdGVzdCBtZXNzYWdlIGZpZWxkX2V4cHJlc3Npb24ucmVwZWF0ZWQuZW51bS5pdGVtcxoJdGhpcyA9PSAxIpQCCiNGaWVsZEV4cHJlc3Npb25SZXBlYXRlZE1lc3NhZ2VJdGVtcxLaAQoDdmFsGAEgAygLMlQuYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzLmN1c3RvbV9ydWxlcy5GaWVsZEV4cHJlc3Npb25SZXBlYXRlZE1lc3NhZ2VJdGVtcy5Nc2dCd7pIdJIBcSJvugFsCidmaWVsZF9leHByZXNzaW9uLnJlcGVhdGVkLm1lc3NhZ2UuaXRlbXMSNHRlc3QgbWVzc2FnZSBmaWVsZF9leHByZXNzaW9uLnJlcGVhdGVkLm1lc3NhZ2UuaXRlbXMaC3RoaXMuYSA9PSAxGhAKA01zZxIJCgFhGAEgASgFKioKBEVudW0SFAoQRU5VTV9VTlNQRUNJRklFRBAAEgwKCEVOVU1fT05FEAFiBnByb3RvMw", [file_buf_validate_validate]);
+
+/**
+ * A message that does not contain any expressions
+ *
+ * @generated from message buf.validate.conformance.cases.custom_rules.NoExpressions
+ */
+export type NoExpressions = Message<"buf.validate.conformance.cases.custom_rules.NoExpressions"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.Enum b = 2;
+ */
+ b: Enum;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.NoExpressions.Nested c = 3;
+ */
+ c?: NoExpressions_Nested;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.NoExpressions.
+ * Use `create(NoExpressionsSchema)` to create a new message.
+ */
+export const NoExpressionsSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.NoExpressions.Nested
+ */
+export type NoExpressions_Nested = Message<"buf.validate.conformance.cases.custom_rules.NoExpressions.Nested"> & {
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.NoExpressions.Nested.
+ * Use `create(NoExpressions_NestedSchema)` to create a new message.
+ */
+export const NoExpressions_NestedSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 0, 0);
+
+/**
+ * A message with message-level custom expressions
+ *
+ * @generated from message buf.validate.conformance.cases.custom_rules.MessageExpressions
+ */
+export type MessageExpressions = Message<"buf.validate.conformance.cases.custom_rules.MessageExpressions"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+
+ /**
+ * @generated from field: int32 b = 2;
+ */
+ b: number;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.Enum c = 3;
+ */
+ c: Enum;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.Enum d = 4;
+ */
+ d: Enum;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.MessageExpressions.Nested e = 5;
+ */
+ e?: MessageExpressions_Nested;
+
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.MessageExpressions.Nested f = 6;
+ */
+ f?: MessageExpressions_Nested;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.MessageExpressions.
+ * Use `create(MessageExpressionsSchema)` to create a new message.
+ */
+export const MessageExpressionsSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 1);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.MessageExpressions.Nested
+ */
+export type MessageExpressions_Nested = Message<"buf.validate.conformance.cases.custom_rules.MessageExpressions.Nested"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+
+ /**
+ * @generated from field: int32 b = 2;
+ */
+ b: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.MessageExpressions.Nested.
+ * Use `create(MessageExpressions_NestedSchema)` to create a new message.
+ */
+export const MessageExpressions_NestedSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 1, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.MissingField
+ */
+export type MissingField = Message<"buf.validate.conformance.cases.custom_rules.MissingField"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.MissingField.
+ * Use `create(MissingFieldSchema)` to create a new message.
+ */
+export const MissingFieldSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 2);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.IncorrectType
+ */
+export type IncorrectType = Message<"buf.validate.conformance.cases.custom_rules.IncorrectType"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.IncorrectType.
+ * Use `create(IncorrectTypeSchema)` to create a new message.
+ */
+export const IncorrectTypeSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 3);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.DynRuntimeError
+ */
+export type DynRuntimeError = Message<"buf.validate.conformance.cases.custom_rules.DynRuntimeError"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.DynRuntimeError.
+ * Use `create(DynRuntimeErrorSchema)` to create a new message.
+ */
+export const DynRuntimeErrorSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 4);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.NowEqualsNow
+ */
+export type NowEqualsNow = Message<"buf.validate.conformance.cases.custom_rules.NowEqualsNow"> & {
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.NowEqualsNow.
+ * Use `create(NowEqualsNowSchema)` to create a new message.
+ */
+export const NowEqualsNowSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 5);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMultipleScalar
+ */
+export type FieldExpressionMultipleScalar = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMultipleScalar"> & {
+ /**
+ * @generated from field: int32 val = 1;
+ */
+ val: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMultipleScalar.
+ * Use `create(FieldExpressionMultipleScalarSchema)` to create a new message.
+ */
+export const FieldExpressionMultipleScalarSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 6);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionNestedScalar
+ */
+export type FieldExpressionNestedScalar = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionNestedScalar"> & {
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.FieldExpressionScalar nested = 1;
+ */
+ nested?: FieldExpressionScalar;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionNestedScalar.
+ * Use `create(FieldExpressionNestedScalarSchema)` to create a new message.
+ */
+export const FieldExpressionNestedScalarSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 7);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionOptionalScalar
+ */
+export type FieldExpressionOptionalScalar = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionOptionalScalar"> & {
+ /**
+ * @generated from field: optional int32 val = 1;
+ */
+ val?: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionOptionalScalar.
+ * Use `create(FieldExpressionOptionalScalarSchema)` to create a new message.
+ */
+export const FieldExpressionOptionalScalarSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 8);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionScalar
+ */
+export type FieldExpressionScalar = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionScalar"> & {
+ /**
+ * @generated from field: int32 val = 1;
+ */
+ val: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionScalar.
+ * Use `create(FieldExpressionScalarSchema)` to create a new message.
+ */
+export const FieldExpressionScalarSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 9);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionEnum
+ */
+export type FieldExpressionEnum = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionEnum"> & {
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.Enum val = 1;
+ */
+ val: Enum;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionEnum.
+ * Use `create(FieldExpressionEnumSchema)` to create a new message.
+ */
+export const FieldExpressionEnumSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 10);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMessage
+ */
+export type FieldExpressionMessage = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMessage"> & {
+ /**
+ * @generated from field: buf.validate.conformance.cases.custom_rules.FieldExpressionMessage.Msg val = 1;
+ */
+ val?: FieldExpressionMessage_Msg;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMessage.
+ * Use `create(FieldExpressionMessageSchema)` to create a new message.
+ */
+export const FieldExpressionMessageSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 11);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMessage.Msg
+ */
+export type FieldExpressionMessage_Msg = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMessage.Msg"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMessage.Msg.
+ * Use `create(FieldExpressionMessage_MsgSchema)` to create a new message.
+ */
+export const FieldExpressionMessage_MsgSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 11, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt32
+ */
+export type FieldExpressionMapInt32 = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt32"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: number };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt32.
+ * Use `create(FieldExpressionMapInt32Schema)` to create a new message.
+ */
+export const FieldExpressionMapInt32Schema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 12);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt64
+ */
+export type FieldExpressionMapInt64 = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt64"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: string]: bigint };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapInt64.
+ * Use `create(FieldExpressionMapInt64Schema)` to create a new message.
+ */
+export const FieldExpressionMapInt64Schema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 13);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint32
+ */
+export type FieldExpressionMapUint32 = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint32"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: number };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint32.
+ * Use `create(FieldExpressionMapUint32Schema)` to create a new message.
+ */
+export const FieldExpressionMapUint32Schema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 14);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint64
+ */
+export type FieldExpressionMapUint64 = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint64"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: string]: bigint };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapUint64.
+ * Use `create(FieldExpressionMapUint64Schema)` to create a new message.
+ */
+export const FieldExpressionMapUint64Schema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 15);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapBool
+ */
+export type FieldExpressionMapBool = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapBool"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: string]: boolean };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapBool.
+ * Use `create(FieldExpressionMapBoolSchema)` to create a new message.
+ */
+export const FieldExpressionMapBoolSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 16);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapString
+ */
+export type FieldExpressionMapString = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapString"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: string]: string };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapString.
+ * Use `create(FieldExpressionMapStringSchema)` to create a new message.
+ */
+export const FieldExpressionMapStringSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 17);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnum
+ */
+export type FieldExpressionMapEnum = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnum"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: Enum };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnum.
+ * Use `create(FieldExpressionMapEnumSchema)` to create a new message.
+ */
+export const FieldExpressionMapEnumSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 18);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage
+ */
+export type FieldExpressionMapMessage = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: FieldExpressionMapMessage_Msg };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage.
+ * Use `create(FieldExpressionMapMessageSchema)` to create a new message.
+ */
+export const FieldExpressionMapMessageSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 19);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage.Msg
+ */
+export type FieldExpressionMapMessage_Msg = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage.Msg"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessage.Msg.
+ * Use `create(FieldExpressionMapMessage_MsgSchema)` to create a new message.
+ */
+export const FieldExpressionMapMessage_MsgSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 19, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapKeys
+ */
+export type FieldExpressionMapKeys = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapKeys"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: number };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapKeys.
+ * Use `create(FieldExpressionMapKeysSchema)` to create a new message.
+ */
+export const FieldExpressionMapKeysSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 20);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapScalarValues
+ */
+export type FieldExpressionMapScalarValues = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapScalarValues"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: number };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapScalarValues.
+ * Use `create(FieldExpressionMapScalarValuesSchema)` to create a new message.
+ */
+export const FieldExpressionMapScalarValuesSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 21);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnumValues
+ */
+export type FieldExpressionMapEnumValues = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnumValues"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: Enum };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapEnumValues.
+ * Use `create(FieldExpressionMapEnumValuesSchema)` to create a new message.
+ */
+export const FieldExpressionMapEnumValuesSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 22);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues
+ */
+export type FieldExpressionMapMessageValues = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues"> & {
+ /**
+ * @generated from field: map val = 1;
+ */
+ val: { [key: number]: FieldExpressionMapMessageValues_Msg };
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues.
+ * Use `create(FieldExpressionMapMessageValuesSchema)` to create a new message.
+ */
+export const FieldExpressionMapMessageValuesSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 23);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues.Msg
+ */
+export type FieldExpressionMapMessageValues_Msg = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues.Msg"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionMapMessageValues.Msg.
+ * Use `create(FieldExpressionMapMessageValues_MsgSchema)` to create a new message.
+ */
+export const FieldExpressionMapMessageValues_MsgSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 23, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalar
+ */
+export type FieldExpressionRepeatedScalar = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalar"> & {
+ /**
+ * @generated from field: repeated int32 val = 1;
+ */
+ val: number[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalar.
+ * Use `create(FieldExpressionRepeatedScalarSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedScalarSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 24);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnum
+ */
+export type FieldExpressionRepeatedEnum = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnum"> & {
+ /**
+ * @generated from field: repeated buf.validate.conformance.cases.custom_rules.Enum val = 1;
+ */
+ val: Enum[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnum.
+ * Use `create(FieldExpressionRepeatedEnumSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedEnumSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 25);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage
+ */
+export type FieldExpressionRepeatedMessage = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage"> & {
+ /**
+ * @generated from field: repeated buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage.Msg val = 1;
+ */
+ val: FieldExpressionRepeatedMessage_Msg[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage.
+ * Use `create(FieldExpressionRepeatedMessageSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedMessageSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 26);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage.Msg
+ */
+export type FieldExpressionRepeatedMessage_Msg = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage.Msg"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessage.Msg.
+ * Use `create(FieldExpressionRepeatedMessage_MsgSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedMessage_MsgSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 26, 0);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalarItems
+ */
+export type FieldExpressionRepeatedScalarItems = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalarItems"> & {
+ /**
+ * @generated from field: repeated int32 val = 1;
+ */
+ val: number[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedScalarItems.
+ * Use `create(FieldExpressionRepeatedScalarItemsSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedScalarItemsSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 27);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnumItems
+ */
+export type FieldExpressionRepeatedEnumItems = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnumItems"> & {
+ /**
+ * @generated from field: repeated buf.validate.conformance.cases.custom_rules.Enum val = 1;
+ */
+ val: Enum[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedEnumItems.
+ * Use `create(FieldExpressionRepeatedEnumItemsSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedEnumItemsSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 28);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems
+ */
+export type FieldExpressionRepeatedMessageItems = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems"> & {
+ /**
+ * @generated from field: repeated buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems.Msg val = 1;
+ */
+ val: FieldExpressionRepeatedMessageItems_Msg[];
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems.
+ * Use `create(FieldExpressionRepeatedMessageItemsSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedMessageItemsSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 29);
+
+/**
+ * @generated from message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems.Msg
+ */
+export type FieldExpressionRepeatedMessageItems_Msg = Message<"buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems.Msg"> & {
+ /**
+ * @generated from field: int32 a = 1;
+ */
+ a: number;
+};
+
+/**
+ * Describes the message buf.validate.conformance.cases.custom_rules.FieldExpressionRepeatedMessageItems.Msg.
+ * Use `create(FieldExpressionRepeatedMessageItems_MsgSchema)` to create a new message.
+ */
+export const FieldExpressionRepeatedMessageItems_MsgSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 29, 0);
+
+/**
+ * @generated from enum buf.validate.conformance.cases.custom_rules.Enum
+ */
+export enum Enum {
+ /**
+ * @generated from enum value: ENUM_UNSPECIFIED = 0;
+ */
+ UNSPECIFIED = 0,
+
+ /**
+ * @generated from enum value: ENUM_ONE = 1;
+ */
+ ONE = 1,
+}
+
+/**
+ * Describes the enum buf.validate.conformance.cases.custom_rules.Enum.
+ */
+export const EnumSchema: GenEnum = /*@__PURE__*/
+ enumDesc(file_buf_validate_conformance_cases_custom_rules_custom_rules, 0);
+
diff --git a/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/numbers_pb.ts b/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/numbers_pb.ts
index e50b5ccc..60282182 100644
--- a/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/numbers_pb.ts
+++ b/packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/numbers_pb.ts
@@ -25,7 +25,7 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file buf/validate/conformance/cases/numbers.proto.
*/
export const file_buf_validate_conformance_cases_numbers: GenFile = /*@__PURE__*/
- fileDesc("CixidWYvdmFsaWRhdGUvY29uZm9ybWFuY2UvY2FzZXMvbnVtYmVycy5wcm90bxIeYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzIhgKCUZsb2F0Tm9uZRILCgN2YWwYASABKAIiJQoKRmxvYXRDb25zdBIXCgN2YWwYASABKAJCCrpIBwoFDaRwnT8iJwoHRmxvYXRJbhIcCgN2YWwYASABKAJCD7pIDAoKNYXrkUA14Xr8QCIlCgpGbG9hdE5vdEluEhcKA3ZhbBgBIAEoAkIKukgHCgU9AAAAACIiCgdGbG9hdExUEhcKA3ZhbBgBIAEoAkIKukgHCgUVAAAAACIjCghGbG9hdExURRIXCgN2YWwYASABKAJCCrpIBwoFHQAAgEIiIgoHRmxvYXRHVBIXCgN2YWwYASABKAJCCrpIBwoFJQAAgEEiIwoIRmxvYXRHVEUSFwoDdmFsGAEgASgCQgq6SAcKBS0AAABBIikKCUZsb2F0R1RMVBIcCgN2YWwYASABKAJCD7pIDAoKFQAAIEElAAAAACIrCgtGbG9hdEV4TFRHVBIcCgN2YWwYASABKAJCD7pIDAoKFQAAAAAlAAAgQSIrCgtGbG9hdEdURUxURRIcCgN2YWwYASABKAJCD7pIDAoKHQAAgEMtAAAAQyItCg1GbG9hdEV4R1RFTFRFEhwKA3ZhbBgBIAEoAkIPukgMCgodAAAAQy0AAIBDIiMKC0Zsb2F0RmluaXRlEhQKA3ZhbBgBIAEoAkIHukgECgJAASImCg5GbG9hdE5vdEZpbml0ZRIUCgN2YWwYASABKAJCB7pIBAoCQAAiLgoLRmxvYXRJZ25vcmUSHwoDdmFsGAEgASgCQhK6SA/YAQEKCh0AAIBDLQAAAEMiMQoSRmxvYXRJbmNvcnJlY3RUeXBlEhsKA3ZhbBgBIAEoAkIOukgLEgkhAAAAAAAAAAAiJwoMRmxvYXRFeGFtcGxlEhcKA3ZhbBgBIAEoAkIKukgHCgVNAAAAQSIZCgpEb3VibGVOb25lEgsKA3ZhbBgBIAEoASIqCgtEb3VibGVDb25zdBIbCgN2YWwYASABKAFCDrpICxIJCa5H4XoUrvM/IjAKCERvdWJsZUluEiQKA3ZhbBgBIAEoAUIXukgUEhIxPQrXo3A9EkAxj8L1KFyPH0AiKgoLRG91YmxlTm90SW4SGwoDdmFsGAEgASgBQg66SAsSCTkAAAAAAAAAACInCghEb3VibGVMVBIbCgN2YWwYASABKAFCDrpICxIJEQAAAAAAAAAAIigKCURvdWJsZUxURRIbCgN2YWwYASABKAFCDrpICxIJGQAAAAAAAFBAIicKCERvdWJsZUdUEhsKA3ZhbBgBIAEoAUIOukgLEgkhAAAAAAAAMEAiKAoJRG91YmxlR1RFEhsKA3ZhbBgBIAEoAUIOukgLEgkpAAAAAAAAIEAiMgoKRG91YmxlR1RMVBIkCgN2YWwYASABKAFCF7pIFBISEQAAAAAAACRAIQAAAAAAAAAAIjQKDERvdWJsZUV4TFRHVBIkCgN2YWwYASABKAFCF7pIFBISEQAAAAAAAAAAIQAAAAAAACRAIjQKDERvdWJsZUdURUxURRIkCgN2YWwYASABKAFCF7pIFBISGQAAAAAAAHBAKQAAAAAAAGBAIjYKDkRvdWJsZUV4R1RFTFRFEiQKA3ZhbBgBIAEoAUIXukgUEhIZAAAAAAAAYEApAAAAAAAAcEAiJAoMRG91YmxlRmluaXRlEhQKA3ZhbBgBIAEoAUIHukgEEgJAASInCg9Eb3VibGVOb3RGaW5pdGUSFAoDdmFsGAEgASgBQge6SAQSAkAAIjcKDERvdWJsZUlnbm9yZRInCgN2YWwYASABKAFCGrpIF9gBARISGQAAAAAAAHBAKQAAAAAAAGBAIi4KE0RvdWJsZUluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgBQgq6SAcKBSUAAAAAIiwKDURvdWJsZUV4YW1wbGUSGwoDdmFsGAEgASgBQg66SAsSCUkAAAAAAAAAACIYCglJbnQzMk5vbmUSCwoDdmFsGAEgASgFIiIKCkludDMyQ29uc3QSFAoDdmFsGAEgASgFQge6SAQaAggBIiEKB0ludDMySW4SFgoDdmFsGAEgASgFQgm6SAYaBDACMAMiIgoKSW50MzJOb3RJbhIUCgN2YWwYASABKAVCB7pIBBoCOAAiHwoHSW50MzJMVBIUCgN2YWwYASABKAVCB7pIBBoCEAAiIAoISW50MzJMVEUSFAoDdmFsGAEgASgFQge6SAQaAhhAIh8KB0ludDMyR1QSFAoDdmFsGAEgASgFQge6SAQaAiAQIiAKCEludDMyR1RFEhQKA3ZhbBgBIAEoBUIHukgEGgIoCCIjCglJbnQzMkdUTFQSFgoDdmFsGAEgASgFQgm6SAYaBBAKIAAiJQoLSW50MzJFeExUR1QSFgoDdmFsGAEgASgFQgm6SAYaBBAAIAoiJwoLSW50MzJHVEVMVEUSGAoDdmFsGAEgASgFQgu6SAgaBhiAAiiAASIpCg1JbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoBUILukgIGgYYgAEogAIiKgoLSW50MzJJZ25vcmUSGwoDdmFsGAEgASgFQg66SAvYAQEaBhiAAiiAASItChJJbnQzMkluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgFQgq6SAcKBSUAAAAAIiQKDEludDMyRXhhbXBsZRIUCgN2YWwYASABKAVCB7pIBBoCQAoiGAoJSW50NjROb25lEgsKA3ZhbBgBIAEoAyIiCgpJbnQ2NENvbnN0EhQKA3ZhbBgBIAEoA0IHukgEIgIIASIhCgdJbnQ2NEluEhYKA3ZhbBgBIAEoA0IJukgGIgQwAjADIiIKCkludDY0Tm90SW4SFAoDdmFsGAEgASgDQge6SAQiAjgAIh8KB0ludDY0TFQSFAoDdmFsGAEgASgDQge6SAQiAhAAIiAKCEludDY0TFRFEhQKA3ZhbBgBIAEoA0IHukgEIgIYQCIfCgdJbnQ2NEdUEhQKA3ZhbBgBIAEoA0IHukgEIgIgECIgCghJbnQ2NEdURRIUCgN2YWwYASABKANCB7pIBCICKAgiIwoJSW50NjRHVExUEhYKA3ZhbBgBIAEoA0IJukgGIgQQCiAAIiUKC0ludDY0RXhMVEdUEhYKA3ZhbBgBIAEoA0IJukgGIgQQACAKIicKC0ludDY0R1RFTFRFEhgKA3ZhbBgBIAEoA0ILukgIIgYYgAIogAEiKQoNSW50NjRFeEdURUxURRIYCgN2YWwYASABKANCC7pICCIGGIABKIACIioKC0ludDY0SWdub3JlEhsKA3ZhbBgBIAEoA0IOukgL2AEBIgYYgAIogAEiqwMKE0ludDY0QmlnQ29uc3RyYWludHMSGwoGbHRfcG9zGAEgASgDQgu6SAgiBhCm3YekFBIgCgZsdF9uZWcYAiABKANCELpIDSILENqi+Nvr/////wESGwoGZ3RfcG9zGAMgASgDQgu6SAgiBiCm3YekFBIgCgZndF9uZWcYBCABKANCELpIDSILINqi+Nvr/////wESHAoHbHRlX3BvcxgFIAEoA0ILukgIIgYYpt2HpBQSIQoHbHRlX25lZxgGIAEoA0IQukgNIgsY2qL42+v/////ARIcCgdndGVfcG9zGAcgASgDQgu6SAgiBiim3YekFBIhCgdndGVfbmVnGAggASgDQhC6SA0iCyjaovjb6/////8BEiEKDGNvbnN0YW50X3BvcxgJIAEoA0ILukgIIgYIpt2HpBQSJgoMY29uc3RhbnRfbmVnGAogASgDQhC6SA0iCwjaovjb6/////8BEiIKAmluGAsgASgDQha6SBMiETCm3YekFDDaovjb6/////8BEiUKBW5vdGluGAwgASgDQha6SBMiETim3YekFDjaovjb6/////8BIi0KEkludDY0SW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKANCCrpIBwoFJQAAAAAiJAoMSW50NjRFeGFtcGxlEhQKA3ZhbBgBIAEoA0IHukgEIgJICiIZCgpVSW50MzJOb25lEgsKA3ZhbBgBIAEoDSIjCgtVSW50MzJDb25zdBIUCgN2YWwYASABKA1CB7pIBCoCCAEiIgoIVUludDMySW4SFgoDdmFsGAEgASgNQgm6SAYqBDACMAMiIwoLVUludDMyTm90SW4SFAoDdmFsGAEgASgNQge6SAQqAjgAIiAKCFVJbnQzMkxUEhQKA3ZhbBgBIAEoDUIHukgEKgIQBSIhCglVSW50MzJMVEUSFAoDdmFsGAEgASgNQge6SAQqAhhAIiAKCFVJbnQzMkdUEhQKA3ZhbBgBIAEoDUIHukgEKgIgECIhCglVSW50MzJHVEUSFAoDdmFsGAEgASgNQge6SAQqAigIIiQKClVJbnQzMkdUTFQSFgoDdmFsGAEgASgNQgm6SAYqBBAKIAUiJgoMVUludDMyRXhMVEdUEhYKA3ZhbBgBIAEoDUIJukgGKgQQBSAKIigKDFVJbnQzMkdURUxURRIYCgN2YWwYASABKA1CC7pICCoGGIACKIABIioKDlVJbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoDUILukgIKgYYgAEogAIiKwoMVUludDMySWdub3JlEhsKA3ZhbBgBIAEoDUIOukgL2AEBKgYYgAIogAEiLgoTVUludDMySW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKA1CCrpIBwoFJQAAAAAiJQoNVUludDMyRXhhbXBsZRIUCgN2YWwYASABKA1CB7pIBCoCQAAiGQoKVUludDY0Tm9uZRILCgN2YWwYASABKAQiIwoLVUludDY0Q29uc3QSFAoDdmFsGAEgASgEQge6SAQyAggBIiIKCFVJbnQ2NEluEhYKA3ZhbBgBIAEoBEIJukgGMgQwAjADIiMKC1VJbnQ2NE5vdEluEhQKA3ZhbBgBIAEoBEIHukgEMgI4ACIgCghVSW50NjRMVBIUCgN2YWwYASABKARCB7pIBDICEAUiIQoJVUludDY0TFRFEhQKA3ZhbBgBIAEoBEIHukgEMgIYQCIgCghVSW50NjRHVBIUCgN2YWwYASABKARCB7pIBDICIBAiIQoJVUludDY0R1RFEhQKA3ZhbBgBIAEoBEIHukgEMgIoCCIkCgpVSW50NjRHVExUEhYKA3ZhbBgBIAEoBEIJukgGMgQQCiAFIiYKDFVJbnQ2NEV4TFRHVBIWCgN2YWwYASABKARCCbpIBjIEEAUgCiIoCgxVSW50NjRHVEVMVEUSGAoDdmFsGAEgASgEQgu6SAgyBhiAAiiAASIqCg5VSW50NjRFeEdURUxURRIYCgN2YWwYASABKARCC7pICDIGGIABKIACIisKDFVJbnQ2NElnbm9yZRIbCgN2YWwYASABKARCDrpIC9gBATIGGIACKIABIi4KE1VJbnQ2NEluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgEQgq6SAcKBSUAAAAAIiUKDVVJbnQ2NEV4YW1wbGUSFAoDdmFsGAEgASgEQge6SAQyAkAAIhkKClNJbnQzMk5vbmUSCwoDdmFsGAEgASgRIiMKC1NJbnQzMkNvbnN0EhQKA3ZhbBgBIAEoEUIHukgEOgIIAiIiCghTSW50MzJJbhIWCgN2YWwYASABKBFCCbpIBjoEMAQwBiIjCgtTSW50MzJOb3RJbhIUCgN2YWwYASABKBFCB7pIBDoCOAAiIAoIU0ludDMyTFQSFAoDdmFsGAEgASgRQge6SAQ6AhAAIiIKCVNJbnQzMkxURRIVCgN2YWwYASABKBFCCLpIBToDGIABIiAKCFNJbnQzMkdUEhQKA3ZhbBgBIAEoEUIHukgEOgIgICIhCglTSW50MzJHVEUSFAoDdmFsGAEgASgRQge6SAQ6AigQIiQKClNJbnQzMkdUTFQSFgoDdmFsGAEgASgRQgm6SAY6BBAUIAAiJgoMU0ludDMyRXhMVEdUEhYKA3ZhbBgBIAEoEUIJukgGOgQQACAUIigKDFNJbnQzMkdURUxURRIYCgN2YWwYASABKBFCC7pICDoGGIAEKIACIioKDlNJbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoEUILukgIOgYYgAIogAQiKwoMU0ludDMySWdub3JlEhsKA3ZhbBgBIAEoEUIOukgL2AEBOgYYgAQogAIiLgoTU0ludDMySW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKBFCCrpIBwoFJQAAAAAiJQoNU0ludDMyRXhhbXBsZRIUCgN2YWwYASABKBFCB7pIBDoCQAAiGQoKU0ludDY0Tm9uZRILCgN2YWwYASABKBIiIwoLU0ludDY0Q29uc3QSFAoDdmFsGAEgASgSQge6SARCAggCIiIKCFNJbnQ2NEluEhYKA3ZhbBgBIAEoEkIJukgGQgQwBDAGIiMKC1NJbnQ2NE5vdEluEhQKA3ZhbBgBIAEoEkIHukgEQgI4ACIgCghTSW50NjRMVBIUCgN2YWwYASABKBJCB7pIBEICEAAiIgoJU0ludDY0TFRFEhUKA3ZhbBgBIAEoEkIIukgFQgMYgAEiIAoIU0ludDY0R1QSFAoDdmFsGAEgASgSQge6SARCAiAgIiEKCVNJbnQ2NEdURRIUCgN2YWwYASABKBJCB7pIBEICKBAiJAoKU0ludDY0R1RMVBIWCgN2YWwYASABKBJCCbpIBkIEEBQgACImCgxTSW50NjRFeExUR1QSFgoDdmFsGAEgASgSQgm6SAZCBBAAIBQiKAoMU0ludDY0R1RFTFRFEhgKA3ZhbBgBIAEoEkILukgIQgYYgAQogAIiKgoOU0ludDY0RXhHVEVMVEUSGAoDdmFsGAEgASgSQgu6SAhCBhiAAiiABCIrCgxTSW50NjRJZ25vcmUSGwoDdmFsGAEgASgSQg66SAvYAQFCBhiABCiAAiIuChNTSW50NjRJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoEkIKukgHCgUlAAAAACIlCg1TSW50NjRFeGFtcGxlEhQKA3ZhbBgBIAEoEkIHukgEQgJAACIaCgtGaXhlZDMyTm9uZRILCgN2YWwYASABKAciJwoMRml4ZWQzMkNvbnN0EhcKA3ZhbBgBIAEoB0IKukgHSgUNAQAAACIpCglGaXhlZDMySW4SHAoDdmFsGAEgASgHQg+6SAxKCjUCAAAANQMAAAAiJwoMRml4ZWQzMk5vdEluEhcKA3ZhbBgBIAEoB0IKukgHSgU9AAAAACIkCglGaXhlZDMyTFQSFwoDdmFsGAEgASgHQgq6SAdKBRUFAAAAIiUKCkZpeGVkMzJMVEUSFwoDdmFsGAEgASgHQgq6SAdKBR1AAAAAIiQKCUZpeGVkMzJHVBIXCgN2YWwYASABKAdCCrpIB0oFJRAAAAAiJQoKRml4ZWQzMkdURRIXCgN2YWwYASABKAdCCrpIB0oFLQgAAAAiKwoLRml4ZWQzMkdUTFQSHAoDdmFsGAEgASgHQg+6SAxKChUKAAAAJQUAAAAiLQoNRml4ZWQzMkV4TFRHVBIcCgN2YWwYASABKAdCD7pIDEoKFQUAAAAlCgAAACItCg1GaXhlZDMyR1RFTFRFEhwKA3ZhbBgBIAEoB0IPukgMSgodAAEAAC2AAAAAIi8KD0ZpeGVkMzJFeEdURUxURRIcCgN2YWwYASABKAdCD7pIDEoKHYAAAAAtAAEAACIwCg1GaXhlZDMySWdub3JlEh8KA3ZhbBgBIAEoB0ISukgP2AEBSgodAAEAAC2AAAAAIi8KFEZpeGVkMzJJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoB0IKukgHCgUlAAAAACIpCg5GaXhlZDMyRXhhbXBsZRIXCgN2YWwYASABKAdCCrpIB0oFRQAAAAAiGgoLRml4ZWQ2NE5vbmUSCwoDdmFsGAEgASgGIisKDEZpeGVkNjRDb25zdBIbCgN2YWwYASABKAZCDrpIC1IJCQEAAAAAAAAAIjEKCUZpeGVkNjRJbhIkCgN2YWwYASABKAZCF7pIFFISMQIAAAAAAAAAMQMAAAAAAAAAIisKDEZpeGVkNjROb3RJbhIbCgN2YWwYASABKAZCDrpIC1IJOQAAAAAAAAAAIigKCUZpeGVkNjRMVBIbCgN2YWwYASABKAZCDrpIC1IJEQUAAAAAAAAAIikKCkZpeGVkNjRMVEUSGwoDdmFsGAEgASgGQg66SAtSCRlAAAAAAAAAACIoCglGaXhlZDY0R1QSGwoDdmFsGAEgASgGQg66SAtSCSEQAAAAAAAAACIpCgpGaXhlZDY0R1RFEhsKA3ZhbBgBIAEoBkIOukgLUgkpCAAAAAAAAAAiMwoLRml4ZWQ2NEdUTFQSJAoDdmFsGAEgASgGQhe6SBRSEhEKAAAAAAAAACEFAAAAAAAAACI1Cg1GaXhlZDY0RXhMVEdUEiQKA3ZhbBgBIAEoBkIXukgUUhIRBQAAAAAAAAAhCgAAAAAAAAAiNQoNRml4ZWQ2NEdURUxURRIkCgN2YWwYASABKAZCF7pIFFISGQABAAAAAAAAKYAAAAAAAAAAIjcKD0ZpeGVkNjRFeEdURUxURRIkCgN2YWwYASABKAZCF7pIFFISGYAAAAAAAAAAKQABAAAAAAAAIjgKDUZpeGVkNjRJZ25vcmUSJwoDdmFsGAEgASgGQhq6SBfYAQFSEhkAAQAAAAAAACmAAAAAAAAAACIvChRGaXhlZDY0SW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKAZCCrpIBwoFJQAAAAAiLQoORml4ZWQ2NEV4YW1wbGUSGwoDdmFsGAEgASgGQg66SAtSCUEAAAAAAAAAACIbCgxTRml4ZWQzMk5vbmUSCwoDdmFsGAEgASgPIigKDVNGaXhlZDMyQ29uc3QSFwoDdmFsGAEgASgPQgq6SAdaBQ0BAAAAIioKClNGaXhlZDMySW4SHAoDdmFsGAEgASgPQg+6SAxaCjUCAAAANQMAAAAiKAoNU0ZpeGVkMzJOb3RJbhIXCgN2YWwYASABKA9CCrpIB1oFPQAAAAAiJQoKU0ZpeGVkMzJMVBIXCgN2YWwYASABKA9CCrpIB1oFFQAAAAAiJgoLU0ZpeGVkMzJMVEUSFwoDdmFsGAEgASgPQgq6SAdaBR1AAAAAIiUKClNGaXhlZDMyR1QSFwoDdmFsGAEgASgPQgq6SAdaBSUQAAAAIiYKC1NGaXhlZDMyR1RFEhcKA3ZhbBgBIAEoD0IKukgHWgUtCAAAACIsCgxTRml4ZWQzMkdUTFQSHAoDdmFsGAEgASgPQg+6SAxaChUKAAAAJQAAAAAiLgoOU0ZpeGVkMzJFeExUR1QSHAoDdmFsGAEgASgPQg+6SAxaChUAAAAAJQoAAAAiLgoOU0ZpeGVkMzJHVEVMVEUSHAoDdmFsGAEgASgPQg+6SAxaCh0AAQAALYAAAAAiMAoQU0ZpeGVkMzJFeEdURUxURRIcCgN2YWwYASABKA9CD7pIDFoKHYAAAAAtAAEAACIxCg5TRml4ZWQzMklnbm9yZRIfCgN2YWwYASABKA9CErpID9gBAVoKHQABAAAtgAAAACIwChVTRml4ZWQzMkluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgPQgq6SAcKBSUAAAAAIioKD1NGaXhlZDMyRXhhbXBsZRIXCgN2YWwYASABKA9CCrpIB1oFRQAAAAAiGwoMU0ZpeGVkNjROb25lEgsKA3ZhbBgBIAEoECIsCg1TRml4ZWQ2NENvbnN0EhsKA3ZhbBgBIAEoEEIOukgLYgkJAQAAAAAAAAAiMgoKU0ZpeGVkNjRJbhIkCgN2YWwYASABKBBCF7pIFGISMQIAAAAAAAAAMQMAAAAAAAAAIiwKDVNGaXhlZDY0Tm90SW4SGwoDdmFsGAEgASgQQg66SAtiCTkAAAAAAAAAACIpCgpTRml4ZWQ2NExUEhsKA3ZhbBgBIAEoEEIOukgLYgkRAAAAAAAAAAAiKgoLU0ZpeGVkNjRMVEUSGwoDdmFsGAEgASgQQg66SAtiCRlAAAAAAAAAACIpCgpTRml4ZWQ2NEdUEhsKA3ZhbBgBIAEoEEIOukgLYgkhEAAAAAAAAAAiKgoLU0ZpeGVkNjRHVEUSGwoDdmFsGAEgASgQQg66SAtiCSkIAAAAAAAAACI0CgxTRml4ZWQ2NEdUTFQSJAoDdmFsGAEgASgQQhe6SBRiEhEKAAAAAAAAACEAAAAAAAAAACI2Cg5TRml4ZWQ2NEV4TFRHVBIkCgN2YWwYASABKBBCF7pIFGISEQAAAAAAAAAAIQoAAAAAAAAAIjYKDlNGaXhlZDY0R1RFTFRFEiQKA3ZhbBgBIAEoEEIXukgUYhIZAAEAAAAAAAApgAAAAAAAAAAiOAoQU0ZpeGVkNjRFeEdURUxURRIkCgN2YWwYASABKBBCF7pIFGISGYAAAAAAAAAAKQABAAAAAAAAIjkKDlNGaXhlZDY0SWdub3JlEicKA3ZhbBgBIAEoEEIaukgX2AEBYhIZAAEAAAAAAAApgAAAAAAAAAAiMAoVU0ZpeGVkNjRJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoEEIKukgHCgUlAAAAACIuCg9TRml4ZWQ2NEV4YW1wbGUSGwoDdmFsGAEgASgQQg66SAtiCUEAAAAAAAAAACI1ChBJbnQ2NExURU9wdGlvbmFsEhkKA3ZhbBgBIAEoA0IHukgEIgIYQEgAiAEBQgYKBF92YWxiBnByb3RvMw", [file_buf_validate_validate]);
+ fileDesc("CixidWYvdmFsaWRhdGUvY29uZm9ybWFuY2UvY2FzZXMvbnVtYmVycy5wcm90bxIeYnVmLnZhbGlkYXRlLmNvbmZvcm1hbmNlLmNhc2VzIhgKCUZsb2F0Tm9uZRILCgN2YWwYASABKAIiJQoKRmxvYXRDb25zdBIXCgN2YWwYASABKAJCCrpIBwoFDaRwnT8iJwoHRmxvYXRJbhIcCgN2YWwYASABKAJCD7pIDAoKNYXrkUA14Xr8QCIlCgpGbG9hdE5vdEluEhcKA3ZhbBgBIAEoAkIKukgHCgU9AAAAACIiCgdGbG9hdExUEhcKA3ZhbBgBIAEoAkIKukgHCgUVAAAAACIjCghGbG9hdExURRIXCgN2YWwYASABKAJCCrpIBwoFHQAAgEIiIgoHRmxvYXRHVBIXCgN2YWwYASABKAJCCrpIBwoFJQAAgEEiIwoIRmxvYXRHVEUSFwoDdmFsGAEgASgCQgq6SAcKBS0AAABBIikKCUZsb2F0R1RMVBIcCgN2YWwYASABKAJCD7pIDAoKFQAAIEElAAAAACIrCgtGbG9hdEV4TFRHVBIcCgN2YWwYASABKAJCD7pIDAoKFQAAAAAlAAAgQSIrCgtGbG9hdEdURUxURRIcCgN2YWwYASABKAJCD7pIDAoKHQAAgEMtAAAAQyItCg1GbG9hdEV4R1RFTFRFEhwKA3ZhbBgBIAEoAkIPukgMCgodAAAAQy0AAIBDIiMKC0Zsb2F0RmluaXRlEhQKA3ZhbBgBIAEoAkIHukgECgJAASImCg5GbG9hdE5vdEZpbml0ZRIUCgN2YWwYASABKAJCB7pIBAoCQAAiLgoLRmxvYXRJZ25vcmUSHwoDdmFsGAEgASgCQhK6SA/YAQEKCh0AAIBDLQAAAEMiMQoSRmxvYXRJbmNvcnJlY3RUeXBlEhsKA3ZhbBgBIAEoAkIOukgLEgkhAAAAAAAAAAAiJwoMRmxvYXRFeGFtcGxlEhcKA3ZhbBgBIAEoAkIKukgHCgVNAAAAQSIZCgpEb3VibGVOb25lEgsKA3ZhbBgBIAEoASIqCgtEb3VibGVDb25zdBIbCgN2YWwYASABKAFCDrpICxIJCa5H4XoUrvM/IjAKCERvdWJsZUluEiQKA3ZhbBgBIAEoAUIXukgUEhIxPQrXo3A9EkAxj8L1KFyPH0AiKgoLRG91YmxlTm90SW4SGwoDdmFsGAEgASgBQg66SAsSCTkAAAAAAAAAACInCghEb3VibGVMVBIbCgN2YWwYASABKAFCDrpICxIJEQAAAAAAAAAAIigKCURvdWJsZUxURRIbCgN2YWwYASABKAFCDrpICxIJGQAAAAAAAFBAIicKCERvdWJsZUdUEhsKA3ZhbBgBIAEoAUIOukgLEgkhAAAAAAAAMEAiKAoJRG91YmxlR1RFEhsKA3ZhbBgBIAEoAUIOukgLEgkpAAAAAAAAIEAiMgoKRG91YmxlR1RMVBIkCgN2YWwYASABKAFCF7pIFBISEQAAAAAAACRAIQAAAAAAAAAAIjQKDERvdWJsZUV4TFRHVBIkCgN2YWwYASABKAFCF7pIFBISEQAAAAAAAAAAIQAAAAAAACRAIjQKDERvdWJsZUdURUxURRIkCgN2YWwYASABKAFCF7pIFBISGQAAAAAAAHBAKQAAAAAAAGBAIjYKDkRvdWJsZUV4R1RFTFRFEiQKA3ZhbBgBIAEoAUIXukgUEhIZAAAAAAAAYEApAAAAAAAAcEAiJAoMRG91YmxlRmluaXRlEhQKA3ZhbBgBIAEoAUIHukgEEgJAASInCg9Eb3VibGVOb3RGaW5pdGUSFAoDdmFsGAEgASgBQge6SAQSAkAAIjcKDERvdWJsZUlnbm9yZRInCgN2YWwYASABKAFCGrpIF9gBARISGQAAAAAAAHBAKQAAAAAAAGBAIi4KE0RvdWJsZUluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgBQgq6SAcKBSUAAAAAIiwKDURvdWJsZUV4YW1wbGUSGwoDdmFsGAEgASgBQg66SAsSCUkAAAAAAAAAACIYCglJbnQzMk5vbmUSCwoDdmFsGAEgASgFIiIKCkludDMyQ29uc3QSFAoDdmFsGAEgASgFQge6SAQaAggBIiEKB0ludDMySW4SFgoDdmFsGAEgASgFQgm6SAYaBDACMAMiIgoKSW50MzJOb3RJbhIUCgN2YWwYASABKAVCB7pIBBoCOAAiHwoHSW50MzJMVBIUCgN2YWwYASABKAVCB7pIBBoCEAAiIAoISW50MzJMVEUSFAoDdmFsGAEgASgFQge6SAQaAhhAIh8KB0ludDMyR1QSFAoDdmFsGAEgASgFQge6SAQaAiAQIiAKCEludDMyR1RFEhQKA3ZhbBgBIAEoBUIHukgEGgIoCCIjCglJbnQzMkdUTFQSFgoDdmFsGAEgASgFQgm6SAYaBBAKIAAiJQoLSW50MzJFeExUR1QSFgoDdmFsGAEgASgFQgm6SAYaBBAAIAoiJwoLSW50MzJHVEVMVEUSGAoDdmFsGAEgASgFQgu6SAgaBhiAAiiAASIpCg1JbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoBUILukgIGgYYgAEogAIiKgoLSW50MzJJZ25vcmUSGwoDdmFsGAEgASgFQg66SAvYAQEaBhiAAiiAASItChJJbnQzMkluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgFQgq6SAcKBSUAAAAAIiQKDEludDMyRXhhbXBsZRIUCgN2YWwYASABKAVCB7pIBBoCQAoiGAoJSW50NjROb25lEgsKA3ZhbBgBIAEoAyIiCgpJbnQ2NENvbnN0EhQKA3ZhbBgBIAEoA0IHukgEIgIIASIhCgdJbnQ2NEluEhYKA3ZhbBgBIAEoA0IJukgGIgQwAjADIiIKCkludDY0Tm90SW4SFAoDdmFsGAEgASgDQge6SAQiAjgAIh8KB0ludDY0TFQSFAoDdmFsGAEgASgDQge6SAQiAhAAIiAKCEludDY0TFRFEhQKA3ZhbBgBIAEoA0IHukgEIgIYQCIfCgdJbnQ2NEdUEhQKA3ZhbBgBIAEoA0IHukgEIgIgECIgCghJbnQ2NEdURRIUCgN2YWwYASABKANCB7pIBCICKAgiIwoJSW50NjRHVExUEhYKA3ZhbBgBIAEoA0IJukgGIgQQCiAAIiUKC0ludDY0RXhMVEdUEhYKA3ZhbBgBIAEoA0IJukgGIgQQACAKIicKC0ludDY0R1RFTFRFEhgKA3ZhbBgBIAEoA0ILukgIIgYYgAIogAEiKQoNSW50NjRFeEdURUxURRIYCgN2YWwYASABKANCC7pICCIGGIABKIACIioKC0ludDY0SWdub3JlEhsKA3ZhbBgBIAEoA0IOukgL2AEBIgYYgAIogAEipQMKDUludDY0QmlnUnVsZXMSGwoGbHRfcG9zGAEgASgDQgu6SAgiBhCm3YekFBIgCgZsdF9uZWcYAiABKANCELpIDSILENqi+Nvr/////wESGwoGZ3RfcG9zGAMgASgDQgu6SAgiBiCm3YekFBIgCgZndF9uZWcYBCABKANCELpIDSILINqi+Nvr/////wESHAoHbHRlX3BvcxgFIAEoA0ILukgIIgYYpt2HpBQSIQoHbHRlX25lZxgGIAEoA0IQukgNIgsY2qL42+v/////ARIcCgdndGVfcG9zGAcgASgDQgu6SAgiBiim3YekFBIhCgdndGVfbmVnGAggASgDQhC6SA0iCyjaovjb6/////8BEiEKDGNvbnN0YW50X3BvcxgJIAEoA0ILukgIIgYIpt2HpBQSJgoMY29uc3RhbnRfbmVnGAogASgDQhC6SA0iCwjaovjb6/////8BEiIKAmluGAsgASgDQha6SBMiETCm3YekFDDaovjb6/////8BEiUKBW5vdGluGAwgASgDQha6SBMiETim3YekFDjaovjb6/////8BIi0KEkludDY0SW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKANCCrpIBwoFJQAAAAAiJAoMSW50NjRFeGFtcGxlEhQKA3ZhbBgBIAEoA0IHukgEIgJICiIZCgpVSW50MzJOb25lEgsKA3ZhbBgBIAEoDSIjCgtVSW50MzJDb25zdBIUCgN2YWwYASABKA1CB7pIBCoCCAEiIgoIVUludDMySW4SFgoDdmFsGAEgASgNQgm6SAYqBDACMAMiIwoLVUludDMyTm90SW4SFAoDdmFsGAEgASgNQge6SAQqAjgAIiAKCFVJbnQzMkxUEhQKA3ZhbBgBIAEoDUIHukgEKgIQBSIhCglVSW50MzJMVEUSFAoDdmFsGAEgASgNQge6SAQqAhhAIiAKCFVJbnQzMkdUEhQKA3ZhbBgBIAEoDUIHukgEKgIgECIhCglVSW50MzJHVEUSFAoDdmFsGAEgASgNQge6SAQqAigIIiQKClVJbnQzMkdUTFQSFgoDdmFsGAEgASgNQgm6SAYqBBAKIAUiJgoMVUludDMyRXhMVEdUEhYKA3ZhbBgBIAEoDUIJukgGKgQQBSAKIigKDFVJbnQzMkdURUxURRIYCgN2YWwYASABKA1CC7pICCoGGIACKIABIioKDlVJbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoDUILukgIKgYYgAEogAIiKwoMVUludDMySWdub3JlEhsKA3ZhbBgBIAEoDUIOukgL2AEBKgYYgAIogAEiLgoTVUludDMySW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKA1CCrpIBwoFJQAAAAAiJQoNVUludDMyRXhhbXBsZRIUCgN2YWwYASABKA1CB7pIBCoCQAAiGQoKVUludDY0Tm9uZRILCgN2YWwYASABKAQiIwoLVUludDY0Q29uc3QSFAoDdmFsGAEgASgEQge6SAQyAggBIiIKCFVJbnQ2NEluEhYKA3ZhbBgBIAEoBEIJukgGMgQwAjADIiMKC1VJbnQ2NE5vdEluEhQKA3ZhbBgBIAEoBEIHukgEMgI4ACIgCghVSW50NjRMVBIUCgN2YWwYASABKARCB7pIBDICEAUiIQoJVUludDY0TFRFEhQKA3ZhbBgBIAEoBEIHukgEMgIYQCIgCghVSW50NjRHVBIUCgN2YWwYASABKARCB7pIBDICIBAiIQoJVUludDY0R1RFEhQKA3ZhbBgBIAEoBEIHukgEMgIoCCIkCgpVSW50NjRHVExUEhYKA3ZhbBgBIAEoBEIJukgGMgQQCiAFIiYKDFVJbnQ2NEV4TFRHVBIWCgN2YWwYASABKARCCbpIBjIEEAUgCiIoCgxVSW50NjRHVEVMVEUSGAoDdmFsGAEgASgEQgu6SAgyBhiAAiiAASIqCg5VSW50NjRFeEdURUxURRIYCgN2YWwYASABKARCC7pICDIGGIABKIACIisKDFVJbnQ2NElnbm9yZRIbCgN2YWwYASABKARCDrpIC9gBATIGGIACKIABIi4KE1VJbnQ2NEluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgEQgq6SAcKBSUAAAAAIiUKDVVJbnQ2NEV4YW1wbGUSFAoDdmFsGAEgASgEQge6SAQyAkAAIhkKClNJbnQzMk5vbmUSCwoDdmFsGAEgASgRIiMKC1NJbnQzMkNvbnN0EhQKA3ZhbBgBIAEoEUIHukgEOgIIAiIiCghTSW50MzJJbhIWCgN2YWwYASABKBFCCbpIBjoEMAQwBiIjCgtTSW50MzJOb3RJbhIUCgN2YWwYASABKBFCB7pIBDoCOAAiIAoIU0ludDMyTFQSFAoDdmFsGAEgASgRQge6SAQ6AhAAIiIKCVNJbnQzMkxURRIVCgN2YWwYASABKBFCCLpIBToDGIABIiAKCFNJbnQzMkdUEhQKA3ZhbBgBIAEoEUIHukgEOgIgICIhCglTSW50MzJHVEUSFAoDdmFsGAEgASgRQge6SAQ6AigQIiQKClNJbnQzMkdUTFQSFgoDdmFsGAEgASgRQgm6SAY6BBAUIAAiJgoMU0ludDMyRXhMVEdUEhYKA3ZhbBgBIAEoEUIJukgGOgQQACAUIigKDFNJbnQzMkdURUxURRIYCgN2YWwYASABKBFCC7pICDoGGIAEKIACIioKDlNJbnQzMkV4R1RFTFRFEhgKA3ZhbBgBIAEoEUILukgIOgYYgAIogAQiKwoMU0ludDMySWdub3JlEhsKA3ZhbBgBIAEoEUIOukgL2AEBOgYYgAQogAIiLgoTU0ludDMySW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKBFCCrpIBwoFJQAAAAAiJQoNU0ludDMyRXhhbXBsZRIUCgN2YWwYASABKBFCB7pIBDoCQAAiGQoKU0ludDY0Tm9uZRILCgN2YWwYASABKBIiIwoLU0ludDY0Q29uc3QSFAoDdmFsGAEgASgSQge6SARCAggCIiIKCFNJbnQ2NEluEhYKA3ZhbBgBIAEoEkIJukgGQgQwBDAGIiMKC1NJbnQ2NE5vdEluEhQKA3ZhbBgBIAEoEkIHukgEQgI4ACIgCghTSW50NjRMVBIUCgN2YWwYASABKBJCB7pIBEICEAAiIgoJU0ludDY0TFRFEhUKA3ZhbBgBIAEoEkIIukgFQgMYgAEiIAoIU0ludDY0R1QSFAoDdmFsGAEgASgSQge6SARCAiAgIiEKCVNJbnQ2NEdURRIUCgN2YWwYASABKBJCB7pIBEICKBAiJAoKU0ludDY0R1RMVBIWCgN2YWwYASABKBJCCbpIBkIEEBQgACImCgxTSW50NjRFeExUR1QSFgoDdmFsGAEgASgSQgm6SAZCBBAAIBQiKAoMU0ludDY0R1RFTFRFEhgKA3ZhbBgBIAEoEkILukgIQgYYgAQogAIiKgoOU0ludDY0RXhHVEVMVEUSGAoDdmFsGAEgASgSQgu6SAhCBhiAAiiABCIrCgxTSW50NjRJZ25vcmUSGwoDdmFsGAEgASgSQg66SAvYAQFCBhiABCiAAiIuChNTSW50NjRJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoEkIKukgHCgUlAAAAACIlCg1TSW50NjRFeGFtcGxlEhQKA3ZhbBgBIAEoEkIHukgEQgJAACIaCgtGaXhlZDMyTm9uZRILCgN2YWwYASABKAciJwoMRml4ZWQzMkNvbnN0EhcKA3ZhbBgBIAEoB0IKukgHSgUNAQAAACIpCglGaXhlZDMySW4SHAoDdmFsGAEgASgHQg+6SAxKCjUCAAAANQMAAAAiJwoMRml4ZWQzMk5vdEluEhcKA3ZhbBgBIAEoB0IKukgHSgU9AAAAACIkCglGaXhlZDMyTFQSFwoDdmFsGAEgASgHQgq6SAdKBRUFAAAAIiUKCkZpeGVkMzJMVEUSFwoDdmFsGAEgASgHQgq6SAdKBR1AAAAAIiQKCUZpeGVkMzJHVBIXCgN2YWwYASABKAdCCrpIB0oFJRAAAAAiJQoKRml4ZWQzMkdURRIXCgN2YWwYASABKAdCCrpIB0oFLQgAAAAiKwoLRml4ZWQzMkdUTFQSHAoDdmFsGAEgASgHQg+6SAxKChUKAAAAJQUAAAAiLQoNRml4ZWQzMkV4TFRHVBIcCgN2YWwYASABKAdCD7pIDEoKFQUAAAAlCgAAACItCg1GaXhlZDMyR1RFTFRFEhwKA3ZhbBgBIAEoB0IPukgMSgodAAEAAC2AAAAAIi8KD0ZpeGVkMzJFeEdURUxURRIcCgN2YWwYASABKAdCD7pIDEoKHYAAAAAtAAEAACIwCg1GaXhlZDMySWdub3JlEh8KA3ZhbBgBIAEoB0ISukgP2AEBSgodAAEAAC2AAAAAIi8KFEZpeGVkMzJJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoB0IKukgHCgUlAAAAACIpCg5GaXhlZDMyRXhhbXBsZRIXCgN2YWwYASABKAdCCrpIB0oFRQAAAAAiGgoLRml4ZWQ2NE5vbmUSCwoDdmFsGAEgASgGIisKDEZpeGVkNjRDb25zdBIbCgN2YWwYASABKAZCDrpIC1IJCQEAAAAAAAAAIjEKCUZpeGVkNjRJbhIkCgN2YWwYASABKAZCF7pIFFISMQIAAAAAAAAAMQMAAAAAAAAAIisKDEZpeGVkNjROb3RJbhIbCgN2YWwYASABKAZCDrpIC1IJOQAAAAAAAAAAIigKCUZpeGVkNjRMVBIbCgN2YWwYASABKAZCDrpIC1IJEQUAAAAAAAAAIikKCkZpeGVkNjRMVEUSGwoDdmFsGAEgASgGQg66SAtSCRlAAAAAAAAAACIoCglGaXhlZDY0R1QSGwoDdmFsGAEgASgGQg66SAtSCSEQAAAAAAAAACIpCgpGaXhlZDY0R1RFEhsKA3ZhbBgBIAEoBkIOukgLUgkpCAAAAAAAAAAiMwoLRml4ZWQ2NEdUTFQSJAoDdmFsGAEgASgGQhe6SBRSEhEKAAAAAAAAACEFAAAAAAAAACI1Cg1GaXhlZDY0RXhMVEdUEiQKA3ZhbBgBIAEoBkIXukgUUhIRBQAAAAAAAAAhCgAAAAAAAAAiNQoNRml4ZWQ2NEdURUxURRIkCgN2YWwYASABKAZCF7pIFFISGQABAAAAAAAAKYAAAAAAAAAAIjcKD0ZpeGVkNjRFeEdURUxURRIkCgN2YWwYASABKAZCF7pIFFISGYAAAAAAAAAAKQABAAAAAAAAIjgKDUZpeGVkNjRJZ25vcmUSJwoDdmFsGAEgASgGQhq6SBfYAQFSEhkAAQAAAAAAACmAAAAAAAAAACIvChRGaXhlZDY0SW5jb3JyZWN0VHlwZRIXCgN2YWwYASABKAZCCrpIBwoFJQAAAAAiLQoORml4ZWQ2NEV4YW1wbGUSGwoDdmFsGAEgASgGQg66SAtSCUEAAAAAAAAAACIbCgxTRml4ZWQzMk5vbmUSCwoDdmFsGAEgASgPIigKDVNGaXhlZDMyQ29uc3QSFwoDdmFsGAEgASgPQgq6SAdaBQ0BAAAAIioKClNGaXhlZDMySW4SHAoDdmFsGAEgASgPQg+6SAxaCjUCAAAANQMAAAAiKAoNU0ZpeGVkMzJOb3RJbhIXCgN2YWwYASABKA9CCrpIB1oFPQAAAAAiJQoKU0ZpeGVkMzJMVBIXCgN2YWwYASABKA9CCrpIB1oFFQAAAAAiJgoLU0ZpeGVkMzJMVEUSFwoDdmFsGAEgASgPQgq6SAdaBR1AAAAAIiUKClNGaXhlZDMyR1QSFwoDdmFsGAEgASgPQgq6SAdaBSUQAAAAIiYKC1NGaXhlZDMyR1RFEhcKA3ZhbBgBIAEoD0IKukgHWgUtCAAAACIsCgxTRml4ZWQzMkdUTFQSHAoDdmFsGAEgASgPQg+6SAxaChUKAAAAJQAAAAAiLgoOU0ZpeGVkMzJFeExUR1QSHAoDdmFsGAEgASgPQg+6SAxaChUAAAAAJQoAAAAiLgoOU0ZpeGVkMzJHVEVMVEUSHAoDdmFsGAEgASgPQg+6SAxaCh0AAQAALYAAAAAiMAoQU0ZpeGVkMzJFeEdURUxURRIcCgN2YWwYASABKA9CD7pIDFoKHYAAAAAtAAEAACIxCg5TRml4ZWQzMklnbm9yZRIfCgN2YWwYASABKA9CErpID9gBAVoKHQABAAAtgAAAACIwChVTRml4ZWQzMkluY29ycmVjdFR5cGUSFwoDdmFsGAEgASgPQgq6SAcKBSUAAAAAIioKD1NGaXhlZDMyRXhhbXBsZRIXCgN2YWwYASABKA9CCrpIB1oFRQAAAAAiGwoMU0ZpeGVkNjROb25lEgsKA3ZhbBgBIAEoECIsCg1TRml4ZWQ2NENvbnN0EhsKA3ZhbBgBIAEoEEIOukgLYgkJAQAAAAAAAAAiMgoKU0ZpeGVkNjRJbhIkCgN2YWwYASABKBBCF7pIFGISMQIAAAAAAAAAMQMAAAAAAAAAIiwKDVNGaXhlZDY0Tm90SW4SGwoDdmFsGAEgASgQQg66SAtiCTkAAAAAAAAAACIpCgpTRml4ZWQ2NExUEhsKA3ZhbBgBIAEoEEIOukgLYgkRAAAAAAAAAAAiKgoLU0ZpeGVkNjRMVEUSGwoDdmFsGAEgASgQQg66SAtiCRlAAAAAAAAAACIpCgpTRml4ZWQ2NEdUEhsKA3ZhbBgBIAEoEEIOukgLYgkhEAAAAAAAAAAiKgoLU0ZpeGVkNjRHVEUSGwoDdmFsGAEgASgQQg66SAtiCSkIAAAAAAAAACI0CgxTRml4ZWQ2NEdUTFQSJAoDdmFsGAEgASgQQhe6SBRiEhEKAAAAAAAAACEAAAAAAAAAACI2Cg5TRml4ZWQ2NEV4TFRHVBIkCgN2YWwYASABKBBCF7pIFGISEQAAAAAAAAAAIQoAAAAAAAAAIjYKDlNGaXhlZDY0R1RFTFRFEiQKA3ZhbBgBIAEoEEIXukgUYhIZAAEAAAAAAAApgAAAAAAAAAAiOAoQU0ZpeGVkNjRFeEdURUxURRIkCgN2YWwYASABKBBCF7pIFGISGYAAAAAAAAAAKQABAAAAAAAAIjkKDlNGaXhlZDY0SWdub3JlEicKA3ZhbBgBIAEoEEIaukgX2AEBYhIZAAEAAAAAAAApgAAAAAAAAAAiMAoVU0ZpeGVkNjRJbmNvcnJlY3RUeXBlEhcKA3ZhbBgBIAEoEEIKukgHCgUlAAAAACIuCg9TRml4ZWQ2NEV4YW1wbGUSGwoDdmFsGAEgASgQQg66SAtiCUEAAAAAAAAAACI1ChBJbnQ2NExURU9wdGlvbmFsEhkKA3ZhbBgBIAEoA0IHukgEIgIYQEgAiAEBQgYKBF92YWxiBnByb3RvMw", [file_buf_validate_validate]);
/**
* @generated from message buf.validate.conformance.cases.FloatNone
@@ -1082,9 +1082,9 @@ export const Int64IgnoreSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_conformance_cases_numbers, 61);
/**
- * @generated from message buf.validate.conformance.cases.Int64BigConstraints
+ * @generated from message buf.validate.conformance.cases.Int64BigRules
*/
-export type Int64BigConstraints = Message<"buf.validate.conformance.cases.Int64BigConstraints"> & {
+export type Int64BigRules = Message<"buf.validate.conformance.cases.Int64BigRules"> & {
/**
* Intentionally choose limits that are outside the range of both signed and unsigned 32-bit integers.
*
@@ -1149,10 +1149,10 @@ export type Int64BigConstraints = Message<"buf.validate.conformance.cases.Int64B
};
/**
- * Describes the message buf.validate.conformance.cases.Int64BigConstraints.
- * Use `create(Int64BigConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.conformance.cases.Int64BigRules.
+ * Use `create(Int64BigRulesSchema)` to create a new message.
*/
-export const Int64BigConstraintsSchema: GenMessage = /*@__PURE__*/
+export const Int64BigRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_conformance_cases_numbers, 62);
/**
diff --git a/packages/protovalidate-testing/src/gen/buf/validate/validate_pb.ts b/packages/protovalidate-testing/src/gen/buf/validate/validate_pb.ts
index f8a08d3d..bc99c1c9 100644
--- a/packages/protovalidate-testing/src/gen/buf/validate/validate_pb.ts
+++ b/packages/protovalidate-testing/src/gen/buf/validate/validate_pb.ts
@@ -26,11 +26,11 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file buf/validate/validate.proto.
*/
export const file_buf_validate_validate: GenFile = /*@__PURE__*/
- fileDesc("ChtidWYvdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8SDGJ1Zi52YWxpZGF0ZSI9CgpDb25zdHJhaW50EgoKAmlkGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEgoKZXhwcmVzc2lvbhgDIAEoCSJNChJNZXNzYWdlQ29uc3RyYWludHMSEAoIZGlzYWJsZWQYASABKAgSJQoDY2VsGAMgAygLMhguYnVmLnZhbGlkYXRlLkNvbnN0cmFpbnQiJAoQT25lb2ZDb25zdHJhaW50cxIQCghyZXF1aXJlZBgBIAEoCCLLCAoQRmllbGRDb25zdHJhaW50cxIlCgNjZWwYFyADKAsyGC5idWYudmFsaWRhdGUuQ29uc3RyYWludBIQCghyZXF1aXJlZBgZIAEoCBIkCgZpZ25vcmUYGyABKA4yFC5idWYudmFsaWRhdGUuSWdub3JlEikKBWZsb2F0GAEgASgLMhguYnVmLnZhbGlkYXRlLkZsb2F0UnVsZXNIABIrCgZkb3VibGUYAiABKAsyGS5idWYudmFsaWRhdGUuRG91YmxlUnVsZXNIABIpCgVpbnQzMhgDIAEoCzIYLmJ1Zi52YWxpZGF0ZS5JbnQzMlJ1bGVzSAASKQoFaW50NjQYBCABKAsyGC5idWYudmFsaWRhdGUuSW50NjRSdWxlc0gAEisKBnVpbnQzMhgFIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50MzJSdWxlc0gAEisKBnVpbnQ2NBgGIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50NjRSdWxlc0gAEisKBnNpbnQzMhgHIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50MzJSdWxlc0gAEisKBnNpbnQ2NBgIIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50NjRSdWxlc0gAEi0KB2ZpeGVkMzIYCSABKAsyGi5idWYudmFsaWRhdGUuRml4ZWQzMlJ1bGVzSAASLQoHZml4ZWQ2NBgKIAEoCzIaLmJ1Zi52YWxpZGF0ZS5GaXhlZDY0UnVsZXNIABIvCghzZml4ZWQzMhgLIAEoCzIbLmJ1Zi52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSAASLwoIc2ZpeGVkNjQYDCABKAsyGy5idWYudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAEicKBGJvb2wYDSABKAsyFy5idWYudmFsaWRhdGUuQm9vbFJ1bGVzSAASKwoGc3RyaW5nGA4gASgLMhkuYnVmLnZhbGlkYXRlLlN0cmluZ1J1bGVzSAASKQoFYnl0ZXMYDyABKAsyGC5idWYudmFsaWRhdGUuQnl0ZXNSdWxlc0gAEicKBGVudW0YECABKAsyFy5idWYudmFsaWRhdGUuRW51bVJ1bGVzSAASLwoIcmVwZWF0ZWQYEiABKAsyGy5idWYudmFsaWRhdGUuUmVwZWF0ZWRSdWxlc0gAEiUKA21hcBgTIAEoCzIWLmJ1Zi52YWxpZGF0ZS5NYXBSdWxlc0gAEiUKA2FueRgUIAEoCzIWLmJ1Zi52YWxpZGF0ZS5BbnlSdWxlc0gAEi8KCGR1cmF0aW9uGBUgASgLMhsuYnVmLnZhbGlkYXRlLkR1cmF0aW9uUnVsZXNIABIxCgl0aW1lc3RhbXAYFiABKAsyHC5idWYudmFsaWRhdGUuVGltZXN0YW1wUnVsZXNIAEIGCgR0eXBlSgQIGBAZSgQIGhAbUgdza2lwcGVkUgxpZ25vcmVfZW1wdHkiXwoVUHJlZGVmaW5lZENvbnN0cmFpbnRzEiUKA2NlbBgBIAMoCzIYLmJ1Zi52YWxpZGF0ZS5Db25zdHJhaW50SgQIGBAZSgQIGhAbUhNza2lwcGVkaWdub3JlX2VtcHR5IrUXCgpGbG9hdFJ1bGVzEmkKBWNvbnN0GAEgASgCQlrCSFcKVQoLZmxvYXQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSnwEKAmx0GAIgASgCQpABwkiMAQqJAQoIZmxvYXQubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASrwEKA2x0ZRgDIAEoAkKfAcJImwEKmAEKCWZsb2F0Lmx0ZRqKASFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEu8HCgJndBgEIAEoAkLgB8JI3AcKjQEKCGZsb2F0Lmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKwwEKC2Zsb2F0Lmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzQEKFWZsb2F0Lmd0X2x0X2V4Y2x1c2l2ZRqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCtMBCgxmbG9hdC5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrdAQoWZmxvYXQuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESuggKA2d0ZRgFIAEoAkKqCMJIpggKmwEKCWZsb2F0Lmd0ZRqNASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrSAQoMZmxvYXQuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrcAQoWZmxvYXQuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4gEKDWZsb2F0Lmd0ZV9sdGUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCuwBChdmbG9hdC5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ1CgJpbhgGIAMoAkJpwkhmCmQKCGZsb2F0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnYKBm5vdF9pbhgHIAMoAkJmwkhjCmEKDGZsb2F0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEnUKBmZpbml0ZRgIIAEoCEJlwkhiCmAKDGZsb2F0LmZpbml0ZRpQcnVsZXMuZmluaXRlID8gKHRoaXMuaXNOYW4oKSB8fCB0aGlzLmlzSW5mKCkgPyAndmFsdWUgbXVzdCBiZSBmaW5pdGUnIDogJycpIDogJycSKwoHZXhhbXBsZRgJIAMoAkIawkgXChUKDWZsb2F0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIscXCgtEb3VibGVSdWxlcxJqCgVjb25zdBgBIAEoAUJbwkhYClYKDGRvdWJsZS5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKgAQoCbHQYAiABKAFCkQHCSI0BCooBCglkb3VibGUubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASsAEKA2x0ZRgDIAEoAUKgAcJInAEKmQEKCmRvdWJsZS5sdGUaigEhaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlKT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABL0BwoCZ3QYBCABKAFC5QfCSOEHCo4BCglkb3VibGUuZ3QagAEhaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwrEAQoMZG91YmxlLmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzgEKFmRvdWJsZS5ndF9sdF9leGNsdXNpdmUaswFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrUAQoNZG91YmxlLmd0X2x0ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCt4BChdkb3VibGUuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESvwgKA2d0ZRgFIAEoAUKvCMJIqwgKnAEKCmRvdWJsZS5ndGUajQEhaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycK0wEKDWRvdWJsZS5ndGVfbHQawQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCt0BChdkb3VibGUuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4wEKDmRvdWJsZS5ndGVfbHRlGtABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrtAQoYZG91YmxlLmd0ZV9sdGVfZXhjbHVzaXZlGtABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEnYKAmluGAYgAygBQmrCSGcKZQoJZG91YmxlLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEncKBm5vdF9pbhgHIAMoAUJnwkhkCmIKDWRvdWJsZS5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ2CgZmaW5pdGUYCCABKAhCZsJIYwphCg1kb3VibGUuZmluaXRlGlBydWxlcy5maW5pdGUgPyAodGhpcy5pc05hbigpIHx8IHRoaXMuaXNJbmYoKSA/ICd2YWx1ZSBtdXN0IGJlIGZpbml0ZScgOiAnJykgOiAnJxIsCgdleGFtcGxlGAkgAygBQhvCSBgKFgoOZG91YmxlLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIucUCgpJbnQzMlJ1bGVzEmkKBWNvbnN0GAEgASgFQlrCSFcKVQoLaW50MzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSigEKAmx0GAIgASgFQnzCSHkKdwoIaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoBUKMAcJIiAEKhQEKCWludDMyLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgFQogHwkiEBwp6CghpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50MzIuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKAVC0wfCSM8HCogBCglpbnQzMi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50MzIuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdQoCaW4YBiADKAVCacJIZgpkCghpbnQzMi5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ2CgZub3RfaW4YByADKAVCZsJIYwphCgxpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIrCgdleGFtcGxlGAggAygFQhrCSBcKFQoNaW50MzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i5xQKCkludDY0UnVsZXMSaQoFY29uc3QYASABKANCWsJIVwpVCgtpbnQ2NC5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKKAQoCbHQYAiABKANCfMJIeQp3CghpbnQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKcAQoDbHRlGAMgASgDQowBwkiIAQqFAQoJaW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKXBwoCZ3QYBCABKANCiAfCSIQHCnoKCGludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwqzAQoLaW50NjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCrsBChVpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrDAQoMaW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrLAQoWaW50NjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES4wcKA2d0ZRgFIAEoA0LTB8JIzwcKiAEKCWludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsIBCgxpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKygEKFmludDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtIBCg1pbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtoBChdpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ1CgJpbhgGIAMoA0JpwkhmCmQKCGludDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnYKBm5vdF9pbhgHIAMoA0JmwkhjCmEKDGludDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEisKB2V4YW1wbGUYCSADKANCGsJIFwoVCg1pbnQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FAoLVUludDMyUnVsZXMSagoFY29uc3QYASABKA1CW8JIWApWCgx1aW50MzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSiwEKAmx0GAIgASgNQn3CSHoKeAoJdWludDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKA1CjQHCSIkBCoYBCgp1aW50MzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKA1CjQfCSIkHCnsKCXVpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHVpbnQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnVpbnQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNdWludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3VpbnQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgNQtgHwkjUBwqJAQoKdWludDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg11aW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChd1aW50MzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnVpbnQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChh1aW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdgoCaW4YBiADKA1CasJIZwplCgl1aW50MzIuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSdwoGbm90X2luGAcgAygNQmfCSGQKYgoNdWludDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEiwKB2V4YW1wbGUYCCADKA1CG8JIGAoWCg51aW50MzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i+BQKC1VJbnQ2NFJ1bGVzEmoKBWNvbnN0GAEgASgEQlvCSFgKVgoMdWludDY0LmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEosBCgJsdBgCIAEoBEJ9wkh6CngKCXVpbnQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKdAQoDbHRlGAMgASgEQo0BwkiJAQqGAQoKdWludDY0Lmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASnAcKAmd0GAQgASgEQo0HwkiJBwp7Cgl1aW50NjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrQBCgx1aW50NjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCrwBChZ1aW50NjQuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxAEKDXVpbnQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCswBChd1aW50NjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES6AcKA2d0ZRgFIAEoBELYB8JI1AcKiQEKCnVpbnQ2NC5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrDAQoNdWludDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrLAQoXdWludDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtMBCg51aW50NjQuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrbAQoYdWludDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEnYKAmluGAYgAygEQmrCSGcKZQoJdWludDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEncKBm5vdF9pbhgHIAMoBEJnwkhkCmIKDXVpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygEQhvCSBgKFgoOdWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIvgUCgtTSW50MzJSdWxlcxJqCgVjb25zdBgBIAEoEUJbwkhYClYKDHNpbnQzMi5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKLAQoCbHQYAiABKBFCfcJIegp4CglzaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEUKNAcJIiQEKhgEKCnNpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEUKNB8JIiQcKewoJc2ludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBFC2AfCSNQHCokBCgpzaW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ2CgJpbhgGIAMoEUJqwkhnCmUKCXNpbnQzMi5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ3CgZub3RfaW4YByADKBFCZ8JIZApiCg1zaW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoEUIbwkgYChYKDnNpbnQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FAoLU0ludDY0UnVsZXMSagoFY29uc3QYASABKBJCW8JIWApWCgxzaW50NjQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSiwEKAmx0GAIgASgSQn3CSHoKeAoJc2ludDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKBJCjQHCSIkBCoYBCgpzaW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKBJCjQfCSIkHCnsKCXNpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHNpbnQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnNpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNc2ludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3NpbnQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgSQtgHwkjUBwqJAQoKc2ludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg1zaW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChdzaW50NjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnNpbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChhzaW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdgoCaW4YBiADKBJCasJIZwplCglzaW50NjQuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSdwoGbm90X2luGAcgAygSQmfCSGQKYgoNc2ludDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEiwKB2V4YW1wbGUYCCADKBJCG8JIGAoWCg5zaW50NjQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iiRUKDEZpeGVkMzJSdWxlcxJrCgVjb25zdBgBIAEoB0JcwkhZClcKDWZpeGVkMzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSjAEKAmx0GAIgASgHQn7CSHsKeQoKZml4ZWQzMi5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgHQo4BwkiKAQqHAQoLZml4ZWQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoB0KSB8JIjgcKfAoKZml4ZWQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkMzIuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkMzIuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoB0LdB8JI2QcKigEKC2ZpeGVkMzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkMzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDMyLmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkMzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdwoCaW4YBiADKAdCa8JIaApmCgpmaXhlZDMyLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEngKBm5vdF9pbhgHIAMoB0JowkhlCmMKDmZpeGVkMzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoB0IcwkgZChcKD2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iiRUKDEZpeGVkNjRSdWxlcxJrCgVjb25zdBgBIAEoBkJcwkhZClcKDWZpeGVkNjQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSjAEKAmx0GAIgASgGQn7CSHsKeQoKZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgGQo4BwkiKAQqHAQoLZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoBkKSB8JIjgcKfAoKZml4ZWQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoBkLdB8JI2QcKigEKC2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkNjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkNjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdwoCaW4YBiADKAZCa8JIaApmCgpmaXhlZDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEngKBm5vdF9pbhgHIAMoBkJowkhlCmMKDmZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoBkIcwkgZChcKD2ZpeGVkNjQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4imhUKDVNGaXhlZDMyUnVsZXMSbAoFY29uc3QYASABKA9CXcJIWgpYCg5zZml4ZWQzMi5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKNAQoCbHQYAiABKA9Cf8JIfAp6CgtzZml4ZWQzMi5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKfAQoDbHRlGAMgASgPQo8BwkiLAQqIAQoMc2ZpeGVkMzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKmBwoCZ3QYBCABKA9ClwfCSJMHCn0KC3NmaXhlZDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq2AQoOc2ZpeGVkMzIuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr4BChhzZml4ZWQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrGAQoPc2ZpeGVkMzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrOAQoZc2ZpeGVkMzIuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES8gcKA2d0ZRgFIAEoD0LiB8JI3gcKiwEKDHNmaXhlZDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsUBCg9zZml4ZWQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzQEKGXNmaXhlZDMyLmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtUBChBzZml4ZWQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt0BChpzZml4ZWQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ4CgJpbhgGIAMoD0JswkhpCmcKC3NmaXhlZDMyLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnkKBm5vdF9pbhgHIAMoD0JpwkhmCmQKD3NmaXhlZDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEi4KB2V4YW1wbGUYCCADKA9CHcJIGgoYChBzZml4ZWQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKaFQoNU0ZpeGVkNjRSdWxlcxJsCgVjb25zdBgBIAEoEEJdwkhaClgKDnNmaXhlZDY0LmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEo0BCgJsdBgCIAEoEEJ/wkh8CnoKC3NmaXhlZDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp8BCgNsdGUYAyABKBBCjwHCSIsBCogBCgxzZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqYHCgJndBgEIAEoEEKXB8JIkwcKfQoLc2ZpeGVkNjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrYBCg5zZml4ZWQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvgEKGHNmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsYBCg9zZml4ZWQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs4BChlzZml4ZWQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLyBwoDZ3RlGAUgASgQQuIHwkjeBwqLAQoMc2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxQEKD3NmaXhlZDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrNAQoZc2ZpeGVkNjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1QEKEHNmaXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3QEKGnNmaXhlZDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEngKAmluGAYgAygQQmzCSGkKZwoLc2ZpeGVkNjQuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSeQoGbm90X2luGAcgAygQQmnCSGYKZAoPc2ZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLgoHZXhhbXBsZRgIIAMoEEIdwkgaChgKEHNmaXhlZDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIqwBCglCb29sUnVsZXMSaAoFY29uc3QYASABKAhCWcJIVgpUCgpib29sLmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEioKB2V4YW1wbGUYAiADKAhCGcJIFgoUCgxib29sLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiLqNgoLU3RyaW5nUnVsZXMSbAoFY29uc3QYASABKAlCXcJIWgpYCgxzdHJpbmcuY29uc3QaSHRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCBgJXNgJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxJ+CgNsZW4YEyABKARCccJIbgpsCgpzdHJpbmcubGVuGl51aW50KHRoaXMuc2l6ZSgpKSAhPSBydWxlcy5sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpkBCgdtaW5fbGVuGAIgASgEQocBwkiDAQqAAQoOc3RyaW5nLm1pbl9sZW4abnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2xlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBsZWFzdCAlcyBjaGFyYWN0ZXJzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEpcBCgdtYXhfbGVuGAMgASgEQoUBwkiBAQp/Cg5zdHJpbmcubWF4X2xlbhptdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKbAQoJbGVuX2J5dGVzGBQgASgEQocBwkiDAQqAAQoQc3RyaW5nLmxlbl9ieXRlcxpsdWludChieXRlcyh0aGlzKS5zaXplKCkpICE9IHJ1bGVzLmxlbl9ieXRlcyA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5fYnl0ZXNdKSA6ICcnEqMBCgltaW5fYnl0ZXMYBCABKARCjwHCSIsBCogBChBzdHJpbmcubWluX2J5dGVzGnR1aW50KGJ5dGVzKHRoaXMpLnNpemUoKSkgPCBydWxlcy5taW5fYnl0ZXMgPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2J5dGVzXSkgOiAnJxKiAQoJbWF4X2J5dGVzGAUgASgEQo4BwkiKAQqHAQoQc3RyaW5nLm1heF9ieXRlcxpzdWludChieXRlcyh0aGlzKS5zaXplKCkpID4gcnVsZXMubWF4X2J5dGVzID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWF4X2J5dGVzXSkgOiAnJxKNAQoHcGF0dGVybhgGIAEoCUJ8wkh5CncKDnN0cmluZy5wYXR0ZXJuGmUhdGhpcy5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIGRvZXMgbm90IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKEAQoGcHJlZml4GAcgASgJQnTCSHEKbwoNc3RyaW5nLnByZWZpeBpeIXRoaXMuc3RhcnRzV2l0aChydWxlcy5wcmVmaXgpID8gJ3ZhbHVlIGRvZXMgbm90IGhhdmUgcHJlZml4IGAlc2AnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxKCAQoGc3VmZml4GAggASgJQnLCSG8KbQoNc3RyaW5nLnN1ZmZpeBpcIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCBgJXNgJy5mb3JtYXQoW3J1bGVzLnN1ZmZpeF0pIDogJycSkAEKCGNvbnRhaW5zGAkgASgJQn7CSHsKeQoPc3RyaW5nLmNvbnRhaW5zGmYhdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiBzdWJzdHJpbmcgYCVzYCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSmAEKDG5vdF9jb250YWlucxgXIAEoCUKBAcJIfgp8ChNzdHJpbmcubm90X2NvbnRhaW5zGmV0aGlzLmNvbnRhaW5zKHJ1bGVzLm5vdF9jb250YWlucykgPyAndmFsdWUgY29udGFpbnMgc3Vic3RyaW5nIGAlc2AnLmZvcm1hdChbcnVsZXMubm90X2NvbnRhaW5zXSkgOiAnJxJ2CgJpbhgKIAMoCUJqwkhnCmUKCXN0cmluZy5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ3CgZub3RfaW4YCyADKAlCZ8JIZApiCg1zdHJpbmcubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycS3wEKBWVtYWlsGAwgASgIQs0BwkjJAQphCgxzdHJpbmcuZW1haWwSI3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGiwhcnVsZXMuZW1haWwgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzRW1haWwoKQpkChJzdHJpbmcuZW1haWxfZW1wdHkSMnZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGhohcnVsZXMuZW1haWwgfHwgdGhpcyAhPSAnJ0gAEucBCghob3N0bmFtZRgNIAEoCELSAcJIzgEKZQoPc3RyaW5nLmhvc3RuYW1lEh52YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaG9zdG5hbWUaMiFydWxlcy5ob3N0bmFtZSB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpCmUKFXN0cmluZy5ob3N0bmFtZV9lbXB0eRItdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3RuYW1lGh0hcnVsZXMuaG9zdG5hbWUgfHwgdGhpcyAhPSAnJ0gAEscBCgJpcBgOIAEoCEK4AcJItAEKVQoJc3RyaW5nLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxomIXJ1bGVzLmlwIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKCkKWwoPc3RyaW5nLmlwX2VtcHR5Ei92YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgYWRkcmVzcxoXIXJ1bGVzLmlwIHx8IHRoaXMgIT0gJydIABLWAQoEaXB2NBgPIAEoCELFAcJIwQEKXAoLc3RyaW5nLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaKSFydWxlcy5pcHY0IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKDQpCmEKEXN0cmluZy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGhkhcnVsZXMuaXB2NCB8fCB0aGlzICE9ICcnSAAS1gEKBGlwdjYYECABKAhCxQHCSMEBClwKC3N0cmluZy5pcHY2EiJ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NiBhZGRyZXNzGikhcnVsZXMuaXB2NiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcCg2KQphChFzdHJpbmcuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxoZIXJ1bGVzLmlwdjYgfHwgdGhpcyAhPSAnJ0gAEr8BCgN1cmkYESABKAhCrwHCSKsBClEKCnN0cmluZy51cmkSGXZhbHVlIG11c3QgYmUgYSB2YWxpZCBVUkkaKCFydWxlcy51cmkgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzVXJpKCkKVgoQc3RyaW5nLnVyaV9lbXB0eRIodmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIFVSSRoYIXJ1bGVzLnVyaSB8fCB0aGlzICE9ICcnSAAScAoHdXJpX3JlZhgSIAEoCEJdwkhaClgKDnN0cmluZy51cmlfcmVmEiN2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVJJIFJlZmVyZW5jZRohIXJ1bGVzLnVyaV9yZWYgfHwgdGhpcy5pc1VyaVJlZigpSAASkAIKB2FkZHJlc3MYFSABKAhC/AHCSPgBCoEBCg5zdHJpbmcuYWRkcmVzcxItdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGhvc3RuYW1lLCBvciBpcCBhZGRyZXNzGkAhcnVsZXMuYWRkcmVzcyB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpIHx8IHRoaXMuaXNJcCgpCnIKFHN0cmluZy5hZGRyZXNzX2VtcHR5Ejx2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdG5hbWUsIG9yIGlwIGFkZHJlc3MaHCFydWxlcy5hZGRyZXNzIHx8IHRoaXMgIT0gJydIABKYAgoEdXVpZBgWIAEoCEKHAsJIgwIKpQEKC3N0cmluZy51dWlkEhp2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVVJRBp6IXJ1bGVzLnV1aWQgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLm1hdGNoZXMoJ15bMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXsxMn0kJykKWQoRc3RyaW5nLnV1aWRfZW1wdHkSKXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBVVUlEGhkhcnVsZXMudXVpZCB8fCB0aGlzICE9ICcnSAAS8AEKBXR1dWlkGCEgASgIQt4BwkjaAQpzCgxzdHJpbmcudHV1aWQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCB0cmltbWVkIFVVSUQaPyFydWxlcy50dXVpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTlhLWZBLUZdezMyfSQnKQpjChJzdHJpbmcudHV1aWRfZW1wdHkSMXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCB0cmltbWVkIFVVSUQaGiFydWxlcy50dXVpZCB8fCB0aGlzICE9ICcnSAASlgIKEWlwX3dpdGhfcHJlZml4bGVuGBogASgIQvgBwkj0AQp4ChhzdHJpbmcuaXBfd2l0aF9wcmVmaXhsZW4SH3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUCBwcmVmaXgaOyFydWxlcy5pcF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCgpCngKHnN0cmluZy5pcF93aXRoX3ByZWZpeGxlbl9lbXB0eRIudmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIHByZWZpeBomIXJ1bGVzLmlwX3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgIT0gJydIABLPAgoTaXB2NF93aXRoX3ByZWZpeGxlbhgbIAEoCEKvAsJIqwIKkwEKGnN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuEjV2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBo+IXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCkKkgEKIHN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuX2VtcHR5EkR2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBooIXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyAhPSAnJ0gAEs8CChNpcHY2X3dpdGhfcHJlZml4bGVuGBwgASgIQq8CwkirAgqTAQoac3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW4SNXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGj4hcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg2KQqSAQogc3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW5fZW1wdHkSRHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGighcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzICE9ICcnSAAS8gEKCWlwX3ByZWZpeBgdIAEoCELcAcJI2AEKbAoQc3RyaW5nLmlwX3ByZWZpeBIfdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQIHByZWZpeBo3IXJ1bGVzLmlwX3ByZWZpeCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCh0cnVlKQpoChZzdHJpbmcuaXBfcHJlZml4X2VtcHR5Ei52YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgcHJlZml4Gh4hcnVsZXMuaXBfcHJlZml4IHx8IHRoaXMgIT0gJydIABKDAgoLaXB2NF9wcmVmaXgYHiABKAhC6wHCSOcBCnUKEnN0cmluZy5pcHY0X3ByZWZpeBIhdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjQgcHJlZml4GjwhcnVsZXMuaXB2NF9wcmVmaXggfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCwgdHJ1ZSkKbgoYc3RyaW5nLmlwdjRfcHJlZml4X2VtcHR5EjB2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBwcmVmaXgaICFydWxlcy5pcHY0X3ByZWZpeCB8fCB0aGlzICE9ICcnSAASgwIKC2lwdjZfcHJlZml4GB8gASgIQusBwkjnAQp1ChJzdHJpbmcuaXB2Nl9wcmVmaXgSIXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IHByZWZpeBo8IXJ1bGVzLmlwdjZfcHJlZml4IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KDYsIHRydWUpCm4KGHN0cmluZy5pcHY2X3ByZWZpeF9lbXB0eRIwdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgcHJlZml4GiAhcnVsZXMuaXB2Nl9wcmVmaXggfHwgdGhpcyAhPSAnJ0gAErUCCg1ob3N0X2FuZF9wb3J0GCAgASgIQpsCwkiXAgqZAQoUc3RyaW5nLmhvc3RfYW5kX3BvcnQSQXZhbHVlIG11c3QgYmUgYSB2YWxpZCBob3N0IChob3N0bmFtZSBvciBJUCBhZGRyZXNzKSBhbmQgcG9ydCBwYWlyGj4hcnVsZXMuaG9zdF9hbmRfcG9ydCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0QW5kUG9ydCh0cnVlKQp5ChpzdHJpbmcuaG9zdF9hbmRfcG9ydF9lbXB0eRI3dmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3QgYW5kIHBvcnQgcGFpchoiIXJ1bGVzLmhvc3RfYW5kX3BvcnQgfHwgdGhpcyAhPSAnJ0gAEqgFChB3ZWxsX2tub3duX3JlZ2V4GBggASgOMhguYnVmLnZhbGlkYXRlLktub3duUmVnZXhC8QTCSO0ECvABCiNzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfbmFtZRImdmFsdWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgaGVhZGVyIG5hbWUaoAFydWxlcy53ZWxsX2tub3duX3JlZ2V4ICE9IDEgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLm1hdGNoZXMoIWhhcyhydWxlcy5zdHJpY3QpIHx8IHJ1bGVzLnN0cmljdCA/J146P1swLTlhLXpBLVohIyQlJlwnKistLl5ffH5ceDYwXSskJyA6J15bXlx1MDAwMFx1MDAwQVx1MDAwRF0rJCcpCo0BCilzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfbmFtZV9lbXB0eRI1dmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIEhUVFAgaGVhZGVyIG5hbWUaKXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMSB8fCB0aGlzICE9ICcnCucBCiRzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfdmFsdWUSJ3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBIVFRQIGhlYWRlciB2YWx1ZRqVAXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMiB8fCB0aGlzLm1hdGNoZXMoIWhhcyhydWxlcy5zdHJpY3QpIHx8IHJ1bGVzLnN0cmljdCA/J15bXlx1MDAwMC1cdTAwMDhcdTAwMEEtXHUwMDFGXHUwMDdGXSokJyA6J15bXlx1MDAwMFx1MDAwQVx1MDAwRF0qJCcpSAASDgoGc3RyaWN0GBkgASgIEiwKB2V4YW1wbGUYIiADKAlCG8JIGAoWCg5zdHJpbmcuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgwKCndlbGxfa25vd24ivxAKCkJ5dGVzUnVsZXMSZgoFY29uc3QYASABKAxCV8JIVApSCgtieXRlcy5jb25zdBpDdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGJlICV4Jy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxJ4CgNsZW4YDSABKARCa8JIaApmCglieXRlcy5sZW4aWXVpbnQodGhpcy5zaXplKCkpICE9IHJ1bGVzLmxlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpABCgdtaW5fbGVuGAIgASgEQn/CSHwKegoNYnl0ZXMubWluX2xlbhppdWludCh0aGlzLnNpemUoKSkgPCBydWxlcy5taW5fbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IGxlYXN0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEogBCgdtYXhfbGVuGAMgASgEQnfCSHQKcgoNYnl0ZXMubWF4X2xlbhphdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIG11c3QgYmUgYXQgbW9zdCAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKQAQoHcGF0dGVybhgEIAEoCUJ/wkh8CnoKDWJ5dGVzLnBhdHRlcm4aaSFzdHJpbmcodGhpcykubWF0Y2hlcyhydWxlcy5wYXR0ZXJuKSA/ICd2YWx1ZSBtdXN0IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKBAQoGcHJlZml4GAUgASgMQnHCSG4KbAoMYnl0ZXMucHJlZml4GlwhdGhpcy5zdGFydHNXaXRoKHJ1bGVzLnByZWZpeCkgPyAndmFsdWUgZG9lcyBub3QgaGF2ZSBwcmVmaXggJXgnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxJ/CgZzdWZmaXgYBiABKAxCb8JIbApqCgxieXRlcy5zdWZmaXgaWiF0aGlzLmVuZHNXaXRoKHJ1bGVzLnN1ZmZpeCkgPyAndmFsdWUgZG9lcyBub3QgaGF2ZSBzdWZmaXggJXgnLmZvcm1hdChbcnVsZXMuc3VmZml4XSkgOiAnJxKDAQoIY29udGFpbnMYByABKAxCccJIbgpsCg5ieXRlcy5jb250YWlucxpaIXRoaXMuY29udGFpbnMocnVsZXMuY29udGFpbnMpID8gJ3ZhbHVlIGRvZXMgbm90IGNvbnRhaW4gJXgnLmZvcm1hdChbcnVsZXMuY29udGFpbnNdKSA6ICcnEpcBCgJpbhgIIAMoDEKKAcJIhgEKgwEKCGJ5dGVzLmluGndkeW4ocnVsZXMpWydpbiddLnNpemUoKSA+IDAgJiYgISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ2CgZub3RfaW4YCSADKAxCZsJIYwphCgxieXRlcy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLrAQoCaXAYCiABKAhC3AHCSNgBCnQKCGJ5dGVzLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxpGIXJ1bGVzLmlwIHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNCB8fCB0aGlzLnNpemUoKSA9PSAxNgpgCg5ieXRlcy5pcF9lbXB0eRIvdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIGFkZHJlc3MaHSFydWxlcy5pcCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5AEKBGlwdjQYCyABKAhC0wHCSM8BCmUKCmJ5dGVzLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaMyFydWxlcy5pcHY0IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNApmChBieXRlcy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGh8hcnVsZXMuaXB2NCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5QEKBGlwdjYYDCABKAhC1AHCSNABCmYKCmJ5dGVzLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaNCFydWxlcy5pcHY2IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gMTYKZgoQYnl0ZXMuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxofIXJ1bGVzLmlwdjYgfHwgdGhpcy5zaXplKCkgIT0gMEgAEisKB2V4YW1wbGUYDiADKAxCGsJIFwoVCg1ieXRlcy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biKvAwoJRW51bVJ1bGVzEmgKBWNvbnN0GAEgASgFQlnCSFYKVAoKZW51bS5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxIUCgxkZWZpbmVkX29ubHkYAiABKAgSdAoCaW4YAyADKAVCaMJIZQpjCgdlbnVtLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnUKBm5vdF9pbhgEIAMoBUJlwkhiCmAKC2VudW0ubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKgoHZXhhbXBsZRgFIAMoBUIZwkgWChQKDGVudW0uZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACIoEECg1SZXBlYXRlZFJ1bGVzEp4BCgltaW5faXRlbXMYASABKARCigHCSIYBCoMBChJyZXBlYXRlZC5taW5faXRlbXMabXVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2l0ZW1zID8gJ3ZhbHVlIG11c3QgY29udGFpbiBhdCBsZWFzdCAlZCBpdGVtKHMpJy5mb3JtYXQoW3J1bGVzLm1pbl9pdGVtc10pIDogJycSogEKCW1heF9pdGVtcxgCIAEoBEKOAcJIigEKhwEKEnJlcGVhdGVkLm1heF9pdGVtcxpxdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfaXRlbXMgPyAndmFsdWUgbXVzdCBjb250YWluIG5vIG1vcmUgdGhhbiAlcyBpdGVtKHMpJy5mb3JtYXQoW3J1bGVzLm1heF9pdGVtc10pIDogJycScAoGdW5pcXVlGAMgASgIQmDCSF0KWwoPcmVwZWF0ZWQudW5pcXVlEihyZXBlYXRlZCB2YWx1ZSBtdXN0IGNvbnRhaW4gdW5pcXVlIGl0ZW1zGh4hcnVsZXMudW5pcXVlIHx8IHRoaXMudW5pcXVlKCkSLQoFaXRlbXMYBCABKAsyHi5idWYudmFsaWRhdGUuRmllbGRDb25zdHJhaW50cyoJCOgHEICAgIACIpYDCghNYXBSdWxlcxKPAQoJbWluX3BhaXJzGAEgASgEQnzCSHkKdwoNbWFwLm1pbl9wYWlycxpmdWludCh0aGlzLnNpemUoKSkgPCBydWxlcy5taW5fcGFpcnMgPyAnbWFwIG11c3QgYmUgYXQgbGVhc3QgJWQgZW50cmllcycuZm9ybWF0KFtydWxlcy5taW5fcGFpcnNdKSA6ICcnEo4BCgltYXhfcGFpcnMYAiABKARCe8JIeAp2Cg1tYXAubWF4X3BhaXJzGmV1aW50KHRoaXMuc2l6ZSgpKSA+IHJ1bGVzLm1heF9wYWlycyA/ICdtYXAgbXVzdCBiZSBhdCBtb3N0ICVkIGVudHJpZXMnLmZvcm1hdChbcnVsZXMubWF4X3BhaXJzXSkgOiAnJxIsCgRrZXlzGAQgASgLMh4uYnVmLnZhbGlkYXRlLkZpZWxkQ29uc3RyYWludHMSLgoGdmFsdWVzGAUgASgLMh4uYnVmLnZhbGlkYXRlLkZpZWxkQ29uc3RyYWludHMqCQjoBxCAgICAAiImCghBbnlSdWxlcxIKCgJpbhgCIAMoCRIOCgZub3RfaW4YAyADKAki9RYKDUR1cmF0aW9uUnVsZXMShwEKBWNvbnN0GAIgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQl3CSFoKWAoOZHVyYXRpb24uY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSqAEKAmx0GAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQn/CSHwKegoLZHVyYXRpb24ubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASugEKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkKPAcJIiwEKiAEKDGR1cmF0aW9uLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASwQcKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQpcHwkiTBwp9CgtkdXJhdGlvbi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDmR1cmF0aW9uLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYZHVyYXRpb24uZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD2R1cmF0aW9uLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGWR1cmF0aW9uLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEo0ICgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25C4gfCSN4HCosBCgxkdXJhdGlvbi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPZHVyYXRpb24uZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlkdXJhdGlvbi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQZHVyYXRpb24uZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoaZHVyYXRpb24uZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESkwEKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQmzCSGkKZwoLZHVyYXRpb24uaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSlAEKBm5vdF9pbhgIIAMoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkJpwkhmCmQKD2R1cmF0aW9uLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEkkKB2V4YW1wbGUYCSADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25CHcJIGgoYChBkdXJhdGlvbi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FwoOVGltZXN0YW1wUnVsZXMSiQEKBWNvbnN0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEJewkhbClkKD3RpbWVzdGFtcC5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKrAQoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQoABwkh9CnsKDHRpbWVzdGFtcC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABK8AQoDbHRlGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKQAcJIjAEKiQEKDXRpbWVzdGFtcC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEmwKBmx0X25vdxgHIAEoCEJawkhXClUKEHRpbWVzdGFtcC5sdF9ub3caQShydWxlcy5sdF9ub3cgJiYgdGhpcyA+IG5vdykgPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gbm93JyA6ICcnSAASxwcKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKcB8JImAcKfgoMdGltZXN0YW1wLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq3AQoPdGltZXN0YW1wLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq/AQoZdGltZXN0YW1wLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCscBChB0aW1lc3RhbXAuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrPAQoadGltZXN0YW1wLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEpMICgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQucHwkjjBwqMAQoNdGltZXN0YW1wLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsYBChB0aW1lc3RhbXAuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs4BChp0aW1lc3RhbXAuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1gEKEXRpbWVzdGFtcC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt4BCht0aW1lc3RhbXAuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESbwoGZ3Rfbm93GAggASgIQl3CSFoKWAoQdGltZXN0YW1wLmd0X25vdxpEKHJ1bGVzLmd0X25vdyAmJiB0aGlzIDwgbm93KSA/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBub3cnIDogJydIARK4AQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQowBwkiIAQqFAQoQdGltZXN0YW1wLndpdGhpbhpxdGhpcyA8IG5vdy1ydWxlcy53aXRoaW4gfHwgdGhpcyA+IG5vdytydWxlcy53aXRoaW4gPyAndmFsdWUgbXVzdCBiZSB3aXRoaW4gJXMgb2Ygbm93Jy5mb3JtYXQoW3J1bGVzLndpdGhpbl0pIDogJycSSwoHZXhhbXBsZRgKIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCHsJIGwoZChF0aW1lc3RhbXAuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iOQoKVmlvbGF0aW9ucxIrCgp2aW9sYXRpb25zGAEgAygLMhcuYnVmLnZhbGlkYXRlLlZpb2xhdGlvbiKlAQoJVmlvbGF0aW9uEiYKBWZpZWxkGAUgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIlCgRydWxlGAYgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIVCg1jb25zdHJhaW50X2lkGAIgASgJEg8KB21lc3NhZ2UYAyABKAkSDwoHZm9yX2tleRgEIAEoCEoECAEQAlIKZmllbGRfcGF0aCI9CglGaWVsZFBhdGgSMAoIZWxlbWVudHMYASADKAsyHi5idWYudmFsaWRhdGUuRmllbGRQYXRoRWxlbWVudCLpAgoQRmllbGRQYXRoRWxlbWVudBIUCgxmaWVsZF9udW1iZXIYASABKAUSEgoKZmllbGRfbmFtZRgCIAEoCRI+CgpmaWVsZF90eXBlGAMgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSPAoIa2V5X3R5cGUYBCABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRI+Cgp2YWx1ZV90eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSDwoFaW5kZXgYBiABKARIABISCghib29sX2tleRgHIAEoCEgAEhEKB2ludF9rZXkYCCABKANIABISCgh1aW50X2tleRgJIAEoBEgAEhQKCnN0cmluZ19rZXkYCiABKAlIAEILCglzdWJzY3JpcHQqhwEKBklnbm9yZRIWChJJR05PUkVfVU5TUEVDSUZJRUQQABIZChVJR05PUkVfSUZfVU5QT1BVTEFURUQQARIbChdJR05PUkVfSUZfREVGQVVMVF9WQUxVRRACEhEKDUlHTk9SRV9BTFdBWVMQAyoaSUdOT1JFX0VNUFRZSUdOT1JFX0RFRkFVTFQqbgoKS25vd25SZWdleBIbChdLTk9XTl9SRUdFWF9VTlNQRUNJRklFRBAAEiAKHEtOT1dOX1JFR0VYX0hUVFBfSEVBREVSX05BTUUQARIhCh1LTk9XTl9SRUdFWF9IVFRQX0hFQURFUl9WQUxVRRACOlwKB21lc3NhZ2USHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhwkgASgLMiAuYnVmLnZhbGlkYXRlLk1lc3NhZ2VDb25zdHJhaW50c1IHbWVzc2FnZTpUCgVvbmVvZhIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMYhwkgASgLMh4uYnVmLnZhbGlkYXRlLk9uZW9mQ29uc3RyYWludHNSBW9uZW9mOlQKBWZpZWxkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiHCSABKAsyHi5idWYudmFsaWRhdGUuRmllbGRDb25zdHJhaW50c1IFZmllbGQ6YwoKcHJlZGVmaW5lZBIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMYiAkgASgLMiMuYnVmLnZhbGlkYXRlLlByZWRlZmluZWRDb25zdHJhaW50c1IKcHJlZGVmaW5lZEJuChJidWlsZC5idWYudmFsaWRhdGVCDVZhbGlkYXRlUHJvdG9QAVpHYnVmLmJ1aWxkL2dlbi9nby9idWZidWlsZC9wcm90b3ZhbGlkYXRlL3Byb3RvY29sYnVmZmVycy9nby9idWYvdmFsaWRhdGU", [file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_timestamp]);
+ fileDesc("ChtidWYvdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8SDGJ1Zi52YWxpZGF0ZSI3CgRSdWxlEgoKAmlkGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEgoKZXhwcmVzc2lvbhgDIAEoCSJBCgxNZXNzYWdlUnVsZXMSEAoIZGlzYWJsZWQYASABKAgSHwoDY2VsGAMgAygLMhIuYnVmLnZhbGlkYXRlLlJ1bGUiHgoKT25lb2ZSdWxlcxIQCghyZXF1aXJlZBgBIAEoCCK/CAoKRmllbGRSdWxlcxIfCgNjZWwYFyADKAsyEi5idWYudmFsaWRhdGUuUnVsZRIQCghyZXF1aXJlZBgZIAEoCBIkCgZpZ25vcmUYGyABKA4yFC5idWYudmFsaWRhdGUuSWdub3JlEikKBWZsb2F0GAEgASgLMhguYnVmLnZhbGlkYXRlLkZsb2F0UnVsZXNIABIrCgZkb3VibGUYAiABKAsyGS5idWYudmFsaWRhdGUuRG91YmxlUnVsZXNIABIpCgVpbnQzMhgDIAEoCzIYLmJ1Zi52YWxpZGF0ZS5JbnQzMlJ1bGVzSAASKQoFaW50NjQYBCABKAsyGC5idWYudmFsaWRhdGUuSW50NjRSdWxlc0gAEisKBnVpbnQzMhgFIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50MzJSdWxlc0gAEisKBnVpbnQ2NBgGIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50NjRSdWxlc0gAEisKBnNpbnQzMhgHIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50MzJSdWxlc0gAEisKBnNpbnQ2NBgIIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50NjRSdWxlc0gAEi0KB2ZpeGVkMzIYCSABKAsyGi5idWYudmFsaWRhdGUuRml4ZWQzMlJ1bGVzSAASLQoHZml4ZWQ2NBgKIAEoCzIaLmJ1Zi52YWxpZGF0ZS5GaXhlZDY0UnVsZXNIABIvCghzZml4ZWQzMhgLIAEoCzIbLmJ1Zi52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSAASLwoIc2ZpeGVkNjQYDCABKAsyGy5idWYudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAEicKBGJvb2wYDSABKAsyFy5idWYudmFsaWRhdGUuQm9vbFJ1bGVzSAASKwoGc3RyaW5nGA4gASgLMhkuYnVmLnZhbGlkYXRlLlN0cmluZ1J1bGVzSAASKQoFYnl0ZXMYDyABKAsyGC5idWYudmFsaWRhdGUuQnl0ZXNSdWxlc0gAEicKBGVudW0YECABKAsyFy5idWYudmFsaWRhdGUuRW51bVJ1bGVzSAASLwoIcmVwZWF0ZWQYEiABKAsyGy5idWYudmFsaWRhdGUuUmVwZWF0ZWRSdWxlc0gAEiUKA21hcBgTIAEoCzIWLmJ1Zi52YWxpZGF0ZS5NYXBSdWxlc0gAEiUKA2FueRgUIAEoCzIWLmJ1Zi52YWxpZGF0ZS5BbnlSdWxlc0gAEi8KCGR1cmF0aW9uGBUgASgLMhsuYnVmLnZhbGlkYXRlLkR1cmF0aW9uUnVsZXNIABIxCgl0aW1lc3RhbXAYFiABKAsyHC5idWYudmFsaWRhdGUuVGltZXN0YW1wUnVsZXNIAEIGCgR0eXBlSgQIGBAZSgQIGhAbUgdza2lwcGVkUgxpZ25vcmVfZW1wdHkiUwoPUHJlZGVmaW5lZFJ1bGVzEh8KA2NlbBgBIAMoCzISLmJ1Zi52YWxpZGF0ZS5SdWxlSgQIGBAZSgQIGhAbUhNza2lwcGVkaWdub3JlX2VtcHR5ItoXCgpGbG9hdFJ1bGVzEoMBCgVjb25zdBgBIAEoAkJ0wkhxCm8KC2Zsb2F0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSnwEKAmx0GAIgASgCQpABwkiMAQqJAQoIZmxvYXQubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASrwEKA2x0ZRgDIAEoAkKfAcJImwEKmAEKCWZsb2F0Lmx0ZRqKASFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEu8HCgJndBgEIAEoAkLgB8JI3AcKjQEKCGZsb2F0Lmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKwwEKC2Zsb2F0Lmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzQEKFWZsb2F0Lmd0X2x0X2V4Y2x1c2l2ZRqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCtMBCgxmbG9hdC5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrdAQoWZmxvYXQuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESuggKA2d0ZRgFIAEoAkKqCMJIpggKmwEKCWZsb2F0Lmd0ZRqNASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrSAQoMZmxvYXQuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrcAQoWZmxvYXQuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4gEKDWZsb2F0Lmd0ZV9sdGUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCuwBChdmbG9hdC5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ/CgJpbhgGIAMoAkJzwkhwCm4KCGZsb2F0LmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ2CgZub3RfaW4YByADKAJCZsJIYwphCgxmbG9hdC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ1CgZmaW5pdGUYCCABKAhCZcJIYgpgCgxmbG9hdC5maW5pdGUaUHJ1bGVzLmZpbml0ZSA/ICh0aGlzLmlzTmFuKCkgfHwgdGhpcy5pc0luZigpID8gJ3ZhbHVlIG11c3QgYmUgZmluaXRlJyA6ICcnKSA6ICcnEisKB2V4YW1wbGUYCSADKAJCGsJIFwoVCg1mbG9hdC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiLtFwoLRG91YmxlUnVsZXMShAEKBWNvbnN0GAEgASgBQnXCSHIKcAoMZG91YmxlLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSoAEKAmx0GAIgASgBQpEBwkiNAQqKAQoJZG91YmxlLmx0Gn0haGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0KT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAErABCgNsdGUYAyABKAFCoAHCSJwBCpkBCgpkb3VibGUubHRlGooBIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSk/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAAS9AcKAmd0GAQgASgBQuUHwkjhBwqOAQoJZG91YmxlLmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKxAEKDGRvdWJsZS5ndF9sdBqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCs4BChZkb3VibGUuZ3RfbHRfZXhjbHVzaXZlGrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycK1AEKDWRvdWJsZS5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwreAQoXZG91YmxlLmd0X2x0ZV9leGNsdXNpdmUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEr8ICgNndGUYBSABKAFCrwjCSKsICpwBCgpkb3VibGUuZ3RlGo0BIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCtMBCg1kb3VibGUuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrdAQoXZG91YmxlLmd0ZV9sdF9leGNsdXNpdmUawQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCuMBCg5kb3VibGUuZ3RlX2x0ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK7QEKGGRvdWJsZS5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKAFCdMJIcQpvCglkb3VibGUuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoAUJnwkhkCmIKDWRvdWJsZS5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ2CgZmaW5pdGUYCCABKAhCZsJIYwphCg1kb3VibGUuZmluaXRlGlBydWxlcy5maW5pdGUgPyAodGhpcy5pc05hbigpIHx8IHRoaXMuaXNJbmYoKSA/ICd2YWx1ZSBtdXN0IGJlIGZpbml0ZScgOiAnJykgOiAnJxIsCgdleGFtcGxlGAkgAygBQhvCSBgKFgoOZG91YmxlLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIowVCgpJbnQzMlJ1bGVzEoMBCgVjb25zdBgBIAEoBUJ0wkhxCm8KC2ludDMyLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSigEKAmx0GAIgASgFQnzCSHkKdwoIaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoBUKMAcJIiAEKhQEKCWludDMyLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgFQogHwkiEBwp6CghpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50MzIuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKAVC0wfCSM8HCogBCglpbnQzMi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50MzIuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESfwoCaW4YBiADKAVCc8JIcApuCghpbnQzMi5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSdgoGbm90X2luGAcgAygFQmbCSGMKYQoMaW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKwoHZXhhbXBsZRgIIAMoBUIawkgXChUKDWludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIowVCgpJbnQ2NFJ1bGVzEoMBCgVjb25zdBgBIAEoA0J0wkhxCm8KC2ludDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSigEKAmx0GAIgASgDQnzCSHkKdwoIaW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoA0KMAcJIiAEKhQEKCWludDY0Lmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgDQogHwkiEBwp6CghpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50NjQuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKANC0wfCSM8HCogBCglpbnQ2NC5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50NjQuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESfwoCaW4YBiADKANCc8JIcApuCghpbnQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSdgoGbm90X2luGAcgAygDQmbCSGMKYQoMaW50NjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKwoHZXhhbXBsZRgJIAMoA0IawkgXChUKDWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtVSW50MzJSdWxlcxKEAQoFY29uc3QYASABKA1CdcJIcgpwCgx1aW50MzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKA1CfcJIegp4Cgl1aW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoDUKNAcJIiQEKhgEKCnVpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoDUKNB8JIiQcKewoJdWludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMdWludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWdWludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg11aW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXdWludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKA1C2AfCSNQHCokBCgp1aW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXVpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3VpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOdWludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHVpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKA1CdMJIcQpvCgl1aW50MzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoDUJnwkhkCmIKDXVpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygNQhvCSBgKFgoOdWludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtVSW50NjRSdWxlcxKEAQoFY29uc3QYASABKARCdcJIcgpwCgx1aW50NjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKARCfcJIegp4Cgl1aW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoBEKNAcJIiQEKhgEKCnVpbnQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoBEKNB8JIiQcKewoJdWludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMdWludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWdWludDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg11aW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXdWludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKARC2AfCSNQHCokBCgp1aW50NjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXVpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3VpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOdWludDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHVpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKARCdMJIcQpvCgl1aW50NjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoBEJnwkhkCmIKDXVpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygEQhvCSBgKFgoOdWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtTSW50MzJSdWxlcxKEAQoFY29uc3QYASABKBFCdcJIcgpwCgxzaW50MzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKBFCfcJIegp4CglzaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEUKNAcJIiQEKhgEKCnNpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEUKNB8JIiQcKewoJc2ludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBFC2AfCSNQHCokBCgpzaW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKBFCdMJIcQpvCglzaW50MzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoEUJnwkhkCmIKDXNpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygRQhvCSBgKFgoOc2ludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtTSW50NjRSdWxlcxKEAQoFY29uc3QYASABKBJCdcJIcgpwCgxzaW50NjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKBJCfcJIegp4CglzaW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEkKNAcJIiQEKhgEKCnNpbnQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEkKNB8JIiQcKewoJc2ludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBJC2AfCSNQHCokBCgpzaW50NjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKBJCdMJIcQpvCglzaW50NjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoEkJnwkhkCmIKDXNpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygSQhvCSBgKFgoOc2ludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIq8VCgxGaXhlZDMyUnVsZXMShQEKBWNvbnN0GAEgASgHQnbCSHMKcQoNZml4ZWQzMi5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEowBCgJsdBgCIAEoB0J+wkh7CnkKCmZpeGVkMzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASngEKA2x0ZRgDIAEoB0KOAcJIigEKhwEKC2ZpeGVkMzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKhBwoCZ3QYBCABKAdCkgfCSI4HCnwKCmZpeGVkMzIuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrUBCg1maXhlZDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq9AQoXZml4ZWQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrFAQoOZml4ZWQzMi5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs0BChhmaXhlZDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEu0HCgNndGUYBSABKAdC3QfCSNkHCooBCgtmaXhlZDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsQBCg5maXhlZDMyLmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrMAQoYZml4ZWQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrUAQoPZml4ZWQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtwBChlmaXhlZDMyLmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEoEBCgJpbhgGIAMoB0J1wkhyCnAKCmZpeGVkMzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEngKBm5vdF9pbhgHIAMoB0JowkhlCmMKDmZpeGVkMzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoB0IcwkgZChcKD2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4irxUKDEZpeGVkNjRSdWxlcxKFAQoFY29uc3QYASABKAZCdsJIcwpxCg1maXhlZDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSjAEKAmx0GAIgASgGQn7CSHsKeQoKZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgGQo4BwkiKAQqHAQoLZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoBkKSB8JIjgcKfAoKZml4ZWQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoBkLdB8JI2QcKigEKC2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkNjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkNjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgQEKAmluGAYgAygGQnXCSHIKcAoKZml4ZWQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSeAoGbm90X2luGAcgAygGQmjCSGUKYwoOZml4ZWQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxItCgdleGFtcGxlGAggAygGQhzCSBkKFwoPZml4ZWQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiLAFQoNU0ZpeGVkMzJSdWxlcxKGAQoFY29uc3QYASABKA9Cd8JIdApyCg5zZml4ZWQzMi5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEo0BCgJsdBgCIAEoD0J/wkh8CnoKC3NmaXhlZDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp8BCgNsdGUYAyABKA9CjwHCSIsBCogBCgxzZml4ZWQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqYHCgJndBgEIAEoD0KXB8JIkwcKfQoLc2ZpeGVkMzIuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrYBCg5zZml4ZWQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvgEKGHNmaXhlZDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsYBCg9zZml4ZWQzMi5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs4BChlzZml4ZWQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLyBwoDZ3RlGAUgASgPQuIHwkjeBwqLAQoMc2ZpeGVkMzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxQEKD3NmaXhlZDMyLmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrNAQoZc2ZpeGVkMzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1QEKEHNmaXhlZDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3QEKGnNmaXhlZDMyLmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEoIBCgJpbhgGIAMoD0J2wkhzCnEKC3NmaXhlZDMyLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ5CgZub3RfaW4YByADKA9CacJIZgpkCg9zZml4ZWQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIuCgdleGFtcGxlGAggAygPQh3CSBoKGAoQc2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iwBUKDVNGaXhlZDY0UnVsZXMShgEKBWNvbnN0GAEgASgQQnfCSHQKcgoOc2ZpeGVkNjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKNAQoCbHQYAiABKBBCf8JIfAp6CgtzZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKfAQoDbHRlGAMgASgQQo8BwkiLAQqIAQoMc2ZpeGVkNjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKmBwoCZ3QYBCABKBBClwfCSJMHCn0KC3NmaXhlZDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq2AQoOc2ZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr4BChhzZml4ZWQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrGAQoPc2ZpeGVkNjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrOAQoZc2ZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES8gcKA2d0ZRgFIAEoEELiB8JI3gcKiwEKDHNmaXhlZDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsUBCg9zZml4ZWQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzQEKGXNmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtUBChBzZml4ZWQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt0BChpzZml4ZWQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKCAQoCaW4YBiADKBBCdsJIcwpxCgtzZml4ZWQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSeQoGbm90X2luGAcgAygQQmnCSGYKZAoPc2ZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLgoHZXhhbXBsZRgIIAMoEEIdwkgaChgKEHNmaXhlZDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIscBCglCb29sUnVsZXMSggEKBWNvbnN0GAEgASgIQnPCSHAKbgoKYm9vbC5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEioKB2V4YW1wbGUYAiADKAhCGcJIFgoUCgxib29sLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiKQNwoLU3RyaW5nUnVsZXMShgEKBWNvbnN0GAEgASgJQnfCSHQKcgoMc3RyaW5nLmNvbnN0GmJ0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsIGAlc2AnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxJ+CgNsZW4YEyABKARCccJIbgpsCgpzdHJpbmcubGVuGl51aW50KHRoaXMuc2l6ZSgpKSAhPSBydWxlcy5sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpkBCgdtaW5fbGVuGAIgASgEQocBwkiDAQqAAQoOc3RyaW5nLm1pbl9sZW4abnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2xlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBsZWFzdCAlcyBjaGFyYWN0ZXJzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEpcBCgdtYXhfbGVuGAMgASgEQoUBwkiBAQp/Cg5zdHJpbmcubWF4X2xlbhptdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKbAQoJbGVuX2J5dGVzGBQgASgEQocBwkiDAQqAAQoQc3RyaW5nLmxlbl9ieXRlcxpsdWludChieXRlcyh0aGlzKS5zaXplKCkpICE9IHJ1bGVzLmxlbl9ieXRlcyA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5fYnl0ZXNdKSA6ICcnEqMBCgltaW5fYnl0ZXMYBCABKARCjwHCSIsBCogBChBzdHJpbmcubWluX2J5dGVzGnR1aW50KGJ5dGVzKHRoaXMpLnNpemUoKSkgPCBydWxlcy5taW5fYnl0ZXMgPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2J5dGVzXSkgOiAnJxKiAQoJbWF4X2J5dGVzGAUgASgEQo4BwkiKAQqHAQoQc3RyaW5nLm1heF9ieXRlcxpzdWludChieXRlcyh0aGlzKS5zaXplKCkpID4gcnVsZXMubWF4X2J5dGVzID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWF4X2J5dGVzXSkgOiAnJxKNAQoHcGF0dGVybhgGIAEoCUJ8wkh5CncKDnN0cmluZy5wYXR0ZXJuGmUhdGhpcy5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIGRvZXMgbm90IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKEAQoGcHJlZml4GAcgASgJQnTCSHEKbwoNc3RyaW5nLnByZWZpeBpeIXRoaXMuc3RhcnRzV2l0aChydWxlcy5wcmVmaXgpID8gJ3ZhbHVlIGRvZXMgbm90IGhhdmUgcHJlZml4IGAlc2AnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxKCAQoGc3VmZml4GAggASgJQnLCSG8KbQoNc3RyaW5nLnN1ZmZpeBpcIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCBgJXNgJy5mb3JtYXQoW3J1bGVzLnN1ZmZpeF0pIDogJycSkAEKCGNvbnRhaW5zGAkgASgJQn7CSHsKeQoPc3RyaW5nLmNvbnRhaW5zGmYhdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiBzdWJzdHJpbmcgYCVzYCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSmAEKDG5vdF9jb250YWlucxgXIAEoCUKBAcJIfgp8ChNzdHJpbmcubm90X2NvbnRhaW5zGmV0aGlzLmNvbnRhaW5zKHJ1bGVzLm5vdF9jb250YWlucykgPyAndmFsdWUgY29udGFpbnMgc3Vic3RyaW5nIGAlc2AnLmZvcm1hdChbcnVsZXMubm90X2NvbnRhaW5zXSkgOiAnJxKAAQoCaW4YCiADKAlCdMJIcQpvCglzdHJpbmcuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgLIAMoCUJnwkhkCmIKDXN0cmluZy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLfAQoFZW1haWwYDCABKAhCzQHCSMkBCmEKDHN0cmluZy5lbWFpbBIjdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGVtYWlsIGFkZHJlc3MaLCFydWxlcy5lbWFpbCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNFbWFpbCgpCmQKEnN0cmluZy5lbWFpbF9lbXB0eRIydmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGVtYWlsIGFkZHJlc3MaGiFydWxlcy5lbWFpbCB8fCB0aGlzICE9ICcnSAAS5wEKCGhvc3RuYW1lGA0gASgIQtIBwkjOAQplCg9zdHJpbmcuaG9zdG5hbWUSHnZhbHVlIG11c3QgYmUgYSB2YWxpZCBob3N0bmFtZRoyIXJ1bGVzLmhvc3RuYW1lIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RuYW1lKCkKZQoVc3RyaW5nLmhvc3RuYW1lX2VtcHR5Ei12YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdG5hbWUaHSFydWxlcy5ob3N0bmFtZSB8fCB0aGlzICE9ICcnSAASxwEKAmlwGA4gASgIQrgBwki0AQpVCglzdHJpbmcuaXASIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUCBhZGRyZXNzGiYhcnVsZXMuaXAgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXAoKQpbCg9zdHJpbmcuaXBfZW1wdHkSL3ZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUCBhZGRyZXNzGhchcnVsZXMuaXAgfHwgdGhpcyAhPSAnJ0gAEtYBCgRpcHY0GA8gASgIQsUBwkjBAQpcCgtzdHJpbmcuaXB2NBIidmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjQgYWRkcmVzcxopIXJ1bGVzLmlwdjQgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXAoNCkKYQoRc3RyaW5nLmlwdjRfZW1wdHkSMXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IGFkZHJlc3MaGSFydWxlcy5pcHY0IHx8IHRoaXMgIT0gJydIABLWAQoEaXB2NhgQIAEoCELFAcJIwQEKXAoLc3RyaW5nLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaKSFydWxlcy5pcHY2IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKDYpCmEKEXN0cmluZy5pcHY2X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NiBhZGRyZXNzGhkhcnVsZXMuaXB2NiB8fCB0aGlzICE9ICcnSAASvwEKA3VyaRgRIAEoCEKvAcJIqwEKUQoKc3RyaW5nLnVyaRIZdmFsdWUgbXVzdCBiZSBhIHZhbGlkIFVSSRooIXJ1bGVzLnVyaSB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNVcmkoKQpWChBzdHJpbmcudXJpX2VtcHR5Eih2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgVVJJGhghcnVsZXMudXJpIHx8IHRoaXMgIT0gJydIABJwCgd1cmlfcmVmGBIgASgIQl3CSFoKWAoOc3RyaW5nLnVyaV9yZWYSI3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBVUkkgUmVmZXJlbmNlGiEhcnVsZXMudXJpX3JlZiB8fCB0aGlzLmlzVXJpUmVmKClIABKQAgoHYWRkcmVzcxgVIAEoCEL8AcJI+AEKgQEKDnN0cmluZy5hZGRyZXNzEi12YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaG9zdG5hbWUsIG9yIGlwIGFkZHJlc3MaQCFydWxlcy5hZGRyZXNzIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RuYW1lKCkgfHwgdGhpcy5pc0lwKCkKcgoUc3RyaW5nLmFkZHJlc3NfZW1wdHkSPHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBob3N0bmFtZSwgb3IgaXAgYWRkcmVzcxocIXJ1bGVzLmFkZHJlc3MgfHwgdGhpcyAhPSAnJ0gAEpgCCgR1dWlkGBYgASgIQocCwkiDAgqlAQoLc3RyaW5nLnV1aWQSGnZhbHVlIG11c3QgYmUgYSB2YWxpZCBVVUlEGnohcnVsZXMudXVpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSQnKQpZChFzdHJpbmcudXVpZF9lbXB0eRIpdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIFVVSUQaGSFydWxlcy51dWlkIHx8IHRoaXMgIT0gJydIABLwAQoFdHV1aWQYISABKAhC3gHCSNoBCnMKDHN0cmluZy50dXVpZBIidmFsdWUgbXVzdCBiZSBhIHZhbGlkIHRyaW1tZWQgVVVJRBo/IXJ1bGVzLnR1dWlkIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5tYXRjaGVzKCdeWzAtOWEtZkEtRl17MzJ9JCcpCmMKEnN0cmluZy50dXVpZF9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIHRyaW1tZWQgVVVJRBoaIXJ1bGVzLnR1dWlkIHx8IHRoaXMgIT0gJydIABKWAgoRaXBfd2l0aF9wcmVmaXhsZW4YGiABKAhC+AHCSPQBCngKGHN0cmluZy5pcF93aXRoX3ByZWZpeGxlbhIfdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQIHByZWZpeBo7IXJ1bGVzLmlwX3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KCkKeAoec3RyaW5nLmlwX3dpdGhfcHJlZml4bGVuX2VtcHR5Ei52YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgcHJlZml4GiYhcnVsZXMuaXBfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyAhPSAnJ0gAEs8CChNpcHY0X3dpdGhfcHJlZml4bGVuGBsgASgIQq8CwkirAgqTAQoac3RyaW5nLmlwdjRfd2l0aF9wcmVmaXhsZW4SNXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGj4hcnVsZXMuaXB2NF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg0KQqSAQogc3RyaW5nLmlwdjRfd2l0aF9wcmVmaXhsZW5fZW1wdHkSRHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGighcnVsZXMuaXB2NF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzICE9ICcnSAASzwIKE2lwdjZfd2l0aF9wcmVmaXhsZW4YHCABKAhCrwLCSKsCCpMBChpzdHJpbmcuaXB2Nl93aXRoX3ByZWZpeGxlbhI1dmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjYgYWRkcmVzcyB3aXRoIHByZWZpeCBsZW5ndGgaPiFydWxlcy5pcHY2X3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KDYpCpIBCiBzdHJpbmcuaXB2Nl93aXRoX3ByZWZpeGxlbl9lbXB0eRJEdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcyB3aXRoIHByZWZpeCBsZW5ndGgaKCFydWxlcy5pcHY2X3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgIT0gJydIABLyAQoJaXBfcHJlZml4GB0gASgIQtwBwkjYAQpsChBzdHJpbmcuaXBfcHJlZml4Eh92YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgcHJlZml4GjchcnVsZXMuaXBfcHJlZml4IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KHRydWUpCmgKFnN0cmluZy5pcF9wcmVmaXhfZW1wdHkSLnZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUCBwcmVmaXgaHiFydWxlcy5pcF9wcmVmaXggfHwgdGhpcyAhPSAnJ0gAEoMCCgtpcHY0X3ByZWZpeBgeIAEoCELrAcJI5wEKdQoSc3RyaW5nLmlwdjRfcHJlZml4EiF2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NCBwcmVmaXgaPCFydWxlcy5pcHY0X3ByZWZpeCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg0LCB0cnVlKQpuChhzdHJpbmcuaXB2NF9wcmVmaXhfZW1wdHkSMHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IHByZWZpeBogIXJ1bGVzLmlwdjRfcHJlZml4IHx8IHRoaXMgIT0gJydIABKDAgoLaXB2Nl9wcmVmaXgYHyABKAhC6wHCSOcBCnUKEnN0cmluZy5pcHY2X3ByZWZpeBIhdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjYgcHJlZml4GjwhcnVsZXMuaXB2Nl9wcmVmaXggfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNiwgdHJ1ZSkKbgoYc3RyaW5nLmlwdjZfcHJlZml4X2VtcHR5EjB2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NiBwcmVmaXgaICFydWxlcy5pcHY2X3ByZWZpeCB8fCB0aGlzICE9ICcnSAAStQIKDWhvc3RfYW5kX3BvcnQYICABKAhCmwLCSJcCCpkBChRzdHJpbmcuaG9zdF9hbmRfcG9ydBJBdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGhvc3QgKGhvc3RuYW1lIG9yIElQIGFkZHJlc3MpIGFuZCBwb3J0IHBhaXIaPiFydWxlcy5ob3N0X2FuZF9wb3J0IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RBbmRQb3J0KHRydWUpCnkKGnN0cmluZy5ob3N0X2FuZF9wb3J0X2VtcHR5Ejd2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdCBhbmQgcG9ydCBwYWlyGiIhcnVsZXMuaG9zdF9hbmRfcG9ydCB8fCB0aGlzICE9ICcnSAASqAUKEHdlbGxfa25vd25fcmVnZXgYGCABKA4yGC5idWYudmFsaWRhdGUuS25vd25SZWdleELxBMJI7QQK8AEKI3N0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lEiZ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRqgAXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMSB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXjo/WzAtOWEtekEtWiEjJCUmXCcqKy0uXl98flx4NjBdKyQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSskJykKjQEKKXN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lX2VtcHR5EjV2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRopcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAxIHx8IHRoaXMgIT0gJycK5wEKJHN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl92YWx1ZRIndmFsdWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgaGVhZGVyIHZhbHVlGpUBcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAyIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXlteXHUwMDAwLVx1MDAwOFx1MDAwQS1cdTAwMUZcdTAwN0ZdKiQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSokJylIABIOCgZzdHJpY3QYGSABKAgSLAoHZXhhbXBsZRgiIAMoCUIbwkgYChYKDnN0cmluZy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLqEAoKQnl0ZXNSdWxlcxKAAQoFY29uc3QYASABKAxCccJIbgpsCgtieXRlcy5jb25zdBpddGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBiZSAleCcuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEngKA2xlbhgNIAEoBEJrwkhoCmYKCWJ5dGVzLmxlbhpZdWludCh0aGlzLnNpemUoKSkgIT0gcnVsZXMubGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLmxlbl0pIDogJycSkAEKB21pbl9sZW4YAiABKARCf8JIfAp6Cg1ieXRlcy5taW5fbGVuGml1aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2xlbl0pIDogJycSiAEKB21heF9sZW4YAyABKARCd8JIdApyCg1ieXRlcy5tYXhfbGVuGmF1aW50KHRoaXMuc2l6ZSgpKSA+IHJ1bGVzLm1heF9sZW4gPyAndmFsdWUgbXVzdCBiZSBhdCBtb3N0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1heF9sZW5dKSA6ICcnEpABCgdwYXR0ZXJuGAQgASgJQn/CSHwKegoNYnl0ZXMucGF0dGVybhppIXN0cmluZyh0aGlzKS5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIG11c3QgbWF0Y2ggcmVnZXggcGF0dGVybiBgJXNgJy5mb3JtYXQoW3J1bGVzLnBhdHRlcm5dKSA6ICcnEoEBCgZwcmVmaXgYBSABKAxCccJIbgpsCgxieXRlcy5wcmVmaXgaXCF0aGlzLnN0YXJ0c1dpdGgocnVsZXMucHJlZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHByZWZpeCAleCcuZm9ybWF0KFtydWxlcy5wcmVmaXhdKSA6ICcnEn8KBnN1ZmZpeBgGIAEoDEJvwkhsCmoKDGJ5dGVzLnN1ZmZpeBpaIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCAleCcuZm9ybWF0KFtydWxlcy5zdWZmaXhdKSA6ICcnEoMBCghjb250YWlucxgHIAEoDEJxwkhuCmwKDmJ5dGVzLmNvbnRhaW5zGlohdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiAleCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSpwEKAmluGAggAygMQpoBwkiWAQqTAQoIYnl0ZXMuaW4ahgFnZXRGaWVsZChydWxlcywgJ2luJykuc2l6ZSgpID4gMCAmJiAhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ2CgZub3RfaW4YCSADKAxCZsJIYwphCgxieXRlcy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLrAQoCaXAYCiABKAhC3AHCSNgBCnQKCGJ5dGVzLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxpGIXJ1bGVzLmlwIHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNCB8fCB0aGlzLnNpemUoKSA9PSAxNgpgCg5ieXRlcy5pcF9lbXB0eRIvdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIGFkZHJlc3MaHSFydWxlcy5pcCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5AEKBGlwdjQYCyABKAhC0wHCSM8BCmUKCmJ5dGVzLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaMyFydWxlcy5pcHY0IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNApmChBieXRlcy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGh8hcnVsZXMuaXB2NCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5QEKBGlwdjYYDCABKAhC1AHCSNABCmYKCmJ5dGVzLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaNCFydWxlcy5pcHY2IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gMTYKZgoQYnl0ZXMuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxofIXJ1bGVzLmlwdjYgfHwgdGhpcy5zaXplKCkgIT0gMEgAEisKB2V4YW1wbGUYDiADKAxCGsJIFwoVCg1ieXRlcy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLUAwoJRW51bVJ1bGVzEoIBCgVjb25zdBgBIAEoBUJzwkhwCm4KCmVudW0uY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxIUCgxkZWZpbmVkX29ubHkYAiABKAgSfgoCaW4YAyADKAVCcsJIbwptCgdlbnVtLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ1CgZub3RfaW4YBCADKAVCZcJIYgpgCgtlbnVtLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEioKB2V4YW1wbGUYBSADKAVCGcJIFgoUCgxlbnVtLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiL7AwoNUmVwZWF0ZWRSdWxlcxKeAQoJbWluX2l0ZW1zGAEgASgEQooBwkiGAQqDAQoScmVwZWF0ZWQubWluX2l0ZW1zGm11aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9pdGVtcyA/ICd2YWx1ZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3QgJWQgaXRlbShzKScuZm9ybWF0KFtydWxlcy5taW5faXRlbXNdKSA6ICcnEqIBCgltYXhfaXRlbXMYAiABKARCjgHCSIoBCocBChJyZXBlYXRlZC5tYXhfaXRlbXMacXVpbnQodGhpcy5zaXplKCkpID4gcnVsZXMubWF4X2l0ZW1zID8gJ3ZhbHVlIG11c3QgY29udGFpbiBubyBtb3JlIHRoYW4gJXMgaXRlbShzKScuZm9ybWF0KFtydWxlcy5tYXhfaXRlbXNdKSA6ICcnEnAKBnVuaXF1ZRgDIAEoCEJgwkhdClsKD3JlcGVhdGVkLnVuaXF1ZRIocmVwZWF0ZWQgdmFsdWUgbXVzdCBjb250YWluIHVuaXF1ZSBpdGVtcxoeIXJ1bGVzLnVuaXF1ZSB8fCB0aGlzLnVuaXF1ZSgpEicKBWl0ZW1zGAQgASgLMhguYnVmLnZhbGlkYXRlLkZpZWxkUnVsZXMqCQjoBxCAgICAAiKKAwoITWFwUnVsZXMSjwEKCW1pbl9wYWlycxgBIAEoBEJ8wkh5CncKDW1hcC5taW5fcGFpcnMaZnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX3BhaXJzID8gJ21hcCBtdXN0IGJlIGF0IGxlYXN0ICVkIGVudHJpZXMnLmZvcm1hdChbcnVsZXMubWluX3BhaXJzXSkgOiAnJxKOAQoJbWF4X3BhaXJzGAIgASgEQnvCSHgKdgoNbWFwLm1heF9wYWlycxpldWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfcGFpcnMgPyAnbWFwIG11c3QgYmUgYXQgbW9zdCAlZCBlbnRyaWVzJy5mb3JtYXQoW3J1bGVzLm1heF9wYWlyc10pIDogJycSJgoEa2V5cxgEIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzEigKBnZhbHVlcxgFIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzKgkI6AcQgICAgAIiJgoIQW55UnVsZXMSCgoCaW4YAiADKAkSDgoGbm90X2luGAMgAygJIpkXCg1EdXJhdGlvblJ1bGVzEqEBCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkJ3wkh0CnIKDmR1cmF0aW9uLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSqAEKAmx0GAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQn/CSHwKegoLZHVyYXRpb24ubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASugEKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkKPAcJIiwEKiAEKDGR1cmF0aW9uLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASwQcKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQpcHwkiTBwp9CgtkdXJhdGlvbi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDmR1cmF0aW9uLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYZHVyYXRpb24uZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD2R1cmF0aW9uLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGWR1cmF0aW9uLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEo0ICgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25C4gfCSN4HCosBCgxkdXJhdGlvbi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPZHVyYXRpb24uZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlkdXJhdGlvbi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQZHVyYXRpb24uZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoaZHVyYXRpb24uZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESnQEKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQnbCSHMKcQoLZHVyYXRpb24uaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEpQBCgZub3RfaW4YCCADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25CacJIZgpkCg9kdXJhdGlvbi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJJCgdleGFtcGxlGAkgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQh3CSBoKGAoQZHVyYXRpb24uZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4ikhgKDlRpbWVzdGFtcFJ1bGVzEqMBCgVjb25zdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCeMJIdQpzCg90aW1lc3RhbXAuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKrAQoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQoABwkh9CnsKDHRpbWVzdGFtcC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABK8AQoDbHRlGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKQAcJIjAEKiQEKDXRpbWVzdGFtcC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEmwKBmx0X25vdxgHIAEoCEJawkhXClUKEHRpbWVzdGFtcC5sdF9ub3caQShydWxlcy5sdF9ub3cgJiYgdGhpcyA+IG5vdykgPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gbm93JyA6ICcnSAASxwcKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKcB8JImAcKfgoMdGltZXN0YW1wLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq3AQoPdGltZXN0YW1wLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq/AQoZdGltZXN0YW1wLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCscBChB0aW1lc3RhbXAuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrPAQoadGltZXN0YW1wLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEpMICgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQucHwkjjBwqMAQoNdGltZXN0YW1wLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsYBChB0aW1lc3RhbXAuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs4BChp0aW1lc3RhbXAuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1gEKEXRpbWVzdGFtcC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt4BCht0aW1lc3RhbXAuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESbwoGZ3Rfbm93GAggASgIQl3CSFoKWAoQdGltZXN0YW1wLmd0X25vdxpEKHJ1bGVzLmd0X25vdyAmJiB0aGlzIDwgbm93KSA/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBub3cnIDogJydIARK4AQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQowBwkiIAQqFAQoQdGltZXN0YW1wLndpdGhpbhpxdGhpcyA8IG5vdy1ydWxlcy53aXRoaW4gfHwgdGhpcyA+IG5vdytydWxlcy53aXRoaW4gPyAndmFsdWUgbXVzdCBiZSB3aXRoaW4gJXMgb2Ygbm93Jy5mb3JtYXQoW3J1bGVzLndpdGhpbl0pIDogJycSSwoHZXhhbXBsZRgKIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCHsJIGwoZChF0aW1lc3RhbXAuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iOQoKVmlvbGF0aW9ucxIrCgp2aW9sYXRpb25zGAEgAygLMhcuYnVmLnZhbGlkYXRlLlZpb2xhdGlvbiKfAQoJVmlvbGF0aW9uEiYKBWZpZWxkGAUgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIlCgRydWxlGAYgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIPCgdydWxlX2lkGAIgASgJEg8KB21lc3NhZ2UYAyABKAkSDwoHZm9yX2tleRgEIAEoCEoECAEQAlIKZmllbGRfcGF0aCI9CglGaWVsZFBhdGgSMAoIZWxlbWVudHMYASADKAsyHi5idWYudmFsaWRhdGUuRmllbGRQYXRoRWxlbWVudCLpAgoQRmllbGRQYXRoRWxlbWVudBIUCgxmaWVsZF9udW1iZXIYASABKAUSEgoKZmllbGRfbmFtZRgCIAEoCRI+CgpmaWVsZF90eXBlGAMgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSPAoIa2V5X3R5cGUYBCABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRI+Cgp2YWx1ZV90eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSDwoFaW5kZXgYBiABKARIABISCghib29sX2tleRgHIAEoCEgAEhEKB2ludF9rZXkYCCABKANIABISCgh1aW50X2tleRgJIAEoBEgAEhQKCnN0cmluZ19rZXkYCiABKAlIAEILCglzdWJzY3JpcHQqhwEKBklnbm9yZRIWChJJR05PUkVfVU5TUEVDSUZJRUQQABIZChVJR05PUkVfSUZfVU5QT1BVTEFURUQQARIbChdJR05PUkVfSUZfREVGQVVMVF9WQUxVRRACEhEKDUlHTk9SRV9BTFdBWVMQAyoaSUdOT1JFX0VNUFRZSUdOT1JFX0RFRkFVTFQqbgoKS25vd25SZWdleBIbChdLTk9XTl9SRUdFWF9VTlNQRUNJRklFRBAAEiAKHEtOT1dOX1JFR0VYX0hUVFBfSEVBREVSX05BTUUQARIhCh1LTk9XTl9SRUdFWF9IVFRQX0hFQURFUl9WQUxVRRACOlYKB21lc3NhZ2USHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhwkgASgLMhouYnVmLnZhbGlkYXRlLk1lc3NhZ2VSdWxlc1IHbWVzc2FnZTpOCgVvbmVvZhIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMYhwkgASgLMhguYnVmLnZhbGlkYXRlLk9uZW9mUnVsZXNSBW9uZW9mOk4KBWZpZWxkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiHCSABKAsyGC5idWYudmFsaWRhdGUuRmllbGRSdWxlc1IFZmllbGQ6XQoKcHJlZGVmaW5lZBIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMYiAkgASgLMh0uYnVmLnZhbGlkYXRlLlByZWRlZmluZWRSdWxlc1IKcHJlZGVmaW5lZEJuChJidWlsZC5idWYudmFsaWRhdGVCDVZhbGlkYXRlUHJvdG9QAVpHYnVmLmJ1aWxkL2dlbi9nby9idWZidWlsZC9wcm90b3ZhbGlkYXRlL3Byb3RvY29sYnVmZmVycy9nby9idWYvdmFsaWRhdGU", [file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_timestamp]);
/**
- * `Constraint` represents a validation rule written in the Common Expression
- * Language (CEL) syntax. Each Constraint includes a unique identifier, an
+ * `Rule` represents a validation rule written in the Common Expression
+ * Language (CEL) syntax. Each Rule includes a unique identifier, an
* optional error message, and the CEL expression to evaluate. For more
* information on CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
*
@@ -45,11 +45,11 @@ export const file_buf_validate_validate: GenFile = /*@__PURE__*/
* }
* ```
*
- * @generated from message buf.validate.Constraint
+ * @generated from message buf.validate.Rule
*/
-export type Constraint = Message<"buf.validate.Constraint"> & {
+export type Rule = Message<"buf.validate.Rule"> & {
/**
- * `id` is a string that serves as a machine-readable name for this Constraint.
+ * `id` is a string that serves as a machine-readable name for this Rule.
* It should be unique within its scope, which could be either a message or a field.
*
* @generated from field: optional string id = 1;
@@ -58,7 +58,7 @@ export type Constraint = Message<"buf.validate.Constraint"> & {
/**
* `message` is an optional field that provides a human-readable error message
- * for this Constraint when the CEL expression evaluates to false. If a
+ * for this Rule when the CEL expression evaluates to false. If a
* non-empty message is provided, any strings resulting from the CEL
* expression evaluation are ignored.
*
@@ -78,19 +78,19 @@ export type Constraint = Message<"buf.validate.Constraint"> & {
};
/**
- * Describes the message buf.validate.Constraint.
- * Use `create(ConstraintSchema)` to create a new message.
+ * Describes the message buf.validate.Rule.
+ * Use `create(RuleSchema)` to create a new message.
*/
-export const ConstraintSchema: GenMessage = /*@__PURE__*/
+export const RuleSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 0);
/**
- * MessageConstraints represents validation rules that are applied to the entire message.
- * It includes disabling options and a list of Constraint messages representing Common Expression Language (CEL) validation rules.
+ * MessageRules represents validation rules that are applied to the entire message.
+ * It includes disabling options and a list of Rule messages representing Common Expression Language (CEL) validation rules.
*
- * @generated from message buf.validate.MessageConstraints
+ * @generated from message buf.validate.MessageRules
*/
-export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
+export type MessageRules = Message<"buf.validate.MessageRules"> & {
/**
* `disabled` is a boolean flag that, when set to true, nullifies any validation rules for this message.
* This includes any fields within the message that would otherwise support validation.
@@ -107,8 +107,8 @@ export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
disabled: boolean;
/**
- * `cel` is a repeated field of type Constraint. Each Constraint specifies a validation rule to be applied to this message.
- * These constraints are written in Common Expression Language (CEL) syntax. For more information on
+ * `cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message.
+ * These rules are written in Common Expression Language (CEL) syntax. For more information on
* CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
*
*
@@ -124,29 +124,29 @@ export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 3;
+ * @generated from field: repeated buf.validate.Rule cel = 3;
*/
- cel: Constraint[];
+ cel: Rule[];
};
/**
- * Describes the message buf.validate.MessageConstraints.
- * Use `create(MessageConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.MessageRules.
+ * Use `create(MessageRulesSchema)` to create a new message.
*/
-export const MessageConstraintsSchema: GenMessage = /*@__PURE__*/
+export const MessageRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 1);
/**
- * The `OneofConstraints` message type enables you to manage constraints for
+ * The `OneofRules` message type enables you to manage rules for
* oneof fields in your protobuf messages.
*
- * @generated from message buf.validate.OneofConstraints
+ * @generated from message buf.validate.OneofRules
*/
-export type OneofConstraints = Message<"buf.validate.OneofConstraints"> & {
+export type OneofRules = Message<"buf.validate.OneofRules"> & {
/**
* If `required` is true, exactly one field of the oneof must be present. A
* validation error is returned if no fields in the oneof are present. The
- * field itself may still be a default value; further constraints
+ * field itself may still be a default value; further rules
* should be placed on the fields themselves to ensure they are valid values,
* such as `min_len` or `gt`.
*
@@ -168,19 +168,19 @@ export type OneofConstraints = Message<"buf.validate.OneofConstraints"> & {
};
/**
- * Describes the message buf.validate.OneofConstraints.
- * Use `create(OneofConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.OneofRules.
+ * Use `create(OneofRulesSchema)` to create a new message.
*/
-export const OneofConstraintsSchema: GenMessage = /*@__PURE__*/
+export const OneofRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 2);
/**
- * FieldConstraints encapsulates the rules for each type of field. Depending on
+ * FieldRules encapsulates the rules for each type of field. Depending on
* the field, the correct set should be used to ensure proper validations.
*
- * @generated from message buf.validate.FieldConstraints
+ * @generated from message buf.validate.FieldRules
*/
-export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
+export type FieldRules = Message<"buf.validate.FieldRules"> & {
/**
* `cel` is a repeated field used to represent a textual expression
* in the Common Expression Language (CEL) syntax. For more information on
@@ -197,9 +197,9 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 23;
+ * @generated from field: repeated buf.validate.Rule cel = 23;
*/
- cel: Constraint[];
+ cel: Rule[];
/**
* If `required` is true, the field must be populated. A populated field can be
@@ -244,7 +244,7 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
ignore: Ignore;
/**
- * @generated from oneof buf.validate.FieldConstraints.type
+ * @generated from oneof buf.validate.FieldRules.type
*/
type: {
/**
@@ -382,19 +382,19 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
};
/**
- * Describes the message buf.validate.FieldConstraints.
- * Use `create(FieldConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.FieldRules.
+ * Use `create(FieldRulesSchema)` to create a new message.
*/
-export const FieldConstraintsSchema: GenMessage = /*@__PURE__*/
+export const FieldRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 3);
/**
- * PredefinedConstraints are custom constraints that can be re-used with
+ * PredefinedRules are custom rules that can be re-used with
* multiple fields.
*
- * @generated from message buf.validate.PredefinedConstraints
+ * @generated from message buf.validate.PredefinedRules
*/
-export type PredefinedConstraints = Message<"buf.validate.PredefinedConstraints"> & {
+export type PredefinedRules = Message<"buf.validate.PredefinedRules"> & {
/**
* `cel` is a repeated field used to represent a textual expression
* in the Common Expression Language (CEL) syntax. For more information on
@@ -411,20 +411,20 @@ export type PredefinedConstraints = Message<"buf.validate.PredefinedConstraints"
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 1;
+ * @generated from field: repeated buf.validate.Rule cel = 1;
*/
- cel: Constraint[];
+ cel: Rule[];
};
/**
- * Describes the message buf.validate.PredefinedConstraints.
- * Use `create(PredefinedConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.PredefinedRules.
+ * Use `create(PredefinedRulesSchema)` to create a new message.
*/
-export const PredefinedConstraintsSchema: GenMessage = /*@__PURE__*/
+export const PredefinedRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 4);
/**
- * FloatRules describes the constraints applied to `float` values. These
+ * FloatRules describes the rules applied to `float` values. These
* rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type.
*
* @generated from message buf.validate.FloatRules
@@ -581,7 +581,7 @@ export type FloatRules = Message<"buf.validate.FloatRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -606,7 +606,7 @@ export const FloatRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 5);
/**
- * DoubleRules describes the constraints applied to `double` values. These
+ * DoubleRules describes the rules applied to `double` values. These
* rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type.
*
* @generated from message buf.validate.DoubleRules
@@ -763,7 +763,7 @@ export type DoubleRules = Message<"buf.validate.DoubleRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -788,7 +788,7 @@ export const DoubleRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 6);
/**
- * Int32Rules describes the constraints applied to `int32` values. These
+ * Int32Rules describes the rules applied to `int32` values. These
* rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type.
*
* @generated from message buf.validate.Int32Rules
@@ -937,7 +937,7 @@ export type Int32Rules = Message<"buf.validate.Int32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -962,7 +962,7 @@ export const Int32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 7);
/**
- * Int64Rules describes the constraints applied to `int64` values. These
+ * Int64Rules describes the rules applied to `int64` values. These
* rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type.
*
* @generated from message buf.validate.Int64Rules
@@ -1111,7 +1111,7 @@ export type Int64Rules = Message<"buf.validate.Int64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1136,7 +1136,7 @@ export const Int64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 8);
/**
- * UInt32Rules describes the constraints applied to `uint32` values. These
+ * UInt32Rules describes the rules applied to `uint32` values. These
* rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type.
*
* @generated from message buf.validate.UInt32Rules
@@ -1285,7 +1285,7 @@ export type UInt32Rules = Message<"buf.validate.UInt32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1310,7 +1310,7 @@ export const UInt32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 9);
/**
- * UInt64Rules describes the constraints applied to `uint64` values. These
+ * UInt64Rules describes the rules applied to `uint64` values. These
* rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type.
*
* @generated from message buf.validate.UInt64Rules
@@ -1459,7 +1459,7 @@ export type UInt64Rules = Message<"buf.validate.UInt64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1484,7 +1484,7 @@ export const UInt64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 10);
/**
- * SInt32Rules describes the constraints applied to `sint32` values.
+ * SInt32Rules describes the rules applied to `sint32` values.
*
* @generated from message buf.validate.SInt32Rules
*/
@@ -1632,7 +1632,7 @@ export type SInt32Rules = Message<"buf.validate.SInt32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1657,7 +1657,7 @@ export const SInt32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 11);
/**
- * SInt64Rules describes the constraints applied to `sint64` values.
+ * SInt64Rules describes the rules applied to `sint64` values.
*
* @generated from message buf.validate.SInt64Rules
*/
@@ -1805,7 +1805,7 @@ export type SInt64Rules = Message<"buf.validate.SInt64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1830,7 +1830,7 @@ export const SInt64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 12);
/**
- * Fixed32Rules describes the constraints applied to `fixed32` values.
+ * Fixed32Rules describes the rules applied to `fixed32` values.
*
* @generated from message buf.validate.Fixed32Rules
*/
@@ -1978,7 +1978,7 @@ export type Fixed32Rules = Message<"buf.validate.Fixed32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2003,7 +2003,7 @@ export const Fixed32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 13);
/**
- * Fixed64Rules describes the constraints applied to `fixed64` values.
+ * Fixed64Rules describes the rules applied to `fixed64` values.
*
* @generated from message buf.validate.Fixed64Rules
*/
@@ -2151,7 +2151,7 @@ export type Fixed64Rules = Message<"buf.validate.Fixed64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2176,7 +2176,7 @@ export const Fixed64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 14);
/**
- * SFixed32Rules describes the constraints applied to `fixed32` values.
+ * SFixed32Rules describes the rules applied to `fixed32` values.
*
* @generated from message buf.validate.SFixed32Rules
*/
@@ -2324,7 +2324,7 @@ export type SFixed32Rules = Message<"buf.validate.SFixed32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2349,7 +2349,7 @@ export const SFixed32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 15);
/**
- * SFixed64Rules describes the constraints applied to `fixed64` values.
+ * SFixed64Rules describes the rules applied to `fixed64` values.
*
* @generated from message buf.validate.SFixed64Rules
*/
@@ -2497,7 +2497,7 @@ export type SFixed64Rules = Message<"buf.validate.SFixed64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2522,7 +2522,7 @@ export const SFixed64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 16);
/**
- * BoolRules describes the constraints applied to `bool` values. These rules
+ * BoolRules describes the rules applied to `bool` values. These rules
* may also be applied to the `google.protobuf.BoolValue` Well-Known-Type.
*
* @generated from message buf.validate.BoolRules
@@ -2545,7 +2545,7 @@ export type BoolRules = Message<"buf.validate.BoolRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2570,7 +2570,7 @@ export const BoolRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 17);
/**
- * StringRules describes the constraints applied to `string` values These
+ * StringRules describes the rules applied to `string` values These
* rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type.
*
* @generated from message buf.validate.StringRules
@@ -2805,15 +2805,21 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
notIn: string[];
/**
- * `WellKnown` rules provide advanced constraints against common string
- * patterns
+ * `WellKnown` rules provide advanced rules against common string
+ * patterns.
*
* @generated from oneof buf.validate.StringRules.well_known
*/
wellKnown: {
/**
- * `email` specifies that the field value must be a valid email address
- * (addr-spec only) as defined by [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1).
+ * `email` specifies that the field value must be a valid email address, for
+ * example "foo@example.com".
+ *
+ * Conforms to the definition for a valid email address from the [HTML standard](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
+ * Note that this standard willfully deviates from [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322),
+ * which allows many unexpected forms of email addresses and will easily match
+ * a typographical error.
+ *
* If the field value isn't a valid email address, an error message will be generated.
*
* ```proto
@@ -2829,10 +2835,18 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "email";
} | {
/**
- * `hostname` specifies that the field value must be a valid
- * hostname as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5). This constraint doesn't support
- * internationalized domain names (IDNs). If the field value isn't a
- * valid hostname, an error message will be generated.
+ * `hostname` specifies that the field value must be a valid hostname, for
+ * example "foo.example.com".
+ *
+ * A valid hostname follows the rules below:
+ * - The name consists of one or more labels, separated by a dot (".").
+ * - Each label can be 1 to 63 alphanumeric characters.
+ * - A label can contain hyphens ("-"), but must not start or end with a hyphen.
+ * - The right-most label must not be digits only.
+ * - The name can have a trailing dot—for example, "foo.example.com.".
+ * - The name can be 253 characters at most, excluding the optional trailing dot.
+ *
+ * If the field value isn't a valid hostname, an error message will be generated.
*
* ```proto
* message MyString {
@@ -2847,8 +2861,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "hostname";
} | {
/**
- * `ip` specifies that the field value must be a valid IP
- * (v4 or v6) address, without surrounding square brackets for IPv6 addresses.
+ * `ip` specifies that the field value must be a valid IP (v4 or v6) address.
+ *
+ * IPv4 addresses are expected in the dotted decimal format—for example, "192.168.5.21".
+ * IPv6 addresses are expected in their text representation—for example, "::1",
+ * or "2001:0DB8:ABCD:0012::0".
+ *
+ * Both formats are well-defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ * Zone identifiers for IPv6 addresses (for example, "fe80::a%en1") are supported.
+ *
* If the field value isn't a valid IP address, an error message will be
* generated.
*
@@ -2865,9 +2886,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ip";
} | {
/**
- * `ipv4` specifies that the field value must be a valid IPv4
- * address. If the field value isn't a valid IPv4 address, an error message
- * will be generated.
+ * `ipv4` specifies that the field value must be a valid IPv4 address—for
+ * example "192.168.5.21". If the field value isn't a valid IPv4 address, an
+ * error message will be generated.
*
* ```proto
* message MyString {
@@ -2882,9 +2903,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv4";
} | {
/**
- * `ipv6` specifies that the field value must be a valid
- * IPv6 address, without surrounding square brackets. If the field value is
- * not a valid IPv6 address, an error message will be generated.
+ * `ipv6` specifies that the field value must be a valid IPv6 address—for
+ * example "::1", or "d7a:115c:a1e0:ab12:4843:cd96:626b:430b". If the field
+ * value is not a valid IPv6 address, an error message will be generated.
*
* ```proto
* message MyString {
@@ -2899,8 +2920,11 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6";
} | {
/**
- * `uri` specifies that the field value must be a valid URI as defined by
- * [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
+ * `uri` specifies that the field value must be a valid URI, for example
+ * "https://example.com/foo/bar?baz=quux#frag".
+ *
+ * URI is defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ * Zone Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
*
* If the field value isn't a valid URI, an error message will be generated.
*
@@ -2917,11 +2941,13 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "uri";
} | {
/**
- * `uri_ref` specifies that the field value must be a valid URI Reference as
- * defined by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-4.1).
+ * `uri_ref` specifies that the field value must be a valid URI Reference—either
+ * a URI such as "https://example.com/foo/bar?baz=quux#frag", or a Relative
+ * Reference such as "./foo/bar?query".
*
- * A URI Reference is either a [URI](https://datatracker.ietf.org/doc/html/rfc3986#section-3),
- * or a [Relative Reference](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2).
+ * URI, URI Reference, and Relative Reference are defined in the internet
+ * standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). Zone
+ * Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
*
* If the field value isn't a valid URI Reference, an error message will be
* generated.
@@ -2940,10 +2966,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `address` specifies that the field value must be either a valid hostname
- * as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5)
- * (which doesn't support internationalized domain names or IDNs) or a valid
- * IP (v4 or v6). If the field value isn't a valid hostname or IP, an error
- * message will be generated.
+ * (for example, "example.com"), or a valid IP (v4 or v6) address (for example,
+ * "192.168.0.1", or "::1"). If the field value isn't a valid hostname or IP,
+ * an error message will be generated.
*
* ```proto
* message MyString {
@@ -2993,10 +3018,10 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "tuuid";
} | {
/**
- * `ip_with_prefixlen` specifies that the field value must be a valid IP (v4 or v6)
- * address with prefix length. If the field value isn't a valid IP with prefix
- * length, an error message will be generated.
- *
+ * `ip_with_prefixlen` specifies that the field value must be a valid IP
+ * (v4 or v6) address with prefix length—for example, "192.168.5.21/16" or
+ * "2001:0DB8:ABCD:0012::F1/64". If the field value isn't a valid IP with
+ * prefix length, an error message will be generated.
*
* ```proto
* message MyString {
@@ -3012,9 +3037,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv4_with_prefixlen` specifies that the field value must be a valid
- * IPv4 address with prefix.
- * If the field value isn't a valid IPv4 address with prefix length,
- * an error message will be generated.
+ * IPv4 address with prefix length—for example, "192.168.5.21/16". If the
+ * field value isn't a valid IPv4 address with prefix length, an error
+ * message will be generated.
*
* ```proto
* message MyString {
@@ -3030,7 +3055,7 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv6_with_prefixlen` specifies that the field value must be a valid
- * IPv6 address with prefix length.
+ * IPv6 address with prefix length—for example, "2001:0DB8:ABCD:0012::F1/64".
* If the field value is not a valid IPv6 address with prefix length,
* an error message will be generated.
*
@@ -3047,10 +3072,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6WithPrefixlen";
} | {
/**
- * `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) prefix.
+ * `ip_prefix` specifies that the field value must be a valid IP (v4 or v6)
+ * prefix—for example, "192.168.0.0/16" or "2001:0DB8:ABCD:0012::0/64".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ * prefix, and the remaining 64 bits must be zero.
+ *
* If the field value isn't a valid IP prefix, an error message will be
- * generated. The prefix must have all zeros for the masked bits of the prefix (e.g.,
- * `127.0.0.0/16`, not `127.0.0.1/16`).
+ * generated.
*
* ```proto
* message MyString {
@@ -3066,9 +3096,14 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv4_prefix` specifies that the field value must be a valid IPv4
- * prefix. If the field value isn't a valid IPv4 prefix, an error message
- * will be generated. The prefix must have all zeros for the masked bits of
- * the prefix (e.g., `127.0.0.0/16`, not `127.0.0.1/16`).
+ * prefix, for example "192.168.0.0/16".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "192.168.0.0/16" designates the left-most 16 bits for the prefix,
+ * and the remaining 16 bits must be zero.
+ *
+ * If the field value isn't a valid IPv4 prefix, an error message
+ * will be generated.
*
* ```proto
* message MyString {
@@ -3083,10 +3118,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv4Prefix";
} | {
/**
- * `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix.
+ * `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix—for
+ * example, "2001:0DB8:ABCD:0012::0/64".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ * prefix, and the remaining 64 bits must be zero.
+ *
* If the field value is not a valid IPv6 prefix, an error message will be
- * generated. The prefix must have all zeros for the masked bits of the prefix
- * (e.g., `2001:db8::/48`, not `2001:db8::1/48`).
+ * generated.
*
* ```proto
* message MyString {
@@ -3101,10 +3141,16 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6Prefix";
} | {
/**
- * `host_and_port` specifies the field value must be a valid host and port
- * pair. The host must be a valid hostname or IP address while the port
- * must be in the range of 0-65535, inclusive. IPv6 addresses must be delimited
- * with square brackets (e.g., `[::1]:1234`).
+ * `host_and_port` specifies that the field value must be valid host/port
+ * pair—for example, "example.com:8080".
+ *
+ * The host can be one of:
+ * - An IPv4 address in dotted decimal format—for example, "192.168.5.21".
+ * - An IPv6 address enclosed in square brackets—for example, "[2001:0DB8:ABCD:0012::F1]".
+ * - A hostname—for example, "example.com".
+ *
+ * The port is separated by a colon. It must be non-empty, with a decimal number
+ * in the range of 0-65535, inclusive.
*
* @generated from field: bool host_and_port = 32;
*/
@@ -3159,7 +3205,7 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3184,7 +3230,7 @@ export const StringRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 18);
/**
- * BytesRules describe the constraints applied to `bytes` values. These rules
+ * BytesRules describe the rules applied to `bytes` values. These rules
* may also be applied to the `google.protobuf.BytesValue` Well-Known-Type.
*
* @generated from message buf.validate.BytesRules
@@ -3352,7 +3398,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
notIn: Uint8Array[];
/**
- * WellKnown rules provide advanced constraints against common byte
+ * WellKnown rules provide advanced rules against common byte
* patterns
*
* @generated from oneof buf.validate.BytesRules.well_known
@@ -3360,7 +3406,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
wellKnown: {
/**
* `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
*
* ```proto
* message MyBytes {
@@ -3376,7 +3422,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
} | {
/**
* `ipv4` ensures that the field `value` is a valid IPv4 address in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
*
* ```proto
* message MyBytes {
@@ -3392,7 +3438,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
} | {
/**
* `ipv6` ensures that the field `value` is a valid IPv6 address in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
* ```proto
* message MyBytes {
* // value must be a valid IPv6 address
@@ -3408,7 +3454,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3433,7 +3479,7 @@ export const BytesRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 19);
/**
- * EnumRules describe the constraints applied to `enum` values.
+ * EnumRules describe the rules applied to `enum` values.
*
* @generated from message buf.validate.EnumRules
*/
@@ -3526,7 +3572,7 @@ export type EnumRules = Message<"buf.validate.EnumRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3555,7 +3601,7 @@ export const EnumRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 20);
/**
- * RepeatedRules describe the constraints applied to `repeated` values.
+ * RepeatedRules describe the rules applied to `repeated` values.
*
* @generated from message buf.validate.RepeatedRules
*/
@@ -3596,7 +3642,7 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
/**
* `unique` indicates that all elements in this field must
- * be unique. This constraint is strictly applicable to scalar and enum
+ * be unique. This rule is strictly applicable to scalar and enum
* types, with message types not being supported.
*
* ```proto
@@ -3611,13 +3657,13 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
unique: boolean;
/**
- * `items` details the constraints to be applied to each item
+ * `items` details the rules to be applied to each item
* in the field. Even for repeated message fields, validation is executed
* against each item unless skip is explicitly specified.
*
* ```proto
* message MyRepeated {
- * // The items in the field `value` must follow the specified constraints.
+ * // The items in the field `value` must follow the specified rules.
* repeated string value = 1 [(buf.validate.field).repeated.items = {
* string: {
* min_len: 3
@@ -3627,9 +3673,9 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints items = 4;
+ * @generated from field: optional buf.validate.FieldRules items = 4;
*/
- items?: FieldConstraints;
+ items?: FieldRules;
};
/**
@@ -3640,7 +3686,7 @@ export const RepeatedRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 21);
/**
- * MapRules describe the constraints applied to `map` values.
+ * MapRules describe the rules applied to `map` values.
*
* @generated from message buf.validate.MapRules
*/
@@ -3676,11 +3722,11 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
maxPairs: bigint;
/**
- * Specifies the constraints to be applied to each key in the field.
+ * Specifies the rules to be applied to each key in the field.
*
* ```proto
* message MyMap {
- * // The keys in the field `value` must follow the specified constraints.
+ * // The keys in the field `value` must follow the specified rules.
* map value = 1 [(buf.validate.field).map.keys = {
* string: {
* min_len: 3
@@ -3690,18 +3736,18 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints keys = 4;
+ * @generated from field: optional buf.validate.FieldRules keys = 4;
*/
- keys?: FieldConstraints;
+ keys?: FieldRules;
/**
- * Specifies the constraints to be applied to the value of each key in the
+ * Specifies the rules to be applied to the value of each key in the
* field. Message values will still have their validations evaluated unless
* skip is specified here.
*
* ```proto
* message MyMap {
- * // The values in the field `value` must follow the specified constraints.
+ * // The values in the field `value` must follow the specified rules.
* map value = 1 [(buf.validate.field).map.values = {
* string: {
* min_len: 5
@@ -3711,9 +3757,9 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints values = 5;
+ * @generated from field: optional buf.validate.FieldRules values = 5;
*/
- values?: FieldConstraints;
+ values?: FieldRules;
};
/**
@@ -3724,7 +3770,7 @@ export const MapRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 22);
/**
- * AnyRules describe constraints applied exclusively to the `google.protobuf.Any` well-known type.
+ * AnyRules describe rules applied exclusively to the `google.protobuf.Any` well-known type.
*
* @generated from message buf.validate.AnyRules
*/
@@ -3768,7 +3814,7 @@ export const AnyRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 23);
/**
- * DurationRules describe the constraints applied exclusively to the `google.protobuf.Duration` well-known type.
+ * DurationRules describe the rules applied exclusively to the `google.protobuf.Duration` well-known type.
*
* @generated from message buf.validate.DurationRules
*/
@@ -3918,7 +3964,7 @@ export type DurationRules = Message<"buf.validate.DurationRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3943,7 +3989,7 @@ export const DurationRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 24);
/**
- * TimestampRules describe the constraints applied exclusively to the `google.protobuf.Timestamp` well-known type.
+ * TimestampRules describe the rules applied exclusively to the `google.protobuf.Timestamp` well-known type.
*
* @generated from message buf.validate.TimestampRules
*/
@@ -4111,7 +4157,7 @@ export const TimestampRulesSchema: GenMessage = /*@__PURE__*/
/**
* `Violations` is a collection of `Violation` messages. This message type is returned by
- * protovalidate when a proto message fails to meet the requirements set by the `Constraint` validation rules.
+ * protovalidate when a proto message fails to meet the requirements set by the `Rule` validation rules.
* Each individual violation is represented by a `Violation` message.
*
* @generated from message buf.validate.Violations
@@ -4134,14 +4180,14 @@ export const ViolationsSchema: GenMessage = /*@__PURE__*/
/**
* `Violation` represents a single instance where a validation rule, expressed
- * as a `Constraint`, was not met. It provides information about the field that
- * caused the violation, the specific constraint that wasn't fulfilled, and a
+ * as a `Rule`, was not met. It provides information about the field that
+ * caused the violation, the specific rule that wasn't fulfilled, and a
* human-readable error message.
*
* ```json
* {
* "fieldPath": "bar",
- * "constraintId": "foo.bar",
+ * "ruleId": "foo.bar",
* "message": "bar must be greater than 0"
* }
* ```
@@ -4175,9 +4221,9 @@ export type Violation = Message<"buf.validate.Violation"> & {
field?: FieldPath;
/**
- * `rule` is a machine-readable path that points to the specific constraint rule that failed validation.
- * This will be a nested field starting from the FieldConstraints of the field that failed validation.
- * For custom constraints, this will provide the path of the constraint, e.g. `cel[0]`.
+ * `rule` is a machine-readable path that points to the specific rule rule that failed validation.
+ * This will be a nested field starting from the FieldRules of the field that failed validation.
+ * For custom rules, this will provide the path of the rule, e.g. `cel[0]`.
*
* For example, consider the following message:
*
@@ -4185,7 +4231,7 @@ export type Violation = Message<"buf.validate.Violation"> & {
* message Message {
* bool a = 1 [(buf.validate.field).required = true];
* bool b = 2 [(buf.validate.field).cel = {
- * id: "custom_constraint",
+ * id: "custom_rule",
* expression: "!this ? 'b must be true': ''"
* }]
* }
@@ -4209,16 +4255,16 @@ export type Violation = Message<"buf.validate.Violation"> & {
rule?: FieldPath;
/**
- * `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled.
- * This is the same `id` that was specified in the `Constraint` message, allowing easy tracing of which rule was violated.
+ * `rule_id` is the unique identifier of the `Rule` that was not fulfilled.
+ * This is the same `id` that was specified in the `Rule` message, allowing easy tracing of which rule was violated.
*
- * @generated from field: optional string constraint_id = 2;
+ * @generated from field: optional string rule_id = 2;
*/
- constraintId: string;
+ ruleId: string;
/**
* `message` is a human-readable error message that describes the nature of the violation.
- * This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation.
+ * This can be the default error message from the violated `Rule`, or it can be a custom message that gives more context about the violation.
*
* @generated from field: optional string message = 3;
*/
@@ -4377,8 +4423,8 @@ export const FieldPathElementSchema: GenMessage = /*@__PURE__*
messageDesc(file_buf_validate_validate, 29);
/**
- * Specifies how FieldConstraints.ignore behaves. See the documentation for
- * FieldConstraints.required for definitions of "populated" and "nullable".
+ * Specifies how FieldRules.ignore behaves. See the documentation for
+ * FieldRules.required for definitions of "populated" and "nullable".
*
* @generated from enum buf.validate.Ignore
*/
@@ -4526,7 +4572,7 @@ export enum Ignore {
* The validation rules of this field will be skipped and not evaluated. This
* is useful for situations that necessitate turning off the rules of a field
* containing a message that may not make sense in the current context, or to
- * temporarily disable constraints during development.
+ * temporarily disable rules during development.
*
* ```proto
* message MyMessage {
@@ -4584,31 +4630,31 @@ export const KnownRegexSchema: GenEnum = /*@__PURE__*/
* Rules specify the validations to be performed on this message. By default,
* no validation is performed against a message.
*
- * @generated from extension: optional buf.validate.MessageConstraints message = 1159;
+ * @generated from extension: optional buf.validate.MessageRules message = 1159;
*/
-export const message: GenExtension = /*@__PURE__*/
+export const message: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 0);
/**
* Rules specify the validations to be performed on this oneof. By default,
* no validation is performed against a oneof.
*
- * @generated from extension: optional buf.validate.OneofConstraints oneof = 1159;
+ * @generated from extension: optional buf.validate.OneofRules oneof = 1159;
*/
-export const oneof: GenExtension = /*@__PURE__*/
+export const oneof: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 1);
/**
* Rules specify the validations to be performed on this field. By default,
* no validation is performed against a field.
*
- * @generated from extension: optional buf.validate.FieldConstraints field = 1159;
+ * @generated from extension: optional buf.validate.FieldRules field = 1159;
*/
-export const field: GenExtension = /*@__PURE__*/
+export const field: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 2);
/**
- * Specifies predefined rules. When extending a standard constraint message,
+ * Specifies predefined rules. When extending a standard rule message,
* this adds additional CEL expressions that apply when the extension is used.
*
* ```proto
@@ -4625,8 +4671,8 @@ export const field: GenExtension = /*@__PURE__*/
* }
* ```
*
- * @generated from extension: optional buf.validate.PredefinedConstraints predefined = 1160;
+ * @generated from extension: optional buf.validate.PredefinedRules predefined = 1160;
*/
-export const predefined: GenExtension = /*@__PURE__*/
+export const predefined: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 3);
diff --git a/packages/protovalidate/README.md b/packages/protovalidate/README.md
index 5b2db813..43ed30cc 100644
--- a/packages/protovalidate/README.md
+++ b/packages/protovalidate/README.md
@@ -1,6 +1,6 @@
# @bufbuild/protovalidate
-[Protovalidate][protovalidate] provides standard annotations to validate common constraints on messages and fields, as well as the ability to use [CEL][cel] to write custom constraints. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf.
+[Protovalidate][protovalidate] provides standard annotations to validate common rules on messages and fields, as well as the ability to use [CEL][cel] to write custom rules. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf.
With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules:
diff --git a/packages/protovalidate/package.json b/packages/protovalidate/package.json
index b18a7284..b6a9a5b1 100644
--- a/packages/protovalidate/package.json
+++ b/packages/protovalidate/package.json
@@ -9,7 +9,7 @@
"directory": "packages/protovalidate"
},
"scripts": {
- "fetch-proto": "buf export buf.build/bufbuild/protovalidate:v0.10.3 --output proto",
+ "fetch-proto": "buf export buf.build/bufbuild/protovalidate:v0.11.0 --output proto",
"postfetch-proto": "license-header proto",
"generate": "buf generate",
"postgenerate": "license-header src/gen",
diff --git a/packages/protovalidate/proto/buf/validate/validate.proto b/packages/protovalidate/proto/buf/validate/validate.proto
index dc78d234..f8db378c 100644
--- a/packages/protovalidate/proto/buf/validate/validate.proto
+++ b/packages/protovalidate/proto/buf/validate/validate.proto
@@ -32,7 +32,7 @@ option java_package = "build.buf.validate";
extend google.protobuf.MessageOptions {
// Rules specify the validations to be performed on this message. By default,
// no validation is performed against a message.
- optional MessageConstraints message = 1159;
+ optional MessageRules message = 1159;
}
// OneofOptions is an extension to google.protobuf.OneofOptions. It allows
@@ -42,7 +42,7 @@ extend google.protobuf.MessageOptions {
extend google.protobuf.OneofOptions {
// Rules specify the validations to be performed on this oneof. By default,
// no validation is performed against a oneof.
- optional OneofConstraints oneof = 1159;
+ optional OneofRules oneof = 1159;
}
// FieldOptions is an extension to google.protobuf.FieldOptions. It allows
@@ -52,9 +52,9 @@ extend google.protobuf.OneofOptions {
extend google.protobuf.FieldOptions {
// Rules specify the validations to be performed on this field. By default,
// no validation is performed against a field.
- optional FieldConstraints field = 1159;
+ optional FieldRules field = 1159;
- // Specifies predefined rules. When extending a standard constraint message,
+ // Specifies predefined rules. When extending a standard rule message,
// this adds additional CEL expressions that apply when the extension is used.
//
// ```proto
@@ -70,11 +70,11 @@ extend google.protobuf.FieldOptions {
// int32 reserved = 1 [(buf.validate.field).int32.(is_zero) = true];
// }
// ```
- optional PredefinedConstraints predefined = 1160;
+ optional PredefinedRules predefined = 1160;
}
-// `Constraint` represents a validation rule written in the Common Expression
-// Language (CEL) syntax. Each Constraint includes a unique identifier, an
+// `Rule` represents a validation rule written in the Common Expression
+// Language (CEL) syntax. Each Rule includes a unique identifier, an
// optional error message, and the CEL expression to evaluate. For more
// information on CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
//
@@ -88,13 +88,13 @@ extend google.protobuf.FieldOptions {
// int32 bar = 1;
// }
// ```
-message Constraint {
- // `id` is a string that serves as a machine-readable name for this Constraint.
+message Rule {
+ // `id` is a string that serves as a machine-readable name for this Rule.
// It should be unique within its scope, which could be either a message or a field.
optional string id = 1;
// `message` is an optional field that provides a human-readable error message
- // for this Constraint when the CEL expression evaluates to false. If a
+ // for this Rule when the CEL expression evaluates to false. If a
// non-empty message is provided, any strings resulting from the CEL
// expression evaluation are ignored.
optional string message = 2;
@@ -106,9 +106,9 @@ message Constraint {
optional string expression = 3;
}
-// MessageConstraints represents validation rules that are applied to the entire message.
-// It includes disabling options and a list of Constraint messages representing Common Expression Language (CEL) validation rules.
-message MessageConstraints {
+// MessageRules represents validation rules that are applied to the entire message.
+// It includes disabling options and a list of Rule messages representing Common Expression Language (CEL) validation rules.
+message MessageRules {
// `disabled` is a boolean flag that, when set to true, nullifies any validation rules for this message.
// This includes any fields within the message that would otherwise support validation.
//
@@ -120,8 +120,8 @@ message MessageConstraints {
// ```
optional bool disabled = 1;
- // `cel` is a repeated field of type Constraint. Each Constraint specifies a validation rule to be applied to this message.
- // These constraints are written in Common Expression Language (CEL) syntax. For more information on
+ // `cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message.
+ // These rules are written in Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
//
//
@@ -136,15 +136,15 @@ message MessageConstraints {
// optional int32 foo = 1;
// }
// ```
- repeated Constraint cel = 3;
+ repeated Rule cel = 3;
}
-// The `OneofConstraints` message type enables you to manage constraints for
+// The `OneofRules` message type enables you to manage rules for
// oneof fields in your protobuf messages.
-message OneofConstraints {
+message OneofRules {
// If `required` is true, exactly one field of the oneof must be present. A
// validation error is returned if no fields in the oneof are present. The
- // field itself may still be a default value; further constraints
+ // field itself may still be a default value; further rules
// should be placed on the fields themselves to ensure they are valid values,
// such as `min_len` or `gt`.
//
@@ -162,9 +162,9 @@ message OneofConstraints {
optional bool required = 1;
}
-// FieldConstraints encapsulates the rules for each type of field. Depending on
+// FieldRules encapsulates the rules for each type of field. Depending on
// the field, the correct set should be used to ensure proper validations.
-message FieldConstraints {
+message FieldRules {
// `cel` is a repeated field used to represent a textual expression
// in the Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
@@ -179,7 +179,7 @@ message FieldConstraints {
// }];
// }
// ```
- repeated Constraint cel = 23;
+ repeated Rule cel = 23;
// If `required` is true, the field must be populated. A populated field can be
// described as "serialized in the wire format," which includes:
//
@@ -246,9 +246,9 @@ message FieldConstraints {
reserved "skipped", "ignore_empty";
}
-// PredefinedConstraints are custom constraints that can be re-used with
+// PredefinedRules are custom rules that can be re-used with
// multiple fields.
-message PredefinedConstraints {
+message PredefinedRules {
// `cel` is a repeated field used to represent a textual expression
// in the Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
@@ -263,7 +263,7 @@ message PredefinedConstraints {
// }];
// }
// ```
- repeated Constraint cel = 1;
+ repeated Rule cel = 1;
reserved 24, 26;
reserved
@@ -272,8 +272,8 @@ message PredefinedConstraints {
;
}
-// Specifies how FieldConstraints.ignore behaves. See the documentation for
-// FieldConstraints.required for definitions of "populated" and "nullable".
+// Specifies how FieldRules.ignore behaves. See the documentation for
+// FieldRules.required for definitions of "populated" and "nullable".
enum Ignore {
// Validation is only skipped if it's an unpopulated nullable fields.
//
@@ -405,7 +405,7 @@ enum Ignore {
// The validation rules of this field will be skipped and not evaluated. This
// is useful for situations that necessitate turning off the rules of a field
// containing a message that may not make sense in the current context, or to
- // temporarily disable constraints during development.
+ // temporarily disable rules during development.
//
// ```proto
// message MyMessage {
@@ -423,7 +423,7 @@ enum Ignore {
;
}
-// FloatRules describes the constraints applied to `float` values. These
+// FloatRules describes the rules applied to `float` values. These
// rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type.
message FloatRules {
// `const` requires the field value to exactly match the specified value. If
@@ -437,7 +437,7 @@ message FloatRules {
// ```
optional float const = 1 [(predefined).cel = {
id: "float.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
@@ -592,7 +592,7 @@ message FloatRules {
// ```
repeated float in = 6 [(predefined).cel = {
id: "float.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `in` requires the field value to not be equal to any of the specified
@@ -618,7 +618,7 @@ message FloatRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -635,8 +635,8 @@ message FloatRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -647,7 +647,7 @@ message FloatRules {
extensions 1000 to max;
}
-// DoubleRules describes the constraints applied to `double` values. These
+// DoubleRules describes the rules applied to `double` values. These
// rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type.
message DoubleRules {
// `const` requires the field value to exactly match the specified value. If
@@ -661,7 +661,7 @@ message DoubleRules {
// ```
optional double const = 1 [(predefined).cel = {
id: "double.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -813,7 +813,7 @@ message DoubleRules {
// ```
repeated double in = 6 [(predefined).cel = {
id: "double.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -839,7 +839,7 @@ message DoubleRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -856,8 +856,8 @@ message DoubleRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -868,7 +868,7 @@ message DoubleRules {
extensions 1000 to max;
}
-// Int32Rules describes the constraints applied to `int32` values. These
+// Int32Rules describes the rules applied to `int32` values. These
// rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type.
message Int32Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -882,7 +882,7 @@ message Int32Rules {
// ```
optional int32 const = 1 [(predefined).cel = {
id: "int32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -1035,7 +1035,7 @@ message Int32Rules {
// ```
repeated int32 in = 6 [(predefined).cel = {
id: "int32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1054,7 +1054,7 @@ message Int32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1071,8 +1071,8 @@ message Int32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1083,7 +1083,7 @@ message Int32Rules {
extensions 1000 to max;
}
-// Int64Rules describes the constraints applied to `int64` values. These
+// Int64Rules describes the rules applied to `int64` values. These
// rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type.
message Int64Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1097,7 +1097,7 @@ message Int64Rules {
// ```
optional int64 const = 1 [(predefined).cel = {
id: "int64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1250,7 +1250,7 @@ message Int64Rules {
// ```
repeated int64 in = 6 [(predefined).cel = {
id: "int64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1269,7 +1269,7 @@ message Int64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1286,8 +1286,8 @@ message Int64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1298,7 +1298,7 @@ message Int64Rules {
extensions 1000 to max;
}
-// UInt32Rules describes the constraints applied to `uint32` values. These
+// UInt32Rules describes the rules applied to `uint32` values. These
// rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type.
message UInt32Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1312,7 +1312,7 @@ message UInt32Rules {
// ```
optional uint32 const = 1 [(predefined).cel = {
id: "uint32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1465,7 +1465,7 @@ message UInt32Rules {
// ```
repeated uint32 in = 6 [(predefined).cel = {
id: "uint32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1484,7 +1484,7 @@ message UInt32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1501,8 +1501,8 @@ message UInt32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1513,7 +1513,7 @@ message UInt32Rules {
extensions 1000 to max;
}
-// UInt64Rules describes the constraints applied to `uint64` values. These
+// UInt64Rules describes the rules applied to `uint64` values. These
// rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type.
message UInt64Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1527,7 +1527,7 @@ message UInt64Rules {
// ```
optional uint64 const = 1 [(predefined).cel = {
id: "uint64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1679,7 +1679,7 @@ message UInt64Rules {
// ```
repeated uint64 in = 6 [(predefined).cel = {
id: "uint64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1698,7 +1698,7 @@ message UInt64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1715,8 +1715,8 @@ message UInt64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1727,7 +1727,7 @@ message UInt64Rules {
extensions 1000 to max;
}
-// SInt32Rules describes the constraints applied to `sint32` values.
+// SInt32Rules describes the rules applied to `sint32` values.
message SInt32Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -1740,7 +1740,7 @@ message SInt32Rules {
// ```
optional sint32 const = 1 [(predefined).cel = {
id: "sint32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -1893,7 +1893,7 @@ message SInt32Rules {
// ```
repeated sint32 in = 6 [(predefined).cel = {
id: "sint32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1912,7 +1912,7 @@ message SInt32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1929,8 +1929,8 @@ message SInt32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1941,7 +1941,7 @@ message SInt32Rules {
extensions 1000 to max;
}
-// SInt64Rules describes the constraints applied to `sint64` values.
+// SInt64Rules describes the rules applied to `sint64` values.
message SInt64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -1954,7 +1954,7 @@ message SInt64Rules {
// ```
optional sint64 const = 1 [(predefined).cel = {
id: "sint64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -2107,7 +2107,7 @@ message SInt64Rules {
// ```
repeated sint64 in = 6 [(predefined).cel = {
id: "sint64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2126,7 +2126,7 @@ message SInt64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2143,8 +2143,8 @@ message SInt64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2155,7 +2155,7 @@ message SInt64Rules {
extensions 1000 to max;
}
-// Fixed32Rules describes the constraints applied to `fixed32` values.
+// Fixed32Rules describes the rules applied to `fixed32` values.
message Fixed32Rules {
// `const` requires the field value to exactly match the specified value.
// If the field value doesn't match, an error message is generated.
@@ -2168,7 +2168,7 @@ message Fixed32Rules {
// ```
optional fixed32 const = 1 [(predefined).cel = {
id: "fixed32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2321,7 +2321,7 @@ message Fixed32Rules {
// ```
repeated fixed32 in = 6 [(predefined).cel = {
id: "fixed32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2340,7 +2340,7 @@ message Fixed32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2357,8 +2357,8 @@ message Fixed32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2369,7 +2369,7 @@ message Fixed32Rules {
extensions 1000 to max;
}
-// Fixed64Rules describes the constraints applied to `fixed64` values.
+// Fixed64Rules describes the rules applied to `fixed64` values.
message Fixed64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2382,7 +2382,7 @@ message Fixed64Rules {
// ```
optional fixed64 const = 1 [(predefined).cel = {
id: "fixed64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2535,7 +2535,7 @@ message Fixed64Rules {
// ```
repeated fixed64 in = 6 [(predefined).cel = {
id: "fixed64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2554,7 +2554,7 @@ message Fixed64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2571,8 +2571,8 @@ message Fixed64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2583,7 +2583,7 @@ message Fixed64Rules {
extensions 1000 to max;
}
-// SFixed32Rules describes the constraints applied to `fixed32` values.
+// SFixed32Rules describes the rules applied to `fixed32` values.
message SFixed32Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2596,7 +2596,7 @@ message SFixed32Rules {
// ```
optional sfixed32 const = 1 [(predefined).cel = {
id: "sfixed32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2749,7 +2749,7 @@ message SFixed32Rules {
// ```
repeated sfixed32 in = 6 [(predefined).cel = {
id: "sfixed32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2768,7 +2768,7 @@ message SFixed32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2785,8 +2785,8 @@ message SFixed32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2797,7 +2797,7 @@ message SFixed32Rules {
extensions 1000 to max;
}
-// SFixed64Rules describes the constraints applied to `fixed64` values.
+// SFixed64Rules describes the rules applied to `fixed64` values.
message SFixed64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2810,7 +2810,7 @@ message SFixed64Rules {
// ```
optional sfixed64 const = 1 [(predefined).cel = {
id: "sfixed64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2963,7 +2963,7 @@ message SFixed64Rules {
// ```
repeated sfixed64 in = 6 [(predefined).cel = {
id: "sfixed64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2982,7 +2982,7 @@ message SFixed64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2999,8 +2999,8 @@ message SFixed64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3011,7 +3011,7 @@ message SFixed64Rules {
extensions 1000 to max;
}
-// BoolRules describes the constraints applied to `bool` values. These rules
+// BoolRules describes the rules applied to `bool` values. These rules
// may also be applied to the `google.protobuf.BoolValue` Well-Known-Type.
message BoolRules {
// `const` requires the field value to exactly match the specified boolean value.
@@ -3025,11 +3025,11 @@ message BoolRules {
// ```
optional bool const = 1 [(predefined).cel = {
id: "bool.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -3046,8 +3046,8 @@ message BoolRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3058,7 +3058,7 @@ message BoolRules {
extensions 1000 to max;
}
-// StringRules describes the constraints applied to `string` values These
+// StringRules describes the rules applied to `string` values These
// rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type.
message StringRules {
// `const` requires the field value to exactly match the specified value. If
@@ -3072,7 +3072,7 @@ message StringRules {
// ```
optional string const = 1 [(predefined).cel = {
id: "string.const"
- expression: "this != rules.const ? 'value must equal `%s`'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal `%s`'.format([getField(rules, 'const')]) : ''"
}];
// `len` dictates that the field value must have the specified
@@ -3258,7 +3258,7 @@ message StringRules {
// ```
repeated string in = 10 [(predefined).cel = {
id: "string.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` specifies that the field value cannot be equal to any
@@ -3275,11 +3275,17 @@ message StringRules {
expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''"
}];
- // `WellKnown` rules provide advanced constraints against common string
- // patterns
+ // `WellKnown` rules provide advanced rules against common string
+ // patterns.
oneof well_known {
- // `email` specifies that the field value must be a valid email address
- // (addr-spec only) as defined by [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1).
+ // `email` specifies that the field value must be a valid email address, for
+ // example "foo@example.com".
+ //
+ // Conforms to the definition for a valid email address from the [HTML standard](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
+ // Note that this standard willfully deviates from [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322),
+ // which allows many unexpected forms of email addresses and will easily match
+ // a typographical error.
+ //
// If the field value isn't a valid email address, an error message will be generated.
//
// ```proto
@@ -3301,10 +3307,18 @@ message StringRules {
}
];
- // `hostname` specifies that the field value must be a valid
- // hostname as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5). This constraint doesn't support
- // internationalized domain names (IDNs). If the field value isn't a
- // valid hostname, an error message will be generated.
+ // `hostname` specifies that the field value must be a valid hostname, for
+ // example "foo.example.com".
+ //
+ // A valid hostname follows the rules below:
+ // - The name consists of one or more labels, separated by a dot (".").
+ // - Each label can be 1 to 63 alphanumeric characters.
+ // - A label can contain hyphens ("-"), but must not start or end with a hyphen.
+ // - The right-most label must not be digits only.
+ // - The name can have a trailing dot—for example, "foo.example.com.".
+ // - The name can be 253 characters at most, excluding the optional trailing dot.
+ //
+ // If the field value isn't a valid hostname, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3325,8 +3339,15 @@ message StringRules {
}
];
- // `ip` specifies that the field value must be a valid IP
- // (v4 or v6) address, without surrounding square brackets for IPv6 addresses.
+ // `ip` specifies that the field value must be a valid IP (v4 or v6) address.
+ //
+ // IPv4 addresses are expected in the dotted decimal format—for example, "192.168.5.21".
+ // IPv6 addresses are expected in their text representation—for example, "::1",
+ // or "2001:0DB8:ABCD:0012::0".
+ //
+ // Both formats are well-defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ // Zone identifiers for IPv6 addresses (for example, "fe80::a%en1") are supported.
+ //
// If the field value isn't a valid IP address, an error message will be
// generated.
//
@@ -3349,9 +3370,9 @@ message StringRules {
}
];
- // `ipv4` specifies that the field value must be a valid IPv4
- // address. If the field value isn't a valid IPv4 address, an error message
- // will be generated.
+ // `ipv4` specifies that the field value must be a valid IPv4 address—for
+ // example "192.168.5.21". If the field value isn't a valid IPv4 address, an
+ // error message will be generated.
//
// ```proto
// message MyString {
@@ -3372,9 +3393,9 @@ message StringRules {
}
];
- // `ipv6` specifies that the field value must be a valid
- // IPv6 address, without surrounding square brackets. If the field value is
- // not a valid IPv6 address, an error message will be generated.
+ // `ipv6` specifies that the field value must be a valid IPv6 address—for
+ // example "::1", or "d7a:115c:a1e0:ab12:4843:cd96:626b:430b". If the field
+ // value is not a valid IPv6 address, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3395,8 +3416,11 @@ message StringRules {
}
];
- // `uri` specifies that the field value must be a valid URI as defined by
- // [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
+ // `uri` specifies that the field value must be a valid URI, for example
+ // "https://example.com/foo/bar?baz=quux#frag".
+ //
+ // URI is defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ // Zone Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
//
// If the field value isn't a valid URI, an error message will be generated.
//
@@ -3419,11 +3443,13 @@ message StringRules {
}
];
- // `uri_ref` specifies that the field value must be a valid URI Reference as
- // defined by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-4.1).
+ // `uri_ref` specifies that the field value must be a valid URI Reference—either
+ // a URI such as "https://example.com/foo/bar?baz=quux#frag", or a Relative
+ // Reference such as "./foo/bar?query".
//
- // A URI Reference is either a [URI](https://datatracker.ietf.org/doc/html/rfc3986#section-3),
- // or a [Relative Reference](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2).
+ // URI, URI Reference, and Relative Reference are defined in the internet
+ // standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). Zone
+ // Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
//
// If the field value isn't a valid URI Reference, an error message will be
// generated.
@@ -3441,10 +3467,9 @@ message StringRules {
}];
// `address` specifies that the field value must be either a valid hostname
- // as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5)
- // (which doesn't support internationalized domain names or IDNs) or a valid
- // IP (v4 or v6). If the field value isn't a valid hostname or IP, an error
- // message will be generated.
+ // (for example, "example.com"), or a valid IP (v4 or v6) address (for example,
+ // "192.168.0.1", or "::1"). If the field value isn't a valid hostname or IP,
+ // an error message will be generated.
//
// ```proto
// message MyString {
@@ -3512,10 +3537,10 @@ message StringRules {
}
];
- // `ip_with_prefixlen` specifies that the field value must be a valid IP (v4 or v6)
- // address with prefix length. If the field value isn't a valid IP with prefix
- // length, an error message will be generated.
- //
+ // `ip_with_prefixlen` specifies that the field value must be a valid IP
+ // (v4 or v6) address with prefix length—for example, "192.168.5.21/16" or
+ // "2001:0DB8:ABCD:0012::F1/64". If the field value isn't a valid IP with
+ // prefix length, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3537,9 +3562,9 @@ message StringRules {
];
// `ipv4_with_prefixlen` specifies that the field value must be a valid
- // IPv4 address with prefix.
- // If the field value isn't a valid IPv4 address with prefix length,
- // an error message will be generated.
+ // IPv4 address with prefix length—for example, "192.168.5.21/16". If the
+ // field value isn't a valid IPv4 address with prefix length, an error
+ // message will be generated.
//
// ```proto
// message MyString {
@@ -3561,7 +3586,7 @@ message StringRules {
];
// `ipv6_with_prefixlen` specifies that the field value must be a valid
- // IPv6 address with prefix length.
+ // IPv6 address with prefix length—for example, "2001:0DB8:ABCD:0012::F1/64".
// If the field value is not a valid IPv6 address with prefix length,
// an error message will be generated.
//
@@ -3584,10 +3609,15 @@ message StringRules {
}
];
- // `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) prefix.
+ // `ip_prefix` specifies that the field value must be a valid IP (v4 or v6)
+ // prefix—for example, "192.168.0.0/16" or "2001:0DB8:ABCD:0012::0/64".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ // prefix, and the remaining 64 bits must be zero.
+ //
// If the field value isn't a valid IP prefix, an error message will be
- // generated. The prefix must have all zeros for the masked bits of the prefix (e.g.,
- // `127.0.0.0/16`, not `127.0.0.1/16`).
+ // generated.
//
// ```proto
// message MyString {
@@ -3609,9 +3639,14 @@ message StringRules {
];
// `ipv4_prefix` specifies that the field value must be a valid IPv4
- // prefix. If the field value isn't a valid IPv4 prefix, an error message
- // will be generated. The prefix must have all zeros for the masked bits of
- // the prefix (e.g., `127.0.0.0/16`, not `127.0.0.1/16`).
+ // prefix, for example "192.168.0.0/16".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "192.168.0.0/16" designates the left-most 16 bits for the prefix,
+ // and the remaining 16 bits must be zero.
+ //
+ // If the field value isn't a valid IPv4 prefix, an error message
+ // will be generated.
//
// ```proto
// message MyString {
@@ -3632,10 +3667,15 @@ message StringRules {
}
];
- // `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix.
+ // `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix—for
+ // example, "2001:0DB8:ABCD:0012::0/64".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ // prefix, and the remaining 64 bits must be zero.
+ //
// If the field value is not a valid IPv6 prefix, an error message will be
- // generated. The prefix must have all zeros for the masked bits of the prefix
- // (e.g., `2001:db8::/48`, not `2001:db8::1/48`).
+ // generated.
//
// ```proto
// message MyString {
@@ -3656,10 +3696,16 @@ message StringRules {
}
];
- // `host_and_port` specifies the field value must be a valid host and port
- // pair. The host must be a valid hostname or IP address while the port
- // must be in the range of 0-65535, inclusive. IPv6 addresses must be delimited
- // with square brackets (e.g., `[::1]:1234`).
+ // `host_and_port` specifies that the field value must be valid host/port
+ // pair—for example, "example.com:8080".
+ //
+ // The host can be one of:
+ //- An IPv4 address in dotted decimal format—for example, "192.168.5.21".
+ //- An IPv6 address enclosed in square brackets—for example, "[2001:0DB8:ABCD:0012::F1]".
+ //- A hostname—for example, "example.com".
+ //
+ // The port is separated by a colon. It must be non-empty, with a decimal number
+ // in the range of 0-65535, inclusive.
bool host_and_port = 32 [
(predefined).cel = {
id: "string.host_and_port"
@@ -3733,7 +3779,7 @@ message StringRules {
optional bool strict = 25;
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -3750,8 +3796,8 @@ message StringRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3773,7 +3819,7 @@ enum KnownRegex {
KNOWN_REGEX_HTTP_HEADER_VALUE = 2;
}
-// BytesRules describe the constraints applied to `bytes` values. These rules
+// BytesRules describe the rules applied to `bytes` values. These rules
// may also be applied to the `google.protobuf.BytesValue` Well-Known-Type.
message BytesRules {
// `const` requires the field value to exactly match the specified bytes
@@ -3787,7 +3833,7 @@ message BytesRules {
// ```
optional bytes const = 1 [(predefined).cel = {
id: "bytes.const"
- expression: "this != rules.const ? 'value must be %x'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must be %x'.format([getField(rules, 'const')]) : ''"
}];
// `len` requires the field value to have the specified length in bytes.
@@ -3908,7 +3954,7 @@ message BytesRules {
// ```
repeated bytes in = 8 [(predefined).cel = {
id: "bytes.in"
- expression: "dyn(rules)['in'].size() > 0 && !(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "getField(rules, 'in').size() > 0 && !(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to be not equal to any of the specified
@@ -3927,11 +3973,11 @@ message BytesRules {
expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''"
}];
- // WellKnown rules provide advanced constraints against common byte
+ // WellKnown rules provide advanced rules against common byte
// patterns
oneof well_known {
// `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
//
// ```proto
// message MyBytes {
@@ -3953,7 +3999,7 @@ message BytesRules {
];
// `ipv4` ensures that the field `value` is a valid IPv4 address in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
//
// ```proto
// message MyBytes {
@@ -3975,7 +4021,7 @@ message BytesRules {
];
// `ipv6` ensures that the field `value` is a valid IPv6 address in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
// ```proto
// message MyBytes {
// // value must be a valid IPv6 address
@@ -3997,7 +4043,7 @@ message BytesRules {
}
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4014,8 +4060,8 @@ message BytesRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4026,7 +4072,7 @@ message BytesRules {
extensions 1000 to max;
}
-// EnumRules describe the constraints applied to `enum` values.
+// EnumRules describe the rules applied to `enum` values.
message EnumRules {
// `const` requires the field value to exactly match the specified enum value.
// If the field value doesn't match, an error message is generated.
@@ -4045,7 +4091,7 @@ message EnumRules {
// ```
optional int32 const = 1 [(predefined).cel = {
id: "enum.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
// `defined_only` requires the field value to be one of the defined values for
@@ -4083,7 +4129,7 @@ message EnumRules {
// ```
repeated int32 in = 3 [(predefined).cel = {
id: "enum.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to be not equal to any of the
@@ -4108,7 +4154,7 @@ message EnumRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4129,8 +4175,8 @@ message EnumRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4141,7 +4187,7 @@ message EnumRules {
extensions 1000 to max;
}
-// RepeatedRules describe the constraints applied to `repeated` values.
+// RepeatedRules describe the rules applied to `repeated` values.
message RepeatedRules {
// `min_items` requires that this field must contain at least the specified
// minimum number of items.
@@ -4176,7 +4222,7 @@ message RepeatedRules {
}];
// `unique` indicates that all elements in this field must
- // be unique. This constraint is strictly applicable to scalar and enum
+ // be unique. This rule is strictly applicable to scalar and enum
// types, with message types not being supported.
//
// ```proto
@@ -4191,13 +4237,13 @@ message RepeatedRules {
expression: "!rules.unique || this.unique()"
}];
- // `items` details the constraints to be applied to each item
+ // `items` details the rules to be applied to each item
// in the field. Even for repeated message fields, validation is executed
// against each item unless skip is explicitly specified.
//
// ```proto
// message MyRepeated {
- // // The items in the field `value` must follow the specified constraints.
+ // // The items in the field `value` must follow the specified rules.
// repeated string value = 1 [(buf.validate.field).repeated.items = {
// string: {
// min_len: 3
@@ -4206,11 +4252,11 @@ message RepeatedRules {
// }];
// }
// ```
- optional FieldConstraints items = 4;
+ optional FieldRules items = 4;
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4221,7 +4267,7 @@ message RepeatedRules {
extensions 1000 to max;
}
-// MapRules describe the constraints applied to `map` values.
+// MapRules describe the rules applied to `map` values.
message MapRules {
//Specifies the minimum number of key-value pairs allowed. If the field has
// fewer key-value pairs than specified, an error message is generated.
@@ -4251,11 +4297,11 @@ message MapRules {
expression: "uint(this.size()) > rules.max_pairs ? 'map must be at most %d entries'.format([rules.max_pairs]) : ''"
}];
- //Specifies the constraints to be applied to each key in the field.
+ //Specifies the rules to be applied to each key in the field.
//
// ```proto
// message MyMap {
- // // The keys in the field `value` must follow the specified constraints.
+ // // The keys in the field `value` must follow the specified rules.
// map value = 1 [(buf.validate.field).map.keys = {
// string: {
// min_len: 3
@@ -4264,15 +4310,15 @@ message MapRules {
// }];
// }
// ```
- optional FieldConstraints keys = 4;
+ optional FieldRules keys = 4;
- //Specifies the constraints to be applied to the value of each key in the
+ //Specifies the rules to be applied to the value of each key in the
// field. Message values will still have their validations evaluated unless
//skip is specified here.
//
// ```proto
// message MyMap {
- // // The values in the field `value` must follow the specified constraints.
+ // // The values in the field `value` must follow the specified rules.
// map value = 1 [(buf.validate.field).map.values = {
// string: {
// min_len: 5
@@ -4281,11 +4327,11 @@ message MapRules {
// }];
// }
// ```
- optional FieldConstraints values = 5;
+ optional FieldRules values = 5;
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4296,7 +4342,7 @@ message MapRules {
extensions 1000 to max;
}
-// AnyRules describe constraints applied exclusively to the `google.protobuf.Any` well-known type.
+// AnyRules describe rules applied exclusively to the `google.protobuf.Any` well-known type.
message AnyRules {
// `in` requires the field's `type_url` to be equal to one of the
//specified values. If it doesn't match any of the specified values, an error
@@ -4321,7 +4367,7 @@ message AnyRules {
repeated string not_in = 3;
}
-// DurationRules describe the constraints applied exclusively to the `google.protobuf.Duration` well-known type.
+// DurationRules describe the rules applied exclusively to the `google.protobuf.Duration` well-known type.
message DurationRules {
// `const` dictates that the field must match the specified value of the `google.protobuf.Duration` type exactly.
// If the field's value deviates from the specified value, an error message
@@ -4335,7 +4381,7 @@ message DurationRules {
// ```
optional google.protobuf.Duration const = 2 [(predefined).cel = {
id: "duration.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` stipulates that the field must be less than the specified value of the `google.protobuf.Duration` type,
@@ -4488,7 +4534,7 @@ message DurationRules {
// ```
repeated google.protobuf.Duration in = 7 [(predefined).cel = {
id: "duration.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` denotes that the field must not be equal to
@@ -4508,7 +4554,7 @@ message DurationRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4525,8 +4571,8 @@ message DurationRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4537,7 +4583,7 @@ message DurationRules {
extensions 1000 to max;
}
-// TimestampRules describe the constraints applied exclusively to the `google.protobuf.Timestamp` well-known type.
+// TimestampRules describe the rules applied exclusively to the `google.protobuf.Timestamp` well-known type.
message TimestampRules {
// `const` dictates that this field, of the `google.protobuf.Timestamp` type, must exactly match the specified value. If the field value doesn't correspond to the specified timestamp, an error message will be generated.
//
@@ -4549,7 +4595,7 @@ message TimestampRules {
// ```
optional google.protobuf.Timestamp const = 2 [(predefined).cel = {
id: "timestamp.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// requires the duration field value to be less than the specified value (field < value). If the field value doesn't meet the required conditions, an error message is generated.
@@ -4726,7 +4772,7 @@ message TimestampRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4744,8 +4790,8 @@ message TimestampRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4757,7 +4803,7 @@ message TimestampRules {
}
// `Violations` is a collection of `Violation` messages. This message type is returned by
-// protovalidate when a proto message fails to meet the requirements set by the `Constraint` validation rules.
+// protovalidate when a proto message fails to meet the requirements set by the `Rule` validation rules.
// Each individual violation is represented by a `Violation` message.
message Violations {
// `violations` is a repeated field that contains all the `Violation` messages corresponding to the violations detected.
@@ -4765,14 +4811,14 @@ message Violations {
}
// `Violation` represents a single instance where a validation rule, expressed
-// as a `Constraint`, was not met. It provides information about the field that
-// caused the violation, the specific constraint that wasn't fulfilled, and a
+// as a `Rule`, was not met. It provides information about the field that
+// caused the violation, the specific rule that wasn't fulfilled, and a
// human-readable error message.
//
// ```json
// {
// "fieldPath": "bar",
-// "constraintId": "foo.bar",
+// "ruleId": "foo.bar",
// "message": "bar must be greater than 0"
// }
// ```
@@ -4798,9 +4844,9 @@ message Violation {
// ```
optional FieldPath field = 5;
- // `rule` is a machine-readable path that points to the specific constraint rule that failed validation.
- // This will be a nested field starting from the FieldConstraints of the field that failed validation.
- // For custom constraints, this will provide the path of the constraint, e.g. `cel[0]`.
+ // `rule` is a machine-readable path that points to the specific rule rule that failed validation.
+ // This will be a nested field starting from the FieldRules of the field that failed validation.
+ // For custom rules, this will provide the path of the rule, e.g. `cel[0]`.
//
// For example, consider the following message:
//
@@ -4808,7 +4854,7 @@ message Violation {
// message Message {
// bool a = 1 [(buf.validate.field).required = true];
// bool b = 2 [(buf.validate.field).cel = {
- // id: "custom_constraint",
+ // id: "custom_rule",
// expression: "!this ? 'b must be true': ''"
// }]
// }
@@ -4828,12 +4874,12 @@ message Violation {
// ```
optional FieldPath rule = 6;
- // `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled.
- // This is the same `id` that was specified in the `Constraint` message, allowing easy tracing of which rule was violated.
- optional string constraint_id = 2;
+ // `rule_id` is the unique identifier of the `Rule` that was not fulfilled.
+ // This is the same `id` that was specified in the `Rule` message, allowing easy tracing of which rule was violated.
+ optional string rule_id = 2;
// `message` is a human-readable error message that describes the nature of the violation.
- // This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation.
+ // This can be the default error message from the violated `Rule`, or it can be a custom message that gives more context about the violation.
optional string message = 3;
// `for_key` indicates whether the violation was caused by a map key, rather than a value.
diff --git a/packages/protovalidate/src/cel.ts b/packages/protovalidate/src/cel.ts
index 58b29c61..9ab81b2d 100644
--- a/packages/protovalidate/src/cel.ts
+++ b/packages/protovalidate/src/cel.ts
@@ -32,8 +32,8 @@ import {
FuncRegistry,
} from "@bufbuild/cel";
import {
- type Constraint,
- type FieldConstraints,
+ type Rule,
+ type FieldRules,
predefined,
} from "./gen/buf/validate/validate_pb.js";
import { CompilationError, RuntimeError } from "./error.js";
@@ -62,20 +62,20 @@ import {
type CelCompiledRules = {
standard: {
field: DescField;
- constraint: Constraint;
- compiled: CelCompiledConstraint;
+ rule: Rule;
+ compiled: CelCompiledRule;
}[];
extensions: Map<
number,
{
ext: DescExtension;
- constraint: Constraint;
- compiled: CelCompiledConstraint;
+ rule: Rule;
+ compiled: CelCompiledRule;
}[]
>;
};
-export type CelCompiledConstraint =
+export type CelCompiledRule =
| {
kind: "compilation_error";
error: CompilationError;
@@ -83,7 +83,7 @@ export type CelCompiledConstraint =
| {
kind: "interpretable";
interpretable: ReturnType;
- constraint: Constraint;
+ rule: Rule;
};
// TODO contains, endsWith, startsWith for bytes
@@ -281,48 +281,48 @@ export class CelManager {
this.env.set(key, value);
}
- eval(compiled: CelCompiledConstraint) {
+ eval(compiled: CelCompiledRule) {
if (compiled.kind == "compilation_error") {
throw compiled.error;
}
- const constraint = compiled.constraint;
+ const rule = compiled.rule;
const result = this.env.eval(compiled.interpretable);
if (typeof result == "string" || typeof result == "boolean") {
const success = typeof result == "boolean" ? result : result.length == 0;
if (success) {
return undefined;
}
- // From field buf.validate.Constraint.message:
+ // From field buf.validate.Rule.message:
// > If a non-empty message is provided, any strings resulting from the CEL
// > expression evaluation are ignored.
return {
message:
- constraint.message.length == 0 && typeof result == "string"
+ rule.message.length == 0 && typeof result == "string"
? result
- : constraint.message,
- constraintId: constraint.id,
+ : rule.message,
+ ruleId: rule.id,
};
}
if (result instanceof CelError) {
throw new RuntimeError(result.message, { cause: result });
}
throw new RuntimeError(
- `expression ${constraint.id} outputs ${typeof result}, wanted either bool or string`,
+ `expression ${rule.id} outputs ${typeof result}, wanted either bool or string`,
);
}
- compileConstraint(constraint: Constraint): CelCompiledConstraint {
+ compileRule(rule: Rule): CelCompiledRule {
try {
return {
kind: "interpretable",
- interpretable: this.env.plan(this.env.parse(constraint.expression)),
- constraint,
+ interpretable: this.env.plan(this.env.parse(rule.expression)),
+ rule,
};
} catch (cause) {
return {
kind: "compilation_error",
error: new CompilationError(
- `failed to compile ${constraint.id}: ${String(cause)}`,
+ `failed to compile ${rule.id}: ${String(cause)}`,
{ cause },
),
};
@@ -347,11 +347,11 @@ export class CelManager {
if (!hasOption(field, predefined)) {
continue;
}
- for (const constraint of getOption(field, predefined).cel) {
+ for (const rule of getOption(field, predefined).cel) {
standard.push({
field,
- constraint,
- compiled: this.compileConstraint(constraint),
+ rule,
+ compiled: this.compileRule(rule),
});
}
}
@@ -363,11 +363,11 @@ export class CelManager {
if (!list) {
extensions.set(ext.number, (list = []));
}
- for (const constraint of getOption(ext, predefined).cel) {
+ for (const rule of getOption(ext, predefined).cel) {
list.push({
ext,
- constraint,
- compiled: this.compileConstraint(constraint),
+ rule,
+ compiled: this.compileRule(rule),
});
}
}
@@ -393,7 +393,7 @@ function registryGetExtensionsFor(
export class EvalCustomCel implements Eval {
private readonly children: {
- compiled: CelCompiledConstraint;
+ compiled: CelCompiledRule;
rulePath: Path;
}[] = [];
@@ -402,7 +402,7 @@ export class EvalCustomCel implements Eval {
private readonly forMapKey: boolean,
) {}
- add(compiled: CelCompiledConstraint, rulePath: Path): void {
+ add(compiled: CelCompiledRule, rulePath: Path): void {
this.children.push({ compiled, rulePath });
}
@@ -413,12 +413,7 @@ export class EvalCustomCel implements Eval {
for (const child of this.children) {
const vio = this.celMan.eval(child.compiled);
if (vio) {
- cursor.violate(
- vio.message,
- vio.constraintId,
- child.rulePath,
- this.forMapKey,
- );
+ cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey);
}
}
}
@@ -430,25 +425,18 @@ export class EvalCustomCel implements Eval {
export class EvalExtendedRulesCel implements Eval {
private readonly children: {
- compiled: CelCompiledConstraint;
+ compiled: CelCompiledRule;
rulePath: Path;
ruleValue: unknown;
}[] = [];
constructor(
private readonly celMan: CelManager,
- private readonly rules: Exclude<
- FieldConstraints["type"]["value"],
- undefined
- >,
+ private readonly rules: Exclude,
private readonly forMapKey: boolean,
) {}
- add(
- compiled: CelCompiledConstraint,
- rulePath: Path,
- ruleValue: unknown,
- ): void {
+ add(compiled: CelCompiledRule, rulePath: Path, ruleValue: unknown): void {
this.children.push({
compiled,
rulePath,
@@ -463,12 +451,7 @@ export class EvalExtendedRulesCel implements Eval {
this.celMan.setEnv("rule", child.ruleValue);
const vio = this.celMan.eval(child.compiled);
if (vio) {
- cursor.violate(
- vio.message,
- vio.constraintId,
- child.rulePath,
- this.forMapKey,
- );
+ cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey);
}
}
}
@@ -480,20 +463,17 @@ export class EvalExtendedRulesCel implements Eval {
export class EvalStandardRulesCel implements Eval {
private readonly children: {
- compiled: CelCompiledConstraint;
+ compiled: CelCompiledRule;
rulePath: Path;
}[] = [];
constructor(
private readonly celMan: CelManager,
- private readonly rules: Exclude<
- FieldConstraints["type"]["value"],
- undefined
- >,
+ private readonly rules: Exclude,
private readonly forMapKey: boolean,
) {}
- add(compiled: CelCompiledConstraint, rulePath: Path): void {
+ add(compiled: CelCompiledRule, rulePath: Path): void {
this.children.push({ compiled, rulePath });
}
@@ -504,12 +484,7 @@ export class EvalStandardRulesCel implements Eval {
for (const child of this.children) {
const vio = this.celMan.eval(child.compiled);
if (vio) {
- cursor.violate(
- vio.message,
- vio.constraintId,
- child.rulePath,
- this.forMapKey,
- );
+ cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey);
}
}
}
diff --git a/packages/protovalidate/src/cursor.test.ts b/packages/protovalidate/src/cursor.test.ts
index 6d5c1bc2..6146d5dd 100644
--- a/packages/protovalidate/src/cursor.test.ts
+++ b/packages/protovalidate/src/cursor.test.ts
@@ -15,24 +15,24 @@
import * as assert from "node:assert";
import { suite, test } from "node:test";
import { Cursor } from "./cursor.js";
-import { ConstraintSchema } from "./gen/buf/validate/validate_pb.js";
+import { RuleSchema } from "./gen/buf/validate/validate_pb.js";
import { ValidationError } from "./error.js";
void suite("Cursor", () => {
void test("create()", () => {
- const cursor = Cursor.create(ConstraintSchema, false);
+ const cursor = Cursor.create(RuleSchema, false);
assert.equal(cursor.getPath().length, 0);
assert.equal(cursor.violated, false);
});
void suite("violate()", () => {
void test("sets violated = true", () => {
- const cursor = Cursor.create(ConstraintSchema, false);
+ const cursor = Cursor.create(RuleSchema, false);
assert.equal(cursor.violated, false);
- cursor.violate("msg", "constraint-id", []);
+ cursor.violate("msg", "rule-id", []);
assert.equal(cursor.violated, true);
});
void test("failFast=true throws on call", () => {
- const cursor = Cursor.create(ConstraintSchema, true);
+ const cursor = Cursor.create(RuleSchema, true);
assert.throws(() => cursor.violate("msg-1", "id-1", []), {
name: "ValidationError",
message: "msg-1 [id-1]",
@@ -41,7 +41,7 @@ void suite("Cursor", () => {
});
void suite("throwIfViolated()", () => {
void test("throws if violated", () => {
- const cursor = Cursor.create(ConstraintSchema, false);
+ const cursor = Cursor.create(RuleSchema, false);
cursor.violate("msg-1", "id-1", []);
assert.equal(cursor.violated, true);
assert.throws(() => cursor.throwIfViolated(), {
@@ -50,7 +50,7 @@ void suite("Cursor", () => {
});
});
void test("throws all violations", () => {
- const cursor = Cursor.create(ConstraintSchema, false);
+ const cursor = Cursor.create(RuleSchema, false);
cursor.violate("msg-1", "id-1", []);
cursor.violate("msg-2", "id-2", []);
assert.equal(cursor.violated, true);
@@ -65,15 +65,15 @@ void suite("Cursor", () => {
}
});
void test("does not throw if not violated", () => {
- const cursor = Cursor.create(ConstraintSchema, false);
+ const cursor = Cursor.create(RuleSchema, false);
assert.equal(cursor.violated, false);
cursor.throwIfViolated();
assert.ok(true);
});
});
void test("field() clones", () => {
- const root = Cursor.create(ConstraintSchema, false);
- const cursor = root.field(ConstraintSchema.field.message);
+ const root = Cursor.create(RuleSchema, false);
+ const cursor = root.field(RuleSchema.field.message);
assert.notStrictEqual(root, cursor);
assert.equal(root.getPath().length, 0);
assert.equal(cursor.getPath().length, 1);
diff --git a/packages/protovalidate/src/cursor.ts b/packages/protovalidate/src/cursor.ts
index 1e2ade5f..447e3014 100644
--- a/packages/protovalidate/src/cursor.ts
+++ b/packages/protovalidate/src/cursor.ts
@@ -42,14 +42,14 @@ export class Cursor {
violate(
message: string,
- constraintId: string,
+ ruleId: string,
rulePath: Path,
forMapKey = false,
): void {
this.violations.push(
new Violation(
message,
- constraintId,
+ ruleId,
this.builder.toPath(),
rulePath,
forMapKey,
diff --git a/packages/protovalidate/src/error.test.ts b/packages/protovalidate/src/error.test.ts
index 1f9e42da..89712b48 100644
--- a/packages/protovalidate/src/error.test.ts
+++ b/packages/protovalidate/src/error.test.ts
@@ -25,7 +25,7 @@ import {
} from "./error.js";
import { buildPath, parsePath, type Path } from "./path.js";
import {
- FieldConstraintsSchema,
+ FieldRulesSchema,
type FieldPath,
FieldPathElementSchema,
ViolationSchema,
@@ -38,44 +38,26 @@ import { FieldDescriptorProto_Type } from "@bufbuild/protobuf/wkt";
void suite("Violation", () => {
void test("constructor", () => {
- const field = parsePath(FieldConstraintsSchema, "cel[1].id");
- const rule = parsePath(FieldConstraintsSchema, "string.min_len");
- const v = new Violation(
- "failure-message",
- "constraint-id",
- field,
- rule,
- false,
- );
+ const field = parsePath(FieldRulesSchema, "cel[1].id");
+ const rule = parsePath(FieldRulesSchema, "string.min_len");
+ const v = new Violation("failure-message", "rule-id", field, rule, false);
assert.strictEqual(v.message, "failure-message");
- assert.strictEqual(v.constraintId, "constraint-id");
+ assert.strictEqual(v.ruleId, "rule-id");
assert.strictEqual(v.field, field);
assert.strictEqual(v.rule, rule);
assert.strictEqual(v.forKey, false);
});
void test("toString", () => {
- const field = parsePath(FieldConstraintsSchema, "cel[1].id");
- const rule = parsePath(FieldConstraintsSchema, "string.min_len");
- const v = new Violation(
- "failure-message",
- "constraint-id",
- field,
- rule,
- false,
- );
- assert.equal(v.toString(), "cel[1].id: failure-message [constraint-id]");
+ const field = parsePath(FieldRulesSchema, "cel[1].id");
+ const rule = parsePath(FieldRulesSchema, "string.min_len");
+ const v = new Violation("failure-message", "rule-id", field, rule, false);
+ assert.equal(v.toString(), "cel[1].id: failure-message [rule-id]");
});
void test("toString with empty field path", () => {
const field: Path = [];
- const rule = parsePath(FieldConstraintsSchema, "string.min_len");
- const v = new Violation(
- "failure-message",
- "constraint-id",
- field,
- rule,
- false,
- );
- assert.equal(v.toString(), "failure-message [constraint-id]");
+ const rule = parsePath(FieldRulesSchema, "string.min_len");
+ const v = new Violation("failure-message", "rule-id", field, rule, false);
+ assert.equal(v.toString(), "failure-message [rule-id]");
});
});
@@ -83,15 +65,15 @@ void suite("violationToProto", () => {
void test("converts as expected", () => {
const violation = new Violation(
"failure-message",
- "constraint-id",
- parsePath(FieldConstraintsSchema, "cel[1].id"),
+ "rule-id",
+ parsePath(FieldRulesSchema, "cel[1].id"),
[],
false,
);
const proto = violationToProto(violation);
assert.ok(isMessage(proto, ViolationSchema));
assert.equal(proto.message, violation.message);
- assert.equal(proto.constraintId, violation.constraintId);
+ assert.equal(proto.ruleId, violation.ruleId);
assert.equal(proto.forKey, violation.forKey);
assert.strictEqual(proto.field?.elements.length, 2);
assert.strictEqual(proto.rule, undefined);
@@ -108,7 +90,7 @@ void suite("violationToProto", () => {
`);
const violation = new Violation(
"failure-message",
- "constraint-id",
+ "rule-id",
buildPath(descMessage).field(descMessage.field.val).toPath(),
[],
false,
@@ -131,7 +113,7 @@ void suite("violationToProto", () => {
`);
const violation = new Violation(
"failure-message",
- "constraint-id",
+ "rule-id",
buildPath(descMessage).field(descMessage.field.m).toPath(),
[],
false,
@@ -160,7 +142,7 @@ void suite("violationToProto", () => {
`);
const violation = new Violation(
"failure-message",
- "constraint-id",
+ "rule-id",
buildPath(descMessage).field(descMessage.field.m).mapKey(123).toPath(),
[],
false,
@@ -213,28 +195,28 @@ void suite("ValidationError", () => {
const violations = [
new Violation(
"failure-message",
- "constraint-id",
- parsePath(FieldConstraintsSchema, "cel[1].id"),
+ "rule-id",
+ parsePath(FieldRulesSchema, "cel[1].id"),
[],
false,
),
];
const err = new ValidationError(violations);
- assert.equal(err.message, "cel[1].id: failure-message [constraint-id]");
+ assert.equal(err.message, "cel[1].id: failure-message [rule-id]");
});
void test("constructor with 2 violations", () => {
const violations = [
new Violation(
"failure-message-1",
- "constraint-id-1",
- parsePath(FieldConstraintsSchema, "cel[1].id"),
+ "rule-id-1",
+ parsePath(FieldRulesSchema, "cel[1].id"),
[],
false,
),
new Violation(
"failure-message-2",
- "constraint-id-2",
- parsePath(FieldConstraintsSchema, "cel[2].id"),
+ "rule-id-2",
+ parsePath(FieldRulesSchema, "cel[2].id"),
[],
false,
),
@@ -242,7 +224,7 @@ void suite("ValidationError", () => {
const err = new ValidationError(violations);
assert.equal(
err.message,
- "cel[1].id: failure-message-1 [constraint-id-1], and 1 more violation",
+ "cel[1].id: failure-message-1 [rule-id-1], and 1 more violation",
);
});
void test("constructor without violations", () => {
diff --git a/packages/protovalidate/src/error.ts b/packages/protovalidate/src/error.ts
index 542d915a..69ffbfab 100644
--- a/packages/protovalidate/src/error.ts
+++ b/packages/protovalidate/src/error.ts
@@ -32,7 +32,7 @@ import { FieldDescriptorProto_Type } from "@bufbuild/protobuf/wkt";
/**
* A CompilationError is raised if a CEL expression cannot be compiled, or if
- * invalid standard constraints are applied.
+ * invalid standard rules are applied.
*/
export class CompilationError extends Error {
override name = "CompilationError";
@@ -57,7 +57,7 @@ export class RuntimeError extends Error {
}
/**
- * A ValidationError is raised if one or more constraint violations were
+ * A ValidationError is raised if one or more rule violations were
* detected.
*/
export class ValidationError extends Error {
@@ -87,23 +87,23 @@ function validationErrorMessage(violations: Violation[]): string {
/**
* Violation represents a single instance where a validation rule was not met.
* It provides information about the field that caused the violation, the
- * specific unfulfilled constraint, and a human-readable error message.
+ * specific unfulfilled rule, and a human-readable error message.
*/
export class Violation {
/**
* A human-readable error message that describes the nature of the violation.
*
- * This can be the default error message from the violated `Constraint`, or it
+ * This can be the default error message from the violated `Rule`, or it
* can be a custom message that gives more context about the violation.
*/
public message: string;
/**
- * The unique identifier of the `Constraint` that was not fulfilled.
- * This is the same `id` that was specified in the `Constraint` message,
+ * The unique identifier of the `Rule` that was not fulfilled.
+ * This is the same `id` that was specified in the `Rule` message,
* allowing easy tracing of which rule was violated.
*/
- public constraintId: string;
+ public ruleId: string;
/**
* A machine-readable path to the field that failed validation.
@@ -114,12 +114,12 @@ export class Violation {
public field: Path;
/**
- * A machine-readable path that points to the specific constraint rule that
- * failed validation.
+ * A machine-readable path that points to the specific rule that failed
+ * validation.
*
- * This will be a nested field starting from the FieldConstraints of the field
- * that failed validation. For custom constraints, this will provide the path
- * of the constraint, e.g. `cel[0]`.
+ * This will be a nested field starting from the FieldRules of the field
+ * that failed validation. For custom rules, this will provide the path
+ * of the rule, e.g. `cel[0]`.
*/
public rule: Path;
@@ -130,13 +130,13 @@ export class Violation {
constructor(
message: string,
- constraintId: string,
+ ruleId: string,
field: Path,
rule: Path,
forKey: boolean,
) {
this.message = message;
- this.constraintId = constraintId;
+ this.ruleId = ruleId;
this.field = field;
this.rule = rule;
this.forKey = forKey;
@@ -147,7 +147,7 @@ export class Violation {
if (path.length > 0) {
path += ": ";
}
- return path + `${this.message} [${this.constraintId}]`;
+ return path + `${this.message} [${this.ruleId}]`;
}
}
@@ -168,7 +168,7 @@ export function violationToProto(violation: Violation) {
field:
violation.field.length > 0 ? pathToProto(violation.field) : undefined,
rule: violation.rule.length > 0 ? pathToProto(violation.rule) : undefined,
- constraintId: violation.constraintId,
+ ruleId: violation.ruleId,
message: violation.message.length > 0 ? violation.message : undefined,
forKey: violation.forKey,
});
diff --git a/packages/protovalidate/src/eval.test.ts b/packages/protovalidate/src/eval.test.ts
index 35888421..89caee8b 100644
--- a/packages/protovalidate/src/eval.test.ts
+++ b/packages/protovalidate/src/eval.test.ts
@@ -16,13 +16,17 @@ import * as assert from "node:assert/strict";
import { suite, test } from "node:test";
import {
AnyRulesSchema,
- ConstraintSchema,
+ RuleSchema,
EnumRulesSchema,
file_buf_validate_validate,
MapRulesSchema,
predefined,
RepeatedRulesSchema,
StringRulesSchema,
+ MessageRulesSchema,
+ OneofRulesSchema,
+ FieldRulesSchema,
+ PredefinedRulesSchema,
} from "./gen/buf/validate/validate_pb.js";
import { nestedTypes } from "@bufbuild/protobuf/reflect";
import { getOption, hasOption } from "@bufbuild/protobuf";
@@ -38,6 +42,34 @@ void suite("check buf.validate.*Rules fields", () => {
RepeatedRulesSchema.field.items,
EnumRulesSchema.field.definedOnly,
StringRulesSchema.field.strict,
+ MessageRulesSchema.field.cel,
+ MessageRulesSchema.field.disabled,
+ OneofRulesSchema.field.required,
+ FieldRulesSchema.field.cel,
+ FieldRulesSchema.field.required,
+ FieldRulesSchema.field.ignore,
+ FieldRulesSchema.field.float,
+ FieldRulesSchema.field.double,
+ FieldRulesSchema.field.int32,
+ FieldRulesSchema.field.int64,
+ FieldRulesSchema.field.uint32,
+ FieldRulesSchema.field.uint64,
+ FieldRulesSchema.field.sint32,
+ FieldRulesSchema.field.sint64,
+ FieldRulesSchema.field.fixed32,
+ FieldRulesSchema.field.fixed64,
+ FieldRulesSchema.field.sfixed32,
+ FieldRulesSchema.field.sfixed64,
+ FieldRulesSchema.field.bool,
+ FieldRulesSchema.field.string,
+ FieldRulesSchema.field.bytes,
+ FieldRulesSchema.field.enum,
+ FieldRulesSchema.field.repeated,
+ FieldRulesSchema.field.map,
+ FieldRulesSchema.field.any,
+ FieldRulesSchema.field.duration,
+ FieldRulesSchema.field.timestamp,
+ PredefinedRulesSchema.field.cel,
];
const rulesMessages = Array.from(nestedTypes(file_buf_validate_validate))
.filter((t) => t.kind == "message")
@@ -96,7 +128,7 @@ void suite("EvalMany", () => {
const a = new EvalTest(false);
const b = new EvalTest(false);
const m = new EvalMany(a, b);
- m.eval("", Cursor.create(ConstraintSchema, false));
+ m.eval("", Cursor.create(RuleSchema, false));
assert.equal(a.evaluated, true);
assert.equal(b.evaluated, true);
});
@@ -105,14 +137,14 @@ void suite("EvalMany", () => {
const a = new EvalTest(true);
const m = new EvalMany(a, EvalNoop.get());
assert.strictEqual(m.prune(), true);
- m.eval("", Cursor.create(ConstraintSchema, false));
+ m.eval("", Cursor.create(RuleSchema, false));
assert.equal(a.evaluated, false);
});
void test("keeps ops", () => {
const a = new EvalTest(false);
const m = new EvalMany(a);
assert.strictEqual(m.prune(), false);
- m.eval("", Cursor.create(ConstraintSchema, false));
+ m.eval("", Cursor.create(RuleSchema, false));
assert.equal(a.evaluated, true);
});
});
diff --git a/packages/protovalidate/src/eval.ts b/packages/protovalidate/src/eval.ts
index ce5902df..ef5ea057 100644
--- a/packages/protovalidate/src/eval.ts
+++ b/packages/protovalidate/src/eval.ts
@@ -30,14 +30,14 @@ import {
AnyRulesSchema,
type EnumRules,
EnumRulesSchema,
- FieldConstraintsSchema,
+ FieldRulesSchema,
} from "./gen/buf/validate/validate_pb.js";
import { Cursor } from "./cursor.js";
import type { Condition } from "./condition.js";
import type { PathBuilder } from "./path.js";
/**
- * Evaluate constraints for a value.
+ * Evaluate rules for a value.
*/
export type Eval = {
eval(val: V, cursor: Cursor): void;
@@ -170,7 +170,7 @@ export class EvalFieldRequired implements Eval {
cursor
.field(this.field)
.violate("value is required", "required", [
- FieldConstraintsSchema.field.required,
+ FieldRulesSchema.field.required,
]);
}
}
@@ -188,7 +188,6 @@ export class EvalOneofRequired implements Eval {
}
cursor
.oneof(this.oneof)
- // TODO protovalidate-go does not populate Violation.rule for OneofConstraints.required
.violate("exactly one field is required in oneof", "required", []);
}
prune(): boolean {
diff --git a/packages/protovalidate/src/gen/buf/validate/validate_pb.ts b/packages/protovalidate/src/gen/buf/validate/validate_pb.ts
index f8a08d3d..bc99c1c9 100644
--- a/packages/protovalidate/src/gen/buf/validate/validate_pb.ts
+++ b/packages/protovalidate/src/gen/buf/validate/validate_pb.ts
@@ -26,11 +26,11 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file buf/validate/validate.proto.
*/
export const file_buf_validate_validate: GenFile = /*@__PURE__*/
- fileDesc("ChtidWYvdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8SDGJ1Zi52YWxpZGF0ZSI9CgpDb25zdHJhaW50EgoKAmlkGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEgoKZXhwcmVzc2lvbhgDIAEoCSJNChJNZXNzYWdlQ29uc3RyYWludHMSEAoIZGlzYWJsZWQYASABKAgSJQoDY2VsGAMgAygLMhguYnVmLnZhbGlkYXRlLkNvbnN0cmFpbnQiJAoQT25lb2ZDb25zdHJhaW50cxIQCghyZXF1aXJlZBgBIAEoCCLLCAoQRmllbGRDb25zdHJhaW50cxIlCgNjZWwYFyADKAsyGC5idWYudmFsaWRhdGUuQ29uc3RyYWludBIQCghyZXF1aXJlZBgZIAEoCBIkCgZpZ25vcmUYGyABKA4yFC5idWYudmFsaWRhdGUuSWdub3JlEikKBWZsb2F0GAEgASgLMhguYnVmLnZhbGlkYXRlLkZsb2F0UnVsZXNIABIrCgZkb3VibGUYAiABKAsyGS5idWYudmFsaWRhdGUuRG91YmxlUnVsZXNIABIpCgVpbnQzMhgDIAEoCzIYLmJ1Zi52YWxpZGF0ZS5JbnQzMlJ1bGVzSAASKQoFaW50NjQYBCABKAsyGC5idWYudmFsaWRhdGUuSW50NjRSdWxlc0gAEisKBnVpbnQzMhgFIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50MzJSdWxlc0gAEisKBnVpbnQ2NBgGIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50NjRSdWxlc0gAEisKBnNpbnQzMhgHIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50MzJSdWxlc0gAEisKBnNpbnQ2NBgIIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50NjRSdWxlc0gAEi0KB2ZpeGVkMzIYCSABKAsyGi5idWYudmFsaWRhdGUuRml4ZWQzMlJ1bGVzSAASLQoHZml4ZWQ2NBgKIAEoCzIaLmJ1Zi52YWxpZGF0ZS5GaXhlZDY0UnVsZXNIABIvCghzZml4ZWQzMhgLIAEoCzIbLmJ1Zi52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSAASLwoIc2ZpeGVkNjQYDCABKAsyGy5idWYudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAEicKBGJvb2wYDSABKAsyFy5idWYudmFsaWRhdGUuQm9vbFJ1bGVzSAASKwoGc3RyaW5nGA4gASgLMhkuYnVmLnZhbGlkYXRlLlN0cmluZ1J1bGVzSAASKQoFYnl0ZXMYDyABKAsyGC5idWYudmFsaWRhdGUuQnl0ZXNSdWxlc0gAEicKBGVudW0YECABKAsyFy5idWYudmFsaWRhdGUuRW51bVJ1bGVzSAASLwoIcmVwZWF0ZWQYEiABKAsyGy5idWYudmFsaWRhdGUuUmVwZWF0ZWRSdWxlc0gAEiUKA21hcBgTIAEoCzIWLmJ1Zi52YWxpZGF0ZS5NYXBSdWxlc0gAEiUKA2FueRgUIAEoCzIWLmJ1Zi52YWxpZGF0ZS5BbnlSdWxlc0gAEi8KCGR1cmF0aW9uGBUgASgLMhsuYnVmLnZhbGlkYXRlLkR1cmF0aW9uUnVsZXNIABIxCgl0aW1lc3RhbXAYFiABKAsyHC5idWYudmFsaWRhdGUuVGltZXN0YW1wUnVsZXNIAEIGCgR0eXBlSgQIGBAZSgQIGhAbUgdza2lwcGVkUgxpZ25vcmVfZW1wdHkiXwoVUHJlZGVmaW5lZENvbnN0cmFpbnRzEiUKA2NlbBgBIAMoCzIYLmJ1Zi52YWxpZGF0ZS5Db25zdHJhaW50SgQIGBAZSgQIGhAbUhNza2lwcGVkaWdub3JlX2VtcHR5IrUXCgpGbG9hdFJ1bGVzEmkKBWNvbnN0GAEgASgCQlrCSFcKVQoLZmxvYXQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSnwEKAmx0GAIgASgCQpABwkiMAQqJAQoIZmxvYXQubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASrwEKA2x0ZRgDIAEoAkKfAcJImwEKmAEKCWZsb2F0Lmx0ZRqKASFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEu8HCgJndBgEIAEoAkLgB8JI3AcKjQEKCGZsb2F0Lmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKwwEKC2Zsb2F0Lmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzQEKFWZsb2F0Lmd0X2x0X2V4Y2x1c2l2ZRqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCtMBCgxmbG9hdC5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrdAQoWZmxvYXQuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESuggKA2d0ZRgFIAEoAkKqCMJIpggKmwEKCWZsb2F0Lmd0ZRqNASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrSAQoMZmxvYXQuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrcAQoWZmxvYXQuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4gEKDWZsb2F0Lmd0ZV9sdGUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCuwBChdmbG9hdC5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ1CgJpbhgGIAMoAkJpwkhmCmQKCGZsb2F0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnYKBm5vdF9pbhgHIAMoAkJmwkhjCmEKDGZsb2F0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEnUKBmZpbml0ZRgIIAEoCEJlwkhiCmAKDGZsb2F0LmZpbml0ZRpQcnVsZXMuZmluaXRlID8gKHRoaXMuaXNOYW4oKSB8fCB0aGlzLmlzSW5mKCkgPyAndmFsdWUgbXVzdCBiZSBmaW5pdGUnIDogJycpIDogJycSKwoHZXhhbXBsZRgJIAMoAkIawkgXChUKDWZsb2F0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIscXCgtEb3VibGVSdWxlcxJqCgVjb25zdBgBIAEoAUJbwkhYClYKDGRvdWJsZS5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKgAQoCbHQYAiABKAFCkQHCSI0BCooBCglkb3VibGUubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASsAEKA2x0ZRgDIAEoAUKgAcJInAEKmQEKCmRvdWJsZS5sdGUaigEhaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlKT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABL0BwoCZ3QYBCABKAFC5QfCSOEHCo4BCglkb3VibGUuZ3QagAEhaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwrEAQoMZG91YmxlLmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzgEKFmRvdWJsZS5ndF9sdF9leGNsdXNpdmUaswFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrUAQoNZG91YmxlLmd0X2x0ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCt4BChdkb3VibGUuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESvwgKA2d0ZRgFIAEoAUKvCMJIqwgKnAEKCmRvdWJsZS5ndGUajQEhaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycK0wEKDWRvdWJsZS5ndGVfbHQawQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCt0BChdkb3VibGUuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4wEKDmRvdWJsZS5ndGVfbHRlGtABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrtAQoYZG91YmxlLmd0ZV9sdGVfZXhjbHVzaXZlGtABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEnYKAmluGAYgAygBQmrCSGcKZQoJZG91YmxlLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEncKBm5vdF9pbhgHIAMoAUJnwkhkCmIKDWRvdWJsZS5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ2CgZmaW5pdGUYCCABKAhCZsJIYwphCg1kb3VibGUuZmluaXRlGlBydWxlcy5maW5pdGUgPyAodGhpcy5pc05hbigpIHx8IHRoaXMuaXNJbmYoKSA/ICd2YWx1ZSBtdXN0IGJlIGZpbml0ZScgOiAnJykgOiAnJxIsCgdleGFtcGxlGAkgAygBQhvCSBgKFgoOZG91YmxlLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIucUCgpJbnQzMlJ1bGVzEmkKBWNvbnN0GAEgASgFQlrCSFcKVQoLaW50MzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSigEKAmx0GAIgASgFQnzCSHkKdwoIaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoBUKMAcJIiAEKhQEKCWludDMyLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgFQogHwkiEBwp6CghpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50MzIuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKAVC0wfCSM8HCogBCglpbnQzMi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50MzIuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdQoCaW4YBiADKAVCacJIZgpkCghpbnQzMi5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ2CgZub3RfaW4YByADKAVCZsJIYwphCgxpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIrCgdleGFtcGxlGAggAygFQhrCSBcKFQoNaW50MzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i5xQKCkludDY0UnVsZXMSaQoFY29uc3QYASABKANCWsJIVwpVCgtpbnQ2NC5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKKAQoCbHQYAiABKANCfMJIeQp3CghpbnQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKcAQoDbHRlGAMgASgDQowBwkiIAQqFAQoJaW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKXBwoCZ3QYBCABKANCiAfCSIQHCnoKCGludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwqzAQoLaW50NjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCrsBChVpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrDAQoMaW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrLAQoWaW50NjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES4wcKA2d0ZRgFIAEoA0LTB8JIzwcKiAEKCWludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsIBCgxpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKygEKFmludDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtIBCg1pbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtoBChdpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ1CgJpbhgGIAMoA0JpwkhmCmQKCGludDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnYKBm5vdF9pbhgHIAMoA0JmwkhjCmEKDGludDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEisKB2V4YW1wbGUYCSADKANCGsJIFwoVCg1pbnQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FAoLVUludDMyUnVsZXMSagoFY29uc3QYASABKA1CW8JIWApWCgx1aW50MzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSiwEKAmx0GAIgASgNQn3CSHoKeAoJdWludDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKA1CjQHCSIkBCoYBCgp1aW50MzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKA1CjQfCSIkHCnsKCXVpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHVpbnQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnVpbnQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNdWludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3VpbnQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgNQtgHwkjUBwqJAQoKdWludDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg11aW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChd1aW50MzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnVpbnQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChh1aW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdgoCaW4YBiADKA1CasJIZwplCgl1aW50MzIuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSdwoGbm90X2luGAcgAygNQmfCSGQKYgoNdWludDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEiwKB2V4YW1wbGUYCCADKA1CG8JIGAoWCg51aW50MzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i+BQKC1VJbnQ2NFJ1bGVzEmoKBWNvbnN0GAEgASgEQlvCSFgKVgoMdWludDY0LmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEosBCgJsdBgCIAEoBEJ9wkh6CngKCXVpbnQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKdAQoDbHRlGAMgASgEQo0BwkiJAQqGAQoKdWludDY0Lmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASnAcKAmd0GAQgASgEQo0HwkiJBwp7Cgl1aW50NjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrQBCgx1aW50NjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCrwBChZ1aW50NjQuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxAEKDXVpbnQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCswBChd1aW50NjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES6AcKA2d0ZRgFIAEoBELYB8JI1AcKiQEKCnVpbnQ2NC5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrDAQoNdWludDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrLAQoXdWludDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtMBCg51aW50NjQuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrbAQoYdWludDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEnYKAmluGAYgAygEQmrCSGcKZQoJdWludDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEncKBm5vdF9pbhgHIAMoBEJnwkhkCmIKDXVpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygEQhvCSBgKFgoOdWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIvgUCgtTSW50MzJSdWxlcxJqCgVjb25zdBgBIAEoEUJbwkhYClYKDHNpbnQzMi5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKLAQoCbHQYAiABKBFCfcJIegp4CglzaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEUKNAcJIiQEKhgEKCnNpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEUKNB8JIiQcKewoJc2ludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBFC2AfCSNQHCokBCgpzaW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ2CgJpbhgGIAMoEUJqwkhnCmUKCXNpbnQzMi5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ3CgZub3RfaW4YByADKBFCZ8JIZApiCg1zaW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoEUIbwkgYChYKDnNpbnQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FAoLU0ludDY0UnVsZXMSagoFY29uc3QYASABKBJCW8JIWApWCgxzaW50NjQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSiwEKAmx0GAIgASgSQn3CSHoKeAoJc2ludDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKBJCjQHCSIkBCoYBCgpzaW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKBJCjQfCSIkHCnsKCXNpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHNpbnQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnNpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNc2ludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3NpbnQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgSQtgHwkjUBwqJAQoKc2ludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg1zaW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChdzaW50NjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnNpbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChhzaW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdgoCaW4YBiADKBJCasJIZwplCglzaW50NjQuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSdwoGbm90X2luGAcgAygSQmfCSGQKYgoNc2ludDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEiwKB2V4YW1wbGUYCCADKBJCG8JIGAoWCg5zaW50NjQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iiRUKDEZpeGVkMzJSdWxlcxJrCgVjb25zdBgBIAEoB0JcwkhZClcKDWZpeGVkMzIuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSjAEKAmx0GAIgASgHQn7CSHsKeQoKZml4ZWQzMi5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgHQo4BwkiKAQqHAQoLZml4ZWQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoB0KSB8JIjgcKfAoKZml4ZWQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkMzIuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkMzIuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoB0LdB8JI2QcKigEKC2ZpeGVkMzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkMzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDMyLmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkMzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdwoCaW4YBiADKAdCa8JIaApmCgpmaXhlZDMyLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEngKBm5vdF9pbhgHIAMoB0JowkhlCmMKDmZpeGVkMzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoB0IcwkgZChcKD2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iiRUKDEZpeGVkNjRSdWxlcxJrCgVjb25zdBgBIAEoBkJcwkhZClcKDWZpeGVkNjQuY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSjAEKAmx0GAIgASgGQn7CSHsKeQoKZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgGQo4BwkiKAQqHAQoLZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoBkKSB8JIjgcKfAoKZml4ZWQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoBkLdB8JI2QcKigEKC2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkNjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkNjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESdwoCaW4YBiADKAZCa8JIaApmCgpmaXhlZDY0LmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEngKBm5vdF9pbhgHIAMoBkJowkhlCmMKDmZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoBkIcwkgZChcKD2ZpeGVkNjQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4imhUKDVNGaXhlZDMyUnVsZXMSbAoFY29uc3QYASABKA9CXcJIWgpYCg5zZml4ZWQzMi5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKNAQoCbHQYAiABKA9Cf8JIfAp6CgtzZml4ZWQzMi5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKfAQoDbHRlGAMgASgPQo8BwkiLAQqIAQoMc2ZpeGVkMzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKmBwoCZ3QYBCABKA9ClwfCSJMHCn0KC3NmaXhlZDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq2AQoOc2ZpeGVkMzIuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr4BChhzZml4ZWQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrGAQoPc2ZpeGVkMzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrOAQoZc2ZpeGVkMzIuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES8gcKA2d0ZRgFIAEoD0LiB8JI3gcKiwEKDHNmaXhlZDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsUBCg9zZml4ZWQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzQEKGXNmaXhlZDMyLmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtUBChBzZml4ZWQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt0BChpzZml4ZWQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ4CgJpbhgGIAMoD0JswkhpCmcKC3NmaXhlZDMyLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnkKBm5vdF9pbhgHIAMoD0JpwkhmCmQKD3NmaXhlZDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEi4KB2V4YW1wbGUYCCADKA9CHcJIGgoYChBzZml4ZWQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKaFQoNU0ZpeGVkNjRSdWxlcxJsCgVjb25zdBgBIAEoEEJdwkhaClgKDnNmaXhlZDY0LmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEo0BCgJsdBgCIAEoEEJ/wkh8CnoKC3NmaXhlZDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp8BCgNsdGUYAyABKBBCjwHCSIsBCogBCgxzZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqYHCgJndBgEIAEoEEKXB8JIkwcKfQoLc2ZpeGVkNjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrYBCg5zZml4ZWQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvgEKGHNmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsYBCg9zZml4ZWQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs4BChlzZml4ZWQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLyBwoDZ3RlGAUgASgQQuIHwkjeBwqLAQoMc2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxQEKD3NmaXhlZDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrNAQoZc2ZpeGVkNjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1QEKEHNmaXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3QEKGnNmaXhlZDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEngKAmluGAYgAygQQmzCSGkKZwoLc2ZpeGVkNjQuaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSeQoGbm90X2luGAcgAygQQmnCSGYKZAoPc2ZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLgoHZXhhbXBsZRgIIAMoEEIdwkgaChgKEHNmaXhlZDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIqwBCglCb29sUnVsZXMSaAoFY29uc3QYASABKAhCWcJIVgpUCgpib29sLmNvbnN0GkZ0aGlzICE9IHJ1bGVzLmNvbnN0ID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbcnVsZXMuY29uc3RdKSA6ICcnEioKB2V4YW1wbGUYAiADKAhCGcJIFgoUCgxib29sLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiLqNgoLU3RyaW5nUnVsZXMSbAoFY29uc3QYASABKAlCXcJIWgpYCgxzdHJpbmcuY29uc3QaSHRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCBgJXNgJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxJ+CgNsZW4YEyABKARCccJIbgpsCgpzdHJpbmcubGVuGl51aW50KHRoaXMuc2l6ZSgpKSAhPSBydWxlcy5sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpkBCgdtaW5fbGVuGAIgASgEQocBwkiDAQqAAQoOc3RyaW5nLm1pbl9sZW4abnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2xlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBsZWFzdCAlcyBjaGFyYWN0ZXJzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEpcBCgdtYXhfbGVuGAMgASgEQoUBwkiBAQp/Cg5zdHJpbmcubWF4X2xlbhptdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKbAQoJbGVuX2J5dGVzGBQgASgEQocBwkiDAQqAAQoQc3RyaW5nLmxlbl9ieXRlcxpsdWludChieXRlcyh0aGlzKS5zaXplKCkpICE9IHJ1bGVzLmxlbl9ieXRlcyA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5fYnl0ZXNdKSA6ICcnEqMBCgltaW5fYnl0ZXMYBCABKARCjwHCSIsBCogBChBzdHJpbmcubWluX2J5dGVzGnR1aW50KGJ5dGVzKHRoaXMpLnNpemUoKSkgPCBydWxlcy5taW5fYnl0ZXMgPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2J5dGVzXSkgOiAnJxKiAQoJbWF4X2J5dGVzGAUgASgEQo4BwkiKAQqHAQoQc3RyaW5nLm1heF9ieXRlcxpzdWludChieXRlcyh0aGlzKS5zaXplKCkpID4gcnVsZXMubWF4X2J5dGVzID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWF4X2J5dGVzXSkgOiAnJxKNAQoHcGF0dGVybhgGIAEoCUJ8wkh5CncKDnN0cmluZy5wYXR0ZXJuGmUhdGhpcy5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIGRvZXMgbm90IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKEAQoGcHJlZml4GAcgASgJQnTCSHEKbwoNc3RyaW5nLnByZWZpeBpeIXRoaXMuc3RhcnRzV2l0aChydWxlcy5wcmVmaXgpID8gJ3ZhbHVlIGRvZXMgbm90IGhhdmUgcHJlZml4IGAlc2AnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxKCAQoGc3VmZml4GAggASgJQnLCSG8KbQoNc3RyaW5nLnN1ZmZpeBpcIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCBgJXNgJy5mb3JtYXQoW3J1bGVzLnN1ZmZpeF0pIDogJycSkAEKCGNvbnRhaW5zGAkgASgJQn7CSHsKeQoPc3RyaW5nLmNvbnRhaW5zGmYhdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiBzdWJzdHJpbmcgYCVzYCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSmAEKDG5vdF9jb250YWlucxgXIAEoCUKBAcJIfgp8ChNzdHJpbmcubm90X2NvbnRhaW5zGmV0aGlzLmNvbnRhaW5zKHJ1bGVzLm5vdF9jb250YWlucykgPyAndmFsdWUgY29udGFpbnMgc3Vic3RyaW5nIGAlc2AnLmZvcm1hdChbcnVsZXMubm90X2NvbnRhaW5zXSkgOiAnJxJ2CgJpbhgKIAMoCUJqwkhnCmUKCXN0cmluZy5pbhpYISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ3CgZub3RfaW4YCyADKAlCZ8JIZApiCg1zdHJpbmcubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycS3wEKBWVtYWlsGAwgASgIQs0BwkjJAQphCgxzdHJpbmcuZW1haWwSI3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGiwhcnVsZXMuZW1haWwgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzRW1haWwoKQpkChJzdHJpbmcuZW1haWxfZW1wdHkSMnZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGhohcnVsZXMuZW1haWwgfHwgdGhpcyAhPSAnJ0gAEucBCghob3N0bmFtZRgNIAEoCELSAcJIzgEKZQoPc3RyaW5nLmhvc3RuYW1lEh52YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaG9zdG5hbWUaMiFydWxlcy5ob3N0bmFtZSB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpCmUKFXN0cmluZy5ob3N0bmFtZV9lbXB0eRItdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3RuYW1lGh0hcnVsZXMuaG9zdG5hbWUgfHwgdGhpcyAhPSAnJ0gAEscBCgJpcBgOIAEoCEK4AcJItAEKVQoJc3RyaW5nLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxomIXJ1bGVzLmlwIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKCkKWwoPc3RyaW5nLmlwX2VtcHR5Ei92YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgYWRkcmVzcxoXIXJ1bGVzLmlwIHx8IHRoaXMgIT0gJydIABLWAQoEaXB2NBgPIAEoCELFAcJIwQEKXAoLc3RyaW5nLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaKSFydWxlcy5pcHY0IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKDQpCmEKEXN0cmluZy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGhkhcnVsZXMuaXB2NCB8fCB0aGlzICE9ICcnSAAS1gEKBGlwdjYYECABKAhCxQHCSMEBClwKC3N0cmluZy5pcHY2EiJ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NiBhZGRyZXNzGikhcnVsZXMuaXB2NiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcCg2KQphChFzdHJpbmcuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxoZIXJ1bGVzLmlwdjYgfHwgdGhpcyAhPSAnJ0gAEr8BCgN1cmkYESABKAhCrwHCSKsBClEKCnN0cmluZy51cmkSGXZhbHVlIG11c3QgYmUgYSB2YWxpZCBVUkkaKCFydWxlcy51cmkgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzVXJpKCkKVgoQc3RyaW5nLnVyaV9lbXB0eRIodmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIFVSSRoYIXJ1bGVzLnVyaSB8fCB0aGlzICE9ICcnSAAScAoHdXJpX3JlZhgSIAEoCEJdwkhaClgKDnN0cmluZy51cmlfcmVmEiN2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVJJIFJlZmVyZW5jZRohIXJ1bGVzLnVyaV9yZWYgfHwgdGhpcy5pc1VyaVJlZigpSAASkAIKB2FkZHJlc3MYFSABKAhC/AHCSPgBCoEBCg5zdHJpbmcuYWRkcmVzcxItdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGhvc3RuYW1lLCBvciBpcCBhZGRyZXNzGkAhcnVsZXMuYWRkcmVzcyB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpIHx8IHRoaXMuaXNJcCgpCnIKFHN0cmluZy5hZGRyZXNzX2VtcHR5Ejx2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdG5hbWUsIG9yIGlwIGFkZHJlc3MaHCFydWxlcy5hZGRyZXNzIHx8IHRoaXMgIT0gJydIABKYAgoEdXVpZBgWIAEoCEKHAsJIgwIKpQEKC3N0cmluZy51dWlkEhp2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVVJRBp6IXJ1bGVzLnV1aWQgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLm1hdGNoZXMoJ15bMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXsxMn0kJykKWQoRc3RyaW5nLnV1aWRfZW1wdHkSKXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBVVUlEGhkhcnVsZXMudXVpZCB8fCB0aGlzICE9ICcnSAAS8AEKBXR1dWlkGCEgASgIQt4BwkjaAQpzCgxzdHJpbmcudHV1aWQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCB0cmltbWVkIFVVSUQaPyFydWxlcy50dXVpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTlhLWZBLUZdezMyfSQnKQpjChJzdHJpbmcudHV1aWRfZW1wdHkSMXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCB0cmltbWVkIFVVSUQaGiFydWxlcy50dXVpZCB8fCB0aGlzICE9ICcnSAASlgIKEWlwX3dpdGhfcHJlZml4bGVuGBogASgIQvgBwkj0AQp4ChhzdHJpbmcuaXBfd2l0aF9wcmVmaXhsZW4SH3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUCBwcmVmaXgaOyFydWxlcy5pcF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCgpCngKHnN0cmluZy5pcF93aXRoX3ByZWZpeGxlbl9lbXB0eRIudmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIHByZWZpeBomIXJ1bGVzLmlwX3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgIT0gJydIABLPAgoTaXB2NF93aXRoX3ByZWZpeGxlbhgbIAEoCEKvAsJIqwIKkwEKGnN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuEjV2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBo+IXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCkKkgEKIHN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuX2VtcHR5EkR2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBooIXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyAhPSAnJ0gAEs8CChNpcHY2X3dpdGhfcHJlZml4bGVuGBwgASgIQq8CwkirAgqTAQoac3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW4SNXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGj4hcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg2KQqSAQogc3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW5fZW1wdHkSRHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGighcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzICE9ICcnSAAS8gEKCWlwX3ByZWZpeBgdIAEoCELcAcJI2AEKbAoQc3RyaW5nLmlwX3ByZWZpeBIfdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQIHByZWZpeBo3IXJ1bGVzLmlwX3ByZWZpeCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCh0cnVlKQpoChZzdHJpbmcuaXBfcHJlZml4X2VtcHR5Ei52YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgcHJlZml4Gh4hcnVsZXMuaXBfcHJlZml4IHx8IHRoaXMgIT0gJydIABKDAgoLaXB2NF9wcmVmaXgYHiABKAhC6wHCSOcBCnUKEnN0cmluZy5pcHY0X3ByZWZpeBIhdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjQgcHJlZml4GjwhcnVsZXMuaXB2NF9wcmVmaXggfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCwgdHJ1ZSkKbgoYc3RyaW5nLmlwdjRfcHJlZml4X2VtcHR5EjB2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBwcmVmaXgaICFydWxlcy5pcHY0X3ByZWZpeCB8fCB0aGlzICE9ICcnSAASgwIKC2lwdjZfcHJlZml4GB8gASgIQusBwkjnAQp1ChJzdHJpbmcuaXB2Nl9wcmVmaXgSIXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IHByZWZpeBo8IXJ1bGVzLmlwdjZfcHJlZml4IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KDYsIHRydWUpCm4KGHN0cmluZy5pcHY2X3ByZWZpeF9lbXB0eRIwdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgcHJlZml4GiAhcnVsZXMuaXB2Nl9wcmVmaXggfHwgdGhpcyAhPSAnJ0gAErUCCg1ob3N0X2FuZF9wb3J0GCAgASgIQpsCwkiXAgqZAQoUc3RyaW5nLmhvc3RfYW5kX3BvcnQSQXZhbHVlIG11c3QgYmUgYSB2YWxpZCBob3N0IChob3N0bmFtZSBvciBJUCBhZGRyZXNzKSBhbmQgcG9ydCBwYWlyGj4hcnVsZXMuaG9zdF9hbmRfcG9ydCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0QW5kUG9ydCh0cnVlKQp5ChpzdHJpbmcuaG9zdF9hbmRfcG9ydF9lbXB0eRI3dmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3QgYW5kIHBvcnQgcGFpchoiIXJ1bGVzLmhvc3RfYW5kX3BvcnQgfHwgdGhpcyAhPSAnJ0gAEqgFChB3ZWxsX2tub3duX3JlZ2V4GBggASgOMhguYnVmLnZhbGlkYXRlLktub3duUmVnZXhC8QTCSO0ECvABCiNzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfbmFtZRImdmFsdWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgaGVhZGVyIG5hbWUaoAFydWxlcy53ZWxsX2tub3duX3JlZ2V4ICE9IDEgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLm1hdGNoZXMoIWhhcyhydWxlcy5zdHJpY3QpIHx8IHJ1bGVzLnN0cmljdCA/J146P1swLTlhLXpBLVohIyQlJlwnKistLl5ffH5ceDYwXSskJyA6J15bXlx1MDAwMFx1MDAwQVx1MDAwRF0rJCcpCo0BCilzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfbmFtZV9lbXB0eRI1dmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIEhUVFAgaGVhZGVyIG5hbWUaKXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMSB8fCB0aGlzICE9ICcnCucBCiRzdHJpbmcud2VsbF9rbm93bl9yZWdleC5oZWFkZXJfdmFsdWUSJ3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBIVFRQIGhlYWRlciB2YWx1ZRqVAXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMiB8fCB0aGlzLm1hdGNoZXMoIWhhcyhydWxlcy5zdHJpY3QpIHx8IHJ1bGVzLnN0cmljdCA/J15bXlx1MDAwMC1cdTAwMDhcdTAwMEEtXHUwMDFGXHUwMDdGXSokJyA6J15bXlx1MDAwMFx1MDAwQVx1MDAwRF0qJCcpSAASDgoGc3RyaWN0GBkgASgIEiwKB2V4YW1wbGUYIiADKAlCG8JIGAoWCg5zdHJpbmcuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgwKCndlbGxfa25vd24ivxAKCkJ5dGVzUnVsZXMSZgoFY29uc3QYASABKAxCV8JIVApSCgtieXRlcy5jb25zdBpDdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGJlICV4Jy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxJ4CgNsZW4YDSABKARCa8JIaApmCglieXRlcy5sZW4aWXVpbnQodGhpcy5zaXplKCkpICE9IHJ1bGVzLmxlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpABCgdtaW5fbGVuGAIgASgEQn/CSHwKegoNYnl0ZXMubWluX2xlbhppdWludCh0aGlzLnNpemUoKSkgPCBydWxlcy5taW5fbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IGxlYXN0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEogBCgdtYXhfbGVuGAMgASgEQnfCSHQKcgoNYnl0ZXMubWF4X2xlbhphdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIG11c3QgYmUgYXQgbW9zdCAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKQAQoHcGF0dGVybhgEIAEoCUJ/wkh8CnoKDWJ5dGVzLnBhdHRlcm4aaSFzdHJpbmcodGhpcykubWF0Y2hlcyhydWxlcy5wYXR0ZXJuKSA/ICd2YWx1ZSBtdXN0IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKBAQoGcHJlZml4GAUgASgMQnHCSG4KbAoMYnl0ZXMucHJlZml4GlwhdGhpcy5zdGFydHNXaXRoKHJ1bGVzLnByZWZpeCkgPyAndmFsdWUgZG9lcyBub3QgaGF2ZSBwcmVmaXggJXgnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxJ/CgZzdWZmaXgYBiABKAxCb8JIbApqCgxieXRlcy5zdWZmaXgaWiF0aGlzLmVuZHNXaXRoKHJ1bGVzLnN1ZmZpeCkgPyAndmFsdWUgZG9lcyBub3QgaGF2ZSBzdWZmaXggJXgnLmZvcm1hdChbcnVsZXMuc3VmZml4XSkgOiAnJxKDAQoIY29udGFpbnMYByABKAxCccJIbgpsCg5ieXRlcy5jb250YWlucxpaIXRoaXMuY29udGFpbnMocnVsZXMuY29udGFpbnMpID8gJ3ZhbHVlIGRvZXMgbm90IGNvbnRhaW4gJXgnLmZvcm1hdChbcnVsZXMuY29udGFpbnNdKSA6ICcnEpcBCgJpbhgIIAMoDEKKAcJIhgEKgwEKCGJ5dGVzLmluGndkeW4ocnVsZXMpWydpbiddLnNpemUoKSA+IDAgJiYgISh0aGlzIGluIGR5bihydWxlcylbJ2luJ10pID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtkeW4ocnVsZXMpWydpbiddXSkgOiAnJxJ2CgZub3RfaW4YCSADKAxCZsJIYwphCgxieXRlcy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLrAQoCaXAYCiABKAhC3AHCSNgBCnQKCGJ5dGVzLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxpGIXJ1bGVzLmlwIHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNCB8fCB0aGlzLnNpemUoKSA9PSAxNgpgCg5ieXRlcy5pcF9lbXB0eRIvdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIGFkZHJlc3MaHSFydWxlcy5pcCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5AEKBGlwdjQYCyABKAhC0wHCSM8BCmUKCmJ5dGVzLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaMyFydWxlcy5pcHY0IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNApmChBieXRlcy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGh8hcnVsZXMuaXB2NCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5QEKBGlwdjYYDCABKAhC1AHCSNABCmYKCmJ5dGVzLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaNCFydWxlcy5pcHY2IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gMTYKZgoQYnl0ZXMuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxofIXJ1bGVzLmlwdjYgfHwgdGhpcy5zaXplKCkgIT0gMEgAEisKB2V4YW1wbGUYDiADKAxCGsJIFwoVCg1ieXRlcy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biKvAwoJRW51bVJ1bGVzEmgKBWNvbnN0GAEgASgFQlnCSFYKVAoKZW51bS5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxIUCgxkZWZpbmVkX29ubHkYAiABKAgSdAoCaW4YAyADKAVCaMJIZQpjCgdlbnVtLmluGlghKHRoaXMgaW4gZHluKHJ1bGVzKVsnaW4nXSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2R5bihydWxlcylbJ2luJ11dKSA6ICcnEnUKBm5vdF9pbhgEIAMoBUJlwkhiCmAKC2VudW0ubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKgoHZXhhbXBsZRgFIAMoBUIZwkgWChQKDGVudW0uZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACIoEECg1SZXBlYXRlZFJ1bGVzEp4BCgltaW5faXRlbXMYASABKARCigHCSIYBCoMBChJyZXBlYXRlZC5taW5faXRlbXMabXVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2l0ZW1zID8gJ3ZhbHVlIG11c3QgY29udGFpbiBhdCBsZWFzdCAlZCBpdGVtKHMpJy5mb3JtYXQoW3J1bGVzLm1pbl9pdGVtc10pIDogJycSogEKCW1heF9pdGVtcxgCIAEoBEKOAcJIigEKhwEKEnJlcGVhdGVkLm1heF9pdGVtcxpxdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfaXRlbXMgPyAndmFsdWUgbXVzdCBjb250YWluIG5vIG1vcmUgdGhhbiAlcyBpdGVtKHMpJy5mb3JtYXQoW3J1bGVzLm1heF9pdGVtc10pIDogJycScAoGdW5pcXVlGAMgASgIQmDCSF0KWwoPcmVwZWF0ZWQudW5pcXVlEihyZXBlYXRlZCB2YWx1ZSBtdXN0IGNvbnRhaW4gdW5pcXVlIGl0ZW1zGh4hcnVsZXMudW5pcXVlIHx8IHRoaXMudW5pcXVlKCkSLQoFaXRlbXMYBCABKAsyHi5idWYudmFsaWRhdGUuRmllbGRDb25zdHJhaW50cyoJCOgHEICAgIACIpYDCghNYXBSdWxlcxKPAQoJbWluX3BhaXJzGAEgASgEQnzCSHkKdwoNbWFwLm1pbl9wYWlycxpmdWludCh0aGlzLnNpemUoKSkgPCBydWxlcy5taW5fcGFpcnMgPyAnbWFwIG11c3QgYmUgYXQgbGVhc3QgJWQgZW50cmllcycuZm9ybWF0KFtydWxlcy5taW5fcGFpcnNdKSA6ICcnEo4BCgltYXhfcGFpcnMYAiABKARCe8JIeAp2Cg1tYXAubWF4X3BhaXJzGmV1aW50KHRoaXMuc2l6ZSgpKSA+IHJ1bGVzLm1heF9wYWlycyA/ICdtYXAgbXVzdCBiZSBhdCBtb3N0ICVkIGVudHJpZXMnLmZvcm1hdChbcnVsZXMubWF4X3BhaXJzXSkgOiAnJxIsCgRrZXlzGAQgASgLMh4uYnVmLnZhbGlkYXRlLkZpZWxkQ29uc3RyYWludHMSLgoGdmFsdWVzGAUgASgLMh4uYnVmLnZhbGlkYXRlLkZpZWxkQ29uc3RyYWludHMqCQjoBxCAgICAAiImCghBbnlSdWxlcxIKCgJpbhgCIAMoCRIOCgZub3RfaW4YAyADKAki9RYKDUR1cmF0aW9uUnVsZXMShwEKBWNvbnN0GAIgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQl3CSFoKWAoOZHVyYXRpb24uY29uc3QaRnRoaXMgIT0gcnVsZXMuY29uc3QgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtydWxlcy5jb25zdF0pIDogJycSqAEKAmx0GAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQn/CSHwKegoLZHVyYXRpb24ubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASugEKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkKPAcJIiwEKiAEKDGR1cmF0aW9uLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASwQcKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQpcHwkiTBwp9CgtkdXJhdGlvbi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDmR1cmF0aW9uLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYZHVyYXRpb24uZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD2R1cmF0aW9uLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGWR1cmF0aW9uLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEo0ICgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25C4gfCSN4HCosBCgxkdXJhdGlvbi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPZHVyYXRpb24uZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlkdXJhdGlvbi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQZHVyYXRpb24uZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoaZHVyYXRpb24uZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESkwEKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQmzCSGkKZwoLZHVyYXRpb24uaW4aWCEodGhpcyBpbiBkeW4ocnVsZXMpWydpbiddKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZHluKHJ1bGVzKVsnaW4nXV0pIDogJycSlAEKBm5vdF9pbhgIIAMoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkJpwkhmCmQKD2R1cmF0aW9uLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEkkKB2V4YW1wbGUYCSADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25CHcJIGgoYChBkdXJhdGlvbi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiL4FwoOVGltZXN0YW1wUnVsZXMSiQEKBWNvbnN0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEJewkhbClkKD3RpbWVzdGFtcC5jb25zdBpGdGhpcyAhPSBydWxlcy5jb25zdCA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW3J1bGVzLmNvbnN0XSkgOiAnJxKrAQoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQoABwkh9CnsKDHRpbWVzdGFtcC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABK8AQoDbHRlGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKQAcJIjAEKiQEKDXRpbWVzdGFtcC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEmwKBmx0X25vdxgHIAEoCEJawkhXClUKEHRpbWVzdGFtcC5sdF9ub3caQShydWxlcy5sdF9ub3cgJiYgdGhpcyA+IG5vdykgPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gbm93JyA6ICcnSAASxwcKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKcB8JImAcKfgoMdGltZXN0YW1wLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq3AQoPdGltZXN0YW1wLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq/AQoZdGltZXN0YW1wLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCscBChB0aW1lc3RhbXAuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrPAQoadGltZXN0YW1wLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEpMICgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQucHwkjjBwqMAQoNdGltZXN0YW1wLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsYBChB0aW1lc3RhbXAuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs4BChp0aW1lc3RhbXAuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1gEKEXRpbWVzdGFtcC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt4BCht0aW1lc3RhbXAuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESbwoGZ3Rfbm93GAggASgIQl3CSFoKWAoQdGltZXN0YW1wLmd0X25vdxpEKHJ1bGVzLmd0X25vdyAmJiB0aGlzIDwgbm93KSA/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBub3cnIDogJydIARK4AQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQowBwkiIAQqFAQoQdGltZXN0YW1wLndpdGhpbhpxdGhpcyA8IG5vdy1ydWxlcy53aXRoaW4gfHwgdGhpcyA+IG5vdytydWxlcy53aXRoaW4gPyAndmFsdWUgbXVzdCBiZSB3aXRoaW4gJXMgb2Ygbm93Jy5mb3JtYXQoW3J1bGVzLndpdGhpbl0pIDogJycSSwoHZXhhbXBsZRgKIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCHsJIGwoZChF0aW1lc3RhbXAuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iOQoKVmlvbGF0aW9ucxIrCgp2aW9sYXRpb25zGAEgAygLMhcuYnVmLnZhbGlkYXRlLlZpb2xhdGlvbiKlAQoJVmlvbGF0aW9uEiYKBWZpZWxkGAUgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIlCgRydWxlGAYgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIVCg1jb25zdHJhaW50X2lkGAIgASgJEg8KB21lc3NhZ2UYAyABKAkSDwoHZm9yX2tleRgEIAEoCEoECAEQAlIKZmllbGRfcGF0aCI9CglGaWVsZFBhdGgSMAoIZWxlbWVudHMYASADKAsyHi5idWYudmFsaWRhdGUuRmllbGRQYXRoRWxlbWVudCLpAgoQRmllbGRQYXRoRWxlbWVudBIUCgxmaWVsZF9udW1iZXIYASABKAUSEgoKZmllbGRfbmFtZRgCIAEoCRI+CgpmaWVsZF90eXBlGAMgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSPAoIa2V5X3R5cGUYBCABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRI+Cgp2YWx1ZV90eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSDwoFaW5kZXgYBiABKARIABISCghib29sX2tleRgHIAEoCEgAEhEKB2ludF9rZXkYCCABKANIABISCgh1aW50X2tleRgJIAEoBEgAEhQKCnN0cmluZ19rZXkYCiABKAlIAEILCglzdWJzY3JpcHQqhwEKBklnbm9yZRIWChJJR05PUkVfVU5TUEVDSUZJRUQQABIZChVJR05PUkVfSUZfVU5QT1BVTEFURUQQARIbChdJR05PUkVfSUZfREVGQVVMVF9WQUxVRRACEhEKDUlHTk9SRV9BTFdBWVMQAyoaSUdOT1JFX0VNUFRZSUdOT1JFX0RFRkFVTFQqbgoKS25vd25SZWdleBIbChdLTk9XTl9SRUdFWF9VTlNQRUNJRklFRBAAEiAKHEtOT1dOX1JFR0VYX0hUVFBfSEVBREVSX05BTUUQARIhCh1LTk9XTl9SRUdFWF9IVFRQX0hFQURFUl9WQUxVRRACOlwKB21lc3NhZ2USHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhwkgASgLMiAuYnVmLnZhbGlkYXRlLk1lc3NhZ2VDb25zdHJhaW50c1IHbWVzc2FnZTpUCgVvbmVvZhIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMYhwkgASgLMh4uYnVmLnZhbGlkYXRlLk9uZW9mQ29uc3RyYWludHNSBW9uZW9mOlQKBWZpZWxkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiHCSABKAsyHi5idWYudmFsaWRhdGUuRmllbGRDb25zdHJhaW50c1IFZmllbGQ6YwoKcHJlZGVmaW5lZBIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMYiAkgASgLMiMuYnVmLnZhbGlkYXRlLlByZWRlZmluZWRDb25zdHJhaW50c1IKcHJlZGVmaW5lZEJuChJidWlsZC5idWYudmFsaWRhdGVCDVZhbGlkYXRlUHJvdG9QAVpHYnVmLmJ1aWxkL2dlbi9nby9idWZidWlsZC9wcm90b3ZhbGlkYXRlL3Byb3RvY29sYnVmZmVycy9nby9idWYvdmFsaWRhdGU", [file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_timestamp]);
+ fileDesc("ChtidWYvdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8SDGJ1Zi52YWxpZGF0ZSI3CgRSdWxlEgoKAmlkGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEgoKZXhwcmVzc2lvbhgDIAEoCSJBCgxNZXNzYWdlUnVsZXMSEAoIZGlzYWJsZWQYASABKAgSHwoDY2VsGAMgAygLMhIuYnVmLnZhbGlkYXRlLlJ1bGUiHgoKT25lb2ZSdWxlcxIQCghyZXF1aXJlZBgBIAEoCCK/CAoKRmllbGRSdWxlcxIfCgNjZWwYFyADKAsyEi5idWYudmFsaWRhdGUuUnVsZRIQCghyZXF1aXJlZBgZIAEoCBIkCgZpZ25vcmUYGyABKA4yFC5idWYudmFsaWRhdGUuSWdub3JlEikKBWZsb2F0GAEgASgLMhguYnVmLnZhbGlkYXRlLkZsb2F0UnVsZXNIABIrCgZkb3VibGUYAiABKAsyGS5idWYudmFsaWRhdGUuRG91YmxlUnVsZXNIABIpCgVpbnQzMhgDIAEoCzIYLmJ1Zi52YWxpZGF0ZS5JbnQzMlJ1bGVzSAASKQoFaW50NjQYBCABKAsyGC5idWYudmFsaWRhdGUuSW50NjRSdWxlc0gAEisKBnVpbnQzMhgFIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50MzJSdWxlc0gAEisKBnVpbnQ2NBgGIAEoCzIZLmJ1Zi52YWxpZGF0ZS5VSW50NjRSdWxlc0gAEisKBnNpbnQzMhgHIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50MzJSdWxlc0gAEisKBnNpbnQ2NBgIIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TSW50NjRSdWxlc0gAEi0KB2ZpeGVkMzIYCSABKAsyGi5idWYudmFsaWRhdGUuRml4ZWQzMlJ1bGVzSAASLQoHZml4ZWQ2NBgKIAEoCzIaLmJ1Zi52YWxpZGF0ZS5GaXhlZDY0UnVsZXNIABIvCghzZml4ZWQzMhgLIAEoCzIbLmJ1Zi52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSAASLwoIc2ZpeGVkNjQYDCABKAsyGy5idWYudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAEicKBGJvb2wYDSABKAsyFy5idWYudmFsaWRhdGUuQm9vbFJ1bGVzSAASKwoGc3RyaW5nGA4gASgLMhkuYnVmLnZhbGlkYXRlLlN0cmluZ1J1bGVzSAASKQoFYnl0ZXMYDyABKAsyGC5idWYudmFsaWRhdGUuQnl0ZXNSdWxlc0gAEicKBGVudW0YECABKAsyFy5idWYudmFsaWRhdGUuRW51bVJ1bGVzSAASLwoIcmVwZWF0ZWQYEiABKAsyGy5idWYudmFsaWRhdGUuUmVwZWF0ZWRSdWxlc0gAEiUKA21hcBgTIAEoCzIWLmJ1Zi52YWxpZGF0ZS5NYXBSdWxlc0gAEiUKA2FueRgUIAEoCzIWLmJ1Zi52YWxpZGF0ZS5BbnlSdWxlc0gAEi8KCGR1cmF0aW9uGBUgASgLMhsuYnVmLnZhbGlkYXRlLkR1cmF0aW9uUnVsZXNIABIxCgl0aW1lc3RhbXAYFiABKAsyHC5idWYudmFsaWRhdGUuVGltZXN0YW1wUnVsZXNIAEIGCgR0eXBlSgQIGBAZSgQIGhAbUgdza2lwcGVkUgxpZ25vcmVfZW1wdHkiUwoPUHJlZGVmaW5lZFJ1bGVzEh8KA2NlbBgBIAMoCzISLmJ1Zi52YWxpZGF0ZS5SdWxlSgQIGBAZSgQIGhAbUhNza2lwcGVkaWdub3JlX2VtcHR5ItoXCgpGbG9hdFJ1bGVzEoMBCgVjb25zdBgBIAEoAkJ0wkhxCm8KC2Zsb2F0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSnwEKAmx0GAIgASgCQpABwkiMAQqJAQoIZmxvYXQubHQafSFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASrwEKA2x0ZRgDIAEoAkKfAcJImwEKmAEKCWZsb2F0Lmx0ZRqKASFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEu8HCgJndBgEIAEoAkLgB8JI3AcKjQEKCGZsb2F0Lmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKwwEKC2Zsb2F0Lmd0X2x0GrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKzQEKFWZsb2F0Lmd0X2x0X2V4Y2x1c2l2ZRqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCtMBCgxmbG9hdC5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrdAQoWZmxvYXQuZ3RfbHRlX2V4Y2x1c2l2ZRrCAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAESuggKA2d0ZRgFIAEoAkKqCMJIpggKmwEKCWZsb2F0Lmd0ZRqNASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrSAQoMZmxvYXQuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrcAQoWZmxvYXQuZ3RlX2x0X2V4Y2x1c2l2ZRrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK4gEKDWZsb2F0Lmd0ZV9sdGUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCuwBChdmbG9hdC5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARJ/CgJpbhgGIAMoAkJzwkhwCm4KCGZsb2F0LmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ2CgZub3RfaW4YByADKAJCZsJIYwphCgxmbG9hdC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ1CgZmaW5pdGUYCCABKAhCZcJIYgpgCgxmbG9hdC5maW5pdGUaUHJ1bGVzLmZpbml0ZSA/ICh0aGlzLmlzTmFuKCkgfHwgdGhpcy5pc0luZigpID8gJ3ZhbHVlIG11c3QgYmUgZmluaXRlJyA6ICcnKSA6ICcnEisKB2V4YW1wbGUYCSADKAJCGsJIFwoVCg1mbG9hdC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiLtFwoLRG91YmxlUnVsZXMShAEKBWNvbnN0GAEgASgBQnXCSHIKcAoMZG91YmxlLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSoAEKAmx0GAIgASgBQpEBwkiNAQqKAQoJZG91YmxlLmx0Gn0haGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0KT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAErABCgNsdGUYAyABKAFCoAHCSJwBCpkBCgpkb3VibGUubHRlGooBIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSk/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAAS9AcKAmd0GAQgASgBQuUHwkjhBwqOAQoJZG91YmxlLmd0GoABIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKxAEKDGRvdWJsZS5ndF9sdBqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCs4BChZkb3VibGUuZ3RfbHRfZXhjbHVzaXZlGrMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycK1AEKDWRvdWJsZS5ndF9sdGUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwreAQoXZG91YmxlLmd0X2x0ZV9leGNsdXNpdmUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEr8ICgNndGUYBSABKAFCrwjCSKsICpwBCgpkb3VibGUuZ3RlGo0BIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCtMBCg1kb3VibGUuZ3RlX2x0GsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrdAQoXZG91YmxlLmd0ZV9sdF9leGNsdXNpdmUawQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCuMBCg5kb3VibGUuZ3RlX2x0ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK7QEKGGRvdWJsZS5ndGVfbHRlX2V4Y2x1c2l2ZRrQAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKAFCdMJIcQpvCglkb3VibGUuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoAUJnwkhkCmIKDWRvdWJsZS5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJ2CgZmaW5pdGUYCCABKAhCZsJIYwphCg1kb3VibGUuZmluaXRlGlBydWxlcy5maW5pdGUgPyAodGhpcy5pc05hbigpIHx8IHRoaXMuaXNJbmYoKSA/ICd2YWx1ZSBtdXN0IGJlIGZpbml0ZScgOiAnJykgOiAnJxIsCgdleGFtcGxlGAkgAygBQhvCSBgKFgoOZG91YmxlLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIowVCgpJbnQzMlJ1bGVzEoMBCgVjb25zdBgBIAEoBUJ0wkhxCm8KC2ludDMyLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSigEKAmx0GAIgASgFQnzCSHkKdwoIaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoBUKMAcJIiAEKhQEKCWludDMyLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgFQogHwkiEBwp6CghpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50MzIuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKAVC0wfCSM8HCogBCglpbnQzMi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50MzIuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESfwoCaW4YBiADKAVCc8JIcApuCghpbnQzMi5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSdgoGbm90X2luGAcgAygFQmbCSGMKYQoMaW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKwoHZXhhbXBsZRgIIAMoBUIawkgXChUKDWludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIowVCgpJbnQ2NFJ1bGVzEoMBCgVjb25zdBgBIAEoA0J0wkhxCm8KC2ludDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSigEKAmx0GAIgASgDQnzCSHkKdwoIaW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnAEKA2x0ZRgDIAEoA0KMAcJIiAEKhQEKCWludDY0Lmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASlwcKAmd0GAQgASgDQogHwkiEBwp6CghpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKswEKC2ludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq7AQoVaW50NjQuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKwwEKDGludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKywEKFmludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEuMHCgNndGUYBSABKANC0wfCSM8HCogBCglpbnQ2NC5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrCAQoMaW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCsoBChZpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrSAQoNaW50NjQuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwraAQoXaW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESfwoCaW4YBiADKANCc8JIcApuCghpbnQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSdgoGbm90X2luGAcgAygDQmbCSGMKYQoMaW50NjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSKwoHZXhhbXBsZRgJIAMoA0IawkgXChUKDWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtVSW50MzJSdWxlcxKEAQoFY29uc3QYASABKA1CdcJIcgpwCgx1aW50MzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKA1CfcJIegp4Cgl1aW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoDUKNAcJIiQEKhgEKCnVpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoDUKNB8JIiQcKewoJdWludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMdWludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWdWludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg11aW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXdWludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKA1C2AfCSNQHCokBCgp1aW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXVpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3VpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOdWludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHVpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKA1CdMJIcQpvCgl1aW50MzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoDUJnwkhkCmIKDXVpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygNQhvCSBgKFgoOdWludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtVSW50NjRSdWxlcxKEAQoFY29uc3QYASABKARCdcJIcgpwCgx1aW50NjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKARCfcJIegp4Cgl1aW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoBEKNAcJIiQEKhgEKCnVpbnQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoBEKNB8JIiQcKewoJdWludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMdWludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWdWludDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg11aW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXdWludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKARC2AfCSNQHCokBCgp1aW50NjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXVpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3VpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOdWludDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHVpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKARCdMJIcQpvCgl1aW50NjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoBEJnwkhkCmIKDXVpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygEQhvCSBgKFgoOdWludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtTSW50MzJSdWxlcxKEAQoFY29uc3QYASABKBFCdcJIcgpwCgxzaW50MzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKBFCfcJIegp4CglzaW50MzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEUKNAcJIiQEKhgEKCnNpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEUKNB8JIiQcKewoJc2ludDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50MzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBFC2AfCSNQHCokBCgpzaW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKBFCdMJIcQpvCglzaW50MzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoEUJnwkhkCmIKDXNpbnQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygRQhvCSBgKFgoOc2ludDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIp4VCgtTSW50NjRSdWxlcxKEAQoFY29uc3QYASABKBJCdcJIcgpwCgxzaW50NjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKLAQoCbHQYAiABKBJCfcJIegp4CglzaW50NjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnQEKA2x0ZRgDIAEoEkKNAcJIiQEKhgEKCnNpbnQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpwHCgJndBgEIAEoEkKNB8JIiQcKewoJc2ludDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq0AQoMc2ludDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq8AQoWc2ludDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsQBCg1zaW50NjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrMAQoXc2ludDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEugHCgNndGUYBSABKBJC2AfCSNQHCokBCgpzaW50NjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwwEKDXNpbnQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKywEKF3NpbnQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrTAQoOc2ludDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2wEKGHNpbnQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKAAQoCaW4YBiADKBJCdMJIcQpvCglzaW50NjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgHIAMoEkJnwkhkCmIKDXNpbnQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIsCgdleGFtcGxlGAggAygSQhvCSBgKFgoOc2ludDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIq8VCgxGaXhlZDMyUnVsZXMShQEKBWNvbnN0GAEgASgHQnbCSHMKcQoNZml4ZWQzMi5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEowBCgJsdBgCIAEoB0J+wkh7CnkKCmZpeGVkMzIubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASngEKA2x0ZRgDIAEoB0KOAcJIigEKhwEKC2ZpeGVkMzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKhBwoCZ3QYBCABKAdCkgfCSI4HCnwKCmZpeGVkMzIuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrUBCg1maXhlZDMyLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq9AQoXZml4ZWQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrFAQoOZml4ZWQzMi5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs0BChhmaXhlZDMyLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEu0HCgNndGUYBSABKAdC3QfCSNkHCooBCgtmaXhlZDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsQBCg5maXhlZDMyLmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrMAQoYZml4ZWQzMi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrUAQoPZml4ZWQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtwBChlmaXhlZDMyLmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEoEBCgJpbhgGIAMoB0J1wkhyCnAKCmZpeGVkMzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEngKBm5vdF9pbhgHIAMoB0JowkhlCmMKDmZpeGVkMzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoB0IcwkgZChcKD2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4irxUKDEZpeGVkNjRSdWxlcxKFAQoFY29uc3QYASABKAZCdsJIcwpxCg1maXhlZDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSjAEKAmx0GAIgASgGQn7CSHsKeQoKZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKeAQoDbHRlGAMgASgGQo4BwkiKAQqHAQoLZml4ZWQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqEHCgJndBgEIAEoBkKSB8JIjgcKfAoKZml4ZWQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtQEKDWZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr0BChdmaXhlZDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsUBCg5maXhlZDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzQEKGGZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES7QcKA2d0ZRgFIAEoBkLdB8JI2QcKigEKC2ZpeGVkNjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxAEKDmZpeGVkNjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCswBChhmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtQBCg9maXhlZDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3AEKGWZpeGVkNjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgQEKAmluGAYgAygGQnXCSHIKcAoKZml4ZWQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSeAoGbm90X2luGAcgAygGQmjCSGUKYwoOZml4ZWQ2NC5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxItCgdleGFtcGxlGAggAygGQhzCSBkKFwoPZml4ZWQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiLAFQoNU0ZpeGVkMzJSdWxlcxKGAQoFY29uc3QYASABKA9Cd8JIdApyCg5zZml4ZWQzMi5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEo0BCgJsdBgCIAEoD0J/wkh8CnoKC3NmaXhlZDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp8BCgNsdGUYAyABKA9CjwHCSIsBCogBCgxzZml4ZWQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEqYHCgJndBgEIAEoD0KXB8JIkwcKfQoLc2ZpeGVkMzIuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrYBCg5zZml4ZWQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvgEKGHNmaXhlZDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsYBCg9zZml4ZWQzMi5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs4BChlzZml4ZWQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLyBwoDZ3RlGAUgASgPQuIHwkjeBwqLAQoMc2ZpeGVkMzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKxQEKD3NmaXhlZDMyLmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrNAQoZc2ZpeGVkMzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1QEKEHNmaXhlZDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK3QEKGnNmaXhlZDMyLmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEoIBCgJpbhgGIAMoD0J2wkhzCnEKC3NmaXhlZDMyLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ5CgZub3RfaW4YByADKA9CacJIZgpkCg9zZml4ZWQzMi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxIuCgdleGFtcGxlGAggAygPQh3CSBoKGAoQc2ZpeGVkMzIuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iwBUKDVNGaXhlZDY0UnVsZXMShgEKBWNvbnN0GAEgASgQQnfCSHQKcgoOc2ZpeGVkNjQuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKNAQoCbHQYAiABKBBCf8JIfAp6CgtzZml4ZWQ2NC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKfAQoDbHRlGAMgASgQQo8BwkiLAQqIAQoMc2ZpeGVkNjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKmBwoCZ3QYBCABKBBClwfCSJMHCn0KC3NmaXhlZDY0Lmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq2AQoOc2ZpeGVkNjQuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr4BChhzZml4ZWQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrGAQoPc2ZpeGVkNjQuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrOAQoZc2ZpeGVkNjQuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES8gcKA2d0ZRgFIAEoEELiB8JI3gcKiwEKDHNmaXhlZDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsUBCg9zZml4ZWQ2NC5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzQEKGXNmaXhlZDY0Lmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtUBChBzZml4ZWQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt0BChpzZml4ZWQ2NC5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKCAQoCaW4YBiADKBBCdsJIcwpxCgtzZml4ZWQ2NC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSeQoGbm90X2luGAcgAygQQmnCSGYKZAoPc2ZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLgoHZXhhbXBsZRgIIAMoEEIdwkgaChgKEHNmaXhlZDY0LmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIscBCglCb29sUnVsZXMSggEKBWNvbnN0GAEgASgIQnPCSHAKbgoKYm9vbC5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEioKB2V4YW1wbGUYAiADKAhCGcJIFgoUCgxib29sLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiKQNwoLU3RyaW5nUnVsZXMShgEKBWNvbnN0GAEgASgJQnfCSHQKcgoMc3RyaW5nLmNvbnN0GmJ0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsIGAlc2AnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxJ+CgNsZW4YEyABKARCccJIbgpsCgpzdHJpbmcubGVuGl51aW50KHRoaXMuc2l6ZSgpKSAhPSBydWxlcy5sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5sZW5dKSA6ICcnEpkBCgdtaW5fbGVuGAIgASgEQocBwkiDAQqAAQoOc3RyaW5nLm1pbl9sZW4abnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX2xlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBsZWFzdCAlcyBjaGFyYWN0ZXJzJy5mb3JtYXQoW3J1bGVzLm1pbl9sZW5dKSA6ICcnEpcBCgdtYXhfbGVuGAMgASgEQoUBwkiBAQp/Cg5zdHJpbmcubWF4X2xlbhptdWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfbGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5tYXhfbGVuXSkgOiAnJxKbAQoJbGVuX2J5dGVzGBQgASgEQocBwkiDAQqAAQoQc3RyaW5nLmxlbl9ieXRlcxpsdWludChieXRlcyh0aGlzKS5zaXplKCkpICE9IHJ1bGVzLmxlbl9ieXRlcyA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSAlcyBieXRlcycuZm9ybWF0KFtydWxlcy5sZW5fYnl0ZXNdKSA6ICcnEqMBCgltaW5fYnl0ZXMYBCABKARCjwHCSIsBCogBChBzdHJpbmcubWluX2J5dGVzGnR1aW50KGJ5dGVzKHRoaXMpLnNpemUoKSkgPCBydWxlcy5taW5fYnl0ZXMgPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2J5dGVzXSkgOiAnJxKiAQoJbWF4X2J5dGVzGAUgASgEQo4BwkiKAQqHAQoQc3RyaW5nLm1heF9ieXRlcxpzdWludChieXRlcyh0aGlzKS5zaXplKCkpID4gcnVsZXMubWF4X2J5dGVzID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IG1vc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWF4X2J5dGVzXSkgOiAnJxKNAQoHcGF0dGVybhgGIAEoCUJ8wkh5CncKDnN0cmluZy5wYXR0ZXJuGmUhdGhpcy5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIGRvZXMgbm90IG1hdGNoIHJlZ2V4IHBhdHRlcm4gYCVzYCcuZm9ybWF0KFtydWxlcy5wYXR0ZXJuXSkgOiAnJxKEAQoGcHJlZml4GAcgASgJQnTCSHEKbwoNc3RyaW5nLnByZWZpeBpeIXRoaXMuc3RhcnRzV2l0aChydWxlcy5wcmVmaXgpID8gJ3ZhbHVlIGRvZXMgbm90IGhhdmUgcHJlZml4IGAlc2AnLmZvcm1hdChbcnVsZXMucHJlZml4XSkgOiAnJxKCAQoGc3VmZml4GAggASgJQnLCSG8KbQoNc3RyaW5nLnN1ZmZpeBpcIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCBgJXNgJy5mb3JtYXQoW3J1bGVzLnN1ZmZpeF0pIDogJycSkAEKCGNvbnRhaW5zGAkgASgJQn7CSHsKeQoPc3RyaW5nLmNvbnRhaW5zGmYhdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiBzdWJzdHJpbmcgYCVzYCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSmAEKDG5vdF9jb250YWlucxgXIAEoCUKBAcJIfgp8ChNzdHJpbmcubm90X2NvbnRhaW5zGmV0aGlzLmNvbnRhaW5zKHJ1bGVzLm5vdF9jb250YWlucykgPyAndmFsdWUgY29udGFpbnMgc3Vic3RyaW5nIGAlc2AnLmZvcm1hdChbcnVsZXMubm90X2NvbnRhaW5zXSkgOiAnJxKAAQoCaW4YCiADKAlCdMJIcQpvCglzdHJpbmcuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEncKBm5vdF9pbhgLIAMoCUJnwkhkCmIKDXN0cmluZy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLfAQoFZW1haWwYDCABKAhCzQHCSMkBCmEKDHN0cmluZy5lbWFpbBIjdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGVtYWlsIGFkZHJlc3MaLCFydWxlcy5lbWFpbCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNFbWFpbCgpCmQKEnN0cmluZy5lbWFpbF9lbXB0eRIydmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGVtYWlsIGFkZHJlc3MaGiFydWxlcy5lbWFpbCB8fCB0aGlzICE9ICcnSAAS5wEKCGhvc3RuYW1lGA0gASgIQtIBwkjOAQplCg9zdHJpbmcuaG9zdG5hbWUSHnZhbHVlIG11c3QgYmUgYSB2YWxpZCBob3N0bmFtZRoyIXJ1bGVzLmhvc3RuYW1lIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RuYW1lKCkKZQoVc3RyaW5nLmhvc3RuYW1lX2VtcHR5Ei12YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdG5hbWUaHSFydWxlcy5ob3N0bmFtZSB8fCB0aGlzICE9ICcnSAASxwEKAmlwGA4gASgIQrgBwki0AQpVCglzdHJpbmcuaXASIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUCBhZGRyZXNzGiYhcnVsZXMuaXAgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXAoKQpbCg9zdHJpbmcuaXBfZW1wdHkSL3ZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUCBhZGRyZXNzGhchcnVsZXMuaXAgfHwgdGhpcyAhPSAnJ0gAEtYBCgRpcHY0GA8gASgIQsUBwkjBAQpcCgtzdHJpbmcuaXB2NBIidmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjQgYWRkcmVzcxopIXJ1bGVzLmlwdjQgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXAoNCkKYQoRc3RyaW5nLmlwdjRfZW1wdHkSMXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IGFkZHJlc3MaGSFydWxlcy5pcHY0IHx8IHRoaXMgIT0gJydIABLWAQoEaXB2NhgQIAEoCELFAcJIwQEKXAoLc3RyaW5nLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaKSFydWxlcy5pcHY2IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKDYpCmEKEXN0cmluZy5pcHY2X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NiBhZGRyZXNzGhkhcnVsZXMuaXB2NiB8fCB0aGlzICE9ICcnSAASvwEKA3VyaRgRIAEoCEKvAcJIqwEKUQoKc3RyaW5nLnVyaRIZdmFsdWUgbXVzdCBiZSBhIHZhbGlkIFVSSRooIXJ1bGVzLnVyaSB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNVcmkoKQpWChBzdHJpbmcudXJpX2VtcHR5Eih2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgVVJJGhghcnVsZXMudXJpIHx8IHRoaXMgIT0gJydIABJwCgd1cmlfcmVmGBIgASgIQl3CSFoKWAoOc3RyaW5nLnVyaV9yZWYSI3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBVUkkgUmVmZXJlbmNlGiEhcnVsZXMudXJpX3JlZiB8fCB0aGlzLmlzVXJpUmVmKClIABKQAgoHYWRkcmVzcxgVIAEoCEL8AcJI+AEKgQEKDnN0cmluZy5hZGRyZXNzEi12YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaG9zdG5hbWUsIG9yIGlwIGFkZHJlc3MaQCFydWxlcy5hZGRyZXNzIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RuYW1lKCkgfHwgdGhpcy5pc0lwKCkKcgoUc3RyaW5nLmFkZHJlc3NfZW1wdHkSPHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBob3N0bmFtZSwgb3IgaXAgYWRkcmVzcxocIXJ1bGVzLmFkZHJlc3MgfHwgdGhpcyAhPSAnJ0gAEpgCCgR1dWlkGBYgASgIQocCwkiDAgqlAQoLc3RyaW5nLnV1aWQSGnZhbHVlIG11c3QgYmUgYSB2YWxpZCBVVUlEGnohcnVsZXMudXVpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSQnKQpZChFzdHJpbmcudXVpZF9lbXB0eRIpdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIFVVSUQaGSFydWxlcy51dWlkIHx8IHRoaXMgIT0gJydIABLwAQoFdHV1aWQYISABKAhC3gHCSNoBCnMKDHN0cmluZy50dXVpZBIidmFsdWUgbXVzdCBiZSBhIHZhbGlkIHRyaW1tZWQgVVVJRBo/IXJ1bGVzLnR1dWlkIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5tYXRjaGVzKCdeWzAtOWEtZkEtRl17MzJ9JCcpCmMKEnN0cmluZy50dXVpZF9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIHRyaW1tZWQgVVVJRBoaIXJ1bGVzLnR1dWlkIHx8IHRoaXMgIT0gJydIABKWAgoRaXBfd2l0aF9wcmVmaXhsZW4YGiABKAhC+AHCSPQBCngKGHN0cmluZy5pcF93aXRoX3ByZWZpeGxlbhIfdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQIHByZWZpeBo7IXJ1bGVzLmlwX3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KCkKeAoec3RyaW5nLmlwX3dpdGhfcHJlZml4bGVuX2VtcHR5Ei52YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgcHJlZml4GiYhcnVsZXMuaXBfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyAhPSAnJ0gAEs8CChNpcHY0X3dpdGhfcHJlZml4bGVuGBsgASgIQq8CwkirAgqTAQoac3RyaW5nLmlwdjRfd2l0aF9wcmVmaXhsZW4SNXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGj4hcnVsZXMuaXB2NF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg0KQqSAQogc3RyaW5nLmlwdjRfd2l0aF9wcmVmaXhsZW5fZW1wdHkSRHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGighcnVsZXMuaXB2NF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzICE9ICcnSAASzwIKE2lwdjZfd2l0aF9wcmVmaXhsZW4YHCABKAhCrwLCSKsCCpMBChpzdHJpbmcuaXB2Nl93aXRoX3ByZWZpeGxlbhI1dmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjYgYWRkcmVzcyB3aXRoIHByZWZpeCBsZW5ndGgaPiFydWxlcy5pcHY2X3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KDYpCpIBCiBzdHJpbmcuaXB2Nl93aXRoX3ByZWZpeGxlbl9lbXB0eRJEdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcyB3aXRoIHByZWZpeCBsZW5ndGgaKCFydWxlcy5pcHY2X3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgIT0gJydIABLyAQoJaXBfcHJlZml4GB0gASgIQtwBwkjYAQpsChBzdHJpbmcuaXBfcHJlZml4Eh92YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgcHJlZml4GjchcnVsZXMuaXBfcHJlZml4IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KHRydWUpCmgKFnN0cmluZy5pcF9wcmVmaXhfZW1wdHkSLnZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUCBwcmVmaXgaHiFydWxlcy5pcF9wcmVmaXggfHwgdGhpcyAhPSAnJ0gAEoMCCgtpcHY0X3ByZWZpeBgeIAEoCELrAcJI5wEKdQoSc3RyaW5nLmlwdjRfcHJlZml4EiF2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NCBwcmVmaXgaPCFydWxlcy5pcHY0X3ByZWZpeCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg0LCB0cnVlKQpuChhzdHJpbmcuaXB2NF9wcmVmaXhfZW1wdHkSMHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY0IHByZWZpeBogIXJ1bGVzLmlwdjRfcHJlZml4IHx8IHRoaXMgIT0gJydIABKDAgoLaXB2Nl9wcmVmaXgYHyABKAhC6wHCSOcBCnUKEnN0cmluZy5pcHY2X3ByZWZpeBIhdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjYgcHJlZml4GjwhcnVsZXMuaXB2Nl9wcmVmaXggfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNiwgdHJ1ZSkKbgoYc3RyaW5nLmlwdjZfcHJlZml4X2VtcHR5EjB2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NiBwcmVmaXgaICFydWxlcy5pcHY2X3ByZWZpeCB8fCB0aGlzICE9ICcnSAAStQIKDWhvc3RfYW5kX3BvcnQYICABKAhCmwLCSJcCCpkBChRzdHJpbmcuaG9zdF9hbmRfcG9ydBJBdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGhvc3QgKGhvc3RuYW1lIG9yIElQIGFkZHJlc3MpIGFuZCBwb3J0IHBhaXIaPiFydWxlcy5ob3N0X2FuZF9wb3J0IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0hvc3RBbmRQb3J0KHRydWUpCnkKGnN0cmluZy5ob3N0X2FuZF9wb3J0X2VtcHR5Ejd2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdCBhbmQgcG9ydCBwYWlyGiIhcnVsZXMuaG9zdF9hbmRfcG9ydCB8fCB0aGlzICE9ICcnSAASqAUKEHdlbGxfa25vd25fcmVnZXgYGCABKA4yGC5idWYudmFsaWRhdGUuS25vd25SZWdleELxBMJI7QQK8AEKI3N0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lEiZ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRqgAXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMSB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXjo/WzAtOWEtekEtWiEjJCUmXCcqKy0uXl98flx4NjBdKyQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSskJykKjQEKKXN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lX2VtcHR5EjV2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRopcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAxIHx8IHRoaXMgIT0gJycK5wEKJHN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl92YWx1ZRIndmFsdWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgaGVhZGVyIHZhbHVlGpUBcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAyIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXlteXHUwMDAwLVx1MDAwOFx1MDAwQS1cdTAwMUZcdTAwN0ZdKiQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSokJylIABIOCgZzdHJpY3QYGSABKAgSLAoHZXhhbXBsZRgiIAMoCUIbwkgYChYKDnN0cmluZy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLqEAoKQnl0ZXNSdWxlcxKAAQoFY29uc3QYASABKAxCccJIbgpsCgtieXRlcy5jb25zdBpddGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBiZSAleCcuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEngKA2xlbhgNIAEoBEJrwkhoCmYKCWJ5dGVzLmxlbhpZdWludCh0aGlzLnNpemUoKSkgIT0gcnVsZXMubGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLmxlbl0pIDogJycSkAEKB21pbl9sZW4YAiABKARCf8JIfAp6Cg1ieXRlcy5taW5fbGVuGml1aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2xlbl0pIDogJycSiAEKB21heF9sZW4YAyABKARCd8JIdApyCg1ieXRlcy5tYXhfbGVuGmF1aW50KHRoaXMuc2l6ZSgpKSA+IHJ1bGVzLm1heF9sZW4gPyAndmFsdWUgbXVzdCBiZSBhdCBtb3N0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1heF9sZW5dKSA6ICcnEpABCgdwYXR0ZXJuGAQgASgJQn/CSHwKegoNYnl0ZXMucGF0dGVybhppIXN0cmluZyh0aGlzKS5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIG11c3QgbWF0Y2ggcmVnZXggcGF0dGVybiBgJXNgJy5mb3JtYXQoW3J1bGVzLnBhdHRlcm5dKSA6ICcnEoEBCgZwcmVmaXgYBSABKAxCccJIbgpsCgxieXRlcy5wcmVmaXgaXCF0aGlzLnN0YXJ0c1dpdGgocnVsZXMucHJlZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHByZWZpeCAleCcuZm9ybWF0KFtydWxlcy5wcmVmaXhdKSA6ICcnEn8KBnN1ZmZpeBgGIAEoDEJvwkhsCmoKDGJ5dGVzLnN1ZmZpeBpaIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCAleCcuZm9ybWF0KFtydWxlcy5zdWZmaXhdKSA6ICcnEoMBCghjb250YWlucxgHIAEoDEJxwkhuCmwKDmJ5dGVzLmNvbnRhaW5zGlohdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiAleCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSpwEKAmluGAggAygMQpoBwkiWAQqTAQoIYnl0ZXMuaW4ahgFnZXRGaWVsZChydWxlcywgJ2luJykuc2l6ZSgpID4gMCAmJiAhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ2CgZub3RfaW4YCSADKAxCZsJIYwphCgxieXRlcy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLrAQoCaXAYCiABKAhC3AHCSNgBCnQKCGJ5dGVzLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxpGIXJ1bGVzLmlwIHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNCB8fCB0aGlzLnNpemUoKSA9PSAxNgpgCg5ieXRlcy5pcF9lbXB0eRIvdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIGFkZHJlc3MaHSFydWxlcy5pcCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5AEKBGlwdjQYCyABKAhC0wHCSM8BCmUKCmJ5dGVzLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaMyFydWxlcy5pcHY0IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNApmChBieXRlcy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGh8hcnVsZXMuaXB2NCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5QEKBGlwdjYYDCABKAhC1AHCSNABCmYKCmJ5dGVzLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaNCFydWxlcy5pcHY2IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gMTYKZgoQYnl0ZXMuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxofIXJ1bGVzLmlwdjYgfHwgdGhpcy5zaXplKCkgIT0gMEgAEisKB2V4YW1wbGUYDiADKAxCGsJIFwoVCg1ieXRlcy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLUAwoJRW51bVJ1bGVzEoIBCgVjb25zdBgBIAEoBUJzwkhwCm4KCmVudW0uY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxIUCgxkZWZpbmVkX29ubHkYAiABKAgSfgoCaW4YAyADKAVCcsJIbwptCgdlbnVtLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ1CgZub3RfaW4YBCADKAVCZcJIYgpgCgtlbnVtLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEioKB2V4YW1wbGUYBSADKAVCGcJIFgoUCgxlbnVtLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiL7AwoNUmVwZWF0ZWRSdWxlcxKeAQoJbWluX2l0ZW1zGAEgASgEQooBwkiGAQqDAQoScmVwZWF0ZWQubWluX2l0ZW1zGm11aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9pdGVtcyA/ICd2YWx1ZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3QgJWQgaXRlbShzKScuZm9ybWF0KFtydWxlcy5taW5faXRlbXNdKSA6ICcnEqIBCgltYXhfaXRlbXMYAiABKARCjgHCSIoBCocBChJyZXBlYXRlZC5tYXhfaXRlbXMacXVpbnQodGhpcy5zaXplKCkpID4gcnVsZXMubWF4X2l0ZW1zID8gJ3ZhbHVlIG11c3QgY29udGFpbiBubyBtb3JlIHRoYW4gJXMgaXRlbShzKScuZm9ybWF0KFtydWxlcy5tYXhfaXRlbXNdKSA6ICcnEnAKBnVuaXF1ZRgDIAEoCEJgwkhdClsKD3JlcGVhdGVkLnVuaXF1ZRIocmVwZWF0ZWQgdmFsdWUgbXVzdCBjb250YWluIHVuaXF1ZSBpdGVtcxoeIXJ1bGVzLnVuaXF1ZSB8fCB0aGlzLnVuaXF1ZSgpEicKBWl0ZW1zGAQgASgLMhguYnVmLnZhbGlkYXRlLkZpZWxkUnVsZXMqCQjoBxCAgICAAiKKAwoITWFwUnVsZXMSjwEKCW1pbl9wYWlycxgBIAEoBEJ8wkh5CncKDW1hcC5taW5fcGFpcnMaZnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX3BhaXJzID8gJ21hcCBtdXN0IGJlIGF0IGxlYXN0ICVkIGVudHJpZXMnLmZvcm1hdChbcnVsZXMubWluX3BhaXJzXSkgOiAnJxKOAQoJbWF4X3BhaXJzGAIgASgEQnvCSHgKdgoNbWFwLm1heF9wYWlycxpldWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfcGFpcnMgPyAnbWFwIG11c3QgYmUgYXQgbW9zdCAlZCBlbnRyaWVzJy5mb3JtYXQoW3J1bGVzLm1heF9wYWlyc10pIDogJycSJgoEa2V5cxgEIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzEigKBnZhbHVlcxgFIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzKgkI6AcQgICAgAIiJgoIQW55UnVsZXMSCgoCaW4YAiADKAkSDgoGbm90X2luGAMgAygJIpkXCg1EdXJhdGlvblJ1bGVzEqEBCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkJ3wkh0CnIKDmR1cmF0aW9uLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSqAEKAmx0GAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQn/CSHwKegoLZHVyYXRpb24ubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASugEKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkKPAcJIiwEKiAEKDGR1cmF0aW9uLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASwQcKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQpcHwkiTBwp9CgtkdXJhdGlvbi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDmR1cmF0aW9uLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYZHVyYXRpb24uZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD2R1cmF0aW9uLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGWR1cmF0aW9uLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEo0ICgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25C4gfCSN4HCosBCgxkdXJhdGlvbi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPZHVyYXRpb24uZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlkdXJhdGlvbi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQZHVyYXRpb24uZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoaZHVyYXRpb24uZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESnQEKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQnbCSHMKcQoLZHVyYXRpb24uaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEpQBCgZub3RfaW4YCCADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25CacJIZgpkCg9kdXJhdGlvbi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJJCgdleGFtcGxlGAkgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQh3CSBoKGAoQZHVyYXRpb24uZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4ikhgKDlRpbWVzdGFtcFJ1bGVzEqMBCgVjb25zdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCeMJIdQpzCg90aW1lc3RhbXAuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKrAQoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQoABwkh9CnsKDHRpbWVzdGFtcC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABK8AQoDbHRlGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKQAcJIjAEKiQEKDXRpbWVzdGFtcC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEmwKBmx0X25vdxgHIAEoCEJawkhXClUKEHRpbWVzdGFtcC5sdF9ub3caQShydWxlcy5sdF9ub3cgJiYgdGhpcyA+IG5vdykgPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gbm93JyA6ICcnSAASxwcKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKcB8JImAcKfgoMdGltZXN0YW1wLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq3AQoPdGltZXN0YW1wLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq/AQoZdGltZXN0YW1wLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCscBChB0aW1lc3RhbXAuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrPAQoadGltZXN0YW1wLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEpMICgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQucHwkjjBwqMAQoNdGltZXN0YW1wLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsYBChB0aW1lc3RhbXAuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs4BChp0aW1lc3RhbXAuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1gEKEXRpbWVzdGFtcC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt4BCht0aW1lc3RhbXAuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESbwoGZ3Rfbm93GAggASgIQl3CSFoKWAoQdGltZXN0YW1wLmd0X25vdxpEKHJ1bGVzLmd0X25vdyAmJiB0aGlzIDwgbm93KSA/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBub3cnIDogJydIARK4AQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQowBwkiIAQqFAQoQdGltZXN0YW1wLndpdGhpbhpxdGhpcyA8IG5vdy1ydWxlcy53aXRoaW4gfHwgdGhpcyA+IG5vdytydWxlcy53aXRoaW4gPyAndmFsdWUgbXVzdCBiZSB3aXRoaW4gJXMgb2Ygbm93Jy5mb3JtYXQoW3J1bGVzLndpdGhpbl0pIDogJycSSwoHZXhhbXBsZRgKIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCHsJIGwoZChF0aW1lc3RhbXAuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iOQoKVmlvbGF0aW9ucxIrCgp2aW9sYXRpb25zGAEgAygLMhcuYnVmLnZhbGlkYXRlLlZpb2xhdGlvbiKfAQoJVmlvbGF0aW9uEiYKBWZpZWxkGAUgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIlCgRydWxlGAYgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIPCgdydWxlX2lkGAIgASgJEg8KB21lc3NhZ2UYAyABKAkSDwoHZm9yX2tleRgEIAEoCEoECAEQAlIKZmllbGRfcGF0aCI9CglGaWVsZFBhdGgSMAoIZWxlbWVudHMYASADKAsyHi5idWYudmFsaWRhdGUuRmllbGRQYXRoRWxlbWVudCLpAgoQRmllbGRQYXRoRWxlbWVudBIUCgxmaWVsZF9udW1iZXIYASABKAUSEgoKZmllbGRfbmFtZRgCIAEoCRI+CgpmaWVsZF90eXBlGAMgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSPAoIa2V5X3R5cGUYBCABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRI+Cgp2YWx1ZV90eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSDwoFaW5kZXgYBiABKARIABISCghib29sX2tleRgHIAEoCEgAEhEKB2ludF9rZXkYCCABKANIABISCgh1aW50X2tleRgJIAEoBEgAEhQKCnN0cmluZ19rZXkYCiABKAlIAEILCglzdWJzY3JpcHQqhwEKBklnbm9yZRIWChJJR05PUkVfVU5TUEVDSUZJRUQQABIZChVJR05PUkVfSUZfVU5QT1BVTEFURUQQARIbChdJR05PUkVfSUZfREVGQVVMVF9WQUxVRRACEhEKDUlHTk9SRV9BTFdBWVMQAyoaSUdOT1JFX0VNUFRZSUdOT1JFX0RFRkFVTFQqbgoKS25vd25SZWdleBIbChdLTk9XTl9SRUdFWF9VTlNQRUNJRklFRBAAEiAKHEtOT1dOX1JFR0VYX0hUVFBfSEVBREVSX05BTUUQARIhCh1LTk9XTl9SRUdFWF9IVFRQX0hFQURFUl9WQUxVRRACOlYKB21lc3NhZ2USHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhwkgASgLMhouYnVmLnZhbGlkYXRlLk1lc3NhZ2VSdWxlc1IHbWVzc2FnZTpOCgVvbmVvZhIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMYhwkgASgLMhguYnVmLnZhbGlkYXRlLk9uZW9mUnVsZXNSBW9uZW9mOk4KBWZpZWxkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiHCSABKAsyGC5idWYudmFsaWRhdGUuRmllbGRSdWxlc1IFZmllbGQ6XQoKcHJlZGVmaW5lZBIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMYiAkgASgLMh0uYnVmLnZhbGlkYXRlLlByZWRlZmluZWRSdWxlc1IKcHJlZGVmaW5lZEJuChJidWlsZC5idWYudmFsaWRhdGVCDVZhbGlkYXRlUHJvdG9QAVpHYnVmLmJ1aWxkL2dlbi9nby9idWZidWlsZC9wcm90b3ZhbGlkYXRlL3Byb3RvY29sYnVmZmVycy9nby9idWYvdmFsaWRhdGU", [file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_timestamp]);
/**
- * `Constraint` represents a validation rule written in the Common Expression
- * Language (CEL) syntax. Each Constraint includes a unique identifier, an
+ * `Rule` represents a validation rule written in the Common Expression
+ * Language (CEL) syntax. Each Rule includes a unique identifier, an
* optional error message, and the CEL expression to evaluate. For more
* information on CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
*
@@ -45,11 +45,11 @@ export const file_buf_validate_validate: GenFile = /*@__PURE__*/
* }
* ```
*
- * @generated from message buf.validate.Constraint
+ * @generated from message buf.validate.Rule
*/
-export type Constraint = Message<"buf.validate.Constraint"> & {
+export type Rule = Message<"buf.validate.Rule"> & {
/**
- * `id` is a string that serves as a machine-readable name for this Constraint.
+ * `id` is a string that serves as a machine-readable name for this Rule.
* It should be unique within its scope, which could be either a message or a field.
*
* @generated from field: optional string id = 1;
@@ -58,7 +58,7 @@ export type Constraint = Message<"buf.validate.Constraint"> & {
/**
* `message` is an optional field that provides a human-readable error message
- * for this Constraint when the CEL expression evaluates to false. If a
+ * for this Rule when the CEL expression evaluates to false. If a
* non-empty message is provided, any strings resulting from the CEL
* expression evaluation are ignored.
*
@@ -78,19 +78,19 @@ export type Constraint = Message<"buf.validate.Constraint"> & {
};
/**
- * Describes the message buf.validate.Constraint.
- * Use `create(ConstraintSchema)` to create a new message.
+ * Describes the message buf.validate.Rule.
+ * Use `create(RuleSchema)` to create a new message.
*/
-export const ConstraintSchema: GenMessage = /*@__PURE__*/
+export const RuleSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 0);
/**
- * MessageConstraints represents validation rules that are applied to the entire message.
- * It includes disabling options and a list of Constraint messages representing Common Expression Language (CEL) validation rules.
+ * MessageRules represents validation rules that are applied to the entire message.
+ * It includes disabling options and a list of Rule messages representing Common Expression Language (CEL) validation rules.
*
- * @generated from message buf.validate.MessageConstraints
+ * @generated from message buf.validate.MessageRules
*/
-export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
+export type MessageRules = Message<"buf.validate.MessageRules"> & {
/**
* `disabled` is a boolean flag that, when set to true, nullifies any validation rules for this message.
* This includes any fields within the message that would otherwise support validation.
@@ -107,8 +107,8 @@ export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
disabled: boolean;
/**
- * `cel` is a repeated field of type Constraint. Each Constraint specifies a validation rule to be applied to this message.
- * These constraints are written in Common Expression Language (CEL) syntax. For more information on
+ * `cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message.
+ * These rules are written in Common Expression Language (CEL) syntax. For more information on
* CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
*
*
@@ -124,29 +124,29 @@ export type MessageConstraints = Message<"buf.validate.MessageConstraints"> & {
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 3;
+ * @generated from field: repeated buf.validate.Rule cel = 3;
*/
- cel: Constraint[];
+ cel: Rule[];
};
/**
- * Describes the message buf.validate.MessageConstraints.
- * Use `create(MessageConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.MessageRules.
+ * Use `create(MessageRulesSchema)` to create a new message.
*/
-export const MessageConstraintsSchema: GenMessage = /*@__PURE__*/
+export const MessageRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 1);
/**
- * The `OneofConstraints` message type enables you to manage constraints for
+ * The `OneofRules` message type enables you to manage rules for
* oneof fields in your protobuf messages.
*
- * @generated from message buf.validate.OneofConstraints
+ * @generated from message buf.validate.OneofRules
*/
-export type OneofConstraints = Message<"buf.validate.OneofConstraints"> & {
+export type OneofRules = Message<"buf.validate.OneofRules"> & {
/**
* If `required` is true, exactly one field of the oneof must be present. A
* validation error is returned if no fields in the oneof are present. The
- * field itself may still be a default value; further constraints
+ * field itself may still be a default value; further rules
* should be placed on the fields themselves to ensure they are valid values,
* such as `min_len` or `gt`.
*
@@ -168,19 +168,19 @@ export type OneofConstraints = Message<"buf.validate.OneofConstraints"> & {
};
/**
- * Describes the message buf.validate.OneofConstraints.
- * Use `create(OneofConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.OneofRules.
+ * Use `create(OneofRulesSchema)` to create a new message.
*/
-export const OneofConstraintsSchema: GenMessage = /*@__PURE__*/
+export const OneofRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 2);
/**
- * FieldConstraints encapsulates the rules for each type of field. Depending on
+ * FieldRules encapsulates the rules for each type of field. Depending on
* the field, the correct set should be used to ensure proper validations.
*
- * @generated from message buf.validate.FieldConstraints
+ * @generated from message buf.validate.FieldRules
*/
-export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
+export type FieldRules = Message<"buf.validate.FieldRules"> & {
/**
* `cel` is a repeated field used to represent a textual expression
* in the Common Expression Language (CEL) syntax. For more information on
@@ -197,9 +197,9 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 23;
+ * @generated from field: repeated buf.validate.Rule cel = 23;
*/
- cel: Constraint[];
+ cel: Rule[];
/**
* If `required` is true, the field must be populated. A populated field can be
@@ -244,7 +244,7 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
ignore: Ignore;
/**
- * @generated from oneof buf.validate.FieldConstraints.type
+ * @generated from oneof buf.validate.FieldRules.type
*/
type: {
/**
@@ -382,19 +382,19 @@ export type FieldConstraints = Message<"buf.validate.FieldConstraints"> & {
};
/**
- * Describes the message buf.validate.FieldConstraints.
- * Use `create(FieldConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.FieldRules.
+ * Use `create(FieldRulesSchema)` to create a new message.
*/
-export const FieldConstraintsSchema: GenMessage = /*@__PURE__*/
+export const FieldRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 3);
/**
- * PredefinedConstraints are custom constraints that can be re-used with
+ * PredefinedRules are custom rules that can be re-used with
* multiple fields.
*
- * @generated from message buf.validate.PredefinedConstraints
+ * @generated from message buf.validate.PredefinedRules
*/
-export type PredefinedConstraints = Message<"buf.validate.PredefinedConstraints"> & {
+export type PredefinedRules = Message<"buf.validate.PredefinedRules"> & {
/**
* `cel` is a repeated field used to represent a textual expression
* in the Common Expression Language (CEL) syntax. For more information on
@@ -411,20 +411,20 @@ export type PredefinedConstraints = Message<"buf.validate.PredefinedConstraints"
* }
* ```
*
- * @generated from field: repeated buf.validate.Constraint cel = 1;
+ * @generated from field: repeated buf.validate.Rule cel = 1;
*/
- cel: Constraint[];
+ cel: Rule[];
};
/**
- * Describes the message buf.validate.PredefinedConstraints.
- * Use `create(PredefinedConstraintsSchema)` to create a new message.
+ * Describes the message buf.validate.PredefinedRules.
+ * Use `create(PredefinedRulesSchema)` to create a new message.
*/
-export const PredefinedConstraintsSchema: GenMessage = /*@__PURE__*/
+export const PredefinedRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 4);
/**
- * FloatRules describes the constraints applied to `float` values. These
+ * FloatRules describes the rules applied to `float` values. These
* rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type.
*
* @generated from message buf.validate.FloatRules
@@ -581,7 +581,7 @@ export type FloatRules = Message<"buf.validate.FloatRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -606,7 +606,7 @@ export const FloatRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 5);
/**
- * DoubleRules describes the constraints applied to `double` values. These
+ * DoubleRules describes the rules applied to `double` values. These
* rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type.
*
* @generated from message buf.validate.DoubleRules
@@ -763,7 +763,7 @@ export type DoubleRules = Message<"buf.validate.DoubleRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -788,7 +788,7 @@ export const DoubleRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 6);
/**
- * Int32Rules describes the constraints applied to `int32` values. These
+ * Int32Rules describes the rules applied to `int32` values. These
* rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type.
*
* @generated from message buf.validate.Int32Rules
@@ -937,7 +937,7 @@ export type Int32Rules = Message<"buf.validate.Int32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -962,7 +962,7 @@ export const Int32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 7);
/**
- * Int64Rules describes the constraints applied to `int64` values. These
+ * Int64Rules describes the rules applied to `int64` values. These
* rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type.
*
* @generated from message buf.validate.Int64Rules
@@ -1111,7 +1111,7 @@ export type Int64Rules = Message<"buf.validate.Int64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1136,7 +1136,7 @@ export const Int64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 8);
/**
- * UInt32Rules describes the constraints applied to `uint32` values. These
+ * UInt32Rules describes the rules applied to `uint32` values. These
* rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type.
*
* @generated from message buf.validate.UInt32Rules
@@ -1285,7 +1285,7 @@ export type UInt32Rules = Message<"buf.validate.UInt32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1310,7 +1310,7 @@ export const UInt32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 9);
/**
- * UInt64Rules describes the constraints applied to `uint64` values. These
+ * UInt64Rules describes the rules applied to `uint64` values. These
* rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type.
*
* @generated from message buf.validate.UInt64Rules
@@ -1459,7 +1459,7 @@ export type UInt64Rules = Message<"buf.validate.UInt64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1484,7 +1484,7 @@ export const UInt64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 10);
/**
- * SInt32Rules describes the constraints applied to `sint32` values.
+ * SInt32Rules describes the rules applied to `sint32` values.
*
* @generated from message buf.validate.SInt32Rules
*/
@@ -1632,7 +1632,7 @@ export type SInt32Rules = Message<"buf.validate.SInt32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1657,7 +1657,7 @@ export const SInt32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 11);
/**
- * SInt64Rules describes the constraints applied to `sint64` values.
+ * SInt64Rules describes the rules applied to `sint64` values.
*
* @generated from message buf.validate.SInt64Rules
*/
@@ -1805,7 +1805,7 @@ export type SInt64Rules = Message<"buf.validate.SInt64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -1830,7 +1830,7 @@ export const SInt64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 12);
/**
- * Fixed32Rules describes the constraints applied to `fixed32` values.
+ * Fixed32Rules describes the rules applied to `fixed32` values.
*
* @generated from message buf.validate.Fixed32Rules
*/
@@ -1978,7 +1978,7 @@ export type Fixed32Rules = Message<"buf.validate.Fixed32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2003,7 +2003,7 @@ export const Fixed32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 13);
/**
- * Fixed64Rules describes the constraints applied to `fixed64` values.
+ * Fixed64Rules describes the rules applied to `fixed64` values.
*
* @generated from message buf.validate.Fixed64Rules
*/
@@ -2151,7 +2151,7 @@ export type Fixed64Rules = Message<"buf.validate.Fixed64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2176,7 +2176,7 @@ export const Fixed64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 14);
/**
- * SFixed32Rules describes the constraints applied to `fixed32` values.
+ * SFixed32Rules describes the rules applied to `fixed32` values.
*
* @generated from message buf.validate.SFixed32Rules
*/
@@ -2324,7 +2324,7 @@ export type SFixed32Rules = Message<"buf.validate.SFixed32Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2349,7 +2349,7 @@ export const SFixed32RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 15);
/**
- * SFixed64Rules describes the constraints applied to `fixed64` values.
+ * SFixed64Rules describes the rules applied to `fixed64` values.
*
* @generated from message buf.validate.SFixed64Rules
*/
@@ -2497,7 +2497,7 @@ export type SFixed64Rules = Message<"buf.validate.SFixed64Rules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2522,7 +2522,7 @@ export const SFixed64RulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 16);
/**
- * BoolRules describes the constraints applied to `bool` values. These rules
+ * BoolRules describes the rules applied to `bool` values. These rules
* may also be applied to the `google.protobuf.BoolValue` Well-Known-Type.
*
* @generated from message buf.validate.BoolRules
@@ -2545,7 +2545,7 @@ export type BoolRules = Message<"buf.validate.BoolRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -2570,7 +2570,7 @@ export const BoolRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 17);
/**
- * StringRules describes the constraints applied to `string` values These
+ * StringRules describes the rules applied to `string` values These
* rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type.
*
* @generated from message buf.validate.StringRules
@@ -2805,15 +2805,21 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
notIn: string[];
/**
- * `WellKnown` rules provide advanced constraints against common string
- * patterns
+ * `WellKnown` rules provide advanced rules against common string
+ * patterns.
*
* @generated from oneof buf.validate.StringRules.well_known
*/
wellKnown: {
/**
- * `email` specifies that the field value must be a valid email address
- * (addr-spec only) as defined by [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1).
+ * `email` specifies that the field value must be a valid email address, for
+ * example "foo@example.com".
+ *
+ * Conforms to the definition for a valid email address from the [HTML standard](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
+ * Note that this standard willfully deviates from [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322),
+ * which allows many unexpected forms of email addresses and will easily match
+ * a typographical error.
+ *
* If the field value isn't a valid email address, an error message will be generated.
*
* ```proto
@@ -2829,10 +2835,18 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "email";
} | {
/**
- * `hostname` specifies that the field value must be a valid
- * hostname as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5). This constraint doesn't support
- * internationalized domain names (IDNs). If the field value isn't a
- * valid hostname, an error message will be generated.
+ * `hostname` specifies that the field value must be a valid hostname, for
+ * example "foo.example.com".
+ *
+ * A valid hostname follows the rules below:
+ * - The name consists of one or more labels, separated by a dot (".").
+ * - Each label can be 1 to 63 alphanumeric characters.
+ * - A label can contain hyphens ("-"), but must not start or end with a hyphen.
+ * - The right-most label must not be digits only.
+ * - The name can have a trailing dot—for example, "foo.example.com.".
+ * - The name can be 253 characters at most, excluding the optional trailing dot.
+ *
+ * If the field value isn't a valid hostname, an error message will be generated.
*
* ```proto
* message MyString {
@@ -2847,8 +2861,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "hostname";
} | {
/**
- * `ip` specifies that the field value must be a valid IP
- * (v4 or v6) address, without surrounding square brackets for IPv6 addresses.
+ * `ip` specifies that the field value must be a valid IP (v4 or v6) address.
+ *
+ * IPv4 addresses are expected in the dotted decimal format—for example, "192.168.5.21".
+ * IPv6 addresses are expected in their text representation—for example, "::1",
+ * or "2001:0DB8:ABCD:0012::0".
+ *
+ * Both formats are well-defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ * Zone identifiers for IPv6 addresses (for example, "fe80::a%en1") are supported.
+ *
* If the field value isn't a valid IP address, an error message will be
* generated.
*
@@ -2865,9 +2886,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ip";
} | {
/**
- * `ipv4` specifies that the field value must be a valid IPv4
- * address. If the field value isn't a valid IPv4 address, an error message
- * will be generated.
+ * `ipv4` specifies that the field value must be a valid IPv4 address—for
+ * example "192.168.5.21". If the field value isn't a valid IPv4 address, an
+ * error message will be generated.
*
* ```proto
* message MyString {
@@ -2882,9 +2903,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv4";
} | {
/**
- * `ipv6` specifies that the field value must be a valid
- * IPv6 address, without surrounding square brackets. If the field value is
- * not a valid IPv6 address, an error message will be generated.
+ * `ipv6` specifies that the field value must be a valid IPv6 address—for
+ * example "::1", or "d7a:115c:a1e0:ab12:4843:cd96:626b:430b". If the field
+ * value is not a valid IPv6 address, an error message will be generated.
*
* ```proto
* message MyString {
@@ -2899,8 +2920,11 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6";
} | {
/**
- * `uri` specifies that the field value must be a valid URI as defined by
- * [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
+ * `uri` specifies that the field value must be a valid URI, for example
+ * "https://example.com/foo/bar?baz=quux#frag".
+ *
+ * URI is defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ * Zone Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
*
* If the field value isn't a valid URI, an error message will be generated.
*
@@ -2917,11 +2941,13 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "uri";
} | {
/**
- * `uri_ref` specifies that the field value must be a valid URI Reference as
- * defined by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-4.1).
+ * `uri_ref` specifies that the field value must be a valid URI Reference—either
+ * a URI such as "https://example.com/foo/bar?baz=quux#frag", or a Relative
+ * Reference such as "./foo/bar?query".
*
- * A URI Reference is either a [URI](https://datatracker.ietf.org/doc/html/rfc3986#section-3),
- * or a [Relative Reference](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2).
+ * URI, URI Reference, and Relative Reference are defined in the internet
+ * standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). Zone
+ * Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
*
* If the field value isn't a valid URI Reference, an error message will be
* generated.
@@ -2940,10 +2966,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `address` specifies that the field value must be either a valid hostname
- * as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5)
- * (which doesn't support internationalized domain names or IDNs) or a valid
- * IP (v4 or v6). If the field value isn't a valid hostname or IP, an error
- * message will be generated.
+ * (for example, "example.com"), or a valid IP (v4 or v6) address (for example,
+ * "192.168.0.1", or "::1"). If the field value isn't a valid hostname or IP,
+ * an error message will be generated.
*
* ```proto
* message MyString {
@@ -2993,10 +3018,10 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "tuuid";
} | {
/**
- * `ip_with_prefixlen` specifies that the field value must be a valid IP (v4 or v6)
- * address with prefix length. If the field value isn't a valid IP with prefix
- * length, an error message will be generated.
- *
+ * `ip_with_prefixlen` specifies that the field value must be a valid IP
+ * (v4 or v6) address with prefix length—for example, "192.168.5.21/16" or
+ * "2001:0DB8:ABCD:0012::F1/64". If the field value isn't a valid IP with
+ * prefix length, an error message will be generated.
*
* ```proto
* message MyString {
@@ -3012,9 +3037,9 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv4_with_prefixlen` specifies that the field value must be a valid
- * IPv4 address with prefix.
- * If the field value isn't a valid IPv4 address with prefix length,
- * an error message will be generated.
+ * IPv4 address with prefix length—for example, "192.168.5.21/16". If the
+ * field value isn't a valid IPv4 address with prefix length, an error
+ * message will be generated.
*
* ```proto
* message MyString {
@@ -3030,7 +3055,7 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv6_with_prefixlen` specifies that the field value must be a valid
- * IPv6 address with prefix length.
+ * IPv6 address with prefix length—for example, "2001:0DB8:ABCD:0012::F1/64".
* If the field value is not a valid IPv6 address with prefix length,
* an error message will be generated.
*
@@ -3047,10 +3072,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6WithPrefixlen";
} | {
/**
- * `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) prefix.
+ * `ip_prefix` specifies that the field value must be a valid IP (v4 or v6)
+ * prefix—for example, "192.168.0.0/16" or "2001:0DB8:ABCD:0012::0/64".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ * prefix, and the remaining 64 bits must be zero.
+ *
* If the field value isn't a valid IP prefix, an error message will be
- * generated. The prefix must have all zeros for the masked bits of the prefix (e.g.,
- * `127.0.0.0/16`, not `127.0.0.1/16`).
+ * generated.
*
* ```proto
* message MyString {
@@ -3066,9 +3096,14 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
} | {
/**
* `ipv4_prefix` specifies that the field value must be a valid IPv4
- * prefix. If the field value isn't a valid IPv4 prefix, an error message
- * will be generated. The prefix must have all zeros for the masked bits of
- * the prefix (e.g., `127.0.0.0/16`, not `127.0.0.1/16`).
+ * prefix, for example "192.168.0.0/16".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "192.168.0.0/16" designates the left-most 16 bits for the prefix,
+ * and the remaining 16 bits must be zero.
+ *
+ * If the field value isn't a valid IPv4 prefix, an error message
+ * will be generated.
*
* ```proto
* message MyString {
@@ -3083,10 +3118,15 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv4Prefix";
} | {
/**
- * `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix.
+ * `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix—for
+ * example, "2001:0DB8:ABCD:0012::0/64".
+ *
+ * The prefix must have all zeros for the unmasked bits. For example,
+ * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ * prefix, and the remaining 64 bits must be zero.
+ *
* If the field value is not a valid IPv6 prefix, an error message will be
- * generated. The prefix must have all zeros for the masked bits of the prefix
- * (e.g., `2001:db8::/48`, not `2001:db8::1/48`).
+ * generated.
*
* ```proto
* message MyString {
@@ -3101,10 +3141,16 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
case: "ipv6Prefix";
} | {
/**
- * `host_and_port` specifies the field value must be a valid host and port
- * pair. The host must be a valid hostname or IP address while the port
- * must be in the range of 0-65535, inclusive. IPv6 addresses must be delimited
- * with square brackets (e.g., `[::1]:1234`).
+ * `host_and_port` specifies that the field value must be valid host/port
+ * pair—for example, "example.com:8080".
+ *
+ * The host can be one of:
+ * - An IPv4 address in dotted decimal format—for example, "192.168.5.21".
+ * - An IPv6 address enclosed in square brackets—for example, "[2001:0DB8:ABCD:0012::F1]".
+ * - A hostname—for example, "example.com".
+ *
+ * The port is separated by a colon. It must be non-empty, with a decimal number
+ * in the range of 0-65535, inclusive.
*
* @generated from field: bool host_and_port = 32;
*/
@@ -3159,7 +3205,7 @@ export type StringRules = Message<"buf.validate.StringRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3184,7 +3230,7 @@ export const StringRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 18);
/**
- * BytesRules describe the constraints applied to `bytes` values. These rules
+ * BytesRules describe the rules applied to `bytes` values. These rules
* may also be applied to the `google.protobuf.BytesValue` Well-Known-Type.
*
* @generated from message buf.validate.BytesRules
@@ -3352,7 +3398,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
notIn: Uint8Array[];
/**
- * WellKnown rules provide advanced constraints against common byte
+ * WellKnown rules provide advanced rules against common byte
* patterns
*
* @generated from oneof buf.validate.BytesRules.well_known
@@ -3360,7 +3406,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
wellKnown: {
/**
* `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
*
* ```proto
* message MyBytes {
@@ -3376,7 +3422,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
} | {
/**
* `ipv4` ensures that the field `value` is a valid IPv4 address in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
*
* ```proto
* message MyBytes {
@@ -3392,7 +3438,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
} | {
/**
* `ipv6` ensures that the field `value` is a valid IPv6 address in byte format.
- * If the field value doesn't meet this constraint, an error message is generated.
+ * If the field value doesn't meet this rule, an error message is generated.
* ```proto
* message MyBytes {
* // value must be a valid IPv6 address
@@ -3408,7 +3454,7 @@ export type BytesRules = Message<"buf.validate.BytesRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3433,7 +3479,7 @@ export const BytesRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 19);
/**
- * EnumRules describe the constraints applied to `enum` values.
+ * EnumRules describe the rules applied to `enum` values.
*
* @generated from message buf.validate.EnumRules
*/
@@ -3526,7 +3572,7 @@ export type EnumRules = Message<"buf.validate.EnumRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3555,7 +3601,7 @@ export const EnumRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 20);
/**
- * RepeatedRules describe the constraints applied to `repeated` values.
+ * RepeatedRules describe the rules applied to `repeated` values.
*
* @generated from message buf.validate.RepeatedRules
*/
@@ -3596,7 +3642,7 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
/**
* `unique` indicates that all elements in this field must
- * be unique. This constraint is strictly applicable to scalar and enum
+ * be unique. This rule is strictly applicable to scalar and enum
* types, with message types not being supported.
*
* ```proto
@@ -3611,13 +3657,13 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
unique: boolean;
/**
- * `items` details the constraints to be applied to each item
+ * `items` details the rules to be applied to each item
* in the field. Even for repeated message fields, validation is executed
* against each item unless skip is explicitly specified.
*
* ```proto
* message MyRepeated {
- * // The items in the field `value` must follow the specified constraints.
+ * // The items in the field `value` must follow the specified rules.
* repeated string value = 1 [(buf.validate.field).repeated.items = {
* string: {
* min_len: 3
@@ -3627,9 +3673,9 @@ export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints items = 4;
+ * @generated from field: optional buf.validate.FieldRules items = 4;
*/
- items?: FieldConstraints;
+ items?: FieldRules;
};
/**
@@ -3640,7 +3686,7 @@ export const RepeatedRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 21);
/**
- * MapRules describe the constraints applied to `map` values.
+ * MapRules describe the rules applied to `map` values.
*
* @generated from message buf.validate.MapRules
*/
@@ -3676,11 +3722,11 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
maxPairs: bigint;
/**
- * Specifies the constraints to be applied to each key in the field.
+ * Specifies the rules to be applied to each key in the field.
*
* ```proto
* message MyMap {
- * // The keys in the field `value` must follow the specified constraints.
+ * // The keys in the field `value` must follow the specified rules.
* map value = 1 [(buf.validate.field).map.keys = {
* string: {
* min_len: 3
@@ -3690,18 +3736,18 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints keys = 4;
+ * @generated from field: optional buf.validate.FieldRules keys = 4;
*/
- keys?: FieldConstraints;
+ keys?: FieldRules;
/**
- * Specifies the constraints to be applied to the value of each key in the
+ * Specifies the rules to be applied to the value of each key in the
* field. Message values will still have their validations evaluated unless
* skip is specified here.
*
* ```proto
* message MyMap {
- * // The values in the field `value` must follow the specified constraints.
+ * // The values in the field `value` must follow the specified rules.
* map value = 1 [(buf.validate.field).map.values = {
* string: {
* min_len: 5
@@ -3711,9 +3757,9 @@ export type MapRules = Message<"buf.validate.MapRules"> & {
* }
* ```
*
- * @generated from field: optional buf.validate.FieldConstraints values = 5;
+ * @generated from field: optional buf.validate.FieldRules values = 5;
*/
- values?: FieldConstraints;
+ values?: FieldRules;
};
/**
@@ -3724,7 +3770,7 @@ export const MapRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 22);
/**
- * AnyRules describe constraints applied exclusively to the `google.protobuf.Any` well-known type.
+ * AnyRules describe rules applied exclusively to the `google.protobuf.Any` well-known type.
*
* @generated from message buf.validate.AnyRules
*/
@@ -3768,7 +3814,7 @@ export const AnyRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 23);
/**
- * DurationRules describe the constraints applied exclusively to the `google.protobuf.Duration` well-known type.
+ * DurationRules describe the rules applied exclusively to the `google.protobuf.Duration` well-known type.
*
* @generated from message buf.validate.DurationRules
*/
@@ -3918,7 +3964,7 @@ export type DurationRules = Message<"buf.validate.DurationRules"> & {
/**
* `example` specifies values that the field may have. These values SHOULD
- * conform to other constraints. `example` values will not impact validation
+ * conform to other rules. `example` values will not impact validation
* but may be used as helpful guidance on how to populate the given field.
*
* ```proto
@@ -3943,7 +3989,7 @@ export const DurationRulesSchema: GenMessage = /*@__PURE__*/
messageDesc(file_buf_validate_validate, 24);
/**
- * TimestampRules describe the constraints applied exclusively to the `google.protobuf.Timestamp` well-known type.
+ * TimestampRules describe the rules applied exclusively to the `google.protobuf.Timestamp` well-known type.
*
* @generated from message buf.validate.TimestampRules
*/
@@ -4111,7 +4157,7 @@ export const TimestampRulesSchema: GenMessage = /*@__PURE__*/
/**
* `Violations` is a collection of `Violation` messages. This message type is returned by
- * protovalidate when a proto message fails to meet the requirements set by the `Constraint` validation rules.
+ * protovalidate when a proto message fails to meet the requirements set by the `Rule` validation rules.
* Each individual violation is represented by a `Violation` message.
*
* @generated from message buf.validate.Violations
@@ -4134,14 +4180,14 @@ export const ViolationsSchema: GenMessage = /*@__PURE__*/
/**
* `Violation` represents a single instance where a validation rule, expressed
- * as a `Constraint`, was not met. It provides information about the field that
- * caused the violation, the specific constraint that wasn't fulfilled, and a
+ * as a `Rule`, was not met. It provides information about the field that
+ * caused the violation, the specific rule that wasn't fulfilled, and a
* human-readable error message.
*
* ```json
* {
* "fieldPath": "bar",
- * "constraintId": "foo.bar",
+ * "ruleId": "foo.bar",
* "message": "bar must be greater than 0"
* }
* ```
@@ -4175,9 +4221,9 @@ export type Violation = Message<"buf.validate.Violation"> & {
field?: FieldPath;
/**
- * `rule` is a machine-readable path that points to the specific constraint rule that failed validation.
- * This will be a nested field starting from the FieldConstraints of the field that failed validation.
- * For custom constraints, this will provide the path of the constraint, e.g. `cel[0]`.
+ * `rule` is a machine-readable path that points to the specific rule rule that failed validation.
+ * This will be a nested field starting from the FieldRules of the field that failed validation.
+ * For custom rules, this will provide the path of the rule, e.g. `cel[0]`.
*
* For example, consider the following message:
*
@@ -4185,7 +4231,7 @@ export type Violation = Message<"buf.validate.Violation"> & {
* message Message {
* bool a = 1 [(buf.validate.field).required = true];
* bool b = 2 [(buf.validate.field).cel = {
- * id: "custom_constraint",
+ * id: "custom_rule",
* expression: "!this ? 'b must be true': ''"
* }]
* }
@@ -4209,16 +4255,16 @@ export type Violation = Message<"buf.validate.Violation"> & {
rule?: FieldPath;
/**
- * `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled.
- * This is the same `id` that was specified in the `Constraint` message, allowing easy tracing of which rule was violated.
+ * `rule_id` is the unique identifier of the `Rule` that was not fulfilled.
+ * This is the same `id` that was specified in the `Rule` message, allowing easy tracing of which rule was violated.
*
- * @generated from field: optional string constraint_id = 2;
+ * @generated from field: optional string rule_id = 2;
*/
- constraintId: string;
+ ruleId: string;
/**
* `message` is a human-readable error message that describes the nature of the violation.
- * This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation.
+ * This can be the default error message from the violated `Rule`, or it can be a custom message that gives more context about the violation.
*
* @generated from field: optional string message = 3;
*/
@@ -4377,8 +4423,8 @@ export const FieldPathElementSchema: GenMessage = /*@__PURE__*
messageDesc(file_buf_validate_validate, 29);
/**
- * Specifies how FieldConstraints.ignore behaves. See the documentation for
- * FieldConstraints.required for definitions of "populated" and "nullable".
+ * Specifies how FieldRules.ignore behaves. See the documentation for
+ * FieldRules.required for definitions of "populated" and "nullable".
*
* @generated from enum buf.validate.Ignore
*/
@@ -4526,7 +4572,7 @@ export enum Ignore {
* The validation rules of this field will be skipped and not evaluated. This
* is useful for situations that necessitate turning off the rules of a field
* containing a message that may not make sense in the current context, or to
- * temporarily disable constraints during development.
+ * temporarily disable rules during development.
*
* ```proto
* message MyMessage {
@@ -4584,31 +4630,31 @@ export const KnownRegexSchema: GenEnum = /*@__PURE__*/
* Rules specify the validations to be performed on this message. By default,
* no validation is performed against a message.
*
- * @generated from extension: optional buf.validate.MessageConstraints message = 1159;
+ * @generated from extension: optional buf.validate.MessageRules message = 1159;
*/
-export const message: GenExtension = /*@__PURE__*/
+export const message: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 0);
/**
* Rules specify the validations to be performed on this oneof. By default,
* no validation is performed against a oneof.
*
- * @generated from extension: optional buf.validate.OneofConstraints oneof = 1159;
+ * @generated from extension: optional buf.validate.OneofRules oneof = 1159;
*/
-export const oneof: GenExtension = /*@__PURE__*/
+export const oneof: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 1);
/**
* Rules specify the validations to be performed on this field. By default,
* no validation is performed against a field.
*
- * @generated from extension: optional buf.validate.FieldConstraints field = 1159;
+ * @generated from extension: optional buf.validate.FieldRules field = 1159;
*/
-export const field: GenExtension = /*@__PURE__*/
+export const field: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 2);
/**
- * Specifies predefined rules. When extending a standard constraint message,
+ * Specifies predefined rules. When extending a standard rule message,
* this adds additional CEL expressions that apply when the extension is used.
*
* ```proto
@@ -4625,8 +4671,8 @@ export const field: GenExtension = /*@__PURE__*/
* }
* ```
*
- * @generated from extension: optional buf.validate.PredefinedConstraints predefined = 1160;
+ * @generated from extension: optional buf.validate.PredefinedRules predefined = 1160;
*/
-export const predefined: GenExtension = /*@__PURE__*/
+export const predefined: GenExtension = /*@__PURE__*/
extDesc(file_buf_validate_validate, 3);
diff --git a/packages/protovalidate/src/lib.test.ts b/packages/protovalidate/src/lib.test.ts
index 664295e1..8a01179e 100644
--- a/packages/protovalidate/src/lib.test.ts
+++ b/packages/protovalidate/src/lib.test.ts
@@ -1301,7 +1301,7 @@ void suite("unique", () => {
// const expect = m[3] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_ip_prefix"),
+// RuleId: proto.String("library.is_ip_prefix"),
// },
// )`;
// const p = version !== undefined ? `, Version: proto.Int32(${version})` : ``;
@@ -1318,7 +1318,7 @@ void suite("unique", () => {
// const expect = m[1] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_hostname"),
+// RuleId: proto.String("library.is_hostname"),
// },
// )`;
// return `"${name}": {
@@ -1334,7 +1334,7 @@ void suite("unique", () => {
// const expect = m[2] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_host_and_port"),
+// RuleId: proto.String("library.is_host_and_port"),
// },
// )`;
// const p = portRequired ? `, PortRequired: true` : ``;
@@ -1350,7 +1350,7 @@ void suite("unique", () => {
// const expect = m[1] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_email"),
+// RuleId: proto.String("library.is_email"),
// },
// )`;
// return `"${name}": {
@@ -1366,7 +1366,7 @@ void suite("unique", () => {
// const expect = m[2] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_ip"),
+// RuleId: proto.String("library.is_ip"),
// },
// )`;
// const p = version !== undefined ? `, Version: proto.Int32(${version})` : ``;
@@ -1382,7 +1382,7 @@ void suite("unique", () => {
// const expect = m[1] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_uri"),
+// RuleId: proto.String("library.is_uri"),
// },
// )`;
// return `"${name}": {
@@ -1397,7 +1397,7 @@ void suite("unique", () => {
// const expect = m[1] === "valid";
// const e = expect ? `results.Success(true)` : `results.Violations(
// &validate.Violation{
-// ConstraintId: proto.String("library.is_uri_ref"),
+// RuleId: proto.String("library.is_uri_ref"),
// },
// )`;
// return `"${name}": {
diff --git a/packages/protovalidate/src/planner.ts b/packages/protovalidate/src/planner.ts
index a2783b54..8ce46a2a 100644
--- a/packages/protovalidate/src/planner.ts
+++ b/packages/protovalidate/src/planner.ts
@@ -24,13 +24,13 @@ import {
type ScalarType,
} from "@bufbuild/protobuf";
import {
- type FieldConstraints,
- type MessageConstraints,
+ type FieldRules,
+ type MessageRules,
Ignore,
field as ext_field,
message as ext_message,
oneof as ext_oneof,
- FieldConstraintsSchema,
+ FieldRulesSchema,
AnyRulesSchema,
} from "./gen/buf/validate/validate_pb.js";
import type {
@@ -86,15 +86,15 @@ export class Planner {
if (existing) {
return existing;
}
- const constraints = getOption(message, ext_message);
- if (constraints.disabled) {
+ const messageRules = getOption(message, ext_message);
+ if (messageRules.disabled) {
return EvalNoop.get();
}
const e = new EvalMany();
this.messageCache.set(message, e);
- if (!constraints.disabled) {
+ if (!messageRules.disabled) {
e.add(this.fields(message.fields));
- e.add(this.messageCel(constraints));
+ e.add(this.messageCel(messageRules));
e.add(this.oneofs(message.oneofs));
}
e.prune();
@@ -112,18 +112,18 @@ export class Planner {
private fields(fields: DescField[]): Eval {
const evals = new EvalMany();
for (const field of fields) {
- const constraints = getOption(field, ext_field);
- if (constraints.required && constraints.ignore !== Ignore.ALWAYS) {
+ const fieldRules = getOption(field, ext_field);
+ if (fieldRules.required && fieldRules.ignore !== Ignore.ALWAYS) {
evals.add(new EvalFieldRequired(field));
}
- const baseRulePath = buildPath(FieldConstraintsSchema);
+ const baseRulePath = buildPath(FieldRulesSchema);
switch (field.fieldKind) {
case "message": {
evals.add(
new EvalField(
field,
- ignoreMessageField(field, constraints.ignore),
- this.message(field.message, constraints, baseRulePath, field),
+ ignoreMessageField(field, fieldRules.ignore),
+ this.message(field.message, fieldRules, baseRulePath, field),
),
);
break;
@@ -132,8 +132,8 @@ export class Planner {
evals.add(
new EvalField(
field,
- ignoreListOrMapField(field, constraints.ignore),
- this.planList(field, constraints, baseRulePath),
+ ignoreListOrMapField(field, fieldRules.ignore),
+ this.planList(field, fieldRules, baseRulePath),
),
);
break;
@@ -142,8 +142,8 @@ export class Planner {
evals.add(
new EvalField(
field,
- ignoreListOrMapField(field, constraints.ignore),
- this.map(field, constraints, baseRulePath),
+ ignoreListOrMapField(field, fieldRules.ignore),
+ this.map(field, fieldRules, baseRulePath),
),
);
break;
@@ -152,8 +152,8 @@ export class Planner {
evals.add(
new EvalField(
field,
- ignoreScalarOrEnumField(field, constraints.ignore),
- this.enumeration(field.enum, constraints, baseRulePath, field),
+ ignoreScalarOrEnumField(field, fieldRules.ignore),
+ this.enumeration(field.enum, fieldRules, baseRulePath, field),
),
);
break;
@@ -162,14 +162,8 @@ export class Planner {
evals.add(
new EvalField(
field,
- ignoreScalarOrEnumField(field, constraints.ignore),
- this.scalar(
- field.scalar,
- constraints,
- baseRulePath,
- false,
- field,
- ),
+ ignoreScalarOrEnumField(field, fieldRules.ignore),
+ this.scalar(field.scalar, fieldRules, baseRulePath, false, field),
),
);
break;
@@ -181,15 +175,15 @@ export class Planner {
private planList(
field: DescField & { fieldKind: "list" },
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
): Eval {
const evals = new EvalMany(
- this.fieldCel(constraints, baseRulePath, false),
+ this.fieldCel(fieldRules, baseRulePath, false),
);
const [rules, rulePath, rulePathItems] = getListRules(
baseRulePath,
- constraints,
+ fieldRules,
field,
);
if (rules) {
@@ -230,15 +224,15 @@ export class Planner {
private map(
field: DescField & { fieldKind: "map" },
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
): Eval {
const evals = new EvalMany(
- this.fieldCel(constraints, baseRulePath, false),
+ this.fieldCel(fieldRules, baseRulePath, false),
);
const [rules, rulePath, rulePathKeys, rulePathValues] = getMapRules(
baseRulePath,
- constraints,
+ fieldRules,
field,
);
if (rules) {
@@ -299,16 +293,16 @@ export class Planner {
private enumeration(
descEnum: DescEnum,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
fieldContext: { toString(): string },
): Eval {
const evals = new EvalMany(
- this.fieldCel(constraints, baseRulePath, false),
+ this.fieldCel(fieldRules, baseRulePath, false),
);
const [rules, rulePath] = getEnumRules(
baseRulePath,
- constraints,
+ fieldRules,
fieldContext,
);
if (rules) {
@@ -320,18 +314,18 @@ export class Planner {
private scalar(
scalar: ScalarType,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
forMapKey: boolean,
fieldContext: { toString(): string },
): Eval {
const evals = new EvalMany(
- this.fieldCel(constraints, baseRulePath, forMapKey),
+ this.fieldCel(fieldRules, baseRulePath, forMapKey),
);
const [rules, rulePath] = getScalarRules(
scalar,
baseRulePath,
- constraints,
+ fieldRules,
fieldContext,
);
if (rules) {
@@ -342,18 +336,18 @@ export class Planner {
private message(
descMessage: DescMessage,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
fieldContext: { toString(): string },
): Eval {
const evals = new EvalMany(
- this.fieldCel(constraints, baseRulePath, false),
+ this.fieldCel(fieldRules, baseRulePath, false),
);
evals.add(this.plan(descMessage));
const [rules, rulePath] = getMessageRules(
descMessage,
baseRulePath,
- constraints,
+ fieldRules,
fieldContext,
);
if (rules) {
@@ -366,7 +360,7 @@ export class Planner {
}
private rules(
- rules: Exclude,
+ rules: Exclude,
rulePath: PathBuilder,
forMapKey: boolean,
) {
@@ -409,30 +403,30 @@ export class Planner {
return new EvalMany(evalStandard, evalExtended);
}
- private messageCel(constraints: MessageConstraints): Eval {
+ private messageCel(messageRules: MessageRules): Eval {
const e = new EvalCustomCel(this.celMan, false);
- for (const constraint of constraints.cel) {
- e.add(this.celMan.compileConstraint(constraint), []);
+ for (const rule of messageRules.cel) {
+ e.add(this.celMan.compileRule(rule), []);
}
return e;
}
private fieldCel(
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
baseRulePath: PathBuilder,
forMapKey: boolean,
): Eval {
- if (!constraints) {
+ if (!fieldRules) {
return EvalNoop.get();
}
const e = new EvalCustomCel(this.celMan, forMapKey);
- for (const [index, constraint] of constraints.cel.entries()) {
+ for (const [index, rule] of fieldRules.cel.entries()) {
const rulePath = baseRulePath
.clone()
- .field(FieldConstraintsSchema.field.cel)
+ .field(FieldRulesSchema.field.cel)
.list(index)
.toPath();
- e.add(this.celMan.compileConstraint(constraint), rulePath);
+ e.add(this.celMan.compileRule(rule), rulePath);
}
return e;
}
diff --git a/packages/protovalidate/src/rules.test.ts b/packages/protovalidate/src/rules.test.ts
index fffc7501..c489ab7e 100644
--- a/packages/protovalidate/src/rules.test.ts
+++ b/packages/protovalidate/src/rules.test.ts
@@ -32,7 +32,7 @@ import {
DoubleRulesSchema,
DurationRulesSchema,
EnumRulesSchema,
- FieldConstraintsSchema,
+ FieldRulesSchema,
FloatRulesSchema,
Int32RulesSchema,
Int64RulesSchema,
@@ -53,48 +53,45 @@ void suite("getListRules()", () => {
const fakeField = {
toString: () => "field fake.Foo.field",
};
- const basePath = buildPath(FieldConstraintsSchema);
- void test("constraints undefined returns rules undefined", () => {
- const constraints = undefined;
- const [rules, path] = getListRules(basePath, constraints, fakeField);
+ const basePath = buildPath(FieldRulesSchema);
+ void test("fieldRules undefined returns rules undefined", () => {
+ const fieldRules = undefined;
+ const [rules, path] = getListRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "repeated");
});
- void test("constraints without rules returns rules undefined", () => {
- const constraints = create(FieldConstraintsSchema);
- const [rules, path] = getListRules(basePath, constraints, fakeField);
+ void test("fieldRules without rules returns rules undefined", () => {
+ const fieldRules = create(FieldRulesSchema);
+ const [rules, path] = getListRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "repeated");
});
- void test("constraints with repeated rules returns rules", () => {
- const constraints = create(FieldConstraintsSchema, {
+ void test("fieldRules with repeated rules returns rules", () => {
+ const fieldRules = create(FieldRulesSchema, {
type: { case: "repeated", value: {} },
});
- const [rules, path] = getListRules(basePath, constraints, fakeField);
+ const [rules, path] = getListRules(basePath, fieldRules, fakeField);
assert.ok(rules);
assert.strictEqual(rules.$typeName, RepeatedRulesSchema.typeName);
assert.strictEqual(pathToString(path.toPath()), "repeated");
});
const failureCases: {
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
error: string;
}[] = [
{
type: { case: "string", value: {} },
- error: `expected constraint "repeated", got "string" on field fake.Foo.field`,
+ error: `expected rule "repeated", got "string" on field fake.Foo.field`,
},
{
type: { case: "map", value: {} },
- error: `expected constraint "repeated", got "map" on field fake.Foo.field`,
+ error: `expected rule "repeated", got "map" on field fake.Foo.field`,
},
];
for (const { type, error } of failureCases) {
void test(`rule "${type.case}" errors`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
- assert.throws(() => getListRules(basePath, constraints, fakeField), {
+ const fieldRules = create(FieldRulesSchema, { type });
+ assert.throws(() => getListRules(basePath, fieldRules, fakeField), {
name: "CompilationError",
message: error,
});
@@ -106,48 +103,45 @@ void suite("getMapRules()", () => {
const fakeField = {
toString: () => "field fake.Foo.field",
};
- const basePath = buildPath(FieldConstraintsSchema);
- void test("constraints undefined returns rules undefined", () => {
- const constraints = undefined;
- const [rules, path] = getMapRules(basePath, constraints, fakeField);
+ const basePath = buildPath(FieldRulesSchema);
+ void test("fieldRules undefined returns rules undefined", () => {
+ const fieldRules = undefined;
+ const [rules, path] = getMapRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "map");
});
- void test("constraints without rules returns rules undefined", () => {
- const constraints = create(FieldConstraintsSchema);
- const [rules, path] = getMapRules(basePath, constraints, fakeField);
+ void test("fieldRules without rules returns rules undefined", () => {
+ const fieldRules = create(FieldRulesSchema);
+ const [rules, path] = getMapRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "map");
});
- void test("constraints with map rules returns rules", () => {
- const constraints = create(FieldConstraintsSchema, {
+ void test("fieldRules with map rules returns rules", () => {
+ const fieldRules = create(FieldRulesSchema, {
type: { case: "map", value: {} },
});
- const [rules, path] = getMapRules(basePath, constraints, fakeField);
+ const [rules, path] = getMapRules(basePath, fieldRules, fakeField);
assert.ok(rules);
assert.strictEqual(rules.$typeName, MapRulesSchema.typeName);
assert.strictEqual(pathToString(path.toPath()), "map");
});
const failureCases: {
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
error: string;
}[] = [
{
type: { case: "string", value: {} },
- error: `expected constraint "map", got "string" on field fake.Foo.field`,
+ error: `expected rule "map", got "string" on field fake.Foo.field`,
},
{
type: { case: "repeated", value: {} },
- error: `expected constraint "map", got "repeated" on field fake.Foo.field`,
+ error: `expected rule "map", got "repeated" on field fake.Foo.field`,
},
];
for (const { type, error } of failureCases) {
void test(`rule "${type.case}" errors`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
- assert.throws(() => getMapRules(basePath, constraints, fakeField), {
+ const rules = create(FieldRulesSchema, { type });
+ assert.throws(() => getMapRules(basePath, rules, fakeField), {
name: "CompilationError",
message: error,
});
@@ -159,50 +153,47 @@ void suite("getEnumRules()", () => {
const fakeField = {
toString: () => "field fake.Foo.field",
};
- const basePath = buildPath(FieldConstraintsSchema)
- .field(FieldConstraintsSchema.field.repeated)
+ const basePath = buildPath(FieldRulesSchema)
+ .field(FieldRulesSchema.field.repeated)
.field(RepeatedRulesSchema.field.items);
- void test("constraints undefined returns rules undefined", () => {
- const constraints = undefined;
- const [rules, path] = getEnumRules(basePath, constraints, fakeField);
+ void test("fieldRules undefined returns rules undefined", () => {
+ const fieldRules = undefined;
+ const [rules, path] = getEnumRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "repeated.items.enum");
});
- void test("constraints without rules returns rules undefined", () => {
- const constraints = create(FieldConstraintsSchema);
- const [rules, path] = getEnumRules(basePath, constraints, fakeField);
+ void test("fieldRules without rules returns rules undefined", () => {
+ const fieldRules = create(FieldRulesSchema);
+ const [rules, path] = getEnumRules(basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
assert.strictEqual(pathToString(path.toPath()), "repeated.items.enum");
});
- void test("constraints with enum rules returns rules", () => {
- const constraints = create(FieldConstraintsSchema, {
+ void test("fieldRules with enum rules returns rules", () => {
+ const fieldRules = create(FieldRulesSchema, {
type: { case: "enum", value: {} },
});
- const [rules, path] = getEnumRules(basePath, constraints, fakeField);
+ const [rules, path] = getEnumRules(basePath, fieldRules, fakeField);
assert.ok(rules);
assert.strictEqual(rules.$typeName, EnumRulesSchema.typeName);
assert.strictEqual(pathToString(path.toPath()), "repeated.items.enum");
});
const failureCases: {
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
error: string;
}[] = [
{
type: { case: "string", value: {} },
- error: `expected constraint "enum", got "string" on field fake.Foo.field`,
+ error: `expected rule "enum", got "string" on field fake.Foo.field`,
},
{
type: { case: "any", value: {} },
- error: `expected constraint "enum", got "any" on field fake.Foo.field`,
+ error: `expected rule "enum", got "any" on field fake.Foo.field`,
},
];
for (const { type, error } of failureCases) {
void test(`rule "${type.case}" errors`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
- assert.throws(() => getEnumRules(basePath, constraints, fakeField), {
+ const fieldRules = create(FieldRulesSchema, { type });
+ assert.throws(() => getEnumRules(basePath, fieldRules, fakeField), {
name: "CompilationError",
message: error,
});
@@ -214,55 +205,42 @@ void suite("getMessageRules()", () => {
const fakeField = {
toString: () => "field fake.Foo.field",
};
- const basePath = buildPath(FieldConstraintsSchema)
- .field(FieldConstraintsSchema.field.repeated)
+ const basePath = buildPath(FieldRulesSchema)
+ .field(FieldRulesSchema.field.repeated)
.field(RepeatedRulesSchema.field.items);
- void test("constraints undefined returns rules undefined", () => {
- const constraints = undefined;
- const [rules] = getMessageRules(
- AnySchema,
- basePath,
- constraints,
- fakeField,
- );
+ void test("fieldRules undefined returns rules undefined", () => {
+ const fieldRules = undefined;
+ const [rules] = getMessageRules(AnySchema, basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
});
- void test("constraints without rules returns rules undefined", () => {
- const constraints = create(FieldConstraintsSchema);
- const [rules] = getMessageRules(
- AnySchema,
- basePath,
- constraints,
- fakeField,
- );
+ void test("fieldRules without rules returns rules undefined", () => {
+ const fieldRules = create(FieldRulesSchema);
+ const [rules] = getMessageRules(AnySchema, basePath, fieldRules, fakeField);
assert.strictEqual(rules, undefined);
});
void test("adds wanted rule to path", () => {
- const constraints = create(FieldConstraintsSchema);
+ const fieldRules = create(FieldRulesSchema);
const [, path] = getMessageRules(
AnySchema,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.strictEqual(pathToString(path.toPath()), "repeated.items.any");
});
void test("does not modify path for message type without rules", () => {
- const constraints = create(FieldConstraintsSchema);
+ const fieldRules = create(FieldRulesSchema);
const [, path] = getMessageRules(
- FieldConstraintsSchema,
+ FieldRulesSchema,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.strictEqual(pathToString(path.toPath()), "repeated.items");
});
const successCases: {
message: DescMessage;
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
wantPath: string;
wantRuleType: DescMessage;
}[] = [
@@ -293,11 +271,11 @@ void suite("getMessageRules()", () => {
];
for (const { message, type, wantPath, wantRuleType } of successCases) {
void test(`rule "${type.case}" on field with ${message.toString()} is ok`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
+ const fieldRules = create(FieldRulesSchema, { type });
const [rules, path] = getMessageRules(
message,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.ok(rules);
@@ -307,28 +285,25 @@ void suite("getMessageRules()", () => {
}
const failureCases: {
message: DescMessage;
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
error: string;
}[] = [
{
- message: FieldConstraintsSchema,
+ message: FieldRulesSchema,
type: { case: "string", value: {} },
- error: `constraint "string" cannot be used on field fake.Foo.field`,
+ error: `rule "string" cannot be used on field fake.Foo.field`,
},
{
message: AnySchema,
type: { case: "repeated", value: {} },
- error: `expected constraint "any", got "repeated" on field fake.Foo.field`,
+ error: `expected rule "any", got "repeated" on field fake.Foo.field`,
},
];
for (const { message, type, error } of failureCases) {
void test(`rule "${type.case}" on field with ${message.toString()} errors`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
+ const fieldRules = create(FieldRulesSchema, { type });
assert.throws(
- () => getMessageRules(message, basePath, constraints, fakeField),
+ () => getMessageRules(message, basePath, fieldRules, fakeField),
{
name: "CompilationError",
message: error,
@@ -342,45 +317,42 @@ void suite("getScalarRules()", () => {
const fakeField = {
toString: () => "field fake.Foo.field",
};
- const basePath = buildPath(FieldConstraintsSchema)
- .field(FieldConstraintsSchema.field.repeated)
+ const basePath = buildPath(FieldRulesSchema)
+ .field(FieldRulesSchema.field.repeated)
.field(RepeatedRulesSchema.field.items);
- void test("constraints undefined returns rules undefined", () => {
- const constraints = undefined;
+ void test("fieldRules undefined returns rules undefined", () => {
+ const fieldRules = undefined;
const [rules] = getScalarRules(
ScalarType.INT32,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.strictEqual(rules, undefined);
});
- void test("constraints without rules returns rules undefined", () => {
- const constraints = create(FieldConstraintsSchema);
+ void test("fieldRules without rules returns rules undefined", () => {
+ const fieldRules = create(FieldRulesSchema);
const [rules] = getScalarRules(
ScalarType.STRING,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.strictEqual(rules, undefined);
});
void test("adds wanted rule to path", () => {
- const constraints = create(FieldConstraintsSchema);
+ const fieldRules = create(FieldRulesSchema);
const [, path] = getScalarRules(
ScalarType.STRING,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.strictEqual(pathToString(path.toPath()), "repeated.items.string");
});
const successCases: {
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
scalar: ScalarType;
wantPath: string;
wantRuleType: DescMessage;
@@ -412,11 +384,11 @@ void suite("getScalarRules()", () => {
];
for (const { scalar, type, wantPath, wantRuleType } of successCases) {
void test(`rule ${type.case} on ${ScalarType[scalar]} field is ok`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
+ const fieldRules = create(FieldRulesSchema, { type });
const [rules, path] = getScalarRules(
scalar,
basePath,
- constraints,
+ fieldRules,
fakeField,
);
assert.ok(rules);
@@ -426,29 +398,26 @@ void suite("getScalarRules()", () => {
}
const failureCases: {
- type: Exclude<
- MessageInitShape["type"],
- undefined
- >;
+ type: Exclude["type"], undefined>;
scalar: ScalarType;
error: string;
}[] = [
{
scalar: ScalarType.FLOAT,
type: { case: "string", value: {} },
- error: `expected constraint "float", got "string" on field fake.Foo.field`,
+ error: `expected rule "float", got "string" on field fake.Foo.field`,
},
{
scalar: ScalarType.STRING,
type: { case: "any", value: {} },
- error: `expected constraint "string", got "any" on field fake.Foo.field`,
+ error: `expected rule "string", got "any" on field fake.Foo.field`,
},
];
for (const { type, scalar, error } of failureCases) {
void test(`rule ${type.case} on ${ScalarType[scalar]} field errors`, () => {
- const constraints = create(FieldConstraintsSchema, { type });
+ const fieldRules = create(FieldRulesSchema, { type });
assert.throws(
- () => getScalarRules(scalar, basePath, constraints, fakeField),
+ () => getScalarRules(scalar, basePath, fieldRules, fakeField),
{
name: "CompilationError",
message: error,
diff --git a/packages/protovalidate/src/rules.ts b/packages/protovalidate/src/rules.ts
index 0d7c761c..93d4e5ee 100644
--- a/packages/protovalidate/src/rules.ts
+++ b/packages/protovalidate/src/rules.ts
@@ -35,8 +35,8 @@ import {
DoubleRulesSchema,
DurationRulesSchema,
EnumRulesSchema,
- type FieldConstraints,
- FieldConstraintsSchema,
+ type FieldRules,
+ FieldRulesSchema,
Fixed32RulesSchema,
Fixed64RulesSchema,
FloatRulesSchema,
@@ -55,7 +55,7 @@ import {
} from "./gen/buf/validate/validate_pb.js";
import { CompilationError } from "./error.js";
-type ruleType = Exclude;
+type ruleType = Exclude;
type ruleTypeMessage =
| "any"
| "duration"
@@ -125,7 +125,7 @@ const scalarToRuleType = new Map([
* Get the descriptor for one of the buf.validate.*Rules messages.
*/
export function getRuleDescriptor(
- typeName: Exclude["$typeName"],
+ typeName: Exclude["$typeName"],
): DescMessage {
for (const d of [
FloatRulesSchema,
@@ -158,36 +158,36 @@ export function getRuleDescriptor(
}
/**
- * Get buf.validate.RepeatedRules from FieldConstraints.
+ * Get buf.validate.RepeatedRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
- * Throws an error if the FieldConstraints has incompatible rules.
+ * Throws an error if the FieldRules has incompatible rules.
*/
export function getListRules(
rulePath: PathBuilder,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
fieldContext: { toString(): string },
) {
const listRules = getRulePath(rulePath, "repeated");
return [
- getRules(constraints, "repeated", fieldContext),
+ getRules(fieldRules, "repeated", fieldContext),
listRules,
listRules.clone().field(RepeatedRulesSchema.field.items),
] as const;
}
/**
- * Get buf.validate.MapRules from FieldConstraints.
+ * Get buf.validate.MapRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
- * Throws an error if the FieldConstraints has incompatible rules.
+ * Throws an error if the FieldRules has incompatible rules.
*/
export function getMapRules(
rulePath: PathBuilder,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
fieldContext: { toString(): string },
) {
const mapRules = getRulePath(rulePath, "map");
return [
- getRules(constraints, "map", fieldContext),
+ getRules(fieldRules, "map", fieldContext),
mapRules,
mapRules.clone().field(MapRulesSchema.field.keys),
mapRules.clone().field(MapRulesSchema.field.values),
@@ -195,53 +195,53 @@ export function getMapRules(
}
/**
- * Get buf.validate.EnumRules from FieldConstraints.
+ * Get buf.validate.EnumRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
- * Throws an error if the FieldConstraints has incompatible rules.
+ * Throws an error if the FieldRules has incompatible rules.
*/
export function getEnumRules(
rulePath: PathBuilder,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
fieldContext: { toString(): string },
) {
return [
- getRules(constraints, "enum", fieldContext),
+ getRules(fieldRules, "enum", fieldContext),
getRulePath(rulePath, "enum"),
] as const;
}
/**
- * Get buf.validate.*Rules for the given message type from FieldConstraints.
+ * Get buf.validate.*Rules for the given message type from FieldRules.
* Returns a tuple with rules, and path to the rules.
- * Throws an error if the FieldConstraints has incompatible rules.
+ * Throws an error if the FieldRules has incompatible rules.
*/
export function getMessageRules(
descMessage: DescMessage,
rulePath: PathBuilder,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
fieldContext: { toString(): string },
) {
const type = messageToRuleType.get(descMessage.typeName);
return [
- getRules(constraints, type, fieldContext),
+ getRules(fieldRules, type, fieldContext),
getRulePath(rulePath, type),
] as const;
}
/**
- * Get buf.validate.*Rules for the given scalar type from FieldConstraints.
+ * Get buf.validate.*Rules for the given scalar type from FieldRules.
* Returns a tuple with rules, and path to the rules.
- * Throws an error if the FieldConstraints has incompatible rules.
+ * Throws an error if the FieldRules has incompatible rules.
*/
export function getScalarRules(
scalar: ScalarType,
rulePath: PathBuilder,
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
fieldContext: { toString(): string },
) {
const type = scalarToRuleType.get(scalar);
return [
- getRules(constraints, type, fieldContext),
+ getRules(fieldRules, type, fieldContext),
getRulePath(rulePath, type),
] as const;
}
@@ -250,7 +250,7 @@ function getRulePath(base: PathBuilder, type: ruleType | undefined) {
if (type == undefined) {
return base;
}
- const field = FieldConstraintsSchema.fields.find((f) => f.name === type);
+ const field = FieldRulesSchema.fields.find((f) => f.name === type);
if (field == undefined) {
throw new CompilationError(`cannot find rule "${type}"`);
}
@@ -258,22 +258,22 @@ function getRulePath(base: PathBuilder, type: ruleType | undefined) {
}
function getRules(
- constraints: FieldConstraints | undefined,
+ fieldRules: FieldRules | undefined,
want: T | undefined,
context: { toString(): string },
) {
- const got = constraints?.type.case;
- if (constraints == undefined || got == undefined) {
+ const got = fieldRules?.type.case;
+ if (fieldRules == undefined || got == undefined) {
return undefined;
}
if (got != want) {
throw new CompilationError(
want == undefined
- ? `constraint "${got}" cannot be used on ${context.toString()}`
- : `expected constraint "${want}", got "${got}" on ${context.toString()}`,
+ ? `rule "${got}" cannot be used on ${context.toString()}`
+ : `expected rule "${want}", got "${got}" on ${context.toString()}`,
);
}
- return constraints.type.value as (FieldConstraints["type"] & {
+ return fieldRules.type.value as (FieldRules["type"] & {
case: T;
})["value"];
}
diff --git a/packages/protovalidate/src/validator.ts b/packages/protovalidate/src/validator.ts
index cfeaaf9d..827c8295 100644
--- a/packages/protovalidate/src/validator.ts
+++ b/packages/protovalidate/src/validator.ts
@@ -37,8 +37,8 @@ export type ValidatorOptions = {
*/
export type Validator = {
/**
- * Checks that message satisfies its constraints. Constraints are defined
- * within the Protobuf file as options from the buf.validate package.
+ * Checks that message satisfies its rules. Rules are defined within the
+ * Protobuf file as options from the buf.validate package.
*/
validate(
schema: Desc,