From b88afdffe7adfd8ce5ba4eb3853c8e65aad6ec34 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Thu, 24 Apr 2025 12:08:54 +0200 Subject: [PATCH 1/4] Update @bufbuild/protovalidate to protovalidate v0.11.0 --- packages/protovalidate/package.json | 2 +- .../proto/buf/validate/validate.proto | 474 ++++++++++-------- packages/protovalidate/src/cel.ts | 72 +-- packages/protovalidate/src/cursor.test.ts | 20 +- packages/protovalidate/src/cursor.ts | 4 +- packages/protovalidate/src/error.test.ts | 52 +- packages/protovalidate/src/error.ts | 32 +- packages/protovalidate/src/eval.test.ts | 38 +- packages/protovalidate/src/eval.ts | 7 +- .../src/gen/buf/validate/validate_pb.ts | 390 +++++++------- packages/protovalidate/src/lib.test.ts | 14 +- packages/protovalidate/src/planner.ts | 88 ++-- packages/protovalidate/src/rules.test.ts | 174 +++---- packages/protovalidate/src/rules.ts | 62 +-- packages/protovalidate/src/validator.ts | 4 +- 15 files changed, 776 insertions(+), 657 deletions(-) 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..fbcc8d8c 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 }); } @@ -415,7 +415,7 @@ export class EvalCustomCel implements Eval { if (vio) { cursor.violate( vio.message, - vio.constraintId, + vio.ruleId, child.rulePath, this.forMapKey, ); @@ -430,7 +430,7 @@ export class EvalCustomCel implements Eval { export class EvalExtendedRulesCel implements Eval { private readonly children: { - compiled: CelCompiledConstraint; + compiled: CelCompiledRule; rulePath: Path; ruleValue: unknown; }[] = []; @@ -438,14 +438,14 @@ export class EvalExtendedRulesCel implements Eval { constructor( private readonly celMan: CelManager, private readonly rules: Exclude< - FieldConstraints["type"]["value"], + FieldRules["type"]["value"], undefined >, private readonly forMapKey: boolean, ) {} add( - compiled: CelCompiledConstraint, + compiled: CelCompiledRule, rulePath: Path, ruleValue: unknown, ): void { @@ -465,7 +465,7 @@ export class EvalExtendedRulesCel implements Eval { if (vio) { cursor.violate( vio.message, - vio.constraintId, + vio.ruleId, child.rulePath, this.forMapKey, ); @@ -480,20 +480,20 @@ 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"], + FieldRules["type"]["value"], undefined >, private readonly forMapKey: boolean, ) {} - add(compiled: CelCompiledConstraint, rulePath: Path): void { + add(compiled: CelCompiledRule, rulePath: Path): void { this.children.push({ compiled, rulePath }); } @@ -506,7 +506,7 @@ export class EvalStandardRulesCel implements Eval { if (vio) { cursor.violate( vio.message, - vio.constraintId, + 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..a190d767 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,44 @@ 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 field = parsePath(FieldRulesSchema, "cel[1].id"); + const rule = parsePath(FieldRulesSchema, "string.min_len"); const v = new Violation( "failure-message", - "constraint-id", + "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 field = parsePath(FieldRulesSchema, "cel[1].id"); + const rule = parsePath(FieldRulesSchema, "string.min_len"); const v = new Violation( "failure-message", - "constraint-id", + "rule-id", field, rule, false, ); - assert.equal(v.toString(), "cel[1].id: failure-message [constraint-id]"); + 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 rule = parsePath(FieldRulesSchema, "string.min_len"); const v = new Violation( "failure-message", - "constraint-id", + "rule-id", field, rule, false, ); - assert.equal(v.toString(), "failure-message [constraint-id]"); + assert.equal(v.toString(), "failure-message [rule-id]"); }); }); @@ -83,15 +83,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 +108,7 @@ void suite("violationToProto", () => { `); const violation = new Violation( "failure-message", - "constraint-id", + "rule-id", buildPath(descMessage).field(descMessage.field.val).toPath(), [], false, @@ -131,7 +131,7 @@ void suite("violationToProto", () => { `); const violation = new Violation( "failure-message", - "constraint-id", + "rule-id", buildPath(descMessage).field(descMessage.field.m).toPath(), [], false, @@ -160,7 +160,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 +213,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 +242,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..e8f26ebc 100644 --- a/packages/protovalidate/src/eval.test.ts +++ b/packages/protovalidate/src/eval.test.ts @@ -16,13 +16,13 @@ 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, + 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 +38,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 +124,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 +133,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..a84ce57f 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,10 +162,10 @@ export class Planner { evals.add( new EvalField( field, - ignoreScalarOrEnumField(field, constraints.ignore), + ignoreScalarOrEnumField(field, fieldRules.ignore), this.scalar( field.scalar, - constraints, + fieldRules, baseRulePath, false, field, @@ -181,15 +181,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 +230,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 +299,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 +320,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 +342,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 +366,7 @@ export class Planner { } private rules( - rules: Exclude, + rules: Exclude, rulePath: PathBuilder, forMapKey: boolean, ) { @@ -409,30 +409,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..72c82a00 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,48 @@ 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"], + MessageInitShape["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 +106,48 @@ 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"], + MessageInitShape["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 +159,50 @@ 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"], + MessageInitShape["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,45 +214,45 @@ 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; + void test("fieldRules undefined returns rules undefined", () => { + const fieldRules = undefined; const [rules] = getMessageRules( AnySchema, 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] = getMessageRules( AnySchema, 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] = 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"); @@ -260,7 +260,7 @@ void suite("getMessageRules()", () => { const successCases: { message: DescMessage; type: Exclude< - MessageInitShape["type"], + MessageInitShape["type"], undefined >; wantPath: string; @@ -293,11 +293,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); @@ -308,27 +308,27 @@ void suite("getMessageRules()", () => { const failureCases: { message: DescMessage; type: Exclude< - MessageInitShape["type"], + MessageInitShape["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,35 +342,35 @@ 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"); @@ -378,7 +378,7 @@ void suite("getScalarRules()", () => { const successCases: { type: Exclude< - MessageInitShape["type"], + MessageInitShape["type"], undefined >; scalar: ScalarType; @@ -412,11 +412,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); @@ -427,7 +427,7 @@ void suite("getScalarRules()", () => { const failureCases: { type: Exclude< - MessageInitShape["type"], + MessageInitShape["type"], undefined >; scalar: ScalarType; @@ -436,19 +436,19 @@ void suite("getScalarRules()", () => { { 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, From ce65e20bc79eab7ae3af3726143b47a10d70c0bd Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Thu, 24 Apr 2025 12:36:58 +0200 Subject: [PATCH 2/4] Update protovalidate-testing to protovalidate v0.11.0 --- .../expected-failures.yaml | 923 ++++++++---------- packages/protovalidate-testing/package.json | 2 +- .../custom_constraints_pb.ts | 630 ------------ .../cases/custom_rules/custom_rules_pb.ts | 715 ++++++++++++++ .../validate/conformance/cases/numbers_pb.ts | 12 +- .../src/gen/buf/validate/validate_pb.ts | 390 ++++---- 6 files changed, 1373 insertions(+), 1299 deletions(-) delete mode 100644 packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_constraints/custom_constraints_pb.ts create mode 100644 packages/protovalidate-testing/src/gen/buf/validate/conformance/cases/custom_rules/custom_rules_pb.ts 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/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); From b681c38d54d844fdd2b65da7c5d098d0fe15d33c Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Thu, 24 Apr 2025 12:37:18 +0200 Subject: [PATCH 3/4] npx turbo run format --- packages/protovalidate/src/cel.ts | 37 +++--------------- packages/protovalidate/src/error.test.ts | 24 ++---------- packages/protovalidate/src/eval.test.ts | 6 ++- packages/protovalidate/src/planner.ts | 8 +--- packages/protovalidate/src/rules.test.ts | 49 +++++------------------- 5 files changed, 24 insertions(+), 100 deletions(-) diff --git a/packages/protovalidate/src/cel.ts b/packages/protovalidate/src/cel.ts index fbcc8d8c..9ab81b2d 100644 --- a/packages/protovalidate/src/cel.ts +++ b/packages/protovalidate/src/cel.ts @@ -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.ruleId, - child.rulePath, - this.forMapKey, - ); + cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey); } } } @@ -437,18 +432,11 @@ export class EvalExtendedRulesCel implements Eval { constructor( private readonly celMan: CelManager, - private readonly rules: Exclude< - FieldRules["type"]["value"], - undefined - >, + private readonly rules: Exclude, private readonly forMapKey: boolean, ) {} - add( - compiled: CelCompiledRule, - 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.ruleId, - child.rulePath, - this.forMapKey, - ); + cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey); } } } @@ -486,10 +469,7 @@ export class EvalStandardRulesCel implements Eval { constructor( private readonly celMan: CelManager, - private readonly rules: Exclude< - FieldRules["type"]["value"], - undefined - >, + private readonly rules: Exclude, private readonly forMapKey: boolean, ) {} @@ -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.ruleId, - child.rulePath, - this.forMapKey, - ); + cursor.violate(vio.message, vio.ruleId, child.rulePath, this.forMapKey); } } } diff --git a/packages/protovalidate/src/error.test.ts b/packages/protovalidate/src/error.test.ts index a190d767..89712b48 100644 --- a/packages/protovalidate/src/error.test.ts +++ b/packages/protovalidate/src/error.test.ts @@ -40,13 +40,7 @@ void suite("Violation", () => { void test("constructor", () => { 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, - ); + const v = new Violation("failure-message", "rule-id", field, rule, false); assert.strictEqual(v.message, "failure-message"); assert.strictEqual(v.ruleId, "rule-id"); assert.strictEqual(v.field, field); @@ -56,25 +50,13 @@ void suite("Violation", () => { void test("toString", () => { 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, - ); + 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(FieldRulesSchema, "string.min_len"); - const v = new Violation( - "failure-message", - "rule-id", - field, - rule, - false, - ); + const v = new Violation("failure-message", "rule-id", field, rule, false); assert.equal(v.toString(), "failure-message [rule-id]"); }); }); diff --git a/packages/protovalidate/src/eval.test.ts b/packages/protovalidate/src/eval.test.ts index e8f26ebc..89caee8b 100644 --- a/packages/protovalidate/src/eval.test.ts +++ b/packages/protovalidate/src/eval.test.ts @@ -22,7 +22,11 @@ import { MapRulesSchema, predefined, RepeatedRulesSchema, - StringRulesSchema, MessageRulesSchema, OneofRulesSchema, FieldRulesSchema, PredefinedRulesSchema, + StringRulesSchema, + MessageRulesSchema, + OneofRulesSchema, + FieldRulesSchema, + PredefinedRulesSchema, } from "./gen/buf/validate/validate_pb.js"; import { nestedTypes } from "@bufbuild/protobuf/reflect"; import { getOption, hasOption } from "@bufbuild/protobuf"; diff --git a/packages/protovalidate/src/planner.ts b/packages/protovalidate/src/planner.ts index a84ce57f..8ce46a2a 100644 --- a/packages/protovalidate/src/planner.ts +++ b/packages/protovalidate/src/planner.ts @@ -163,13 +163,7 @@ export class Planner { new EvalField( field, ignoreScalarOrEnumField(field, fieldRules.ignore), - this.scalar( - field.scalar, - fieldRules, - baseRulePath, - false, - field, - ), + this.scalar(field.scalar, fieldRules, baseRulePath, false, field), ), ); break; diff --git a/packages/protovalidate/src/rules.test.ts b/packages/protovalidate/src/rules.test.ts index 72c82a00..c489ab7e 100644 --- a/packages/protovalidate/src/rules.test.ts +++ b/packages/protovalidate/src/rules.test.ts @@ -76,10 +76,7 @@ void suite("getListRules()", () => { assert.strictEqual(pathToString(path.toPath()), "repeated"); }); const failureCases: { - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; error: string; }[] = [ { @@ -129,10 +126,7 @@ void suite("getMapRules()", () => { assert.strictEqual(pathToString(path.toPath()), "map"); }); const failureCases: { - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; error: string; }[] = [ { @@ -184,10 +178,7 @@ void suite("getEnumRules()", () => { assert.strictEqual(pathToString(path.toPath()), "repeated.items.enum"); }); const failureCases: { - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; error: string; }[] = [ { @@ -219,22 +210,12 @@ void suite("getMessageRules()", () => { .field(RepeatedRulesSchema.field.items); void test("fieldRules undefined returns rules undefined", () => { const fieldRules = undefined; - const [rules] = getMessageRules( - AnySchema, - basePath, - fieldRules, - fakeField, - ); + const [rules] = getMessageRules(AnySchema, basePath, fieldRules, fakeField); assert.strictEqual(rules, undefined); }); void test("fieldRules without rules returns rules undefined", () => { const fieldRules = create(FieldRulesSchema); - const [rules] = getMessageRules( - AnySchema, - basePath, - fieldRules, - fakeField, - ); + const [rules] = getMessageRules(AnySchema, basePath, fieldRules, fakeField); assert.strictEqual(rules, undefined); }); void test("adds wanted rule to path", () => { @@ -259,10 +240,7 @@ void suite("getMessageRules()", () => { }); const successCases: { message: DescMessage; - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; wantPath: string; wantRuleType: DescMessage; }[] = [ @@ -307,10 +285,7 @@ void suite("getMessageRules()", () => { } const failureCases: { message: DescMessage; - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; error: string; }[] = [ { @@ -377,10 +352,7 @@ void suite("getScalarRules()", () => { }); const successCases: { - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; scalar: ScalarType; wantPath: string; wantRuleType: DescMessage; @@ -426,10 +398,7 @@ void suite("getScalarRules()", () => { } const failureCases: { - type: Exclude< - MessageInitShape["type"], - undefined - >; + type: Exclude["type"], undefined>; scalar: ScalarType; error: string; }[] = [ From d5eed1098ca160c32da609ac0ddaacd7c43cd44b Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Thu, 24 Apr 2025 12:39:46 +0200 Subject: [PATCH 4/4] Replace "constraint" with "rule" in README.md and others --- README.md | 2 +- packages/protovalidate-testing/scripts/failure-list.js | 2 +- packages/protovalidate/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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/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/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: