diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9d9132c0c..2e3c2997b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Meta information and status events in the event views in the Console.
- Support for setting the frame counter width of an end device in the Console.
- Include consumed airtime metadata in uplink messages and join requests (see `uplink_message.consumed_airtime` field).
+- Add end device location metadata on forwarded uplink messages (see `uplink_message.locations` field).
### Changed
diff --git a/api/api.md b/api/api.md
index efb9740640..2cc280d0ca 100644
--- a/api/api.md
+++ b/api/api.md
@@ -355,6 +355,7 @@
- [Message `ApplicationServiceData`](#ttn.lorawan.v3.ApplicationServiceData)
- [Message `ApplicationUp`](#ttn.lorawan.v3.ApplicationUp)
- [Message `ApplicationUplink`](#ttn.lorawan.v3.ApplicationUplink)
+ - [Message `ApplicationUplink.LocationsEntry`](#ttn.lorawan.v3.ApplicationUplink.LocationsEntry)
- [Message `DownlinkMessage`](#ttn.lorawan.v3.DownlinkMessage)
- [Message `DownlinkQueueRequest`](#ttn.lorawan.v3.DownlinkQueueRequest)
- [Message `GatewayUplinkMessage`](#ttn.lorawan.v3.GatewayUplinkMessage)
@@ -5062,6 +5063,7 @@ Encodes and decodes uplink messages.
| `last_a_f_cnt_down` | [`uint32`](#uint32) | | The last AFCntDown of the current session. This field is only present if the skip_payload_crypto field of the EndDevice is true. Can be used with app_s_key to encrypt downlink payloads. |
| `confirmed` | [`bool`](#bool) | | |
| `consumed_airtime` | [`google.protobuf.Duration`](#google.protobuf.Duration) | | Consumed airtime for the transmission of the uplink message. Calculated by Network Server using the RawPayload size and the transmission settings. |
+| `locations` | [`ApplicationUplink.LocationsEntry`](#ttn.lorawan.v3.ApplicationUplink.LocationsEntry) | repeated | End device location metadata, set by the Application Server while handling the message. |
#### Field Rules
@@ -5072,6 +5074,13 @@ Encodes and decodes uplink messages.
| `rx_metadata` |
`repeated.min_items`: `1`
|
| `settings` | `message.required`: `true`
|
+### Message `ApplicationUplink.LocationsEntry`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `key` | [`string`](#string) | | |
+| `value` | [`Location`](#ttn.lorawan.v3.Location) | | |
+
### Message `DownlinkMessage`
Downlink message from the network to the end device
diff --git a/api/api.swagger.json b/api/api.swagger.json
index 4cc303fe39..b96a7e7561 100644
--- a/api/api.swagger.json
+++ b/api/api.swagger.json
@@ -9174,6 +9174,13 @@
"consumed_airtime": {
"type": "string",
"description": "Consumed airtime for the transmission of the uplink message. Calculated by Network Server using the RawPayload size and the transmission settings."
+ },
+ "locations": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/lorawanv3Location"
+ },
+ "description": "End device location metadata, set by the Application Server while handling the message."
}
}
},
diff --git a/api/messages.proto b/api/messages.proto
index 3e2bf3ceda..5219e9d884 100644
--- a/api/messages.proto
+++ b/api/messages.proto
@@ -209,7 +209,10 @@ message ApplicationUplink {
// Consumed airtime for the transmission of the uplink message. Calculated by Network Server using the RawPayload size and the transmission settings.
google.protobuf.Duration consumed_airtime = 13 [(gogoproto.stdduration) = true, (gogoproto.nullable) = true];
- // next: 14
+ // End device location metadata, set by the Application Server while handling the message.
+ map locations = 14;
+
+ // next: 15
}
message ApplicationLocation {
diff --git a/pkg/applicationserver/applicationserver.go b/pkg/applicationserver/applicationserver.go
index 00ded3b1db..b55141e7a5 100644
--- a/pkg/applicationserver/applicationserver.go
+++ b/pkg/applicationserver/applicationserver.go
@@ -131,6 +131,10 @@ func New(c *component.Component, conf *Config) (as *ApplicationServer, err error
interopID: conf.Interop.ID,
endDeviceFetcher: conf.EndDeviceFetcher.Fetcher,
}
+
+ if as.endDeviceFetcher == nil {
+ as.endDeviceFetcher = &NoopEndDeviceFetcher{}
+ }
retryIO := io.NewRetryServer(as)
as.grpc.asDevices = asEndDeviceRegistryServer{
@@ -935,6 +939,13 @@ func (as *ApplicationServer) handleUplink(ctx context.Context, ids ttnpb.EndDevi
uplink.LastAFCntDown = dev.Session.LastAFCntDown
}
+ isDev, err := as.endDeviceFetcher.Get(ctx, ids, "locations")
+ if err != nil {
+ logger.WithError(err).Warn("Failed to retrieve end device locations")
+ } else {
+ uplink.Locations = isDev.GetLocations()
+ }
+
// TODO: Run uplink messages through location solvers async (https://github.com/TheThingsNetwork/lorawan-stack/issues/37)
return nil
}
@@ -950,6 +961,14 @@ func (as *ApplicationServer) handleSimulatedUplink(ctx context.Context, ids ttnp
if err != nil {
return err
}
+
+ isDev, err := as.endDeviceFetcher.Get(ctx, ids, "locations")
+ if err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Failed to retrieve end device locations")
+ } else {
+ uplink.Locations = isDev.GetLocations()
+ }
+
return as.decodeUplink(ctx, dev, uplink, link.DefaultFormatters)
}
diff --git a/pkg/applicationserver/applicationserver_test.go b/pkg/applicationserver/applicationserver_test.go
index e8dcbf03a7..0d8642923c 100644
--- a/pkg/applicationserver/applicationserver_test.go
+++ b/pkg/applicationserver/applicationserver_test.go
@@ -2249,6 +2249,9 @@ func TestSkipPayloadCrypto(t *testing.T) {
LinkMode: "all",
Devices: deviceRegistry,
Links: linkRegistry,
+ EndDeviceFetcher: applicationserver.EndDeviceFetcherConfig{
+ Fetcher: &noopEndDeviceFetcher{},
+ },
}
as, err := applicationserver.New(c, config)
if !a.So(err, should.BeNil) {
diff --git a/pkg/applicationserver/device_fetcher.go b/pkg/applicationserver/device_fetcher.go
index 9548ae85d4..d80f81c679 100644
--- a/pkg/applicationserver/device_fetcher.go
+++ b/pkg/applicationserver/device_fetcher.go
@@ -31,6 +31,14 @@ type EndDeviceFetcher interface {
Get(ctx context.Context, ids ttnpb.EndDeviceIdentifiers, fieldMaskPaths ...string) (*ttnpb.EndDevice, error)
}
+// NoopEndDeviceFetcher is a no-op.
+type NoopEndDeviceFetcher struct{}
+
+// Get implements the EndDeviceFetcher interface.
+func (f *NoopEndDeviceFetcher) Get(ctx context.Context, ids ttnpb.EndDeviceIdentifiers, fieldMaskPaths ...string) (*ttnpb.EndDevice, error) {
+ return nil, errDeviceNotFound.WithAttributes("device_uid", unique.ID(ctx, ids))
+}
+
// endDeviceFetcher fetches end devices
type endDeviceFetcher struct {
c *component.Component
diff --git a/pkg/ttnpb/message_services.pb.paths.fm.go b/pkg/ttnpb/message_services.pb.paths.fm.go
index a7a748767f..6285787f66 100644
--- a/pkg/ttnpb/message_services.pb.paths.fm.go
+++ b/pkg/ttnpb/message_services.pb.paths.fm.go
@@ -66,6 +66,7 @@ var DecodeUplinkMessageRequestFieldPathsNested = []string{
"message.f_port",
"message.frm_payload",
"message.last_a_f_cnt_down",
+ "message.locations",
"message.received_at",
"message.rx_metadata",
"message.session_key_id",
diff --git a/pkg/ttnpb/messages.pb.go b/pkg/ttnpb/messages.pb.go
index 6fe9ef2c93..bb6af84474 100644
--- a/pkg/ttnpb/messages.pb.go
+++ b/pkg/ttnpb/messages.pb.go
@@ -472,9 +472,11 @@ type ApplicationUplink struct {
LastAFCntDown uint32 `protobuf:"varint,10,opt,name=last_a_f_cnt_down,json=lastAFCntDown,proto3" json:"last_a_f_cnt_down,omitempty"`
Confirmed bool `protobuf:"varint,11,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
// Consumed airtime for the transmission of the uplink message. Calculated by Network Server using the RawPayload size and the transmission settings.
- ConsumedAirtime *time.Duration `protobuf:"bytes,13,opt,name=consumed_airtime,json=consumedAirtime,proto3,stdduration" json:"consumed_airtime,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ConsumedAirtime *time.Duration `protobuf:"bytes,13,opt,name=consumed_airtime,json=consumedAirtime,proto3,stdduration" json:"consumed_airtime,omitempty"`
+ // End device location metadata, set by the Application Server while handling the message.
+ Locations map[string]*Location `protobuf:"bytes,14,rep,name=locations,proto3" json:"locations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *ApplicationUplink) Reset() { *m = ApplicationUplink{} }
@@ -600,6 +602,13 @@ func (m *ApplicationUplink) GetConsumedAirtime() *time.Duration {
return nil
}
+func (m *ApplicationUplink) GetLocations() map[string]*Location {
+ if m != nil {
+ return m.Locations
+ }
+ return nil
+}
+
type ApplicationLocation struct {
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
Location `protobuf:"bytes,2,opt,name=location,proto3,embedded=location" json:"location"`
@@ -1477,6 +1486,8 @@ func init() {
golang_proto.RegisterType((*GatewayUplinkMessage)(nil), "ttn.lorawan.v3.GatewayUplinkMessage")
proto.RegisterType((*ApplicationUplink)(nil), "ttn.lorawan.v3.ApplicationUplink")
golang_proto.RegisterType((*ApplicationUplink)(nil), "ttn.lorawan.v3.ApplicationUplink")
+ proto.RegisterMapType((map[string]*Location)(nil), "ttn.lorawan.v3.ApplicationUplink.LocationsEntry")
+ golang_proto.RegisterMapType((map[string]*Location)(nil), "ttn.lorawan.v3.ApplicationUplink.LocationsEntry")
proto.RegisterType((*ApplicationLocation)(nil), "ttn.lorawan.v3.ApplicationLocation")
golang_proto.RegisterType((*ApplicationLocation)(nil), "ttn.lorawan.v3.ApplicationLocation")
proto.RegisterMapType((map[string]string)(nil), "ttn.lorawan.v3.ApplicationLocation.AttributesEntry")
@@ -1509,153 +1520,155 @@ func init() {
}
var fileDescriptor_bbc6bff5780bdc9d = []byte{
- // 2322 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6c, 0x1b, 0xd7,
- 0xf1, 0xdf, 0x47, 0xf1, 0x73, 0xf8, 0xa1, 0xcd, 0x8b, 0xe2, 0x3f, 0xa3, 0xbf, 0xb3, 0x54, 0x19,
- 0x27, 0x91, 0x93, 0x88, 0x6a, 0xe5, 0x16, 0x4d, 0x5d, 0xb4, 0x09, 0x97, 0xa4, 0x2c, 0x5a, 0x12,
- 0x49, 0x3f, 0xd2, 0x49, 0xdc, 0x34, 0x5d, 0xac, 0xb8, 0x4f, 0xf4, 0x46, 0xe4, 0x2e, 0xb3, 0xbb,
- 0xd4, 0x47, 0x8a, 0x02, 0x69, 0x4e, 0x41, 0x81, 0x16, 0x86, 0x81, 0x16, 0x41, 0x81, 0x16, 0xbe,
- 0x14, 0xc8, 0xa1, 0x07, 0x1f, 0x8d, 0xf6, 0x92, 0x5b, 0x7d, 0x2a, 0x7c, 0x0c, 0x0a, 0x54, 0xb5,
- 0xa8, 0x4b, 0x8e, 0x39, 0x1a, 0xba, 0xa4, 0xd8, 0xb7, 0xbb, 0xe4, 0x92, 0x62, 0x64, 0x59, 0x69,
- 0x6f, 0x3d, 0x71, 0xf7, 0xcd, 0xcc, 0x6f, 0xe7, 0xbd, 0x99, 0xf9, 0xcd, 0x3c, 0xc2, 0x5c, 0x5b,
- 0x37, 0xe4, 0x1d, 0x59, 0x5b, 0x30, 0x2d, 0xb9, 0xb9, 0xb5, 0x28, 0x77, 0xd5, 0xc5, 0x0e, 0x35,
- 0x4d, 0xb9, 0x45, 0xcd, 0x5c, 0xd7, 0xd0, 0x2d, 0x1d, 0xa7, 0x2c, 0x4b, 0xcb, 0xb9, 0x5a, 0xb9,
- 0xed, 0x4b, 0xb3, 0xf9, 0x96, 0x6a, 0xdd, 0xec, 0x6d, 0xe4, 0x9a, 0x7a, 0x67, 0x91, 0x6a, 0xdb,
- 0xfa, 0x5e, 0xd7, 0xd0, 0x77, 0xf7, 0x16, 0x99, 0x72, 0x73, 0xa1, 0x45, 0xb5, 0x85, 0x6d, 0xb9,
- 0xad, 0x2a, 0xb2, 0x45, 0x17, 0x8f, 0x3d, 0x38, 0x90, 0xb3, 0x0b, 0x3e, 0x88, 0x96, 0xde, 0xd2,
- 0x1d, 0xe3, 0x8d, 0xde, 0x26, 0x7b, 0x63, 0x2f, 0xec, 0xc9, 0x55, 0x3f, 0xdf, 0xd2, 0xf5, 0x56,
- 0x9b, 0x0e, 0xb5, 0x4c, 0xcb, 0xe8, 0x35, 0x2d, 0x57, 0x9a, 0x19, 0x97, 0x5a, 0x6a, 0x87, 0x9a,
- 0x96, 0xdc, 0xe9, 0xba, 0x0a, 0xc2, 0xb8, 0x82, 0xd2, 0x33, 0x64, 0x4b, 0xd5, 0x35, 0x57, 0xfe,
- 0xdc, 0xf1, 0x23, 0xa0, 0x86, 0xa1, 0x1b, 0xae, 0xf8, 0xf9, 0xe3, 0x62, 0x55, 0xa1, 0x9a, 0xa5,
- 0x6e, 0xaa, 0xd4, 0x30, 0x3d, 0x17, 0x8f, 0x2b, 0x6d, 0xd1, 0x3d, 0x4f, 0x9a, 0x39, 0x2e, 0xf5,
- 0x0e, 0xd4, 0x51, 0x98, 0x18, 0x05, 0x4b, 0x56, 0x64, 0x4b, 0x76, 0x34, 0xb2, 0xbf, 0x09, 0x42,
- 0xf2, 0x7a, 0xb7, 0xad, 0x6a, 0x5b, 0xeb, 0x4e, 0x78, 0x70, 0x06, 0xe2, 0x86, 0xbc, 0x23, 0x75,
- 0xe5, 0xbd, 0xb6, 0x2e, 0x2b, 0x69, 0x34, 0x87, 0xe6, 0x13, 0x04, 0x0c, 0x79, 0xa7, 0xe6, 0xac,
- 0xe0, 0xef, 0x40, 0xc4, 0x13, 0x06, 0xe6, 0xd0, 0x7c, 0x7c, 0xe9, 0xff, 0x72, 0xa3, 0xa1, 0xcc,
- 0xb9, 0x50, 0xc4, 0xd3, 0xc3, 0x45, 0x88, 0x9a, 0xd4, 0xb2, 0x54, 0xad, 0x65, 0xa6, 0x83, 0xcc,
- 0x66, 0x76, 0xdc, 0xa6, 0xb1, 0x5b, 0x77, 0x35, 0xc4, 0xc4, 0x91, 0x18, 0xfa, 0x15, 0x0a, 0xf0,
- 0xe8, 0xfe, 0x7e, 0x86, 0x23, 0x03, 0x4b, 0xfc, 0x43, 0x88, 0x1b, 0xbb, 0x92, 0xb7, 0x81, 0x74,
- 0x68, 0x6e, 0x6a, 0x12, 0x10, 0xd9, 0x5d, 0x77, 0x35, 0x08, 0x18, 0x83, 0x67, 0x5c, 0x82, 0xb8,
- 0x41, 0x9b, 0x54, 0xdd, 0xa6, 0x8a, 0x24, 0x5b, 0xe9, 0xb0, 0xeb, 0x85, 0x13, 0xc3, 0x9c, 0x17,
- 0xc3, 0x5c, 0xc3, 0x0b, 0xb2, 0x18, 0xb5, 0xbf, 0x7e, 0xeb, 0x5f, 0x19, 0x44, 0xc0, 0x33, 0xcc,
- 0x5b, 0xf8, 0x0a, 0x4c, 0x37, 0x75, 0xc3, 0xa0, 0x6d, 0x16, 0x69, 0x49, 0x55, 0xcc, 0x74, 0x64,
- 0x6e, 0x6a, 0x3e, 0x26, 0x0a, 0x47, 0x62, 0xec, 0x36, 0x0a, 0x67, 0x83, 0x46, 0x20, 0xad, 0xf4,
- 0xf7, 0x33, 0xa9, 0xc2, 0x50, 0xad, 0x5c, 0x34, 0x49, 0xca, 0x67, 0x56, 0x56, 0x4c, 0x7c, 0x19,
- 0x66, 0x14, 0xba, 0xad, 0x36, 0xa9, 0xd4, 0xbc, 0x29, 0x6b, 0x1a, 0x6d, 0x4b, 0xaa, 0xa6, 0xd0,
- 0xdd, 0x74, 0x6c, 0x0e, 0xcd, 0x27, 0xc5, 0xe8, 0x91, 0x18, 0x7a, 0x79, 0x2a, 0xfd, 0x15, 0x22,
- 0xd8, 0xd1, 0x2a, 0x38, 0x4a, 0x65, 0x5b, 0x07, 0x57, 0x80, 0x6f, 0xea, 0x9a, 0xd9, 0xeb, 0xd8,
- 0x7b, 0x51, 0x0d, 0x3b, 0x31, 0xd3, 0xc0, 0x36, 0xf4, 0xec, 0xb1, 0x0d, 0x15, 0xdd, 0xa4, 0x64,
- 0xfb, 0x41, 0x9f, 0xd8, 0xfb, 0x99, 0xf6, 0x8c, 0xf3, 0x8e, 0xed, 0xe5, 0xe0, 0xbd, 0x3b, 0x19,
- 0xee, 0x6a, 0x30, 0x1a, 0xe5, 0x63, 0xd9, 0xdf, 0x4d, 0xc1, 0x74, 0x51, 0xdf, 0xd1, 0xfe, 0xdb,
- 0x29, 0xf1, 0x53, 0x48, 0x51, 0x4d, 0x91, 0xdc, 0x33, 0xb0, 0xcf, 0x71, 0x8a, 0x59, 0x5e, 0x18,
- 0xb7, 0x2c, 0x69, 0x4a, 0x91, 0x29, 0x95, 0x87, 0xd5, 0x21, 0xf2, 0xfd, 0xfd, 0x4c, 0x62, 0x28,
- 0x29, 0x9a, 0x24, 0x41, 0x87, 0x7a, 0x26, 0xfe, 0x1e, 0x44, 0x0c, 0xfa, 0x7e, 0x8f, 0x9a, 0x96,
- 0x9b, 0x6f, 0xcf, 0x1e, 0xcf, 0x37, 0xe2, 0x28, 0xac, 0x70, 0xc4, 0xd3, 0xc5, 0x97, 0x21, 0x66,
- 0x36, 0x6f, 0x52, 0xa5, 0xd7, 0xa6, 0x4a, 0x3a, 0xf4, 0xb8, 0x44, 0x5d, 0xe1, 0xc8, 0x50, 0x7d,
- 0x52, 0x66, 0x84, 0xcf, 0x92, 0x19, 0x4e, 0x34, 0xc4, 0xe9, 0x61, 0xc9, 0xe0, 0xa9, 0x47, 0x22,
- 0xca, 0xfe, 0x2d, 0x00, 0x7c, 0x63, 0x37, 0xdf, 0xdc, 0xd2, 0xf4, 0x9d, 0x36, 0x55, 0x5a, 0x1d,
- 0xaa, 0x4d, 0x4c, 0x47, 0x74, 0xa6, 0x74, 0x2c, 0x43, 0xd8, 0xa0, 0x66, 0xaf, 0x6d, 0xb1, 0x00,
- 0xa6, 0x96, 0x5e, 0x3a, 0xbe, 0xed, 0xd1, 0x4f, 0xe7, 0x08, 0x53, 0x67, 0x99, 0xfa, 0x91, 0x5d,
- 0xac, 0xc4, 0x05, 0xc8, 0xfe, 0x11, 0x41, 0xd8, 0x11, 0xe2, 0x38, 0x44, 0xea, 0xd7, 0x0b, 0x85,
- 0x52, 0xbd, 0xce, 0x73, 0xf8, 0x29, 0x48, 0x5e, 0xaf, 0xac, 0x56, 0xaa, 0x6f, 0x55, 0xa4, 0x12,
- 0x21, 0x55, 0xc2, 0x23, 0x9c, 0x80, 0x68, 0xa3, 0x5a, 0x95, 0xd6, 0xf2, 0x8d, 0x12, 0x1f, 0xc0,
- 0x49, 0x88, 0xd9, 0x6f, 0xa5, 0x3c, 0x59, 0xbb, 0xc1, 0x4f, 0xe1, 0x19, 0xe0, 0x0b, 0xd5, 0xb5,
- 0xb5, 0x72, 0xbd, 0x5c, 0xad, 0x48, 0xb5, 0x7c, 0x61, 0xb5, 0xd4, 0xe0, 0x83, 0xa3, 0xab, 0x62,
- 0x29, 0x5f, 0xa8, 0x56, 0xf8, 0x90, 0xfd, 0xa1, 0xc6, 0xdb, 0xd2, 0x32, 0x29, 0x5d, 0xe3, 0xc3,
- 0x0c, 0xf5, 0x6d, 0xa9, 0x56, 0x7d, 0xab, 0x44, 0xf8, 0x08, 0xe6, 0x21, 0x71, 0xa5, 0x56, 0x97,
- 0xae, 0x57, 0xd6, 0xaa, 0x85, 0xd5, 0x52, 0x91, 0x8f, 0x66, 0x3f, 0x42, 0x30, 0x73, 0x45, 0xb6,
- 0xe8, 0x8e, 0xbc, 0x37, 0x4a, 0x7d, 0x25, 0x88, 0xb8, 0x4d, 0x8a, 0xe5, 0x78, 0x7c, 0xe9, 0xb9,
- 0xf1, 0x53, 0x18, 0xd1, 0x1f, 0x12, 0xd5, 0x83, 0xfd, 0x0c, 0x22, 0x9e, 0x2d, 0x7e, 0x1e, 0x22,
- 0x1b, 0xb2, 0xa6, 0x48, 0xaa, 0x53, 0x0d, 0x31, 0x11, 0xfa, 0xfb, 0x99, 0xb0, 0x28, 0x6b, 0x4a,
- 0xb9, 0x48, 0xc2, 0xb6, 0xa8, 0xac, 0x64, 0x1f, 0x86, 0xe0, 0xa9, 0x7c, 0xb7, 0xdb, 0x56, 0x9b,
- 0x2c, 0x06, 0x0e, 0x30, 0xfe, 0x31, 0xa4, 0x4c, 0x6a, 0x9a, 0x76, 0x2c, 0xb7, 0xe8, 0x9e, 0x8d,
- 0xc0, 0x8a, 0x4d, 0x4c, 0x1f, 0x89, 0xa1, 0x0f, 0xa6, 0xd2, 0x1f, 0xb2, 0xbc, 0xaf, 0x3b, 0x1a,
- 0xab, 0x74, 0xaf, 0x5c, 0x24, 0x09, 0x73, 0xf8, 0xa6, 0xe0, 0x0b, 0x10, 0xde, 0x94, 0xba, 0xba,
- 0xe1, 0x84, 0x31, 0x29, 0x26, 0x8f, 0x44, 0x78, 0x39, 0x9a, 0xfe, 0x0a, 0xcd, 0xa3, 0xd7, 0x1e,
- 0x22, 0x12, 0xda, 0xac, 0xe9, 0x86, 0x85, 0x9f, 0x86, 0xd0, 0xa6, 0xd4, 0xd4, 0x2c, 0x56, 0x72,
- 0x49, 0x12, 0xdc, 0x2c, 0x68, 0x16, 0x5e, 0x84, 0xf8, 0xa6, 0xd1, 0x19, 0x14, 0x79, 0x90, 0x7d,
- 0x37, 0xd5, 0xdf, 0xcf, 0xc0, 0x32, 0x59, 0x77, 0x0b, 0x9d, 0xc0, 0xa6, 0xd1, 0xf1, 0x8a, 0xfe,
- 0x0d, 0x98, 0x56, 0x68, 0x53, 0x57, 0xa8, 0x32, 0x30, 0x0a, 0xb9, 0xc5, 0x3f, 0x4e, 0x42, 0x75,
- 0xd6, 0x58, 0x49, 0xca, 0xd5, 0xf7, 0x10, 0x5e, 0x83, 0xf4, 0x18, 0x82, 0xb4, 0x23, 0x1b, 0x1a,
- 0x6b, 0x13, 0x09, 0x3b, 0x8d, 0xc9, 0xb9, 0x51, 0x8b, 0xb7, 0x5c, 0x29, 0x63, 0x73, 0x5f, 0x2b,
- 0x08, 0x3f, 0xae, 0x15, 0xb0, 0x34, 0xbd, 0x8d, 0x02, 0x51, 0x34, 0xd2, 0x14, 0xfc, 0x7d, 0x29,
- 0x72, 0xe6, 0xbe, 0x34, 0xd6, 0x5a, 0xa2, 0x67, 0x6c, 0x2d, 0xdf, 0x87, 0x98, 0xdc, 0xed, 0x4a,
- 0xa6, 0x1d, 0x79, 0xd6, 0x06, 0xe2, 0x4b, 0xff, 0x3f, 0xee, 0xcd, 0x2a, 0xdd, 0x2b, 0x69, 0xdb,
- 0xb4, 0xad, 0x77, 0x29, 0x89, 0xc8, 0xdd, 0x6e, 0x7d, 0x95, 0xee, 0xe1, 0x79, 0x78, 0xaa, 0x2d,
- 0x9b, 0x96, 0x24, 0x4b, 0x2c, 0xaa, 0x92, 0xa2, 0xef, 0x68, 0xac, 0x1f, 0x24, 0x49, 0xd2, 0x16,
- 0xe4, 0x97, 0x0b, 0x9a, 0x65, 0x73, 0x3a, 0x3e, 0x0f, 0xb1, 0xa6, 0xae, 0x6d, 0xaa, 0x46, 0x87,
- 0x2a, 0xe9, 0xf8, 0x1c, 0x9a, 0x8f, 0x92, 0xe1, 0xc2, 0xc4, 0xb6, 0x92, 0x3c, 0x7b, 0x5b, 0xc9,
- 0xfe, 0x25, 0x00, 0x4f, 0xfb, 0x52, 0x7c, 0x4d, 0x77, 0x7e, 0x71, 0x1a, 0x22, 0x26, 0x35, 0x6c,
- 0xaa, 0x66, 0xd9, 0x1d, 0x23, 0xde, 0x2b, 0x5e, 0x86, 0x68, 0xdb, 0xd5, 0x72, 0x1b, 0x49, 0x7a,
- 0xfc, 0x04, 0x3c, 0x14, 0x91, 0xf7, 0x47, 0x83, 0x15, 0xe0, 0xc0, 0x16, 0xff, 0x12, 0x01, 0xc8,
- 0x96, 0x65, 0xa8, 0x1b, 0x3d, 0x8b, 0xda, 0x9d, 0xc5, 0x4e, 0x8f, 0x4b, 0xe3, 0x50, 0x13, 0x7c,
- 0xcb, 0xe5, 0x07, 0x56, 0x25, 0xcd, 0x32, 0xf6, 0xc4, 0x57, 0x8f, 0xc4, 0x8b, 0xbf, 0x47, 0x2f,
- 0x66, 0x2f, 0x18, 0xd9, 0xf4, 0x85, 0x25, 0xe1, 0x67, 0xef, 0xc8, 0x0b, 0x1f, 0x7c, 0x7b, 0xe1,
- 0x07, 0xef, 0xce, 0xbf, 0x7e, 0xf9, 0x9d, 0x85, 0x77, 0x5f, 0xf7, 0x5e, 0x2f, 0xfe, 0x7c, 0xe9,
- 0xd5, 0x5f, 0x5c, 0x20, 0xbe, 0x8f, 0xce, 0xfe, 0x08, 0xa6, 0xc7, 0xc0, 0x30, 0x0f, 0x53, 0x76,
- 0x6c, 0x9d, 0x4d, 0xdb, 0x8f, 0x78, 0x06, 0x42, 0xdb, 0x72, 0xbb, 0x47, 0x1d, 0xa2, 0x20, 0xce,
- 0xcb, 0xe5, 0xc0, 0x6b, 0x28, 0xfb, 0x8f, 0x00, 0x3c, 0xe3, 0x73, 0xf0, 0xaa, 0xae, 0x6a, 0xf9,
- 0x66, 0x93, 0x76, 0xad, 0x6f, 0xcc, 0x11, 0x23, 0x79, 0x16, 0x78, 0x82, 0x3c, 0x7b, 0x1b, 0x9e,
- 0x51, 0x35, 0x6f, 0xe4, 0x56, 0x58, 0x9a, 0xd9, 0xa4, 0xe5, 0x9d, 0xef, 0xf3, 0x27, 0x9c, 0xaf,
- 0x37, 0x51, 0x90, 0x19, 0x1f, 0x82, 0xb7, 0x68, 0xe2, 0x97, 0x60, 0xba, 0x4b, 0x35, 0x45, 0xd5,
- 0x5a, 0x92, 0xeb, 0x2a, 0xe3, 0x9f, 0x28, 0x49, 0xb9, 0xcb, 0xee, 0x76, 0xfe, 0x43, 0xa5, 0x96,
- 0xfd, 0x67, 0x68, 0x24, 0x33, 0x3d, 0x47, 0xfe, 0x47, 0xbf, 0x03, 0xfa, 0x85, 0x13, 0xe9, 0x77,
- 0x84, 0x47, 0xc2, 0xe3, 0x3c, 0x72, 0x05, 0x62, 0xcd, 0xb6, 0x6c, 0x9a, 0xd2, 0x86, 0xd4, 0x74,
- 0x69, 0xf5, 0x95, 0x53, 0xe4, 0x46, 0xae, 0x60, 0x1b, 0x89, 0x05, 0x12, 0x69, 0x3a, 0x0f, 0x78,
- 0x05, 0xa2, 0x5d, 0x43, 0xd5, 0x0d, 0xd5, 0xda, 0x63, 0xa1, 0x4e, 0x2d, 0x65, 0x27, 0xd0, 0xb3,
- 0x3b, 0x81, 0xd5, 0x5c, 0x4d, 0xdf, 0x44, 0x32, 0xb0, 0x9e, 0x34, 0x27, 0xc5, 0xce, 0x32, 0x27,
- 0xcd, 0xfe, 0x01, 0x41, 0xc4, 0xf5, 0x13, 0xaf, 0x42, 0xb4, 0xe5, 0x8c, 0x11, 0xce, 0x25, 0x20,
- 0xbe, 0x74, 0x71, 0xdc, 0x3d, 0x77, 0xcc, 0xc8, 0x6b, 0x16, 0xd5, 0x34, 0xd9, 0x3f, 0xc1, 0x06,
- 0x9d, 0x26, 0xe2, 0x01, 0xe0, 0x12, 0x24, 0xe5, 0x0d, 0x53, 0x6f, 0xf7, 0x2c, 0x2a, 0x31, 0xe6,
- 0x7d, 0x7c, 0x6e, 0x07, 0x59, 0x5e, 0x27, 0x3c, 0xb3, 0xc6, 0x60, 0x94, 0xcf, 0xde, 0x80, 0x99,
- 0x09, 0x07, 0x6c, 0xe2, 0x3c, 0xc4, 0x86, 0x55, 0x8b, 0x4e, 0x5f, 0xb5, 0x43, 0xab, 0xec, 0x5d,
- 0x04, 0xcf, 0x4e, 0x50, 0x59, 0x96, 0x55, 0x7b, 0x08, 0xbe, 0x06, 0x51, 0x4f, 0xd5, 0x1d, 0xa1,
- 0x4e, 0x83, 0x3f, 0x89, 0xcb, 0x3d, 0x18, 0xfc, 0x06, 0x84, 0xd8, 0xb5, 0xd9, 0xa5, 0xaa, 0xf3,
- 0xc7, 0xee, 0x07, 0xb6, 0xb0, 0x48, 0x2d, 0x59, 0x6d, 0x8f, 0xb7, 0x68, 0xc7, 0x30, 0xfb, 0x5b,
- 0x04, 0x19, 0xdf, 0x57, 0xcb, 0x93, 0x18, 0x68, 0xf5, 0x6c, 0x27, 0xe3, 0x9b, 0x2b, 0x86, 0xf6,
- 0xf8, 0x05, 0x98, 0x66, 0x0d, 0xd9, 0xd7, 0x8e, 0x19, 0x1f, 0x90, 0x84, 0xbd, 0xec, 0x75, 0xe3,
- 0xac, 0x04, 0xe7, 0x7c, 0x90, 0x75, 0xa7, 0x07, 0x16, 0xed, 0xb9, 0xe4, 0xeb, 0x3b, 0xe4, 0x2b,
- 0x10, 0x64, 0x13, 0x4f, 0xe0, 0xe4, 0x52, 0x67, 0x4a, 0xd9, 0xbf, 0x47, 0x21, 0x39, 0x32, 0x63,
- 0x4e, 0xb8, 0x75, 0xa1, 0x27, 0xb9, 0x75, 0x1d, 0x0b, 0xd3, 0xe8, 0xad, 0x6b, 0x42, 0x95, 0x05,
- 0xce, 0x74, 0x1b, 0xc9, 0x8f, 0xd2, 0x7c, 0xe2, 0x94, 0xa5, 0xe0, 0x9f, 0xa6, 0xae, 0x42, 0xaa,
- 0xc7, 0x66, 0x6a, 0xc9, 0x1b, 0xe9, 0x9d, 0xfb, 0xe5, 0xb7, 0x4e, 0x88, 0xaa, 0x33, 0x84, 0xaf,
- 0x70, 0x24, 0xd9, 0x1b, 0xb9, 0x17, 0xac, 0x40, 0xfc, 0x3d, 0x5d, 0xd5, 0x24, 0x99, 0x35, 0x60,
- 0xf7, 0x46, 0xf9, 0xc2, 0x09, 0x40, 0xc3, 0x6e, 0xbd, 0xc2, 0x11, 0x78, 0x6f, 0xd8, 0xbb, 0x57,
- 0x20, 0xe1, 0xa5, 0x89, 0x24, 0x37, 0xb7, 0x5c, 0xc6, 0x3e, 0x4d, 0xa6, 0xad, 0x70, 0x24, 0xee,
- 0x99, 0xe6, 0x9b, 0x5b, 0xf8, 0x2a, 0x24, 0x07, 0x48, 0x9a, 0x0d, 0x15, 0x7e, 0x12, 0xa8, 0x81,
- 0x17, 0x15, 0x79, 0x0c, 0xcb, 0xa4, 0x9a, 0xe5, 0x92, 0xf6, 0x93, 0x62, 0xd5, 0xed, 0x1b, 0x69,
- 0x03, 0xa6, 0x07, 0x58, 0x9b, 0x8c, 0x14, 0x5c, 0x26, 0xbb, 0x78, 0x0a, 0x34, 0x87, 0x45, 0x56,
- 0x38, 0x92, 0x52, 0x46, 0x79, 0xa5, 0xe2, 0x43, 0x7d, 0xbf, 0x47, 0x7b, 0x54, 0x71, 0x27, 0xe4,
- 0x53, 0xfa, 0x38, 0xc0, 0xbb, 0xc6, 0x8c, 0xb1, 0x0e, 0xb3, 0xa3, 0x78, 0x92, 0x6f, 0x2e, 0x71,
- 0xff, 0x4b, 0x59, 0x3c, 0x01, 0x7a, 0x12, 0x87, 0xac, 0x70, 0x24, 0x3d, 0xf2, 0x19, 0x9f, 0x92,
- 0xbd, 0x01, 0x6f, 0x3a, 0x95, 0x4c, 0xbd, 0xbd, 0xed, 0xce, 0xdf, 0x27, 0x6f, 0xc0, 0x9b, 0x4a,
- 0xed, 0x0d, 0x78, 0xd6, 0x75, 0x66, 0x8c, 0x57, 0x21, 0xe1, 0x52, 0x82, 0xc4, 0xf8, 0xc0, 0x99,
- 0xd3, 0x5f, 0x3c, 0x01, 0xcc, 0xc7, 0x2f, 0x76, 0x2e, 0x99, 0x3e, 0xba, 0x39, 0x0f, 0x31, 0x53,
- 0xed, 0xf4, 0xda, 0x6c, 0xf3, 0x29, 0xa7, 0x9d, 0x0f, 0x16, 0xc4, 0x18, 0x04, 0x7a, 0x5d, 0xe7,
- 0x3f, 0x88, 0x3f, 0x07, 0x20, 0xed, 0x16, 0x85, 0x3b, 0x12, 0x2c, 0xeb, 0x46, 0x47, 0xb6, 0x2c,
- 0x6a, 0x98, 0x78, 0x1d, 0x12, 0xbd, 0xae, 0xb4, 0xe9, 0x2d, 0x30, 0x66, 0x49, 0x2d, 0xcd, 0x8d,
- 0xbb, 0x34, 0x6e, 0xe8, 0xeb, 0xd7, 0xf1, 0x5e, 0x77, 0xb0, 0x8c, 0xbf, 0x0b, 0xe7, 0xfc, 0x70,
- 0x52, 0x57, 0x36, 0xe4, 0x0e, 0xb5, 0x81, 0x9d, 0x59, 0x79, 0xc6, 0xa7, 0x5c, 0xf3, 0x64, 0xf8,
- 0x1a, 0xb0, 0x50, 0xfb, 0xdc, 0x98, 0x7a, 0x62, 0x37, 0x58, 0x31, 0x0c, 0x1d, 0xb1, 0xc7, 0xa4,
- 0x11, 0x48, 0x9f, 0x2b, 0x41, 0xe6, 0xca, 0xb9, 0x11, 0x83, 0x81, 0x33, 0xd9, 0xbf, 0x22, 0x98,
- 0x29, 0xfa, 0x33, 0xc2, 0xfd, 0xcb, 0x09, 0x37, 0xbe, 0x11, 0x0d, 0x47, 0xbf, 0x86, 0x7e, 0xd7,
- 0xfd, 0x3d, 0x2c, 0x70, 0xfa, 0x1e, 0x06, 0x47, 0x62, 0xe4, 0x36, 0x0a, 0xf2, 0x77, 0x7e, 0x1d,
- 0xf6, 0x75, 0xb1, 0x97, 0x6f, 0x21, 0xe0, 0xc7, 0x4f, 0x09, 0x63, 0x48, 0x2d, 0x57, 0xc9, 0x7a,
- 0xbe, 0xd1, 0x28, 0x11, 0xa9, 0x52, 0xad, 0x94, 0x78, 0x0e, 0xa7, 0x61, 0x66, 0xb8, 0x46, 0x4a,
- 0xb5, 0x6a, 0xbd, 0xdc, 0xa8, 0x92, 0x1b, 0x3c, 0xc2, 0xb3, 0x70, 0x6e, 0x28, 0xb9, 0x42, 0x6a,
- 0x05, 0xa9, 0x5e, 0x22, 0x6f, 0x96, 0x0b, 0x25, 0x3e, 0x30, 0x6a, 0x75, 0x35, 0xff, 0x66, 0xbe,
- 0x5e, 0x20, 0xe5, 0x5a, 0x83, 0x9f, 0x1a, 0x95, 0x14, 0xf2, 0x37, 0x4a, 0x95, 0x4a, 0x69, 0xad,
- 0x56, 0xe3, 0x83, 0xe2, 0x9f, 0xd0, 0xfd, 0x03, 0x01, 0x3d, 0x38, 0x10, 0xd0, 0xe7, 0x07, 0x02,
- 0xf7, 0xf0, 0x40, 0xe0, 0xbe, 0x38, 0x10, 0xb8, 0x2f, 0x0f, 0x04, 0xee, 0xd1, 0x81, 0x80, 0x3e,
- 0xec, 0x0b, 0xe8, 0xe3, 0xbe, 0xc0, 0x7d, 0xda, 0x17, 0xd0, 0xdd, 0xbe, 0xc0, 0xdd, 0xeb, 0x0b,
- 0xdc, 0x67, 0x7d, 0x81, 0xbb, 0xdf, 0x17, 0xd0, 0x83, 0xbe, 0x80, 0x3e, 0xef, 0x0b, 0xdc, 0xc3,
- 0xbe, 0x80, 0xbe, 0xe8, 0x0b, 0xdc, 0x97, 0x7d, 0x01, 0x3d, 0xea, 0x0b, 0xdc, 0x87, 0x87, 0x02,
- 0xf7, 0xf1, 0xa1, 0x80, 0x6e, 0x1d, 0x0a, 0xdc, 0x27, 0x87, 0x02, 0xba, 0x73, 0x28, 0x70, 0x9f,
- 0x1e, 0x0a, 0xdc, 0xdd, 0x43, 0x01, 0xdd, 0x3b, 0x14, 0xd0, 0x67, 0x87, 0x02, 0xfa, 0xc9, 0x62,
- 0x4b, 0xcf, 0x59, 0x37, 0xa9, 0x75, 0xd3, 0x1e, 0x7e, 0x73, 0x1a, 0xb5, 0x76, 0x74, 0x63, 0x6b,
- 0x71, 0xf4, 0xbf, 0xf5, 0xed, 0x4b, 0x8b, 0xdd, 0xad, 0xd6, 0xa2, 0x65, 0x69, 0xdd, 0x8d, 0x8d,
- 0x30, 0x6b, 0x51, 0x97, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x2f, 0x2e, 0xfc, 0x2b, 0x06, 0x19,
- 0x00, 0x00,
+ // 2357 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0x4d, 0x6c, 0x1b, 0xc7,
+ 0x15, 0xde, 0xa1, 0xf8, 0xfb, 0xf8, 0xa3, 0xcd, 0x44, 0x71, 0x19, 0xd5, 0x59, 0xaa, 0x8c, 0x93,
+ 0xc8, 0x49, 0x44, 0xa5, 0x72, 0x8b, 0xa6, 0x2e, 0xda, 0x84, 0x4b, 0x52, 0x16, 0x2d, 0x89, 0xa4,
+ 0x87, 0x74, 0x12, 0x37, 0x4d, 0x17, 0x2b, 0xee, 0x88, 0xde, 0x88, 0xdc, 0x65, 0x76, 0x97, 0xfa,
+ 0x49, 0x51, 0x20, 0xcd, 0x29, 0x28, 0xd0, 0x22, 0x30, 0xd0, 0x22, 0x28, 0xd0, 0xc2, 0x97, 0x02,
+ 0x39, 0xf4, 0xe0, 0xa3, 0xd1, 0x5e, 0x72, 0xab, 0x4f, 0x85, 0x8f, 0x41, 0x81, 0xaa, 0x16, 0x75,
+ 0xc9, 0x31, 0x47, 0x43, 0x97, 0x14, 0x3b, 0xbb, 0x4b, 0x2e, 0x29, 0x46, 0x96, 0x95, 0xf6, 0xd6,
+ 0x1b, 0x77, 0xde, 0x7b, 0xdf, 0xbc, 0x99, 0xf7, 0xf3, 0xbd, 0x91, 0x60, 0xae, 0xad, 0x1b, 0xf2,
+ 0x8e, 0xac, 0x2d, 0x98, 0x96, 0xdc, 0xdc, 0x5a, 0x94, 0xbb, 0xea, 0x62, 0x87, 0x9a, 0xa6, 0xdc,
+ 0xa2, 0x66, 0xae, 0x6b, 0xe8, 0x96, 0x8e, 0x53, 0x96, 0xa5, 0xe5, 0x5c, 0xad, 0xdc, 0xf6, 0xa5,
+ 0xd9, 0x7c, 0x4b, 0xb5, 0x6e, 0xf6, 0x36, 0x72, 0x4d, 0xbd, 0xb3, 0x48, 0xb5, 0x6d, 0x7d, 0xaf,
+ 0x6b, 0xe8, 0xbb, 0x7b, 0x8b, 0x4c, 0xb9, 0xb9, 0xd0, 0xa2, 0xda, 0xc2, 0xb6, 0xdc, 0x56, 0x15,
+ 0xd9, 0xa2, 0x8b, 0xc7, 0x7e, 0x38, 0x90, 0xb3, 0x0b, 0x3e, 0x88, 0x96, 0xde, 0xd2, 0x1d, 0xe3,
+ 0x8d, 0xde, 0x26, 0xfb, 0x62, 0x1f, 0xec, 0x97, 0xab, 0x7e, 0xbe, 0xa5, 0xeb, 0xad, 0x36, 0x1d,
+ 0x6a, 0x99, 0x96, 0xd1, 0x6b, 0x5a, 0xae, 0x34, 0x33, 0x2e, 0xb5, 0xd4, 0x0e, 0x35, 0x2d, 0xb9,
+ 0xd3, 0x75, 0x15, 0x84, 0x71, 0x05, 0xa5, 0x67, 0xc8, 0x96, 0xaa, 0x6b, 0xae, 0xfc, 0x99, 0xe3,
+ 0x57, 0x40, 0x0d, 0x43, 0x37, 0x5c, 0xf1, 0xb3, 0xc7, 0xc5, 0xaa, 0x42, 0x35, 0x4b, 0xdd, 0x54,
+ 0xa9, 0x61, 0x7a, 0x2e, 0x1e, 0x57, 0xda, 0xa2, 0x7b, 0x9e, 0x34, 0x73, 0x5c, 0xea, 0x5d, 0xa8,
+ 0xa3, 0x30, 0x31, 0x0a, 0x96, 0xac, 0xc8, 0x96, 0xec, 0x68, 0x64, 0x7f, 0x1b, 0x84, 0xe4, 0xf5,
+ 0x6e, 0x5b, 0xd5, 0xb6, 0xd6, 0x9d, 0xf0, 0xe0, 0x0c, 0xc4, 0x0d, 0x79, 0x47, 0xea, 0xca, 0x7b,
+ 0x6d, 0x5d, 0x56, 0xd2, 0x68, 0x0e, 0xcd, 0x27, 0x08, 0x18, 0xf2, 0x4e, 0xcd, 0x59, 0xc1, 0xdf,
+ 0x85, 0x88, 0x27, 0x0c, 0xcc, 0xa1, 0xf9, 0xf8, 0xd2, 0xb7, 0x72, 0xa3, 0xa1, 0xcc, 0xb9, 0x50,
+ 0xc4, 0xd3, 0xc3, 0x45, 0x88, 0x9a, 0xd4, 0xb2, 0x54, 0xad, 0x65, 0xa6, 0x83, 0xcc, 0x66, 0x76,
+ 0xdc, 0xa6, 0xb1, 0x5b, 0x77, 0x35, 0xc4, 0xc4, 0x91, 0x18, 0xfa, 0x35, 0x0a, 0xf0, 0xe8, 0xde,
+ 0x7e, 0x86, 0x23, 0x03, 0x4b, 0xfc, 0x23, 0x88, 0x1b, 0xbb, 0x92, 0x77, 0x80, 0x74, 0x68, 0x6e,
+ 0x6a, 0x12, 0x10, 0xd9, 0x5d, 0x77, 0x35, 0x08, 0x18, 0x83, 0xdf, 0xb8, 0x04, 0x71, 0x83, 0x36,
+ 0xa9, 0xba, 0x4d, 0x15, 0x49, 0xb6, 0xd2, 0x61, 0xd7, 0x0b, 0x27, 0x86, 0x39, 0x2f, 0x86, 0xb9,
+ 0x86, 0x17, 0x64, 0x31, 0x6a, 0xef, 0xfe, 0xf1, 0xbf, 0x33, 0x88, 0x80, 0x67, 0x98, 0xb7, 0xf0,
+ 0x15, 0x98, 0x6e, 0xea, 0x86, 0x41, 0xdb, 0x2c, 0xd2, 0x92, 0xaa, 0x98, 0xe9, 0xc8, 0xdc, 0xd4,
+ 0x7c, 0x4c, 0x14, 0x8e, 0xc4, 0xd8, 0x2d, 0x14, 0xce, 0x06, 0x8d, 0x40, 0x5a, 0xe9, 0xef, 0x67,
+ 0x52, 0x85, 0xa1, 0x5a, 0xb9, 0x68, 0x92, 0x94, 0xcf, 0xac, 0xac, 0x98, 0xf8, 0x32, 0xcc, 0x28,
+ 0x74, 0x5b, 0x6d, 0x52, 0xa9, 0x79, 0x53, 0xd6, 0x34, 0xda, 0x96, 0x54, 0x4d, 0xa1, 0xbb, 0xe9,
+ 0xd8, 0x1c, 0x9a, 0x4f, 0x8a, 0xd1, 0x23, 0x31, 0xf4, 0xe2, 0x54, 0xfa, 0x2b, 0x44, 0xb0, 0xa3,
+ 0x55, 0x70, 0x94, 0xca, 0xb6, 0x0e, 0xae, 0x00, 0xdf, 0xd4, 0x35, 0xb3, 0xd7, 0xb1, 0xcf, 0xa2,
+ 0x1a, 0x76, 0x62, 0xa6, 0x81, 0x1d, 0xe8, 0xe9, 0x63, 0x07, 0x2a, 0xba, 0x49, 0xc9, 0xce, 0x83,
+ 0x3e, 0xb1, 0xcf, 0x33, 0xed, 0x19, 0xe7, 0x1d, 0xdb, 0xcb, 0xc1, 0xbb, 0xb7, 0x33, 0xdc, 0xd5,
+ 0x60, 0x34, 0xca, 0xc7, 0xb2, 0xbf, 0x9f, 0x82, 0xe9, 0xa2, 0xbe, 0xa3, 0xfd, 0xaf, 0x53, 0xe2,
+ 0x67, 0x90, 0xa2, 0x9a, 0x22, 0xb9, 0x77, 0x60, 0xdf, 0xe3, 0x14, 0xb3, 0xbc, 0x30, 0x6e, 0x59,
+ 0xd2, 0x94, 0x22, 0x53, 0x2a, 0x0f, 0xab, 0x43, 0xe4, 0xfb, 0xfb, 0x99, 0xc4, 0x50, 0x52, 0x34,
+ 0x49, 0x82, 0x0e, 0xf5, 0x4c, 0xfc, 0x7d, 0x88, 0x18, 0xf4, 0xbd, 0x1e, 0x35, 0x2d, 0x37, 0xdf,
+ 0x9e, 0x3e, 0x9e, 0x6f, 0xc4, 0x51, 0x58, 0xe1, 0x88, 0xa7, 0x8b, 0x2f, 0x43, 0xcc, 0x6c, 0xde,
+ 0xa4, 0x4a, 0xaf, 0x4d, 0x95, 0x74, 0xe8, 0x51, 0x89, 0xba, 0xc2, 0x91, 0xa1, 0xfa, 0xa4, 0xcc,
+ 0x08, 0x9f, 0x25, 0x33, 0x9c, 0x68, 0x88, 0xd3, 0xc3, 0x92, 0xc1, 0x53, 0x0f, 0x45, 0x94, 0xfd,
+ 0x7b, 0x00, 0xf8, 0xc6, 0x6e, 0xbe, 0xb9, 0xa5, 0xe9, 0x3b, 0x6d, 0xaa, 0xb4, 0x3a, 0x54, 0x9b,
+ 0x98, 0x8e, 0xe8, 0x4c, 0xe9, 0x58, 0x86, 0xb0, 0x41, 0xcd, 0x5e, 0xdb, 0x62, 0x01, 0x4c, 0x2d,
+ 0xbd, 0x70, 0xfc, 0xd8, 0xa3, 0x5b, 0xe7, 0x08, 0x53, 0x67, 0x99, 0xfa, 0xa1, 0x5d, 0xac, 0xc4,
+ 0x05, 0xc8, 0xfe, 0x09, 0x41, 0xd8, 0x11, 0xe2, 0x38, 0x44, 0xea, 0xd7, 0x0b, 0x85, 0x52, 0xbd,
+ 0xce, 0x73, 0xf8, 0x09, 0x48, 0x5e, 0xaf, 0xac, 0x56, 0xaa, 0x6f, 0x56, 0xa4, 0x12, 0x21, 0x55,
+ 0xc2, 0x23, 0x9c, 0x80, 0x68, 0xa3, 0x5a, 0x95, 0xd6, 0xf2, 0x8d, 0x12, 0x1f, 0xc0, 0x49, 0x88,
+ 0xd9, 0x5f, 0xa5, 0x3c, 0x59, 0xbb, 0xc1, 0x4f, 0xe1, 0x19, 0xe0, 0x0b, 0xd5, 0xb5, 0xb5, 0x72,
+ 0xbd, 0x5c, 0xad, 0x48, 0xb5, 0x7c, 0x61, 0xb5, 0xd4, 0xe0, 0x83, 0xa3, 0xab, 0x62, 0x29, 0x5f,
+ 0xa8, 0x56, 0xf8, 0x90, 0xbd, 0x51, 0xe3, 0x2d, 0x69, 0x99, 0x94, 0xae, 0xf1, 0x61, 0x86, 0xfa,
+ 0x96, 0x54, 0xab, 0xbe, 0x59, 0x22, 0x7c, 0x04, 0xf3, 0x90, 0xb8, 0x52, 0xab, 0x4b, 0xd7, 0x2b,
+ 0x6b, 0xd5, 0xc2, 0x6a, 0xa9, 0xc8, 0x47, 0xb3, 0x1f, 0x22, 0x98, 0xb9, 0x22, 0x5b, 0x74, 0x47,
+ 0xde, 0x1b, 0x6d, 0x7d, 0x25, 0x88, 0xb8, 0x24, 0xc5, 0x72, 0x3c, 0xbe, 0xf4, 0xcc, 0xf8, 0x2d,
+ 0x8c, 0xe8, 0x0f, 0x1b, 0xd5, 0xfd, 0xfd, 0x0c, 0x22, 0x9e, 0x2d, 0x7e, 0x16, 0x22, 0x1b, 0xb2,
+ 0xa6, 0x48, 0xaa, 0x53, 0x0d, 0x31, 0x11, 0xfa, 0xfb, 0x99, 0xb0, 0x28, 0x6b, 0x4a, 0xb9, 0x48,
+ 0xc2, 0xb6, 0xa8, 0xac, 0x64, 0x3f, 0x8a, 0xc0, 0x13, 0xf9, 0x6e, 0xb7, 0xad, 0x36, 0x59, 0x0c,
+ 0x1c, 0x60, 0xfc, 0x13, 0x48, 0x99, 0xd4, 0x34, 0xed, 0x58, 0x6e, 0xd1, 0x3d, 0x1b, 0x81, 0x15,
+ 0x9b, 0x98, 0x3e, 0x12, 0x43, 0xef, 0x4f, 0xa5, 0x3f, 0x60, 0x79, 0x5f, 0x77, 0x34, 0x56, 0xe9,
+ 0x5e, 0xb9, 0x48, 0x12, 0xe6, 0xf0, 0x4b, 0xc1, 0x17, 0x20, 0xbc, 0x29, 0x75, 0x75, 0xc3, 0x09,
+ 0x63, 0x52, 0x4c, 0x1e, 0x89, 0xf0, 0x62, 0x34, 0xfd, 0x15, 0x9a, 0x47, 0xaf, 0x3e, 0x40, 0x24,
+ 0xb4, 0x59, 0xd3, 0x0d, 0x0b, 0x3f, 0x09, 0xa1, 0x4d, 0xa9, 0xa9, 0x59, 0xac, 0xe4, 0x92, 0x24,
+ 0xb8, 0x59, 0xd0, 0x2c, 0xbc, 0x08, 0xf1, 0x4d, 0xa3, 0x33, 0x28, 0xf2, 0x20, 0xdb, 0x37, 0xd5,
+ 0xdf, 0xcf, 0xc0, 0x32, 0x59, 0x77, 0x0b, 0x9d, 0xc0, 0xa6, 0xd1, 0xf1, 0x8a, 0xfe, 0x75, 0x98,
+ 0x56, 0x68, 0x53, 0x57, 0xa8, 0x32, 0x30, 0x0a, 0xb9, 0xc5, 0x3f, 0xde, 0x84, 0xea, 0x8c, 0x58,
+ 0x49, 0xca, 0xd5, 0xf7, 0x10, 0x5e, 0x85, 0xf4, 0x18, 0x82, 0xb4, 0x23, 0x1b, 0x1a, 0xa3, 0x89,
+ 0x84, 0x9d, 0xc6, 0xe4, 0xdc, 0xa8, 0xc5, 0x9b, 0xae, 0x94, 0x75, 0x73, 0x1f, 0x15, 0x84, 0x1f,
+ 0x45, 0x05, 0x2c, 0x4d, 0x6f, 0xa1, 0x40, 0x14, 0x8d, 0x90, 0x82, 0x9f, 0x97, 0x22, 0x67, 0xe6,
+ 0xa5, 0x31, 0x6a, 0x89, 0x9e, 0x91, 0x5a, 0x7e, 0x00, 0x31, 0xb9, 0xdb, 0x95, 0x4c, 0x3b, 0xf2,
+ 0x8c, 0x06, 0xe2, 0x4b, 0xdf, 0x1e, 0xf7, 0x66, 0x95, 0xee, 0x95, 0xb4, 0x6d, 0xda, 0xd6, 0xbb,
+ 0x94, 0x44, 0xe4, 0x6e, 0xb7, 0xbe, 0x4a, 0xf7, 0xf0, 0x3c, 0x3c, 0xd1, 0x96, 0x4d, 0x4b, 0x92,
+ 0x25, 0x16, 0x55, 0x49, 0xd1, 0x77, 0x34, 0xc6, 0x07, 0x49, 0x92, 0xb4, 0x05, 0xf9, 0xe5, 0x82,
+ 0x66, 0xd9, 0x3d, 0x1d, 0x9f, 0x87, 0x58, 0x53, 0xd7, 0x36, 0x55, 0xa3, 0x43, 0x95, 0x74, 0x7c,
+ 0x0e, 0xcd, 0x47, 0xc9, 0x70, 0x61, 0x22, 0xad, 0x24, 0xcf, 0x4e, 0x2b, 0xb8, 0x02, 0xb1, 0xb6,
+ 0xee, 0xa4, 0xb7, 0x99, 0x4e, 0xb1, 0x10, 0xbd, 0x32, 0x7e, 0xa0, 0x63, 0x25, 0x90, 0x5b, 0xf3,
+ 0x4c, 0x4a, 0x9a, 0x65, 0xec, 0x91, 0x21, 0xc4, 0xec, 0x1b, 0x90, 0x1a, 0x15, 0x62, 0x1e, 0xa6,
+ 0xec, 0xcb, 0xb2, 0x6b, 0x24, 0x46, 0xec, 0x9f, 0x38, 0x07, 0xa1, 0x6d, 0xb9, 0xdd, 0xa3, 0x2e,
+ 0x0f, 0xa5, 0xc7, 0xf7, 0xf3, 0x00, 0x88, 0xa3, 0x76, 0x39, 0xf0, 0x2a, 0xca, 0xfe, 0x35, 0x00,
+ 0x4f, 0xfa, 0xfc, 0xf0, 0x54, 0x70, 0x1a, 0x22, 0x26, 0x35, 0x6c, 0x4a, 0x71, 0x77, 0xf0, 0x3e,
+ 0xf1, 0x32, 0x44, 0x3d, 0xb7, 0x1e, 0xb5, 0x91, 0xc8, 0xfb, 0xb3, 0x86, 0x35, 0x8a, 0x81, 0x2d,
+ 0xfe, 0x15, 0x02, 0x90, 0x2d, 0xcb, 0x50, 0x37, 0x7a, 0x16, 0xb5, 0x19, 0xd0, 0xbe, 0xa3, 0x4b,
+ 0x27, 0xdc, 0x91, 0x87, 0x9a, 0xcb, 0x0f, 0xac, 0xd8, 0x4d, 0x88, 0x2f, 0x1f, 0x89, 0x17, 0xff,
+ 0x80, 0x9e, 0xcf, 0x5e, 0x30, 0xb2, 0xe9, 0x0b, 0x4b, 0xc2, 0xcf, 0xdf, 0x96, 0x17, 0xde, 0x7f,
+ 0x65, 0xe1, 0x87, 0xef, 0xcc, 0xbf, 0x76, 0xf9, 0xed, 0x85, 0x77, 0x5e, 0xf3, 0x3e, 0x2f, 0xfe,
+ 0x62, 0xe9, 0xe5, 0x5f, 0x5e, 0x20, 0xbe, 0x4d, 0x67, 0x7f, 0x0c, 0xd3, 0x63, 0x60, 0x13, 0xae,
+ 0x75, 0xc6, 0x7f, 0xad, 0x31, 0xff, 0xe5, 0xfd, 0x33, 0x00, 0x4f, 0xf9, 0x1c, 0xbc, 0xaa, 0xab,
+ 0x5a, 0xbe, 0xd9, 0xa4, 0x5d, 0xeb, 0x1b, 0xf7, 0xb2, 0x91, 0x7a, 0x08, 0x3c, 0x46, 0x3d, 0xbc,
+ 0x05, 0x4f, 0xa9, 0x9a, 0xf7, 0x34, 0x50, 0x58, 0x39, 0xd8, 0x99, 0xe5, 0xdd, 0xef, 0xb3, 0x27,
+ 0xdc, 0xaf, 0x37, 0xf9, 0x90, 0x19, 0x1f, 0x82, 0xb7, 0x68, 0xe2, 0x17, 0x60, 0xba, 0x4b, 0x35,
+ 0x45, 0xd5, 0x5a, 0x92, 0xeb, 0x2a, 0xeb, 0x93, 0x51, 0x92, 0x72, 0x97, 0xdd, 0xe3, 0xfc, 0x97,
+ 0x5a, 0x42, 0xf6, 0x5f, 0xa1, 0x91, 0xcc, 0xf4, 0x1c, 0xf9, 0x3f, 0x4d, 0x0c, 0x68, 0x02, 0x4e,
+ 0xa4, 0x89, 0x91, 0x7e, 0x17, 0x1e, 0xef, 0x77, 0x57, 0x20, 0xd6, 0x6c, 0xcb, 0xa6, 0x29, 0x6d,
+ 0x48, 0x4d, 0xb7, 0xfd, 0xbf, 0x74, 0x8a, 0xdc, 0xc8, 0x15, 0x6c, 0x23, 0xb1, 0x40, 0x22, 0x4d,
+ 0xe7, 0x07, 0x5e, 0x81, 0x68, 0xd7, 0x50, 0x75, 0x43, 0xb5, 0xf6, 0x58, 0xa8, 0x53, 0x4b, 0xd9,
+ 0x09, 0x34, 0xe2, 0x4e, 0x8a, 0x35, 0x57, 0xd3, 0x37, 0x39, 0x0d, 0xac, 0x27, 0xcd, 0x73, 0xb1,
+ 0xb3, 0xcc, 0x73, 0xb3, 0x7f, 0x44, 0x10, 0x71, 0xfd, 0xc4, 0xab, 0x10, 0x6d, 0x39, 0xe3, 0x8e,
+ 0xf3, 0x58, 0x89, 0x2f, 0x5d, 0x1c, 0x77, 0xcf, 0x1d, 0x87, 0xf2, 0x9a, 0x45, 0x35, 0x4d, 0xf6,
+ 0x4f, 0xda, 0x41, 0x87, 0xec, 0x3c, 0x00, 0x5c, 0x82, 0xa4, 0xbc, 0x61, 0xea, 0xed, 0x9e, 0x45,
+ 0x25, 0xc6, 0x10, 0x8f, 0xce, 0xed, 0x20, 0xcb, 0xeb, 0x84, 0x67, 0xd6, 0x18, 0x3c, 0x39, 0xb2,
+ 0x37, 0x60, 0x66, 0xc2, 0x05, 0x9b, 0x38, 0x0f, 0xb1, 0x61, 0xd5, 0xa2, 0xd3, 0x57, 0xed, 0xd0,
+ 0x2a, 0x7b, 0x07, 0xc1, 0xd3, 0x13, 0x54, 0x96, 0x65, 0xd5, 0x1e, 0xd6, 0xaf, 0x41, 0xd4, 0x53,
+ 0x75, 0x47, 0xbd, 0xd3, 0xe0, 0x4f, 0xea, 0xe5, 0x1e, 0x0c, 0x7e, 0x1d, 0x42, 0xec, 0x79, 0xef,
+ 0xb6, 0xaa, 0xf3, 0xc7, 0xde, 0x31, 0xb6, 0xb0, 0x48, 0x2d, 0x59, 0x6d, 0x8f, 0x8f, 0x12, 0x8e,
+ 0x61, 0xf6, 0x77, 0x08, 0x32, 0xbe, 0x5d, 0xcb, 0x93, 0x3a, 0xd0, 0xea, 0xd9, 0x6e, 0xc6, 0x37,
+ 0xff, 0x0c, 0xed, 0xf1, 0x73, 0x30, 0xcd, 0x06, 0x07, 0xdf, 0xd8, 0xc0, 0xfa, 0x01, 0x49, 0xd8,
+ 0xcb, 0xde, 0xd4, 0x90, 0x95, 0xe0, 0x9c, 0x0f, 0xb2, 0xee, 0x70, 0x60, 0xd1, 0x9e, 0x9f, 0xbe,
+ 0x9e, 0x21, 0x5f, 0x82, 0x20, 0x9b, 0xcc, 0x02, 0x27, 0x97, 0x3a, 0x53, 0xca, 0xfe, 0x23, 0x0a,
+ 0xc9, 0x91, 0x41, 0x60, 0xc2, 0xeb, 0x10, 0x3d, 0xce, 0xeb, 0xf0, 0x58, 0x98, 0x46, 0x5f, 0x87,
+ 0x13, 0xaa, 0x2c, 0x70, 0xa6, 0x57, 0x53, 0x7e, 0xb4, 0xcd, 0x27, 0x4e, 0x59, 0x0a, 0xfe, 0xa9,
+ 0xef, 0x2a, 0xa4, 0x7a, 0x6c, 0xf0, 0x91, 0xbc, 0xa7, 0x87, 0xf3, 0x0e, 0xfe, 0xce, 0x23, 0x27,
+ 0xa5, 0x15, 0x8e, 0x24, 0x7b, 0x23, 0xef, 0x97, 0x15, 0x88, 0xbf, 0xab, 0xab, 0x9a, 0x24, 0x33,
+ 0x02, 0x76, 0x5f, 0xbe, 0xcf, 0x9d, 0x00, 0x34, 0x64, 0xeb, 0x15, 0x8e, 0xc0, 0xbb, 0x43, 0xee,
+ 0x5e, 0x81, 0x84, 0x97, 0x26, 0x92, 0xdc, 0xdc, 0x72, 0x3b, 0xf6, 0x69, 0x32, 0x6d, 0x85, 0x23,
+ 0x71, 0xcf, 0x34, 0xdf, 0xdc, 0xc2, 0x57, 0x21, 0x39, 0x40, 0xd2, 0x6c, 0xa8, 0xf0, 0xe3, 0x40,
+ 0x0d, 0xbc, 0xa8, 0xc8, 0x63, 0x58, 0x26, 0xd5, 0x2c, 0xb7, 0x69, 0x3f, 0x2e, 0x56, 0xdd, 0x7e,
+ 0x39, 0x37, 0x60, 0x7a, 0x80, 0xb5, 0xc9, 0x9a, 0x82, 0xdb, 0xc9, 0x2e, 0x9e, 0x02, 0xcd, 0xe9,
+ 0x22, 0x2b, 0x1c, 0x49, 0x29, 0xa3, 0x7d, 0xa5, 0xe2, 0x43, 0x7d, 0xaf, 0x47, 0x7b, 0x54, 0x71,
+ 0x27, 0xf9, 0x53, 0xfa, 0x38, 0xc0, 0xbb, 0xc6, 0x8c, 0xb1, 0x0e, 0xb3, 0xa3, 0x78, 0x92, 0x6f,
+ 0x2e, 0x71, 0xff, 0xe6, 0xb3, 0x78, 0x02, 0xf4, 0xa4, 0x1e, 0xb2, 0xc2, 0x91, 0xf4, 0xc8, 0x36,
+ 0x3e, 0x25, 0xfb, 0x00, 0xde, 0x74, 0x2a, 0x99, 0x7a, 0x7b, 0xdb, 0x7d, 0x27, 0x9c, 0x7c, 0x00,
+ 0x6f, 0x2a, 0xb5, 0x0f, 0xe0, 0x59, 0xd7, 0x99, 0x31, 0x5e, 0x85, 0x84, 0xdb, 0x12, 0x24, 0xd6,
+ 0x0f, 0x9c, 0xf7, 0xc4, 0xf3, 0x27, 0x80, 0xf9, 0xfa, 0x8b, 0x9d, 0x4b, 0xa6, 0xaf, 0xdd, 0x9c,
+ 0x87, 0x98, 0xa9, 0x76, 0x7a, 0x6d, 0x76, 0xf8, 0x94, 0x43, 0xe7, 0x83, 0x05, 0x31, 0x06, 0x81,
+ 0x5e, 0xd7, 0xf9, 0x5b, 0xc9, 0x5f, 0x02, 0x90, 0x76, 0x8b, 0xc2, 0x1d, 0x09, 0x96, 0x75, 0xa3,
+ 0x23, 0x5b, 0x16, 0x35, 0x4c, 0xbc, 0x0e, 0x89, 0x5e, 0x57, 0xda, 0xf4, 0x16, 0x58, 0x67, 0x49,
+ 0x2d, 0xcd, 0x8d, 0xbb, 0x34, 0x6e, 0xe8, 0xe3, 0xeb, 0x78, 0xaf, 0x3b, 0x58, 0xc6, 0xdf, 0x83,
+ 0x73, 0x7e, 0x38, 0xa9, 0x2b, 0x1b, 0x72, 0x87, 0xda, 0xc0, 0xce, 0xac, 0x3c, 0xe3, 0x53, 0xae,
+ 0x79, 0x32, 0x7c, 0x0d, 0x58, 0xa8, 0x7d, 0x6e, 0x4c, 0x3d, 0xb6, 0x1b, 0xac, 0x18, 0x86, 0x8e,
+ 0xd8, 0x63, 0xd2, 0x08, 0xa4, 0xcf, 0x95, 0x20, 0x73, 0xe5, 0xdc, 0x88, 0xc1, 0xc0, 0x99, 0xec,
+ 0xdf, 0x10, 0xcc, 0x14, 0xfd, 0x19, 0xe1, 0xfe, 0x69, 0x0c, 0x37, 0xbe, 0x51, 0x1b, 0x8e, 0x7e,
+ 0x4d, 0xfb, 0x5d, 0xf7, 0x73, 0x58, 0xe0, 0xf4, 0x1c, 0x06, 0x47, 0x62, 0xe4, 0x16, 0x0a, 0xf2,
+ 0xb7, 0x7f, 0x13, 0xf6, 0xb1, 0xd8, 0x8b, 0x1f, 0x23, 0xe0, 0xc7, 0x6f, 0x09, 0x63, 0x48, 0x2d,
+ 0x57, 0xc9, 0x7a, 0xbe, 0xd1, 0x28, 0x11, 0xa9, 0x52, 0xad, 0x94, 0x78, 0x0e, 0xa7, 0x61, 0x66,
+ 0xb8, 0x46, 0x4a, 0xb5, 0x6a, 0xbd, 0xdc, 0xa8, 0x92, 0x1b, 0x3c, 0xc2, 0xb3, 0x70, 0x6e, 0x28,
+ 0xb9, 0x42, 0x6a, 0x05, 0xa9, 0x5e, 0x22, 0x6f, 0x94, 0x0b, 0x25, 0x3e, 0x30, 0x6a, 0x75, 0x35,
+ 0xff, 0x46, 0xbe, 0x5e, 0x20, 0xe5, 0x5a, 0x83, 0x9f, 0x1a, 0x95, 0x14, 0xf2, 0x37, 0x4a, 0x95,
+ 0x4a, 0x69, 0xad, 0x56, 0xe3, 0x83, 0xe2, 0x9f, 0xd1, 0xbd, 0x03, 0x01, 0xdd, 0x3f, 0x10, 0xd0,
+ 0xe7, 0x07, 0x02, 0xf7, 0xe0, 0x40, 0xe0, 0xbe, 0x38, 0x10, 0xb8, 0x2f, 0x0f, 0x04, 0xee, 0xe1,
+ 0x81, 0x80, 0x3e, 0xe8, 0x0b, 0xe8, 0xa3, 0xbe, 0xc0, 0x7d, 0xda, 0x17, 0xd0, 0x9d, 0xbe, 0xc0,
+ 0xdd, 0xed, 0x0b, 0xdc, 0x67, 0x7d, 0x81, 0xbb, 0xd7, 0x17, 0xd0, 0xfd, 0xbe, 0x80, 0x3e, 0xef,
+ 0x0b, 0xdc, 0x83, 0xbe, 0x80, 0xbe, 0xe8, 0x0b, 0xdc, 0x97, 0x7d, 0x01, 0x3d, 0xec, 0x0b, 0xdc,
+ 0x07, 0x87, 0x02, 0xf7, 0xd1, 0xa1, 0x80, 0x3e, 0x3e, 0x14, 0xb8, 0x4f, 0x0e, 0x05, 0x74, 0xfb,
+ 0x50, 0xe0, 0x3e, 0x3d, 0x14, 0xb8, 0x3b, 0x87, 0x02, 0xba, 0x7b, 0x28, 0xa0, 0xcf, 0x0e, 0x05,
+ 0xf4, 0xd3, 0xc5, 0x96, 0x9e, 0xb3, 0x6e, 0x52, 0xeb, 0xa6, 0x3d, 0xfc, 0xe6, 0x34, 0x6a, 0xed,
+ 0xe8, 0xc6, 0xd6, 0xe2, 0xe8, 0xff, 0x00, 0xb6, 0x2f, 0x2d, 0x76, 0xb7, 0x5a, 0x8b, 0x96, 0xa5,
+ 0x75, 0x37, 0x36, 0xc2, 0x8c, 0xa2, 0x2e, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x71, 0xcc,
+ 0x5d, 0xae, 0x19, 0x00, 0x00,
}
func (x PayloadFormatter) String() string {
@@ -1961,6 +1974,14 @@ func (this *ApplicationUplink) Equal(that interface{}) bool {
} else if that1.ConsumedAirtime != nil {
return false
}
+ if len(this.Locations) != len(that1.Locations) {
+ return false
+ }
+ for i := range this.Locations {
+ if !this.Locations[i].Equal(that1.Locations[i]) {
+ return false
+ }
+ }
return true
}
func (this *ApplicationLocation) Equal(that interface{}) bool {
@@ -2918,13 +2939,39 @@ func (m *ApplicationUplink) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.Locations) > 0 {
+ for k := range m.Locations {
+ v := m.Locations[k]
+ baseI := i
+ if v != nil {
+ {
+ size, err := v.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMessages(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ i -= len(k)
+ copy(dAtA[i:], k)
+ i = encodeVarintMessages(dAtA, i, uint64(len(k)))
+ i--
+ dAtA[i] = 0xa
+ i = encodeVarintMessages(dAtA, i, uint64(baseI-i))
+ i--
+ dAtA[i] = 0x72
+ }
+ }
if m.ConsumedAirtime != nil {
- n10, err10 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ConsumedAirtime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ConsumedAirtime):])
- if err10 != nil {
- return 0, err10
+ n11, err11 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ConsumedAirtime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ConsumedAirtime):])
+ if err11 != nil {
+ return 0, err11
}
- i -= n10
- i = encodeVarintMessages(dAtA, i, uint64(n10))
+ i -= n11
+ i = encodeVarintMessages(dAtA, i, uint64(n11))
i--
dAtA[i] = 0x6a
}
@@ -2964,12 +3011,12 @@ func (m *ApplicationUplink) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x4a
}
- n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ReceivedAt):])
- if err12 != nil {
- return 0, err12
+ n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ReceivedAt):])
+ if err13 != nil {
+ return 0, err13
}
- i -= n12
- i = encodeVarintMessages(dAtA, i, uint64(n12))
+ i -= n13
+ i = encodeVarintMessages(dAtA, i, uint64(n13))
i--
dAtA[i] = 0x42
{
@@ -3114,12 +3161,12 @@ func (m *ApplicationJoinAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- n16, err16 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ReceivedAt):])
- if err16 != nil {
- return 0, err16
+ n17, err17 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ReceivedAt):])
+ if err17 != nil {
+ return 0, err17
}
- i -= n16
- i = encodeVarintMessages(dAtA, i, uint64(n16))
+ i -= n17
+ i = encodeVarintMessages(dAtA, i, uint64(n17))
i--
dAtA[i] = 0x42
if m.PendingSession {
@@ -3293,12 +3340,12 @@ func (m *ApplicationDownlink_ClassBC) MarshalToSizedBuffer(dAtA []byte) (int, er
var l int
_ = l
if m.AbsoluteTime != nil {
- n20, err20 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AbsoluteTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AbsoluteTime):])
- if err20 != nil {
- return 0, err20
+ n21, err21 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AbsoluteTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AbsoluteTime):])
+ if err21 != nil {
+ return 0, err21
}
- i -= n20
- i = encodeVarintMessages(dAtA, i, uint64(n20))
+ i -= n21
+ i = encodeVarintMessages(dAtA, i, uint64(n21))
i--
dAtA[i] = 0x42
}
@@ -3523,12 +3570,12 @@ func (m *ApplicationUp) MarshalToSizedBuffer(dAtA []byte) (int, error) {
}
}
if m.ReceivedAt != nil {
- n24, err24 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ReceivedAt):])
- if err24 != nil {
- return 0, err24
+ n25, err25 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ReceivedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ReceivedAt):])
+ if err25 != nil {
+ return 0, err25
}
- i -= n24
- i = encodeVarintMessages(dAtA, i, uint64(n24))
+ i -= n25
+ i = encodeVarintMessages(dAtA, i, uint64(n25))
i--
dAtA[i] = 0x62
}
@@ -3934,6 +3981,13 @@ func NewPopulatedApplicationUplink(r randyMessages, easy bool) *ApplicationUplin
if r.Intn(5) != 0 {
this.ConsumedAirtime = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy)
}
+ if r.Intn(5) != 0 {
+ v8 := r.Intn(10)
+ this.Locations = make(map[string]*Location)
+ for i := 0; i < v8; i++ {
+ this.Locations[randStringMessages(r)] = NewPopulatedLocation(r, easy)
+ }
+ }
if !easy && r.Intn(10) != 0 {
}
return this
@@ -3942,12 +3996,12 @@ func NewPopulatedApplicationUplink(r randyMessages, easy bool) *ApplicationUplin
func NewPopulatedApplicationLocation(r randyMessages, easy bool) *ApplicationLocation {
this := &ApplicationLocation{}
this.Service = randStringMessages(r)
- v8 := NewPopulatedLocation(r, easy)
- this.Location = *v8
+ v9 := NewPopulatedLocation(r, easy)
+ this.Location = *v9
if r.Intn(5) != 0 {
- v9 := r.Intn(10)
+ v10 := r.Intn(10)
this.Attributes = make(map[string]string)
- for i := 0; i < v9; i++ {
+ for i := 0; i < v10; i++ {
this.Attributes[randStringMessages(r)] = randStringMessages(r)
}
}
@@ -3958,24 +4012,24 @@ func NewPopulatedApplicationLocation(r randyMessages, easy bool) *ApplicationLoc
func NewPopulatedApplicationJoinAccept(r randyMessages, easy bool) *ApplicationJoinAccept {
this := &ApplicationJoinAccept{}
- v10 := r.Intn(100)
- this.SessionKeyID = make([]byte, v10)
- for i := 0; i < v10; i++ {
+ v11 := r.Intn(100)
+ this.SessionKeyID = make([]byte, v11)
+ for i := 0; i < v11; i++ {
this.SessionKeyID[i] = byte(r.Intn(256))
}
if r.Intn(5) != 0 {
this.AppSKey = NewPopulatedKeyEnvelope(r, easy)
}
if r.Intn(5) != 0 {
- v11 := r.Intn(5)
- this.InvalidatedDownlinks = make([]*ApplicationDownlink, v11)
- for i := 0; i < v11; i++ {
+ v12 := r.Intn(5)
+ this.InvalidatedDownlinks = make([]*ApplicationDownlink, v12)
+ for i := 0; i < v12; i++ {
this.InvalidatedDownlinks[i] = NewPopulatedApplicationDownlink(r, easy)
}
}
this.PendingSession = bool(r.Intn(2) == 0)
- v12 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
- this.ReceivedAt = *v12
+ v13 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
+ this.ReceivedAt = *v13
if !easy && r.Intn(10) != 0 {
}
return this
@@ -3984,11 +4038,11 @@ func NewPopulatedApplicationJoinAccept(r randyMessages, easy bool) *ApplicationJ
func NewPopulatedApplicationDownlink_ClassBC(r randyMessages, easy bool) *ApplicationDownlink_ClassBC {
this := &ApplicationDownlink_ClassBC{}
if r.Intn(5) != 0 {
- v13 := r.Intn(5)
- this.Gateways = make([]GatewayAntennaIdentifiers, v13)
- for i := 0; i < v13; i++ {
- v14 := NewPopulatedGatewayAntennaIdentifiers(r, easy)
- this.Gateways[i] = *v14
+ v14 := r.Intn(5)
+ this.Gateways = make([]GatewayAntennaIdentifiers, v14)
+ for i := 0; i < v14; i++ {
+ v15 := NewPopulatedGatewayAntennaIdentifiers(r, easy)
+ this.Gateways[i] = *v15
}
}
if r.Intn(5) != 0 {
@@ -4002,9 +4056,9 @@ func NewPopulatedApplicationDownlink_ClassBC(r randyMessages, easy bool) *Applic
func NewPopulatedApplicationDownlinks(r randyMessages, easy bool) *ApplicationDownlinks {
this := &ApplicationDownlinks{}
if r.Intn(5) != 0 {
- v15 := r.Intn(5)
- this.Downlinks = make([]*ApplicationDownlink, v15)
- for i := 0; i < v15; i++ {
+ v16 := r.Intn(5)
+ this.Downlinks = make([]*ApplicationDownlink, v16)
+ for i := 0; i < v16; i++ {
this.Downlinks[i] = NewPopulatedApplicationDownlink(r, easy)
}
}
@@ -4015,10 +4069,10 @@ func NewPopulatedApplicationDownlinks(r randyMessages, easy bool) *ApplicationDo
func NewPopulatedApplicationDownlinkFailed(r randyMessages, easy bool) *ApplicationDownlinkFailed {
this := &ApplicationDownlinkFailed{}
- v16 := NewPopulatedApplicationDownlink(r, easy)
- this.ApplicationDownlink = *v16
- v17 := NewPopulatedErrorDetails(r, easy)
- this.Error = *v17
+ v17 := NewPopulatedApplicationDownlink(r, easy)
+ this.ApplicationDownlink = *v17
+ v18 := NewPopulatedErrorDetails(r, easy)
+ this.Error = *v18
if !easy && r.Intn(10) != 0 {
}
return this
@@ -4027,9 +4081,9 @@ func NewPopulatedApplicationDownlinkFailed(r randyMessages, easy bool) *Applicat
func NewPopulatedApplicationInvalidatedDownlinks(r randyMessages, easy bool) *ApplicationInvalidatedDownlinks {
this := &ApplicationInvalidatedDownlinks{}
if r.Intn(5) != 0 {
- v18 := r.Intn(5)
- this.Downlinks = make([]*ApplicationDownlink, v18)
- for i := 0; i < v18; i++ {
+ v19 := r.Intn(5)
+ this.Downlinks = make([]*ApplicationDownlink, v19)
+ for i := 0; i < v19; i++ {
this.Downlinks[i] = NewPopulatedApplicationDownlink(r, easy)
}
}
@@ -4052,11 +4106,11 @@ func NewPopulatedApplicationServiceData(r randyMessages, easy bool) *Application
func NewPopulatedApplicationUp(r randyMessages, easy bool) *ApplicationUp {
this := &ApplicationUp{}
- v19 := NewPopulatedEndDeviceIdentifiers(r, easy)
- this.EndDeviceIdentifiers = *v19
- v20 := r.Intn(10)
- this.CorrelationIDs = make([]string, v20)
- for i := 0; i < v20; i++ {
+ v20 := NewPopulatedEndDeviceIdentifiers(r, easy)
+ this.EndDeviceIdentifiers = *v20
+ v21 := r.Intn(10)
+ this.CorrelationIDs = make([]string, v21)
+ for i := 0; i < v21; i++ {
this.CorrelationIDs[i] = randStringMessages(r)
}
oneofNumber_Up := []int32{3, 4, 5, 6, 7, 8, 9, 10, 11, 13}[r.Intn(10)]
@@ -4154,12 +4208,12 @@ func NewPopulatedMessagePayloadFormatters(r randyMessages, easy bool) *MessagePa
func NewPopulatedDownlinkQueueRequest(r randyMessages, easy bool) *DownlinkQueueRequest {
this := &DownlinkQueueRequest{}
- v21 := NewPopulatedEndDeviceIdentifiers(r, easy)
- this.EndDeviceIdentifiers = *v21
+ v22 := NewPopulatedEndDeviceIdentifiers(r, easy)
+ this.EndDeviceIdentifiers = *v22
if r.Intn(5) != 0 {
- v22 := r.Intn(5)
- this.Downlinks = make([]*ApplicationDownlink, v22)
- for i := 0; i < v22; i++ {
+ v23 := r.Intn(5)
+ this.Downlinks = make([]*ApplicationDownlink, v23)
+ for i := 0; i < v23; i++ {
this.Downlinks[i] = NewPopulatedApplicationDownlink(r, easy)
}
}
@@ -4187,9 +4241,9 @@ func randUTF8RuneMessages(r randyMessages) rune {
return rune(ru + 61)
}
func randStringMessages(r randyMessages) string {
- v23 := r.Intn(100)
- tmps := make([]rune, v23)
- for i := 0; i < v23; i++ {
+ v24 := r.Intn(100)
+ tmps := make([]rune, v24)
+ for i := 0; i < v24; i++ {
tmps[i] = randUTF8RuneMessages(r)
}
return string(tmps)
@@ -4211,11 +4265,11 @@ func randFieldMessages(dAtA []byte, r randyMessages, fieldNumber int, wire int)
switch wire {
case 0:
dAtA = encodeVarintPopulateMessages(dAtA, uint64(key))
- v24 := r.Int63()
+ v25 := r.Int63()
if r.Intn(2) == 0 {
- v24 *= -1
+ v25 *= -1
}
- dAtA = encodeVarintPopulateMessages(dAtA, uint64(v24))
+ dAtA = encodeVarintPopulateMessages(dAtA, uint64(v25))
case 1:
dAtA = encodeVarintPopulateMessages(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
@@ -4423,6 +4477,19 @@ func (m *ApplicationUplink) Size() (n int) {
l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ConsumedAirtime)
n += 1 + l + sovMessages(uint64(l))
}
+ if len(m.Locations) > 0 {
+ for k, v := range m.Locations {
+ _ = k
+ _ = v
+ l = 0
+ if v != nil {
+ l = v.Size()
+ l += 1 + sovMessages(uint64(l))
+ }
+ mapEntrySize := 1 + len(k) + sovMessages(uint64(len(k))) + l
+ n += mapEntrySize + 1 + sovMessages(uint64(mapEntrySize))
+ }
+ }
return n
}
@@ -4888,6 +4955,16 @@ func (this *ApplicationUplink) String() string {
repeatedStringForRxMetadata += strings.Replace(fmt.Sprintf("%v", f), "RxMetadata", "RxMetadata", 1) + ","
}
repeatedStringForRxMetadata += "}"
+ keysForLocations := make([]string, 0, len(this.Locations))
+ for k := range this.Locations {
+ keysForLocations = append(keysForLocations, k)
+ }
+ github_com_gogo_protobuf_sortkeys.Strings(keysForLocations)
+ mapStringForLocations := "map[string]*Location{"
+ for _, k := range keysForLocations {
+ mapStringForLocations += fmt.Sprintf("%v: %v,", k, this.Locations[k])
+ }
+ mapStringForLocations += "}"
s := strings.Join([]string{`&ApplicationUplink{`,
`SessionKeyID:` + fmt.Sprintf("%v", this.SessionKeyID) + `,`,
`FPort:` + fmt.Sprintf("%v", this.FPort) + `,`,
@@ -4902,6 +4979,7 @@ func (this *ApplicationUplink) String() string {
`Confirmed:` + fmt.Sprintf("%v", this.Confirmed) + `,`,
`DecodedPayloadWarnings:` + fmt.Sprintf("%v", this.DecodedPayloadWarnings) + `,`,
`ConsumedAirtime:` + strings.Replace(fmt.Sprintf("%v", this.ConsumedAirtime), "Duration", "types.Duration", 1) + `,`,
+ `Locations:` + mapStringForLocations + `,`,
`}`,
}, "")
return s
@@ -6396,6 +6474,135 @@ func (m *ApplicationUplink) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 14:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Locations", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMessages
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMessages
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMessages
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Locations == nil {
+ m.Locations = make(map[string]*Location)
+ }
+ var mapkey string
+ var mapvalue *Location
+ for iNdEx < postIndex {
+ entryPreIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMessages
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ if fieldNum == 1 {
+ var stringLenmapkey uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMessages
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLenmapkey |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLenmapkey := int(stringLenmapkey)
+ if intStringLenmapkey < 0 {
+ return ErrInvalidLengthMessages
+ }
+ postStringIndexmapkey := iNdEx + intStringLenmapkey
+ if postStringIndexmapkey < 0 {
+ return ErrInvalidLengthMessages
+ }
+ if postStringIndexmapkey > l {
+ return io.ErrUnexpectedEOF
+ }
+ mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+ iNdEx = postStringIndexmapkey
+ } else if fieldNum == 2 {
+ var mapmsglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMessages
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ mapmsglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if mapmsglen < 0 {
+ return ErrInvalidLengthMessages
+ }
+ postmsgIndex := iNdEx + mapmsglen
+ if postmsgIndex < 0 {
+ return ErrInvalidLengthMessages
+ }
+ if postmsgIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ mapvalue = &Location{}
+ if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+ return err
+ }
+ iNdEx = postmsgIndex
+ } else {
+ iNdEx = entryPreIndex
+ skippy, err := skipMessages(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMessages
+ }
+ if (iNdEx + skippy) > postIndex {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+ m.Locations[mapkey] = mapvalue
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipMessages(dAtA[iNdEx:])
diff --git a/pkg/ttnpb/messages.pb.paths.fm.go b/pkg/ttnpb/messages.pb.paths.fm.go
index 6e9dc70de5..b111964e19 100644
--- a/pkg/ttnpb/messages.pb.paths.fm.go
+++ b/pkg/ttnpb/messages.pb.paths.fm.go
@@ -279,6 +279,7 @@ var ApplicationUplinkFieldPathsNested = []string{
"f_port",
"frm_payload",
"last_a_f_cnt_down",
+ "locations",
"received_at",
"rx_metadata",
"session_key_id",
@@ -312,6 +313,7 @@ var ApplicationUplinkFieldPathsTopLevel = []string{
"f_port",
"frm_payload",
"last_a_f_cnt_down",
+ "locations",
"received_at",
"rx_metadata",
"session_key_id",
@@ -566,6 +568,7 @@ var ApplicationUpFieldPathsNested = []string{
"up.uplink_message.f_port",
"up.uplink_message.frm_payload",
"up.uplink_message.last_a_f_cnt_down",
+ "up.uplink_message.locations",
"up.uplink_message.received_at",
"up.uplink_message.rx_metadata",
"up.uplink_message.session_key_id",
diff --git a/pkg/ttnpb/messages.pb.setters.fm.go b/pkg/ttnpb/messages.pb.setters.fm.go
index dc99db986c..e7270afe91 100644
--- a/pkg/ttnpb/messages.pb.setters.fm.go
+++ b/pkg/ttnpb/messages.pb.setters.fm.go
@@ -509,6 +509,15 @@ func (dst *ApplicationUplink) SetFields(src *ApplicationUplink, paths ...string)
} else {
dst.ConsumedAirtime = nil
}
+ case "locations":
+ if len(subs) > 0 {
+ return fmt.Errorf("'locations' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Locations = src.Locations
+ } else {
+ dst.Locations = nil
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
diff --git a/pkg/ttnpb/messages.pb.validate.go b/pkg/ttnpb/messages.pb.validate.go
index 4bc6ab87b1..de653c6ba0 100644
--- a/pkg/ttnpb/messages.pb.validate.go
+++ b/pkg/ttnpb/messages.pb.validate.go
@@ -710,6 +710,25 @@ func (m *ApplicationUplink) ValidateFields(paths ...string) error {
}
}
+ case "locations":
+
+ for key, val := range m.GetLocations() {
+ _ = val
+
+ // no validation rules for Locations[key]
+
+ if v, ok := interface{}(val).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ApplicationUplinkValidationError{
+ field: fmt.Sprintf("locations[%v]", key),
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ }
+
default:
return ApplicationUplinkValidationError{
field: name,
diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json
index 86228178bd..08cf7354d8 100644
--- a/sdk/js/generated/api.json
+++ b/sdk/js/generated/api.json
@@ -20888,6 +20888,47 @@
"fullType": "google.protobuf.Duration",
"ismap": false,
"defaultValue": ""
+ },
+ {
+ "name": "locations",
+ "description": "End device location metadata, set by the Application Server while handling the message.",
+ "label": "repeated",
+ "type": "LocationsEntry",
+ "longType": "ApplicationUplink.LocationsEntry",
+ "fullType": "ttn.lorawan.v3.ApplicationUplink.LocationsEntry",
+ "ismap": true,
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "LocationsEntry",
+ "longName": "ApplicationUplink.LocationsEntry",
+ "fullName": "ttn.lorawan.v3.ApplicationUplink.LocationsEntry",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "key",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "defaultValue": ""
+ },
+ {
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "Location",
+ "longType": "Location",
+ "fullType": "ttn.lorawan.v3.Location",
+ "ismap": false,
+ "defaultValue": ""
}
]
},