From 9025a30f5d6d23cf6ca5dd6e8b8eba9d08842c96 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:52:44 -0800 Subject: [PATCH 01/19] lnwire/features: add EmptyFeatureVector constructor --- lnwire/features.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lnwire/features.go b/lnwire/features.go index d2ffa136..0feb7627 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -357,6 +357,11 @@ func NewFeatureVector(featureVector *RawFeatureVector, } } +// EmptyFeatureVector returns a feature vector with no bits set. +func EmptyFeatureVector() *FeatureVector { + return NewFeatureVector(nil, Features) +} + // HasFeature returns whether a particular feature is included in the set. The // feature can be seen as set either if the bit is set directly OR the queried // bit has the same meaning as its corresponding even/odd bit, which is set From 80802d8e84b21ff86fc3466adc9c06d9053fb61f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:53:05 -0800 Subject: [PATCH 02/19] channeldb/graph: always populate LightningNode features Previously we would return nil features when we didn't have a node announcement or a given node. With this change, we can always assume the feature vector is populated during pathfinding. --- channeldb/graph.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index c3887655..abfc5d49 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -3461,6 +3461,10 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) { err error ) + // Always populate a feature vector, even if we don't have a node + // announcement and short circuit below. + node.Features = lnwire.EmptyFeatureVector() + if _, err := r.Read(scratch[:]); err != nil { return LightningNode{}, err } @@ -3506,12 +3510,10 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) { return LightningNode{}, err } - fv := lnwire.NewFeatureVector(nil, lnwire.Features) - err = fv.Decode(r) + err = node.Features.Decode(r) if err != nil { return LightningNode{}, err } - node.Features = fv if _, err := r.Read(scratch[:2]); err != nil { return LightningNode{}, err From 618810394ce255077ab78475beccf53c611f75f8 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:53:18 -0800 Subject: [PATCH 03/19] routing/pathfind_test: add asymmetric chan consructor Later this will be used to populate distinct feature vectors for either end of the channel. --- routing/pathfind_test.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index a66d81f0..15fc0d04 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -325,7 +325,7 @@ type testChannelEnd struct { *testChannelPolicy } -func symmetricTestChannel(alias1 string, alias2 string, capacity btcutil.Amount, +func symmetricTestChannel(alias1, alias2 string, capacity btcutil.Amount, policy *testChannelPolicy, chanID ...uint64) *testChannel { // Leaving id zero will result in auto-generation of a channel id during @@ -335,18 +335,26 @@ func symmetricTestChannel(alias1 string, alias2 string, capacity btcutil.Amount, id = chanID[0] } - node2Policy := *policy - node2Policy.Direction = !policy.Direction + policy2 := *policy + policy2.Direction = !policy.Direction + + return asymmetricTestChannel( + alias1, alias2, capacity, policy, &policy2, id, + ) +} + +func asymmetricTestChannel(alias1, alias2 string, capacity btcutil.Amount, + policy1, policy2 *testChannelPolicy, id uint64) *testChannel { return &testChannel{ Capacity: capacity, Node1: &testChannelEnd{ Alias: alias1, - testChannelPolicy: policy, + testChannelPolicy: policy1, }, Node2: &testChannelEnd{ Alias: alias2, - testChannelPolicy: &node2Policy, + testChannelPolicy: policy2, }, ChannelID: id, } From bd66c0d34e4812a56e2f74b202120ee071465f2b Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:53:32 -0800 Subject: [PATCH 04/19] routing/pathfind_test: allow custom node features This commit allows custom node features to be populated in specific test instances. For consistency, we auto-populate an empty feature vector for nodes that have nil feature vectors before writing them to the database. --- routing/pathfind_test.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 15fc0d04..1afd5a67 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -318,6 +318,7 @@ type testChannelPolicy struct { LastUpdate time.Time Disabled bool Direction bool + Features *lnwire.FeatureVector } type testChannelEnd struct { @@ -409,7 +410,9 @@ func createTestGraphFromChannels(testChannels []*testChannel, source string) ( privKeyMap := make(map[string]*btcec.PrivateKey) nodeIndex := byte(0) - addNodeWithAlias := func(alias string) (*channeldb.LightningNode, error) { + addNodeWithAlias := func(alias string, features *lnwire.FeatureVector) ( + *channeldb.LightningNode, error) { + keyBytes := make([]byte, 32) keyBytes = []byte{ 0, 0, 0, 0, 0, 0, 0, 0, @@ -421,13 +424,17 @@ func createTestGraphFromChannels(testChannels []*testChannel, source string) ( privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), keyBytes) + if features == nil { + features = lnwire.EmptyFeatureVector() + } + dbNode := &channeldb.LightningNode{ HaveNodeAnnouncement: true, AuthSigBytes: testSig.Serialize(), LastUpdate: testTime, Addresses: testAddrs, Alias: alias, - Features: testFeatures, + Features: features, } copy(dbNode.PubKeyBytes[:], pubKey.SerializeCompressed()) @@ -447,7 +454,7 @@ func createTestGraphFromChannels(testChannels []*testChannel, source string) ( } // Add the source node. - dbNode, err := addNodeWithAlias(source) + dbNode, err := addNodeWithAlias(source, lnwire.EmptyFeatureVector()) if err != nil { return nil, err } @@ -461,12 +468,19 @@ func createTestGraphFromChannels(testChannels []*testChannel, source string) ( nextUnassignedChannelID := uint64(100000) for _, testChannel := range testChannels { - for _, alias := range []string{ - testChannel.Node1.Alias, testChannel.Node2.Alias} { + for _, node := range []*testChannelEnd{ + testChannel.Node1, testChannel.Node2} { - _, exists := aliasMap[alias] + _, exists := aliasMap[node.Alias] if !exists { - _, err := addNodeWithAlias(alias) + var features *lnwire.FeatureVector + if node.testChannelPolicy != nil { + features = + node.testChannelPolicy.Features + } + _, err := addNodeWithAlias( + node.Alias, features, + ) if err != nil { return nil, err } From cfa3fe292135fd8e5acf5db8a3b636fd72c3c56d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:53:51 -0800 Subject: [PATCH 05/19] routing/pathfind: fix TLV fallback for unadvertised hops In this commit, we fix a bug that prevents us from sending custom records to nodes that aren't in the graph. Previously we would simply fail if we were unable to retrieve the node's features. To remedy, we add the option of supplying the destination's feature bits into path finding. If present, we will use them directly without consulting the graph, resolving the original issue. Instead, we will only consult the graph as a fallback, which will still fail if the node doesn't exist since the TLV features won't be populated in the empty feature vector. Furthermore, this also permits us to provide "virtual features" into the pathfinding logic, where we make assumptions about what the receiver supports even if the feature vector isn't actually taken from an invoice. This can useful in cases like keysend, where we don't have an invoice, but we can still attempt the payment if we assume the receiver supports TLV. --- routing/pathfind.go | 43 +++++++--- routing/pathfind_test.go | 166 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 188 insertions(+), 21 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 3fa48355..cb0e5c02 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -292,6 +292,11 @@ type RestrictParams struct { // DestCustomRecords contains the custom records to drop off at the // final hop, if any. DestCustomRecords record.CustomSet + + // DestFeatures is a feature vector describing what the final hop + // supports. If none are provided, pathfinding will try to inspect any + // features on the node announcement instead. + DestFeatures *lnwire.FeatureVector } // PathFindingConfig defines global parameters that control the trade-off in @@ -395,29 +400,41 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, defer tx.Rollback() } - if len(r.DestCustomRecords) > 0 { - // Check if the target has TLV enabled - + // If no destination features are provided, we will load what features + // we have for the target node from our graph. + features := r.DestFeatures + if features == nil { targetKey, err := btcec.ParsePubKey(target[:], btcec.S256()) if err != nil { return nil, err } targetNode, err := g.graph.FetchLightningNode(targetKey) - if err != nil { - return nil, err - } + switch { - if targetNode.Features != nil { - supportsTLV := targetNode.Features.HasFeature( - lnwire.TLVOnionPayloadOptional, - ) - if !supportsTLV { - return nil, errNoTlvPayload - } + // If the node exists and has features, use them directly. + case err == nil: + features = targetNode.Features + + // If an error other than the node not existing is hit, abort. + case err != channeldb.ErrGraphNodeNotFound: + return nil, err + + // Otherwise, we couldn't find a node announcement, populate a + // blank feature vector. + default: + features = lnwire.EmptyFeatureVector() } } + // If the caller needs to send custom records, check that our + // destination feature vector supports TLV. + if len(r.DestCustomRecords) > 0 && + !features.HasFeature(lnwire.TLVOnionPayloadOptional) { + + return nil, errNoTlvPayload + } + // If we are routing from ourselves, check that we have enough local // balance available. if source == self { diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 1afd5a67..ea366277 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -23,6 +23,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/zpay32" ) @@ -58,6 +59,12 @@ var ( } testPathFindingConfig = &PathFindingConfig{} + + tlvFeatures = lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + ), lnwire.Features, + ) ) var ( @@ -917,6 +924,10 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc } } +// TestPathFindingWithAdditionalEdges asserts that we are able to find paths to +// nodes that do not exist in the graph by way of hop hints. We also test that +// the path can support custom TLV records for the receiver under the +// appropriate circumstances. func TestPathFindingWithAdditionalEdges(t *testing.T) { t.Parallel() @@ -968,15 +979,21 @@ func TestPathFindingWithAdditionalEdges(t *testing.T) { graph.aliasMap["songoku"]: {songokuToDoge}, } + find := func(r *RestrictParams) ( + []*channeldb.ChannelEdgePolicy, error) { + + return findPath( + &graphParams{ + graph: graph.graph, + additionalEdges: additionalEdges, + }, + r, testPathFindingConfig, + sourceNode.PubKeyBytes, doge.PubKeyBytes, paymentAmt, + ) + } + // We should now be able to find a path from roasbeef to doge. - path, err := findPath( - &graphParams{ - graph: graph.graph, - additionalEdges: additionalEdges, - }, - noRestrictions, testPathFindingConfig, - sourceNode.PubKeyBytes, doge.PubKeyBytes, paymentAmt, - ) + path, err := find(noRestrictions) if err != nil { t.Fatalf("unable to find private path to doge: %v", err) } @@ -984,6 +1001,35 @@ func TestPathFindingWithAdditionalEdges(t *testing.T) { // The path should represent the following hops: // roasbeef -> songoku -> doge assertExpectedPath(t, graph.aliasMap, path, "songoku", "doge") + + // Now, set custom records for the final hop. This should fail since no + // dest features are set, and we won't have a node ann to fall back on. + restrictions := *noRestrictions + restrictions.DestCustomRecords = record.CustomSet{70000: []byte{}} + + _, err = find(&restrictions) + if err != errNoTlvPayload { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // Set empty dest features so we don't try the fallback. We should still + // fail since the tlv feature isn't set. + restrictions.DestFeatures = lnwire.EmptyFeatureVector() + + _, err = find(&restrictions) + if err != errNoTlvPayload { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // Finally, set the tlv feature in the payload and assert we found the + // same path as before. + restrictions.DestFeatures = tlvFeatures + + path, err = find(&restrictions) + if err != nil { + t.Fatalf("path should have been found: %v", err) + } + assertExpectedPath(t, graph.aliasMap, path, "songoku", "doge") } // TestNewRoute tests whether the construction of hop payloads by newRoute @@ -1296,6 +1342,110 @@ func TestPathNotAvailable(t *testing.T) { } } +// TestDestTLVGraphFallback asserts that we properly detect when we can send TLV +// records to a receiver, and also that we fallback to the receiver's node +// announcement if we don't have an invoice features. +func TestDestTLVGraphFallback(t *testing.T) { + t.Parallel() + + testChannels := []*testChannel{ + asymmetricTestChannel("roasbeef", "luoji", 100000, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, 0), + asymmetricTestChannel("roasbeef", "satoshi", 100000, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + Features: tlvFeatures, + }, 0), + } + + ctx := newPathFindingTestContext(t, testChannels, "roasbeef") + defer ctx.cleanup() + + sourceNode, err := ctx.graphParams.graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + + } + + find := func(r *RestrictParams, + target route.Vertex) ([]*channeldb.ChannelEdgePolicy, error) { + + return findPath( + &graphParams{ + graph: ctx.graphParams.graph, + }, + r, testPathFindingConfig, + sourceNode.PubKeyBytes, target, 100, + ) + } + + // Luoji's node ann has an empty feature vector. + luoji := ctx.testGraphInstance.aliasMap["luoji"] + + // Satoshi's node ann supports TLV. + satoshi := ctx.testGraphInstance.aliasMap["satoshi"] + + restrictions := *noRestrictions + + // Add custom records w/o any dest features. + restrictions.DestCustomRecords = record.CustomSet{70000: []byte{}} + + // Path to luoji should fail because his node ann features are empty. + _, err = find(&restrictions, luoji) + if err != errNoTlvPayload { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // However, path to satoshi should succeed via the fallback because his + // node ann features have the TLV bit. + path, err := find(&restrictions, satoshi) + if err != nil { + t.Fatalf("path should have been found: %v", err) + } + assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "satoshi") + + // Add empty destination features. This should cause both paths to fail, + // since this override anything in the graph. + restrictions.DestFeatures = lnwire.EmptyFeatureVector() + + _, err = find(&restrictions, luoji) + if err != errNoTlvPayload { + t.Fatalf("path shouldn't have been found: %v", err) + } + _, err = find(&restrictions, satoshi) + if err != errNoTlvPayload { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // Finally, set the TLV dest feature. We should succeed in finding a + // path to luoji. + restrictions.DestFeatures = tlvFeatures + + path, err = find(&restrictions, luoji) + if err != nil { + t.Fatalf("path should have been found: %v", err) + } + assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "luoji") +} + func TestPathInsufficientCapacity(t *testing.T) { t.Parallel() From acb7b83eadf9e4ac615d73dcaea8762b51ccefcc Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:54:11 -0800 Subject: [PATCH 06/19] routing/pathfind: validate final hop feature dependencies --- feature/deps.go | 7 +++- routing/pathfind.go | 12 ++++++ routing/pathfind_test.go | 86 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/feature/deps.go b/feature/deps.go index 173318d5..6382ff33 100644 --- a/feature/deps.go +++ b/feature/deps.go @@ -30,6 +30,11 @@ type ErrMissingFeatureDep struct { dep lnwire.FeatureBit } +// NewErrMissingFeatureDep creates a new ErrMissingFeatureDep error. +func NewErrMissingFeatureDep(dep lnwire.FeatureBit) ErrMissingFeatureDep { + return ErrMissingFeatureDep{dep: dep} +} + // Error returns a human-readable description of the missing dep error. func (e ErrMissingFeatureDep) Error() string { return fmt.Sprintf("missing feature dependency: %v", e.dep) @@ -74,7 +79,7 @@ func validateDeps(features featureSet, supported supportedFeatures) error { // vector is invalid. checked, ok := supported[bit] if !ok { - return ErrMissingFeatureDep{bit} + return NewErrMissingFeatureDep(bit) } // Alternatively, if we know that this depdendency is valid, we diff --git a/routing/pathfind.go b/routing/pathfind.go index cb0e5c02..90c4e576 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/coreos/bbolt" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" @@ -427,6 +428,17 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, } } + // With the destination's feature vector selected, ensure that all + // transitive depdencies are set. + err = feature.ValidateDeps(features) + if err != nil { + return nil, err + } + + // Now that we know the feature vector is well formed, we'll proceed in + // checking that it supports the features we need, given our + // restrictions on the final hop. + // If the caller needs to send custom records, check that our // destination feature vector supports TLV. if len(r.DestCustomRecords) > 0 && diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index ea366277..3647d9cb 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -22,6 +22,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" @@ -65,6 +66,19 @@ var ( lnwire.TLVOnionPayloadOptional, ), lnwire.Features, ) + + payAddrFeatures = lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector( + lnwire.PaymentAddrOptional, + ), lnwire.Features, + ) + + tlvPayAddrFeatures = lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.PaymentAddrOptional, + ), lnwire.Features, + ) ) var ( @@ -1446,6 +1460,78 @@ func TestDestTLVGraphFallback(t *testing.T) { assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "luoji") } +// TestMissingFeatureDep asserts that we fail path finding when the +// destination's features are broken, in that the feature vector doesn't signal +// all transitive dependencies. +func TestMissingFeatureDep(t *testing.T) { + t.Parallel() + + testChannels := []*testChannel{ + asymmetricTestChannel("roasbeef", "conner", 100000, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + Features: payAddrFeatures, + }, 0, + ), + } + + ctx := newPathFindingTestContext(t, testChannels, "roasbeef") + defer ctx.cleanup() + + sourceNode, err := ctx.graphParams.graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + + } + + find := func(r *RestrictParams, + target route.Vertex) ([]*channeldb.ChannelEdgePolicy, error) { + + return findPath( + &graphParams{ + graph: ctx.graphParams.graph, + }, + r, testPathFindingConfig, + sourceNode.PubKeyBytes, target, 100, + ) + } + + // Conner's node in the graph has a broken feature vector, since it + // signals payment addresses without signaling tlv onions. Pathfinding + // should fail since we validate transitive feature dependencies for the + // final node. + conner := ctx.testGraphInstance.aliasMap["conner"] + + restrictions := *noRestrictions + + _, err = find(&restrictions, conner) + if err != feature.NewErrMissingFeatureDep( + lnwire.TLVOnionPayloadOptional, + ) { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // Now, set the TLV and payment addresses features to override the + // broken features found in the graph. We should succeed in finding a + // path to conner. + restrictions.DestFeatures = tlvPayAddrFeatures + + path, err := find(&restrictions, conner) + if err != nil { + t.Fatalf("path should have been found: %v", err) + } + assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "conner") +} + func TestPathInsufficientCapacity(t *testing.T) { t.Parallel() From 990d55d08c0204a43f983ca05ffcd26b81db7b7f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:54:31 -0800 Subject: [PATCH 07/19] routing/pathfind: ensure final hop supports payment addrs This commit adds an optional PaymentAddr field to the RestrictParams, so that we can verify the final hop can support it before doing an expensive round of pathfindig. --- routing/pathfind.go | 18 ++++++++++ routing/pathfind_test.go | 65 ++++++++++++++++++++++++++++++++++++ routing/payment_lifecycle.go | 6 +++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 90c4e576..428caf42 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -70,6 +70,11 @@ var ( errNoTlvPayload = errors.New("destination hop doesn't " + "understand new TLV payloads") + // errNoPaymentAddr is returned when the destination hop does not + // support payment addresses. + errNoPaymentAddr = errors.New("destination hop doesn't " + + "understand payment addresses") + // errNoPathFound is returned when a path to the target destination does // not exist in the graph. errNoPathFound = errors.New("unable to find a path to destination") @@ -298,6 +303,11 @@ type RestrictParams struct { // supports. If none are provided, pathfinding will try to inspect any // features on the node announcement instead. DestFeatures *lnwire.FeatureVector + + // PaymentAddr is a random 32-byte value generated by the receiver to + // mitigate probing vectors and payment sniping attacks on overpaid + // invoices. + PaymentAddr *[32]byte } // PathFindingConfig defines global parameters that control the trade-off in @@ -447,6 +457,14 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, return nil, errNoTlvPayload } + // If the caller has a payment address to attach, check that our + // destination feature vector supports them. + if r.PaymentAddr != nil && + !features.HasFeature(lnwire.PaymentAddrOptional) { + + return nil, errNoPaymentAddr + } + // If we are routing from ourselves, check that we have enough local // balance available. if source == self { diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 3647d9cb..bcd40cf0 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -1532,6 +1532,71 @@ func TestMissingFeatureDep(t *testing.T) { assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "conner") } +// TestDestPaymentAddr asserts that we properly detect when we can send a +// payment address to a receiver, and also that we fallback to the receiver's +// node announcement if we don't have an invoice features. +func TestDestPaymentAddr(t *testing.T) { + t.Parallel() + + testChannels := []*testChannel{ + symmetricTestChannel("roasbeef", "luoji", 100000, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, + ), + } + + ctx := newPathFindingTestContext(t, testChannels, "roasbeef") + defer ctx.cleanup() + + sourceNode, err := ctx.graphParams.graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + + } + + find := func(r *RestrictParams, + target route.Vertex) ([]*channeldb.ChannelEdgePolicy, error) { + + return findPath( + &graphParams{ + graph: ctx.graphParams.graph, + }, + r, testPathFindingConfig, + sourceNode.PubKeyBytes, target, 100, + ) + } + + luoji := ctx.testGraphInstance.aliasMap["luoji"] + + restrictions := *noRestrictions + + // Add payment address w/o any invoice features. + restrictions.PaymentAddr = &[32]byte{1} + + // Add empty destination features. This should cause us to fail, since + // this overrides anything in the graph. + restrictions.DestFeatures = lnwire.EmptyFeatureVector() + + _, err = find(&restrictions, luoji) + if err != errNoPaymentAddr { + t.Fatalf("path shouldn't have been found: %v", err) + } + + // Now, set the TLV and payment address features for the destination. We + // should succeed in finding a path to luoji. + restrictions.DestFeatures = tlvPayAddrFeatures + + path, err := find(&restrictions, luoji) + if err != nil { + t.Fatalf("path should have been found: %v", err) + } + assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "luoji") +} + func TestPathInsufficientCapacity(t *testing.T) { t.Parallel() diff --git a/routing/payment_lifecycle.go b/routing/payment_lifecycle.go index 093ee8bc..b5203671 100644 --- a/routing/payment_lifecycle.go +++ b/routing/payment_lifecycle.go @@ -192,7 +192,11 @@ func (p *paymentLifecycle) resumePayment() ([32]byte, *route.Route, error) { // payment-level failure. func errorToPaymentFailure(err error) channeldb.FailureReason { switch err { - case errNoTlvPayload, errNoPathFound, errMaxHopsExceeded, + case + errNoTlvPayload, + errNoPaymentAddr, + errNoPathFound, + errMaxHopsExceeded, errPrebuiltRouteTried: return channeldb.FailureReasonNoRoute From 71e05e05bf950d3405b335ed7e8bb020622fdf99 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:54:49 -0800 Subject: [PATCH 08/19] routing/pathfind: set final hop features used in pathfinding In this commit, we overwrite the final hop's features with either the destination features or those loaded from the graph fallback. This ensures that the same features used in pathfinding will be provided to route construction. In an earlier commit, we validated the final hop's transitive feature dependencies, so we also add validation to non-final nodes. --- routing/pathfind.go | 30 ++++++++++++++++++++++++++++++ routing/pathfind_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/routing/pathfind.go b/routing/pathfind.go index 428caf42..3b1c4433 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -644,6 +644,36 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, edge.ChannelID) } + switch { + + // If this edge takes us to the final hop, we'll set the node + // features to those determined above. These are either taken + // from the destination features, e.g. virtual or invoice + // features, or loaded as a fallback from the graph. The + // transitive dependencies were already validated above, so no + // need to do so now. + // + // NOTE: This may overwrite features loaded from the graph if + // destination features were provided. This is fine though, + // since our route construction does not care where the features + // are actually taken from. In the future we may wish to do + // route construction within findPath, and avoid using + // ChannelEdgePolicy altogether. + case edge.Node.PubKeyBytes == target: + edge.Node.Features = features + + // Otherwise, this is some other intermediary node. Verify the + // transitive feature dependencies for this node, and skip the + // channel if they are invalid. + default: + err := feature.ValidateDeps(edge.Node.Features) + if err != nil { + log.Tracef("Node %x has invalid features", + edge.Node.PubKeyBytes) + return + } + } + // All conditions are met and this new tentative distance is // better than the current best known distance to this node. // The new better distance is recorded, and also our "next hop" diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index bcd40cf0..d65090f1 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -1482,6 +1482,21 @@ func TestMissingFeatureDep(t *testing.T) { Features: payAddrFeatures, }, 0, ), + asymmetricTestChannel("conner", "joost", 100000, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + Features: payAddrFeatures, + }, + &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000000, + }, 0, + ), } ctx := newPathFindingTestContext(t, testChannels, "roasbeef") @@ -1530,6 +1545,19 @@ func TestMissingFeatureDep(t *testing.T) { t.Fatalf("path should have been found: %v", err) } assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "conner") + + // Finally, try to find a route to joost through conner. The + // destination features are set properly from the previous assertions, + // but conner's feature vector in the graph is still broken. We expect + // errNoPathFound and not the missing feature dep err above since + // intermediate hops are simply skipped if they have invalid feature + // vectors, leaving no possible route to joost. + joost := ctx.testGraphInstance.aliasMap["joost"] + + _, err = find(&restrictions, joost) + if err != errNoPathFound { + t.Fatalf("path shouldn't have been found: %v", err) + } } // TestDestPaymentAddr asserts that we properly detect when we can send a From 495ae8ca424f1d292b4b1cbc93dfdfdcdb36e713 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:55:08 -0800 Subject: [PATCH 09/19] routing: consolidate final hop params for newRoute This commit creates a wrapper struct, grouping all parameters that influence the final hop during route construction. This is a preliminary step for passing in the receiver's invoice feature bits, which will be used to select an appropriate payment or payload type. --- routing/pathfind.go | 38 +++++++++++++++++++---------- routing/pathfind_test.go | 49 ++++++++++++++++++++++++++++---------- routing/payment_session.go | 8 +++++-- routing/router.go | 16 +++++++++---- 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 3b1c4433..1d6ff4f4 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -96,17 +96,29 @@ type edgePolicyWithSource struct { edge *channeldb.ChannelEdgePolicy } -// newRoute returns a fully valid route between the source and target that's -// capable of supporting a payment of `amtToSend` after fees are fully -// computed. If the route is too long, or the selected path cannot support the -// fully payment including fees, then a non-nil error is returned. +// finalHopParams encapsulates various parameters for route construction that +// apply to the final hop in a route. These features include basic payment data +// such as amounts and cltvs, as well as more complex features like destination +// custom records. +type finalHopParams struct { + amt lnwire.MilliSatoshi + cltvDelta uint16 + records record.CustomSet +} + +// newRoute constructs a route using the provided path and final hop constraints. +// Any destination specific fields from the final hop params will be attached +// assuming the destination's feature vector signals support, otherwise this +// method will fail. If the route is too long, or the selected path cannot +// support the fully payment including fees, then a non-nil error is returned. // // NOTE: The passed slice of ChannelHops MUST be sorted in forward order: from -// the source to the target node of the path finding attempt. -func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex, +// the source to the target node of the path finding attempt. It is assumed that +// any feature vectors on all hops have been validated for transitive +// dependencies. +func newRoute(sourceVertex route.Vertex, pathEdges []*channeldb.ChannelEdgePolicy, currentHeight uint32, - finalCLTVDelta uint16, - destCustomRecords record.CustomSet) (*route.Route, error) { + finalHop finalHopParams) (*route.Route, error) { var ( hops []*route.Hop @@ -132,7 +144,7 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex, // If this is the last hop, then the hop payload will contain // the exact amount. In BOLT #4: Onion Routing // Protocol / "Payload for the Last Node", this is detailed. - amtToForward := amtToSend + amtToForward := finalHop.amt // Fee is not part of the hop payload, but only used for // reporting through RPC. Set to zero for the final hop. @@ -161,9 +173,9 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex, // As this is the last hop, we'll use the specified // final CLTV delta value instead of the value from the // last link in the route. - totalTimeLock += uint32(finalCLTVDelta) + totalTimeLock += uint32(finalHop.cltvDelta) - outgoingTimeLock = currentHeight + uint32(finalCLTVDelta) + outgoingTimeLock = currentHeight + uint32(finalHop.cltvDelta) } else { // Next, increment the total timelock of the entire // route such that each hops time lock increases as we @@ -204,8 +216,8 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex, // If this is the last hop, then we'll populate any TLV records // destined for it. - if i == len(pathEdges)-1 && len(destCustomRecords) != 0 { - currentHop.CustomRecords = destCustomRecords + if i == len(pathEdges)-1 && len(finalHop.records) != 0 { + currentHop.CustomRecords = finalHop.records } hops = append([]*route.Hop{currentHop}, hops...) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index d65090f1..104d47b5 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -680,8 +680,12 @@ func TestFindLowestFeePath(t *testing.T) { t.Fatalf("unable to find path: %v", err) } route, err := newRoute( - paymentAmt, ctx.source, path, startingHeight, - finalHopCLTV, nil, + ctx.source, path, startingHeight, + finalHopParams{ + amt: paymentAmt, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if err != nil { t.Fatalf("unable to create path: %v", err) @@ -830,8 +834,12 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc } route, err := newRoute( - paymentAmt, sourceVertex, path, startingHeight, - finalHopCLTV, nil, + sourceVertex, path, startingHeight, + finalHopParams{ + amt: paymentAmt, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if err != nil { t.Fatalf("unable to create path: %v", err) @@ -1244,9 +1252,12 @@ func TestNewRoute(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { route, err := newRoute( - testCase.paymentAmount, sourceVertex, - testCase.hops, startingHeight, finalHopCLTV, - nil, + sourceVertex, testCase.hops, startingHeight, + finalHopParams{ + amt: testCase.paymentAmount, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if testCase.expectError { @@ -2210,8 +2221,12 @@ func TestRestrictOutgoingChannel(t *testing.T) { t.Fatalf("unable to find path: %v", err) } route, err := newRoute( - paymentAmt, ctx.source, path, startingHeight, - finalHopCLTV, nil, + ctx.source, path, startingHeight, + finalHopParams{ + amt: paymentAmt, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if err != nil { t.Fatalf("unable to create path: %v", err) @@ -2336,8 +2351,12 @@ func testCltvLimit(t *testing.T, limit uint32, expectedChannel uint64) { finalHopCLTV = 1 ) route, err := newRoute( - paymentAmt, ctx.source, path, startingHeight, finalHopCLTV, - nil, + ctx.source, path, startingHeight, + finalHopParams{ + amt: paymentAmt, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if err != nil { t.Fatalf("unable to create path: %v", err) @@ -2623,8 +2642,12 @@ func TestNoCycle(t *testing.T) { t.Fatalf("unable to find path: %v", err) } route, err := newRoute( - paymentAmt, ctx.source, path, startingHeight, - finalHopCLTV, nil, + ctx.source, path, startingHeight, + finalHopParams{ + amt: paymentAmt, + cltvDelta: finalHopCLTV, + records: nil, + }, ) if err != nil { t.Fatalf("unable to create path: %v", err) diff --git a/routing/payment_session.go b/routing/payment_session.go index 5168ba28..d8e765f1 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -129,8 +129,12 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment, // a route by applying the time-lock and fee requirements. sourceVertex := route.Vertex(ss.SelfNode.PubKeyBytes) route, err := newRoute( - payment.Amount, sourceVertex, path, height, finalCltvDelta, - payment.DestCustomRecords, + sourceVertex, path, height, + finalHopParams{ + amt: payment.Amount, + cltvDelta: finalCltvDelta, + records: payment.DestCustomRecords, + }, ) if err != nil { // TODO(roasbeef): return which edge/vertex didn't work diff --git a/routing/router.go b/routing/router.go index c8d4bebd..e8b42173 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1454,8 +1454,12 @@ func (r *ChannelRouter) FindRoute(source, target route.Vertex, // Create the route with absolute time lock values. route, err := newRoute( - amt, source, path, uint32(currentHeight), finalCLTVDelta, - destCustomRecords, + source, path, uint32(currentHeight), + finalHopParams{ + amt: amt, + cltvDelta: finalCLTVDelta, + records: destCustomRecords, + }, ) if err != nil { return nil, err @@ -2403,7 +2407,11 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi, } return newRoute( - receiverAmt, source, pathEdges, uint32(height), - uint16(finalCltvDelta), nil, + source, pathEdges, uint32(height), + finalHopParams{ + amt: receiverAmt, + cltvDelta: uint16(finalCltvDelta), + records: nil, + }, ) } From b97adf79a4752524684ddae0de629b35e1c8eb67 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:55:27 -0800 Subject: [PATCH 10/19] routing/pathfind: consolidate final vs non-final hop processing --- routing/pathfind.go | 49 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 1d6ff4f4..b11ca15b 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -141,18 +141,34 @@ func newRoute(sourceVertex route.Vertex, // payload for the hop this edge is leading to. edge := pathEdges[i] - // If this is the last hop, then the hop payload will contain - // the exact amount. In BOLT #4: Onion Routing - // Protocol / "Payload for the Last Node", this is detailed. - amtToForward := finalHop.amt + // We'll calculate the amounts, timelocks, and fees for each hop + // in the route. The base case is the final hop which includes + // their amount and timelocks. These values will accumulate + // contributions from the preceding hops back to the sender as + // we compute the route in reverse. + var ( + amtToForward lnwire.MilliSatoshi + fee lnwire.MilliSatoshi + outgoingTimeLock uint32 + ) + if i == len(pathEdges)-1 { + // If this is the last hop, then the hop payload will + // contain the exact amount. In BOLT #4: Onion Routing + // Protocol / "Payload for the Last Node", this is + // detailed. + amtToForward = finalHop.amt - // Fee is not part of the hop payload, but only used for - // reporting through RPC. Set to zero for the final hop. - fee := lnwire.MilliSatoshi(0) + // Fee is not part of the hop payload, but only used for + // reporting through RPC. Set to zero for the final hop. + fee = lnwire.MilliSatoshi(0) - // If the current hop isn't the last hop, then add enough funds - // to pay for transit over the next link. - if i != len(pathEdges)-1 { + // As this is the last hop, we'll use the specified + // final CLTV delta value instead of the value from the + // last link in the route. + totalTimeLock += uint32(finalHop.cltvDelta) + + outgoingTimeLock = currentHeight + uint32(finalHop.cltvDelta) + } else { // The amount that the current hop needs to forward is // equal to the incoming amount of the next hop. amtToForward = nextIncomingAmount @@ -163,20 +179,7 @@ func newRoute(sourceVertex route.Vertex, // is stored as part of the incoming channel of // the next hop. fee = pathEdges[i+1].ComputeFee(amtToForward) - } - // If this is the last hop, then for verification purposes, the - // value of the outgoing time-lock should be _exactly_ the - // absolute time out they'd expect in the HTLC. - var outgoingTimeLock uint32 - if i == len(pathEdges)-1 { - // As this is the last hop, we'll use the specified - // final CLTV delta value instead of the value from the - // last link in the route. - totalTimeLock += uint32(finalHop.cltvDelta) - - outgoingTimeLock = currentHeight + uint32(finalHop.cltvDelta) - } else { // Next, increment the total timelock of the entire // route such that each hops time lock increases as we // walk backwards in the route, using the delta of the From e3a9603846ea6801879022ca7a25ffc7e5567631 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:55:47 -0800 Subject: [PATCH 11/19] routing/pathfind: simplify cltv calculation --- routing/pathfind.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index b11ca15b..50c9e107 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -166,8 +166,7 @@ func newRoute(sourceVertex route.Vertex, // final CLTV delta value instead of the value from the // last link in the route. totalTimeLock += uint32(finalHop.cltvDelta) - - outgoingTimeLock = currentHeight + uint32(finalHop.cltvDelta) + outgoingTimeLock = totalTimeLock } else { // The amount that the current hop needs to forward is // equal to the incoming amount of the next hop. @@ -180,18 +179,11 @@ func newRoute(sourceVertex route.Vertex, // the next hop. fee = pathEdges[i+1].ComputeFee(amtToForward) - // Next, increment the total timelock of the entire - // route such that each hops time lock increases as we - // walk backwards in the route, using the delta of the - // previous hop. - delta := uint32(pathEdges[i+1].TimeLockDelta) - totalTimeLock += delta - - // Otherwise, the value of the outgoing time-lock will - // be the value of the time-lock for the _outgoing_ - // HTLC, so we factor in their specified grace period - // (time lock delta). - outgoingTimeLock = totalTimeLock - delta + // We'll take the total timelock of the preceding hop as + // the outgoing timelock or this hop. Then we'll + // increment the total timelock incurred by this hop. + outgoingTimeLock = totalTimeLock + totalTimeLock += uint32(pathEdges[i+1].TimeLockDelta) } // Since we're traversing the path backwards atm, we prepend From cddb71ee53bb87f1b9939ca8fdba984e9147d014 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:56:05 -0800 Subject: [PATCH 12/19] routing/pathfind: evaluate TLV support sooner We move up the check for TLV support, since we will later use it to determine if we can use dependent features, e.g. TLV records and payment addresses. --- routing/pathfind.go | 29 +++++++++++++++------------- routing/pathfind_test.go | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 50c9e107..7788dc83 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -150,7 +150,22 @@ func newRoute(sourceVertex route.Vertex, amtToForward lnwire.MilliSatoshi fee lnwire.MilliSatoshi outgoingTimeLock uint32 + tlvPayload bool ) + + // Define a helper function that checks this edge's feature + // vector for support for a given feature. We assume at this + // point that the feature vectors transitive dependencies have + // been validated. + supports := edge.Node.Features.HasFeature + + // We start by assuming the node doesn't support TLV. We'll now + // inspect the node's feature vector to see if we can promote + // the hop. We assume already that the feature vector's + // transitive dependencies have already been validated by path + // finding or some other means. + tlvPayload = supports(lnwire.TLVOnionPayloadOptional) + if i == len(pathEdges)-1 { // If this is the last hop, then the hop payload will // contain the exact amount. In BOLT #4: Onion Routing @@ -194,19 +209,7 @@ func newRoute(sourceVertex route.Vertex, ChannelID: edge.ChannelID, AmtToForward: amtToForward, OutgoingTimeLock: outgoingTimeLock, - LegacyPayload: true, - } - - // We start out above by assuming that this node needs the - // legacy payload, as if we don't have the full - // NodeAnnouncement information for this node, then we can't - // assume it knows the latest features. If we do have a feature - // vector for this node, then we'll update the info now. - if edge.Node.Features != nil { - features := edge.Node.Features - currentHop.LegacyPayload = !features.HasFeature( - lnwire.TLVOnionPayloadOptional, - ) + LegacyPayload: !tlvPayload, } // If this is the last hop, then we'll populate any TLV records diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 104d47b5..f7607166 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -1095,6 +1095,10 @@ func TestNewRoute(t *testing.T) { // indicated by hops. paymentAmount lnwire.MilliSatoshi + // destFeatures is a feature vector, that if non-nil, will + // overwrite the final hop's feature vector in the graph. + destFeatures *lnwire.FeatureVector + // expectedFees is a list of fees that every hop is expected // to charge for forwarding. expectedFees []lnwire.MilliSatoshi @@ -1123,6 +1127,8 @@ func TestNewRoute(t *testing.T) { // expectedErrorCode indicates the expected error code when // expectError is true. expectedErrorCode errorCode + + expectedTLVPayload bool }{ { // For a single hop payment, no fees are expected to be paid. @@ -1149,6 +1155,22 @@ func TestNewRoute(t *testing.T) { expectedTimeLocks: []uint32{1, 1}, expectedTotalAmount: 100130, expectedTotalTimeLock: 6, + }, { + // For a two hop payment, only the fee for the first hop + // needs to be paid. The destination hop does not require + // a fee to receive the payment. + name: "two hop tlv onion feature", + destFeatures: tlvFeatures, + paymentAmount: 100000, + hops: []*channeldb.ChannelEdgePolicy{ + createHop(0, 1000, 1000000, 10), + createHop(30, 1000, 1000000, 5), + }, + expectedFees: []lnwire.MilliSatoshi{130, 0}, + expectedTimeLocks: []uint32{1, 1}, + expectedTotalAmount: 100130, + expectedTotalTimeLock: 6, + expectedTLVPayload: true, }, { // A three hop payment where the first and second hop // will both charge 1 msat. The fee for the first hop @@ -1205,6 +1227,15 @@ func TestNewRoute(t *testing.T) { }} for _, testCase := range testCases { + testCase := testCase + + // Overwrite the final hop's features if the test requires a + // custom feature vector. + if testCase.destFeatures != nil { + finalHop := testCase.hops[len(testCase.hops)-1] + finalHop.Node.Features = testCase.destFeatures + } + assertRoute := func(t *testing.T, route *route.Route) { if route.TotalAmount != testCase.expectedTotalAmount { t.Errorf("Expected total amount is be %v"+ @@ -1248,6 +1279,16 @@ func TestNewRoute(t *testing.T) { route.Hops[i].OutgoingTimeLock) } } + + finalHop := route.Hops[len(route.Hops)-1] + if !finalHop.LegacyPayload != + testCase.expectedTLVPayload { + + t.Errorf("Expected tlv payload: %t, "+ + "but got: %t instead", + testCase.expectedTLVPayload, + !finalHop.LegacyPayload) + } } t.Run(testCase.name, func(t *testing.T) { From 7965cb08db9ece400c575729494ea37fa3924167 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:56:23 -0800 Subject: [PATCH 13/19] routing/pathfind: consolidate population of custom records --- routing/pathfind.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 7788dc83..297392a0 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -151,6 +151,7 @@ func newRoute(sourceVertex route.Vertex, fee lnwire.MilliSatoshi outgoingTimeLock uint32 tlvPayload bool + customRecords record.CustomSet ) // Define a helper function that checks this edge's feature @@ -182,6 +183,14 @@ func newRoute(sourceVertex route.Vertex, // last link in the route. totalTimeLock += uint32(finalHop.cltvDelta) outgoingTimeLock = totalTimeLock + + // Attach any custom records to the final hop if the + // receiver supports TLV. + if !tlvPayload && finalHop.records != nil { + return nil, errors.New("cannot attach " + + "custom records") + } + customRecords = finalHop.records } else { // The amount that the current hop needs to forward is // equal to the incoming amount of the next hop. @@ -210,12 +219,7 @@ func newRoute(sourceVertex route.Vertex, AmtToForward: amtToForward, OutgoingTimeLock: outgoingTimeLock, LegacyPayload: !tlvPayload, - } - - // If this is the last hop, then we'll populate any TLV records - // destined for it. - if i == len(pathEdges)-1 && len(finalHop.records) != 0 { - currentHop.CustomRecords = finalHop.records + CustomRecords: customRecords, } hops = append([]*route.Hop{currentHop}, hops...) From 0993256b77ce89d8a6b3cf97462d28f15712e745 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:56:42 -0800 Subject: [PATCH 14/19] routing/pathfind: set single-shot MPP if payment addr is known --- routing/pathfind.go | 26 ++++++++++++++++++++---- routing/pathfind_test.go | 44 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 297392a0..ea5315b6 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -99,11 +99,12 @@ type edgePolicyWithSource struct { // finalHopParams encapsulates various parameters for route construction that // apply to the final hop in a route. These features include basic payment data // such as amounts and cltvs, as well as more complex features like destination -// custom records. +// custom records and payment address. type finalHopParams struct { - amt lnwire.MilliSatoshi - cltvDelta uint16 - records record.CustomSet + amt lnwire.MilliSatoshi + cltvDelta uint16 + records record.CustomSet + paymentAddr *[32]byte } // newRoute constructs a route using the provided path and final hop constraints. @@ -152,6 +153,7 @@ func newRoute(sourceVertex route.Vertex, outgoingTimeLock uint32 tlvPayload bool customRecords record.CustomSet + mpp *record.MPP ) // Define a helper function that checks this edge's feature @@ -191,6 +193,21 @@ func newRoute(sourceVertex route.Vertex, "custom records") } customRecords = finalHop.records + + // If we're attaching a payment addr but the receiver + // doesn't support both TLV and payment addrs, fail. + payAddr := supports(lnwire.PaymentAddrOptional) + if !payAddr && finalHop.paymentAddr != nil { + return nil, errors.New("cannot attach " + + "payment addr") + } + + // Otherwise attach the mpp record if it exists. + if finalHop.paymentAddr != nil { + mpp = record.NewMPP( + finalHop.amt, *finalHop.paymentAddr, + ) + } } else { // The amount that the current hop needs to forward is // equal to the incoming amount of the next hop. @@ -220,6 +237,7 @@ func newRoute(sourceVertex route.Vertex, OutgoingTimeLock: outgoingTimeLock, LegacyPayload: !tlvPayload, CustomRecords: customRecords, + MPP: mpp, } hops = append([]*route.Hop{currentHop}, hops...) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index f7607166..acff0d2b 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -13,6 +13,7 @@ import ( "math/big" "net" "os" + "reflect" "strings" "testing" "time" @@ -1061,6 +1062,8 @@ func TestNewRoute(t *testing.T) { var sourceKey [33]byte sourceVertex := route.Vertex(sourceKey) + testPaymentAddr := [32]byte{0x01, 0x02, 0x03} + const ( startingHeight = 100 finalHopCLTV = 1 @@ -1099,6 +1102,8 @@ func TestNewRoute(t *testing.T) { // overwrite the final hop's feature vector in the graph. destFeatures *lnwire.FeatureVector + paymentAddr *[32]byte + // expectedFees is a list of fees that every hop is expected // to charge for forwarding. expectedFees []lnwire.MilliSatoshi @@ -1129,6 +1134,8 @@ func TestNewRoute(t *testing.T) { expectedErrorCode errorCode expectedTLVPayload bool + + expectedMPP *record.MPP }{ { // For a single hop payment, no fees are expected to be paid. @@ -1171,6 +1178,26 @@ func TestNewRoute(t *testing.T) { expectedTotalAmount: 100130, expectedTotalTimeLock: 6, expectedTLVPayload: true, + }, { + // For a two hop payment, only the fee for the first hop + // needs to be paid. The destination hop does not require + // a fee to receive the payment. + name: "two hop single shot mpp", + destFeatures: tlvPayAddrFeatures, + paymentAddr: &testPaymentAddr, + paymentAmount: 100000, + hops: []*channeldb.ChannelEdgePolicy{ + createHop(0, 1000, 1000000, 10), + createHop(30, 1000, 1000000, 5), + }, + expectedFees: []lnwire.MilliSatoshi{130, 0}, + expectedTimeLocks: []uint32{1, 1}, + expectedTotalAmount: 100130, + expectedTotalTimeLock: 6, + expectedTLVPayload: true, + expectedMPP: record.NewMPP( + 100000, testPaymentAddr, + ), }, { // A three hop payment where the first and second hop // will both charge 1 msat. The fee for the first hop @@ -1284,20 +1311,29 @@ func TestNewRoute(t *testing.T) { if !finalHop.LegacyPayload != testCase.expectedTLVPayload { - t.Errorf("Expected tlv payload: %t, "+ + t.Errorf("Expected final hop tlv payload: %t, "+ "but got: %t instead", testCase.expectedTLVPayload, !finalHop.LegacyPayload) } + + if !reflect.DeepEqual( + finalHop.MPP, testCase.expectedMPP, + ) { + t.Errorf("Expected final hop mpp field: %v, "+ + " but got: %v instead", + testCase.expectedMPP, finalHop.MPP) + } } t.Run(testCase.name, func(t *testing.T) { route, err := newRoute( sourceVertex, testCase.hops, startingHeight, finalHopParams{ - amt: testCase.paymentAmount, - cltvDelta: finalHopCLTV, - records: nil, + amt: testCase.paymentAmount, + cltvDelta: finalHopCLTV, + records: nil, + paymentAddr: testCase.paymentAddr, }, ) From f868bc128b412876b08880b716c5ffb2be69d4de Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:56:59 -0800 Subject: [PATCH 15/19] rpcserver+routerrpc: thread features + payment addr to SendPayment --- lnrpc/routerrpc/router_backend.go | 2 ++ routing/payment_session.go | 9 ++++++--- routing/router.go | 13 +++++++++++++ rpcserver.go | 6 ++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index 7722a3c8..383180a3 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -602,6 +602,8 @@ func (r *RouterBackend) extractIntentFromSendRequest( payIntent.RouteHints = append( payIntent.RouteHints, payReq.RouteHints..., ) + payIntent.DestFeatures = payReq.Features + payIntent.PaymentAddr = payReq.PaymentAddr } else { // Otherwise, If the payment request field was not specified // (and a custom route wasn't specified), construct the payment diff --git a/routing/payment_session.go b/routing/payment_session.go index d8e765f1..e5474ddf 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -98,6 +98,8 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment, LastHop: payment.LastHop, CltvLimit: cltvLimit, DestCustomRecords: payment.DestCustomRecords, + DestFeatures: payment.DestFeatures, + PaymentAddr: payment.PaymentAddr, } // We'll also obtain a set of bandwidthHints from the lower layer for @@ -131,9 +133,10 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment, route, err := newRoute( sourceVertex, path, height, finalHopParams{ - amt: payment.Amount, - cltvDelta: finalCltvDelta, - records: payment.DestCustomRecords, + amt: payment.Amount, + cltvDelta: finalCltvDelta, + records: payment.DestCustomRecords, + paymentAddr: payment.PaymentAddr, }, ) if err != nil { diff --git a/routing/router.go b/routing/router.go index e8b42173..ef38788d 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1601,6 +1601,19 @@ type LightningPayment struct { // is reached. If nil, any node may be used. LastHop *route.Vertex + // DestFeatures specifies the set of features we assume the final node + // has for pathfinding. Typically these will be taken directly from an + // invoice, but they can also be manually supplied or assumed by the + // sender. If a nil feature vector is provided, the router will try to + // fallback to the graph in order to load a feature vector for a node in + // the public graph. + DestFeatures *lnwire.FeatureVector + + // PaymentAddr is the payment address specified by the receiver. This + // field should be a random 32-byte nonce presented in the receiver's + // invoice to prevent probing of the destination. + PaymentAddr *[32]byte + // PaymentRequest is an optional payment request that this payment is // attempting to complete. PaymentRequest []byte diff --git a/rpcserver.go b/rpcserver.go index b016ca98..1e5e71b1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3241,6 +3241,8 @@ type rpcPaymentIntent struct { routeHints [][]zpay32.HopHint outgoingChannelID *uint64 lastHop *route.Vertex + destFeatures *lnwire.FeatureVector + paymentAddr *[32]byte payReq []byte destCustomRecords record.CustomSet @@ -3370,6 +3372,8 @@ func (r *rpcServer) extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPayme payIntent.cltvDelta = uint16(payReq.MinFinalCLTVExpiry()) payIntent.routeHints = payReq.RouteHints payIntent.payReq = []byte(rpcPayReq.PaymentRequest) + payIntent.destFeatures = payReq.Features + payIntent.paymentAddr = payReq.PaymentAddr if err := validateDest(payIntent.dest); err != nil { return payIntent, err @@ -3492,6 +3496,8 @@ func (r *rpcServer) dispatchPaymentIntent( PaymentRequest: payIntent.payReq, PayAttemptTimeout: routing.DefaultPayAttemptTimeout, DestCustomRecords: payIntent.destCustomRecords, + DestFeatures: payIntent.destFeatures, + PaymentAddr: payIntent.paymentAddr, } preImage, route, routerErr = r.server.chanRouter.SendPayment( From 396a978cec9fd0f95bdfaec01262051b6735a946 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:57:12 -0800 Subject: [PATCH 16/19] lntest+wait: replace sleeps in assertAmountSent This commit constructs a helper closure assertAmountSent that can be reused by other functions. The closure returns an error so that it can be used with wait.NoError or the new wait.InvariantNoError. The latter is added since the predicate could otherwise pass immediately for the sphinx_replay_persistence tests, but change shortly after. It also rounds out the wait package so that we offer all combinations of predicate and no-error style waits. --- lntest/itest/lnd_test.go | 129 +++++++++++++++++++++------------------ lntest/wait/wait.go | 20 ++++++ 2 files changed, 88 insertions(+), 61 deletions(-) diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 8cd889b4..d64d314b 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -3704,6 +3704,48 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { } } +// assertAmountSent generates a closure which queries listchannels for sndr and +// rcvr, and asserts that sndr sent amt satoshis, and that rcvr received amt +// satoshis. +// +// NOTE: This method assumes that each node only has one channel, and it is the +// channel used to send the payment. +func assertAmountSent(amt btcutil.Amount, sndr, rcvr *lntest.HarnessNode) func() error { + return func() error { + // Both channels should also have properly accounted from the + // amount that has been sent/received over the channel. + listReq := &lnrpc.ListChannelsRequest{} + ctxb := context.Background() + ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) + sndrListChannels, err := sndr.ListChannels(ctxt, listReq) + if err != nil { + return fmt.Errorf("unable to query for %s's channel "+ + "list: %v", sndr.Name(), err) + } + sndrSatoshisSent := sndrListChannels.Channels[0].TotalSatoshisSent + if sndrSatoshisSent != int64(amt) { + return fmt.Errorf("%s's satoshis sent is incorrect "+ + "got %v, expected %v", sndr.Name(), + sndrSatoshisSent, amt) + } + + ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) + rcvrListChannels, err := rcvr.ListChannels(ctxt, listReq) + if err != nil { + return fmt.Errorf("unable to query for %s's channel "+ + "list: %v", rcvr.Name(), err) + } + rcvrSatoshisReceived := rcvrListChannels.Channels[0].TotalSatoshisReceived + if rcvrSatoshisReceived != int64(amt) { + return fmt.Errorf("%s's satoshis received is "+ + "incorrect got %v, expected %v", rcvr.Name(), + rcvrSatoshisReceived, amt) + } + + return nil + } +} + // testSphinxReplayPersistence verifies that replayed onion packets are rejected // by a remote peer after a restart. We use a combination of unsafe // configuration arguments to force Carol to replay the same sphinx packet after @@ -3753,33 +3795,6 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) { }, ) - assertAmountSent := func(amt btcutil.Amount) { - // Both channels should also have properly accounted from the - // amount that has been sent/received over the channel. - listReq := &lnrpc.ListChannelsRequest{} - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - carolListChannels, err := carol.ListChannels(ctxt, listReq) - if err != nil { - t.Fatalf("unable to query for alice's channel list: %v", err) - } - carolSatoshisSent := carolListChannels.Channels[0].TotalSatoshisSent - if carolSatoshisSent != int64(amt) { - t.Fatalf("Carol's satoshis sent is incorrect got %v, expected %v", - carolSatoshisSent, amt) - } - - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - daveListChannels, err := dave.ListChannels(ctxt, listReq) - if err != nil { - t.Fatalf("unable to query for Dave's channel list: %v", err) - } - daveSatoshisReceived := daveListChannels.Channels[0].TotalSatoshisReceived - if daveSatoshisReceived != int64(amt) { - t.Fatalf("Dave's satoshis received is incorrect got %v, expected %v", - daveSatoshisReceived, amt) - } - } - // Now that the channel is open, create an invoice for Dave which // expects a payment of 1000 satoshis from Carol paid via a particular // preimage. @@ -3844,8 +3859,12 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) { // With the payment sent but hedl, all balance related stats should not // have changed. - time.Sleep(time.Millisecond * 200) - assertAmountSent(0) + err = wait.InvariantNoError( + assertAmountSent(0, carol, dave), 3*time.Second, + ) + if err != nil { + t.Fatalf(err.Error()) + } // With the first payment sent, restart dave to make sure he is // persisting the information required to detect replayed sphinx @@ -3874,7 +3893,12 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) { // Since the payment failed, the balance should still be left // unaltered. - assertAmountSent(0) + err = wait.InvariantNoError( + assertAmountSent(0, carol, dave), 3*time.Second, + ) + if err != nil { + t.Fatalf(err.Error()) + } ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) closeChannelAndAssert(ctxt, t, net, carol, chanPoint, true) @@ -3897,33 +3921,6 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) { }, ) - assertAmountSent := func(amt btcutil.Amount) { - // Both channels should also have properly accounted from the - // amount that has been sent/received over the channel. - listReq := &lnrpc.ListChannelsRequest{} - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - aliceListChannels, err := net.Alice.ListChannels(ctxt, listReq) - if err != nil { - t.Fatalf("unable to query for alice's channel list: %v", err) - } - aliceSatoshisSent := aliceListChannels.Channels[0].TotalSatoshisSent - if aliceSatoshisSent != int64(amt) { - t.Fatalf("Alice's satoshis sent is incorrect got %v, expected %v", - aliceSatoshisSent, amt) - } - - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - bobListChannels, err := net.Bob.ListChannels(ctxt, listReq) - if err != nil { - t.Fatalf("unable to query for bob's channel list: %v", err) - } - bobSatoshisReceived := bobListChannels.Channels[0].TotalSatoshisReceived - if bobSatoshisReceived != int64(amt) { - t.Fatalf("Bob's satoshis received is incorrect got %v, expected %v", - bobSatoshisReceived, amt) - } - } - // Now that the channel is open, create an invoice for Bob which // expects a payment of 1000 satoshis from Alice paid via a particular // preimage. @@ -3989,8 +3986,13 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) { // With the payment completed all balance related stats should be // properly updated. - time.Sleep(time.Millisecond * 200) - assertAmountSent(paymentAmt) + err = wait.NoError( + assertAmountSent(paymentAmt, net.Alice, net.Bob), + 3*time.Second, + ) + if err != nil { + t.Fatalf(err.Error()) + } // Create another invoice for Bob, this time leaving off the preimage // to one will be randomly generated. We'll test the proper @@ -4021,8 +4023,13 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) { // The second payment should also have succeeded, with the balances // being update accordingly. - time.Sleep(time.Millisecond * 200) - assertAmountSent(paymentAmt * 2) + err = wait.NoError( + assertAmountSent(2*paymentAmt, net.Alice, net.Bob), + 3*time.Second, + ) + if err != nil { + t.Fatalf(err.Error()) + } ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) diff --git a/lntest/wait/wait.go b/lntest/wait/wait.go index 1ff16914..88cdb27d 100644 --- a/lntest/wait/wait.go +++ b/lntest/wait/wait.go @@ -76,3 +76,23 @@ func Invariant(statement func() bool, timeout time.Duration) error { } } } + +// InvariantNoError is a wrapper around Invariant that waits out the duration +// specified by timeout. It fails if the predicate ever returns an error during +// that time. +func InvariantNoError(f func() error, timeout time.Duration) error { + var predErr error + pred := func() bool { + if err := f(); err != nil { + predErr = err + return false + } + return true + } + + if err := Invariant(pred, timeout); err != nil { + return predErr + } + + return nil +} From 457fda6095312eb7f28ce7e79a33262df187295a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:57:23 -0800 Subject: [PATCH 17/19] routerrpc: add dest_features to SendPaymentRequest --- lnrpc/routerrpc/router.pb.go | 283 ++++---- lnrpc/routerrpc/router.proto | 7 + lnrpc/rpc.pb.go | 1264 ++++++++++++++++++---------------- lnrpc/rpc.proto | 27 + lnrpc/rpc.swagger.json | 30 + 5 files changed, 893 insertions(+), 718 deletions(-) diff --git a/lnrpc/routerrpc/router.pb.go b/lnrpc/routerrpc/router.pb.go index b0cdb7bf..4f872cfc 100644 --- a/lnrpc/routerrpc/router.pb.go +++ b/lnrpc/routerrpc/router.pb.go @@ -254,10 +254,15 @@ type SendPaymentRequest struct { //must be encoded as base64. DestCustomRecords map[uint64][]byte `protobuf:"bytes,11,rep,name=dest_custom_records,json=destCustomRecords,proto3" json:"dest_custom_records,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` /// If set, circular payments to self are permitted. - AllowSelfPayment bool `protobuf:"varint,15,opt,name=allow_self_payment,json=allowSelfPayment,proto3" json:"allow_self_payment,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AllowSelfPayment bool `protobuf:"varint,15,opt,name=allow_self_payment,json=allowSelfPayment,proto3" json:"allow_self_payment,omitempty"` + //* + //Features assumed to be supported by the final node. All transitive feature + //depdencies must also be set properly. For a given feature bit pair, either + //optional or remote may be set, but not both. + DestFeatures []lnrpc.FeatureBit `protobuf:"varint,16,rep,packed,name=dest_features,json=destFeatures,proto3,enum=lnrpc.FeatureBit" json:"dest_features,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SendPaymentRequest) Reset() { *m = SendPaymentRequest{} } @@ -390,6 +395,13 @@ func (m *SendPaymentRequest) GetAllowSelfPayment() bool { return false } +func (m *SendPaymentRequest) GetDestFeatures() []lnrpc.FeatureBit { + if m != nil { + return m.DestFeatures + } + return nil +} + type TrackPaymentRequest struct { /// The hash of the payment to look up. PaymentHash []byte `protobuf:"bytes,1,opt,name=payment_hash,json=paymentHash,proto3" json:"payment_hash,omitempty"` @@ -1512,137 +1524,138 @@ func init() { func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) } var fileDescriptor_7a0613f69d37b0a5 = []byte{ - // 2065 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0xdd, 0x72, 0xdb, 0xc6, - 0x15, 0x0e, 0xc4, 0xff, 0x43, 0x52, 0x84, 0x56, 0x8a, 0x4c, 0x53, 0x56, 0xa2, 0x20, 0xae, 0xc3, - 0xf1, 0x38, 0x92, 0xab, 0x36, 0x19, 0x4f, 0x2f, 0xda, 0xa1, 0x48, 0x30, 0x82, 0x4c, 0x82, 0xf2, - 0x92, 0x74, 0xe2, 0xe6, 0x62, 0x67, 0x45, 0xae, 0x44, 0x8c, 0x40, 0x80, 0x01, 0x96, 0x8e, 0xf5, - 0x0e, 0x7d, 0x8f, 0xf6, 0xa2, 0xed, 0x4d, 0x9f, 0xa0, 0x2f, 0xd3, 0xde, 0x77, 0xa6, 0xf7, 0x9d, - 0xdd, 0x05, 0x48, 0x90, 0xa2, 0x9c, 0x5e, 0x89, 0xfb, 0x9d, 0x6f, 0xcf, 0x59, 0xec, 0x39, 0xfb, - 0xed, 0x59, 0xc1, 0x7e, 0xe0, 0xcf, 0x39, 0x0b, 0x82, 0xd9, 0xe8, 0x44, 0xfd, 0x3a, 0x9e, 0x05, - 0x3e, 0xf7, 0x51, 0x61, 0x81, 0xd7, 0x0a, 0xc1, 0x6c, 0xa4, 0x50, 0xe3, 0x9f, 0x19, 0x40, 0x7d, - 0xe6, 0x8d, 0x2f, 0xe9, 0xdd, 0x94, 0x79, 0x1c, 0xb3, 0x9f, 0xe6, 0x2c, 0xe4, 0x08, 0x41, 0x7a, - 0xcc, 0x42, 0x5e, 0xd5, 0x8e, 0xb4, 0x7a, 0x09, 0xcb, 0xdf, 0x48, 0x87, 0x14, 0x9d, 0xf2, 0xea, - 0xd6, 0x91, 0x56, 0x4f, 0x61, 0xf1, 0x13, 0x3d, 0x86, 0x3c, 0x9d, 0x72, 0x32, 0x0d, 0x29, 0xaf, - 0x96, 0x24, 0x9c, 0xa3, 0x53, 0xde, 0x0d, 0x29, 0x47, 0x5f, 0x40, 0x69, 0xa6, 0x5c, 0x92, 0x09, - 0x0d, 0x27, 0xd5, 0x94, 0x74, 0x54, 0x8c, 0xb0, 0x73, 0x1a, 0x4e, 0x50, 0x1d, 0xf4, 0x6b, 0xc7, - 0xa3, 0x2e, 0x19, 0xb9, 0xfc, 0x3d, 0x19, 0x33, 0x97, 0xd3, 0x6a, 0xfa, 0x48, 0xab, 0x67, 0xf0, - 0xb6, 0xc4, 0x9b, 0x2e, 0x7f, 0xdf, 0x12, 0x28, 0xfa, 0x0a, 0x2a, 0xb1, 0xb3, 0x40, 0x2d, 0xb0, - 0x9a, 0x39, 0xd2, 0xea, 0x05, 0xbc, 0x3d, 0x5b, 0x5d, 0xf6, 0x57, 0x50, 0xe1, 0xce, 0x94, 0xf9, - 0x73, 0x4e, 0x42, 0x36, 0xf2, 0xbd, 0x71, 0x58, 0xcd, 0x2a, 0x8f, 0x11, 0xdc, 0x57, 0x28, 0x32, - 0xa0, 0x7c, 0xcd, 0x18, 0x71, 0x9d, 0xa9, 0xc3, 0x89, 0x58, 0x7e, 0x4e, 0x2e, 0xbf, 0x78, 0xcd, - 0x58, 0x47, 0x60, 0x7d, 0xca, 0xd1, 0x53, 0xd8, 0x5e, 0x72, 0xe4, 0x37, 0x96, 0x25, 0xa9, 0x14, - 0x93, 0xe4, 0x87, 0xbe, 0x00, 0xdd, 0x9f, 0xf3, 0x1b, 0xdf, 0xf1, 0x6e, 0xc8, 0x68, 0x42, 0x3d, - 0xe2, 0x8c, 0xab, 0xf9, 0x23, 0xad, 0x9e, 0x3e, 0xdb, 0x7a, 0xa9, 0xe1, 0xed, 0xd8, 0xd6, 0x9c, - 0x50, 0xcf, 0x1a, 0xa3, 0x67, 0x50, 0x71, 0x69, 0xc8, 0xc9, 0xc4, 0x9f, 0x91, 0xd9, 0xfc, 0xea, - 0x96, 0xdd, 0x55, 0xb7, 0xe5, 0xce, 0x94, 0x05, 0x7c, 0xee, 0xcf, 0x2e, 0x25, 0x88, 0x0e, 0x01, - 0xe4, 0xae, 0xc8, 0xe0, 0xd5, 0x82, 0xfc, 0x86, 0x82, 0x40, 0x64, 0x60, 0x74, 0x0a, 0x45, 0x99, - 0x4d, 0x32, 0x71, 0x3c, 0x1e, 0x56, 0xe1, 0x28, 0x55, 0x2f, 0x9e, 0xea, 0xc7, 0xae, 0x27, 0x12, - 0x8b, 0x85, 0xe5, 0xdc, 0xf1, 0x38, 0x4e, 0x92, 0xd0, 0x18, 0x76, 0x45, 0x1a, 0xc9, 0x68, 0x1e, - 0x72, 0x7f, 0x4a, 0x02, 0x36, 0xf2, 0x83, 0x71, 0x58, 0x2d, 0xca, 0xb9, 0xbf, 0x3d, 0x5e, 0x54, - 0xc7, 0xf1, 0xfd, 0x72, 0x38, 0x6e, 0xb1, 0x90, 0x37, 0xe5, 0x3c, 0xac, 0xa6, 0x99, 0x1e, 0x0f, - 0xee, 0xf0, 0xce, 0x78, 0x1d, 0x47, 0x2f, 0x00, 0x51, 0xd7, 0xf5, 0x7f, 0x26, 0x21, 0x73, 0xaf, - 0x49, 0x94, 0x9e, 0x6a, 0xe5, 0x48, 0xab, 0xe7, 0xb1, 0x2e, 0x2d, 0x7d, 0xe6, 0x5e, 0x47, 0xee, - 0x6b, 0x2d, 0xd8, 0xdf, 0xec, 0x5a, 0x14, 0x9b, 0xd8, 0x1c, 0x51, 0x7f, 0x69, 0x2c, 0x7e, 0xa2, - 0x3d, 0xc8, 0xbc, 0xa7, 0xee, 0x9c, 0xc9, 0x02, 0x2c, 0x61, 0x35, 0xf8, 0xdd, 0xd6, 0x2b, 0xcd, - 0x78, 0x05, 0xbb, 0x83, 0x80, 0x8e, 0x6e, 0xd7, 0x6a, 0x78, 0xbd, 0x04, 0xb5, 0x7b, 0x25, 0x68, - 0xfc, 0x45, 0x83, 0x72, 0x34, 0xab, 0xcf, 0x29, 0x9f, 0x87, 0xe8, 0x6b, 0xc8, 0x84, 0x9c, 0x72, - 0x26, 0xd9, 0xdb, 0xa7, 0x8f, 0x12, 0xfb, 0x92, 0x20, 0x32, 0xac, 0x58, 0xa8, 0x06, 0xf9, 0x59, - 0xc0, 0x9c, 0x29, 0xbd, 0x89, 0xd7, 0xb5, 0x18, 0x23, 0x03, 0x32, 0x72, 0xb2, 0xac, 0xfd, 0xe2, - 0x69, 0x29, 0x99, 0x1e, 0xac, 0x4c, 0xa8, 0x0e, 0x99, 0x09, 0x77, 0x47, 0x61, 0x35, 0x2d, 0xd3, - 0x80, 0x22, 0xce, 0xf9, 0xa0, 0xd3, 0x6c, 0x70, 0xce, 0xa6, 0x33, 0x8e, 0x15, 0xc1, 0xf8, 0x3d, - 0x54, 0xe4, 0xcc, 0x36, 0x63, 0x1f, 0x3b, 0xa4, 0x8f, 0x40, 0x1c, 0x41, 0x59, 0xd2, 0xea, 0xa0, - 0x66, 0xe9, 0x54, 0x54, 0xb3, 0x31, 0x06, 0x7d, 0x39, 0x3f, 0x9c, 0xf9, 0x5e, 0x28, 0xa2, 0xeb, - 0x62, 0x19, 0xa2, 0x74, 0x45, 0xa5, 0xcb, 0x1a, 0xd7, 0xe4, 0xac, 0xed, 0x08, 0x6f, 0x33, 0x26, - 0xab, 0xfc, 0x99, 0x3a, 0x58, 0xc4, 0xf5, 0x47, 0xb7, 0xe2, 0xa8, 0xd2, 0xbb, 0xc8, 0x7d, 0x59, - 0xc0, 0x1d, 0x7f, 0x74, 0xdb, 0x12, 0xa0, 0xf1, 0xa3, 0x52, 0x93, 0x81, 0xaf, 0xbe, 0xf2, 0xff, - 0xce, 0xc4, 0x72, 0xb3, 0xb6, 0x1e, 0xdc, 0x2c, 0x83, 0xc0, 0xee, 0x8a, 0xf3, 0xe8, 0x2b, 0x92, - 0x39, 0xd0, 0xd6, 0x72, 0xf0, 0x02, 0x72, 0xd7, 0xd4, 0x71, 0xe7, 0x41, 0xec, 0x18, 0x25, 0x12, - 0xda, 0x56, 0x16, 0x1c, 0x53, 0x8c, 0xff, 0xe6, 0x20, 0x17, 0x81, 0xe8, 0x14, 0xd2, 0x23, 0x7f, - 0x1c, 0xd7, 0xc1, 0x67, 0xf7, 0xa7, 0xc5, 0x7f, 0x9b, 0xfe, 0x98, 0x61, 0xc9, 0x45, 0x7f, 0x80, - 0x6d, 0x21, 0x01, 0x1e, 0x73, 0xc9, 0x7c, 0x36, 0xa6, 0x8b, 0xd4, 0x57, 0x13, 0xb3, 0x9b, 0x8a, - 0x30, 0x94, 0x76, 0x5c, 0x1e, 0x25, 0x87, 0xe8, 0x00, 0x0a, 0x22, 0xdb, 0x2a, 0x13, 0x69, 0x59, - 0xfb, 0x79, 0x01, 0xc8, 0x1c, 0x18, 0x50, 0xf6, 0x3d, 0xc7, 0xf7, 0x48, 0x38, 0xa1, 0xe4, 0xf4, - 0x9b, 0x6f, 0xa5, 0x06, 0x96, 0x70, 0x51, 0x82, 0xfd, 0x09, 0x3d, 0xfd, 0xe6, 0x5b, 0xf4, 0x39, - 0x14, 0xa5, 0x6e, 0xb0, 0x0f, 0x33, 0x27, 0xb8, 0x93, 0xe2, 0x57, 0xc6, 0x52, 0x4a, 0x4c, 0x89, - 0x88, 0x53, 0x74, 0xed, 0xd2, 0x9b, 0x50, 0x0a, 0x5e, 0x19, 0xab, 0x01, 0x7a, 0x09, 0x7b, 0xd1, - 0x1e, 0x90, 0xd0, 0x9f, 0x07, 0x23, 0x46, 0x1c, 0x6f, 0xcc, 0x3e, 0x48, 0x21, 0x2b, 0x63, 0x14, - 0xd9, 0xfa, 0xd2, 0x64, 0x09, 0x0b, 0xda, 0x87, 0xec, 0x84, 0x39, 0x37, 0x13, 0x25, 0x4e, 0x65, - 0x1c, 0x8d, 0x8c, 0xbf, 0x66, 0xa0, 0x98, 0xd8, 0x18, 0x54, 0x82, 0x3c, 0x36, 0xfb, 0x26, 0x7e, - 0x6b, 0xb6, 0xf4, 0x4f, 0x50, 0x1d, 0x9e, 0x5a, 0x76, 0xb3, 0x87, 0xb1, 0xd9, 0x1c, 0x90, 0x1e, - 0x26, 0x43, 0xfb, 0xb5, 0xdd, 0xfb, 0xde, 0x26, 0x97, 0x8d, 0x77, 0x5d, 0xd3, 0x1e, 0x90, 0x96, - 0x39, 0x68, 0x58, 0x9d, 0xbe, 0xae, 0xa1, 0x27, 0x50, 0x5d, 0x32, 0x63, 0x73, 0xa3, 0xdb, 0x1b, - 0xda, 0x03, 0x7d, 0x0b, 0x7d, 0x0e, 0x07, 0x6d, 0xcb, 0x6e, 0x74, 0xc8, 0x92, 0xd3, 0xec, 0x0c, - 0xde, 0x12, 0xf3, 0x87, 0x4b, 0x0b, 0xbf, 0xd3, 0x53, 0x9b, 0x08, 0xe2, 0x4c, 0xc5, 0x1e, 0xd2, - 0xe8, 0x31, 0x7c, 0xaa, 0x08, 0x6a, 0x0a, 0x19, 0xf4, 0x7a, 0xa4, 0xdf, 0xeb, 0xd9, 0x7a, 0x06, - 0xed, 0x40, 0xd9, 0xb2, 0xdf, 0x36, 0x3a, 0x56, 0x8b, 0x60, 0xb3, 0xd1, 0xe9, 0xea, 0x59, 0xb4, - 0x0b, 0x95, 0x75, 0x5e, 0x4e, 0xb8, 0x88, 0x79, 0x3d, 0xdb, 0xea, 0xd9, 0xe4, 0xad, 0x89, 0xfb, - 0x56, 0xcf, 0xd6, 0xf3, 0x68, 0x1f, 0xd0, 0xaa, 0xe9, 0xbc, 0xdb, 0x68, 0xea, 0x05, 0xf4, 0x29, - 0xec, 0xac, 0xe2, 0xaf, 0xcd, 0x77, 0x3a, 0xa0, 0x2a, 0xec, 0xa9, 0x85, 0x91, 0x33, 0xb3, 0xd3, - 0xfb, 0x9e, 0x74, 0x2d, 0xdb, 0xea, 0x0e, 0xbb, 0x7a, 0x11, 0xed, 0x81, 0xde, 0x36, 0x4d, 0x62, - 0xd9, 0xfd, 0x61, 0xbb, 0x6d, 0x35, 0x2d, 0xd3, 0x1e, 0xe8, 0x25, 0x15, 0x79, 0xd3, 0x87, 0x97, - 0xc5, 0x84, 0xe6, 0x79, 0xc3, 0xb6, 0xcd, 0x0e, 0x69, 0x59, 0xfd, 0xc6, 0x59, 0xc7, 0x6c, 0xe9, - 0xdb, 0xe8, 0x10, 0x1e, 0x0f, 0xcc, 0xee, 0x65, 0x0f, 0x37, 0xf0, 0x3b, 0x12, 0xdb, 0xdb, 0x0d, - 0xab, 0x33, 0xc4, 0xa6, 0x5e, 0x41, 0x5f, 0xc0, 0x21, 0x36, 0xdf, 0x0c, 0x2d, 0x6c, 0xb6, 0x88, - 0xdd, 0x6b, 0x99, 0xa4, 0x6d, 0x36, 0x06, 0x43, 0x6c, 0x92, 0xae, 0xd5, 0xef, 0x5b, 0xf6, 0x77, - 0xba, 0x8e, 0x9e, 0xc2, 0xd1, 0x82, 0xb2, 0x70, 0xb0, 0xc6, 0xda, 0x11, 0xdf, 0x17, 0xa7, 0xd4, - 0x36, 0x7f, 0x18, 0x90, 0x4b, 0xd3, 0xc4, 0x3a, 0x42, 0x35, 0xd8, 0x5f, 0x86, 0x57, 0x01, 0xa2, - 0xd8, 0xbb, 0xc2, 0x76, 0x69, 0xe2, 0x6e, 0xc3, 0x16, 0x09, 0x5e, 0xb1, 0xed, 0x89, 0x65, 0x2f, - 0x6d, 0xeb, 0xcb, 0xfe, 0x14, 0x21, 0xd8, 0x4e, 0x64, 0xa5, 0xdd, 0xc0, 0xfa, 0x3e, 0xda, 0x83, - 0x4a, 0xbc, 0x82, 0x98, 0xf8, 0xaf, 0x1c, 0x7a, 0x04, 0x68, 0x68, 0x63, 0xb3, 0xd1, 0x12, 0x1b, - 0xb2, 0x30, 0xfc, 0x3b, 0x77, 0x91, 0xce, 0x6f, 0xe9, 0x29, 0xe3, 0x1f, 0x29, 0x28, 0xaf, 0x9c, - 0x4b, 0xf4, 0x04, 0x0a, 0xa1, 0x73, 0xe3, 0x51, 0x2e, 0x94, 0x43, 0x89, 0xca, 0x12, 0x90, 0xb7, - 0xf3, 0x84, 0x3a, 0x9e, 0x52, 0x33, 0xa5, 0xfb, 0x05, 0x89, 0x48, 0x2d, 0x3b, 0x80, 0x5c, 0xdc, - 0x09, 0xa4, 0x16, 0x9d, 0x40, 0x76, 0xa4, 0x3a, 0x80, 0x27, 0x50, 0x10, 0x92, 0x19, 0x72, 0x3a, - 0x9d, 0xc9, 0x23, 0x5e, 0xc6, 0x4b, 0x00, 0x7d, 0x09, 0xe5, 0x29, 0x0b, 0x43, 0x7a, 0xc3, 0x88, - 0x3a, 0xa6, 0x20, 0x19, 0xa5, 0x08, 0x6c, 0xcb, 0xd3, 0xfa, 0x25, 0xc4, 0xb2, 0x11, 0x91, 0x32, - 0x8a, 0x14, 0x81, 0x8a, 0xb4, 0xae, 0xd8, 0x9c, 0x46, 0x6a, 0x90, 0x54, 0x6c, 0x4e, 0xd1, 0x73, - 0xd8, 0x51, 0x92, 0xe3, 0x78, 0xce, 0x74, 0x3e, 0x55, 0xd2, 0x93, 0x93, 0xd2, 0x53, 0x91, 0xd2, - 0xa3, 0x70, 0xa9, 0x40, 0x8f, 0x21, 0x7f, 0x45, 0x43, 0x26, 0x2e, 0x8b, 0x48, 0x1a, 0x72, 0x62, - 0xdc, 0x66, 0x4c, 0x98, 0xc4, 0x15, 0x12, 0x08, 0xd1, 0x53, 0x8a, 0x90, 0xbb, 0x66, 0x0c, 0x8b, - 0xbd, 0x5c, 0x44, 0xa0, 0x1f, 0x96, 0x11, 0x8a, 0x89, 0x08, 0x0a, 0x97, 0x11, 0x9e, 0xc3, 0x0e, - 0xfb, 0xc0, 0x03, 0x4a, 0xfc, 0x19, 0xfd, 0x69, 0xce, 0xc8, 0x98, 0x72, 0x2a, 0x5b, 0xcb, 0x12, - 0xae, 0x48, 0x43, 0x4f, 0xe2, 0x2d, 0xca, 0xa9, 0xf1, 0x04, 0x6a, 0x98, 0x85, 0x8c, 0x77, 0x9d, - 0x30, 0x74, 0x7c, 0xaf, 0xe9, 0x7b, 0x3c, 0xf0, 0xdd, 0xe8, 0xce, 0x31, 0x0e, 0xe1, 0x60, 0xa3, - 0x55, 0x5d, 0x1a, 0x62, 0xf2, 0x9b, 0x39, 0x0b, 0xee, 0x36, 0x4f, 0x7e, 0x03, 0x07, 0x1b, 0xad, - 0xd1, 0x8d, 0xf3, 0x02, 0x32, 0x33, 0xea, 0x04, 0x61, 0x75, 0x4b, 0xde, 0xda, 0xfb, 0x2b, 0x4d, - 0x82, 0x13, 0x9c, 0x3b, 0x21, 0xf7, 0x83, 0x3b, 0xac, 0x48, 0x17, 0xe9, 0xbc, 0xa6, 0x6f, 0x19, - 0x7f, 0xd2, 0xa0, 0x98, 0x30, 0x8a, 0x3a, 0xf0, 0xfc, 0x31, 0x23, 0xd7, 0x81, 0x3f, 0x8d, 0x2b, - 0x6c, 0x01, 0xa0, 0x2a, 0xe4, 0xe4, 0x80, 0xfb, 0x51, 0x79, 0xc5, 0x43, 0xf4, 0x35, 0xe4, 0x26, - 0xca, 0x85, 0xcc, 0x52, 0xf1, 0x74, 0x77, 0x2d, 0xba, 0xd8, 0x1b, 0x1c, 0x73, 0x2e, 0xd2, 0xf9, - 0x94, 0x9e, 0xbe, 0x48, 0xe7, 0xd3, 0x7a, 0xe6, 0x22, 0x9d, 0xcf, 0xe8, 0xd9, 0x8b, 0x74, 0x3e, - 0xab, 0xe7, 0x8c, 0xff, 0x68, 0x90, 0x8f, 0xd9, 0x62, 0x2d, 0x42, 0xe2, 0x89, 0xa8, 0x8c, 0xa8, - 0x01, 0x58, 0x02, 0xc8, 0x80, 0x92, 0x1c, 0xac, 0xf6, 0x15, 0x2b, 0x18, 0x7a, 0x0a, 0xe5, 0xc5, - 0x78, 0x71, 0x79, 0xa5, 0xf0, 0x2a, 0x28, 0x3c, 0x85, 0xf3, 0xd1, 0x88, 0x85, 0xa1, 0x0a, 0x95, - 0x51, 0x9e, 0x92, 0x18, 0xaa, 0x43, 0x25, 0x1e, 0xc7, 0x01, 0xb3, 0x92, 0xb6, 0x0e, 0xa3, 0xe7, - 0xa0, 0x27, 0xa1, 0xe9, 0xb2, 0x8d, 0xbf, 0x87, 0xab, 0x6d, 0x30, 0xa6, 0xf0, 0x48, 0xa6, 0xf5, - 0x32, 0xf0, 0xaf, 0xe8, 0x95, 0xe3, 0x3a, 0xfc, 0x2e, 0x6e, 0x51, 0xc4, 0x16, 0x04, 0xfe, 0x94, - 0x78, 0xf1, 0x9d, 0x5f, 0xc2, 0x4b, 0x40, 0xa4, 0x83, 0xfb, 0xca, 0x16, 0xa5, 0x23, 0x1a, 0x8a, - 0xe6, 0x63, 0x11, 0x3c, 0x25, 0x83, 0x2f, 0xc6, 0xc6, 0x2d, 0x54, 0xef, 0x87, 0x8b, 0x4a, 0xe8, - 0x08, 0x8a, 0xb3, 0x25, 0x2c, 0x23, 0x6a, 0x38, 0x09, 0x25, 0x13, 0xbd, 0xf5, 0xcb, 0x89, 0x36, - 0xfe, 0xac, 0xc1, 0xce, 0xd9, 0xdc, 0x71, 0xc7, 0x2b, 0x9d, 0x57, 0xf2, 0x85, 0xa6, 0xad, 0xbe, - 0xd0, 0x36, 0x3d, 0xbf, 0xb6, 0x36, 0x3e, 0xbf, 0x36, 0x3d, 0x71, 0x52, 0x0f, 0x3e, 0x71, 0x3e, - 0x87, 0xe2, 0xf2, 0x75, 0xa3, 0x1a, 0xdb, 0x12, 0x86, 0x49, 0xfc, 0xb4, 0x09, 0x8d, 0x57, 0x80, - 0x92, 0x0b, 0x8d, 0x36, 0x64, 0xd1, 0x00, 0x6a, 0x0f, 0x36, 0x80, 0xcf, 0xff, 0xae, 0x41, 0x29, - 0xd9, 0x85, 0xa3, 0x32, 0x14, 0x2c, 0x9b, 0xb4, 0x3b, 0xd6, 0x77, 0xe7, 0x03, 0xfd, 0x13, 0x31, - 0xec, 0x0f, 0x9b, 0x4d, 0xd3, 0x6c, 0x99, 0x2d, 0x5d, 0x13, 0xf7, 0x83, 0x90, 0x7a, 0xb3, 0x45, - 0x06, 0x56, 0xd7, 0xec, 0x0d, 0x45, 0xe7, 0xb0, 0x0b, 0x95, 0x08, 0xb3, 0x7b, 0x04, 0xf7, 0x86, - 0x03, 0x53, 0x4f, 0x21, 0x1d, 0x4a, 0x11, 0x68, 0x62, 0xdc, 0xc3, 0x7a, 0x5a, 0x5c, 0x77, 0x11, - 0x72, 0xbf, 0x0b, 0x89, 0x9b, 0x94, 0x8c, 0xec, 0x32, 0x62, 0xd6, 0xf2, 0x82, 0x26, 0x67, 0x8d, - 0x4e, 0xc3, 0x6e, 0x9a, 0x7a, 0xf6, 0xf4, 0x6f, 0x19, 0xc8, 0xca, 0x2f, 0x08, 0xd0, 0x39, 0x14, - 0x13, 0x0f, 0x2b, 0x74, 0xf8, 0xd1, 0x07, 0x57, 0xad, 0xba, 0xf9, 0xdd, 0x31, 0x0f, 0x5f, 0x6a, - 0xe8, 0x02, 0x4a, 0xc9, 0xe7, 0x0e, 0x4a, 0xf6, 0xa6, 0x1b, 0xde, 0x41, 0x1f, 0xf5, 0xf5, 0x1a, - 0x74, 0x33, 0xe4, 0xce, 0x54, 0xf4, 0xa2, 0xd1, 0xeb, 0x00, 0xd5, 0x12, 0xfc, 0xb5, 0x27, 0x47, - 0xed, 0x60, 0xa3, 0x2d, 0x4a, 0x61, 0x47, 0x7d, 0x62, 0xd4, 0x9f, 0xdf, 0xfb, 0xc4, 0xd5, 0x47, - 0x41, 0xed, 0xb3, 0x87, 0xcc, 0x91, 0xb7, 0x31, 0xec, 0x6e, 0x10, 0x70, 0xf4, 0xab, 0xe4, 0x0a, - 0x1e, 0x94, 0xff, 0xda, 0xb3, 0x5f, 0xa2, 0x2d, 0xa3, 0x6c, 0x50, 0xfa, 0x95, 0x28, 0x0f, 0xdf, - 0x13, 0x2b, 0x51, 0x3e, 0x76, 0x61, 0xfc, 0x08, 0xfa, 0xba, 0x12, 0x20, 0x63, 0x7d, 0xee, 0x7d, - 0x55, 0xaa, 0x7d, 0xf9, 0x51, 0x4e, 0xe4, 0xdc, 0x02, 0x58, 0x9e, 0x27, 0xf4, 0x24, 0x31, 0xe5, - 0x9e, 0x1e, 0xd4, 0x0e, 0x1f, 0xb0, 0x2a, 0x57, 0x67, 0xbf, 0xfe, 0xe3, 0xc9, 0x8d, 0xc3, 0x27, - 0xf3, 0xab, 0xe3, 0x91, 0x3f, 0x3d, 0x71, 0x45, 0x47, 0xef, 0x39, 0xde, 0x8d, 0xc7, 0xf8, 0xcf, - 0x7e, 0x70, 0x7b, 0xe2, 0x7a, 0xe3, 0x13, 0x79, 0x2c, 0x4f, 0x16, 0x5e, 0xae, 0xb2, 0xf2, 0xff, - 0x48, 0xbf, 0xf9, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, 0xfb, 0xd9, 0x67, 0x77, 0x12, 0x00, - 0x00, + // 2093 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0x4f, 0x73, 0xdb, 0xb8, + 0x15, 0x5f, 0x5a, 0xff, 0x9f, 0xfe, 0xd1, 0xb0, 0xe3, 0x30, 0x72, 0xbc, 0xf1, 0x32, 0x69, 0x56, + 0x93, 0xc9, 0xda, 0xa9, 0xdb, 0xcd, 0x64, 0x7a, 0x68, 0x47, 0x96, 0xa8, 0x35, 0x1d, 0x89, 0x72, + 0x20, 0x29, 0xbb, 0xe9, 0x1e, 0x30, 0xb4, 0x04, 0x5b, 0x1c, 0x53, 0xa4, 0x96, 0x84, 0xb2, 0xf1, + 0x77, 0xe8, 0xf7, 0x68, 0x0f, 0x6d, 0x2f, 0xfd, 0x4e, 0xed, 0xbd, 0x33, 0x3d, 0xf4, 0xd6, 0x01, + 0x40, 0x4a, 0x94, 0x2c, 0x67, 0x7b, 0xb2, 0xf0, 0x7b, 0x3f, 0xbc, 0x07, 0xe2, 0xe1, 0xfd, 0xf0, + 0x60, 0xd8, 0x0b, 0xfc, 0x39, 0xa3, 0x41, 0x30, 0x1b, 0x1d, 0xcb, 0x5f, 0x47, 0xb3, 0xc0, 0x67, + 0x3e, 0x2a, 0x2c, 0xf0, 0x5a, 0x21, 0x98, 0x8d, 0x24, 0xaa, 0xff, 0x37, 0x03, 0xa8, 0x4f, 0xbd, + 0xf1, 0x85, 0x7d, 0x3b, 0xa5, 0x1e, 0xc3, 0xf4, 0xa7, 0x39, 0x0d, 0x19, 0x42, 0x90, 0x1e, 0xd3, + 0x90, 0x69, 0xca, 0xa1, 0x52, 0x2f, 0x61, 0xf1, 0x1b, 0xa9, 0x90, 0xb2, 0xa7, 0x4c, 0xdb, 0x3a, + 0x54, 0xea, 0x29, 0xcc, 0x7f, 0xa2, 0x47, 0x90, 0xb7, 0xa7, 0x8c, 0x4c, 0x43, 0x9b, 0x69, 0x25, + 0x01, 0xe7, 0xec, 0x29, 0xeb, 0x86, 0x36, 0x43, 0x5f, 0x41, 0x69, 0x26, 0x5d, 0x92, 0x89, 0x1d, + 0x4e, 0xb4, 0x94, 0x70, 0x54, 0x8c, 0xb0, 0x33, 0x3b, 0x9c, 0xa0, 0x3a, 0xa8, 0x57, 0x8e, 0x67, + 0xbb, 0x64, 0xe4, 0xb2, 0x8f, 0x64, 0x4c, 0x5d, 0x66, 0x6b, 0xe9, 0x43, 0xa5, 0x9e, 0xc1, 0x15, + 0x81, 0x37, 0x5d, 0xf6, 0xb1, 0xc5, 0x51, 0xf4, 0x35, 0x54, 0x63, 0x67, 0x81, 0x5c, 0xa0, 0x96, + 0x39, 0x54, 0xea, 0x05, 0x5c, 0x99, 0xad, 0x2e, 0xfb, 0x6b, 0xa8, 0x32, 0x67, 0x4a, 0xfd, 0x39, + 0x23, 0x21, 0x1d, 0xf9, 0xde, 0x38, 0xd4, 0xb2, 0xd2, 0x63, 0x04, 0xf7, 0x25, 0x8a, 0x74, 0x28, + 0x5f, 0x51, 0x4a, 0x5c, 0x67, 0xea, 0x30, 0xc2, 0x97, 0x9f, 0x13, 0xcb, 0x2f, 0x5e, 0x51, 0xda, + 0xe1, 0x58, 0xdf, 0x66, 0xe8, 0x19, 0x54, 0x96, 0x1c, 0xf1, 0x8d, 0x65, 0x41, 0x2a, 0xc5, 0x24, + 0xf1, 0xa1, 0x2f, 0x41, 0xf5, 0xe7, 0xec, 0xda, 0x77, 0xbc, 0x6b, 0x32, 0x9a, 0xd8, 0x1e, 0x71, + 0xc6, 0x5a, 0xfe, 0x50, 0xa9, 0xa7, 0x4f, 0xb7, 0x5e, 0x29, 0xb8, 0x12, 0xdb, 0x9a, 0x13, 0xdb, + 0x33, 0xc7, 0xe8, 0x39, 0x54, 0x5d, 0x3b, 0x64, 0x64, 0xe2, 0xcf, 0xc8, 0x6c, 0x7e, 0x79, 0x43, + 0x6f, 0xb5, 0x8a, 0xd8, 0x99, 0x32, 0x87, 0xcf, 0xfc, 0xd9, 0x85, 0x00, 0xd1, 0x01, 0x80, 0xd8, + 0x15, 0x11, 0x5c, 0x2b, 0x88, 0x6f, 0x28, 0x70, 0x44, 0x04, 0x46, 0x27, 0x50, 0x14, 0xd9, 0x24, + 0x13, 0xc7, 0x63, 0xa1, 0x06, 0x87, 0xa9, 0x7a, 0xf1, 0x44, 0x3d, 0x72, 0x3d, 0x9e, 0x58, 0xcc, + 0x2d, 0x67, 0x8e, 0xc7, 0x70, 0x92, 0x84, 0xc6, 0xb0, 0xc3, 0xd3, 0x48, 0x46, 0xf3, 0x90, 0xf9, + 0x53, 0x12, 0xd0, 0x91, 0x1f, 0x8c, 0x43, 0xad, 0x28, 0xe6, 0xfe, 0xf6, 0x68, 0x71, 0x3a, 0x8e, + 0xee, 0x1e, 0x87, 0xa3, 0x16, 0x0d, 0x59, 0x53, 0xcc, 0xc3, 0x72, 0x9a, 0xe1, 0xb1, 0xe0, 0x16, + 0x6f, 0x8f, 0xd7, 0x71, 0xf4, 0x12, 0x90, 0xed, 0xba, 0xfe, 0xcf, 0x24, 0xa4, 0xee, 0x15, 0x89, + 0xd2, 0xa3, 0x55, 0x0f, 0x95, 0x7a, 0x1e, 0xab, 0xc2, 0xd2, 0xa7, 0xee, 0x55, 0xe4, 0x1e, 0xbd, + 0x86, 0xb2, 0x58, 0xd3, 0x15, 0xb5, 0xd9, 0x3c, 0xa0, 0xa1, 0xa6, 0x1e, 0xa6, 0xea, 0x95, 0x93, + 0xed, 0xe8, 0x4b, 0xda, 0x12, 0x3e, 0x75, 0x18, 0x2e, 0x71, 0x5e, 0x34, 0x0e, 0x6b, 0x2d, 0xd8, + 0xdb, 0xbc, 0x24, 0x7e, 0x48, 0xf9, 0xa6, 0xf2, 0x73, 0x9b, 0xc6, 0xfc, 0x27, 0xda, 0x85, 0xcc, + 0x47, 0xdb, 0x9d, 0x53, 0x71, 0x70, 0x4b, 0x58, 0x0e, 0x7e, 0xb7, 0xf5, 0x46, 0xd1, 0xdf, 0xc0, + 0xce, 0x20, 0xb0, 0x47, 0x37, 0x6b, 0x67, 0x7f, 0xfd, 0xe8, 0x2a, 0x77, 0x8e, 0xae, 0xfe, 0x17, + 0x05, 0xca, 0xd1, 0xac, 0x3e, 0xb3, 0xd9, 0x3c, 0x44, 0xdf, 0x40, 0x26, 0x64, 0x36, 0xa3, 0x82, + 0x5d, 0x39, 0x79, 0x98, 0xd8, 0xcf, 0x04, 0x91, 0x62, 0xc9, 0x42, 0x35, 0xc8, 0xcf, 0x02, 0xea, + 0x4c, 0xed, 0xeb, 0x78, 0x5d, 0x8b, 0x31, 0xd2, 0x21, 0x23, 0x26, 0x8b, 0x9a, 0x29, 0x9e, 0x94, + 0x92, 0x69, 0xc5, 0xd2, 0x84, 0xea, 0x90, 0x99, 0x30, 0x77, 0x14, 0x6a, 0x69, 0x91, 0x3e, 0x14, + 0x71, 0xce, 0x06, 0x9d, 0x66, 0x83, 0x31, 0x3a, 0x9d, 0x31, 0x2c, 0x09, 0xfa, 0xef, 0xa1, 0x2a, + 0x66, 0xb6, 0x29, 0xfd, 0x5c, 0x71, 0x3f, 0x04, 0x5e, 0xba, 0xa2, 0x14, 0x64, 0x81, 0x67, 0xed, + 0x29, 0xaf, 0x02, 0x7d, 0x0c, 0xea, 0x72, 0x7e, 0x38, 0xf3, 0xbd, 0x90, 0x47, 0x57, 0xf9, 0x32, + 0xf8, 0x91, 0xe7, 0x15, 0x22, 0x6a, 0x43, 0x11, 0xb3, 0x2a, 0x11, 0xde, 0xa6, 0x54, 0x54, 0xc7, + 0x73, 0x59, 0x90, 0xc4, 0xf5, 0x47, 0x37, 0xbc, 0xc4, 0xed, 0xdb, 0xc8, 0x7d, 0x99, 0xc3, 0x1d, + 0x7f, 0x74, 0xd3, 0xe2, 0xa0, 0xfe, 0xa3, 0x54, 0xa1, 0x81, 0x2f, 0xbf, 0xf2, 0xff, 0xce, 0xc4, + 0x72, 0xb3, 0xb6, 0xee, 0xdd, 0x2c, 0x9d, 0xc0, 0xce, 0x8a, 0xf3, 0xe8, 0x2b, 0x92, 0x39, 0x50, + 0xd6, 0x72, 0xf0, 0x12, 0x72, 0x57, 0xb6, 0xe3, 0xce, 0x83, 0xd8, 0x31, 0x4a, 0x24, 0xb4, 0x2d, + 0x2d, 0x38, 0xa6, 0xe8, 0xff, 0xc9, 0x41, 0x2e, 0x02, 0xd1, 0x09, 0xa4, 0x47, 0xfe, 0x38, 0x3e, + 0x07, 0x5f, 0xde, 0x9d, 0x16, 0xff, 0x6d, 0xfa, 0x63, 0x8a, 0x05, 0x17, 0xfd, 0x01, 0x2a, 0x5c, + 0x3a, 0x3c, 0xea, 0x92, 0xf9, 0x6c, 0x6c, 0x2f, 0x52, 0xaf, 0x25, 0x66, 0x37, 0x25, 0x61, 0x28, + 0xec, 0xb8, 0x3c, 0x4a, 0x0e, 0xd1, 0x3e, 0x14, 0x78, 0xb6, 0x65, 0x26, 0xd2, 0xe2, 0xec, 0xe7, + 0x39, 0x20, 0x72, 0xa0, 0x43, 0xd9, 0xf7, 0x1c, 0xdf, 0x23, 0xe1, 0xc4, 0x26, 0x27, 0xdf, 0xbe, + 0x16, 0xda, 0x59, 0xc2, 0x45, 0x01, 0xf6, 0x27, 0xf6, 0xc9, 0xb7, 0xaf, 0xd1, 0x13, 0x28, 0x0a, + 0xbd, 0xa1, 0x9f, 0x66, 0x4e, 0x70, 0x2b, 0x44, 0xb3, 0x8c, 0x85, 0x04, 0x19, 0x02, 0xe1, 0x55, + 0x74, 0xe5, 0xda, 0xd7, 0xa1, 0x10, 0xca, 0x32, 0x96, 0x03, 0xf4, 0x0a, 0x76, 0xa3, 0x3d, 0x20, + 0xa1, 0x3f, 0x0f, 0x46, 0x94, 0x38, 0xde, 0x98, 0x7e, 0x12, 0x02, 0x58, 0xc6, 0x28, 0xb2, 0xf5, + 0x85, 0xc9, 0xe4, 0x16, 0xb4, 0x07, 0xd9, 0x09, 0x75, 0xae, 0x27, 0x52, 0xd4, 0xca, 0x38, 0x1a, + 0xe9, 0x7f, 0xcd, 0x40, 0x31, 0xb1, 0x31, 0xa8, 0x04, 0x79, 0x6c, 0xf4, 0x0d, 0xfc, 0xde, 0x68, + 0xa9, 0x5f, 0xa0, 0x3a, 0x3c, 0x33, 0xad, 0x66, 0x0f, 0x63, 0xa3, 0x39, 0x20, 0x3d, 0x4c, 0x86, + 0xd6, 0x5b, 0xab, 0xf7, 0xbd, 0x45, 0x2e, 0x1a, 0x1f, 0xba, 0x86, 0x35, 0x20, 0x2d, 0x63, 0xd0, + 0x30, 0x3b, 0x7d, 0x55, 0x41, 0x8f, 0x41, 0x5b, 0x32, 0x63, 0x73, 0xa3, 0xdb, 0x1b, 0x5a, 0x03, + 0x75, 0x0b, 0x3d, 0x81, 0xfd, 0xb6, 0x69, 0x35, 0x3a, 0x64, 0xc9, 0x69, 0x76, 0x06, 0xef, 0x89, + 0xf1, 0xc3, 0x85, 0x89, 0x3f, 0xa8, 0xa9, 0x4d, 0x04, 0x5e, 0x53, 0xb1, 0x87, 0x34, 0x7a, 0x04, + 0x0f, 0x24, 0x41, 0x4e, 0x21, 0x83, 0x5e, 0x8f, 0xf4, 0x7b, 0x3d, 0x4b, 0xcd, 0xa0, 0x6d, 0x28, + 0x9b, 0xd6, 0xfb, 0x46, 0xc7, 0x6c, 0x11, 0x6c, 0x34, 0x3a, 0x5d, 0x35, 0x8b, 0x76, 0xa0, 0xba, + 0xce, 0xcb, 0x71, 0x17, 0x31, 0xaf, 0x67, 0x99, 0x3d, 0x8b, 0xbc, 0x37, 0x70, 0xdf, 0xec, 0x59, + 0x6a, 0x1e, 0xed, 0x01, 0x5a, 0x35, 0x9d, 0x75, 0x1b, 0x4d, 0xb5, 0x80, 0x1e, 0xc0, 0xf6, 0x2a, + 0xfe, 0xd6, 0xf8, 0xa0, 0x02, 0xd2, 0x60, 0x57, 0x2e, 0x8c, 0x9c, 0x1a, 0x9d, 0xde, 0xf7, 0xa4, + 0x6b, 0x5a, 0x66, 0x77, 0xd8, 0x55, 0x8b, 0x68, 0x17, 0xd4, 0xb6, 0x61, 0x10, 0xd3, 0xea, 0x0f, + 0xdb, 0x6d, 0xb3, 0x69, 0x1a, 0xd6, 0x40, 0x2d, 0xc9, 0xc8, 0x9b, 0x3e, 0xbc, 0xcc, 0x27, 0x34, + 0xcf, 0x1a, 0x96, 0x65, 0x74, 0x48, 0xcb, 0xec, 0x37, 0x4e, 0x3b, 0x46, 0x4b, 0xad, 0xa0, 0x03, + 0x78, 0x34, 0x30, 0xba, 0x17, 0x3d, 0xdc, 0xc0, 0x1f, 0x48, 0x6c, 0x6f, 0x37, 0xcc, 0xce, 0x10, + 0x1b, 0x6a, 0x15, 0x7d, 0x05, 0x07, 0xd8, 0x78, 0x37, 0x34, 0xb1, 0xd1, 0x22, 0x56, 0xaf, 0x65, + 0x90, 0xb6, 0xd1, 0x18, 0x0c, 0xb1, 0x41, 0xba, 0x66, 0xbf, 0x6f, 0x5a, 0xdf, 0xa9, 0x2a, 0x7a, + 0x06, 0x87, 0x0b, 0xca, 0xc2, 0xc1, 0x1a, 0x6b, 0x9b, 0x7f, 0x5f, 0x9c, 0x52, 0xcb, 0xf8, 0x61, + 0x40, 0x2e, 0x0c, 0x03, 0xab, 0x08, 0xd5, 0x60, 0x6f, 0x19, 0x5e, 0x06, 0x88, 0x62, 0xef, 0x70, + 0xdb, 0x85, 0x81, 0xbb, 0x0d, 0x8b, 0x27, 0x78, 0xc5, 0xb6, 0xcb, 0x97, 0xbd, 0xb4, 0xad, 0x2f, + 0xfb, 0x01, 0x42, 0x50, 0x49, 0x64, 0xa5, 0xdd, 0xc0, 0xea, 0x1e, 0xda, 0x85, 0x6a, 0xbc, 0x82, + 0x98, 0xf8, 0xcf, 0x1c, 0x7a, 0x08, 0x68, 0x68, 0x61, 0xa3, 0xd1, 0xe2, 0x1b, 0xb2, 0x30, 0xfc, + 0x2b, 0x77, 0x9e, 0xce, 0x6f, 0xa9, 0x29, 0xfd, 0x1f, 0x29, 0x28, 0xaf, 0xd4, 0x25, 0x7a, 0x0c, + 0x85, 0xd0, 0xb9, 0xf6, 0xc4, 0x35, 0x15, 0x89, 0xca, 0x12, 0x10, 0xb7, 0xfa, 0xc4, 0x76, 0x3c, + 0xa9, 0x66, 0x52, 0xf7, 0x0b, 0x02, 0x11, 0x5a, 0xb6, 0x0f, 0xb9, 0xb8, 0x83, 0x48, 0x2d, 0x3a, + 0x88, 0xec, 0x48, 0x76, 0x0e, 0x8f, 0xa1, 0xc0, 0x25, 0x33, 0x64, 0xf6, 0x74, 0x26, 0x4a, 0xbc, + 0x8c, 0x97, 0x00, 0x7a, 0x0a, 0xe5, 0x29, 0x0d, 0x43, 0xfb, 0x9a, 0x12, 0x59, 0xa6, 0x20, 0x18, + 0xa5, 0x08, 0x6c, 0x8b, 0x6a, 0x7d, 0x0a, 0xb1, 0x6c, 0x44, 0xa4, 0x8c, 0x24, 0x45, 0xa0, 0x24, + 0xad, 0x2b, 0x36, 0xb3, 0x23, 0x35, 0x48, 0x2a, 0x36, 0xb3, 0xd1, 0x0b, 0xd8, 0x96, 0x92, 0xe3, + 0x78, 0xce, 0x74, 0x3e, 0x95, 0xd2, 0x93, 0x13, 0xd2, 0x53, 0x15, 0xd2, 0x23, 0x71, 0xa1, 0x40, + 0x8f, 0x20, 0x7f, 0x69, 0x87, 0x94, 0x5f, 0x16, 0x91, 0x34, 0xe4, 0xf8, 0xb8, 0x4d, 0x29, 0x37, + 0xf1, 0x2b, 0x24, 0xe0, 0xa2, 0x27, 0x15, 0x21, 0x77, 0x45, 0x29, 0xe6, 0x7b, 0xb9, 0x88, 0x60, + 0x7f, 0x5a, 0x46, 0x28, 0x26, 0x22, 0x48, 0x5c, 0x44, 0x78, 0x01, 0xdb, 0xf4, 0x13, 0x0b, 0x6c, + 0xe2, 0xcf, 0xec, 0x9f, 0xe6, 0x94, 0x8c, 0x6d, 0x66, 0x8b, 0x96, 0xb4, 0x84, 0xab, 0xc2, 0xd0, + 0x13, 0x78, 0xcb, 0x66, 0xb6, 0xfe, 0x18, 0x6a, 0x98, 0x86, 0x94, 0x75, 0x9d, 0x30, 0x74, 0x7c, + 0xaf, 0xe9, 0x7b, 0x2c, 0xf0, 0xdd, 0xe8, 0xce, 0xd1, 0x0f, 0x60, 0x7f, 0xa3, 0x55, 0x5e, 0x1a, + 0x7c, 0xf2, 0xbb, 0x39, 0x0d, 0x6e, 0x37, 0x4f, 0x7e, 0x07, 0xfb, 0x1b, 0xad, 0xd1, 0x8d, 0xf3, + 0x12, 0x32, 0x33, 0xdb, 0x09, 0x42, 0x6d, 0x4b, 0xdc, 0xda, 0x7b, 0x2b, 0x4d, 0x82, 0x13, 0x9c, + 0x39, 0x21, 0xf3, 0x83, 0x5b, 0x2c, 0x49, 0xe7, 0xe9, 0xbc, 0xa2, 0x6e, 0xe9, 0x7f, 0x52, 0xa0, + 0x98, 0x30, 0xf2, 0x73, 0xe0, 0xf9, 0x63, 0x4a, 0xae, 0x02, 0x7f, 0x1a, 0x9f, 0xb0, 0x05, 0x80, + 0x34, 0xc8, 0x89, 0x01, 0xf3, 0xa3, 0xe3, 0x15, 0x0f, 0xd1, 0x37, 0x90, 0x9b, 0x48, 0x17, 0x22, + 0x4b, 0xc5, 0x93, 0x9d, 0xb5, 0xe8, 0x7c, 0x6f, 0x70, 0xcc, 0x39, 0x4f, 0xe7, 0x53, 0x6a, 0xfa, + 0x3c, 0x9d, 0x4f, 0xab, 0x99, 0xf3, 0x74, 0x3e, 0xa3, 0x66, 0xcf, 0xd3, 0xf9, 0xac, 0x9a, 0xd3, + 0xff, 0xad, 0x40, 0x3e, 0x66, 0xf3, 0xb5, 0x70, 0x89, 0x27, 0xfc, 0x64, 0x44, 0x0d, 0xc0, 0x12, + 0x40, 0x3a, 0x94, 0xc4, 0x60, 0xb5, 0xaf, 0x58, 0xc1, 0xd0, 0x33, 0x28, 0x2f, 0xc6, 0x8b, 0xcb, + 0x2b, 0x85, 0x57, 0x41, 0xee, 0x29, 0x9c, 0x8f, 0x46, 0x34, 0x0c, 0x65, 0xa8, 0x8c, 0xf4, 0x94, + 0xc4, 0x50, 0x1d, 0xaa, 0xf1, 0x38, 0x0e, 0x98, 0x15, 0xb4, 0x75, 0x18, 0xbd, 0x00, 0x35, 0x09, + 0x4d, 0x97, 0xed, 0xff, 0x1d, 0x5c, 0x6e, 0x83, 0x3e, 0x85, 0x87, 0x22, 0xad, 0x17, 0x81, 0x7f, + 0x69, 0x5f, 0x3a, 0xae, 0xc3, 0x6e, 0xe3, 0x16, 0x85, 0x6f, 0x41, 0xe0, 0x4f, 0x89, 0x17, 0xdf, + 0xf9, 0x25, 0xbc, 0x04, 0x78, 0x3a, 0x98, 0x2f, 0x6d, 0x51, 0x3a, 0xa2, 0x21, 0x6f, 0x3e, 0x16, + 0xc1, 0x53, 0x22, 0xf8, 0x62, 0xac, 0xdf, 0x80, 0x76, 0x37, 0x5c, 0x74, 0x84, 0x0e, 0xa1, 0x38, + 0x5b, 0xc2, 0x22, 0xa2, 0x82, 0x93, 0x50, 0x32, 0xd1, 0x5b, 0xbf, 0x9c, 0x68, 0xfd, 0xcf, 0x0a, + 0x6c, 0x9f, 0xce, 0x1d, 0x77, 0xbc, 0xd2, 0x79, 0x25, 0x5f, 0x76, 0xca, 0xea, 0xcb, 0x6e, 0xd3, + 0xb3, 0x6d, 0x6b, 0xe3, 0xb3, 0x6d, 0xd3, 0xd3, 0x28, 0x75, 0xef, 0xd3, 0xe8, 0x09, 0x14, 0x97, + 0xaf, 0x22, 0xd9, 0xd8, 0x96, 0x30, 0x4c, 0xe2, 0x27, 0x51, 0xa8, 0xbf, 0x01, 0x94, 0x5c, 0x68, + 0xb4, 0x21, 0x8b, 0x06, 0x50, 0xb9, 0xb7, 0x01, 0x7c, 0xf1, 0x77, 0x05, 0x4a, 0xc9, 0x2e, 0x1c, + 0x95, 0xa1, 0x60, 0x5a, 0xa4, 0xdd, 0x31, 0xbf, 0x3b, 0x1b, 0xa8, 0x5f, 0xf0, 0x61, 0x7f, 0xd8, + 0x6c, 0x1a, 0x46, 0xcb, 0x68, 0xa9, 0x0a, 0xbf, 0x1f, 0xb8, 0xd4, 0x1b, 0x2d, 0x32, 0x30, 0xbb, + 0x46, 0x6f, 0xc8, 0x3b, 0x87, 0x1d, 0xa8, 0x46, 0x98, 0xd5, 0x23, 0xb8, 0x37, 0x1c, 0x18, 0x6a, + 0x0a, 0xa9, 0x50, 0x8a, 0x40, 0x03, 0xe3, 0x1e, 0x56, 0xd3, 0xfc, 0xba, 0x8b, 0x90, 0xbb, 0x5d, + 0x48, 0xdc, 0xa4, 0x64, 0x44, 0x97, 0x11, 0xb3, 0x96, 0x17, 0x34, 0x39, 0x6d, 0x74, 0x1a, 0x56, + 0xd3, 0x50, 0xb3, 0x27, 0x7f, 0xcb, 0x40, 0x56, 0x7c, 0x41, 0x80, 0xce, 0xa0, 0x98, 0x78, 0x90, + 0xa1, 0x83, 0xcf, 0x3e, 0xd4, 0x6a, 0xda, 0xe6, 0x77, 0xc7, 0x3c, 0x7c, 0xa5, 0xa0, 0x73, 0x28, + 0x25, 0x9f, 0x3b, 0x28, 0xd9, 0x9b, 0x6e, 0x78, 0x07, 0x7d, 0xd6, 0xd7, 0x5b, 0x50, 0x8d, 0x90, + 0x39, 0x53, 0xde, 0x8b, 0x46, 0xaf, 0x03, 0x54, 0x4b, 0xf0, 0xd7, 0x9e, 0x1c, 0xb5, 0xfd, 0x8d, + 0xb6, 0x28, 0x85, 0x1d, 0xf9, 0x89, 0x51, 0x7f, 0x7e, 0xe7, 0x13, 0x57, 0x1f, 0x05, 0xb5, 0x2f, + 0xef, 0x33, 0x47, 0xde, 0xc6, 0xb0, 0xb3, 0x41, 0xc0, 0xd1, 0xaf, 0x92, 0x2b, 0xb8, 0x57, 0xfe, + 0x6b, 0xcf, 0x7f, 0x89, 0xb6, 0x8c, 0xb2, 0x41, 0xe9, 0x57, 0xa2, 0xdc, 0x7f, 0x4f, 0xac, 0x44, + 0xf9, 0xdc, 0x85, 0xf1, 0x23, 0xa8, 0xeb, 0x4a, 0x80, 0xf4, 0xf5, 0xb9, 0x77, 0x55, 0xa9, 0xf6, + 0xf4, 0xb3, 0x9c, 0xc8, 0xb9, 0x09, 0xb0, 0xac, 0x27, 0xf4, 0x38, 0x31, 0xe5, 0x8e, 0x1e, 0xd4, + 0x0e, 0xee, 0xb1, 0x4a, 0x57, 0xa7, 0xbf, 0xfe, 0xe3, 0xf1, 0xb5, 0xc3, 0x26, 0xf3, 0xcb, 0xa3, + 0x91, 0x3f, 0x3d, 0x76, 0x79, 0x47, 0xef, 0x39, 0xde, 0xb5, 0x47, 0xd9, 0xcf, 0x7e, 0x70, 0x73, + 0xec, 0x7a, 0xe3, 0x63, 0x51, 0x96, 0xc7, 0x0b, 0x2f, 0x97, 0x59, 0xf1, 0xff, 0xa7, 0xdf, 0xfc, + 0x2f, 0x00, 0x00, 0xff, 0xff, 0x42, 0x87, 0x8c, 0xeb, 0xaf, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/lnrpc/routerrpc/router.proto b/lnrpc/routerrpc/router.proto index 24a3c105..3019eaeb 100644 --- a/lnrpc/routerrpc/router.proto +++ b/lnrpc/routerrpc/router.proto @@ -105,6 +105,13 @@ message SendPaymentRequest { /// If set, circular payments to self are permitted. bool allow_self_payment = 15; + + /** + Features assumed to be supported by the final node. All transitive feature + depdencies must also be set properly. For a given feature bit pair, either + optional or remote may be set, but not both. + */ + repeated lnrpc.FeatureBit dest_features = 16; } message TrackPaymentRequest { diff --git a/lnrpc/rpc.pb.go b/lnrpc/rpc.pb.go index 9279a250..74b5ceb7 100644 --- a/lnrpc/rpc.pb.go +++ b/lnrpc/rpc.pb.go @@ -87,6 +87,76 @@ func (InvoiceHTLCState) EnumDescriptor() ([]byte, []int) { return fileDescriptor_77a6da22d6a3feb1, []int{1} } +type FeatureBit int32 + +const ( + FeatureBit_DATALOSS_PROTECT_REQ FeatureBit = 0 + FeatureBit_DATALOSS_PROTECT_OPT FeatureBit = 1 + FeatureBit_INITIAL_ROUING_SYNC FeatureBit = 3 + FeatureBit_UPFRONT_SHUTDOWN_SCRIPT_REQ FeatureBit = 4 + FeatureBit_UPFRONT_SHUTDOWN_SCRIPT_OPT FeatureBit = 5 + FeatureBit_GOSSIP_QUERIES_REQ FeatureBit = 6 + FeatureBit_GOSSIP_QUERIES_OPT FeatureBit = 7 + FeatureBit_TLV_ONION_REQ FeatureBit = 8 + FeatureBit_TLV_ONION_OPT FeatureBit = 9 + FeatureBit_EXT_GOSSIP_QUERIES_REQ FeatureBit = 10 + FeatureBit_EXT_GOSSIP_QUERIES_OPT FeatureBit = 11 + FeatureBit_STATIC_REMOTE_KEY_REQ FeatureBit = 12 + FeatureBit_STATIC_REMOTE_KEY_OPT FeatureBit = 13 + FeatureBit_PAYMENT_ADDR_REQ FeatureBit = 14 + FeatureBit_PAYMENT_ADDR_OPT FeatureBit = 15 + FeatureBit_MPP_REQ FeatureBit = 16 + FeatureBit_MPP_OPT FeatureBit = 17 +) + +var FeatureBit_name = map[int32]string{ + 0: "DATALOSS_PROTECT_REQ", + 1: "DATALOSS_PROTECT_OPT", + 3: "INITIAL_ROUING_SYNC", + 4: "UPFRONT_SHUTDOWN_SCRIPT_REQ", + 5: "UPFRONT_SHUTDOWN_SCRIPT_OPT", + 6: "GOSSIP_QUERIES_REQ", + 7: "GOSSIP_QUERIES_OPT", + 8: "TLV_ONION_REQ", + 9: "TLV_ONION_OPT", + 10: "EXT_GOSSIP_QUERIES_REQ", + 11: "EXT_GOSSIP_QUERIES_OPT", + 12: "STATIC_REMOTE_KEY_REQ", + 13: "STATIC_REMOTE_KEY_OPT", + 14: "PAYMENT_ADDR_REQ", + 15: "PAYMENT_ADDR_OPT", + 16: "MPP_REQ", + 17: "MPP_OPT", +} + +var FeatureBit_value = map[string]int32{ + "DATALOSS_PROTECT_REQ": 0, + "DATALOSS_PROTECT_OPT": 1, + "INITIAL_ROUING_SYNC": 3, + "UPFRONT_SHUTDOWN_SCRIPT_REQ": 4, + "UPFRONT_SHUTDOWN_SCRIPT_OPT": 5, + "GOSSIP_QUERIES_REQ": 6, + "GOSSIP_QUERIES_OPT": 7, + "TLV_ONION_REQ": 8, + "TLV_ONION_OPT": 9, + "EXT_GOSSIP_QUERIES_REQ": 10, + "EXT_GOSSIP_QUERIES_OPT": 11, + "STATIC_REMOTE_KEY_REQ": 12, + "STATIC_REMOTE_KEY_OPT": 13, + "PAYMENT_ADDR_REQ": 14, + "PAYMENT_ADDR_OPT": 15, + "MPP_REQ": 16, + "MPP_OPT": 17, +} + +func (x FeatureBit) String() string { + return proto.EnumName(FeatureBit_name, int32(x)) +} + +func (FeatureBit) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{2} +} + type ChannelCloseSummary_ClosureType int32 const ( @@ -1155,10 +1225,15 @@ type SendRequest struct { //must be encoded as base64. DestCustomRecords map[uint64][]byte `protobuf:"bytes,11,rep,name=dest_custom_records,json=destCustomRecords,proto3" json:"dest_custom_records,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` /// If set, circular payments to self are permitted. - AllowSelfPayment bool `protobuf:"varint,14,opt,name=allow_self_payment,json=allowSelfPayment,proto3" json:"allow_self_payment,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AllowSelfPayment bool `protobuf:"varint,14,opt,name=allow_self_payment,json=allowSelfPayment,proto3" json:"allow_self_payment,omitempty"` + //* + //Features assumed to be supported by the final node. All transitive feature + //depdencies must also be set properly. For a given feature bit pair, either + //optional or remote may be set, but not both. + DestFeatures []FeatureBit `protobuf:"varint,15,rep,packed,name=dest_features,json=destFeatures,proto3,enum=lnrpc.FeatureBit" json:"dest_features,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SendRequest) Reset() { *m = SendRequest{} } @@ -1286,6 +1361,13 @@ func (m *SendRequest) GetAllowSelfPayment() bool { return false } +func (m *SendRequest) GetDestFeatures() []FeatureBit { + if m != nil { + return m.DestFeatures + } + return nil +} + type SendResponse struct { PaymentError string `protobuf:"bytes,1,opt,name=payment_error,proto3" json:"payment_error,omitempty"` PaymentPreimage []byte `protobuf:"bytes,2,opt,name=payment_preimage,proto3" json:"payment_preimage,omitempty"` @@ -9812,6 +9894,7 @@ func (m *BakeMacaroonResponse) GetMacaroon() string { func init() { proto.RegisterEnum("lnrpc.AddressType", AddressType_name, AddressType_value) proto.RegisterEnum("lnrpc.InvoiceHTLCState", InvoiceHTLCState_name, InvoiceHTLCState_value) + proto.RegisterEnum("lnrpc.FeatureBit", FeatureBit_name, FeatureBit_value) proto.RegisterEnum("lnrpc.ChannelCloseSummary_ClosureType", ChannelCloseSummary_ClosureType_name, ChannelCloseSummary_ClosureType_value) proto.RegisterEnum("lnrpc.Peer_SyncType", Peer_SyncType_name, Peer_SyncType_value) proto.RegisterEnum("lnrpc.PeerEvent_EventType", PeerEvent_EventType_name, PeerEvent_EventType_value) @@ -9979,585 +10062,600 @@ func init() { func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } var fileDescriptor_77a6da22d6a3feb1 = []byte{ - // 9241 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x4d, 0x6c, 0x1c, 0x49, - 0x96, 0x1e, 0xb3, 0x7e, 0xc8, 0xaa, 0x57, 0x3f, 0x2c, 0x06, 0x29, 0xb2, 0x54, 0xfa, 0x69, 0x76, - 0x8e, 0x46, 0xad, 0xd6, 0xf4, 0x50, 0x6a, 0xce, 0x74, 0xaf, 0xb6, 0xdb, 0xbb, 0x3b, 0x14, 0x49, - 0x89, 0xea, 0xa6, 0x28, 0x4e, 0x52, 0x1a, 0x79, 0x66, 0x76, 0x91, 0x93, 0xac, 0x0a, 0x92, 0x39, - 0xaa, 0xca, 0xac, 0xce, 0xcc, 0x22, 0xc5, 0x69, 0xb7, 0x0f, 0x86, 0x6d, 0x18, 0xbe, 0x2c, 0xc6, - 0x0b, 0x03, 0xb6, 0x61, 0x63, 0x81, 0x59, 0x03, 0x86, 0xe1, 0x83, 0x7d, 0xb1, 0xb1, 0x36, 0xd6, - 0x27, 0x1f, 0xec, 0x8b, 0xed, 0x83, 0x0d, 0x18, 0xf0, 0x02, 0x06, 0x8c, 0xf5, 0xc1, 0x03, 0xc3, - 0x37, 0xdb, 0x67, 0x23, 0x5e, 0xfc, 0x64, 0x44, 0x66, 0x96, 0xc8, 0x9e, 0xe9, 0xed, 0x8b, 0x54, - 0xf1, 0xbd, 0xc8, 0xf8, 0x7d, 0xf1, 0xe2, 0xc5, 0x7b, 0x2f, 0x82, 0x50, 0x8f, 0xc6, 0xfd, 0xb5, - 0x71, 0x14, 0x26, 0x21, 0xa9, 0x0e, 0x83, 0x68, 0xdc, 0xef, 0x5d, 0x3f, 0x0e, 0xc3, 0xe3, 0x21, - 0xbd, 0xe7, 0x8d, 0xfd, 0x7b, 0x5e, 0x10, 0x84, 0x89, 0x97, 0xf8, 0x61, 0x10, 0xf3, 0x4c, 0xf6, - 0x4f, 0xa0, 0xfd, 0x98, 0x06, 0x07, 0x94, 0x0e, 0x1c, 0xfa, 0xd9, 0x84, 0xc6, 0x09, 0xf9, 0x16, - 0x2c, 0x78, 0xf4, 0x67, 0x94, 0x0e, 0xdc, 0xb1, 0x17, 0xc7, 0xe3, 0x93, 0xc8, 0x8b, 0x69, 0xd7, - 0x5a, 0xb5, 0xee, 0x34, 0x9d, 0x0e, 0x27, 0xec, 0x2b, 0x9c, 0xbc, 0x0d, 0xcd, 0x98, 0x65, 0xa5, - 0x41, 0x12, 0x85, 0xe3, 0xf3, 0x6e, 0x09, 0xf3, 0x35, 0x18, 0xb6, 0xcd, 0x21, 0x7b, 0x08, 0xf3, - 0xaa, 0x86, 0x78, 0x1c, 0x06, 0x31, 0x25, 0xf7, 0x61, 0xa9, 0xef, 0x8f, 0x4f, 0x68, 0xe4, 0xe2, - 0xc7, 0xa3, 0x80, 0x8e, 0xc2, 0xc0, 0xef, 0x77, 0xad, 0xd5, 0xf2, 0x9d, 0xba, 0x43, 0x38, 0x8d, - 0x7d, 0xf1, 0x54, 0x50, 0xc8, 0x3b, 0x30, 0x4f, 0x03, 0x8e, 0xd3, 0x01, 0x7e, 0x25, 0xaa, 0x6a, - 0xa7, 0x30, 0xfb, 0xc0, 0xfe, 0x1b, 0x25, 0x58, 0x78, 0x12, 0xf8, 0xc9, 0x4b, 0x6f, 0x38, 0xa4, - 0x89, 0xec, 0xd3, 0x3b, 0x30, 0x7f, 0x86, 0x00, 0xf6, 0xe9, 0x2c, 0x8c, 0x06, 0xa2, 0x47, 0x6d, - 0x0e, 0xef, 0x0b, 0x74, 0x6a, 0xcb, 0x4a, 0x53, 0x5b, 0x56, 0x38, 0x5c, 0xe5, 0x29, 0xc3, 0xf5, - 0x0e, 0xcc, 0x47, 0xb4, 0x1f, 0x9e, 0xd2, 0xe8, 0xdc, 0x3d, 0xf3, 0x83, 0x41, 0x78, 0xd6, 0xad, - 0xac, 0x5a, 0x77, 0xaa, 0x4e, 0x5b, 0xc2, 0x2f, 0x11, 0x25, 0x0f, 0x61, 0xbe, 0x7f, 0xe2, 0x05, - 0x01, 0x1d, 0xba, 0x87, 0x5e, 0xff, 0xd5, 0x64, 0x1c, 0x77, 0xab, 0xab, 0xd6, 0x9d, 0xc6, 0xfa, - 0xd5, 0x35, 0x9c, 0xd5, 0xb5, 0xcd, 0x13, 0x2f, 0x78, 0x88, 0x94, 0x83, 0xc0, 0x1b, 0xc7, 0x27, - 0x61, 0xe2, 0xb4, 0xc5, 0x17, 0x1c, 0x8e, 0xed, 0x25, 0x20, 0xfa, 0x48, 0xf0, 0xb1, 0xb7, 0xff, - 0x89, 0x05, 0x8b, 0x2f, 0x82, 0x61, 0xd8, 0x7f, 0xf5, 0x2b, 0x0e, 0x51, 0x41, 0x1f, 0x4a, 0x97, - 0xed, 0x43, 0xf9, 0xcb, 0xf6, 0x61, 0x19, 0x96, 0xcc, 0xc6, 0x8a, 0x5e, 0x50, 0xb8, 0xc2, 0xbe, - 0x3e, 0xa6, 0xb2, 0x59, 0xb2, 0x1b, 0xef, 0x42, 0xa7, 0x3f, 0x89, 0x22, 0x1a, 0xe4, 0xfa, 0x31, - 0x2f, 0x70, 0xd5, 0x91, 0xb7, 0xa1, 0x19, 0xd0, 0xb3, 0x34, 0x9b, 0xe0, 0xdd, 0x80, 0x9e, 0xc9, - 0x2c, 0x76, 0x17, 0x96, 0xb3, 0xd5, 0x88, 0x06, 0xfc, 0x77, 0x0b, 0x2a, 0x2f, 0x92, 0xd7, 0x21, - 0x59, 0x83, 0x4a, 0x72, 0x3e, 0xe6, 0x2b, 0xa4, 0xbd, 0x4e, 0x44, 0xd7, 0x36, 0x06, 0x83, 0x88, - 0xc6, 0xf1, 0xf3, 0xf3, 0x31, 0x75, 0x9a, 0x1e, 0x4f, 0xb8, 0x2c, 0x1f, 0xe9, 0xc2, 0x9c, 0x48, - 0x63, 0x85, 0x75, 0x47, 0x26, 0xc9, 0x4d, 0x00, 0x6f, 0x14, 0x4e, 0x82, 0xc4, 0x8d, 0xbd, 0x04, - 0x87, 0xaa, 0xec, 0x68, 0x08, 0xb9, 0x0e, 0xf5, 0xf1, 0x2b, 0x37, 0xee, 0x47, 0xfe, 0x38, 0x41, - 0xb6, 0xa9, 0x3b, 0x29, 0x40, 0xbe, 0x05, 0xb5, 0x70, 0x92, 0x8c, 0x43, 0x3f, 0x48, 0x04, 0xab, - 0xcc, 0x8b, 0xb6, 0x3c, 0x9b, 0x24, 0xfb, 0x0c, 0x76, 0x54, 0x06, 0x72, 0x0b, 0x5a, 0xfd, 0x30, - 0x38, 0xf2, 0xa3, 0x11, 0x17, 0x06, 0xdd, 0x59, 0xac, 0xcd, 0x04, 0xed, 0x7f, 0x59, 0x82, 0xc6, - 0xf3, 0xc8, 0x0b, 0x62, 0xaf, 0xcf, 0x00, 0xd6, 0xf4, 0xe4, 0xb5, 0x7b, 0xe2, 0xc5, 0x27, 0xd8, - 0xdb, 0xba, 0x23, 0x93, 0x64, 0x19, 0x66, 0x79, 0x43, 0xb1, 0x4f, 0x65, 0x47, 0xa4, 0xc8, 0x7b, - 0xb0, 0x10, 0x4c, 0x46, 0xae, 0x59, 0x57, 0x19, 0xb9, 0x25, 0x4f, 0x60, 0x03, 0x70, 0xc8, 0xe6, - 0x9a, 0x57, 0xc1, 0x7b, 0xa8, 0x21, 0xc4, 0x86, 0xa6, 0x48, 0x51, 0xff, 0xf8, 0x84, 0x77, 0xb3, - 0xea, 0x18, 0x18, 0x2b, 0x23, 0xf1, 0x47, 0xd4, 0x8d, 0x13, 0x6f, 0x34, 0x16, 0xdd, 0xd2, 0x10, - 0xa4, 0x87, 0x89, 0x37, 0x74, 0x8f, 0x28, 0x8d, 0xbb, 0x73, 0x82, 0xae, 0x10, 0x72, 0x1b, 0xda, - 0x03, 0x1a, 0x27, 0xae, 0x98, 0x14, 0x1a, 0x77, 0x6b, 0xb8, 0xf4, 0x33, 0x28, 0x2b, 0x27, 0xf2, - 0xce, 0x5c, 0x36, 0x00, 0xf4, 0x75, 0xb7, 0xce, 0xdb, 0x9a, 0x22, 0x8c, 0x73, 0x1e, 0xd3, 0x44, - 0x1b, 0xbd, 0x58, 0x70, 0xa8, 0xbd, 0x0b, 0x44, 0x83, 0xb7, 0x68, 0xe2, 0xf9, 0xc3, 0x98, 0x7c, - 0x08, 0xcd, 0x44, 0xcb, 0x8c, 0xa2, 0xb0, 0xa1, 0xd8, 0x49, 0xfb, 0xc0, 0x31, 0xf2, 0xd9, 0x27, - 0x50, 0x7b, 0x44, 0xe9, 0xae, 0x3f, 0xf2, 0x13, 0xb2, 0x0c, 0xd5, 0x23, 0xff, 0x35, 0xe5, 0x0c, - 0x5f, 0xde, 0x99, 0x71, 0x78, 0x92, 0xbc, 0x05, 0x80, 0x3f, 0xdc, 0x91, 0x62, 0xac, 0x9d, 0x19, - 0xa7, 0x8e, 0xd8, 0x53, 0xc6, 0x59, 0x3d, 0x98, 0x1b, 0xd3, 0xa8, 0x4f, 0xe5, 0xfc, 0xed, 0xcc, - 0x38, 0x12, 0x78, 0x38, 0x07, 0xd5, 0x21, 0x2b, 0xdd, 0xfe, 0xfd, 0x2a, 0x34, 0x0e, 0x68, 0xa0, - 0x56, 0x1a, 0x81, 0x0a, 0x1b, 0x13, 0xb1, 0xba, 0xf0, 0x37, 0xf9, 0x06, 0x34, 0x70, 0x9c, 0xe2, - 0x24, 0xf2, 0x83, 0x63, 0xce, 0xe0, 0x0f, 0x4b, 0x5d, 0xcb, 0x01, 0x06, 0x1f, 0x20, 0x4a, 0x3a, - 0x50, 0xf6, 0x46, 0x92, 0xc1, 0xd9, 0x4f, 0x72, 0x15, 0x6a, 0xde, 0x28, 0xe1, 0xcd, 0x6b, 0x22, - 0x3c, 0xe7, 0x8d, 0x12, 0x6c, 0xda, 0xdb, 0xd0, 0x1c, 0x7b, 0xe7, 0x23, 0xb6, 0x9e, 0x15, 0x57, - 0x34, 0x9d, 0x86, 0xc0, 0x76, 0x18, 0x5b, 0xac, 0xc3, 0xa2, 0x9e, 0x45, 0x56, 0x5e, 0x55, 0x95, - 0x2f, 0x68, 0xb9, 0x45, 0x1b, 0xde, 0x81, 0x79, 0xf9, 0x4d, 0xc4, 0xfb, 0x83, 0xbc, 0x52, 0x77, - 0xda, 0x02, 0x96, 0xbd, 0xbc, 0x03, 0x9d, 0x23, 0x3f, 0xf0, 0x86, 0x6e, 0x7f, 0x98, 0x9c, 0xba, - 0x03, 0x3a, 0x4c, 0x3c, 0xe4, 0x9a, 0xaa, 0xd3, 0x46, 0x7c, 0x73, 0x98, 0x9c, 0x6e, 0x31, 0x94, - 0xbc, 0x07, 0xf5, 0x23, 0x4a, 0x5d, 0x1c, 0xac, 0x6e, 0xcd, 0x58, 0x81, 0x72, 0x86, 0x9c, 0xda, - 0x91, 0x9c, 0xab, 0xf7, 0xa0, 0x13, 0x4e, 0x92, 0xe3, 0xd0, 0x0f, 0x8e, 0x5d, 0x26, 0xf3, 0x5c, - 0x7f, 0x80, 0x5c, 0x54, 0x79, 0x58, 0xba, 0x6f, 0x39, 0x6d, 0x49, 0x63, 0xd2, 0xe7, 0xc9, 0x80, - 0xdc, 0x86, 0xf9, 0xa1, 0x17, 0x27, 0xee, 0x49, 0x38, 0x76, 0xc7, 0x93, 0xc3, 0x57, 0xf4, 0xbc, - 0xdb, 0xc2, 0x81, 0x68, 0x31, 0x78, 0x27, 0x1c, 0xef, 0x23, 0x48, 0x6e, 0x00, 0x60, 0x3b, 0x79, - 0x23, 0x60, 0xd5, 0xba, 0xd3, 0x72, 0xea, 0x0c, 0xe1, 0x95, 0xfe, 0x10, 0x16, 0x71, 0x7a, 0xfa, - 0x93, 0x38, 0x09, 0x47, 0x2e, 0x93, 0xd7, 0xd1, 0x20, 0xee, 0x36, 0x90, 0xd7, 0xde, 0x15, 0x8d, - 0xd5, 0xe6, 0x78, 0x6d, 0x8b, 0xc6, 0xc9, 0x26, 0x66, 0x76, 0x78, 0x5e, 0xb6, 0xa9, 0x9f, 0x3b, - 0x0b, 0x83, 0x2c, 0x4e, 0xde, 0x03, 0xe2, 0x0d, 0x87, 0xe1, 0x99, 0x1b, 0xd3, 0xe1, 0x91, 0x2b, - 0x06, 0xb1, 0xdb, 0x5e, 0xb5, 0xee, 0xd4, 0x9c, 0x0e, 0x52, 0x0e, 0xe8, 0xf0, 0x68, 0x9f, 0xe3, - 0xbd, 0x2d, 0x58, 0x2e, 0x2e, 0x9a, 0x31, 0x07, 0xeb, 0x1d, 0x63, 0xaa, 0x8a, 0xc3, 0x7e, 0x92, - 0x25, 0xa8, 0x9e, 0x7a, 0xc3, 0x09, 0x15, 0xf2, 0x99, 0x27, 0x3e, 0x2a, 0x3d, 0xb0, 0xec, 0x3f, - 0xb6, 0xa0, 0xc9, 0x5b, 0x2b, 0xf4, 0x8a, 0x5b, 0xd0, 0x92, 0xb3, 0x4a, 0xa3, 0x28, 0x8c, 0x84, - 0x98, 0x32, 0x41, 0x72, 0x17, 0x3a, 0x12, 0x18, 0x47, 0xd4, 0x1f, 0x79, 0xc7, 0xb2, 0xec, 0x1c, - 0x4e, 0xd6, 0xd3, 0x12, 0xa3, 0x70, 0x92, 0x50, 0xb1, 0x83, 0x35, 0xc5, 0x58, 0x39, 0x0c, 0x73, - 0xcc, 0x2c, 0x4c, 0x4c, 0x15, 0xb0, 0xac, 0x81, 0xd9, 0x7f, 0xdb, 0x02, 0xc2, 0x9a, 0xfe, 0x3c, - 0xe4, 0x45, 0x08, 0x6e, 0xcb, 0x72, 0xbb, 0x75, 0x69, 0x6e, 0x2f, 0xbd, 0x89, 0xdb, 0x6d, 0xa8, - 0xf2, 0xd6, 0x57, 0x0a, 0x5a, 0xcf, 0x49, 0x9f, 0x54, 0x6a, 0xe5, 0x4e, 0xc5, 0xfe, 0xaf, 0x65, - 0x58, 0xda, 0xe4, 0x5b, 0xf0, 0x46, 0xbf, 0x4f, 0xc7, 0x6a, 0x1d, 0xbc, 0x05, 0x8d, 0x20, 0x1c, - 0x50, 0xc9, 0x7d, 0xbc, 0x61, 0xc0, 0x20, 0x8d, 0xf5, 0x4e, 0x3c, 0x3f, 0xe0, 0x0d, 0xe7, 0xe3, - 0x59, 0x47, 0x04, 0x9b, 0x7d, 0x1b, 0xe6, 0xc7, 0x34, 0x18, 0xe8, 0xec, 0xce, 0x95, 0xa4, 0x96, - 0x80, 0x05, 0xa7, 0xbf, 0x05, 0x8d, 0xa3, 0x09, 0xcf, 0xc7, 0x84, 0x44, 0x05, 0xf9, 0x00, 0x04, - 0xb4, 0xc1, 0x65, 0xc5, 0x78, 0x12, 0x9f, 0x20, 0xb5, 0x8a, 0xd4, 0x39, 0x96, 0x66, 0xa4, 0x1b, - 0x00, 0x83, 0x49, 0x9c, 0x08, 0xee, 0x9f, 0x45, 0x62, 0x9d, 0x21, 0x9c, 0xfb, 0xbf, 0x0d, 0x8b, - 0x23, 0xef, 0xb5, 0x8b, 0xfc, 0xe3, 0xfa, 0x81, 0x7b, 0x34, 0xc4, 0x5d, 0x64, 0x0e, 0xf3, 0x75, - 0x46, 0xde, 0xeb, 0x1f, 0x30, 0xca, 0x93, 0xe0, 0x11, 0xe2, 0x4c, 0x44, 0x48, 0xf5, 0x25, 0xa2, - 0x31, 0x8d, 0x4e, 0x29, 0xae, 0xea, 0x8a, 0xd2, 0x51, 0x1c, 0x8e, 0xb2, 0x16, 0x8d, 0x58, 0xbf, - 0x93, 0x61, 0x9f, 0x2f, 0x61, 0x67, 0x6e, 0xe4, 0x07, 0x3b, 0xc9, 0xb0, 0x4f, 0xae, 0x03, 0x30, - 0x99, 0x30, 0xa6, 0x91, 0xfb, 0xea, 0x0c, 0xd7, 0x63, 0x05, 0x65, 0xc0, 0x3e, 0x8d, 0x3e, 0x3d, - 0x23, 0xd7, 0xa0, 0xde, 0x8f, 0x51, 0xa8, 0x78, 0xe7, 0xdd, 0x06, 0x2e, 0xd6, 0x5a, 0x3f, 0x66, - 0xe2, 0xc4, 0x3b, 0x67, 0x0b, 0x8a, 0xb5, 0xd6, 0xc3, 0x59, 0xa0, 0x03, 0x2c, 0x3e, 0x46, 0xe9, - 0xd8, 0xc2, 0xc6, 0x6e, 0x08, 0x02, 0xab, 0x27, 0x26, 0xdf, 0x80, 0x96, 0x6c, 0xec, 0xd1, 0xd0, - 0x3b, 0x8e, 0x51, 0x3c, 0xb4, 0x9c, 0xa6, 0x00, 0x1f, 0x31, 0xcc, 0x7e, 0xc9, 0x95, 0x26, 0x6d, - 0x6e, 0xc5, 0xba, 0x61, 0xdb, 0x37, 0x22, 0x38, 0xaf, 0x35, 0x47, 0xa4, 0x8a, 0x26, 0xad, 0x54, - 0x30, 0x69, 0xf6, 0x2f, 0x2c, 0x68, 0x8a, 0x92, 0x51, 0xd3, 0x20, 0xf7, 0x81, 0xc8, 0x59, 0x4c, - 0x5e, 0xfb, 0x03, 0xf7, 0xf0, 0x3c, 0xa1, 0x31, 0x67, 0x9a, 0x9d, 0x19, 0xa7, 0x80, 0xc6, 0xe4, - 0xa1, 0x81, 0xc6, 0x49, 0xc4, 0x79, 0x7a, 0x67, 0xc6, 0xc9, 0x51, 0xd8, 0x12, 0x63, 0xba, 0xcc, - 0x24, 0x71, 0xfd, 0x60, 0x40, 0x5f, 0x23, 0x2b, 0xb5, 0x1c, 0x03, 0x7b, 0xd8, 0x86, 0xa6, 0xfe, - 0x9d, 0xfd, 0x53, 0xa8, 0x49, 0x4d, 0x08, 0xb5, 0x80, 0x4c, 0xbb, 0x1c, 0x0d, 0x21, 0x3d, 0xa8, - 0x99, 0xad, 0x70, 0x6a, 0x5f, 0xa6, 0x6e, 0xfb, 0xb7, 0xa1, 0xb3, 0xcb, 0x98, 0x28, 0x60, 0x4c, - 0x2b, 0xd4, 0xbb, 0x65, 0x98, 0xd5, 0x16, 0x4f, 0xdd, 0x11, 0x29, 0xb6, 0x8f, 0x9e, 0x84, 0x71, - 0x22, 0xea, 0xc1, 0xdf, 0xf6, 0xbf, 0xb5, 0x80, 0x6c, 0xc7, 0x89, 0x3f, 0xf2, 0x12, 0xfa, 0x88, - 0x2a, 0xf1, 0xf0, 0x0c, 0x9a, 0xac, 0xb4, 0xe7, 0xe1, 0x06, 0x57, 0xb6, 0xb8, 0x92, 0xf0, 0x2d, - 0xb1, 0x9c, 0xf3, 0x1f, 0xac, 0xe9, 0xb9, 0xb9, 0xe8, 0x36, 0x0a, 0x60, 0xab, 0x2d, 0xf1, 0xa2, - 0x63, 0x9a, 0xa0, 0x26, 0x26, 0xf4, 0x78, 0xe0, 0xd0, 0x66, 0x18, 0x1c, 0xf5, 0x7e, 0x07, 0x16, - 0x72, 0x65, 0xe8, 0x32, 0xba, 0x5e, 0x20, 0xa3, 0xcb, 0xba, 0x8c, 0xee, 0xc3, 0xa2, 0xd1, 0x2e, - 0xc1, 0x71, 0x5d, 0x98, 0x63, 0x0b, 0x83, 0x6d, 0xf8, 0x16, 0xdf, 0xf0, 0x45, 0x92, 0xac, 0xc3, - 0xd2, 0x11, 0xa5, 0x91, 0x97, 0x60, 0x12, 0x97, 0x0e, 0x9b, 0x13, 0x51, 0x72, 0x21, 0xcd, 0xfe, - 0x33, 0x0b, 0xe6, 0x99, 0x34, 0x7d, 0xea, 0x05, 0xe7, 0x72, 0xac, 0x76, 0x0b, 0xc7, 0xea, 0x8e, - 0xb6, 0xc9, 0x69, 0xb9, 0xbf, 0xec, 0x40, 0x95, 0xb3, 0x03, 0x45, 0x56, 0xa1, 0x69, 0x34, 0xb7, - 0xca, 0x35, 0xcb, 0xd8, 0x4b, 0xf6, 0x69, 0xf4, 0xf0, 0x3c, 0xa1, 0xbf, 0xfe, 0x50, 0xde, 0x86, - 0x4e, 0xda, 0x6c, 0x31, 0x8e, 0x04, 0x2a, 0x8c, 0x31, 0x45, 0x01, 0xf8, 0xdb, 0xfe, 0xfb, 0x16, - 0xcf, 0xb8, 0x19, 0xfa, 0x4a, 0xeb, 0x64, 0x19, 0x99, 0xf2, 0x2a, 0x33, 0xb2, 0xdf, 0x53, 0xb5, - 0xf6, 0x5f, 0xbf, 0xb3, 0x4c, 0x26, 0xc6, 0x34, 0x18, 0xb8, 0xde, 0x70, 0x88, 0x82, 0xb8, 0xe6, - 0xcc, 0xb1, 0xf4, 0xc6, 0x70, 0x68, 0xbf, 0x03, 0x0b, 0x5a, 0xeb, 0xde, 0xd0, 0x8f, 0x3d, 0x20, - 0xbb, 0x7e, 0x9c, 0xbc, 0x08, 0xe2, 0xb1, 0xa6, 0x90, 0x5d, 0x83, 0x3a, 0x93, 0xb6, 0xac, 0x65, - 0x7c, 0xe5, 0x56, 0x1d, 0x26, 0x7e, 0x59, 0xbb, 0x62, 0x24, 0x7a, 0xaf, 0x05, 0xb1, 0x24, 0x88, - 0xde, 0x6b, 0x24, 0xda, 0x0f, 0x60, 0xd1, 0x28, 0x4f, 0x54, 0xfd, 0x36, 0x54, 0x27, 0xc9, 0xeb, - 0x50, 0xaa, 0xdc, 0x0d, 0xc1, 0x21, 0xec, 0x70, 0xe7, 0x70, 0x8a, 0xfd, 0x31, 0x2c, 0xec, 0xd1, - 0x33, 0xb1, 0x90, 0x65, 0x43, 0x6e, 0x5f, 0x78, 0xf0, 0x43, 0xba, 0xbd, 0x06, 0x44, 0xff, 0x38, - 0x5d, 0x00, 0xf2, 0x18, 0x68, 0x19, 0xc7, 0x40, 0xfb, 0x36, 0x90, 0x03, 0xff, 0x38, 0x78, 0x4a, - 0xe3, 0xd8, 0x3b, 0x56, 0x4b, 0xbf, 0x03, 0xe5, 0x51, 0x7c, 0x2c, 0x44, 0x15, 0xfb, 0x69, 0x7f, - 0x07, 0x16, 0x8d, 0x7c, 0xa2, 0xe0, 0xeb, 0x50, 0x8f, 0xfd, 0xe3, 0xc0, 0x4b, 0x26, 0x11, 0x15, - 0x45, 0xa7, 0x80, 0xfd, 0x08, 0x96, 0x7e, 0x40, 0x23, 0xff, 0xe8, 0xfc, 0xa2, 0xe2, 0xcd, 0x72, - 0x4a, 0xd9, 0x72, 0xb6, 0xe1, 0x4a, 0xa6, 0x1c, 0x51, 0x3d, 0x67, 0x5f, 0x31, 0x93, 0x35, 0x87, - 0x27, 0x34, 0xd9, 0x57, 0xd2, 0x65, 0x9f, 0xfd, 0x02, 0xc8, 0x66, 0x18, 0x04, 0xb4, 0x9f, 0xec, - 0x53, 0x1a, 0xa5, 0x16, 0xa8, 0x94, 0x57, 0x1b, 0xeb, 0x2b, 0x62, 0x64, 0xb3, 0x02, 0x55, 0x30, - 0x31, 0x81, 0xca, 0x98, 0x46, 0x23, 0x2c, 0xb8, 0xe6, 0xe0, 0x6f, 0xfb, 0x0a, 0x2c, 0x1a, 0xc5, - 0x8a, 0x33, 0xfb, 0xfb, 0x70, 0x65, 0xcb, 0x8f, 0xfb, 0xf9, 0x0a, 0xbb, 0x30, 0x37, 0x9e, 0x1c, - 0xba, 0xe9, 0x4a, 0x94, 0x49, 0x76, 0x8c, 0xcb, 0x7e, 0x22, 0x0a, 0xfb, 0xeb, 0x16, 0x54, 0x76, - 0x9e, 0xef, 0x6e, 0xb2, 0xbd, 0xc2, 0x0f, 0xfa, 0xe1, 0x88, 0x69, 0x61, 0xbc, 0xd3, 0x2a, 0x3d, - 0x75, 0x85, 0x5d, 0x87, 0x3a, 0x2a, 0x6f, 0xec, 0xe4, 0x2a, 0xf4, 0xa0, 0x14, 0x60, 0xa7, 0x66, - 0xfa, 0x7a, 0xec, 0x47, 0x78, 0x2c, 0x96, 0x87, 0xdd, 0x0a, 0x6e, 0x33, 0x79, 0x82, 0xfd, 0xef, - 0xe6, 0x60, 0x4e, 0x6c, 0xbe, 0x7c, 0x23, 0x4f, 0xfc, 0x53, 0x9a, 0x6e, 0xe4, 0x2c, 0xc5, 0x14, - 0xe3, 0x88, 0x8e, 0xc2, 0x44, 0xe9, 0x6f, 0x7c, 0x1a, 0x4c, 0x10, 0xad, 0x02, 0x42, 0x89, 0xe0, - 0x76, 0x84, 0x32, 0xcf, 0x65, 0x80, 0xe4, 0x3a, 0xcc, 0x49, 0x65, 0xa0, 0xa2, 0x0e, 0x2c, 0x12, - 0x62, 0xa3, 0xd1, 0xf7, 0xc6, 0x5e, 0xdf, 0x4f, 0xce, 0x85, 0x58, 0x50, 0x69, 0x56, 0xfe, 0x30, - 0xec, 0x7b, 0x43, 0xf7, 0xd0, 0x1b, 0x7a, 0x41, 0x9f, 0x4a, 0xab, 0x83, 0x01, 0xb2, 0x13, 0xb8, - 0x68, 0x96, 0xcc, 0xc6, 0x4f, 0xe9, 0x19, 0x94, 0xed, 0xe1, 0xfd, 0x70, 0x34, 0xf2, 0x13, 0x76, - 0x70, 0x47, 0xd5, 0xac, 0xec, 0x68, 0x08, 0xb7, 0x71, 0x60, 0xea, 0x8c, 0x8f, 0x60, 0x5d, 0xda, - 0x38, 0x34, 0x90, 0x95, 0x92, 0xd1, 0xd0, 0xca, 0x8e, 0x86, 0xb0, 0xb9, 0x98, 0x04, 0x31, 0x4d, - 0x92, 0x21, 0x1d, 0xa8, 0x06, 0x35, 0x30, 0x5b, 0x9e, 0x40, 0xee, 0xc3, 0x22, 0xb7, 0x25, 0xc4, - 0x5e, 0x12, 0xc6, 0x27, 0x7e, 0xec, 0xc6, 0xec, 0x18, 0xc4, 0xcf, 0xb4, 0x45, 0x24, 0xf2, 0x00, - 0x56, 0x32, 0x70, 0x44, 0xfb, 0xd4, 0x3f, 0xa5, 0x03, 0x54, 0xe1, 0xca, 0xce, 0x34, 0x32, 0x59, - 0x85, 0x46, 0x30, 0x19, 0xb9, 0x93, 0xf1, 0xc0, 0x63, 0x4a, 0x4c, 0x1b, 0x95, 0x4b, 0x1d, 0x22, - 0xef, 0x83, 0xd4, 0xd3, 0x84, 0xf6, 0x38, 0x6f, 0x48, 0x38, 0xc6, 0xbd, 0x8e, 0x99, 0x83, 0x31, - 0x66, 0xaa, 0x92, 0x76, 0xc4, 0xf9, 0x51, 0x02, 0xb8, 0x4e, 0x22, 0xff, 0xd4, 0x4b, 0x68, 0x77, - 0x81, 0x0b, 0x75, 0x91, 0x64, 0xdf, 0xf9, 0x81, 0x9f, 0xf8, 0x5e, 0x12, 0x46, 0x5d, 0x82, 0xb4, - 0x14, 0x60, 0x83, 0x88, 0xfc, 0x11, 0x27, 0x5e, 0x32, 0x89, 0x85, 0x86, 0xba, 0x88, 0xcc, 0x95, - 0x27, 0x90, 0x0f, 0x61, 0x99, 0x73, 0x04, 0x92, 0x84, 0xee, 0x8d, 0xaa, 0xc2, 0x12, 0x8e, 0xc8, - 0x14, 0x2a, 0x1b, 0x4a, 0xc1, 0x22, 0xb9, 0x0f, 0xaf, 0xf0, 0xa1, 0x9c, 0x42, 0x66, 0xed, 0x63, - 0x2d, 0xf0, 0xfb, 0xae, 0xc8, 0xc1, 0x96, 0xc8, 0x32, 0xf6, 0x22, 0x4f, 0x60, 0x2c, 0x3e, 0xf4, - 0x8f, 0x68, 0xe2, 0x8f, 0x68, 0x77, 0x85, 0xb3, 0xb8, 0x4c, 0xb3, 0x05, 0x38, 0x19, 0x23, 0xa5, - 0xcb, 0x17, 0x3c, 0x4f, 0x21, 0x33, 0x0e, 0xc3, 0x98, 0x4a, 0x0b, 0x52, 0xf7, 0xaa, 0x58, 0x5a, - 0x3a, 0x68, 0xff, 0xa1, 0xc5, 0xb7, 0x28, 0xb1, 0x9c, 0x63, 0xed, 0xf0, 0xc5, 0x17, 0xb2, 0x1b, - 0x06, 0xc3, 0x73, 0xb1, 0xb6, 0x81, 0x43, 0xcf, 0x82, 0xe1, 0x39, 0x53, 0xff, 0xfd, 0x40, 0xcf, - 0xc2, 0xa5, 0x61, 0x53, 0x82, 0x98, 0xe9, 0x2d, 0x68, 0x8c, 0x27, 0x87, 0x43, 0xbf, 0xcf, 0xb3, - 0x94, 0x79, 0x29, 0x1c, 0xc2, 0x0c, 0xec, 0xf4, 0xc9, 0xe7, 0x93, 0xe7, 0xa8, 0x60, 0x8e, 0x86, - 0xc0, 0x58, 0x16, 0xfb, 0x21, 0x2c, 0x99, 0x0d, 0x14, 0x62, 0xff, 0x2e, 0xd4, 0x84, 0x94, 0x90, - 0xe6, 0x84, 0xb6, 0x66, 0xe4, 0x65, 0x87, 0x25, 0x45, 0xb7, 0xff, 0x55, 0x05, 0x16, 0x05, 0xba, - 0xc9, 0xba, 0x7f, 0x30, 0x19, 0x8d, 0xbc, 0xa8, 0x40, 0xfc, 0x58, 0x17, 0x88, 0x9f, 0x52, 0x5e, - 0xfc, 0xdc, 0x34, 0x4e, 0xa1, 0x5c, 0x7e, 0x69, 0x08, 0xb9, 0x03, 0xf3, 0x6c, 0xc8, 0xf9, 0xa1, - 0x40, 0xb7, 0x33, 0x66, 0xe1, 0xbc, 0xc8, 0xac, 0x16, 0x89, 0x4c, 0x5d, 0xdc, 0xcd, 0x66, 0xc4, - 0x9d, 0x0d, 0x4d, 0x3e, 0xbd, 0x42, 0x82, 0xcf, 0x89, 0x23, 0x99, 0x86, 0xb1, 0xf6, 0x64, 0x85, - 0x0b, 0x97, 0x64, 0xf3, 0x45, 0xa2, 0xc5, 0x1f, 0x51, 0xdc, 0x21, 0xb4, 0xdc, 0x75, 0x21, 0x5a, - 0xf2, 0x24, 0xf2, 0x08, 0x80, 0xd7, 0x85, 0x6a, 0x0a, 0xa0, 0x9a, 0x72, 0xdb, 0x9c, 0x15, 0x7d, - 0xfc, 0xd7, 0x58, 0x62, 0x12, 0x51, 0x54, 0x5d, 0xb4, 0x2f, 0xed, 0xbf, 0x69, 0x41, 0x43, 0xa3, - 0x91, 0x2b, 0xb0, 0xb0, 0xf9, 0xec, 0xd9, 0xfe, 0xb6, 0xb3, 0xf1, 0xfc, 0xc9, 0x0f, 0xb6, 0xdd, - 0xcd, 0xdd, 0x67, 0x07, 0xdb, 0x9d, 0x19, 0x06, 0xef, 0x3e, 0xdb, 0xdc, 0xd8, 0x75, 0x1f, 0x3d, - 0x73, 0x36, 0x25, 0x6c, 0x91, 0x65, 0x20, 0xce, 0xf6, 0xd3, 0x67, 0xcf, 0xb7, 0x0d, 0xbc, 0x44, - 0x3a, 0xd0, 0x7c, 0xe8, 0x6c, 0x6f, 0x6c, 0xee, 0x08, 0xa4, 0x4c, 0x96, 0xa0, 0xf3, 0xe8, 0xc5, - 0xde, 0xd6, 0x93, 0xbd, 0xc7, 0xee, 0xe6, 0xc6, 0xde, 0xe6, 0xf6, 0xee, 0xf6, 0x56, 0xa7, 0x42, - 0x5a, 0x50, 0xdf, 0x78, 0xb8, 0xb1, 0xb7, 0xf5, 0x6c, 0x6f, 0x7b, 0xab, 0x53, 0xb5, 0xff, 0x9b, - 0x05, 0x57, 0xb0, 0xd5, 0x83, 0xec, 0x22, 0x59, 0x85, 0x46, 0x3f, 0x0c, 0xc7, 0xec, 0x78, 0x90, - 0x6e, 0x80, 0x3a, 0xc4, 0x16, 0x00, 0x17, 0x1d, 0x47, 0x61, 0xd4, 0xa7, 0x62, 0x8d, 0x00, 0x42, - 0x8f, 0x18, 0xc2, 0x16, 0x80, 0x98, 0x5e, 0x9e, 0x83, 0x2f, 0x91, 0x06, 0xc7, 0x78, 0x96, 0x65, - 0x98, 0x3d, 0x8c, 0xa8, 0xd7, 0x3f, 0x11, 0xab, 0x43, 0xa4, 0xc8, 0xbb, 0xe9, 0xf9, 0xb5, 0xcf, - 0x46, 0x7f, 0x48, 0x07, 0xc8, 0x31, 0x35, 0x67, 0x5e, 0xe0, 0x9b, 0x02, 0x66, 0xb2, 0xd2, 0x3b, - 0xf4, 0x82, 0x41, 0x18, 0xd0, 0x81, 0x50, 0x8e, 0x53, 0xc0, 0xde, 0x87, 0xe5, 0x6c, 0xff, 0xc4, - 0x1a, 0xfb, 0x50, 0x5b, 0x63, 0x5c, 0x57, 0xed, 0x4d, 0x9f, 0x4d, 0x6d, 0xbd, 0xfd, 0x59, 0x19, - 0x2a, 0x4c, 0x75, 0x99, 0xae, 0xe6, 0xe8, 0xda, 0x68, 0x39, 0xe7, 0x94, 0xc0, 0x23, 0x31, 0xdf, - 0xc8, 0x84, 0x39, 0x26, 0x45, 0x52, 0x7a, 0x44, 0xfb, 0xa7, 0xc2, 0x20, 0xa3, 0x21, 0x6c, 0x81, - 0xb0, 0xa3, 0x02, 0x7e, 0x2d, 0x16, 0x88, 0x4c, 0x4b, 0x1a, 0x7e, 0x39, 0x97, 0xd2, 0xf0, 0xbb, - 0x2e, 0xcc, 0xf9, 0xc1, 0x61, 0x38, 0x09, 0x06, 0xb8, 0x20, 0x6a, 0x8e, 0x4c, 0xa2, 0x1b, 0x04, - 0x17, 0x2a, 0x93, 0xb2, 0x9c, 0xfd, 0x53, 0x80, 0xac, 0x43, 0x3d, 0x3e, 0x0f, 0xfa, 0x3a, 0xcf, - 0x2f, 0x89, 0x51, 0x62, 0x63, 0xb0, 0x76, 0x70, 0x1e, 0xf4, 0x91, 0xc3, 0xd3, 0x6c, 0xe4, 0x03, - 0xa8, 0x1d, 0x51, 0xd4, 0x6b, 0xa5, 0xf0, 0xba, 0xaa, 0x7f, 0xf2, 0x48, 0xd0, 0xf8, 0xb9, 0x50, - 0x65, 0xed, 0x7d, 0x0a, 0x2d, 0x83, 0xa4, 0x1f, 0xe6, 0x5a, 0xfc, 0x30, 0x77, 0x4b, 0x3f, 0xcc, - 0xa5, 0x32, 0x51, 0x7c, 0xa6, 0x1f, 0xee, 0x7e, 0x07, 0x6a, 0xb2, 0x69, 0x6c, 0x69, 0xbc, 0xd8, - 0xfb, 0x74, 0xef, 0xd9, 0xcb, 0x3d, 0xf7, 0xe0, 0x87, 0x7b, 0x9b, 0x9d, 0x19, 0x32, 0x0f, 0x8d, - 0x8d, 0x4d, 0x5c, 0x6d, 0x08, 0x58, 0x2c, 0xcb, 0xfe, 0xc6, 0xc1, 0x81, 0x42, 0x4a, 0x36, 0x81, - 0x0e, 0x93, 0xcc, 0xac, 0xc5, 0xca, 0xd5, 0xf0, 0x21, 0x2c, 0x68, 0x58, 0x7a, 0xde, 0x19, 0x33, - 0x20, 0x73, 0xde, 0x41, 0xe5, 0x96, 0x53, 0xec, 0x15, 0xb8, 0xc2, 0x92, 0xdb, 0xa7, 0x34, 0x48, - 0x0e, 0x26, 0x87, 0xdc, 0xc3, 0xe4, 0x87, 0x81, 0xfd, 0xd7, 0x2c, 0xa8, 0x2b, 0xca, 0x1b, 0xf8, - 0x49, 0x3a, 0xc5, 0x4a, 0x38, 0x01, 0x3d, 0xad, 0x0a, 0xfc, 0x72, 0x0d, 0xff, 0x35, 0xce, 0x48, - 0x75, 0x05, 0xb1, 0xce, 0xee, 0x6f, 0x6f, 0x3b, 0xee, 0xb3, 0xbd, 0xdd, 0x27, 0x7b, 0x4c, 0xb2, - 0xb0, 0xce, 0x22, 0xf0, 0xe8, 0x11, 0x22, 0x96, 0xdd, 0x81, 0xf6, 0x63, 0x9a, 0x3c, 0x09, 0x8e, - 0x42, 0xd9, 0xd5, 0xff, 0x57, 0x85, 0x79, 0x05, 0x89, 0x9e, 0xde, 0x81, 0x79, 0x7f, 0x40, 0x83, - 0xc4, 0x4f, 0xce, 0x5d, 0xc3, 0xf4, 0x92, 0x85, 0xd9, 0xa9, 0xc5, 0x1b, 0xfa, 0x9e, 0x74, 0xc9, - 0xf1, 0x04, 0x59, 0x87, 0x25, 0xa6, 0x4e, 0xe9, 0x26, 0x30, 0x5c, 0x7c, 0xdc, 0xe2, 0x53, 0x48, - 0x63, 0x62, 0x9a, 0xe1, 0x62, 0x2f, 0x56, 0x9f, 0x70, 0xed, 0xbd, 0x88, 0xc4, 0xf8, 0x99, 0x97, - 0xc4, 0xe6, 0xa4, 0xca, 0x55, 0x2e, 0x05, 0xe4, 0x7c, 0x5e, 0xb3, 0x7c, 0x13, 0xc9, 0xfa, 0xbc, - 0x34, 0xbf, 0x59, 0x2d, 0xe7, 0x37, 0x63, 0x9b, 0xcc, 0x79, 0xd0, 0xa7, 0x03, 0x37, 0x09, 0x5d, - 0xdc, 0x0c, 0x71, 0xdd, 0xd4, 0x9c, 0x2c, 0xcc, 0x36, 0xd7, 0x84, 0xc6, 0x49, 0x40, 0xb9, 0xf3, - 0xa0, 0x86, 0x06, 0x65, 0x09, 0xb1, 0xa3, 0xd6, 0x24, 0xf2, 0xe3, 0x6e, 0x13, 0x3d, 0x62, 0xf8, - 0x9b, 0x7c, 0x17, 0xae, 0x1c, 0xd2, 0x38, 0x71, 0x4f, 0xa8, 0x37, 0xa0, 0x11, 0xae, 0x41, 0xee, - 0x7a, 0xe3, 0xda, 0x6b, 0x31, 0x91, 0x71, 0xce, 0x29, 0x8d, 0x62, 0x3f, 0x0c, 0x50, 0x6f, 0xad, - 0x3b, 0x32, 0xc9, 0xca, 0x63, 0x9d, 0x57, 0xda, 0x8c, 0x1a, 0xc1, 0x79, 0xec, 0x78, 0x31, 0x91, - 0xdc, 0x82, 0x59, 0xec, 0x40, 0xdc, 0xed, 0x20, 0x53, 0x37, 0x53, 0xc1, 0xe8, 0x07, 0x8e, 0xa0, - 0xb1, 0x59, 0xee, 0x87, 0xc3, 0x30, 0x42, 0xe5, 0xb5, 0xee, 0xf0, 0x84, 0x39, 0x3a, 0xc7, 0x91, - 0x37, 0x3e, 0x11, 0x0a, 0x6c, 0x16, 0x26, 0xdf, 0xd3, 0xe4, 0xc4, 0x22, 0xd6, 0x73, 0x4b, 0xd4, - 0x93, 0xe1, 0xbc, 0xaf, 0x45, 0x64, 0x7c, 0x52, 0xa9, 0x35, 0x3a, 0x4d, 0xfb, 0x37, 0xa0, 0x8a, - 0xbd, 0xc4, 0xde, 0xe1, 0xdc, 0x5a, 0xa2, 0x77, 0x88, 0x76, 0x61, 0x2e, 0xa0, 0xc9, 0x59, 0x18, - 0xbd, 0x92, 0xee, 0x66, 0x91, 0xb4, 0x7f, 0x86, 0x67, 0x6f, 0xe5, 0x7e, 0x7d, 0x81, 0x87, 0x06, - 0x72, 0x0d, 0xea, 0x9c, 0x73, 0xe2, 0x13, 0x4f, 0x98, 0x03, 0x6a, 0x08, 0x1c, 0x9c, 0x78, 0x6c, - 0x7f, 0x34, 0x98, 0x91, 0x5b, 0x58, 0x1a, 0x88, 0xed, 0x70, 0x5e, 0xbc, 0x05, 0x6d, 0xe9, 0xd8, - 0x8d, 0xdd, 0x21, 0x3d, 0x4a, 0xa4, 0x7d, 0x34, 0x98, 0x8c, 0xd0, 0x0c, 0xb3, 0x4b, 0x8f, 0x12, - 0x7b, 0x0f, 0x16, 0xc4, 0x9e, 0xf5, 0x6c, 0x4c, 0x65, 0xd5, 0xbf, 0x59, 0xa4, 0xff, 0x35, 0xd6, - 0x17, 0xcd, 0x4d, 0x8e, 0xbb, 0xb2, 0xcd, 0x9c, 0xb6, 0x03, 0x44, 0xdf, 0x03, 0x45, 0x81, 0x42, - 0x01, 0x93, 0x16, 0x60, 0xd1, 0x1d, 0x03, 0x63, 0xe3, 0x13, 0x4f, 0xfa, 0x7d, 0xe9, 0x8e, 0xaf, - 0x39, 0x32, 0x69, 0xff, 0x67, 0x0b, 0x16, 0xb1, 0x34, 0xa9, 0xc1, 0x0a, 0x3d, 0xe3, 0xc1, 0x97, - 0x68, 0xa6, 0xb4, 0xbf, 0x73, 0xab, 0xf3, 0x12, 0x54, 0x75, 0xcd, 0x83, 0x27, 0xbe, 0xbc, 0xb5, - 0xad, 0x92, 0xb3, 0xb6, 0xdd, 0x85, 0xce, 0x80, 0x0e, 0x7d, 0x0c, 0xc9, 0x90, 0xfb, 0x38, 0x57, - 0x57, 0x73, 0xb8, 0xfd, 0x77, 0x2c, 0x58, 0xe0, 0x8a, 0x02, 0x9e, 0xb9, 0xc4, 0x50, 0xfd, 0x05, - 0x79, 0x3e, 0x11, 0x02, 0x4d, 0x74, 0x2a, 0xdd, 0x3a, 0x11, 0xe5, 0x99, 0x77, 0x66, 0x1c, 0x33, - 0x33, 0xf9, 0x18, 0xb5, 0xee, 0xc0, 0x45, 0xb4, 0x20, 0xc8, 0xc3, 0x9c, 0x97, 0x9d, 0x19, 0x47, - 0xcb, 0xfe, 0xb0, 0xc6, 0x8e, 0x4c, 0x0c, 0xb7, 0x1f, 0x43, 0xcb, 0xa8, 0xc8, 0xb0, 0x0a, 0x36, - 0xb9, 0x55, 0x30, 0x67, 0x7e, 0x2f, 0x15, 0x98, 0xdf, 0xff, 0xb4, 0x0c, 0x84, 0x31, 0x56, 0x66, - 0xe6, 0x56, 0x4d, 0x1f, 0x96, 0x8c, 0xf7, 0x48, 0x21, 0xb2, 0x0e, 0x44, 0x4b, 0x4a, 0xdf, 0x5a, - 0x59, 0xf9, 0xd6, 0x0a, 0xa8, 0x6c, 0x97, 0x10, 0x5a, 0xa5, 0xf2, 0x5b, 0xa1, 0xc5, 0x87, 0x4f, - 0x53, 0x21, 0x8d, 0x69, 0x3e, 0xe8, 0xc4, 0x62, 0x67, 0x53, 0x61, 0x25, 0x91, 0xe9, 0x2c, 0x3f, - 0xcc, 0x5e, 0xc8, 0x0f, 0x73, 0x39, 0x7e, 0xd0, 0xce, 0xe9, 0x35, 0xf3, 0x9c, 0x7e, 0x0b, 0x5a, - 0xd2, 0x57, 0xc5, 0xdd, 0xed, 0xc2, 0x28, 0x62, 0x80, 0x8c, 0x9f, 0xe4, 0x51, 0x59, 0x19, 0x03, - 0xb8, 0x33, 0x39, 0x87, 0xb3, 0xed, 0x2b, 0xb5, 0xc7, 0x36, 0xb0, 0xb1, 0x29, 0x80, 0x27, 0x6b, - 0xc6, 0x25, 0xee, 0x24, 0x10, 0xb1, 0x1e, 0x74, 0x80, 0xe6, 0x10, 0x76, 0xb2, 0xce, 0x12, 0xf2, - 0xa7, 0xe4, 0x56, 0xd1, 0x29, 0xf9, 0x6f, 0x59, 0xd0, 0x61, 0xb3, 0x6b, 0x30, 0xf0, 0x47, 0x80, - 0x6b, 0xed, 0x92, 0xfc, 0x6b, 0xe4, 0x25, 0x0f, 0xa0, 0x8e, 0xe9, 0x70, 0x4c, 0x03, 0xc1, 0xbd, - 0x5d, 0x93, 0x7b, 0x53, 0x29, 0xb5, 0x33, 0xe3, 0xa4, 0x99, 0x35, 0xde, 0xfd, 0x8f, 0x16, 0x34, - 0x44, 0x2d, 0xbf, 0xb2, 0x55, 0xb0, 0xa7, 0x85, 0xf0, 0x70, 0x35, 0x3c, 0x8d, 0xd8, 0xb9, 0x03, - 0xf3, 0x23, 0xb6, 0x03, 0x30, 0xa5, 0xc5, 0xb0, 0x08, 0x66, 0x61, 0xa6, 0x81, 0xa0, 0x40, 0x8e, - 0xdd, 0xc4, 0x1f, 0xba, 0x92, 0x2a, 0x82, 0x65, 0x8a, 0x48, 0x4c, 0x2e, 0xc5, 0x89, 0x77, 0x4c, - 0x85, 0x72, 0xc1, 0x13, 0x76, 0x17, 0x96, 0xf7, 0x53, 0x2f, 0x9f, 0x76, 0xd2, 0xb2, 0xff, 0x69, - 0x0b, 0x56, 0x72, 0x24, 0x15, 0xda, 0x27, 0xcc, 0x5c, 0x43, 0x7f, 0x74, 0x18, 0xaa, 0x63, 0xaa, - 0xa5, 0x5b, 0xc0, 0x0c, 0x12, 0x39, 0x86, 0x2b, 0x52, 0x8b, 0x62, 0x63, 0x9a, 0xee, 0xf8, 0x25, - 0xdc, 0x62, 0xdf, 0x37, 0xa7, 0x30, 0x5b, 0xa1, 0xc4, 0xf5, 0xe5, 0x5e, 0x5c, 0x1e, 0x39, 0x81, - 0xae, 0x52, 0xd7, 0xc4, 0x16, 0xa0, 0xa9, 0x74, 0xac, 0xae, 0xf7, 0x2e, 0xa8, 0xcb, 0x38, 0x98, - 0x39, 0x53, 0x4b, 0x23, 0xe7, 0x70, 0x53, 0xd2, 0x50, 0xc6, 0xe7, 0xeb, 0xab, 0x5c, 0xaa, 0x6f, - 0x78, 0xe4, 0x34, 0x2b, 0xbd, 0xa0, 0x60, 0xf2, 0x53, 0x58, 0x3e, 0xf3, 0xfc, 0x44, 0x36, 0x4b, - 0x53, 0xa0, 0xaa, 0x58, 0xe5, 0xfa, 0x05, 0x55, 0xbe, 0xe4, 0x1f, 0x1b, 0x1b, 0xdf, 0x94, 0x12, - 0x7b, 0x7f, 0x52, 0x82, 0xb6, 0x59, 0x0e, 0x63, 0x53, 0x21, 0x21, 0xa4, 0xa4, 0x94, 0x2a, 0x77, - 0x06, 0xce, 0x5b, 0x7b, 0x4a, 0x45, 0xd6, 0x1e, 0xdd, 0xbe, 0x52, 0xbe, 0xc8, 0x9c, 0x5c, 0xb9, - 0x9c, 0x39, 0xb9, 0x5a, 0x68, 0x4e, 0x9e, 0x6e, 0x75, 0x9c, 0xfd, 0x55, 0xad, 0x8e, 0x73, 0x6f, - 0xb4, 0x3a, 0xf6, 0xfe, 0xaf, 0x05, 0x24, 0xcf, 0xbd, 0xe4, 0x31, 0x37, 0x70, 0x05, 0x74, 0x28, - 0x84, 0xd8, 0xb7, 0x2f, 0xb7, 0x02, 0xe4, 0x6c, 0xc9, 0xaf, 0xd9, 0x52, 0xd4, 0xe3, 0xeb, 0x74, - 0xa5, 0xad, 0xe5, 0x14, 0x91, 0x32, 0x26, 0xf5, 0xca, 0xc5, 0x26, 0xf5, 0xea, 0xc5, 0x26, 0xf5, - 0xd9, 0xac, 0x49, 0xbd, 0xf7, 0x57, 0x2d, 0x58, 0x2c, 0x60, 0xb3, 0xaf, 0xae, 0xe3, 0x8c, 0x31, - 0x0c, 0xe9, 0x53, 0x12, 0x8c, 0xa1, 0x83, 0xbd, 0xbf, 0x04, 0x2d, 0x63, 0x69, 0x7d, 0x75, 0xf5, - 0x67, 0xf5, 0x4e, 0xce, 0xd9, 0x06, 0xd6, 0xfb, 0x5f, 0x25, 0x20, 0xf9, 0xe5, 0xfd, 0xb5, 0xb6, - 0x21, 0x3f, 0x4e, 0xe5, 0x82, 0x71, 0xfa, 0x73, 0xdd, 0x79, 0xde, 0x83, 0x05, 0x11, 0x34, 0xac, - 0x99, 0x34, 0x39, 0xc7, 0xe4, 0x09, 0x4c, 0xf3, 0x36, 0xfd, 0x19, 0x35, 0x23, 0x48, 0x52, 0xdb, - 0x7e, 0x33, 0x6e, 0x0d, 0xbb, 0x07, 0x5d, 0x31, 0x42, 0x79, 0x9b, 0xc6, 0x3f, 0x2f, 0xab, 0xc3, - 0x03, 0x12, 0x85, 0x42, 0xf1, 0x5d, 0x68, 0xea, 0xdb, 0x87, 0x98, 0x8e, 0x8c, 0x55, 0x9b, 0xa9, - 0x12, 0x7a, 0x2e, 0xb2, 0x05, 0x6d, 0x14, 0x92, 0x03, 0xf5, 0x1d, 0x3f, 0xc6, 0xbd, 0xc1, 0x52, - 0xb7, 0x33, 0xe3, 0x64, 0xbe, 0x21, 0xbf, 0x05, 0x6d, 0xf3, 0x84, 0x2b, 0xb4, 0x92, 0xa2, 0x33, - 0x06, 0xfb, 0xdc, 0xcc, 0x4c, 0x36, 0xa0, 0x93, 0x3d, 0x22, 0x8b, 0xc8, 0xaf, 0x29, 0x05, 0xe4, - 0xb2, 0x93, 0x07, 0xc2, 0x80, 0x53, 0x45, 0x03, 0xce, 0x2d, 0xf3, 0x33, 0x6d, 0x98, 0xd6, 0xf8, - 0x7f, 0x9a, 0x29, 0xe7, 0x77, 0x01, 0x52, 0x8c, 0x74, 0xa0, 0xf9, 0x6c, 0x7f, 0x7b, 0xcf, 0xdd, - 0xdc, 0xd9, 0xd8, 0xdb, 0xdb, 0xde, 0xed, 0xcc, 0x10, 0x02, 0x6d, 0x34, 0xf8, 0x6e, 0x29, 0xcc, - 0x62, 0x98, 0x30, 0x6f, 0x49, 0xac, 0x44, 0x96, 0xa0, 0xf3, 0x64, 0x2f, 0x83, 0x96, 0x1f, 0xd6, - 0xd5, 0xfa, 0xb0, 0x97, 0x61, 0x89, 0x07, 0x85, 0x3f, 0xe4, 0xec, 0x21, 0xb5, 0x93, 0x7f, 0x60, - 0xc1, 0x95, 0x0c, 0x21, 0x0d, 0x0f, 0xe4, 0x0a, 0x88, 0xa9, 0x95, 0x98, 0x20, 0x3a, 0xab, 0xa4, - 0x46, 0x9a, 0x91, 0x20, 0x79, 0x02, 0xe3, 0x79, 0x4d, 0x83, 0xcd, 0xac, 0xa4, 0x22, 0x92, 0xbd, - 0xa2, 0xa2, 0xb0, 0x32, 0x0d, 0x3f, 0xe2, 0xc1, 0xe6, 0x3a, 0x21, 0x0d, 0x16, 0x30, 0x9b, 0x2c, - 0x93, 0xec, 0xf0, 0x61, 0x28, 0x3b, 0x66, 0x7b, 0x0b, 0x69, 0xf6, 0xff, 0xae, 0x00, 0xf9, 0xfe, - 0x84, 0x46, 0xe7, 0x18, 0xff, 0xa7, 0xec, 0xe7, 0x2b, 0x59, 0x6b, 0xde, 0xec, 0x78, 0x72, 0xf8, - 0x29, 0x3d, 0x97, 0xf1, 0xba, 0xa5, 0x4b, 0xc5, 0xeb, 0x16, 0xc5, 0xcb, 0x56, 0x2e, 0x8e, 0x97, - 0xad, 0x5e, 0x14, 0x2f, 0xfb, 0x0d, 0x68, 0xf9, 0xc7, 0x41, 0xc8, 0xc4, 0x01, 0x53, 0x21, 0xe2, - 0xee, 0xec, 0x6a, 0x99, 0x1d, 0xe6, 0x05, 0xb8, 0xc7, 0x30, 0xf2, 0x71, 0x9a, 0x89, 0x0e, 0x8e, - 0x31, 0xbe, 0x5b, 0x17, 0x10, 0xdb, 0x83, 0x63, 0xba, 0x1b, 0xf6, 0xbd, 0x24, 0x8c, 0xf0, 0x34, - 0x27, 0x3f, 0x66, 0x78, 0x4c, 0x6e, 0x41, 0x3b, 0x0e, 0x27, 0x4c, 0xa9, 0x92, 0xc3, 0xc0, 0x2d, - 0x69, 0x4d, 0x8e, 0xee, 0xf3, 0xc1, 0x58, 0x83, 0xc5, 0x49, 0x4c, 0xdd, 0x91, 0x1f, 0xc7, 0x6c, - 0xe3, 0xec, 0x87, 0x41, 0x12, 0x85, 0x43, 0x61, 0x4f, 0x5b, 0x98, 0xc4, 0xf4, 0x29, 0xa7, 0x6c, - 0x72, 0x02, 0xf9, 0x6e, 0xda, 0xa4, 0xb1, 0xe7, 0x47, 0x71, 0x17, 0xb0, 0x49, 0xb2, 0xa7, 0xac, - 0xdd, 0xfb, 0x9e, 0x1f, 0xa9, 0xb6, 0xb0, 0x44, 0x9c, 0x89, 0xe3, 0x6d, 0x64, 0xe3, 0x78, 0x7f, - 0x52, 0x1c, 0xc7, 0xdb, 0xc2, 0xa2, 0xef, 0x8b, 0xa2, 0xf3, 0x53, 0x7c, 0xf9, 0x70, 0xde, 0xaf, - 0x26, 0x40, 0x57, 0xc4, 0x94, 0xae, 0x41, 0x4d, 0x76, 0x93, 0x9d, 0xe8, 0x8f, 0xa2, 0x70, 0x24, - 0x4f, 0xf4, 0xec, 0x37, 0x69, 0x43, 0x29, 0x09, 0xc5, 0xc7, 0xa5, 0x24, 0xb4, 0x7f, 0x0f, 0x1a, - 0xda, 0x4c, 0x91, 0xb7, 0xb9, 0x71, 0x81, 0xe9, 0x84, 0xc2, 0x14, 0xc0, 0x7d, 0x7e, 0x75, 0x81, - 0x3e, 0x19, 0x90, 0x6f, 0xc1, 0xc2, 0xc0, 0x8f, 0x28, 0x86, 0xc4, 0xbb, 0x11, 0x3d, 0xa5, 0x51, - 0x2c, 0x8d, 0x2c, 0x1d, 0x45, 0x70, 0x38, 0x6e, 0xbb, 0xb0, 0x68, 0x0c, 0x8d, 0x12, 0x0e, 0xb3, - 0x18, 0x08, 0x2b, 0xed, 0xe2, 0x66, 0x90, 0xac, 0xa0, 0xb1, 0x6d, 0x55, 0xd8, 0x87, 0xdc, 0x71, - 0x14, 0x1e, 0x62, 0x25, 0x96, 0x63, 0x60, 0xf6, 0xff, 0x2c, 0x43, 0x79, 0x27, 0x1c, 0xeb, 0x9e, - 0x4a, 0x2b, 0xef, 0xa9, 0x14, 0xfa, 0xaf, 0xab, 0xd4, 0x5b, 0xa1, 0xa4, 0x18, 0x20, 0xb9, 0x0b, - 0x6d, 0xb6, 0xd2, 0x92, 0x90, 0xe9, 0xfb, 0x67, 0x5e, 0xc4, 0xa3, 0x66, 0xcb, 0xc8, 0xbe, 0x19, - 0x0a, 0x59, 0x82, 0xb2, 0x52, 0xdb, 0x30, 0x03, 0x4b, 0xb2, 0xc3, 0x26, 0xc6, 0x8c, 0x9c, 0x0b, - 0xdb, 0xb2, 0x48, 0x31, 0xc1, 0x65, 0x7e, 0xcf, 0x97, 0x33, 0xdf, 0x7c, 0x8b, 0x48, 0x4c, 0x17, - 0x67, 0x0b, 0x76, 0x94, 0xaa, 0xb6, 0x2a, 0xad, 0xbb, 0x02, 0x6a, 0xa6, 0x2b, 0x60, 0x15, 0x1a, - 0xc9, 0xf0, 0xd4, 0x1d, 0x7b, 0xe7, 0xc3, 0xd0, 0x1b, 0x88, 0x85, 0xa2, 0x43, 0xe4, 0x3e, 0xc0, - 0x68, 0x3c, 0x16, 0x5c, 0x8c, 0x76, 0x86, 0xc6, 0x7a, 0x47, 0x8c, 0xfe, 0xd3, 0xfd, 0x7d, 0xce, - 0x7d, 0x8e, 0x96, 0x87, 0x6c, 0x43, 0xbb, 0x30, 0x84, 0xfd, 0x86, 0x8c, 0x6c, 0x08, 0xc7, 0x6b, - 0x05, 0x7c, 0x9e, 0xf9, 0xa8, 0xf7, 0x3d, 0x20, 0xbf, 0x66, 0x04, 0xfa, 0x4b, 0xa8, 0xab, 0x16, - 0xea, 0x71, 0xdf, 0x18, 0xbe, 0xd4, 0x30, 0xe3, 0xbe, 0x31, 0x5a, 0xe9, 0x36, 0xb4, 0xf9, 0x6e, - 0xa3, 0xe4, 0x27, 0x0f, 0x39, 0xc9, 0xa0, 0xf6, 0x2f, 0x2d, 0xa8, 0x22, 0xe7, 0x31, 0xf5, 0x8b, - 0xd3, 0x94, 0x8b, 0x57, 0x58, 0x8b, 0xb3, 0x30, 0xb1, 0x8d, 0xab, 0x2d, 0x25, 0xc5, 0x06, 0xfa, - 0xf5, 0x96, 0x55, 0xa8, 0xab, 0x9a, 0x34, 0x56, 0x4a, 0x41, 0x72, 0x13, 0x2a, 0x27, 0xe1, 0x58, - 0x9e, 0x50, 0x21, 0x1d, 0x51, 0x07, 0xf1, 0xb4, 0x3d, 0xac, 0x3c, 0xde, 0x05, 0x7e, 0x0a, 0xc8, - 0xc2, 0x05, 0x7d, 0x9d, 0x2d, 0xec, 0xeb, 0x0b, 0x98, 0x67, 0xf2, 0x41, 0xf3, 0xe6, 0x4c, 0xdf, - 0x8b, 0xde, 0x65, 0xaa, 0x4d, 0x7f, 0x38, 0x19, 0x50, 0xdd, 0x4e, 0x80, 0xd6, 0x7a, 0x81, 0x4b, - 0x0d, 0xd9, 0xfe, 0x67, 0x16, 0x97, 0x3b, 0xac, 0x5c, 0x72, 0x07, 0x2a, 0x6c, 0xdb, 0xc8, 0x98, - 0x85, 0x54, 0x48, 0x19, 0xcb, 0xe7, 0x60, 0x0e, 0x36, 0x8b, 0x68, 0xc0, 0xd6, 0x4b, 0xe7, 0xe6, - 0xeb, 0xf4, 0x90, 0xad, 0x7a, 0x96, 0x39, 0x9b, 0x66, 0x50, 0xb2, 0xa6, 0x79, 0x6c, 0x2b, 0xc6, - 0x56, 0x24, 0x35, 0xa9, 0xc1, 0x31, 0xd5, 0x3c, 0xb5, 0xff, 0xa2, 0x04, 0x2d, 0xa3, 0x4d, 0x6c, - 0xf5, 0xe0, 0xc5, 0x0f, 0x6e, 0x65, 0x12, 0x33, 0xaf, 0x43, 0xfa, 0xca, 0x2b, 0x99, 0x2b, 0x4f, - 0x39, 0xb5, 0xca, 0xba, 0x53, 0xeb, 0x3e, 0xd4, 0xd3, 0xbb, 0x4d, 0x66, 0xa3, 0x58, 0x8d, 0x32, - 0xb8, 0x2e, 0xcd, 0x94, 0xba, 0x4d, 0xaa, 0xba, 0xdb, 0xe4, 0xb7, 0x35, 0x67, 0xc8, 0x2c, 0x16, - 0x63, 0x17, 0x8d, 0xea, 0xd7, 0xe3, 0x3d, 0xfd, 0x18, 0x1a, 0x5a, 0xe3, 0x75, 0xa7, 0x87, 0x65, - 0x38, 0x3d, 0x54, 0x18, 0x6c, 0x29, 0x0d, 0x83, 0xb5, 0x7f, 0x5e, 0x82, 0x16, 0x5b, 0x6b, 0x7e, - 0x70, 0xbc, 0x1f, 0x0e, 0xfd, 0xfe, 0x39, 0xf2, 0xb8, 0x5c, 0x56, 0x42, 0x87, 0x91, 0x6b, 0xce, - 0x84, 0x99, 0x4c, 0x54, 0xb1, 0xff, 0x5c, 0x80, 0xab, 0x34, 0x93, 0xf0, 0x4c, 0x3e, 0x1e, 0x7a, - 0x31, 0xd5, 0x6e, 0x5e, 0x39, 0x26, 0xc8, 0xe4, 0x30, 0x03, 0x30, 0xa8, 0x79, 0xe4, 0x0f, 0x87, - 0x3e, 0xcf, 0xcb, 0x0f, 0xdf, 0x45, 0x24, 0x56, 0xe7, 0xc0, 0x8f, 0xbd, 0xc3, 0x34, 0xc4, 0x40, - 0xa5, 0xd1, 0xbe, 0xeb, 0xbd, 0xd6, 0xec, 0xbb, 0xfc, 0x16, 0x84, 0x09, 0x66, 0xb9, 0x6a, 0x2e, - 0xc7, 0x55, 0xf6, 0xbf, 0x29, 0x41, 0x43, 0xe3, 0x51, 0x26, 0x5b, 0x0a, 0x37, 0x61, 0x0d, 0x15, - 0xb1, 0x37, 0x81, 0x61, 0xce, 0xd1, 0x10, 0x72, 0xcb, 0xac, 0x15, 0xfd, 0x42, 0x28, 0x7d, 0x0c, - 0x7e, 0xbe, 0x0e, 0x75, 0xb6, 0x0e, 0xdf, 0x47, 0xdb, 0x91, 0xb8, 0xe5, 0xa8, 0x00, 0x49, 0x5d, - 0x47, 0x6a, 0x35, 0xa5, 0x22, 0xf0, 0xc6, 0x68, 0x9c, 0x07, 0xd0, 0x14, 0xc5, 0xe0, 0x1c, 0x63, - 0xa7, 0x53, 0x49, 0x60, 0xcc, 0xbf, 0x63, 0xe4, 0x94, 0x5f, 0xae, 0xcb, 0x2f, 0x6b, 0x17, 0x7d, - 0x29, 0x73, 0xda, 0x8f, 0x55, 0xa0, 0xd3, 0xe3, 0xc8, 0x1b, 0x9f, 0x48, 0xe9, 0x76, 0x1f, 0x16, - 0xa5, 0x10, 0x9b, 0x04, 0x5e, 0x10, 0x84, 0x93, 0xa0, 0x4f, 0x65, 0xc4, 0x6c, 0x11, 0xc9, 0x1e, - 0xa8, 0xfb, 0x15, 0x58, 0x10, 0xb9, 0x0b, 0x55, 0xae, 0x05, 0x73, 0x5d, 0xa5, 0x58, 0x9e, 0xf1, - 0x2c, 0xe4, 0x0e, 0x54, 0xb9, 0x32, 0x5c, 0x9a, 0x2a, 0x81, 0x78, 0x06, 0x7b, 0x0d, 0xe6, 0xf1, - 0x42, 0x87, 0x26, 0x88, 0xaf, 0x15, 0xe9, 0x30, 0xb3, 0x7d, 0x7e, 0xed, 0x63, 0x09, 0xc8, 0x1e, - 0x5f, 0x57, 0xba, 0x27, 0xfe, 0x97, 0x65, 0x68, 0x68, 0x30, 0x13, 0x96, 0xe8, 0x3e, 0x75, 0x07, - 0xbe, 0x37, 0xa2, 0x09, 0x8d, 0xc4, 0x5a, 0xca, 0xa0, 0x2c, 0x9f, 0x77, 0x7a, 0xec, 0x86, 0x93, - 0xc4, 0x1d, 0xd0, 0xe3, 0x88, 0x52, 0xa1, 0x5c, 0x65, 0x50, 0x96, 0x8f, 0x71, 0xb3, 0x96, 0x8f, - 0x7b, 0x18, 0x33, 0xa8, 0xf4, 0xab, 0xf3, 0x71, 0xaa, 0xa4, 0x7e, 0x75, 0x3e, 0x2a, 0x59, 0x31, - 0x5f, 0x2d, 0x10, 0xf3, 0x1f, 0xc2, 0x32, 0x17, 0xe8, 0x42, 0x7a, 0xb8, 0x19, 0xe6, 0x9a, 0x42, - 0x25, 0x77, 0xa1, 0xc3, 0xda, 0x2c, 0x97, 0x46, 0xec, 0xff, 0x8c, 0xaf, 0x31, 0xcb, 0xc9, 0xe1, - 0x2c, 0x2f, 0x7a, 0x4b, 0xf4, 0xbc, 0x3c, 0x02, 0x2c, 0x87, 0x63, 0x5e, 0xef, 0xb5, 0x99, 0xb7, - 0x2e, 0xf2, 0x66, 0x70, 0xf2, 0x00, 0x56, 0x46, 0x74, 0xe0, 0x7b, 0x66, 0x11, 0x6e, 0xaa, 0x71, - 0x4c, 0x23, 0xb3, 0x5a, 0xd8, 0x28, 0xfc, 0x2c, 0x1c, 0x1d, 0xfa, 0x7c, 0x97, 0xe5, 0x7e, 0x9d, - 0x8a, 0x93, 0xc3, 0xed, 0x16, 0x34, 0x0e, 0x92, 0x70, 0x2c, 0xa7, 0xbe, 0x0d, 0x4d, 0x9e, 0x14, - 0x31, 0xd2, 0xd7, 0xe0, 0x2a, 0xf2, 0xeb, 0xf3, 0x70, 0x1c, 0x0e, 0xc3, 0xe3, 0x73, 0xc3, 0xee, - 0xf2, 0xef, 0x2d, 0x58, 0x34, 0xa8, 0xa9, 0xe1, 0x05, 0x8d, 0xc4, 0x32, 0xb0, 0x95, 0xb3, 0xf8, - 0x82, 0xb6, 0x47, 0xf1, 0x8c, 0xdc, 0x73, 0xf7, 0x42, 0xc4, 0xba, 0x6e, 0xa4, 0xb7, 0xb5, 0xe4, - 0x87, 0x9c, 0xdf, 0xbb, 0x79, 0x7e, 0x17, 0xdf, 0xcb, 0x7b, 0x5c, 0xb2, 0x88, 0xdf, 0x12, 0xf1, - 0x7a, 0x03, 0xd1, 0xe9, 0xb2, 0x19, 0x63, 0xa5, 0xdb, 0xe9, 0x64, 0x0b, 0xfa, 0x0a, 0x8c, 0xed, - 0x5f, 0x58, 0x00, 0x69, 0xeb, 0x30, 0xca, 0x4b, 0xed, 0xb3, 0xfc, 0x61, 0x03, 0x6d, 0x4f, 0x7d, - 0x1b, 0x9a, 0x2a, 0x06, 0x25, 0xdd, 0xba, 0x1b, 0x12, 0x63, 0xaa, 0xce, 0x3b, 0x30, 0x7f, 0x3c, - 0x0c, 0x0f, 0x51, 0xa5, 0x12, 0xfb, 0x2c, 0x8f, 0x14, 0x6f, 0x73, 0x58, 0xee, 0x9e, 0xe9, 0x3e, - 0x5f, 0xd1, 0xf7, 0xf9, 0xc2, 0x5d, 0x9b, 0xed, 0x75, 0x0b, 0xb9, 0x91, 0x78, 0xe3, 0x2a, 0x27, - 0xeb, 0x39, 0xb1, 0x3e, 0xc5, 0xd9, 0x8d, 0x07, 0xb2, 0xfd, 0x0b, 0xcd, 0xf6, 0x1f, 0x43, 0x3b, - 0xe2, 0x32, 0x53, 0x0a, 0xd4, 0xca, 0x1b, 0x04, 0x6a, 0x2b, 0x32, 0x76, 0xe6, 0x77, 0xa1, 0xe3, - 0x0d, 0x4e, 0x69, 0x94, 0xf8, 0x68, 0xc6, 0x44, 0x9d, 0x8e, 0x77, 0x70, 0x5e, 0xc3, 0x51, 0x75, - 0x7a, 0x07, 0xe6, 0x45, 0xdc, 0xbe, 0xca, 0x29, 0xae, 0xf8, 0xa6, 0x30, 0xcb, 0x68, 0xff, 0x23, - 0xe9, 0xe8, 0x37, 0x67, 0xf7, 0xcd, 0xa3, 0xa2, 0xf7, 0xb0, 0x94, 0xe9, 0xe1, 0x37, 0x84, 0x1b, - 0x73, 0x20, 0xed, 0xa5, 0x65, 0x2d, 0xf2, 0x73, 0x20, 0x02, 0x25, 0xcc, 0x61, 0xad, 0x5c, 0x66, - 0x58, 0xed, 0xff, 0x62, 0xc1, 0xdc, 0x4e, 0x38, 0xde, 0xf1, 0x79, 0xf0, 0x15, 0x2e, 0x13, 0x75, - 0x69, 0x46, 0x26, 0x2f, 0x88, 0x90, 0x2d, 0xd4, 0x4a, 0x5a, 0x59, 0xad, 0xe4, 0x7b, 0x70, 0x0d, - 0x2d, 0xf6, 0x51, 0x38, 0x0e, 0x23, 0xb6, 0x5c, 0xbd, 0x21, 0x57, 0x41, 0xc2, 0x20, 0x39, 0x91, - 0xe2, 0xf4, 0x4d, 0x59, 0xd0, 0x8c, 0x36, 0x4c, 0x4e, 0x5d, 0x7e, 0xdc, 0x14, 0x5a, 0x14, 0x97, - 0xb2, 0x79, 0x82, 0xfd, 0x9b, 0x50, 0xc7, 0xe3, 0x0e, 0x76, 0xed, 0x3d, 0xa8, 0x9f, 0x84, 0x63, - 0xf7, 0xc4, 0x0f, 0x12, 0xb9, 0xfc, 0xdb, 0xe9, 0x39, 0x64, 0x07, 0x07, 0x45, 0x65, 0xb0, 0xff, - 0xc3, 0x1c, 0xcc, 0x3d, 0x09, 0x4e, 0x43, 0xbf, 0x8f, 0x01, 0x03, 0x23, 0x3a, 0x0a, 0xe5, 0x35, - 0x22, 0xf6, 0x1b, 0x6f, 0xea, 0xa7, 0x17, 0x7d, 0xf9, 0x12, 0xd2, 0x10, 0x76, 0x40, 0x8e, 0xf4, - 0x8b, 0xba, 0x22, 0x95, 0x9e, 0xfa, 0xaa, 0xda, 0x45, 0x2c, 0x56, 0x1a, 0xbf, 0x40, 0x8a, 0x63, - 0xc7, 0xc3, 0xbf, 0x35, 0x84, 0x0d, 0xbe, 0x88, 0xdc, 0xe5, 0xa1, 0x9d, 0x3c, 0x82, 0x4a, 0x40, - 0x78, 0xe8, 0x8f, 0x28, 0xf7, 0xb9, 0x28, 0xd5, 0x8b, 0x1d, 0xfa, 0x75, 0x90, 0xa9, 0x67, 0xfc, - 0x03, 0x9e, 0x87, 0x6f, 0x07, 0x3a, 0xc4, 0x14, 0xd4, 0xec, 0xf5, 0x75, 0xfe, 0x04, 0x41, 0x16, - 0xe6, 0xa1, 0x21, 0x4a, 0xe8, 0xf2, 0x7e, 0x02, 0xbf, 0xec, 0x9c, 0xc5, 0x35, 0x53, 0x01, 0xbf, - 0xe0, 0x20, 0x4d, 0x05, 0x8c, 0x65, 0xbc, 0xe1, 0xf0, 0xd0, 0xeb, 0xbf, 0xe2, 0x27, 0xdb, 0x26, - 0x77, 0xd5, 0x19, 0x20, 0xc6, 0xdf, 0xa6, 0xf3, 0x8a, 0xae, 0xfb, 0x8a, 0xa3, 0x43, 0x64, 0x1d, - 0x1a, 0x68, 0x46, 0x11, 0x33, 0xdb, 0xc6, 0x99, 0xed, 0xe8, 0x76, 0x16, 0x9c, 0x5b, 0x3d, 0x93, - 0x1e, 0xca, 0x30, 0x9f, 0xbb, 0x72, 0xe0, 0x0d, 0x06, 0x22, 0x0a, 0xa4, 0xc3, 0x2f, 0xfb, 0x2a, - 0x00, 0x0d, 0x35, 0x7c, 0xc0, 0x78, 0x86, 0x05, 0xcc, 0x60, 0x60, 0xe4, 0x26, 0x37, 0x63, 0x8e, - 0x3d, 0x7f, 0x80, 0x21, 0x5f, 0xfc, 0x2c, 0xac, 0x30, 0x56, 0x86, 0xfc, 0x8d, 0x1b, 0xe7, 0x22, - 0x8e, 0x8a, 0x81, 0xb1, 0xb1, 0x51, 0xe9, 0x51, 0x7a, 0x47, 0xc1, 0x04, 0xc9, 0xfb, 0xe8, 0x61, - 0x4f, 0x28, 0x5e, 0x44, 0x68, 0xaf, 0x5f, 0x13, 0x7d, 0x16, 0x6c, 0x2b, 0xff, 0x3f, 0x60, 0x59, - 0x1c, 0x9e, 0x93, 0xa9, 0x6d, 0xdc, 0xc9, 0xb1, 0x6c, 0xa8, 0x6d, 0x22, 0x2b, 0x3a, 0x39, 0x78, - 0x06, 0xf2, 0x40, 0x3b, 0x89, 0x75, 0x31, 0xf3, 0xf5, 0x4c, 0xf9, 0x5f, 0xcb, 0x19, 0x6c, 0x03, - 0x9a, 0x7a, 0x3f, 0x48, 0x0d, 0x2a, 0xcf, 0xf6, 0xb7, 0xf7, 0x3a, 0x33, 0xa4, 0x01, 0x73, 0x07, - 0xdb, 0xcf, 0x9f, 0xef, 0x6e, 0x6f, 0x75, 0x2c, 0xd2, 0x84, 0x9a, 0x8a, 0xee, 0x2e, 0xb1, 0xd4, - 0xc6, 0xe6, 0xe6, 0xf6, 0xfe, 0xf3, 0xed, 0xad, 0x4e, 0xf9, 0x93, 0x4a, 0xad, 0xd4, 0x29, 0xa3, - 0x02, 0xa9, 0x75, 0xf3, 0x02, 0x3b, 0xda, 0x4d, 0x00, 0x3c, 0xd8, 0xa4, 0xd1, 0x40, 0x15, 0x47, - 0x43, 0x98, 0xa0, 0x56, 0xf6, 0x87, 0x32, 0xbf, 0x80, 0x2d, 0xd3, 0x38, 0x79, 0x78, 0xd3, 0x59, - 0x77, 0x6c, 0x55, 0x1d, 0x13, 0x64, 0x8c, 0x2d, 0x00, 0x0c, 0x39, 0xe6, 0xe2, 0x40, 0x87, 0x18, - 0xa3, 0x44, 0x34, 0x0e, 0x87, 0xa7, 0x94, 0x67, 0xe1, 0xea, 0xa1, 0x81, 0xb1, 0xba, 0x84, 0xc4, - 0xd3, 0xae, 0x03, 0x54, 0x1d, 0x13, 0x24, 0xdf, 0x96, 0x8c, 0x52, 0x43, 0x46, 0x59, 0xc9, 0xcf, - 0xba, 0xc1, 0x24, 0x4f, 0x73, 0x86, 0xb0, 0x3a, 0x32, 0xc0, 0x37, 0xf3, 0xdf, 0x5d, 0xc2, 0x20, - 0x46, 0xd6, 0x80, 0x8c, 0xc6, 0x63, 0xb7, 0xc0, 0x42, 0x55, 0x71, 0x0a, 0x28, 0x5f, 0x81, 0x01, - 0x2d, 0x01, 0xb2, 0x31, 0x18, 0x88, 0x66, 0xea, 0xf7, 0xd1, 0x23, 0xfd, 0x01, 0x04, 0x29, 0x92, - 0x0b, 0xc4, 0x5e, 0xa9, 0x58, 0xec, 0xbd, 0x51, 0x38, 0xd8, 0x4f, 0xa0, 0xb1, 0xaf, 0x3d, 0xa9, - 0x60, 0xb3, 0x1d, 0x42, 0x3e, 0xa6, 0xc0, 0xf7, 0x0e, 0x6e, 0x38, 0x4b, 0x51, 0xad, 0x49, 0x25, - 0xbd, 0x49, 0xf6, 0x3f, 0xb4, 0xf8, 0x2d, 0x55, 0xd5, 0x05, 0x5e, 0xbf, 0x0d, 0x4d, 0xe5, 0x7b, - 0x49, 0xaf, 0xec, 0x18, 0x18, 0xcb, 0x83, 0xcd, 0x71, 0xc3, 0xa3, 0xa3, 0x98, 0xca, 0xe0, 0x7a, - 0x03, 0x93, 0xca, 0x38, 0x53, 0xef, 0x7d, 0x5e, 0x43, 0x2c, 0x82, 0xec, 0x73, 0x38, 0xe3, 0x74, - 0x61, 0xfb, 0x96, 0xd7, 0x0a, 0x54, 0x5a, 0xdd, 0x2c, 0xca, 0x8e, 0xf4, 0x5d, 0xa8, 0xa9, 0x72, - 0xcd, 0x9d, 0x56, 0xe6, 0x54, 0x74, 0xb6, 0xa3, 0xe3, 0x41, 0xdd, 0x68, 0x34, 0x5f, 0x70, 0x79, - 0x02, 0xe3, 0xa5, 0x23, 0x3f, 0xca, 0x66, 0xe7, 0x2b, 0xb0, 0x80, 0x62, 0xbf, 0x84, 0x45, 0x29, - 0x3e, 0xb4, 0x53, 0x82, 0x39, 0x91, 0xd6, 0x45, 0x52, 0xbe, 0x94, 0x97, 0xf2, 0xf6, 0xbf, 0xae, - 0xc0, 0x9c, 0x98, 0xed, 0xdc, 0xd3, 0x1c, 0x5c, 0x4f, 0x30, 0x30, 0xd2, 0x35, 0x2e, 0x60, 0x23, - 0x23, 0x88, 0xbd, 0xff, 0x4e, 0x76, 0xf7, 0x4e, 0x0d, 0xa8, 0x99, 0x1d, 0x7c, 0x19, 0x2a, 0x63, - 0x2f, 0x39, 0x41, 0xfb, 0x1a, 0xe7, 0x25, 0x4c, 0x4b, 0x13, 0x7d, 0xd5, 0x34, 0xd1, 0x17, 0x3d, - 0x48, 0xc2, 0x55, 0xd5, 0xfc, 0x83, 0x24, 0xd7, 0xa1, 0xce, 0xb5, 0x8d, 0xd4, 0x0a, 0x9f, 0x02, - 0x19, 0xed, 0xa4, 0x96, 0xd3, 0x4e, 0x2e, 0xaf, 0x37, 0x7c, 0x17, 0x66, 0xf9, 0xa5, 0x3c, 0x71, - 0x89, 0x42, 0x6e, 0x29, 0x62, 0x24, 0xe5, 0xff, 0x3c, 0x06, 0xcf, 0x11, 0x79, 0xf5, 0x6b, 0xfd, - 0x0d, 0xf3, 0x5a, 0xbf, 0xee, 0x3c, 0x68, 0x66, 0x9c, 0x07, 0x77, 0xa1, 0xa3, 0x86, 0x0f, 0x0d, - 0x6c, 0x41, 0x2c, 0xc2, 0xc7, 0x73, 0x78, 0xba, 0x2d, 0xb6, 0x8d, 0x6d, 0x91, 0x49, 0xb8, 0x8d, - 0x24, 0xa1, 0xa3, 0x71, 0x22, 0xb6, 0x45, 0xfb, 0x11, 0xb4, 0x8c, 0x46, 0xb2, 0x6d, 0x48, 0x5c, - 0xab, 0xe8, 0xcc, 0x90, 0x16, 0xd4, 0x9f, 0xec, 0xb9, 0x8f, 0x76, 0x9f, 0x3c, 0xde, 0x79, 0xde, - 0xb1, 0x58, 0xf2, 0xe0, 0xc5, 0xe6, 0xe6, 0xf6, 0xf6, 0x16, 0x6e, 0x4b, 0x00, 0xb3, 0x8f, 0x36, - 0x9e, 0xb0, 0x2d, 0xaa, 0x6c, 0xff, 0x1f, 0x0b, 0x1a, 0x5a, 0xf1, 0xe4, 0x03, 0x35, 0x32, 0xfc, - 0xe6, 0xf7, 0x8d, 0x7c, 0x13, 0xd6, 0xa4, 0xa0, 0xd6, 0x86, 0x46, 0xbd, 0xc1, 0x52, 0x9a, 0xfa, - 0x06, 0x0b, 0x9b, 0x1e, 0x8f, 0x97, 0xa0, 0xc6, 0x81, 0x9f, 0x9e, 0xb2, 0x30, 0x8f, 0xb3, 0x4a, - 0x77, 0x17, 0x96, 0x93, 0x5b, 0x0c, 0xb3, 0xb0, 0xfd, 0x21, 0x40, 0xda, 0x1a, 0xb3, 0xdb, 0x33, - 0x66, 0xb7, 0x2d, 0xad, 0xdb, 0x25, 0x7b, 0x8b, 0x0b, 0x0c, 0x31, 0x84, 0xca, 0x4b, 0xfc, 0x6d, - 0x20, 0xd2, 0x40, 0x85, 0xf1, 0x8c, 0xe3, 0x21, 0x4d, 0xe4, 0x65, 0xab, 0x05, 0x41, 0x79, 0xa2, - 0x08, 0xf2, 0xbe, 0x60, 0x5a, 0x4a, 0x2a, 0x77, 0x04, 0xc7, 0x65, 0xe5, 0x8e, 0xc8, 0xea, 0x28, - 0xba, 0xdd, 0x83, 0xee, 0x16, 0x65, 0xa5, 0x6d, 0x0c, 0x87, 0x99, 0xe6, 0xd8, 0xd7, 0xe0, 0x6a, - 0x01, 0x4d, 0x98, 0x1f, 0xbe, 0x0f, 0x57, 0x36, 0xf8, 0xbd, 0xaa, 0xaf, 0x2a, 0x84, 0xdb, 0xee, - 0xc2, 0x72, 0xb6, 0x48, 0x51, 0xd9, 0x23, 0x58, 0xd8, 0xa2, 0x87, 0x93, 0xe3, 0x5d, 0x7a, 0x9a, - 0x56, 0x44, 0xa0, 0x12, 0x9f, 0x84, 0x67, 0x62, 0x7c, 0xf0, 0x37, 0xb9, 0x01, 0x30, 0x64, 0x79, - 0xdc, 0x78, 0x4c, 0xfb, 0xf2, 0x66, 0x3d, 0x22, 0x07, 0x63, 0xda, 0xb7, 0x3f, 0x04, 0xa2, 0x97, - 0x23, 0xc6, 0x8b, 0x1d, 0x09, 0x26, 0x87, 0x6e, 0x7c, 0x1e, 0x27, 0x74, 0x24, 0x9f, 0x0c, 0xd0, - 0x21, 0xfb, 0x1d, 0x68, 0xee, 0x7b, 0xe7, 0x0e, 0xfd, 0x4c, 0xbc, 0xf9, 0xb3, 0x02, 0x73, 0x63, - 0xef, 0x9c, 0xad, 0x67, 0xe5, 0x42, 0x41, 0xb2, 0xfd, 0xc7, 0x15, 0x98, 0xe5, 0x39, 0x59, 0xa9, - 0x03, 0x1a, 0x27, 0x7e, 0x80, 0x6b, 0x4c, 0x96, 0xaa, 0x41, 0x39, 0x81, 0x59, 0x2a, 0x10, 0x98, - 0xc2, 0x94, 0x26, 0x6f, 0x28, 0x0b, 0x96, 0x35, 0x30, 0x26, 0xb6, 0xd2, 0xab, 0x21, 0x9c, 0x53, - 0x53, 0x20, 0xe3, 0xa3, 0x4c, 0x0f, 0x1e, 0xbc, 0x7d, 0x72, 0x2f, 0x10, 0x32, 0x51, 0x87, 0x0a, - 0x8f, 0x37, 0x73, 0x32, 0xf2, 0x3d, 0x73, 0xbc, 0xc9, 0x1d, 0x63, 0x6a, 0x97, 0x38, 0xc6, 0x70, - 0xfb, 0xda, 0x9b, 0x8e, 0x31, 0x70, 0x99, 0x63, 0xcc, 0x65, 0x7c, 0x83, 0x3d, 0xa8, 0xe1, 0x9e, - 0xae, 0x89, 0x48, 0x99, 0x26, 0xbf, 0xa1, 0xe9, 0xf8, 0xdc, 0xcd, 0x7f, 0x2d, 0x5d, 0x2f, 0x0e, - 0xfd, 0xec, 0xeb, 0x51, 0xf1, 0x7f, 0x0c, 0x73, 0x02, 0x65, 0x9c, 0x1d, 0x78, 0x23, 0xf9, 0x32, - 0x04, 0xfe, 0x66, 0x43, 0x87, 0x17, 0xd4, 0x3f, 0x9b, 0xf8, 0x11, 0x1d, 0xc8, 0xdb, 0x93, 0x1a, - 0x84, 0x51, 0xd1, 0xb1, 0xfb, 0x2a, 0x08, 0xcf, 0x02, 0x71, 0x7f, 0x52, 0xa5, 0x6d, 0x02, 0x1d, - 0x7c, 0x21, 0x66, 0x1c, 0x46, 0xf2, 0xb1, 0x0f, 0xfb, 0xef, 0x5a, 0xd0, 0x11, 0x0b, 0x4d, 0xd1, - 0x64, 0x40, 0xc0, 0x9b, 0x2e, 0x09, 0xdf, 0x82, 0x16, 0xda, 0x32, 0xd4, 0x96, 0x23, 0x9c, 0xeb, - 0x06, 0xc8, 0xda, 0x2b, 0xc3, 0x12, 0x47, 0xfe, 0x50, 0xf0, 0xad, 0x0e, 0xc9, 0x5d, 0x2b, 0xf2, - 0xc4, 0xb5, 0x0b, 0xcb, 0x51, 0x69, 0xfb, 0x4f, 0x2c, 0x58, 0xd0, 0x1a, 0x2c, 0x16, 0xea, 0xc7, - 0xd0, 0x54, 0x0f, 0x31, 0x51, 0xa5, 0x54, 0xad, 0x98, 0x92, 0x25, 0xfd, 0xcc, 0xc8, 0x8c, 0xfc, - 0xee, 0x9d, 0x63, 0x03, 0xe3, 0xc9, 0x48, 0x68, 0x33, 0x3a, 0xc4, 0xf8, 0xe8, 0x8c, 0xd2, 0x57, - 0x2a, 0x0b, 0xd7, 0xa7, 0x0c, 0x0c, 0x7d, 0x40, 0x61, 0x90, 0x9c, 0xa8, 0x4c, 0x15, 0xe1, 0x03, - 0xd2, 0x41, 0xfb, 0x4f, 0x4b, 0xb0, 0xc8, 0x8d, 0x6a, 0xc2, 0x98, 0xa9, 0xde, 0xc2, 0x98, 0xe5, - 0xf6, 0x45, 0x2e, 0xb4, 0x76, 0x66, 0x1c, 0x91, 0x26, 0x1f, 0x5c, 0xd2, 0x10, 0xa8, 0xee, 0x77, - 0x4c, 0x99, 0x8b, 0x72, 0xd1, 0x5c, 0xbc, 0x61, 0xa4, 0x8b, 0xdc, 0x71, 0xd5, 0x62, 0x77, 0xdc, - 0xe5, 0xdc, 0x5f, 0xb9, 0x4b, 0x10, 0x73, 0x22, 0x97, 0x71, 0x09, 0x62, 0x1d, 0x56, 0x0c, 0x00, - 0xe5, 0xb5, 0x7f, 0xe4, 0x53, 0x79, 0x23, 0x75, 0x21, 0xa6, 0x89, 0x6b, 0x64, 0x79, 0x38, 0x07, - 0xd5, 0xb8, 0x1f, 0x8e, 0xa9, 0xbd, 0x0c, 0x4b, 0xe6, 0xe0, 0x8a, 0x5d, 0xe2, 0x17, 0x16, 0x74, - 0x1f, 0xf1, 0xa0, 0x0a, 0x3f, 0x38, 0xde, 0xf1, 0xe3, 0x24, 0x8c, 0xd4, 0x93, 0x45, 0x37, 0x01, - 0xe2, 0xc4, 0x8b, 0xc4, 0x39, 0x93, 0x2b, 0xbb, 0x1a, 0xc2, 0xc6, 0x88, 0x06, 0x03, 0x4e, 0xe5, - 0xbc, 0xa1, 0xd2, 0xb9, 0xc3, 0x84, 0x30, 0x39, 0x1a, 0x2a, 0xf9, 0x6d, 0x7e, 0x37, 0x8b, 0x0d, - 0x06, 0x3d, 0xc5, 0xad, 0x97, 0xdb, 0xf1, 0x32, 0xa8, 0xfd, 0x87, 0x25, 0x98, 0x4f, 0x1b, 0xc9, - 0xef, 0x7a, 0x1a, 0x02, 0x5c, 0xe8, 0xe1, 0xa9, 0x00, 0x17, 0xee, 0x41, 0xd7, 0x67, 0x8a, 0xb9, - 0x66, 0x75, 0xd4, 0x50, 0x72, 0x0b, 0x1a, 0x32, 0x15, 0x4e, 0x12, 0xed, 0xed, 0x10, 0x1d, 0xe6, - 0x77, 0x23, 0xd8, 0xd1, 0x40, 0x1c, 0x73, 0x44, 0x0a, 0x6f, 0x28, 0x8f, 0x12, 0xfc, 0x92, 0xcf, - 0xa9, 0x4c, 0x32, 0x81, 0xc6, 0x74, 0x6a, 0x3e, 0x87, 0xa8, 0x4f, 0xeb, 0xba, 0x66, 0x4d, 0xbd, - 0xb9, 0xa6, 0xd6, 0x3c, 0x2f, 0x31, 0xbd, 0xfe, 0x52, 0x71, 0x74, 0x48, 0x5a, 0x7d, 0xc2, 0x89, - 0x71, 0xfc, 0x35, 0x30, 0xfb, 0xf7, 0x2d, 0xb8, 0x5a, 0x30, 0x8d, 0x42, 0x06, 0x6c, 0xc1, 0xc2, - 0x91, 0x22, 0xca, 0xa1, 0xe6, 0x82, 0x60, 0x59, 0x0a, 0x57, 0x73, 0x78, 0x9d, 0xfc, 0x07, 0xea, - 0xb8, 0xc5, 0x27, 0xcf, 0xb8, 0xed, 0x94, 0x27, 0xd8, 0xfb, 0xd0, 0xdb, 0x7e, 0xcd, 0x44, 0xca, - 0xa6, 0xfe, 0x80, 0xae, 0xe4, 0xac, 0xf5, 0x9c, 0xc8, 0xbc, 0xd8, 0xd8, 0x7c, 0x04, 0x2d, 0xa3, - 0x2c, 0xf2, 0x9d, 0xcb, 0x16, 0xa2, 0xaf, 0xfe, 0x55, 0x31, 0xeb, 0xfc, 0x05, 0x60, 0x79, 0xe7, - 0x4a, 0x83, 0xec, 0x53, 0x98, 0x7f, 0x3a, 0x19, 0x26, 0x7e, 0xfa, 0x1a, 0x30, 0xf9, 0x40, 0x7c, - 0x84, 0x45, 0xc8, 0xa1, 0x2b, 0xac, 0x4a, 0xcf, 0xc7, 0x46, 0x6c, 0xc4, 0x4a, 0x72, 0xf3, 0x35, - 0xe6, 0x09, 0xf6, 0x55, 0x58, 0x49, 0xab, 0xe4, 0x63, 0x27, 0xb7, 0x9d, 0x3f, 0xb2, 0x78, 0x48, - 0xb0, 0xf9, 0x38, 0x31, 0x79, 0x0c, 0x8b, 0xb1, 0x1f, 0x1c, 0x0f, 0xa9, 0x5e, 0x4e, 0x2c, 0x46, - 0xe2, 0x8a, 0xd9, 0x3c, 0xf1, 0x80, 0xb1, 0x53, 0xf4, 0x05, 0x63, 0x90, 0xe2, 0x86, 0xa6, 0x0c, - 0x92, 0x19, 0x92, 0xa2, 0x0e, 0x7c, 0x02, 0x6d, 0xb3, 0x32, 0xf2, 0x40, 0x5c, 0x82, 0x4a, 0x5b, - 0xa6, 0x7b, 0x87, 0x4d, 0xce, 0x30, 0x72, 0xda, 0x3f, 0xb7, 0xa0, 0xeb, 0x50, 0xc6, 0xc6, 0x54, - 0xab, 0x54, 0x70, 0xcf, 0xc7, 0xb9, 0x62, 0xa7, 0x77, 0x58, 0x5d, 0xae, 0x92, 0x7d, 0x5d, 0x9b, - 0x3a, 0x29, 0x3b, 0x33, 0x05, 0xbd, 0x7a, 0x58, 0x83, 0x59, 0xd1, 0xbf, 0x15, 0xb8, 0x22, 0x9a, - 0x24, 0x9b, 0x93, 0xba, 0x15, 0x8d, 0x4a, 0x0d, 0xb7, 0x62, 0x0f, 0xba, 0xfc, 0x65, 0x2a, 0xbd, - 0x1f, 0xe2, 0xc3, 0x2d, 0x20, 0x4f, 0xbd, 0xbe, 0x17, 0x85, 0x61, 0xb0, 0x4f, 0x23, 0x11, 0xc3, - 0x89, 0xda, 0x27, 0x7a, 0xdd, 0xa4, 0xa2, 0xcc, 0x53, 0xf2, 0x31, 0xa5, 0x30, 0x90, 0x8f, 0x56, - 0xf1, 0x94, 0xed, 0xc0, 0xe2, 0x43, 0xef, 0x15, 0x95, 0x25, 0xa5, 0xa3, 0xd4, 0x18, 0xab, 0x42, - 0xe5, 0xd8, 0xcb, 0x5b, 0x90, 0xf9, 0x6a, 0x1d, 0x3d, 0xb7, 0xbd, 0x0e, 0x4b, 0x66, 0x99, 0x42, - 0x94, 0xf4, 0xa0, 0x36, 0x12, 0x98, 0x68, 0x9d, 0x4a, 0xdf, 0xfd, 0x02, 0x1a, 0xda, 0x6b, 0x63, - 0x64, 0x05, 0x16, 0x5f, 0x3e, 0x79, 0xbe, 0xb7, 0x7d, 0x70, 0xe0, 0xee, 0xbf, 0x78, 0xf8, 0xe9, - 0xf6, 0x0f, 0xdd, 0x9d, 0x8d, 0x83, 0x9d, 0xce, 0x0c, 0x59, 0x06, 0xb2, 0xb7, 0x7d, 0xf0, 0x7c, - 0x7b, 0xcb, 0xc0, 0x2d, 0x72, 0x13, 0x7a, 0x2f, 0xf6, 0x5e, 0x1c, 0x6c, 0x6f, 0xb9, 0x45, 0xdf, - 0x95, 0xc8, 0x0d, 0xb8, 0x2a, 0xe8, 0x05, 0x9f, 0x97, 0xef, 0x7e, 0x0c, 0x9d, 0xac, 0x59, 0xd2, - 0x30, 0xe7, 0xbe, 0xc9, 0xee, 0xbb, 0xfe, 0xf3, 0x32, 0xb4, 0x79, 0x90, 0x36, 0x7f, 0xde, 0x9b, - 0x46, 0xe4, 0x29, 0xcc, 0x89, 0x77, 0xe2, 0xc9, 0x15, 0x75, 0xad, 0x5a, 0x7f, 0x99, 0xbe, 0xb7, - 0x9c, 0x85, 0xc5, 0xb4, 0x2e, 0xfe, 0x95, 0xff, 0xf4, 0x3f, 0xfe, 0xa0, 0xd4, 0x22, 0x8d, 0x7b, - 0xa7, 0xef, 0xdf, 0x3b, 0xa6, 0x41, 0xcc, 0xca, 0xf8, 0x5d, 0x80, 0xf4, 0xf5, 0x73, 0xd2, 0x55, - 0x56, 0xad, 0xcc, 0xd3, 0xf0, 0xbd, 0xab, 0x05, 0x14, 0x51, 0xee, 0x55, 0x2c, 0x77, 0xd1, 0x6e, - 0xb3, 0x72, 0xfd, 0xc0, 0x4f, 0xf8, 0x4b, 0xe8, 0x1f, 0x59, 0x77, 0xc9, 0x00, 0x9a, 0xfa, 0xbb, - 0xe4, 0x44, 0x7a, 0x89, 0x0b, 0x5e, 0x56, 0xef, 0x5d, 0x2b, 0xa4, 0x49, 0x5e, 0xc6, 0x3a, 0xae, - 0xd8, 0x1d, 0x56, 0xc7, 0x04, 0x73, 0xa4, 0xb5, 0x0c, 0xf9, 0x0a, 0x4f, 0x9f, 0x1f, 0x27, 0xd7, - 0xb5, 0x45, 0x97, 0x7b, 0xfc, 0xbc, 0x77, 0x63, 0x0a, 0x55, 0xd4, 0x75, 0x03, 0xeb, 0x5a, 0xb1, - 0x09, 0xab, 0xab, 0x8f, 0x79, 0xe4, 0xe3, 0xe7, 0x1f, 0x59, 0x77, 0xd7, 0xff, 0xe0, 0x0e, 0xd4, - 0x55, 0x04, 0x09, 0xf9, 0x29, 0xb4, 0x8c, 0x28, 0x7a, 0x22, 0xbb, 0x51, 0x14, 0x74, 0xdf, 0xbb, - 0x5e, 0x4c, 0x14, 0x15, 0xdf, 0xc4, 0x8a, 0xbb, 0x64, 0x99, 0x55, 0x2c, 0xc2, 0xd0, 0xef, 0xe1, - 0x7d, 0x10, 0x7e, 0x49, 0xfd, 0x95, 0x26, 0xc9, 0x78, 0x65, 0xd7, 0xb3, 0xc2, 0xc5, 0xa8, 0xed, - 0xc6, 0x14, 0xaa, 0xa8, 0xee, 0x3a, 0x56, 0xb7, 0x4c, 0x96, 0xf4, 0xea, 0x54, 0x54, 0x07, 0xc5, - 0x87, 0x22, 0xf4, 0x97, 0xb9, 0xc9, 0x8d, 0xf4, 0x1a, 0x7f, 0xc1, 0x8b, 0xdd, 0x8a, 0x45, 0xf2, - 0xcf, 0x76, 0xdb, 0x5d, 0xac, 0x8a, 0x10, 0x9c, 0x3e, 0xfd, 0x61, 0x6e, 0x72, 0x08, 0x0d, 0xed, - 0xe1, 0x4b, 0x72, 0x75, 0xea, 0x23, 0x9d, 0xbd, 0x5e, 0x11, 0xa9, 0xa8, 0x2b, 0x7a, 0xf9, 0xf7, - 0x98, 0xa2, 0xf3, 0x63, 0xa8, 0xab, 0xa7, 0x14, 0xc9, 0x8a, 0xf6, 0xb4, 0xa5, 0xfe, 0xf4, 0x63, - 0xaf, 0x9b, 0x27, 0x14, 0x31, 0x9f, 0x5e, 0x3a, 0x63, 0xbe, 0x97, 0xd0, 0xd0, 0x9e, 0x4b, 0x54, - 0x1d, 0xc8, 0x3f, 0xc9, 0xa8, 0x3a, 0x50, 0xf0, 0xba, 0xa2, 0xbd, 0x80, 0x55, 0x34, 0x48, 0x1d, - 0xf9, 0x3b, 0x79, 0x1d, 0xc6, 0x64, 0x17, 0xae, 0x08, 0x89, 0x7d, 0x48, 0xbf, 0xcc, 0x34, 0x14, - 0x3c, 0x86, 0x7e, 0xdf, 0x22, 0x1f, 0x43, 0x4d, 0xbe, 0x8a, 0x49, 0x96, 0x8b, 0x5f, 0xf7, 0xec, - 0xad, 0xe4, 0x70, 0x21, 0x5e, 0x7f, 0x08, 0x90, 0xbe, 0xcd, 0xa8, 0x84, 0x44, 0xee, 0xad, 0x47, - 0xc5, 0x01, 0xf9, 0x87, 0x1c, 0xed, 0x65, 0xec, 0x60, 0x87, 0xa0, 0x90, 0x08, 0xe8, 0x99, 0x7c, - 0x38, 0xe7, 0x27, 0xd0, 0xd0, 0x9e, 0x67, 0x54, 0xc3, 0x97, 0x7f, 0xda, 0x51, 0x0d, 0x5f, 0xc1, - 0x6b, 0x8e, 0x76, 0x0f, 0x4b, 0x5f, 0xb2, 0xe7, 0x59, 0xe9, 0xb1, 0x7f, 0x1c, 0x8c, 0x78, 0x06, - 0x36, 0x41, 0x27, 0xd0, 0x32, 0xde, 0x60, 0x54, 0x2b, 0xb4, 0xe8, 0x85, 0x47, 0xb5, 0x42, 0x0b, - 0x9f, 0x6d, 0x94, 0x7c, 0x66, 0x2f, 0xb0, 0x7a, 0x4e, 0x31, 0x8b, 0x56, 0xd3, 0x8f, 0xa0, 0xa1, - 0xbd, 0xa7, 0xa8, 0xfa, 0x92, 0x7f, 0xba, 0x51, 0xf5, 0xa5, 0xe8, 0xf9, 0xc5, 0x25, 0xac, 0xa3, - 0x6d, 0x23, 0x2b, 0xe0, 0xeb, 0x26, 0xac, 0xec, 0x9f, 0x42, 0xdb, 0x7c, 0x61, 0x51, 0xad, 0xfd, - 0xc2, 0xb7, 0x1a, 0xd5, 0xda, 0x9f, 0xf2, 0x2c, 0xa3, 0x60, 0xe9, 0xbb, 0x8b, 0xaa, 0x92, 0x7b, - 0x9f, 0x8b, 0x80, 0xd8, 0x2f, 0xc8, 0xf7, 0x99, 0x80, 0x13, 0xef, 0xe1, 0x90, 0x15, 0x8d, 0x6b, - 0xf5, 0x57, 0x73, 0xd4, 0x7a, 0xc9, 0x3d, 0x9d, 0x63, 0x32, 0x33, 0x7f, 0x9f, 0xe5, 0x31, 0x2c, - 0x2a, 0x66, 0x56, 0xef, 0xdb, 0xc4, 0xaa, 0x0f, 0x85, 0xcf, 0xe8, 0xf4, 0x3a, 0x59, 0xea, 0x7d, - 0x8b, 0x6f, 0x7f, 0xf8, 0x8a, 0x88, 0xb6, 0xfd, 0xe9, 0x4f, 0xdc, 0x68, 0xdb, 0x9f, 0xf1, 0xd8, - 0x48, 0x76, 0xfb, 0x4b, 0x7c, 0x56, 0x46, 0x00, 0xf3, 0x99, 0x2b, 0x83, 0x6a, 0x79, 0x15, 0xdf, - 0xea, 0xee, 0xdd, 0x7c, 0xf3, 0x4d, 0x43, 0x53, 0x14, 0x49, 0x69, 0x7a, 0x4f, 0xde, 0xa1, 0xff, - 0x3d, 0x68, 0xea, 0x0f, 0xc3, 0x11, 0x5d, 0x26, 0x64, 0x6b, 0xba, 0x56, 0x48, 0x33, 0xb9, 0x84, - 0x34, 0xf5, 0x6a, 0xc8, 0x0f, 0x60, 0x59, 0x0d, 0xb3, 0x7e, 0x0b, 0x2d, 0x26, 0x6f, 0x15, 0xdc, - 0x4d, 0x33, 0x06, 0xfb, 0xea, 0xd4, 0xcb, 0x6b, 0xf7, 0x2d, 0xc6, 0x7d, 0xe6, 0x6b, 0x5b, 0xe9, - 0xce, 0x53, 0xf4, 0xc8, 0x58, 0xba, 0xf3, 0x14, 0x3e, 0xd1, 0x25, 0xb9, 0x8f, 0x2c, 0x1a, 0x63, - 0xc4, 0xe3, 0x7e, 0xc8, 0x8f, 0x60, 0x5e, 0xbb, 0xe7, 0x7b, 0x70, 0x1e, 0xf4, 0xd5, 0x4a, 0xca, - 0x3f, 0x56, 0xd1, 0x2b, 0x3a, 0xee, 0xd8, 0x2b, 0x58, 0xfe, 0x82, 0x6d, 0x0c, 0x0e, 0x5b, 0x45, - 0x9b, 0xd0, 0xd0, 0xef, 0x10, 0xbf, 0xa1, 0xdc, 0x15, 0x8d, 0xa4, 0xbf, 0xa0, 0x70, 0xdf, 0x22, - 0xfb, 0x3c, 0xfe, 0x53, 0xbd, 0x0f, 0x1e, 0x46, 0xd9, 0x7d, 0xd8, 0x7c, 0x37, 0x5c, 0x4d, 0x64, - 0xd1, 0x8b, 0xf1, 0x77, 0xac, 0xfb, 0x16, 0xf9, 0x7b, 0x16, 0x34, 0x8d, 0x3b, 0xbe, 0x46, 0x34, - 0x5d, 0xa6, 0x65, 0x5d, 0x9d, 0xa6, 0x37, 0xcd, 0x76, 0xb0, 0xdb, 0xbb, 0x77, 0x3f, 0x31, 0x86, - 0xf5, 0x73, 0xc3, 0xe6, 0xb7, 0x96, 0x7d, 0x24, 0xfc, 0x8b, 0x6c, 0x06, 0xfd, 0x89, 0x90, 0x2f, - 0xee, 0x5b, 0xe4, 0x1f, 0x5b, 0xd0, 0x36, 0x8d, 0xf9, 0xaa, 0xbb, 0x85, 0x6e, 0x03, 0x35, 0xf9, - 0x53, 0x3c, 0x00, 0x3f, 0xc2, 0x56, 0x3e, 0xbf, 0xeb, 0x18, 0xad, 0x14, 0x2f, 0xbb, 0xfd, 0x7a, - 0xad, 0x25, 0x1f, 0xf1, 0xbf, 0xbd, 0x21, 0xfd, 0x98, 0x24, 0xff, 0xb7, 0x1a, 0x14, 0xc3, 0xe8, - 0x7f, 0x11, 0x01, 0x27, 0xe1, 0x27, 0xfc, 0x71, 0x6c, 0xe9, 0x0c, 0x63, 0x7c, 0x77, 0xd9, 0xef, - 0xed, 0x5b, 0xd8, 0xa7, 0x9b, 0xf6, 0x55, 0xa3, 0x4f, 0x59, 0x55, 0x61, 0x83, 0xb7, 0x4e, 0xfc, - 0x31, 0x83, 0x74, 0xaf, 0xcb, 0xfd, 0x81, 0x83, 0xe9, 0x8d, 0x1c, 0xf1, 0x46, 0x8a, 0xec, 0xc6, - 0xe2, 0xb8, 0x64, 0x31, 0xf6, 0x5d, 0x6c, 0xeb, 0x2d, 0xfb, 0xad, 0xa9, 0x6d, 0xbd, 0x87, 0x26, - 0x79, 0xd6, 0xe2, 0x7d, 0x80, 0x34, 0xee, 0x80, 0x64, 0x7c, 0xde, 0x4a, 0x64, 0xe4, 0x43, 0x13, - 0xcc, 0x15, 0x28, 0x5d, 0xe3, 0xac, 0xc4, 0x1f, 0x73, 0x01, 0xf8, 0x44, 0x7a, 0xcb, 0x75, 0x7d, - 0xc9, 0x0c, 0x0e, 0x30, 0xf4, 0xa5, 0x6c, 0xf9, 0x86, 0xf8, 0x53, 0xae, 0xf7, 0x17, 0xd0, 0xda, - 0x0d, 0xc3, 0x57, 0x93, 0xb1, 0x0a, 0x74, 0x33, 0xbd, 0x65, 0x3b, 0x5e, 0x7c, 0xd2, 0xcb, 0xf4, - 0xc2, 0x5e, 0xc5, 0xa2, 0x7a, 0xa4, 0xab, 0x15, 0x75, 0xef, 0xf3, 0x34, 0xa6, 0xe1, 0x0b, 0xe2, - 0xc1, 0x82, 0x92, 0xaa, 0xaa, 0xe1, 0x3d, 0xb3, 0x18, 0x43, 0x96, 0x66, 0xab, 0x30, 0x14, 0x7b, - 0xd9, 0xda, 0x7b, 0xb1, 0x2c, 0x13, 0x65, 0x4a, 0x73, 0x8b, 0xf6, 0xf1, 0xfa, 0x1f, 0xba, 0x9c, - 0x16, 0x0d, 0xb7, 0x05, 0xf7, 0x55, 0xf5, 0x5a, 0x06, 0x68, 0xee, 0x34, 0x63, 0xef, 0x3c, 0xa2, - 0x9f, 0xdd, 0xfb, 0x5c, 0x38, 0xb3, 0xbe, 0x90, 0x3b, 0x8d, 0xf4, 0xf6, 0x19, 0x3b, 0x4d, 0xc6, - 0x3d, 0x68, 0xec, 0x34, 0x39, 0xf7, 0xa0, 0x31, 0xd4, 0xd2, 0xdb, 0x48, 0x86, 0xb0, 0x90, 0xf3, - 0x28, 0xaa, 0x4d, 0x66, 0x9a, 0x1f, 0xb2, 0xb7, 0x3a, 0x3d, 0x83, 0x59, 0xdb, 0x5d, 0xb3, 0xb6, - 0x03, 0x68, 0x6d, 0x51, 0x3e, 0x58, 0x3c, 0xb2, 0x3f, 0x73, 0x51, 0x5c, 0xbf, 0x37, 0x90, 0xdd, - 0x12, 0x90, 0x66, 0xea, 0x24, 0xfc, 0x9d, 0xb2, 0x1f, 0x43, 0xe3, 0x31, 0x4d, 0x64, 0x28, 0xbf, - 0xd2, 0x8a, 0x33, 0xb1, 0xfd, 0xbd, 0x82, 0x9b, 0x00, 0x26, 0xcf, 0x60, 0x69, 0xf7, 0xe8, 0xe0, - 0x98, 0x72, 0xe1, 0xe4, 0xfa, 0x83, 0x2f, 0xc8, 0x5f, 0xc4, 0xc2, 0xd5, 0xc5, 0xaa, 0x65, 0x2d, - 0x2e, 0x5b, 0x2f, 0x7c, 0x3e, 0x83, 0x17, 0x95, 0x1c, 0x84, 0x03, 0xaa, 0x69, 0x67, 0x01, 0x34, - 0xb4, 0x8b, 0x99, 0x6a, 0x01, 0xe5, 0xef, 0xb1, 0xaa, 0x05, 0x54, 0x70, 0x8f, 0xd3, 0xbe, 0x83, - 0xf5, 0xd8, 0x64, 0x35, 0xad, 0x87, 0xdf, 0xdd, 0x4c, 0x6b, 0xba, 0xf7, 0xb9, 0x37, 0x4a, 0xbe, - 0x20, 0x2f, 0xf1, 0x11, 0x41, 0xfd, 0xaa, 0x42, 0xaa, 0xe6, 0x67, 0x6f, 0x35, 0xa8, 0xc1, 0xd2, - 0x48, 0xa6, 0xea, 0xcf, 0xab, 0x42, 0xdd, 0xeb, 0x03, 0x80, 0x83, 0x24, 0x1c, 0x6f, 0x79, 0x74, - 0x14, 0x06, 0xa9, 0xac, 0x4d, 0x03, 0xe5, 0x53, 0xf9, 0xa5, 0x45, 0xcb, 0x93, 0x97, 0xda, 0xb9, - 0xc8, 0xb8, 0xed, 0x21, 0x99, 0x6b, 0x6a, 0x2c, 0xbd, 0x1a, 0x90, 0x82, 0x78, 0xfa, 0xfb, 0x16, - 0xd9, 0x00, 0x48, 0x5d, 0xca, 0xea, 0x94, 0x93, 0xf3, 0x56, 0x2b, 0xb1, 0x57, 0xe0, 0x7f, 0xde, - 0x87, 0x7a, 0xea, 0x80, 0x5b, 0x49, 0xaf, 0x69, 0x1b, 0xee, 0x3a, 0xb5, 0x83, 0xe7, 0xdc, 0x62, - 0x76, 0x07, 0x87, 0x0a, 0x48, 0x8d, 0x0d, 0x15, 0xfa, 0xba, 0x7c, 0x58, 0xe4, 0x0d, 0x54, 0x0a, - 0x0e, 0x06, 0x78, 0xab, 0xb7, 0x22, 0xf3, 0xae, 0x29, 0xb5, 0x9a, 0x0b, 0x3d, 0x2b, 0x86, 0xb1, - 0x86, 0x71, 0x2b, 0x0f, 0x2e, 0x67, 0xa2, 0x79, 0x04, 0x0b, 0x39, 0x63, 0xbd, 0x5a, 0xd2, 0xd3, - 0xbc, 0x31, 0x6a, 0x49, 0x4f, 0xb5, 0xf3, 0xdb, 0x57, 0xb0, 0xca, 0x79, 0x1b, 0xf0, 0x70, 0x76, - 0xe6, 0x27, 0xfd, 0x13, 0x56, 0xdd, 0x1f, 0x59, 0xb0, 0x58, 0x60, 0x8b, 0x27, 0x6f, 0xcb, 0x73, - 0xfe, 0x54, 0x3b, 0x7d, 0xaf, 0xd0, 0x54, 0x6b, 0x1f, 0x60, 0x3d, 0x4f, 0xc9, 0xa7, 0xc6, 0xc6, - 0xc6, 0xad, 0xa4, 0x62, 0x65, 0xbe, 0x51, 0xa9, 0x28, 0xd4, 0x28, 0x3e, 0x83, 0x15, 0xde, 0x90, - 0x8d, 0xe1, 0x30, 0x63, 0x46, 0xbe, 0x99, 0xfb, 0xfb, 0x7c, 0x86, 0x79, 0xbc, 0x37, 0xfd, 0xef, - 0xf7, 0x4d, 0x51, 0x80, 0x79, 0x53, 0xc9, 0x04, 0x3a, 0x59, 0xd3, 0x2c, 0x99, 0x5e, 0x56, 0xef, - 0x2d, 0xe3, 0xc4, 0x5a, 0x60, 0xce, 0xfd, 0x26, 0x56, 0xf6, 0x96, 0xdd, 0x2b, 0x1a, 0x17, 0x7e, - 0x88, 0x65, 0xf3, 0xf1, 0x97, 0x95, 0x1d, 0x39, 0xd3, 0x4f, 0x59, 0xc1, 0x34, 0xc3, 0xb7, 0x3a, - 0x33, 0x17, 0x9b, 0xa1, 0x6f, 0x63, 0xf5, 0xab, 0xf6, 0xb5, 0xa2, 0xea, 0x23, 0xfe, 0x09, 0x3f, - 0x3d, 0xaf, 0x64, 0xd7, 0xb5, 0x6c, 0xc1, 0x6a, 0xd1, 0x7c, 0x4f, 0x3d, 0xbd, 0x64, 0xc6, 0x7a, - 0x06, 0x75, 0xbb, 0xa6, 0x6e, 0x37, 0x56, 0xcb, 0xa7, 0xc0, 0x40, 0xad, 0x96, 0x4f, 0x91, 0xa1, - 0xd9, 0xd4, 0x6b, 0xa4, 0x89, 0xf9, 0x23, 0xeb, 0xee, 0xc3, 0x77, 0x7e, 0xf4, 0xcd, 0x63, 0x3f, - 0x39, 0x99, 0x1c, 0xae, 0xf5, 0xc3, 0xd1, 0xbd, 0xa1, 0xb4, 0x0f, 0x8a, 0x4b, 0x4f, 0xf7, 0x86, - 0xc1, 0xe0, 0x1e, 0x16, 0x7b, 0x38, 0x8b, 0x7f, 0x50, 0xf4, 0x3b, 0xff, 0x3f, 0x00, 0x00, 0xff, - 0xff, 0xc7, 0x34, 0x63, 0x53, 0x82, 0x74, 0x00, 0x00, + // 9477 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x4d, 0x6c, 0x24, 0xc9, + 0x95, 0x1e, 0xb3, 0x7e, 0xc8, 0xaa, 0x57, 0x3f, 0x2c, 0x06, 0xd9, 0x64, 0x75, 0xf5, 0xcf, 0x70, + 0x52, 0xad, 0x9e, 0x56, 0x6b, 0xc4, 0xee, 0xa1, 0xa4, 0xd9, 0xde, 0x19, 0xef, 0xae, 0xd8, 0x24, + 0xbb, 0x49, 0x0d, 0x9b, 0xa4, 0x92, 0x6c, 0xf5, 0x4a, 0xda, 0x45, 0x2a, 0x59, 0x15, 0x24, 0x53, + 0x5d, 0x95, 0x59, 0x93, 0x99, 0x45, 0x36, 0x25, 0x8f, 0x0f, 0x86, 0x6d, 0x18, 0xbe, 0x18, 0xf2, + 0xc2, 0x80, 0x6d, 0xd8, 0x58, 0x40, 0x6b, 0xc3, 0x30, 0x7c, 0xb0, 0x2f, 0x36, 0xd6, 0xc6, 0xfa, + 0xe4, 0xc3, 0xfa, 0x62, 0xfb, 0x60, 0x03, 0x06, 0xbc, 0x80, 0x01, 0x63, 0x7d, 0xf0, 0xc2, 0xf0, + 0xcd, 0xf6, 0xd9, 0x88, 0x17, 0x3f, 0x19, 0x91, 0x99, 0xd5, 0xdd, 0x23, 0xcd, 0xce, 0xa5, 0xbb, + 0xe2, 0x8b, 0xc8, 0xf8, 0x7d, 0xef, 0xc5, 0x8b, 0xf7, 0x5e, 0x04, 0xa1, 0x1e, 0x8d, 0xfb, 0x6b, + 0xe3, 0x28, 0x4c, 0x42, 0x52, 0x1d, 0x06, 0xd1, 0xb8, 0xdf, 0xbb, 0x79, 0x16, 0x86, 0x67, 0x43, + 0xfa, 0xc0, 0x1b, 0xfb, 0x0f, 0xbc, 0x20, 0x08, 0x13, 0x2f, 0xf1, 0xc3, 0x20, 0xe6, 0x85, 0xec, + 0x1f, 0x43, 0xfb, 0x29, 0x0d, 0x8e, 0x28, 0x1d, 0x38, 0xf4, 0xd3, 0x09, 0x8d, 0x13, 0xf2, 0x75, + 0x58, 0xf0, 0xe8, 0x4f, 0x29, 0x1d, 0xb8, 0x63, 0x2f, 0x8e, 0xc7, 0xe7, 0x91, 0x17, 0xd3, 0xae, + 0xb5, 0x6a, 0xdd, 0x6b, 0x3a, 0x1d, 0x9e, 0x71, 0xa8, 0x70, 0xf2, 0x2e, 0x34, 0x63, 0x56, 0x94, + 0x06, 0x49, 0x14, 0x8e, 0xaf, 0xba, 0x25, 0x2c, 0xd7, 0x60, 0xd8, 0x36, 0x87, 0xec, 0x21, 0xcc, + 0xab, 0x16, 0xe2, 0x71, 0x18, 0xc4, 0x94, 0x3c, 0x84, 0xa5, 0xbe, 0x3f, 0x3e, 0xa7, 0x91, 0x8b, + 0x1f, 0x8f, 0x02, 0x3a, 0x0a, 0x03, 0xbf, 0xdf, 0xb5, 0x56, 0xcb, 0xf7, 0xea, 0x0e, 0xe1, 0x79, + 0xec, 0x8b, 0x67, 0x22, 0x87, 0xbc, 0x07, 0xf3, 0x34, 0xe0, 0x38, 0x1d, 0xe0, 0x57, 0xa2, 0xa9, + 0x76, 0x0a, 0xb3, 0x0f, 0xec, 0xbf, 0x5e, 0x82, 0x85, 0xdd, 0xc0, 0x4f, 0x5e, 0x78, 0xc3, 0x21, + 0x4d, 0xe4, 0x98, 0xde, 0x83, 0xf9, 0x4b, 0x04, 0x70, 0x4c, 0x97, 0x61, 0x34, 0x10, 0x23, 0x6a, + 0x73, 0xf8, 0x50, 0xa0, 0x53, 0x7b, 0x56, 0x9a, 0xda, 0xb3, 0xc2, 0xe9, 0x2a, 0x4f, 0x99, 0xae, + 0xf7, 0x60, 0x3e, 0xa2, 0xfd, 0xf0, 0x82, 0x46, 0x57, 0xee, 0xa5, 0x1f, 0x0c, 0xc2, 0xcb, 0x6e, + 0x65, 0xd5, 0xba, 0x57, 0x75, 0xda, 0x12, 0x7e, 0x81, 0x28, 0x79, 0x0c, 0xf3, 0xfd, 0x73, 0x2f, + 0x08, 0xe8, 0xd0, 0x3d, 0xf1, 0xfa, 0x2f, 0x27, 0xe3, 0xb8, 0x5b, 0x5d, 0xb5, 0xee, 0x35, 0xd6, + 0xaf, 0xaf, 0xe1, 0xaa, 0xae, 0x6d, 0x9e, 0x7b, 0xc1, 0x63, 0xcc, 0x39, 0x0a, 0xbc, 0x71, 0x7c, + 0x1e, 0x26, 0x4e, 0x5b, 0x7c, 0xc1, 0xe1, 0xd8, 0x5e, 0x02, 0xa2, 0xcf, 0x04, 0x9f, 0x7b, 0xfb, + 0x9f, 0x5a, 0xb0, 0xf8, 0x3c, 0x18, 0x86, 0xfd, 0x97, 0xbf, 0xe4, 0x14, 0x15, 0x8c, 0xa1, 0xf4, + 0xb6, 0x63, 0x28, 0x7f, 0xde, 0x31, 0x2c, 0xc3, 0x92, 0xd9, 0x59, 0x31, 0x0a, 0x0a, 0xd7, 0xd8, + 0xd7, 0x67, 0x54, 0x76, 0x4b, 0x0e, 0xe3, 0x6b, 0xd0, 0xe9, 0x4f, 0xa2, 0x88, 0x06, 0xb9, 0x71, + 0xcc, 0x0b, 0x5c, 0x0d, 0xe4, 0x5d, 0x68, 0x06, 0xf4, 0x32, 0x2d, 0x26, 0x68, 0x37, 0xa0, 0x97, + 0xb2, 0x88, 0xdd, 0x85, 0xe5, 0x6c, 0x33, 0xa2, 0x03, 0xff, 0xdd, 0x82, 0xca, 0xf3, 0xe4, 0x55, + 0x48, 0xd6, 0xa0, 0x92, 0x5c, 0x8d, 0x39, 0x87, 0xb4, 0xd7, 0x89, 0x18, 0xda, 0xc6, 0x60, 0x10, + 0xd1, 0x38, 0x3e, 0xbe, 0x1a, 0x53, 0xa7, 0xe9, 0xf1, 0x84, 0xcb, 0xca, 0x91, 0x2e, 0xcc, 0x89, + 0x34, 0x36, 0x58, 0x77, 0x64, 0x92, 0xdc, 0x06, 0xf0, 0x46, 0xe1, 0x24, 0x48, 0xdc, 0xd8, 0x4b, + 0x70, 0xaa, 0xca, 0x8e, 0x86, 0x90, 0x9b, 0x50, 0x1f, 0xbf, 0x74, 0xe3, 0x7e, 0xe4, 0x8f, 0x13, + 0x24, 0x9b, 0xba, 0x93, 0x02, 0xe4, 0xeb, 0x50, 0x0b, 0x27, 0xc9, 0x38, 0xf4, 0x83, 0x44, 0x90, + 0xca, 0xbc, 0xe8, 0xcb, 0xc1, 0x24, 0x39, 0x64, 0xb0, 0xa3, 0x0a, 0x90, 0x3b, 0xd0, 0xea, 0x87, + 0xc1, 0xa9, 0x1f, 0x8d, 0xb8, 0x30, 0xe8, 0xce, 0x62, 0x6b, 0x26, 0x68, 0xff, 0xab, 0x12, 0x34, + 0x8e, 0x23, 0x2f, 0x88, 0xbd, 0x3e, 0x03, 0x58, 0xd7, 0x93, 0x57, 0xee, 0xb9, 0x17, 0x9f, 0xe3, + 0x68, 0xeb, 0x8e, 0x4c, 0x92, 0x65, 0x98, 0xe5, 0x1d, 0xc5, 0x31, 0x95, 0x1d, 0x91, 0x22, 0xef, + 0xc3, 0x42, 0x30, 0x19, 0xb9, 0x66, 0x5b, 0x65, 0xa4, 0x96, 0x7c, 0x06, 0x9b, 0x80, 0x13, 0xb6, + 0xd6, 0xbc, 0x09, 0x3e, 0x42, 0x0d, 0x21, 0x36, 0x34, 0x45, 0x8a, 0xfa, 0x67, 0xe7, 0x7c, 0x98, + 0x55, 0xc7, 0xc0, 0x58, 0x1d, 0x89, 0x3f, 0xa2, 0x6e, 0x9c, 0x78, 0xa3, 0xb1, 0x18, 0x96, 0x86, + 0x60, 0x7e, 0x98, 0x78, 0x43, 0xf7, 0x94, 0xd2, 0xb8, 0x3b, 0x27, 0xf2, 0x15, 0x42, 0xee, 0x42, + 0x7b, 0x40, 0xe3, 0xc4, 0x15, 0x8b, 0x42, 0xe3, 0x6e, 0x0d, 0x59, 0x3f, 0x83, 0xb2, 0x7a, 0x22, + 0xef, 0xd2, 0x65, 0x13, 0x40, 0x5f, 0x75, 0xeb, 0xbc, 0xaf, 0x29, 0xc2, 0x28, 0xe7, 0x29, 0x4d, + 0xb4, 0xd9, 0x8b, 0x05, 0x85, 0xda, 0x7b, 0x40, 0x34, 0x78, 0x8b, 0x26, 0x9e, 0x3f, 0x8c, 0xc9, + 0x87, 0xd0, 0x4c, 0xb4, 0xc2, 0x28, 0x0a, 0x1b, 0x8a, 0x9c, 0xb4, 0x0f, 0x1c, 0xa3, 0x9c, 0x7d, + 0x0e, 0xb5, 0x27, 0x94, 0xee, 0xf9, 0x23, 0x3f, 0x21, 0xcb, 0x50, 0x3d, 0xf5, 0x5f, 0x51, 0x4e, + 0xf0, 0xe5, 0x9d, 0x19, 0x87, 0x27, 0xc9, 0x3b, 0x00, 0xf8, 0xc3, 0x1d, 0x29, 0xc2, 0xda, 0x99, + 0x71, 0xea, 0x88, 0x3d, 0x63, 0x94, 0xd5, 0x83, 0xb9, 0x31, 0x8d, 0xfa, 0x54, 0xae, 0xdf, 0xce, + 0x8c, 0x23, 0x81, 0xc7, 0x73, 0x50, 0x1d, 0xb2, 0xda, 0xed, 0x3f, 0xae, 0x42, 0xe3, 0x88, 0x06, + 0x8a, 0xd3, 0x08, 0x54, 0xd8, 0x9c, 0x08, 0xee, 0xc2, 0xdf, 0xe4, 0x2b, 0xd0, 0xc0, 0x79, 0x8a, + 0x93, 0xc8, 0x0f, 0xce, 0x38, 0x81, 0x3f, 0x2e, 0x75, 0x2d, 0x07, 0x18, 0x7c, 0x84, 0x28, 0xe9, + 0x40, 0xd9, 0x1b, 0x49, 0x02, 0x67, 0x3f, 0xc9, 0x75, 0xa8, 0x79, 0xa3, 0x84, 0x77, 0xaf, 0x89, + 0xf0, 0x9c, 0x37, 0x4a, 0xb0, 0x6b, 0xef, 0x42, 0x73, 0xec, 0x5d, 0x8d, 0x18, 0x3f, 0x2b, 0xaa, + 0x68, 0x3a, 0x0d, 0x81, 0xed, 0x30, 0xb2, 0x58, 0x87, 0x45, 0xbd, 0x88, 0x6c, 0xbc, 0xaa, 0x1a, + 0x5f, 0xd0, 0x4a, 0x8b, 0x3e, 0xbc, 0x07, 0xf3, 0xf2, 0x9b, 0x88, 0x8f, 0x07, 0x69, 0xa5, 0xee, + 0xb4, 0x05, 0x2c, 0x47, 0x79, 0x0f, 0x3a, 0xa7, 0x7e, 0xe0, 0x0d, 0xdd, 0xfe, 0x30, 0xb9, 0x70, + 0x07, 0x74, 0x98, 0x78, 0x48, 0x35, 0x55, 0xa7, 0x8d, 0xf8, 0xe6, 0x30, 0xb9, 0xd8, 0x62, 0x28, + 0x79, 0x1f, 0xea, 0xa7, 0x94, 0xba, 0x38, 0x59, 0xdd, 0x9a, 0xc1, 0x81, 0x72, 0x85, 0x9c, 0xda, + 0xa9, 0x5c, 0xab, 0xf7, 0xa1, 0x13, 0x4e, 0x92, 0xb3, 0xd0, 0x0f, 0xce, 0x5c, 0x26, 0xf3, 0x5c, + 0x7f, 0x80, 0x54, 0x54, 0x79, 0x5c, 0x7a, 0x68, 0x39, 0x6d, 0x99, 0xc7, 0xa4, 0xcf, 0xee, 0x80, + 0xdc, 0x85, 0xf9, 0xa1, 0x17, 0x27, 0xee, 0x79, 0x38, 0x76, 0xc7, 0x93, 0x93, 0x97, 0xf4, 0xaa, + 0xdb, 0xc2, 0x89, 0x68, 0x31, 0x78, 0x27, 0x1c, 0x1f, 0x22, 0x48, 0x6e, 0x01, 0x60, 0x3f, 0x79, + 0x27, 0x60, 0xd5, 0xba, 0xd7, 0x72, 0xea, 0x0c, 0xe1, 0x8d, 0xfe, 0x00, 0x16, 0x71, 0x79, 0xfa, + 0x93, 0x38, 0x09, 0x47, 0x2e, 0x93, 0xd7, 0xd1, 0x20, 0xee, 0x36, 0x90, 0xd6, 0xbe, 0x26, 0x3a, + 0xab, 0xad, 0xf1, 0xda, 0x16, 0x8d, 0x93, 0x4d, 0x2c, 0xec, 0xf0, 0xb2, 0x6c, 0x53, 0xbf, 0x72, + 0x16, 0x06, 0x59, 0x9c, 0xbc, 0x0f, 0xc4, 0x1b, 0x0e, 0xc3, 0x4b, 0x37, 0xa6, 0xc3, 0x53, 0x57, + 0x4c, 0x62, 0xb7, 0xbd, 0x6a, 0xdd, 0xab, 0x39, 0x1d, 0xcc, 0x39, 0xa2, 0xc3, 0xd3, 0x43, 0x8e, + 0x93, 0x0f, 0xa1, 0x85, 0x1d, 0x39, 0xa5, 0x5e, 0x32, 0x89, 0x68, 0xdc, 0x9d, 0x5f, 0x2d, 0xdf, + 0x6b, 0xaf, 0x2f, 0xa8, 0xf9, 0x42, 0xf8, 0xb1, 0x9f, 0x38, 0x4d, 0x56, 0x4e, 0xa4, 0xe3, 0xde, + 0x16, 0x2c, 0x17, 0x77, 0x89, 0x11, 0x15, 0x9b, 0x15, 0x46, 0x8c, 0x15, 0x87, 0xfd, 0x24, 0x4b, + 0x50, 0xbd, 0xf0, 0x86, 0x13, 0x2a, 0xe4, 0x3a, 0x4f, 0x7c, 0x54, 0x7a, 0x64, 0xd9, 0x7f, 0x68, + 0x41, 0x93, 0x8f, 0x52, 0xe8, 0x23, 0x77, 0xa0, 0x25, 0xa9, 0x81, 0x46, 0x51, 0x18, 0x09, 0xf1, + 0x66, 0x82, 0xe4, 0x3e, 0x74, 0x24, 0x30, 0x8e, 0xa8, 0x3f, 0xf2, 0xce, 0x64, 0xdd, 0x39, 0x9c, + 0xac, 0xa7, 0x35, 0x46, 0xe1, 0x24, 0xa1, 0x62, 0xe7, 0x6b, 0x8a, 0x01, 0x3a, 0x0c, 0x73, 0xcc, + 0x22, 0x4c, 0xbc, 0x15, 0x90, 0xba, 0x81, 0xd9, 0x7f, 0xdb, 0x02, 0xc2, 0xba, 0x7e, 0x1c, 0xf2, + 0x2a, 0x04, 0x95, 0x66, 0xb9, 0xc4, 0x7a, 0x6b, 0x2e, 0x29, 0xbd, 0x8e, 0x4b, 0x6c, 0xa8, 0xf2, + 0xde, 0x57, 0x0a, 0x7a, 0xcf, 0xb3, 0xbe, 0x5b, 0xa9, 0x95, 0x3b, 0x15, 0xfb, 0xbf, 0x96, 0x61, + 0x69, 0x93, 0x6f, 0xdd, 0x1b, 0xfd, 0x3e, 0x1d, 0x2b, 0xfe, 0x79, 0x07, 0x1a, 0x41, 0x38, 0xa0, + 0x92, 0x6a, 0x79, 0xc7, 0x80, 0x41, 0x1a, 0xc9, 0x9e, 0x7b, 0x7e, 0xc0, 0x3b, 0xce, 0xe7, 0xb3, + 0x8e, 0x08, 0x76, 0xfb, 0x2e, 0xcc, 0x8f, 0x69, 0x30, 0xd0, 0xd9, 0x84, 0x2b, 0x57, 0x2d, 0x01, + 0x0b, 0x0e, 0x79, 0x07, 0x1a, 0xa7, 0x13, 0x5e, 0x8e, 0x09, 0x97, 0x0a, 0xd2, 0x01, 0x08, 0x68, + 0x83, 0xcb, 0x98, 0xf1, 0x24, 0x3e, 0xc7, 0xdc, 0x2a, 0xe6, 0xce, 0xb1, 0x34, 0xcb, 0xba, 0x05, + 0x30, 0x98, 0xc4, 0x89, 0xe0, 0x9a, 0x59, 0xcc, 0xac, 0x33, 0x84, 0x73, 0xcd, 0x37, 0x60, 0x71, + 0xe4, 0xbd, 0x72, 0x91, 0x7e, 0x5c, 0x3f, 0x70, 0x4f, 0x87, 0xb8, 0xfb, 0xcc, 0x61, 0xb9, 0xce, + 0xc8, 0x7b, 0xf5, 0x7d, 0x96, 0xb3, 0x1b, 0x3c, 0x41, 0x9c, 0x89, 0x16, 0xa9, 0xf6, 0x44, 0x34, + 0xa6, 0xd1, 0x05, 0x45, 0x69, 0x50, 0x51, 0xba, 0x8d, 0xc3, 0x51, 0xd6, 0xa3, 0x11, 0x1b, 0x77, + 0x32, 0xec, 0x73, 0xd6, 0x77, 0xe6, 0x46, 0x7e, 0xb0, 0x93, 0x0c, 0xfb, 0xe4, 0x26, 0x00, 0x93, + 0x25, 0x63, 0x1a, 0xb9, 0x2f, 0x2f, 0x91, 0x8f, 0x2b, 0x28, 0x3b, 0x0e, 0x69, 0xf4, 0xc9, 0x25, + 0xb9, 0x01, 0xf5, 0x7e, 0x8c, 0xc2, 0xc8, 0xbb, 0xea, 0x36, 0x90, 0xc9, 0x6b, 0xfd, 0x98, 0x89, + 0x21, 0xef, 0x8a, 0x31, 0x22, 0xeb, 0xad, 0x87, 0xab, 0x40, 0x07, 0x58, 0x7d, 0x8c, 0x52, 0xb5, + 0x85, 0x9d, 0xdd, 0x10, 0x19, 0xac, 0x9d, 0x98, 0x7c, 0x05, 0x5a, 0xb2, 0xb3, 0xa7, 0x43, 0xef, + 0x2c, 0x46, 0xb1, 0xd2, 0x72, 0x9a, 0x02, 0x7c, 0xc2, 0x30, 0xfb, 0x05, 0x57, 0xb6, 0xb4, 0xb5, + 0x15, 0x7c, 0xc3, 0xb6, 0x7d, 0x44, 0x70, 0x5d, 0x6b, 0x8e, 0x48, 0x15, 0x2d, 0x5a, 0xa9, 0x60, + 0xd1, 0xec, 0x5f, 0x58, 0xd0, 0x14, 0x35, 0xa3, 0x86, 0x42, 0x1e, 0x02, 0x91, 0xab, 0x98, 0xbc, + 0xf2, 0x07, 0xee, 0xc9, 0x55, 0x42, 0x63, 0x4e, 0x34, 0x3b, 0x33, 0x4e, 0x41, 0x1e, 0x93, 0xa3, + 0x06, 0x1a, 0x27, 0x11, 0xa7, 0xe9, 0x9d, 0x19, 0x27, 0x97, 0xc3, 0x58, 0x8c, 0xe9, 0x40, 0x93, + 0xc4, 0xf5, 0x83, 0x01, 0x7d, 0x85, 0xa4, 0xd4, 0x72, 0x0c, 0xec, 0x71, 0x1b, 0x9a, 0xfa, 0x77, + 0xf6, 0x4f, 0xa0, 0x26, 0x35, 0x28, 0xd4, 0x1e, 0x32, 0xfd, 0x72, 0x34, 0x84, 0xf4, 0xa0, 0x66, + 0xf6, 0xc2, 0xa9, 0x7d, 0x9e, 0xb6, 0xed, 0xdf, 0x84, 0xce, 0x1e, 0x23, 0xa2, 0x80, 0x11, 0xad, + 0x50, 0x0b, 0x97, 0x61, 0x56, 0x63, 0x9e, 0xba, 0x23, 0x52, 0x6c, 0xff, 0x3d, 0x0f, 0xe3, 0x44, + 0xb4, 0x83, 0xbf, 0xed, 0x3f, 0xb6, 0x80, 0x6c, 0xc7, 0x89, 0x3f, 0xf2, 0x12, 0xfa, 0x84, 0x2a, + 0xf1, 0x70, 0x00, 0x4d, 0x56, 0xdb, 0x71, 0xb8, 0xc1, 0x95, 0x34, 0xae, 0x5c, 0x7c, 0x5d, 0xb0, + 0x73, 0xfe, 0x83, 0x35, 0xbd, 0x34, 0x17, 0xf9, 0x46, 0x05, 0x8c, 0xdb, 0x12, 0x2f, 0x3a, 0xa3, + 0x09, 0x6a, 0x70, 0x42, 0xff, 0x07, 0x0e, 0x6d, 0x86, 0xc1, 0x69, 0xef, 0xb7, 0x60, 0x21, 0x57, + 0x87, 0x2e, 0xa3, 0xeb, 0x05, 0x32, 0xba, 0xac, 0xcb, 0xe8, 0x3e, 0x2c, 0x1a, 0xfd, 0x12, 0x14, + 0xd7, 0x85, 0x39, 0xc6, 0x18, 0x4c, 0x51, 0xb0, 0xb8, 0xa2, 0x20, 0x92, 0x64, 0x1d, 0x96, 0x4e, + 0x29, 0x8d, 0xbc, 0x04, 0x93, 0xc8, 0x3a, 0x6c, 0x4d, 0x44, 0xcd, 0x85, 0x79, 0xf6, 0x9f, 0x5a, + 0x30, 0xcf, 0xa4, 0xe9, 0x33, 0x2f, 0xb8, 0x92, 0x73, 0xb5, 0x57, 0x38, 0x57, 0xf7, 0xb4, 0xcd, + 0x51, 0x2b, 0xfd, 0x79, 0x27, 0xaa, 0x9c, 0x9d, 0x28, 0xb2, 0x0a, 0x4d, 0xa3, 0xbb, 0x55, 0xae, + 0x91, 0xc6, 0x5e, 0x72, 0x48, 0xa3, 0xc7, 0x57, 0x09, 0xfd, 0xd5, 0xa7, 0xf2, 0x2e, 0x74, 0xd2, + 0x6e, 0x8b, 0x79, 0x24, 0x50, 0x61, 0x84, 0x29, 0x2a, 0xc0, 0xdf, 0xf6, 0xdf, 0xb7, 0x78, 0xc1, + 0xcd, 0xd0, 0x57, 0xda, 0x2a, 0x2b, 0xc8, 0x94, 0x5e, 0x59, 0x90, 0xfd, 0x9e, 0xaa, 0xed, 0xff, + 0xea, 0x83, 0x65, 0x32, 0x31, 0xa6, 0xc1, 0xc0, 0xf5, 0x86, 0x43, 0x14, 0xc4, 0x35, 0x67, 0x8e, + 0xa5, 0x37, 0x86, 0x43, 0xfb, 0x3d, 0x58, 0xd0, 0x7a, 0xf7, 0x9a, 0x71, 0xec, 0x03, 0xd9, 0xf3, + 0xe3, 0xe4, 0x79, 0x10, 0x8f, 0x35, 0x45, 0xee, 0x06, 0xd4, 0x99, 0xb4, 0x65, 0x3d, 0xe3, 0x9c, + 0x5b, 0x75, 0x98, 0xf8, 0x65, 0xfd, 0x8a, 0x31, 0xd3, 0x7b, 0x25, 0x32, 0x4b, 0x22, 0xd3, 0x7b, + 0x85, 0x99, 0xf6, 0x23, 0x58, 0x34, 0xea, 0x13, 0x4d, 0xbf, 0x0b, 0xd5, 0x49, 0xf2, 0x2a, 0x94, + 0xaa, 0x7a, 0x43, 0x50, 0x08, 0x3b, 0x14, 0x3a, 0x3c, 0xc7, 0xfe, 0x18, 0x16, 0xf6, 0xe9, 0xa5, + 0x60, 0x64, 0xd9, 0x91, 0xbb, 0x6f, 0x3c, 0x30, 0x62, 0xbe, 0xbd, 0x06, 0x44, 0xff, 0x38, 0x65, + 0x00, 0x79, 0x7c, 0xb4, 0x8c, 0xe3, 0xa3, 0x7d, 0x17, 0xc8, 0x91, 0x7f, 0x16, 0x3c, 0xa3, 0x71, + 0xec, 0x9d, 0x29, 0xd6, 0xef, 0x40, 0x79, 0x14, 0x9f, 0x09, 0x51, 0xc5, 0x7e, 0xda, 0xdf, 0x84, + 0x45, 0xa3, 0x9c, 0xa8, 0xf8, 0x26, 0xd4, 0x63, 0xff, 0x2c, 0x40, 0x45, 0x4b, 0x54, 0x9d, 0x02, + 0xf6, 0x13, 0x58, 0xfa, 0x3e, 0x8d, 0xfc, 0xd3, 0xab, 0x37, 0x55, 0x6f, 0xd6, 0x53, 0xca, 0xd6, + 0xb3, 0x0d, 0xd7, 0x32, 0xf5, 0x88, 0xe6, 0x39, 0xf9, 0x8a, 0x95, 0xac, 0x39, 0x3c, 0xa1, 0xc9, + 0xbe, 0x92, 0x2e, 0xfb, 0xec, 0xe7, 0x40, 0x36, 0xc3, 0x20, 0xa0, 0xfd, 0xe4, 0x90, 0xd2, 0x28, + 0xb5, 0x5c, 0xa5, 0xb4, 0xda, 0x58, 0x5f, 0x11, 0x33, 0x9b, 0x15, 0xa8, 0x82, 0x88, 0x09, 0x54, + 0xc6, 0x34, 0x1a, 0x61, 0xc5, 0x35, 0x07, 0x7f, 0xdb, 0xd7, 0x60, 0xd1, 0xa8, 0x56, 0x9c, 0xf5, + 0x3f, 0x80, 0x6b, 0x5b, 0x7e, 0xdc, 0xcf, 0x37, 0xd8, 0x85, 0xb9, 0xf1, 0xe4, 0xc4, 0x4d, 0x39, + 0x51, 0x26, 0xd9, 0xf1, 0x2f, 0xfb, 0x89, 0xa8, 0xec, 0xaf, 0x59, 0x50, 0xd9, 0x39, 0xde, 0xdb, + 0x64, 0x7b, 0x85, 0x1f, 0xf4, 0xc3, 0x11, 0xd3, 0xc2, 0xf8, 0xa0, 0x55, 0x7a, 0x2a, 0x87, 0xdd, + 0x84, 0x3a, 0x2a, 0x6f, 0xec, 0xc4, 0x2b, 0xf4, 0xa0, 0x14, 0x60, 0xa7, 0x6d, 0xfa, 0x6a, 0xec, + 0x47, 0x78, 0x9c, 0x96, 0x87, 0xe4, 0x0a, 0x6e, 0x33, 0xf9, 0x0c, 0xfb, 0xdf, 0xcd, 0xc1, 0x9c, + 0xd8, 0x7c, 0xf9, 0x46, 0x9e, 0xf8, 0x17, 0x34, 0xdd, 0xc8, 0x59, 0x8a, 0x29, 0xc6, 0x11, 0x1d, + 0x85, 0x89, 0xd2, 0xdf, 0xf8, 0x32, 0x98, 0x20, 0x5a, 0x13, 0x84, 0x12, 0xc1, 0xed, 0x0f, 0x65, + 0x5e, 0xca, 0x00, 0xc9, 0x4d, 0x98, 0x93, 0xca, 0x40, 0x45, 0x1d, 0x74, 0x24, 0xc4, 0x66, 0xa3, + 0xef, 0x8d, 0xbd, 0xbe, 0x9f, 0x5c, 0x09, 0xb1, 0xa0, 0xd2, 0xac, 0xfe, 0x61, 0xd8, 0xf7, 0x86, + 0xee, 0x89, 0x37, 0xf4, 0x82, 0x3e, 0x95, 0xd6, 0x0a, 0x03, 0x64, 0x27, 0x77, 0xd1, 0x2d, 0x59, + 0x8c, 0x9f, 0xee, 0x33, 0x28, 0xdb, 0xc3, 0xfb, 0xe1, 0x68, 0xe4, 0xb3, 0xd3, 0x07, 0x57, 0xcd, + 0xca, 0x8e, 0x86, 0x70, 0xdb, 0x08, 0xa6, 0x2e, 0xf9, 0x0c, 0xd6, 0xa5, 0x6d, 0x44, 0x03, 0x59, + 0x2d, 0x19, 0x0d, 0xad, 0xec, 0x68, 0x08, 0x5b, 0x8b, 0x49, 0x10, 0xd3, 0x24, 0x19, 0xd2, 0x81, + 0xea, 0x50, 0x03, 0x8b, 0xe5, 0x33, 0xc8, 0x43, 0x58, 0xe4, 0x36, 0x88, 0xd8, 0x4b, 0xc2, 0xf8, + 0xdc, 0x8f, 0xdd, 0x98, 0x1d, 0x9f, 0xf8, 0x59, 0xb8, 0x28, 0x8b, 0x3c, 0x82, 0x95, 0x0c, 0x1c, + 0xd1, 0x3e, 0xf5, 0x2f, 0xe8, 0x00, 0x55, 0xb8, 0xb2, 0x33, 0x2d, 0x9b, 0xac, 0x42, 0x23, 0x98, + 0x8c, 0xdc, 0xc9, 0x78, 0xe0, 0x31, 0x25, 0xa6, 0x8d, 0xca, 0xa5, 0x0e, 0x91, 0x0f, 0x40, 0xea, + 0x69, 0x42, 0x7b, 0x9c, 0x37, 0x24, 0x1c, 0xa3, 0x5e, 0xc7, 0x2c, 0xc1, 0x08, 0x33, 0x55, 0x49, + 0x3b, 0xe2, 0xdc, 0x29, 0x01, 0xe4, 0x93, 0xc8, 0xbf, 0xf0, 0x12, 0xda, 0x5d, 0xe0, 0x42, 0x5d, + 0x24, 0xd9, 0x77, 0x7e, 0xe0, 0x27, 0xbe, 0x97, 0x84, 0x51, 0x97, 0x60, 0x5e, 0x0a, 0xb0, 0x49, + 0x44, 0xfa, 0x88, 0x13, 0x2f, 0x99, 0xc4, 0x42, 0x43, 0x5d, 0x44, 0xe2, 0xca, 0x67, 0x90, 0x0f, + 0x61, 0x99, 0x53, 0x04, 0x66, 0x09, 0xdd, 0x1b, 0x55, 0x85, 0x25, 0x9c, 0x91, 0x29, 0xb9, 0x6c, + 0x2a, 0x05, 0x89, 0xe4, 0x3e, 0xbc, 0xc6, 0xa7, 0x72, 0x4a, 0x36, 0xeb, 0x1f, 0xeb, 0x81, 0xdf, + 0x77, 0x45, 0x09, 0xc6, 0x22, 0xcb, 0x38, 0x8a, 0x7c, 0x06, 0x23, 0xf1, 0xa1, 0x7f, 0x4a, 0x13, + 0x7f, 0x44, 0xbb, 0x2b, 0x9c, 0xc4, 0x65, 0x9a, 0x31, 0xe0, 0x64, 0x8c, 0x39, 0x5d, 0xce, 0xf0, + 0x3c, 0x85, 0xc4, 0x38, 0x0c, 0x63, 0x2a, 0x2d, 0x4f, 0xdd, 0xeb, 0x82, 0xb5, 0x74, 0xd0, 0xfe, + 0x7d, 0x8b, 0x6f, 0x51, 0x82, 0x9d, 0x63, 0xed, 0xf0, 0xc5, 0x19, 0xd9, 0x0d, 0x83, 0xe1, 0x95, + 0xe0, 0x6d, 0xe0, 0xd0, 0x41, 0x30, 0xbc, 0x62, 0xea, 0xbf, 0x1f, 0xe8, 0x45, 0xb8, 0x34, 0x6c, + 0x4a, 0x10, 0x0b, 0xbd, 0x03, 0x8d, 0xf1, 0xe4, 0x64, 0xe8, 0xf7, 0x79, 0x91, 0x32, 0xaf, 0x85, + 0x43, 0x58, 0x80, 0x9d, 0x3e, 0xf9, 0x7a, 0xf2, 0x12, 0x15, 0x2c, 0xd1, 0x10, 0x18, 0x2b, 0x62, + 0x3f, 0x86, 0x25, 0xb3, 0x83, 0x42, 0xec, 0xdf, 0x87, 0x9a, 0x90, 0x12, 0xd2, 0x0c, 0xd1, 0xd6, + 0x8c, 0xc3, 0xec, 0xb0, 0xa4, 0xf2, 0xed, 0x7f, 0x5d, 0x81, 0x45, 0x81, 0x6e, 0xb2, 0xe1, 0x1f, + 0x4d, 0x46, 0x23, 0x2f, 0x2a, 0x10, 0x3f, 0xd6, 0x1b, 0xc4, 0x4f, 0x29, 0x2f, 0x7e, 0x6e, 0x1b, + 0xa7, 0x50, 0x2e, 0xbf, 0x34, 0x84, 0xdc, 0x83, 0x79, 0x36, 0xe5, 0xfc, 0x50, 0xa0, 0xdb, 0x27, + 0xb3, 0x70, 0x5e, 0x64, 0x56, 0x8b, 0x44, 0xa6, 0x2e, 0xee, 0x66, 0x33, 0xe2, 0xce, 0x86, 0x26, + 0x5f, 0x5e, 0x21, 0xc1, 0xe7, 0xc4, 0x91, 0x4c, 0xc3, 0x58, 0x7f, 0xb2, 0xc2, 0x85, 0x4b, 0xb2, + 0xf9, 0x22, 0xd1, 0xe2, 0x8f, 0x28, 0xee, 0x10, 0x5a, 0xe9, 0xba, 0x10, 0x2d, 0xf9, 0x2c, 0xf2, + 0x04, 0x80, 0xb7, 0x85, 0x6a, 0x0a, 0xa0, 0x9a, 0x72, 0xd7, 0x5c, 0x15, 0x7d, 0xfe, 0xd7, 0x58, + 0x62, 0x12, 0x51, 0x54, 0x5d, 0xb4, 0x2f, 0xed, 0xbf, 0x61, 0x41, 0x43, 0xcb, 0x23, 0xd7, 0x60, + 0x61, 0xf3, 0xe0, 0xe0, 0x70, 0xdb, 0xd9, 0x38, 0xde, 0xfd, 0xfe, 0xb6, 0xbb, 0xb9, 0x77, 0x70, + 0xb4, 0xdd, 0x99, 0x61, 0xf0, 0xde, 0xc1, 0xe6, 0xc6, 0x9e, 0xfb, 0xe4, 0xc0, 0xd9, 0x94, 0xb0, + 0x45, 0x96, 0x81, 0x38, 0xdb, 0xcf, 0x0e, 0x8e, 0xb7, 0x0d, 0xbc, 0x44, 0x3a, 0xd0, 0x7c, 0xec, + 0x6c, 0x6f, 0x6c, 0xee, 0x08, 0xa4, 0x4c, 0x96, 0xa0, 0xf3, 0xe4, 0xf9, 0xfe, 0xd6, 0xee, 0xfe, + 0x53, 0x77, 0x73, 0x63, 0x7f, 0x73, 0x7b, 0x6f, 0x7b, 0xab, 0x53, 0x21, 0x2d, 0xa8, 0x6f, 0x3c, + 0xde, 0xd8, 0xdf, 0x3a, 0xd8, 0xdf, 0xde, 0xea, 0x54, 0xed, 0xff, 0x66, 0xc1, 0x35, 0xec, 0xf5, + 0x20, 0xcb, 0x24, 0xab, 0xd0, 0xe8, 0x87, 0xe1, 0x98, 0x1d, 0x0f, 0xd2, 0x0d, 0x50, 0x87, 0x18, + 0x03, 0x70, 0xd1, 0x71, 0x1a, 0x46, 0x7d, 0x2a, 0x78, 0x04, 0x10, 0x7a, 0xc2, 0x10, 0xc6, 0x00, + 0x62, 0x79, 0x79, 0x09, 0xce, 0x22, 0x0d, 0x8e, 0xf1, 0x22, 0xcb, 0x30, 0x7b, 0x12, 0x51, 0xaf, + 0x7f, 0x2e, 0xb8, 0x43, 0xa4, 0xc8, 0xd7, 0xd2, 0xf3, 0x6b, 0x9f, 0xcd, 0xfe, 0x90, 0x0e, 0x90, + 0x62, 0x6a, 0xce, 0xbc, 0xc0, 0x37, 0x05, 0xcc, 0x64, 0xa5, 0x77, 0xe2, 0x05, 0x83, 0x30, 0xa0, + 0x03, 0xa1, 0x1c, 0xa7, 0x80, 0x7d, 0x08, 0xcb, 0xd9, 0xf1, 0x09, 0x1e, 0xfb, 0x50, 0xe3, 0x31, + 0xae, 0xab, 0xf6, 0xa6, 0xaf, 0xa6, 0xc6, 0x6f, 0x7f, 0x5a, 0x86, 0x0a, 0x53, 0x5d, 0xa6, 0xab, + 0x39, 0xba, 0x36, 0x5a, 0xce, 0x39, 0x33, 0xf0, 0x48, 0xcc, 0x37, 0x32, 0x61, 0x8e, 0x49, 0x91, + 0x34, 0x3f, 0xa2, 0xfd, 0x0b, 0x61, 0x90, 0xd1, 0x10, 0xc6, 0x20, 0xec, 0xa8, 0x80, 0x5f, 0x0b, + 0x06, 0x91, 0x69, 0x99, 0x87, 0x5f, 0xce, 0xa5, 0x79, 0xf8, 0x5d, 0x17, 0xe6, 0xfc, 0xe0, 0x24, + 0x9c, 0x04, 0x03, 0x64, 0x88, 0x9a, 0x23, 0x93, 0xe8, 0x3e, 0x41, 0x46, 0x65, 0x52, 0x96, 0x93, + 0x7f, 0x0a, 0x90, 0x75, 0xa8, 0xc7, 0x57, 0x41, 0x5f, 0xa7, 0xf9, 0x25, 0x31, 0x4b, 0x6c, 0x0e, + 0xd6, 0x8e, 0xae, 0x82, 0x3e, 0x52, 0x78, 0x5a, 0x8c, 0x7c, 0x1b, 0x6a, 0xca, 0x80, 0xc9, 0x85, + 0xd7, 0x75, 0xfd, 0x13, 0x69, 0xb5, 0xe4, 0xe7, 0x42, 0x55, 0xb4, 0xf7, 0x09, 0xb4, 0x8c, 0x2c, + 0xfd, 0x30, 0xd7, 0xe2, 0x87, 0xb9, 0x3b, 0xfa, 0x61, 0x2e, 0x95, 0x89, 0xe2, 0x33, 0xfd, 0x70, + 0xf7, 0x5b, 0x50, 0x93, 0x5d, 0x63, 0xac, 0xf1, 0x7c, 0xff, 0x93, 0xfd, 0x83, 0x17, 0xfb, 0xee, + 0xd1, 0x0f, 0xf6, 0x37, 0x3b, 0x33, 0x64, 0x1e, 0x1a, 0x1b, 0x9b, 0xc8, 0x6d, 0x08, 0x58, 0xac, + 0xc8, 0xe1, 0xc6, 0xd1, 0x91, 0x42, 0x4a, 0x36, 0x81, 0x0e, 0x93, 0xcc, 0xac, 0xc7, 0xca, 0x45, + 0xf1, 0x21, 0x2c, 0x68, 0x58, 0x7a, 0xde, 0x19, 0x33, 0x20, 0x73, 0xde, 0x41, 0xe5, 0x96, 0xe7, + 0xd8, 0x2b, 0x70, 0x8d, 0x25, 0xb7, 0x2f, 0x68, 0x90, 0x1c, 0x4d, 0x4e, 0xb8, 0x67, 0xca, 0x0f, + 0x03, 0xfb, 0xaf, 0x5a, 0x50, 0x57, 0x39, 0xaf, 0xa1, 0x27, 0xe9, 0x4c, 0x2b, 0xe1, 0x02, 0xf4, + 0xb4, 0x26, 0xf0, 0xcb, 0x35, 0xfc, 0xd7, 0x38, 0x23, 0xd5, 0x15, 0xc4, 0x06, 0x7b, 0xb8, 0xbd, + 0xed, 0xb8, 0x07, 0xfb, 0x7b, 0xbb, 0xfb, 0x4c, 0xb2, 0xb0, 0xc1, 0x22, 0xf0, 0xe4, 0x09, 0x22, + 0x96, 0xdd, 0x81, 0xf6, 0x53, 0x9a, 0xec, 0x06, 0xa7, 0xa1, 0x1c, 0xea, 0xff, 0xab, 0xc2, 0xbc, + 0x82, 0xc4, 0x48, 0xef, 0xc1, 0xbc, 0x3f, 0xa0, 0x41, 0xe2, 0x27, 0x57, 0xae, 0x61, 0x7a, 0xc9, + 0xc2, 0xec, 0xd4, 0xe2, 0x0d, 0x7d, 0x4f, 0xba, 0xf2, 0x78, 0x82, 0xac, 0xc3, 0x12, 0x53, 0xa7, + 0x74, 0x13, 0x18, 0x32, 0x1f, 0xb7, 0xf8, 0x14, 0xe6, 0x31, 0x31, 0xcd, 0x70, 0xb1, 0x17, 0xab, + 0x4f, 0xb8, 0xf6, 0x5e, 0x94, 0xc5, 0xe8, 0x99, 0xd7, 0xc4, 0xd6, 0xa4, 0xca, 0x55, 0x2e, 0x05, + 0xe4, 0x7c, 0x65, 0xb3, 0x7c, 0x13, 0xc9, 0xfa, 0xca, 0x34, 0x7f, 0x5b, 0x2d, 0xe7, 0x6f, 0x63, + 0x9b, 0xcc, 0x55, 0xd0, 0xa7, 0x03, 0x37, 0x09, 0x5d, 0xdc, 0x0c, 0x91, 0x6f, 0x6a, 0x4e, 0x16, + 0x66, 0x9b, 0x6b, 0x42, 0xe3, 0x24, 0xa0, 0xdc, 0xe9, 0x50, 0x43, 0x83, 0xb2, 0x84, 0xd8, 0x51, + 0x6b, 0x12, 0xf9, 0x71, 0xb7, 0x89, 0x9e, 0x34, 0xfc, 0x4d, 0xbe, 0x05, 0xd7, 0x4e, 0x68, 0x9c, + 0xb8, 0xe7, 0xd4, 0x1b, 0xd0, 0x08, 0x79, 0x90, 0xbb, 0xec, 0xb8, 0xf6, 0x5a, 0x9c, 0xc9, 0x28, + 0xe7, 0x82, 0x46, 0xb1, 0x1f, 0x06, 0xa8, 0xb7, 0xd6, 0x1d, 0x99, 0x64, 0xf5, 0xb1, 0xc1, 0x2b, + 0x6d, 0x46, 0xcd, 0xe0, 0x3c, 0x0e, 0xbc, 0x38, 0x93, 0xdc, 0x81, 0x59, 0x1c, 0x40, 0xdc, 0xed, + 0x20, 0x51, 0x37, 0x53, 0xc1, 0xe8, 0x07, 0x8e, 0xc8, 0x63, 0xab, 0xdc, 0x0f, 0x87, 0x61, 0x84, + 0xca, 0x6b, 0xdd, 0xe1, 0x09, 0x73, 0x76, 0xce, 0x22, 0x6f, 0x7c, 0x2e, 0x14, 0xd8, 0x2c, 0x4c, + 0xbe, 0xa3, 0xc9, 0x89, 0x45, 0x6c, 0xe7, 0x8e, 0x68, 0x27, 0x43, 0x79, 0x5f, 0x8a, 0xc8, 0xf8, + 0x6e, 0xa5, 0xd6, 0xe8, 0x34, 0xed, 0x5f, 0x83, 0x2a, 0x8e, 0x12, 0x47, 0x87, 0x6b, 0x6b, 0x89, + 0xd1, 0x21, 0xda, 0x85, 0xb9, 0x80, 0x26, 0x97, 0x61, 0xf4, 0x52, 0xba, 0xa9, 0x45, 0xd2, 0xfe, + 0x29, 0x9e, 0xbd, 0x95, 0xdb, 0xf6, 0x39, 0x1e, 0x1a, 0xc8, 0x0d, 0xa8, 0x73, 0xca, 0x89, 0xcf, + 0x3d, 0x61, 0x0e, 0xa8, 0x21, 0x70, 0x74, 0xee, 0xb1, 0xfd, 0xd1, 0x20, 0x46, 0x6e, 0x61, 0x69, + 0x20, 0xb6, 0xc3, 0x69, 0xf1, 0x0e, 0xb4, 0xa5, 0x43, 0x38, 0x76, 0x87, 0xf4, 0x34, 0x91, 0xf6, + 0xd1, 0x60, 0x32, 0x42, 0x33, 0xcc, 0x1e, 0x3d, 0x4d, 0xec, 0x7d, 0x58, 0x10, 0x7b, 0xd6, 0xc1, + 0x98, 0xca, 0xa6, 0x7f, 0xbd, 0x48, 0xff, 0x6b, 0xac, 0x2f, 0x9a, 0x9b, 0x1c, 0x77, 0x81, 0x9b, + 0x25, 0x6d, 0x07, 0x88, 0xbe, 0x07, 0x8a, 0x0a, 0x85, 0x02, 0x26, 0x2d, 0xc0, 0x62, 0x38, 0x06, + 0xc6, 0xe6, 0x27, 0x9e, 0xf4, 0xfb, 0xd2, 0x8d, 0x5f, 0x73, 0x64, 0xd2, 0xfe, 0xcf, 0x16, 0x2c, + 0x62, 0x6d, 0x52, 0x83, 0x15, 0x7a, 0xc6, 0xa3, 0xcf, 0xd1, 0x4d, 0x69, 0x7f, 0xe7, 0x56, 0xe7, + 0x25, 0xa8, 0xea, 0x9a, 0x07, 0x4f, 0x7c, 0x7e, 0x6b, 0x5b, 0x25, 0x67, 0x6d, 0xbb, 0x0f, 0x9d, + 0x01, 0x1d, 0xfa, 0x18, 0xca, 0x21, 0xf7, 0x71, 0xae, 0xae, 0xe6, 0x70, 0xfb, 0xef, 0x58, 0xb0, + 0xc0, 0x15, 0x05, 0x3c, 0x73, 0x89, 0xa9, 0xfa, 0x0b, 0xf2, 0x7c, 0x22, 0x04, 0x9a, 0x18, 0x54, + 0xba, 0x75, 0x22, 0xca, 0x0b, 0xef, 0xcc, 0x38, 0x66, 0x61, 0xf2, 0x31, 0x6a, 0xdd, 0x81, 0x8b, + 0x68, 0x41, 0x70, 0x88, 0xb9, 0x2e, 0x3b, 0x33, 0x8e, 0x56, 0xfc, 0x71, 0x8d, 0x1d, 0x99, 0x18, + 0x6e, 0x3f, 0x85, 0x96, 0xd1, 0x90, 0x61, 0x15, 0x6c, 0x72, 0xab, 0x60, 0xce, 0xfc, 0x5e, 0x2a, + 0x30, 0xbf, 0xff, 0x49, 0x19, 0x08, 0x23, 0xac, 0xcc, 0xca, 0xad, 0x9a, 0x3e, 0x2c, 0x19, 0x27, + 0x92, 0x42, 0x64, 0x1d, 0x88, 0x96, 0x94, 0xbe, 0xb5, 0xb2, 0xf2, 0xad, 0x15, 0xe4, 0xb2, 0x5d, + 0x42, 0x68, 0x95, 0xca, 0x6f, 0x85, 0x16, 0x1f, 0xbe, 0x4c, 0x85, 0x79, 0x4c, 0xf3, 0x41, 0x27, + 0x16, 0x3b, 0x9b, 0x0a, 0x2b, 0x89, 0x4c, 0x67, 0xe9, 0x61, 0xf6, 0x8d, 0xf4, 0x30, 0x97, 0xa3, + 0x07, 0xed, 0x9c, 0x5e, 0x33, 0xcf, 0xe9, 0x77, 0xa0, 0x25, 0x7d, 0x55, 0xdc, 0x4d, 0x2f, 0x8c, + 0x22, 0x06, 0xc8, 0xe8, 0x49, 0x1e, 0x95, 0x95, 0x31, 0x80, 0x3b, 0xa1, 0x73, 0x38, 0xdb, 0xbe, + 0x52, 0x7b, 0x6c, 0x03, 0x3b, 0x9b, 0x02, 0x78, 0xb2, 0x66, 0x54, 0xe2, 0x4e, 0x02, 0x11, 0x23, + 0x42, 0x07, 0x68, 0x0e, 0x61, 0x27, 0xeb, 0x6c, 0x46, 0xfe, 0x94, 0xdc, 0x2a, 0x3a, 0x25, 0xff, + 0x2d, 0x0b, 0x3a, 0x6c, 0x75, 0x0d, 0x02, 0xfe, 0x08, 0x90, 0xd7, 0xde, 0x92, 0x7e, 0x8d, 0xb2, + 0xe4, 0x11, 0xd4, 0x31, 0x1d, 0x8e, 0x69, 0x20, 0xa8, 0xb7, 0x6b, 0x52, 0x6f, 0x2a, 0xa5, 0x76, + 0x66, 0x9c, 0xb4, 0xb0, 0x46, 0xbb, 0xff, 0xd1, 0x82, 0x86, 0x68, 0xe5, 0x97, 0xb6, 0x0a, 0xf6, + 0xb4, 0xd0, 0x1f, 0xae, 0x86, 0xa7, 0x91, 0x3e, 0xf7, 0x60, 0x7e, 0xc4, 0x76, 0x00, 0xa6, 0xb4, + 0x18, 0x16, 0xc1, 0x2c, 0xcc, 0x34, 0x10, 0x14, 0xc8, 0xb1, 0x9b, 0xf8, 0x43, 0x57, 0xe6, 0x8a, + 0x20, 0x9b, 0xa2, 0x2c, 0x26, 0x97, 0xe2, 0xc4, 0x3b, 0xa3, 0x42, 0xb9, 0xe0, 0x09, 0xbb, 0x0b, + 0xcb, 0x87, 0xa9, 0x97, 0x4f, 0x3b, 0x69, 0xd9, 0xff, 0xac, 0x05, 0x2b, 0xb9, 0x2c, 0x15, 0x12, + 0x28, 0xcc, 0x5c, 0x43, 0x7f, 0x74, 0x12, 0xaa, 0x63, 0xaa, 0xa5, 0x5b, 0xc0, 0x8c, 0x2c, 0x72, + 0x06, 0xd7, 0xa4, 0x16, 0xc5, 0xe6, 0x34, 0xdd, 0xf1, 0x4b, 0xb8, 0xc5, 0x7e, 0x60, 0x2e, 0x61, + 0xb6, 0x41, 0x89, 0xeb, 0xec, 0x5e, 0x5c, 0x1f, 0x39, 0x87, 0xae, 0x52, 0xd7, 0xc4, 0x16, 0xa0, + 0xa9, 0x74, 0xac, 0xad, 0xf7, 0xdf, 0xd0, 0x96, 0x71, 0x30, 0x73, 0xa6, 0xd6, 0x46, 0xae, 0xe0, + 0xb6, 0xcc, 0x43, 0x19, 0x9f, 0x6f, 0xaf, 0xf2, 0x56, 0x63, 0xc3, 0x23, 0xa7, 0xd9, 0xe8, 0x1b, + 0x2a, 0x26, 0x3f, 0x81, 0xe5, 0x4b, 0xcf, 0x4f, 0x64, 0xb7, 0x34, 0x05, 0xaa, 0x8a, 0x4d, 0xae, + 0xbf, 0xa1, 0xc9, 0x17, 0xfc, 0x63, 0x63, 0xe3, 0x9b, 0x52, 0x63, 0xef, 0x8f, 0x4a, 0xd0, 0x36, + 0xeb, 0x61, 0x64, 0x2a, 0x24, 0x84, 0x94, 0x94, 0x52, 0xe5, 0xce, 0xc0, 0x79, 0x6b, 0x4f, 0xa9, + 0xc8, 0xda, 0xa3, 0xdb, 0x57, 0xca, 0x6f, 0x32, 0x27, 0x57, 0xde, 0xce, 0x9c, 0x5c, 0x2d, 0x34, + 0x27, 0x4f, 0xb7, 0x3a, 0xce, 0xfe, 0xb2, 0x56, 0xc7, 0xb9, 0xd7, 0x5a, 0x1d, 0x7b, 0xff, 0xd7, + 0x02, 0x92, 0xa7, 0x5e, 0xf2, 0x94, 0x1b, 0xb8, 0x02, 0x3a, 0x14, 0x42, 0xec, 0x1b, 0x6f, 0xc7, + 0x01, 0x72, 0xb5, 0xe4, 0xd7, 0x8c, 0x15, 0xf5, 0xb8, 0x3c, 0x5d, 0x69, 0x6b, 0x39, 0x45, 0x59, + 0x19, 0x93, 0x7a, 0xe5, 0xcd, 0x26, 0xf5, 0xea, 0x9b, 0x4d, 0xea, 0xb3, 0x59, 0x93, 0x7a, 0xef, + 0xaf, 0x58, 0xb0, 0x58, 0x40, 0x66, 0x5f, 0xdc, 0xc0, 0x19, 0x61, 0x18, 0xd2, 0xa7, 0x24, 0x08, + 0x43, 0x07, 0x7b, 0x7f, 0x11, 0x5a, 0x06, 0x6b, 0x7d, 0x71, 0xed, 0x67, 0xf5, 0x4e, 0x4e, 0xd9, + 0x06, 0xd6, 0xfb, 0x5f, 0x25, 0x20, 0x79, 0xf6, 0xfe, 0x52, 0xfb, 0x90, 0x9f, 0xa7, 0x72, 0xc1, + 0x3c, 0xfd, 0xb9, 0xee, 0x3c, 0xef, 0xc3, 0x82, 0x08, 0x36, 0xd6, 0x4c, 0x9a, 0x9c, 0x62, 0xf2, + 0x19, 0x4c, 0xf3, 0x36, 0xfd, 0x19, 0x35, 0x23, 0xb8, 0x52, 0xdb, 0x7e, 0x33, 0x6e, 0x0d, 0xbb, + 0x07, 0x5d, 0x31, 0x43, 0x79, 0x9b, 0xc6, 0xbf, 0x28, 0xab, 0xc3, 0x03, 0x66, 0x0a, 0x85, 0xe2, + 0x5b, 0xd0, 0xd4, 0xb7, 0x0f, 0xb1, 0x1c, 0x19, 0xab, 0x36, 0x53, 0x25, 0xf4, 0x52, 0x64, 0x0b, + 0xda, 0x28, 0x24, 0x07, 0xea, 0x3b, 0x7e, 0x8c, 0x7b, 0x8d, 0xa5, 0x6e, 0x67, 0xc6, 0xc9, 0x7c, + 0x43, 0x7e, 0x03, 0xda, 0xe6, 0x09, 0x57, 0x68, 0x25, 0x45, 0x67, 0x0c, 0xf6, 0xb9, 0x59, 0x98, + 0x6c, 0x40, 0x27, 0x7b, 0x44, 0x16, 0x91, 0x5f, 0x53, 0x2a, 0xc8, 0x15, 0x27, 0x8f, 0x84, 0x01, + 0xa7, 0x8a, 0x06, 0x9c, 0x3b, 0xe6, 0x67, 0xda, 0x34, 0xad, 0xf1, 0xff, 0x34, 0x53, 0xce, 0xef, + 0x00, 0xa4, 0x18, 0xe9, 0x40, 0xf3, 0xe0, 0x70, 0x7b, 0xdf, 0xdd, 0xdc, 0xd9, 0xd8, 0xdf, 0xdf, + 0xde, 0xeb, 0xcc, 0x10, 0x02, 0x6d, 0x34, 0xf8, 0x6e, 0x29, 0xcc, 0x62, 0x98, 0x30, 0x6f, 0x49, + 0xac, 0x44, 0x96, 0xa0, 0xb3, 0xbb, 0x9f, 0x41, 0xcb, 0x8f, 0xeb, 0x8a, 0x3f, 0xec, 0x65, 0x58, + 0xe2, 0xc1, 0xe4, 0x8f, 0x39, 0x79, 0x48, 0xed, 0xe4, 0x1f, 0x58, 0x70, 0x2d, 0x93, 0x91, 0x86, + 0x07, 0x72, 0x05, 0xc4, 0xd4, 0x4a, 0x4c, 0x10, 0x9d, 0x55, 0x52, 0x23, 0xcd, 0x48, 0x90, 0x7c, + 0x06, 0xa3, 0x79, 0x4d, 0x83, 0xcd, 0x70, 0x52, 0x51, 0x96, 0xbd, 0xa2, 0xa2, 0xb0, 0x32, 0x1d, + 0x3f, 0xe5, 0x41, 0xea, 0x7a, 0x46, 0x1a, 0x2c, 0x60, 0x76, 0x59, 0x26, 0xd9, 0xe1, 0xc3, 0x50, + 0x76, 0xcc, 0xfe, 0x16, 0xe6, 0xd9, 0xff, 0xbb, 0x02, 0xe4, 0x7b, 0x13, 0x1a, 0x5d, 0x61, 0xfc, + 0x9f, 0xb2, 0x9f, 0xaf, 0x64, 0xad, 0x79, 0xb3, 0xe3, 0xc9, 0xc9, 0x27, 0xf4, 0x4a, 0xc6, 0xf9, + 0x96, 0xde, 0x2a, 0xce, 0xb7, 0x28, 0xce, 0xb6, 0xf2, 0xe6, 0x38, 0xdb, 0xea, 0x9b, 0xe2, 0x6c, + 0xbf, 0x02, 0x2d, 0xff, 0x2c, 0x08, 0x99, 0x38, 0x60, 0x2a, 0x44, 0xdc, 0x9d, 0x5d, 0x2d, 0xb3, + 0xc3, 0xbc, 0x00, 0xf7, 0x19, 0x46, 0x3e, 0x4e, 0x0b, 0xd1, 0xc1, 0x19, 0xc6, 0x85, 0xeb, 0x02, + 0x62, 0x7b, 0x70, 0x46, 0xf7, 0xc2, 0xbe, 0x97, 0x84, 0x11, 0x9e, 0xe6, 0xe4, 0xc7, 0x0c, 0x8f, + 0xc9, 0x1d, 0x68, 0xc7, 0xe1, 0x84, 0x29, 0x55, 0x72, 0x1a, 0xb8, 0x25, 0xad, 0xc9, 0xd1, 0x43, + 0x3e, 0x19, 0x6b, 0xb0, 0x38, 0x89, 0xa9, 0x3b, 0xf2, 0xe3, 0x98, 0x6d, 0x9c, 0xfd, 0x30, 0x48, + 0xa2, 0x70, 0x28, 0xec, 0x69, 0x0b, 0x93, 0x98, 0x3e, 0xe3, 0x39, 0x9b, 0x3c, 0x83, 0x7c, 0x2b, + 0xed, 0xd2, 0xd8, 0xf3, 0xa3, 0xb8, 0x0b, 0xd8, 0x25, 0x39, 0x52, 0xd6, 0xef, 0x43, 0xcf, 0x8f, + 0x54, 0x5f, 0x58, 0x22, 0xce, 0xc4, 0xff, 0x36, 0xb2, 0xf1, 0xbf, 0x3f, 0x2e, 0x8e, 0xff, 0x6d, + 0x61, 0xd5, 0x0f, 0x45, 0xd5, 0xf9, 0x25, 0x7e, 0xfb, 0x30, 0xe0, 0x2f, 0x26, 0x40, 0x57, 0xc4, + 0x94, 0xae, 0x41, 0x4d, 0x0e, 0x93, 0x9d, 0xe8, 0x4f, 0xa3, 0x70, 0x24, 0x4f, 0xf4, 0xec, 0x37, + 0x69, 0x43, 0x29, 0x09, 0xc5, 0xc7, 0xa5, 0x24, 0xb4, 0x7f, 0x17, 0x1a, 0xda, 0x4a, 0x91, 0x77, + 0xb9, 0x71, 0x81, 0xe9, 0x84, 0xc2, 0x14, 0xc0, 0x7d, 0x7e, 0x75, 0x81, 0xee, 0x0e, 0xc8, 0xd7, + 0x61, 0x61, 0xe0, 0x47, 0x14, 0x43, 0xe9, 0xdd, 0x88, 0x5e, 0xd0, 0x28, 0x96, 0x46, 0x96, 0x8e, + 0xca, 0x70, 0x38, 0x6e, 0xbb, 0xb0, 0x68, 0x4c, 0x8d, 0x12, 0x0e, 0xb3, 0x18, 0x08, 0x2b, 0xed, + 0xe2, 0x66, 0x90, 0xac, 0xc8, 0x63, 0xdb, 0xaa, 0xb0, 0x0f, 0xb9, 0xe3, 0x28, 0x3c, 0xc1, 0x46, + 0x2c, 0xc7, 0xc0, 0xec, 0xff, 0x59, 0x86, 0xf2, 0x4e, 0x38, 0xd6, 0x3d, 0x95, 0x56, 0xde, 0x53, + 0x29, 0xf4, 0x5f, 0x57, 0xa9, 0xb7, 0x42, 0x49, 0x31, 0x40, 0x72, 0x1f, 0xda, 0x8c, 0xd3, 0x92, + 0x90, 0xe9, 0xfb, 0x97, 0x5e, 0xc4, 0xa3, 0x66, 0xcb, 0x48, 0xbe, 0x99, 0x1c, 0xb2, 0x04, 0x65, + 0xa5, 0xb6, 0x61, 0x01, 0x96, 0x64, 0x87, 0x4d, 0x8c, 0x19, 0xb9, 0x12, 0xb6, 0x65, 0x91, 0x62, + 0x82, 0xcb, 0xfc, 0x9e, 0xb3, 0x33, 0xdf, 0x7c, 0x8b, 0xb2, 0x98, 0x2e, 0xce, 0x18, 0x76, 0x94, + 0xaa, 0xb6, 0x2a, 0xad, 0xbb, 0x02, 0x6a, 0xa6, 0x2b, 0x60, 0x15, 0x1a, 0xc9, 0xf0, 0xc2, 0x1d, + 0x7b, 0x57, 0xc3, 0xd0, 0x1b, 0x08, 0x46, 0xd1, 0x21, 0xf2, 0x10, 0x60, 0x34, 0x1e, 0x0b, 0x2a, + 0x46, 0x3b, 0x43, 0x63, 0xbd, 0x23, 0x66, 0xff, 0xd9, 0xe1, 0x21, 0xa7, 0x3e, 0x47, 0x2b, 0x43, + 0xb6, 0xa1, 0x5d, 0x18, 0xfa, 0x7e, 0x4b, 0x46, 0x36, 0x84, 0xe3, 0xb5, 0x02, 0x3a, 0xcf, 0x7c, + 0xd4, 0xfb, 0x0e, 0x90, 0x5f, 0x31, 0x02, 0xfd, 0x05, 0xd4, 0x55, 0x0f, 0xf5, 0xb8, 0x6f, 0x0c, + 0x5f, 0x6a, 0x98, 0x71, 0xdf, 0x18, 0xad, 0x74, 0x17, 0xda, 0x7c, 0xb7, 0x51, 0xf2, 0x93, 0x87, + 0x9c, 0x64, 0x50, 0xfb, 0xcf, 0x2c, 0xa8, 0x22, 0xe5, 0x31, 0xf5, 0x8b, 0xe7, 0x29, 0x17, 0xaf, + 0xb0, 0x16, 0x67, 0x61, 0x62, 0x1b, 0x57, 0x62, 0x4a, 0x8a, 0x0c, 0xf4, 0x6b, 0x31, 0xab, 0x50, + 0x57, 0x2d, 0x69, 0xa4, 0x94, 0x82, 0xe4, 0x36, 0x54, 0xce, 0xc3, 0xb1, 0x3c, 0xa1, 0x42, 0x3a, + 0xa3, 0x0e, 0xe2, 0x69, 0x7f, 0x58, 0x7d, 0x7c, 0x08, 0xfc, 0x14, 0x90, 0x85, 0x0b, 0xc6, 0x3a, + 0x5b, 0x38, 0xd6, 0xe7, 0x30, 0xcf, 0xe4, 0x83, 0xe6, 0xcd, 0x99, 0xbe, 0x17, 0x7d, 0x8d, 0xa9, + 0x36, 0xfd, 0xe1, 0x64, 0x40, 0x75, 0x3b, 0x01, 0x5a, 0xeb, 0x05, 0x2e, 0x35, 0x64, 0xfb, 0x9f, + 0x5b, 0x5c, 0xee, 0xb0, 0x7a, 0xc9, 0x3d, 0xa8, 0xb0, 0x6d, 0x23, 0x63, 0x16, 0x52, 0x21, 0x65, + 0xac, 0x9c, 0x83, 0x25, 0xd8, 0x2a, 0xa2, 0x01, 0x5b, 0xaf, 0x9d, 0x9b, 0xaf, 0xd3, 0x43, 0xb6, + 0x1a, 0x59, 0xe6, 0x6c, 0x9a, 0x41, 0xc9, 0x9a, 0xe6, 0xb1, 0xad, 0x18, 0x5b, 0x91, 0xd4, 0xa4, + 0x06, 0x67, 0x54, 0xf3, 0xd4, 0xfe, 0xcb, 0x12, 0xb4, 0x8c, 0x3e, 0x31, 0xee, 0xc1, 0x0b, 0x23, + 0xdc, 0xca, 0x24, 0x56, 0x5e, 0x87, 0x74, 0xce, 0x2b, 0x99, 0x9c, 0xa7, 0x9c, 0x5a, 0x65, 0xdd, + 0xa9, 0xf5, 0x10, 0xea, 0xe9, 0x9d, 0x28, 0xb3, 0x53, 0xac, 0x45, 0x19, 0x5c, 0x97, 0x16, 0x4a, + 0xdd, 0x26, 0x55, 0xdd, 0x6d, 0xf2, 0x9b, 0x9a, 0x33, 0x64, 0x16, 0xab, 0xb1, 0x8b, 0x66, 0xf5, + 0xcb, 0xf1, 0x9e, 0x7e, 0x0c, 0x0d, 0xad, 0xf3, 0xba, 0xd3, 0xc3, 0x32, 0x9c, 0x1e, 0x2a, 0x0c, + 0xb6, 0x94, 0x86, 0xc1, 0xda, 0x3f, 0x2f, 0x41, 0x8b, 0xf1, 0x9a, 0x1f, 0x9c, 0x1d, 0x86, 0x43, + 0xbf, 0x7f, 0x85, 0x34, 0x2e, 0xd9, 0x4a, 0xe8, 0x30, 0x92, 0xe7, 0x4c, 0x98, 0xc9, 0x44, 0x15, + 0xfb, 0xcf, 0x05, 0xb8, 0x4a, 0x33, 0x09, 0xcf, 0xe4, 0xe3, 0x89, 0x17, 0x53, 0xed, 0xc6, 0x96, + 0x63, 0x82, 0x4c, 0x0e, 0x33, 0x00, 0x83, 0x9a, 0x47, 0xfe, 0x70, 0xe8, 0xf3, 0xb2, 0xfc, 0xf0, + 0x5d, 0x94, 0xc5, 0xda, 0x1c, 0xf8, 0xb1, 0x77, 0x92, 0x86, 0x18, 0xa8, 0x34, 0xda, 0x77, 0xbd, + 0x57, 0x9a, 0x7d, 0x97, 0xdf, 0x82, 0x30, 0xc1, 0x2c, 0x55, 0xcd, 0xe5, 0xa8, 0xca, 0xfe, 0xb7, + 0x25, 0x68, 0x68, 0x34, 0xca, 0x64, 0x4b, 0xe1, 0x26, 0xac, 0xa1, 0x22, 0xf6, 0x26, 0x30, 0xcc, + 0x39, 0x1a, 0x42, 0xee, 0x98, 0xad, 0xa2, 0x5f, 0x08, 0xa5, 0x8f, 0x41, 0xcf, 0x37, 0xa1, 0xce, + 0xf8, 0xf0, 0x03, 0xb4, 0x1d, 0x89, 0xdb, 0x91, 0x0a, 0x90, 0xb9, 0xeb, 0x98, 0x5b, 0x4d, 0x73, + 0x11, 0x78, 0x6d, 0x34, 0xce, 0x23, 0x68, 0x8a, 0x6a, 0x70, 0x8d, 0x71, 0xd0, 0xa9, 0x24, 0x30, + 0xd6, 0xdf, 0x31, 0x4a, 0xca, 0x2f, 0xd7, 0xe5, 0x97, 0xb5, 0x37, 0x7d, 0x29, 0x4b, 0xda, 0x4f, + 0x55, 0xa0, 0xd3, 0xd3, 0xc8, 0x1b, 0x9f, 0x4b, 0xe9, 0xf6, 0x10, 0x16, 0xa5, 0x10, 0x9b, 0x04, + 0x5e, 0x10, 0x84, 0x93, 0xa0, 0x4f, 0x65, 0xc4, 0x6c, 0x51, 0x96, 0x3d, 0x50, 0xf7, 0x2b, 0xb0, + 0x22, 0x72, 0x1f, 0xaa, 0x5c, 0x0b, 0xe6, 0xba, 0x4a, 0xb1, 0x3c, 0xe3, 0x45, 0xc8, 0x3d, 0xa8, + 0x72, 0x65, 0xb8, 0x34, 0x55, 0x02, 0xf1, 0x02, 0xf6, 0x1a, 0xcc, 0xe3, 0x85, 0x0e, 0x4d, 0x10, + 0xdf, 0x28, 0xd2, 0x61, 0x66, 0xfb, 0xfc, 0xda, 0xc7, 0x12, 0x90, 0x7d, 0xce, 0x57, 0xba, 0x27, + 0xfe, 0xcf, 0xca, 0xd0, 0xd0, 0x60, 0x26, 0x2c, 0xd1, 0x7d, 0xea, 0x0e, 0x7c, 0x6f, 0x44, 0x13, + 0x1a, 0x09, 0x5e, 0xca, 0xa0, 0xac, 0x9c, 0x77, 0x71, 0xe6, 0x86, 0x93, 0xc4, 0x1d, 0xd0, 0xb3, + 0x88, 0x52, 0xa1, 0x5c, 0x65, 0x50, 0x56, 0x8e, 0x51, 0xb3, 0x56, 0x8e, 0x7b, 0x18, 0x33, 0xa8, + 0xf4, 0xab, 0xf3, 0x79, 0xaa, 0xa4, 0x7e, 0x75, 0x3e, 0x2b, 0x59, 0x31, 0x5f, 0x2d, 0x10, 0xf3, + 0x1f, 0xc2, 0x32, 0x17, 0xe8, 0x42, 0x7a, 0xb8, 0x19, 0xe2, 0x9a, 0x92, 0x4b, 0xee, 0x43, 0x87, + 0xf5, 0x59, 0xb2, 0x46, 0xec, 0xff, 0x94, 0xf3, 0x98, 0xe5, 0xe4, 0x70, 0x56, 0x16, 0xbd, 0x25, + 0x7a, 0x59, 0x1e, 0x01, 0x96, 0xc3, 0xb1, 0xac, 0xf7, 0xca, 0x2c, 0x5b, 0x17, 0x65, 0x33, 0x38, + 0x79, 0x04, 0x2b, 0x23, 0x3a, 0xf0, 0x3d, 0xb3, 0x0a, 0x37, 0xd5, 0x38, 0xa6, 0x65, 0xb3, 0x56, + 0xd8, 0x2c, 0xfc, 0x34, 0x1c, 0x9d, 0xf8, 0x7c, 0x97, 0xe5, 0x7e, 0x9d, 0x8a, 0x93, 0xc3, 0xed, + 0x16, 0x34, 0x8e, 0x92, 0x70, 0x2c, 0x97, 0xbe, 0x0d, 0x4d, 0x9e, 0x14, 0x31, 0xd2, 0x37, 0xe0, + 0x3a, 0xd2, 0xeb, 0x71, 0x38, 0x0e, 0x87, 0xe1, 0xd9, 0x95, 0x61, 0x77, 0xf9, 0xf7, 0x16, 0x2c, + 0x1a, 0xb9, 0xa9, 0xe1, 0x05, 0x8d, 0xc4, 0x32, 0xb0, 0x95, 0x93, 0xf8, 0x82, 0xb6, 0x47, 0xf1, + 0x82, 0xdc, 0x73, 0xf7, 0x5c, 0xc4, 0xba, 0x6e, 0xa4, 0xb7, 0xb5, 0xe4, 0x87, 0x9c, 0xde, 0xbb, + 0x79, 0x7a, 0x17, 0xdf, 0xcb, 0x7b, 0x5c, 0xb2, 0x8a, 0xdf, 0x10, 0xf1, 0x7a, 0x03, 0x31, 0xe8, + 0xb2, 0x19, 0x63, 0xa5, 0xdb, 0xe9, 0x64, 0x0f, 0xfa, 0x0a, 0x8c, 0xed, 0x5f, 0x58, 0x00, 0x69, + 0xef, 0x30, 0xca, 0x4b, 0xed, 0xb3, 0xfc, 0x41, 0x04, 0x6d, 0x4f, 0x7d, 0x17, 0x9a, 0x2a, 0x06, + 0x25, 0xdd, 0xba, 0x1b, 0x12, 0x63, 0xaa, 0xce, 0x7b, 0x30, 0x7f, 0x36, 0x0c, 0x4f, 0x50, 0xa5, + 0x12, 0xfb, 0x2c, 0x8f, 0x14, 0x6f, 0x73, 0x58, 0xee, 0x9e, 0xe9, 0x3e, 0x5f, 0xd1, 0xf7, 0xf9, + 0xc2, 0x5d, 0x9b, 0xed, 0x75, 0x0b, 0xb9, 0x99, 0x78, 0x2d, 0x97, 0x93, 0xf5, 0x9c, 0x58, 0x9f, + 0xe2, 0xec, 0xc6, 0x03, 0xd9, 0xe1, 0x1b, 0xcd, 0xf6, 0x1f, 0x43, 0x3b, 0xe2, 0x32, 0x53, 0x0a, + 0xd4, 0xca, 0x6b, 0x04, 0x6a, 0x2b, 0x32, 0x76, 0xe6, 0xaf, 0x41, 0xc7, 0x1b, 0x5c, 0xd0, 0x28, + 0xf1, 0xd1, 0x8c, 0x89, 0x3a, 0x1d, 0x1f, 0xe0, 0xbc, 0x86, 0xa3, 0xea, 0xf4, 0x1e, 0xcc, 0x8b, + 0xb8, 0x7d, 0x55, 0x52, 0x5c, 0x0d, 0x4e, 0x61, 0x56, 0xd0, 0xfe, 0xc7, 0xd2, 0xd1, 0x6f, 0xae, + 0xee, 0xeb, 0x67, 0x45, 0x1f, 0x61, 0x29, 0x33, 0xc2, 0xaf, 0x08, 0x37, 0xe6, 0x40, 0xda, 0x4b, + 0xcb, 0x5a, 0xe4, 0xe7, 0x40, 0x04, 0x4a, 0x98, 0xd3, 0x5a, 0x79, 0x9b, 0x69, 0xb5, 0xff, 0x8b, + 0x05, 0x73, 0x3b, 0xe1, 0x78, 0xc7, 0xe7, 0xc1, 0x57, 0xc8, 0x26, 0xea, 0xd2, 0x8c, 0x4c, 0xbe, + 0x21, 0x42, 0xb6, 0x50, 0x2b, 0x69, 0x65, 0xb5, 0x92, 0xef, 0xc0, 0x0d, 0xb4, 0xd8, 0x47, 0xe1, + 0x38, 0x8c, 0x18, 0xbb, 0x7a, 0x43, 0xae, 0x82, 0x84, 0x41, 0x72, 0x2e, 0xc5, 0xe9, 0xeb, 0x8a, + 0xa0, 0x19, 0x6d, 0x98, 0x5c, 0xb8, 0xfc, 0xb8, 0x29, 0xb4, 0x28, 0x2e, 0x65, 0xf3, 0x19, 0xf6, + 0xaf, 0x43, 0x1d, 0x8f, 0x3b, 0x38, 0xb4, 0xf7, 0xa1, 0x7e, 0x1e, 0x8e, 0xdd, 0x73, 0x3f, 0x48, + 0x24, 0xfb, 0xb7, 0xd3, 0x73, 0xc8, 0x0e, 0x4e, 0x8a, 0x2a, 0x60, 0xff, 0x87, 0x39, 0x98, 0xdb, + 0x0d, 0x2e, 0x42, 0xbf, 0x8f, 0x01, 0x03, 0x23, 0x3a, 0x0a, 0xe5, 0x35, 0x22, 0xf6, 0x1b, 0x6f, + 0xf8, 0xa7, 0x17, 0x7d, 0x39, 0x0b, 0x69, 0x08, 0x3b, 0x20, 0x47, 0xfa, 0x45, 0x5d, 0x91, 0x4a, + 0x4f, 0x7d, 0x55, 0xed, 0x22, 0x16, 0xab, 0x8d, 0x5f, 0x20, 0xc5, 0xb9, 0xe3, 0xe1, 0xdf, 0x1a, + 0xc2, 0x26, 0x5f, 0x44, 0xee, 0xf2, 0xd0, 0x4e, 0x1e, 0x41, 0x25, 0x20, 0x3c, 0xf4, 0x47, 0x94, + 0xfb, 0x5c, 0x94, 0xea, 0xc5, 0x0e, 0xfd, 0x3a, 0xc8, 0xd4, 0x33, 0xfe, 0x01, 0x2f, 0xc3, 0xb7, + 0x03, 0x1d, 0x62, 0x0a, 0x6a, 0xf6, 0xda, 0x3b, 0x7f, 0xba, 0x20, 0x0b, 0xf3, 0xd0, 0x10, 0x25, + 0x74, 0xf9, 0x38, 0x81, 0x5f, 0x76, 0xce, 0xe2, 0x9a, 0xa9, 0x80, 0x5f, 0x70, 0x90, 0xa6, 0x02, + 0x46, 0x32, 0xde, 0x70, 0x78, 0xe2, 0xf5, 0x5f, 0xf2, 0x93, 0x6d, 0x93, 0xbb, 0xea, 0x0c, 0x10, + 0xe3, 0x6f, 0xd3, 0x75, 0x45, 0xd7, 0x7d, 0xc5, 0xd1, 0x21, 0xb2, 0x0e, 0x0d, 0x34, 0xa3, 0x88, + 0x95, 0x6d, 0xe3, 0xca, 0x76, 0x74, 0x3b, 0x0b, 0xae, 0xad, 0x5e, 0x48, 0x0f, 0x65, 0x98, 0xcf, + 0x5d, 0x39, 0xf0, 0x06, 0x03, 0x11, 0x05, 0xd2, 0xe1, 0x97, 0x7d, 0x15, 0x80, 0x86, 0x1a, 0x3e, + 0x61, 0xbc, 0xc0, 0x02, 0x16, 0x30, 0x30, 0x72, 0x9b, 0x9b, 0x31, 0xc7, 0x9e, 0x3f, 0xc0, 0x90, + 0x2f, 0x7e, 0x16, 0x56, 0x18, 0xab, 0x43, 0xfe, 0xc6, 0x8d, 0x73, 0x11, 0x67, 0xc5, 0xc0, 0xd8, + 0xdc, 0xa8, 0xf4, 0x28, 0xbd, 0xa3, 0x60, 0x82, 0xe4, 0x03, 0xf4, 0xb0, 0x27, 0x14, 0x2f, 0x22, + 0xb4, 0xd7, 0x6f, 0x88, 0x31, 0x0b, 0xb2, 0x95, 0xff, 0x1f, 0xb1, 0x22, 0x0e, 0x2f, 0xc9, 0xd4, + 0x36, 0xee, 0xe4, 0x58, 0x36, 0xd4, 0x36, 0x51, 0x14, 0x9d, 0x1c, 0xbc, 0x00, 0x79, 0xa4, 0x9d, + 0xc4, 0xba, 0x58, 0xf8, 0x66, 0xa6, 0xfe, 0x2f, 0xe5, 0x0c, 0xb6, 0x01, 0x4d, 0x7d, 0x1c, 0xa4, + 0x06, 0x95, 0x83, 0xc3, 0xed, 0xfd, 0xce, 0x0c, 0x69, 0xc0, 0xdc, 0xd1, 0xf6, 0xf1, 0xf1, 0xde, + 0xf6, 0x56, 0xc7, 0x22, 0x4d, 0xa8, 0xa9, 0xe8, 0xee, 0x12, 0x4b, 0x6d, 0x6c, 0x6e, 0x6e, 0x1f, + 0x1e, 0x6f, 0x6f, 0x75, 0xca, 0xdf, 0xad, 0xd4, 0x4a, 0x9d, 0x32, 0x2a, 0x90, 0xda, 0x30, 0xdf, + 0x60, 0x47, 0xbb, 0x0d, 0x80, 0x07, 0x9b, 0x34, 0x1a, 0xa8, 0xe2, 0x68, 0x08, 0x13, 0xd4, 0xca, + 0xfe, 0x50, 0xe6, 0x17, 0xb0, 0x65, 0x1a, 0x17, 0x0f, 0x6f, 0x3a, 0xeb, 0x8e, 0xad, 0xaa, 0x63, + 0x82, 0x8c, 0xb0, 0x05, 0x80, 0x21, 0xc7, 0x5c, 0x1c, 0xe8, 0x10, 0x23, 0x94, 0x88, 0xc6, 0xe1, + 0xf0, 0x82, 0xf2, 0x22, 0x5c, 0x3d, 0x34, 0x30, 0xd6, 0x96, 0x90, 0x78, 0xda, 0x75, 0x80, 0xaa, + 0x63, 0x82, 0xe4, 0x1b, 0x92, 0x50, 0x6a, 0x48, 0x28, 0x2b, 0xf9, 0x55, 0x37, 0x88, 0xe4, 0x59, + 0xce, 0x10, 0x56, 0x47, 0x02, 0xf8, 0x6a, 0xfe, 0xbb, 0xb7, 0x30, 0x88, 0x91, 0x35, 0x20, 0xa3, + 0xf1, 0xd8, 0x2d, 0xb0, 0x50, 0x55, 0x9c, 0x82, 0x9c, 0x2f, 0xc0, 0x80, 0x96, 0x00, 0xd9, 0x18, + 0x0c, 0x44, 0x37, 0xf5, 0xfb, 0xe8, 0x91, 0xfe, 0x00, 0x82, 0x14, 0xc9, 0x05, 0x62, 0xaf, 0x54, + 0x2c, 0xf6, 0x5e, 0x2b, 0x1c, 0xec, 0x5d, 0x68, 0x1c, 0x6a, 0x4f, 0x2a, 0xd8, 0x6c, 0x87, 0x90, + 0x8f, 0x29, 0xf0, 0xbd, 0x83, 0x1b, 0xce, 0x52, 0x54, 0xeb, 0x52, 0x49, 0xef, 0x92, 0xfd, 0x0f, + 0x2d, 0x7e, 0x4b, 0x55, 0x0d, 0x81, 0xb7, 0x6f, 0x43, 0x53, 0xf9, 0x5e, 0xd2, 0x2b, 0x3b, 0x06, + 0xc6, 0xca, 0x60, 0x77, 0xdc, 0xf0, 0xf4, 0x34, 0xa6, 0x32, 0xb8, 0xde, 0xc0, 0xa4, 0x32, 0xce, + 0xd4, 0x7b, 0x9f, 0xb7, 0x10, 0x8b, 0x20, 0xfb, 0x1c, 0xce, 0x28, 0x5d, 0xd8, 0xbe, 0xe5, 0xb5, + 0x02, 0x95, 0x56, 0x37, 0x8b, 0xb2, 0x33, 0x7d, 0x1f, 0x6a, 0xaa, 0x5e, 0x73, 0xa7, 0x95, 0x25, + 0x55, 0x3e, 0xdb, 0xd1, 0xf1, 0xa0, 0x6e, 0x74, 0x9a, 0x33, 0x5c, 0x3e, 0x83, 0xd1, 0xd2, 0xa9, + 0x1f, 0x65, 0x8b, 0x73, 0x0e, 0x2c, 0xc8, 0xb1, 0x5f, 0xc0, 0xa2, 0x14, 0x1f, 0xda, 0x29, 0xc1, + 0x5c, 0x48, 0xeb, 0x4d, 0x52, 0xbe, 0x94, 0x97, 0xf2, 0xf6, 0xbf, 0xa9, 0xc0, 0x9c, 0x7c, 0xaf, + 0xc4, 0x2e, 0x78, 0x5f, 0xa3, 0x6e, 0x3e, 0xcd, 0x41, 0xba, 0xc6, 0x05, 0x6c, 0x24, 0x04, 0xb1, + 0xf7, 0xdf, 0xcb, 0xee, 0xde, 0xa9, 0x01, 0x35, 0xb3, 0x83, 0x2f, 0x43, 0x65, 0xec, 0x25, 0xe7, + 0x68, 0x5f, 0xe3, 0xb4, 0x84, 0x69, 0x69, 0xa2, 0xaf, 0x9a, 0x26, 0xfa, 0xa2, 0x07, 0x49, 0xb8, + 0xaa, 0x9a, 0x7f, 0x90, 0xe4, 0x26, 0xd4, 0xb9, 0xb6, 0x91, 0x5a, 0xe1, 0x53, 0x20, 0xa3, 0x9d, + 0xd4, 0x72, 0xda, 0xc9, 0xdb, 0xeb, 0x0d, 0xdf, 0x82, 0x59, 0x7e, 0x29, 0x4f, 0x5c, 0xa2, 0x90, + 0x5b, 0x8a, 0x98, 0x49, 0xf9, 0x3f, 0x8f, 0xc1, 0x73, 0x44, 0x59, 0xfd, 0x5a, 0x7f, 0xc3, 0xbc, + 0xd6, 0xaf, 0x3b, 0x0f, 0x9a, 0x19, 0xe7, 0xc1, 0x7d, 0xe8, 0xa8, 0xe9, 0x43, 0x03, 0x5b, 0x10, + 0x8b, 0xf0, 0xf1, 0x1c, 0x9e, 0x6e, 0x8b, 0x6d, 0x63, 0x5b, 0x64, 0x12, 0x6e, 0x23, 0x49, 0xe8, + 0x68, 0x9c, 0x88, 0x6d, 0xd1, 0x7e, 0x02, 0x2d, 0xa3, 0x93, 0x6c, 0x1b, 0x12, 0xd7, 0x2a, 0x3a, + 0x33, 0xa4, 0x05, 0xf5, 0xdd, 0x7d, 0xf7, 0xc9, 0xde, 0xee, 0xd3, 0x9d, 0xe3, 0x8e, 0xc5, 0x92, + 0x47, 0xcf, 0x37, 0x37, 0xb7, 0xb7, 0xb7, 0x70, 0x5b, 0x02, 0x98, 0x7d, 0xb2, 0xb1, 0xcb, 0xb6, + 0xa8, 0xb2, 0xfd, 0x7f, 0x2c, 0x68, 0x68, 0xd5, 0x93, 0x6f, 0xab, 0x99, 0xe1, 0x37, 0xbf, 0x6f, + 0xe5, 0xbb, 0xb0, 0x26, 0x05, 0xb5, 0x36, 0x35, 0xea, 0x0d, 0x96, 0xd2, 0xd4, 0x37, 0x58, 0xd8, + 0xf2, 0x78, 0xbc, 0x06, 0x35, 0x0f, 0xfc, 0xf4, 0x94, 0x85, 0x79, 0x9c, 0x55, 0xba, 0xbb, 0xb0, + 0x92, 0xdc, 0x62, 0x98, 0x85, 0xed, 0x0f, 0x01, 0xd2, 0xde, 0x98, 0xc3, 0x9e, 0x31, 0x87, 0x6d, + 0x69, 0xc3, 0x2e, 0xd9, 0x5b, 0x5c, 0x60, 0x88, 0x29, 0x54, 0x5e, 0xe2, 0x6f, 0x00, 0x91, 0x06, + 0x2a, 0x8c, 0x67, 0x1c, 0x0f, 0x69, 0x22, 0x2f, 0x5b, 0x2d, 0x88, 0x9c, 0x5d, 0x95, 0x21, 0xef, + 0x0b, 0xa6, 0xb5, 0xa4, 0x72, 0x47, 0x50, 0x5c, 0x56, 0xee, 0x88, 0xa2, 0x8e, 0xca, 0xb7, 0x7b, + 0xd0, 0xdd, 0xa2, 0xac, 0xb6, 0x8d, 0xe1, 0x30, 0xd3, 0x1d, 0xfb, 0x06, 0x5c, 0x2f, 0xc8, 0x13, + 0xe6, 0x87, 0xef, 0xc1, 0xb5, 0x0d, 0x7e, 0xaf, 0xea, 0x8b, 0x0a, 0xe1, 0xb6, 0xbb, 0xb0, 0x9c, + 0xad, 0x52, 0x34, 0xf6, 0x04, 0x16, 0xb6, 0xe8, 0xc9, 0xe4, 0x6c, 0x8f, 0x5e, 0xa4, 0x0d, 0x11, + 0xa8, 0xc4, 0xe7, 0xe1, 0xa5, 0x98, 0x1f, 0xfc, 0x4d, 0x6e, 0x01, 0x0c, 0x59, 0x19, 0x37, 0x1e, + 0xd3, 0xbe, 0xbc, 0x59, 0x8f, 0xc8, 0xd1, 0x98, 0xf6, 0xed, 0x0f, 0x81, 0xe8, 0xf5, 0x88, 0xf9, + 0x62, 0x47, 0x82, 0xc9, 0x89, 0x1b, 0x5f, 0xc5, 0x09, 0x1d, 0xc9, 0x27, 0x03, 0x74, 0xc8, 0x7e, + 0x0f, 0x9a, 0x87, 0xde, 0x95, 0x43, 0x3f, 0x15, 0x6f, 0xfe, 0xac, 0xc0, 0xdc, 0xd8, 0xbb, 0x62, + 0xfc, 0xac, 0x5c, 0x28, 0x98, 0x6d, 0xff, 0x61, 0x05, 0x66, 0x79, 0x49, 0x56, 0xeb, 0x80, 0xc6, + 0x89, 0x1f, 0x20, 0x8f, 0xc9, 0x5a, 0x35, 0x28, 0x27, 0x30, 0x4b, 0x05, 0x02, 0x53, 0x98, 0xd2, + 0xe4, 0x0d, 0x65, 0x41, 0xb2, 0x06, 0xc6, 0xc4, 0x56, 0x7a, 0x35, 0x84, 0x53, 0x6a, 0x0a, 0x64, + 0x7c, 0x94, 0xe9, 0xc1, 0x83, 0xf7, 0x4f, 0xee, 0x05, 0x42, 0x26, 0xea, 0x50, 0xe1, 0xf1, 0x66, + 0x4e, 0x46, 0xbe, 0x67, 0x8e, 0x37, 0xb9, 0x63, 0x4c, 0xed, 0x2d, 0x8e, 0x31, 0xdc, 0xbe, 0xf6, + 0xba, 0x63, 0x0c, 0xbc, 0xcd, 0x31, 0xe6, 0x6d, 0x7c, 0x83, 0x3d, 0xa8, 0xe1, 0x9e, 0xae, 0x89, + 0x48, 0x99, 0x26, 0xbf, 0xa6, 0xe9, 0xf8, 0xdc, 0xcd, 0x7f, 0x23, 0xe5, 0x17, 0x87, 0x7e, 0xfa, + 0xe5, 0xa8, 0xf8, 0x3f, 0x82, 0x39, 0x81, 0x32, 0xca, 0x0e, 0xbc, 0x91, 0x7c, 0x19, 0x02, 0x7f, + 0xb3, 0xa9, 0xc3, 0x0b, 0xea, 0x9f, 0x4e, 0xfc, 0x88, 0x0e, 0xe4, 0xed, 0x49, 0x0d, 0xc2, 0xa8, + 0xe8, 0xd8, 0x7d, 0x19, 0x84, 0x97, 0x81, 0xb8, 0x3f, 0xa9, 0xd2, 0x36, 0x81, 0x0e, 0xbe, 0x10, + 0x33, 0x0e, 0x23, 0xf9, 0xd8, 0x87, 0xfd, 0x77, 0x2d, 0xe8, 0x08, 0x46, 0x53, 0x79, 0x32, 0x20, + 0xe0, 0x75, 0x97, 0x84, 0xef, 0x40, 0x0b, 0x6d, 0x19, 0x6a, 0xcb, 0x11, 0xce, 0x75, 0x03, 0x64, + 0xfd, 0x95, 0x61, 0x89, 0x23, 0x7f, 0x28, 0xe8, 0x56, 0x87, 0xe4, 0xae, 0x15, 0x79, 0xe2, 0xda, + 0x85, 0xe5, 0xa8, 0xb4, 0xfd, 0x47, 0x16, 0x2c, 0x68, 0x1d, 0x16, 0x8c, 0xfa, 0x31, 0x34, 0xd5, + 0x43, 0x4c, 0x54, 0x29, 0x55, 0x2b, 0xa6, 0x64, 0x49, 0x3f, 0x33, 0x0a, 0x23, 0xbd, 0x7b, 0x57, + 0xd8, 0xc1, 0x78, 0x32, 0x12, 0xda, 0x8c, 0x0e, 0x31, 0x3a, 0xba, 0xa4, 0xf4, 0xa5, 0x2a, 0xc2, + 0xf5, 0x29, 0x03, 0x43, 0x1f, 0x50, 0x18, 0x24, 0xe7, 0xaa, 0x50, 0x45, 0xf8, 0x80, 0x74, 0xd0, + 0xfe, 0x93, 0x12, 0x2c, 0x72, 0xa3, 0x9a, 0x30, 0x66, 0xaa, 0xb7, 0x30, 0x66, 0xb9, 0x7d, 0x91, + 0x0b, 0xad, 0x9d, 0x19, 0x47, 0xa4, 0xc9, 0xb7, 0xdf, 0xd2, 0x10, 0xa8, 0xee, 0x77, 0x4c, 0x59, + 0x8b, 0x72, 0xd1, 0x5a, 0xbc, 0x66, 0xa6, 0x8b, 0xdc, 0x71, 0xd5, 0x62, 0x77, 0xdc, 0xdb, 0xb9, + 0xbf, 0x72, 0x97, 0x20, 0xe6, 0x44, 0x29, 0xe3, 0x12, 0xc4, 0x3a, 0xac, 0x18, 0x00, 0xca, 0x6b, + 0xff, 0xd4, 0xa7, 0xf2, 0x46, 0xea, 0x42, 0x4c, 0x13, 0xd7, 0x28, 0xf2, 0x78, 0x0e, 0xaa, 0x71, + 0x3f, 0x1c, 0x53, 0x7b, 0x19, 0x96, 0xcc, 0xc9, 0x15, 0xbb, 0xc4, 0x2f, 0x2c, 0xe8, 0x3e, 0xe1, + 0x41, 0x15, 0x7e, 0x70, 0xb6, 0xe3, 0xc7, 0x49, 0x18, 0xa9, 0x27, 0x8b, 0x6e, 0x03, 0xc4, 0x89, + 0x17, 0x89, 0x73, 0x26, 0x57, 0x76, 0x35, 0x84, 0xcd, 0x11, 0x0d, 0x06, 0x3c, 0x97, 0xd3, 0x86, + 0x4a, 0xe7, 0x0e, 0x13, 0xc2, 0xe4, 0x68, 0xa8, 0xe4, 0x77, 0xf9, 0xdd, 0x2c, 0x36, 0x19, 0xf4, + 0x02, 0xb7, 0x5e, 0x6e, 0xc7, 0xcb, 0xa0, 0xf6, 0xef, 0x97, 0x60, 0x3e, 0xed, 0x24, 0xbf, 0xeb, + 0x69, 0x08, 0x70, 0xa1, 0x87, 0xa7, 0x02, 0x5c, 0xb8, 0x07, 0x5d, 0x9f, 0x29, 0xe6, 0x9a, 0xd5, + 0x51, 0x43, 0xc9, 0x1d, 0x68, 0xc8, 0x54, 0x38, 0x49, 0xb4, 0xb7, 0x43, 0x74, 0x98, 0xdf, 0x8d, + 0x60, 0x47, 0x03, 0x71, 0xcc, 0x11, 0x29, 0xbc, 0xa1, 0x3c, 0x4a, 0xf0, 0x4b, 0xbe, 0xa6, 0x32, + 0xc9, 0x04, 0x1a, 0xd3, 0xa9, 0xf9, 0x1a, 0xa2, 0x3e, 0xad, 0xeb, 0x9a, 0x35, 0xf5, 0xe6, 0x9a, + 0xe2, 0x79, 0x5e, 0x63, 0x7a, 0xfd, 0xa5, 0xe2, 0xe8, 0x90, 0xb4, 0xfa, 0x84, 0x13, 0xe3, 0xf8, + 0x6b, 0x60, 0xf6, 0xdf, 0xb4, 0xe0, 0x7a, 0xc1, 0x32, 0x0a, 0x19, 0xb0, 0x05, 0x0b, 0xa7, 0x2a, + 0x53, 0x4e, 0x35, 0x17, 0x04, 0xcb, 0x52, 0xb8, 0x9a, 0xd3, 0xeb, 0xe4, 0x3f, 0x50, 0xc7, 0x2d, + 0xbe, 0x78, 0xc6, 0x6d, 0xa7, 0x7c, 0x86, 0x7d, 0x08, 0xbd, 0xed, 0x57, 0x4c, 0xa4, 0x6c, 0xea, + 0x0f, 0xef, 0x4a, 0xca, 0x5a, 0xcf, 0x89, 0xcc, 0x37, 0x1b, 0x9b, 0x4f, 0xa1, 0x65, 0xd4, 0x45, + 0xbe, 0xf9, 0xb6, 0x95, 0xe8, 0xdc, 0xbf, 0x2a, 0x56, 0x9d, 0xbf, 0x1c, 0x2c, 0xef, 0x5c, 0x69, + 0x90, 0x7d, 0x01, 0xf3, 0xcf, 0x26, 0xc3, 0xc4, 0x4f, 0x5f, 0x11, 0x26, 0xdf, 0x16, 0x1f, 0x61, + 0x15, 0x72, 0xea, 0x0a, 0x9b, 0xd2, 0xcb, 0xb1, 0x19, 0x1b, 0xb1, 0x9a, 0xdc, 0x7c, 0x8b, 0xf9, + 0x0c, 0xfb, 0x3a, 0xac, 0xa4, 0x4d, 0xf2, 0xb9, 0x93, 0xdb, 0xce, 0x1f, 0x58, 0x3c, 0x24, 0xd8, + 0x7c, 0xd4, 0x98, 0x3c, 0x85, 0xc5, 0xd8, 0x0f, 0xce, 0x86, 0x54, 0xaf, 0x27, 0x16, 0x33, 0x71, + 0xcd, 0xec, 0x9e, 0x78, 0xf8, 0xd8, 0x29, 0xfa, 0x82, 0x11, 0x48, 0x71, 0x47, 0x53, 0x02, 0xc9, + 0x4c, 0x49, 0xd1, 0x00, 0xbe, 0x0b, 0x6d, 0xb3, 0x31, 0xf2, 0x48, 0x5c, 0x82, 0x4a, 0x7b, 0xa6, + 0x7b, 0x87, 0x4d, 0xca, 0x30, 0x4a, 0xda, 0x3f, 0xb7, 0xa0, 0xeb, 0x50, 0x46, 0xc6, 0x54, 0x6b, + 0x54, 0x50, 0xcf, 0xc7, 0xb9, 0x6a, 0xa7, 0x0f, 0x58, 0x5d, 0xae, 0x92, 0x63, 0x5d, 0x9b, 0xba, + 0x28, 0x3b, 0x33, 0x05, 0xa3, 0x7a, 0x5c, 0x83, 0x59, 0x31, 0xbe, 0x15, 0xb8, 0x26, 0xba, 0x24, + 0xbb, 0x93, 0xba, 0x15, 0x8d, 0x46, 0x0d, 0xb7, 0x62, 0x0f, 0xba, 0xfc, 0x65, 0x2a, 0x7d, 0x1c, + 0xe2, 0xc3, 0x2d, 0x20, 0xcf, 0xbc, 0xbe, 0x17, 0x85, 0x61, 0x70, 0x48, 0x23, 0x11, 0xc3, 0x89, + 0xda, 0x27, 0x7a, 0xdd, 0xa4, 0xa2, 0xcc, 0x53, 0xf2, 0x31, 0xa5, 0x30, 0x90, 0x8f, 0x56, 0xf1, + 0x94, 0xed, 0xc0, 0xe2, 0x63, 0xef, 0x25, 0x95, 0x35, 0xa5, 0xb3, 0xd4, 0x18, 0xab, 0x4a, 0xe5, + 0xdc, 0xcb, 0x5b, 0x90, 0xf9, 0x66, 0x1d, 0xbd, 0xb4, 0xbd, 0x0e, 0x4b, 0x66, 0x9d, 0x42, 0x94, + 0xf4, 0xa0, 0x36, 0x12, 0x98, 0xe8, 0x9d, 0x4a, 0xdf, 0xff, 0x0c, 0x1a, 0xda, 0x6b, 0x63, 0x64, + 0x05, 0x16, 0x5f, 0xec, 0x1e, 0xef, 0x6f, 0x1f, 0x1d, 0xb9, 0x87, 0xcf, 0x1f, 0x7f, 0xb2, 0xfd, + 0x03, 0x77, 0x67, 0xe3, 0x68, 0xa7, 0x33, 0x43, 0x96, 0x81, 0xec, 0x6f, 0x1f, 0x1d, 0x6f, 0x6f, + 0x19, 0xb8, 0x45, 0x6e, 0x43, 0xef, 0xf9, 0xfe, 0xf3, 0xa3, 0xed, 0x2d, 0xb7, 0xe8, 0xbb, 0x12, + 0xb9, 0x05, 0xd7, 0x45, 0x7e, 0xc1, 0xe7, 0xe5, 0xfb, 0x1f, 0x43, 0x27, 0x6b, 0x96, 0x34, 0xcc, + 0xb9, 0xaf, 0xb3, 0xfb, 0xde, 0xff, 0x47, 0x65, 0x80, 0xf4, 0x75, 0x58, 0xd2, 0x85, 0xa5, 0xad, + 0x8d, 0xe3, 0x8d, 0xbd, 0x03, 0xd6, 0x09, 0xe7, 0xe0, 0x78, 0x7b, 0xf3, 0xd8, 0x75, 0xb6, 0xbf, + 0xd7, 0x99, 0x29, 0xcc, 0x39, 0x38, 0x64, 0x47, 0xf6, 0x15, 0x58, 0xdc, 0xdd, 0xdf, 0x3d, 0xde, + 0xdd, 0xd8, 0x73, 0x9d, 0x83, 0xe7, 0xbb, 0xfb, 0x4f, 0xf9, 0x4b, 0x08, 0x65, 0xf2, 0x0e, 0xdc, + 0x78, 0x7e, 0xf8, 0xc4, 0x39, 0xd8, 0x3f, 0x76, 0x8f, 0x76, 0x9e, 0x1f, 0x6f, 0xe1, 0x3b, 0x0a, + 0x9b, 0xce, 0xee, 0x21, 0xaf, 0xb3, 0xf2, 0xba, 0x02, 0xac, 0xea, 0x2a, 0x9b, 0xb1, 0xa7, 0x07, + 0x47, 0x47, 0xbb, 0x87, 0xee, 0xf7, 0x9e, 0x6f, 0x3b, 0xbb, 0xdb, 0x47, 0xf8, 0xe1, 0x6c, 0x01, + 0xce, 0xca, 0xcf, 0x91, 0x05, 0x68, 0x1d, 0xef, 0x7d, 0xdf, 0x3d, 0xd8, 0xdf, 0x3d, 0xd8, 0xc7, + 0xa2, 0x35, 0x13, 0x62, 0xa5, 0xea, 0xa4, 0x07, 0xcb, 0xdb, 0xbf, 0x7d, 0xec, 0x16, 0xd4, 0x0c, + 0x53, 0xf2, 0xd8, 0x77, 0x0d, 0x72, 0x1d, 0xae, 0x1d, 0x1d, 0x6f, 0x1c, 0xef, 0x6e, 0xba, 0xe2, + 0x21, 0x15, 0xb6, 0x08, 0xec, 0xb3, 0x66, 0x71, 0x16, 0xfb, 0xaa, 0x45, 0x96, 0xa0, 0x73, 0xb8, + 0xf1, 0x83, 0x67, 0xdb, 0xfb, 0xc7, 0xee, 0xc6, 0xd6, 0x96, 0x83, 0x1f, 0xb4, 0x73, 0x28, 0x2b, + 0x3b, 0xcf, 0x16, 0xea, 0xd9, 0xe1, 0x21, 0x16, 0xe9, 0xc8, 0x04, 0xcb, 0x59, 0x58, 0xff, 0x79, + 0x19, 0xda, 0x3c, 0x98, 0x9e, 0x3f, 0xdf, 0x4e, 0x23, 0xf2, 0x0c, 0xe6, 0xc4, 0xdf, 0x01, 0x20, + 0xd7, 0xd4, 0xf5, 0x77, 0xfd, 0x2f, 0x0f, 0xf4, 0x96, 0xb3, 0xb0, 0x60, 0xbf, 0xc5, 0xbf, 0xfc, + 0x9f, 0xfe, 0xc7, 0xef, 0x95, 0x5a, 0xa4, 0xf1, 0xe0, 0xe2, 0x83, 0x07, 0x67, 0x34, 0x88, 0x59, + 0x1d, 0xbf, 0x03, 0x90, 0xbe, 0x6e, 0x4f, 0xba, 0xca, 0xfa, 0x98, 0x79, 0xfa, 0xbf, 0x77, 0xbd, + 0x20, 0x47, 0xd4, 0x7b, 0x1d, 0xeb, 0x5d, 0xb4, 0xdb, 0xac, 0x5e, 0x3f, 0xf0, 0x13, 0xfe, 0xd2, + 0xfd, 0x47, 0xd6, 0x7d, 0x32, 0x80, 0xa6, 0xfe, 0xee, 0x3c, 0x91, 0xde, 0xfc, 0x82, 0x97, 0xf3, + 0x7b, 0x37, 0x0a, 0xf3, 0xa4, 0xcc, 0xc1, 0x36, 0xae, 0xd9, 0x1d, 0xd6, 0xc6, 0x04, 0x4b, 0xa4, + 0xad, 0x0c, 0xb9, 0x24, 0x4e, 0x9f, 0x97, 0x27, 0x37, 0x35, 0xe1, 0x98, 0x7b, 0xdc, 0xbe, 0x77, + 0x6b, 0x4a, 0xae, 0x68, 0xeb, 0x16, 0xb6, 0xb5, 0x62, 0x13, 0xd6, 0x56, 0x1f, 0xcb, 0xc8, 0xc7, + 0xed, 0x3f, 0xb2, 0xee, 0xaf, 0xff, 0xde, 0x3d, 0xa8, 0xab, 0x48, 0x1f, 0xf2, 0x13, 0x68, 0x19, + 0xb7, 0x1d, 0x88, 0x1c, 0x46, 0xd1, 0xe5, 0x88, 0xde, 0xcd, 0xe2, 0x4c, 0xd1, 0xf0, 0x6d, 0x6c, + 0xb8, 0x4b, 0x96, 0x59, 0xc3, 0xe2, 0xba, 0xc0, 0x03, 0xbc, 0xb7, 0xc3, 0x1f, 0x13, 0x78, 0xa9, + 0xed, 0x38, 0xbc, 0xb1, 0x9b, 0xd9, 0x4d, 0xc0, 0x68, 0xed, 0xd6, 0x94, 0x5c, 0xd1, 0xdc, 0x4d, + 0x6c, 0x6e, 0x99, 0x2c, 0xe9, 0xcd, 0xa9, 0xe8, 0x1b, 0x8a, 0x0f, 0x7a, 0xe8, 0x2f, 0xaf, 0x93, + 0x5b, 0xe9, 0x73, 0x0b, 0x05, 0x2f, 0xb2, 0x2b, 0x12, 0xc9, 0x3f, 0xcb, 0x6e, 0x77, 0xb1, 0x29, + 0x42, 0x70, 0xf9, 0xf4, 0x87, 0xd7, 0xc9, 0x09, 0x34, 0xb4, 0x07, 0x4a, 0xc9, 0xf5, 0xa9, 0x8f, + 0xa9, 0xf6, 0x7a, 0x45, 0x59, 0x45, 0x43, 0xd1, 0xeb, 0x7f, 0xc0, 0x14, 0xd2, 0x1f, 0x41, 0x5d, + 0x3d, 0x79, 0x49, 0x56, 0xb4, 0x27, 0x48, 0xf5, 0x27, 0x3a, 0x7b, 0xdd, 0x7c, 0x46, 0x11, 0xf1, + 0xe9, 0xb5, 0x33, 0xe2, 0x7b, 0x01, 0x0d, 0xed, 0x59, 0x4b, 0x35, 0x80, 0xfc, 0xd3, 0x99, 0x6a, + 0x00, 0x05, 0xaf, 0x60, 0xda, 0x0b, 0xd8, 0x44, 0x83, 0xd4, 0x91, 0xbe, 0x93, 0x57, 0x61, 0x4c, + 0xf6, 0xe0, 0x9a, 0xd8, 0x59, 0x4f, 0xe8, 0xe7, 0x59, 0x86, 0x82, 0xc7, 0xee, 0x1f, 0x5a, 0xe4, + 0x63, 0xa8, 0xc9, 0xd7, 0x4b, 0xc9, 0x72, 0xf1, 0x2b, 0xac, 0xbd, 0x95, 0x1c, 0x2e, 0xb6, 0xc1, + 0x1f, 0x00, 0xa4, 0x6f, 0x68, 0x2a, 0x21, 0x91, 0x7b, 0x93, 0x53, 0x51, 0x40, 0xfe, 0xc1, 0x4d, + 0x7b, 0x19, 0x07, 0xd8, 0x21, 0x28, 0x24, 0x02, 0x7a, 0x29, 0x1f, 0x38, 0xfa, 0x31, 0x34, 0xb4, + 0x67, 0x34, 0xd5, 0xf4, 0xe5, 0x9f, 0xe0, 0x54, 0xd3, 0x57, 0xf0, 0xea, 0xa6, 0xdd, 0xc3, 0xda, + 0x97, 0xec, 0x79, 0x56, 0x7b, 0xec, 0x9f, 0x05, 0x23, 0x5e, 0x80, 0x2d, 0xd0, 0x39, 0xb4, 0x8c, + 0xb7, 0x32, 0x15, 0x87, 0x16, 0xbd, 0xc4, 0xa9, 0x38, 0xb4, 0xf0, 0x79, 0x4d, 0x49, 0x67, 0xf6, + 0x02, 0x6b, 0xe7, 0x02, 0x8b, 0x68, 0x2d, 0xfd, 0x10, 0x1a, 0xda, 0xbb, 0x97, 0x6a, 0x2c, 0xf9, + 0x27, 0x36, 0xd5, 0x58, 0x8a, 0x9e, 0xc9, 0x5c, 0xc2, 0x36, 0xda, 0x36, 0x92, 0x02, 0xbe, 0x42, + 0xc3, 0xea, 0xfe, 0x09, 0xb4, 0xcd, 0x97, 0x30, 0x15, 0xef, 0x17, 0xbe, 0xa9, 0xa9, 0x78, 0x7f, + 0xca, 0xf3, 0x99, 0x82, 0xa4, 0xef, 0x2f, 0xaa, 0x46, 0x1e, 0xfc, 0x4c, 0x04, 0x2e, 0x7f, 0x46, + 0xbe, 0xc7, 0x04, 0x9c, 0x78, 0xb7, 0x88, 0xac, 0x68, 0x54, 0xab, 0xbf, 0x6e, 0xa4, 0xf8, 0x25, + 0xf7, 0xc4, 0x91, 0x49, 0xcc, 0xfc, 0x1d, 0x9d, 0xa7, 0xb0, 0xa8, 0x88, 0x59, 0xbd, 0x43, 0x14, + 0xab, 0x31, 0x14, 0x3e, 0x77, 0xd4, 0xeb, 0x64, 0x73, 0x1f, 0x5a, 0x7c, 0xfb, 0xc3, 0xd7, 0x5e, + 0xb4, 0xed, 0x4f, 0x7f, 0x8a, 0x48, 0xdb, 0xfe, 0x8c, 0x47, 0x61, 0xb2, 0xdb, 0x5f, 0xe2, 0xb3, + 0x3a, 0x02, 0x98, 0xcf, 0x5c, 0xed, 0x54, 0xec, 0x55, 0x7c, 0xfb, 0xbe, 0x77, 0xfb, 0xf5, 0x37, + 0x42, 0x4d, 0x51, 0x24, 0xa5, 0xe9, 0x03, 0xf9, 0xd6, 0xc1, 0xef, 0x42, 0x53, 0x7f, 0xc0, 0x8f, + 0xe8, 0x32, 0x21, 0xdb, 0xd2, 0x8d, 0xc2, 0x3c, 0x93, 0x4a, 0x48, 0x53, 0x6f, 0x86, 0x7c, 0x1f, + 0x96, 0xd5, 0x34, 0xeb, 0xb7, 0x05, 0x63, 0xf2, 0x4e, 0xc1, 0x1d, 0x42, 0x63, 0xb2, 0xaf, 0x4f, + 0xbd, 0x64, 0xf8, 0xd0, 0x62, 0xd4, 0x67, 0xbe, 0x8a, 0x96, 0xee, 0x3c, 0x45, 0x8f, 0xc1, 0xa5, + 0x3b, 0x4f, 0xe1, 0x53, 0x6a, 0x92, 0xfa, 0xc8, 0xa2, 0x31, 0x47, 0x3c, 0x3e, 0x8b, 0xfc, 0x10, + 0xe6, 0xb5, 0xfb, 0xd8, 0x47, 0x57, 0x41, 0x5f, 0x71, 0x52, 0xfe, 0x51, 0x91, 0x5e, 0xd1, 0xb1, + 0xd4, 0x5e, 0xc1, 0xfa, 0x17, 0x6c, 0x63, 0x72, 0x18, 0x17, 0x6d, 0x42, 0x43, 0xbf, 0xeb, 0xfd, + 0x9a, 0x7a, 0x57, 0xb4, 0x2c, 0xfd, 0xa5, 0x8b, 0x87, 0x16, 0x39, 0xe4, 0x71, 0xba, 0xea, 0x1d, + 0xf7, 0x30, 0xca, 0xee, 0xc3, 0xe6, 0xfb, 0xee, 0x6a, 0x21, 0x8b, 0x5e, 0xf6, 0xbf, 0x67, 0x3d, + 0xb4, 0xc8, 0xdf, 0xb3, 0xa0, 0x69, 0xdc, 0xc5, 0x36, 0xa2, 0x1e, 0x33, 0x3d, 0xeb, 0xea, 0x79, + 0x7a, 0xd7, 0x6c, 0x07, 0x87, 0xbd, 0x77, 0xff, 0xbb, 0xc6, 0xb4, 0xfe, 0xcc, 0xb0, 0xcd, 0xae, + 0x65, 0x1f, 0x73, 0xff, 0x2c, 0x5b, 0x40, 0x7f, 0xca, 0xe5, 0xb3, 0x87, 0x16, 0xf9, 0x27, 0x16, + 0xb4, 0x4d, 0xa7, 0x8b, 0x1a, 0x6e, 0xa1, 0x7b, 0x47, 0x2d, 0xfe, 0x14, 0x4f, 0xcd, 0x0f, 0xb1, + 0x97, 0xc7, 0xf7, 0x1d, 0xa3, 0x97, 0xe2, 0x05, 0xbe, 0x5f, 0xad, 0xb7, 0xe4, 0x23, 0xfe, 0xb7, + 0x55, 0xa4, 0xbf, 0x99, 0xe4, 0xff, 0x16, 0x87, 0x22, 0x18, 0xfd, 0x2f, 0x57, 0xe0, 0x22, 0xfc, + 0x98, 0x3f, 0x62, 0x2e, 0x9d, 0x96, 0x8c, 0xee, 0xde, 0xf6, 0x7b, 0xfb, 0x0e, 0x8e, 0xe9, 0xb6, + 0x7d, 0xdd, 0x18, 0x53, 0x56, 0x55, 0xd8, 0xe0, 0xbd, 0x13, 0x7f, 0x74, 0x22, 0xdd, 0xeb, 0x72, + 0x7f, 0x88, 0x62, 0x7a, 0x27, 0x47, 0xbc, 0x93, 0xa2, 0xb8, 0xc1, 0x1c, 0x6f, 0x59, 0x8d, 0x7d, + 0x1f, 0xfb, 0x7a, 0xc7, 0x7e, 0x67, 0x6a, 0x5f, 0x1f, 0xa0, 0xeb, 0x84, 0xf5, 0xf8, 0x10, 0x20, + 0x8d, 0x0f, 0x21, 0x99, 0xd8, 0x04, 0x25, 0x32, 0xf2, 0x21, 0x24, 0x26, 0x07, 0xca, 0x10, 0x06, + 0x56, 0xe3, 0x8f, 0xb8, 0x00, 0xdc, 0x95, 0x51, 0x0d, 0xba, 0xbe, 0x64, 0x06, 0x71, 0x18, 0xfa, + 0x52, 0xb6, 0x7e, 0x43, 0xfc, 0xa9, 0x10, 0x89, 0xe7, 0xd0, 0xda, 0x0b, 0xc3, 0x97, 0x93, 0xb1, + 0x0a, 0x48, 0x34, 0xbd, 0x9a, 0x3b, 0x5e, 0x7c, 0xde, 0xcb, 0x8c, 0xc2, 0x5e, 0xc5, 0xaa, 0x7a, + 0xa4, 0xab, 0x55, 0xf5, 0xe0, 0x67, 0x69, 0xec, 0xc9, 0x67, 0xc4, 0x83, 0x05, 0x25, 0x55, 0x55, + 0xc7, 0x7b, 0x66, 0x35, 0x86, 0x2c, 0xcd, 0x36, 0x61, 0x28, 0xf6, 0xb2, 0xb7, 0x0f, 0x62, 0x59, + 0x27, 0xca, 0x94, 0xe6, 0x16, 0xed, 0xe3, 0x35, 0x4d, 0x74, 0x0d, 0x2e, 0x1a, 0xee, 0x25, 0xee, + 0x53, 0xec, 0xb5, 0x0c, 0xd0, 0xdc, 0x69, 0xc6, 0xde, 0x55, 0x44, 0x3f, 0x7d, 0xf0, 0x33, 0xe1, + 0x74, 0xfc, 0x4c, 0xee, 0x34, 0xd2, 0x2b, 0x6b, 0xec, 0x34, 0x19, 0x37, 0xae, 0xb1, 0xd3, 0xe4, + 0xdc, 0xb8, 0xc6, 0x54, 0x4b, 0xaf, 0x30, 0x19, 0xc2, 0x42, 0xce, 0xf3, 0xab, 0x36, 0x99, 0x69, + 0xfe, 0xe2, 0xde, 0xea, 0xf4, 0x02, 0x66, 0x6b, 0xf7, 0xcd, 0xd6, 0x8e, 0xa0, 0xb5, 0x45, 0xf9, + 0x64, 0xf1, 0x1b, 0x18, 0x99, 0x0b, 0xfd, 0xfa, 0xfd, 0x8e, 0xec, 0x96, 0x80, 0x79, 0xa6, 0x4e, + 0xc2, 0xdf, 0x93, 0xfb, 0x11, 0x34, 0x9e, 0xd2, 0x44, 0x5e, 0xb9, 0x50, 0x5a, 0x71, 0xe6, 0x0e, + 0x46, 0xaf, 0xe0, 0xc6, 0x86, 0x49, 0x33, 0x58, 0xdb, 0x03, 0x3a, 0x38, 0xa3, 0x5c, 0x38, 0xb9, + 0xfe, 0xe0, 0x33, 0xf2, 0xdb, 0x58, 0xb9, 0xba, 0x00, 0xb7, 0xac, 0xc5, 0xcf, 0xeb, 0x95, 0xcf, + 0x67, 0xf0, 0xa2, 0x9a, 0x83, 0x70, 0x40, 0x35, 0xed, 0x2c, 0x80, 0x86, 0x76, 0x81, 0x56, 0x31, + 0x50, 0xfe, 0xbe, 0xb1, 0x62, 0xa0, 0x82, 0xfb, 0xb6, 0xf6, 0x3d, 0x6c, 0xc7, 0x26, 0xab, 0x69, + 0x3b, 0xfc, 0x8e, 0x6d, 0xda, 0xd2, 0x83, 0x9f, 0x79, 0xa3, 0xe4, 0x33, 0xf2, 0x02, 0x1f, 0x7b, + 0xd4, 0xaf, 0x94, 0xa4, 0x6a, 0x7e, 0xf6, 0xf6, 0x89, 0x9a, 0x2c, 0x2d, 0xcb, 0x54, 0xfd, 0x79, + 0x53, 0xa8, 0x7b, 0x7d, 0x1b, 0xe0, 0x28, 0x09, 0xc7, 0x5b, 0x1e, 0x1d, 0x85, 0x41, 0x2a, 0x6b, + 0xd3, 0x0b, 0x0d, 0xa9, 0xfc, 0xd2, 0x6e, 0x35, 0x90, 0x17, 0xda, 0xb9, 0xc8, 0xb8, 0x95, 0x23, + 0x89, 0x6b, 0xea, 0x9d, 0x07, 0x35, 0x21, 0x05, 0xf7, 0x1e, 0x1e, 0x5a, 0x64, 0x03, 0x20, 0x75, + 0xfd, 0xab, 0x53, 0x4e, 0x2e, 0xaa, 0x40, 0x89, 0xbd, 0x82, 0x38, 0x81, 0x43, 0xa8, 0xa7, 0x8e, + 0xd2, 0x95, 0xf4, 0x3a, 0xbd, 0xe1, 0x56, 0x55, 0x3b, 0x78, 0xce, 0x7d, 0x69, 0x77, 0x70, 0xaa, + 0x80, 0xd4, 0xd8, 0x54, 0xa1, 0x4f, 0xd2, 0x87, 0x45, 0xde, 0x41, 0xa5, 0xe0, 0x60, 0x20, 0xbe, + 0x7a, 0xd3, 0x33, 0xef, 0x42, 0x54, 0xdc, 0x5c, 0xe8, 0x01, 0x33, 0x8c, 0x35, 0x8c, 0x5a, 0xf9, + 0x25, 0x00, 0x26, 0x9a, 0x47, 0xb0, 0x90, 0x73, 0xaa, 0x28, 0x96, 0x9e, 0xe6, 0x35, 0x53, 0x2c, + 0x3d, 0xd5, 0x1f, 0x63, 0x5f, 0xc3, 0x26, 0xe7, 0x6d, 0xc0, 0xc3, 0xd9, 0xa5, 0x9f, 0xf4, 0xcf, + 0x59, 0x73, 0x7f, 0x60, 0xc1, 0x62, 0x81, 0xcf, 0x84, 0xbc, 0x2b, 0xcf, 0xf9, 0x53, 0xfd, 0x29, + 0xbd, 0x42, 0x93, 0xba, 0x7d, 0x84, 0xed, 0x3c, 0x23, 0x9f, 0x18, 0x1b, 0x1b, 0xb7, 0x66, 0x0b, + 0xce, 0x7c, 0xad, 0x52, 0x51, 0xa8, 0x51, 0x7c, 0x0a, 0x2b, 0xbc, 0x23, 0x1b, 0xc3, 0x61, 0xc6, + 0xdc, 0x7f, 0x3b, 0xf7, 0xf7, 0x17, 0x0d, 0x37, 0x46, 0x6f, 0xfa, 0xdf, 0x67, 0x9c, 0xa2, 0x00, + 0xf3, 0xae, 0x92, 0x09, 0x74, 0xb2, 0x26, 0x74, 0x32, 0xbd, 0xae, 0xde, 0x3b, 0xc6, 0x89, 0xb5, + 0xc0, 0xec, 0xfe, 0x55, 0x6c, 0xec, 0x1d, 0xbb, 0x57, 0x34, 0x2f, 0xfc, 0x10, 0xcb, 0xd6, 0xe3, + 0x2f, 0x29, 0x7b, 0x7f, 0x66, 0x9c, 0xb2, 0x81, 0x69, 0x0e, 0x0a, 0x75, 0x66, 0x2e, 0x76, 0x17, + 0xdc, 0xc5, 0xe6, 0x57, 0xed, 0x1b, 0x45, 0xcd, 0x47, 0xfc, 0x13, 0x7e, 0x7a, 0x5e, 0xc9, 0xf2, + 0xb5, 0xec, 0xc1, 0x6a, 0xd1, 0x7a, 0x4f, 0x3d, 0xbd, 0x64, 0xe6, 0x7a, 0x06, 0x75, 0xbb, 0xa6, + 0x6e, 0xdf, 0x57, 0xec, 0x53, 0xe0, 0x48, 0x50, 0xec, 0x53, 0xe4, 0x10, 0x30, 0xf5, 0x1a, 0xe9, + 0x0a, 0xf8, 0xc8, 0xba, 0xff, 0xf8, 0xbd, 0x1f, 0x7e, 0xf5, 0xcc, 0x4f, 0xce, 0x27, 0x27, 0x6b, + 0xfd, 0x70, 0xf4, 0x60, 0x28, 0xed, 0x83, 0xe2, 0x72, 0xda, 0x83, 0x61, 0x30, 0x78, 0x80, 0xd5, + 0x9e, 0xcc, 0xe2, 0x1f, 0x8c, 0xfd, 0xe6, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x92, 0x0a, 0x1a, + 0x05, 0x62, 0x76, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/lnrpc/rpc.proto b/lnrpc/rpc.proto index 28cc409a..1f724878 100644 --- a/lnrpc/rpc.proto +++ b/lnrpc/rpc.proto @@ -967,6 +967,13 @@ message SendRequest { /// If set, circular payments to self are permitted. bool allow_self_payment = 14; + + /** + Features assumed to be supported by the final node. All transitive feature + depdencies must also be set properly. For a given feature bit pair, either + optional or remote may be set, but not both. + */ + repeated FeatureBit dest_features = 15; } message SendResponse { @@ -2696,6 +2703,26 @@ message PayReq { map features = 13 [json_name = "features"]; } +enum FeatureBit { + DATALOSS_PROTECT_REQ = 0; + DATALOSS_PROTECT_OPT = 1; + INITIAL_ROUING_SYNC = 3; + UPFRONT_SHUTDOWN_SCRIPT_REQ = 4; + UPFRONT_SHUTDOWN_SCRIPT_OPT = 5; + GOSSIP_QUERIES_REQ = 6; + GOSSIP_QUERIES_OPT = 7; + TLV_ONION_REQ = 8; + TLV_ONION_OPT = 9; + EXT_GOSSIP_QUERIES_REQ = 10; + EXT_GOSSIP_QUERIES_OPT = 11; + STATIC_REMOTE_KEY_REQ = 12; + STATIC_REMOTE_KEY_OPT = 13; + PAYMENT_ADDR_REQ = 14; + PAYMENT_ADDR_OPT = 15; + MPP_REQ = 16; + MPP_OPT = 17; +} + message Feature { string name = 2 [json_name = "name"]; bool is_required = 3 [json_name = "is_required"]; diff --git a/lnrpc/rpc.swagger.json b/lnrpc/rpc.swagger.json index bfcb4bbb..af574245 100644 --- a/lnrpc/rpc.swagger.json +++ b/lnrpc/rpc.swagger.json @@ -2271,6 +2271,29 @@ } } }, + "lnrpcFeatureBit": { + "type": "string", + "enum": [ + "DATALOSS_PROTECT_REQ", + "DATALOSS_PROTECT_OPT", + "INITIAL_ROUING_SYNC", + "UPFRONT_SHUTDOWN_SCRIPT_REQ", + "UPFRONT_SHUTDOWN_SCRIPT_OPT", + "GOSSIP_QUERIES_REQ", + "GOSSIP_QUERIES_OPT", + "TLV_ONION_REQ", + "TLV_ONION_OPT", + "EXT_GOSSIP_QUERIES_REQ", + "EXT_GOSSIP_QUERIES_OPT", + "STATIC_REMOTE_KEY_REQ", + "STATIC_REMOTE_KEY_OPT", + "PAYMENT_ADDR_REQ", + "PAYMENT_ADDR_OPT", + "MPP_REQ", + "MPP_OPT" + ], + "default": "DATALOSS_PROTECT_REQ" + }, "lnrpcFeeLimit": { "type": "object", "properties": { @@ -3845,6 +3868,13 @@ "type": "boolean", "format": "boolean", "description": "/ If set, circular payments to self are permitted." + }, + "dest_features": { + "type": "array", + "items": { + "$ref": "#/definitions/lnrpcFeatureBit" + }, + "description": "*\nFeatures assumed to be supported by the final node. All transitive feature\ndepdencies must also be set properly. For a given feature bit pair, either\noptional or remote may be set, but not both." } } }, From 35dd5f354d44691991a9bc6a694947e710377e02 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:57:38 -0800 Subject: [PATCH 18/19] routerrpc: parse dest_features bits for manual SendPayment --- lnrpc/routerrpc/router_backend.go | 23 +++++++++++++++++++++++ rpcserver.go | 8 ++++++++ 2 files changed, 31 insertions(+) diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index 383180a3..acd3125a 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -633,6 +633,14 @@ func (r *RouterBackend) extractIntentFromSendRequest( // Payment hash. copy(payIntent.PaymentHash[:], rpcPayReq.PaymentHash) + + // Parse destination feature bits. + features, err := UnmarshalFeatures(rpcPayReq.DestFeatures) + if err != nil { + return nil, err + } + + payIntent.DestFeatures = features } // Currently, within the bootstrap phase of the network, we limit the @@ -699,6 +707,21 @@ func unmarshallHopHint(rpcHint *lnrpc.HopHint) (zpay32.HopHint, error) { }, nil } +// UnmarshalFeatures converts a list of uint32's into a valid feature vector. +// This method checks that feature bit pairs aren't assigned toegether, and +// validates transitive depdencies. +func UnmarshalFeatures(rpcFeatures []lnrpc.FeatureBit) (*lnwire.FeatureVector, error) { + raw := lnwire.NewRawFeatureVector() + for _, bit := range rpcFeatures { + err := raw.SafeSet(lnwire.FeatureBit(bit)) + if err != nil { + return nil, err + } + } + + return lnwire.NewFeatureVector(raw, lnwire.Features), nil +} + // ValidatePayReqExpiry checks if the passed payment request has expired. In // the case it has expired, an error will be returned. func ValidatePayReqExpiry(payReq *zpay32.Invoice) error { diff --git a/rpcserver.go b/rpcserver.go index 1e5e71b1..239df76d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3442,6 +3442,14 @@ func (r *rpcServer) extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPayme copy(payIntent.rHash[:], rpcPayReq.PaymentHash) } + // Unmarshal any custom destination features. + payIntent.destFeatures, err = routerrpc.UnmarshalFeatures( + rpcPayReq.DestFeatures, + ) + if err != nil { + return payIntent, err + } + // Currently, within the bootstrap phase of the network, we limit the // largest payment size allotted to (2^32) - 1 mSAT or 4.29 million // satoshis. From 1dbeb34a66bcb06638fac978c16c1389dc06333a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 18 Dec 2019 23:58:11 -0800 Subject: [PATCH 19/19] feature/default_sets: expose optional mpp and pay_addr features IN9 --- feature/default_sets.go | 10 ++++++++++ lnwire/features.go | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/feature/default_sets.go b/feature/default_sets.go index 5d285c0e..32807654 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -33,4 +33,14 @@ var defaultSetDesc = setDesc{ SetInit: {}, // I SetNodeAnn: {}, // N }, + lnwire.PaymentAddrOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + SetInvoice: {}, // 9 + }, + lnwire.MPPOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + SetInvoice: {}, // 9 + }, } diff --git a/lnwire/features.go b/lnwire/features.go index 0feb7627..db170f6d 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -134,6 +134,10 @@ var Features = map[FeatureBit]string{ TLVOnionPayloadOptional: "tlv-onion", StaticRemoteKeyOptional: "static-remote-key", StaticRemoteKeyRequired: "static-remote-key", + PaymentAddrOptional: "payment-addr", + PaymentAddrRequired: "payment-addr", + MPPOptional: "multi-path-payments", + MPPRequired: "multi-path-payments", } // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A