diff --git a/liquidity/fees.go b/liquidity/fees.go index f5555f3..443c34d 100644 --- a/liquidity/fees.go +++ b/liquidity/fees.go @@ -37,6 +37,11 @@ const ( // defaultSweepFeeRateLimit is the default limit we place on estimated // sweep fees, (750 * 4 /1000 = 3 sat/vByte). defaultSweepFeeRateLimit = chainfee.SatPerKWeight(750) + + // minerMultiplier is a multiplier we use to scale our miner fee to + // ensure that we will still be able to complete our swap in the case + // of a severe fee spike. + minerMultiplier = 100 ) var ( @@ -55,6 +60,10 @@ var ( // ErrZeroPrepay is returned if a zero maximum prepay is set. ErrZeroPrepay = errors.New("maximum prepay must be non-zero") + // ErrInvalidPPM is returned is the parts per million for a fee rate + // are invalid. + ErrInvalidPPM = errors.New("invalid ppm") + // ErrInvalidSweepFeeRateLimit is returned if an invalid sweep fee limit // is set. ErrInvalidSweepFeeRateLimit = fmt.Errorf("sweep fee rate limit must "+ @@ -224,3 +233,144 @@ func (f *FeeCategoryLimit) loopOutFees(amount btcutil.Amount, return prepayMaxFee, routeMaxFee, f.MaximumMinerFee } + +// Compile time assertion that FeePortion implements FeeLimit interface. +var _ FeeLimit = (*FeePortion)(nil) + +// FeePortion is a fee limitation which limits fees to a set portion of +// the swap amount. +type FeePortion struct { + // PartsPerMillion is the total portion of the swap amount that the + // swap may consume. + PartsPerMillion uint64 +} + +// NewFeePortion creates a fee limit based on a flat percentage of swap amount. +func NewFeePortion(ppm uint64) *FeePortion { + return &FeePortion{ + PartsPerMillion: ppm, + } +} + +// String returns a string representation of the fee limit. +func (f *FeePortion) String() string { + return fmt.Sprintf("parts per million: %v", f.PartsPerMillion) +} + +// validate returns an error if the values provided are invalid. +func (f *FeePortion) validate() error { + if f.PartsPerMillion <= 0 { + return ErrInvalidPPM + } + + return nil +} + +// mayLoopOut checks our estimated loop out sweep fee against our sweep limit. +// For fee percentage, we do not check anything because we need the full quote +// to determine whether we can perform a swap. +func (f *FeePortion) mayLoopOut(_ chainfee.SatPerKWeight) error { + return nil +} + +// loopOutLimits checks whether the quote provided is within our fee +// limits for the swap amount. +func (f *FeePortion) loopOutLimits(swapAmt btcutil.Amount, + quote *loop.LoopOutQuote) error { + + // First, check whether any of the individual fee categories provided + // by the server are more than our total limit. We do this so that we + // can provide more specific reasons for not executing swaps. + feeLimit := ppmToSat(swapAmt, f.PartsPerMillion) + minerFee := scaleMinerFee(quote.MinerFee) + + if minerFee > feeLimit { + log.Debugf("miner fee: %v greater than fee limit: %v, at "+ + "%v ppm", minerFee, feeLimit, f.PartsPerMillion) + + return newReasonError(ReasonMinerFee) + } + + if quote.SwapFee > feeLimit { + log.Debugf("swap fee: %v greater than fee limit: %v, at "+ + "%v ppm", quote.SwapFee, feeLimit, f.PartsPerMillion) + + return newReasonError(ReasonSwapFee) + } + + if quote.PrepayAmount > feeLimit { + log.Debugf("prepay amount: %v greater than fee limit: %v, at "+ + "%v ppm", quote.PrepayAmount, feeLimit, f.PartsPerMillion) + + return newReasonError(ReasonPrepay) + } + + // If our miner and swap fee equal our limit, we will have nothing left + // for off-chain fees, so we fail out early. + if minerFee+quote.SwapFee >= feeLimit { + log.Debugf("no budget for off-chain routing with miner fee: "+ + "%v, swap fee: %v and fee limit: %v, at %v ppm", + minerFee, quote.SwapFee, feeLimit, f.PartsPerMillion) + + return newReasonError(ReasonFeePPMInsufficient) + } + + prepay, route, miner := f.loopOutFees(swapAmt, quote) + + // Calculate the worst case fees that we could pay for this swap, + // ensuring that we are within our fee limit even if the swap fails. + fees := worstCaseOutFees( + prepay, route, quote.SwapFee, miner, quote.PrepayAmount, + ) + + if fees > feeLimit { + log.Debugf("total fees for swap: %v > fee limit: %v, at "+ + "%v ppm", fees, feeLimit, f.PartsPerMillion) + + return newReasonError(ReasonFeePPMInsufficient) + } + + return nil +} + +// loopOutFees return the maximum prepay and invoice routing fees for a swap +// amount and quote. Note that the fee portion implementation just returns +// the quote's miner fee, assuming that this value has already been validated. +// We also assume that the quote's minerfee + swapfee < fee limit, so that we +// have some fees left for off-chain routing. +func (f *FeePortion) loopOutFees(amount btcutil.Amount, + quote *loop.LoopOutQuote) (btcutil.Amount, btcutil.Amount, + btcutil.Amount) { + + // Calculate the total amount we can spend in fees, and subtract the + // amounts provided by the quote to get the total available for + // off-chain fees. + feeLimit := ppmToSat(amount, f.PartsPerMillion) + minerFee := scaleMinerFee(quote.MinerFee) + + available := feeLimit - minerFee - quote.SwapFee + + prepayMaxFee, routeMaxFee := splitOffChain( + available, quote.PrepayAmount, amount, + ) + + return prepayMaxFee, routeMaxFee, minerFee +} + +// splitOffChain takes an available fee budget and divides it among our prepay +// and swap payments proportional to their volume. +func splitOffChain(available, prepayAmt, + swapAmt btcutil.Amount) (btcutil.Amount, btcutil.Amount) { + + total := swapAmt + prepayAmt + + prepayMaxFee := available * prepayAmt / total + routeMaxFee := available * swapAmt / total + + return prepayMaxFee, routeMaxFee +} + +// scaleMinerFee scales our miner fee by our constant multiplier. +func scaleMinerFee(estimate btcutil.Amount) btcutil.Amount { + return estimate * btcutil.Amount(minerMultiplier) +} diff --git a/liquidity/liquidity_test.go b/liquidity/liquidity_test.go index 9d9564c..5972acf 100644 --- a/liquidity/liquidity_test.go +++ b/liquidity/liquidity_test.go @@ -151,6 +151,19 @@ func newTestConfig() (*Config, *test.LndMockServices) { }, lnd } +// testPPMFees calculates the split of fees between prepay and swap invoice +// for the swap amount and ppm, relying on the test quote. +func testPPMFees(ppm uint64, quote *loop.LoopOutQuote, + swapAmount btcutil.Amount) (btcutil.Amount, btcutil.Amount) { + + feeTotal := ppmToSat(swapAmount, ppm) + feeAvailable := feeTotal - scaleMinerFee(quote.MinerFee) - quote.SwapFee + + return splitOffChain( + feeAvailable, quote.PrepayAmount, swapAmount, + ) +} + // TestParameters tests getting and setting of parameters for our manager. func TestParameters(t *testing.T) { cfg, _ := newTestConfig() @@ -1269,6 +1282,147 @@ func TestSizeRestrictions(t *testing.T) { } } +// TestFeePercentage tests use of a flat fee percentage to limit the fees we +// pay for swaps. Our test is setup to require a 7500 sat swap, and we test +// this amount against various fee percentages and server quotes. +func TestFeePercentage(t *testing.T) { + var ( + okPPM uint64 = 30000 + okQuote = &loop.LoopOutQuote{ + SwapFee: 15, + PrepayAmount: 30, + MinerFee: 1, + } + + rec = loop.OutRequest{ + Amount: 7500, + OutgoingChanSet: loopdb.ChannelSet{chanID1.ToUint64()}, + MaxMinerFee: scaleMinerFee(okQuote.MinerFee), + MaxSwapFee: okQuote.SwapFee, + MaxPrepayAmount: okQuote.PrepayAmount, + SweepConfTarget: loop.DefaultSweepConfTarget, + Initiator: autoloopSwapInitiator, + } + ) + + rec.MaxPrepayRoutingFee, rec.MaxSwapRoutingFee = testPPMFees( + okPPM, okQuote, 7500, + ) + + tests := []struct { + name string + feePPM uint64 + quote *loop.LoopOutQuote + suggestions *Suggestions + }{ + { + // With our limit set to 3% of swap amount 7500, we + // have a total budget of 225 sat. + name: "fees ok", + feePPM: okPPM, + quote: okQuote, + suggestions: &Suggestions{ + OutSwaps: []loop.OutRequest{ + rec, + }, + DisqualifiedChans: noneDisqualified, + DisqualifiedPeers: noPeersDisqualified, + }, + }, + { + name: "swap fee too high", + feePPM: 20000, + quote: &loop.LoopOutQuote{ + SwapFee: 300, + PrepayAmount: 30, + MinerFee: 1, + }, + suggestions: &Suggestions{ + DisqualifiedChans: map[lnwire.ShortChannelID]Reason{ + chanID1: ReasonSwapFee, + }, + DisqualifiedPeers: noPeersDisqualified, + }, + }, + { + name: "miner fee too high", + feePPM: 20000, + quote: &loop.LoopOutQuote{ + SwapFee: 80, + PrepayAmount: 30, + MinerFee: 300, + }, + suggestions: &Suggestions{ + DisqualifiedChans: map[lnwire.ShortChannelID]Reason{ + chanID1: ReasonMinerFee, + }, + DisqualifiedPeers: noPeersDisqualified, + }, + }, + { + name: "miner and swap too high", + feePPM: 20000, + quote: &loop.LoopOutQuote{ + SwapFee: 60, + PrepayAmount: 30, + MinerFee: 1, + }, + suggestions: &Suggestions{ + DisqualifiedChans: map[lnwire.ShortChannelID]Reason{ + chanID1: ReasonFeePPMInsufficient, + }, + DisqualifiedPeers: noPeersDisqualified, + }, + }, + { + name: "prepay too high", + feePPM: 30000, + quote: &loop.LoopOutQuote{ + SwapFee: 75, + PrepayAmount: 300, + MinerFee: 1, + }, + suggestions: &Suggestions{ + DisqualifiedChans: map[lnwire.ShortChannelID]Reason{ + chanID1: ReasonPrepay, + }, + DisqualifiedPeers: noPeersDisqualified, + }, + }, + } + + for _, testCase := range tests { + testCase := testCase + + t.Run(testCase.name, func(t *testing.T) { + cfg, lnd := newTestConfig() + + cfg.LoopOutQuote = func(_ context.Context, + _ *loop.LoopOutQuoteRequest) (*loop.LoopOutQuote, + error) { + + return testCase.quote, nil + + } + + lnd.Channels = []lndclient.ChannelInfo{ + channel1, + } + + params := defaultParameters + params.FeeLimit = NewFeePortion(testCase.feePPM) + params.ChannelRules = map[lnwire.ShortChannelID]*ThresholdRule{ + chanID1: chanRule, + } + + testSuggestSwaps( + t, newSuggestSwapsSetup(cfg, lnd, params), + testCase.suggestions, nil, + ) + }) + } +} + // testSuggestSwapsSetup contains the elements that are used to create a // suggest swaps test. type testSuggestSwapsSetup struct { diff --git a/liquidity/reasons.go b/liquidity/reasons.go index c97616f..00601e8 100644 --- a/liquidity/reasons.go +++ b/liquidity/reasons.go @@ -61,6 +61,10 @@ const ( // from budget elapsed, because we still have some budget available, // but we have allocated it to other swaps. ReasonBudgetInsufficient + + // ReasonFeePPMInsufficient indicates that the fees a swap would require + // are greater than the portion of swap amount allocated to fees. + ReasonFeePPMInsufficient ) // String returns a string representation of a reason. @@ -105,6 +109,9 @@ func (r Reason) String() string { case ReasonBudgetInsufficient: return "budget insufficient" + case ReasonFeePPMInsufficient: + return "fee portion insufficient" + default: return "unknown" } diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index d7ebbc2..490ddc6 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -859,6 +859,9 @@ func rpcAutoloopReason(reason liquidity.Reason) (looprpc.AutoReason, error) { case liquidity.ReasonBudgetInsufficient: return looprpc.AutoReason_AUTO_REASON_BUDGET_INSUFFICIENT, nil + case liquidity.ReasonFeePPMInsufficient: + return looprpc.AutoReason_AUTO_REASON_SWAP_FEE, nil + default: return 0, fmt.Errorf("unknown autoloop reason: %v", reason) } diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index 8025431..8e54ed0 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -251,6 +251,10 @@ const ( //because we still have some budget available, but we have allocated it to //other swaps. AutoReason_AUTO_REASON_BUDGET_INSUFFICIENT AutoReason = 12 + // + //Fee insufficient indicates that the fee estimate for a swap is higher than + //the portion of total swap amount that we allow fees to consume. + AutoReason_AUTO_REASON_FEE_INSUFFICIENT AutoReason = 13 ) var AutoReason_name = map[int32]string{ @@ -267,6 +271,7 @@ var AutoReason_name = map[int32]string{ 10: "AUTO_REASON_LOOP_IN", 11: "AUTO_REASON_LIQUIDITY_OK", 12: "AUTO_REASON_BUDGET_INSUFFICIENT", + 13: "AUTO_REASON_FEE_INSUFFICIENT", } var AutoReason_value = map[string]int32{ @@ -283,6 +288,7 @@ var AutoReason_value = map[string]int32{ "AUTO_REASON_LOOP_IN": 10, "AUTO_REASON_LIQUIDITY_OK": 11, "AUTO_REASON_BUDGET_INSUFFICIENT": 12, + "AUTO_REASON_FEE_INSUFFICIENT": 13, } func (x AutoReason) String() string { @@ -2208,171 +2214,172 @@ func init() { func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) } var fileDescriptor_014de31d7ac8c57c = []byte{ - // 2624 bytes of a gzipped FileDescriptorProto + // 2633 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x73, 0xe3, 0xc6, 0xb1, 0x5f, 0xfe, 0x13, 0xc9, 0x26, 0x48, 0x42, 0xa3, 0x5d, 0x89, 0xa2, 0x65, 0xaf, 0x16, 0xf6, 0x3e, 0xcb, 0xb2, 0xbd, 0x7a, 0x96, 0x4f, 0x76, 0xd9, 0xaf, 0x8a, 0xa2, 0xa0, 0x15, 0xd7, 0x12, 0x49, 0x83, 0xe4, 0xba, 0xf6, 0xd5, 0xab, 0x42, 0x8d, 0xc8, 0x91, 0x84, 0x32, 0xf1, 0x67, 0x81, - 0xe1, 0xae, 0x54, 0xae, 0x97, 0x54, 0xa5, 0xe2, 0x73, 0x0e, 0xf9, 0x06, 0xb9, 0xe7, 0x96, 0x5b, - 0x3e, 0x40, 0x2e, 0x39, 0x25, 0xb9, 0xe5, 0x9a, 0x4b, 0x0e, 0xf9, 0x0e, 0xa9, 0xe9, 0x01, 0x40, - 0x80, 0x22, 0xe5, 0xe4, 0x90, 0x9b, 0xd8, 0xfd, 0x9b, 0x9e, 0xe9, 0xff, 0xdd, 0x10, 0x28, 0xe3, - 0xa9, 0xc5, 0x1c, 0xfe, 0xcc, 0xf3, 0x5d, 0xee, 0x92, 0xe2, 0xd4, 0x75, 0x3d, 0xdf, 0x1b, 0x37, - 0x77, 0xae, 0x5c, 0xf7, 0x6a, 0xca, 0x0e, 0xa8, 0x67, 0x1d, 0x50, 0xc7, 0x71, 0x39, 0xe5, 0x96, - 0xeb, 0x04, 0x12, 0xa6, 0xfd, 0x36, 0x0f, 0xb5, 0x33, 0xd7, 0xf5, 0x7a, 0x33, 0x6e, 0xb0, 0xd7, - 0x33, 0x16, 0x70, 0xa2, 0x42, 0x8e, 0xda, 0xbc, 0x91, 0xd9, 0xcd, 0xec, 0xe5, 0x0c, 0xf1, 0x27, - 0x21, 0x90, 0x9f, 0xb0, 0x80, 0x37, 0xb2, 0xbb, 0x99, 0xbd, 0xb2, 0x81, 0x7f, 0x93, 0x03, 0x78, - 0x68, 0xd3, 0x1b, 0x33, 0x78, 0x4b, 0x3d, 0xd3, 0x77, 0x67, 0xdc, 0x72, 0xae, 0xcc, 0x4b, 0xc6, - 0x1a, 0x39, 0x3c, 0xb6, 0x6e, 0xd3, 0x9b, 0xc1, 0x5b, 0xea, 0x19, 0x92, 0x73, 0xc2, 0x18, 0xf9, - 0x1c, 0x36, 0xc5, 0x01, 0xcf, 0x67, 0x1e, 0xbd, 0x4d, 0x1d, 0xc9, 0xe3, 0x91, 0x0d, 0x9b, 0xde, - 0xf4, 0x91, 0x99, 0x38, 0xb4, 0x0b, 0x4a, 0x7c, 0x8b, 0x80, 0x16, 0x10, 0x0a, 0xa1, 0x74, 0x81, - 0xf8, 0x00, 0x6a, 0x09, 0xb1, 0xe2, 0xe1, 0x6b, 0x88, 0x51, 0x62, 0x71, 0x2d, 0x9b, 0x13, 0x0d, - 0xaa, 0x02, 0x65, 0x5b, 0x0e, 0xf3, 0x51, 0x50, 0x11, 0x41, 0x15, 0x9b, 0xde, 0x9c, 0x0b, 0x9a, - 0x90, 0xf4, 0x09, 0xa8, 0xc2, 0x66, 0xa6, 0x3b, 0xe3, 0xe6, 0xf8, 0x9a, 0x3a, 0x0e, 0x9b, 0x36, - 0x4a, 0xbb, 0x99, 0xbd, 0xfc, 0x51, 0xb6, 0x91, 0x31, 0x6a, 0x53, 0x69, 0xa5, 0xb6, 0xe4, 0x90, - 0x7d, 0x58, 0x77, 0x67, 0xfc, 0xca, 0x15, 0x4a, 0x08, 0xb4, 0x19, 0x30, 0xde, 0xa8, 0xec, 0xe6, - 0xf6, 0xf2, 0x46, 0x3d, 0x62, 0x08, 0xec, 0x80, 0x71, 0x81, 0x0d, 0xde, 0x32, 0xe6, 0x99, 0x63, - 0xd7, 0xb9, 0x34, 0x39, 0xf5, 0xaf, 0x18, 0x6f, 0x94, 0x77, 0x33, 0x7b, 0x05, 0xa3, 0x8e, 0x8c, - 0xb6, 0xeb, 0x5c, 0x0e, 0x91, 0x4c, 0x3e, 0x05, 0x72, 0xcd, 0xa7, 0x63, 0x84, 0x5a, 0xbe, 0x2d, - 0x9d, 0xd5, 0xa8, 0x22, 0x78, 0x5d, 0x70, 0xda, 0x49, 0x06, 0xf9, 0x12, 0xb6, 0xd1, 0x38, 0xde, - 0xec, 0x62, 0x6a, 0x8d, 0x91, 0x68, 0x4e, 0x18, 0x9d, 0x4c, 0x2d, 0x87, 0x35, 0x40, 0xbc, 0xde, - 0xd8, 0x12, 0x80, 0xfe, 0x9c, 0x7f, 0x1c, 0xb2, 0xc9, 0x43, 0x28, 0x4c, 0xe9, 0x05, 0x9b, 0x36, - 0x14, 0xf4, 0xab, 0xfc, 0x41, 0x76, 0xa0, 0x6c, 0x39, 0x16, 0xb7, 0x28, 0x77, 0xfd, 0x46, 0x0d, - 0x39, 0x73, 0x82, 0xf6, 0x63, 0x16, 0xaa, 0x22, 0x5e, 0x3a, 0xce, 0xea, 0x70, 0x59, 0x74, 0x5a, - 0xf6, 0x8e, 0xd3, 0xee, 0xb8, 0x23, 0x77, 0xd7, 0x1d, 0xdb, 0x50, 0x9a, 0xd2, 0x80, 0x9b, 0xd7, - 0xae, 0x87, 0x11, 0xa2, 0x18, 0x45, 0xf1, 0xfb, 0xd4, 0xf5, 0xc8, 0xfb, 0x50, 0x65, 0x37, 0x9c, - 0xf9, 0x0e, 0x9d, 0x9a, 0xc2, 0x24, 0x18, 0x16, 0x25, 0x43, 0x89, 0x88, 0xa7, 0x7c, 0x3a, 0x26, - 0x7b, 0xa0, 0xc6, 0x86, 0x8c, 0x6c, 0xbe, 0x86, 0x66, 0xac, 0x45, 0x66, 0x0c, 0x4d, 0x1e, 0xdb, - 0xa1, 0xb8, 0xd2, 0x0e, 0xa5, 0x45, 0x3b, 0xfc, 0x3d, 0x03, 0x0a, 0x06, 0x38, 0x0b, 0x3c, 0xd7, - 0x09, 0x18, 0x21, 0x90, 0xb5, 0x26, 0x68, 0x85, 0x32, 0xc6, 0x4b, 0xd6, 0x9a, 0x08, 0x15, 0xac, - 0x89, 0x79, 0x71, 0xcb, 0x59, 0x80, 0x1a, 0x2a, 0x46, 0xd1, 0x9a, 0x1c, 0x89, 0x9f, 0xe4, 0x29, - 0x28, 0xf8, 0x3a, 0x3a, 0x99, 0xf8, 0x2c, 0x08, 0x64, 0x6a, 0xe1, 0xc1, 0x8a, 0xa0, 0xb7, 0x24, - 0x99, 0x3c, 0x83, 0x8d, 0x24, 0xcc, 0x74, 0xbc, 0xc3, 0xb7, 0xc1, 0x35, 0xda, 0xa3, 0x2c, 0xc3, - 0x21, 0x44, 0x76, 0x91, 0x41, 0x3e, 0x09, 0xa3, 0x27, 0xc2, 0x4b, 0x78, 0x01, 0xe1, 0x6a, 0x02, - 0xde, 0x47, 0xf4, 0x53, 0xa8, 0x05, 0xcc, 0x7f, 0xc3, 0x7c, 0xd3, 0x66, 0x41, 0x40, 0xaf, 0x18, - 0x1a, 0xa8, 0x6c, 0x54, 0x25, 0xf5, 0x5c, 0x12, 0x35, 0x15, 0x6a, 0xe7, 0xae, 0x63, 0x71, 0xd7, - 0x0f, 0x7d, 0xae, 0xfd, 0x2e, 0x0f, 0x20, 0xb4, 0x1f, 0x70, 0xca, 0x67, 0xc1, 0xd2, 0x8a, 0x21, - 0xac, 0x91, 0x5d, 0x69, 0x8d, 0xca, 0xa2, 0x35, 0xf2, 0xfc, 0xd6, 0x93, 0x61, 0x50, 0x3b, 0x5c, - 0x7f, 0x16, 0xd6, 0xae, 0x67, 0xe2, 0x8e, 0xe1, 0xad, 0xc7, 0x0c, 0x64, 0x93, 0x3d, 0x28, 0x04, - 0x9c, 0x72, 0x59, 0x31, 0x6a, 0x87, 0x24, 0x85, 0x13, 0x6f, 0x61, 0x86, 0x04, 0x90, 0xaf, 0xa1, - 0x76, 0x49, 0xad, 0xe9, 0xcc, 0x67, 0xa6, 0xcf, 0x68, 0xe0, 0x3a, 0x18, 0xc9, 0xb5, 0xc3, 0xcd, - 0xf8, 0xc8, 0x89, 0x64, 0x1b, 0xc8, 0x35, 0xaa, 0x97, 0xc9, 0x9f, 0xe4, 0x43, 0xa8, 0x87, 0xae, - 0x16, 0xf9, 0xc4, 0x2d, 0x3b, 0xaa, 0x3c, 0xb5, 0x39, 0x79, 0x68, 0xd9, 0xe2, 0x45, 0x2a, 0x06, - 0xe9, 0xcc, 0x9b, 0x50, 0xce, 0x24, 0x52, 0xd6, 0x9f, 0x9a, 0xa0, 0x8f, 0x90, 0x8c, 0xc8, 0x45, - 0x87, 0x17, 0x97, 0x3b, 0x7c, 0xb9, 0x03, 0x95, 0x15, 0x0e, 0x5c, 0x11, 0x1e, 0xd5, 0x55, 0xe1, - 0xf1, 0x18, 0x2a, 0x63, 0x37, 0xe0, 0xa6, 0xf4, 0x2f, 0x46, 0x75, 0xce, 0x00, 0x41, 0x1a, 0x20, - 0x85, 0x3c, 0x01, 0x05, 0x01, 0xae, 0x33, 0xbe, 0xa6, 0x96, 0x83, 0x45, 0x2a, 0x67, 0xe0, 0xa1, - 0x9e, 0x24, 0x89, 0xe4, 0x93, 0x90, 0xcb, 0x4b, 0x89, 0x01, 0x59, 0x6f, 0x11, 0x13, 0xd2, 0xe6, - 0x29, 0x55, 0x4f, 0xa4, 0x94, 0x46, 0x40, 0x3d, 0xb3, 0x02, 0x2e, 0xbc, 0x15, 0x44, 0xa1, 0xf4, - 0x3f, 0xb0, 0x9e, 0xa0, 0x85, 0xc9, 0xf4, 0x11, 0x14, 0x44, 0xf5, 0x08, 0x1a, 0x99, 0xdd, 0xdc, - 0x5e, 0xe5, 0x70, 0xe3, 0x8e, 0xa3, 0x67, 0x81, 0x21, 0x11, 0xda, 0x13, 0xa8, 0x0b, 0x62, 0xc7, - 0xb9, 0x74, 0xa3, 0x8a, 0x54, 0x8b, 0x53, 0x51, 0x11, 0x81, 0xa7, 0xd5, 0x40, 0x19, 0x32, 0xdf, - 0x8e, 0xaf, 0xfc, 0x39, 0xd4, 0x3b, 0x4e, 0x48, 0x09, 0x2f, 0xfc, 0x2f, 0xa8, 0xdb, 0x96, 0x23, - 0x4b, 0x16, 0xb5, 0xdd, 0x99, 0xc3, 0x43, 0x87, 0x57, 0x6d, 0xcb, 0x11, 0xf2, 0x5b, 0x48, 0x44, - 0x5c, 0x54, 0xda, 0x42, 0xdc, 0x5a, 0x88, 0x93, 0xd5, 0x4d, 0xe2, 0x5e, 0xe4, 0x4b, 0x19, 0x35, - 0xfb, 0x22, 0x5f, 0xca, 0xaa, 0xb9, 0x17, 0xf9, 0x52, 0x4e, 0xcd, 0xbf, 0xc8, 0x97, 0xf2, 0x6a, - 0xe1, 0x45, 0xbe, 0x54, 0x54, 0x4b, 0xda, 0x1f, 0x33, 0xa0, 0xf6, 0x66, 0xfc, 0x3f, 0xfa, 0x04, - 0x6c, 0x8c, 0x96, 0x63, 0x8e, 0xa7, 0xfc, 0x8d, 0x39, 0x61, 0x53, 0x4e, 0xd1, 0xdd, 0x05, 0x43, - 0xb1, 0x2d, 0xa7, 0x3d, 0xe5, 0x6f, 0x8e, 0x05, 0x2d, 0x6a, 0x9f, 0x09, 0x54, 0x39, 0x44, 0xd1, - 0x9b, 0x18, 0xf5, 0x13, 0xea, 0xfc, 0x26, 0x03, 0xca, 0xb7, 0x33, 0x97, 0xb3, 0xd5, 0x2d, 0x01, - 0x03, 0x6f, 0x5e, 0x87, 0xb3, 0x78, 0x07, 0x8c, 0xe7, 0x35, 0xf8, 0x4e, 0x49, 0xcf, 0x2d, 0x29, - 0xe9, 0xf7, 0x36, 0xbb, 0xfc, 0xbd, 0xcd, 0x4e, 0xfb, 0x55, 0x46, 0x78, 0x3d, 0x7c, 0x66, 0x68, - 0xf2, 0x5d, 0x50, 0xa2, 0x26, 0x65, 0x06, 0x34, 0x7a, 0x30, 0x04, 0xb2, 0x4b, 0x0d, 0x28, 0x4e, - 0x39, 0x98, 0x60, 0x78, 0x63, 0x70, 0x1d, 0x23, 0xc3, 0x29, 0x47, 0xf0, 0xfa, 0x92, 0x15, 0x1e, - 0x78, 0x17, 0x20, 0x61, 0xcb, 0x02, 0xea, 0x59, 0x1e, 0x27, 0x0c, 0x29, 0x4d, 0x98, 0x57, 0x0b, - 0xda, 0x9f, 0x64, 0x14, 0xfc, 0xbb, 0x4f, 0xfa, 0x00, 0x6a, 0xf3, 0x61, 0x07, 0x31, 0xb2, 0xbf, - 0x2a, 0x5e, 0x34, 0xed, 0x08, 0xd4, 0xc7, 0x61, 0x1d, 0x91, 0x73, 0x47, 0xfa, 0xd9, 0x75, 0xc1, - 0x19, 0x08, 0x46, 0x28, 0x12, 0xe7, 0x13, 0x61, 0x57, 0x7a, 0x6b, 0x33, 0x87, 0x9b, 0x38, 0xec, - 0xc9, 0x9e, 0x5b, 0x47, 0x7b, 0x4a, 0xfa, 0xb1, 0xf0, 0xed, 0xfd, 0x0a, 0x6a, 0x75, 0xa8, 0x0e, - 0xdd, 0xef, 0x99, 0x13, 0x27, 0xdb, 0x57, 0x50, 0x8b, 0x08, 0xa1, 0x8a, 0xfb, 0xb0, 0xc6, 0x91, - 0x12, 0x66, 0xf7, 0xbc, 0x8c, 0x9f, 0x05, 0x94, 0x23, 0xd8, 0x08, 0x11, 0xda, 0xef, 0xb3, 0x50, - 0x8e, 0xa9, 0x22, 0x48, 0x2e, 0x68, 0xc0, 0x4c, 0x9b, 0x8e, 0xa9, 0xef, 0xba, 0x4e, 0x98, 0xe3, - 0x8a, 0x20, 0x9e, 0x87, 0x34, 0x51, 0xc2, 0x22, 0x3d, 0xae, 0x69, 0x70, 0x8d, 0xd6, 0x51, 0x8c, - 0x4a, 0x48, 0x3b, 0xa5, 0xc1, 0x35, 0xf9, 0x08, 0xd4, 0x08, 0xe2, 0xf9, 0xcc, 0xb2, 0x45, 0xe7, - 0x93, 0xfd, 0xb9, 0x1e, 0xd2, 0xfb, 0x21, 0x59, 0x14, 0x78, 0x99, 0x64, 0xa6, 0x47, 0xad, 0x89, - 0x69, 0x0b, 0x2b, 0xca, 0x79, 0xb5, 0x26, 0xe9, 0x7d, 0x6a, 0x4d, 0xce, 0x03, 0xca, 0xc9, 0x67, - 0xf0, 0x28, 0x31, 0xd4, 0x26, 0xe0, 0x32, 0x8b, 0x89, 0x1f, 0x4f, 0xb5, 0xf1, 0x91, 0x27, 0xa0, - 0x88, 0x8e, 0x61, 0x8e, 0x7d, 0x46, 0x39, 0x9b, 0x84, 0x79, 0x5c, 0x11, 0xb4, 0xb6, 0x24, 0x91, - 0x06, 0x14, 0xd9, 0x8d, 0x67, 0xf9, 0x6c, 0x82, 0x1d, 0xa3, 0x64, 0x44, 0x3f, 0xc5, 0xe1, 0x80, - 0xbb, 0x3e, 0xbd, 0x62, 0xa6, 0x43, 0x6d, 0x16, 0x8e, 0x28, 0x95, 0x90, 0xd6, 0xa5, 0x36, 0xd3, - 0xde, 0x81, 0xed, 0xe7, 0x8c, 0x9f, 0x59, 0xaf, 0x67, 0xd6, 0xc4, 0xe2, 0xb7, 0x7d, 0xea, 0xd3, - 0x79, 0x15, 0xfc, 0x43, 0x01, 0x36, 0xd2, 0x2c, 0xc6, 0x99, 0x2f, 0x3a, 0x50, 0xc1, 0x9f, 0x4d, - 0x59, 0xe4, 0x9d, 0x79, 0xc7, 0x8c, 0xc1, 0xc6, 0x6c, 0xca, 0x0c, 0x09, 0x22, 0x5f, 0xc3, 0xce, - 0x3c, 0xc4, 0x7c, 0xd1, 0x03, 0x03, 0xca, 0x4d, 0x8f, 0xf9, 0xe6, 0x1b, 0xd1, 0xe9, 0xd1, 0xfa, - 0x98, 0x95, 0x32, 0xda, 0x0c, 0xca, 0x45, 0xc4, 0xf5, 0x99, 0xff, 0x52, 0xb0, 0xc9, 0x87, 0xa0, - 0x26, 0x47, 0x45, 0xd3, 0xf3, 0x6c, 0xf4, 0x44, 0x3e, 0xae, 0x66, 0xc2, 0x5e, 0x9e, 0x4d, 0x3e, - 0x05, 0xb1, 0x1f, 0x98, 0x29, 0x0b, 0x7b, 0x76, 0x98, 0xf4, 0x42, 0xc6, 0x7c, 0x69, 0x10, 0xf0, - 0x2f, 0xa1, 0xb9, 0x7c, 0xd9, 0xc0, 0x53, 0x05, 0x3c, 0xb5, 0xb9, 0x64, 0xe1, 0x10, 0x67, 0xd3, - 0x1b, 0x85, 0xf0, 0xe0, 0x1a, 0xe2, 0xe7, 0x1b, 0x85, 0xc8, 0x99, 0x8f, 0x60, 0x3d, 0x35, 0xc2, - 0x22, 0xb0, 0x88, 0xc0, 0x5a, 0x62, 0x8c, 0x8d, 0xd3, 0x6b, 0x71, 0xfc, 0x2f, 0x2d, 0x1f, 0xff, - 0x9f, 0xc1, 0x46, 0x34, 0xb8, 0x5c, 0xd0, 0xf1, 0xf7, 0xee, 0xe5, 0xa5, 0x19, 0xb0, 0x31, 0x16, - 0xe5, 0xbc, 0xb1, 0x1e, 0xb2, 0x8e, 0x24, 0x67, 0xc0, 0xc6, 0xa4, 0x09, 0x25, 0x3a, 0xe3, 0xae, - 0xf0, 0x11, 0x36, 0xe2, 0x92, 0x11, 0xff, 0x16, 0xb2, 0xa2, 0xbf, 0xcd, 0x8b, 0xd9, 0xe4, 0x8a, - 0xc9, 0x72, 0x51, 0x91, 0xb2, 0x22, 0xd6, 0x11, 0x72, 0xc4, 0x3b, 0xbf, 0x80, 0xed, 0x3b, 0x78, - 0x4e, 0x7d, 0x8e, 0x2f, 0x50, 0xa4, 0xcd, 0x16, 0x4e, 0x09, 0xb6, 0x78, 0xc6, 0xc7, 0x40, 0x04, - 0xc7, 0x14, 0x26, 0xb1, 0x1c, 0xf3, 0x72, 0x6a, 0x5d, 0x5d, 0x73, 0x9c, 0x43, 0xf2, 0x46, 0x5d, - 0x70, 0xce, 0xe9, 0x4d, 0xc7, 0x39, 0x41, 0xf2, 0xb2, 0x4e, 0x57, 0x0b, 0x7d, 0xfe, 0x53, 0x9d, - 0xae, 0x9e, 0x8a, 0x0d, 0x89, 0xd3, 0xfe, 0x92, 0x81, 0x6a, 0x2a, 0x38, 0xb1, 0x48, 0xc9, 0x3d, - 0xcd, 0x0c, 0x27, 0x81, 0xbc, 0x51, 0x0e, 0x29, 0x9d, 0x09, 0xd9, 0x84, 0x35, 0x6f, 0x76, 0xf1, - 0x3d, 0xbb, 0xc5, 0x48, 0x50, 0x8c, 0xf0, 0x17, 0x79, 0x16, 0x8e, 0xa1, 0x59, 0x9c, 0x15, 0x9b, - 0xcb, 0x23, 0x3f, 0x31, 0x8f, 0x7e, 0x0a, 0xc4, 0x72, 0xc6, 0xae, 0x2d, 0x62, 0x8b, 0x5f, 0xfb, - 0x2c, 0xb8, 0x76, 0xa7, 0x13, 0x8c, 0xdf, 0xaa, 0xb1, 0x1e, 0x71, 0x86, 0x11, 0x43, 0xc0, 0xe3, - 0x95, 0x71, 0x0e, 0xcf, 0x4b, 0x78, 0xc4, 0x89, 0xe1, 0xda, 0x2b, 0xd8, 0x1e, 0xac, 0xca, 0x5e, - 0xf2, 0x15, 0x80, 0x17, 0xe7, 0x2c, 0x6a, 0x58, 0x39, 0xdc, 0xb9, 0xfb, 0xe0, 0x79, 0x5e, 0x1b, - 0x09, 0xbc, 0xb6, 0x03, 0xcd, 0x65, 0xa2, 0x65, 0x81, 0xd6, 0x1e, 0xc1, 0xc6, 0x60, 0x76, 0x75, - 0xc5, 0x16, 0x26, 0x35, 0x1f, 0x94, 0x63, 0x2b, 0x78, 0x3d, 0xa3, 0x53, 0xeb, 0xd2, 0x62, 0x93, - 0x7f, 0xdd, 0xc8, 0xb9, 0x94, 0x91, 0x3f, 0x86, 0xb5, 0x70, 0x24, 0x97, 0x66, 0x9e, 0x0f, 0x77, - 0xad, 0x19, 0x77, 0xc3, 0x79, 0x3c, 0x84, 0x68, 0x3f, 0x66, 0xe0, 0x61, 0xfa, 0x2d, 0x61, 0x13, - 0x39, 0x84, 0x52, 0xb4, 0xac, 0x87, 0x85, 0x6a, 0x6b, 0xae, 0x7d, 0xea, 0x7b, 0x86, 0x51, 0x0c, - 0x37, 0x77, 0xf2, 0x05, 0x28, 0x93, 0x84, 0x02, 0x8d, 0x2c, 0x9e, 0x7b, 0x14, 0x9f, 0x4b, 0x6a, - 0x67, 0xa4, 0xa0, 0xfb, 0x4f, 0xa1, 0x14, 0xed, 0x22, 0x44, 0x81, 0xd2, 0x59, 0xaf, 0xd7, 0x37, - 0x7b, 0xa3, 0xa1, 0xfa, 0x80, 0x54, 0xa0, 0x88, 0xbf, 0x3a, 0x5d, 0x35, 0xb3, 0x1f, 0x40, 0x39, - 0x5e, 0x45, 0x48, 0x15, 0xca, 0x9d, 0x6e, 0x67, 0xd8, 0x69, 0x0d, 0xf5, 0x63, 0xf5, 0x01, 0x79, - 0x04, 0xeb, 0x7d, 0x43, 0xef, 0x9c, 0xb7, 0x9e, 0xeb, 0xa6, 0xa1, 0xbf, 0xd4, 0x5b, 0x67, 0xfa, - 0xb1, 0x9a, 0x21, 0x04, 0x6a, 0xa7, 0xc3, 0xb3, 0xb6, 0xd9, 0x1f, 0x1d, 0x9d, 0x75, 0x06, 0xa7, - 0xfa, 0xb1, 0x9a, 0x15, 0x32, 0x07, 0xa3, 0x76, 0x5b, 0x1f, 0x0c, 0xd4, 0x1c, 0x01, 0x58, 0x3b, - 0x69, 0x75, 0x04, 0x38, 0x4f, 0x36, 0xa0, 0xde, 0xe9, 0xbe, 0xec, 0x75, 0xda, 0xba, 0x39, 0xd0, - 0x87, 0x43, 0x41, 0x2c, 0xec, 0xff, 0x23, 0x03, 0xd5, 0xd4, 0x36, 0x43, 0xb6, 0x60, 0x43, 0x1c, - 0x19, 0x19, 0xe2, 0xa6, 0xd6, 0xa0, 0xd7, 0x35, 0xbb, 0xbd, 0xae, 0xae, 0x3e, 0x20, 0xef, 0xc0, - 0xd6, 0x02, 0xa3, 0x77, 0x72, 0xd2, 0x3e, 0x6d, 0x89, 0xc7, 0x93, 0x26, 0x6c, 0x2e, 0x30, 0x87, - 0x9d, 0x73, 0x5d, 0x68, 0x99, 0x25, 0xbb, 0xb0, 0xb3, 0xc0, 0x1b, 0x7c, 0xa7, 0xeb, 0xfd, 0x18, - 0x91, 0x23, 0x4f, 0xe1, 0xc9, 0x02, 0xa2, 0xd3, 0x1d, 0x8c, 0x4e, 0x4e, 0x3a, 0xed, 0x8e, 0xde, - 0x1d, 0x9a, 0x2f, 0x5b, 0x67, 0x23, 0x5d, 0xcd, 0x93, 0x1d, 0x68, 0x2c, 0x5e, 0xa2, 0x9f, 0xf7, - 0x7b, 0x46, 0xcb, 0x78, 0xa5, 0x16, 0xc8, 0xfb, 0xf0, 0xf8, 0x8e, 0x90, 0x76, 0xcf, 0x30, 0xf4, - 0xf6, 0xd0, 0x6c, 0x9d, 0xf7, 0x46, 0xdd, 0xa1, 0xba, 0xb6, 0x7f, 0x20, 0x36, 0x86, 0x85, 0x84, - 0x14, 0x26, 0x1b, 0x75, 0xbf, 0xe9, 0xf6, 0xbe, 0xeb, 0xaa, 0x0f, 0x84, 0xe5, 0x87, 0xa7, 0x86, - 0x3e, 0x38, 0xed, 0x9d, 0x1d, 0xab, 0x99, 0xfd, 0x5f, 0xe6, 0x00, 0xe6, 0xb1, 0x25, 0xac, 0xd3, - 0x1a, 0x0d, 0x7b, 0xd1, 0x0d, 0xf3, 0x63, 0x1a, 0xbc, 0x97, 0x64, 0x1c, 0x8d, 0x8e, 0x9f, 0xeb, - 0x43, 0xb3, 0xdb, 0x1b, 0x9a, 0x83, 0x61, 0xcb, 0x18, 0xa2, 0xbb, 0x9a, 0xb0, 0x99, 0xc4, 0x48, - 0x2b, 0x9c, 0xe8, 0xfa, 0x40, 0xcd, 0x92, 0xf7, 0xa0, 0xb9, 0xe4, 0xbc, 0x7e, 0xd6, 0xea, 0x0f, - 0xf4, 0x63, 0x35, 0x47, 0xb6, 0xe1, 0x51, 0x92, 0xdf, 0xe9, 0x9a, 0x27, 0x67, 0x9d, 0xe7, 0xa7, - 0x43, 0x35, 0x4f, 0x1a, 0xf0, 0x30, 0x2d, 0xb6, 0x85, 0x52, 0xd5, 0xc2, 0xe2, 0xa1, 0xf3, 0x4e, - 0x57, 0x37, 0x90, 0xb5, 0x46, 0x36, 0x81, 0x24, 0x59, 0x7d, 0x43, 0xef, 0xb7, 0x5e, 0xa9, 0x45, - 0xf2, 0x18, 0xde, 0x49, 0xd2, 0x23, 0x8b, 0x1e, 0xb5, 0xda, 0xdf, 0xf4, 0x4e, 0x4e, 0xd4, 0xd2, - 0xe2, 0x6d, 0x71, 0x34, 0x97, 0x17, 0x6d, 0x13, 0x45, 0x36, 0x08, 0xbf, 0xa5, 0x18, 0x9d, 0x6f, - 0x47, 0x9d, 0xe3, 0xce, 0xf0, 0x95, 0xd9, 0xfb, 0x46, 0xad, 0x08, 0xbf, 0x2d, 0xd1, 0x3c, 0x19, - 0x00, 0xaa, 0x72, 0xf8, 0xd7, 0xb2, 0xfc, 0x68, 0xd0, 0xc6, 0xcf, 0x94, 0xc4, 0x80, 0x62, 0x98, - 0xa8, 0x64, 0x55, 0xea, 0x36, 0x1f, 0xa5, 0x16, 0xbf, 0xb8, 0x40, 0x6d, 0xfd, 0xe2, 0xcf, 0x7f, - 0xfb, 0x75, 0x76, 0x5d, 0x53, 0x0e, 0xde, 0x7c, 0x76, 0x20, 0x10, 0x07, 0xee, 0x8c, 0x7f, 0x99, - 0xd9, 0x27, 0x3d, 0x58, 0x93, 0x1f, 0xa7, 0xc8, 0x66, 0x4a, 0x64, 0xfc, 0xb5, 0x6a, 0x95, 0xc4, - 0x4d, 0x94, 0xa8, 0x6a, 0x95, 0x58, 0xa2, 0xe5, 0x08, 0x81, 0x5f, 0x40, 0x31, 0xfc, 0xf4, 0x91, - 0x78, 0x64, 0xfa, 0x63, 0x48, 0x73, 0xd9, 0x76, 0xfa, 0xdf, 0x19, 0xf2, 0xbf, 0x50, 0x8e, 0x17, - 0x5b, 0xb2, 0x9d, 0x28, 0xcd, 0xe9, 0xb2, 0xda, 0x6c, 0x2e, 0x63, 0xa5, 0x9f, 0x45, 0x6a, 0xf1, - 0xb3, 0x70, 0xe9, 0x25, 0x23, 0x59, 0x8e, 0xc4, 0xd2, 0x4b, 0x1a, 0xa9, 0xeb, 0x13, 0x7b, 0xf0, - 0xd2, 0x87, 0x69, 0x4d, 0x14, 0xf9, 0x90, 0x90, 0x94, 0xc8, 0x83, 0x1f, 0xac, 0xc9, 0xff, 0x93, - 0xff, 0x03, 0x25, 0x74, 0x00, 0xae, 0xa6, 0x64, 0x6e, 0xac, 0xe4, 0xfe, 0xdc, 0x9c, 0x2b, 0xb3, - 0xb8, 0xc4, 0x2e, 0x91, 0xee, 0xce, 0xf8, 0x01, 0x47, 0x69, 0x17, 0xb1, 0x74, 0x5c, 0x79, 0x12, - 0xd2, 0x93, 0xcb, 0x63, 0x5a, 0x7a, 0x6a, 0x39, 0xd2, 0x76, 0x51, 0x7a, 0x93, 0x34, 0x52, 0xd2, - 0x5f, 0x0b, 0xcc, 0xc1, 0x0f, 0xd4, 0xe6, 0x42, 0x83, 0x9a, 0x98, 0x78, 0xd1, 0xe5, 0xf7, 0xea, - 0x30, 0xb7, 0xda, 0xc2, 0xa7, 0x00, 0x6d, 0x1b, 0x2f, 0xd9, 0x20, 0xeb, 0x89, 0x50, 0x88, 0x35, - 0x98, 0x4b, 0xbf, 0x57, 0x87, 0xa4, 0xf4, 0xb4, 0x0a, 0x8f, 0x51, 0xfa, 0x36, 0xd9, 0x4a, 0x4a, - 0x4f, 0x6a, 0xf0, 0x0a, 0xaa, 0xe2, 0x8e, 0x68, 0xe7, 0x09, 0x12, 0x91, 0x9c, 0x5a, 0xac, 0x9a, - 0x5b, 0x77, 0xe8, 0xe9, 0xec, 0x20, 0x75, 0xbc, 0x22, 0xa0, 0xfc, 0x40, 0x2e, 0x53, 0x84, 0x03, - 0xb9, 0xbb, 0x0e, 0x10, 0x2d, 0x96, 0xb3, 0x72, 0x57, 0x68, 0xde, 0x3b, 0x59, 0x68, 0x3b, 0x78, - 0xe1, 0x26, 0x79, 0x88, 0x17, 0x46, 0x80, 0x03, 0x4f, 0xca, 0xff, 0x19, 0x90, 0xc1, 0x7d, 0xb7, - 0xae, 0x9c, 0x71, 0x9a, 0xef, 0xdf, 0x8b, 0x49, 0x1b, 0x54, 0x5b, 0x7a, 0xb9, 0x48, 0x61, 0x06, - 0x4a, 0x72, 0x82, 0x20, 0x73, 0x5d, 0x96, 0x0c, 0x39, 0xcd, 0x77, 0x57, 0x70, 0xc3, 0xdb, 0x1a, - 0x78, 0x1b, 0x21, 0xaa, 0xb8, 0x4d, 0xcc, 0xb5, 0x07, 0x81, 0x84, 0x5d, 0xac, 0xe1, 0xff, 0x53, - 0x3e, 0xff, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x11, 0x1a, 0x17, 0x86, 0x19, 0x00, 0x00, + 0xe1, 0xae, 0x54, 0xae, 0x97, 0x54, 0xa5, 0xca, 0xe7, 0x1c, 0xf2, 0x0d, 0x72, 0xc8, 0x2d, 0xb7, + 0xdc, 0xf2, 0x01, 0x72, 0xc9, 0x29, 0xc9, 0x2d, 0xd7, 0x5c, 0x72, 0xc8, 0x77, 0x48, 0x4d, 0x0f, + 0x00, 0x02, 0x14, 0x29, 0x27, 0x87, 0xdc, 0xc4, 0xee, 0xdf, 0xf4, 0x4c, 0xff, 0xef, 0x86, 0x40, + 0x19, 0x4f, 0x2d, 0xe6, 0xf0, 0x67, 0x9e, 0xef, 0x72, 0x97, 0x14, 0xa7, 0xae, 0xeb, 0xf9, 0xde, + 0xb8, 0xb9, 0x73, 0xe5, 0xba, 0x57, 0x53, 0x76, 0x40, 0x3d, 0xeb, 0x80, 0x3a, 0x8e, 0xcb, 0x29, + 0xb7, 0x5c, 0x27, 0x90, 0x30, 0xed, 0xb7, 0x79, 0xa8, 0x9d, 0xb9, 0xae, 0xd7, 0x9b, 0x71, 0x83, + 0xbd, 0x9e, 0xb1, 0x80, 0x13, 0x15, 0x72, 0xd4, 0xe6, 0x8d, 0xcc, 0x6e, 0x66, 0x2f, 0x67, 0x88, + 0x3f, 0x09, 0x81, 0xfc, 0x84, 0x05, 0xbc, 0x91, 0xdd, 0xcd, 0xec, 0x95, 0x0d, 0xfc, 0x9b, 0x1c, + 0xc0, 0x43, 0x9b, 0xde, 0x98, 0xc1, 0x5b, 0xea, 0x99, 0xbe, 0x3b, 0xe3, 0x96, 0x73, 0x65, 0x5e, + 0x32, 0xd6, 0xc8, 0xe1, 0xb1, 0x75, 0x9b, 0xde, 0x0c, 0xde, 0x52, 0xcf, 0x90, 0x9c, 0x13, 0xc6, + 0xc8, 0xe7, 0xb0, 0x29, 0x0e, 0x78, 0x3e, 0xf3, 0xe8, 0x6d, 0xea, 0x48, 0x1e, 0x8f, 0x6c, 0xd8, + 0xf4, 0xa6, 0x8f, 0xcc, 0xc4, 0xa1, 0x5d, 0x50, 0xe2, 0x5b, 0x04, 0xb4, 0x80, 0x50, 0x08, 0xa5, + 0x0b, 0xc4, 0x07, 0x50, 0x4b, 0x88, 0x15, 0x0f, 0x5f, 0x43, 0x8c, 0x12, 0x8b, 0x6b, 0xd9, 0x9c, + 0x68, 0x50, 0x15, 0x28, 0xdb, 0x72, 0x98, 0x8f, 0x82, 0x8a, 0x08, 0xaa, 0xd8, 0xf4, 0xe6, 0x5c, + 0xd0, 0x84, 0xa4, 0x4f, 0x40, 0x15, 0x36, 0x33, 0xdd, 0x19, 0x37, 0xc7, 0xd7, 0xd4, 0x71, 0xd8, + 0xb4, 0x51, 0xda, 0xcd, 0xec, 0xe5, 0x8f, 0xb2, 0x8d, 0x8c, 0x51, 0x9b, 0x4a, 0x2b, 0xb5, 0x25, + 0x87, 0xec, 0xc3, 0xba, 0x3b, 0xe3, 0x57, 0xae, 0x50, 0x42, 0xa0, 0xcd, 0x80, 0xf1, 0x46, 0x65, + 0x37, 0xb7, 0x97, 0x37, 0xea, 0x11, 0x43, 0x60, 0x07, 0x8c, 0x0b, 0x6c, 0xf0, 0x96, 0x31, 0xcf, + 0x1c, 0xbb, 0xce, 0xa5, 0xc9, 0xa9, 0x7f, 0xc5, 0x78, 0xa3, 0xbc, 0x9b, 0xd9, 0x2b, 0x18, 0x75, + 0x64, 0xb4, 0x5d, 0xe7, 0x72, 0x88, 0x64, 0xf2, 0x29, 0x90, 0x6b, 0x3e, 0x1d, 0x23, 0xd4, 0xf2, + 0x6d, 0xe9, 0xac, 0x46, 0x15, 0xc1, 0xeb, 0x82, 0xd3, 0x4e, 0x32, 0xc8, 0x97, 0xb0, 0x8d, 0xc6, + 0xf1, 0x66, 0x17, 0x53, 0x6b, 0x8c, 0x44, 0x73, 0xc2, 0xe8, 0x64, 0x6a, 0x39, 0xac, 0x01, 0xe2, + 0xf5, 0xc6, 0x96, 0x00, 0xf4, 0xe7, 0xfc, 0xe3, 0x90, 0x4d, 0x1e, 0x42, 0x61, 0x4a, 0x2f, 0xd8, + 0xb4, 0xa1, 0xa0, 0x5f, 0xe5, 0x0f, 0xb2, 0x03, 0x65, 0xcb, 0xb1, 0xb8, 0x45, 0xb9, 0xeb, 0x37, + 0x6a, 0xc8, 0x99, 0x13, 0xb4, 0x1f, 0xb3, 0x50, 0x15, 0xf1, 0xd2, 0x71, 0x56, 0x87, 0xcb, 0xa2, + 0xd3, 0xb2, 0x77, 0x9c, 0x76, 0xc7, 0x1d, 0xb9, 0xbb, 0xee, 0xd8, 0x86, 0xd2, 0x94, 0x06, 0xdc, + 0xbc, 0x76, 0x3d, 0x8c, 0x10, 0xc5, 0x28, 0x8a, 0xdf, 0xa7, 0xae, 0x47, 0xde, 0x87, 0x2a, 0xbb, + 0xe1, 0xcc, 0x77, 0xe8, 0xd4, 0x14, 0x26, 0xc1, 0xb0, 0x28, 0x19, 0x4a, 0x44, 0x3c, 0xe5, 0xd3, + 0x31, 0xd9, 0x03, 0x35, 0x36, 0x64, 0x64, 0xf3, 0x35, 0x34, 0x63, 0x2d, 0x32, 0x63, 0x68, 0xf2, + 0xd8, 0x0e, 0xc5, 0x95, 0x76, 0x28, 0x2d, 0xda, 0xe1, 0xef, 0x19, 0x50, 0x30, 0xc0, 0x59, 0xe0, + 0xb9, 0x4e, 0xc0, 0x08, 0x81, 0xac, 0x35, 0x41, 0x2b, 0x94, 0x31, 0x5e, 0xb2, 0xd6, 0x44, 0xa8, + 0x60, 0x4d, 0xcc, 0x8b, 0x5b, 0xce, 0x02, 0xd4, 0x50, 0x31, 0x8a, 0xd6, 0xe4, 0x48, 0xfc, 0x24, + 0x4f, 0x41, 0xc1, 0xd7, 0xd1, 0xc9, 0xc4, 0x67, 0x41, 0x20, 0x53, 0x0b, 0x0f, 0x56, 0x04, 0xbd, + 0x25, 0xc9, 0xe4, 0x19, 0x6c, 0x24, 0x61, 0xa6, 0xe3, 0x1d, 0xbe, 0x0d, 0xae, 0xd1, 0x1e, 0x65, + 0x19, 0x0e, 0x21, 0xb2, 0x8b, 0x0c, 0xf2, 0x49, 0x18, 0x3d, 0x11, 0x5e, 0xc2, 0x0b, 0x08, 0x57, + 0x13, 0xf0, 0x3e, 0xa2, 0x9f, 0x42, 0x2d, 0x60, 0xfe, 0x1b, 0xe6, 0x9b, 0x36, 0x0b, 0x02, 0x7a, + 0xc5, 0xd0, 0x40, 0x65, 0xa3, 0x2a, 0xa9, 0xe7, 0x92, 0xa8, 0xa9, 0x50, 0x3b, 0x77, 0x1d, 0x8b, + 0xbb, 0x7e, 0xe8, 0x73, 0xed, 0x77, 0x79, 0x00, 0xa1, 0xfd, 0x80, 0x53, 0x3e, 0x0b, 0x96, 0x56, + 0x0c, 0x61, 0x8d, 0xec, 0x4a, 0x6b, 0x54, 0x16, 0xad, 0x91, 0xe7, 0xb7, 0x9e, 0x0c, 0x83, 0xda, + 0xe1, 0xfa, 0xb3, 0xb0, 0x76, 0x3d, 0x13, 0x77, 0x0c, 0x6f, 0x3d, 0x66, 0x20, 0x9b, 0xec, 0x41, + 0x21, 0xe0, 0x94, 0xcb, 0x8a, 0x51, 0x3b, 0x24, 0x29, 0x9c, 0x78, 0x0b, 0x33, 0x24, 0x80, 0x7c, + 0x0d, 0xb5, 0x4b, 0x6a, 0x4d, 0x67, 0x3e, 0x33, 0x7d, 0x46, 0x03, 0xd7, 0xc1, 0x48, 0xae, 0x1d, + 0x6e, 0xc6, 0x47, 0x4e, 0x24, 0xdb, 0x40, 0xae, 0x51, 0xbd, 0x4c, 0xfe, 0x24, 0x1f, 0x42, 0x3d, + 0x74, 0xb5, 0xc8, 0x27, 0x6e, 0xd9, 0x51, 0xe5, 0xa9, 0xcd, 0xc9, 0x43, 0xcb, 0x16, 0x2f, 0x52, + 0x31, 0x48, 0x67, 0xde, 0x84, 0x72, 0x26, 0x91, 0xb2, 0xfe, 0xd4, 0x04, 0x7d, 0x84, 0x64, 0x44, + 0x2e, 0x3a, 0xbc, 0xb8, 0xdc, 0xe1, 0xcb, 0x1d, 0xa8, 0xac, 0x70, 0xe0, 0x8a, 0xf0, 0xa8, 0xae, + 0x0a, 0x8f, 0xc7, 0x50, 0x19, 0xbb, 0x01, 0x37, 0xa5, 0x7f, 0x31, 0xaa, 0x73, 0x06, 0x08, 0xd2, + 0x00, 0x29, 0xe4, 0x09, 0x28, 0x08, 0x70, 0x9d, 0xf1, 0x35, 0xb5, 0x1c, 0x2c, 0x52, 0x39, 0x03, + 0x0f, 0xf5, 0x24, 0x49, 0x24, 0x9f, 0x84, 0x5c, 0x5e, 0x4a, 0x0c, 0xc8, 0x7a, 0x8b, 0x98, 0x90, + 0x36, 0x4f, 0xa9, 0x7a, 0x22, 0xa5, 0x34, 0x02, 0xea, 0x99, 0x15, 0x70, 0xe1, 0xad, 0x20, 0x0a, + 0xa5, 0xff, 0x81, 0xf5, 0x04, 0x2d, 0x4c, 0xa6, 0x8f, 0xa0, 0x20, 0xaa, 0x47, 0xd0, 0xc8, 0xec, + 0xe6, 0xf6, 0x2a, 0x87, 0x1b, 0x77, 0x1c, 0x3d, 0x0b, 0x0c, 0x89, 0xd0, 0x9e, 0x40, 0x5d, 0x10, + 0x3b, 0xce, 0xa5, 0x1b, 0x55, 0xa4, 0x5a, 0x9c, 0x8a, 0x8a, 0x08, 0x3c, 0xad, 0x06, 0xca, 0x90, + 0xf9, 0x76, 0x7c, 0xe5, 0xcf, 0xa1, 0xde, 0x71, 0x42, 0x4a, 0x78, 0xe1, 0x7f, 0x41, 0xdd, 0xb6, + 0x1c, 0x59, 0xb2, 0xa8, 0xed, 0xce, 0x1c, 0x1e, 0x3a, 0xbc, 0x6a, 0x5b, 0x8e, 0x90, 0xdf, 0x42, + 0x22, 0xe2, 0xa2, 0xd2, 0x16, 0xe2, 0xd6, 0x42, 0x9c, 0xac, 0x6e, 0x12, 0xf7, 0x22, 0x5f, 0xca, + 0xa8, 0xd9, 0x17, 0xf9, 0x52, 0x56, 0xcd, 0xbd, 0xc8, 0x97, 0x72, 0x6a, 0xfe, 0x45, 0xbe, 0x94, + 0x57, 0x0b, 0x2f, 0xf2, 0xa5, 0xa2, 0x5a, 0xd2, 0xfe, 0x98, 0x01, 0xb5, 0x37, 0xe3, 0xff, 0xd1, + 0x27, 0x60, 0x63, 0xb4, 0x1c, 0x73, 0x3c, 0xe5, 0x6f, 0xcc, 0x09, 0x9b, 0x72, 0x8a, 0xee, 0x2e, + 0x18, 0x8a, 0x6d, 0x39, 0xed, 0x29, 0x7f, 0x73, 0x2c, 0x68, 0x51, 0xfb, 0x4c, 0xa0, 0xca, 0x21, + 0x8a, 0xde, 0xc4, 0xa8, 0x9f, 0x50, 0xe7, 0xd7, 0x19, 0x50, 0xbe, 0x9d, 0xb9, 0x9c, 0xad, 0x6e, + 0x09, 0x18, 0x78, 0xf3, 0x3a, 0x9c, 0xc5, 0x3b, 0x60, 0x3c, 0xaf, 0xc1, 0x77, 0x4a, 0x7a, 0x6e, + 0x49, 0x49, 0xbf, 0xb7, 0xd9, 0xe5, 0xef, 0x6d, 0x76, 0xda, 0x2f, 0x33, 0xc2, 0xeb, 0xe1, 0x33, + 0x43, 0x93, 0xef, 0x82, 0x12, 0x35, 0x29, 0x33, 0xa0, 0xd1, 0x83, 0x21, 0x90, 0x5d, 0x6a, 0x40, + 0x71, 0xca, 0xc1, 0x04, 0xc3, 0x1b, 0x83, 0xeb, 0x18, 0x19, 0x4e, 0x39, 0x82, 0xd7, 0x97, 0xac, + 0xf0, 0xc0, 0xbb, 0x00, 0x09, 0x5b, 0x16, 0x50, 0xcf, 0xf2, 0x38, 0x61, 0x48, 0x69, 0xc2, 0xbc, + 0x5a, 0xd0, 0xfe, 0x24, 0xa3, 0xe0, 0xdf, 0x7d, 0xd2, 0x07, 0x50, 0x9b, 0x0f, 0x3b, 0x88, 0x91, + 0xfd, 0x55, 0xf1, 0xa2, 0x69, 0x47, 0xa0, 0x3e, 0x0e, 0xeb, 0x88, 0x9c, 0x3b, 0xd2, 0xcf, 0xae, + 0x0b, 0xce, 0x40, 0x30, 0x42, 0x91, 0x38, 0x9f, 0x08, 0xbb, 0xd2, 0x5b, 0x9b, 0x39, 0xdc, 0xc4, + 0x61, 0x4f, 0xf6, 0xdc, 0x3a, 0xda, 0x53, 0xd2, 0x8f, 0x85, 0x6f, 0xef, 0x57, 0x50, 0xab, 0x43, + 0x75, 0xe8, 0x7e, 0xcf, 0x9c, 0x38, 0xd9, 0xbe, 0x82, 0x5a, 0x44, 0x08, 0x55, 0xdc, 0x87, 0x35, + 0x8e, 0x94, 0x30, 0xbb, 0xe7, 0x65, 0xfc, 0x2c, 0xa0, 0x1c, 0xc1, 0x46, 0x88, 0xd0, 0x7e, 0x9f, + 0x85, 0x72, 0x4c, 0x15, 0x41, 0x72, 0x41, 0x03, 0x66, 0xda, 0x74, 0x4c, 0x7d, 0xd7, 0x75, 0xc2, + 0x1c, 0x57, 0x04, 0xf1, 0x3c, 0xa4, 0x89, 0x12, 0x16, 0xe9, 0x71, 0x4d, 0x83, 0x6b, 0xb4, 0x8e, + 0x62, 0x54, 0x42, 0xda, 0x29, 0x0d, 0xae, 0xc9, 0x47, 0xa0, 0x46, 0x10, 0xcf, 0x67, 0x96, 0x2d, + 0x3a, 0x9f, 0xec, 0xcf, 0xf5, 0x90, 0xde, 0x0f, 0xc9, 0xa2, 0xc0, 0xcb, 0x24, 0x33, 0x3d, 0x6a, + 0x4d, 0x4c, 0x5b, 0x58, 0x51, 0xce, 0xab, 0x35, 0x49, 0xef, 0x53, 0x6b, 0x72, 0x1e, 0x50, 0x4e, + 0x3e, 0x83, 0x47, 0x89, 0xa1, 0x36, 0x01, 0x97, 0x59, 0x4c, 0xfc, 0x78, 0xaa, 0x8d, 0x8f, 0x3c, + 0x01, 0x45, 0x74, 0x0c, 0x73, 0xec, 0x33, 0xca, 0xd9, 0x24, 0xcc, 0xe3, 0x8a, 0xa0, 0xb5, 0x25, + 0x89, 0x34, 0xa0, 0xc8, 0x6e, 0x3c, 0xcb, 0x67, 0x13, 0xec, 0x18, 0x25, 0x23, 0xfa, 0x29, 0x0e, + 0x07, 0xdc, 0xf5, 0xe9, 0x15, 0x33, 0x1d, 0x6a, 0xb3, 0x70, 0x44, 0xa9, 0x84, 0xb4, 0x2e, 0xb5, + 0x99, 0xf6, 0x0e, 0x6c, 0x3f, 0x67, 0xfc, 0xcc, 0x7a, 0x3d, 0xb3, 0x26, 0x16, 0xbf, 0xed, 0x53, + 0x9f, 0xce, 0xab, 0xe0, 0x1f, 0x0a, 0xb0, 0x91, 0x66, 0x31, 0xce, 0x7c, 0xd1, 0x81, 0x0a, 0xfe, + 0x6c, 0xca, 0x22, 0xef, 0xcc, 0x3b, 0x66, 0x0c, 0x36, 0x66, 0x53, 0x66, 0x48, 0x10, 0xf9, 0x1a, + 0x76, 0xe6, 0x21, 0xe6, 0x8b, 0x1e, 0x18, 0x50, 0x6e, 0x7a, 0xcc, 0x37, 0xdf, 0x88, 0x4e, 0x8f, + 0xd6, 0xc7, 0xac, 0x94, 0xd1, 0x66, 0x50, 0x2e, 0x22, 0xae, 0xcf, 0xfc, 0x97, 0x82, 0x4d, 0x3e, + 0x04, 0x35, 0x39, 0x2a, 0x9a, 0x9e, 0x67, 0xa3, 0x27, 0xf2, 0x71, 0x35, 0x13, 0xf6, 0xf2, 0x6c, + 0xf2, 0x29, 0x88, 0xfd, 0xc0, 0x4c, 0x59, 0xd8, 0xb3, 0xc3, 0xa4, 0x17, 0x32, 0xe6, 0x4b, 0x83, + 0x80, 0x7f, 0x09, 0xcd, 0xe5, 0xcb, 0x06, 0x9e, 0x2a, 0xe0, 0xa9, 0xcd, 0x25, 0x0b, 0x87, 0x38, + 0x9b, 0xde, 0x28, 0x84, 0x07, 0xd7, 0x10, 0x3f, 0xdf, 0x28, 0x44, 0xce, 0x7c, 0x04, 0xeb, 0xa9, + 0x11, 0x16, 0x81, 0x45, 0x04, 0xd6, 0x12, 0x63, 0x6c, 0x9c, 0x5e, 0x8b, 0xe3, 0x7f, 0x69, 0xf9, + 0xf8, 0xff, 0x0c, 0x36, 0xa2, 0xc1, 0xe5, 0x82, 0x8e, 0xbf, 0x77, 0x2f, 0x2f, 0xcd, 0x80, 0x8d, + 0xb1, 0x28, 0xe7, 0x8d, 0xf5, 0x90, 0x75, 0x24, 0x39, 0x03, 0x36, 0x26, 0x4d, 0x28, 0xd1, 0x19, + 0x77, 0x85, 0x8f, 0xb0, 0x11, 0x97, 0x8c, 0xf8, 0xb7, 0x90, 0x15, 0xfd, 0x6d, 0x5e, 0xcc, 0x26, + 0x57, 0x4c, 0x96, 0x8b, 0x8a, 0x94, 0x15, 0xb1, 0x8e, 0x90, 0x23, 0xde, 0xf9, 0x05, 0x6c, 0xdf, + 0xc1, 0x73, 0xea, 0x73, 0x7c, 0x81, 0x22, 0x6d, 0xb6, 0x70, 0x4a, 0xb0, 0xc5, 0x33, 0x3e, 0x06, + 0x22, 0x38, 0xa6, 0x30, 0x89, 0xe5, 0x98, 0x97, 0x53, 0xeb, 0xea, 0x9a, 0xe3, 0x1c, 0x92, 0x37, + 0xea, 0x82, 0x73, 0x4e, 0x6f, 0x3a, 0xce, 0x09, 0x92, 0x97, 0x75, 0xba, 0x5a, 0xe8, 0xf3, 0x9f, + 0xea, 0x74, 0xf5, 0x54, 0x6c, 0x48, 0x9c, 0xf6, 0x97, 0x0c, 0x54, 0x53, 0xc1, 0x89, 0x45, 0x4a, + 0xee, 0x69, 0x66, 0x38, 0x09, 0xe4, 0x8d, 0x72, 0x48, 0xe9, 0x4c, 0xc8, 0x26, 0xac, 0x79, 0xb3, + 0x8b, 0xef, 0xd9, 0x2d, 0x46, 0x82, 0x62, 0x84, 0xbf, 0xc8, 0xb3, 0x70, 0x0c, 0xcd, 0xe2, 0xac, + 0xd8, 0x5c, 0x1e, 0xf9, 0x89, 0x79, 0xf4, 0x53, 0x20, 0x96, 0x33, 0x76, 0x6d, 0x11, 0x5b, 0xfc, + 0xda, 0x67, 0xc1, 0xb5, 0x3b, 0x9d, 0x60, 0xfc, 0x56, 0x8d, 0xf5, 0x88, 0x33, 0x8c, 0x18, 0x02, + 0x1e, 0xaf, 0x8c, 0x73, 0x78, 0x5e, 0xc2, 0x23, 0x4e, 0x0c, 0xd7, 0x5e, 0xc1, 0xf6, 0x60, 0x55, + 0xf6, 0x92, 0xaf, 0x00, 0xbc, 0x38, 0x67, 0x51, 0xc3, 0xca, 0xe1, 0xce, 0xdd, 0x07, 0xcf, 0xf3, + 0xda, 0x48, 0xe0, 0xb5, 0x1d, 0x68, 0x2e, 0x13, 0x2d, 0x0b, 0xb4, 0xf6, 0x08, 0x36, 0x06, 0xb3, + 0xab, 0x2b, 0xb6, 0x30, 0xa9, 0xf9, 0xa0, 0x1c, 0x5b, 0xc1, 0xeb, 0x19, 0x9d, 0x5a, 0x97, 0x16, + 0x9b, 0xfc, 0xeb, 0x46, 0xce, 0xa5, 0x8c, 0xfc, 0x31, 0xac, 0x85, 0x23, 0xb9, 0x34, 0xf3, 0x7c, + 0xb8, 0x6b, 0xcd, 0xb8, 0x1b, 0xce, 0xe3, 0x21, 0x44, 0xfb, 0x31, 0x03, 0x0f, 0xd3, 0x6f, 0x09, + 0x9b, 0xc8, 0x21, 0x94, 0xa2, 0x65, 0x3d, 0x2c, 0x54, 0x5b, 0x73, 0xed, 0x53, 0xdf, 0x33, 0x8c, + 0x62, 0xb8, 0xb9, 0x93, 0x2f, 0x40, 0x99, 0x24, 0x14, 0x68, 0x64, 0xf1, 0xdc, 0xa3, 0xf8, 0x5c, + 0x52, 0x3b, 0x23, 0x05, 0xdd, 0x7f, 0x0a, 0xa5, 0x68, 0x17, 0x21, 0x0a, 0x94, 0xce, 0x7a, 0xbd, + 0xbe, 0xd9, 0x1b, 0x0d, 0xd5, 0x07, 0xa4, 0x02, 0x45, 0xfc, 0xd5, 0xe9, 0xaa, 0x99, 0xfd, 0x00, + 0xca, 0xf1, 0x2a, 0x42, 0xaa, 0x50, 0xee, 0x74, 0x3b, 0xc3, 0x4e, 0x6b, 0xa8, 0x1f, 0xab, 0x0f, + 0xc8, 0x23, 0x58, 0xef, 0x1b, 0x7a, 0xe7, 0xbc, 0xf5, 0x5c, 0x37, 0x0d, 0xfd, 0xa5, 0xde, 0x3a, + 0xd3, 0x8f, 0xd5, 0x0c, 0x21, 0x50, 0x3b, 0x1d, 0x9e, 0xb5, 0xcd, 0xfe, 0xe8, 0xe8, 0xac, 0x33, + 0x38, 0xd5, 0x8f, 0xd5, 0xac, 0x90, 0x39, 0x18, 0xb5, 0xdb, 0xfa, 0x60, 0xa0, 0xe6, 0x08, 0xc0, + 0xda, 0x49, 0xab, 0x23, 0xc0, 0x79, 0xb2, 0x01, 0xf5, 0x4e, 0xf7, 0x65, 0xaf, 0xd3, 0xd6, 0xcd, + 0x81, 0x3e, 0x1c, 0x0a, 0x62, 0x61, 0xff, 0x1f, 0x19, 0xa8, 0xa6, 0xb6, 0x19, 0xb2, 0x05, 0x1b, + 0xe2, 0xc8, 0xc8, 0x10, 0x37, 0xb5, 0x06, 0xbd, 0xae, 0xd9, 0xed, 0x75, 0x75, 0xf5, 0x01, 0x79, + 0x07, 0xb6, 0x16, 0x18, 0xbd, 0x93, 0x93, 0xf6, 0x69, 0x4b, 0x3c, 0x9e, 0x34, 0x61, 0x73, 0x81, + 0x39, 0xec, 0x9c, 0xeb, 0x42, 0xcb, 0x2c, 0xd9, 0x85, 0x9d, 0x05, 0xde, 0xe0, 0x3b, 0x5d, 0xef, + 0xc7, 0x88, 0x1c, 0x79, 0x0a, 0x4f, 0x16, 0x10, 0x9d, 0xee, 0x60, 0x74, 0x72, 0xd2, 0x69, 0x77, + 0xf4, 0xee, 0xd0, 0x7c, 0xd9, 0x3a, 0x1b, 0xe9, 0x6a, 0x9e, 0xec, 0x40, 0x63, 0xf1, 0x12, 0xfd, + 0xbc, 0xdf, 0x33, 0x5a, 0xc6, 0x2b, 0xb5, 0x40, 0xde, 0x87, 0xc7, 0x77, 0x84, 0xb4, 0x7b, 0x86, + 0xa1, 0xb7, 0x87, 0x66, 0xeb, 0xbc, 0x37, 0xea, 0x0e, 0xd5, 0xb5, 0xfd, 0x03, 0xb1, 0x31, 0x2c, + 0x24, 0xa4, 0x30, 0xd9, 0xa8, 0xfb, 0x4d, 0xb7, 0xf7, 0x5d, 0x57, 0x7d, 0x20, 0x2c, 0x3f, 0x3c, + 0x35, 0xf4, 0xc1, 0x69, 0xef, 0xec, 0x58, 0xcd, 0xec, 0xff, 0x26, 0x07, 0x30, 0x8f, 0x2d, 0x61, + 0x9d, 0xd6, 0x68, 0xd8, 0x8b, 0x6e, 0x98, 0x1f, 0xd3, 0xe0, 0xbd, 0x24, 0xe3, 0x68, 0x74, 0xfc, + 0x5c, 0x1f, 0x9a, 0xdd, 0xde, 0xd0, 0x1c, 0x0c, 0x5b, 0xc6, 0x10, 0xdd, 0xd5, 0x84, 0xcd, 0x24, + 0x46, 0x5a, 0xe1, 0x44, 0xd7, 0x07, 0x6a, 0x96, 0xbc, 0x07, 0xcd, 0x25, 0xe7, 0xf5, 0xb3, 0x56, + 0x7f, 0xa0, 0x1f, 0xab, 0x39, 0xb2, 0x0d, 0x8f, 0x92, 0xfc, 0x4e, 0xd7, 0x3c, 0x39, 0xeb, 0x3c, + 0x3f, 0x1d, 0xaa, 0x79, 0xd2, 0x80, 0x87, 0x69, 0xb1, 0x2d, 0x94, 0xaa, 0x16, 0x16, 0x0f, 0x9d, + 0x77, 0xba, 0xba, 0x81, 0xac, 0x35, 0xb2, 0x09, 0x24, 0xc9, 0xea, 0x1b, 0x7a, 0xbf, 0xf5, 0x4a, + 0x2d, 0x92, 0xc7, 0xf0, 0x4e, 0x92, 0x1e, 0x59, 0xf4, 0xa8, 0xd5, 0xfe, 0xa6, 0x77, 0x72, 0xa2, + 0x96, 0x16, 0x6f, 0x8b, 0xa3, 0xb9, 0xbc, 0x68, 0x9b, 0x28, 0xb2, 0x41, 0xf8, 0x2d, 0xc5, 0xe8, + 0x7c, 0x3b, 0xea, 0x1c, 0x77, 0x86, 0xaf, 0xcc, 0xde, 0x37, 0x6a, 0x45, 0xf8, 0x6d, 0x89, 0xe6, + 0xc9, 0x00, 0x50, 0x15, 0x11, 0x43, 0xa9, 0x67, 0xe9, 0x7a, 0x1a, 0x51, 0x3d, 0xfc, 0x6b, 0x59, + 0x7e, 0x56, 0x68, 0xe3, 0x87, 0x4c, 0x62, 0x40, 0x31, 0x4c, 0x65, 0xb2, 0x2a, 0xb9, 0x9b, 0x8f, + 0x52, 0xab, 0x61, 0x5c, 0xc2, 0xb6, 0x7e, 0xf1, 0xe7, 0xbf, 0xfd, 0x2a, 0xbb, 0xae, 0x29, 0x07, + 0x6f, 0x3e, 0x3b, 0x10, 0x88, 0x03, 0x77, 0xc6, 0xbf, 0xcc, 0xec, 0x93, 0x1e, 0xac, 0xc9, 0xcf, + 0x57, 0x64, 0x33, 0x25, 0x32, 0xfe, 0x9e, 0xb5, 0x4a, 0xe2, 0x26, 0x4a, 0x54, 0xb5, 0x4a, 0x2c, + 0xd1, 0x72, 0x84, 0xc0, 0x2f, 0xa0, 0x18, 0x7e, 0x1c, 0x49, 0x3c, 0x32, 0xfd, 0xb9, 0xa4, 0xb9, + 0x6c, 0x7f, 0xfd, 0xef, 0x0c, 0xf9, 0x5f, 0x28, 0xc7, 0xab, 0x2f, 0xd9, 0x4e, 0x14, 0xef, 0x74, + 0xe1, 0x6d, 0x36, 0x97, 0xb1, 0xd2, 0xcf, 0x22, 0xb5, 0xf8, 0x59, 0xb8, 0x16, 0x93, 0x91, 0x2c, + 0x58, 0x62, 0x2d, 0x26, 0x8d, 0xd4, 0xf5, 0x89, 0x4d, 0x79, 0xe9, 0xc3, 0xb4, 0x26, 0x8a, 0x7c, + 0x48, 0x48, 0x4a, 0xe4, 0xc1, 0x0f, 0xd6, 0xe4, 0xff, 0xc9, 0xff, 0x81, 0x12, 0x3a, 0x00, 0x97, + 0x57, 0x32, 0x37, 0x56, 0x72, 0xc3, 0x6e, 0xce, 0x95, 0x59, 0x5c, 0x73, 0x97, 0x48, 0x77, 0x67, + 0xfc, 0x80, 0xa3, 0xb4, 0x8b, 0x58, 0x3a, 0x2e, 0x45, 0x09, 0xe9, 0xc9, 0xf5, 0x32, 0x2d, 0x3d, + 0xb5, 0x3e, 0x69, 0xbb, 0x28, 0xbd, 0x49, 0x1a, 0x29, 0xe9, 0xaf, 0x05, 0xe6, 0xe0, 0x07, 0x6a, + 0x73, 0xa1, 0x41, 0x4d, 0xcc, 0xc4, 0xe8, 0xf2, 0x7b, 0x75, 0x98, 0x5b, 0x6d, 0xe1, 0x63, 0x81, + 0xb6, 0x8d, 0x97, 0x6c, 0x90, 0xf5, 0x44, 0x28, 0xc4, 0x1a, 0xcc, 0xa5, 0xdf, 0xab, 0x43, 0x52, + 0x7a, 0x5a, 0x85, 0xc7, 0x28, 0x7d, 0x9b, 0x6c, 0x25, 0xa5, 0x27, 0x35, 0x78, 0x05, 0x55, 0x71, + 0x47, 0xb4, 0x15, 0x05, 0x89, 0x48, 0x4e, 0xad, 0x5e, 0xcd, 0xad, 0x3b, 0xf4, 0x74, 0x76, 0x90, + 0x3a, 0x5e, 0x11, 0x50, 0x7e, 0x20, 0xd7, 0x2d, 0xc2, 0x81, 0xdc, 0x5d, 0x18, 0x88, 0x16, 0xcb, + 0x59, 0xb9, 0x4d, 0x34, 0xef, 0x9d, 0x3d, 0xb4, 0x1d, 0xbc, 0x70, 0x93, 0x3c, 0xc4, 0x0b, 0x23, + 0xc0, 0x81, 0x27, 0xe5, 0xff, 0x0c, 0xc8, 0xe0, 0xbe, 0x5b, 0x57, 0x4e, 0x41, 0xcd, 0xf7, 0xef, + 0xc5, 0xa4, 0x0d, 0xaa, 0x2d, 0xbd, 0x5c, 0xa4, 0x30, 0x03, 0x25, 0x39, 0x63, 0x90, 0xb9, 0x2e, + 0x4b, 0xc6, 0xa0, 0xe6, 0xbb, 0x2b, 0xb8, 0xe1, 0x6d, 0x0d, 0xbc, 0x8d, 0x10, 0x55, 0xdc, 0x26, + 0x26, 0xdf, 0x83, 0x40, 0xc2, 0x2e, 0xd6, 0xf0, 0x3f, 0x2e, 0x9f, 0xff, 0x33, 0x00, 0x00, 0xff, + 0xff, 0x07, 0x5c, 0xde, 0x26, 0xa8, 0x19, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/looprpc/client.proto b/looprpc/client.proto index cb39798..8d0f891 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -952,6 +952,12 @@ enum AutoReason { other swaps. */ AUTO_REASON_BUDGET_INSUFFICIENT = 12; + + /* + Fee insufficient indicates that the fee estimate for a swap is higher than + the portion of total swap amount that we allow fees to consume. + */ + AUTO_REASON_FEE_INSUFFICIENT = 13; } message Disqualified { diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index b402ac1..425c533 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -410,10 +410,11 @@ "AUTO_REASON_LOOP_OUT", "AUTO_REASON_LOOP_IN", "AUTO_REASON_LIQUIDITY_OK", - "AUTO_REASON_BUDGET_INSUFFICIENT" + "AUTO_REASON_BUDGET_INSUFFICIENT", + "AUTO_REASON_FEE_INSUFFICIENT" ], "default": "AUTO_REASON_UNKNOWN", - "description": " - AUTO_REASON_BUDGET_NOT_STARTED: Budget not started indicates that we do not recommend any swaps because \nthe start time for our budget has not arrived yet.\n - AUTO_REASON_SWEEP_FEES: Sweep fees indicates that the estimated fees to sweep swaps are too high \nright now.\n - AUTO_REASON_BUDGET_ELAPSED: Budget elapsed indicates that the autoloop budget for the period has been \nelapsed.\n - AUTO_REASON_IN_FLIGHT: In flight indicates that the limit on in-flight automatically dispatched \nswaps has already been reached.\n - AUTO_REASON_SWAP_FEE: Swap fee indicates that the server fee for a specific swap is too high.\n - AUTO_REASON_MINER_FEE: Miner fee indicates that the miner fee for a specific swap is to high.\n - AUTO_REASON_PREPAY: Prepay indicates that the prepay fee for a specific swap is too high.\n - AUTO_REASON_FAILURE_BACKOFF: Failure backoff indicates that a swap has recently failed for this target,\nand the backoff period has not yet passed.\n - AUTO_REASON_LOOP_OUT: Loop out indicates that a loop out swap is currently utilizing the channel,\nso it is not eligible.\n - AUTO_REASON_LOOP_IN: Loop In indicates that a loop in swap is currently in flight for the peer, \nso it is not eligible.\n - AUTO_REASON_LIQUIDITY_OK: Liquidity ok indicates that a target meets the liquidity balance expressed \nin its rule, so no swap is needed.\n - AUTO_REASON_BUDGET_INSUFFICIENT: Budget insufficient indicates that we cannot perform a swap because we do \nnot have enough pending budget available. This differs from budget elapsed, \nbecause we still have some budget available, but we have allocated it to \nother swaps." + "description": " - AUTO_REASON_BUDGET_NOT_STARTED: Budget not started indicates that we do not recommend any swaps because \nthe start time for our budget has not arrived yet.\n - AUTO_REASON_SWEEP_FEES: Sweep fees indicates that the estimated fees to sweep swaps are too high \nright now.\n - AUTO_REASON_BUDGET_ELAPSED: Budget elapsed indicates that the autoloop budget for the period has been \nelapsed.\n - AUTO_REASON_IN_FLIGHT: In flight indicates that the limit on in-flight automatically dispatched \nswaps has already been reached.\n - AUTO_REASON_SWAP_FEE: Swap fee indicates that the server fee for a specific swap is too high.\n - AUTO_REASON_MINER_FEE: Miner fee indicates that the miner fee for a specific swap is to high.\n - AUTO_REASON_PREPAY: Prepay indicates that the prepay fee for a specific swap is too high.\n - AUTO_REASON_FAILURE_BACKOFF: Failure backoff indicates that a swap has recently failed for this target,\nand the backoff period has not yet passed.\n - AUTO_REASON_LOOP_OUT: Loop out indicates that a loop out swap is currently utilizing the channel,\nso it is not eligible.\n - AUTO_REASON_LOOP_IN: Loop In indicates that a loop in swap is currently in flight for the peer, \nso it is not eligible.\n - AUTO_REASON_LIQUIDITY_OK: Liquidity ok indicates that a target meets the liquidity balance expressed \nin its rule, so no swap is needed.\n - AUTO_REASON_BUDGET_INSUFFICIENT: Budget insufficient indicates that we cannot perform a swap because we do \nnot have enough pending budget available. This differs from budget elapsed, \nbecause we still have some budget available, but we have allocated it to \nother swaps.\n - AUTO_REASON_FEE_INSUFFICIENT: Fee insufficient indicates that the fee estimate for a swap is higher than\nthe portion of total swap amount that we allow fees to consume." }, "looprpcDisqualified": { "type": "object",