diff --git a/channeldb/invoice_test.go b/channeldb/invoice_test.go index 3b0416d1..61806d39 100644 --- a/channeldb/invoice_test.go +++ b/channeldb/invoice_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/lightningnetwork/lnd/clock" + "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" @@ -16,7 +17,15 @@ import ( var ( emptyFeatures = lnwire.NewFeatureVector(nil, lnwire.Features) - testNow = time.Unix(1, 0) + ampFeatures = lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.PaymentAddrOptional, + lnwire.AMPRequired, + ), + lnwire.Features, + ) + testNow = time.Unix(1, 0) ) func randInvoice(value lnwire.MilliSatoshi) (*Invoice, error) { @@ -1208,23 +1217,30 @@ func TestInvoiceRef(t *testing.T) { // An InvoiceRef by hash should return the provided hash and a nil // payment addr. refByHash := InvoiceRefByHash(payHash) - require.Equal(t, payHash, refByHash.PayHash()) + require.Equal(t, &payHash, refByHash.PayHash()) require.Equal(t, (*[32]byte)(nil), refByHash.PayAddr()) require.Equal(t, (*[32]byte)(nil), refByHash.SetID()) // An InvoiceRef by hash and addr should return the payment hash and // payment addr passed to the constructor. refByHashAndAddr := InvoiceRefByHashAndAddr(payHash, payAddr) - require.Equal(t, payHash, refByHashAndAddr.PayHash()) + require.Equal(t, &payHash, refByHashAndAddr.PayHash()) require.Equal(t, &payAddr, refByHashAndAddr.PayAddr()) require.Equal(t, (*[32]byte)(nil), refByHashAndAddr.SetID()) // An InvoiceRef by set id should return an empty pay hash, a nil pay // addr, and a reference to the given set id. refBySetID := InvoiceRefBySetID(setID) - require.Equal(t, lntypes.Hash{}, refBySetID.PayHash()) + require.Equal(t, (*lntypes.Hash)(nil), refBySetID.PayHash()) require.Equal(t, (*[32]byte)(nil), refBySetID.PayAddr()) require.Equal(t, &setID, refBySetID.SetID()) + + // An InvoiceRef by pay addr should only return a pay addr, but nil for + // pay hash and set id. + refByAddr := InvoiceRefByAddr(payAddr) + require.Equal(t, (*lntypes.Hash)(nil), refByAddr.PayHash()) + require.Equal(t, &payAddr, refByAddr.PayAddr()) + require.Equal(t, (*[32]byte)(nil), refByAddr.SetID()) } // TestHTLCSet asserts that HTLCSet returns the proper set of accepted HTLCs @@ -1366,7 +1382,7 @@ func TestSetIDIndex(t *testing.T) { invoice.AmtPaid = amt invoice.SettleDate = dbInvoice.SettleDate invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{ - {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, preimage), + {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, payHash, &preimage), } // We should get back the exact same invoice that we just inserted. @@ -1406,9 +1422,9 @@ func TestSetIDIndex(t *testing.T) { invoice.AmtPaid += 2 * amt invoice.SettleDate = dbInvoice.SettleDate invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{ - {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, preimage), - {HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, preimage), - {HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, preimage), + {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, payHash, &preimage), + {HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil), + {HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil), } // We should get back the exact same invoice that we just inserted. @@ -1452,7 +1468,7 @@ func TestSetIDIndex(t *testing.T) { } func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte, - preimage lntypes.Preimage) *InvoiceHTLC { + hash lntypes.Hash, preimage *lntypes.Preimage) *InvoiceHTLC { return &InvoiceHTLC{ Amt: amt, @@ -1462,8 +1478,8 @@ func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte, CustomRecords: make(record.CustomSet), AMP: &InvoiceHtlcAMPData{ Record: *record.NewAMP([32]byte{}, setID, 0), - Hash: preimage.Hash(), - Preimage: &preimage, + Hash: hash, + Preimage: preimage, }, } } @@ -1480,18 +1496,23 @@ func updateAcceptAMPHtlc(id uint64, amt lnwire.MilliSatoshi, noRecords := make(record.CustomSet) - var state *InvoiceStateUpdateDesc + var ( + state *InvoiceStateUpdateDesc + preimage *lntypes.Preimage + ) if accept { state = &InvoiceStateUpdateDesc{ NewState: ContractAccepted, SetID: setID, } + pre := *invoice.Terms.PaymentPreimage + preimage = &pre } ampData := &InvoiceHtlcAMPData{ Record: *record.NewAMP([32]byte{}, *setID, 0), Hash: invoice.Terms.PaymentPreimage.Hash(), - Preimage: invoice.Terms.PaymentPreimage, + Preimage: preimage, } update := &InvoiceUpdateDesc{ State: state, @@ -1526,6 +1547,792 @@ func getUpdateInvoiceAMPSettle(setID *[32]byte) InvoiceUpdateCallback { } } +// TestUnexpectedInvoicePreimage asserts that legacy or MPP invoices cannot be +// settled when referenced by payment address only. Since regular or MPP +// payments do not store the payment hash explicitly (it is stored in the +// index), this enforces that they can only be updated using a InvoiceRefByHash +// or InvoiceRefByHashOrAddr. +func TestUnexpectedInvoicePreimage(t *testing.T) { + t.Parallel() + + db, cleanup, err := MakeTestDB() + defer cleanup() + require.NoError(t, err, "unable to make test db") + + invoice, err := randInvoice(lnwire.MilliSatoshi(100)) + require.NoError(t, err) + + // Add a random invoice indexed by payment hash and payment addr. + paymentHash := invoice.Terms.PaymentPreimage.Hash() + _, err = db.AddInvoice(invoice, paymentHash) + require.NoError(t, err) + + // Attempt to update the invoice by pay addr only. This will fail since, + // in order to settle an MPP invoice, the InvoiceRef must present a + // payment hash against which to validate the preimage. + _, err = db.UpdateInvoice( + InvoiceRefByAddr(invoice.Terms.PaymentAddr), + getUpdateInvoice(invoice.Terms.Value), + ) + + //Assert that we get ErrUnexpectedInvoicePreimage. + require.Error(t, ErrUnexpectedInvoicePreimage, err) +} + +type updateHTLCPreimageTestCase struct { + name string + settleSamePreimage bool + expError error +} + +// TestUpdateHTLCPreimages asserts various properties of setting HTLC-level +// preimages on invoice state transitions. +func TestUpdateHTLCPreimages(t *testing.T) { + t.Parallel() + + tests := []updateHTLCPreimageTestCase{ + { + name: "same preimage on settle", + settleSamePreimage: true, + expError: nil, + }, + { + name: "diff preimage on settle", + settleSamePreimage: false, + expError: ErrHTLCPreimageAlreadyExists, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + testUpdateHTLCPreimages(t, test) + }) + } +} + +func testUpdateHTLCPreimages(t *testing.T, test updateHTLCPreimageTestCase) { + db, cleanup, err := MakeTestDB() + defer cleanup() + require.NoError(t, err, "unable to make test db") + + // We'll start out by creating an invoice and writing it to the DB. + amt := lnwire.NewMSatFromSatoshis(1000) + invoice, err := randInvoice(amt) + require.Nil(t, err) + + preimage := *invoice.Terms.PaymentPreimage + payHash := preimage.Hash() + + // Set AMP-specific features so that we can settle with HTLC-level + // preimages. + invoice.Terms.Features = ampFeatures + + _, err = db.AddInvoice(invoice, payHash) + require.Nil(t, err) + + setID := &[32]byte{1} + + // Update the invoice with an accepted HTLC that also accepts the + // invoice. + ref := InvoiceRefByAddr(invoice.Terms.PaymentAddr) + dbInvoice, err := db.UpdateInvoice(ref, updateAcceptAMPHtlc(0, amt, setID, true)) + require.Nil(t, err) + + htlcPreimages := make(map[CircuitKey]lntypes.Preimage) + for key := range dbInvoice.Htlcs { + // Set the either the same preimage used to accept above, or a + // blank preimage depending on the test case. + var pre lntypes.Preimage + if test.settleSamePreimage { + pre = preimage + } + htlcPreimages[key] = pre + } + + updateInvoice := func(invoice *Invoice) (*InvoiceUpdateDesc, error) { + update := &InvoiceUpdateDesc{ + State: &InvoiceStateUpdateDesc{ + Preimage: nil, + NewState: ContractSettled, + HTLCPreimages: htlcPreimages, + SetID: setID, + }, + } + + return update, nil + } + + // Now settle the HTLC set and assert the resulting error. + _, err = db.UpdateInvoice(ref, updateInvoice) + require.Equal(t, test.expError, err) +} + +type updateHTLCTest struct { + name string + input InvoiceHTLC + invState ContractState + setID *[32]byte + output InvoiceHTLC + expErr error +} + +// TestUpdateHTLC asserts the behavior of the updateHTLC method in various +// scenarios for MPP and AMP. +func TestUpdateHTLC(t *testing.T) { + t.Parallel() + + setID := [32]byte{0x01} + ampRecord := record.NewAMP([32]byte{0x02}, setID, 3) + preimage := lntypes.Preimage{0x04} + hash := preimage.Hash() + + diffSetID := [32]byte{0x05} + fakePreimage := lntypes.Preimage{0x06} + testAlreadyNow := time.Now() + + tests := []updateHTLCTest{ + { + name: "MPP accept", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + invState: ContractAccepted, + setID: nil, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + expErr: nil, + }, + { + name: "MPP settle", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + invState: ContractSettled, + setID: nil, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + expErr: nil, + }, + { + name: "MPP cancel", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + invState: ContractCanceled, + setID: nil, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: nil, + }, + expErr: nil, + }, + { + name: "AMP accept missing preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: nil, + }, + }, + invState: ContractAccepted, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: nil, + }, + }, + expErr: ErrHTLCPreimageMissing, + }, + { + name: "AMP accept invalid preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &fakePreimage, + }, + }, + invState: ContractAccepted, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &fakePreimage, + }, + }, + expErr: ErrHTLCPreimageMismatch, + }, + { + name: "AMP accept valid preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractAccepted, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "AMP accept valid preimage different htlc set", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractAccepted, + setID: &diffSetID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "AMP settle missing preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: nil, + }, + }, + invState: ContractSettled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: nil, + }, + }, + expErr: ErrHTLCPreimageMissing, + }, + { + name: "AMP settle invalid preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &fakePreimage, + }, + }, + invState: ContractSettled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &fakePreimage, + }, + }, + expErr: ErrHTLCPreimageMismatch, + }, + { + name: "AMP settle valid preimage", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractSettled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "AMP settle valid preimage different htlc set", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractSettled, + setID: &diffSetID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "accept invoice htlc already settled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractAccepted, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: ErrHTLCAlreadySettled, + }, + { + name: "cancel invoice htlc already settled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractCanceled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: ErrHTLCAlreadySettled, + }, + { + name: "settle invoice htlc already settled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractSettled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateSettled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "cancel invoice", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: time.Time{}, + Expiry: 40, + State: HtlcStateAccepted, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractCanceled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "accept invoice htlc already canceled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractAccepted, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "cancel invoice htlc already canceled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractCanceled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + { + name: "settle invoice htlc already canceled", + input: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + invState: ContractSettled, + setID: &setID, + output: InvoiceHTLC{ + Amt: 5000, + MppTotalAmt: 5000, + AcceptHeight: 100, + AcceptTime: testNow, + ResolveTime: testAlreadyNow, + Expiry: 40, + State: HtlcStateCanceled, + CustomRecords: make(record.CustomSet), + AMP: &InvoiceHtlcAMPData{ + Record: *ampRecord, + Hash: hash, + Preimage: &preimage, + }, + }, + expErr: nil, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + testUpdateHTLC(t, test) + }) + } +} + +func testUpdateHTLC(t *testing.T, test updateHTLCTest) { + htlc := test.input.Copy() + err := updateHtlc(testNow, htlc, test.invState, test.setID) + require.Equal(t, test.expErr, err) + require.Equal(t, test.output, *htlc) +} + // TestDeleteInvoices tests that deleting a list of invoices will succeed // if all delete references are valid, or will fail otherwise. func TestDeleteInvoices(t *testing.T) { @@ -1619,3 +2426,30 @@ func TestDeleteInvoices(t *testing.T) { assertInvoiceCount(0) } + +// TestAddInvoiceInvalidFeatureDeps asserts that inserting an invoice with +// invalid transitive feature dependencies fails with the appropriate error. +func TestAddInvoiceInvalidFeatureDeps(t *testing.T) { + t.Parallel() + + db, cleanup, err := MakeTestDB() + require.NoError(t, err, "unable to make test db") + defer cleanup() + + invoice, err := randInvoice(500) + require.NoError(t, err) + + invoice.Terms.Features = lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.MPPOptional, + ), + lnwire.Features, + ) + + hash := invoice.Terms.PaymentPreimage.Hash() + _, err = db.AddInvoice(invoice, hash) + require.Error(t, err, feature.NewErrMissingFeatureDep( + lnwire.PaymentAddrOptional, + )) +} diff --git a/channeldb/invoices.go b/channeldb/invoices.go index 7598575a..fbec1a39 100644 --- a/channeldb/invoices.go +++ b/channeldb/invoices.go @@ -6,9 +6,11 @@ import ( "errors" "fmt" "io" + "strings" "time" "github.com/lightningnetwork/lnd/channeldb/kvdb" + "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/htlcswitch/hop" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" @@ -115,6 +117,19 @@ var ( // match the invoice hash. ErrInvoicePreimageMismatch = errors.New("preimage does not match") + // ErrHTLCPreimageMissing is returned when trying to accept/settle an + // AMP HTLC but the HTLC-level preimage has not been set. + ErrHTLCPreimageMissing = errors.New("AMP htlc missing preimage") + + // ErrHTLCPreimageMismatch is returned when trying to accept/settle an + // AMP HTLC but the HTLC-level preimage does not satisfying the + // HTLC-level payment hash. + ErrHTLCPreimageMismatch = errors.New("htlc preimage mismatch") + + // ErrHTLCAlreadySettled is returned when trying to settle an invoice + // but HTLC already exists in the settled state. + ErrHTLCAlreadySettled = errors.New("htlc already settled") + // ErrInvoiceHasHtlcs is returned when attempting to insert an invoice // that already has HTLCs. ErrInvoiceHasHtlcs = errors.New("cannot add invoice with htlcs") @@ -122,6 +137,19 @@ var ( // ErrEmptyHTLCSet is returned when attempting to accept or settle and // HTLC set that has no HTLCs. ErrEmptyHTLCSet = errors.New("cannot settle/accept empty HTLC set") + + // ErrUnexpectedInvoicePreimage is returned when an invoice-level + // preimage is provided when trying to settle an invoice that shouldn't + // have one, e.g. an AMP invoice. + ErrUnexpectedInvoicePreimage = errors.New( + "unexpected invoice preimage provided on settle", + ) + + // ErrHTLCPreimageAlreadyExists is returned when trying to set an + // htlc-level preimage but one is already known. + ErrHTLCPreimageAlreadyExists = errors.New( + "htlc-level preimage already exists", + ) ) // ErrDuplicateSetID is an error returned when attempting to adding an AMP HTLC @@ -198,7 +226,7 @@ type InvoiceRef struct { // payHash is the payment hash of the target invoice. All invoices are // currently indexed by payment hash. This value will be used as a // fallback when no payment address is known. - payHash lntypes.Hash + payHash *lntypes.Hash // payAddr is the payment addr of the target invoice. Newer invoices // (0.11 and up) are indexed by payment address in addition to payment @@ -220,7 +248,7 @@ type InvoiceRef struct { // its payment hash. func InvoiceRefByHash(payHash lntypes.Hash) InvoiceRef { return InvoiceRef{ - payHash: payHash, + payHash: &payHash, } } @@ -231,11 +259,19 @@ func InvoiceRefByHashAndAddr(payHash lntypes.Hash, payAddr [32]byte) InvoiceRef { return InvoiceRef{ - payHash: payHash, + payHash: &payHash, payAddr: &payAddr, } } +// InvoiceRefByAddr creates an InvoiceRef that queries the payment addr index +// for an invoice with the provided payment address. +func InvoiceRefByAddr(addr [32]byte) InvoiceRef { + return InvoiceRef{ + payAddr: &addr, + } +} + // InvoiceRefBySetID creates an InvoiceRef that queries the set id index for an // invoice with the provided setID. If the invoice is not found, the query will // not fallback to payHash or payAddr. @@ -245,9 +281,15 @@ func InvoiceRefBySetID(setID [32]byte) InvoiceRef { } } -// PayHash returns the target invoice's payment hash. -func (r InvoiceRef) PayHash() lntypes.Hash { - return r.payHash +// PayHash returns the optional payment hash of the target invoice. +// +// NOTE: This value may be nil. +func (r InvoiceRef) PayHash() *lntypes.Hash { + if r.payHash != nil { + hash := *r.payHash + return &hash + } + return nil } // PayAddr returns the optional payment address of the target invoice. @@ -274,10 +316,17 @@ func (r InvoiceRef) SetID() *[32]byte { // String returns a human-readable representation of an InvoiceRef. func (r InvoiceRef) String() string { - if r.payAddr != nil { - return fmt.Sprintf("(pay_hash=%v, pay_addr=%x)", r.payHash, *r.payAddr) + var ids []string + if r.payHash != nil { + ids = append(ids, fmt.Sprintf("pay_hash=%v", *r.payHash)) } - return fmt.Sprintf("(pay_hash=%v)", r.payHash) + if r.payAddr != nil { + ids = append(ids, fmt.Sprintf("pay_addr=%x", *r.payAddr)) + } + if r.setID != nil { + ids = append(ids, fmt.Sprintf("set_id=%x", *r.setID)) + } + return fmt.Sprintf("(%s)", strings.Join(ids, ", ")) } // ContractState describes the state the invoice is in. @@ -499,6 +548,21 @@ type InvoiceHTLC struct { AMP *InvoiceHtlcAMPData } +// Copy makes a deep copy of the target InvoiceHTLC. +func (h *InvoiceHTLC) Copy() *InvoiceHTLC { + result := *h + + // Make a copy of the CustomSet map. + result.CustomRecords = make(record.CustomSet) + for k, v := range h.CustomRecords { + result.CustomRecords[k] = v + } + + result.AMP = h.AMP.Copy() + + return &result +} + // IsInHTLCSet returns true if this HTLC is part an HTLC set. If nil is passed, // this method returns true if this is an MPP HTLC. Otherwise, it only returns // true if the AMP HTLC's set id matches the populated setID. @@ -616,6 +680,11 @@ type InvoiceStateUpdateDesc struct { // Preimage must be set to the preimage when NewState is settled. Preimage *lntypes.Preimage + // HTLCPreimages set the HTLC-level preimages stored for AMP HTLCs. + // These are only learned when settling the invoice as a whole. Must be + // set when settling an invoice with non-nil SetID. + HTLCPreimages map[CircuitKey]lntypes.Preimage + // SetID identifies a specific set of HTLCs destined for the same // invoice as part of a larger AMP payment. This value will be nil for // legacy or MPP payments. @@ -645,7 +714,17 @@ func validateInvoice(i *Invoice, paymentHash lntypes.Hash) error { return errors.New("invoice must have a feature vector") } - if i.Terms.PaymentPreimage == nil && !i.HodlInvoice { + err := feature.ValidateDeps(i.Terms.Features) + if err != nil { + return err + } + + // AMP invoices and hodl invoices are allowed to have no preimage + // specified. + isAMP := i.Terms.Features.HasFeature( + lnwire.AMPOptional, + ) + if i.Terms.PaymentPreimage == nil && !(i.HodlInvoice || isAMP) { return errors.New("non-hodl invoices must have a preimage") } @@ -879,19 +958,27 @@ func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket, payHash := ref.PayHash() payAddr := ref.PayAddr() - var ( - invoiceNumByHash = invoiceIndex.Get(payHash[:]) - invoiceNumByAddr []byte - ) - if payAddr != nil { - // Only allow lookups for payment address if it is not a blank - // payment address, which is a special-cased value for legacy - // keysend invoices. - if *payAddr != BlankPayAddr { - invoiceNumByAddr = payAddrIndex.Get(payAddr[:]) + getInvoiceNumByHash := func() []byte { + if payHash != nil { + return invoiceIndex.Get(payHash[:]) } + return nil } + getInvoiceNumByAddr := func() []byte { + if payAddr != nil { + // Only allow lookups for payment address if it is not a + // blank payment address, which is a special-cased value + // for legacy keysend invoices. + if *payAddr != BlankPayAddr { + return payAddrIndex.Get(payAddr[:]) + } + } + return nil + } + + invoiceNumByHash := getInvoiceNumByHash() + invoiceNumByAddr := getInvoiceNumByAddr() switch { // If payment address and payment hash both reference an existing @@ -903,6 +990,10 @@ func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket, return invoiceNumByAddr, nil + // Return invoices by payment addr only. + case invoiceNumByAddr != nil: + return invoiceNumByAddr, nil + // If we were only able to reference the invoice by hash, return the // corresponding invoice number. This can happen when no payment address // was provided, or if it didn't match anything in our records. @@ -1684,21 +1775,6 @@ func copySlice(src []byte) []byte { return dest } -// copyInvoiceHTLC makes a deep copy of the supplied invoice HTLC. -func copyInvoiceHTLC(src *InvoiceHTLC) *InvoiceHTLC { - result := *src - - // Make a copy of the CustomSet map. - result.CustomRecords = make(record.CustomSet) - for k, v := range src.CustomRecords { - result.CustomRecords[k] = v - } - - result.AMP = src.AMP.Copy() - - return &result -} - // copyInvoice makes a deep copy of the supplied invoice. func copyInvoice(src *Invoice) *Invoice { dest := Invoice{ @@ -1725,7 +1801,7 @@ func copyInvoice(src *Invoice) *Invoice { } for k, v := range src.Htlcs { - dest.Htlcs[k] = copyInvoiceHTLC(v) + dest.Htlcs[k] = v.Copy() } return &dest @@ -1733,7 +1809,7 @@ func copyInvoice(src *Invoice) *Invoice { // updateInvoice fetches the invoice, obtains the update descriptor from the // callback and applies the updates in a single db transaction. -func (d *DB) updateInvoice(hash lntypes.Hash, invoices, +func (d *DB) updateInvoice(hash *lntypes.Hash, invoices, settleIndex, setIDIndex kvdb.RwBucket, invoiceNum []byte, callback InvoiceUpdateCallback) (*Invoice, error) { @@ -1867,7 +1943,25 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, // the process by updating the state transitions for individual HTLCs // and recalculate the total amount paid to the invoice. var amtPaid lnwire.MilliSatoshi - for _, htlc := range invoice.Htlcs { + for key, htlc := range invoice.Htlcs { + // Set the HTLC preimage for any AMP HTLCs. + if setID != nil { + preimage, ok := update.State.HTLCPreimages[key] + switch { + + // If we don't already have a preiamge for this HTLC, we + // can set it now. + case ok && htlc.AMP.Preimage == nil: + htlc.AMP.Preimage = &preimage + + // Otherwise, prevent over-writing an existing preimage. + // Ignore the case where the preimage is identical. + case ok && *htlc.AMP.Preimage != preimage: + return nil, ErrHTLCPreimageAlreadyExists + + } + } + // The invoice state may have changed and this could have // implications for the states of the individual htlcs. Align // the htlc state with the current invoice state. @@ -1901,7 +1995,7 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, } // updateInvoiceState validates and processes an invoice state update. -func updateInvoiceState(invoice *Invoice, hash lntypes.Hash, +func updateInvoiceState(invoice *Invoice, hash *lntypes.Hash, update InvoiceStateUpdateDesc) error { // Returning to open is never allowed from any state. @@ -1950,9 +2044,14 @@ func updateInvoiceState(invoice *Invoice, hash lntypes.Hash, switch { + // If an invoice-level preimage was supplied, but the InvoiceRef + // doesn't specify a hash (e.g. AMP invoices) we fail. + case update.Preimage != nil && hash == nil: + return ErrUnexpectedInvoicePreimage + // Validate the supplied preimage for non-AMP invoices. case update.Preimage != nil: - if update.Preimage.Hash() != hash { + if update.Preimage.Hash() != *hash { return ErrInvoicePreimageMismatch } invoice.Terms.PaymentPreimage = update.Preimage @@ -2027,10 +2126,25 @@ func updateHtlc(resolveTime time.Time, htlc *InvoiceHTLC, // already know the preimage is valid due to checks at // the invoice level. For AMP HTLCs, verify that the // per-HTLC preimage-hash pair is valid. - if setID != nil && !htlc.AMP.Preimage.Matches(htlc.AMP.Hash) { - return fmt.Errorf("AMP preimage mismatch, "+ - "preimage=%v hash=%v", *htlc.AMP.Preimage, - htlc.AMP.Hash) + switch { + + // Non-AMP HTLCs can be settle immediately since we + // already know the preimage is valid due to checks at + // the invoice level. + case setID == nil: + + // At this popint, the setID is non-nil, meaning this is + // an AMP HTLC. We know that htlc.AMP cannot be nil, + // otherwise IsInHTLCSet would have returned false. + // + // Fail if an accepted AMP HTLC has no preimage. + case htlc.AMP.Preimage == nil: + return ErrHTLCPreimageMissing + + // Fail if the accepted AMP HTLC has an invalid + // preimage. + case !htlc.AMP.Preimage.Matches(htlc.AMP.Hash): + return ErrHTLCPreimageMismatch } htlcState = HtlcStateSettled @@ -2059,8 +2173,7 @@ func updateHtlc(resolveTime time.Time, htlc *InvoiceHTLC, // We should never find a settled HTLC on an invoice that isn't in // ContractSettled. if htlc.State == HtlcStateSettled { - return fmt.Errorf("cannot have a settled htlc with "+ - "invoice in state %v", invState) + return ErrHTLCAlreadySettled } switch invState { diff --git a/feature/default_sets.go b/feature/default_sets.go index 50b503f8..4c0de569 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -51,4 +51,9 @@ var defaultSetDesc = setDesc{ SetInit: {}, // I SetNodeAnn: {}, // N }, + lnwire.AMPOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + SetInvoice: {}, // 9 + }, } diff --git a/feature/deps.go b/feature/deps.go index c2b8f175..51ee37e9 100644 --- a/feature/deps.go +++ b/feature/deps.go @@ -58,6 +58,9 @@ var deps = depDesc{ lnwire.AnchorsOptional: { lnwire.StaticRemoteKeyOptional: {}, }, + lnwire.AMPOptional: { + lnwire.PaymentAddrOptional: {}, + }, } // ValidateDeps asserts that a feature vector sets all features and their diff --git a/feature/manager.go b/feature/manager.go index cbaf8f57..98918071 100644 --- a/feature/manager.go +++ b/feature/manager.go @@ -77,6 +77,8 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) { raw.Unset(lnwire.PaymentAddrRequired) raw.Unset(lnwire.MPPOptional) raw.Unset(lnwire.MPPRequired) + raw.Unset(lnwire.AMPOptional) + raw.Unset(lnwire.AMPRequired) } if cfg.NoStaticRemoteKey { raw.Unset(lnwire.StaticRemoteKeyOptional) diff --git a/htlcswitch/hop/payload.go b/htlcswitch/hop/payload.go index c6a25ba6..e233537f 100644 --- a/htlcswitch/hop/payload.go +++ b/htlcswitch/hop/payload.go @@ -119,6 +119,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) { amt uint64 cltv uint32 mpp = &record.MPP{} + amp = &record.AMP{} ) tlvStream, err := tlv.NewStream( @@ -126,6 +127,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) { record.NewLockTimeRecord(&cltv), record.NewNextHopIDRecord(&cid), mpp.Record(), + amp.Record(), ) if err != nil { return nil, err @@ -160,6 +162,12 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) { mpp = nil } + // If no AMP field was parsed, set the MPP field on the resulting + // payload to nil. + if _, ok := parsedTypes[record.AMPOnionType]; !ok { + amp = nil + } + // Filter out the custom records. customRecords := NewCustomRecords(parsedTypes) @@ -171,6 +179,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) { OutgoingCTLV: cltv, }, MPP: mpp, + AMP: amp, customRecords: customRecords, }, nil } @@ -207,6 +216,7 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap, _, hasLockTime := parsedTypes[record.LockTimeOnionType] _, hasNextHop := parsedTypes[record.NextHopOnionType] _, hasMPP := parsedTypes[record.MPPOnionType] + _, hasAMP := parsedTypes[record.AMPOnionType] switch { @@ -243,6 +253,14 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap, Violation: IncludedViolation, FinalHop: isFinalHop, } + + // Intermediate nodes should never receive AMP fields. + case !isFinalHop && hasAMP: + return ErrInvalidPayload{ + Type: record.AMPOnionType, + Violation: IncludedViolation, + FinalHop: isFinalHop, + } } return nil diff --git a/htlcswitch/hop/payload_test.go b/htlcswitch/hop/payload_test.go index b0a92534..c7abc9fa 100644 --- a/htlcswitch/hop/payload_test.go +++ b/htlcswitch/hop/payload_test.go @@ -8,14 +8,18 @@ import ( "github.com/lightningnetwork/lnd/htlcswitch/hop" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" + "github.com/stretchr/testify/require" ) +const testUnknownRequiredType = 0x10 + type decodePayloadTest struct { name string payload []byte expErr error expCustomRecords map[uint64][]byte shouldHaveMPP bool + shouldHaveAMP bool } var decodePayloadTests = []decodePayloadTest{ @@ -81,21 +85,26 @@ var decodePayloadTests = []decodePayloadTest{ }, }, { - name: "required type after omitted hop id", - payload: []byte{0x02, 0x00, 0x04, 0x00, 0x0a, 0x00}, + name: "required type after omitted hop id", + payload: []byte{ + 0x02, 0x00, 0x04, 0x00, + testUnknownRequiredType, 0x00, + }, expErr: hop.ErrInvalidPayload{ - Type: 10, + Type: testUnknownRequiredType, Violation: hop.RequiredViolation, FinalHop: true, }, }, { name: "required type after included hop id", - payload: []byte{0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + payload: []byte{ + 0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + testUnknownRequiredType, 0x00, }, expErr: hop.ErrInvalidPayload{ - Type: 10, + Type: testUnknownRequiredType, Violation: hop.RequiredViolation, FinalHop: false, }, @@ -176,6 +185,37 @@ var decodePayloadTests = []decodePayloadTest{ FinalHop: false, }, }, + { + name: "intermediate hop with amp", + payload: []byte{ + // amount + 0x02, 0x00, + // cltv + 0x04, 0x00, + // next hop id + 0x06, 0x08, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // amp + 0x0e, 0x41, + // amp.root_share + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + // amp.set_id + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + // amp.child_index + 0x09, + }, + expErr: hop.ErrInvalidPayload{ + Type: record.AMPOnionType, + Violation: hop.IncludedViolation, + FinalHop: false, + }, + }, { name: "final hop with mpp", payload: []byte{ @@ -194,6 +234,30 @@ var decodePayloadTests = []decodePayloadTest{ expErr: nil, shouldHaveMPP: true, }, + { + name: "final hop with amp", + payload: []byte{ + // amount + 0x02, 0x00, + // cltv + 0x04, 0x00, + // amp + 0x0e, 0x41, + // amp.root_share + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + // amp.set_id + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + // amp.child_index + 0x09, + }, + shouldHaveAMP: true, + }, } // TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the @@ -216,6 +280,20 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, } + + testRootShare = [32]byte{ + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + } + testSetID = [32]byte{ + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + } + testChildIndex = uint32(9) ) p, err := hop.NewPayloadFromReader(bytes.NewReader(test.payload)) @@ -242,6 +320,17 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) { t.Fatalf("unexpected MPP payload") } + if test.shouldHaveAMP { + if p.AMP == nil { + t.Fatalf("payload should have AMP record") + } + require.Equal(t, testRootShare, p.AMP.RootShare()) + require.Equal(t, testSetID, p.AMP.SetID()) + require.Equal(t, testChildIndex, p.AMP.ChildIndex()) + } else if p.AMP != nil { + t.Fatalf("unexpected AMP payload") + } + // Convert expected nil map to empty map, because we always expect an // initiated map from the payload. expCustomRecords := make(record.CustomSet) diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go index e6e4093b..b73de5e5 100644 --- a/invoices/invoiceregistry.go +++ b/invoices/invoiceregistry.go @@ -377,7 +377,8 @@ func (i *InvoiceRegistry) invoiceEventLoop() { func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) { // Dispatch to single invoice subscribers. for _, client := range i.singleNotificationClients { - if client.invoiceRef.PayHash() != event.hash { + payHash := client.invoiceRef.PayHash() + if payHash == nil || *payHash != event.hash { continue } @@ -524,8 +525,13 @@ func (i *InvoiceRegistry) deliverSingleBacklogEvents( return err } + payHash := client.invoiceRef.PayHash() + if payHash == nil { + return nil + } + err = client.notify(&invoiceEvent{ - hash: client.invoiceRef.PayHash(), + hash: *payHash, invoice: &invoice, }) if err != nil { @@ -775,6 +781,67 @@ func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error { return nil } +// processAMP just-in-time inserts an invoice if this htlc is a keysend +// htlc. +func (i *InvoiceRegistry) processAMP(ctx invoiceUpdateCtx) error { + // AMP payments MUST also include an MPP record. + if ctx.mpp == nil { + return errors.New("no MPP record for AMP") + } + + // Create an invoice for the total amount expected, provided in the MPP + // record. + amt := ctx.mpp.TotalMsat() + + // Set the TLV and MPP optional features on the invoice. We'll also make + // the AMP features required so that it can't be paid by legacy or MPP + // htlcs. + rawFeatures := lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.PaymentAddrOptional, + lnwire.AMPRequired, + ) + features := lnwire.NewFeatureVector(rawFeatures, lnwire.Features) + + // Use the minimum block delta that we require for settling htlcs. + finalCltvDelta := i.cfg.FinalCltvRejectDelta + + // Pre-check expiry here to prevent inserting an invoice that will not + // be settled. + if ctx.expiry < uint32(ctx.currentHeight+finalCltvDelta) { + return errors.New("final expiry too soon") + } + + // We'll use the sender-generated payment address provided in the HTLC + // to create our AMP invoice. + payAddr := ctx.mpp.PaymentAddr() + + // Create placeholder invoice. + invoice := &channeldb.Invoice{ + CreationDate: i.cfg.Clock.Now(), + Terms: channeldb.ContractTerm{ + FinalCltvDelta: finalCltvDelta, + Value: amt, + PaymentPreimage: nil, + PaymentAddr: payAddr, + Features: features, + }, + } + + // Insert invoice into database. Ignore duplicates payment hashes and + // payment addrs, this may be a replay or a different HTLC for the AMP + // invoice. + _, err := i.AddInvoice(invoice, ctx.hash) + switch { + case err == channeldb.ErrDuplicateInvoice: + return nil + case err == channeldb.ErrDuplicatePayAddr: + return nil + default: + return err + } +} + // NotifyExitHopHtlc attempts to mark an invoice as settled. The return value // describes how the htlc should be resolved. // @@ -813,13 +880,24 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, // AddInvoice obtains its own lock. This is no problem, because the // operation is idempotent. if i.cfg.AcceptKeySend { - err := i.processKeySend(ctx) - if err != nil { - ctx.log(fmt.Sprintf("keysend error: %v", err)) + if ctx.amp != nil { + err := i.processAMP(ctx) + if err != nil { + ctx.log(fmt.Sprintf("amp error: %v", err)) - return NewFailResolution( - circuitKey, currentHeight, ResultKeySendError, - ), nil + return NewFailResolution( + circuitKey, currentHeight, ResultAmpError, + ), nil + } + } else { + err := i.processKeySend(ctx) + if err != nil { + ctx.log(fmt.Sprintf("keysend error: %v", err)) + + return NewFailResolution( + circuitKey, currentHeight, ResultKeySendError, + ), nil + } } } @@ -926,6 +1004,31 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked( "outcome: %v, at accept height: %v", res.Outcome, res.AcceptHeight)) + // Some failures apply to the entire HTLC set. Break here if + // this isn't one of them. + if !res.Outcome.IsSetFailure() { + break + } + + // Also cancel any HTLCs in the HTLC set that are also in the + // canceled state with the same failure result. + setID := ctx.setID() + for key, htlc := range invoice.Htlcs { + if htlc.State != channeldb.HtlcStateCanceled { + continue + } + + if !htlc.IsInHTLCSet(setID) { + continue + } + + htlcFailResolution := NewFailResolution( + key, int32(htlc.AcceptHeight), res.Outcome, + ) + + i.notifyHodlSubscribers(htlcFailResolution) + } + // If the htlc was settled, we will settle any previously accepted // htlcs and notify our peer to settle them. case *HtlcSettleResolution: @@ -941,13 +1044,18 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked( continue } + preimage := res.Preimage + if htlc.AMP != nil && htlc.AMP.Preimage != nil { + preimage = *htlc.AMP.Preimage + } + // Notify subscribers that the htlcs should be settled // with our peer. Note that the outcome of the // resolution is set based on the outcome of the single // htlc that we just settled, so may not be accurate // for all htlcs. htlcSettleResolution := NewSettleResolution( - res.Preimage, key, + preimage, key, int32(htlc.AcceptHeight), res.Outcome, ) diff --git a/invoices/invoiceregistry_test.go b/invoices/invoiceregistry_test.go index 9e465eaa..1d1198eb 100644 --- a/invoices/invoiceregistry_test.go +++ b/invoices/invoiceregistry_test.go @@ -1,10 +1,12 @@ package invoices import ( + "crypto/rand" "math" "testing" "time" + "github.com/lightningnetwork/lnd/amp" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/lntypes" @@ -29,9 +31,7 @@ func TestSettleInvoice(t *testing.T) { } defer subscription.Cancel() - if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { - t.Fatalf("expected subscription for provided hash") - } + require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash) // Add the invoice. addIdx, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash) @@ -77,19 +77,11 @@ func TestSettleInvoice(t *testing.T) { if err != nil { t.Fatal(err) } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.AcceptHeight != testCurrentHeight { - t.Fatalf("expected acceptHeight %v, but got %v", - testCurrentHeight, failResolution.AcceptHeight) - } - if failResolution.Outcome != ResultExpiryTooSoon { - t.Fatalf("expected expiry too soon, got: %v", - failResolution.Outcome) - } + require.NotNil(t, resolution) + failResolution := checkFailResolution( + t, resolution, ResultExpiryTooSoon, + ) + require.Equal(t, testCurrentHeight, failResolution.AcceptHeight) // Settle invoice with a slightly higher amount. amtPaid := lnwire.MilliSatoshi(100500) @@ -101,15 +93,11 @@ func TestSettleInvoice(t *testing.T) { if err != nil { t.Fatal(err) } - settleResolution, ok := resolution.(*HtlcSettleResolution) - if !ok { - t.Fatalf("expected settle resolution, got: %T", - resolution) - } - if settleResolution.Outcome != ResultSettled { - t.Fatalf("expected settled, got: %v", - settleResolution.Outcome) - } + require.NotNil(t, resolution) + settleResolution := checkSettleResolution( + t, resolution, testInvoicePreimage, + ) + require.Equal(t, ResultSettled, settleResolution.Outcome) // We expect the settled state to be sent to the single invoice // subscriber. @@ -146,15 +134,11 @@ func TestSettleInvoice(t *testing.T) { if err != nil { t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) } - settleResolution, ok = resolution.(*HtlcSettleResolution) - if !ok { - t.Fatalf("expected settle resolution, got: %T", - resolution) - } - if settleResolution.Outcome != ResultReplayToSettled { - t.Fatalf("expected replay settled, got: %v", - settleResolution.Outcome) - } + require.NotNil(t, resolution) + settleResolution = checkSettleResolution( + t, resolution, testInvoicePreimage, + ) + require.Equal(t, ResultReplayToSettled, settleResolution.Outcome) // Try to settle again with a new higher-valued htlc. This payment // should also be accepted, to prevent any change in behaviour for a @@ -166,15 +150,11 @@ func TestSettleInvoice(t *testing.T) { if err != nil { t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) } - settleResolution, ok = resolution.(*HtlcSettleResolution) - if !ok { - t.Fatalf("expected settle resolution, got: %T", - resolution) - } - if settleResolution.Outcome != ResultDuplicateToSettled { - t.Fatalf("expected duplicate settled, got: %v", - settleResolution.Outcome) - } + require.NotNil(t, resolution) + settleResolution = checkSettleResolution( + t, resolution, testInvoicePreimage, + ) + require.Equal(t, ResultDuplicateToSettled, settleResolution.Outcome) // Try to settle again with a lower amount. This should fail just as it // would have failed if it were the first payment. @@ -185,15 +165,8 @@ func TestSettleInvoice(t *testing.T) { if err != nil { t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) } - failResolution, ok = resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.Outcome != ResultAmountTooLow { - t.Fatalf("expected amount too low, got: %v", - failResolution.Outcome) - } + require.NotNil(t, resolution) + checkFailResolution(t, resolution, ResultAmountTooLow) // Check that settled amount is equal to the sum of values of the htlcs // 0 and 1. @@ -244,9 +217,7 @@ func testCancelInvoice(t *testing.T, gc bool) { } defer subscription.Cancel() - if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { - t.Fatalf("expected subscription for provided hash") - } + require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash) // Add the invoice. amt := lnwire.MilliSatoshi(100000) @@ -333,27 +304,23 @@ func testCancelInvoice(t *testing.T, gc bool) { if err != nil { t.Fatal("expected settlement of a canceled invoice to succeed") } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.AcceptHeight != testCurrentHeight { - t.Fatalf("expected acceptHeight %v, but got %v", - testCurrentHeight, failResolution.AcceptHeight) - } + require.NotNil(t, resolution) // If the invoice has been deleted (or not present) then we expect the // outcome to be ResultInvoiceNotFound instead of when the invoice is // in our database in which case we expect ResultInvoiceAlreadyCanceled. + var failResolution *HtlcFailResolution if gc { - require.Equal(t, failResolution.Outcome, ResultInvoiceNotFound) + failResolution = checkFailResolution( + t, resolution, ResultInvoiceNotFound, + ) } else { - require.Equal(t, - failResolution.Outcome, - ResultInvoiceAlreadyCanceled, + failResolution = checkFailResolution( + t, resolution, ResultInvoiceAlreadyCanceled, ) } + + require.Equal(t, testCurrentHeight, failResolution.AcceptHeight) } // TestCancelInvoice tests cancelation of an invoice and related notifications. @@ -404,9 +371,7 @@ func TestSettleHoldInvoice(t *testing.T) { } defer subscription.Cancel() - if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { - t.Fatalf("expected subscription for provided hash") - } + require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash) // Add the invoice. _, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash) @@ -480,15 +445,8 @@ func TestSettleHoldInvoice(t *testing.T) { if err != nil { t.Fatalf("expected settle to succeed but got %v", err) } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.Outcome != ResultExpiryTooSoon { - t.Fatalf("expected expiry too soon, got: %v", - failResolution.Outcome) - } + require.NotNil(t, resolution) + checkFailResolution(t, resolution, ResultExpiryTooSoon) // We expect the accepted state to be sent to the single invoice // subscriber. For all invoice subscribers, we don't expect an update. @@ -509,22 +467,12 @@ func TestSettleHoldInvoice(t *testing.T) { } htlcResolution := (<-hodlChan).(HtlcResolution) - settleResolution, ok := htlcResolution.(*HtlcSettleResolution) - if !ok { - t.Fatalf("expected settle resolution, got: %T", - htlcResolution) - } - if settleResolution.Preimage != testInvoicePreimage { - t.Fatal("unexpected preimage in hodl resolution") - } - if settleResolution.AcceptHeight != testCurrentHeight { - t.Fatalf("expected acceptHeight %v, but got %v", - testCurrentHeight, settleResolution.AcceptHeight) - } - if settleResolution.Outcome != ResultSettled { - t.Fatalf("expected result settled, got: %v", - settleResolution.Outcome) - } + require.NotNil(t, htlcResolution) + settleResolution := checkSettleResolution( + t, htlcResolution, testInvoicePreimage, + ) + require.Equal(t, testCurrentHeight, settleResolution.AcceptHeight) + require.Equal(t, ResultSettled, settleResolution.Outcome) // We expect a settled notification to be sent out for both all and // single invoice subscribers. @@ -610,11 +558,8 @@ func TestCancelHoldInvoice(t *testing.T) { } htlcResolution := (<-hodlChan).(HtlcResolution) - _, ok := htlcResolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - htlcResolution) - } + require.NotNil(t, htlcResolution) + checkFailResolution(t, htlcResolution, ResultCanceled) // Offering the same htlc again at a higher height should still result // in a rejection. The accept height is expected to be the original @@ -626,19 +571,11 @@ func TestCancelHoldInvoice(t *testing.T) { if err != nil { t.Fatalf("expected settle to succeed but got %v", err) } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.AcceptHeight != testCurrentHeight { - t.Fatalf("expected acceptHeight %v, but got %v", - testCurrentHeight, failResolution.AcceptHeight) - } - if failResolution.Outcome != ResultReplayToCanceled { - t.Fatalf("expected replay to canceled, got %v", - failResolution.Outcome) - } + require.NotNil(t, resolution) + failResolution := checkFailResolution( + t, resolution, ResultReplayToCanceled, + ) + require.Equal(t, testCurrentHeight, failResolution.AcceptHeight) } // TestUnknownInvoice tests that invoice registry returns an error when the @@ -661,15 +598,8 @@ func TestUnknownInvoice(t *testing.T) { if err != nil { t.Fatal("unexpected error") } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.Outcome != ResultInvoiceNotFound { - t.Fatalf("expected ResultInvoiceNotFound, got: %v", - failResolution.Outcome) - } + require.NotNil(t, resolution) + checkFailResolution(t, resolution, ResultInvoiceNotFound) } // TestKeySend tests receiving a spontaneous payment with and without keysend @@ -721,18 +651,12 @@ func testKeySend(t *testing.T, keySendEnabled bool) { if err != nil { t.Fatal(err) } - failResolution, ok := resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } + require.NotNil(t, resolution) - switch { - case !keySendEnabled && failResolution.Outcome != ResultInvoiceNotFound: - t.Fatal("expected invoice not found outcome") - - case keySendEnabled && failResolution.Outcome != ResultKeySendError: - t.Fatal("expected keysend error") + if !keySendEnabled { + checkFailResolution(t, resolution, ResultInvoiceNotFound) + } else { + checkFailResolution(t, resolution, ResultKeySendError) } // Try to settle invoice with a valid keysend htlc. @@ -752,23 +676,10 @@ func testKeySend(t *testing.T, keySendEnabled bool) { // Expect a cancel resolution if keysend is disabled. if !keySendEnabled { - failResolution, ok = resolution.(*HtlcFailResolution) - if !ok { - t.Fatalf("expected fail resolution, got: %T", - resolution) - } - if failResolution.Outcome != ResultInvoiceNotFound { - t.Fatal("expected keysend payment not to be accepted") - } + checkFailResolution(t, resolution, ResultInvoiceNotFound) return } - checkResolution := func(res HtlcResolution, pimg lntypes.Preimage) { - // Otherwise we expect no error and a settle res for the htlc. - settleResolution, ok := res.(*HtlcSettleResolution) - require.True(t, ok) - require.Equal(t, settleResolution.Preimage, pimg) - } checkSubscription := func() { // We expect a new invoice notification to be sent out. newInvoice := <-allSubscriptions.NewInvoices @@ -779,7 +690,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) { require.Equal(t, settledInvoice.State, channeldb.ContractSettled) } - checkResolution(resolution, preimage) + checkSettleResolution(t, resolution, preimage) checkSubscription() // Replay the same keysend payment. We expect an identical resolution, @@ -789,7 +700,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) { testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload, ) require.Nil(t, err) - checkResolution(resolution, preimage) + checkSettleResolution(t, resolution, preimage) select { case <-allSubscriptions.NewInvoices: @@ -814,7 +725,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) { ) require.Nil(t, err) - checkResolution(resolution, preimage2) + checkSettleResolution(t, resolution, preimage2) checkSubscription() } @@ -1211,7 +1122,7 @@ func TestSettleInvoicePaymentAddrRequired(t *testing.T) { defer subscription.Cancel() require.Equal( - t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash, + t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash, ) // Add the invoice, which requires the MPP payload to always be @@ -1287,7 +1198,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) { defer subscription.Cancel() require.Equal( - t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash, + t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash, ) // Add the invoice, which requires the MPP payload to always be @@ -1364,3 +1275,254 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) { t.Fatal("no update received") } } + +// TestAMPWithoutMPPPayload asserts that we correctly reject an AMP HTLC that +// does not include an MPP record. +func TestAMPWithoutMPPPayload(t *testing.T) { + defer timeout()() + + ctx := newTestContext(t) + defer ctx.cleanup() + + ctx.registry.cfg.AcceptKeySend = true + + const ( + shardAmt = lnwire.MilliSatoshi(10) + expiry = uint32(testCurrentHeight + 20) + ) + + // Create payload with missing MPP field. + payload := &mockPayload{ + amp: record.NewAMP([32]byte{}, [32]byte{}, 0), + } + + hodlChan := make(chan interface{}, 1) + resolution, err := ctx.registry.NotifyExitHopHtlc( + lntypes.Hash{}, shardAmt, expiry, + testCurrentHeight, getCircuitKey(uint64(10)), hodlChan, + payload, + ) + require.NoError(t, err) + + // We should receive the ResultAmpError failure. + require.NotNil(t, resolution) + checkFailResolution(t, resolution, ResultAmpError) +} + +// TestSpontaneousAmpPayment tests receiving a spontaneous AMP payment with both +// valid and invalid reconstructions. +func TestSpontaneousAmpPayment(t *testing.T) { + tests := []struct { + name string + keySendEnabled bool + failReconstruction bool + numShards int + }{ + { + name: "enabled valid one shard", + keySendEnabled: true, + failReconstruction: false, + numShards: 1, + }, + { + name: "enabled valid multiple shards", + keySendEnabled: true, + failReconstruction: false, + numShards: 3, + }, + { + name: "enabled invalid one shard", + keySendEnabled: true, + failReconstruction: true, + numShards: 1, + }, + { + name: "enabled invalid multiple shards", + keySendEnabled: true, + failReconstruction: true, + numShards: 3, + }, + { + name: "disabled valid multiple shards", + keySendEnabled: false, + failReconstruction: false, + numShards: 3, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + testSpontaneousAmpPayment( + t, test.keySendEnabled, test.failReconstruction, + test.numShards, + ) + }) + } +} + +// testSpontaneousAmpPayment runs a specific spontaneous AMP test case. +func testSpontaneousAmpPayment( + t *testing.T, keySendEnabled, failReconstruction bool, numShards int) { + + defer timeout()() + + ctx := newTestContext(t) + defer ctx.cleanup() + + ctx.registry.cfg.AcceptKeySend = keySendEnabled + + allSubscriptions, err := ctx.registry.SubscribeNotifications(0, 0) + require.Nil(t, err) + defer allSubscriptions.Cancel() + + const ( + totalAmt = lnwire.MilliSatoshi(360) + expiry = uint32(testCurrentHeight + 20) + ) + + var ( + shardAmt = totalAmt / lnwire.MilliSatoshi(numShards) + payAddr [32]byte + setID [32]byte + ) + _, err = rand.Read(payAddr[:]) + require.NoError(t, err) + _, err = rand.Read(setID[:]) + require.NoError(t, err) + + var sharer amp.Sharer + sharer, err = amp.NewSeedSharer() + require.NoError(t, err) + + // Asserts that a new invoice is published on the NewInvoices channel. + checkOpenSubscription := func() { + t.Helper() + newInvoice := <-allSubscriptions.NewInvoices + require.Equal(t, newInvoice.State, channeldb.ContractOpen) + } + + // Asserts that a settled invoice is published on the SettledInvoices + // channel. + checkSettleSubscription := func() { + t.Helper() + settledInvoice := <-allSubscriptions.SettledInvoices + require.Equal(t, settledInvoice.State, channeldb.ContractSettled) + } + + // Asserts that no invoice is published on the SettledInvoices channel + // w/in two seconds. + checkNoSettleSubscription := func() { + t.Helper() + select { + case <-allSubscriptions.SettledInvoices: + t.Fatal("no settle ntfn expected") + case <-time.After(2 * time.Second): + } + } + + // Record the hodl channels of all HTLCs but the last one, which + // received its resolution directly from NotifyExistHopHtlc. + hodlChans := make(map[lntypes.Preimage]chan interface{}) + for i := 0; i < numShards; i++ { + isFinalShard := i == numShards-1 + + hodlChan := make(chan interface{}, 1) + + var child *amp.Child + if !isFinalShard { + var left amp.Sharer + left, sharer, err = sharer.Split() + require.NoError(t, err) + + child = left.Child(uint32(i)) + + // Only store the first numShards-1 hodlChans. + hodlChans[child.Preimage] = hodlChan + } else { + child = sharer.Child(uint32(i)) + } + + // Send a blank share when the set should fail reconstruction, + // otherwise send the derived share. + var share [32]byte + if !failReconstruction { + share = child.Share + } + + payload := &mockPayload{ + mpp: record.NewMPP(totalAmt, payAddr), + amp: record.NewAMP(share, setID, uint32(i)), + } + + resolution, err := ctx.registry.NotifyExitHopHtlc( + child.Hash, shardAmt, expiry, + testCurrentHeight, getCircuitKey(uint64(i)), hodlChan, + payload, + ) + require.NoError(t, err) + + // When keysend is disabled all HTLC should fail with invoice + // not found, since one is not inserted before executing + // UpdateInvoice. + if !keySendEnabled { + require.NotNil(t, resolution) + checkFailResolution(t, resolution, ResultInvoiceNotFound) + continue + } + + // Check that resolutions are properly formed. + if !isFinalShard { + // Non-final shares should always return a nil + // resolution, theirs will be delivered via the + // hodlChan. + require.Nil(t, resolution) + } else { + // The final share should receive a non-nil resolution. + // Also assert that it is the proper type based on the + // test case. + require.NotNil(t, resolution) + if failReconstruction { + checkFailResolution(t, resolution, ResultAmpReconstruction) + } else { + checkSettleResolution(t, resolution, child.Preimage) + } + } + + // Assert the behavior of the Open and Settle notifications. + // There should always be an open (keysend is enabled) followed + // by settle for valid AMP payments. + // + // NOTE: The cases are split in separate if conditions, rather + // than else-if, to properly handle the case when there is only + // one shard. + if i == 0 { + checkOpenSubscription() + } + if isFinalShard { + if failReconstruction { + checkNoSettleSubscription() + } else { + checkSettleSubscription() + } + } + } + + // No need to check the hodl chans when keysend is not enabled. + if !keySendEnabled { + return + } + + // For the non-final hodl chans, assert that they receive the expected + // failure or preimage. + for preimage, hodlChan := range hodlChans { + resolution, ok := (<-hodlChan).(HtlcResolution) + require.True(t, ok) + require.NotNil(t, resolution) + if failReconstruction { + checkFailResolution(t, resolution, ResultAmpReconstruction) + } else { + checkSettleResolution(t, resolution, preimage) + } + } +} diff --git a/invoices/resolution_result.go b/invoices/resolution_result.go index b979d3ac..810f2053 100644 --- a/invoices/resolution_result.go +++ b/invoices/resolution_result.go @@ -105,6 +105,13 @@ const ( // ResultMppInProgress is returned when we are busy receiving a mpp // payment. ResultMppInProgress + + // ResultAmpError is returned when we receive invalid AMP parameters. + ResultAmpError + + // ResultAmpReconstruction is returned when the derived child + // hash/preimage pairs were invalid for at least one HTLC in the set. + ResultAmpReconstruction ) // String returns a string representation of the result. @@ -162,11 +169,34 @@ func (f FailResolutionResult) FailureString() string { case ResultMppInProgress: return "mpp reception in progress" + case ResultAmpError: + return "invalid amp parameters" + + case ResultAmpReconstruction: + return "amp reconstruction failed" + default: return "unknown failure resolution result" } } +// IsSetFailure returns true if this failure should result in the entire HTLC +// set being failed with the same result. +func (f FailResolutionResult) IsSetFailure() bool { + switch f { + case + ResultAmpReconstruction, + ResultHtlcSetTotalTooLow, + ResultHtlcSetTotalMismatch, + ResultHtlcSetOverpayment: + + return true + + default: + return false + } +} + // SettleResolutionResult provides metadata which about a htlc that was failed // by the registry. It can be used to take custom actions on resolution of the // htlc. diff --git a/invoices/test_utils_test.go b/invoices/test_utils_test.go index 73d41346..6a454a9e 100644 --- a/invoices/test_utils_test.go +++ b/invoices/test_utils_test.go @@ -19,6 +19,7 @@ import ( "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/zpay32" + "github.com/stretchr/testify/require" ) type mockPayload struct { @@ -45,6 +46,16 @@ func (p *mockPayload) CustomRecords() record.CustomSet { return p.customRecords } +const ( + testHtlcExpiry = uint32(5) + + testInvoiceCltvDelta = uint32(4) + + testFinalCltvRejectDelta = int32(4) + + testCurrentHeight = int32(1) +) + var ( testTimeout = 5 * time.Second @@ -54,14 +65,6 @@ var ( testInvoicePaymentHash = testInvoicePreimage.Hash() - testHtlcExpiry = uint32(5) - - testInvoiceCltvDelta = uint32(4) - - testFinalCltvRejectDelta = int32(4) - - testCurrentHeight = int32(1) - testPrivKeyBytes, _ = hex.DecodeString( "e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734") @@ -111,7 +114,10 @@ var ( Value: testInvoiceAmt, Expiry: time.Hour, Features: lnwire.NewFeatureVector( - lnwire.NewRawFeatureVector(lnwire.PaymentAddrRequired), + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.PaymentAddrRequired, + ), lnwire.Features, ), }, @@ -124,7 +130,10 @@ var ( Value: testInvoiceAmt, Expiry: time.Hour, Features: lnwire.NewFeatureVector( - lnwire.NewRawFeatureVector(lnwire.PaymentAddrOptional), + lnwire.NewRawFeatureVector( + lnwire.TLVOnionPayloadOptional, + lnwire.PaymentAddrOptional, + ), lnwire.Features, ), }, @@ -325,3 +334,32 @@ func generateInvoiceExpiryTestData( return testData } + +// checkSettleResolution asserts the resolution is a settle with the correct +// preimage. If successful, the HtlcSettleResolution is returned in case further +// checks are desired. +func checkSettleResolution(t *testing.T, res HtlcResolution, + expPreimage lntypes.Preimage) *HtlcSettleResolution { + + t.Helper() + + settleResolution, ok := res.(*HtlcSettleResolution) + require.True(t, ok) + require.Equal(t, expPreimage, settleResolution.Preimage) + + return settleResolution +} + +// checkFailResolution asserts the resolution is a fail with the correct reason. +// If successful, the HtlcFailResolutionis returned in case further checks are +// desired. +func checkFailResolution(t *testing.T, res HtlcResolution, + expOutcome FailResolutionResult) *HtlcFailResolution { + + t.Helper() + failResolution, ok := res.(*HtlcFailResolution) + require.True(t, ok) + require.Equal(t, expOutcome, failResolution.Outcome) + + return failResolution +} diff --git a/invoices/update.go b/invoices/update.go index 45435ca8..e10b92c6 100644 --- a/invoices/update.go +++ b/invoices/update.go @@ -3,6 +3,7 @@ package invoices import ( "errors" + "github.com/lightningnetwork/lnd/amp" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" @@ -26,11 +27,16 @@ type invoiceUpdateCtx struct { // invoiceRef returns an identifier that can be used to lookup or update the // invoice this HTLC is targeting. func (i *invoiceUpdateCtx) invoiceRef() channeldb.InvoiceRef { - if i.mpp != nil { + switch { + case i.amp != nil && i.mpp != nil: + payAddr := i.mpp.PaymentAddr() + return channeldb.InvoiceRefByAddr(payAddr) + case i.mpp != nil: payAddr := i.mpp.PaymentAddr() return channeldb.InvoiceRefByHashAndAddr(i.hash, payAddr) + default: + return channeldb.InvoiceRefByHash(i.hash) } - return channeldb.InvoiceRefByHash(i.hash) } // setID returns an identifier that identifies other possible HTLCs that this @@ -47,7 +53,7 @@ func (i invoiceUpdateCtx) setID() *[32]byte { // log logs a message specific to this update context. func (i *invoiceUpdateCtx) log(s string) { log.Debugf("Invoice%v: %v, amt=%v, expiry=%v, circuit=%v, mpp=%v, "+ - "amp=%v", i.hash[:], s, i.amtPaid, i.expiry, i.circuitKey, + "amp=%v", i.invoiceRef(), s, i.amtPaid, i.expiry, i.circuitKey, i.mpp, i.amp) } @@ -130,6 +136,14 @@ func updateMpp(ctx *invoiceUpdateCtx, CustomRecords: ctx.customRecords, } + if ctx.amp != nil { + acceptDesc.AMP = &channeldb.InvoiceHtlcAMPData{ + Record: *ctx.amp, + Hash: ctx.hash, + Preimage: nil, + } + } + // Only accept payments to open invoices. This behaviour differs from // non-mpp payments that are accepted even after the invoice is settled. // Because non-mpp payments don't have a payment address, this is needed @@ -154,9 +168,18 @@ func updateMpp(ctx *invoiceUpdateCtx, return nil, ctx.failRes(ResultHtlcSetTotalTooLow), nil } + htlcSet := inv.HTLCSet(setID) + // Check whether total amt matches other htlcs in the set. var newSetTotal lnwire.MilliSatoshi - for _, htlc := range inv.HTLCSet(setID) { + for _, htlc := range htlcSet { + // Only consider accepted mpp htlcs. It is possible that there + // are htlcs registered in the invoice database that previously + // timed out and are in the canceled state now. + if htlc.State != channeldb.HtlcStateAccepted { + continue + } + if ctx.mpp.TotalMsat() != htlc.MppTotalAmt { return nil, ctx.failRes(ResultHtlcSetTotalMismatch), nil } @@ -206,15 +229,107 @@ func updateMpp(ctx *invoiceUpdateCtx, return &update, ctx.acceptRes(resultAccepted), nil } - update.State = &channeldb.InvoiceStateUpdateDesc{ - NewState: channeldb.ContractSettled, - Preimage: inv.Terms.PaymentPreimage, - SetID: setID, + var ( + htlcPreimages map[channeldb.CircuitKey]lntypes.Preimage + htlcPreimage lntypes.Preimage + ) + if ctx.amp != nil { + var failRes *HtlcFailResolution + htlcPreimages, failRes = reconstructAMPPreimages(ctx, htlcSet) + if failRes != nil { + update.State = &channeldb.InvoiceStateUpdateDesc{ + NewState: channeldb.ContractCanceled, + SetID: setID, + } + return &update, failRes, nil + } + + // The preimage for _this_ HTLC will be the one with context's + // circuit key. + htlcPreimage = htlcPreimages[ctx.circuitKey] + } else { + htlcPreimage = *inv.Terms.PaymentPreimage } - return &update, ctx.settleRes( - *inv.Terms.PaymentPreimage, ResultSettled, - ), nil + update.State = &channeldb.InvoiceStateUpdateDesc{ + NewState: channeldb.ContractSettled, + Preimage: inv.Terms.PaymentPreimage, + HTLCPreimages: htlcPreimages, + SetID: setID, + } + + return &update, ctx.settleRes(htlcPreimage, ResultSettled), nil +} + +// HTLCSet is a map of CircuitKey to InvoiceHTLC. +type HTLCSet = map[channeldb.CircuitKey]*channeldb.InvoiceHTLC + +// HTLCPreimages is a map of CircuitKey to preimage. +type HTLCPreimages = map[channeldb.CircuitKey]lntypes.Preimage + +// reconstructAMPPreimages reconstructs the root seed for an AMP HTLC set and +// verifies that all derived child hashes match the payment hashes of the HTLCs +// in the set. This method is meant to be called after receiving the full amount +// committed to via mpp_total_msat. This method will return a fail resolution if +// any of the child hashes fail to matche theire corresponding HTLCs. +func reconstructAMPPreimages(ctx *invoiceUpdateCtx, + htlcSet HTLCSet) (HTLCPreimages, *HtlcFailResolution) { + + // Create a slice containing all the child descriptors to be used for + // reconstruction. This should include all HTLCs currently in the HTLC + // set, plus the incoming HTLC. + childDescs := make([]amp.ChildDesc, 0, 1+len(htlcSet)) + + // Add the new HTLC's child descriptor at index 0. + childDescs = append(childDescs, amp.ChildDesc{ + Share: ctx.amp.RootShare(), + Index: ctx.amp.ChildIndex(), + }) + + // Next, construct an index mapping the position in childDescs to a + // circuit key for all preexisting HTLCs. + indexToCircuitKey := make(map[int]channeldb.CircuitKey) + + // Add the child descriptor for each HTLC in the HTLC set, recording + // it's position within the slice. + var htlcSetIndex int + for circuitKey, htlc := range htlcSet { + childDescs = append(childDescs, amp.ChildDesc{ + Share: htlc.AMP.Record.RootShare(), + Index: htlc.AMP.Record.ChildIndex(), + }) + indexToCircuitKey[htlcSetIndex] = circuitKey + htlcSetIndex++ + } + + // Using the child descriptors, reconstruct the root seed and derive the + // child hash/preimage pairs for each of the HTLCs. + children := amp.ReconstructChildren(childDescs...) + + // Validate that the derived child preimages match the hash of each + // HTLC's respective hash. + if ctx.hash != children[0].Hash { + return nil, ctx.failRes(ResultAmpReconstruction) + } + for idx, child := range children[1:] { + circuitKey := indexToCircuitKey[idx] + htlc := htlcSet[circuitKey] + if htlc.AMP.Hash != child.Hash { + return nil, ctx.failRes(ResultAmpReconstruction) + } + } + + // Finally, construct the map of learned preimages indexed by circuit + // key, so that they can be persisted along with each HTLC when updating + // the invoice. + htlcPreimages := make(map[channeldb.CircuitKey]lntypes.Preimage) + htlcPreimages[ctx.circuitKey] = children[0].Preimage + for idx, child := range children[1:] { + circuitKey := indexToCircuitKey[idx] + htlcPreimages[circuitKey] = child.Preimage + } + + return htlcPreimages, nil } // updateLegacy is a callback for DB.UpdateInvoice that contains the invoice diff --git a/lnrpc/invoicesrpc/utils.go b/lnrpc/invoicesrpc/utils.go index ad7c0e68..93300982 100644 --- a/lnrpc/invoicesrpc/utils.go +++ b/lnrpc/invoicesrpc/utils.go @@ -2,7 +2,6 @@ package invoicesrpc import ( "encoding/hex" - "errors" "fmt" "github.com/btcsuite/btcd/btcec" @@ -24,7 +23,7 @@ func decodePayReq(invoice *channeldb.Invoice, if paymentRequest == "" { preimage := invoice.Terms.PaymentPreimage if preimage == nil { - return nil, errors.New("cannot reconstruct pay req") + return &zpay32.Invoice{}, nil } hash := [32]byte(preimage.Hash()) return &zpay32.Invoice{ @@ -51,6 +50,11 @@ func CreateRPCInvoice(invoice *channeldb.Invoice, return nil, err } + var rHash []byte + if decoded.PaymentHash != nil { + rHash = decoded.PaymentHash[:] + } + var descHash []byte if decoded.DescriptionHash != nil { descHash = decoded.DescriptionHash[:] @@ -129,7 +133,7 @@ func CreateRPCInvoice(invoice *channeldb.Invoice, rpcHtlc.Amp = &lnrpc.AMP{ RootShare: rootShare[:], SetId: setID[:], - ChildIndex: uint32(htlc.AMP.Record.ChildIndex()), + ChildIndex: htlc.AMP.Record.ChildIndex(), Hash: htlc.AMP.Hash[:], Preimage: preimage, } @@ -144,8 +148,8 @@ func CreateRPCInvoice(invoice *channeldb.Invoice, } rpcInvoice := &lnrpc.Invoice{ - Memo: string(invoice.Memo[:]), - RHash: decoded.PaymentHash[:], + Memo: string(invoice.Memo), + RHash: rHash, Value: int64(satAmt), ValueMsat: int64(invoice.Terms.Value), CreationDate: invoice.CreationDate.Unix(), diff --git a/lnrpc/routerrpc/router.swagger.json b/lnrpc/routerrpc/router.swagger.json index 390e3194..32f0af50 100644 --- a/lnrpc/routerrpc/router.swagger.json +++ b/lnrpc/routerrpc/router.swagger.json @@ -441,6 +441,23 @@ ], "default": "IN_FLIGHT" }, + "lnrpcAMPRecord": { + "type": "object", + "properties": { + "root_share": { + "type": "string", + "format": "byte" + }, + "set_id": { + "type": "string", + "format": "byte" + }, + "child_index": { + "type": "integer", + "format": "int64" + } + } + }, "lnrpcChannelPoint": { "type": "object", "properties": { @@ -677,7 +694,11 @@ }, "mpp_record": { "$ref": "#/definitions/lnrpcMPPRecord", - "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that that the same mpp_record is included in the\nfinal hop payload of all non-zero payments in the HTLC set. If empty, a\nregular single-shot payment is or was attempted." + "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that the same mpp_record is included in the final\nhop payload of all non-zero payments in the HTLC set. If empty, a regular\nsingle-shot payment is or was attempted." + }, + "amp_record": { + "$ref": "#/definitions/lnrpcAMPRecord", + "description": "An optional TLV record that signals the use of an AMP payment. If present,\nthe receiver will treat all received payments including the same\n(payment_addr, set_id) pair as being part of one logical payment. The\npayment will be settled by XORing the root_share's together and deriving the\nchild hashes and preimages according to BOLT XX. Must be used in conjunction\nwith mpp_record." }, "custom_records": { "type": "object", diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index 7944dddc..66fab66e 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -455,6 +455,11 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop return nil, err } + amp, err := UnmarshalAMP(rpcHop.AmpRecord) + if err != nil { + return nil, err + } + return &route.Hop{ OutgoingTimeLock: rpcHop.Expiry, AmtToForward: lnwire.MilliSatoshi(rpcHop.AmtToForwardMsat), @@ -463,6 +468,7 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop CustomRecords: customRecords, LegacyPayload: !rpcHop.TlvPayload, MPP: mpp, + AMP: amp, }, nil } @@ -895,6 +901,32 @@ func UnmarshalMPP(reqMPP *lnrpc.MPPRecord) (*record.MPP, error) { return record.NewMPP(total, addr), nil } +func UnmarshalAMP(reqAMP *lnrpc.AMPRecord) (*record.AMP, error) { + if reqAMP == nil { + return nil, nil + } + + reqRootShare := reqAMP.RootShare + reqSetID := reqAMP.SetId + + switch { + case len(reqRootShare) != 32: + return nil, errors.New("AMP root_share must be 32 bytes") + + case len(reqSetID) != 32: + return nil, errors.New("AMP set_id must be 32 bytes") + } + + var ( + rootShare [32]byte + setID [32]byte + ) + copy(rootShare[:], reqRootShare) + copy(setID[:], reqSetID) + + return record.NewAMP(rootShare, setID, reqAMP.ChildIndex), nil +} + // MarshalHTLCAttempt constructs an RPC HTLCAttempt from the db representation. func (r *RouterBackend) MarshalHTLCAttempt( htlc channeldb.HTLCAttempt) (*lnrpc.HTLCAttempt, error) { diff --git a/lnrpc/routerrpc/router_backend_test.go b/lnrpc/routerrpc/router_backend_test.go index f100909a..f92a6f15 100644 --- a/lnrpc/routerrpc/router_backend_test.go +++ b/lnrpc/routerrpc/router_backend_test.go @@ -12,6 +12,7 @@ import ( "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing" "github.com/lightningnetwork/lnd/routing/route" + "github.com/stretchr/testify/require" "github.com/lightningnetwork/lnd/lnrpc" ) @@ -239,18 +240,18 @@ func (m *mockMissionControl) GetPairHistorySnapshot(fromNode, return routing.TimedPairResult{} } -type mppOutcome byte +type recordParseOutcome byte const ( - valid mppOutcome = iota + valid recordParseOutcome = iota invalid - nompp + norecord ) type unmarshalMPPTest struct { name string mpp *lnrpc.MPPRecord - outcome mppOutcome + outcome recordParseOutcome } // TestUnmarshalMPP checks both positive and negative cases of UnmarshalMPP to @@ -262,7 +263,7 @@ func TestUnmarshalMPP(t *testing.T) { { name: "nil record", mpp: nil, - outcome: nompp, + outcome: norecord, }, { name: "invalid total or addr", @@ -346,7 +347,7 @@ func testUnmarshalMPP(t *testing.T, test unmarshalMPPTest) { // Arguments that produce no MPP field should return no error and no MPP // record. - case nompp: + case norecord: if err != nil { t.Fatalf("failure for args resulting for no-mpp") } @@ -358,3 +359,95 @@ func testUnmarshalMPP(t *testing.T, test unmarshalMPPTest) { t.Fatalf("test case has non-standard outcome") } } + +type unmarshalAMPTest struct { + name string + amp *lnrpc.AMPRecord + outcome recordParseOutcome +} + +// TestUnmarshalAMP asserts the behavior of decoding an RPC AMPRecord. +func TestUnmarshalAMP(t *testing.T) { + rootShare := bytes.Repeat([]byte{0x01}, 32) + setID := bytes.Repeat([]byte{0x02}, 32) + + // All child indexes are valid. + childIndex := uint32(3) + + tests := []unmarshalAMPTest{ + { + name: "nil record", + amp: nil, + outcome: norecord, + }, + { + name: "invalid root share invalid set id", + amp: &lnrpc.AMPRecord{ + RootShare: []byte{0x01}, + SetId: []byte{0x02}, + ChildIndex: childIndex, + }, + outcome: invalid, + }, + { + name: "valid root share invalid set id", + amp: &lnrpc.AMPRecord{ + RootShare: rootShare, + SetId: []byte{0x02}, + ChildIndex: childIndex, + }, + outcome: invalid, + }, + { + name: "invalid root share valid set id", + amp: &lnrpc.AMPRecord{ + RootShare: []byte{0x01}, + SetId: setID, + ChildIndex: childIndex, + }, + outcome: invalid, + }, + { + name: "valid root share valid set id", + amp: &lnrpc.AMPRecord{ + RootShare: rootShare, + SetId: setID, + ChildIndex: childIndex, + }, + outcome: valid, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + testUnmarshalAMP(t, test) + }) + } +} + +func testUnmarshalAMP(t *testing.T, test unmarshalAMPTest) { + amp, err := UnmarshalAMP(test.amp) + switch test.outcome { + case valid: + require.NoError(t, err) + require.NotNil(t, amp) + + rootShare := amp.RootShare() + setID := amp.SetID() + require.Equal(t, test.amp.RootShare, rootShare[:]) + require.Equal(t, test.amp.SetId, setID[:]) + require.Equal(t, test.amp.ChildIndex, amp.ChildIndex()) + + case invalid: + require.Error(t, err) + require.Nil(t, amp) + + case norecord: + require.NoError(t, err) + require.Nil(t, amp) + + default: + t.Fatalf("test case has non-standard outcome") + } +} diff --git a/lnrpc/rpc.pb.go b/lnrpc/rpc.pb.go index 55d176be..cb13ab99 100644 --- a/lnrpc/rpc.pb.go +++ b/lnrpc/rpc.pb.go @@ -613,7 +613,7 @@ func (x Invoice_InvoiceState) String() string { } func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{111, 0} + return fileDescriptor_77a6da22d6a3feb1, []int{112, 0} } type Payment_PaymentStatus int32 @@ -644,7 +644,7 @@ func (x Payment_PaymentStatus) String() string { } func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{119, 0} + return fileDescriptor_77a6da22d6a3feb1, []int{120, 0} } type HTLCAttempt_HTLCStatus int32 @@ -672,7 +672,7 @@ func (x HTLCAttempt_HTLCStatus) String() string { } func (HTLCAttempt_HTLCStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{120, 0} + return fileDescriptor_77a6da22d6a3feb1, []int{121, 0} } type Failure_FailureCode int32 @@ -786,7 +786,7 @@ func (x Failure_FailureCode) String() string { } func (Failure_FailureCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{160, 0} + return fileDescriptor_77a6da22d6a3feb1, []int{161, 0} } type Utxo struct { @@ -7717,11 +7717,19 @@ type Hop struct { TlvPayload bool `protobuf:"varint,9,opt,name=tlv_payload,json=tlvPayload,proto3" json:"tlv_payload,omitempty"` // //An optional TLV record that signals the use of an MPP payment. If present, - //the receiver will enforce that that the same mpp_record is included in the - //final hop payload of all non-zero payments in the HTLC set. If empty, a - //regular single-shot payment is or was attempted. + //the receiver will enforce that the same mpp_record is included in the final + //hop payload of all non-zero payments in the HTLC set. If empty, a regular + //single-shot payment is or was attempted. MppRecord *MPPRecord `protobuf:"bytes,10,opt,name=mpp_record,json=mppRecord,proto3" json:"mpp_record,omitempty"` // + //An optional TLV record that signals the use of an AMP payment. If present, + //the receiver will treat all received payments including the same + //(payment_addr, set_id) pair as being part of one logical payment. The + //payment will be settled by XORing the root_share's together and deriving the + //child hashes and preimages according to BOLT XX. Must be used in conjunction + //with mpp_record. + AmpRecord *AMPRecord `protobuf:"bytes,12,opt,name=amp_record,json=ampRecord,proto3" json:"amp_record,omitempty"` + // //An optional set of key-value TLV records. This is useful within the context //of the SendToRoute call as it allows callers to specify arbitrary K-V pairs //to drop off at each hop within the onion. @@ -7828,6 +7836,13 @@ func (m *Hop) GetMppRecord() *MPPRecord { return nil } +func (m *Hop) GetAmpRecord() *AMPRecord { + if m != nil { + return m.AmpRecord + } + return nil +} + func (m *Hop) GetCustomRecords() map[uint64][]byte { if m != nil { return m.CustomRecords @@ -7892,6 +7907,61 @@ func (m *MPPRecord) GetTotalAmtMsat() int64 { return 0 } +type AMPRecord struct { + RootShare []byte `protobuf:"bytes,1,opt,name=root_share,json=rootShare,proto3" json:"root_share,omitempty"` + SetId []byte `protobuf:"bytes,2,opt,name=set_id,json=setId,proto3" json:"set_id,omitempty"` + ChildIndex uint32 `protobuf:"varint,3,opt,name=child_index,json=childIndex,proto3" json:"child_index,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AMPRecord) Reset() { *m = AMPRecord{} } +func (m *AMPRecord) String() string { return proto.CompactTextString(m) } +func (*AMPRecord) ProtoMessage() {} +func (*AMPRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{87} +} + +func (m *AMPRecord) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AMPRecord.Unmarshal(m, b) +} +func (m *AMPRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AMPRecord.Marshal(b, m, deterministic) +} +func (m *AMPRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_AMPRecord.Merge(m, src) +} +func (m *AMPRecord) XXX_Size() int { + return xxx_messageInfo_AMPRecord.Size(m) +} +func (m *AMPRecord) XXX_DiscardUnknown() { + xxx_messageInfo_AMPRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_AMPRecord proto.InternalMessageInfo + +func (m *AMPRecord) GetRootShare() []byte { + if m != nil { + return m.RootShare + } + return nil +} + +func (m *AMPRecord) GetSetId() []byte { + if m != nil { + return m.SetId + } + return nil +} + +func (m *AMPRecord) GetChildIndex() uint32 { + if m != nil { + return m.ChildIndex + } + return 0 +} + // //A path through the channel graph which runs over one or more channels in //succession. This struct carries all the information required to craft the @@ -7935,7 +8005,7 @@ func (m *Route) Reset() { *m = Route{} } func (m *Route) String() string { return proto.CompactTextString(m) } func (*Route) ProtoMessage() {} func (*Route) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{87} + return fileDescriptor_77a6da22d6a3feb1, []int{88} } func (m *Route) XXX_Unmarshal(b []byte) error { @@ -8014,7 +8084,7 @@ func (m *NodeInfoRequest) Reset() { *m = NodeInfoRequest{} } func (m *NodeInfoRequest) String() string { return proto.CompactTextString(m) } func (*NodeInfoRequest) ProtoMessage() {} func (*NodeInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{88} + return fileDescriptor_77a6da22d6a3feb1, []int{89} } func (m *NodeInfoRequest) XXX_Unmarshal(b []byte) error { @@ -8071,7 +8141,7 @@ func (m *NodeInfo) Reset() { *m = NodeInfo{} } func (m *NodeInfo) String() string { return proto.CompactTextString(m) } func (*NodeInfo) ProtoMessage() {} func (*NodeInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{89} + return fileDescriptor_77a6da22d6a3feb1, []int{90} } func (m *NodeInfo) XXX_Unmarshal(b []byte) error { @@ -8141,7 +8211,7 @@ func (m *LightningNode) Reset() { *m = LightningNode{} } func (m *LightningNode) String() string { return proto.CompactTextString(m) } func (*LightningNode) ProtoMessage() {} func (*LightningNode) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{90} + return fileDescriptor_77a6da22d6a3feb1, []int{91} } func (m *LightningNode) XXX_Unmarshal(b []byte) error { @@ -8216,7 +8286,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} } func (m *NodeAddress) String() string { return proto.CompactTextString(m) } func (*NodeAddress) ProtoMessage() {} func (*NodeAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{91} + return fileDescriptor_77a6da22d6a3feb1, []int{92} } func (m *NodeAddress) XXX_Unmarshal(b []byte) error { @@ -8268,7 +8338,7 @@ func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} } func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) } func (*RoutingPolicy) ProtoMessage() {} func (*RoutingPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{92} + return fileDescriptor_77a6da22d6a3feb1, []int{93} } func (m *RoutingPolicy) XXX_Unmarshal(b []byte) error { @@ -8366,7 +8436,7 @@ func (m *ChannelEdge) Reset() { *m = ChannelEdge{} } func (m *ChannelEdge) String() string { return proto.CompactTextString(m) } func (*ChannelEdge) ProtoMessage() {} func (*ChannelEdge) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{93} + return fileDescriptor_77a6da22d6a3feb1, []int{94} } func (m *ChannelEdge) XXX_Unmarshal(b []byte) error { @@ -8459,7 +8529,7 @@ func (m *ChannelGraphRequest) Reset() { *m = ChannelGraphRequest{} } func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) } func (*ChannelGraphRequest) ProtoMessage() {} func (*ChannelGraphRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{94} + return fileDescriptor_77a6da22d6a3feb1, []int{95} } func (m *ChannelGraphRequest) XXX_Unmarshal(b []byte) error { @@ -8502,7 +8572,7 @@ func (m *ChannelGraph) Reset() { *m = ChannelGraph{} } func (m *ChannelGraph) String() string { return proto.CompactTextString(m) } func (*ChannelGraph) ProtoMessage() {} func (*ChannelGraph) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{95} + return fileDescriptor_77a6da22d6a3feb1, []int{96} } func (m *ChannelGraph) XXX_Unmarshal(b []byte) error { @@ -8549,7 +8619,7 @@ func (m *NodeMetricsRequest) Reset() { *m = NodeMetricsRequest{} } func (m *NodeMetricsRequest) String() string { return proto.CompactTextString(m) } func (*NodeMetricsRequest) ProtoMessage() {} func (*NodeMetricsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{96} + return fileDescriptor_77a6da22d6a3feb1, []int{97} } func (m *NodeMetricsRequest) XXX_Unmarshal(b []byte) error { @@ -8594,7 +8664,7 @@ func (m *NodeMetricsResponse) Reset() { *m = NodeMetricsResponse{} } func (m *NodeMetricsResponse) String() string { return proto.CompactTextString(m) } func (*NodeMetricsResponse) ProtoMessage() {} func (*NodeMetricsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{97} + return fileDescriptor_77a6da22d6a3feb1, []int{98} } func (m *NodeMetricsResponse) XXX_Unmarshal(b []byte) error { @@ -8636,7 +8706,7 @@ func (m *FloatMetric) Reset() { *m = FloatMetric{} } func (m *FloatMetric) String() string { return proto.CompactTextString(m) } func (*FloatMetric) ProtoMessage() {} func (*FloatMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{98} + return fileDescriptor_77a6da22d6a3feb1, []int{99} } func (m *FloatMetric) XXX_Unmarshal(b []byte) error { @@ -8686,7 +8756,7 @@ func (m *ChanInfoRequest) Reset() { *m = ChanInfoRequest{} } func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) } func (*ChanInfoRequest) ProtoMessage() {} func (*ChanInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{99} + return fileDescriptor_77a6da22d6a3feb1, []int{100} } func (m *ChanInfoRequest) XXX_Unmarshal(b []byte) error { @@ -8724,7 +8794,7 @@ func (m *NetworkInfoRequest) Reset() { *m = NetworkInfoRequest{} } func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) } func (*NetworkInfoRequest) ProtoMessage() {} func (*NetworkInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{100} + return fileDescriptor_77a6da22d6a3feb1, []int{101} } func (m *NetworkInfoRequest) XXX_Unmarshal(b []byte) error { @@ -8767,7 +8837,7 @@ func (m *NetworkInfo) Reset() { *m = NetworkInfo{} } func (m *NetworkInfo) String() string { return proto.CompactTextString(m) } func (*NetworkInfo) ProtoMessage() {} func (*NetworkInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{101} + return fileDescriptor_77a6da22d6a3feb1, []int{102} } func (m *NetworkInfo) XXX_Unmarshal(b []byte) error { @@ -8875,7 +8945,7 @@ func (m *StopRequest) Reset() { *m = StopRequest{} } func (m *StopRequest) String() string { return proto.CompactTextString(m) } func (*StopRequest) ProtoMessage() {} func (*StopRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{102} + return fileDescriptor_77a6da22d6a3feb1, []int{103} } func (m *StopRequest) XXX_Unmarshal(b []byte) error { @@ -8906,7 +8976,7 @@ func (m *StopResponse) Reset() { *m = StopResponse{} } func (m *StopResponse) String() string { return proto.CompactTextString(m) } func (*StopResponse) ProtoMessage() {} func (*StopResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{103} + return fileDescriptor_77a6da22d6a3feb1, []int{104} } func (m *StopResponse) XXX_Unmarshal(b []byte) error { @@ -8937,7 +9007,7 @@ func (m *GraphTopologySubscription) Reset() { *m = GraphTopologySubscrip func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) } func (*GraphTopologySubscription) ProtoMessage() {} func (*GraphTopologySubscription) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{104} + return fileDescriptor_77a6da22d6a3feb1, []int{105} } func (m *GraphTopologySubscription) XXX_Unmarshal(b []byte) error { @@ -8971,7 +9041,7 @@ func (m *GraphTopologyUpdate) Reset() { *m = GraphTopologyUpdate{} } func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) } func (*GraphTopologyUpdate) ProtoMessage() {} func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{105} + return fileDescriptor_77a6da22d6a3feb1, []int{106} } func (m *GraphTopologyUpdate) XXX_Unmarshal(b []byte) error { @@ -9032,7 +9102,7 @@ func (m *NodeUpdate) Reset() { *m = NodeUpdate{} } func (m *NodeUpdate) String() string { return proto.CompactTextString(m) } func (*NodeUpdate) ProtoMessage() {} func (*NodeUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{106} + return fileDescriptor_77a6da22d6a3feb1, []int{107} } func (m *NodeUpdate) XXX_Unmarshal(b []byte) error { @@ -9116,7 +9186,7 @@ func (m *ChannelEdgeUpdate) Reset() { *m = ChannelEdgeUpdate{} } func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) } func (*ChannelEdgeUpdate) ProtoMessage() {} func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{107} + return fileDescriptor_77a6da22d6a3feb1, []int{108} } func (m *ChannelEdgeUpdate) XXX_Unmarshal(b []byte) error { @@ -9197,7 +9267,7 @@ func (m *ClosedChannelUpdate) Reset() { *m = ClosedChannelUpdate{} } func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) } func (*ClosedChannelUpdate) ProtoMessage() {} func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{108} + return fileDescriptor_77a6da22d6a3feb1, []int{109} } func (m *ClosedChannelUpdate) XXX_Unmarshal(b []byte) error { @@ -9268,7 +9338,7 @@ func (m *HopHint) Reset() { *m = HopHint{} } func (m *HopHint) String() string { return proto.CompactTextString(m) } func (*HopHint) ProtoMessage() {} func (*HopHint) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{109} + return fileDescriptor_77a6da22d6a3feb1, []int{110} } func (m *HopHint) XXX_Unmarshal(b []byte) error { @@ -9338,7 +9408,7 @@ func (m *RouteHint) Reset() { *m = RouteHint{} } func (m *RouteHint) String() string { return proto.CompactTextString(m) } func (*RouteHint) ProtoMessage() {} func (*RouteHint) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{110} + return fileDescriptor_77a6da22d6a3feb1, []int{111} } func (m *RouteHint) XXX_Unmarshal(b []byte) error { @@ -9476,7 +9546,7 @@ func (m *Invoice) Reset() { *m = Invoice{} } func (m *Invoice) String() string { return proto.CompactTextString(m) } func (*Invoice) ProtoMessage() {} func (*Invoice) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{111} + return fileDescriptor_77a6da22d6a3feb1, []int{112} } func (m *Invoice) XXX_Unmarshal(b []byte) error { @@ -9707,7 +9777,7 @@ func (m *InvoiceHTLC) Reset() { *m = InvoiceHTLC{} } func (m *InvoiceHTLC) String() string { return proto.CompactTextString(m) } func (*InvoiceHTLC) ProtoMessage() {} func (*InvoiceHTLC) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{112} + return fileDescriptor_77a6da22d6a3feb1, []int{113} } func (m *InvoiceHTLC) XXX_Unmarshal(b []byte) error { @@ -9830,7 +9900,7 @@ func (m *AMP) Reset() { *m = AMP{} } func (m *AMP) String() string { return proto.CompactTextString(m) } func (*AMP) ProtoMessage() {} func (*AMP) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{113} + return fileDescriptor_77a6da22d6a3feb1, []int{114} } func (m *AMP) XXX_Unmarshal(b []byte) error { @@ -9913,7 +9983,7 @@ func (m *AddInvoiceResponse) Reset() { *m = AddInvoiceResponse{} } func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) } func (*AddInvoiceResponse) ProtoMessage() {} func (*AddInvoiceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{114} + return fileDescriptor_77a6da22d6a3feb1, []int{115} } func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error { @@ -9982,7 +10052,7 @@ func (m *PaymentHash) Reset() { *m = PaymentHash{} } func (m *PaymentHash) String() string { return proto.CompactTextString(m) } func (*PaymentHash) ProtoMessage() {} func (*PaymentHash) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{115} + return fileDescriptor_77a6da22d6a3feb1, []int{116} } func (m *PaymentHash) XXX_Unmarshal(b []byte) error { @@ -10042,7 +10112,7 @@ func (m *ListInvoiceRequest) Reset() { *m = ListInvoiceRequest{} } func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) } func (*ListInvoiceRequest) ProtoMessage() {} func (*ListInvoiceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{116} + return fileDescriptor_77a6da22d6a3feb1, []int{117} } func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error { @@ -10113,7 +10183,7 @@ func (m *ListInvoiceResponse) Reset() { *m = ListInvoiceResponse{} } func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) } func (*ListInvoiceResponse) ProtoMessage() {} func (*ListInvoiceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{117} + return fileDescriptor_77a6da22d6a3feb1, []int{118} } func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error { @@ -10177,7 +10247,7 @@ func (m *InvoiceSubscription) Reset() { *m = InvoiceSubscription{} } func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) } func (*InvoiceSubscription) ProtoMessage() {} func (*InvoiceSubscription) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{118} + return fileDescriptor_77a6da22d6a3feb1, []int{119} } func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error { @@ -10254,7 +10324,7 @@ func (m *Payment) Reset() { *m = Payment{} } func (m *Payment) String() string { return proto.CompactTextString(m) } func (*Payment) ProtoMessage() {} func (*Payment) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{119} + return fileDescriptor_77a6da22d6a3feb1, []int{120} } func (m *Payment) XXX_Unmarshal(b []byte) error { @@ -10409,7 +10479,7 @@ func (m *HTLCAttempt) Reset() { *m = HTLCAttempt{} } func (m *HTLCAttempt) String() string { return proto.CompactTextString(m) } func (*HTLCAttempt) ProtoMessage() {} func (*HTLCAttempt) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{120} + return fileDescriptor_77a6da22d6a3feb1, []int{121} } func (m *HTLCAttempt) XXX_Unmarshal(b []byte) error { @@ -10509,7 +10579,7 @@ func (m *ListPaymentsRequest) Reset() { *m = ListPaymentsRequest{} } func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) } func (*ListPaymentsRequest) ProtoMessage() {} func (*ListPaymentsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{121} + return fileDescriptor_77a6da22d6a3feb1, []int{122} } func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error { @@ -10578,7 +10648,7 @@ func (m *ListPaymentsResponse) Reset() { *m = ListPaymentsResponse{} } func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) } func (*ListPaymentsResponse) ProtoMessage() {} func (*ListPaymentsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{122} + return fileDescriptor_77a6da22d6a3feb1, []int{123} } func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error { @@ -10635,7 +10705,7 @@ func (m *DeleteAllPaymentsRequest) Reset() { *m = DeleteAllPaymentsReque func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) } func (*DeleteAllPaymentsRequest) ProtoMessage() {} func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{123} + return fileDescriptor_77a6da22d6a3feb1, []int{124} } func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error { @@ -10680,7 +10750,7 @@ func (m *DeleteAllPaymentsResponse) Reset() { *m = DeleteAllPaymentsResp func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) } func (*DeleteAllPaymentsResponse) ProtoMessage() {} func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{124} + return fileDescriptor_77a6da22d6a3feb1, []int{125} } func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error { @@ -10713,7 +10783,7 @@ func (m *AbandonChannelRequest) Reset() { *m = AbandonChannelRequest{} } func (m *AbandonChannelRequest) String() string { return proto.CompactTextString(m) } func (*AbandonChannelRequest) ProtoMessage() {} func (*AbandonChannelRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{125} + return fileDescriptor_77a6da22d6a3feb1, []int{126} } func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error { @@ -10758,7 +10828,7 @@ func (m *AbandonChannelResponse) Reset() { *m = AbandonChannelResponse{} func (m *AbandonChannelResponse) String() string { return proto.CompactTextString(m) } func (*AbandonChannelResponse) ProtoMessage() {} func (*AbandonChannelResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{126} + return fileDescriptor_77a6da22d6a3feb1, []int{127} } func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error { @@ -10791,7 +10861,7 @@ func (m *DebugLevelRequest) Reset() { *m = DebugLevelRequest{} } func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) } func (*DebugLevelRequest) ProtoMessage() {} func (*DebugLevelRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{127} + return fileDescriptor_77a6da22d6a3feb1, []int{128} } func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error { @@ -10837,7 +10907,7 @@ func (m *DebugLevelResponse) Reset() { *m = DebugLevelResponse{} } func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) } func (*DebugLevelResponse) ProtoMessage() {} func (*DebugLevelResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{128} + return fileDescriptor_77a6da22d6a3feb1, []int{129} } func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error { @@ -10877,7 +10947,7 @@ func (m *PayReqString) Reset() { *m = PayReqString{} } func (m *PayReqString) String() string { return proto.CompactTextString(m) } func (*PayReqString) ProtoMessage() {} func (*PayReqString) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{129} + return fileDescriptor_77a6da22d6a3feb1, []int{130} } func (m *PayReqString) XXX_Unmarshal(b []byte) error { @@ -10928,7 +10998,7 @@ func (m *PayReq) Reset() { *m = PayReq{} } func (m *PayReq) String() string { return proto.CompactTextString(m) } func (*PayReq) ProtoMessage() {} func (*PayReq) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{130} + return fileDescriptor_77a6da22d6a3feb1, []int{131} } func (m *PayReq) XXX_Unmarshal(b []byte) error { @@ -11053,7 +11123,7 @@ func (m *Feature) Reset() { *m = Feature{} } func (m *Feature) String() string { return proto.CompactTextString(m) } func (*Feature) ProtoMessage() {} func (*Feature) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{131} + return fileDescriptor_77a6da22d6a3feb1, []int{132} } func (m *Feature) XXX_Unmarshal(b []byte) error { @@ -11105,7 +11175,7 @@ func (m *FeeReportRequest) Reset() { *m = FeeReportRequest{} } func (m *FeeReportRequest) String() string { return proto.CompactTextString(m) } func (*FeeReportRequest) ProtoMessage() {} func (*FeeReportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{132} + return fileDescriptor_77a6da22d6a3feb1, []int{133} } func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error { @@ -11148,7 +11218,7 @@ func (m *ChannelFeeReport) Reset() { *m = ChannelFeeReport{} } func (m *ChannelFeeReport) String() string { return proto.CompactTextString(m) } func (*ChannelFeeReport) ProtoMessage() {} func (*ChannelFeeReport) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{133} + return fileDescriptor_77a6da22d6a3feb1, []int{134} } func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error { @@ -11226,7 +11296,7 @@ func (m *FeeReportResponse) Reset() { *m = FeeReportResponse{} } func (m *FeeReportResponse) String() string { return proto.CompactTextString(m) } func (*FeeReportResponse) ProtoMessage() {} func (*FeeReportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{134} + return fileDescriptor_77a6da22d6a3feb1, []int{135} } func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error { @@ -11304,7 +11374,7 @@ func (m *PolicyUpdateRequest) Reset() { *m = PolicyUpdateRequest{} } func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) } func (*PolicyUpdateRequest) ProtoMessage() {} func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{135} + return fileDescriptor_77a6da22d6a3feb1, []int{136} } func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error { @@ -11422,7 +11492,7 @@ func (m *PolicyUpdateResponse) Reset() { *m = PolicyUpdateResponse{} } func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) } func (*PolicyUpdateResponse) ProtoMessage() {} func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{136} + return fileDescriptor_77a6da22d6a3feb1, []int{137} } func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error { @@ -11467,7 +11537,7 @@ func (m *ForwardingHistoryRequest) Reset() { *m = ForwardingHistoryReque func (m *ForwardingHistoryRequest) String() string { return proto.CompactTextString(m) } func (*ForwardingHistoryRequest) ProtoMessage() {} func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{137} + return fileDescriptor_77a6da22d6a3feb1, []int{138} } func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error { @@ -11553,7 +11623,7 @@ func (m *ForwardingEvent) Reset() { *m = ForwardingEvent{} } func (m *ForwardingEvent) String() string { return proto.CompactTextString(m) } func (*ForwardingEvent) ProtoMessage() {} func (*ForwardingEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{138} + return fileDescriptor_77a6da22d6a3feb1, []int{139} } func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error { @@ -11661,7 +11731,7 @@ func (m *ForwardingHistoryResponse) Reset() { *m = ForwardingHistoryResp func (m *ForwardingHistoryResponse) String() string { return proto.CompactTextString(m) } func (*ForwardingHistoryResponse) ProtoMessage() {} func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{139} + return fileDescriptor_77a6da22d6a3feb1, []int{140} } func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error { @@ -11708,7 +11778,7 @@ func (m *ExportChannelBackupRequest) Reset() { *m = ExportChannelBackupR func (m *ExportChannelBackupRequest) String() string { return proto.CompactTextString(m) } func (*ExportChannelBackupRequest) ProtoMessage() {} func (*ExportChannelBackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{140} + return fileDescriptor_77a6da22d6a3feb1, []int{141} } func (m *ExportChannelBackupRequest) XXX_Unmarshal(b []byte) error { @@ -11755,7 +11825,7 @@ func (m *ChannelBackup) Reset() { *m = ChannelBackup{} } func (m *ChannelBackup) String() string { return proto.CompactTextString(m) } func (*ChannelBackup) ProtoMessage() {} func (*ChannelBackup) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{141} + return fileDescriptor_77a6da22d6a3feb1, []int{142} } func (m *ChannelBackup) XXX_Unmarshal(b []byte) error { @@ -11809,7 +11879,7 @@ func (m *MultiChanBackup) Reset() { *m = MultiChanBackup{} } func (m *MultiChanBackup) String() string { return proto.CompactTextString(m) } func (*MultiChanBackup) ProtoMessage() {} func (*MultiChanBackup) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{142} + return fileDescriptor_77a6da22d6a3feb1, []int{143} } func (m *MultiChanBackup) XXX_Unmarshal(b []byte) error { @@ -11854,7 +11924,7 @@ func (m *ChanBackupExportRequest) Reset() { *m = ChanBackupExportRequest func (m *ChanBackupExportRequest) String() string { return proto.CompactTextString(m) } func (*ChanBackupExportRequest) ProtoMessage() {} func (*ChanBackupExportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{143} + return fileDescriptor_77a6da22d6a3feb1, []int{144} } func (m *ChanBackupExportRequest) XXX_Unmarshal(b []byte) error { @@ -11893,7 +11963,7 @@ func (m *ChanBackupSnapshot) Reset() { *m = ChanBackupSnapshot{} } func (m *ChanBackupSnapshot) String() string { return proto.CompactTextString(m) } func (*ChanBackupSnapshot) ProtoMessage() {} func (*ChanBackupSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{144} + return fileDescriptor_77a6da22d6a3feb1, []int{145} } func (m *ChanBackupSnapshot) XXX_Unmarshal(b []byte) error { @@ -11941,7 +12011,7 @@ func (m *ChannelBackups) Reset() { *m = ChannelBackups{} } func (m *ChannelBackups) String() string { return proto.CompactTextString(m) } func (*ChannelBackups) ProtoMessage() {} func (*ChannelBackups) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{145} + return fileDescriptor_77a6da22d6a3feb1, []int{146} } func (m *ChannelBackups) XXX_Unmarshal(b []byte) error { @@ -11983,7 +12053,7 @@ func (m *RestoreChanBackupRequest) Reset() { *m = RestoreChanBackupReque func (m *RestoreChanBackupRequest) String() string { return proto.CompactTextString(m) } func (*RestoreChanBackupRequest) ProtoMessage() {} func (*RestoreChanBackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{146} + return fileDescriptor_77a6da22d6a3feb1, []int{147} } func (m *RestoreChanBackupRequest) XXX_Unmarshal(b []byte) error { @@ -12059,7 +12129,7 @@ func (m *RestoreBackupResponse) Reset() { *m = RestoreBackupResponse{} } func (m *RestoreBackupResponse) String() string { return proto.CompactTextString(m) } func (*RestoreBackupResponse) ProtoMessage() {} func (*RestoreBackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{147} + return fileDescriptor_77a6da22d6a3feb1, []int{148} } func (m *RestoreBackupResponse) XXX_Unmarshal(b []byte) error { @@ -12090,7 +12160,7 @@ func (m *ChannelBackupSubscription) Reset() { *m = ChannelBackupSubscrip func (m *ChannelBackupSubscription) String() string { return proto.CompactTextString(m) } func (*ChannelBackupSubscription) ProtoMessage() {} func (*ChannelBackupSubscription) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{148} + return fileDescriptor_77a6da22d6a3feb1, []int{149} } func (m *ChannelBackupSubscription) XXX_Unmarshal(b []byte) error { @@ -12121,7 +12191,7 @@ func (m *VerifyChanBackupResponse) Reset() { *m = VerifyChanBackupRespon func (m *VerifyChanBackupResponse) String() string { return proto.CompactTextString(m) } func (*VerifyChanBackupResponse) ProtoMessage() {} func (*VerifyChanBackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{149} + return fileDescriptor_77a6da22d6a3feb1, []int{150} } func (m *VerifyChanBackupResponse) XXX_Unmarshal(b []byte) error { @@ -12156,7 +12226,7 @@ func (m *MacaroonPermission) Reset() { *m = MacaroonPermission{} } func (m *MacaroonPermission) String() string { return proto.CompactTextString(m) } func (*MacaroonPermission) ProtoMessage() {} func (*MacaroonPermission) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{150} + return fileDescriptor_77a6da22d6a3feb1, []int{151} } func (m *MacaroonPermission) XXX_Unmarshal(b []byte) error { @@ -12205,7 +12275,7 @@ func (m *BakeMacaroonRequest) Reset() { *m = BakeMacaroonRequest{} } func (m *BakeMacaroonRequest) String() string { return proto.CompactTextString(m) } func (*BakeMacaroonRequest) ProtoMessage() {} func (*BakeMacaroonRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{151} + return fileDescriptor_77a6da22d6a3feb1, []int{152} } func (m *BakeMacaroonRequest) XXX_Unmarshal(b []byte) error { @@ -12252,7 +12322,7 @@ func (m *BakeMacaroonResponse) Reset() { *m = BakeMacaroonResponse{} } func (m *BakeMacaroonResponse) String() string { return proto.CompactTextString(m) } func (*BakeMacaroonResponse) ProtoMessage() {} func (*BakeMacaroonResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{152} + return fileDescriptor_77a6da22d6a3feb1, []int{153} } func (m *BakeMacaroonResponse) XXX_Unmarshal(b []byte) error { @@ -12290,7 +12360,7 @@ func (m *ListMacaroonIDsRequest) Reset() { *m = ListMacaroonIDsRequest{} func (m *ListMacaroonIDsRequest) String() string { return proto.CompactTextString(m) } func (*ListMacaroonIDsRequest) ProtoMessage() {} func (*ListMacaroonIDsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{153} + return fileDescriptor_77a6da22d6a3feb1, []int{154} } func (m *ListMacaroonIDsRequest) XXX_Unmarshal(b []byte) error { @@ -12323,7 +12393,7 @@ func (m *ListMacaroonIDsResponse) Reset() { *m = ListMacaroonIDsResponse func (m *ListMacaroonIDsResponse) String() string { return proto.CompactTextString(m) } func (*ListMacaroonIDsResponse) ProtoMessage() {} func (*ListMacaroonIDsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{154} + return fileDescriptor_77a6da22d6a3feb1, []int{155} } func (m *ListMacaroonIDsResponse) XXX_Unmarshal(b []byte) error { @@ -12363,7 +12433,7 @@ func (m *DeleteMacaroonIDRequest) Reset() { *m = DeleteMacaroonIDRequest func (m *DeleteMacaroonIDRequest) String() string { return proto.CompactTextString(m) } func (*DeleteMacaroonIDRequest) ProtoMessage() {} func (*DeleteMacaroonIDRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{155} + return fileDescriptor_77a6da22d6a3feb1, []int{156} } func (m *DeleteMacaroonIDRequest) XXX_Unmarshal(b []byte) error { @@ -12403,7 +12473,7 @@ func (m *DeleteMacaroonIDResponse) Reset() { *m = DeleteMacaroonIDRespon func (m *DeleteMacaroonIDResponse) String() string { return proto.CompactTextString(m) } func (*DeleteMacaroonIDResponse) ProtoMessage() {} func (*DeleteMacaroonIDResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{156} + return fileDescriptor_77a6da22d6a3feb1, []int{157} } func (m *DeleteMacaroonIDResponse) XXX_Unmarshal(b []byte) error { @@ -12443,7 +12513,7 @@ func (m *MacaroonPermissionList) Reset() { *m = MacaroonPermissionList{} func (m *MacaroonPermissionList) String() string { return proto.CompactTextString(m) } func (*MacaroonPermissionList) ProtoMessage() {} func (*MacaroonPermissionList) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{157} + return fileDescriptor_77a6da22d6a3feb1, []int{158} } func (m *MacaroonPermissionList) XXX_Unmarshal(b []byte) error { @@ -12481,7 +12551,7 @@ func (m *ListPermissionsRequest) Reset() { *m = ListPermissionsRequest{} func (m *ListPermissionsRequest) String() string { return proto.CompactTextString(m) } func (*ListPermissionsRequest) ProtoMessage() {} func (*ListPermissionsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{158} + return fileDescriptor_77a6da22d6a3feb1, []int{159} } func (m *ListPermissionsRequest) XXX_Unmarshal(b []byte) error { @@ -12516,7 +12586,7 @@ func (m *ListPermissionsResponse) Reset() { *m = ListPermissionsResponse func (m *ListPermissionsResponse) String() string { return proto.CompactTextString(m) } func (*ListPermissionsResponse) ProtoMessage() {} func (*ListPermissionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{159} + return fileDescriptor_77a6da22d6a3feb1, []int{160} } func (m *ListPermissionsResponse) XXX_Unmarshal(b []byte) error { @@ -12572,7 +12642,7 @@ func (m *Failure) Reset() { *m = Failure{} } func (m *Failure) String() string { return proto.CompactTextString(m) } func (*Failure) ProtoMessage() {} func (*Failure) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{160} + return fileDescriptor_77a6da22d6a3feb1, []int{161} } func (m *Failure) XXX_Unmarshal(b []byte) error { @@ -12716,7 +12786,7 @@ func (m *ChannelUpdate) Reset() { *m = ChannelUpdate{} } func (m *ChannelUpdate) String() string { return proto.CompactTextString(m) } func (*ChannelUpdate) ProtoMessage() {} func (*ChannelUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{161} + return fileDescriptor_77a6da22d6a3feb1, []int{162} } func (m *ChannelUpdate) XXX_Unmarshal(b []byte) error { @@ -12834,7 +12904,7 @@ func (m *MacaroonId) Reset() { *m = MacaroonId{} } func (m *MacaroonId) String() string { return proto.CompactTextString(m) } func (*MacaroonId) ProtoMessage() {} func (*MacaroonId) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{162} + return fileDescriptor_77a6da22d6a3feb1, []int{163} } func (m *MacaroonId) XXX_Unmarshal(b []byte) error { @@ -12888,7 +12958,7 @@ func (m *Op) Reset() { *m = Op{} } func (m *Op) String() string { return proto.CompactTextString(m) } func (*Op) ProtoMessage() {} func (*Op) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{163} + return fileDescriptor_77a6da22d6a3feb1, []int{164} } func (m *Op) XXX_Unmarshal(b []byte) error { @@ -13043,6 +13113,7 @@ func init() { proto.RegisterType((*Hop)(nil), "lnrpc.Hop") proto.RegisterMapType((map[uint64][]byte)(nil), "lnrpc.Hop.CustomRecordsEntry") proto.RegisterType((*MPPRecord)(nil), "lnrpc.MPPRecord") + proto.RegisterType((*AMPRecord)(nil), "lnrpc.AMPRecord") proto.RegisterType((*Route)(nil), "lnrpc.Route") proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest") proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo") @@ -13132,800 +13203,802 @@ func init() { func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } var fileDescriptor_77a6da22d6a3feb1 = []byte{ - // 12685 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0xbd, 0x5b, 0x6c, 0x23, 0x59, - 0x7a, 0x18, 0xdc, 0xbc, 0x89, 0xe4, 0x47, 0x52, 0xa2, 0x8e, 0x6e, 0x6c, 0xf5, 0xf4, 0x74, 0x4f, - 0xcd, 0xec, 0x4c, 0x6f, 0xcf, 0x8e, 0xa6, 0xa7, 0x67, 0x7a, 0x2e, 0x3b, 0xbf, 0xd7, 0x4b, 0x49, - 0x54, 0x8b, 0xdb, 0x12, 0xa9, 0x2d, 0x52, 0x3d, 0x6e, 0xc3, 0x76, 0xb9, 0x44, 0x1e, 0x49, 0xf5, - 0x37, 0x59, 0xc5, 0xad, 0x2a, 0xaa, 0xa5, 0x0d, 0x02, 0xf8, 0xc1, 0xb1, 0x03, 0xc3, 0x08, 0x10, - 0x20, 0x0e, 0x10, 0x24, 0x46, 0x12, 0x24, 0x48, 0xde, 0x0c, 0x03, 0xb6, 0x9f, 0x92, 0x87, 0x3c, - 0x25, 0x08, 0x90, 0x20, 0x08, 0x10, 0x23, 0x17, 0x04, 0x09, 0x02, 0x24, 0x0e, 0x10, 0x03, 0x89, - 0x01, 0x3f, 0x26, 0x41, 0x82, 0xf3, 0x9d, 0x4b, 0x9d, 0xba, 0xa8, 0xbb, 0x67, 0x3d, 0xd9, 0x17, - 0x89, 0xf5, 0x9d, 0xef, 0xdc, 0xcf, 0xf9, 0xce, 0x77, 0x3b, 0xdf, 0x81, 0xaa, 0x3f, 0x1b, 0x6d, - 0xcd, 0x7c, 0x2f, 0xf4, 0x48, 0x69, 0xe2, 0xfa, 0xb3, 0x91, 0xf1, 0x47, 0x39, 0x28, 0x1e, 0x87, - 0x97, 0x1e, 0x79, 0x04, 0x75, 0x7b, 0x3c, 0xf6, 0x69, 0x10, 0x58, 0xe1, 0xd5, 0x8c, 0xb6, 0x72, - 0x77, 0x73, 0xf7, 0x16, 0x1f, 0x92, 0x2d, 0x44, 0xdb, 0x6a, 0xf3, 0xa4, 0xe1, 0xd5, 0x8c, 0x9a, - 0x35, 0x3b, 0xfa, 0x20, 0x2d, 0x28, 0x8b, 0xcf, 0x56, 0xfe, 0x6e, 0xee, 0x5e, 0xd5, 0x94, 0x9f, - 0xe4, 0x36, 0x80, 0x3d, 0xf5, 0xe6, 0x6e, 0x68, 0x05, 0x76, 0xd8, 0x2a, 0xdc, 0xcd, 0xdd, 0x2b, - 0x98, 0x55, 0x0e, 0x19, 0xd8, 0x21, 0xb9, 0x05, 0xd5, 0xd9, 0x73, 0x2b, 0x18, 0xf9, 0xce, 0x2c, - 0x6c, 0x15, 0x31, 0x6b, 0x65, 0xf6, 0x7c, 0x80, 0xdf, 0xe4, 0x7d, 0xa8, 0x78, 0xf3, 0x70, 0xe6, - 0x39, 0x6e, 0xd8, 0x2a, 0xdd, 0xcd, 0xdd, 0xab, 0x3d, 0x5c, 0x12, 0x0d, 0xe9, 0xcf, 0xc3, 0x23, - 0x06, 0x36, 0x15, 0x02, 0x79, 0x07, 0x1a, 0x23, 0xcf, 0x3d, 0x75, 0xfc, 0xa9, 0x1d, 0x3a, 0x9e, - 0x1b, 0xb4, 0x16, 0xb0, 0xae, 0x38, 0xd0, 0xf8, 0xc7, 0x79, 0xa8, 0x0d, 0x7d, 0xdb, 0x0d, 0xec, - 0x11, 0x03, 0x90, 0x0d, 0x28, 0x87, 0x97, 0xd6, 0xb9, 0x1d, 0x9c, 0x63, 0x57, 0xab, 0xe6, 0x42, - 0x78, 0xb9, 0x6f, 0x07, 0xe7, 0x64, 0x1d, 0x16, 0x78, 0x2b, 0xb1, 0x43, 0x05, 0x53, 0x7c, 0x91, - 0xf7, 0x61, 0xd9, 0x9d, 0x4f, 0xad, 0x78, 0x55, 0xac, 0x5b, 0x25, 0xb3, 0xe9, 0xce, 0xa7, 0x3b, - 0x3a, 0x9c, 0x75, 0xfe, 0x64, 0xe2, 0x8d, 0x9e, 0xf3, 0x0a, 0x78, 0xf7, 0xaa, 0x08, 0xc1, 0x3a, - 0xde, 0x82, 0xba, 0x48, 0xa6, 0xce, 0xd9, 0x39, 0xef, 0x63, 0xc9, 0xac, 0x71, 0x04, 0x04, 0xb1, - 0x12, 0x42, 0x67, 0x4a, 0xad, 0x20, 0xb4, 0xa7, 0x33, 0xd1, 0xa5, 0x2a, 0x83, 0x0c, 0x18, 0x00, - 0x93, 0xbd, 0xd0, 0x9e, 0x58, 0xa7, 0x94, 0x06, 0xad, 0xb2, 0x48, 0x66, 0x90, 0x3d, 0x4a, 0x03, - 0xf2, 0x2d, 0x58, 0x1c, 0xd3, 0x20, 0xb4, 0xc4, 0x64, 0xd0, 0xa0, 0x55, 0xb9, 0x5b, 0xb8, 0x57, - 0x35, 0x1b, 0x0c, 0xda, 0x96, 0x40, 0xf2, 0x06, 0x80, 0x6f, 0xbf, 0xb0, 0xd8, 0x40, 0xd0, 0xcb, - 0x56, 0x95, 0xcf, 0x82, 0x6f, 0xbf, 0x18, 0x5e, 0xee, 0xd3, 0x4b, 0xb2, 0x0a, 0xa5, 0x89, 0x7d, - 0x42, 0x27, 0x2d, 0xc0, 0x04, 0xfe, 0x61, 0x84, 0xb0, 0xfe, 0x98, 0x86, 0xda, 0x50, 0x06, 0x26, - 0xfd, 0xd1, 0x9c, 0x06, 0x21, 0xeb, 0x55, 0x10, 0xda, 0x7e, 0x28, 0x7b, 0x95, 0xe3, 0xbd, 0x42, - 0x58, 0xd4, 0x2b, 0xea, 0x8e, 0x25, 0x42, 0x1e, 0x11, 0xaa, 0xd4, 0x1d, 0x8b, 0x64, 0xb6, 0x9a, - 0x46, 0x23, 0x1c, 0xfc, 0x82, 0x58, 0x4d, 0xfc, 0xd3, 0x38, 0x00, 0xa2, 0x55, 0xb9, 0x4b, 0x43, - 0xdb, 0x99, 0x04, 0xe4, 0x53, 0xa8, 0x87, 0x5a, 0x43, 0x5a, 0xb9, 0xbb, 0x85, 0x7b, 0x35, 0xb5, - 0x68, 0xb5, 0x0c, 0x66, 0x0c, 0xcf, 0x38, 0x87, 0xca, 0x1e, 0xa5, 0x07, 0xce, 0xd4, 0x09, 0xc9, - 0x3a, 0x94, 0x4e, 0x9d, 0x4b, 0x3a, 0xc6, 0xe6, 0x16, 0xf6, 0x6f, 0x98, 0xfc, 0x93, 0xdc, 0x01, - 0xc0, 0x1f, 0xd6, 0x54, 0xad, 0xdf, 0xfd, 0x1b, 0x66, 0x15, 0x61, 0x87, 0x81, 0x1d, 0x92, 0x4d, - 0x28, 0xcf, 0xa8, 0x3f, 0xa2, 0x72, 0xa5, 0xec, 0xdf, 0x30, 0x25, 0x60, 0xbb, 0x0c, 0xa5, 0x09, - 0x2b, 0xdd, 0xf8, 0x6f, 0x25, 0xa8, 0x0d, 0xa8, 0x3b, 0x96, 0x63, 0x44, 0xa0, 0xc8, 0xa6, 0x00, - 0x2b, 0xab, 0x9b, 0xf8, 0x9b, 0xbc, 0x0d, 0x35, 0x9c, 0xac, 0x20, 0xf4, 0x1d, 0xf7, 0x8c, 0xef, - 0xa3, 0xed, 0x7c, 0x2b, 0x67, 0x02, 0x03, 0x0f, 0x10, 0x4a, 0x9a, 0x50, 0xb0, 0xa7, 0x72, 0x1f, - 0xb1, 0x9f, 0xe4, 0x26, 0x54, 0xec, 0x69, 0xc8, 0x9b, 0x57, 0x47, 0x70, 0xd9, 0x9e, 0x86, 0xd8, - 0xb4, 0xb7, 0xa0, 0x3e, 0xb3, 0xaf, 0xa6, 0xd4, 0x0d, 0xa3, 0x05, 0x58, 0x37, 0x6b, 0x02, 0x86, - 0x4b, 0xf0, 0x21, 0xac, 0xe8, 0x28, 0xb2, 0xf2, 0x92, 0xaa, 0x7c, 0x59, 0xc3, 0x16, 0x6d, 0x78, - 0x0f, 0x96, 0x64, 0x1e, 0x9f, 0xf7, 0x07, 0x17, 0x66, 0xd5, 0x5c, 0x14, 0x60, 0xd9, 0xcb, 0x7b, - 0xd0, 0x3c, 0x75, 0x5c, 0x7b, 0x62, 0x8d, 0x26, 0xe1, 0x85, 0x35, 0xa6, 0x93, 0xd0, 0xc6, 0x35, - 0x5a, 0x32, 0x17, 0x11, 0xbe, 0x33, 0x09, 0x2f, 0x76, 0x19, 0x94, 0x7c, 0x07, 0xaa, 0xa7, 0x94, - 0x5a, 0x38, 0x58, 0xad, 0x4a, 0x6c, 0xab, 0xcb, 0x19, 0x32, 0x2b, 0xa7, 0x72, 0xae, 0xbe, 0x03, - 0x4d, 0x6f, 0x1e, 0x9e, 0x79, 0x8e, 0x7b, 0x66, 0x8d, 0xce, 0x6d, 0xd7, 0x72, 0xc6, 0xb8, 0x6a, - 0x8b, 0xdb, 0xf9, 0x07, 0x39, 0x73, 0x51, 0xa6, 0xed, 0x9c, 0xdb, 0x6e, 0x77, 0x4c, 0xde, 0x85, - 0xa5, 0x89, 0x1d, 0x84, 0xd6, 0xb9, 0x37, 0xb3, 0x66, 0xf3, 0x93, 0xe7, 0xf4, 0xaa, 0xd5, 0xc0, - 0x81, 0x68, 0x30, 0xf0, 0xbe, 0x37, 0x3b, 0x42, 0x20, 0x5b, 0x94, 0xd8, 0x4e, 0xde, 0x08, 0xb6, - 0xd8, 0x1b, 0x66, 0x95, 0x41, 0x78, 0xa5, 0xcf, 0x60, 0x05, 0xa7, 0x67, 0x34, 0x0f, 0x42, 0x6f, - 0x6a, 0xf9, 0x74, 0xe4, 0xf9, 0xe3, 0xa0, 0x55, 0xc3, 0xb5, 0xf6, 0x6d, 0xd1, 0x58, 0x6d, 0x8e, - 0xb7, 0x76, 0x69, 0x10, 0xee, 0x20, 0xb2, 0xc9, 0x71, 0x3b, 0x6e, 0xe8, 0x5f, 0x99, 0xcb, 0xe3, - 0x24, 0x9c, 0x7c, 0x07, 0x88, 0x3d, 0x99, 0x78, 0x2f, 0xac, 0x80, 0x4e, 0x4e, 0x2d, 0x31, 0x88, - 0xad, 0xc5, 0xbb, 0xb9, 0x7b, 0x15, 0xb3, 0x89, 0x29, 0x03, 0x3a, 0x39, 0x3d, 0xe2, 0x70, 0xf2, - 0x29, 0xe0, 0xf6, 0xb5, 0x4e, 0xa9, 0x1d, 0xce, 0x7d, 0x1a, 0xb4, 0x96, 0xee, 0x16, 0xee, 0x2d, - 0x3e, 0x5c, 0x56, 0xe3, 0x85, 0xe0, 0x6d, 0x27, 0x34, 0xeb, 0x0c, 0x4f, 0x7c, 0x07, 0xfa, 0x6a, - 0x60, 0xf4, 0xa0, 0xd5, 0x8c, 0xad, 0x06, 0x46, 0x0d, 0x36, 0x77, 0x61, 0x3d, 0xbb, 0xd5, 0x6c, - 0xdd, 0xb1, 0x81, 0x63, 0xeb, 0xb5, 0x68, 0xb2, 0x9f, 0x8c, 0x2c, 0x5c, 0xd8, 0x93, 0x39, 0xc5, - 0x85, 0x5a, 0x37, 0xf9, 0xc7, 0x77, 0xf3, 0x9f, 0xe7, 0x8c, 0xdf, 0xcf, 0x41, 0x9d, 0x0f, 0x44, - 0x30, 0xf3, 0xdc, 0x80, 0x92, 0xb7, 0xa1, 0x21, 0x6b, 0xa6, 0xbe, 0xef, 0xf9, 0x82, 0xd4, 0xca, - 0xe6, 0x74, 0x18, 0x8c, 0x7c, 0x1b, 0x9a, 0x12, 0x69, 0xe6, 0x53, 0x67, 0x6a, 0x9f, 0xc9, 0xa2, - 0xe5, 0x6a, 0x3b, 0x12, 0x60, 0xf2, 0x51, 0x54, 0x9e, 0xef, 0xcd, 0x43, 0x8a, 0xdb, 0xa1, 0xf6, - 0xb0, 0x2e, 0x46, 0xc0, 0x64, 0x30, 0x55, 0x3a, 0x7e, 0xbd, 0xc6, 0x56, 0x30, 0x7e, 0x2b, 0x07, - 0x84, 0x35, 0x7b, 0xe8, 0xf1, 0x02, 0x22, 0x72, 0x16, 0xcb, 0x99, 0x7b, 0xed, 0x4d, 0x94, 0x7f, - 0xd9, 0x26, 0x32, 0xa0, 0xc4, 0xdb, 0x5e, 0xcc, 0x68, 0x3b, 0x4f, 0xfa, 0x41, 0xb1, 0x52, 0x68, - 0x16, 0x8d, 0x7f, 0x57, 0x80, 0x55, 0xb6, 0x94, 0x5d, 0x3a, 0x69, 0x8f, 0x46, 0x74, 0xa6, 0xb6, - 0xd7, 0x1d, 0xa8, 0xb9, 0xde, 0x98, 0xca, 0x45, 0xcd, 0x1b, 0x06, 0x0c, 0xa4, 0xad, 0xe8, 0x73, - 0xdb, 0x71, 0x79, 0xc3, 0xf9, 0x60, 0x56, 0x11, 0x82, 0xcd, 0x7e, 0x17, 0x96, 0x66, 0xd4, 0x1d, - 0xeb, 0xbb, 0xa8, 0xc0, 0x37, 0x86, 0x00, 0x8b, 0x0d, 0x74, 0x07, 0x6a, 0xa7, 0x73, 0x8e, 0xc7, - 0x68, 0x4f, 0x11, 0xd7, 0x00, 0x08, 0x50, 0x9b, 0x93, 0xa0, 0xd9, 0x3c, 0x38, 0xc7, 0xd4, 0x12, - 0xa6, 0x96, 0xd9, 0x37, 0x4b, 0xba, 0x0d, 0x30, 0x9e, 0x07, 0xa1, 0xd8, 0x54, 0x0b, 0x98, 0x58, - 0x65, 0x10, 0xbe, 0xa9, 0x3e, 0x80, 0x95, 0xa9, 0x7d, 0x69, 0xe1, 0xda, 0xb1, 0x1c, 0xd7, 0x3a, - 0x9d, 0xe0, 0x89, 0x50, 0x46, 0xbc, 0xe6, 0xd4, 0xbe, 0x7c, 0xca, 0x52, 0xba, 0xee, 0x1e, 0xc2, - 0x19, 0xe5, 0x19, 0xf1, 0x91, 0xb0, 0x7c, 0x1a, 0x50, 0xff, 0x82, 0x22, 0xb1, 0x28, 0x9a, 0x8b, - 0x02, 0x6c, 0x72, 0x28, 0x6b, 0xd1, 0x94, 0xf5, 0x3b, 0x9c, 0x8c, 0x38, 0x65, 0x30, 0xcb, 0x53, - 0xc7, 0xdd, 0x0f, 0x27, 0x23, 0x76, 0xd8, 0x31, 0x52, 0x33, 0xa3, 0xbe, 0xf5, 0xfc, 0x05, 0x6e, - 0xf3, 0x22, 0x92, 0x96, 0x23, 0xea, 0x3f, 0x79, 0xc1, 0xf8, 0x91, 0x51, 0x80, 0xb4, 0xca, 0xbe, - 0x6a, 0xd5, 0x90, 0x06, 0x54, 0x46, 0x01, 0xa3, 0x52, 0xf6, 0x15, 0xdb, 0xa7, 0xac, 0xb5, 0x36, - 0xce, 0x02, 0x1d, 0x63, 0xf1, 0x01, 0x12, 0xdd, 0x06, 0x36, 0xb6, 0x2d, 0x12, 0x58, 0x3d, 0x01, - 0x5b, 0xf5, 0xb2, 0xb1, 0xa7, 0x13, 0xfb, 0x2c, 0x40, 0xaa, 0xd3, 0x30, 0xeb, 0x02, 0xb8, 0xc7, - 0x60, 0xc6, 0x9f, 0xe6, 0x61, 0x2d, 0x31, 0xb9, 0x62, 0xd3, 0x30, 0x06, 0x04, 0x21, 0x38, 0xb1, - 0x15, 0x53, 0x7c, 0x65, 0xcd, 0x5a, 0x3e, 0x6b, 0xd6, 0x56, 0xa1, 0xc4, 0x37, 0x1b, 0x3f, 0x42, - 0xf9, 0x07, 0xdb, 0x65, 0xf3, 0xd9, 0xa9, 0xef, 0x31, 0x7e, 0xec, 0x7c, 0x1e, 0x8e, 0xbd, 0x17, - 0xae, 0xe0, 0x4b, 0x96, 0x04, 0x7c, 0x20, 0xc0, 0xf1, 0xa1, 0x28, 0x25, 0x86, 0xe2, 0x0e, 0xd4, - 0xc4, 0x0c, 0x20, 0x5f, 0xc7, 0x27, 0x16, 0x04, 0x88, 0x31, 0x76, 0xef, 0x03, 0x51, 0xf3, 0x69, - 0xb1, 0x51, 0xc3, 0x03, 0x8a, 0x4f, 0xec, 0x92, 0x23, 0x26, 0xf4, 0xd0, 0xbe, 0xc4, 0x83, 0xea, - 0x1d, 0x58, 0x64, 0x28, 0x6c, 0x3c, 0x2d, 0x7e, 0xee, 0x57, 0xf8, 0x58, 0x4d, 0xed, 0x4b, 0x36, - 0x98, 0x3b, 0xc8, 0x7a, 0xbd, 0x09, 0x35, 0x39, 0xa9, 0x96, 0xe3, 0x8a, 0x79, 0xad, 0x8a, 0x79, - 0xed, 0xba, 0xec, 0xb8, 0x61, 0xe9, 0x7c, 0x9c, 0xac, 0x31, 0x9d, 0x85, 0xe7, 0x82, 0x8c, 0x2f, - 0x4e, 0x1d, 0x97, 0x0f, 0xef, 0x2e, 0x83, 0x1a, 0xbf, 0x9d, 0x83, 0xba, 0x18, 0x75, 0x64, 0x23, - 0xc9, 0x16, 0x10, 0xb9, 0xc4, 0xc3, 0x4b, 0x67, 0x6c, 0x9d, 0x5c, 0x85, 0x34, 0xe0, 0x3b, 0x6a, - 0xff, 0x86, 0xd9, 0x14, 0x69, 0xc3, 0x4b, 0x67, 0xbc, 0xcd, 0x52, 0xc8, 0x7d, 0x68, 0xc6, 0xf0, - 0x83, 0xd0, 0xe7, 0xdb, 0x7d, 0xff, 0x86, 0xb9, 0xa8, 0x61, 0x0f, 0x42, 0x9f, 0x11, 0x10, 0xc6, - 0xa4, 0xce, 0x43, 0xcb, 0x71, 0xc7, 0xf4, 0x12, 0xe7, 0xa3, 0x61, 0xd6, 0x38, 0xac, 0xcb, 0x40, - 0xdb, 0x8b, 0x50, 0xd7, 0x8b, 0x33, 0xce, 0xa0, 0x22, 0x39, 0x5c, 0x64, 0xf1, 0x12, 0x4d, 0x32, - 0xab, 0xa1, 0x6a, 0xc9, 0x4d, 0xa8, 0xc4, 0x5b, 0x60, 0x96, 0xc3, 0xd7, 0xae, 0xd8, 0xf8, 0x1e, - 0x34, 0x0f, 0xd8, 0x44, 0xb8, 0x6c, 0x27, 0x0b, 0x8e, 0x7d, 0x1d, 0x16, 0x34, 0x8a, 0x52, 0x35, - 0xc5, 0x17, 0xe3, 0x59, 0xce, 0xbd, 0x20, 0x14, 0xb5, 0xe0, 0x6f, 0xe3, 0x9f, 0xe4, 0x80, 0x74, - 0x82, 0xd0, 0x99, 0xda, 0x21, 0xdd, 0xa3, 0x8a, 0x66, 0xf6, 0xa1, 0xce, 0x4a, 0x1b, 0x7a, 0x6d, - 0xce, 0x42, 0x73, 0x86, 0xec, 0x7d, 0x41, 0xe3, 0xd2, 0x19, 0xb6, 0x74, 0x6c, 0x7e, 0x4c, 0xc6, - 0x0a, 0x60, 0xcb, 0x2d, 0xb4, 0xfd, 0x33, 0x1a, 0x22, 0xe3, 0x2d, 0x38, 0x46, 0xe0, 0x20, 0xc6, - 0x72, 0x6f, 0xfe, 0x2c, 0x2c, 0xa7, 0xca, 0xd0, 0x0f, 0xad, 0x6a, 0xc6, 0xa1, 0x55, 0xd0, 0x0f, - 0xad, 0x5f, 0xcf, 0xc1, 0x4a, 0xac, 0x61, 0x62, 0x1b, 0x6e, 0x40, 0x99, 0x91, 0x0b, 0xb6, 0x78, - 0x73, 0x5c, 0x10, 0x38, 0xa5, 0xb8, 0xc0, 0x3f, 0x86, 0xd5, 0x53, 0x4a, 0x7d, 0x3b, 0xc4, 0x44, - 0xa4, 0x27, 0x6c, 0x8a, 0x78, 0xc9, 0x9c, 0xea, 0x8b, 0xf4, 0x81, 0x1d, 0x1e, 0x51, 0x9f, 0x4d, - 0x17, 0x31, 0xa0, 0x21, 0x91, 0x2f, 0x10, 0xbb, 0x80, 0x8b, 0xb8, 0x16, 0x20, 0xca, 0x53, 0x06, - 0x32, 0xfe, 0x38, 0x0f, 0x4b, 0xec, 0x1c, 0x3a, 0xb4, 0xdd, 0x2b, 0x39, 0xa0, 0x07, 0x99, 0x03, - 0x7a, 0x4f, 0xe3, 0x3a, 0x34, 0xec, 0xaf, 0x3b, 0x9a, 0x85, 0xe4, 0x68, 0xa6, 0x9b, 0x59, 0x4c, - 0x35, 0x93, 0xbc, 0x03, 0xf5, 0x58, 0xbf, 0x4b, 0xaa, 0xdf, 0x10, 0x44, 0x1d, 0x56, 0xc2, 0xc3, - 0x82, 0x26, 0x3c, 0x30, 0xd2, 0xc2, 0x76, 0x2a, 0xab, 0x3d, 0x10, 0x1c, 0x21, 0xa3, 0xd7, 0xac, - 0xee, 0x80, 0x49, 0x58, 0x01, 0x23, 0x65, 0xd6, 0xdc, 0x15, 0x52, 0x16, 0x1d, 0x23, 0x3d, 0xa8, - 0x98, 0x4d, 0x4c, 0x38, 0x8e, 0xe0, 0x7f, 0xf6, 0x79, 0x7f, 0x17, 0x9a, 0xd1, 0xf0, 0x89, 0x39, - 0x27, 0x50, 0x64, 0x7b, 0x48, 0x14, 0x80, 0xbf, 0x8d, 0xbf, 0x9b, 0xe7, 0x88, 0x3b, 0x9e, 0x13, - 0x89, 0x3a, 0x04, 0x8a, 0xc8, 0x4a, 0x09, 0x44, 0xf6, 0xfb, 0x5a, 0xc1, 0xf1, 0xa7, 0x38, 0xe8, - 0x37, 0xa1, 0x12, 0xb0, 0x01, 0xb4, 0x27, 0x7c, 0xdc, 0x2b, 0x66, 0x99, 0x7d, 0xb7, 0x27, 0x93, - 0x68, 0x3e, 0xca, 0xd7, 0xce, 0x47, 0xe5, 0x75, 0xe6, 0xa3, 0x9a, 0x3d, 0x1f, 0xc6, 0x7b, 0xb0, - 0xac, 0x8d, 0xd2, 0x4b, 0xc6, 0xf3, 0x1c, 0xc8, 0x81, 0x13, 0x84, 0xc7, 0x2e, 0x2b, 0x42, 0xb1, - 0x34, 0xb1, 0x86, 0xe4, 0x12, 0x0d, 0x61, 0x89, 0xf6, 0xa5, 0x48, 0xcc, 0x8b, 0x44, 0xfb, 0x92, - 0x27, 0x5e, 0x2f, 0x33, 0x7e, 0x0e, 0x2b, 0xb1, 0x9a, 0x44, 0xa3, 0xde, 0x82, 0xd2, 0x3c, 0xbc, - 0xf4, 0xa4, 0xb4, 0x58, 0x13, 0x7b, 0xe9, 0x38, 0xbc, 0xf4, 0x4c, 0x9e, 0x62, 0x1c, 0xc3, 0x72, - 0x8f, 0xbe, 0x10, 0x74, 0x51, 0x36, 0xf1, 0x5d, 0x28, 0xbe, 0x42, 0x33, 0x82, 0xe9, 0x7a, 0x83, - 0xf2, 0xf1, 0x06, 0x6d, 0x01, 0xd1, 0x8b, 0x15, 0xed, 0xd1, 0x54, 0x28, 0xb9, 0x98, 0x0a, 0xc5, - 0x78, 0x17, 0xc8, 0xc0, 0x39, 0x73, 0x0f, 0x69, 0x10, 0xd8, 0x67, 0x8a, 0xc6, 0x36, 0xa1, 0x30, - 0x0d, 0xce, 0xc4, 0x81, 0xc0, 0x7e, 0x1a, 0x1f, 0xc3, 0x4a, 0x0c, 0x4f, 0x14, 0xfc, 0x06, 0x54, - 0x03, 0xe7, 0xcc, 0x45, 0x29, 0x40, 0x14, 0x1d, 0x01, 0x8c, 0x3d, 0x58, 0x7d, 0x4a, 0x7d, 0xe7, - 0xf4, 0xea, 0x55, 0xc5, 0xc7, 0xcb, 0xc9, 0x27, 0xcb, 0xe9, 0xc0, 0x5a, 0xa2, 0x1c, 0x51, 0x3d, - 0xdf, 0x7a, 0x62, 0xf6, 0x2b, 0x26, 0xff, 0xd0, 0x0e, 0x99, 0xbc, 0x7e, 0xc8, 0x18, 0x1e, 0x90, - 0x1d, 0xcf, 0x75, 0xe9, 0x28, 0x3c, 0xa2, 0xd4, 0x97, 0x8d, 0x79, 0x5f, 0xdb, 0x67, 0xb5, 0x87, - 0x1b, 0x62, 0xcc, 0x93, 0x27, 0x97, 0xd8, 0x80, 0x04, 0x8a, 0x33, 0xea, 0x4f, 0xb1, 0xe0, 0x8a, - 0x89, 0xbf, 0xd9, 0xe0, 0x86, 0xce, 0x94, 0x7a, 0xf3, 0x50, 0x50, 0x5c, 0xf9, 0x69, 0xac, 0xc1, - 0x4a, 0xac, 0x42, 0xde, 0x6a, 0xe3, 0x01, 0xac, 0xed, 0x3a, 0xc1, 0x28, 0xdd, 0x94, 0x0d, 0x28, - 0xcf, 0xe6, 0x27, 0x56, 0xfc, 0x78, 0x7c, 0x42, 0xaf, 0x8c, 0x16, 0xac, 0x27, 0x73, 0x88, 0xb2, - 0x7e, 0x2d, 0x0f, 0xc5, 0xfd, 0xe1, 0xc1, 0x0e, 0xd9, 0x84, 0x8a, 0xe3, 0x8e, 0xbc, 0x29, 0x13, - 0x0e, 0xf8, 0x68, 0xa8, 0xef, 0x6b, 0xc9, 0xc6, 0x2d, 0xa8, 0xa2, 0x4c, 0x31, 0xf1, 0x46, 0xcf, - 0x05, 0x7b, 0x5e, 0x61, 0x80, 0x03, 0x6f, 0xf4, 0x9c, 0x6d, 0x4d, 0x7a, 0x39, 0x73, 0x7c, 0x54, - 0x37, 0x49, 0x75, 0x4a, 0x91, 0xf3, 0xa3, 0x51, 0x42, 0xa4, 0x74, 0x11, 0xac, 0x13, 0x63, 0x06, - 0x38, 0x9f, 0x5e, 0x3d, 0x47, 0xd6, 0x69, 0x4c, 0x2f, 0xc9, 0x07, 0x40, 0x4e, 0x3d, 0xff, 0x85, - 0xed, 0x2b, 0xd6, 0xd2, 0x15, 0x64, 0xbb, 0x68, 0x2e, 0x47, 0x29, 0x82, 0x6d, 0x22, 0x0f, 0x61, - 0x4d, 0x43, 0xd7, 0x0a, 0xe6, 0x2c, 0xde, 0x4a, 0x94, 0xb8, 0x2f, 0xab, 0x30, 0x7e, 0x35, 0x0f, - 0x44, 0xe4, 0xdf, 0xf1, 0xdc, 0x20, 0xf4, 0x6d, 0xc7, 0x0d, 0x83, 0x38, 0xa3, 0x99, 0x4b, 0x30, - 0x9a, 0xf7, 0xa0, 0x89, 0x6c, 0xae, 0xce, 0x6d, 0xe6, 0x23, 0x9e, 0xdf, 0x8c, 0x38, 0xce, 0x77, - 0x60, 0x31, 0x12, 0x35, 0x94, 0xb6, 0xb1, 0x68, 0xd6, 0x95, 0xb8, 0xc1, 0xb0, 0x3e, 0x84, 0x55, - 0x46, 0x44, 0x24, 0x0b, 0xad, 0x54, 0x27, 0x9c, 0xd8, 0x2e, 0x4f, 0xed, 0xcb, 0x23, 0x2a, 0x05, - 0x1b, 0xe4, 0x4d, 0x0d, 0x68, 0x28, 0xae, 0x13, 0x31, 0xf9, 0xc8, 0xd5, 0x04, 0xdf, 0x89, 0x38, - 0xd9, 0x82, 0xc1, 0x42, 0xb6, 0x60, 0x60, 0xfc, 0xeb, 0x2a, 0x94, 0xe5, 0x30, 0x22, 0x97, 0x1f, - 0x3a, 0x17, 0x34, 0xe2, 0xf2, 0xd9, 0x17, 0x13, 0x1e, 0x7c, 0x3a, 0xf5, 0x42, 0x25, 0xdd, 0xf1, - 0x6d, 0x52, 0xe7, 0x40, 0x21, 0xdf, 0x69, 0x12, 0x06, 0x57, 0x92, 0x72, 0xca, 0x27, 0x25, 0x0c, - 0xce, 0x3f, 0xde, 0x82, 0xb2, 0x94, 0x13, 0x8a, 0x4a, 0x47, 0xb2, 0x30, 0xe2, 0x42, 0xc2, 0x26, - 0x54, 0x46, 0xf6, 0xcc, 0x1e, 0x39, 0x21, 0x67, 0xf1, 0x0b, 0xa6, 0xfa, 0x66, 0xa5, 0x4f, 0xbc, - 0x91, 0x3d, 0xb1, 0x4e, 0xec, 0x89, 0xed, 0x8e, 0xa8, 0xd0, 0x3e, 0xd6, 0x11, 0xb8, 0xcd, 0x61, - 0xe4, 0x5b, 0xb0, 0x28, 0xda, 0x29, 0xb1, 0xb8, 0x12, 0x52, 0xb4, 0x5e, 0xa2, 0x31, 0x49, 0xd4, - 0x9b, 0xb2, 0x79, 0x39, 0xa5, 0x5c, 0x66, 0x2b, 0x98, 0x55, 0x0e, 0xd9, 0xa3, 0xd8, 0x5b, 0x91, - 0xfc, 0x82, 0xaf, 0xe1, 0x2a, 0xaf, 0x8a, 0x03, 0xbf, 0xe2, 0xeb, 0x37, 0x2d, 0xb8, 0x15, 0x34, - 0xc1, 0xed, 0x7d, 0x58, 0x9e, 0xbb, 0x01, 0x0d, 0xc3, 0x09, 0x1d, 0xab, 0xb6, 0xd4, 0x10, 0xa9, - 0xa9, 0x12, 0x64, 0x73, 0xb6, 0x60, 0x85, 0xab, 0x4d, 0x03, 0x3b, 0xf4, 0x82, 0x73, 0x27, 0xb0, - 0x02, 0xea, 0x4a, 0xf5, 0xd9, 0x32, 0x26, 0x0d, 0x44, 0xca, 0x80, 0xab, 0x5c, 0x36, 0x12, 0xf8, - 0x3e, 0x1d, 0x51, 0xe7, 0x82, 0x8e, 0x51, 0xa8, 0x2b, 0x98, 0x6b, 0xb1, 0x3c, 0xa6, 0x48, 0x44, - 0x09, 0x7d, 0x3e, 0xb5, 0xe6, 0xb3, 0xb1, 0xcd, 0x98, 0xf7, 0x45, 0x2e, 0x25, 0xb9, 0xf3, 0xe9, - 0x31, 0x87, 0x90, 0x07, 0x20, 0xa5, 0x36, 0xb1, 0x66, 0x96, 0x62, 0x87, 0x11, 0xa3, 0x1a, 0x66, - 0x5d, 0x60, 0x70, 0xa9, 0xf2, 0x8e, 0xbe, 0x59, 0x9a, 0x6c, 0x85, 0xe1, 0xf1, 0x1f, 0x6d, 0x98, - 0x16, 0x94, 0x67, 0xbe, 0x73, 0x61, 0x87, 0xb4, 0xb5, 0xcc, 0xcf, 0x7e, 0xf1, 0xc9, 0x08, 0xb8, - 0xe3, 0x3a, 0xa1, 0x63, 0x87, 0x9e, 0xdf, 0x22, 0x98, 0x16, 0x01, 0xc8, 0x7d, 0x58, 0xc6, 0x75, - 0x12, 0x84, 0x76, 0x38, 0x0f, 0x84, 0xc8, 0xba, 0xc2, 0x45, 0x43, 0x96, 0x30, 0x40, 0x38, 0x4a, - 0xad, 0xe4, 0x33, 0x58, 0xe7, 0x4b, 0x23, 0xb5, 0x35, 0x57, 0x15, 0x43, 0xb2, 0x82, 0x18, 0x3b, - 0xf1, 0x3d, 0xfa, 0x05, 0x6c, 0x88, 0xe5, 0x92, 0xca, 0xb9, 0xa6, 0x72, 0xae, 0x72, 0x94, 0x44, - 0xd6, 0x2d, 0x58, 0x66, 0x4d, 0x73, 0x46, 0x96, 0x28, 0x81, 0xed, 0x8a, 0x75, 0xd6, 0x0b, 0xcc, - 0xb4, 0xc4, 0x13, 0x4d, 0x4c, 0x7b, 0x42, 0xaf, 0xc8, 0xf7, 0x60, 0x89, 0x2f, 0x1f, 0xd4, 0xcb, - 0xe0, 0x91, 0xbd, 0x89, 0x47, 0xf6, 0x9a, 0x18, 0xdc, 0x1d, 0x95, 0x8a, 0xa7, 0xf6, 0xe2, 0x28, - 0xf6, 0xcd, 0xb6, 0xc6, 0xc4, 0x39, 0xa5, 0xec, 0x9c, 0x68, 0x6d, 0xf0, 0xc5, 0x26, 0xbf, 0xd9, - 0xae, 0x9d, 0xcf, 0x30, 0xa5, 0xc5, 0x89, 0x35, 0xff, 0xc2, 0x75, 0x3c, 0xf1, 0x02, 0x2a, 0x15, - 0xee, 0xad, 0x9b, 0x62, 0x43, 0x32, 0xa0, 0x94, 0xaf, 0x98, 0x00, 0xcf, 0xb5, 0x25, 0xca, 0x2c, - 0x72, 0x0b, 0x17, 0x46, 0x83, 0x2b, 0x4d, 0xa4, 0x69, 0x84, 0x31, 0x8c, 0xe7, 0xf6, 0x0b, 0x49, - 0xd6, 0xdf, 0x40, 0x6a, 0x02, 0x0c, 0x24, 0x08, 0xfa, 0x1e, 0x2c, 0x8b, 0x59, 0x88, 0x88, 0x69, - 0xeb, 0x36, 0x1e, 0x91, 0x37, 0x65, 0x1f, 0x53, 0xd4, 0xd6, 0x6c, 0xf2, 0x79, 0xd1, 0xe8, 0xef, - 0x3e, 0x10, 0x39, 0x29, 0x5a, 0x41, 0x6f, 0xbe, 0xaa, 0xa0, 0x65, 0x31, 0x4d, 0x11, 0xc8, 0xf8, - 0xbd, 0x1c, 0xe7, 0xb5, 0x04, 0x76, 0xa0, 0x69, 0xaa, 0x38, 0x5d, 0xb3, 0x3c, 0x77, 0x72, 0x25, - 0x48, 0x1d, 0x70, 0x50, 0xdf, 0x9d, 0x20, 0xad, 0x71, 0x5c, 0x1d, 0x85, 0x1f, 0xde, 0x75, 0x09, - 0x44, 0xa4, 0x3b, 0x50, 0x9b, 0xcd, 0x4f, 0x26, 0xce, 0x88, 0xa3, 0x14, 0x78, 0x29, 0x1c, 0x84, - 0x08, 0x6f, 0x41, 0x5d, 0xac, 0x75, 0x8e, 0x51, 0x44, 0x8c, 0x9a, 0x80, 0x21, 0x0a, 0x32, 0x07, - 0xd4, 0x47, 0x62, 0x57, 0x37, 0xf1, 0xb7, 0xb1, 0x0d, 0xab, 0xf1, 0x46, 0x0b, 0xce, 0xe5, 0x3e, - 0x54, 0x04, 0x25, 0x95, 0x6a, 0xde, 0xc5, 0xf8, 0x68, 0x98, 0x2a, 0xdd, 0xf8, 0x37, 0x25, 0x58, - 0x91, 0x63, 0xc4, 0x26, 0x7b, 0x30, 0x9f, 0x4e, 0x6d, 0x3f, 0x83, 0x44, 0xe7, 0x5e, 0x4e, 0xa2, - 0xf3, 0x29, 0x12, 0x1d, 0x57, 0xe2, 0x71, 0x0a, 0x1f, 0x57, 0xe2, 0xb1, 0xd5, 0xc5, 0x55, 0x07, - 0xba, 0x9d, 0xa9, 0x21, 0xc0, 0x43, 0x6e, 0xcf, 0x4a, 0x1d, 0x28, 0xa5, 0x8c, 0x03, 0x45, 0x3f, - 0x0e, 0x16, 0x12, 0xc7, 0xc1, 0x5b, 0xc0, 0x97, 0xb1, 0x5c, 0x8f, 0x65, 0xae, 0x4d, 0x40, 0x98, - 0x58, 0x90, 0xef, 0xc1, 0x52, 0x92, 0x02, 0x73, 0x52, 0xbf, 0x98, 0x41, 0x7f, 0x9d, 0x29, 0x45, - 0xa6, 0x46, 0x43, 0xae, 0x0a, 0xfa, 0xeb, 0x4c, 0xe9, 0x01, 0xa6, 0x48, 0xfc, 0x0e, 0x00, 0xaf, - 0x1b, 0xb7, 0x31, 0xe0, 0x36, 0x7e, 0x37, 0xb1, 0x32, 0xb5, 0x51, 0xdf, 0x62, 0x1f, 0x73, 0x9f, - 0xe2, 0xbe, 0xae, 0x62, 0x4e, 0xdc, 0xd2, 0x9f, 0xc1, 0xa2, 0x37, 0xa3, 0xae, 0x15, 0x51, 0xc1, - 0x1a, 0x16, 0xd5, 0x14, 0x45, 0x75, 0x25, 0xdc, 0x6c, 0x30, 0x3c, 0xf5, 0x49, 0xbe, 0xe0, 0x83, - 0x4c, 0xb5, 0x9c, 0xf5, 0x6b, 0x72, 0x2e, 0x22, 0x62, 0x94, 0xf5, 0x63, 0x54, 0x94, 0x79, 0x93, - 0x39, 0x37, 0x4d, 0x35, 0x70, 0x1d, 0x49, 0x5d, 0xbd, 0xa9, 0x52, 0x4c, 0x1d, 0xcb, 0xf8, 0x8d, - 0x1c, 0xd4, 0xb4, 0x3e, 0x90, 0x35, 0x58, 0xde, 0xe9, 0xf7, 0x8f, 0x3a, 0x66, 0x7b, 0xd8, 0x7d, - 0xda, 0xb1, 0x76, 0x0e, 0xfa, 0x83, 0x4e, 0xf3, 0x06, 0x03, 0x1f, 0xf4, 0x77, 0xda, 0x07, 0xd6, - 0x5e, 0xdf, 0xdc, 0x91, 0xe0, 0x1c, 0x59, 0x07, 0x62, 0x76, 0x0e, 0xfb, 0xc3, 0x4e, 0x0c, 0x9e, - 0x27, 0x4d, 0xa8, 0x6f, 0x9b, 0x9d, 0xf6, 0xce, 0xbe, 0x80, 0x14, 0xc8, 0x2a, 0x34, 0xf7, 0x8e, - 0x7b, 0xbb, 0xdd, 0xde, 0x63, 0x6b, 0xa7, 0xdd, 0xdb, 0xe9, 0x1c, 0x74, 0x76, 0x9b, 0x45, 0xd2, - 0x80, 0x6a, 0x7b, 0xbb, 0xdd, 0xdb, 0xed, 0xf7, 0x3a, 0xbb, 0xcd, 0x92, 0xf1, 0xc7, 0x39, 0x80, - 0xa8, 0xa1, 0x8c, 0xae, 0x46, 0x4d, 0xd5, 0x8d, 0xc4, 0x6b, 0xa9, 0x4e, 0x71, 0xba, 0xea, 0xc7, - 0xbe, 0xc9, 0x43, 0x28, 0x7b, 0xf3, 0x70, 0xe4, 0x4d, 0xb9, 0x10, 0xb1, 0xf8, 0xb0, 0x95, 0xca, - 0xd7, 0xe7, 0xe9, 0xa6, 0x44, 0x8c, 0x19, 0x82, 0x0b, 0xaf, 0x32, 0x04, 0xc7, 0x2d, 0xce, 0x9c, - 0xaf, 0xd3, 0x2c, 0xce, 0xb7, 0x01, 0x82, 0x17, 0x94, 0xce, 0x50, 0xd3, 0x26, 0x76, 0x41, 0x15, - 0x21, 0x43, 0x26, 0x97, 0xfe, 0x87, 0x1c, 0xac, 0xe1, 0x5a, 0x1a, 0x27, 0x89, 0xd8, 0x5d, 0xa8, - 0x8d, 0x3c, 0x6f, 0x46, 0x19, 0x53, 0xad, 0xf8, 0x35, 0x1d, 0xc4, 0x08, 0x14, 0x27, 0xc8, 0xa7, - 0x9e, 0x3f, 0xa2, 0x82, 0x86, 0x01, 0x82, 0xf6, 0x18, 0x84, 0xed, 0x21, 0xb1, 0x09, 0x39, 0x06, - 0x27, 0x61, 0x35, 0x0e, 0xe3, 0x28, 0xeb, 0xb0, 0x70, 0xe2, 0x53, 0x7b, 0x74, 0x2e, 0xa8, 0x97, - 0xf8, 0x22, 0xdf, 0x8e, 0x34, 0x8e, 0x23, 0xb6, 0x27, 0x26, 0x94, 0x37, 0xbe, 0x62, 0x2e, 0x09, - 0xf8, 0x8e, 0x00, 0xb3, 0x73, 0xde, 0x3e, 0xb1, 0xdd, 0xb1, 0xe7, 0xd2, 0xb1, 0x90, 0xff, 0x23, - 0x80, 0x71, 0x04, 0xeb, 0xc9, 0xfe, 0x09, 0x7a, 0xf7, 0xa9, 0x46, 0xef, 0xb8, 0x50, 0xbc, 0x79, - 0xfd, 0x1e, 0xd3, 0x68, 0xdf, 0x7f, 0x2c, 0x42, 0x91, 0x09, 0x3c, 0xd7, 0xca, 0x46, 0xba, 0x6c, - 0x5b, 0x48, 0xb9, 0x07, 0xa0, 0x62, 0x93, 0x33, 0x60, 0x62, 0xb2, 0x10, 0x82, 0x8c, 0x97, 0x4a, - 0xf6, 0xe9, 0xe8, 0x42, 0xca, 0x2c, 0x08, 0x31, 0xe9, 0xe8, 0x02, 0x15, 0x1d, 0x76, 0xc8, 0xf3, - 0x72, 0x7a, 0x55, 0x0e, 0xec, 0x10, 0x73, 0x8a, 0x24, 0xcc, 0x57, 0x56, 0x49, 0x98, 0xab, 0x05, - 0x65, 0xc7, 0x3d, 0xf1, 0xe6, 0xae, 0x54, 0x2b, 0xc9, 0x4f, 0xf4, 0x46, 0x40, 0x4a, 0xca, 0x8e, - 0x76, 0x4e, 0x8d, 0x2a, 0x0c, 0x30, 0x64, 0x87, 0xfb, 0x47, 0x50, 0x0d, 0xae, 0xdc, 0x91, 0x4e, - 0x83, 0x56, 0xc5, 0xf8, 0xb0, 0xde, 0x6f, 0x0d, 0xae, 0xdc, 0x11, 0xae, 0xf8, 0x4a, 0x20, 0x7e, - 0x91, 0x47, 0x50, 0x51, 0x56, 0x3a, 0x7e, 0x82, 0xdc, 0xd4, 0x73, 0x48, 0xd3, 0x1c, 0xd7, 0xd1, - 0x29, 0x54, 0xf2, 0x21, 0x2c, 0xa0, 0xb6, 0x3e, 0x68, 0xd5, 0x31, 0x93, 0x14, 0x78, 0x59, 0x33, - 0xd0, 0x11, 0x80, 0x8e, 0xd1, 0x66, 0x66, 0x0a, 0x34, 0x36, 0x4c, 0xa7, 0x13, 0x7b, 0x26, 0x74, - 0xe7, 0x0d, 0x6e, 0x4f, 0x67, 0x10, 0xae, 0x38, 0xbf, 0x0b, 0x75, 0xb4, 0x80, 0x22, 0x8e, 0xcb, - 0xf9, 0xd0, 0x82, 0x09, 0x0c, 0xb6, 0x37, 0xb1, 0x67, 0xbd, 0x60, 0xf3, 0x09, 0x34, 0x62, 0x8d, - 0xd1, 0x55, 0x68, 0x0d, 0xae, 0x42, 0x7b, 0x47, 0x57, 0xa1, 0x45, 0x47, 0xa1, 0xc8, 0xa6, 0xab, - 0xd4, 0x8e, 0xa0, 0x22, 0xc7, 0x82, 0xd1, 0x9c, 0xe3, 0xde, 0x93, 0x5e, 0xff, 0xab, 0x9e, 0x35, - 0x78, 0xd6, 0xdb, 0x69, 0xde, 0x20, 0x4b, 0x50, 0x6b, 0xef, 0x20, 0x19, 0x43, 0x40, 0x8e, 0xa1, - 0x1c, 0xb5, 0x07, 0x03, 0x05, 0xc9, 0x33, 0x94, 0xa3, 0x6e, 0xaf, 0xd7, 0xd9, 0xe5, 0x80, 0x82, - 0xb1, 0x07, 0xcd, 0x64, 0xdf, 0xd9, 0x2a, 0x0f, 0x25, 0x4c, 0xd8, 0x25, 0x23, 0x40, 0x64, 0xfd, - 0xc8, 0x6b, 0xd6, 0x0f, 0xe3, 0x11, 0x34, 0xd9, 0x49, 0xcf, 0x06, 0x5f, 0x77, 0x57, 0x98, 0x30, - 0x5e, 0x5c, 0xb7, 0x4d, 0x56, 0xcc, 0x1a, 0x87, 0x61, 0x55, 0xc6, 0xa7, 0xb0, 0xac, 0x65, 0x8b, - 0xf4, 0x47, 0x8c, 0x7b, 0x48, 0xea, 0x8f, 0x50, 0xf2, 0xe7, 0x29, 0xc6, 0x06, 0xac, 0xb1, 0xcf, - 0xce, 0x05, 0x75, 0xc3, 0xc1, 0xfc, 0x84, 0x7b, 0xb9, 0x38, 0x9e, 0x6b, 0xfc, 0x6a, 0x0e, 0xaa, - 0x2a, 0xe5, 0xfa, 0x6d, 0xb3, 0x25, 0x54, 0x4d, 0x9c, 0x4e, 0x6e, 0x6a, 0x35, 0x60, 0xc6, 0x2d, - 0xfc, 0x1b, 0xa9, 0x9c, 0x8c, 0x2d, 0xa8, 0x2a, 0x10, 0x0e, 0x62, 0xa7, 0x63, 0x5a, 0xfd, 0xde, - 0x41, 0xb7, 0xc7, 0x4e, 0x0b, 0x36, 0xce, 0x08, 0xd8, 0xdb, 0x43, 0x48, 0xce, 0x68, 0xc2, 0xe2, - 0x63, 0x1a, 0x76, 0xdd, 0x53, 0x4f, 0x0c, 0x86, 0xf1, 0xeb, 0x0b, 0xb0, 0xa4, 0x40, 0x91, 0x62, - 0xea, 0x82, 0xfa, 0x81, 0xe3, 0xb9, 0xb8, 0x70, 0xaa, 0xa6, 0xfc, 0x64, 0xf4, 0x4e, 0x88, 0x6d, - 0xc8, 0x77, 0xac, 0x62, 0xaa, 0x10, 0xf4, 0x90, 0xe9, 0x78, 0x0f, 0x96, 0x9c, 0x31, 0x75, 0x43, - 0x27, 0xbc, 0xb2, 0x62, 0x36, 0x85, 0x45, 0x09, 0x16, 0x8c, 0xc7, 0x2a, 0x94, 0xec, 0x89, 0x63, - 0x4b, 0xef, 0x21, 0xfe, 0xc1, 0xa0, 0x23, 0x6f, 0xe2, 0xf9, 0x28, 0xc8, 0x54, 0x4d, 0xfe, 0x41, - 0x1e, 0xc0, 0x2a, 0x13, 0xaa, 0x74, 0x23, 0x18, 0x92, 0x2c, 0x6e, 0xde, 0x20, 0xee, 0x7c, 0x7a, - 0x14, 0x19, 0xc2, 0x58, 0x0a, 0x63, 0x37, 0x58, 0x0e, 0xc1, 0x5f, 0xaa, 0x0c, 0x5c, 0x51, 0xb2, - 0xec, 0xce, 0xa7, 0x6d, 0x4c, 0x51, 0xf8, 0x0f, 0x61, 0x8d, 0xe1, 0x2b, 0x8e, 0x54, 0xe5, 0x58, - 0xc2, 0x1c, 0xac, 0xb0, 0xae, 0x48, 0x53, 0x79, 0x6e, 0x41, 0x95, 0xb7, 0x8a, 0x2d, 0x09, 0x61, - 0x2d, 0xc3, 0xa6, 0x50, 0x3f, 0x48, 0x39, 0xfa, 0x70, 0xcd, 0x40, 0xd2, 0xd1, 0x47, 0x73, 0x15, - 0xaa, 0x24, 0x5d, 0x85, 0x1e, 0xc2, 0xda, 0x09, 0x5b, 0xa3, 0xe7, 0xd4, 0x1e, 0x53, 0xdf, 0x8a, - 0x56, 0x3e, 0x97, 0x3f, 0x57, 0x58, 0xe2, 0x3e, 0xa6, 0xa9, 0x8d, 0xc2, 0x58, 0x43, 0x46, 0x89, - 0xe8, 0xd8, 0x0a, 0x3d, 0x0b, 0x39, 0x46, 0xa1, 0xb6, 0x6d, 0x70, 0xf0, 0xd0, 0xdb, 0x61, 0xc0, - 0x38, 0xde, 0x99, 0x6f, 0xcf, 0xce, 0x85, 0x74, 0xa8, 0xf0, 0x1e, 0x33, 0x20, 0x79, 0x03, 0xca, - 0x6c, 0x4f, 0xb8, 0x94, 0x7b, 0x47, 0x70, 0xb9, 0x4b, 0x82, 0xc8, 0x3b, 0xb0, 0x80, 0x75, 0x04, - 0xad, 0x26, 0x6e, 0x88, 0x7a, 0x74, 0x76, 0x38, 0xae, 0x29, 0xd2, 0x18, 0xff, 0x3d, 0xf7, 0x1d, - 0x4e, 0xd8, 0xaa, 0x26, 0xfe, 0x26, 0xdf, 0xd7, 0xa8, 0xe4, 0x0a, 0xe6, 0x7d, 0x47, 0xe4, 0x4d, - 0x2c, 0xc5, 0xeb, 0x08, 0xe6, 0x37, 0x4a, 0xbe, 0x7e, 0x50, 0xac, 0xd4, 0x9a, 0x75, 0xa3, 0x85, - 0xfe, 0x4d, 0x26, 0x1d, 0x79, 0x17, 0xd4, 0xbf, 0x8a, 0xed, 0x91, 0x1c, 0x6c, 0xa4, 0x92, 0x22, - 0x4f, 0x07, 0x5f, 0xc0, 0xad, 0xa9, 0x37, 0x96, 0x5c, 0x42, 0x5d, 0x02, 0x0f, 0xbd, 0x31, 0xe3, - 0x66, 0x96, 0x15, 0xd2, 0xa9, 0xe3, 0x3a, 0xc1, 0x39, 0x1d, 0x0b, 0x66, 0xa1, 0x29, 0x13, 0xf6, - 0x04, 0x9c, 0xb1, 0xe4, 0x33, 0xdf, 0x3b, 0x53, 0x67, 0x67, 0xce, 0x54, 0xdf, 0xc6, 0x67, 0x50, - 0xe2, 0x33, 0xc8, 0x36, 0x0a, 0xce, 0x6f, 0x4e, 0x6c, 0x14, 0x84, 0xb6, 0xa0, 0xec, 0xd2, 0xf0, - 0x85, 0xe7, 0x3f, 0x97, 0x1a, 0x68, 0xf1, 0x69, 0xfc, 0x18, 0xb5, 0xac, 0xca, 0x51, 0x8d, 0x6b, - 0x23, 0xd8, 0x12, 0xe6, 0x4b, 0x30, 0x38, 0xb7, 0x85, 0xe2, 0xb7, 0x82, 0x80, 0xc1, 0xb9, 0x9d, - 0x5a, 0xc2, 0xf9, 0xb4, 0xaf, 0xda, 0x3b, 0xb0, 0x28, 0x5d, 0xe3, 0x02, 0x6b, 0x42, 0x4f, 0x43, - 0xb1, 0x25, 0xeb, 0xc2, 0x2f, 0x2e, 0x38, 0xa0, 0xa7, 0xa1, 0x71, 0x08, 0xcb, 0x62, 0xd3, 0xf4, - 0x67, 0x54, 0x56, 0xfd, 0x79, 0x96, 0x98, 0x54, 0x7b, 0xb8, 0x12, 0xe7, 0x3f, 0x38, 0xa7, 0x17, - 0x93, 0x9d, 0x8c, 0x1f, 0x46, 0x2a, 0x45, 0xc6, 0x9d, 0x88, 0xf2, 0x84, 0xb0, 0x22, 0x0d, 0xaa, - 0xd2, 0x69, 0x43, 0x89, 0x44, 0xce, 0x98, 0x8d, 0x4e, 0x30, 0x1f, 0x8d, 0xa4, 0xcb, 0x62, 0xc5, - 0x94, 0x9f, 0xc6, 0xff, 0xcc, 0xc1, 0x0a, 0x16, 0x26, 0xc5, 0x3c, 0x71, 0x52, 0xfc, 0xc4, 0x8d, - 0x64, 0xf3, 0xa3, 0xb3, 0x84, 0xfc, 0xe3, 0xd5, 0x16, 0xa1, 0xa4, 0xb5, 0xa7, 0x98, 0x69, 0xed, - 0xf9, 0x36, 0x34, 0xc7, 0x74, 0xe2, 0xe0, 0x72, 0x92, 0x5c, 0x16, 0x67, 0x6b, 0x97, 0x24, 0x5c, - 0xaa, 0x1e, 0x52, 0x26, 0xa6, 0x85, 0xb4, 0xf9, 0xf1, 0xaf, 0xe6, 0x60, 0x99, 0x33, 0x7a, 0xa8, - 0xf0, 0x11, 0x03, 0xfa, 0xa5, 0xd4, 0x6c, 0x08, 0xb2, 0x2b, 0xfa, 0x1e, 0x31, 0x40, 0x08, 0xe5, - 0xc8, 0xfb, 0x37, 0x84, 0xc6, 0x43, 0x40, 0xc9, 0x77, 0x51, 0x84, 0x75, 0x2d, 0x04, 0x0a, 0x06, - 0xfe, 0x66, 0x06, 0x6b, 0xa9, 0xb2, 0x33, 0xf9, 0xd6, 0x45, 0xd0, 0x76, 0x05, 0x16, 0xb8, 0xfa, - 0xcc, 0xd8, 0x83, 0x46, 0xac, 0x9a, 0x98, 0x59, 0xa9, 0xce, 0xcd, 0x4a, 0x29, 0x9b, 0x77, 0x3e, - 0x6d, 0xf3, 0xbe, 0x82, 0x15, 0x93, 0xda, 0xe3, 0xab, 0x3d, 0xcf, 0x3f, 0x0a, 0x4e, 0xc2, 0x3d, - 0xce, 0x3d, 0xb3, 0xb3, 0x4a, 0x79, 0xb9, 0xc4, 0xec, 0x30, 0xd2, 0x9e, 0x2f, 0x07, 0xf1, 0x5b, - 0xb0, 0x18, 0xb9, 0xc3, 0x68, 0x1a, 0xfb, 0x86, 0xf2, 0x88, 0x41, 0xa6, 0x8b, 0x40, 0x71, 0x16, - 0x9c, 0x84, 0x42, 0x67, 0x8f, 0xbf, 0x8d, 0x7f, 0x54, 0x02, 0xc2, 0x56, 0x7d, 0x62, 0x61, 0xa5, - 0xa6, 0x25, 0x97, 0xb6, 0xfc, 0x25, 0x9c, 0x7d, 0xf2, 0x29, 0x67, 0x9f, 0x07, 0x40, 0x34, 0x04, - 0xe9, 0x83, 0x54, 0x50, 0x3e, 0x48, 0xcd, 0x08, 0x57, 0xb8, 0x20, 0x3d, 0x80, 0x55, 0x21, 0xae, - 0xc4, 0xbb, 0x83, 0xcb, 0xcc, 0x24, 0x5c, 0x6e, 0x89, 0xf5, 0x49, 0x3a, 0xfa, 0x48, 0x35, 0x78, - 0x81, 0x3b, 0xfa, 0x48, 0x6d, 0x95, 0xb6, 0x98, 0x17, 0x5e, 0xb9, 0x98, 0xcb, 0x99, 0x8b, 0x59, - 0xd3, 0x5e, 0x56, 0xe2, 0xda, 0xcb, 0x94, 0x1e, 0x9e, 0xf3, 0xe7, 0x31, 0x3d, 0xfc, 0x3d, 0x68, - 0x4a, 0x4d, 0x96, 0xd2, 0x91, 0x0a, 0x0f, 0x10, 0xa1, 0xac, 0x92, 0x5a, 0xd2, 0x98, 0xa1, 0xb1, - 0xf6, 0x3a, 0x16, 0xcf, 0x7a, 0xb6, 0xc5, 0x33, 0xad, 0xf3, 0x6b, 0x64, 0xe8, 0xfc, 0x1e, 0x45, - 0x0e, 0x1e, 0xc1, 0xb9, 0x33, 0x45, 0x46, 0x2a, 0xf2, 0x50, 0x15, 0x83, 0x3c, 0x38, 0x77, 0xa6, - 0xa6, 0x74, 0xb5, 0x62, 0x1f, 0x64, 0x07, 0xee, 0x88, 0xfe, 0x64, 0x78, 0x49, 0xf1, 0x51, 0x58, - 0xc2, 0xa5, 0xb2, 0xc9, 0xd1, 0x0e, 0x13, 0x0e, 0x53, 0x89, 0x41, 0x91, 0x3e, 0x36, 0x01, 0x57, - 0x1c, 0xcb, 0x41, 0x39, 0xe4, 0x4e, 0x36, 0x48, 0x1e, 0x18, 0x8a, 0x50, 0x2a, 0x06, 0x17, 0xc8, - 0x77, 0x35, 0xcc, 0xda, 0xd4, 0xbe, 0x3c, 0x40, 0xa5, 0x61, 0x70, 0x61, 0xfc, 0x69, 0x0e, 0x9a, - 0x6c, 0x09, 0xc7, 0xa8, 0xc3, 0x17, 0x80, 0xf4, 0xee, 0x35, 0x89, 0x43, 0x8d, 0xe1, 0x4a, 0xda, - 0xf0, 0x19, 0xe0, 0x66, 0xb7, 0xbc, 0x19, 0x75, 0x05, 0x69, 0x68, 0xc5, 0x49, 0x43, 0x74, 0x4c, - 0xec, 0xdf, 0xe0, 0x52, 0x27, 0x83, 0x90, 0x2f, 0xa0, 0xca, 0xf6, 0x14, 0x2e, 0x5e, 0xe1, 0x1d, - 0xbe, 0xa9, 0x34, 0x09, 0xa9, 0xed, 0xcd, 0xb2, 0xce, 0xc4, 0x67, 0x96, 0x0b, 0x55, 0x31, 0xc3, - 0x85, 0x4a, 0xa3, 0x3d, 0xfb, 0x00, 0x4f, 0xe8, 0x15, 0x1b, 0x84, 0xd0, 0xf3, 0x19, 0xaf, 0xc6, - 0xb6, 0xd8, 0xa9, 0x3d, 0x75, 0x84, 0x36, 0xb3, 0x64, 0x56, 0x9f, 0xd3, 0xab, 0x3d, 0x04, 0xb0, - 0xb5, 0xc5, 0x92, 0x23, 0x02, 0x54, 0x32, 0x2b, 0xcf, 0xe9, 0x15, 0xa7, 0x3e, 0x16, 0x34, 0x9e, - 0xd0, 0xab, 0x5d, 0xca, 0x85, 0x01, 0xcf, 0x67, 0x83, 0xee, 0xdb, 0x2f, 0x18, 0xf7, 0x1f, 0x73, - 0xf1, 0xa9, 0xf9, 0xf6, 0x8b, 0x27, 0xf4, 0x4a, 0xba, 0x1b, 0x95, 0x59, 0xfa, 0xc4, 0x1b, 0x09, - 0xf6, 0x45, 0x2a, 0x90, 0xa2, 0x46, 0x99, 0x0b, 0xcf, 0xf1, 0xb7, 0xf1, 0x27, 0x39, 0x68, 0xb0, - 0xf6, 0xe3, 0xc9, 0x83, 0xab, 0x48, 0xf8, 0x0c, 0xe7, 0x22, 0x9f, 0xe1, 0x87, 0x82, 0x20, 0xf3, - 0x63, 0x2c, 0x7f, 0xfd, 0x31, 0x86, 0x73, 0xc3, 0xcf, 0xb0, 0x8f, 0xa0, 0xca, 0x17, 0x06, 0x23, - 0x3f, 0x85, 0xd8, 0x04, 0xc7, 0x3a, 0x64, 0x56, 0x10, 0xed, 0x09, 0xf7, 0x3f, 0xd4, 0x74, 0xf5, - 0x7c, 0x88, 0xab, 0xbe, 0xd2, 0xd0, 0x67, 0x4c, 0x43, 0xe9, 0x1a, 0xff, 0x43, 0x5d, 0x11, 0xbe, - 0x90, 0x54, 0x84, 0x1b, 0x2e, 0x54, 0xd8, 0x54, 0x63, 0x67, 0x33, 0x0a, 0xcd, 0x65, 0x15, 0xca, - 0x98, 0x1d, 0x9b, 0x9d, 0x67, 0x8c, 0x46, 0xe7, 0x05, 0xb3, 0x63, 0x07, 0x94, 0x15, 0xc4, 0x1a, - 0xee, 0x7a, 0x16, 0x6a, 0x96, 0x85, 0xce, 0xb5, 0x62, 0x56, 0x5d, 0xef, 0x88, 0x03, 0x8c, 0xbf, - 0x90, 0x83, 0x9a, 0xb6, 0x67, 0xd1, 0xd4, 0xa0, 0x86, 0x93, 0x6f, 0xf0, 0xf8, 0x0e, 0x88, 0xcd, - 0xc7, 0xfe, 0x0d, 0xb3, 0x31, 0x8a, 0x4d, 0xd0, 0x96, 0x58, 0xca, 0x98, 0x33, 0x1f, 0xd3, 0x6f, - 0xc9, 0x7e, 0xc9, 0xf5, 0xcb, 0x7e, 0x6f, 0x2f, 0x40, 0x91, 0xa1, 0x1a, 0x5f, 0xc2, 0xb2, 0xd6, - 0x0c, 0xae, 0xff, 0x79, 0xdd, 0x01, 0x30, 0x7e, 0x41, 0x65, 0x66, 0x75, 0x70, 0xdb, 0xbd, 0x74, - 0xf5, 0xa4, 0x63, 0x3e, 0x2e, 0xc2, 0xa5, 0x94, 0x83, 0x70, 0x64, 0x5e, 0xd3, 0xfb, 0xd0, 0xf8, - 0x95, 0x1c, 0xac, 0x68, 0xc5, 0xef, 0x39, 0xae, 0x3d, 0x71, 0x7e, 0x8c, 0xc7, 0x58, 0xe0, 0x9c, - 0xb9, 0x89, 0x0a, 0x38, 0xe8, 0xeb, 0x54, 0x40, 0xee, 0x42, 0x9d, 0xfb, 0x96, 0xf3, 0x9b, 0x0b, - 0xe2, 0x98, 0x05, 0x84, 0x99, 0xf6, 0x8b, 0xe1, 0xa5, 0xf1, 0xd7, 0xf2, 0xb0, 0x2a, 0x9a, 0x80, - 0x57, 0x00, 0x1c, 0xc6, 0xea, 0x1e, 0x06, 0x67, 0xe4, 0x0b, 0x68, 0xb0, 0xe1, 0xb3, 0x7c, 0x7a, - 0xe6, 0x04, 0x21, 0x95, 0x6e, 0x05, 0x19, 0xd4, 0x98, 0x71, 0x32, 0x0c, 0xd5, 0x14, 0x98, 0xe4, - 0x4b, 0xa8, 0x61, 0x56, 0xae, 0x82, 0x13, 0x73, 0xd5, 0x4a, 0x67, 0xe4, 0x73, 0xb1, 0x7f, 0xc3, - 0x84, 0x20, 0x9a, 0x99, 0x2f, 0xa1, 0x86, 0xd3, 0x7c, 0x81, 0x63, 0x9d, 0x20, 0x76, 0xa9, 0xb9, - 0x60, 0x99, 0x67, 0xd1, 0xcc, 0xb4, 0xa1, 0xc1, 0xc9, 0x9d, 0x18, 0x49, 0xe1, 0x37, 0xbc, 0x99, - 0xce, 0x2e, 0xc7, 0x9a, 0x35, 0x7e, 0xa6, 0x7d, 0x6f, 0x57, 0xa1, 0x1c, 0xfa, 0xce, 0xd9, 0x19, - 0xf5, 0x8d, 0x75, 0x35, 0x34, 0x8c, 0x8e, 0xd3, 0x41, 0x48, 0x67, 0x4c, 0x86, 0x31, 0xfe, 0x59, - 0x0e, 0x6a, 0x82, 0x32, 0xff, 0xc4, 0x1e, 0x0b, 0x9b, 0x09, 0x65, 0x6d, 0x55, 0xd3, 0xcd, 0xbe, - 0x07, 0x4b, 0x53, 0x26, 0x70, 0x39, 0xe1, 0x55, 0xdc, 0x5d, 0x61, 0x51, 0x82, 0x85, 0x2c, 0xb1, - 0x05, 0x2b, 0x28, 0x5a, 0x04, 0x56, 0xe8, 0x4c, 0x2c, 0x99, 0x28, 0x6e, 0xc8, 0x2c, 0xf3, 0xa4, - 0xa1, 0x33, 0x39, 0x14, 0x09, 0x8c, 0xc3, 0x0e, 0x42, 0xfb, 0x8c, 0x0a, 0xea, 0xc0, 0x3f, 0x98, - 0x10, 0x97, 0xd0, 0x05, 0x48, 0x21, 0xee, 0x7f, 0x2f, 0xc3, 0x46, 0x2a, 0x49, 0x08, 0x71, 0xca, - 0x3a, 0x3c, 0x71, 0xa6, 0x27, 0x9e, 0xb2, 0x4e, 0xe4, 0x34, 0xeb, 0xf0, 0x01, 0x4b, 0x91, 0xd6, - 0x09, 0x0a, 0x6b, 0x72, 0xc9, 0xa2, 0x79, 0x41, 0xa9, 0x0b, 0xf2, 0x28, 0xcc, 0x7e, 0x14, 0x3f, - 0x06, 0x93, 0xd5, 0x49, 0xb8, 0xce, 0x17, 0xae, 0xcc, 0x52, 0xb0, 0x80, 0xfc, 0xff, 0xd0, 0x52, - 0x3b, 0x43, 0xc8, 0x36, 0x9a, 0xee, 0x83, 0xd5, 0xf4, 0x9d, 0x57, 0xd4, 0x14, 0xd3, 0xfb, 0x22, - 0xeb, 0xb5, 0x2e, 0x37, 0x15, 0x2f, 0x50, 0xd5, 0x75, 0x01, 0x6f, 0xca, 0xba, 0x50, 0x56, 0x49, - 0xd7, 0x58, 0x7c, 0xad, 0xbe, 0xa1, 0x4e, 0x3b, 0x56, 0xad, 0x79, 0x4b, 0x14, 0xac, 0x92, 0xf4, - 0x7a, 0xcf, 0x61, 0xfd, 0x85, 0xed, 0x84, 0xb2, 0x8f, 0x9a, 0xea, 0xa5, 0x84, 0xf5, 0x3d, 0x7c, - 0x45, 0x7d, 0x5f, 0xf1, 0xcc, 0x31, 0xe9, 0x6d, 0xf5, 0x45, 0x1a, 0x18, 0x6c, 0xfe, 0xed, 0x02, - 0x2c, 0xc6, 0x4b, 0x61, 0xa4, 0x47, 0x1c, 0x57, 0x92, 0x91, 0x16, 0x12, 0x80, 0xb0, 0x9c, 0xf5, - 0x38, 0x03, 0x9d, 0xb6, 0xe9, 0xe5, 0x33, 0x6c, 0x7a, 0xba, 0x29, 0xad, 0xf0, 0x2a, 0xcf, 0x8a, - 0xe2, 0x6b, 0x79, 0x56, 0x94, 0xb2, 0x3c, 0x2b, 0x3e, 0xbe, 0xd6, 0x14, 0xcf, 0x15, 0xe2, 0x99, - 0x66, 0xf8, 0x47, 0xd7, 0x9b, 0xe1, 0xb9, 0xae, 0xfc, 0x3a, 0x13, 0xbc, 0xe6, 0x40, 0x50, 0xb9, - 0xc6, 0x00, 0xa6, 0xb9, 0x14, 0x64, 0x98, 0xe0, 0xab, 0x5f, 0xc3, 0x04, 0xbf, 0xf9, 0x27, 0x39, - 0x20, 0xe9, 0xdd, 0x41, 0x1e, 0x73, 0x73, 0xa9, 0x4b, 0x27, 0x82, 0x72, 0x7f, 0xf0, 0x7a, 0x3b, - 0x4c, 0x2e, 0x08, 0x99, 0x9b, 0x7c, 0x08, 0x2b, 0xfa, 0x3d, 0x3e, 0x5d, 0xb5, 0xd1, 0x30, 0x89, - 0x9e, 0x14, 0x29, 0xe9, 0x34, 0x37, 0x96, 0xe2, 0x2b, 0xdd, 0x58, 0x4a, 0xaf, 0x74, 0x63, 0x59, - 0x88, 0xbb, 0xb1, 0x6c, 0xfe, 0xcb, 0x1c, 0xac, 0x64, 0x2c, 0xe2, 0x6f, 0xae, 0xcf, 0x6c, 0xed, - 0xc5, 0xc8, 0x5a, 0x5e, 0xac, 0x3d, 0x9d, 0xa2, 0x1d, 0x48, 0xc5, 0x2e, 0x9b, 0x8a, 0x40, 0x9c, - 0x54, 0xf7, 0x5f, 0x45, 0x5d, 0xa2, 0x1c, 0xa6, 0x9e, 0x7d, 0xf3, 0xef, 0xe4, 0xa1, 0xa6, 0x25, - 0xb2, 0x51, 0xe4, 0x4b, 0x56, 0x73, 0x0a, 0xe5, 0xbc, 0x25, 0x2a, 0x66, 0xf0, 0x6a, 0x01, 0x2e, - 0x4e, 0x4c, 0xe7, 0x9b, 0x4b, 0x30, 0x92, 0x88, 0xb0, 0x05, 0x2b, 0xd2, 0x94, 0x4d, 0x23, 0xa7, - 0x79, 0x71, 0xd6, 0x08, 0xaf, 0x04, 0xd1, 0x48, 0xc4, 0xff, 0x50, 0xca, 0xb9, 0xd1, 0xdc, 0x69, - 0xa6, 0xc1, 0x65, 0xe1, 0x0f, 0x21, 0x26, 0x91, 0xad, 0xf3, 0x8f, 0x60, 0x4d, 0x39, 0x44, 0xc4, - 0x72, 0x70, 0x03, 0x14, 0x91, 0x8e, 0x0f, 0x5a, 0x96, 0xef, 0xc3, 0xed, 0x44, 0x9b, 0x12, 0x59, - 0xb9, 0xa6, 0xe5, 0x66, 0xac, 0x75, 0x7a, 0x09, 0x9b, 0x7f, 0x0e, 0x1a, 0x31, 0x42, 0xf9, 0xcd, - 0x4d, 0x79, 0x52, 0x19, 0xc6, 0x47, 0x54, 0x57, 0x86, 0x6d, 0xfe, 0xf7, 0x02, 0x90, 0x34, 0xad, - 0xfe, 0x69, 0x36, 0x21, 0xbd, 0x30, 0x0b, 0x19, 0x0b, 0xf3, 0xff, 0x19, 0xff, 0x10, 0xe9, 0x64, - 0x35, 0x7f, 0x04, 0xbe, 0x39, 0x9b, 0x2a, 0x41, 0xb6, 0xe2, 0xb3, 0xa4, 0xd7, 0x56, 0x25, 0x76, - 0xe1, 0x54, 0x63, 0xa0, 0x12, 0xce, 0x5b, 0xc7, 0xb0, 0x60, 0xbb, 0xa3, 0x73, 0xcf, 0x17, 0x74, - 0xf0, 0x67, 0xbe, 0xf6, 0xf1, 0xb9, 0xd5, 0xc6, 0xfc, 0xc8, 0xb5, 0x99, 0xa2, 0x30, 0xe3, 0x23, - 0xa8, 0x69, 0x60, 0x52, 0x85, 0xd2, 0x41, 0xf7, 0x70, 0xbb, 0xdf, 0xbc, 0x41, 0x1a, 0x50, 0x35, - 0x3b, 0x3b, 0xfd, 0xa7, 0x1d, 0xb3, 0xb3, 0xdb, 0xcc, 0x91, 0x0a, 0x14, 0x0f, 0xfa, 0x83, 0x61, - 0x33, 0x6f, 0x6c, 0x42, 0x4b, 0x94, 0x98, 0xb6, 0x4e, 0xfd, 0x56, 0x51, 0xe9, 0x54, 0x31, 0x51, - 0x08, 0xf9, 0x1f, 0x43, 0x5d, 0x67, 0x6f, 0xc4, 0x8a, 0x48, 0xb8, 0xc4, 0x30, 0xf1, 0xde, 0xd3, - 0x68, 0xf5, 0x0e, 0x70, 0x87, 0x88, 0xb1, 0xca, 0x96, 0x8f, 0xf1, 0xad, 0x19, 0x96, 0x65, 0x94, - 0x8f, 0x62, 0xcb, 0xf0, 0xff, 0x83, 0xc5, 0xb8, 0x25, 0x46, 0x50, 0xa4, 0x2c, 0x91, 0x95, 0xe5, - 0x8e, 0x99, 0x66, 0xc8, 0xf7, 0xa1, 0x99, 0xb4, 0xe4, 0x08, 0xe6, 0xf9, 0x9a, 0xfc, 0x4b, 0x4e, - 0xdc, 0xb8, 0x43, 0xf6, 0x61, 0x35, 0x8b, 0xc1, 0xc3, 0xf5, 0x71, 0xbd, 0x9a, 0x83, 0xa4, 0x99, - 0x38, 0xf2, 0xb9, 0xb0, 0xe8, 0x95, 0x70, 0xfa, 0xdf, 0x89, 0xd7, 0xaf, 0x0d, 0xf6, 0x16, 0xff, - 0xa7, 0xd9, 0xf6, 0x2e, 0x00, 0x22, 0x18, 0x69, 0x42, 0xbd, 0x7f, 0xd4, 0xe9, 0x59, 0x3b, 0xfb, - 0xed, 0x5e, 0xaf, 0x73, 0xd0, 0xbc, 0x41, 0x08, 0x2c, 0xa2, 0x57, 0xc7, 0xae, 0x82, 0xe5, 0x18, - 0x4c, 0x98, 0x5a, 0x25, 0x2c, 0x4f, 0x56, 0xa1, 0xd9, 0xed, 0x25, 0xa0, 0x05, 0xd2, 0x82, 0xd5, - 0xa3, 0x0e, 0x77, 0x04, 0x89, 0x95, 0x5b, 0x64, 0x42, 0x83, 0xe8, 0xae, 0x11, 0xc2, 0xea, 0x57, - 0xf6, 0x64, 0x42, 0xc3, 0x36, 0x77, 0x64, 0x97, 0xdb, 0xe1, 0x7d, 0x58, 0x56, 0xea, 0xb0, 0x04, - 0xb7, 0xdc, 0x54, 0x09, 0x12, 0xf9, 0x43, 0x58, 0xd1, 0xb4, 0x6a, 0x89, 0x53, 0x88, 0x68, 0x49, - 0x22, 0x03, 0x13, 0x55, 0x78, 0xad, 0x02, 0x20, 0x39, 0xf8, 0x3f, 0xcc, 0xc3, 0x5a, 0x22, 0x21, - 0x32, 0xc2, 0x70, 0xfe, 0x3d, 0xde, 0x96, 0x3a, 0x02, 0x5f, 0xda, 0xe8, 0xfc, 0xd7, 0x6b, 0x74, - 0xe1, 0xba, 0x46, 0x93, 0x67, 0xb0, 0x24, 0xbc, 0xfd, 0x35, 0x1e, 0x8f, 0xd1, 0x88, 0x07, 0x62, - 0xca, 0x33, 0x5b, 0xbe, 0x15, 0x1f, 0x58, 0x6e, 0xe5, 0x5a, 0xb4, 0x63, 0xc0, 0xcd, 0x5f, 0x82, - 0x95, 0x0c, 0xb4, 0x8c, 0x3b, 0x2f, 0x1f, 0xc5, 0x2d, 0x5e, 0xb7, 0x62, 0x35, 0xc7, 0x8b, 0xd0, - 0xad, 0xf7, 0x5b, 0xb0, 0x20, 0xb4, 0xbd, 0x4d, 0x28, 0xc8, 0x6b, 0x4f, 0x45, 0x93, 0xfd, 0x24, - 0x04, 0x8a, 0xd3, 0xc8, 0x01, 0x1b, 0x7f, 0x1b, 0x1b, 0xea, 0x02, 0x63, 0x62, 0x82, 0x7e, 0xa5, - 0x08, 0xeb, 0xc9, 0x14, 0x75, 0x25, 0xa1, 0x1c, 0x9b, 0x1b, 0x6e, 0x49, 0x14, 0x20, 0xf2, 0x49, - 0x62, 0xbb, 0xc5, 0x66, 0x07, 0x51, 0xf5, 0xad, 0x25, 0x87, 0xfc, 0x61, 0x92, 0xa9, 0xe6, 0x34, - 0xa2, 0x21, 0x2f, 0x68, 0x60, 0x9f, 0x12, 0x3c, 0xf6, 0x27, 0x29, 0x1e, 0xbb, 0x98, 0x95, 0x29, - 0xc1, 0x72, 0x77, 0x60, 0x23, 0x72, 0x35, 0x8e, 0xd7, 0x59, 0xca, 0xca, 0xbe, 0xa6, 0xb0, 0x0f, - 0xf4, 0xca, 0x1f, 0x43, 0x2b, 0x2a, 0x26, 0xd1, 0x8c, 0x85, 0xac, 0x72, 0xd6, 0x15, 0xba, 0x19, - 0x6b, 0xcf, 0x0f, 0x60, 0x33, 0x36, 0x5e, 0xf1, 0x26, 0x95, 0xb3, 0x8a, 0xda, 0xd0, 0x06, 0x30, - 0xd6, 0xa8, 0x03, 0xb8, 0x15, 0x2b, 0x2b, 0xd1, 0xae, 0x4a, 0x56, 0x61, 0x2d, 0xad, 0xb0, 0x58, - 0xcb, 0x8c, 0xdf, 0x59, 0x00, 0xf2, 0xc3, 0x39, 0xf5, 0xaf, 0xf0, 0x5a, 0x73, 0xf0, 0xaa, 0x3b, - 0x14, 0x52, 0x53, 0x99, 0x7f, 0xad, 0xe8, 0x06, 0x59, 0xd1, 0x05, 0x8a, 0xaf, 0x8e, 0x2e, 0x50, - 0x7a, 0x55, 0x74, 0x81, 0xb7, 0xa1, 0xe1, 0x9c, 0xb9, 0x1e, 0x63, 0x04, 0x98, 0x1c, 0x18, 0xb4, - 0x16, 0xee, 0x16, 0xee, 0xd5, 0xcd, 0xba, 0x00, 0x32, 0x29, 0x30, 0x20, 0x5f, 0x46, 0x48, 0x74, - 0x7c, 0x86, 0xb1, 0x37, 0x74, 0x16, 0xa0, 0x33, 0x3e, 0xa3, 0x42, 0x31, 0x8b, 0x0b, 0x56, 0x66, - 0x66, 0xf0, 0x80, 0xbc, 0x03, 0x8b, 0x81, 0x37, 0x67, 0x62, 0xb5, 0x1c, 0x06, 0x6e, 0xef, 0xaf, - 0x73, 0xe8, 0x91, 0xf4, 0xfe, 0x58, 0x99, 0x07, 0xd4, 0x9a, 0x3a, 0x41, 0xc0, 0x84, 0x93, 0x91, - 0xe7, 0x86, 0xbe, 0x37, 0x11, 0x26, 0xfc, 0xe5, 0x79, 0x40, 0x0f, 0x79, 0xca, 0x0e, 0x4f, 0x20, - 0x9f, 0x44, 0x4d, 0x9a, 0xd9, 0x8e, 0x1f, 0xb4, 0x00, 0x9b, 0x24, 0x7b, 0x8a, 0xd2, 0xab, 0xed, - 0xf8, 0xaa, 0x2d, 0xec, 0x23, 0x48, 0x44, 0x3d, 0xa8, 0x25, 0xa3, 0x1e, 0xfc, 0x72, 0x76, 0xd4, - 0x83, 0x46, 0x8c, 0x98, 0xa5, 0xa7, 0xf8, 0x6b, 0x05, 0x3f, 0x48, 0x07, 0x73, 0x58, 0xfc, 0x3a, - 0xc1, 0x1c, 0x96, 0xb2, 0x82, 0x39, 0x7c, 0x04, 0x35, 0xbc, 0x43, 0x6f, 0x9d, 0xa3, 0x33, 0x33, - 0x77, 0x49, 0x68, 0xea, 0x97, 0xec, 0xf7, 0x1d, 0x37, 0x34, 0xc1, 0x97, 0x3f, 0x83, 0x74, 0x5c, - 0x85, 0xe5, 0xd7, 0x8a, 0xab, 0xf0, 0xcd, 0x04, 0x4d, 0x10, 0x77, 0xfd, 0xb7, 0xa0, 0x22, 0xe7, - 0x89, 0x11, 0xdb, 0x53, 0xdf, 0x9b, 0x4a, 0xf3, 0x26, 0xfb, 0x4d, 0x16, 0x21, 0x1f, 0x7a, 0x22, - 0x73, 0x3e, 0xf4, 0x8c, 0x5f, 0x84, 0x9a, 0xb6, 0xd4, 0xc8, 0x5b, 0x5c, 0xaf, 0xef, 0xd2, 0x89, - 0x54, 0xfb, 0xf2, 0x51, 0xac, 0x0a, 0x68, 0x77, 0xcc, 0xce, 0xbd, 0xb1, 0xe3, 0x53, 0x8c, 0x80, - 0x62, 0xf9, 0xf4, 0x82, 0xfa, 0x81, 0x34, 0x4b, 0x37, 0x55, 0x82, 0xc9, 0xe1, 0xc6, 0x2f, 0xc1, - 0x4a, 0x6c, 0x6e, 0x05, 0xf9, 0x7e, 0x07, 0x16, 0x70, 0xdc, 0xa4, 0xef, 0x53, 0x3c, 0x78, 0x81, - 0x48, 0xc3, 0x38, 0x30, 0xdc, 0xa2, 0x6e, 0xcd, 0x7c, 0xef, 0x04, 0x2b, 0xc9, 0x99, 0x35, 0x01, - 0x3b, 0xf2, 0xbd, 0x13, 0xe3, 0xdf, 0x17, 0xa0, 0xb0, 0xef, 0xcd, 0x74, 0x07, 0xe8, 0x5c, 0xca, - 0x01, 0x5a, 0xa8, 0x5b, 0x2c, 0xa5, 0x4e, 0x11, 0x12, 0x2b, 0xda, 0x88, 0xa5, 0x4a, 0xe5, 0x1e, - 0x2c, 0x32, 0x3a, 0x11, 0x7a, 0x96, 0xb8, 0x78, 0xc4, 0x0f, 0x67, 0xbe, 0xf9, 0xec, 0x69, 0x38, - 0xf4, 0xf6, 0x38, 0x9c, 0xac, 0x42, 0x41, 0x09, 0xef, 0x98, 0xcc, 0x3e, 0xc9, 0x3a, 0x2c, 0xe0, - 0x85, 0x29, 0x79, 0xd3, 0x5d, 0x7c, 0x91, 0x0f, 0x60, 0x25, 0x5e, 0x2e, 0x27, 0x45, 0x42, 0x32, - 0xd0, 0x0b, 0x46, 0x9a, 0x74, 0x13, 0x18, 0x1d, 0x89, 0xee, 0xba, 0x17, 0xcc, 0xf2, 0x29, 0xa5, - 0x98, 0xa4, 0x11, 0xbd, 0x4a, 0x8c, 0xe8, 0xdd, 0x81, 0x5a, 0x38, 0xb9, 0xb0, 0x66, 0xf6, 0xd5, - 0xc4, 0xb3, 0xe5, 0xcd, 0x4a, 0x08, 0x27, 0x17, 0x47, 0x1c, 0x42, 0x3e, 0x04, 0x98, 0xce, 0x66, - 0x62, 0xef, 0xa1, 0x3d, 0x33, 0x5a, 0xca, 0x87, 0x47, 0x47, 0x7c, 0xc9, 0x99, 0xd5, 0xe9, 0x6c, - 0xc6, 0x7f, 0x92, 0x5d, 0x58, 0xcc, 0x8c, 0x52, 0x72, 0x5b, 0x5e, 0x2b, 0xf1, 0x66, 0x5b, 0x19, - 0x9b, 0xb3, 0x31, 0xd2, 0x61, 0x9b, 0xdf, 0x07, 0xf2, 0x67, 0x0c, 0x04, 0x32, 0x84, 0xaa, 0x6a, - 0x5f, 0x2a, 0xfc, 0x48, 0x2d, 0x15, 0x7e, 0x84, 0xd1, 0x45, 0xce, 0xb8, 0x29, 0x92, 0x0f, 0x1a, - 0xe7, 0x26, 0x2e, 0x64, 0x19, 0xff, 0x29, 0x07, 0x25, 0x1e, 0xd4, 0xe3, 0x5d, 0x58, 0xe2, 0xf8, - 0xca, 0x99, 0x5c, 0x78, 0xfc, 0x70, 0xfe, 0x6f, 0x28, 0xfc, 0xc8, 0xd9, 0xb6, 0xd0, 0xa2, 0x24, - 0x45, 0x6c, 0x84, 0x16, 0x29, 0xe9, 0x0e, 0x54, 0x55, 0xd5, 0xda, 0xd2, 0xa9, 0xc8, 0x9a, 0xc9, - 0x9b, 0x50, 0x3c, 0xf7, 0x66, 0x52, 0xef, 0x09, 0xd1, 0x48, 0x9a, 0x08, 0x8f, 0xda, 0xc2, 0xea, - 0x88, 0x2e, 0x8a, 0x15, 0x44, 0x5b, 0x58, 0x25, 0x32, 0xd4, 0x41, 0xa2, 0x8f, 0x0b, 0x19, 0x7d, - 0x3c, 0x86, 0x25, 0x46, 0x07, 0x34, 0xb7, 0xa3, 0xeb, 0x0f, 0xcd, 0x6f, 0x33, 0xf9, 0x66, 0x34, - 0x99, 0x8f, 0xa9, 0xae, 0x79, 0x46, 0xcf, 0x60, 0x01, 0x97, 0x72, 0xa5, 0xf1, 0x3b, 0x39, 0x4e, - 0x5f, 0x58, 0xb9, 0xe4, 0x1e, 0x14, 0x5d, 0xe9, 0xa2, 0x14, 0x49, 0x31, 0xea, 0x52, 0x25, 0xc3, - 0x33, 0x11, 0x83, 0x4d, 0x1d, 0x3a, 0xf6, 0xe8, 0xa5, 0x37, 0xcc, 0x9a, 0x3b, 0x9f, 0x2a, 0xc5, - 0xed, 0xb7, 0x64, 0xb7, 0x12, 0x4a, 0x4f, 0xde, 0x7b, 0xb5, 0x4d, 0xb7, 0x34, 0x17, 0xe3, 0x62, - 0xec, 0xc4, 0x94, 0x32, 0xd0, 0xf8, 0x8c, 0x6a, 0xae, 0xc5, 0xbf, 0x9f, 0x87, 0x46, 0xac, 0x45, - 0xe8, 0x63, 0xcd, 0x0e, 0x00, 0x6e, 0x98, 0x15, 0xf3, 0x8d, 0xae, 0xac, 0x42, 0x4c, 0xd5, 0xc6, - 0x29, 0x1f, 0x1b, 0x27, 0xe5, 0x63, 0x58, 0xd0, 0x7d, 0x0c, 0x1f, 0x40, 0x35, 0x8a, 0x8e, 0x15, - 0x6f, 0x12, 0xab, 0x4f, 0x5e, 0x2d, 0x8d, 0x90, 0x22, 0xaf, 0xc4, 0x92, 0xee, 0x95, 0xf8, 0x3d, - 0xcd, 0x89, 0x6d, 0x01, 0x8b, 0x31, 0xb2, 0x46, 0xf4, 0xa7, 0xe2, 0xc2, 0x66, 0x7c, 0x09, 0x35, - 0xad, 0xf1, 0xba, 0x23, 0x58, 0x2e, 0xe6, 0x08, 0xa6, 0x2e, 0xb0, 0xe7, 0xa3, 0x0b, 0xec, 0xc6, - 0xaf, 0xe5, 0xa1, 0xc1, 0xf6, 0x97, 0xe3, 0x9e, 0x1d, 0x79, 0x13, 0x67, 0x84, 0x86, 0x5a, 0xb5, - 0xc3, 0x04, 0xa3, 0x25, 0xf7, 0x99, 0xd8, 0x62, 0x9c, 0xcf, 0xd2, 0xa3, 0xae, 0x70, 0x22, 0xad, - 0xa2, 0xae, 0x18, 0xd0, 0x60, 0x84, 0x11, 0x4d, 0xae, 0x51, 0x24, 0x2d, 0xb3, 0x76, 0x4a, 0xe9, - 0xb6, 0x1d, 0x70, 0x0a, 0xf9, 0x01, 0xac, 0x30, 0x1c, 0x0c, 0xa9, 0x30, 0x75, 0x26, 0x13, 0x27, - 0xba, 0x99, 0x59, 0x30, 0x9b, 0xa7, 0x94, 0x9a, 0x76, 0x48, 0x0f, 0x59, 0x82, 0x08, 0xbc, 0x55, - 0x19, 0x3b, 0x81, 0x7d, 0x12, 0x79, 0xc2, 0xab, 0x6f, 0xe9, 0xc9, 0x10, 0x39, 0x8b, 0x08, 0x47, - 0x27, 0x11, 0x4f, 0x04, 0xf3, 0x27, 0x56, 0x52, 0x39, 0xb9, 0x92, 0x8c, 0x7f, 0x98, 0x87, 0x9a, - 0xb6, 0x2c, 0x5f, 0xe7, 0x74, 0xbd, 0x9d, 0x32, 0xac, 0x57, 0x75, 0x1b, 0xfa, 0xdb, 0xf1, 0x2a, - 0x0b, 0xea, 0xfa, 0x9e, 0xbe, 0x80, 0x6f, 0x41, 0x95, 0xed, 0xba, 0x8f, 0xd0, 0x00, 0x21, 0x42, - 0xe2, 0x21, 0xe0, 0x68, 0x7e, 0x22, 0x13, 0x1f, 0x62, 0x62, 0x29, 0x4a, 0x7c, 0xc8, 0x12, 0x5f, - 0x76, 0x7d, 0xe7, 0x33, 0xa8, 0x8b, 0x52, 0x71, 0x4e, 0x85, 0x58, 0xb0, 0xaa, 0x9d, 0xdc, 0x6a, - 0xbe, 0xcd, 0x1a, 0xaf, 0x8e, 0x4f, 0xbe, 0xc8, 0xf8, 0x50, 0x66, 0xac, 0xbc, 0x2a, 0xe3, 0x43, - 0xfe, 0x61, 0xec, 0xa9, 0x1b, 0x51, 0xe8, 0x3e, 0x2a, 0xe9, 0xd8, 0x87, 0xb0, 0x22, 0xc9, 0xd5, - 0xdc, 0xb5, 0x5d, 0xd7, 0x9b, 0xbb, 0x23, 0x2a, 0x6f, 0x87, 0x13, 0x91, 0x74, 0x1c, 0xa5, 0x18, - 0x63, 0x15, 0xab, 0x85, 0xbb, 0xa1, 0xde, 0x87, 0x12, 0xe7, 0xcb, 0x39, 0xf3, 0x91, 0x4d, 0xb8, - 0x38, 0x0a, 0xb9, 0x07, 0x25, 0xce, 0x9e, 0xe7, 0xaf, 0x25, 0x36, 0x1c, 0xc1, 0x68, 0x03, 0x61, - 0x19, 0x0f, 0x69, 0xe8, 0x3b, 0xa3, 0x20, 0xba, 0x78, 0x5e, 0x0a, 0xaf, 0x66, 0xa2, 0xae, 0xc8, - 0x6e, 0x11, 0x61, 0xa2, 0x86, 0x86, 0xe3, 0xb0, 0x83, 0x69, 0x25, 0x56, 0x86, 0x60, 0x97, 0x26, - 0xb0, 0x7e, 0x42, 0xc3, 0x17, 0x94, 0xba, 0x2e, 0x63, 0x86, 0x46, 0xd4, 0x0d, 0x7d, 0x7b, 0xc2, - 0x26, 0x89, 0xf7, 0xe0, 0x51, 0xaa, 0xd4, 0x48, 0x03, 0xb8, 0x1d, 0x65, 0xdc, 0x51, 0xf9, 0x38, - 0xed, 0x58, 0x3b, 0xc9, 0x4a, 0xdb, 0xfc, 0x05, 0xd8, 0xbc, 0x3e, 0x53, 0x86, 0x9a, 0xe0, 0x5e, - 0x9c, 0xaa, 0x28, 0x2b, 0xf8, 0xc4, 0xb3, 0x43, 0xde, 0x1a, 0x9d, 0xb2, 0xf4, 0xa0, 0xa6, 0xa5, - 0x44, 0x67, 0x7f, 0x0e, 0x99, 0x3b, 0xfe, 0xc1, 0x4e, 0x24, 0xd7, 0xf3, 0xa7, 0x68, 0x75, 0x1e, - 0x5b, 0x51, 0xe9, 0x39, 0x73, 0x29, 0x82, 0xa3, 0xa3, 0x92, 0xb1, 0x05, 0x4b, 0xc8, 0xd9, 0x6b, - 0x07, 0xdd, 0xcb, 0x98, 0x41, 0x63, 0x15, 0x48, 0x8f, 0xd3, 0x2e, 0xdd, 0x25, 0xf7, 0x0f, 0x0b, - 0x50, 0xd3, 0xc0, 0xec, 0x34, 0x42, 0x3f, 0x66, 0x6b, 0xec, 0xd8, 0x53, 0x2a, 0x4d, 0xfc, 0x0d, - 0xb3, 0x81, 0xd0, 0x5d, 0x01, 0x64, 0x67, 0xb1, 0x7d, 0x71, 0x66, 0x79, 0xf3, 0xd0, 0x1a, 0xd3, - 0x33, 0x9f, 0xca, 0x56, 0xd6, 0xed, 0x8b, 0xb3, 0xfe, 0x3c, 0xdc, 0x45, 0x98, 0x0c, 0x4e, 0xa4, - 0x61, 0x15, 0x54, 0x70, 0xa2, 0x08, 0x4b, 0xf8, 0x7f, 0xf3, 0x95, 0x59, 0x54, 0xfe, 0xdf, 0x5c, - 0x5a, 0x4c, 0x1e, 0xa0, 0xa5, 0xf4, 0x01, 0xfa, 0x09, 0xac, 0xf3, 0x03, 0x54, 0x90, 0x66, 0x2b, - 0xb1, 0x93, 0x57, 0x31, 0x55, 0x74, 0x52, 0x63, 0x7b, 0x9b, 0xac, 0x07, 0x92, 0x2c, 0x05, 0xce, - 0x8f, 0x39, 0x21, 0xcb, 0x99, 0xac, 0x67, 0xa2, 0xf0, 0x81, 0xf3, 0x63, 0x2a, 0x83, 0x23, 0xc5, - 0x30, 0xc5, 0xe5, 0xbc, 0xa9, 0xe3, 0x26, 0x31, 0xed, 0xcb, 0x38, 0x66, 0x55, 0x60, 0xda, 0x97, - 0x3a, 0xe6, 0x23, 0xd8, 0x98, 0xd2, 0xb1, 0x63, 0xc7, 0x8b, 0xb5, 0x22, 0xc6, 0x6d, 0x95, 0x27, - 0x6b, 0x79, 0x06, 0x5c, 0x70, 0x67, 0xa3, 0xf1, 0x63, 0x6f, 0x7a, 0xe2, 0x70, 0x9e, 0x85, 0xbb, - 0xe0, 0x15, 0xcd, 0x45, 0x77, 0x3e, 0xfd, 0x79, 0x04, 0xb3, 0x2c, 0x81, 0xd1, 0x80, 0xda, 0x20, - 0xf4, 0x66, 0x72, 0x9a, 0x17, 0xa1, 0xce, 0x3f, 0x45, 0x60, 0x85, 0x5b, 0x70, 0x13, 0x49, 0xc2, - 0xd0, 0x9b, 0x79, 0x13, 0xef, 0xec, 0x2a, 0xa6, 0xc5, 0xfe, 0xe7, 0x39, 0x58, 0x89, 0xa5, 0x0a, - 0xf2, 0xfa, 0x09, 0xa7, 0x67, 0xea, 0x52, 0x76, 0x2e, 0x76, 0x23, 0x8f, 0xcd, 0x17, 0x47, 0xe4, - 0xc4, 0x4c, 0x5e, 0xd4, 0x6e, 0x47, 0x91, 0xc7, 0x64, 0x46, 0x4e, 0x52, 0x5a, 0x69, 0x92, 0x22, - 0xf2, 0xcb, 0x98, 0x64, 0xb2, 0x88, 0x9f, 0x11, 0x17, 0x28, 0xc7, 0xa2, 0xcb, 0x85, 0xf8, 0x15, - 0x2b, 0x5d, 0xe3, 0x2d, 0x5b, 0x10, 0xa9, 0xc1, 0x03, 0xe3, 0x77, 0xf3, 0x00, 0x51, 0xeb, 0xf0, - 0x92, 0x97, 0xe2, 0x5b, 0x72, 0xe8, 0x4d, 0xaf, 0xf1, 0x28, 0x6f, 0x41, 0x5d, 0x5d, 0xbc, 0x88, - 0x38, 0xa1, 0x9a, 0x84, 0x31, 0x76, 0xe8, 0x7d, 0x58, 0x3a, 0x9b, 0x78, 0x27, 0xc8, 0xb1, 0x0a, - 0xbe, 0x05, 0x7d, 0x68, 0xf0, 0x3c, 0x5a, 0xe4, 0x49, 0x2a, 0x76, 0xa0, 0xe2, 0x9d, 0x8a, 0x99, - 0xf7, 0x33, 0x62, 0x9c, 0xd0, 0x97, 0x29, 0x4e, 0xe8, 0x4e, 0x6a, 0x70, 0x7f, 0x3a, 0x6c, 0xd0, - 0x5f, 0xce, 0x2b, 0x5f, 0xf3, 0x68, 0x5e, 0x5e, 0x2e, 0x6c, 0xfe, 0x24, 0x9e, 0x71, 0x2f, 0x33, - 0xf5, 0x7f, 0x09, 0x8b, 0x3e, 0x3f, 0x22, 0xe5, 0xf9, 0x59, 0x7c, 0xc9, 0xf9, 0xd9, 0xf0, 0x63, - 0x7c, 0xd7, 0xb7, 0xa1, 0x69, 0x8f, 0x2f, 0xa8, 0x1f, 0x3a, 0x68, 0x39, 0x43, 0x6e, 0x5d, 0x78, - 0x76, 0x6b, 0x70, 0x64, 0x8b, 0xdf, 0x83, 0x25, 0x11, 0x7a, 0x44, 0x61, 0x8a, 0x98, 0x9c, 0x11, - 0x98, 0x21, 0x1a, 0x7f, 0x5f, 0x3a, 0xb7, 0xc7, 0xd7, 0xda, 0xcb, 0x47, 0x45, 0xef, 0x61, 0x3e, - 0xed, 0xcc, 0x20, 0x96, 0xb5, 0x30, 0xc8, 0x09, 0xea, 0xc8, 0x81, 0xc2, 0x1c, 0x17, 0x1f, 0xd6, - 0xe2, 0xeb, 0x0c, 0xab, 0xf1, 0x2f, 0x72, 0x50, 0xde, 0xf7, 0x66, 0xfb, 0x0e, 0xbf, 0x22, 0x85, - 0x9b, 0x56, 0xd9, 0x8b, 0x17, 0xd8, 0x27, 0xba, 0xf1, 0xbd, 0xe4, 0xea, 0x74, 0x26, 0xd3, 0xd9, - 0x88, 0x33, 0x9d, 0xdf, 0x83, 0x5b, 0x68, 0x8e, 0xf7, 0xbd, 0x99, 0xe7, 0x33, 0xc2, 0x61, 0x4f, - 0x38, 0xf3, 0xe9, 0xb9, 0xe1, 0xb9, 0xa4, 0xe4, 0x37, 0x4f, 0x29, 0x3d, 0xd2, 0x30, 0x0e, 0x15, - 0x02, 0x86, 0x4d, 0x98, 0x84, 0x17, 0x16, 0xd7, 0x17, 0x08, 0xee, 0x98, 0xd3, 0xf7, 0x25, 0x96, - 0xd0, 0x41, 0x38, 0xf2, 0xc7, 0xc6, 0xe7, 0x50, 0x55, 0xaa, 0x27, 0xf2, 0x3e, 0x54, 0xcf, 0xbd, - 0x99, 0xd0, 0x4f, 0xe5, 0x62, 0xd7, 0xcb, 0x45, 0xaf, 0xcd, 0xca, 0x39, 0xff, 0x11, 0x18, 0xff, - 0xa7, 0x0c, 0xe5, 0xae, 0x7b, 0xe1, 0x39, 0x23, 0x74, 0x7b, 0x9f, 0xd2, 0xa9, 0x27, 0xa3, 0x29, - 0xb1, 0xdf, 0xe8, 0x69, 0x19, 0x85, 0xcd, 0x2c, 0x08, 0x4f, 0x4b, 0x15, 0x30, 0x73, 0x0d, 0x16, - 0x7c, 0x3d, 0xee, 0x65, 0xc9, 0xc7, 0x4b, 0x45, 0xea, 0xf4, 0x2e, 0x69, 0x51, 0xb1, 0x58, 0x59, - 0xdc, 0xd3, 0x18, 0x87, 0x8c, 0x87, 0x3e, 0xa8, 0x22, 0x04, 0x07, 0xec, 0x0d, 0x28, 0x0b, 0x2d, - 0x34, 0xbf, 0x5b, 0xca, 0x75, 0xf7, 0x02, 0x84, 0xab, 0xc1, 0xa7, 0xdc, 0x9d, 0x42, 0xb1, 0xd5, - 0x05, 0xb3, 0x2e, 0x81, 0xbb, 0x36, 0xf7, 0x65, 0xe7, 0xf8, 0x1c, 0x85, 0x1f, 0x43, 0xc0, 0x41, - 0x88, 0x90, 0x11, 0x61, 0xb6, 0x9a, 0x19, 0x61, 0x16, 0xef, 0x3e, 0x28, 0x9a, 0xcf, 0xbb, 0x08, - 0x3c, 0x68, 0xa8, 0x06, 0x97, 0x01, 0x9d, 0x85, 0x86, 0x87, 0x47, 0x05, 0x91, 0x1a, 0x9e, 0xb7, - 0xa1, 0x71, 0x6a, 0x4f, 0x26, 0x27, 0xf6, 0xe8, 0x39, 0x57, 0x4c, 0xd4, 0xb9, 0x2e, 0x56, 0x02, - 0x51, 0x33, 0x71, 0x07, 0x6a, 0xda, 0x2c, 0xa3, 0x8b, 0x77, 0xd1, 0x84, 0x68, 0x7e, 0x93, 0xfa, - 0xc6, 0xc5, 0xd7, 0xd0, 0x37, 0x6a, 0xae, 0xee, 0x4b, 0x71, 0x57, 0xf7, 0x5b, 0x48, 0xdb, 0x85, - 0x03, 0x71, 0x93, 0x47, 0xa8, 0xb4, 0xc7, 0x63, 0x1e, 0xa7, 0xe7, 0x2d, 0xa8, 0x8b, 0xc1, 0xe3, - 0xe9, 0xcb, 0xe2, 0xae, 0x00, 0xc2, 0x38, 0xca, 0x6d, 0xae, 0x34, 0x9f, 0xd9, 0xce, 0x18, 0x6f, - 0x72, 0x09, 0xfb, 0x8a, 0x3d, 0x0d, 0x8f, 0x6c, 0x07, 0x5d, 0x27, 0x65, 0x32, 0x9e, 0xd5, 0x2b, - 0x7c, 0xfc, 0x45, 0xf2, 0x80, 0xc7, 0xbc, 0x51, 0x18, 0x53, 0x15, 0xd6, 0xc3, 0xac, 0x09, 0x14, - 0x5c, 0x07, 0x1f, 0xa1, 0xc7, 0x5d, 0x48, 0x31, 0x70, 0xc7, 0xa2, 0x32, 0x2f, 0x89, 0x55, 0x2a, - 0xff, 0x73, 0x43, 0x35, 0xc7, 0x64, 0xac, 0x26, 0xb7, 0x97, 0xaf, 0xc7, 0xb8, 0x71, 0x81, 0x8a, - 0xf6, 0x72, 0x8e, 0x40, 0x3e, 0xd7, 0xce, 0x90, 0x16, 0x22, 0xbf, 0x91, 0x28, 0xff, 0xba, 0xbb, - 0xb3, 0xb7, 0x01, 0x9c, 0x80, 0x9d, 0x79, 0x01, 0x75, 0xc7, 0x18, 0x7f, 0xa3, 0x62, 0x56, 0x9d, - 0xe0, 0x09, 0x07, 0xa4, 0xb4, 0x50, 0x9b, 0xe9, 0x20, 0xb8, 0xdf, 0xe8, 0x11, 0xd4, 0x86, 0xba, - 0x3e, 0x12, 0xa4, 0x02, 0xc5, 0xfe, 0x51, 0xa7, 0xd7, 0xbc, 0x41, 0x6a, 0x50, 0x1e, 0x74, 0x86, - 0xc3, 0x03, 0x34, 0xcc, 0xd7, 0xa1, 0xa2, 0x2e, 0xe0, 0xe7, 0xd9, 0x57, 0x7b, 0x67, 0xa7, 0x73, - 0x34, 0xec, 0xec, 0x36, 0x0b, 0x3f, 0x28, 0x56, 0xf2, 0xcd, 0x82, 0xf1, 0xbf, 0x0a, 0x50, 0xd3, - 0x06, 0xea, 0xe5, 0xf4, 0x3a, 0x1e, 0xea, 0x29, 0x9f, 0x0c, 0xf5, 0xa4, 0x1b, 0x55, 0x44, 0x38, - 0x2c, 0x69, 0x54, 0x79, 0x1b, 0x1a, 0x22, 0x7e, 0xa6, 0xe6, 0x5e, 0x51, 0x32, 0xeb, 0x1c, 0x28, - 0xa8, 0x39, 0x86, 0xf3, 0x40, 0x24, 0xbc, 0x28, 0x5d, 0x12, 0xeb, 0x07, 0x41, 0x78, 0x55, 0x1a, - 0xef, 0xb9, 0x07, 0xde, 0xe4, 0x82, 0x72, 0x0c, 0xce, 0xc2, 0xd6, 0x04, 0x6c, 0x28, 0x42, 0xa5, - 0x08, 0x92, 0xa9, 0xc5, 0x93, 0x28, 0x99, 0x75, 0x0e, 0x14, 0x15, 0x7d, 0x20, 0xd7, 0x18, 0x77, - 0x36, 0xdb, 0x48, 0x2f, 0x98, 0xd8, 0xfa, 0x3a, 0x48, 0xe9, 0x3d, 0xab, 0xb8, 0x76, 0xbe, 0x95, - 0xce, 0xf7, 0x6a, 0xfd, 0x27, 0x79, 0x1f, 0xc8, 0x74, 0x36, 0xb3, 0x32, 0x34, 0x92, 0x45, 0x73, - 0x69, 0x3a, 0x9b, 0x0d, 0x35, 0x85, 0x1d, 0x79, 0x03, 0x0a, 0xf6, 0x74, 0x86, 0xa4, 0x25, 0xd2, - 0x0e, 0xb6, 0x0f, 0x8f, 0x4c, 0x06, 0xfe, 0x06, 0x54, 0xa9, 0xbf, 0x99, 0x83, 0x42, 0xfb, 0xf0, - 0x08, 0x09, 0xbd, 0xe7, 0x85, 0x56, 0x70, 0x6e, 0x8b, 0x68, 0x6e, 0x8c, 0xd0, 0x7b, 0x5e, 0x38, - 0x60, 0x00, 0x46, 0xe8, 0x03, 0x1a, 0x46, 0x4e, 0xd3, 0xa5, 0x80, 0x86, 0xdc, 0x83, 0x7e, 0x74, - 0xee, 0x4c, 0xc6, 0xb1, 0x40, 0xa0, 0x80, 0x20, 0xbe, 0x22, 0x08, 0x14, 0xb5, 0xe3, 0x01, 0x7f, - 0xf3, 0x9b, 0x87, 0xe2, 0x44, 0xe1, 0x7e, 0xf9, 0xea, 0xdb, 0xf8, 0x2b, 0x39, 0x20, 0x6d, 0x46, - 0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c, 0xc9, 0x20, 0xe7, 0xf9, 0x4c, - 0x72, 0xfe, 0x2a, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b, 0xec, 0x41, 0xed, 0x48, 0x8b, - 0xcb, 0x7c, 0x97, 0x9d, 0x8a, 0x32, 0x22, 0x33, 0x3f, 0x2f, 0xb9, 0x56, 0xd7, 0x17, 0x81, 0x98, - 0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x2b, 0xc7, 0xa3, 0x13, 0xaa, 0xfe, 0x45, 0xa1, 0xa0, - 0xa5, 0x71, 0x34, 0x8a, 0x63, 0x53, 0x93, 0xe6, 0x4f, 0x11, 0x82, 0x06, 0x5b, 0x6f, 0x79, 0xa7, - 0xa7, 0x01, 0x95, 0x3e, 0x66, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5, 0x1f, 0x26, 0x63, 0x39, 0xbc, - 0xfc, 0x40, 0x38, 0x96, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5, 0x06, 0x6c, 0x06, 0x84, 0x85, - 0x46, 0xc6, 0x71, 0x50, 0xdf, 0xc6, 0x5f, 0x17, 0xa1, 0x76, 0x92, 0x53, 0x70, 0x1f, 0x2a, 0xaa, - 0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d, 0x15, 0x6b, 0x31, 0xa7, 0x16, - 0x68, 0x65, 0xeb, 0x6a, 0xad, 0xfe, 0x0e, 0x90, 0x53, 0xc7, 0x4f, 0x22, 0x73, 0xea, 0xd1, 0xc4, - 0x14, 0x0d, 0xdb, 0x38, 0x86, 0x15, 0x49, 0xf6, 0x34, 0x99, 0x2c, 0x3e, 0xbf, 0xb9, 0x57, 0x1c, - 0x6c, 0xf9, 0xd4, 0xc1, 0x66, 0xfc, 0x46, 0x09, 0xca, 0x32, 0x0c, 0x7a, 0x56, 0x5c, 0xee, 0x6a, - 0x3c, 0x2e, 0x77, 0x2b, 0x16, 0xf5, 0x13, 0xa7, 0x5e, 0xf0, 0x38, 0xef, 0x25, 0xd9, 0x14, 0xcd, - 0x5a, 0x14, 0x63, 0x55, 0x84, 0xb5, 0xa8, 0x14, 0xb7, 0x16, 0x65, 0xc5, 0x2a, 0xe7, 0xec, 0x76, - 0x2a, 0x56, 0xf9, 0x2d, 0xe0, 0xbc, 0x93, 0xe6, 0x5c, 0x5b, 0x41, 0x80, 0x88, 0x45, 0xa2, 0xb1, - 0x5a, 0x95, 0x24, 0xab, 0xf5, 0xda, 0x6c, 0xd0, 0x27, 0xb0, 0xc0, 0xc3, 0x76, 0x89, 0xb8, 0x14, - 0xf2, 0xb0, 0x14, 0x63, 0x25, 0xff, 0xf3, 0x3b, 0x5b, 0xa6, 0xc0, 0xd5, 0x43, 0xdb, 0xd6, 0x62, - 0xa1, 0x6d, 0x75, 0x2b, 0x56, 0x3d, 0x6e, 0xc5, 0xba, 0x07, 0x4d, 0x35, 0x70, 0xa8, 0x13, 0x76, - 0x03, 0x71, 0x05, 0x7d, 0x51, 0xc2, 0x19, 0x79, 0xef, 0x05, 0xd1, 0x61, 0xbf, 0x18, 0x3b, 0xec, - 0x19, 0xf1, 0x6d, 0x87, 0x21, 0x9d, 0xce, 0x42, 0x79, 0xd8, 0x6b, 0xe1, 0xe1, 0xf9, 0xcc, 0xf3, - 0x3b, 0x6d, 0x72, 0x7a, 0xf9, 0xea, 0xd8, 0x86, 0xc5, 0x53, 0xdb, 0x99, 0xcc, 0x7d, 0x6a, 0xf9, - 0xd4, 0x0e, 0x3c, 0x17, 0xe9, 0x43, 0xc4, 0x77, 0x88, 0x2e, 0xee, 0x71, 0x1c, 0x13, 0x51, 0xcc, - 0xc6, 0xa9, 0xfe, 0x89, 0x37, 0x48, 0xf5, 0x91, 0x60, 0x67, 0xb0, 0x88, 0x4e, 0xc1, 0x7d, 0xe5, - 0xba, 0x3d, 0x6b, 0xef, 0xa0, 0xfb, 0x78, 0x7f, 0xd8, 0xcc, 0xb1, 0xcf, 0xc1, 0xf1, 0xce, 0x4e, - 0xa7, 0xb3, 0x8b, 0x67, 0x32, 0xc0, 0xc2, 0x5e, 0xbb, 0x7b, 0x20, 0x4e, 0xe4, 0x62, 0xb3, 0x64, - 0xfc, 0x61, 0x1e, 0x6a, 0x5a, 0x6f, 0x30, 0xee, 0x0c, 0xff, 0xc9, 0xe8, 0x6f, 0x59, 0xc4, 0x9d, - 0xe1, 0x90, 0xee, 0x98, 0x3c, 0x52, 0x73, 0xc4, 0xc3, 0xe5, 0xdc, 0x4e, 0x0f, 0xc8, 0x96, 0x3c, - 0xd1, 0xb4, 0x49, 0x52, 0x71, 0xe2, 0xf3, 0xd7, 0xc6, 0x89, 0x27, 0xef, 0xc2, 0x92, 0xac, 0x59, - 0xce, 0x89, 0xb0, 0xbe, 0x08, 0xb0, 0x98, 0x92, 0x77, 0x45, 0xe8, 0x1e, 0x71, 0x2c, 0x33, 0xbc, - 0xa2, 0xf4, 0x29, 0x57, 0x27, 0x33, 0x4e, 0x5d, 0x59, 0x0c, 0x9c, 0xf0, 0x96, 0x50, 0x0c, 0x8e, - 0x18, 0x4e, 0x99, 0x1c, 0x3b, 0x23, 0x16, 0x12, 0x67, 0xc4, 0xa7, 0x00, 0x51, 0x7f, 0xe2, 0xa3, - 0x7b, 0x23, 0x3e, 0xba, 0x39, 0x6d, 0x74, 0xf3, 0xc6, 0xdf, 0x13, 0x94, 0x4d, 0x4c, 0x95, 0xd2, - 0xc5, 0x7e, 0x00, 0x52, 0x3b, 0x6c, 0xe1, 0x1d, 0x94, 0xd9, 0x84, 0x86, 0xf2, 0x82, 0xfd, 0xb2, - 0x48, 0xe9, 0xaa, 0x84, 0x14, 0x25, 0xce, 0xa7, 0x29, 0xf1, 0x5b, 0x50, 0xc7, 0x58, 0x90, 0xa2, - 0x22, 0x19, 0x8c, 0x79, 0x6a, 0x5f, 0xca, 0xba, 0x63, 0x24, 0xb8, 0x98, 0x20, 0xc1, 0x7f, 0x23, - 0xc7, 0x03, 0x87, 0x45, 0x0d, 0x8d, 0x68, 0xb0, 0x2a, 0x33, 0x4e, 0x83, 0x05, 0xaa, 0xa9, 0xd2, - 0xaf, 0xa1, 0xab, 0xf9, 0x6c, 0xba, 0x9a, 0x4d, 0xb1, 0x0b, 0x99, 0x14, 0xdb, 0xb8, 0x84, 0xd6, - 0x2e, 0x65, 0x43, 0xd1, 0x9e, 0x4c, 0x92, 0x63, 0xf9, 0x00, 0x56, 0xd9, 0x14, 0xa2, 0xab, 0x08, - 0x4f, 0xd1, 0x4f, 0x34, 0xc2, 0xd3, 0x64, 0x26, 0x3c, 0xd8, 0xee, 0xc3, 0xb2, 0xc8, 0x81, 0x9b, - 0x56, 0x8f, 0xd2, 0xb6, 0xc4, 0x13, 0xd0, 0xc5, 0x95, 0xe1, 0x1a, 0xb7, 0xe0, 0x66, 0x46, 0xcd, - 0x42, 0x69, 0xf7, 0x9b, 0x39, 0x58, 0x6b, 0xf3, 0x68, 0x44, 0xdf, 0xd8, 0xfd, 0xfa, 0x2f, 0xe0, - 0xa6, 0xba, 0xae, 0xa2, 0x5d, 0xb3, 0xd5, 0x1b, 0x29, 0x6f, 0xba, 0x68, 0x97, 0xb4, 0xb0, 0xad, - 0x2d, 0x58, 0x4f, 0xb6, 0x46, 0x34, 0x74, 0x0f, 0x96, 0x77, 0xe9, 0xc9, 0xfc, 0xec, 0x80, 0x5e, - 0x44, 0x6d, 0x24, 0x50, 0x0c, 0xce, 0xbd, 0x17, 0x62, 0xa0, 0xf0, 0x37, 0xfa, 0xb3, 0x33, 0x1c, - 0x2b, 0x98, 0xd1, 0x91, 0x34, 0xfa, 0x20, 0x64, 0x30, 0xa3, 0x23, 0xe3, 0x11, 0x10, 0xbd, 0x1c, - 0xb1, 0x46, 0x98, 0x0c, 0x3c, 0x3f, 0xb1, 0x82, 0xab, 0x20, 0xa4, 0x53, 0x79, 0xd5, 0x1c, 0x82, - 0xf9, 0xc9, 0x80, 0x43, 0x8c, 0xf7, 0xa0, 0x7e, 0x64, 0x5f, 0x99, 0xf4, 0x47, 0xe2, 0xb6, 0xf6, - 0x06, 0x94, 0x67, 0xf6, 0x15, 0x3b, 0x08, 0x94, 0xfd, 0x17, 0x93, 0x8d, 0xdf, 0x2d, 0xc2, 0x02, - 0xc7, 0x24, 0x77, 0xf9, 0x13, 0x32, 0x8e, 0x8b, 0x84, 0x58, 0x1e, 0x89, 0x1a, 0x28, 0x75, 0x6a, - 0xe6, 0xd3, 0xa7, 0xa6, 0x50, 0x56, 0xcb, 0x50, 0x97, 0xd2, 0x52, 0xe7, 0xce, 0xa7, 0x32, 0xbe, - 0x65, 0x3c, 0xf6, 0x4e, 0x31, 0x7a, 0x94, 0x88, 0xc7, 0x1d, 0x89, 0xfb, 0x52, 0x44, 0x92, 0x36, - 0x6f, 0x9d, 0x64, 0x06, 0xc4, 0x81, 0xa9, 0x83, 0x32, 0xc5, 0xf9, 0xb2, 0x0c, 0x65, 0x10, 0x17, - 0xe7, 0x53, 0x62, 0x7b, 0xe5, 0xd5, 0x62, 0x3b, 0xd7, 0x62, 0xbf, 0x44, 0x6c, 0x87, 0xd7, 0x10, - 0xdb, 0x5f, 0xc3, 0x8f, 0xe1, 0x26, 0x54, 0x90, 0xc3, 0xd3, 0xce, 0x4f, 0xc6, 0xd9, 0xb1, 0xf3, - 0xf3, 0x33, 0x4d, 0xb0, 0xe5, 0x4e, 0x54, 0xda, 0x01, 0x66, 0xd2, 0x1f, 0xfd, 0x74, 0x14, 0xa3, - 0xcf, 0xa0, 0x2c, 0xa0, 0x6c, 0x41, 0xbb, 0xf6, 0x54, 0x06, 0x74, 0xc6, 0xdf, 0x6c, 0xd8, 0x30, - 0xc4, 0xe9, 0x8f, 0xe6, 0x8e, 0x4f, 0xc7, 0x32, 0xd0, 0xa2, 0x83, 0xd4, 0x83, 0x41, 0x58, 0x07, - 0x99, 0x90, 0xed, 0xca, 0xd7, 0x23, 0x2a, 0x66, 0xd9, 0x09, 0x9e, 0xb0, 0x4f, 0x83, 0x40, 0x13, - 0xc3, 0xe7, 0xcf, 0x3c, 0x5f, 0xb2, 0x27, 0xc6, 0xef, 0xe5, 0xa0, 0x29, 0x76, 0x97, 0x4a, 0xd3, - 0x05, 0xd8, 0xd2, 0x75, 0x3e, 0x3f, 0x2f, 0x0f, 0x9b, 0x68, 0x40, 0x03, 0x55, 0x7b, 0x8a, 0x57, - 0xe1, 0xaa, 0xc9, 0x1a, 0x03, 0xee, 0x09, 0x7e, 0xe5, 0x4d, 0xa8, 0xc9, 0xdb, 0x36, 0x53, 0x67, - 0x22, 0xdf, 0x1f, 0xe3, 0xd7, 0x6d, 0x0e, 0x9d, 0x89, 0x64, 0x75, 0x7c, 0x5b, 0x84, 0xd7, 0xc8, - 0x21, 0xab, 0x63, 0xda, 0x21, 0x35, 0xfe, 0x20, 0x07, 0xcb, 0x5a, 0x57, 0xc4, 0xbe, 0xfd, 0x2e, - 0xd4, 0xd5, 0xab, 0x1e, 0x54, 0xf1, 0xd8, 0x1b, 0x71, 0x1a, 0x15, 0x65, 0xab, 0x8d, 0x14, 0x24, - 0x60, 0x8d, 0x19, 0xdb, 0x57, 0xfc, 0x4a, 0xc8, 0x7c, 0x2a, 0xe5, 0xf2, 0xb1, 0x7d, 0xb5, 0x47, - 0xe9, 0x60, 0x3e, 0x25, 0x77, 0xa1, 0xfe, 0x82, 0xd2, 0xe7, 0x0a, 0x81, 0x13, 0x76, 0x60, 0x30, - 0x81, 0x61, 0x40, 0x63, 0xea, 0xb9, 0xe1, 0xb9, 0x42, 0x11, 0xf2, 0x05, 0x02, 0x39, 0x8e, 0xf1, - 0xaf, 0xf2, 0xb0, 0xc2, 0x15, 0xc8, 0xc2, 0x8c, 0x20, 0x48, 0x57, 0x0b, 0x16, 0xb8, 0x56, 0x9f, - 0x13, 0xaf, 0xfd, 0x1b, 0xa6, 0xf8, 0x26, 0x9f, 0xbc, 0xa6, 0xd2, 0x5b, 0x46, 0xe6, 0xb8, 0x66, - 0xf8, 0x0b, 0xe9, 0xe1, 0xbf, 0x7e, 0x78, 0xb3, 0x9c, 0x0a, 0x4a, 0x59, 0x4e, 0x05, 0xaf, 0x63, - 0xca, 0x4f, 0xc5, 0x86, 0x28, 0xa7, 0x63, 0x34, 0x3f, 0x82, 0x8d, 0x18, 0x0e, 0x52, 0x6b, 0xe7, - 0xd4, 0x51, 0x8f, 0x0b, 0xac, 0x6a, 0xd8, 0x03, 0x99, 0xb6, 0x5d, 0x86, 0x52, 0x30, 0xf2, 0x66, - 0xe8, 0x87, 0x1e, 0x1f, 0x55, 0x71, 0x4c, 0xfc, 0x76, 0x0e, 0x5a, 0x7b, 0x51, 0xb0, 0x6b, 0x27, - 0x08, 0x3d, 0x5f, 0xbd, 0xdb, 0x70, 0x1b, 0x80, 0xbf, 0x85, 0x86, 0x6a, 0x10, 0x11, 0xa5, 0x0c, - 0x21, 0xa8, 0x04, 0xb9, 0x09, 0x15, 0xea, 0x8e, 0x79, 0x22, 0x5f, 0x0d, 0x65, 0xea, 0x8e, 0xa5, - 0x0a, 0x25, 0x75, 0xc8, 0x37, 0xe2, 0xec, 0x8b, 0x88, 0xb7, 0xc3, 0x46, 0x87, 0x5e, 0x20, 0xb3, - 0x51, 0x54, 0xf1, 0x76, 0x0e, 0xed, 0x4b, 0xbc, 0x4e, 0x10, 0x18, 0xff, 0x20, 0x0f, 0x4b, 0x51, - 0xfb, 0x78, 0xc4, 0xb1, 0xbb, 0xa9, 0xd8, 0x69, 0xc2, 0x1f, 0x4a, 0xd1, 0xf0, 0xbb, 0x62, 0x49, - 0x38, 0x4c, 0x5a, 0xd3, 0x54, 0xeb, 0x15, 0xbe, 0x41, 0xbb, 0x2e, 0x31, 0xa0, 0x26, 0x31, 0xbc, - 0x79, 0xa8, 0xc5, 0x96, 0xae, 0x72, 0x94, 0xfe, 0x3c, 0x64, 0xe2, 0xb5, 0x3d, 0x65, 0xdc, 0x8a, - 0x10, 0x70, 0x4b, 0xf6, 0x34, 0xec, 0xe2, 0xa3, 0x7b, 0x0c, 0xcc, 0xb2, 0xf1, 0xc9, 0x64, 0x58, - 0x0c, 0xbf, 0xc9, 0xa5, 0x2d, 0x3e, 0x7b, 0x28, 0x69, 0xe9, 0xa2, 0x08, 0x7f, 0xea, 0x47, 0x89, - 0x22, 0x6f, 0x42, 0x8d, 0x17, 0x1e, 0x85, 0x03, 0xc1, 0x40, 0x8f, 0x61, 0xd7, 0xc5, 0x74, 0xa1, - 0xe6, 0xf4, 0xe6, 0x31, 0xcd, 0x0d, 0xf0, 0xaa, 0xe4, 0xfb, 0x68, 0xaa, 0xc7, 0x96, 0x32, 0x42, - 0xd6, 0x14, 0xac, 0x17, 0x30, 0x6e, 0xe5, 0x66, 0xc6, 0xec, 0x0a, 0x62, 0xb0, 0x03, 0x5a, 0x64, - 0x74, 0x39, 0x09, 0x9c, 0x22, 0xac, 0x4b, 0xea, 0x1b, 0x1f, 0x7a, 0xb3, 0x79, 0x1a, 0x07, 0x44, - 0x52, 0x38, 0x9f, 0xe8, 0x58, 0xdc, 0x1a, 0xe4, 0xe9, 0xf8, 0x6c, 0x73, 0x01, 0xf8, 0x08, 0x36, - 0x3b, 0x97, 0x8c, 0xb0, 0x28, 0xc7, 0xfa, 0xd1, 0xf3, 0xb9, 0xb4, 0x8f, 0x26, 0xac, 0x2c, 0xb9, - 0xd7, 0xb2, 0xb2, 0x8c, 0x79, 0xb4, 0x08, 0x55, 0xd6, 0x4f, 0x52, 0x08, 0xd7, 0x2f, 0xd9, 0xae, - 0x75, 0x82, 0x45, 0xc8, 0xe0, 0x34, 0x0c, 0xc4, 0x0b, 0x35, 0x02, 0x58, 0x3a, 0x9c, 0x4f, 0x42, - 0x67, 0x47, 0x81, 0xc8, 0x27, 0x22, 0x0f, 0xd6, 0x23, 0x47, 0x2d, 0xb3, 0x22, 0x50, 0x15, 0xe1, - 0x60, 0x4d, 0x59, 0x41, 0x56, 0xba, 0xbe, 0xa5, 0x69, 0xbc, 0x06, 0xe3, 0x26, 0x6c, 0x44, 0x5f, - 0x7c, 0xd8, 0xe4, 0x89, 0xf4, 0x37, 0x73, 0xfc, 0x8a, 0x13, 0x4f, 0x1b, 0xb8, 0xf6, 0x2c, 0x38, - 0xf7, 0x42, 0xd2, 0x81, 0x95, 0xc0, 0x71, 0xcf, 0x26, 0x54, 0x2f, 0x3e, 0x10, 0x83, 0xb0, 0x16, - 0x6f, 0x1b, 0xcf, 0x1a, 0x98, 0xcb, 0x3c, 0x47, 0x54, 0x5a, 0x40, 0xb6, 0xaf, 0x6b, 0x64, 0xb4, - 0x2c, 0x12, 0xa3, 0x91, 0x6e, 0x7c, 0x17, 0x16, 0xe3, 0x15, 0x91, 0xcf, 0x44, 0x90, 0x95, 0xa8, - 0x55, 0x85, 0x44, 0x88, 0x89, 0x68, 0x41, 0xd4, 0xa2, 0xb1, 0x0f, 0x8c, 0xbf, 0x94, 0x83, 0x96, - 0x49, 0xd9, 0xca, 0xd5, 0x5a, 0x29, 0xd7, 0xcc, 0x77, 0x53, 0xa5, 0x5e, 0xdf, 0x57, 0x19, 0xbb, - 0x45, 0xb6, 0xe8, 0x3b, 0xd7, 0x4e, 0xc6, 0xfe, 0x8d, 0x54, 0x8f, 0xb6, 0x2b, 0xb0, 0xc0, 0x51, - 0x8c, 0x0d, 0x58, 0x13, 0xed, 0x91, 0x6d, 0x89, 0x0c, 0xfa, 0xb1, 0x1a, 0x63, 0x06, 0xfd, 0x4d, - 0x68, 0xf1, 0x58, 0x08, 0x7a, 0x27, 0x44, 0xc6, 0x5d, 0x20, 0x87, 0xf6, 0xc8, 0xf6, 0x3d, 0xcf, - 0x3d, 0xa2, 0xbe, 0x70, 0x99, 0x47, 0x46, 0x14, 0xed, 0xdd, 0x92, 0x63, 0xe6, 0x5f, 0x32, 0xe8, - 0xbe, 0xe7, 0x4a, 0x0f, 0x41, 0xfe, 0x65, 0xf8, 0xb0, 0xb2, 0x6d, 0x3f, 0xa7, 0xb2, 0x24, 0x39, - 0x44, 0x5f, 0x42, 0x6d, 0xa6, 0x0a, 0x95, 0xe3, 0x2e, 0xe3, 0x57, 0xa5, 0xab, 0x35, 0x75, 0x6c, - 0x46, 0xa5, 0x50, 0x61, 0x8b, 0x11, 0x61, 0xc6, 0xf2, 0xcc, 0x67, 0xa0, 0x27, 0xf4, 0xaa, 0x3b, - 0x36, 0x1e, 0xc2, 0x6a, 0xbc, 0x4e, 0x41, 0x5a, 0x36, 0xa1, 0x32, 0x15, 0x30, 0xd1, 0x7a, 0xf5, - 0xcd, 0x64, 0x16, 0x26, 0x77, 0xca, 0x3c, 0xdd, 0x5d, 0x15, 0xd6, 0xe0, 0x4b, 0xd8, 0x48, 0xa5, - 0x88, 0x02, 0xef, 0x42, 0x5d, 0x6b, 0x08, 0xef, 0x46, 0xd1, 0x04, 0xd5, 0x92, 0xc0, 0xf8, 0x02, - 0x36, 0xb8, 0xd8, 0x16, 0x65, 0x97, 0x43, 0x90, 0xe8, 0x45, 0x2e, 0xd9, 0x8b, 0x4f, 0xa4, 0xac, - 0xa9, 0x67, 0x8d, 0xe2, 0x47, 0x8e, 0x31, 0x4d, 0x3a, 0x79, 0xc9, 0x4f, 0xe3, 0x18, 0xd6, 0xd3, - 0xc3, 0xc7, 0xda, 0xff, 0x67, 0x1a, 0x72, 0x39, 0x3c, 0x51, 0xb2, 0x1a, 0x9e, 0xff, 0x9c, 0xe3, - 0xe3, 0x13, 0x4b, 0x12, 0xcd, 0x1c, 0x03, 0x99, 0xd2, 0xf0, 0xdc, 0x1b, 0x5b, 0xe9, 0x9a, 0x1f, - 0x29, 0x1f, 0xb3, 0xcc, 0xbc, 0x5b, 0x87, 0x98, 0x51, 0x4b, 0x11, 0xb7, 0x1d, 0xa6, 0x49, 0xf8, - 0xe6, 0x08, 0xd6, 0xb3, 0x91, 0x33, 0x3c, 0xb3, 0x3e, 0x8e, 0xf3, 0xf3, 0xb7, 0xaf, 0xed, 0x3e, - 0x6b, 0x96, 0xce, 0xde, 0xff, 0x6e, 0x05, 0xca, 0x42, 0x55, 0x43, 0xb6, 0xa0, 0x38, 0x92, 0x5e, - 0xbe, 0x51, 0x0c, 0x51, 0x91, 0x2a, 0xff, 0xef, 0xa0, 0xaf, 0x2f, 0xc3, 0x23, 0x5f, 0xc2, 0x62, - 0xdc, 0xd1, 0x25, 0x11, 0xeb, 0x27, 0xee, 0xa1, 0xd2, 0x18, 0x25, 0x9c, 0x08, 0xaa, 0x11, 0x0f, - 0xc6, 0x59, 0xd3, 0xca, 0xb9, 0xc6, 0xa4, 0x79, 0x2e, 0x13, 0xeb, 0x82, 0x73, 0xdb, 0x7a, 0xf8, - 0xe8, 0x53, 0x61, 0x54, 0xa8, 0x21, 0x70, 0x70, 0x6e, 0x3f, 0x7c, 0xf4, 0x69, 0x52, 0x60, 0x13, - 0xa1, 0x7e, 0x34, 0x81, 0x6d, 0x15, 0x4a, 0xfc, 0x65, 0x02, 0xee, 0xae, 0xc9, 0x3f, 0xa4, 0x3a, - 0x63, 0xee, 0x53, 0x4b, 0x5c, 0xac, 0xe1, 0xa7, 0x28, 0x7f, 0x45, 0x8e, 0x88, 0xb4, 0x01, 0x26, - 0x71, 0x75, 0xe2, 0x3a, 0x2c, 0x9c, 0x47, 0x4f, 0x4d, 0x34, 0x4c, 0xf1, 0x65, 0xfc, 0x8f, 0x12, - 0xd4, 0xb4, 0x41, 0x21, 0x75, 0xa8, 0x98, 0x9d, 0x41, 0xc7, 0x7c, 0xda, 0xd9, 0x6d, 0xde, 0x20, - 0xf7, 0xe0, 0x9d, 0x6e, 0x6f, 0xa7, 0x6f, 0x9a, 0x9d, 0x9d, 0xa1, 0xd5, 0x37, 0x2d, 0x19, 0xda, - 0xf6, 0xa8, 0xfd, 0xec, 0xb0, 0xd3, 0x1b, 0x5a, 0xbb, 0x9d, 0x61, 0xbb, 0x7b, 0x30, 0x68, 0xe6, - 0xc8, 0x1b, 0xd0, 0x8a, 0x30, 0x65, 0x72, 0xfb, 0xb0, 0x7f, 0xdc, 0x1b, 0x36, 0xf3, 0xe4, 0x0e, - 0xdc, 0xda, 0xeb, 0xf6, 0xda, 0x07, 0x56, 0x84, 0xb3, 0x73, 0x30, 0x7c, 0x6a, 0x75, 0x7e, 0xee, - 0xa8, 0x6b, 0x3e, 0x6b, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b, 0xb2, 0x84, 0x22, 0xb9, 0x09, - 0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7, 0x7b, 0xcd, 0x12, 0x59, 0x86, - 0x46, 0xb7, 0xf7, 0xb4, 0x7d, 0xd0, 0xdd, 0xb5, 0xcc, 0x4e, 0xfb, 0xe0, 0xb0, 0xb9, 0x40, 0x56, - 0x60, 0x29, 0x89, 0x57, 0x66, 0x45, 0x48, 0xbc, 0x7e, 0xaf, 0xdb, 0xef, 0x59, 0x4f, 0x3b, 0xe6, - 0xa0, 0xdb, 0xef, 0x35, 0x2b, 0x64, 0x1d, 0x48, 0x3c, 0x69, 0xff, 0xb0, 0xbd, 0xd3, 0xac, 0x92, - 0x35, 0x58, 0x8e, 0xc3, 0x9f, 0x74, 0x9e, 0x35, 0x81, 0xb4, 0x60, 0x95, 0x37, 0xcc, 0xda, 0xee, - 0x1c, 0xf4, 0xbf, 0xb2, 0x0e, 0xbb, 0xbd, 0xee, 0xe1, 0xf1, 0x61, 0xb3, 0x86, 0x01, 0xc6, 0x3b, - 0x1d, 0xab, 0xdb, 0x1b, 0x1c, 0xef, 0xed, 0x75, 0x77, 0xba, 0x9d, 0xde, 0xb0, 0x59, 0xe7, 0x35, - 0x67, 0x75, 0xbc, 0xc1, 0x32, 0x88, 0xbb, 0xa7, 0xd6, 0x6e, 0x77, 0xd0, 0xde, 0x3e, 0xe8, 0xec, - 0x36, 0x17, 0xc9, 0x6d, 0xb8, 0x39, 0xec, 0x1c, 0x1e, 0xf5, 0xcd, 0xb6, 0xf9, 0x4c, 0xde, 0x4d, - 0xb5, 0xf6, 0xda, 0xdd, 0x83, 0x63, 0xb3, 0xd3, 0x5c, 0x22, 0x6f, 0xc1, 0x6d, 0xb3, 0xf3, 0xc3, - 0xe3, 0xae, 0xd9, 0xd9, 0xb5, 0x7a, 0xfd, 0xdd, 0x8e, 0xb5, 0xd7, 0x69, 0x0f, 0x8f, 0xcd, 0x8e, - 0x75, 0xd8, 0x1d, 0x0c, 0xba, 0xbd, 0xc7, 0xcd, 0x26, 0x79, 0x07, 0xee, 0x2a, 0x14, 0x55, 0x40, - 0x02, 0x6b, 0x99, 0xf5, 0x4f, 0x4e, 0x69, 0xaf, 0xf3, 0x73, 0x43, 0xeb, 0xa8, 0xd3, 0x31, 0x9b, - 0x84, 0x6c, 0xc2, 0x7a, 0x54, 0x3d, 0xaf, 0x40, 0xd4, 0xbd, 0xc2, 0xd2, 0x8e, 0x3a, 0xe6, 0x61, - 0xbb, 0xc7, 0x26, 0x38, 0x96, 0xb6, 0xca, 0x9a, 0x1d, 0xa5, 0x25, 0x9b, 0xbd, 0x46, 0x08, 0x2c, - 0x6a, 0xb3, 0xb2, 0xd7, 0x36, 0x9b, 0xeb, 0x64, 0x09, 0x6a, 0x87, 0x47, 0x47, 0xd6, 0xb0, 0x7b, - 0xd8, 0xe9, 0x1f, 0x0f, 0x9b, 0x1b, 0xe9, 0x59, 0x3a, 0x6a, 0x3f, 0x3b, 0xe8, 0xb7, 0x77, 0x9b, - 0x2d, 0xb2, 0x06, 0xcd, 0x6e, 0x6f, 0xd8, 0x31, 0xd9, 0x32, 0x90, 0xa5, 0xfe, 0x97, 0x32, 0x59, - 0x85, 0x25, 0xd9, 0x09, 0x09, 0xfd, 0xa3, 0x32, 0xd9, 0x00, 0x72, 0xdc, 0x33, 0x3b, 0xed, 0x5d, - 0x36, 0xa6, 0x2a, 0xe1, 0xbf, 0x96, 0x85, 0x79, 0xf9, 0xf7, 0x0a, 0x8a, 0x0f, 0x8c, 0x1c, 0xcc, - 0xe2, 0xcf, 0x46, 0xd5, 0xb5, 0xe7, 0x9e, 0x5e, 0xf5, 0xb4, 0xa8, 0x26, 0xdc, 0x17, 0x52, 0xc2, - 0x7d, 0x4a, 0x7b, 0xd4, 0xd0, 0x25, 0x8f, 0xb7, 0xa1, 0x31, 0xe5, 0x4f, 0x48, 0x89, 0x37, 0x48, - 0x40, 0x78, 0x5b, 0x72, 0x20, 0x7f, 0x80, 0x24, 0xf5, 0xb6, 0x66, 0x29, 0xfd, 0xb6, 0x66, 0x96, - 0x84, 0xb9, 0x90, 0x25, 0x61, 0xde, 0x87, 0x65, 0x4e, 0xb5, 0x1c, 0xd7, 0x99, 0x4a, 0xbd, 0x8d, - 0x78, 0xa9, 0x12, 0xa9, 0x17, 0x87, 0x4b, 0x81, 0x56, 0x0a, 0xbd, 0x82, 0xba, 0x94, 0x85, 0xbc, - 0x1b, 0x93, 0x75, 0x39, 0x51, 0x51, 0xb2, 0xae, 0xaa, 0xc1, 0xbe, 0x8c, 0x6a, 0xa8, 0x69, 0x35, - 0x70, 0x38, 0xd6, 0x70, 0x1f, 0x96, 0xe9, 0x65, 0xe8, 0xdb, 0x96, 0x37, 0xb3, 0x7f, 0x34, 0x47, - 0x17, 0x19, 0x1b, 0xb5, 0x48, 0x75, 0x73, 0x09, 0x13, 0xfa, 0x08, 0xdf, 0xb5, 0x43, 0xdb, 0xf8, - 0x45, 0x00, 0x75, 0xe0, 0xe2, 0x8b, 0x9f, 0xae, 0x27, 0xef, 0xd4, 0xd6, 0x4d, 0xfe, 0x81, 0xf3, - 0x18, 0x7a, 0xbe, 0x7d, 0x46, 0xbb, 0xd2, 0x2a, 0x1c, 0x01, 0xc8, 0x2d, 0x28, 0x78, 0x33, 0xe9, - 0x8b, 0x58, 0x95, 0x41, 0xf5, 0x67, 0x26, 0x83, 0x1a, 0x9f, 0x42, 0xbe, 0x3f, 0xbb, 0x96, 0x8b, - 0xc2, 0x07, 0xce, 0xf8, 0xab, 0x06, 0x79, 0xf4, 0x3f, 0x94, 0x9f, 0xf7, 0xff, 0x3c, 0xd4, 0xb4, - 0xf7, 0xd0, 0xc8, 0x06, 0xac, 0x7c, 0xd5, 0x1d, 0xf6, 0x3a, 0x83, 0x81, 0x75, 0x74, 0xbc, 0xfd, - 0xa4, 0xf3, 0xcc, 0xda, 0x6f, 0x0f, 0xf6, 0x9b, 0x37, 0x18, 0x99, 0xe9, 0x75, 0x06, 0xc3, 0xce, - 0x6e, 0x0c, 0x9e, 0x23, 0x6f, 0xc2, 0xe6, 0x71, 0xef, 0x78, 0xd0, 0xd9, 0xb5, 0xb2, 0xf2, 0xe5, - 0xd9, 0xbe, 0x12, 0xe9, 0x19, 0xd9, 0x0b, 0xf7, 0x7f, 0x09, 0x16, 0xe3, 0x81, 0x65, 0x08, 0xc0, - 0xc2, 0x41, 0xe7, 0x71, 0x7b, 0xe7, 0x19, 0x7f, 0x34, 0x61, 0x30, 0x6c, 0x0f, 0xbb, 0x3b, 0x96, - 0x78, 0x24, 0x81, 0xd1, 0xb0, 0x1c, 0xa9, 0x41, 0xb9, 0xdd, 0xdb, 0xd9, 0xef, 0x9b, 0x83, 0x66, - 0x9e, 0xbc, 0x01, 0x1b, 0x72, 0x0b, 0xed, 0xf4, 0x0f, 0x0f, 0xbb, 0x43, 0x24, 0xdf, 0xc3, 0x67, - 0x47, 0x6c, 0xc7, 0xdc, 0xb7, 0xa1, 0x1a, 0xbd, 0xef, 0x80, 0x24, 0xb1, 0x3b, 0xec, 0xb6, 0x87, - 0xd1, 0x79, 0xd0, 0xbc, 0xc1, 0x28, 0x6e, 0x04, 0xc6, 0x47, 0x1a, 0x9a, 0x39, 0x7e, 0xf7, 0x5e, - 0x02, 0x79, 0xed, 0xcd, 0x3c, 0x23, 0x03, 0x11, 0x74, 0xbb, 0x3f, 0x64, 0x5d, 0xf8, 0x65, 0x58, - 0x8c, 0x3f, 0xa3, 0x40, 0x9a, 0x50, 0x67, 0xf5, 0x6b, 0x55, 0x00, 0x2c, 0xf0, 0x16, 0x37, 0x73, - 0x9c, 0xe6, 0xef, 0xf4, 0x0f, 0xbb, 0xbd, 0xc7, 0x78, 0x50, 0x34, 0xf3, 0x0c, 0xd4, 0x3f, 0x1e, - 0x3e, 0xee, 0x2b, 0x50, 0x81, 0xe5, 0xe0, 0xdd, 0x69, 0x16, 0xef, 0xff, 0x08, 0x96, 0x53, 0x0f, - 0x2e, 0xb0, 0x56, 0xf7, 0x8f, 0x87, 0x3b, 0xfd, 0x43, 0xbd, 0x9e, 0x1a, 0x94, 0x77, 0x0e, 0xda, - 0xdd, 0x43, 0x34, 0xd4, 0x34, 0xa0, 0x7a, 0xdc, 0x93, 0x9f, 0xf9, 0xf8, 0x53, 0x11, 0x05, 0x46, - 0xbd, 0xf6, 0xba, 0xe6, 0x60, 0x68, 0x0d, 0x86, 0xed, 0xc7, 0x9d, 0x66, 0x91, 0xe5, 0x95, 0xa4, - 0xac, 0x74, 0xff, 0x0b, 0x58, 0x8c, 0x3b, 0xce, 0xc7, 0xed, 0x6f, 0x9b, 0xb0, 0xbe, 0xdd, 0x19, - 0x7e, 0xd5, 0xe9, 0xf4, 0x70, 0xca, 0x77, 0x3a, 0xbd, 0xa1, 0xd9, 0x3e, 0xe8, 0x0e, 0x9f, 0x35, - 0x73, 0xf7, 0xbf, 0x84, 0x66, 0xd2, 0xe9, 0x23, 0xe6, 0x25, 0xf3, 0x32, 0x77, 0x9a, 0xfb, 0xff, - 0x36, 0x07, 0xab, 0x59, 0xe6, 0x41, 0xb6, 0x30, 0x05, 0x21, 0x64, 0x27, 0xe5, 0xa0, 0xdf, 0xb3, - 0x7a, 0x7d, 0x0c, 0x95, 0xbe, 0x09, 0xeb, 0x89, 0x04, 0xd9, 0x8b, 0x1c, 0xb9, 0x05, 0x1b, 0xa9, - 0x4c, 0x96, 0xd9, 0x3f, 0xc6, 0xb9, 0x6c, 0xc1, 0x6a, 0x22, 0xb1, 0x63, 0x9a, 0x7d, 0xb3, 0x59, - 0x20, 0xdf, 0x81, 0x7b, 0x89, 0x94, 0x34, 0x7f, 0x20, 0xd9, 0x87, 0x22, 0x79, 0x0f, 0xde, 0x4e, - 0x61, 0x47, 0x47, 0xa8, 0xb5, 0xdd, 0x3e, 0x60, 0xdd, 0x6b, 0x96, 0xee, 0xff, 0x41, 0x11, 0x20, - 0xba, 0x99, 0xca, 0xea, 0xdf, 0x6d, 0x0f, 0xdb, 0x07, 0x7d, 0xb6, 0x67, 0xcc, 0xfe, 0x90, 0x95, - 0x6e, 0x76, 0x7e, 0xd8, 0xbc, 0x91, 0x99, 0xd2, 0x3f, 0x62, 0x1d, 0xda, 0x80, 0x15, 0xbe, 0xfe, - 0x0e, 0x58, 0x37, 0xd8, 0x72, 0xe1, 0x51, 0xf7, 0x19, 0x13, 0x72, 0x7c, 0xb4, 0x67, 0xf6, 0x7b, - 0x43, 0x6b, 0xb0, 0x7f, 0x3c, 0xdc, 0xc5, 0x20, 0xfe, 0x3b, 0x66, 0xf7, 0x88, 0x97, 0x59, 0x7c, - 0x19, 0x02, 0x2b, 0xba, 0xc4, 0x36, 0xf8, 0xe3, 0xfe, 0x60, 0xd0, 0x3d, 0xb2, 0x7e, 0x78, 0xdc, - 0x31, 0xbb, 0x9d, 0x01, 0x66, 0x5c, 0xc8, 0x80, 0x33, 0xfc, 0x32, 0x5b, 0xb3, 0xc3, 0x83, 0xa7, - 0xe2, 0xa0, 0x63, 0xa8, 0x95, 0x38, 0x88, 0x61, 0x55, 0xd9, 0xec, 0xb0, 0xc3, 0x39, 0xa3, 0x64, - 0xb8, 0x26, 0x8d, 0xe5, 0xab, 0xb1, 0xa3, 0x34, 0xb5, 0xf3, 0x31, 0x5b, 0x3d, 0x3b, 0x89, 0xe5, - 0x42, 0x8e, 0x44, 0xf1, 0x6f, 0xbb, 0xbb, 0x26, 0x66, 0x58, 0x4c, 0x41, 0x19, 0xee, 0x12, 0x5b, - 0x84, 0xec, 0xf4, 0x66, 0x28, 0x4d, 0xf9, 0xc1, 0x52, 0x96, 0x59, 0x8f, 0xbf, 0x3a, 0x3e, 0xdc, - 0xee, 0x4b, 0x36, 0x80, 0xb7, 0x97, 0x64, 0xc0, 0x19, 0xfe, 0x0a, 0xbe, 0x92, 0xc0, 0xc9, 0x11, - 0x22, 0xae, 0xea, 0x00, 0x86, 0xb1, 0xc6, 0x88, 0xa0, 0x04, 0xfc, 0x7c, 0xc7, 0xec, 0x5b, 0x8c, - 0xcf, 0x42, 0x1e, 0x91, 0xe1, 0xaf, 0x5f, 0x9f, 0xcc, 0x72, 0x6f, 0x3c, 0xfc, 0xa7, 0x6f, 0x41, - 0x55, 0xdd, 0x98, 0x21, 0x3f, 0x80, 0x46, 0x2c, 0x20, 0x05, 0xb9, 0x95, 0x1d, 0xa6, 0x02, 0xa5, - 0xa8, 0xcd, 0x37, 0x5e, 0x16, 0xc3, 0x82, 0x1c, 0x6a, 0x8a, 0x0b, 0x5e, 0xd8, 0x1b, 0x49, 0x65, - 0x42, 0xac, 0xb4, 0xdb, 0xd7, 0xa4, 0x8a, 0xe2, 0x9e, 0xe0, 0x83, 0x04, 0x18, 0xc0, 0x51, 0x1c, - 0x2f, 0xe4, 0x76, 0x14, 0x1d, 0x5e, 0x87, 0xcb, 0x02, 0xa5, 0x98, 0xa8, 0xa5, 0xed, 0xd2, 0xd0, - 0x76, 0x26, 0x01, 0xd9, 0x85, 0x9a, 0xf6, 0xc6, 0x2f, 0xb9, 0x79, 0xed, 0x83, 0xc4, 0x9b, 0x9b, - 0x59, 0x49, 0xa2, 0x49, 0xdf, 0x83, 0xaa, 0x7a, 0xe3, 0x94, 0x6c, 0x68, 0x6f, 0xf0, 0xea, 0x6f, - 0xc3, 0x6e, 0xb6, 0xd2, 0x09, 0x22, 0xff, 0x2e, 0xd4, 0xb4, 0x07, 0x49, 0x55, 0x2b, 0xd2, 0xcf, - 0xa1, 0xaa, 0x56, 0x64, 0xbd, 0x5f, 0x7a, 0x00, 0x6b, 0x42, 0x3d, 0x72, 0x42, 0xbf, 0xce, 0xf0, - 0x90, 0xf4, 0xf0, 0x3c, 0xc8, 0x91, 0x2f, 0xa1, 0x22, 0x9f, 0xc1, 0x25, 0xeb, 0xd9, 0xcf, 0x0a, - 0x6f, 0x6e, 0xa4, 0xe0, 0xa2, 0x29, 0x6d, 0x80, 0xe8, 0x41, 0x53, 0x22, 0x3b, 0x9e, 0x7a, 0x3a, - 0x55, 0xcd, 0x4c, 0xc6, 0xeb, 0xa7, 0xbb, 0x50, 0xd3, 0xde, 0x2e, 0x55, 0x63, 0x92, 0x7e, 0xf7, - 0x54, 0x8d, 0x49, 0xd6, 0x53, 0xa7, 0x3f, 0x80, 0x46, 0xec, 0x11, 0x52, 0xb5, 0x8e, 0xb3, 0x9e, - 0x38, 0x55, 0xeb, 0x38, 0xfb, 0xdd, 0xd2, 0x5d, 0xa8, 0x69, 0x0f, 0x83, 0xaa, 0x16, 0xa5, 0x5f, - 0x27, 0x55, 0x2d, 0xca, 0x78, 0x47, 0x94, 0xed, 0x86, 0xf8, 0xab, 0xa0, 0x6a, 0x37, 0x64, 0x3e, - 0x2f, 0xaa, 0x76, 0x43, 0xf6, 0x53, 0xa2, 0x6c, 0xe9, 0xa9, 0x97, 0x48, 0xc8, 0x46, 0x4c, 0x2b, - 0x11, 0x3d, 0x69, 0xa2, 0x96, 0x5e, 0xfa, 0xd1, 0x92, 0xc7, 0xb0, 0xa2, 0x16, 0x8d, 0x7a, 0x47, - 0x24, 0x50, 0x6d, 0xca, 0x7c, 0xad, 0x64, 0xb3, 0x99, 0x4c, 0x7d, 0x90, 0x23, 0x9f, 0x43, 0x59, - 0x3c, 0xce, 0x40, 0xd6, 0x92, 0x8f, 0x35, 0xf0, 0x46, 0xac, 0x67, 0xbf, 0xe1, 0x40, 0x8e, 0x70, - 0x43, 0xeb, 0xaf, 0x27, 0xe8, 0x2b, 0x36, 0xe3, 0xc1, 0x85, 0xcd, 0x37, 0xaf, 0x4b, 0x8e, 0x4a, - 0x4c, 0xbe, 0xf8, 0x71, 0xfb, 0xba, 0xc0, 0x5a, 0xf1, 0x12, 0xaf, 0x8b, 0x00, 0xfa, 0x18, 0xea, - 0xfa, 0x8b, 0x70, 0x44, 0xdf, 0x87, 0xc9, 0xb2, 0x6e, 0x65, 0xa6, 0x89, 0x82, 0x9e, 0xc2, 0xba, - 0x1a, 0x6f, 0x3d, 0xca, 0x53, 0x40, 0xee, 0x64, 0xc4, 0x7e, 0x8a, 0x8d, 0xfa, 0xcd, 0x6b, 0x83, - 0x43, 0x3d, 0xc8, 0x21, 0x91, 0x8d, 0x3d, 0xe2, 0x14, 0x11, 0xd9, 0xac, 0xb7, 0xab, 0x22, 0x22, - 0x9b, 0xfd, 0xf2, 0x53, 0x1b, 0x96, 0xb4, 0x28, 0x55, 0x83, 0x2b, 0x77, 0xa4, 0xd6, 0x7b, 0x3a, - 0x5c, 0xfd, 0x66, 0x96, 0x92, 0x9e, 0xec, 0x40, 0x4d, 0x0f, 0x74, 0xf5, 0x92, 0xec, 0x1b, 0x5a, - 0x92, 0x1e, 0x45, 0xfc, 0x41, 0x8e, 0x1c, 0x40, 0x33, 0x19, 0x96, 0x56, 0x6d, 0xe1, 0xac, 0x50, - 0xbe, 0x9b, 0x89, 0xc4, 0x58, 0x30, 0x5b, 0xb6, 0x2e, 0x44, 0xd5, 0xfc, 0xfd, 0x55, 0xcf, 0x4f, - 0x1e, 0x45, 0x1c, 0x2e, 0x87, 0x41, 0x95, 0x96, 0x48, 0xc5, 0x66, 0xdf, 0xcb, 0x3d, 0xc8, 0x91, - 0x3d, 0xa8, 0xc7, 0xa2, 0x32, 0xc6, 0x2e, 0x6f, 0x25, 0xba, 0xd9, 0xd2, 0xd3, 0x12, 0xfd, 0x3c, - 0x84, 0xc5, 0xb8, 0xd3, 0x89, 0x6a, 0x58, 0xa6, 0x67, 0x8c, 0x9a, 0xbe, 0x6c, 0x4f, 0x15, 0xf2, - 0xb3, 0x50, 0x63, 0x34, 0x59, 0x7a, 0x46, 0x12, 0x8d, 0x4e, 0x27, 0xe7, 0x8c, 0xc3, 0x84, 0xd6, - 0xbc, 0xf0, 0x17, 0xf3, 0x39, 0xec, 0xd7, 0x77, 0xf9, 0x8b, 0xf3, 0xd2, 0x39, 0x8e, 0xcd, 0xff, - 0xeb, 0x16, 0x42, 0xf6, 0x78, 0xe5, 0x43, 0x8f, 0xc7, 0x64, 0xb8, 0xa9, 0xe1, 0x08, 0xd8, 0xeb, - 0xb5, 0xa1, 0xcd, 0xdb, 0x20, 0xf2, 0xc4, 0xd6, 0xe0, 0x6b, 0x96, 0x45, 0x3e, 0x03, 0x88, 0x9c, - 0x92, 0x49, 0xc2, 0xef, 0x55, 0x6d, 0xa8, 0x0c, 0xbf, 0xe5, 0x0e, 0xdf, 0xef, 0xca, 0xf1, 0x56, - 0x3f, 0x92, 0xe3, 0x3e, 0xc0, 0xb1, 0x23, 0x39, 0x59, 0xcc, 0xc7, 0xd0, 0x38, 0xf0, 0xbc, 0xe7, - 0xf3, 0x99, 0xba, 0xaa, 0x13, 0x77, 0xfb, 0xda, 0xb7, 0x83, 0xf3, 0xcd, 0x44, 0xb3, 0x48, 0x1b, - 0x96, 0x15, 0x89, 0x88, 0x3c, 0x7f, 0xe3, 0x48, 0x31, 0xc2, 0x90, 0x28, 0xe0, 0x41, 0x8e, 0x3c, - 0x84, 0xfa, 0x2e, 0x1d, 0x61, 0xdc, 0x18, 0x74, 0x03, 0x5a, 0x89, 0xb9, 0x94, 0x70, 0xff, 0xa1, - 0xcd, 0x46, 0x0c, 0x28, 0x49, 0x5c, 0xe4, 0xe8, 0xa6, 0x9f, 0x19, 0x71, 0x6f, 0xb1, 0x18, 0x89, - 0x4b, 0x39, 0xbb, 0x3d, 0x85, 0xe5, 0x94, 0xb3, 0x97, 0xa2, 0x6e, 0xd7, 0x39, 0xa0, 0x6d, 0xde, - 0xbd, 0x1e, 0x41, 0x94, 0xfb, 0x7d, 0x68, 0xf0, 0xa0, 0xf2, 0x27, 0x94, 0xdf, 0xfb, 0x4e, 0x84, - 0x0c, 0xd4, 0x2f, 0x95, 0x27, 0x49, 0x12, 0xcf, 0xf0, 0x18, 0x9f, 0xb7, 0xd2, 0x6e, 0x55, 0xab, - 0x79, 0x4d, 0xdf, 0xf4, 0x56, 0xf3, 0x9a, 0x75, 0x81, 0xfb, 0x0b, 0xa8, 0x3d, 0xa6, 0xa1, 0xbc, - 0xa7, 0xac, 0xf8, 0xa3, 0xc4, 0xc5, 0xe5, 0xcd, 0x8c, 0xdb, 0xe5, 0xe4, 0x53, 0xcc, 0xaa, 0x62, - 0x6e, 0xac, 0x6b, 0xb5, 0xe8, 0x59, 0x97, 0x12, 0x70, 0xc6, 0x7d, 0x68, 0x91, 0x77, 0x54, 0xc3, - 0xd3, 0x91, 0x96, 0x54, 0xc3, 0xb3, 0x02, 0xf5, 0xfc, 0x2c, 0x1f, 0x01, 0xed, 0x66, 0x74, 0xc4, - 0x82, 0x25, 0x2f, 0x51, 0xab, 0xe6, 0xeb, 0xe8, 0x8f, 0x00, 0x06, 0xa1, 0x37, 0xdb, 0xb5, 0xe9, - 0xd4, 0x73, 0x23, 0x9a, 0x10, 0xdd, 0xc9, 0x8d, 0x36, 0xa2, 0x76, 0x31, 0x97, 0x7c, 0xa5, 0xf1, - 0xa6, 0xb1, 0x29, 0x91, 0xd3, 0x7e, 0xed, 0xb5, 0x5d, 0xd5, 0x9d, 0x8c, 0xab, 0xbb, 0x48, 0x24, - 0x20, 0xf2, 0xa5, 0x53, 0x9c, 0x66, 0xca, 0x4d, 0x4f, 0xed, 0xf5, 0x0c, 0xc7, 0xbb, 0xef, 0x41, - 0x35, 0x72, 0x42, 0xda, 0x88, 0xc2, 0x80, 0xc5, 0x5c, 0x96, 0x14, 0xf5, 0x4e, 0x3b, 0x00, 0xf5, - 0x60, 0x85, 0x37, 0x47, 0x1d, 0x7f, 0x78, 0x57, 0x53, 0xbd, 0xce, 0x96, 0xf6, 0xbc, 0x51, 0xfb, - 0x27, 0xcb, 0x7f, 0x84, 0xed, 0x9f, 0x94, 0x83, 0x81, 0xda, 0x3f, 0xd7, 0x39, 0x96, 0xa8, 0xfd, - 0x73, 0xbd, 0x6f, 0x42, 0x0f, 0x56, 0x32, 0x5c, 0x05, 0xc8, 0x5b, 0x52, 0xb0, 0xb9, 0xd6, 0x8d, - 0x60, 0x33, 0xd3, 0xa4, 0x4c, 0x86, 0xb0, 0xc1, 0xf3, 0xb4, 0x27, 0x93, 0x84, 0x65, 0xfa, 0x4d, - 0x2d, 0x43, 0x86, 0xb5, 0x3d, 0xc6, 0xca, 0x24, 0x2c, 0xee, 0x3d, 0x68, 0x26, 0x8d, 0xba, 0xe4, - 0x7a, 0xf4, 0xcd, 0x3b, 0x31, 0x96, 0x3d, 0x6d, 0x08, 0x26, 0x4f, 0x95, 0x69, 0x39, 0xd1, 0xc6, - 0x3b, 0xd1, 0x2b, 0xa3, 0x99, 0x86, 0x70, 0x25, 0x0d, 0x64, 0x5a, 0xa6, 0xc9, 0xcf, 0xc1, 0x46, - 0x72, 0x45, 0xcb, 0x92, 0xef, 0x66, 0x0d, 0xd7, 0xb5, 0xac, 0x5c, 0xbc, 0x43, 0x0f, 0x72, 0x8c, - 0x10, 0xeb, 0x06, 0x60, 0xb5, 0x90, 0x32, 0x2c, 0xd1, 0x6a, 0x21, 0x65, 0x5a, 0x8c, 0x8f, 0x60, - 0x29, 0x61, 0xfb, 0x55, 0x6c, 0x70, 0xb6, 0xb5, 0x58, 0xb1, 0xc1, 0xd7, 0x99, 0x8c, 0x07, 0xd0, - 0x4c, 0x5a, 0x75, 0xd5, 0x5c, 0x5f, 0x63, 0x29, 0xde, 0xbc, 0x73, 0x6d, 0x7a, 0xbc, 0x99, 0x9a, - 0xfd, 0x33, 0xd6, 0xcc, 0xb4, 0xd5, 0x36, 0xd6, 0xcc, 0x0c, 0xeb, 0xeb, 0xf6, 0x7b, 0x3f, 0xff, - 0xad, 0x33, 0x27, 0x3c, 0x9f, 0x9f, 0x6c, 0x8d, 0xbc, 0xe9, 0x87, 0x13, 0xa9, 0xd5, 0x10, 0x81, - 0x14, 0x3e, 0x9c, 0xb8, 0xe3, 0x0f, 0xb1, 0x80, 0x93, 0x85, 0x99, 0xef, 0x85, 0xde, 0xc7, 0xff, - 0x37, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xea, 0x86, 0x7c, 0x00, 0x95, 0x00, 0x00, + // 12707 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x5b, 0x6c, 0x23, 0x59, + 0x76, 0x58, 0xf3, 0x25, 0x92, 0x87, 0xa4, 0x44, 0x5d, 0xbd, 0xd8, 0xea, 0xe9, 0xe9, 0x9e, 0x9a, + 0xd9, 0x99, 0xde, 0x9e, 0x19, 0x4d, 0x4f, 0xcf, 0xf4, 0x3c, 0x76, 0xe2, 0xf5, 0x52, 0x12, 0xd5, + 0xe2, 0xb6, 0x44, 0x6a, 0x8b, 0xd4, 0x8c, 0xdb, 0xb0, 0x5d, 0x2e, 0x91, 0x57, 0x52, 0xa5, 0xc9, + 0x2a, 0x6e, 0x55, 0x51, 0x2d, 0x6d, 0x10, 0xc0, 0x1f, 0x8e, 0x1d, 0x18, 0x4e, 0x80, 0x00, 0x71, + 0x80, 0x20, 0x31, 0x92, 0x20, 0x41, 0xf2, 0x67, 0x18, 0xb0, 0xfd, 0x95, 0x7c, 0xe4, 0x2b, 0x41, + 0x80, 0x04, 0x41, 0x80, 0x18, 0x79, 0x7c, 0x24, 0x08, 0x90, 0x38, 0x40, 0x0c, 0x24, 0x06, 0xfc, + 0x99, 0x04, 0x09, 0xee, 0xb9, 0x8f, 0xba, 0xf5, 0x50, 0x77, 0xcf, 0xee, 0x78, 0x7f, 0x24, 0xd6, + 0xb9, 0xe7, 0xbe, 0xef, 0x3d, 0xf7, 0xbc, 0xee, 0xb9, 0x50, 0xf5, 0x67, 0xa3, 0xad, 0x99, 0xef, + 0x85, 0x1e, 0x29, 0x4d, 0x5c, 0x7f, 0x36, 0x32, 0xfe, 0x28, 0x07, 0xc5, 0xe3, 0xf0, 0xd2, 0x23, + 0x8f, 0xa0, 0x6e, 0x8f, 0xc7, 0x3e, 0x0d, 0x02, 0x2b, 0xbc, 0x9a, 0xd1, 0x56, 0xee, 0x6e, 0xee, + 0xde, 0xe2, 0x43, 0xb2, 0x85, 0x68, 0x5b, 0x6d, 0x9e, 0x34, 0xbc, 0x9a, 0x51, 0xb3, 0x66, 0x47, + 0x1f, 0xa4, 0x05, 0x65, 0xf1, 0xd9, 0xca, 0xdf, 0xcd, 0xdd, 0xab, 0x9a, 0xf2, 0x93, 0xdc, 0x06, + 0xb0, 0xa7, 0xde, 0xdc, 0x0d, 0xad, 0xc0, 0x0e, 0x5b, 0x85, 0xbb, 0xb9, 0x7b, 0x05, 0xb3, 0xca, + 0x21, 0x03, 0x3b, 0x24, 0xb7, 0xa0, 0x3a, 0x7b, 0x66, 0x05, 0x23, 0xdf, 0x99, 0x85, 0xad, 0x22, + 0x66, 0xad, 0xcc, 0x9e, 0x0d, 0xf0, 0x9b, 0xbc, 0x0b, 0x15, 0x6f, 0x1e, 0xce, 0x3c, 0xc7, 0x0d, + 0x5b, 0xa5, 0xbb, 0xb9, 0x7b, 0xb5, 0x87, 0x4b, 0xa2, 0x21, 0xfd, 0x79, 0x78, 0xc4, 0xc0, 0xa6, + 0x42, 0x20, 0x6f, 0x41, 0x63, 0xe4, 0xb9, 0xa7, 0x8e, 0x3f, 0xb5, 0x43, 0xc7, 0x73, 0x83, 0xd6, + 0x02, 0xd6, 0x15, 0x07, 0x1a, 0xff, 0x2c, 0x0f, 0xb5, 0xa1, 0x6f, 0xbb, 0x81, 0x3d, 0x62, 0x00, + 0xb2, 0x01, 0xe5, 0xf0, 0xd2, 0x3a, 0xb7, 0x83, 0x73, 0xec, 0x6a, 0xd5, 0x5c, 0x08, 0x2f, 0xf7, + 0xed, 0xe0, 0x9c, 0xac, 0xc3, 0x02, 0x6f, 0x25, 0x76, 0xa8, 0x60, 0x8a, 0x2f, 0xf2, 0x2e, 0x2c, + 0xbb, 0xf3, 0xa9, 0x15, 0xaf, 0x8a, 0x75, 0xab, 0x64, 0x36, 0xdd, 0xf9, 0x74, 0x47, 0x87, 0xb3, + 0xce, 0x9f, 0x4c, 0xbc, 0xd1, 0x33, 0x5e, 0x01, 0xef, 0x5e, 0x15, 0x21, 0x58, 0xc7, 0x1b, 0x50, + 0x17, 0xc9, 0xd4, 0x39, 0x3b, 0xe7, 0x7d, 0x2c, 0x99, 0x35, 0x8e, 0x80, 0x20, 0x56, 0x42, 0xe8, + 0x4c, 0xa9, 0x15, 0x84, 0xf6, 0x74, 0x26, 0xba, 0x54, 0x65, 0x90, 0x01, 0x03, 0x60, 0xb2, 0x17, + 0xda, 0x13, 0xeb, 0x94, 0xd2, 0xa0, 0x55, 0x16, 0xc9, 0x0c, 0xb2, 0x47, 0x69, 0x40, 0xbe, 0x05, + 0x8b, 0x63, 0x1a, 0x84, 0x96, 0x98, 0x0c, 0x1a, 0xb4, 0x2a, 0x77, 0x0b, 0xf7, 0xaa, 0x66, 0x83, + 0x41, 0xdb, 0x12, 0x48, 0x5e, 0x03, 0xf0, 0xed, 0xe7, 0x16, 0x1b, 0x08, 0x7a, 0xd9, 0xaa, 0xf2, + 0x59, 0xf0, 0xed, 0xe7, 0xc3, 0xcb, 0x7d, 0x7a, 0x49, 0x56, 0xa1, 0x34, 0xb1, 0x4f, 0xe8, 0xa4, + 0x05, 0x98, 0xc0, 0x3f, 0x8c, 0x10, 0xd6, 0x1f, 0xd3, 0x50, 0x1b, 0xca, 0xc0, 0xa4, 0x3f, 0x9c, + 0xd3, 0x20, 0x64, 0xbd, 0x0a, 0x42, 0xdb, 0x0f, 0x65, 0xaf, 0x72, 0xbc, 0x57, 0x08, 0x8b, 0x7a, + 0x45, 0xdd, 0xb1, 0x44, 0xc8, 0x23, 0x42, 0x95, 0xba, 0x63, 0x91, 0xcc, 0x56, 0xd3, 0x68, 0x84, + 0x83, 0x5f, 0x10, 0xab, 0x89, 0x7f, 0x1a, 0x07, 0x40, 0xb4, 0x2a, 0x77, 0x69, 0x68, 0x3b, 0x93, + 0x80, 0x7c, 0x02, 0xf5, 0x50, 0x6b, 0x48, 0x2b, 0x77, 0xb7, 0x70, 0xaf, 0xa6, 0x16, 0xad, 0x96, + 0xc1, 0x8c, 0xe1, 0x19, 0xe7, 0x50, 0xd9, 0xa3, 0xf4, 0xc0, 0x99, 0x3a, 0x21, 0x59, 0x87, 0xd2, + 0xa9, 0x73, 0x49, 0xc7, 0xd8, 0xdc, 0xc2, 0xfe, 0x0d, 0x93, 0x7f, 0x92, 0x3b, 0x00, 0xf8, 0xc3, + 0x9a, 0xaa, 0xf5, 0xbb, 0x7f, 0xc3, 0xac, 0x22, 0xec, 0x30, 0xb0, 0x43, 0xb2, 0x09, 0xe5, 0x19, + 0xf5, 0x47, 0x54, 0xae, 0x94, 0xfd, 0x1b, 0xa6, 0x04, 0x6c, 0x97, 0xa1, 0x34, 0x61, 0xa5, 0x1b, + 0xff, 0xa3, 0x04, 0xb5, 0x01, 0x75, 0xc7, 0x72, 0x8c, 0x08, 0x14, 0xd9, 0x14, 0x60, 0x65, 0x75, + 0x13, 0x7f, 0x93, 0x37, 0xa1, 0x86, 0x93, 0x15, 0x84, 0xbe, 0xe3, 0x9e, 0xf1, 0x7d, 0xb4, 0x9d, + 0x6f, 0xe5, 0x4c, 0x60, 0xe0, 0x01, 0x42, 0x49, 0x13, 0x0a, 0xf6, 0x54, 0xee, 0x23, 0xf6, 0x93, + 0xdc, 0x84, 0x8a, 0x3d, 0x0d, 0x79, 0xf3, 0xea, 0x08, 0x2e, 0xdb, 0xd3, 0x10, 0x9b, 0xf6, 0x06, + 0xd4, 0x67, 0xf6, 0xd5, 0x94, 0xba, 0x61, 0xb4, 0x00, 0xeb, 0x66, 0x4d, 0xc0, 0x70, 0x09, 0x3e, + 0x84, 0x15, 0x1d, 0x45, 0x56, 0x5e, 0x52, 0x95, 0x2f, 0x6b, 0xd8, 0xa2, 0x0d, 0xef, 0xc0, 0x92, + 0xcc, 0xe3, 0xf3, 0xfe, 0xe0, 0xc2, 0xac, 0x9a, 0x8b, 0x02, 0x2c, 0x7b, 0x79, 0x0f, 0x9a, 0xa7, + 0x8e, 0x6b, 0x4f, 0xac, 0xd1, 0x24, 0xbc, 0xb0, 0xc6, 0x74, 0x12, 0xda, 0xb8, 0x46, 0x4b, 0xe6, + 0x22, 0xc2, 0x77, 0x26, 0xe1, 0xc5, 0x2e, 0x83, 0x92, 0xf7, 0xa0, 0x7a, 0x4a, 0xa9, 0x85, 0x83, + 0xd5, 0xaa, 0xc4, 0xb6, 0xba, 0x9c, 0x21, 0xb3, 0x72, 0x2a, 0xe7, 0xea, 0x3d, 0x68, 0x7a, 0xf3, + 0xf0, 0xcc, 0x73, 0xdc, 0x33, 0x6b, 0x74, 0x6e, 0xbb, 0x96, 0x33, 0xc6, 0x55, 0x5b, 0xdc, 0xce, + 0x3f, 0xc8, 0x99, 0x8b, 0x32, 0x6d, 0xe7, 0xdc, 0x76, 0xbb, 0x63, 0xf2, 0x36, 0x2c, 0x4d, 0xec, + 0x20, 0xb4, 0xce, 0xbd, 0x99, 0x35, 0x9b, 0x9f, 0x3c, 0xa3, 0x57, 0xad, 0x06, 0x0e, 0x44, 0x83, + 0x81, 0xf7, 0xbd, 0xd9, 0x11, 0x02, 0xd9, 0xa2, 0xc4, 0x76, 0xf2, 0x46, 0xb0, 0xc5, 0xde, 0x30, + 0xab, 0x0c, 0xc2, 0x2b, 0x7d, 0x0a, 0x2b, 0x38, 0x3d, 0xa3, 0x79, 0x10, 0x7a, 0x53, 0xcb, 0xa7, + 0x23, 0xcf, 0x1f, 0x07, 0xad, 0x1a, 0xae, 0xb5, 0x6f, 0x8b, 0xc6, 0x6a, 0x73, 0xbc, 0xb5, 0x4b, + 0x83, 0x70, 0x07, 0x91, 0x4d, 0x8e, 0xdb, 0x71, 0x43, 0xff, 0xca, 0x5c, 0x1e, 0x27, 0xe1, 0xe4, + 0x3d, 0x20, 0xf6, 0x64, 0xe2, 0x3d, 0xb7, 0x02, 0x3a, 0x39, 0xb5, 0xc4, 0x20, 0xb6, 0x16, 0xef, + 0xe6, 0xee, 0x55, 0xcc, 0x26, 0xa6, 0x0c, 0xe8, 0xe4, 0xf4, 0x88, 0xc3, 0xc9, 0x27, 0x80, 0xdb, + 0xd7, 0x3a, 0xa5, 0x76, 0x38, 0xf7, 0x69, 0xd0, 0x5a, 0xba, 0x5b, 0xb8, 0xb7, 0xf8, 0x70, 0x59, + 0x8d, 0x17, 0x82, 0xb7, 0x9d, 0xd0, 0xac, 0x33, 0x3c, 0xf1, 0x1d, 0xe8, 0xab, 0x81, 0xd1, 0x83, + 0x56, 0x33, 0xb6, 0x1a, 0x18, 0x35, 0xd8, 0xdc, 0x85, 0xf5, 0xec, 0x56, 0xb3, 0x75, 0xc7, 0x06, + 0x8e, 0xad, 0xd7, 0xa2, 0xc9, 0x7e, 0x32, 0xb2, 0x70, 0x61, 0x4f, 0xe6, 0x14, 0x17, 0x6a, 0xdd, + 0xe4, 0x1f, 0xdf, 0xc9, 0x7f, 0x96, 0x33, 0x7e, 0x3f, 0x07, 0x75, 0x3e, 0x10, 0xc1, 0xcc, 0x73, + 0x03, 0x4a, 0xde, 0x84, 0x86, 0xac, 0x99, 0xfa, 0xbe, 0xe7, 0x0b, 0x52, 0x2b, 0x9b, 0xd3, 0x61, + 0x30, 0xf2, 0x6d, 0x68, 0x4a, 0xa4, 0x99, 0x4f, 0x9d, 0xa9, 0x7d, 0x26, 0x8b, 0x96, 0xab, 0xed, + 0x48, 0x80, 0xc9, 0x87, 0x51, 0x79, 0xbe, 0x37, 0x0f, 0x29, 0x6e, 0x87, 0xda, 0xc3, 0xba, 0x18, + 0x01, 0x93, 0xc1, 0x54, 0xe9, 0xf8, 0xf5, 0x0a, 0x5b, 0xc1, 0xf8, 0xad, 0x1c, 0x10, 0xd6, 0xec, + 0xa1, 0xc7, 0x0b, 0x88, 0xc8, 0x59, 0x2c, 0x67, 0xee, 0x95, 0x37, 0x51, 0xfe, 0x45, 0x9b, 0xc8, + 0x80, 0x12, 0x6f, 0x7b, 0x31, 0xa3, 0xed, 0x3c, 0xe9, 0xfb, 0xc5, 0x4a, 0xa1, 0x59, 0x34, 0xfe, + 0x63, 0x01, 0x56, 0xd9, 0x52, 0x76, 0xe9, 0xa4, 0x3d, 0x1a, 0xd1, 0x99, 0xda, 0x5e, 0x77, 0xa0, + 0xe6, 0x7a, 0x63, 0x2a, 0x17, 0x35, 0x6f, 0x18, 0x30, 0x90, 0xb6, 0xa2, 0xcf, 0x6d, 0xc7, 0xe5, + 0x0d, 0xe7, 0x83, 0x59, 0x45, 0x08, 0x36, 0xfb, 0x6d, 0x58, 0x9a, 0x51, 0x77, 0xac, 0xef, 0xa2, + 0x02, 0xdf, 0x18, 0x02, 0x2c, 0x36, 0xd0, 0x1d, 0xa8, 0x9d, 0xce, 0x39, 0x1e, 0xa3, 0x3d, 0x45, + 0x5c, 0x03, 0x20, 0x40, 0x6d, 0x4e, 0x82, 0x66, 0xf3, 0xe0, 0x1c, 0x53, 0x4b, 0x98, 0x5a, 0x66, + 0xdf, 0x2c, 0xe9, 0x36, 0xc0, 0x78, 0x1e, 0x84, 0x62, 0x53, 0x2d, 0x60, 0x62, 0x95, 0x41, 0xf8, + 0xa6, 0x7a, 0x1f, 0x56, 0xa6, 0xf6, 0xa5, 0x85, 0x6b, 0xc7, 0x72, 0x5c, 0xeb, 0x74, 0x82, 0x27, + 0x42, 0x19, 0xf1, 0x9a, 0x53, 0xfb, 0xf2, 0x4b, 0x96, 0xd2, 0x75, 0xf7, 0x10, 0xce, 0x28, 0xcf, + 0x88, 0x8f, 0x84, 0xe5, 0xd3, 0x80, 0xfa, 0x17, 0x14, 0x89, 0x45, 0xd1, 0x5c, 0x14, 0x60, 0x93, + 0x43, 0x59, 0x8b, 0xa6, 0xac, 0xdf, 0xe1, 0x64, 0xc4, 0x29, 0x83, 0x59, 0x9e, 0x3a, 0xee, 0x7e, + 0x38, 0x19, 0xb1, 0xc3, 0x8e, 0x91, 0x9a, 0x19, 0xf5, 0xad, 0x67, 0xcf, 0x71, 0x9b, 0x17, 0x91, + 0xb4, 0x1c, 0x51, 0xff, 0xc9, 0x73, 0xc6, 0x8f, 0x8c, 0x02, 0xa4, 0x55, 0xf6, 0x55, 0xab, 0x86, + 0x34, 0xa0, 0x32, 0x0a, 0x18, 0x95, 0xb2, 0xaf, 0xd8, 0x3e, 0x65, 0xad, 0xb5, 0x71, 0x16, 0xe8, + 0x18, 0x8b, 0x0f, 0x90, 0xe8, 0x36, 0xb0, 0xb1, 0x6d, 0x91, 0xc0, 0xea, 0x09, 0xd8, 0xaa, 0x97, + 0x8d, 0x3d, 0x9d, 0xd8, 0x67, 0x01, 0x52, 0x9d, 0x86, 0x59, 0x17, 0xc0, 0x3d, 0x06, 0x33, 0xfe, + 0x34, 0x0f, 0x6b, 0x89, 0xc9, 0x15, 0x9b, 0x86, 0x31, 0x20, 0x08, 0xc1, 0x89, 0xad, 0x98, 0xe2, + 0x2b, 0x6b, 0xd6, 0xf2, 0x59, 0xb3, 0xb6, 0x0a, 0x25, 0xbe, 0xd9, 0xf8, 0x11, 0xca, 0x3f, 0xd8, + 0x2e, 0x9b, 0xcf, 0x4e, 0x7d, 0x8f, 0xf1, 0x63, 0xe7, 0xf3, 0x70, 0xec, 0x3d, 0x77, 0x05, 0x5f, + 0xb2, 0x24, 0xe0, 0x03, 0x01, 0x8e, 0x0f, 0x45, 0x29, 0x31, 0x14, 0x77, 0xa0, 0x26, 0x66, 0x00, + 0xf9, 0x3a, 0x3e, 0xb1, 0x20, 0x40, 0x8c, 0xb1, 0x7b, 0x17, 0x88, 0x9a, 0x4f, 0x8b, 0x8d, 0x1a, + 0x1e, 0x50, 0x7c, 0x62, 0x97, 0x1c, 0x31, 0xa1, 0x87, 0xf6, 0x25, 0x1e, 0x54, 0x6f, 0xc1, 0x22, + 0x43, 0x61, 0xe3, 0x69, 0xf1, 0x73, 0xbf, 0xc2, 0xc7, 0x6a, 0x6a, 0x5f, 0xb2, 0xc1, 0xdc, 0x41, + 0xd6, 0xeb, 0x75, 0xa8, 0xc9, 0x49, 0xb5, 0x1c, 0x57, 0xcc, 0x6b, 0x55, 0xcc, 0x6b, 0xd7, 0x65, + 0xc7, 0x0d, 0x4b, 0xe7, 0xe3, 0x64, 0x8d, 0xe9, 0x2c, 0x3c, 0x17, 0x64, 0x7c, 0x71, 0xea, 0xb8, + 0x7c, 0x78, 0x77, 0x19, 0xd4, 0xf8, 0xed, 0x1c, 0xd4, 0xc5, 0xa8, 0x23, 0x1b, 0x49, 0xb6, 0x80, + 0xc8, 0x25, 0x1e, 0x5e, 0x3a, 0x63, 0xeb, 0xe4, 0x2a, 0xa4, 0x01, 0xdf, 0x51, 0xfb, 0x37, 0xcc, + 0xa6, 0x48, 0x1b, 0x5e, 0x3a, 0xe3, 0x6d, 0x96, 0x42, 0xee, 0x43, 0x33, 0x86, 0x1f, 0x84, 0x3e, + 0xdf, 0xee, 0xfb, 0x37, 0xcc, 0x45, 0x0d, 0x7b, 0x10, 0xfa, 0x8c, 0x80, 0x30, 0x26, 0x75, 0x1e, + 0x5a, 0x8e, 0x3b, 0xa6, 0x97, 0x38, 0x1f, 0x0d, 0xb3, 0xc6, 0x61, 0x5d, 0x06, 0xda, 0x5e, 0x84, + 0xba, 0x5e, 0x9c, 0x71, 0x06, 0x15, 0xc9, 0xe1, 0x22, 0x8b, 0x97, 0x68, 0x92, 0x59, 0x0d, 0x55, + 0x4b, 0x6e, 0x42, 0x25, 0xde, 0x02, 0xb3, 0x1c, 0xbe, 0x72, 0xc5, 0xc6, 0x77, 0xa1, 0x79, 0xc0, + 0x26, 0xc2, 0x65, 0x3b, 0x59, 0x70, 0xec, 0xeb, 0xb0, 0xa0, 0x51, 0x94, 0xaa, 0x29, 0xbe, 0x18, + 0xcf, 0x72, 0xee, 0x05, 0xa1, 0xa8, 0x05, 0x7f, 0x1b, 0xff, 0x3c, 0x07, 0xa4, 0x13, 0x84, 0xce, + 0xd4, 0x0e, 0xe9, 0x1e, 0x55, 0x34, 0xb3, 0x0f, 0x75, 0x56, 0xda, 0xd0, 0x6b, 0x73, 0x16, 0x9a, + 0x33, 0x64, 0xef, 0x0a, 0x1a, 0x97, 0xce, 0xb0, 0xa5, 0x63, 0xf3, 0x63, 0x32, 0x56, 0x00, 0x5b, + 0x6e, 0xa1, 0xed, 0x9f, 0xd1, 0x10, 0x19, 0x6f, 0xc1, 0x31, 0x02, 0x07, 0x31, 0x96, 0x7b, 0xf3, + 0x67, 0x61, 0x39, 0x55, 0x86, 0x7e, 0x68, 0x55, 0x33, 0x0e, 0xad, 0x82, 0x7e, 0x68, 0xfd, 0x7a, + 0x0e, 0x56, 0x62, 0x0d, 0x13, 0xdb, 0x70, 0x03, 0xca, 0x8c, 0x5c, 0xb0, 0xc5, 0x9b, 0xe3, 0x82, + 0xc0, 0x29, 0xc5, 0x05, 0xfe, 0x11, 0xac, 0x9e, 0x52, 0xea, 0xdb, 0x21, 0x26, 0x22, 0x3d, 0x61, + 0x53, 0xc4, 0x4b, 0xe6, 0x54, 0x5f, 0xa4, 0x0f, 0xec, 0xf0, 0x88, 0xfa, 0x6c, 0xba, 0x88, 0x01, + 0x0d, 0x89, 0x7c, 0x81, 0xd8, 0x05, 0x5c, 0xc4, 0xb5, 0x00, 0x51, 0xbe, 0x64, 0x20, 0xe3, 0x8f, + 0xf3, 0xb0, 0xc4, 0xce, 0xa1, 0x43, 0xdb, 0xbd, 0x92, 0x03, 0x7a, 0x90, 0x39, 0xa0, 0xf7, 0x34, + 0xae, 0x43, 0xc3, 0xfe, 0xba, 0xa3, 0x59, 0x48, 0x8e, 0x66, 0xba, 0x99, 0xc5, 0x54, 0x33, 0xc9, + 0x5b, 0x50, 0x8f, 0xf5, 0xbb, 0xa4, 0xfa, 0x0d, 0x41, 0xd4, 0x61, 0x25, 0x3c, 0x2c, 0x68, 0xc2, + 0x03, 0x23, 0x2d, 0x6c, 0xa7, 0xb2, 0xda, 0x03, 0xc1, 0x11, 0x32, 0x7a, 0xcd, 0xea, 0x0e, 0x98, + 0x84, 0x15, 0x30, 0x52, 0x66, 0xcd, 0x5d, 0x21, 0x65, 0xd1, 0x31, 0xd2, 0x83, 0x8a, 0xd9, 0xc4, + 0x84, 0xe3, 0x08, 0xfe, 0x93, 0xcf, 0xfb, 0xdb, 0xd0, 0x8c, 0x86, 0x4f, 0xcc, 0x39, 0x81, 0x22, + 0xdb, 0x43, 0xa2, 0x00, 0xfc, 0x6d, 0xfc, 0x83, 0x3c, 0x47, 0xdc, 0xf1, 0x9c, 0x48, 0xd4, 0x21, + 0x50, 0x44, 0x56, 0x4a, 0x20, 0xb2, 0xdf, 0xd7, 0x0a, 0x8e, 0x3f, 0xc5, 0x41, 0xbf, 0x09, 0x95, + 0x80, 0x0d, 0xa0, 0x3d, 0xe1, 0xe3, 0x5e, 0x31, 0xcb, 0xec, 0xbb, 0x3d, 0x99, 0x44, 0xf3, 0x51, + 0xbe, 0x76, 0x3e, 0x2a, 0xaf, 0x32, 0x1f, 0xd5, 0xec, 0xf9, 0x30, 0xde, 0x81, 0x65, 0x6d, 0x94, + 0x5e, 0x30, 0x9e, 0xe7, 0x40, 0x0e, 0x9c, 0x20, 0x3c, 0x76, 0x59, 0x11, 0x8a, 0xa5, 0x89, 0x35, + 0x24, 0x97, 0x68, 0x08, 0x4b, 0xb4, 0x2f, 0x45, 0x62, 0x5e, 0x24, 0xda, 0x97, 0x3c, 0xf1, 0x7a, + 0x99, 0xf1, 0x33, 0x58, 0x89, 0xd5, 0x24, 0x1a, 0xf5, 0x06, 0x94, 0xe6, 0xe1, 0xa5, 0x27, 0xa5, + 0xc5, 0x9a, 0xd8, 0x4b, 0xc7, 0xe1, 0xa5, 0x67, 0xf2, 0x14, 0xe3, 0x18, 0x96, 0x7b, 0xf4, 0xb9, + 0xa0, 0x8b, 0xb2, 0x89, 0x6f, 0x43, 0xf1, 0x25, 0x9a, 0x11, 0x4c, 0xd7, 0x1b, 0x94, 0x8f, 0x37, + 0x68, 0x0b, 0x88, 0x5e, 0xac, 0x68, 0x8f, 0xa6, 0x42, 0xc9, 0xc5, 0x54, 0x28, 0xc6, 0xdb, 0x40, + 0x06, 0xce, 0x99, 0x7b, 0x48, 0x83, 0xc0, 0x3e, 0x53, 0x34, 0xb6, 0x09, 0x85, 0x69, 0x70, 0x26, + 0x0e, 0x04, 0xf6, 0xd3, 0xf8, 0x08, 0x56, 0x62, 0x78, 0xa2, 0xe0, 0xd7, 0xa0, 0x1a, 0x38, 0x67, + 0x2e, 0x4a, 0x01, 0xa2, 0xe8, 0x08, 0x60, 0xec, 0xc1, 0xea, 0x97, 0xd4, 0x77, 0x4e, 0xaf, 0x5e, + 0x56, 0x7c, 0xbc, 0x9c, 0x7c, 0xb2, 0x9c, 0x0e, 0xac, 0x25, 0xca, 0x11, 0xd5, 0xf3, 0xad, 0x27, + 0x66, 0xbf, 0x62, 0xf2, 0x0f, 0xed, 0x90, 0xc9, 0xeb, 0x87, 0x8c, 0xe1, 0x01, 0xd9, 0xf1, 0x5c, + 0x97, 0x8e, 0xc2, 0x23, 0x4a, 0x7d, 0xd9, 0x98, 0x77, 0xb5, 0x7d, 0x56, 0x7b, 0xb8, 0x21, 0xc6, + 0x3c, 0x79, 0x72, 0x89, 0x0d, 0x48, 0xa0, 0x38, 0xa3, 0xfe, 0x14, 0x0b, 0xae, 0x98, 0xf8, 0x9b, + 0x0d, 0x6e, 0xe8, 0x4c, 0xa9, 0x37, 0x0f, 0x05, 0xc5, 0x95, 0x9f, 0xc6, 0x1a, 0xac, 0xc4, 0x2a, + 0xe4, 0xad, 0x36, 0x1e, 0xc0, 0xda, 0xae, 0x13, 0x8c, 0xd2, 0x4d, 0xd9, 0x80, 0xf2, 0x6c, 0x7e, + 0x62, 0xc5, 0x8f, 0xc7, 0x27, 0xf4, 0xca, 0x68, 0xc1, 0x7a, 0x32, 0x87, 0x28, 0xeb, 0xd7, 0xf2, + 0x50, 0xdc, 0x1f, 0x1e, 0xec, 0x90, 0x4d, 0xa8, 0x38, 0xee, 0xc8, 0x9b, 0x32, 0xe1, 0x80, 0x8f, + 0x86, 0xfa, 0xbe, 0x96, 0x6c, 0xdc, 0x82, 0x2a, 0xca, 0x14, 0x13, 0x6f, 0xf4, 0x4c, 0xb0, 0xe7, + 0x15, 0x06, 0x38, 0xf0, 0x46, 0xcf, 0xd8, 0xd6, 0xa4, 0x97, 0x33, 0xc7, 0x47, 0x75, 0x93, 0x54, + 0xa7, 0x14, 0x39, 0x3f, 0x1a, 0x25, 0x44, 0x4a, 0x17, 0xc1, 0x3a, 0x31, 0x66, 0x80, 0xf3, 0xe9, + 0xd5, 0x73, 0x64, 0x9d, 0xc6, 0xf4, 0x92, 0xbc, 0x0f, 0xe4, 0xd4, 0xf3, 0x9f, 0xdb, 0xbe, 0x62, + 0x2d, 0x5d, 0x41, 0xb6, 0x8b, 0xe6, 0x72, 0x94, 0x22, 0xd8, 0x26, 0xf2, 0x10, 0xd6, 0x34, 0x74, + 0xad, 0x60, 0xce, 0xe2, 0xad, 0x44, 0x89, 0xfb, 0xb2, 0x0a, 0xe3, 0x57, 0xf3, 0x40, 0x44, 0xfe, + 0x1d, 0xcf, 0x0d, 0x42, 0xdf, 0x76, 0xdc, 0x30, 0x88, 0x33, 0x9a, 0xb9, 0x04, 0xa3, 0x79, 0x0f, + 0x9a, 0xc8, 0xe6, 0xea, 0xdc, 0x66, 0x3e, 0xe2, 0xf9, 0xcd, 0x88, 0xe3, 0x7c, 0x0b, 0x16, 0x23, + 0x51, 0x43, 0x69, 0x1b, 0x8b, 0x66, 0x5d, 0x89, 0x1b, 0x0c, 0xeb, 0x03, 0x58, 0x65, 0x44, 0x44, + 0xb2, 0xd0, 0x4a, 0x75, 0xc2, 0x89, 0xed, 0xf2, 0xd4, 0xbe, 0x3c, 0xa2, 0x52, 0xb0, 0x41, 0xde, + 0xd4, 0x80, 0x86, 0xe2, 0x3a, 0x11, 0x93, 0x8f, 0x5c, 0x4d, 0xf0, 0x9d, 0x88, 0x93, 0x2d, 0x18, + 0x2c, 0x64, 0x0b, 0x06, 0xc6, 0xbf, 0xab, 0x42, 0x59, 0x0e, 0x23, 0x72, 0xf9, 0xa1, 0x73, 0x41, + 0x23, 0x2e, 0x9f, 0x7d, 0x31, 0xe1, 0xc1, 0xa7, 0x53, 0x2f, 0x54, 0xd2, 0x1d, 0xdf, 0x26, 0x75, + 0x0e, 0x14, 0xf2, 0x9d, 0x26, 0x61, 0x70, 0x25, 0x29, 0xa7, 0x7c, 0x52, 0xc2, 0xe0, 0xfc, 0xe3, + 0x2d, 0x28, 0x4b, 0x39, 0xa1, 0xa8, 0x74, 0x24, 0x0b, 0x23, 0x2e, 0x24, 0x6c, 0x42, 0x65, 0x64, + 0xcf, 0xec, 0x91, 0x13, 0x72, 0x16, 0xbf, 0x60, 0xaa, 0x6f, 0x56, 0xfa, 0xc4, 0x1b, 0xd9, 0x13, + 0xeb, 0xc4, 0x9e, 0xd8, 0xee, 0x88, 0x0a, 0xed, 0x63, 0x1d, 0x81, 0xdb, 0x1c, 0x46, 0xbe, 0x05, + 0x8b, 0xa2, 0x9d, 0x12, 0x8b, 0x2b, 0x21, 0x45, 0xeb, 0x25, 0x1a, 0x93, 0x44, 0xbd, 0x29, 0x9b, + 0x97, 0x53, 0xca, 0x65, 0xb6, 0x82, 0x59, 0xe5, 0x90, 0x3d, 0x8a, 0xbd, 0x15, 0xc9, 0xcf, 0xf9, + 0x1a, 0xae, 0xf2, 0xaa, 0x38, 0xf0, 0x2b, 0xbe, 0x7e, 0xd3, 0x82, 0x5b, 0x41, 0x13, 0xdc, 0xde, + 0x85, 0xe5, 0xb9, 0x1b, 0xd0, 0x30, 0x9c, 0xd0, 0xb1, 0x6a, 0x4b, 0x0d, 0x91, 0x9a, 0x2a, 0x41, + 0x36, 0x67, 0x0b, 0x56, 0xb8, 0xda, 0x34, 0xb0, 0x43, 0x2f, 0x38, 0x77, 0x02, 0x2b, 0xa0, 0xae, + 0x54, 0x9f, 0x2d, 0x63, 0xd2, 0x40, 0xa4, 0x0c, 0xb8, 0xca, 0x65, 0x23, 0x81, 0xef, 0xd3, 0x11, + 0x75, 0x2e, 0xe8, 0x18, 0x85, 0xba, 0x82, 0xb9, 0x16, 0xcb, 0x63, 0x8a, 0x44, 0x94, 0xd0, 0xe7, + 0x53, 0x6b, 0x3e, 0x1b, 0xdb, 0x8c, 0x79, 0x5f, 0xe4, 0x52, 0x92, 0x3b, 0x9f, 0x1e, 0x73, 0x08, + 0x79, 0x00, 0x52, 0x6a, 0x13, 0x6b, 0x66, 0x29, 0x76, 0x18, 0x31, 0xaa, 0x61, 0xd6, 0x05, 0x06, + 0x97, 0x2a, 0xef, 0xe8, 0x9b, 0xa5, 0xc9, 0x56, 0x18, 0x1e, 0xff, 0xd1, 0x86, 0x69, 0x41, 0x79, + 0xe6, 0x3b, 0x17, 0x76, 0x48, 0x5b, 0xcb, 0xfc, 0xec, 0x17, 0x9f, 0x8c, 0x80, 0x3b, 0xae, 0x13, + 0x3a, 0x76, 0xe8, 0xf9, 0x2d, 0x82, 0x69, 0x11, 0x80, 0xdc, 0x87, 0x65, 0x5c, 0x27, 0x41, 0x68, + 0x87, 0xf3, 0x40, 0x88, 0xac, 0x2b, 0x5c, 0x34, 0x64, 0x09, 0x03, 0x84, 0xa3, 0xd4, 0x4a, 0x3e, + 0x85, 0x75, 0xbe, 0x34, 0x52, 0x5b, 0x73, 0x55, 0x31, 0x24, 0x2b, 0x88, 0xb1, 0x13, 0xdf, 0xa3, + 0x9f, 0xc3, 0x86, 0x58, 0x2e, 0xa9, 0x9c, 0x6b, 0x2a, 0xe7, 0x2a, 0x47, 0x49, 0x64, 0xdd, 0x82, + 0x65, 0xd6, 0x34, 0x67, 0x64, 0x89, 0x12, 0xd8, 0xae, 0x58, 0x67, 0xbd, 0xc0, 0x4c, 0x4b, 0x3c, + 0xd1, 0xc4, 0xb4, 0x27, 0xf4, 0x8a, 0x7c, 0x17, 0x96, 0xf8, 0xf2, 0x41, 0xbd, 0x0c, 0x1e, 0xd9, + 0x9b, 0x78, 0x64, 0xaf, 0x89, 0xc1, 0xdd, 0x51, 0xa9, 0x78, 0x6a, 0x2f, 0x8e, 0x62, 0xdf, 0x6c, + 0x6b, 0x4c, 0x9c, 0x53, 0xca, 0xce, 0x89, 0xd6, 0x06, 0x5f, 0x6c, 0xf2, 0x9b, 0xed, 0xda, 0xf9, + 0x0c, 0x53, 0x5a, 0x9c, 0x58, 0xf3, 0x2f, 0x5c, 0xc7, 0x13, 0x2f, 0xa0, 0x52, 0xe1, 0xde, 0xba, + 0x29, 0x36, 0x24, 0x03, 0x4a, 0xf9, 0x8a, 0x09, 0xf0, 0x5c, 0x5b, 0xa2, 0xcc, 0x22, 0xb7, 0x70, + 0x61, 0x34, 0xb8, 0xd2, 0x44, 0x9a, 0x46, 0x18, 0xc3, 0x78, 0x6e, 0x3f, 0x97, 0x64, 0xfd, 0x35, + 0xa4, 0x26, 0xc0, 0x40, 0x82, 0xa0, 0xef, 0xc1, 0xb2, 0x98, 0x85, 0x88, 0x98, 0xb6, 0x6e, 0xe3, + 0x11, 0x79, 0x53, 0xf6, 0x31, 0x45, 0x6d, 0xcd, 0x26, 0x9f, 0x17, 0x8d, 0xfe, 0xee, 0x03, 0x91, + 0x93, 0xa2, 0x15, 0xf4, 0xfa, 0xcb, 0x0a, 0x5a, 0x16, 0xd3, 0x14, 0x81, 0x8c, 0xdf, 0xcb, 0x71, + 0x5e, 0x4b, 0x60, 0x07, 0x9a, 0xa6, 0x8a, 0xd3, 0x35, 0xcb, 0x73, 0x27, 0x57, 0x82, 0xd4, 0x01, + 0x07, 0xf5, 0xdd, 0x09, 0xd2, 0x1a, 0xc7, 0xd5, 0x51, 0xf8, 0xe1, 0x5d, 0x97, 0x40, 0x44, 0xba, + 0x03, 0xb5, 0xd9, 0xfc, 0x64, 0xe2, 0x8c, 0x38, 0x4a, 0x81, 0x97, 0xc2, 0x41, 0x88, 0xf0, 0x06, + 0xd4, 0xc5, 0x5a, 0xe7, 0x18, 0x45, 0xc4, 0xa8, 0x09, 0x18, 0xa2, 0x20, 0x73, 0x40, 0x7d, 0x24, + 0x76, 0x75, 0x13, 0x7f, 0x1b, 0xdb, 0xb0, 0x1a, 0x6f, 0xb4, 0xe0, 0x5c, 0xee, 0x43, 0x45, 0x50, + 0x52, 0xa9, 0xe6, 0x5d, 0x8c, 0x8f, 0x86, 0xa9, 0xd2, 0x8d, 0x7f, 0x5f, 0x82, 0x15, 0x39, 0x46, + 0x6c, 0xb2, 0x07, 0xf3, 0xe9, 0xd4, 0xf6, 0x33, 0x48, 0x74, 0xee, 0xc5, 0x24, 0x3a, 0x9f, 0x22, + 0xd1, 0x71, 0x25, 0x1e, 0xa7, 0xf0, 0x71, 0x25, 0x1e, 0x5b, 0x5d, 0x5c, 0x75, 0xa0, 0xdb, 0x99, + 0x1a, 0x02, 0x3c, 0xe4, 0xf6, 0xac, 0xd4, 0x81, 0x52, 0xca, 0x38, 0x50, 0xf4, 0xe3, 0x60, 0x21, + 0x71, 0x1c, 0xbc, 0x01, 0x7c, 0x19, 0xcb, 0xf5, 0x58, 0xe6, 0xda, 0x04, 0x84, 0x89, 0x05, 0xf9, + 0x0e, 0x2c, 0x25, 0x29, 0x30, 0x27, 0xf5, 0x8b, 0x19, 0xf4, 0xd7, 0x99, 0x52, 0x64, 0x6a, 0x34, + 0xe4, 0xaa, 0xa0, 0xbf, 0xce, 0x94, 0x1e, 0x60, 0x8a, 0xc4, 0xef, 0x00, 0xf0, 0xba, 0x71, 0x1b, + 0x03, 0x6e, 0xe3, 0xb7, 0x13, 0x2b, 0x53, 0x1b, 0xf5, 0x2d, 0xf6, 0x31, 0xf7, 0x29, 0xee, 0xeb, + 0x2a, 0xe6, 0xc4, 0x2d, 0xfd, 0x29, 0x2c, 0x7a, 0x33, 0xea, 0x5a, 0x11, 0x15, 0xac, 0x61, 0x51, + 0x4d, 0x51, 0x54, 0x57, 0xc2, 0xcd, 0x06, 0xc3, 0x53, 0x9f, 0xe4, 0x73, 0x3e, 0xc8, 0x54, 0xcb, + 0x59, 0xbf, 0x26, 0xe7, 0x22, 0x22, 0x46, 0x59, 0x3f, 0x42, 0x45, 0x99, 0x37, 0x99, 0x73, 0xd3, + 0x54, 0x03, 0xd7, 0x91, 0xd4, 0xd5, 0x9b, 0x2a, 0xc5, 0xd4, 0xb1, 0x8c, 0xdf, 0xc8, 0x41, 0x4d, + 0xeb, 0x03, 0x59, 0x83, 0xe5, 0x9d, 0x7e, 0xff, 0xa8, 0x63, 0xb6, 0x87, 0xdd, 0x2f, 0x3b, 0xd6, + 0xce, 0x41, 0x7f, 0xd0, 0x69, 0xde, 0x60, 0xe0, 0x83, 0xfe, 0x4e, 0xfb, 0xc0, 0xda, 0xeb, 0x9b, + 0x3b, 0x12, 0x9c, 0x23, 0xeb, 0x40, 0xcc, 0xce, 0x61, 0x7f, 0xd8, 0x89, 0xc1, 0xf3, 0xa4, 0x09, + 0xf5, 0x6d, 0xb3, 0xd3, 0xde, 0xd9, 0x17, 0x90, 0x02, 0x59, 0x85, 0xe6, 0xde, 0x71, 0x6f, 0xb7, + 0xdb, 0x7b, 0x6c, 0xed, 0xb4, 0x7b, 0x3b, 0x9d, 0x83, 0xce, 0x6e, 0xb3, 0x48, 0x1a, 0x50, 0x6d, + 0x6f, 0xb7, 0x7b, 0xbb, 0xfd, 0x5e, 0x67, 0xb7, 0x59, 0x32, 0xfe, 0x38, 0x07, 0x10, 0x35, 0x94, + 0xd1, 0xd5, 0xa8, 0xa9, 0xba, 0x91, 0x78, 0x2d, 0xd5, 0x29, 0x4e, 0x57, 0xfd, 0xd8, 0x37, 0x79, + 0x08, 0x65, 0x6f, 0x1e, 0x8e, 0xbc, 0x29, 0x17, 0x22, 0x16, 0x1f, 0xb6, 0x52, 0xf9, 0xfa, 0x3c, + 0xdd, 0x94, 0x88, 0x31, 0x43, 0x70, 0xe1, 0x65, 0x86, 0xe0, 0xb8, 0xc5, 0x99, 0xf3, 0x75, 0x9a, + 0xc5, 0xf9, 0x36, 0x40, 0xf0, 0x9c, 0xd2, 0x19, 0x6a, 0xda, 0xc4, 0x2e, 0xa8, 0x22, 0x64, 0xc8, + 0xe4, 0xd2, 0xff, 0x94, 0x83, 0x35, 0x5c, 0x4b, 0xe3, 0x24, 0x11, 0xbb, 0x0b, 0xb5, 0x91, 0xe7, + 0xcd, 0x28, 0x63, 0xaa, 0x15, 0xbf, 0xa6, 0x83, 0x18, 0x81, 0xe2, 0x04, 0xf9, 0xd4, 0xf3, 0x47, + 0x54, 0xd0, 0x30, 0x40, 0xd0, 0x1e, 0x83, 0xb0, 0x3d, 0x24, 0x36, 0x21, 0xc7, 0xe0, 0x24, 0xac, + 0xc6, 0x61, 0x1c, 0x65, 0x1d, 0x16, 0x4e, 0x7c, 0x6a, 0x8f, 0xce, 0x05, 0xf5, 0x12, 0x5f, 0xe4, + 0xdb, 0x91, 0xc6, 0x71, 0xc4, 0xf6, 0xc4, 0x84, 0xf2, 0xc6, 0x57, 0xcc, 0x25, 0x01, 0xdf, 0x11, + 0x60, 0x76, 0xce, 0xdb, 0x27, 0xb6, 0x3b, 0xf6, 0x5c, 0x3a, 0x16, 0xf2, 0x7f, 0x04, 0x30, 0x8e, + 0x60, 0x3d, 0xd9, 0x3f, 0x41, 0xef, 0x3e, 0xd1, 0xe8, 0x1d, 0x17, 0x8a, 0x37, 0xaf, 0xdf, 0x63, + 0x1a, 0xed, 0xfb, 0xcf, 0x45, 0x28, 0x32, 0x81, 0xe7, 0x5a, 0xd9, 0x48, 0x97, 0x6d, 0x0b, 0x29, + 0xf7, 0x00, 0x54, 0x6c, 0x72, 0x06, 0x4c, 0x4c, 0x16, 0x42, 0x90, 0xf1, 0x52, 0xc9, 0x3e, 0x1d, + 0x5d, 0x48, 0x99, 0x05, 0x21, 0x26, 0x1d, 0x5d, 0xa0, 0xa2, 0xc3, 0x0e, 0x79, 0x5e, 0x4e, 0xaf, + 0xca, 0x81, 0x1d, 0x62, 0x4e, 0x91, 0x84, 0xf9, 0xca, 0x2a, 0x09, 0x73, 0xb5, 0xa0, 0xec, 0xb8, + 0x27, 0xde, 0xdc, 0x95, 0x6a, 0x25, 0xf9, 0x89, 0xde, 0x08, 0x48, 0x49, 0xd9, 0xd1, 0xce, 0xa9, + 0x51, 0x85, 0x01, 0x86, 0xec, 0x70, 0xff, 0x10, 0xaa, 0xc1, 0x95, 0x3b, 0xd2, 0x69, 0xd0, 0xaa, + 0x18, 0x1f, 0xd6, 0xfb, 0xad, 0xc1, 0x95, 0x3b, 0xc2, 0x15, 0x5f, 0x09, 0xc4, 0x2f, 0xf2, 0x08, + 0x2a, 0xca, 0x4a, 0xc7, 0x4f, 0x90, 0x9b, 0x7a, 0x0e, 0x69, 0x9a, 0xe3, 0x3a, 0x3a, 0x85, 0x4a, + 0x3e, 0x80, 0x05, 0xd4, 0xd6, 0x07, 0xad, 0x3a, 0x66, 0x92, 0x02, 0x2f, 0x6b, 0x06, 0x3a, 0x02, + 0xd0, 0x31, 0xda, 0xcc, 0x4c, 0x81, 0xc6, 0x86, 0xe9, 0x74, 0x62, 0xcf, 0x84, 0xee, 0xbc, 0xc1, + 0xed, 0xe9, 0x0c, 0xc2, 0x15, 0xe7, 0x77, 0xa1, 0x8e, 0x16, 0x50, 0xc4, 0x71, 0x39, 0x1f, 0x5a, + 0x30, 0x81, 0xc1, 0xf6, 0x26, 0xf6, 0xac, 0x17, 0x6c, 0x3e, 0x81, 0x46, 0xac, 0x31, 0xba, 0x0a, + 0xad, 0xc1, 0x55, 0x68, 0x6f, 0xe9, 0x2a, 0xb4, 0xe8, 0x28, 0x14, 0xd9, 0x74, 0x95, 0xda, 0x11, + 0x54, 0xe4, 0x58, 0x30, 0x9a, 0x73, 0xdc, 0x7b, 0xd2, 0xeb, 0x7f, 0xd5, 0xb3, 0x06, 0x4f, 0x7b, + 0x3b, 0xcd, 0x1b, 0x64, 0x09, 0x6a, 0xed, 0x1d, 0x24, 0x63, 0x08, 0xc8, 0x31, 0x94, 0xa3, 0xf6, + 0x60, 0xa0, 0x20, 0x79, 0x86, 0x72, 0xd4, 0xed, 0xf5, 0x3a, 0xbb, 0x1c, 0x50, 0x30, 0xf6, 0xa0, + 0x99, 0xec, 0x3b, 0x5b, 0xe5, 0xa1, 0x84, 0x09, 0xbb, 0x64, 0x04, 0x88, 0xac, 0x1f, 0x79, 0xcd, + 0xfa, 0x61, 0x3c, 0x82, 0x26, 0x3b, 0xe9, 0xd9, 0xe0, 0xeb, 0xee, 0x0a, 0x13, 0xc6, 0x8b, 0xeb, + 0xb6, 0xc9, 0x8a, 0x59, 0xe3, 0x30, 0xac, 0xca, 0xf8, 0x04, 0x96, 0xb5, 0x6c, 0x91, 0xfe, 0x88, + 0x71, 0x0f, 0x49, 0xfd, 0x11, 0x4a, 0xfe, 0x3c, 0xc5, 0xd8, 0x80, 0x35, 0xf6, 0xd9, 0xb9, 0xa0, + 0x6e, 0x38, 0x98, 0x9f, 0x70, 0x2f, 0x17, 0xc7, 0x73, 0x8d, 0x5f, 0xcd, 0x41, 0x55, 0xa5, 0x5c, + 0xbf, 0x6d, 0xb6, 0x84, 0xaa, 0x89, 0xd3, 0xc9, 0x4d, 0xad, 0x06, 0xcc, 0xb8, 0x85, 0x7f, 0x23, + 0x95, 0x93, 0xb1, 0x05, 0x55, 0x05, 0xc2, 0x41, 0xec, 0x74, 0x4c, 0xab, 0xdf, 0x3b, 0xe8, 0xf6, + 0xd8, 0x69, 0xc1, 0xc6, 0x19, 0x01, 0x7b, 0x7b, 0x08, 0xc9, 0x19, 0x4d, 0x58, 0x7c, 0x4c, 0xc3, + 0xae, 0x7b, 0xea, 0x89, 0xc1, 0x30, 0x7e, 0x7d, 0x01, 0x96, 0x14, 0x28, 0x52, 0x4c, 0x5d, 0x50, + 0x3f, 0x70, 0x3c, 0x17, 0x17, 0x4e, 0xd5, 0x94, 0x9f, 0x8c, 0xde, 0x09, 0xb1, 0x0d, 0xf9, 0x8e, + 0x55, 0x4c, 0x15, 0x82, 0x1e, 0x32, 0x1d, 0xef, 0xc0, 0x92, 0x33, 0xa6, 0x6e, 0xe8, 0x84, 0x57, + 0x56, 0xcc, 0xa6, 0xb0, 0x28, 0xc1, 0x82, 0xf1, 0x58, 0x85, 0x92, 0x3d, 0x71, 0x6c, 0xe9, 0x3d, + 0xc4, 0x3f, 0x18, 0x74, 0xe4, 0x4d, 0x3c, 0x1f, 0x05, 0x99, 0xaa, 0xc9, 0x3f, 0xc8, 0x03, 0x58, + 0x65, 0x42, 0x95, 0x6e, 0x04, 0x43, 0x92, 0xc5, 0xcd, 0x1b, 0xc4, 0x9d, 0x4f, 0x8f, 0x22, 0x43, + 0x18, 0x4b, 0x61, 0xec, 0x06, 0xcb, 0x21, 0xf8, 0x4b, 0x95, 0x81, 0x2b, 0x4a, 0x96, 0xdd, 0xf9, + 0xb4, 0x8d, 0x29, 0x0a, 0xff, 0x21, 0xac, 0x31, 0x7c, 0xc5, 0x91, 0xaa, 0x1c, 0x4b, 0x98, 0x83, + 0x15, 0xd6, 0x15, 0x69, 0x2a, 0xcf, 0x2d, 0xa8, 0xf2, 0x56, 0xb1, 0x25, 0x21, 0xac, 0x65, 0xd8, + 0x14, 0xea, 0x07, 0x29, 0x47, 0x1f, 0xae, 0x19, 0x48, 0x3a, 0xfa, 0x68, 0xae, 0x42, 0x95, 0xa4, + 0xab, 0xd0, 0x43, 0x58, 0x3b, 0x61, 0x6b, 0xf4, 0x9c, 0xda, 0x63, 0xea, 0x5b, 0xd1, 0xca, 0xe7, + 0xf2, 0xe7, 0x0a, 0x4b, 0xdc, 0xc7, 0x34, 0xb5, 0x51, 0x18, 0x6b, 0xc8, 0x28, 0x11, 0x1d, 0x5b, + 0xa1, 0x67, 0x21, 0xc7, 0x28, 0xd4, 0xb6, 0x0d, 0x0e, 0x1e, 0x7a, 0x3b, 0x0c, 0x18, 0xc7, 0x3b, + 0xf3, 0xed, 0xd9, 0xb9, 0x90, 0x0e, 0x15, 0xde, 0x63, 0x06, 0x24, 0xaf, 0x41, 0x99, 0xed, 0x09, + 0x97, 0x72, 0xef, 0x08, 0x2e, 0x77, 0x49, 0x10, 0x79, 0x0b, 0x16, 0xb0, 0x8e, 0xa0, 0xd5, 0xc4, + 0x0d, 0x51, 0x8f, 0xce, 0x0e, 0xc7, 0x35, 0x45, 0x1a, 0xe3, 0xbf, 0xe7, 0xbe, 0xc3, 0x09, 0x5b, + 0xd5, 0xc4, 0xdf, 0xe4, 0x7b, 0x1a, 0x95, 0x5c, 0xc1, 0xbc, 0x6f, 0x89, 0xbc, 0x89, 0xa5, 0x78, + 0x1d, 0xc1, 0xfc, 0x46, 0xc9, 0xd7, 0xf7, 0x8b, 0x95, 0x5a, 0xb3, 0x6e, 0xb4, 0xd0, 0xbf, 0xc9, + 0xa4, 0x23, 0xef, 0x82, 0xfa, 0x57, 0xb1, 0x3d, 0x92, 0x83, 0x8d, 0x54, 0x52, 0xe4, 0xe9, 0xe0, + 0x0b, 0xb8, 0x35, 0xf5, 0xc6, 0x92, 0x4b, 0xa8, 0x4b, 0xe0, 0xa1, 0x37, 0x66, 0xdc, 0xcc, 0xb2, + 0x42, 0x3a, 0x75, 0x5c, 0x27, 0x38, 0xa7, 0x63, 0xc1, 0x2c, 0x34, 0x65, 0xc2, 0x9e, 0x80, 0x33, + 0x96, 0x7c, 0xe6, 0x7b, 0x67, 0xea, 0xec, 0xcc, 0x99, 0xea, 0xdb, 0xf8, 0x14, 0x4a, 0x7c, 0x06, + 0xd9, 0x46, 0xc1, 0xf9, 0xcd, 0x89, 0x8d, 0x82, 0xd0, 0x16, 0x94, 0x5d, 0x1a, 0x3e, 0xf7, 0xfc, + 0x67, 0x52, 0x03, 0x2d, 0x3e, 0x8d, 0x1f, 0xa1, 0x96, 0x55, 0x39, 0xaa, 0x71, 0x6d, 0x04, 0x5b, + 0xc2, 0x7c, 0x09, 0x06, 0xe7, 0xb6, 0x50, 0xfc, 0x56, 0x10, 0x30, 0x38, 0xb7, 0x53, 0x4b, 0x38, + 0x9f, 0xf6, 0x55, 0x7b, 0x0b, 0x16, 0xa5, 0x6b, 0x5c, 0x60, 0x4d, 0xe8, 0x69, 0x28, 0xb6, 0x64, + 0x5d, 0xf8, 0xc5, 0x05, 0x07, 0xf4, 0x34, 0x34, 0x0e, 0x61, 0x59, 0x6c, 0x9a, 0xfe, 0x8c, 0xca, + 0xaa, 0x3f, 0xcb, 0x12, 0x93, 0x6a, 0x0f, 0x57, 0xe2, 0xfc, 0x07, 0xe7, 0xf4, 0x62, 0xb2, 0x93, + 0xf1, 0x83, 0x48, 0xa5, 0xc8, 0xb8, 0x13, 0x51, 0x9e, 0x10, 0x56, 0xa4, 0x41, 0x55, 0x3a, 0x6d, + 0x28, 0x91, 0xc8, 0x19, 0xb3, 0xd1, 0x09, 0xe6, 0xa3, 0x91, 0x74, 0x59, 0xac, 0x98, 0xf2, 0xd3, + 0xf8, 0xdf, 0x39, 0x58, 0xc1, 0xc2, 0xa4, 0x98, 0x27, 0x4e, 0x8a, 0x1f, 0xbb, 0x91, 0x6c, 0x7e, + 0x74, 0x96, 0x90, 0x7f, 0xbc, 0xdc, 0x22, 0x94, 0xb4, 0xf6, 0x14, 0x33, 0xad, 0x3d, 0xdf, 0x86, + 0xe6, 0x98, 0x4e, 0x1c, 0x5c, 0x4e, 0x92, 0xcb, 0xe2, 0x6c, 0xed, 0x92, 0x84, 0x4b, 0xd5, 0x43, + 0xca, 0xc4, 0xb4, 0x90, 0x36, 0x3f, 0xfe, 0x8d, 0x1c, 0x2c, 0x73, 0x46, 0x0f, 0x15, 0x3e, 0x62, + 0x40, 0xbf, 0x90, 0x9a, 0x0d, 0x41, 0x76, 0x45, 0xdf, 0x23, 0x06, 0x08, 0xa1, 0x1c, 0x79, 0xff, + 0x86, 0xd0, 0x78, 0x08, 0x28, 0xf9, 0x0e, 0x8a, 0xb0, 0xae, 0x85, 0x40, 0xc1, 0xc0, 0xdf, 0xcc, + 0x60, 0x2d, 0x55, 0x76, 0x26, 0xdf, 0xba, 0x08, 0xda, 0xae, 0xc0, 0x02, 0x57, 0x9f, 0x19, 0x7b, + 0xd0, 0x88, 0x55, 0x13, 0x33, 0x2b, 0xd5, 0xb9, 0x59, 0x29, 0x65, 0xf3, 0xce, 0xa7, 0x6d, 0xde, + 0x57, 0xb0, 0x62, 0x52, 0x7b, 0x7c, 0xb5, 0xe7, 0xf9, 0x47, 0xc1, 0x49, 0xb8, 0xc7, 0xb9, 0x67, + 0x76, 0x56, 0x29, 0x2f, 0x97, 0x98, 0x1d, 0x46, 0xda, 0xf3, 0xe5, 0x20, 0x7e, 0x0b, 0x16, 0x23, + 0x77, 0x18, 0x4d, 0x63, 0xdf, 0x50, 0x1e, 0x31, 0xc8, 0x74, 0x11, 0x28, 0xce, 0x82, 0x93, 0x50, + 0xe8, 0xec, 0xf1, 0xb7, 0xf1, 0x4f, 0x4b, 0x40, 0xd8, 0xaa, 0x4f, 0x2c, 0xac, 0xd4, 0xb4, 0xe4, + 0xd2, 0x96, 0xbf, 0x84, 0xb3, 0x4f, 0x3e, 0xe5, 0xec, 0xf3, 0x00, 0x88, 0x86, 0x20, 0x7d, 0x90, + 0x0a, 0xca, 0x07, 0xa9, 0x19, 0xe1, 0x0a, 0x17, 0xa4, 0x07, 0xb0, 0x2a, 0xc4, 0x95, 0x78, 0x77, + 0x70, 0x99, 0x99, 0x84, 0xcb, 0x2d, 0xb1, 0x3e, 0x49, 0x47, 0x1f, 0xa9, 0x06, 0x2f, 0x70, 0x47, + 0x1f, 0xa9, 0xad, 0xd2, 0x16, 0xf3, 0xc2, 0x4b, 0x17, 0x73, 0x39, 0x73, 0x31, 0x6b, 0xda, 0xcb, + 0x4a, 0x5c, 0x7b, 0x99, 0xd2, 0xc3, 0x73, 0xfe, 0x3c, 0xa6, 0x87, 0xbf, 0x07, 0x4d, 0xa9, 0xc9, + 0x52, 0x3a, 0x52, 0xe1, 0x01, 0x22, 0x94, 0x55, 0x52, 0x4b, 0x1a, 0x33, 0x34, 0xd6, 0x5e, 0xc5, + 0xe2, 0x59, 0xcf, 0xb6, 0x78, 0xa6, 0x75, 0x7e, 0x8d, 0x0c, 0x9d, 0xdf, 0xa3, 0xc8, 0xc1, 0x23, + 0x38, 0x77, 0xa6, 0xc8, 0x48, 0x45, 0x1e, 0xaa, 0x62, 0x90, 0x07, 0xe7, 0xce, 0xd4, 0x94, 0xae, + 0x56, 0xec, 0x83, 0xec, 0xc0, 0x1d, 0xd1, 0x9f, 0x0c, 0x2f, 0x29, 0x3e, 0x0a, 0x4b, 0xb8, 0x54, + 0x36, 0x39, 0xda, 0x61, 0xc2, 0x61, 0x2a, 0x31, 0x28, 0xd2, 0xc7, 0x26, 0xe0, 0x8a, 0x63, 0x39, + 0x28, 0x87, 0xdc, 0xc9, 0x06, 0xc9, 0x03, 0x43, 0x11, 0x4a, 0xc5, 0xe0, 0x02, 0xf9, 0xae, 0x86, + 0x59, 0x9b, 0xda, 0x97, 0x07, 0xa8, 0x34, 0x0c, 0x2e, 0x8c, 0x3f, 0xcd, 0x41, 0x93, 0x2d, 0xe1, + 0x18, 0x75, 0xf8, 0x1c, 0x90, 0xde, 0xbd, 0x22, 0x71, 0xa8, 0x31, 0x5c, 0x49, 0x1b, 0x3e, 0x05, + 0xdc, 0xec, 0x96, 0x37, 0xa3, 0xae, 0x20, 0x0d, 0xad, 0x38, 0x69, 0x88, 0x8e, 0x89, 0xfd, 0x1b, + 0x5c, 0xea, 0x64, 0x10, 0xf2, 0x39, 0x54, 0xd9, 0x9e, 0xc2, 0xc5, 0x2b, 0xbc, 0xc3, 0x37, 0x95, + 0x26, 0x21, 0xb5, 0xbd, 0x59, 0xd6, 0x99, 0xf8, 0xcc, 0x72, 0xa1, 0x2a, 0x66, 0xb8, 0x50, 0x69, + 0xb4, 0x67, 0x1f, 0xe0, 0x09, 0xbd, 0x62, 0x83, 0x10, 0x7a, 0x3e, 0xe3, 0xd5, 0xd8, 0x16, 0x3b, + 0xb5, 0xa7, 0x8e, 0xd0, 0x66, 0x96, 0xcc, 0xea, 0x33, 0x7a, 0xb5, 0x87, 0x00, 0xb6, 0xb6, 0x58, + 0x72, 0x44, 0x80, 0x4a, 0x66, 0xe5, 0x19, 0xbd, 0xe2, 0xd4, 0xc7, 0x82, 0xc6, 0x13, 0x7a, 0xb5, + 0x4b, 0xb9, 0x30, 0xe0, 0xf9, 0x6c, 0xd0, 0x7d, 0xfb, 0x39, 0xe3, 0xfe, 0x63, 0x2e, 0x3e, 0x35, + 0xdf, 0x7e, 0xfe, 0x84, 0x5e, 0x49, 0x77, 0xa3, 0x32, 0x4b, 0x9f, 0x78, 0x23, 0xc1, 0xbe, 0x48, + 0x05, 0x52, 0xd4, 0x28, 0x73, 0xe1, 0x19, 0xfe, 0x36, 0xfe, 0x24, 0x07, 0x0d, 0xd6, 0x7e, 0x3c, + 0x79, 0x70, 0x15, 0x09, 0x9f, 0xe1, 0x5c, 0xe4, 0x33, 0xfc, 0x50, 0x10, 0x64, 0x7e, 0x8c, 0xe5, + 0xaf, 0x3f, 0xc6, 0x70, 0x6e, 0xf8, 0x19, 0xf6, 0x21, 0x54, 0xf9, 0xc2, 0x60, 0xe4, 0xa7, 0x10, + 0x9b, 0xe0, 0x58, 0x87, 0xcc, 0x0a, 0xa2, 0x3d, 0xe1, 0xfe, 0x87, 0x9a, 0xae, 0x9e, 0x0f, 0x71, + 0xd5, 0x57, 0x1a, 0xfa, 0x8c, 0x69, 0x28, 0x5d, 0xe3, 0x7f, 0xa8, 0x2b, 0xc2, 0x17, 0x92, 0x8a, + 0x70, 0xc3, 0x85, 0x0a, 0x9b, 0x6a, 0xec, 0x6c, 0x46, 0xa1, 0xb9, 0xac, 0x42, 0x19, 0xb3, 0x63, + 0xb3, 0xf3, 0x8c, 0xd1, 0xe8, 0xbc, 0x60, 0x76, 0xec, 0x80, 0xb2, 0x82, 0x58, 0xc3, 0x5d, 0xcf, + 0x42, 0xcd, 0xb2, 0xd0, 0xb9, 0x56, 0xcc, 0xaa, 0xeb, 0x1d, 0x71, 0x80, 0xf1, 0x97, 0x72, 0x50, + 0xd3, 0xf6, 0x2c, 0x9a, 0x1a, 0xd4, 0x70, 0xf2, 0x0d, 0x1e, 0xdf, 0x01, 0xb1, 0xf9, 0xd8, 0xbf, + 0x61, 0x36, 0x46, 0xb1, 0x09, 0xda, 0x12, 0x4b, 0x19, 0x73, 0xe6, 0x63, 0xfa, 0x2d, 0xd9, 0x2f, + 0xb9, 0x7e, 0xd9, 0xef, 0xed, 0x05, 0x28, 0x32, 0x54, 0xe3, 0x0b, 0x58, 0xd6, 0x9a, 0xc1, 0xf5, + 0x3f, 0xaf, 0x3a, 0x00, 0xc6, 0x2f, 0xa8, 0xcc, 0xac, 0x0e, 0x6e, 0xbb, 0x97, 0xae, 0x9e, 0x74, + 0xcc, 0xc7, 0x45, 0xb8, 0x94, 0x72, 0x10, 0x8e, 0xcc, 0x2b, 0x7a, 0x1f, 0x1a, 0xbf, 0x92, 0x83, + 0x15, 0xad, 0xf8, 0x3d, 0xc7, 0xb5, 0x27, 0xce, 0x8f, 0xf0, 0x18, 0x0b, 0x9c, 0x33, 0x37, 0x51, + 0x01, 0x07, 0x7d, 0x9d, 0x0a, 0xc8, 0x5d, 0xa8, 0x73, 0xdf, 0x72, 0x7e, 0x73, 0x41, 0x1c, 0xb3, + 0x80, 0x30, 0xd3, 0x7e, 0x3e, 0xbc, 0x34, 0xfe, 0x66, 0x1e, 0x56, 0x45, 0x13, 0xf0, 0x0a, 0x80, + 0xc3, 0x58, 0xdd, 0xc3, 0xe0, 0x8c, 0x7c, 0x0e, 0x0d, 0x36, 0x7c, 0x96, 0x4f, 0xcf, 0x9c, 0x20, + 0xa4, 0xd2, 0xad, 0x20, 0x83, 0x1a, 0x33, 0x4e, 0x86, 0xa1, 0x9a, 0x02, 0x93, 0x7c, 0x01, 0x35, + 0xcc, 0xca, 0x55, 0x70, 0x62, 0xae, 0x5a, 0xe9, 0x8c, 0x7c, 0x2e, 0xf6, 0x6f, 0x98, 0x10, 0x44, + 0x33, 0xf3, 0x05, 0xd4, 0x70, 0x9a, 0x2f, 0x70, 0xac, 0x13, 0xc4, 0x2e, 0x35, 0x17, 0x2c, 0xf3, + 0x2c, 0x9a, 0x99, 0x36, 0x34, 0x38, 0xb9, 0x13, 0x23, 0x29, 0xfc, 0x86, 0x37, 0xd3, 0xd9, 0xe5, + 0x58, 0xb3, 0xc6, 0xcf, 0xb4, 0xef, 0xed, 0x2a, 0x94, 0x43, 0xdf, 0x39, 0x3b, 0xa3, 0xbe, 0xb1, + 0xae, 0x86, 0x86, 0xd1, 0x71, 0x3a, 0x08, 0xe9, 0x8c, 0xc9, 0x30, 0xc6, 0xbf, 0xcc, 0x41, 0x4d, + 0x50, 0xe6, 0x1f, 0xdb, 0x63, 0x61, 0x33, 0xa1, 0xac, 0xad, 0x6a, 0xba, 0xd9, 0x77, 0x60, 0x69, + 0xca, 0x04, 0x2e, 0x27, 0xbc, 0x8a, 0xbb, 0x2b, 0x2c, 0x4a, 0xb0, 0x90, 0x25, 0xb6, 0x60, 0x05, + 0x45, 0x8b, 0xc0, 0x0a, 0x9d, 0x89, 0x25, 0x13, 0xc5, 0x0d, 0x99, 0x65, 0x9e, 0x34, 0x74, 0x26, + 0x87, 0x22, 0x81, 0x71, 0xd8, 0x41, 0x68, 0x9f, 0x51, 0x41, 0x1d, 0xf8, 0x07, 0x13, 0xe2, 0x12, + 0xba, 0x00, 0x29, 0xc4, 0xfd, 0xdf, 0x65, 0xd8, 0x48, 0x25, 0x09, 0x21, 0x4e, 0x59, 0x87, 0x27, + 0xce, 0xf4, 0xc4, 0x53, 0xd6, 0x89, 0x9c, 0x66, 0x1d, 0x3e, 0x60, 0x29, 0xd2, 0x3a, 0x41, 0x61, + 0x4d, 0x2e, 0x59, 0x34, 0x2f, 0x28, 0x75, 0x41, 0x1e, 0x85, 0xd9, 0x0f, 0xe3, 0xc7, 0x60, 0xb2, + 0x3a, 0x09, 0xd7, 0xf9, 0xc2, 0x95, 0x59, 0x0a, 0x16, 0x90, 0x3f, 0x0f, 0x2d, 0xb5, 0x33, 0x84, + 0x6c, 0xa3, 0xe9, 0x3e, 0x58, 0x4d, 0xef, 0xbd, 0xa4, 0xa6, 0x98, 0xde, 0x17, 0x59, 0xaf, 0x75, + 0xb9, 0xa9, 0x78, 0x81, 0xaa, 0xae, 0x0b, 0x78, 0x5d, 0xd6, 0x85, 0xb2, 0x4a, 0xba, 0xc6, 0xe2, + 0x2b, 0xf5, 0x0d, 0x75, 0xda, 0xb1, 0x6a, 0xcd, 0x5b, 0xa2, 0x60, 0x95, 0xa4, 0xd7, 0x7b, 0x0e, + 0xeb, 0xcf, 0x6d, 0x27, 0x94, 0x7d, 0xd4, 0x54, 0x2f, 0x25, 0xac, 0xef, 0xe1, 0x4b, 0xea, 0xfb, + 0x8a, 0x67, 0x8e, 0x49, 0x6f, 0xab, 0xcf, 0xd3, 0xc0, 0x60, 0xf3, 0xef, 0x15, 0x60, 0x31, 0x5e, + 0x0a, 0x23, 0x3d, 0xe2, 0xb8, 0x92, 0x8c, 0xb4, 0x90, 0x00, 0x84, 0xe5, 0xac, 0xc7, 0x19, 0xe8, + 0xb4, 0x4d, 0x2f, 0x9f, 0x61, 0xd3, 0xd3, 0x4d, 0x69, 0x85, 0x97, 0x79, 0x56, 0x14, 0x5f, 0xc9, + 0xb3, 0xa2, 0x94, 0xe5, 0x59, 0xf1, 0xd1, 0xb5, 0xa6, 0x78, 0xae, 0x10, 0xcf, 0x34, 0xc3, 0x3f, + 0xba, 0xde, 0x0c, 0xcf, 0x75, 0xe5, 0xd7, 0x99, 0xe0, 0x35, 0x07, 0x82, 0xca, 0x35, 0x06, 0x30, + 0xcd, 0xa5, 0x20, 0xc3, 0x04, 0x5f, 0xfd, 0x1a, 0x26, 0xf8, 0xcd, 0x3f, 0xc9, 0x01, 0x49, 0xef, + 0x0e, 0xf2, 0x98, 0x9b, 0x4b, 0x5d, 0x3a, 0x11, 0x94, 0xfb, 0xfd, 0x57, 0xdb, 0x61, 0x72, 0x41, + 0xc8, 0xdc, 0xe4, 0x03, 0x58, 0xd1, 0xef, 0xf1, 0xe9, 0xaa, 0x8d, 0x86, 0x49, 0xf4, 0xa4, 0x48, + 0x49, 0xa7, 0xb9, 0xb1, 0x14, 0x5f, 0xea, 0xc6, 0x52, 0x7a, 0xa9, 0x1b, 0xcb, 0x42, 0xdc, 0x8d, + 0x65, 0xf3, 0xdf, 0xe4, 0x60, 0x25, 0x63, 0x11, 0x7f, 0x73, 0x7d, 0x66, 0x6b, 0x2f, 0x46, 0xd6, + 0xf2, 0x62, 0xed, 0xe9, 0x14, 0xed, 0x40, 0x2a, 0x76, 0xd9, 0x54, 0x04, 0xe2, 0xa4, 0xba, 0xff, + 0x32, 0xea, 0x12, 0xe5, 0x30, 0xf5, 0xec, 0x9b, 0x7f, 0x3f, 0x0f, 0x35, 0x2d, 0x91, 0x8d, 0x22, + 0x5f, 0xb2, 0x9a, 0x53, 0x28, 0xe7, 0x2d, 0x51, 0x31, 0x83, 0x57, 0x0b, 0x70, 0x71, 0x62, 0x3a, + 0xdf, 0x5c, 0x82, 0x91, 0x44, 0x84, 0x2d, 0x58, 0x91, 0xa6, 0x6c, 0x1a, 0x39, 0xcd, 0x8b, 0xb3, + 0x46, 0x78, 0x25, 0x88, 0x46, 0x22, 0xfe, 0x07, 0x52, 0xce, 0x8d, 0xe6, 0x4e, 0x33, 0x0d, 0x2e, + 0x0b, 0x7f, 0x08, 0x31, 0x89, 0x6c, 0x9d, 0x7f, 0x08, 0x6b, 0xca, 0x21, 0x22, 0x96, 0x83, 0x1b, + 0xa0, 0x88, 0x74, 0x7c, 0xd0, 0xb2, 0x7c, 0x0f, 0x6e, 0x27, 0xda, 0x94, 0xc8, 0xca, 0x35, 0x2d, + 0x37, 0x63, 0xad, 0xd3, 0x4b, 0xd8, 0xfc, 0x0b, 0xd0, 0x88, 0x11, 0xca, 0x6f, 0x6e, 0xca, 0x93, + 0xca, 0x30, 0x3e, 0xa2, 0xba, 0x32, 0x6c, 0xf3, 0x7f, 0x16, 0x80, 0xa4, 0x69, 0xf5, 0x4f, 0xb3, + 0x09, 0xe9, 0x85, 0x59, 0xc8, 0x58, 0x98, 0x7f, 0x66, 0xfc, 0x43, 0xa4, 0x93, 0xd5, 0xfc, 0x11, + 0xf8, 0xe6, 0x6c, 0xaa, 0x04, 0xd9, 0x8a, 0x4f, 0x93, 0x5e, 0x5b, 0x95, 0xd8, 0x85, 0x53, 0x8d, + 0x81, 0x4a, 0x38, 0x6f, 0x1d, 0xc3, 0x82, 0xed, 0x8e, 0xce, 0x3d, 0x5f, 0xd0, 0xc1, 0x9f, 0xf9, + 0xda, 0xc7, 0xe7, 0x56, 0x1b, 0xf3, 0x23, 0xd7, 0x66, 0x8a, 0xc2, 0x8c, 0x0f, 0xa1, 0xa6, 0x81, + 0x49, 0x15, 0x4a, 0x07, 0xdd, 0xc3, 0xed, 0x7e, 0xf3, 0x06, 0x69, 0x40, 0xd5, 0xec, 0xec, 0xf4, + 0xbf, 0xec, 0x98, 0x9d, 0xdd, 0x66, 0x8e, 0x54, 0xa0, 0x78, 0xd0, 0x1f, 0x0c, 0x9b, 0x79, 0x63, + 0x13, 0x5a, 0xa2, 0xc4, 0xb4, 0x75, 0xea, 0xb7, 0x8a, 0x4a, 0xa7, 0x8a, 0x89, 0x42, 0xc8, 0xff, + 0x08, 0xea, 0x3a, 0x7b, 0x23, 0x56, 0x44, 0xc2, 0x25, 0x86, 0x89, 0xf7, 0x9e, 0x46, 0xab, 0x77, + 0x80, 0x3b, 0x44, 0x8c, 0x55, 0xb6, 0x7c, 0x8c, 0x6f, 0xcd, 0xb0, 0x2c, 0xa3, 0x7c, 0x14, 0x5b, + 0x86, 0x7f, 0x0e, 0x16, 0xe3, 0x96, 0x18, 0x41, 0x91, 0xb2, 0x44, 0x56, 0x96, 0x3b, 0x66, 0x9a, + 0x21, 0xdf, 0x83, 0x66, 0xd2, 0x92, 0x23, 0x98, 0xe7, 0x6b, 0xf2, 0x2f, 0x39, 0x71, 0xe3, 0x0e, + 0xd9, 0x87, 0xd5, 0x2c, 0x06, 0x0f, 0xd7, 0xc7, 0xf5, 0x6a, 0x0e, 0x92, 0x66, 0xe2, 0xc8, 0x67, + 0xc2, 0xa2, 0x57, 0xc2, 0xe9, 0x7f, 0x2b, 0x5e, 0xbf, 0x36, 0xd8, 0x5b, 0xfc, 0x9f, 0x66, 0xdb, + 0xbb, 0x00, 0x88, 0x60, 0xa4, 0x09, 0xf5, 0xfe, 0x51, 0xa7, 0x67, 0xed, 0xec, 0xb7, 0x7b, 0xbd, + 0xce, 0x41, 0xf3, 0x06, 0x21, 0xb0, 0x88, 0x5e, 0x1d, 0xbb, 0x0a, 0x96, 0x63, 0x30, 0x61, 0x6a, + 0x95, 0xb0, 0x3c, 0x59, 0x85, 0x66, 0xb7, 0x97, 0x80, 0x16, 0x48, 0x0b, 0x56, 0x8f, 0x3a, 0xdc, + 0x11, 0x24, 0x56, 0x6e, 0x91, 0x09, 0x0d, 0xa2, 0xbb, 0x46, 0x08, 0xab, 0x5f, 0xd9, 0x93, 0x09, + 0x0d, 0xdb, 0xdc, 0x91, 0x5d, 0x6e, 0x87, 0x77, 0x61, 0x59, 0xa9, 0xc3, 0x12, 0xdc, 0x72, 0x53, + 0x25, 0x48, 0xe4, 0x0f, 0x60, 0x45, 0xd3, 0xaa, 0x25, 0x4e, 0x21, 0xa2, 0x25, 0x89, 0x0c, 0x4c, + 0x54, 0xe1, 0xb5, 0x0a, 0x80, 0xe4, 0xe0, 0xff, 0x30, 0x0f, 0x6b, 0x89, 0x84, 0xc8, 0x08, 0xc3, + 0xf9, 0xf7, 0x78, 0x5b, 0xea, 0x08, 0x7c, 0x61, 0xa3, 0xf3, 0x5f, 0xaf, 0xd1, 0x85, 0xeb, 0x1a, + 0x4d, 0x9e, 0xc2, 0x92, 0xf0, 0xf6, 0xd7, 0x78, 0x3c, 0x46, 0x23, 0x1e, 0x88, 0x29, 0xcf, 0x6c, + 0xf9, 0x56, 0x7c, 0x60, 0xb9, 0x95, 0x6b, 0xd1, 0x8e, 0x01, 0x37, 0x7f, 0x09, 0x56, 0x32, 0xd0, + 0x32, 0xee, 0xbc, 0x7c, 0x18, 0xb7, 0x78, 0xdd, 0x8a, 0xd5, 0x1c, 0x2f, 0x42, 0xb7, 0xde, 0x6f, + 0xc1, 0x82, 0xd0, 0xf6, 0x36, 0xa1, 0x20, 0xaf, 0x3d, 0x15, 0x4d, 0xf6, 0x93, 0x10, 0x28, 0x4e, + 0x23, 0x07, 0x6c, 0xfc, 0x6d, 0x6c, 0xa8, 0x0b, 0x8c, 0x89, 0x09, 0xfa, 0x95, 0x22, 0xac, 0x27, + 0x53, 0xd4, 0x95, 0x84, 0x72, 0x6c, 0x6e, 0xb8, 0x25, 0x51, 0x80, 0xc8, 0xc7, 0x89, 0xed, 0x16, + 0x9b, 0x1d, 0x44, 0xd5, 0xb7, 0x96, 0x1c, 0xf2, 0x87, 0x49, 0xa6, 0x9a, 0xd3, 0x88, 0x86, 0xbc, + 0xa0, 0x81, 0x7d, 0x4a, 0xf0, 0xd8, 0x1f, 0xa7, 0x78, 0xec, 0x62, 0x56, 0xa6, 0x04, 0xcb, 0xdd, + 0x81, 0x8d, 0xc8, 0xd5, 0x38, 0x5e, 0x67, 0x29, 0x2b, 0xfb, 0x9a, 0xc2, 0x3e, 0xd0, 0x2b, 0x7f, + 0x0c, 0xad, 0xa8, 0x98, 0x44, 0x33, 0x16, 0xb2, 0xca, 0x59, 0x57, 0xe8, 0x66, 0xac, 0x3d, 0xdf, + 0x87, 0xcd, 0xd8, 0x78, 0xc5, 0x9b, 0x54, 0xce, 0x2a, 0x6a, 0x43, 0x1b, 0xc0, 0x58, 0xa3, 0x0e, + 0xe0, 0x56, 0xac, 0xac, 0x44, 0xbb, 0x2a, 0x59, 0x85, 0xb5, 0xb4, 0xc2, 0x62, 0x2d, 0x33, 0x7e, + 0x67, 0x01, 0xc8, 0x0f, 0xe6, 0xd4, 0xbf, 0xc2, 0x6b, 0xcd, 0xc1, 0xcb, 0xee, 0x50, 0x48, 0x4d, + 0x65, 0xfe, 0x95, 0xa2, 0x1b, 0x64, 0x45, 0x17, 0x28, 0xbe, 0x3c, 0xba, 0x40, 0xe9, 0x65, 0xd1, + 0x05, 0xde, 0x84, 0x86, 0x73, 0xe6, 0x7a, 0x8c, 0x11, 0x60, 0x72, 0x60, 0xd0, 0x5a, 0xb8, 0x5b, + 0xb8, 0x57, 0x37, 0xeb, 0x02, 0xc8, 0xa4, 0xc0, 0x80, 0x7c, 0x11, 0x21, 0xd1, 0xf1, 0x19, 0xc6, + 0xde, 0xd0, 0x59, 0x80, 0xce, 0xf8, 0x8c, 0x0a, 0xc5, 0x2c, 0x2e, 0x58, 0x99, 0x99, 0xc1, 0x03, + 0xf2, 0x16, 0x2c, 0x06, 0xde, 0x9c, 0x89, 0xd5, 0x72, 0x18, 0xb8, 0xbd, 0xbf, 0xce, 0xa1, 0x47, + 0xd2, 0xfb, 0x63, 0x65, 0x1e, 0x50, 0x6b, 0xea, 0x04, 0x01, 0x13, 0x4e, 0x46, 0x9e, 0x1b, 0xfa, + 0xde, 0x44, 0x98, 0xf0, 0x97, 0xe7, 0x01, 0x3d, 0xe4, 0x29, 0x3b, 0x3c, 0x81, 0x7c, 0x1c, 0x35, + 0x69, 0x66, 0x3b, 0x7e, 0xd0, 0x02, 0x6c, 0x92, 0xec, 0x29, 0x4a, 0xaf, 0xb6, 0xe3, 0xab, 0xb6, + 0xb0, 0x8f, 0x20, 0x11, 0xf5, 0xa0, 0x96, 0x8c, 0x7a, 0xf0, 0xcb, 0xd9, 0x51, 0x0f, 0x1a, 0x31, + 0x62, 0x96, 0x9e, 0xe2, 0xaf, 0x15, 0xfc, 0x20, 0x1d, 0xcc, 0x61, 0xf1, 0xeb, 0x04, 0x73, 0x58, + 0xca, 0x0a, 0xe6, 0xf0, 0x21, 0xd4, 0xf0, 0x0e, 0xbd, 0x75, 0x8e, 0xce, 0xcc, 0xdc, 0x25, 0xa1, + 0xa9, 0x5f, 0xb2, 0xdf, 0x77, 0xdc, 0xd0, 0x04, 0x5f, 0xfe, 0x0c, 0xd2, 0x71, 0x15, 0x96, 0x5f, + 0x29, 0xae, 0xc2, 0x37, 0x13, 0x34, 0x41, 0xdc, 0xf5, 0xdf, 0x82, 0x8a, 0x9c, 0x27, 0x46, 0x6c, + 0x4f, 0x7d, 0x6f, 0x2a, 0xcd, 0x9b, 0xec, 0x37, 0x59, 0x84, 0x7c, 0xe8, 0x89, 0xcc, 0xf9, 0xd0, + 0x33, 0x7e, 0x11, 0x6a, 0xda, 0x52, 0x23, 0x6f, 0x70, 0xbd, 0xbe, 0x4b, 0x27, 0x52, 0xed, 0xcb, + 0x47, 0xb1, 0x2a, 0xa0, 0xdd, 0x31, 0x3b, 0xf7, 0xc6, 0x8e, 0x4f, 0x31, 0x02, 0x8a, 0xe5, 0xd3, + 0x0b, 0xea, 0x07, 0xd2, 0x2c, 0xdd, 0x54, 0x09, 0x26, 0x87, 0x1b, 0xbf, 0x04, 0x2b, 0xb1, 0xb9, + 0x15, 0xe4, 0xfb, 0x2d, 0x58, 0xc0, 0x71, 0x93, 0xbe, 0x4f, 0xf1, 0xe0, 0x05, 0x22, 0x0d, 0xe3, + 0xc0, 0x70, 0x8b, 0xba, 0x35, 0xf3, 0xbd, 0x13, 0xac, 0x24, 0x67, 0xd6, 0x04, 0xec, 0xc8, 0xf7, + 0x4e, 0x8c, 0xbf, 0x52, 0x84, 0xc2, 0xbe, 0x37, 0xd3, 0x1d, 0xa0, 0x73, 0x29, 0x07, 0x68, 0xa1, + 0x6e, 0xb1, 0x94, 0x3a, 0x45, 0x48, 0xac, 0x68, 0x23, 0x96, 0x2a, 0x95, 0x7b, 0xb0, 0xc8, 0xe8, + 0x44, 0xe8, 0x59, 0xe2, 0xe2, 0x11, 0x3f, 0x9c, 0xf9, 0xe6, 0xb3, 0xa7, 0xe1, 0xd0, 0xdb, 0xe3, + 0x70, 0xb2, 0x0a, 0x05, 0x25, 0xbc, 0x63, 0x32, 0xfb, 0x24, 0xeb, 0xb0, 0x80, 0x17, 0xa6, 0xe4, + 0x4d, 0x77, 0xf1, 0x45, 0xde, 0x87, 0x95, 0x78, 0xb9, 0x9c, 0x14, 0x09, 0xc9, 0x40, 0x2f, 0x18, + 0x69, 0xd2, 0x4d, 0x60, 0x74, 0x24, 0xba, 0xeb, 0x5e, 0x30, 0xcb, 0xa7, 0x94, 0x62, 0x92, 0x46, + 0xf4, 0x2a, 0x31, 0xa2, 0x77, 0x07, 0x6a, 0xe1, 0xe4, 0xc2, 0x9a, 0xd9, 0x57, 0x13, 0xcf, 0x96, + 0x37, 0x2b, 0x21, 0x9c, 0x5c, 0x1c, 0x71, 0x08, 0xf9, 0x00, 0x60, 0x3a, 0x9b, 0x89, 0xbd, 0x87, + 0xf6, 0xcc, 0x68, 0x29, 0x1f, 0x1e, 0x1d, 0xf1, 0x25, 0x67, 0x56, 0xa7, 0xb3, 0x19, 0xff, 0xc9, + 0x32, 0xd8, 0x53, 0x95, 0xa1, 0x1e, 0xcb, 0xd0, 0x3e, 0x54, 0x19, 0xec, 0xa9, 0xcc, 0xb0, 0x0b, + 0x8b, 0x99, 0x61, 0x4d, 0x6e, 0xcb, 0x7b, 0x28, 0xde, 0x6c, 0x2b, 0x63, 0x37, 0x37, 0x46, 0x3a, + 0x6c, 0xf3, 0x7b, 0x40, 0x7e, 0xc2, 0xc8, 0x21, 0x43, 0xa8, 0xaa, 0x0e, 0xa5, 0xe2, 0x95, 0xd4, + 0x52, 0xf1, 0x4a, 0x18, 0x21, 0xe5, 0x9c, 0x9e, 0x3a, 0x23, 0x40, 0x63, 0xf5, 0xc4, 0x0d, 0x2e, + 0xe3, 0x04, 0xaa, 0xaa, 0xd7, 0x68, 0x93, 0xf2, 0xbc, 0xd0, 0x0a, 0xce, 0x6d, 0x71, 0x1d, 0xb2, + 0x6e, 0x56, 0x19, 0x64, 0xc0, 0x00, 0x64, 0x0d, 0x16, 0x02, 0x1a, 0x46, 0x56, 0x87, 0x52, 0x40, + 0x43, 0x6e, 0x82, 0x1a, 0x9d, 0x3b, 0x93, 0x71, 0xec, 0x26, 0x3d, 0x20, 0x88, 0x9b, 0xf5, 0xfe, + 0x4b, 0x0e, 0x4a, 0x3c, 0xd2, 0xc8, 0xdb, 0xb0, 0xc4, 0xdb, 0xa4, 0x3c, 0xdc, 0x85, 0x1b, 0x12, + 0x67, 0x4a, 0x87, 0xc2, 0xb9, 0x9d, 0xed, 0x55, 0x2d, 0x74, 0x53, 0xc4, 0xdb, 0x68, 0xe1, 0x9b, + 0xee, 0x40, 0x55, 0x75, 0x4f, 0x5b, 0xcf, 0x15, 0xd9, 0x3b, 0xf2, 0x3a, 0x14, 0xcf, 0xbd, 0x99, + 0x54, 0xc6, 0x42, 0x34, 0x5b, 0x26, 0xc2, 0xa3, 0xb6, 0xb0, 0x3a, 0xa2, 0xdb, 0x6b, 0x05, 0xd1, + 0x16, 0x56, 0x89, 0x8c, 0xbf, 0x90, 0x18, 0xc7, 0x85, 0x8c, 0x71, 0x3c, 0x86, 0x25, 0x46, 0x9c, + 0x34, 0x5f, 0xa8, 0xeb, 0x4f, 0xf2, 0x6f, 0x33, 0xa1, 0x6b, 0x34, 0x99, 0x8f, 0xa9, 0xae, 0x0e, + 0x47, 0x77, 0x65, 0x01, 0x97, 0xc2, 0xae, 0xf1, 0x3b, 0x39, 0x4e, 0xf4, 0x58, 0xb9, 0xe4, 0x1e, + 0x14, 0x5d, 0xe9, 0x37, 0x15, 0x89, 0x56, 0xea, 0xa6, 0x27, 0xc3, 0x33, 0x11, 0x83, 0x2d, 0x0f, + 0xf4, 0x36, 0xd2, 0x4b, 0x6f, 0x98, 0x35, 0x77, 0x3e, 0x55, 0xda, 0xe4, 0x6f, 0xc9, 0x6e, 0x25, + 0x34, 0xb1, 0xbc, 0xf7, 0x8a, 0x76, 0x6c, 0x69, 0x7e, 0xcf, 0xc5, 0xd8, 0x31, 0x2e, 0x05, 0xb3, + 0xf1, 0x19, 0xd5, 0xfc, 0x9d, 0x7f, 0x3f, 0x0f, 0x8d, 0x58, 0x8b, 0xd0, 0xf1, 0x9b, 0x9d, 0x4a, + 0xdc, 0x5a, 0x2c, 0xe6, 0x1b, 0xfd, 0x6b, 0x85, 0xec, 0xac, 0x8d, 0x53, 0x3e, 0x36, 0x4e, 0xca, + 0xf1, 0xb1, 0xa0, 0x3b, 0x3e, 0x3e, 0x80, 0x6a, 0x14, 0xb2, 0x2b, 0xde, 0x24, 0x56, 0x9f, 0xbc, + 0xef, 0x1a, 0x21, 0x45, 0xae, 0x92, 0x25, 0xdd, 0x55, 0xf2, 0xbb, 0x9a, 0x67, 0xdd, 0x02, 0x16, + 0x63, 0x64, 0x8d, 0xe8, 0x4f, 0xc5, 0xaf, 0xce, 0xf8, 0x02, 0x6a, 0x5a, 0xe3, 0x75, 0xef, 0xb4, + 0x5c, 0xcc, 0x3b, 0x4d, 0xdd, 0xaa, 0xcf, 0x47, 0xb7, 0xea, 0x8d, 0x5f, 0xcb, 0x43, 0x83, 0xed, + 0x2f, 0xc7, 0x3d, 0x3b, 0xf2, 0x26, 0xce, 0x08, 0xad, 0xc7, 0x6a, 0x87, 0x09, 0xee, 0x4f, 0xee, + 0x33, 0xb1, 0xc5, 0x38, 0xf3, 0xa7, 0x87, 0x82, 0xe1, 0x27, 0x87, 0x0a, 0x05, 0x63, 0x40, 0x83, + 0x51, 0x6b, 0xb4, 0x03, 0x47, 0xe1, 0xbd, 0xcc, 0xda, 0x29, 0xa5, 0xdb, 0x76, 0xc0, 0xc9, 0xf6, + 0xfb, 0xb0, 0xc2, 0x70, 0x30, 0xce, 0xc3, 0xd4, 0x99, 0x4c, 0x9c, 0xe8, 0xba, 0x68, 0xc1, 0x6c, + 0x9e, 0x52, 0x6a, 0xda, 0x21, 0x3d, 0x64, 0x09, 0x22, 0x1a, 0x58, 0x65, 0xec, 0x04, 0xf6, 0x49, + 0xe4, 0x9e, 0xaf, 0xbe, 0xa5, 0x7b, 0x45, 0xe4, 0xc1, 0x22, 0xbc, 0xaf, 0x44, 0x90, 0x13, 0xcc, + 0x9f, 0x58, 0x49, 0xe5, 0xe4, 0x4a, 0x32, 0xfe, 0x49, 0x1e, 0x6a, 0xda, 0xb2, 0x7c, 0x95, 0x23, + 0xff, 0x76, 0xca, 0xda, 0x5f, 0xd5, 0x0d, 0xfb, 0x6f, 0xc6, 0xab, 0x2c, 0xa8, 0x3b, 0x85, 0xfa, + 0x02, 0xbe, 0x05, 0x55, 0xb6, 0xeb, 0x3e, 0x44, 0xab, 0x88, 0x88, 0xd3, 0x87, 0x80, 0xa3, 0xf9, + 0x89, 0x4c, 0x7c, 0x88, 0x89, 0xa5, 0x28, 0xf1, 0x21, 0x4b, 0x7c, 0xd1, 0x9d, 0xa2, 0x4f, 0xa1, + 0x2e, 0x4a, 0xc5, 0x39, 0x15, 0xb2, 0xca, 0xaa, 0xc6, 0x4e, 0xa8, 0xf9, 0x36, 0x6b, 0xbc, 0x3a, + 0x3e, 0xf9, 0x22, 0xe3, 0x43, 0x99, 0xb1, 0xf2, 0xb2, 0x8c, 0x0f, 0xf9, 0x87, 0xb1, 0xa7, 0xae, + 0x69, 0xa1, 0x4f, 0xab, 0xa4, 0x63, 0x1f, 0xc0, 0x8a, 0x24, 0x57, 0x73, 0xd7, 0x76, 0x5d, 0x6f, + 0xee, 0x8e, 0xa8, 0xbc, 0xb2, 0x4e, 0x44, 0xd2, 0x71, 0x94, 0x62, 0x8c, 0x55, 0x00, 0x19, 0xee, + 0x1b, 0x7b, 0x1f, 0x4a, 0x5c, 0x58, 0xe0, 0x1c, 0x51, 0x36, 0xe1, 0xe2, 0x28, 0xe4, 0x1e, 0x94, + 0xb8, 0xcc, 0x90, 0xbf, 0x96, 0xd8, 0x70, 0x04, 0xa3, 0x0d, 0x84, 0x65, 0x3c, 0xa4, 0xa1, 0xef, + 0x8c, 0x82, 0xe8, 0x36, 0x7c, 0x29, 0xbc, 0x9a, 0x89, 0xba, 0x22, 0x63, 0x4a, 0x84, 0x89, 0x6a, + 0x23, 0x8e, 0xc3, 0x0e, 0xa6, 0x95, 0x58, 0x19, 0x82, 0x87, 0x9b, 0xc0, 0xfa, 0x09, 0x0d, 0x9f, + 0x53, 0xea, 0xba, 0x8c, 0x43, 0x1b, 0x51, 0x37, 0xf4, 0xed, 0x09, 0x9b, 0x24, 0xde, 0x83, 0x47, + 0xa9, 0x52, 0x23, 0xb5, 0xe4, 0x76, 0x94, 0x71, 0x47, 0xe5, 0xe3, 0xb4, 0x63, 0xed, 0x24, 0x2b, + 0x6d, 0xf3, 0x17, 0x60, 0xf3, 0xfa, 0x4c, 0x19, 0xba, 0x8b, 0x7b, 0x71, 0xaa, 0xa2, 0x4c, 0xf3, + 0x13, 0xcf, 0x0e, 0x79, 0x6b, 0x74, 0xca, 0xd2, 0x83, 0x9a, 0x96, 0x12, 0xf1, 0x17, 0x39, 0xe4, + 0x38, 0xf9, 0x07, 0x3b, 0x91, 0x5c, 0xcf, 0x9f, 0xa2, 0x29, 0x7c, 0x6c, 0x45, 0xa5, 0xe7, 0xcc, + 0xa5, 0x08, 0x8e, 0xde, 0x53, 0xc6, 0x16, 0x2c, 0xa1, 0xb8, 0xa1, 0x1d, 0x74, 0x2f, 0xe2, 0x50, + 0x8d, 0x55, 0x20, 0x3d, 0x4e, 0xbb, 0x74, 0x3f, 0xe1, 0x3f, 0x2c, 0x40, 0x4d, 0x03, 0xb3, 0xd3, + 0x08, 0x9d, 0xab, 0xad, 0xb1, 0x63, 0x4f, 0xa9, 0xf4, 0x3b, 0x68, 0x98, 0x0d, 0x84, 0xee, 0x0a, + 0x20, 0x3b, 0x8b, 0xed, 0x8b, 0x33, 0xcb, 0x9b, 0x87, 0xd6, 0x98, 0x9e, 0xf9, 0x54, 0xb6, 0xb2, + 0x6e, 0x5f, 0x9c, 0xf5, 0xe7, 0xe1, 0x2e, 0xc2, 0x64, 0xc4, 0x24, 0x0d, 0xab, 0xa0, 0x22, 0x26, + 0x45, 0x58, 0xc2, 0x29, 0x9d, 0xaf, 0xcc, 0xa2, 0x72, 0x4a, 0xe7, 0x22, 0x6c, 0xf2, 0x00, 0x2d, + 0xa5, 0x0f, 0xd0, 0x8f, 0x61, 0x9d, 0x1f, 0xa0, 0x82, 0x34, 0x5b, 0x89, 0x9d, 0xbc, 0x8a, 0xa9, + 0xa2, 0x93, 0x1a, 0x2f, 0xde, 0x64, 0x3d, 0x90, 0x64, 0x29, 0x70, 0x7e, 0xc4, 0x09, 0x59, 0xce, + 0x64, 0x3d, 0x13, 0x85, 0x0f, 0x9c, 0x1f, 0x51, 0x19, 0xb1, 0x29, 0x86, 0x29, 0x6e, 0x0c, 0x4e, + 0x1d, 0x37, 0x89, 0x69, 0x5f, 0xc6, 0x31, 0xab, 0x02, 0xd3, 0xbe, 0xd4, 0x31, 0x1f, 0xc1, 0xc6, + 0x94, 0x8e, 0x1d, 0x3b, 0x5e, 0xac, 0x15, 0x31, 0x87, 0xab, 0x3c, 0x59, 0xcb, 0x33, 0xe0, 0xda, + 0x04, 0x36, 0x1a, 0x3f, 0xf2, 0xa6, 0x27, 0x0e, 0xe7, 0x59, 0xb8, 0x5f, 0x60, 0xd1, 0x5c, 0x74, + 0xe7, 0xd3, 0x9f, 0x47, 0x30, 0xcb, 0x12, 0x18, 0x0d, 0xa8, 0x0d, 0x42, 0x6f, 0x26, 0xa7, 0x79, + 0x11, 0xea, 0xfc, 0x53, 0x44, 0x7b, 0xb8, 0x05, 0x37, 0x91, 0x24, 0x0c, 0xbd, 0x99, 0x37, 0xf1, + 0xce, 0xae, 0x62, 0xaa, 0xf5, 0x7f, 0x95, 0x83, 0x95, 0x58, 0xaa, 0x20, 0xaf, 0x1f, 0x73, 0x7a, + 0xa6, 0x6e, 0x8a, 0xe7, 0x62, 0xd7, 0x04, 0xd9, 0x7c, 0x71, 0x44, 0x4e, 0xcc, 0xe4, 0xed, 0xf1, + 0x76, 0x14, 0x0e, 0x4d, 0x66, 0xe4, 0x24, 0xa5, 0x95, 0x26, 0x29, 0x22, 0xbf, 0x0c, 0x94, 0x26, + 0x8b, 0xf8, 0x19, 0x71, 0xab, 0x73, 0x2c, 0xba, 0x5c, 0x88, 0xdf, 0xfb, 0xd2, 0xd5, 0xf0, 0xb2, + 0x05, 0x91, 0x6e, 0x3e, 0x30, 0x7e, 0x37, 0x0f, 0x10, 0xb5, 0x0e, 0x6f, 0x9e, 0x29, 0xbe, 0x25, + 0x87, 0x2e, 0xfe, 0x1a, 0x8f, 0xf2, 0x06, 0xd4, 0xd5, 0x6d, 0x90, 0x88, 0x13, 0xaa, 0x49, 0x18, + 0x63, 0x87, 0xde, 0x85, 0xa5, 0xb3, 0x89, 0x77, 0x82, 0x1c, 0xab, 0xe0, 0x5b, 0xd0, 0xb1, 0x07, + 0xcf, 0xa3, 0x45, 0x9e, 0xa4, 0x02, 0x1a, 0x2a, 0xde, 0xa9, 0x98, 0x79, 0x69, 0x24, 0xc6, 0x09, + 0x7d, 0x91, 0xe2, 0x84, 0xee, 0xa4, 0x06, 0xf7, 0xa7, 0xc3, 0x06, 0xfd, 0xb5, 0xbc, 0x72, 0x80, + 0x8f, 0xe6, 0xe5, 0xc5, 0x12, 0xf0, 0x8f, 0xe3, 0xae, 0xf7, 0x22, 0xff, 0x83, 0x2f, 0x60, 0xd1, + 0xe7, 0x47, 0xa4, 0x3c, 0x3f, 0x8b, 0x2f, 0x38, 0x3f, 0x1b, 0x7e, 0x8c, 0xef, 0xfa, 0x36, 0x34, + 0xed, 0xf1, 0x05, 0xf5, 0x43, 0x07, 0xcd, 0x79, 0xc8, 0xad, 0x0b, 0x77, 0x73, 0x0d, 0x8e, 0x6c, + 0xf1, 0x3b, 0xb0, 0x24, 0xe2, 0xa1, 0x28, 0x4c, 0x11, 0x28, 0x34, 0x02, 0x33, 0x44, 0xe3, 0x1f, + 0x49, 0x8f, 0xfb, 0xf8, 0x5a, 0x7b, 0xf1, 0xa8, 0xe8, 0x3d, 0xcc, 0xa7, 0x3d, 0x2c, 0xc4, 0xb2, + 0x16, 0x56, 0x42, 0x41, 0x1d, 0x39, 0x50, 0xd8, 0x08, 0xe3, 0xc3, 0x5a, 0x7c, 0x95, 0x61, 0x35, + 0xfe, 0x75, 0x0e, 0xca, 0xfb, 0xde, 0x6c, 0xdf, 0xe1, 0xf7, 0xb6, 0x70, 0xd3, 0x2a, 0x23, 0xf6, + 0x02, 0xfb, 0x44, 0xdf, 0xc2, 0x17, 0xdc, 0xe7, 0xce, 0x64, 0x3a, 0x1b, 0x71, 0xa6, 0xf3, 0xbb, + 0x70, 0x0b, 0x7d, 0x04, 0x7c, 0x6f, 0xe6, 0xf9, 0x8c, 0x70, 0xd8, 0x13, 0xce, 0x7c, 0x7a, 0x6e, + 0x78, 0x2e, 0x29, 0xf9, 0xcd, 0x53, 0x4a, 0x8f, 0x34, 0x8c, 0x43, 0x85, 0x80, 0xb1, 0x1c, 0x26, + 0xe1, 0x85, 0xc5, 0x95, 0x18, 0x82, 0x3b, 0xe6, 0xf4, 0x7d, 0x89, 0x25, 0x74, 0x10, 0x8e, 0xfc, + 0xb1, 0xf1, 0x19, 0x54, 0x95, 0x3e, 0x8c, 0xbc, 0x0b, 0xd5, 0x73, 0x6f, 0x26, 0x94, 0x66, 0xb9, + 0xd8, 0x9d, 0x77, 0xd1, 0x6b, 0xb3, 0x72, 0xce, 0x7f, 0x04, 0xc6, 0xff, 0x2b, 0x43, 0xb9, 0xeb, + 0x5e, 0x78, 0xce, 0x08, 0x7d, 0xf1, 0xa7, 0x74, 0xea, 0xc9, 0x10, 0x4f, 0xec, 0x37, 0x8a, 0xda, + 0x51, 0x2c, 0xcf, 0x82, 0x10, 0xb5, 0x55, 0x14, 0xcf, 0x35, 0x58, 0xf0, 0xf5, 0x60, 0x9c, 0x25, + 0x1f, 0x6f, 0x3a, 0xa9, 0xd3, 0xbb, 0xa4, 0x85, 0xea, 0x62, 0x65, 0x71, 0xf7, 0x67, 0x1c, 0x32, + 0x1e, 0x8f, 0xa1, 0x8a, 0x10, 0x1c, 0xb0, 0xd7, 0xa0, 0x2c, 0x54, 0xe3, 0xfc, 0xc2, 0x2b, 0x37, + 0x28, 0x08, 0x10, 0xae, 0x06, 0x9f, 0x72, 0x1f, 0x0f, 0xc5, 0x56, 0x17, 0xcc, 0xba, 0x04, 0xee, + 0xda, 0xdc, 0xc1, 0x9e, 0xe3, 0x73, 0x14, 0x7e, 0x0c, 0x01, 0x07, 0x21, 0x42, 0x46, 0xd8, 0xdb, + 0x6a, 0x66, 0xd8, 0x5b, 0xbc, 0x90, 0xa1, 0x68, 0x3e, 0xef, 0x22, 0xf0, 0x48, 0xa6, 0x1a, 0x5c, + 0x46, 0x99, 0x16, 0x6a, 0x27, 0x1e, 0xaa, 0x44, 0xaa, 0x9d, 0xde, 0x84, 0xc6, 0xa9, 0x3d, 0x99, + 0x9c, 0xd8, 0xa3, 0x67, 0x5c, 0xf9, 0x51, 0xe7, 0x0a, 0x62, 0x09, 0x44, 0xed, 0xc7, 0x1d, 0xa8, + 0x69, 0xb3, 0x8c, 0x7e, 0xe7, 0x45, 0x13, 0xa2, 0xf9, 0x4d, 0x2a, 0x41, 0x17, 0x5f, 0x41, 0x09, + 0xaa, 0xf9, 0xdf, 0x2f, 0xc5, 0xfd, 0xef, 0x6f, 0x21, 0x6d, 0x17, 0x0a, 0x90, 0x26, 0x0f, 0x9b, + 0x69, 0x8f, 0xb9, 0xfa, 0x03, 0x75, 0x7d, 0x7c, 0xf0, 0x78, 0xfa, 0xb2, 0xb8, 0xc0, 0x80, 0x30, + 0x8e, 0x72, 0x9b, 0x6b, 0xf2, 0x67, 0xb6, 0x33, 0xc6, 0xeb, 0x65, 0xc2, 0xe8, 0x63, 0x4f, 0xc3, + 0x23, 0xdb, 0x41, 0x7f, 0x4e, 0x99, 0x8c, 0x67, 0xf5, 0x0a, 0x1f, 0x7f, 0x91, 0x3c, 0xe0, 0x81, + 0x78, 0x14, 0xc6, 0x54, 0xc5, 0x1a, 0x31, 0x6b, 0x02, 0x05, 0xd7, 0xc1, 0x87, 0xe8, 0x06, 0x18, + 0x52, 0x8c, 0x26, 0xb2, 0xa8, 0x6c, 0x5e, 0x62, 0x95, 0xca, 0xff, 0xdc, 0x7a, 0xce, 0x31, 0x19, + 0xab, 0xc9, 0x8d, 0xf8, 0xeb, 0x31, 0x6e, 0x5c, 0xa0, 0xa2, 0x11, 0x9f, 0x23, 0x90, 0xcf, 0xb4, + 0x33, 0xa4, 0x85, 0xc8, 0xaf, 0x25, 0xca, 0xbf, 0xee, 0x42, 0xef, 0x6d, 0x00, 0x27, 0x60, 0x67, + 0x5e, 0x40, 0xdd, 0x31, 0x06, 0x05, 0xa9, 0x98, 0x55, 0x27, 0x78, 0xc2, 0x01, 0x29, 0x4d, 0xd7, + 0x66, 0x3a, 0x32, 0xef, 0x37, 0x7a, 0x04, 0xb5, 0xa1, 0xae, 0x8f, 0x04, 0xa9, 0x40, 0xb1, 0x7f, + 0xd4, 0xe9, 0x35, 0x6f, 0x90, 0x1a, 0x94, 0x07, 0x9d, 0xe1, 0xf0, 0x00, 0xbd, 0x05, 0xea, 0x50, + 0x51, 0x51, 0x01, 0xf2, 0xec, 0xab, 0xbd, 0xb3, 0xd3, 0x39, 0x1a, 0x76, 0x76, 0x9b, 0x85, 0xef, + 0x17, 0x2b, 0xf9, 0x66, 0xc1, 0xf8, 0x3f, 0x05, 0xa8, 0x69, 0x03, 0xf5, 0x62, 0x7a, 0x1d, 0x8f, + 0x3f, 0x95, 0x4f, 0xc6, 0x9f, 0xd2, 0x2d, 0x3d, 0x22, 0x46, 0x97, 0xb4, 0xf4, 0xbc, 0x09, 0x0d, + 0x11, 0xd4, 0x53, 0xf3, 0xf9, 0x28, 0x99, 0x75, 0x0e, 0x14, 0xd4, 0x1c, 0x63, 0x8c, 0x20, 0x12, + 0xde, 0xde, 0x2e, 0x89, 0xf5, 0x83, 0x20, 0xbc, 0xbf, 0x8d, 0x97, 0xef, 0x03, 0x6f, 0x72, 0x41, + 0x39, 0x06, 0x67, 0x61, 0x6b, 0x02, 0x36, 0x14, 0xf1, 0x5b, 0x04, 0xc9, 0xd4, 0x82, 0x5c, 0x94, + 0xcc, 0x3a, 0x07, 0x8a, 0x8a, 0xde, 0x97, 0x6b, 0x8c, 0x7b, 0xc0, 0x6d, 0xa4, 0x17, 0x4c, 0x6c, + 0x7d, 0x1d, 0xa4, 0x74, 0xab, 0x55, 0x5c, 0x3b, 0xdf, 0x4a, 0xe7, 0x7b, 0xb9, 0x8e, 0x95, 0xbc, + 0x0b, 0x64, 0x3a, 0x9b, 0x59, 0x19, 0x5a, 0xcf, 0xa2, 0xb9, 0x34, 0x9d, 0xcd, 0x86, 0x9a, 0xc2, + 0x8e, 0xbc, 0x06, 0x05, 0x7b, 0x3a, 0x43, 0xd2, 0x12, 0x69, 0x07, 0xdb, 0x87, 0x47, 0x26, 0x03, + 0x7f, 0x03, 0xea, 0xda, 0xdf, 0xcc, 0x41, 0xa1, 0x7d, 0x78, 0xf4, 0x67, 0xa4, 0x53, 0xc5, 0x80, + 0xa3, 0xd1, 0xf1, 0x80, 0xbf, 0xf9, 0x75, 0x48, 0x71, 0xa2, 0xf0, 0xcb, 0x02, 0xea, 0xdb, 0xf8, + 0xeb, 0x39, 0x20, 0x6d, 0x46, 0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c, + 0xc9, 0x20, 0xe7, 0xf9, 0x4c, 0x72, 0xfe, 0x32, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b, + 0xec, 0x41, 0xed, 0x48, 0x0b, 0x16, 0x7d, 0x97, 0x9d, 0x8a, 0x32, 0x4c, 0x34, 0x3f, 0x2f, 0xb9, + 0x56, 0xd7, 0x17, 0xd1, 0xa1, 0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x37, 0xc7, 0x43, 0x26, + 0xaa, 0xfe, 0x45, 0xf1, 0xa9, 0xa5, 0xc5, 0x36, 0x0a, 0xae, 0x53, 0x93, 0x36, 0x59, 0x11, 0x17, + 0x07, 0x5b, 0x6f, 0x79, 0xa7, 0xa7, 0x01, 0x95, 0x8e, 0x6f, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5, + 0x1f, 0x26, 0x63, 0x39, 0xbc, 0xfc, 0x40, 0x78, 0xbb, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5, + 0x06, 0x6c, 0x06, 0x84, 0xd9, 0x48, 0x06, 0x97, 0x50, 0xdf, 0xc6, 0xdf, 0x12, 0xf1, 0x7f, 0x92, + 0x53, 0x70, 0x1f, 0x2a, 0xaa, 0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d, + 0x15, 0x6b, 0x31, 0xa7, 0x16, 0x68, 0xfa, 0xeb, 0x6a, 0xad, 0x7e, 0x0f, 0xc8, 0xa9, 0xe3, 0x27, + 0x91, 0x39, 0xf5, 0x68, 0x62, 0x8a, 0x86, 0x6d, 0x1c, 0xc3, 0x8a, 0x24, 0x7b, 0x9a, 0x4c, 0x16, + 0x9f, 0xdf, 0xdc, 0x4b, 0x0e, 0xb6, 0x7c, 0xea, 0x60, 0x33, 0x7e, 0xa3, 0x04, 0x65, 0x19, 0x9b, + 0x3d, 0x2b, 0x58, 0x78, 0x35, 0x1e, 0x2c, 0xbc, 0x15, 0x0b, 0x45, 0x8a, 0x53, 0x2f, 0x78, 0x9c, + 0x77, 0x92, 0x6c, 0x8a, 0x66, 0xc2, 0x8a, 0xb1, 0x2a, 0xc2, 0x84, 0x55, 0x8a, 0x9b, 0xb0, 0xb2, + 0x02, 0xa8, 0x73, 0x76, 0x3b, 0x15, 0x40, 0xfd, 0x16, 0x70, 0xde, 0x49, 0xf3, 0xf8, 0xad, 0x20, + 0x40, 0x04, 0x48, 0xd1, 0x58, 0xad, 0x4a, 0x92, 0xd5, 0x7a, 0x65, 0x36, 0xe8, 0x63, 0x58, 0xe0, + 0xb1, 0xc4, 0x44, 0xb0, 0x0c, 0x79, 0x58, 0x8a, 0xb1, 0x92, 0xff, 0xf9, 0x45, 0x32, 0x53, 0xe0, + 0xea, 0xf1, 0x76, 0x6b, 0xb1, 0x78, 0xbb, 0xba, 0x69, 0xad, 0x1e, 0x37, 0xad, 0xdd, 0x83, 0xa6, + 0x1a, 0x38, 0xd4, 0x09, 0xbb, 0x81, 0xb8, 0x17, 0xbf, 0x28, 0xe1, 0x8c, 0xbc, 0xf7, 0x82, 0xe8, + 0xb0, 0x5f, 0x8c, 0x1d, 0xf6, 0x8c, 0xf8, 0xb6, 0xc3, 0x90, 0x4e, 0x67, 0xa1, 0x3c, 0xec, 0xb5, + 0x98, 0xf5, 0x7c, 0xe6, 0xf9, 0x45, 0x3b, 0x39, 0xbd, 0x7c, 0x75, 0x6c, 0xc3, 0xe2, 0xa9, 0xed, + 0x4c, 0xe6, 0x3e, 0xb5, 0x7c, 0x6a, 0x07, 0x9e, 0x8b, 0xf4, 0x21, 0xe2, 0x3b, 0x44, 0x17, 0xf7, + 0x38, 0x8e, 0x89, 0x28, 0x66, 0xe3, 0x54, 0xff, 0xc4, 0x6b, 0xad, 0xfa, 0x48, 0xb0, 0x33, 0x58, + 0x84, 0xcc, 0xe0, 0x0e, 0x7c, 0xdd, 0x9e, 0xb5, 0x77, 0xd0, 0x7d, 0xbc, 0x3f, 0x6c, 0xe6, 0xd8, + 0xe7, 0xe0, 0x78, 0x67, 0xa7, 0xd3, 0xd9, 0xc5, 0x33, 0x19, 0x60, 0x61, 0xaf, 0xdd, 0x3d, 0x10, + 0x27, 0x72, 0xb1, 0x59, 0x32, 0xfe, 0x30, 0x0f, 0x35, 0xad, 0x37, 0x18, 0x0c, 0x87, 0xff, 0x64, + 0xf4, 0xb7, 0x2c, 0x82, 0xe1, 0x70, 0x48, 0x77, 0x4c, 0x1e, 0xa9, 0x39, 0xe2, 0x31, 0x7c, 0x6e, + 0xa7, 0x07, 0x64, 0x4b, 0x9e, 0x68, 0xda, 0x24, 0xa9, 0xe0, 0xf5, 0xf9, 0x6b, 0x83, 0xd7, 0x93, + 0xb7, 0x61, 0x49, 0xd6, 0x2c, 0xe7, 0x44, 0x58, 0x5f, 0x04, 0x58, 0x4c, 0xc9, 0xdb, 0x22, 0x9e, + 0x90, 0x38, 0x96, 0x19, 0x5e, 0x51, 0x3a, 0xba, 0xab, 0x93, 0x19, 0xa7, 0xae, 0x2c, 0x06, 0x4e, + 0xb8, 0x70, 0x28, 0x06, 0x47, 0x0c, 0xa7, 0x4c, 0x8e, 0x9d, 0x11, 0x0b, 0x89, 0x33, 0xe2, 0x13, + 0x80, 0xa8, 0x3f, 0xf1, 0xd1, 0xbd, 0x11, 0x1f, 0xdd, 0x9c, 0x36, 0xba, 0x79, 0xe3, 0x1f, 0x0a, + 0xca, 0x26, 0xa6, 0x4a, 0xe9, 0x62, 0xdf, 0x07, 0xa9, 0x1d, 0xb6, 0xf0, 0x62, 0xcc, 0x6c, 0x42, + 0x43, 0x79, 0xeb, 0x7f, 0x59, 0xa4, 0x74, 0x55, 0x42, 0x8a, 0x12, 0xe7, 0xd3, 0x94, 0xf8, 0x0d, + 0xa8, 0x63, 0x80, 0x4a, 0x51, 0x91, 0x8c, 0x10, 0x3d, 0xb5, 0x2f, 0x65, 0xdd, 0x31, 0x12, 0x5c, + 0x4c, 0x90, 0xe0, 0xbf, 0x9d, 0xe3, 0xd1, 0xcc, 0xa2, 0x86, 0x46, 0x34, 0x58, 0x95, 0x19, 0xa7, + 0xc1, 0x02, 0xd5, 0x54, 0xe9, 0xd7, 0xd0, 0xd5, 0x7c, 0x36, 0x5d, 0xcd, 0xa6, 0xd8, 0x85, 0x4c, + 0x8a, 0x6d, 0x5c, 0x42, 0x6b, 0x97, 0xb2, 0xa1, 0x68, 0x4f, 0x26, 0xc9, 0xb1, 0x7c, 0x00, 0xab, + 0x6c, 0x0a, 0xd1, 0x7f, 0x85, 0xa7, 0xe8, 0x27, 0x1a, 0xe1, 0x69, 0x32, 0x13, 0x1e, 0x6c, 0xf7, + 0x61, 0x59, 0xe4, 0xc0, 0x4d, 0xab, 0x87, 0x8e, 0x5b, 0xe2, 0x09, 0xe8, 0x77, 0xcb, 0x70, 0x8d, + 0x5b, 0x70, 0x33, 0xa3, 0x66, 0xa1, 0xb4, 0xfb, 0xcd, 0x1c, 0xac, 0xb5, 0x79, 0x88, 0xa4, 0x6f, + 0xec, 0xd2, 0xff, 0xe7, 0x70, 0x53, 0xdd, 0xa1, 0xd1, 0xee, 0xfe, 0xea, 0x8d, 0x94, 0xd7, 0x6f, + 0xb4, 0x9b, 0x63, 0xd8, 0xd6, 0x16, 0xac, 0x27, 0x5b, 0x23, 0x1a, 0xba, 0x07, 0xcb, 0xbb, 0xf4, + 0x64, 0x7e, 0x76, 0x40, 0x2f, 0xa2, 0x36, 0x12, 0x28, 0x06, 0xe7, 0xde, 0x73, 0x31, 0x50, 0xf8, + 0x1b, 0x9d, 0xec, 0x19, 0x8e, 0x15, 0xcc, 0xe8, 0x48, 0x1a, 0x7d, 0x10, 0x32, 0x98, 0xd1, 0x91, + 0xf1, 0x08, 0x88, 0x5e, 0x8e, 0x58, 0x23, 0x4c, 0x06, 0x9e, 0x9f, 0x58, 0xc1, 0x55, 0x10, 0xd2, + 0xa9, 0xbc, 0xff, 0x0e, 0xc1, 0xfc, 0x64, 0xc0, 0x21, 0xc6, 0x3b, 0x50, 0x3f, 0xb2, 0xaf, 0x4c, + 0xfa, 0x43, 0x71, 0x85, 0x7c, 0x03, 0xca, 0x33, 0xfb, 0x8a, 0x1d, 0x04, 0xca, 0xfe, 0x8b, 0xc9, + 0xc6, 0xef, 0x16, 0x61, 0x81, 0x63, 0x92, 0xbb, 0xfc, 0x5d, 0x1b, 0xc7, 0x45, 0x42, 0x2c, 0x8f, + 0x44, 0x0d, 0x94, 0x3a, 0x35, 0xf3, 0xe9, 0x53, 0x53, 0x28, 0xab, 0x65, 0xfc, 0x4d, 0x69, 0xa9, + 0x73, 0xe7, 0x53, 0x19, 0x74, 0x33, 0x1e, 0x10, 0xa8, 0x18, 0xbd, 0x94, 0xc4, 0x83, 0xa1, 0xc4, + 0x1d, 0x3c, 0x22, 0x49, 0x9b, 0xb7, 0x4e, 0x32, 0x03, 0xe2, 0xc0, 0xd4, 0x41, 0x99, 0xe2, 0x7c, + 0x59, 0xc6, 0x57, 0x88, 0x8b, 0xf3, 0x29, 0xb1, 0xbd, 0xf2, 0x72, 0xb1, 0x9d, 0x6b, 0xb1, 0x5f, + 0x20, 0xb6, 0xc3, 0x2b, 0x88, 0xed, 0xaf, 0xe0, 0x2b, 0x71, 0x13, 0x2a, 0xc8, 0xe1, 0x69, 0xe7, + 0x27, 0xe3, 0xec, 0xd8, 0xf9, 0xf9, 0xa9, 0x26, 0xd8, 0x72, 0xcf, 0x2e, 0xed, 0x00, 0x33, 0xe9, + 0x0f, 0x7f, 0x3a, 0x8a, 0xd1, 0xa7, 0x50, 0x16, 0x50, 0xb6, 0xa0, 0x5d, 0x7b, 0x2a, 0xa3, 0x4c, + 0xe3, 0x6f, 0x36, 0x6c, 0x18, 0x77, 0xf5, 0x87, 0x73, 0xc7, 0xa7, 0x63, 0x19, 0xfd, 0xd1, 0x41, + 0xea, 0xc1, 0x20, 0xac, 0x83, 0x4c, 0xc8, 0x76, 0xe5, 0x93, 0x16, 0x15, 0xb3, 0xec, 0x04, 0x4f, + 0xd8, 0xa7, 0x41, 0xa0, 0x89, 0x31, 0xfd, 0x67, 0x9e, 0x2f, 0xd9, 0x13, 0xe3, 0xf7, 0x72, 0xd0, + 0x14, 0xbb, 0x4b, 0xa5, 0xe9, 0x02, 0x6c, 0xe9, 0x3a, 0x47, 0xa4, 0x17, 0xc7, 0x72, 0x34, 0xa0, + 0x81, 0xaa, 0x3d, 0xc5, 0xab, 0x70, 0xd5, 0x64, 0x8d, 0x01, 0xf7, 0x04, 0xbf, 0xf2, 0x3a, 0xd4, + 0xe4, 0x15, 0xa0, 0xa9, 0x33, 0x91, 0x8f, 0xa2, 0xf1, 0x3b, 0x40, 0x87, 0xce, 0x44, 0xb2, 0x3a, + 0xbe, 0x2d, 0x62, 0x7e, 0xe4, 0x90, 0xd5, 0x31, 0xed, 0x90, 0x1a, 0x7f, 0x90, 0x83, 0x65, 0xad, + 0x2b, 0x62, 0xdf, 0x7e, 0x07, 0xea, 0xea, 0xa9, 0x11, 0xaa, 0x78, 0xec, 0x8d, 0x38, 0x8d, 0x8a, + 0xb2, 0xd5, 0x46, 0x0a, 0x12, 0xb0, 0xc6, 0x8c, 0xed, 0x2b, 0x7e, 0x4f, 0x65, 0x3e, 0x95, 0x72, + 0xf9, 0xd8, 0xbe, 0xda, 0xa3, 0x74, 0x30, 0x9f, 0x92, 0xbb, 0x50, 0x7f, 0x4e, 0xe9, 0x33, 0x85, + 0xc0, 0x09, 0x3b, 0x30, 0x98, 0xc0, 0x30, 0xa0, 0x31, 0xf5, 0xdc, 0xf0, 0x5c, 0xa1, 0x08, 0xf9, + 0x02, 0x81, 0x1c, 0xc7, 0xf8, 0xb7, 0x79, 0x58, 0xe1, 0x0a, 0x64, 0x61, 0x46, 0x10, 0xa4, 0xab, + 0x05, 0x0b, 0x5c, 0xab, 0xcf, 0x89, 0xd7, 0xfe, 0x0d, 0x53, 0x7c, 0x93, 0x8f, 0x5f, 0x51, 0xe9, + 0x2d, 0xc3, 0x85, 0x5c, 0x33, 0xfc, 0x85, 0xf4, 0xf0, 0x5f, 0x3f, 0xbc, 0x59, 0x4e, 0x05, 0xa5, + 0x2c, 0xa7, 0x82, 0x57, 0x31, 0xe5, 0xa7, 0x02, 0x56, 0x94, 0xd3, 0x81, 0xa3, 0x1f, 0xc1, 0x46, + 0x0c, 0x07, 0xa9, 0xb5, 0x73, 0xea, 0xa8, 0x17, 0x0f, 0x56, 0x35, 0xec, 0x81, 0x4c, 0xdb, 0x2e, + 0x43, 0x29, 0x18, 0x79, 0x33, 0x74, 0x8e, 0x8f, 0x8f, 0xaa, 0x38, 0x26, 0x7e, 0x3b, 0x07, 0xad, + 0xbd, 0x28, 0x02, 0xb7, 0x13, 0x84, 0x9e, 0xaf, 0x1e, 0x93, 0xb8, 0x0d, 0xc0, 0x1f, 0x68, 0x43, + 0x35, 0x88, 0x08, 0x9d, 0x86, 0x10, 0x54, 0x82, 0xdc, 0x84, 0x0a, 0x75, 0xc7, 0x3c, 0x91, 0xaf, + 0x86, 0x32, 0x75, 0xc7, 0x52, 0x85, 0x92, 0x3a, 0xe4, 0x1b, 0x71, 0xf6, 0x45, 0x04, 0x01, 0x62, + 0xa3, 0x43, 0x2f, 0x90, 0xd9, 0x28, 0xaa, 0x20, 0x40, 0x87, 0xf6, 0x25, 0xde, 0x71, 0x08, 0x8c, + 0x7f, 0x9c, 0x87, 0xa5, 0xa8, 0x7d, 0x3c, 0x0c, 0xda, 0xdd, 0x54, 0x40, 0x37, 0xe1, 0x0f, 0xa5, + 0x68, 0xf8, 0x5d, 0xb1, 0x24, 0x1c, 0x26, 0xad, 0x69, 0xaa, 0xf5, 0x0a, 0xdf, 0xa0, 0x5d, 0x97, + 0x18, 0x50, 0x93, 0x18, 0xde, 0x3c, 0xd4, 0x02, 0x5e, 0x57, 0x39, 0x4a, 0x7f, 0x1e, 0x32, 0xf1, + 0xda, 0x9e, 0x32, 0x6e, 0x45, 0x08, 0xb8, 0x25, 0x7b, 0x1a, 0x76, 0xf1, 0x25, 0x40, 0x06, 0x66, + 0xd9, 0xf8, 0x64, 0x32, 0x2c, 0x86, 0xdf, 0xe4, 0xd2, 0x16, 0x9f, 0x3d, 0x94, 0xb4, 0x74, 0x51, + 0x84, 0xbf, 0x3f, 0xa4, 0x44, 0x91, 0xd7, 0xa1, 0xc6, 0x0b, 0x8f, 0x62, 0x94, 0x60, 0xf4, 0xc9, + 0xb0, 0xeb, 0x62, 0xba, 0x50, 0x73, 0x7a, 0xf3, 0x98, 0xe6, 0x06, 0x78, 0x55, 0xf2, 0xd1, 0x36, + 0xd5, 0x63, 0x4b, 0x19, 0x21, 0x6b, 0x0a, 0xd6, 0x0b, 0x18, 0xb7, 0x72, 0x33, 0x63, 0x76, 0x05, + 0x31, 0xd8, 0x01, 0x2d, 0x5c, 0xbb, 0x9c, 0x04, 0x4e, 0x11, 0xd6, 0x25, 0xf5, 0x8d, 0x0f, 0xbd, + 0xd9, 0x3c, 0x8d, 0x03, 0x22, 0x29, 0x9c, 0x4f, 0x74, 0x2c, 0x98, 0x0e, 0xf2, 0x74, 0x7c, 0xb6, + 0xb9, 0x00, 0x7c, 0x04, 0x9b, 0x9d, 0x4b, 0x46, 0x58, 0x94, 0xb7, 0xff, 0xe8, 0xd9, 0x5c, 0xda, + 0x47, 0x13, 0x56, 0x96, 0xdc, 0x2b, 0x59, 0x59, 0xc6, 0x3c, 0x84, 0x85, 0x2a, 0xeb, 0xc7, 0x29, + 0x84, 0xeb, 0x97, 0x6c, 0xd7, 0x3a, 0xc1, 0x22, 0x64, 0xc4, 0x1c, 0x06, 0xe2, 0x85, 0x1a, 0x01, + 0x2c, 0x1d, 0xce, 0x27, 0xa1, 0xb3, 0xa3, 0x40, 0xe4, 0x63, 0x91, 0x07, 0xeb, 0x91, 0xa3, 0x96, + 0x59, 0x11, 0xa8, 0x8a, 0x70, 0xb0, 0xa6, 0xac, 0x20, 0x2b, 0x5d, 0xdf, 0xd2, 0x34, 0x5e, 0x83, + 0x71, 0x13, 0x36, 0xa2, 0x2f, 0x3e, 0x6c, 0xf2, 0x44, 0xfa, 0x3b, 0x39, 0x7e, 0xef, 0x8a, 0xa7, + 0x0d, 0x5c, 0x7b, 0x16, 0x9c, 0x7b, 0x21, 0xe9, 0xc0, 0x4a, 0xe0, 0xb8, 0x67, 0x13, 0xaa, 0x17, + 0x1f, 0x88, 0x41, 0x58, 0x8b, 0xb7, 0x8d, 0x67, 0x0d, 0xcc, 0x65, 0x9e, 0x23, 0x2a, 0x2d, 0x20, + 0xdb, 0xd7, 0x35, 0x32, 0x5a, 0x16, 0x89, 0xd1, 0x48, 0x37, 0xbe, 0x0b, 0x8b, 0xf1, 0x8a, 0xc8, + 0xa7, 0x22, 0xf2, 0x4b, 0xd4, 0xaa, 0x42, 0x22, 0xee, 0x45, 0xb4, 0x20, 0x6a, 0xd1, 0xd8, 0x07, + 0xc6, 0x5f, 0xcd, 0x41, 0xcb, 0xa4, 0x6c, 0xe5, 0x6a, 0xad, 0x94, 0x6b, 0xe6, 0x3b, 0xa9, 0x52, + 0xaf, 0xef, 0xab, 0x0c, 0x28, 0x23, 0x5b, 0xf4, 0xde, 0xb5, 0x93, 0xb1, 0x7f, 0x23, 0xd5, 0xa3, + 0xed, 0x0a, 0x2c, 0x70, 0x14, 0x63, 0x03, 0xd6, 0x44, 0x7b, 0x64, 0x5b, 0x22, 0x83, 0x7e, 0xac, + 0xc6, 0x98, 0x41, 0x7f, 0x13, 0x5a, 0x3c, 0x40, 0x83, 0xde, 0x09, 0x91, 0x71, 0x17, 0xc8, 0xa1, + 0x3d, 0xb2, 0x7d, 0xcf, 0x73, 0x8f, 0xa8, 0x2f, 0xfc, 0xf8, 0x91, 0x11, 0x45, 0x7b, 0xb7, 0xe4, + 0x98, 0xf9, 0x97, 0x7c, 0x09, 0xc0, 0x73, 0xa5, 0x87, 0x20, 0xff, 0x32, 0x7c, 0x58, 0xd9, 0xb6, + 0x9f, 0x51, 0x59, 0x92, 0x1c, 0xa2, 0x2f, 0xa0, 0x36, 0x53, 0x85, 0xca, 0x71, 0x97, 0x41, 0xb5, + 0xd2, 0xd5, 0x9a, 0x3a, 0x36, 0xa3, 0x52, 0xa8, 0xb0, 0xc5, 0x30, 0x35, 0x63, 0x79, 0xe6, 0x33, + 0xd0, 0x13, 0x7a, 0xd5, 0x1d, 0x1b, 0x0f, 0x61, 0x35, 0x5e, 0xa7, 0x20, 0x2d, 0x9b, 0x50, 0x99, + 0x0a, 0x98, 0x68, 0xbd, 0xfa, 0x66, 0x32, 0x0b, 0x93, 0x3b, 0x65, 0x9e, 0xee, 0xae, 0x8a, 0xb5, + 0xf0, 0x05, 0x6c, 0xa4, 0x52, 0x44, 0x81, 0x77, 0xa1, 0xae, 0x35, 0x84, 0x77, 0xa3, 0x68, 0x82, + 0x6a, 0x49, 0x60, 0x7c, 0x0e, 0x1b, 0x5c, 0x6c, 0x8b, 0xb2, 0xcb, 0x21, 0x48, 0xf4, 0x22, 0x97, + 0xec, 0xc5, 0xc7, 0x52, 0xd6, 0xd4, 0xb3, 0x46, 0x41, 0x2d, 0xc7, 0x98, 0x26, 0x9d, 0xbc, 0xe4, + 0xa7, 0x71, 0x0c, 0xeb, 0xe9, 0xe1, 0x63, 0xed, 0xff, 0x89, 0x86, 0x5c, 0x0e, 0x4f, 0x94, 0xac, + 0x86, 0xe7, 0xbf, 0xe6, 0xf8, 0xf8, 0xc4, 0x92, 0x44, 0x33, 0xc7, 0x40, 0xa6, 0x34, 0x3c, 0xf7, + 0xc6, 0x56, 0xba, 0xe6, 0x47, 0xca, 0xc7, 0x2c, 0x33, 0xef, 0xd6, 0x21, 0x66, 0xd4, 0x52, 0xc4, + 0x15, 0x8c, 0x69, 0x12, 0xbe, 0x39, 0x82, 0xf5, 0x6c, 0xe4, 0x0c, 0xcf, 0xac, 0x8f, 0xe2, 0xfc, + 0xfc, 0xed, 0x6b, 0xbb, 0xcf, 0x9a, 0xa5, 0xb3, 0xf7, 0xbf, 0x5b, 0x81, 0xb2, 0x50, 0xd5, 0x90, + 0x2d, 0x28, 0x8e, 0xa4, 0x97, 0x6f, 0x14, 0xd8, 0x54, 0xa4, 0xca, 0xff, 0x3b, 0xe8, 0xeb, 0xcb, + 0xf0, 0xc8, 0x17, 0xb0, 0x18, 0x77, 0x74, 0x49, 0x04, 0x20, 0x8a, 0x7b, 0xa8, 0x34, 0x46, 0x09, + 0x27, 0x82, 0x6a, 0xc4, 0x83, 0x71, 0xd6, 0xb4, 0x72, 0xae, 0x31, 0x69, 0x9e, 0xcb, 0xc4, 0xba, + 0xe0, 0xdc, 0xb6, 0x1e, 0x3e, 0xfa, 0x44, 0x18, 0x15, 0x6a, 0x08, 0x1c, 0x9c, 0xdb, 0x0f, 0x1f, + 0x7d, 0x92, 0x14, 0xd8, 0x44, 0xfc, 0x21, 0x4d, 0x60, 0x5b, 0x85, 0x12, 0x7f, 0x2e, 0x81, 0xbb, + 0x6b, 0xf2, 0x0f, 0xa9, 0xce, 0x98, 0xfb, 0xd4, 0x12, 0xb7, 0x7d, 0xf8, 0x29, 0xca, 0x9f, 0xb6, + 0x23, 0x22, 0x6d, 0x80, 0x49, 0x5c, 0x9d, 0xb8, 0x0e, 0x0b, 0xe7, 0xd1, 0xfb, 0x17, 0x0d, 0x53, + 0x7c, 0x19, 0xff, 0xab, 0x04, 0x35, 0x6d, 0x50, 0x48, 0x1d, 0x2a, 0x66, 0x67, 0xd0, 0x31, 0xbf, + 0xec, 0xec, 0x36, 0x6f, 0x90, 0x7b, 0xf0, 0x56, 0xb7, 0xb7, 0xd3, 0x37, 0xcd, 0xce, 0xce, 0xd0, + 0xea, 0x9b, 0x96, 0x8c, 0xb7, 0x7b, 0xd4, 0x7e, 0x7a, 0xd8, 0xe9, 0x0d, 0xad, 0xdd, 0xce, 0xb0, + 0xdd, 0x3d, 0x18, 0x34, 0x73, 0xe4, 0x35, 0x68, 0x45, 0x98, 0x32, 0xb9, 0x7d, 0xd8, 0x3f, 0xee, + 0x0d, 0x9b, 0x79, 0x72, 0x07, 0x6e, 0xed, 0x75, 0x7b, 0xed, 0x03, 0x2b, 0xc2, 0xd9, 0x39, 0x18, + 0x7e, 0x69, 0x75, 0x7e, 0xee, 0xa8, 0x6b, 0x3e, 0x6d, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b, + 0xb2, 0x84, 0x22, 0xb9, 0x09, 0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7, + 0x7b, 0xcd, 0x12, 0x59, 0x86, 0x46, 0xb7, 0xf7, 0x65, 0xfb, 0xa0, 0xbb, 0x6b, 0x99, 0x9d, 0xf6, + 0xc1, 0x61, 0x73, 0x81, 0xac, 0xc0, 0x52, 0x12, 0xaf, 0xcc, 0x8a, 0x90, 0x78, 0xfd, 0x5e, 0xb7, + 0xdf, 0xb3, 0xbe, 0xec, 0x98, 0x83, 0x6e, 0xbf, 0xd7, 0xac, 0x90, 0x75, 0x20, 0xf1, 0xa4, 0xfd, + 0xc3, 0xf6, 0x4e, 0xb3, 0x4a, 0xd6, 0x60, 0x39, 0x0e, 0x7f, 0xd2, 0x79, 0xda, 0x04, 0xd2, 0x82, + 0x55, 0xde, 0x30, 0x6b, 0xbb, 0x73, 0xd0, 0xff, 0xca, 0x3a, 0xec, 0xf6, 0xba, 0x87, 0xc7, 0x87, + 0xcd, 0x1a, 0x46, 0x3d, 0xef, 0x74, 0xac, 0x6e, 0x6f, 0x70, 0xbc, 0xb7, 0xd7, 0xdd, 0xe9, 0x76, + 0x7a, 0xc3, 0x66, 0x9d, 0xd7, 0x9c, 0xd5, 0xf1, 0x06, 0xcb, 0x20, 0x2e, 0xc4, 0x5a, 0xbb, 0xdd, + 0x41, 0x7b, 0xfb, 0xa0, 0xb3, 0xdb, 0x5c, 0x24, 0xb7, 0xe1, 0xe6, 0xb0, 0x73, 0x78, 0xd4, 0x37, + 0xdb, 0xe6, 0x53, 0x79, 0x61, 0xd6, 0xda, 0x6b, 0x77, 0x0f, 0x8e, 0xcd, 0x4e, 0x73, 0x89, 0xbc, + 0x01, 0xb7, 0xcd, 0xce, 0x0f, 0x8e, 0xbb, 0x66, 0x67, 0xd7, 0xea, 0xf5, 0x77, 0x3b, 0xd6, 0x5e, + 0xa7, 0x3d, 0x3c, 0x36, 0x3b, 0xd6, 0x61, 0x77, 0x30, 0xe8, 0xf6, 0x1e, 0x37, 0x9b, 0xe4, 0x2d, + 0xb8, 0xab, 0x50, 0x54, 0x01, 0x09, 0xac, 0x65, 0xd6, 0x3f, 0x39, 0xa5, 0xbd, 0xce, 0xcf, 0x0d, + 0xad, 0xa3, 0x4e, 0xc7, 0x6c, 0x12, 0xb2, 0x09, 0xeb, 0x51, 0xf5, 0xbc, 0x02, 0x51, 0xf7, 0x0a, + 0x4b, 0x3b, 0xea, 0x98, 0x87, 0xed, 0x1e, 0x9b, 0xe0, 0x58, 0xda, 0x2a, 0x6b, 0x76, 0x94, 0x96, + 0x6c, 0xf6, 0x1a, 0x21, 0xb0, 0xa8, 0xcd, 0xca, 0x5e, 0xdb, 0x6c, 0xae, 0x93, 0x25, 0xa8, 0x1d, + 0x1e, 0x1d, 0x59, 0xc3, 0xee, 0x61, 0xa7, 0x7f, 0x3c, 0x6c, 0x6e, 0xa4, 0x67, 0xe9, 0xa8, 0xfd, + 0xf4, 0xa0, 0xdf, 0xde, 0x6d, 0xb6, 0xc8, 0x1a, 0x34, 0xbb, 0xbd, 0x61, 0xc7, 0x64, 0xcb, 0x40, + 0x96, 0xfa, 0xdf, 0xca, 0x64, 0x15, 0x96, 0x64, 0x27, 0x24, 0xf4, 0x8f, 0xca, 0x64, 0x03, 0xc8, + 0x71, 0xcf, 0xec, 0xb4, 0x77, 0xd9, 0x98, 0xaa, 0x84, 0xff, 0x5e, 0x16, 0xe6, 0xe5, 0xdf, 0x2b, + 0x28, 0x3e, 0x30, 0x72, 0x30, 0x8b, 0xbf, 0x65, 0x55, 0xd7, 0xde, 0xa0, 0x7a, 0xd9, 0x7b, 0xa7, + 0x9a, 0x70, 0x5f, 0x48, 0x09, 0xf7, 0x29, 0xed, 0x51, 0x43, 0x97, 0x3c, 0xde, 0x84, 0xc6, 0x94, + 0xbf, 0x6b, 0x25, 0x1e, 0x46, 0x01, 0xe1, 0x6d, 0xc9, 0x81, 0xfc, 0x55, 0x94, 0xd4, 0x83, 0x9f, + 0xa5, 0xf4, 0x83, 0x9f, 0x59, 0x12, 0xe6, 0x42, 0x96, 0x84, 0x79, 0x1f, 0x96, 0x39, 0xd5, 0x72, + 0x5c, 0x67, 0x2a, 0xf5, 0x36, 0xe2, 0xf9, 0x4c, 0xa4, 0x5e, 0x1c, 0x2e, 0x05, 0x5a, 0x29, 0xf4, + 0x0a, 0xea, 0x52, 0x16, 0xf2, 0x6e, 0x4c, 0xd6, 0xe5, 0x44, 0x45, 0xc9, 0xba, 0xaa, 0x06, 0xfb, + 0x32, 0xaa, 0xa1, 0xa6, 0xd5, 0xc0, 0xe1, 0x58, 0xc3, 0x7d, 0x58, 0xa6, 0x97, 0xa1, 0x6f, 0x5b, + 0xde, 0xcc, 0xfe, 0xe1, 0x1c, 0x5d, 0x64, 0x6c, 0xd4, 0x22, 0xd5, 0xcd, 0x25, 0x4c, 0xe8, 0x23, + 0x7c, 0xd7, 0x0e, 0x6d, 0xe3, 0x17, 0x01, 0xd4, 0x81, 0x8b, 0xcf, 0x90, 0xba, 0x9e, 0xbc, 0xe8, + 0x5b, 0x37, 0xf9, 0x07, 0xce, 0x63, 0xe8, 0xf9, 0xf6, 0x19, 0xed, 0x4a, 0xab, 0x70, 0x04, 0x20, + 0xb7, 0xa0, 0xe0, 0xcd, 0xa4, 0x2f, 0x62, 0x55, 0x46, 0xfa, 0x9f, 0x99, 0x0c, 0x6a, 0x7c, 0x02, + 0xf9, 0xfe, 0xec, 0x5a, 0x2e, 0x0a, 0x5f, 0x5d, 0xe3, 0x4f, 0x2d, 0xe4, 0xd1, 0xff, 0x50, 0x7e, + 0xde, 0xff, 0x8b, 0x50, 0xd3, 0x1e, 0x69, 0x23, 0x1b, 0xb0, 0xf2, 0x55, 0x77, 0xd8, 0xeb, 0x0c, + 0x06, 0xd6, 0xd1, 0xf1, 0xf6, 0x93, 0xce, 0x53, 0x6b, 0xbf, 0x3d, 0xd8, 0x6f, 0xde, 0x60, 0x64, + 0xa6, 0xd7, 0x19, 0x0c, 0x3b, 0xbb, 0x31, 0x78, 0x8e, 0xbc, 0x0e, 0x9b, 0xc7, 0xbd, 0xe3, 0x41, + 0x67, 0xd7, 0xca, 0xca, 0x97, 0x67, 0xfb, 0x4a, 0xa4, 0x67, 0x64, 0x2f, 0xdc, 0xff, 0x25, 0x58, + 0x8c, 0x47, 0xbb, 0x21, 0x00, 0x0b, 0x07, 0x9d, 0xc7, 0xed, 0x9d, 0xa7, 0xfc, 0x25, 0x87, 0xc1, + 0xb0, 0x3d, 0xec, 0xee, 0x58, 0xe2, 0xe5, 0x06, 0x46, 0xc3, 0x72, 0xa4, 0x06, 0xe5, 0x76, 0x6f, + 0x67, 0xbf, 0x6f, 0x0e, 0x9a, 0x79, 0xf2, 0x1a, 0x6c, 0xc8, 0x2d, 0xb4, 0xd3, 0x3f, 0x3c, 0xec, + 0x0e, 0x91, 0x7c, 0x0f, 0x9f, 0x1e, 0xb1, 0x1d, 0x73, 0xdf, 0x86, 0x6a, 0xf4, 0xe8, 0x04, 0x92, + 0xc4, 0xee, 0xb0, 0xdb, 0x1e, 0x46, 0xe7, 0x41, 0xf3, 0x06, 0xa3, 0xb8, 0x11, 0x18, 0x5f, 0x8e, + 0x68, 0xe6, 0x78, 0x40, 0x00, 0x09, 0xe4, 0xb5, 0x37, 0xf3, 0x8c, 0x0c, 0x44, 0xd0, 0xed, 0xfe, + 0x90, 0x75, 0xe1, 0x97, 0x61, 0x31, 0xfe, 0xb6, 0x03, 0x69, 0x42, 0x9d, 0xd5, 0xaf, 0x55, 0x01, + 0xb0, 0xc0, 0x5b, 0xdc, 0xcc, 0x71, 0x9a, 0xbf, 0xd3, 0x3f, 0xec, 0xf6, 0x1e, 0xe3, 0x41, 0xd1, + 0xcc, 0x33, 0x50, 0xff, 0x78, 0xf8, 0xb8, 0xaf, 0x40, 0x05, 0x96, 0x83, 0x77, 0xa7, 0x59, 0xbc, + 0xff, 0x43, 0x58, 0x4e, 0xbd, 0x02, 0xc1, 0x5a, 0xdd, 0x3f, 0x1e, 0xee, 0xf4, 0x0f, 0xf5, 0x7a, + 0x6a, 0x50, 0xde, 0x39, 0x68, 0x77, 0x0f, 0xd1, 0x50, 0xd3, 0x80, 0xea, 0x71, 0x4f, 0x7e, 0xe6, + 0xe3, 0xef, 0x57, 0x14, 0x18, 0xf5, 0xda, 0xeb, 0x9a, 0x83, 0xa1, 0x35, 0x18, 0xb6, 0x1f, 0x77, + 0x9a, 0x45, 0x96, 0x57, 0x92, 0xb2, 0xd2, 0xfd, 0xcf, 0x61, 0x31, 0xee, 0x38, 0x1f, 0xb7, 0xbf, + 0x6d, 0xc2, 0xfa, 0x76, 0x67, 0xf8, 0x55, 0xa7, 0xd3, 0xc3, 0x29, 0xdf, 0xe9, 0xf4, 0x86, 0x66, + 0xfb, 0xa0, 0x3b, 0x7c, 0xda, 0xcc, 0xdd, 0xff, 0x02, 0x9a, 0x49, 0xa7, 0x8f, 0x98, 0x97, 0xcc, + 0x8b, 0xdc, 0x69, 0xee, 0xff, 0x87, 0x1c, 0xac, 0x66, 0x99, 0x07, 0xd9, 0xc2, 0x14, 0x84, 0x90, + 0x9d, 0x94, 0x83, 0x7e, 0xcf, 0xea, 0xf5, 0x31, 0x7e, 0xfb, 0x26, 0xac, 0x27, 0x12, 0x64, 0x2f, + 0x72, 0xe4, 0x16, 0x6c, 0xa4, 0x32, 0x59, 0x66, 0xff, 0x18, 0xe7, 0xb2, 0x05, 0xab, 0x89, 0xc4, + 0x8e, 0x69, 0xf6, 0xcd, 0x66, 0x81, 0xbc, 0x07, 0xf7, 0x12, 0x29, 0x69, 0xfe, 0x40, 0xb2, 0x0f, + 0x45, 0xf2, 0x0e, 0xbc, 0x99, 0xc2, 0x8e, 0x8e, 0x50, 0x6b, 0xbb, 0x7d, 0xc0, 0xba, 0xd7, 0x2c, + 0xdd, 0xff, 0x83, 0x22, 0x40, 0x74, 0x5d, 0x96, 0xd5, 0xbf, 0xdb, 0x1e, 0xb6, 0x0f, 0xfa, 0x6c, + 0xcf, 0x98, 0xfd, 0x21, 0x2b, 0xdd, 0xec, 0xfc, 0xa0, 0x79, 0x23, 0x33, 0xa5, 0x7f, 0xc4, 0x3a, + 0xb4, 0x01, 0x2b, 0x7c, 0xfd, 0x1d, 0xb0, 0x6e, 0xb0, 0xe5, 0xc2, 0x9f, 0x02, 0x60, 0x4c, 0xc8, + 0xf1, 0xd1, 0x9e, 0xd9, 0xef, 0x0d, 0xad, 0xc1, 0xfe, 0xf1, 0x70, 0x17, 0x5f, 0x16, 0xd8, 0x31, + 0xbb, 0x47, 0xbc, 0xcc, 0xe2, 0x8b, 0x10, 0x58, 0xd1, 0x25, 0xb6, 0xc1, 0x1f, 0xf7, 0x07, 0x83, + 0xee, 0x91, 0xf5, 0x83, 0xe3, 0x8e, 0xd9, 0xed, 0x0c, 0x30, 0xe3, 0x42, 0x06, 0x9c, 0xe1, 0x97, + 0xd9, 0x9a, 0x1d, 0x1e, 0x7c, 0x29, 0x0e, 0x3a, 0x86, 0x5a, 0x89, 0x83, 0x18, 0x56, 0x95, 0xcd, + 0x0e, 0x3b, 0x9c, 0x33, 0x4a, 0x86, 0x6b, 0xd2, 0x58, 0xbe, 0x1a, 0x3b, 0x4a, 0x53, 0x3b, 0x1f, + 0xb3, 0xd5, 0xb3, 0x93, 0x58, 0x2e, 0xe4, 0x48, 0x14, 0xff, 0xb6, 0xbb, 0x6b, 0x62, 0x86, 0xc5, + 0x14, 0x94, 0xe1, 0x2e, 0xb1, 0x45, 0xc8, 0x4e, 0x6f, 0x86, 0xd2, 0x94, 0x1f, 0x2c, 0x65, 0x99, + 0xf5, 0xf8, 0xab, 0xe3, 0xc3, 0xed, 0xbe, 0x64, 0x03, 0x78, 0x7b, 0x49, 0x06, 0x9c, 0xe1, 0xaf, + 0xe0, 0xd3, 0x0d, 0x9c, 0x1c, 0x21, 0xe2, 0xaa, 0x0e, 0x60, 0x18, 0x6b, 0x8c, 0x08, 0x4a, 0xc0, + 0xcf, 0x77, 0xcc, 0xbe, 0xc5, 0xf8, 0x2c, 0xe4, 0x11, 0x19, 0xfe, 0xfa, 0xf5, 0xc9, 0x2c, 0xf7, + 0xc6, 0xc3, 0x7f, 0xf1, 0x06, 0x54, 0xd5, 0x8d, 0x19, 0xf2, 0x7d, 0x68, 0xc4, 0xa2, 0x64, 0x90, + 0x5b, 0xd9, 0xb1, 0x33, 0x50, 0x8a, 0xda, 0x7c, 0xed, 0x45, 0x81, 0x35, 0xc8, 0xa1, 0xa6, 0xb8, + 0xe0, 0x85, 0xbd, 0x96, 0x54, 0x26, 0xc4, 0x4a, 0xbb, 0x7d, 0x4d, 0xaa, 0x28, 0xee, 0x09, 0xbe, + 0x92, 0x80, 0x51, 0x25, 0xc5, 0xf1, 0x42, 0x6e, 0x47, 0x21, 0xeb, 0x75, 0xb8, 0x2c, 0x50, 0x8a, + 0x89, 0x5a, 0xda, 0x2e, 0x0d, 0x6d, 0x67, 0x12, 0x90, 0x5d, 0xa8, 0x69, 0x0f, 0x0f, 0x93, 0x9b, + 0xd7, 0xbe, 0x92, 0xbc, 0xb9, 0x99, 0x95, 0x24, 0x9a, 0xf4, 0x5d, 0xa8, 0xaa, 0x87, 0x57, 0xc9, + 0x86, 0xf6, 0x30, 0xb0, 0xfe, 0x60, 0xed, 0x66, 0x2b, 0x9d, 0x20, 0xf2, 0xef, 0x42, 0x4d, 0x7b, + 0x25, 0x55, 0xb5, 0x22, 0xfd, 0x46, 0xab, 0x6a, 0x45, 0xd6, 0xa3, 0xaa, 0x07, 0xb0, 0x26, 0xd4, + 0x23, 0x27, 0xf4, 0xeb, 0x0c, 0x0f, 0x49, 0x0f, 0xcf, 0x83, 0x1c, 0xf9, 0x02, 0x2a, 0xf2, 0x6d, + 0x5e, 0xb2, 0x9e, 0xfd, 0xd6, 0xf1, 0xe6, 0x46, 0x0a, 0x2e, 0x9a, 0xd2, 0x06, 0x88, 0x5e, 0x59, + 0x25, 0xb2, 0xe3, 0xa9, 0xf7, 0x5c, 0xd5, 0xcc, 0x64, 0x3c, 0xc9, 0xba, 0x0b, 0x35, 0xed, 0x41, + 0x55, 0x35, 0x26, 0xe9, 0xc7, 0x58, 0xd5, 0x98, 0x64, 0xbd, 0xbf, 0xfa, 0x7d, 0x68, 0xc4, 0x5e, + 0x46, 0x55, 0xeb, 0x38, 0xeb, 0xdd, 0x55, 0xb5, 0x8e, 0xb3, 0x1f, 0x53, 0xdd, 0x85, 0x9a, 0xf6, + 0x5a, 0xa9, 0x6a, 0x51, 0xfa, 0xc9, 0x54, 0xd5, 0xa2, 0x8c, 0xc7, 0x4d, 0xd9, 0x6e, 0x88, 0x3f, + 0x55, 0xaa, 0x76, 0x43, 0xe6, 0x9b, 0xa7, 0x6a, 0x37, 0x64, 0xbf, 0x6f, 0xca, 0x96, 0x9e, 0x7a, + 0x1e, 0x85, 0x6c, 0xc4, 0xb4, 0x12, 0xd1, 0x3b, 0x2b, 0x6a, 0xe9, 0xa5, 0x5f, 0x52, 0x79, 0x0c, + 0x2b, 0x6a, 0xd1, 0xa8, 0xc7, 0x4d, 0x02, 0xd5, 0xa6, 0xcc, 0x27, 0x54, 0x36, 0x9b, 0xc9, 0xd4, + 0x07, 0x39, 0xf2, 0x19, 0x94, 0xc5, 0x8b, 0x11, 0x64, 0x2d, 0xf9, 0x82, 0x04, 0x6f, 0xc4, 0x7a, + 0xf6, 0xc3, 0x12, 0xe4, 0x08, 0x37, 0xb4, 0xfe, 0xa4, 0x83, 0xbe, 0x62, 0x33, 0x5e, 0x81, 0xd8, + 0x7c, 0xfd, 0xba, 0xe4, 0xa8, 0xc4, 0xe4, 0x33, 0x24, 0xb7, 0xaf, 0x8b, 0xf6, 0x15, 0x2f, 0xf1, + 0xba, 0xb0, 0xa4, 0x8f, 0xa1, 0xae, 0x3f, 0x53, 0x47, 0xf4, 0x7d, 0x98, 0x2c, 0xeb, 0x56, 0x66, + 0x9a, 0x28, 0xe8, 0x4b, 0x58, 0x57, 0xe3, 0xad, 0x87, 0x9e, 0x0a, 0xc8, 0x9d, 0x8c, 0x80, 0x54, + 0xb1, 0x51, 0xbf, 0x79, 0x6d, 0xc4, 0xaa, 0x07, 0x39, 0x24, 0xb2, 0xb1, 0x97, 0xa5, 0x22, 0x22, + 0x9b, 0xf5, 0xa0, 0x56, 0x44, 0x64, 0xb3, 0x9f, 0xa3, 0x6a, 0xc3, 0x92, 0x16, 0x3a, 0x6b, 0x70, + 0xe5, 0x8e, 0xd4, 0x7a, 0x4f, 0xc7, 0xd0, 0xdf, 0xcc, 0x52, 0xd2, 0x93, 0x1d, 0xa8, 0xe9, 0xd1, + 0xb7, 0x5e, 0x90, 0x7d, 0x43, 0x4b, 0xd2, 0x43, 0x9b, 0x3f, 0xc8, 0x91, 0x03, 0x68, 0x26, 0x63, + 0xe5, 0xaa, 0x2d, 0x9c, 0x15, 0x5f, 0x78, 0x33, 0x91, 0x18, 0x8b, 0xb0, 0xcb, 0xd6, 0x85, 0xa8, + 0x9a, 0x3f, 0x0a, 0xeb, 0xf9, 0xc9, 0xa3, 0x88, 0xc3, 0xe5, 0x30, 0xa8, 0xd2, 0x12, 0xa9, 0xd8, + 0xec, 0x7b, 0xb9, 0x07, 0x39, 0xb2, 0x07, 0xf5, 0x58, 0xa8, 0xc8, 0xd8, 0xe5, 0xad, 0x44, 0x37, + 0x5b, 0x7a, 0x5a, 0xa2, 0x9f, 0x87, 0xb0, 0x18, 0x77, 0x3a, 0x51, 0x0d, 0xcb, 0xf4, 0x8c, 0x51, + 0xd3, 0x97, 0xed, 0xa9, 0x42, 0x7e, 0x16, 0x6a, 0x8c, 0x26, 0x4b, 0xcf, 0x48, 0xa2, 0xd1, 0xe9, + 0xe4, 0x9c, 0x71, 0x98, 0xd0, 0x9a, 0x17, 0xfe, 0x72, 0x3e, 0x87, 0xfd, 0xfa, 0x0e, 0x7f, 0x06, + 0x5f, 0x3a, 0xc7, 0xb1, 0xf9, 0x7f, 0xd5, 0x42, 0xc8, 0x1e, 0xaf, 0x7c, 0xe8, 0xf1, 0x98, 0x0c, + 0x37, 0x35, 0x1c, 0x01, 0x7b, 0xb5, 0x36, 0xb4, 0x79, 0x1b, 0x44, 0x9e, 0xd8, 0x1a, 0x7c, 0xc5, + 0xb2, 0xc8, 0xa7, 0x00, 0x91, 0x53, 0x32, 0x49, 0xf8, 0xbd, 0xaa, 0x0d, 0x95, 0xe1, 0xb7, 0xdc, + 0xe1, 0xfb, 0x5d, 0x39, 0xde, 0xea, 0x47, 0x72, 0xdc, 0x07, 0x38, 0x76, 0x24, 0x27, 0x8b, 0xf9, + 0x08, 0x1a, 0x07, 0x9e, 0xf7, 0x6c, 0x3e, 0x53, 0x57, 0x75, 0xe2, 0x6e, 0x5f, 0xfb, 0x76, 0x70, + 0xbe, 0x99, 0x68, 0x16, 0x69, 0xc3, 0xb2, 0x22, 0x11, 0x91, 0xe7, 0x6f, 0x1c, 0x29, 0x46, 0x18, + 0x12, 0x05, 0x3c, 0xc8, 0x91, 0x87, 0x50, 0xdf, 0xa5, 0x23, 0x0c, 0x66, 0x83, 0x6e, 0x40, 0x2b, + 0x31, 0x97, 0x12, 0xee, 0x3f, 0xb4, 0xd9, 0x88, 0x01, 0x25, 0x89, 0x8b, 0x1c, 0xdd, 0xf4, 0x33, + 0x23, 0xee, 0x2d, 0x16, 0x23, 0x71, 0x29, 0x67, 0xb7, 0x2f, 0x61, 0x39, 0xe5, 0xec, 0xa5, 0xa8, + 0xdb, 0x75, 0x0e, 0x68, 0x9b, 0x77, 0xaf, 0x47, 0x10, 0xe5, 0x7e, 0x0f, 0x1a, 0x3c, 0xd2, 0xfd, + 0x09, 0xe5, 0xf7, 0xbe, 0x13, 0x71, 0x0c, 0xf5, 0x4b, 0xe5, 0x49, 0x92, 0xc4, 0x33, 0x3c, 0xc6, + 0x37, 0xb7, 0xb4, 0x5b, 0xd5, 0x6a, 0x5e, 0xd3, 0x37, 0xbd, 0xd5, 0xbc, 0x66, 0x5d, 0xe0, 0xfe, + 0x1c, 0x6a, 0x8f, 0x69, 0x28, 0xef, 0x29, 0x2b, 0xfe, 0x28, 0x71, 0x71, 0x79, 0x33, 0xe3, 0x76, + 0x39, 0xf9, 0x04, 0xb3, 0xaa, 0x98, 0x1b, 0xeb, 0x5a, 0x2d, 0x7a, 0xd6, 0xa5, 0x04, 0x9c, 0x71, + 0x1f, 0x5a, 0x38, 0x20, 0xd5, 0xf0, 0x74, 0xf8, 0x27, 0xd5, 0xf0, 0xac, 0xe8, 0x41, 0x3f, 0xcb, + 0x47, 0x40, 0xbb, 0x19, 0x1d, 0xb1, 0x60, 0xc9, 0x4b, 0xd4, 0xaa, 0xf9, 0x3a, 0xfa, 0x23, 0x80, + 0x41, 0xe8, 0xcd, 0x76, 0x6d, 0x3a, 0xf5, 0xdc, 0x88, 0x26, 0x44, 0x77, 0x72, 0xa3, 0x8d, 0xa8, + 0x5d, 0xcc, 0x25, 0x5f, 0x69, 0xbc, 0x69, 0x6c, 0x4a, 0xe4, 0xb4, 0x5f, 0x7b, 0x6d, 0x57, 0x75, + 0x27, 0xe3, 0xea, 0x2e, 0x12, 0x09, 0x88, 0x7c, 0xe9, 0x14, 0xa7, 0x99, 0x72, 0xd3, 0x53, 0x7b, + 0x3d, 0xc3, 0xf1, 0xee, 0xbb, 0x50, 0x8d, 0x9c, 0x90, 0x36, 0xa2, 0xd8, 0x64, 0x31, 0x97, 0x25, + 0x45, 0xbd, 0xd3, 0x0e, 0x40, 0x3d, 0x58, 0xe1, 0xcd, 0x51, 0xc7, 0x1f, 0xde, 0xd5, 0x54, 0x4f, + 0xc6, 0xa5, 0x3d, 0x6f, 0xd4, 0xfe, 0xc9, 0xf2, 0x1f, 0x61, 0xfb, 0x27, 0xe5, 0x60, 0xa0, 0xf6, + 0xcf, 0x75, 0x8e, 0x25, 0x6a, 0xff, 0x5c, 0xef, 0x9b, 0xd0, 0x83, 0x95, 0x0c, 0x57, 0x01, 0xf2, + 0x86, 0x14, 0x6c, 0xae, 0x75, 0x23, 0xd8, 0xcc, 0x34, 0x29, 0x93, 0x21, 0x6c, 0xf0, 0x3c, 0xed, + 0xc9, 0x24, 0x61, 0x99, 0x7e, 0x5d, 0xcb, 0x90, 0x61, 0x6d, 0x8f, 0xb1, 0x32, 0x09, 0x8b, 0x7b, + 0x0f, 0x9a, 0x49, 0xa3, 0x2e, 0xb9, 0x1e, 0x7d, 0xf3, 0x4e, 0x8c, 0x65, 0x4f, 0x1b, 0x82, 0xc9, + 0x97, 0xca, 0xb4, 0x9c, 0x68, 0xe3, 0x9d, 0xe8, 0xe9, 0xd3, 0x4c, 0x43, 0xb8, 0x92, 0x06, 0x32, + 0x2d, 0xd3, 0xe4, 0xe7, 0x60, 0x23, 0xb9, 0xa2, 0x65, 0xc9, 0x77, 0xb3, 0x86, 0xeb, 0x5a, 0x56, + 0x2e, 0xde, 0xa1, 0x07, 0x39, 0x46, 0x88, 0x75, 0x03, 0xb0, 0x5a, 0x48, 0x19, 0x96, 0x68, 0xb5, + 0x90, 0x32, 0x2d, 0xc6, 0x47, 0xb0, 0x94, 0xb0, 0xfd, 0x2a, 0x36, 0x38, 0xdb, 0x5a, 0xac, 0xd8, + 0xe0, 0xeb, 0x4c, 0xc6, 0x03, 0x68, 0x26, 0xad, 0xba, 0x6a, 0xae, 0xaf, 0xb1, 0x14, 0x6f, 0xde, + 0xb9, 0x36, 0x3d, 0xde, 0x4c, 0xcd, 0xfe, 0x19, 0x6b, 0x66, 0xda, 0x6a, 0x1b, 0x6b, 0x66, 0x86, + 0xf5, 0x75, 0xfb, 0x9d, 0x9f, 0xff, 0xd6, 0x99, 0x13, 0x9e, 0xcf, 0x4f, 0xb6, 0x46, 0xde, 0xf4, + 0x83, 0x89, 0xd4, 0x6a, 0x88, 0x40, 0x0a, 0x1f, 0x4c, 0xdc, 0xf1, 0x07, 0x58, 0xc0, 0xc9, 0xc2, + 0xcc, 0xf7, 0x42, 0xef, 0xa3, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x5d, 0x18, 0x9c, 0x95, + 0x95, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/lnrpc/rpc.proto b/lnrpc/rpc.proto index 61fe65ec..7f5ff92e 100644 --- a/lnrpc/rpc.proto +++ b/lnrpc/rpc.proto @@ -2493,12 +2493,22 @@ message Hop { /* An optional TLV record that signals the use of an MPP payment. If present, - the receiver will enforce that that the same mpp_record is included in the - final hop payload of all non-zero payments in the HTLC set. If empty, a - regular single-shot payment is or was attempted. + the receiver will enforce that the same mpp_record is included in the final + hop payload of all non-zero payments in the HTLC set. If empty, a regular + single-shot payment is or was attempted. */ MPPRecord mpp_record = 10; + /* + An optional TLV record that signals the use of an AMP payment. If present, + the receiver will treat all received payments including the same + (payment_addr, set_id) pair as being part of one logical payment. The + payment will be settled by XORing the root_share's together and deriving the + child hashes and preimages according to BOLT XX. Must be used in conjunction + with mpp_record. + */ + AMPRecord amp_record = 12; + /* An optional set of key-value TLV records. This is useful within the context of the SendToRoute call as it allows callers to specify arbitrary K-V pairs @@ -2525,6 +2535,14 @@ message MPPRecord { int64 total_amt_msat = 10; } +message AMPRecord { + bytes root_share = 1; + + bytes set_id = 2; + + uint32 child_index = 3; +} + /* A path through the channel graph which runs over one or more channels in succession. This struct carries all the information required to craft the diff --git a/lnrpc/rpc.swagger.json b/lnrpc/rpc.swagger.json index 1c186ba0..f19ac88c 100644 --- a/lnrpc/rpc.swagger.json +++ b/lnrpc/rpc.swagger.json @@ -2536,6 +2536,23 @@ }, "description": "Details specific to AMP HTLCs." }, + "lnrpcAMPRecord": { + "type": "object", + "properties": { + "root_share": { + "type": "string", + "format": "byte" + }, + "set_id": { + "type": "string", + "format": "byte" + }, + "child_index": { + "type": "integer", + "format": "int64" + } + } + }, "lnrpcAbandonChannelResponse": { "type": "object" }, @@ -4025,7 +4042,11 @@ }, "mpp_record": { "$ref": "#/definitions/lnrpcMPPRecord", - "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that that the same mpp_record is included in the\nfinal hop payload of all non-zero payments in the HTLC set. If empty, a\nregular single-shot payment is or was attempted." + "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that the same mpp_record is included in the final\nhop payload of all non-zero payments in the HTLC set. If empty, a regular\nsingle-shot payment is or was attempted." + }, + "amp_record": { + "$ref": "#/definitions/lnrpcAMPRecord", + "description": "An optional TLV record that signals the use of an AMP payment. If present,\nthe receiver will treat all received payments including the same\n(payment_addr, set_id) pair as being part of one logical payment. The\npayment will be settled by XORing the root_share's together and deriving the\nchild hashes and preimages according to BOLT XX. Must be used in conjunction\nwith mpp_record." }, "custom_records": { "type": "object", diff --git a/lntest/itest/lnd_amp_test.go b/lntest/itest/lnd_amp_test.go new file mode 100644 index 00000000..d6c3b89a --- /dev/null +++ b/lntest/itest/lnd_amp_test.go @@ -0,0 +1,208 @@ +package itest + +import ( + "context" + "crypto/rand" + "time" + + "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/amp" + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/stretchr/testify/require" +) + +func testSendToRouteAMP(net *lntest.NetworkHarness, t *harnessTest) { + ctxb := context.Background() + + ctx := newMppTestContext(t, net) + defer ctx.shutdownNodes() + + const ( + paymentAmt = btcutil.Amount(300000) + numShards = 3 + shardAmt = paymentAmt / numShards + chanAmt = shardAmt * 3 / 2 + ) + + // Set up a network with three different paths Alice <-> Bob. + // _ Eve _ + // / \ + // Alice -- Carol ---- Bob + // \ / + // \__ Dave ____/ + // + ctx.openChannel(ctx.carol, ctx.bob, chanAmt) + ctx.openChannel(ctx.dave, ctx.bob, chanAmt) + ctx.openChannel(ctx.alice, ctx.dave, chanAmt) + ctx.openChannel(ctx.eve, ctx.bob, chanAmt) + ctx.openChannel(ctx.carol, ctx.eve, chanAmt) + + // Since the channel Alice-> Carol will have to carry two + // shards, we make it larger. + ctx.openChannel(ctx.alice, ctx.carol, chanAmt+shardAmt) + + defer ctx.closeChannels() + + ctx.waitForChannels() + + // We'll send shards along three routes from Alice. + sendRoutes := [numShards][]*lntest.HarnessNode{ + {ctx.carol, ctx.bob}, + {ctx.dave, ctx.bob}, + {ctx.carol, ctx.eve, ctx.bob}, + } + + payAddr := make([]byte, 32) + _, err := rand.Read(payAddr) + require.NoError(t.t, err) + + setID := make([]byte, 32) + _, err = rand.Read(setID) + require.NoError(t.t, err) + + var sharer amp.Sharer + sharer, err = amp.NewSeedSharer() + require.NoError(t.t, err) + + childPreimages := make(map[lntypes.Preimage]uint32) + responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes)) + for i, hops := range sendRoutes { + // Build a route for the specified hops. + r, err := ctx.buildRoute(ctxb, shardAmt, net.Alice, hops) + if err != nil { + t.Fatalf("unable to build route: %v", err) + } + + // Set the MPP records to indicate this is a payment shard. + hop := r.Hops[len(r.Hops)-1] + hop.TlvPayload = true + hop.MppRecord = &lnrpc.MPPRecord{ + PaymentAddr: payAddr, + TotalAmtMsat: int64(paymentAmt * 1000), + } + + var child *amp.Child + if i < len(sendRoutes)-1 { + var left amp.Sharer + left, sharer, err = sharer.Split() + require.NoError(t.t, err) + + child = left.Child(uint32(i)) + } else { + child = sharer.Child(uint32(i)) + } + childPreimages[child.Preimage] = child.Index + + hop.AmpRecord = &lnrpc.AMPRecord{ + RootShare: child.Share[:], + SetId: setID, + ChildIndex: child.Index, + } + + // Send the shard. + sendReq := &routerrpc.SendToRouteRequest{ + PaymentHash: child.Hash[:], + Route: r, + } + + // We'll send all shards in their own goroutine, since SendToRoute will + // block as long as the payment is in flight. + go func() { + ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) + resp, err := net.Alice.RouterClient.SendToRouteV2(ctxt, sendReq) + if err != nil { + t.Fatalf("unable to send payment: %v", err) + } + + responses <- resp + }() + } + + // Assert that all of the child preimages are unique. + require.Equal(t.t, len(sendRoutes), len(childPreimages)) + + // Make a copy of the childPreimages map for validating the resulting + // invoice. + childPreimagesCopy := make(map[lntypes.Preimage]uint32) + for preimage, childIndex := range childPreimages { + childPreimagesCopy[preimage] = childIndex + } + + // Wait for all responses to be back, and check that they all + // succeeded. + for range sendRoutes { + var resp *lnrpc.HTLCAttempt + select { + case resp = <-responses: + case <-time.After(defaultTimeout): + t.Fatalf("response not received") + } + + if resp.Failure != nil { + t.Fatalf("received payment failure : %v", resp.Failure) + } + + preimage, err := lntypes.MakePreimage(resp.Preimage) + require.NoError(t.t, err) + + // Assert that the response includes one of our child preimages. + _, ok := childPreimages[preimage] + require.True(t.t, ok) + + // Remove this preimage from out set so that we ensure all + // responses have a unique child preimage. + delete(childPreimages, preimage) + } + childPreimages = childPreimagesCopy + + // Fetch Bob's invoices. + invoiceResp, err := net.Bob.ListInvoices( + ctxb, &lnrpc.ListInvoiceRequest{}, + ) + require.NoError(t.t, err) + + // There should only be one invoice. + require.Equal(t.t, 1, len(invoiceResp.Invoices)) + rpcInvoice := invoiceResp.Invoices[0] + + // Assert that the invoice is settled for the total payment amount and + // has the correct payment address. + require.True(t.t, rpcInvoice.Settled) + require.Equal(t.t, lnrpc.Invoice_SETTLED, rpcInvoice.State) + require.Equal(t.t, int64(paymentAmt), rpcInvoice.AmtPaidSat) + require.Equal(t.t, int64(paymentAmt*1000), rpcInvoice.AmtPaidMsat) + require.Equal(t.t, payAddr, rpcInvoice.PaymentAddr) + + // Finally, assert that the proper set id is recorded for each htlc, and + // that the preimage hash pair is valid. + require.Equal(t.t, numShards, len(rpcInvoice.Htlcs)) + for _, htlc := range rpcInvoice.Htlcs { + require.NotNil(t.t, htlc.Amp) + require.Equal(t.t, setID, htlc.Amp.SetId) + + // Parse the child hash and child preimage, and assert they are + // well-formed. + childHash, err := lntypes.MakeHash(htlc.Amp.Hash) + require.NoError(t.t, err) + childPreimage, err := lntypes.MakePreimage(htlc.Amp.Preimage) + require.NoError(t.t, err) + + // Assert that the preimage actually matches the hashes. + validPreimage := childPreimage.Matches(childHash) + require.True(t.t, validPreimage) + + // Assert that the HTLC includes one of our child preimages. + childIndex, ok := childPreimages[childPreimage] + require.True(t.t, ok) + + // Assert that the correct child index is reflected. + require.Equal(t.t, childIndex, htlc.Amp.ChildIndex) + + // Remove this preimage from our set so that we ensure all HTLCs + // have a unique child preimage. + delete(childPreimages, childPreimage) + } +} diff --git a/lntest/itest/lnd_mpp_test.go b/lntest/itest/lnd_mpp_test.go index 7ccca9e4..0113a8fa 100644 --- a/lntest/itest/lnd_mpp_test.go +++ b/lntest/itest/lnd_mpp_test.go @@ -74,36 +74,6 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) { payAddr := decodeResp.PaymentAddr - // Helper function for Alice to build a route from pubkeys. - buildRoute := func(amt btcutil.Amount, hops []*lntest.HarnessNode) ( - *lnrpc.Route, error) { - - rpcHops := make([][]byte, 0, len(hops)) - for _, hop := range hops { - k := hop.PubKeyStr - pubkey, err := route.NewVertexFromStr(k) - if err != nil { - return nil, fmt.Errorf("error parsing %v: %v", - k, err) - } - rpcHops = append(rpcHops, pubkey[:]) - } - - req := &routerrpc.BuildRouteRequest{ - AmtMsat: int64(amt * 1000), - FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta, - HopPubkeys: rpcHops, - } - - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - routeResp, err := net.Alice.RouterClient.BuildRoute(ctxt, req) - if err != nil { - return nil, err - } - - return routeResp.Route, nil - } - // We'll send shards along three routes from Alice. sendRoutes := [][]*lntest.HarnessNode{ {ctx.carol, ctx.bob}, @@ -114,7 +84,7 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) { responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes)) for _, hops := range sendRoutes { // Build a route for the specified hops. - r, err := buildRoute(shardAmt, hops) + r, err := ctx.buildRoute(ctxb, shardAmt, net.Alice, hops) if err != nil { t.Fatalf("unable to build route: %v", err) } @@ -394,3 +364,34 @@ func (c *mppTestContext) waitForChannels() { } } } + +// Helper function for Alice to build a route from pubkeys. +func (c *mppTestContext) buildRoute(ctxb context.Context, amt btcutil.Amount, + sender *lntest.HarnessNode, hops []*lntest.HarnessNode) (*lnrpc.Route, + error) { + + rpcHops := make([][]byte, 0, len(hops)) + for _, hop := range hops { + k := hop.PubKeyStr + pubkey, err := route.NewVertexFromStr(k) + if err != nil { + return nil, fmt.Errorf("error parsing %v: %v", + k, err) + } + rpcHops = append(rpcHops, pubkey[:]) + } + + req := &routerrpc.BuildRouteRequest{ + AmtMsat: int64(amt * 1000), + FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta, + HopPubkeys: rpcHops, + } + + ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) + routeResp, err := sender.RouterClient.BuildRoute(ctxt, req) + if err != nil { + return nil, err + } + + return routeResp.Route, nil +} diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index 216851e2..7f630c0d 100644 --- a/lntest/itest/lnd_test_list_on_test.go +++ b/lntest/itest/lnd_test_list_on_test.go @@ -266,6 +266,10 @@ var allTestCases = []*testCase{ name: "sendtoroute multi path payment", test: testSendToRouteMultiPath, }, + { + name: "sendtoroute amp", + test: testSendToRouteAMP, + }, { name: "send multi path payment", test: testSendMultiPathPayment, diff --git a/lnwire/features.go b/lnwire/features.go index 279e72c9..9dfa07ee 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -129,6 +129,16 @@ const ( // transactions, which also imply anchor commitments. AnchorsZeroFeeHtlcTxOptional FeatureBit = 23 + // AMPRequired is a required feature bit that signals that the receiver + // of a payment supports accepts spontaneous payments, i.e. + // sender-generated preimages according to BOLT XX. + AMPRequired FeatureBit = 30 + + // AMPOptional is an optional feature bit that signals that the receiver + // of a payment supports accepts spontaneous payments, i.e. + // sender-generated preimages according to BOLT XX. + AMPOptional FeatureBit = 31 + // maxAllowedSize is a maximum allowed size of feature vector. // // NOTE: Within the protocol, the maximum allowed message size is 65535 @@ -172,6 +182,8 @@ var Features = map[FeatureBit]string{ AnchorsZeroFeeHtlcTxOptional: "anchors-zero-fee-htlc-tx", WumboChannelsRequired: "wumbo-channels", WumboChannelsOptional: "wumbo-channels", + AMPRequired: "amp", + AMPOptional: "amp", } // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A diff --git a/record/amp.go b/record/amp.go index 72b4cbf4..53c9b441 100644 --- a/record/amp.go +++ b/record/amp.go @@ -9,19 +9,19 @@ import ( // AMPOnionType is the type used in the onion to reference the AMP fields: // root_share, set_id, and child_index. -const AMPOnionType tlv.Type = 10 +const AMPOnionType tlv.Type = 14 // AMP is a record that encodes the fields necessary for atomic multi-path // payments. type AMP struct { rootShare [32]byte setID [32]byte - childIndex uint16 + childIndex uint32 } // NewAMP generate a new AMP record with the given root_share, set_id, and // child_index. -func NewAMP(rootShare, setID [32]byte, childIndex uint16) *AMP { +func NewAMP(rootShare, setID [32]byte, childIndex uint32) *AMP { return &{ rootShare: rootShare, setID: setID, @@ -40,7 +40,7 @@ func (a *AMP) SetID() [32]byte { } // ChildIndex returns the child index contained in the AMP record. -func (a *AMP) ChildIndex() uint16 { +func (a *AMP) ChildIndex() uint32 { return a.childIndex } @@ -55,7 +55,7 @@ func AMPEncoder(w io.Writer, val interface{}, buf *[8]byte) error { return err } - return tlv.ETUint16T(w, v.childIndex, buf) + return tlv.ETUint32T(w, v.childIndex, buf) } return tlv.NewTypeForEncodingErr(val, "AMP") } @@ -69,7 +69,7 @@ const ( // maxAMPLength is the maximum legnth of a serialized AMP TLV record, // which occurs when the truncated endoing of a child_index takes 2 // bytes. - maxAMPLength = 66 + maxAMPLength = 68 ) // AMPDecoder reads the AMP record from the provided io.Reader. @@ -83,7 +83,7 @@ func AMPDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { return err } - return tlv.DTUint16(r, &v.childIndex, buf, l-64) + return tlv.DTUint32(r, &v.childIndex, buf, l-minAMPLength) } return tlv.NewTypeForDecodingErr(val, "AMP", l, maxAMPLength) } @@ -97,7 +97,7 @@ func (a *AMP) Record() tlv.Record { // PayloadSize returns the size this record takes up in encoded form. func (a *AMP) PayloadSize() uint64 { - return 32 + 32 + tlv.SizeTUint16(a.childIndex) + return 32 + 32 + tlv.SizeTUint32(a.childIndex) } // String returns a human-readble description of the amp payload fields. diff --git a/record/record_test.go b/record/record_test.go index 8c39790e..45faa9f7 100644 --- a/record/record_test.go +++ b/record/record_test.go @@ -21,7 +21,7 @@ var ( testAddr = [32]byte{0x01, 0x02} testShare = [32]byte{0x03, 0x04} testSetID = [32]byte{0x05, 0x06} - testChildIndex = uint16(17) + testChildIndex = uint32(17) ) var recordEncDecTests = []recordEncDecTest{