diff --git a/.travis.yml b/.travis.yml
index d3e154df895ebc9e382ddf7c7cb1585234cb4e91..038ee859601b6b8cbad78c6a95c3b66966ee1094 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,6 +24,42 @@ jobs:
       script:
         - go run build/ci.go lint
 
+    # These builders create the Docker sub-images for multi-arch push and each
+    # will attempt to push the multi-arch image if they are the last builder
+    - stage: build
+      if: type = push
+      os: linux
+      arch: amd64
+      dist: bionic
+      go: 1.16.x
+      env:
+        - docker
+      services:
+        - docker
+      git:
+        submodules: false # avoid cloning ethereum/tests
+      before_install:
+        - export DOCKER_CLI_EXPERIMENTAL=enabled
+      script:
+        - go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
+
+    - stage: build
+      if: type = push
+      os: linux
+      arch: arm64
+      dist: bionic
+      go: 1.16.x
+      env:
+        - docker
+      services:
+        - docker
+      git:
+        submodules: false # avoid cloning ethereum/tests
+      before_install:
+        - export DOCKER_CLI_EXPERIMENTAL=enabled
+      script:
+        - go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
+
     # This builder does the Ubuntu PPA upload
     - stage: build
       if: type = push
diff --git a/Dockerfile b/Dockerfile
index 1716354d492924d731569608caeba717f77c48e3..1e6501a2076ecb6ea0c995ef4bf5d69c2b8c2fb9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,4 +13,4 @@ RUN apk add --no-cache ca-certificates
 COPY --from=builder /bor/build/bin/bor /usr/local/bin/
 COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/
 
-EXPOSE 8545 8546 8547 30303 30303/udp
+EXPOSE 8545 8546 8547 30303 30303/udp
\ No newline at end of file
diff --git a/Dockerfile.alltools b/Dockerfile.alltools
index 217d1cc3409f36a46cc6401b1e175f1dc11a272e..dc10a907c83e54f73fc4295f1ee5a6c1a241ec2e 100644
--- a/Dockerfile.alltools
+++ b/Dockerfile.alltools
@@ -12,4 +12,4 @@ FROM alpine:latest
 RUN apk add --no-cache ca-certificates
 COPY --from=builder /bor/build/bin/* /usr/local/bin/
 
-EXPOSE 8545 8546 30303 30303/udp
+EXPOSE 8545 8546 30303 30303/udp
\ No newline at end of file
diff --git a/README.md b/README.md
index dff63fe267e5ff0711239e44fbef44938c5241ff..9e64b4d717e4fd2d24e050fdf18112bb7718e431 100644
--- a/README.md
+++ b/README.md
@@ -25,4 +25,4 @@ also included in our repository in the `COPYING.LESSER` file.
 
 The go-ethereum binaries (i.e. all code inside of the `cmd` directory) is licensed under the
 [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also
-included in our repository in the `COPYING` file.
+included in our repository in the `COPYING` file.
\ No newline at end of file
diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go
index b8065e8488edf91d177ef8c403a2c6325d0b91e6..a4307a9529101d83ba2dcef7e5795cfd2ed88675 100644
--- a/accounts/abi/bind/auth.go
+++ b/accounts/abi/bind/auth.go
@@ -17,6 +17,7 @@
 package bind
 
 import (
+	"context"
 	"crypto/ecdsa"
 	"errors"
 	"io"
@@ -74,6 +75,7 @@ func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account
 			}
 			return tx.WithSignature(signer, signature)
 		},
+		Context: context.Background(),
 	}, nil
 }
 
@@ -97,6 +99,7 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
 			}
 			return tx.WithSignature(signer, signature)
 		},
+		Context: context.Background(),
 	}
 }
 
@@ -133,6 +136,7 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou
 			}
 			return tx.WithSignature(signer, signature)
 		},
+		Context: context.Background(),
 	}, nil
 }
 
@@ -156,6 +160,7 @@ func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*Tr
 			}
 			return tx.WithSignature(signer, signature)
 		},
+		Context: context.Background(),
 	}, nil
 }
 
@@ -170,5 +175,6 @@ func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account)
 			}
 			return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id
 		},
+		Context: context.Background(),
 	}
 }
diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go
index eed6a44bbcf0a9b004dc9b3442d849cafaa5800b..c16990f395c488cff44eb02884b459e331786d88 100644
--- a/accounts/abi/bind/backend.go
+++ b/accounts/abi/bind/backend.go
@@ -32,12 +32,12 @@ var (
 	// have any code associated with it (i.e. suicided).
 	ErrNoCode = errors.New("no contract code at given address")
 
-	// This error is raised when attempting to perform a pending state action
+	// ErrNoPendingState is raised when attempting to perform a pending state action
 	// on a backend that doesn't implement PendingContractCaller.
 	ErrNoPendingState = errors.New("backend does not support pending state")
 
-	// This error is returned by WaitDeployed if contract creation leaves an
-	// empty contract behind.
+	// ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves
+	// an empty contract behind.
 	ErrNoCodeAfterDeploy = errors.New("no contract code after deployment")
 )
 
@@ -47,7 +47,8 @@ type ContractCaller interface {
 	// CodeAt returns the code of the given account. This is needed to differentiate
 	// between contract internal errors and the local chain being out of sync.
 	CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
-	// ContractCall executes an Ethereum contract call with the specified data as the
+
+	// CallContract executes an Ethereum contract call with the specified data as the
 	// input.
 	CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
 }
@@ -58,6 +59,7 @@ type ContractCaller interface {
 type PendingContractCaller interface {
 	// PendingCodeAt returns the code of the given account in the pending state.
 	PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error)
+
 	// PendingCallContract executes an Ethereum contract call against the pending state.
 	PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error)
 }
@@ -67,19 +69,31 @@ type PendingContractCaller interface {
 // used when the user does not provide some needed values, but rather leaves it up
 // to the transactor to decide.
 type ContractTransactor interface {
+	// HeaderByNumber returns a block header from the current canonical chain. If
+	// number is nil, the latest known header is returned.
+	HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
+
 	// PendingCodeAt returns the code of the given account in the pending state.
 	PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
+
 	// PendingNonceAt retrieves the current pending nonce associated with an account.
 	PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
+
 	// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
 	// execution of a transaction.
 	SuggestGasPrice(ctx context.Context) (*big.Int, error)
+
+	// SuggestGasTipCap retrieves the currently suggested 1559 priority fee to allow
+	// a timely execution of a transaction.
+	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
+
 	// EstimateGas tries to estimate the gas needed to execute a specific
 	// transaction based on the current pending state of the backend blockchain.
 	// There is no guarantee that this is the true gas limit requirement as other
 	// transactions may be added or removed by miners, but it should provide a basis
 	// for setting a reasonable default.
 	EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)
+
 	// SendTransaction injects the transaction into the pending pool for execution.
 	SendTransaction(ctx context.Context, tx *types.Transaction) error
 }
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index d6d525eae10da3dbf51b87843082994a9be61215..e410522ac8bf8edcc49f28d93382cccdcd335efa 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -86,7 +86,7 @@ func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.Genesis
 		config:     genesis.Config,
 		events:     filters.NewEventSystem(&filterBackend{database, blockchain}, false),
 	}
-	backend.rollback()
+	backend.rollback(blockchain.CurrentBlock())
 	return backend
 }
 
@@ -112,7 +112,9 @@ func (b *SimulatedBackend) Commit() {
 	if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil {
 		panic(err) // This cannot happen unless the simulator is wrong, fail in that case
 	}
-	b.rollback()
+	// Using the last inserted block here makes it possible to build on a side
+	// chain after a fork.
+	b.rollback(b.pendingBlock)
 }
 
 // Rollback aborts all pending transactions, reverting to the last committed state.
@@ -120,22 +122,49 @@ func (b *SimulatedBackend) Rollback() {
 	b.mu.Lock()
 	defer b.mu.Unlock()
 
-	b.rollback()
+	b.rollback(b.blockchain.CurrentBlock())
 }
 
-func (b *SimulatedBackend) rollback() {
-	blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
+func (b *SimulatedBackend) rollback(parent *types.Block) {
+	blocks, _ := core.GenerateChain(b.config, parent, ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
 
 	b.pendingBlock = blocks[0]
 	b.pendingState, _ = state.New(b.pendingBlock.Root(), b.blockchain.StateCache(), nil)
 }
 
+// Fork creates a side-chain that can be used to simulate reorgs.
+//
+// This function should be called with the ancestor block where the new side
+// chain should be started. Transactions (old and new) can then be applied on
+// top and Commit-ed.
+//
+// Note, the side-chain will only become canonical (and trigger the events) when
+// it becomes longer. Until then CallContract will still operate on the current
+// canonical chain.
+//
+// There is a % chance that the side chain becomes canonical at the same length
+// to simulate live network behavior.
+func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+
+	if len(b.pendingBlock.Transactions()) != 0 {
+		return errors.New("pending block dirty")
+	}
+	block, err := b.blockByHash(ctx, parent)
+	if err != nil {
+		return err
+	}
+	b.rollback(block)
+	return nil
+}
+
 // stateByBlockNumber retrieves a state by a given blocknumber.
 func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
 	if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 {
 		return b.blockchain.State()
 	}
-	block, err := b.blockByNumberNoLock(ctx, blockNumber)
+	block, err := b.blockByNumber(ctx, blockNumber)
 	if err != nil {
 		return nil, err
 	}
@@ -228,6 +257,11 @@ func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*
 	b.mu.Lock()
 	defer b.mu.Unlock()
 
+	return b.blockByHash(ctx, hash)
+}
+
+// blockByHash retrieves a block based on the block hash without Locking.
+func (b *SimulatedBackend) blockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
 	if hash == b.pendingBlock.Hash() {
 		return b.pendingBlock, nil
 	}
@@ -246,12 +280,12 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (
 	b.mu.Lock()
 	defer b.mu.Unlock()
 
-	return b.blockByNumberNoLock(ctx, number)
+	return b.blockByNumber(ctx, number)
 }
 
-// blockByNumberNoLock retrieves a block from the database by number, caching it
+// blockByNumber retrieves a block from the database by number, caching it
 // (associated with its hash) if found without Lock.
-func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) {
+func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
 	if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
 		return b.blockchain.CurrentBlock(), nil
 	}
@@ -431,6 +465,12 @@ func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error
 	return big.NewInt(1), nil
 }
 
+// SuggestGasTipCap implements ContractTransactor.SuggestGasTipCap. Since the simulated
+// chain doesn't have miners, we just return a gas tip of 1 for any call.
+func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
+	return big.NewInt(1), nil
+}
+
 // EstimateGas executes the requested code against the currently pending block/state and
 // returns the used amount of gas.
 func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
@@ -448,8 +488,19 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
 	} else {
 		hi = b.pendingBlock.GasLimit()
 	}
+	// Normalize the max fee per gas the call is willing to spend.
+	var feeCap *big.Int
+	if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
+		return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	} else if call.GasPrice != nil {
+		feeCap = call.GasPrice
+	} else if call.GasFeeCap != nil {
+		feeCap = call.GasFeeCap
+	} else {
+		feeCap = common.Big0
+	}
 	// Recap the highest gas allowance with account's balance.
-	if call.GasPrice != nil && call.GasPrice.BitLen() != 0 {
+	if feeCap.BitLen() != 0 {
 		balance := b.pendingState.GetBalance(call.From) // from can't be nil
 		available := new(big.Int).Set(balance)
 		if call.Value != nil {
@@ -458,14 +509,14 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
 			}
 			available.Sub(available, call.Value)
 		}
-		allowance := new(big.Int).Div(available, call.GasPrice)
+		allowance := new(big.Int).Div(available, feeCap)
 		if allowance.IsUint64() && hi > allowance.Uint64() {
 			transfer := call.Value
 			if transfer == nil {
 				transfer = new(big.Int)
 			}
 			log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
-				"sent", transfer, "gasprice", call.GasPrice, "fundable", allowance)
+				"sent", transfer, "feecap", feeCap, "fundable", allowance)
 			hi = allowance.Uint64()
 		}
 	}
@@ -527,10 +578,38 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
 // callContract implements common code between normal and pending contract calls.
 // state is modified during execution, make sure to copy it if necessary.
 func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) {
-	// Ensure message is initialized properly.
-	if call.GasPrice == nil {
-		call.GasPrice = big.NewInt(1)
+	// Gas prices post 1559 need to be initialized
+	if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
+		return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	}
+	head := b.blockchain.CurrentHeader()
+	if !b.blockchain.Config().IsLondon(head.Number) {
+		// If there's no basefee, then it must be a non-1559 execution
+		if call.GasPrice == nil {
+			call.GasPrice = new(big.Int)
+		}
+		call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
+	} else {
+		// A basefee is provided, necessitating 1559-type execution
+		if call.GasPrice != nil {
+			// User specified the legacy gas field, convert to 1559 gas typing
+			call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
+		} else {
+			// User specified 1559 gas feilds (or none), use those
+			if call.GasFeeCap == nil {
+				call.GasFeeCap = new(big.Int)
+			}
+			if call.GasTipCap == nil {
+				call.GasTipCap = new(big.Int)
+			}
+			// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
+			call.GasPrice = new(big.Int)
+			if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 {
+				call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, head.BaseFee), call.GasFeeCap)
+			}
+		}
 	}
+	// Ensure message is initialized properly.
 	if call.Gas == 0 {
 		call.Gas = 50000000
 	}
@@ -547,7 +626,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
 	evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
 	// Create a new environment which holds all relevant information
 	// about the transaction and calling mechanisms.
-	vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{})
+	vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
 	gasPool := new(core.GasPool).AddGas(math.MaxUint64)
 
 	return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb()
@@ -559,8 +638,12 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
 	b.mu.Lock()
 	defer b.mu.Unlock()
 
-	// Check transaction validity.
-	block := b.blockchain.CurrentBlock()
+	// Get the last block
+	block, err := b.blockByHash(ctx, b.pendingBlock.ParentHash())
+	if err != nil {
+		panic("could not fetch parent")
+	}
+	// Check transaction validity
 	signer := types.MakeSigner(b.blockchain.Config(), block.Number())
 	sender, err := types.Sender(signer, tx)
 	if err != nil {
@@ -570,8 +653,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
 	if tx.Nonce() != nonce {
 		panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
 	}
-
-	// Include tx in chain.
+	// Include tx in chain
 	blocks, _ := core.GenerateChain(b.config, block, ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
 		for _, tx := range b.pendingBlock.Transactions() {
 			block.AddTxWithChain(b.blockchain, tx)
@@ -713,9 +795,11 @@ type callMsg struct {
 
 func (m callMsg) From() common.Address         { return m.CallMsg.From }
 func (m callMsg) Nonce() uint64                { return 0 }
-func (m callMsg) CheckNonce() bool             { return false }
+func (m callMsg) IsFake() bool                 { return true }
 func (m callMsg) To() *common.Address          { return m.CallMsg.To }
 func (m callMsg) GasPrice() *big.Int           { return m.CallMsg.GasPrice }
+func (m callMsg) GasFeeCap() *big.Int          { return m.CallMsg.GasFeeCap }
+func (m callMsg) GasTipCap() *big.Int          { return m.CallMsg.GasTipCap }
 func (m callMsg) Gas() uint64                  { return m.CallMsg.Gas }
 func (m callMsg) Value() *big.Int              { return m.CallMsg.Value }
 func (m callMsg) Data() []byte                 { return m.CallMsg.Data }
diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go
index 64ddf8bb2c3cb623c076c840468d319fa40c275b..613267810744aa8d10be411354daa665bbe4fc3b 100644
--- a/accounts/abi/bind/backends/simulated_test.go
+++ b/accounts/abi/bind/backends/simulated_test.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"errors"
 	"math/big"
+	"math/rand"
 	"reflect"
 	"strings"
 	"testing"
@@ -58,9 +59,12 @@ func TestSimulatedBackend(t *testing.T) {
 	}
 
 	// generate a transaction and confirm you can retrieve it
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
 	code := `6060604052600a8060106000396000f360606040526008565b00`
 	var gas uint64 = 3000000
-	tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code))
+	tx := types.NewContractCreation(0, big.NewInt(0), gas, gasPrice, common.FromHex(code))
 	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key)
 
 	err = sim.SendTransaction(context.Background(), tx)
@@ -110,14 +114,14 @@ var expectedReturn = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 func simTestBackend(testAddr common.Address) *SimulatedBackend {
 	return NewSimulatedBackend(
 		core.GenesisAlloc{
-			testAddr: {Balance: big.NewInt(10000000000)},
+			testAddr: {Balance: big.NewInt(10000000000000000)},
 		}, 10000000,
 	)
 }
 
 func TestNewSimulatedBackend(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
-	expectedBal := big.NewInt(10000000000)
+	expectedBal := big.NewInt(10000000000000000)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
 
@@ -136,7 +140,7 @@ func TestNewSimulatedBackend(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_AdjustTime(t *testing.T) {
+func TestAdjustTime(t *testing.T) {
 	sim := NewSimulatedBackend(
 		core.GenesisAlloc{}, 10000000,
 	)
@@ -153,11 +157,15 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) {
 	}
 }
 
-func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
+func TestNewAdjustTimeFail(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 	sim := simTestBackend(testAddr)
+
 	// Create tx and send
-	tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -178,7 +186,7 @@ func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
 		t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime)
 	}
 	// Put a transaction after adjusting time
-	tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -191,9 +199,9 @@ func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_BalanceAt(t *testing.T) {
+func TestBalanceAt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
-	expectedBal := big.NewInt(10000000000)
+	expectedBal := big.NewInt(10000000000000000)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
 	bgCtx := context.Background()
@@ -208,7 +216,7 @@ func TestSimulatedBackend_BalanceAt(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_BlockByHash(t *testing.T) {
+func TestBlockByHash(t *testing.T) {
 	sim := NewSimulatedBackend(
 		core.GenesisAlloc{}, 10000000,
 	)
@@ -229,7 +237,7 @@ func TestSimulatedBackend_BlockByHash(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_BlockByNumber(t *testing.T) {
+func TestBlockByNumber(t *testing.T) {
 	sim := NewSimulatedBackend(
 		core.GenesisAlloc{}, 10000000,
 	)
@@ -264,7 +272,7 @@ func TestSimulatedBackend_BlockByNumber(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_NonceAt(t *testing.T) {
+func TestNonceAt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -281,7 +289,10 @@ func TestSimulatedBackend_NonceAt(t *testing.T) {
 	}
 
 	// create a signed transaction to send
-	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -314,7 +325,7 @@ func TestSimulatedBackend_NonceAt(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_SendTransaction(t *testing.T) {
+func TestSendTransaction(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -322,7 +333,10 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) {
 	bgCtx := context.Background()
 
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -345,19 +359,22 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_TransactionByHash(t *testing.T) {
+func TestTransactionByHash(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := NewSimulatedBackend(
 		core.GenesisAlloc{
-			testAddr: {Balance: big.NewInt(10000000000)},
+			testAddr: {Balance: big.NewInt(10000000000000000)},
 		}, 10000000,
 	)
 	defer sim.Close()
 	bgCtx := context.Background()
 
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -396,7 +413,7 @@ func TestSimulatedBackend_TransactionByHash(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_EstimateGas(t *testing.T) {
+func TestEstimateGas(t *testing.T) {
 	/*
 		pragma solidity ^0.6.4;
 		contract GasEstimation {
@@ -514,7 +531,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) {
+func TestEstimateGasWithPrice(t *testing.T) {
 	key, _ := crypto.GenerateKey()
 	addr := crypto.PubkeyToAddress(key.PublicKey)
 
@@ -533,7 +550,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) {
 			To:       &recipient,
 			Gas:      0,
 			GasPrice: big.NewInt(0),
-			Value:    big.NewInt(1000),
+			Value:    big.NewInt(100000000000),
 			Data:     nil,
 		}, 21000, nil},
 
@@ -541,8 +558,8 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) {
 			From:     addr,
 			To:       &recipient,
 			Gas:      0,
-			GasPrice: big.NewInt(1000),
-			Value:    big.NewInt(1000),
+			GasPrice: big.NewInt(100000000000),
+			Value:    big.NewInt(100000000000),
 			Data:     nil,
 		}, 21000, nil},
 
@@ -560,28 +577,51 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) {
 			To:       &recipient,
 			Gas:      0,
 			GasPrice: big.NewInt(2e14), // gascost = 4.2ether
-			Value:    big.NewInt(1000),
+			Value:    big.NewInt(100000000000),
 			Data:     nil,
 		}, 21000, errors.New("gas required exceeds allowance (10999)")}, // 10999=(2.2ether-1000wei)/(2e14)
-	}
-	for _, c := range cases {
+
+		{"EstimateEIP1559WithHighFees", ethereum.CallMsg{
+			From:      addr,
+			To:        &addr,
+			Gas:       0,
+			GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether
+			GasTipCap: big.NewInt(1),
+			Value:     big.NewInt(1e17), // the remaining balance for fee is 2.1ether
+			Data:      nil,
+		}, params.TxGas, nil},
+
+		{"EstimateEIP1559WithSuperHighFees", ethereum.CallMsg{
+			From:      addr,
+			To:        &addr,
+			Gas:       0,
+			GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether
+			GasTipCap: big.NewInt(1),
+			Value:     big.NewInt(1e17 + 1), // the remaining balance for fee is 2.1ether
+			Data:      nil,
+		}, params.TxGas, errors.New("gas required exceeds allowance (20999)")}, // 20999=(2.2ether-0.1ether-1wei)/(1e14)
+	}
+	for i, c := range cases {
 		got, err := sim.EstimateGas(context.Background(), c.message)
 		if c.expectError != nil {
 			if err == nil {
-				t.Fatalf("Expect error, got nil")
+				t.Fatalf("test %d: expect error, got nil", i)
 			}
 			if c.expectError.Error() != err.Error() {
-				t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
+				t.Fatalf("test %d: expect error, want %v, got %v", i, c.expectError, err)
 			}
 			continue
 		}
+		if c.expectError == nil && err != nil {
+			t.Fatalf("test %d: didn't expect error, got %v", i, err)
+		}
 		if got != c.expect {
-			t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got)
+			t.Fatalf("test %d: gas estimation mismatch, want %d, got %d", i, c.expect, got)
 		}
 	}
 }
 
-func TestSimulatedBackend_HeaderByHash(t *testing.T) {
+func TestHeaderByHash(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -602,7 +642,7 @@ func TestSimulatedBackend_HeaderByHash(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
+func TestHeaderByNumber(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -649,7 +689,7 @@ func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_TransactionCount(t *testing.T) {
+func TestTransactionCount(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -668,9 +708,11 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) {
 	if count != 0 {
 		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
 	}
-
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -699,7 +741,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
+func TestTransactionInBlock(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -723,9 +765,11 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
 	if pendingNonce != uint64(0) {
 		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
 	}
-
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -762,7 +806,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
+func TestPendingNonceAt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -780,7 +824,10 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
 	}
 
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -803,7 +850,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
 	}
 
 	// make a new transaction with a nonce of 1
-	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -824,7 +871,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
+func TestTransactionReceipt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 
 	sim := simTestBackend(testAddr)
@@ -832,7 +879,10 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
 	bgCtx := context.Background()
 
 	// create a signed transaction to send
-	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
 	signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	if err != nil {
 		t.Errorf("could not sign tx: %v", err)
@@ -855,7 +905,7 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
+func TestSuggestGasPrice(t *testing.T) {
 	sim := NewSimulatedBackend(
 		core.GenesisAlloc{},
 		10000000,
@@ -871,7 +921,7 @@ func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
+func TestPendingCodeAt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
@@ -907,7 +957,7 @@ func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
 	}
 }
 
-func TestSimulatedBackend_CodeAt(t *testing.T) {
+func TestCodeAt(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
@@ -946,7 +996,7 @@ func TestSimulatedBackend_CodeAt(t *testing.T) {
 
 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
 //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
-func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
+func TestPendingAndCallContract(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
@@ -1030,7 +1080,7 @@ contract Reverter {
         }
     }
 }*/
-func TestSimulatedBackend_CallContractRevert(t *testing.T) {
+func TestCallContractRevert(t *testing.T) {
 	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
 	sim := simTestBackend(testAddr)
 	defer sim.Close()
@@ -1114,3 +1164,175 @@ func TestSimulatedBackend_CallContractRevert(t *testing.T) {
 		sim.Commit()
 	}
 }
+
+// TestFork check that the chain length after a reorg is correct.
+// Steps:
+//  1. Save the current block which will serve as parent for the fork.
+//  2. Mine n blocks with n ∈ [0, 20].
+//  3. Assert that the chain length is n.
+//  4. Fork by using the parent block as ancestor.
+//  5. Mine n+1 blocks which should trigger a reorg.
+//  6. Assert that the chain length is n+1.
+//     Since Commit() was called 2n+1 times in total,
+//     having a chain length of just n+1 means that a reorg occurred.
+func TestFork(t *testing.T) {
+	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
+	sim := simTestBackend(testAddr)
+	defer sim.Close()
+	// 1.
+	parent := sim.blockchain.CurrentBlock()
+	// 2.
+	n := int(rand.Int31n(21))
+	for i := 0; i < n; i++ {
+		sim.Commit()
+	}
+	// 3.
+	if sim.blockchain.CurrentBlock().NumberU64() != uint64(n) {
+		t.Error("wrong chain length")
+	}
+	// 4.
+	sim.Fork(context.Background(), parent.Hash())
+	// 5.
+	for i := 0; i < n+1; i++ {
+		sim.Commit()
+	}
+	// 6.
+	if sim.blockchain.CurrentBlock().NumberU64() != uint64(n+1) {
+		t.Error("wrong chain length")
+	}
+}
+
+/*
+Example contract to test event emission:
+
+pragma solidity >=0.7.0 <0.9.0;
+contract Callable {
+    event Called();
+    function Call() public { emit Called(); }
+}
+*/
+const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
+
+const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806334e2292114602d575b600080fd5b60336035565b005b7f81fab7a4a0aa961db47eefc81f143a5220e8c8495260dd65b1356f1d19d3c7b860405160405180910390a156fea2646970667358221220029436d24f3ac598ceca41d4d712e13ced6d70727f4cdc580667de66d2f51d8b64736f6c63430008010033"
+
+// TestForkLogsReborn check that the simulated reorgs
+// correctly remove and reborn logs.
+// Steps:
+//  1. Deploy the Callable contract.
+//  2. Set up an event subscription.
+//  3. Save the current block which will serve as parent for the fork.
+//  4. Send a transaction.
+//  5. Check that the event was included.
+//  6. Fork by using the parent block as ancestor.
+//  7. Mine two blocks to trigger a reorg.
+//  8. Check that the event was removed.
+//  9. Re-send the transaction and mine a block.
+// 10. Check that the event was reborn.
+func TestForkLogsReborn(t *testing.T) {
+	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
+	sim := simTestBackend(testAddr)
+	defer sim.Close()
+	// 1.
+	parsed, _ := abi.JSON(strings.NewReader(callableAbi))
+	auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
+	_, _, contract, err := bind.DeployContract(auth, parsed, common.FromHex(callableBin), sim)
+	if err != nil {
+		t.Errorf("deploying contract: %v", err)
+	}
+	sim.Commit()
+	// 2.
+	logs, sub, err := contract.WatchLogs(nil, "Called")
+	if err != nil {
+		t.Errorf("watching logs: %v", err)
+	}
+	defer sub.Unsubscribe()
+	// 3.
+	parent := sim.blockchain.CurrentBlock()
+	// 4.
+	tx, err := contract.Transact(auth, "Call")
+	if err != nil {
+		t.Errorf("transacting: %v", err)
+	}
+	sim.Commit()
+	// 5.
+	log := <-logs
+	if log.TxHash != tx.Hash() {
+		t.Error("wrong event tx hash")
+	}
+	if log.Removed {
+		t.Error("Event should be included")
+	}
+	// 6.
+	if err := sim.Fork(context.Background(), parent.Hash()); err != nil {
+		t.Errorf("forking: %v", err)
+	}
+	// 7.
+	sim.Commit()
+	sim.Commit()
+	// 8.
+	log = <-logs
+	if log.TxHash != tx.Hash() {
+		t.Error("wrong event tx hash")
+	}
+	if !log.Removed {
+		t.Error("Event should be removed")
+	}
+	// 9.
+	if err := sim.SendTransaction(context.Background(), tx); err != nil {
+		t.Errorf("sending transaction: %v", err)
+	}
+	sim.Commit()
+	// 10.
+	log = <-logs
+	if log.TxHash != tx.Hash() {
+		t.Error("wrong event tx hash")
+	}
+	if log.Removed {
+		t.Error("Event should be included")
+	}
+}
+
+// TestForkResendTx checks that re-sending a TX after a fork
+// is possible and does not cause a "nonce mismatch" panic.
+// Steps:
+//  1. Save the current block which will serve as parent for the fork.
+//  2. Send a transaction.
+//  3. Check that the TX is included in block 1.
+//  4. Fork by using the parent block as ancestor.
+//  5. Mine a block, Re-send the transaction and mine another one.
+//  6. Check that the TX is now included in block 2.
+func TestForkResendTx(t *testing.T) {
+	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
+	sim := simTestBackend(testAddr)
+	defer sim.Close()
+	// 1.
+	parent := sim.blockchain.CurrentBlock()
+	// 2.
+	head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+	_tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil)
+	tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey)
+	sim.SendTransaction(context.Background(), tx)
+	sim.Commit()
+	// 3.
+	receipt, _ := sim.TransactionReceipt(context.Background(), tx.Hash())
+	if h := receipt.BlockNumber.Uint64(); h != 1 {
+		t.Errorf("TX included in wrong block: %d", h)
+	}
+	// 4.
+	if err := sim.Fork(context.Background(), parent.Hash()); err != nil {
+		t.Errorf("forking: %v", err)
+	}
+	// 5.
+	sim.Commit()
+	if err := sim.SendTransaction(context.Background(), tx); err != nil {
+		t.Errorf("sending transaction: %v", err)
+	}
+	sim.Commit()
+	// 6.
+	receipt, _ = sim.TransactionReceipt(context.Background(), tx.Hash())
+	if h := receipt.BlockNumber.Uint64(); h != 2 {
+		t.Errorf("TX included in wrong block: %d", h)
+	}
+}
diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go
index 55aca31a1a46d4a9667a841412bfb580189329f0..354632b257a5730cf0b82c58c1ce0f145ef8e8f9 100644
--- a/accounts/abi/bind/base.go
+++ b/accounts/abi/bind/base.go
@@ -21,6 +21,8 @@ import (
 	"errors"
 	"fmt"
 	"math/big"
+	"strings"
+	"sync"
 
 	"github.com/ethereum/go-ethereum"
 	"github.com/ethereum/go-ethereum/accounts/abi"
@@ -49,9 +51,11 @@ type TransactOpts struct {
 	Nonce  *big.Int       // Nonce to use for the transaction execution (nil = use pending state)
 	Signer SignerFn       // Method to use for signing the transaction (mandatory)
 
-	Value    *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
-	GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
-	GasLimit uint64   // Gas limit to set for the transaction execution (0 = estimate)
+	Value     *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
+	GasPrice  *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
+	GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
+	GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
+	GasLimit  uint64   // Gas limit to set for the transaction execution (0 = estimate)
 
 	Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
 
@@ -74,6 +78,29 @@ type WatchOpts struct {
 	Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
 }
 
+// MetaData collects all metadata for a bound contract.
+type MetaData struct {
+	mu   sync.Mutex
+	Sigs map[string]string
+	Bin  string
+	ABI  string
+	ab   *abi.ABI
+}
+
+func (m *MetaData) GetAbi() (*abi.ABI, error) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.ab != nil {
+		return m.ab, nil
+	}
+	if parsed, err := abi.JSON(strings.NewReader(m.ABI)); err != nil {
+		return nil, err
+	} else {
+		m.ab = &parsed
+	}
+	return m.ab, nil
+}
+
 // BoundContract is the base wrapper object that reflects a contract on the
 // Ethereum network. It contains a collection of methods that are used by the
 // higher level contract bindings to operate.
@@ -223,12 +250,42 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
 	} else {
 		nonce = opts.Nonce.Uint64()
 	}
-	// Figure out the gas allowance and gas price values
-	gasPrice := opts.GasPrice
-	if gasPrice == nil {
-		gasPrice, err = c.transactor.SuggestGasPrice(ensureContext(opts.Context))
-		if err != nil {
-			return nil, fmt.Errorf("failed to suggest gas price: %v", err)
+	// Figure out reasonable gas price values
+	if opts.GasPrice != nil && (opts.GasFeeCap != nil || opts.GasTipCap != nil) {
+		return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	}
+	head, err := c.transactor.HeaderByNumber(ensureContext(opts.Context), nil)
+	if err != nil {
+		return nil, err
+	}
+	if head.BaseFee != nil && opts.GasPrice == nil {
+		if opts.GasTipCap == nil {
+			tip, err := c.transactor.SuggestGasTipCap(ensureContext(opts.Context))
+			if err != nil {
+				return nil, err
+			}
+			opts.GasTipCap = tip
+		}
+		if opts.GasFeeCap == nil {
+			gasFeeCap := new(big.Int).Add(
+				opts.GasTipCap,
+				new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
+			)
+			opts.GasFeeCap = gasFeeCap
+		}
+		if opts.GasFeeCap.Cmp(opts.GasTipCap) < 0 {
+			return nil, fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", opts.GasFeeCap, opts.GasTipCap)
+		}
+	} else {
+		if opts.GasFeeCap != nil || opts.GasTipCap != nil {
+			return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
+		}
+		if opts.GasPrice == nil {
+			price, err := c.transactor.SuggestGasPrice(ensureContext(opts.Context))
+			if err != nil {
+				return nil, err
+			}
+			opts.GasPrice = price
 		}
 	}
 	gasLimit := opts.GasLimit
@@ -242,7 +299,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
 			}
 		}
 		// If the contract surely has code (or code is not needed), estimate the transaction
-		msg := ethereum.CallMsg{From: opts.From, To: contract, GasPrice: gasPrice, Value: value, Data: input}
+		msg := ethereum.CallMsg{From: opts.From, To: contract, GasPrice: opts.GasPrice, GasTipCap: opts.GasTipCap, GasFeeCap: opts.GasFeeCap, Value: value, Data: input}
 		gasLimit, err = c.transactor.EstimateGas(ensureContext(opts.Context), msg)
 		if err != nil {
 			return nil, fmt.Errorf("failed to estimate gas needed: %v", err)
@@ -250,10 +307,31 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
 	}
 	// Create the transaction, sign it and schedule it for execution
 	var rawTx *types.Transaction
-	if contract == nil {
-		rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input)
+	if opts.GasFeeCap == nil {
+		baseTx := &types.LegacyTx{
+			Nonce:    nonce,
+			GasPrice: opts.GasPrice,
+			Gas:      gasLimit,
+			Value:    value,
+			Data:     input,
+		}
+		if contract != nil {
+			baseTx.To = &c.address
+		}
+		rawTx = types.NewTx(baseTx)
 	} else {
-		rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input)
+		baseTx := &types.DynamicFeeTx{
+			Nonce:     nonce,
+			GasFeeCap: opts.GasFeeCap,
+			GasTipCap: opts.GasTipCap,
+			Gas:       gasLimit,
+			Value:     value,
+			Data:      input,
+		}
+		if contract != nil {
+			baseTx.To = &c.address
+		}
+		rawTx = types.NewTx(baseTx)
 	}
 	if opts.Signer == nil {
 		return nil, errors.New("no signer to authorize the transaction with")
@@ -387,7 +465,7 @@ func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event strin
 // user specified it as such.
 func ensureContext(ctx context.Context) context.Context {
 	if ctx == nil {
-		return context.TODO()
+		return context.Background()
 	}
 	return ctx
 }
diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go
index d0958cb62f9a7543bc64bbd03c86a7dab0c38054..d49b436db6f5ec20b20db26593c9c103c36cb91d 100644
--- a/accounts/abi/bind/bind_test.go
+++ b/accounts/abi/bind/bind_test.go
@@ -298,7 +298,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy an interaction tester contract and call a transaction on it
@@ -353,7 +353,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a tuple tester contract and execute a structured call on it
@@ -399,7 +399,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a tuple tester contract and execute a structured call on it
@@ -457,7 +457,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a slice tester contract and execute a n array call on it
@@ -505,7 +505,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a default method invoker contract and execute its default method
@@ -571,7 +571,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 		
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 		
 			// Deploy a structs method invoker contract and execute its default method
@@ -703,7 +703,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a funky gas pattern contract
@@ -753,7 +753,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a sender tester contract and execute a structured call on it
@@ -828,7 +828,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a underscorer tester contract and execute a structured call on it
@@ -922,7 +922,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy an eventer contract
@@ -1112,7 +1112,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			//deploy the test contract
@@ -1247,7 +1247,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			_, _, contract, err := DeployTuple(auth, sim)
@@ -1389,7 +1389,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			//deploy the test contract
@@ -1454,7 +1454,7 @@ var bindTests = []struct {
 		// Initialize test accounts
 		key, _ := crypto.GenerateKey()
 		auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
-		sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+		sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 		defer sim.Close()
 
 		// deploy the test contract
@@ -1544,7 +1544,7 @@ var bindTests = []struct {
 		addr := crypto.PubkeyToAddress(key.PublicKey)
 
 		// Deploy registrar contract
-		sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
+		sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 		defer sim.Close()
 
 		transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
@@ -1606,7 +1606,7 @@ var bindTests = []struct {
 		addr := crypto.PubkeyToAddress(key.PublicKey)
 
 		// Deploy registrar contract
-		sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
+		sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 		defer sim.Close()
 
 		transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
@@ -1668,7 +1668,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
 
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
 			defer sim.Close()
 
 			// Deploy a tester contract and execute a structured call on it
@@ -1728,7 +1728,7 @@ var bindTests = []struct {
 			key, _ := crypto.GenerateKey()
 			addr := crypto.PubkeyToAddress(key.PublicKey)
 	
-			sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 1000000)
+			sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000)
 			defer sim.Close()
 	
 			opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go
index e9bdd3d4149b3fb63b2e0997a44492af1f475393..492bad8c577fc22bccebc2bab6f2331c1dc390eb 100644
--- a/accounts/abi/bind/template.go
+++ b/accounts/abi/bind/template.go
@@ -90,6 +90,7 @@ package {{.Package}}
 import (
 	"math/big"
 	"strings"
+	"errors"
 
 	ethereum "github.com/ethereum/go-ethereum"
 	"github.com/ethereum/go-ethereum/accounts/abi"
@@ -101,6 +102,7 @@ import (
 
 // Reference imports to suppress errors if they are not otherwise used.
 var (
+	_ = errors.New
 	_ = big.NewInt
 	_ = strings.NewReader
 	_ = ethereum.NotFound
@@ -120,32 +122,48 @@ var (
 {{end}}
 
 {{range $contract := .Contracts}}
+	// {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract.
+	var {{.Type}}MetaData = &bind.MetaData{
+		ABI: "{{.InputABI}}",
+		{{if $contract.FuncSigs -}}
+		Sigs: map[string]string{
+			{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
+			{{end}}
+		},
+		{{end -}}
+		{{if .InputBin -}}
+		Bin: "0x{{.InputBin}}",
+		{{end}}
+	}
 	// {{.Type}}ABI is the input ABI used to generate the binding from.
-	const {{.Type}}ABI = "{{.InputABI}}"
+	// Deprecated: Use {{.Type}}MetaData.ABI instead.
+	var {{.Type}}ABI = {{.Type}}MetaData.ABI
 
 	{{if $contract.FuncSigs}}
+		// Deprecated: Use {{.Type}}MetaData.Sigs instead.
 		// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
-		var {{.Type}}FuncSigs = map[string]string{
-			{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
-			{{end}}
-		}
+		var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs
 	{{end}}
 
 	{{if .InputBin}}
 		// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
-		var {{.Type}}Bin = "0x{{.InputBin}}"
+		// Deprecated: Use {{.Type}}MetaData.Bin instead.
+		var {{.Type}}Bin = {{.Type}}MetaData.Bin
 
 		// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
 		func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
-		  parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI))
+		  parsed, err := {{.Type}}MetaData.GetAbi()
 		  if err != nil {
 		    return common.Address{}, nil, nil, err
 		  }
+		  if parsed == nil {
+			return common.Address{}, nil, nil, errors.New("GetABI returned nil")
+		  }
 		  {{range $pattern, $name := .Libraries}}
 			{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
 			{{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:], -1)
 		  {{end}}
-		  address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
+		  address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
 		  if err != nil {
 		    return common.Address{}, nil, nil, err
 		  }
diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go
index 9f9b7a000d6b4a7fd56a2524f21609f88ca22df9..75fbc91cebfe4935743869d354edaf08be31d558 100644
--- a/accounts/abi/bind/util_test.go
+++ b/accounts/abi/bind/util_test.go
@@ -56,14 +56,17 @@ func TestWaitDeployed(t *testing.T) {
 	for name, test := range waitDeployedTests {
 		backend := backends.NewSimulatedBackend(
 			core.GenesisAlloc{
-				crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
+				crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
 			},
 			10000000,
 		)
 		defer backend.Close()
 
-		// Create the transaction.
-		tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code))
+		// Create the transaction
+		head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+		gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
+		tx := types.NewContractCreation(0, big.NewInt(0), test.gas, gasPrice, common.FromHex(test.code))
 		tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
 
 		// Wait for it to get mined in the background.
@@ -99,15 +102,18 @@ func TestWaitDeployed(t *testing.T) {
 func TestWaitDeployedCornerCases(t *testing.T) {
 	backend := backends.NewSimulatedBackend(
 		core.GenesisAlloc{
-			crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
+			crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
 		},
 		10000000,
 	)
 	defer backend.Close()
 
+	head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
+	gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
+
 	// Create a transaction to an account.
 	code := "6060604052600a8060106000396000f360606040526008565b00"
-	tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code))
+	tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
 	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
@@ -119,7 +125,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
 	}
 
 	// Create a transaction that is not mined.
-	tx = types.NewContractCreation(1, big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code))
+	tx = types.NewContractCreation(1, big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
 	tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
 
 	go func() {
diff --git a/accounts/external/backend.go b/accounts/external/backend.go
index de241385c2d29abbae39dd88c074b0b847433120..e3f754eafcc428f43f8e8ebdec2978a386a263db 100644
--- a/accounts/external/backend.go
+++ b/accounts/external/backend.go
@@ -29,7 +29,7 @@ import (
 	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/rpc"
-	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 type ExternalBackend struct {
@@ -196,6 +196,10 @@ type signTransactionResult struct {
 	Tx  *types.Transaction `json:"tx"`
 }
 
+// SignTx sends the transaction to the external signer.
+// If chainID is nil, or tx.ChainID is zero, the chain ID will be assigned
+// by the external signer. For non-legacy transactions, the chain ID of the
+// transaction overrides the chainID parameter.
 func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
 	data := hexutil.Bytes(tx.Data())
 	var to *common.MixedcaseAddress
@@ -203,26 +207,34 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
 		t := common.NewMixedcaseAddress(*tx.To())
 		to = &t
 	}
-	args := &core.SendTxArgs{
-		Data:     &data,
-		Nonce:    hexutil.Uint64(tx.Nonce()),
-		Value:    hexutil.Big(*tx.Value()),
-		Gas:      hexutil.Uint64(tx.Gas()),
-		GasPrice: hexutil.Big(*tx.GasPrice()),
-		To:       to,
-		From:     common.NewMixedcaseAddress(account.Address),
+	args := &apitypes.SendTxArgs{
+		Data:  &data,
+		Nonce: hexutil.Uint64(tx.Nonce()),
+		Value: hexutil.Big(*tx.Value()),
+		Gas:   hexutil.Uint64(tx.Gas()),
+		To:    to,
+		From:  common.NewMixedcaseAddress(account.Address),
+	}
+	switch tx.Type() {
+	case types.LegacyTxType, types.AccessListTxType:
+		args.GasPrice = (*hexutil.Big)(tx.GasPrice())
+	case types.DynamicFeeTxType:
+		args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
+		args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
+	default:
+		return nil, fmt.Errorf("unsupported tx type %d", tx.Type())
 	}
 	// We should request the default chain id that we're operating with
 	// (the chain we're executing on)
-	if chainID != nil {
+	if chainID != nil && chainID.Sign() != 0 {
 		args.ChainID = (*hexutil.Big)(chainID)
 	}
-	// However, if the user asked for a particular chain id, then we should
-	// use that instead.
-	if tx.Type() != types.LegacyTxType && tx.ChainId() != nil {
-		args.ChainID = (*hexutil.Big)(tx.ChainId())
-	}
-	if tx.Type() == types.AccessListTxType {
+	if tx.Type() != types.LegacyTxType {
+		// However, if the user asked for a particular chain id, then we should
+		// use that instead.
+		if tx.ChainId().Sign() != 0 {
+			args.ChainID = (*hexutil.Big)(tx.ChainId())
+		}
 		accessList := tx.AccessList()
 		args.AccessList = &accessList
 	}
diff --git a/build/checksums.txt b/build/checksums.txt
index 0e33e07f2cb5ae7245107ed170ce4e32383a803c..e667b30ce67faa82df7df40f775aea615535f2b3 100644
--- a/build/checksums.txt
+++ b/build/checksums.txt
@@ -1,18 +1,18 @@
 # This file contains sha256 checksums of optional build dependencies.
 
-b298d29de9236ca47a023e382313bcc2d2eed31dfa706b60a04103ce83a71a25  go1.16.3.src.tar.gz
-6bb1cf421f8abc2a9a4e39140b7397cdae6aca3e8d36dcff39a1a77f4f1170ac  go1.16.3.darwin-amd64.tar.gz
-f4e96bbcd5d2d1942f5b55d9e4ab19564da4fad192012f6d7b0b9b055ba4208f  go1.16.3.darwin-arm64.tar.gz
-48b2d1481db756c88c18b1f064dbfc3e265ce4a775a23177ca17e25d13a24c5d  go1.16.3.linux-386.tar.gz
-951a3c7c6ce4e56ad883f97d9db74d3d6d80d5fec77455c6ada6c1f7ac4776d2  go1.16.3.linux-amd64.tar.gz
-566b1d6f17d2bc4ad5f81486f0df44f3088c3ed47a3bec4099d8ed9939e90d5d  go1.16.3.linux-arm64.tar.gz
-0dae30385e3564a557dac7f12a63eedc73543e6da0f6017990e214ce8cc8797c  go1.16.3.linux-armv6l.tar.gz
-a3c16e1531bf9726f47911c4a9ed7cb665a6207a51c44f10ebad4db63b4bcc5a  go1.16.3.windows-386.zip
-a4400345135b36cb7942e52bbaf978b66814738b855eeff8de879a09fd99de7f  go1.16.3.windows-amd64.zip
-31ecd11d497684fa8b0f01ba784590c4c760943665fdc4fe0adaa1405c71736c  go1.16.3.freebsd-386.tar.gz
-ffbd920b309e62e807457b11d80e8c17fefe3ef6de423aaba4b1e270b2ca4c3d  go1.16.3.freebsd-amd64.tar.gz
-5eb046bbbbc7fe2591846a4303884cb5a01abb903e3e61e33459affe7874e811  go1.16.3.linux-ppc64le.tar.gz
-3e8bd7bde533a73fd6fa75b5288678ef397e76c198cfb26b8ae086035383b1cf  go1.16.3.linux-s390x.tar.gz
+ae4f6b6e2a1677d31817984655a762074b5356da50fb58722b99104870d43503  go1.16.4.src.tar.gz
+18fe94775763db3878717393b6d41371b0b45206055e49b3838328120c977d13  go1.16.4.darwin-amd64.tar.gz
+cb6b972cc42e669f3585c648198cd5b6f6d7a0811d413ad64b50c02ba06ccc3a  go1.16.4.darwin-arm64.tar.gz
+cd1b146ef6e9006f27dd99e9687773e7fef30e8c985b7d41bff33e955a3bb53a  go1.16.4.linux-386.tar.gz
+7154e88f5a8047aad4b80ebace58a059e36e7e2e4eb3b383127a28c711b4ff59  go1.16.4.linux-amd64.tar.gz
+8b18eb05ddda2652d69ab1b1dd1f40dd731799f43c6a58b512ad01ae5b5bba21  go1.16.4.linux-arm64.tar.gz
+a53391a800ddec749ee90d38992babb27b95cfb864027350c737b9aa8e069494  go1.16.4.linux-armv6l.tar.gz
+e75c0b114a09eb5499874162b208931dc260de0fedaeedac8621bf263c974605  go1.16.4.windows-386.zip
+d40139b7ade8a3008e3240a6f86fe8f899a9c465c917e11dac8758af216f5eb0  go1.16.4.windows-amd64.zip
+7cf2bc8a175d6d656861165bfc554f92dc78d2abf5afe5631db3579555d97409  go1.16.4.freebsd-386.tar.gz
+ccdd2b76de1941b60734408fda0d750aaa69330d8a07430eed4c56bdb3502f6f  go1.16.4.freebsd-amd64.tar.gz
+80cfac566e344096a8df8f37bbd21f89e76a6fbe601406565d71a87a665fc125  go1.16.4.linux-ppc64le.tar.gz
+d6431881b3573dc29ecc24fbeab5e5ec25d8c9273aa543769c86a1a3bbac1ddf  go1.16.4.linux-s390x.tar.gz
 
 7e9a47ab540aa3e8472fbf8120d28bed3b9d9cf625b955818e8bc69628d7187c  golangci-lint-1.39.0-darwin-amd64.tar.gz
 574daa2c9c299b01672a6daeb1873b5f12e413cdb6dc0e30f2ff163956778064  golangci-lint-1.39.0-darwin-arm64.tar.gz
diff --git a/build/ci.go b/build/ci.go
index d9f147ef0ea2b000d71cbbc3ab61234091e2be88..d7d2ce72e06c70b97dd2410d7de5163f30159d8e 100644
--- a/build/ci.go
+++ b/build/ci.go
@@ -54,6 +54,7 @@ import (
 	"path/filepath"
 	"regexp"
 	"runtime"
+	"strconv"
 	"strings"
 	"time"
 
@@ -152,7 +153,7 @@ var (
 	// This is the version of go that will be downloaded by
 	//
 	//     go run ci.go install -dlgo
-	dlgoVersion = "1.16.3"
+	dlgoVersion = "1.16.4"
 )
 
 var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin"))
@@ -182,6 +183,8 @@ func main() {
 		doLint(os.Args[2:])
 	case "archive":
 		doArchive(os.Args[2:])
+	case "docker":
+		doDocker(os.Args[2:])
 	case "debsrc":
 		doDebianSource(os.Args[2:])
 	case "nsis":
@@ -447,11 +450,177 @@ func maybeSkipArchive(env build.Environment) {
 		os.Exit(0)
 	}
 	if env.Branch != "master" && !strings.HasPrefix(env.Tag, "v1.") {
-		log.Printf("skipping archive creation because branch %q, tag %q is not on the whitelist", env.Branch, env.Tag)
+		log.Printf("skipping archive creation because branch %q, tag %q is not on the inclusion list", env.Branch, env.Tag)
 		os.Exit(0)
 	}
 }
 
+// Builds the docker images and optionally uploads them to Docker Hub.
+func doDocker(cmdline []string) {
+	var (
+		image    = flag.Bool("image", false, `Whether to build and push an arch specific docker image`)
+		manifest = flag.String("manifest", "", `Push a multi-arch docker image for the specified architectures (usually "amd64,arm64")`)
+		upload   = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`)
+	)
+	flag.CommandLine.Parse(cmdline)
+
+	// Skip building and pushing docker images for PR builds
+	env := build.Env()
+	maybeSkipArchive(env)
+
+	// Retrieve the upload credentials and authenticate
+	user := getenvBase64("DOCKER_HUB_USERNAME")
+	pass := getenvBase64("DOCKER_HUB_PASSWORD")
+
+	if len(user) > 0 && len(pass) > 0 {
+		auther := exec.Command("docker", "login", "-u", string(user), "--password-stdin")
+		auther.Stdin = bytes.NewReader(pass)
+		build.MustRun(auther)
+	}
+	// Retrieve the version infos to build and push to the following paths:
+	//  - ethereum/client-go:latest                            - Pushes to the master branch, Geth only
+	//  - ethereum/client-go:stable                            - Version tag publish on GitHub, Geth only
+	//  - ethereum/client-go:alltools-latest                   - Pushes to the master branch, Geth & tools
+	//  - ethereum/client-go:alltools-stable                   - Version tag publish on GitHub, Geth & tools
+	//  - ethereum/client-go:release-<major>.<minor>           - Version tag publish on GitHub, Geth only
+	//  - ethereum/client-go:alltools-release-<major>.<minor>  - Version tag publish on GitHub, Geth & tools
+	//  - ethereum/client-go:v<major>.<minor>.<patch>          - Version tag publish on GitHub, Geth only
+	//  - ethereum/client-go:alltools-v<major>.<minor>.<patch> - Version tag publish on GitHub, Geth & tools
+	var tags []string
+
+	switch {
+	case env.Branch == "master":
+		tags = []string{"latest"}
+	case strings.HasPrefix(env.Tag, "v1."):
+		tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), "v" + params.Version}
+	}
+	// If architecture specific image builds are requested, build and push them
+	if *image {
+		build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:TAG", *upload), ".")
+		build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:alltools-TAG", *upload), "-f", "Dockerfile.alltools", ".")
+
+		// Tag and upload the images to Docker Hub
+		for _, tag := range tags {
+			gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, runtime.GOARCH)
+			toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, runtime.GOARCH)
+
+			// If the image already exists (non version tag), check the build
+			// number to prevent overwriting a newer commit if concurrent builds
+			// are running. This is still a tiny bit racey if two published are
+			// done at the same time, but that's extremely unlikely even on the
+			// master branch.
+			for _, img := range []string{gethImage, toolImage} {
+				if exec.Command("docker", "pull", img).Run() != nil {
+					continue // Generally the only failure is a missing image, which is good
+				}
+				buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput()
+				if err != nil {
+					log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum))
+				}
+				buildnum = bytes.TrimSpace(buildnum)
+
+				if len(buildnum) > 0 && len(env.Buildnum) > 0 {
+					oldnum, err := strconv.Atoi(string(buildnum))
+					if err != nil {
+						log.Fatalf("Failed to parse old image build number: %v", err)
+					}
+					newnum, err := strconv.Atoi(env.Buildnum)
+					if err != nil {
+						log.Fatalf("Failed to parse current build number: %v", err)
+					}
+					if oldnum > newnum {
+						log.Fatalf("Current build number %d not newer than existing %d", newnum, oldnum)
+					} else {
+						log.Printf("Updating %s from build %d to %d", img, oldnum, newnum)
+					}
+				}
+			}
+			build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:TAG", *upload), gethImage)
+			build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:alltools-TAG", *upload), toolImage)
+			build.MustRunCommand("docker", "push", gethImage)
+			build.MustRunCommand("docker", "push", toolImage)
+		}
+	}
+	// If multi-arch image manifest push is requested, assemble it
+	if len(*manifest) != 0 {
+		// Since different architectures are pushed by different builders, wait
+		// until all required images are updated.
+		var mismatch bool
+		for i := 0; i < 2; i++ { // 2 attempts, second is race check
+			mismatch = false // hope there's no mismatch now
+
+			for _, tag := range tags {
+				for _, arch := range strings.Split(*manifest, ",") {
+					gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, arch)
+					toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, arch)
+
+					for _, img := range []string{gethImage, toolImage} {
+						if out, err := exec.Command("docker", "pull", img).CombinedOutput(); err != nil {
+							log.Printf("Required image %s unavailable: %v\nOutput: %s", img, err, out)
+							mismatch = true
+							break
+						}
+						buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput()
+						if err != nil {
+							log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum))
+						}
+						buildnum = bytes.TrimSpace(buildnum)
+
+						if string(buildnum) != env.Buildnum {
+							log.Printf("Build number mismatch on %s: want %s, have %s", img, env.Buildnum, buildnum)
+							mismatch = true
+							break
+						}
+					}
+					if mismatch {
+						break
+					}
+				}
+				if mismatch {
+					break
+				}
+			}
+			if mismatch {
+				// Build numbers mismatching, retry in a short time to
+				// avoid concurrent failes in both publisher images. If
+				// however the retry failed too, it means the concurrent
+				// builder is still crunching, let that do the publish.
+				if i == 0 {
+					time.Sleep(30 * time.Second)
+				}
+				continue
+			}
+			break
+		}
+		if mismatch {
+			log.Println("Relinquishing publish to other builder")
+			return
+		}
+		// Assemble and push the Geth manifest image
+		for _, tag := range tags {
+			gethImage := fmt.Sprintf("%s:%s", *upload, tag)
+
+			var gethSubImages []string
+			for _, arch := range strings.Split(*manifest, ",") {
+				gethSubImages = append(gethSubImages, gethImage+"-"+arch)
+			}
+			build.MustRunCommand("docker", append([]string{"manifest", "create", gethImage}, gethSubImages...)...)
+			build.MustRunCommand("docker", "manifest", "push", gethImage)
+		}
+		// Assemble and push the alltools manifest image
+		for _, tag := range tags {
+			toolImage := fmt.Sprintf("%s:alltools-%s", *upload, tag)
+
+			var toolSubImages []string
+			for _, arch := range strings.Split(*manifest, ",") {
+				toolSubImages = append(toolSubImages, toolImage+"-"+arch)
+			}
+			build.MustRunCommand("docker", append([]string{"manifest", "create", toolImage}, toolSubImages...)...)
+			build.MustRunCommand("docker", "manifest", "push", toolImage)
+		}
+	}
+}
+
 // Debian Packaging
 func doDebianSource(cmdline []string) {
 	var (
diff --git a/cmd/abidump/main.go b/cmd/abidump/main.go
index 35cbcbb0ed2dac2cd3429c95ed655fc767d1012b..4f942749dfdf97be13acf0526819dd1d63d08cae 100644
--- a/cmd/abidump/main.go
+++ b/cmd/abidump/main.go
@@ -23,7 +23,7 @@ import (
 	"os"
 	"strings"
 
-	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 	"github.com/ethereum/go-ethereum/signer/fourbyte"
 )
 
@@ -41,7 +41,7 @@ func parse(data []byte) {
 	if err != nil {
 		die(err)
 	}
-	messages := core.ValidationMessages{}
+	messages := apitypes.ValidationMessages{}
 	db.ValidateCallData(nil, data, &messages)
 	for _, m := range messages.Messages {
 		fmt.Printf("%v: %v\n", m.Typ, m.Message)
diff --git a/cmd/clef/main.go b/cmd/clef/main.go
index 8befce88dc93ec034bb9e7edbaa837f91c147517..61d2811f65699d7680d38bd4f78bfbca1179610b 100644
--- a/cmd/clef/main.go
+++ b/cmd/clef/main.go
@@ -50,10 +50,10 @@ import (
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/rpc"
 	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 	"github.com/ethereum/go-ethereum/signer/fourbyte"
 	"github.com/ethereum/go-ethereum/signer/rules"
 	"github.com/ethereum/go-ethereum/signer/storage"
-
 	"github.com/mattn/go-colorable"
 	"github.com/mattn/go-isatty"
 	"gopkg.in/urfave/cli.v1"
@@ -657,7 +657,7 @@ func signer(c *cli.Context) error {
 		cors := utils.SplitAndTrim(c.GlobalString(utils.HTTPCORSDomainFlag.Name))
 
 		srv := rpc.NewServer()
-		err := node.RegisterApisFromWhitelist(rpcAPI, []string{"account"}, srv, false)
+		err := node.RegisterApis(rpcAPI, []string{"account"}, srv, false)
 		if err != nil {
 			utils.Fatalf("Could not register API: %w", err)
 		}
@@ -923,13 +923,13 @@ func testExternalUI(api *core.SignerAPI) {
 		time.Sleep(delay)
 		data := hexutil.Bytes([]byte{})
 		to := common.NewMixedcaseAddress(a)
-		tx := core.SendTxArgs{
+		tx := apitypes.SendTxArgs{
 			Data:     &data,
 			Nonce:    0x1,
 			Value:    hexutil.Big(*big.NewInt(6)),
 			From:     common.NewMixedcaseAddress(a),
 			To:       &to,
-			GasPrice: hexutil.Big(*big.NewInt(5)),
+			GasPrice: (*hexutil.Big)(big.NewInt(5)),
 			Gas:      1000,
 			Input:    nil,
 		}
@@ -1055,17 +1055,17 @@ func GenDoc(ctx *cli.Context) {
 		data := hexutil.Bytes([]byte{0x01, 0x02, 0x03, 0x04})
 		add("SignTxRequest", desc, &core.SignTxRequest{
 			Meta: meta,
-			Callinfo: []core.ValidationInfo{
+			Callinfo: []apitypes.ValidationInfo{
 				{Typ: "Warning", Message: "Something looks odd, show this message as a warning"},
 				{Typ: "Info", Message: "User should see this as well"},
 			},
-			Transaction: core.SendTxArgs{
+			Transaction: apitypes.SendTxArgs{
 				Data:     &data,
 				Nonce:    0x1,
 				Value:    hexutil.Big(*big.NewInt(6)),
 				From:     common.NewMixedcaseAddress(a),
 				To:       nil,
-				GasPrice: hexutil.Big(*big.NewInt(5)),
+				GasPrice: (*hexutil.Big)(big.NewInt(5)),
 				Gas:      1000,
 				Input:    nil,
 			}})
@@ -1075,13 +1075,13 @@ func GenDoc(ctx *cli.Context) {
 		add("SignTxResponse - approve", "Response to request to sign a transaction. This response needs to contain the `transaction`"+
 			", because the UI is free to make modifications to the transaction.",
 			&core.SignTxResponse{Approved: true,
-				Transaction: core.SendTxArgs{
+				Transaction: apitypes.SendTxArgs{
 					Data:     &data,
 					Nonce:    0x4,
 					Value:    hexutil.Big(*big.NewInt(6)),
 					From:     common.NewMixedcaseAddress(a),
 					To:       nil,
-					GasPrice: hexutil.Big(*big.NewInt(5)),
+					GasPrice: (*hexutil.Big)(big.NewInt(5)),
 					Gas:      1000,
 					Input:    nil,
 				}})
diff --git a/cmd/clef/testdata/sign_1559_missing_field_exp_fail.json b/cmd/clef/testdata/sign_1559_missing_field_exp_fail.json
new file mode 100644
index 0000000000000000000000000000000000000000..c5a133686085f694c99f4993cccc2dac170e3f07
--- /dev/null
+++ b/cmd/clef/testdata/sign_1559_missing_field_exp_fail.json
@@ -0,0 +1,16 @@
+{
+  "jsonrpc": "2.0",
+  "method": "account_signTransaction",
+  "params": [
+    {
+      "from": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "to": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "gas": "0x333",
+      "maxFeePerGas": "0x123",
+      "nonce": "0x0",
+      "value": "0x10",
+      "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+    }
+  ],
+  "id": 67
+}
diff --git a/cmd/clef/testdata/sign_1559_missing_maxfeepergas_exp_fail.json b/cmd/clef/testdata/sign_1559_missing_maxfeepergas_exp_fail.json
new file mode 100644
index 0000000000000000000000000000000000000000..df69231d7efe935744d48b0de45df7b33741764b
--- /dev/null
+++ b/cmd/clef/testdata/sign_1559_missing_maxfeepergas_exp_fail.json
@@ -0,0 +1,16 @@
+{
+  "jsonrpc": "2.0",
+  "method": "account_signTransaction",
+  "params": [
+    {
+      "from": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "to": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "gas": "0x333",
+      "maxPriorityFeePerGas": "0x123",
+      "nonce": "0x0",
+      "value": "0x10",
+      "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+    }
+  ],
+  "id": 67
+}
diff --git a/cmd/clef/testdata/sign_1559_tx.json b/cmd/clef/testdata/sign_1559_tx.json
new file mode 100644
index 0000000000000000000000000000000000000000..29355f6cf5bdb55349c2760736419727202d2c04
--- /dev/null
+++ b/cmd/clef/testdata/sign_1559_tx.json
@@ -0,0 +1,17 @@
+{
+  "jsonrpc": "2.0",
+  "method": "account_signTransaction",
+  "params": [
+    {
+      "from": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "to": "0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "gas": "0x333",
+      "maxPriorityFeePerGas": "0x123",
+      "maxFeePerGas": "0x123",
+      "nonce": "0x0",
+      "value": "0x10",
+      "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+    }
+  ],
+  "id": 67
+}
diff --git a/cmd/clef/testdata/sign_bad_checksum_exp_fail.json b/cmd/clef/testdata/sign_bad_checksum_exp_fail.json
new file mode 100644
index 0000000000000000000000000000000000000000..21ba7b3fc090a114d39a3dfdeaae5058a65c594b
--- /dev/null
+++ b/cmd/clef/testdata/sign_bad_checksum_exp_fail.json
@@ -0,0 +1,17 @@
+{
+  "jsonrpc": "2.0",
+  "method": "account_signTransaction",
+  "params": [
+    {
+	"from":"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192",
+	"to":"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192",
+      "gas": "0x333",
+      "gasPrice": "0x123",
+      "nonce": "0x0",
+      "value": "0x10",
+      "data":
+        "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+    }
+  ],
+  "id": 67
+}
diff --git a/cmd/clef/testdata/sign_normal_exp_ok.json b/cmd/clef/testdata/sign_normal_exp_ok.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f3a9202a07de70751d51b76dc2d40be9b397ffd
--- /dev/null
+++ b/cmd/clef/testdata/sign_normal_exp_ok.json
@@ -0,0 +1,17 @@
+{
+  "jsonrpc": "2.0",
+  "method": "account_signTransaction",
+  "params": [
+    {
+	"from":"0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+	"to":"0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192",
+      "gas": "0x333",
+      "gasPrice": "0x123",
+      "nonce": "0x0",
+      "value": "0x10",
+      "data":
+        "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+    }
+  ],
+  "id": 67
+}
diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go
index 83c55181ada4ca3b923533900ea19c0b8eed074c..34a20c515b2325478d211dcf11cdc787b894a4bc 100644
--- a/cmd/devp2p/internal/ethtest/chain.go
+++ b/cmd/devp2p/internal/ethtest/chain.go
@@ -54,10 +54,24 @@ func (c *Chain) Len() int {
 	return len(c.blocks)
 }
 
-// TD calculates the total difficulty of the chain.
-func (c *Chain) TD(height int) *big.Int { // TODO later on channge scheme so that the height is included in range
+// TD calculates the total difficulty of the chain at the
+// chain head.
+func (c *Chain) TD() *big.Int {
 	sum := big.NewInt(0)
-	for _, block := range c.blocks[:height] {
+	for _, block := range c.blocks[:c.Len()] {
+		sum.Add(sum, block.Difficulty())
+	}
+	return sum
+}
+
+// TotalDifficultyAt calculates the total difficulty of the chain
+// at the given block height.
+func (c *Chain) TotalDifficultyAt(height int) *big.Int {
+	sum := big.NewInt(0)
+	if height >= c.Len() {
+		return sum
+	}
+	for _, block := range c.blocks[:height+1] {
 		sum.Add(sum, block.Difficulty())
 	}
 	return sum
diff --git a/cmd/devp2p/internal/ethtest/eth66_suite.go b/cmd/devp2p/internal/ethtest/eth66_suite.go
deleted file mode 100644
index 903a90c7eb2b66ad0515c790718f72576b355b77..0000000000000000000000000000000000000000
--- a/cmd/devp2p/internal/ethtest/eth66_suite.go
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2021 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package ethtest
-
-import (
-	"time"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/eth/protocols/eth"
-	"github.com/ethereum/go-ethereum/internal/utesting"
-	"github.com/ethereum/go-ethereum/p2p"
-)
-
-// Is_66 checks if the node supports the eth66 protocol version,
-// and if not, exists the test suite
-func (s *Suite) Is_66(t *utesting.T) {
-	conn := s.dial66(t)
-	conn.handshake(t)
-	if conn.negotiatedProtoVersion < 66 {
-		t.Fail()
-	}
-}
-
-// TestStatus_66 attempts to connect to the given node and exchange
-// a status message with it on the eth66 protocol, and then check to
-// make sure the chain head is correct.
-func (s *Suite) TestStatus_66(t *utesting.T) {
-	conn := s.dial66(t)
-	defer conn.Close()
-	// get protoHandshake
-	conn.handshake(t)
-	// get status
-	switch msg := conn.statusExchange66(t, s.chain).(type) {
-	case *Status:
-		status := *msg
-		if status.ProtocolVersion != uint32(66) {
-			t.Fatalf("mismatch in version: wanted 66, got %d", status.ProtocolVersion)
-		}
-		t.Logf("got status message: %s", pretty.Sdump(msg))
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
-	}
-}
-
-// TestGetBlockHeaders_66 tests whether the given node can respond to
-// an eth66 `GetBlockHeaders` request and that the response is accurate.
-func (s *Suite) TestGetBlockHeaders_66(t *utesting.T) {
-	conn := s.setupConnection66(t)
-	defer conn.Close()
-	// get block headers
-	req := &eth.GetBlockHeadersPacket66{
-		RequestId: 3,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Hash: s.chain.blocks[1].Hash(),
-			},
-			Amount:  2,
-			Skip:    1,
-			Reverse: false,
-		},
-	}
-	// write message
-	headers, err := s.getBlockHeaders66(conn, req, req.RequestId)
-	if err != nil {
-		t.Fatalf("could not get block headers: %v", err)
-	}
-	// check for correct headers
-	if !headersMatch(t, s.chain, headers) {
-		t.Fatal("received wrong header(s)")
-	}
-}
-
-// TestSimultaneousRequests_66 sends two simultaneous `GetBlockHeader` requests
-// with different request IDs and checks to make sure the node responds with the correct
-// headers per request.
-func (s *Suite) TestSimultaneousRequests_66(t *utesting.T) {
-	// create two connections
-	conn := s.setupConnection66(t)
-	defer conn.Close()
-	// create two requests
-	req1 := &eth.GetBlockHeadersPacket66{
-		RequestId: 111,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Hash: s.chain.blocks[1].Hash(),
-			},
-			Amount:  2,
-			Skip:    1,
-			Reverse: false,
-		},
-	}
-	req2 := &eth.GetBlockHeadersPacket66{
-		RequestId: 222,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Hash: s.chain.blocks[1].Hash(),
-			},
-			Amount:  4,
-			Skip:    1,
-			Reverse: false,
-		},
-	}
-	// write first request
-	if err := conn.write66(req1, GetBlockHeaders{}.Code()); err != nil {
-		t.Fatalf("failed to write to connection: %v", err)
-	}
-	// write second request
-	if err := conn.write66(req2, GetBlockHeaders{}.Code()); err != nil {
-		t.Fatalf("failed to write to connection: %v", err)
-	}
-	// wait for responses
-	headers1, err := s.waitForBlockHeadersResponse66(conn, req1.RequestId)
-	if err != nil {
-		t.Fatalf("error while waiting for block headers: %v", err)
-	}
-	headers2, err := s.waitForBlockHeadersResponse66(conn, req2.RequestId)
-	if err != nil {
-		t.Fatalf("error while waiting for block headers: %v", err)
-	}
-	// check headers of both responses
-	if !headersMatch(t, s.chain, headers1) {
-		t.Fatalf("wrong header(s) in response to req1: got %v", headers1)
-	}
-	if !headersMatch(t, s.chain, headers2) {
-		t.Fatalf("wrong header(s) in response to req2: got %v", headers2)
-	}
-}
-
-// TestBroadcast_66 tests whether a block announcement is correctly
-// propagated to the given node's peer(s) on the eth66 protocol.
-func (s *Suite) TestBroadcast_66(t *utesting.T) {
-	s.sendNextBlock66(t)
-}
-
-// TestGetBlockBodies_66 tests whether the given node can respond to
-// a `GetBlockBodies` request and that the response is accurate over
-// the eth66 protocol.
-func (s *Suite) TestGetBlockBodies_66(t *utesting.T) {
-	conn := s.setupConnection66(t)
-	defer conn.Close()
-	// create block bodies request
-	id := uint64(55)
-	req := &eth.GetBlockBodiesPacket66{
-		RequestId: id,
-		GetBlockBodiesPacket: eth.GetBlockBodiesPacket{
-			s.chain.blocks[54].Hash(),
-			s.chain.blocks[75].Hash(),
-		},
-	}
-	if err := conn.write66(req, GetBlockBodies{}.Code()); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-
-	reqID, msg := conn.readAndServe66(s.chain, timeout)
-	switch msg := msg.(type) {
-	case BlockBodies:
-		if reqID != req.RequestId {
-			t.Fatalf("request ID mismatch: wanted %d, got %d", req.RequestId, reqID)
-		}
-		t.Logf("received %d block bodies", len(msg))
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
-	}
-}
-
-// TestLargeAnnounce_66 tests the announcement mechanism with a large block.
-func (s *Suite) TestLargeAnnounce_66(t *utesting.T) {
-	nextBlock := len(s.chain.blocks)
-	blocks := []*NewBlock{
-		{
-			Block: largeBlock(),
-			TD:    s.fullChain.TD(nextBlock + 1),
-		},
-		{
-			Block: s.fullChain.blocks[nextBlock],
-			TD:    largeNumber(2),
-		},
-		{
-			Block: largeBlock(),
-			TD:    largeNumber(2),
-		},
-		{
-			Block: s.fullChain.blocks[nextBlock],
-			TD:    s.fullChain.TD(nextBlock + 1),
-		},
-	}
-
-	for i, blockAnnouncement := range blocks[0:3] {
-		t.Logf("Testing malicious announcement: %v\n", i)
-		sendConn := s.setupConnection66(t)
-		if err := sendConn.Write(blockAnnouncement); err != nil {
-			t.Fatalf("could not write to connection: %v", err)
-		}
-		// Invalid announcement, check that peer disconnected
-		switch msg := sendConn.ReadAndServe(s.chain, time.Second*8).(type) {
-		case *Disconnect:
-		case *Error:
-			break
-		default:
-			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg))
-		}
-		sendConn.Close()
-	}
-	// Test the last block as a valid block
-	s.sendNextBlock66(t)
-}
-
-func (s *Suite) TestOldAnnounce_66(t *utesting.T) {
-	sendConn, recvConn := s.setupConnection66(t), s.setupConnection66(t)
-	defer sendConn.Close()
-	defer recvConn.Close()
-
-	s.oldAnnounce(t, sendConn, recvConn)
-}
-
-// TestMaliciousHandshake_66 tries to send malicious data during the handshake.
-func (s *Suite) TestMaliciousHandshake_66(t *utesting.T) {
-	conn := s.dial66(t)
-	defer conn.Close()
-	// write hello to client
-	pub0 := crypto.FromECDSAPub(&conn.ourKey.PublicKey)[1:]
-	handshakes := []*Hello{
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: largeString(2), Version: 66},
-			},
-			ID: pub0,
-		},
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-				{Name: "eth", Version: 66},
-			},
-			ID: append(pub0, byte(0)),
-		},
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-				{Name: "eth", Version: 66},
-			},
-			ID: append(pub0, pub0...),
-		},
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-				{Name: "eth", Version: 66},
-			},
-			ID: largeBuffer(2),
-		},
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: largeString(2), Version: 66},
-			},
-			ID: largeBuffer(2),
-		},
-	}
-	for i, handshake := range handshakes {
-		t.Logf("Testing malicious handshake %v\n", i)
-		// Init the handshake
-		if err := conn.Write(handshake); err != nil {
-			t.Fatalf("could not write to connection: %v", err)
-		}
-		// check that the peer disconnected
-		timeout := 20 * time.Second
-		// Discard one hello
-		for i := 0; i < 2; i++ {
-			switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-			case *Disconnect:
-			case *Error:
-			case *Hello:
-				// Hello's are sent concurrently, so ignore them
-				continue
-			default:
-				t.Fatalf("unexpected: %s", pretty.Sdump(msg))
-			}
-		}
-		// Dial for the next round
-		conn = s.dial66(t)
-	}
-}
-
-// TestMaliciousStatus_66 sends a status package with a large total difficulty.
-func (s *Suite) TestMaliciousStatus_66(t *utesting.T) {
-	conn := s.dial66(t)
-	defer conn.Close()
-	// get protoHandshake
-	conn.handshake(t)
-	status := &Status{
-		ProtocolVersion: uint32(66),
-		NetworkID:       s.chain.chainConfig.ChainID.Uint64(),
-		TD:              largeNumber(2),
-		Head:            s.chain.blocks[s.chain.Len()-1].Hash(),
-		Genesis:         s.chain.blocks[0].Hash(),
-		ForkID:          s.chain.ForkID(),
-	}
-	// get status
-	switch msg := conn.statusExchange(t, s.chain, status).(type) {
-	case *Status:
-		t.Logf("%+v\n", msg)
-	default:
-		t.Fatalf("expected status, got: %#v ", msg)
-	}
-	// wait for disconnect
-	switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-	case *Disconnect:
-	case *Error:
-		return
-	default:
-		t.Fatalf("expected disconnect, got: %s", pretty.Sdump(msg))
-	}
-}
-
-func (s *Suite) TestTransaction_66(t *utesting.T) {
-	tests := []*types.Transaction{
-		getNextTxFromChain(t, s),
-		unknownTx(t, s),
-	}
-	for i, tx := range tests {
-		t.Logf("Testing tx propagation: %v\n", i)
-		sendSuccessfulTx66(t, s, tx)
-	}
-}
-
-func (s *Suite) TestMaliciousTx_66(t *utesting.T) {
-	badTxs := []*types.Transaction{
-		getOldTxFromChain(t, s),
-		invalidNonceTx(t, s),
-		hugeAmount(t, s),
-		hugeGasPrice(t, s),
-		hugeData(t, s),
-	}
-	sendConn := s.setupConnection66(t)
-	defer sendConn.Close()
-	// set up receiving connection before sending txs to make sure
-	// no announcements are missed
-	recvConn := s.setupConnection66(t)
-	defer recvConn.Close()
-
-	for i, tx := range badTxs {
-		t.Logf("Testing malicious tx propagation: %v\n", i)
-		if err := sendConn.Write(&Transactions{tx}); err != nil {
-			t.Fatalf("could not write to connection: %v", err)
-		}
-
-	}
-	// check to make sure bad txs aren't propagated
-	waitForTxPropagation(t, s, badTxs, recvConn)
-}
-
-// TestZeroRequestID_66 checks that a request ID of zero is still handled
-// by the node.
-func (s *Suite) TestZeroRequestID_66(t *utesting.T) {
-	conn := s.setupConnection66(t)
-	defer conn.Close()
-
-	req := &eth.GetBlockHeadersPacket66{
-		RequestId: 0,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Number: 0,
-			},
-			Amount: 2,
-		},
-	}
-	headers, err := s.getBlockHeaders66(conn, req, req.RequestId)
-	if err != nil {
-		t.Fatalf("could not get block headers: %v", err)
-	}
-	if !headersMatch(t, s.chain, headers) {
-		t.Fatal("received wrong header(s)")
-	}
-}
-
-// TestSameRequestID_66 sends two requests with the same request ID
-// concurrently to a single node.
-func (s *Suite) TestSameRequestID_66(t *utesting.T) {
-	conn := s.setupConnection66(t)
-	// create two requests with the same request ID
-	reqID := uint64(1234)
-	request1 := &eth.GetBlockHeadersPacket66{
-		RequestId: reqID,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Number: 1,
-			},
-			Amount: 2,
-		},
-	}
-	request2 := &eth.GetBlockHeadersPacket66{
-		RequestId: reqID,
-		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-			Origin: eth.HashOrNumber{
-				Number: 33,
-			},
-			Amount: 2,
-		},
-	}
-	// write the first request
-	err := conn.write66(request1, GetBlockHeaders{}.Code())
-	if err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-	// perform second request
-	headers2, err := s.getBlockHeaders66(conn, request2, reqID)
-	if err != nil {
-		t.Fatalf("could not get block headers: %v", err)
-		return
-	}
-	// wait for response to first request
-	headers1, err := s.waitForBlockHeadersResponse66(conn, reqID)
-	if err != nil {
-		t.Fatalf("could not get BlockHeaders response: %v", err)
-	}
-	// check if headers match
-	if !headersMatch(t, s.chain, headers1) || !headersMatch(t, s.chain, headers2) {
-		t.Fatal("received wrong header(s)")
-	}
-}
-
-// TestLargeTxRequest_66 tests whether a node can fulfill a large GetPooledTransactions
-// request.
-func (s *Suite) TestLargeTxRequest_66(t *utesting.T) {
-	// send the next block to ensure the node is no longer syncing and is able to accept
-	// txs
-	s.sendNextBlock66(t)
-	// send 2000 transactions to the node
-	hashMap, txs := generateTxs(t, s, 2000)
-	sendConn := s.setupConnection66(t)
-	defer sendConn.Close()
-
-	sendMultipleSuccessfulTxs(t, s, sendConn, txs)
-	// set up connection to receive to ensure node is peered with the receiving connection
-	// before tx request is sent
-	recvConn := s.setupConnection66(t)
-	defer recvConn.Close()
-	// create and send pooled tx request
-	hashes := make([]common.Hash, 0)
-	for _, hash := range hashMap {
-		hashes = append(hashes, hash)
-	}
-	getTxReq := &eth.GetPooledTransactionsPacket66{
-		RequestId:                   1234,
-		GetPooledTransactionsPacket: hashes,
-	}
-	if err := recvConn.write66(getTxReq, GetPooledTransactions{}.Code()); err != nil {
-		t.Fatalf("could not write to conn: %v", err)
-	}
-	// check that all received transactions match those that were sent to node
-	switch msg := recvConn.waitForResponse(s.chain, timeout, getTxReq.RequestId).(type) {
-	case PooledTransactions:
-		for _, gotTx := range msg {
-			if _, exists := hashMap[gotTx.Hash()]; !exists {
-				t.Fatalf("unexpected tx received: %v", gotTx.Hash())
-			}
-		}
-	default:
-		t.Fatalf("unexpected %s", pretty.Sdump(msg))
-	}
-}
-
-// TestNewPooledTxs_66 tests whether a node will do a GetPooledTransactions
-// request upon receiving a NewPooledTransactionHashes announcement.
-func (s *Suite) TestNewPooledTxs_66(t *utesting.T) {
-	// send the next block to ensure the node is no longer syncing and is able to accept
-	// txs
-	s.sendNextBlock66(t)
-	// generate 50 txs
-	hashMap, _ := generateTxs(t, s, 50)
-	// create new pooled tx hashes announcement
-	hashes := make([]common.Hash, 0)
-	for _, hash := range hashMap {
-		hashes = append(hashes, hash)
-	}
-	announce := NewPooledTransactionHashes(hashes)
-	// send announcement
-	conn := s.setupConnection66(t)
-	defer conn.Close()
-	if err := conn.Write(announce); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-	// wait for GetPooledTxs request
-	for {
-		_, msg := conn.readAndServe66(s.chain, timeout)
-		switch msg := msg.(type) {
-		case GetPooledTransactions:
-			if len(msg) != len(hashes) {
-				t.Fatalf("unexpected number of txs requested: wanted %d, got %d", len(hashes), len(msg))
-			}
-			return
-		case *NewPooledTransactionHashes, *NewBlock, *NewBlockHashes:
-			// ignore propagated txs and blocks from old tests
-			continue
-		default:
-			t.Fatalf("unexpected %s", pretty.Sdump(msg))
-		}
-	}
-}
diff --git a/cmd/devp2p/internal/ethtest/eth66_suiteHelpers.go b/cmd/devp2p/internal/ethtest/eth66_suiteHelpers.go
deleted file mode 100644
index 3c5b22f0b5ef42dcb1e88f79d0b5cffe3eb20eab..0000000000000000000000000000000000000000
--- a/cmd/devp2p/internal/ethtest/eth66_suiteHelpers.go
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2021 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package ethtest
-
-import (
-	"fmt"
-	"reflect"
-	"time"
-
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/eth/protocols/eth"
-	"github.com/ethereum/go-ethereum/internal/utesting"
-	"github.com/ethereum/go-ethereum/p2p"
-	"github.com/ethereum/go-ethereum/rlp"
-	"github.com/stretchr/testify/assert"
-)
-
-func (c *Conn) statusExchange66(t *utesting.T, chain *Chain) Message {
-	status := &Status{
-		ProtocolVersion: uint32(66),
-		NetworkID:       chain.chainConfig.ChainID.Uint64(),
-		TD:              chain.TD(chain.Len()),
-		Head:            chain.blocks[chain.Len()-1].Hash(),
-		Genesis:         chain.blocks[0].Hash(),
-		ForkID:          chain.ForkID(),
-	}
-	return c.statusExchange(t, chain, status)
-}
-
-func (s *Suite) dial66(t *utesting.T) *Conn {
-	conn, err := s.dial()
-	if err != nil {
-		t.Fatalf("could not dial: %v", err)
-	}
-	conn.caps = append(conn.caps, p2p.Cap{Name: "eth", Version: 66})
-	conn.ourHighestProtoVersion = 66
-	return conn
-}
-
-func (c *Conn) write66(req eth.Packet, code int) error {
-	payload, err := rlp.EncodeToBytes(req)
-	if err != nil {
-		return err
-	}
-	_, err = c.Conn.Write(uint64(code), payload)
-	return err
-}
-
-func (c *Conn) read66() (uint64, Message) {
-	code, rawData, _, err := c.Conn.Read()
-	if err != nil {
-		return 0, errorf("could not read from connection: %v", err)
-	}
-
-	var msg Message
-
-	switch int(code) {
-	case (Hello{}).Code():
-		msg = new(Hello)
-
-	case (Ping{}).Code():
-		msg = new(Ping)
-	case (Pong{}).Code():
-		msg = new(Pong)
-	case (Disconnect{}).Code():
-		msg = new(Disconnect)
-	case (Status{}).Code():
-		msg = new(Status)
-	case (GetBlockHeaders{}).Code():
-		ethMsg := new(eth.GetBlockHeadersPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, GetBlockHeaders(*ethMsg.GetBlockHeadersPacket)
-	case (BlockHeaders{}).Code():
-		ethMsg := new(eth.BlockHeadersPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, BlockHeaders(ethMsg.BlockHeadersPacket)
-	case (GetBlockBodies{}).Code():
-		ethMsg := new(eth.GetBlockBodiesPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, GetBlockBodies(ethMsg.GetBlockBodiesPacket)
-	case (BlockBodies{}).Code():
-		ethMsg := new(eth.BlockBodiesPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, BlockBodies(ethMsg.BlockBodiesPacket)
-	case (NewBlock{}).Code():
-		msg = new(NewBlock)
-	case (NewBlockHashes{}).Code():
-		msg = new(NewBlockHashes)
-	case (Transactions{}).Code():
-		msg = new(Transactions)
-	case (NewPooledTransactionHashes{}).Code():
-		msg = new(NewPooledTransactionHashes)
-	case (GetPooledTransactions{}.Code()):
-		ethMsg := new(eth.GetPooledTransactionsPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, GetPooledTransactions(ethMsg.GetPooledTransactionsPacket)
-	case (PooledTransactions{}.Code()):
-		ethMsg := new(eth.PooledTransactionsPacket66)
-		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return ethMsg.RequestId, PooledTransactions(ethMsg.PooledTransactionsPacket)
-	default:
-		msg = errorf("invalid message code: %d", code)
-	}
-
-	if msg != nil {
-		if err := rlp.DecodeBytes(rawData, msg); err != nil {
-			return 0, errorf("could not rlp decode message: %v", err)
-		}
-		return 0, msg
-	}
-	return 0, errorf("invalid message: %s", string(rawData))
-}
-
-func (c *Conn) waitForResponse(chain *Chain, timeout time.Duration, requestID uint64) Message {
-	for {
-		id, msg := c.readAndServe66(chain, timeout)
-		if id == requestID {
-			return msg
-		}
-	}
-}
-
-// ReadAndServe serves GetBlockHeaders requests while waiting
-// on another message from the node.
-func (c *Conn) readAndServe66(chain *Chain, timeout time.Duration) (uint64, Message) {
-	start := time.Now()
-	for time.Since(start) < timeout {
-		c.SetReadDeadline(time.Now().Add(10 * time.Second))
-
-		reqID, msg := c.read66()
-
-		switch msg := msg.(type) {
-		case *Ping:
-			c.Write(&Pong{})
-		case *GetBlockHeaders:
-			headers, err := chain.GetHeaders(*msg)
-			if err != nil {
-				return 0, errorf("could not get headers for inbound header request: %v", err)
-			}
-			resp := &eth.BlockHeadersPacket66{
-				RequestId:          reqID,
-				BlockHeadersPacket: eth.BlockHeadersPacket(headers),
-			}
-			if err := c.write66(resp, BlockHeaders{}.Code()); err != nil {
-				return 0, errorf("could not write to connection: %v", err)
-			}
-		default:
-			return reqID, msg
-		}
-	}
-	return 0, errorf("no message received within %v", timeout)
-}
-
-func (s *Suite) setupConnection66(t *utesting.T) *Conn {
-	// create conn
-	sendConn := s.dial66(t)
-	sendConn.handshake(t)
-	sendConn.statusExchange66(t, s.chain)
-	return sendConn
-}
-
-func (s *Suite) testAnnounce66(t *utesting.T, sendConn, receiveConn *Conn, blockAnnouncement *NewBlock) {
-	// Announce the block.
-	if err := sendConn.Write(blockAnnouncement); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-	s.waitAnnounce66(t, receiveConn, blockAnnouncement)
-}
-
-func (s *Suite) waitAnnounce66(t *utesting.T, conn *Conn, blockAnnouncement *NewBlock) {
-	for {
-		_, msg := conn.readAndServe66(s.chain, timeout)
-		switch msg := msg.(type) {
-		case *NewBlock:
-			t.Logf("received NewBlock message: %s", pretty.Sdump(msg.Block))
-			assert.Equal(t,
-				blockAnnouncement.Block.Header(), msg.Block.Header(),
-				"wrong block header in announcement",
-			)
-			assert.Equal(t,
-				blockAnnouncement.TD, msg.TD,
-				"wrong TD in announcement",
-			)
-			return
-		case *NewBlockHashes:
-			blockHashes := *msg
-			t.Logf("received NewBlockHashes message: %s", pretty.Sdump(blockHashes))
-			assert.Equal(t, blockAnnouncement.Block.Hash(), blockHashes[0].Hash,
-				"wrong block hash in announcement",
-			)
-			return
-		case *NewPooledTransactionHashes:
-			// ignore old txs being propagated
-			continue
-		default:
-			t.Fatalf("unexpected: %s", pretty.Sdump(msg))
-		}
-	}
-}
-
-// waitForBlock66 waits for confirmation from the client that it has
-// imported the given block.
-func (c *Conn) waitForBlock66(block *types.Block) error {
-	defer c.SetReadDeadline(time.Time{})
-
-	c.SetReadDeadline(time.Now().Add(20 * time.Second))
-	// note: if the node has not yet imported the block, it will respond
-	// to the GetBlockHeaders request with an empty BlockHeaders response,
-	// so the GetBlockHeaders request must be sent again until the BlockHeaders
-	// response contains the desired header.
-	for {
-		req := eth.GetBlockHeadersPacket66{
-			RequestId: 54,
-			GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
-				Origin: eth.HashOrNumber{
-					Hash: block.Hash(),
-				},
-				Amount: 1,
-			},
-		}
-		if err := c.write66(req, GetBlockHeaders{}.Code()); err != nil {
-			return err
-		}
-
-		reqID, msg := c.read66()
-		// check message
-		switch msg := msg.(type) {
-		case BlockHeaders:
-			// check request ID
-			if reqID != req.RequestId {
-				return fmt.Errorf("request ID mismatch: wanted %d, got %d", req.RequestId, reqID)
-			}
-			for _, header := range msg {
-				if header.Number.Uint64() == block.NumberU64() {
-					return nil
-				}
-			}
-			time.Sleep(100 * time.Millisecond)
-		case *NewPooledTransactionHashes:
-			// ignore old announcements
-			continue
-		default:
-			return fmt.Errorf("invalid message: %s", pretty.Sdump(msg))
-		}
-	}
-}
-
-func sendSuccessfulTx66(t *utesting.T, s *Suite, tx *types.Transaction) {
-	sendConn := s.setupConnection66(t)
-	defer sendConn.Close()
-	sendSuccessfulTxWithConn(t, s, tx, sendConn)
-}
-
-// waitForBlockHeadersResponse66 waits for a BlockHeaders message with the given expected request ID
-func (s *Suite) waitForBlockHeadersResponse66(conn *Conn, expectedID uint64) (BlockHeaders, error) {
-	reqID, msg := conn.readAndServe66(s.chain, timeout)
-	switch msg := msg.(type) {
-	case BlockHeaders:
-		if reqID != expectedID {
-			return nil, fmt.Errorf("request ID mismatch: wanted %d, got %d", expectedID, reqID)
-		}
-		return msg, nil
-	default:
-		return nil, fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
-	}
-}
-
-func (s *Suite) getBlockHeaders66(conn *Conn, req eth.Packet, expectedID uint64) (BlockHeaders, error) {
-	if err := conn.write66(req, GetBlockHeaders{}.Code()); err != nil {
-		return nil, fmt.Errorf("could not write to connection: %v", err)
-	}
-	return s.waitForBlockHeadersResponse66(conn, expectedID)
-}
-
-func headersMatch(t *utesting.T, chain *Chain, headers BlockHeaders) bool {
-	mismatched := 0
-	for _, header := range headers {
-		num := header.Number.Uint64()
-		t.Logf("received header (%d): %s", num, pretty.Sdump(header.Hash()))
-		if !reflect.DeepEqual(chain.blocks[int(num)].Header(), header) {
-			mismatched += 1
-			t.Logf("received wrong header: %v", pretty.Sdump(header))
-		}
-	}
-	return mismatched == 0
-}
-
-func (s *Suite) sendNextBlock66(t *utesting.T) {
-	sendConn, receiveConn := s.setupConnection66(t), s.setupConnection66(t)
-	defer sendConn.Close()
-	defer receiveConn.Close()
-
-	// create new block announcement
-	nextBlock := len(s.chain.blocks)
-	blockAnnouncement := &NewBlock{
-		Block: s.fullChain.blocks[nextBlock],
-		TD:    s.fullChain.TD(nextBlock + 1),
-	}
-	// send announcement and wait for node to request the header
-	s.testAnnounce66(t, sendConn, receiveConn, blockAnnouncement)
-	// wait for client to update its chain
-	if err := receiveConn.waitForBlock66(s.fullChain.blocks[nextBlock]); err != nil {
-		t.Fatal(err)
-	}
-	// update test suite chain
-	s.chain.blocks = append(s.chain.blocks, s.fullChain.blocks[nextBlock])
-}
diff --git a/cmd/devp2p/internal/ethtest/helpers.go b/cmd/devp2p/internal/ethtest/helpers.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f7365483a5c091fb53b1fc024135ae622613f15
--- /dev/null
+++ b/cmd/devp2p/internal/ethtest/helpers.go
@@ -0,0 +1,749 @@
+// Copyright 2020 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package ethtest
+
+import (
+	"fmt"
+	"net"
+	"reflect"
+	"strings"
+	"time"
+
+	"github.com/davecgh/go-spew/spew"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/eth/protocols/eth"
+	"github.com/ethereum/go-ethereum/internal/utesting"
+	"github.com/ethereum/go-ethereum/p2p"
+	"github.com/ethereum/go-ethereum/p2p/rlpx"
+)
+
+var (
+	pretty = spew.ConfigState{
+		Indent:                  "  ",
+		DisableCapacities:       true,
+		DisablePointerAddresses: true,
+		SortKeys:                true,
+	}
+	timeout = 20 * time.Second
+)
+
+// Is_66 checks if the node supports the eth66 protocol version,
+// and if not, exists the test suite
+func (s *Suite) Is_66(t *utesting.T) {
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	if err := conn.handshake(); err != nil {
+		t.Fatalf("handshake failed: %v", err)
+	}
+	if conn.negotiatedProtoVersion < 66 {
+		t.Fail()
+	}
+}
+
+// dial attempts to dial the given node and perform a handshake,
+// returning the created Conn if successful.
+func (s *Suite) dial() (*Conn, error) {
+	// dial
+	fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", s.Dest.IP(), s.Dest.TCP()))
+	if err != nil {
+		return nil, err
+	}
+	conn := Conn{Conn: rlpx.NewConn(fd, s.Dest.Pubkey())}
+	// do encHandshake
+	conn.ourKey, _ = crypto.GenerateKey()
+	_, err = conn.Handshake(conn.ourKey)
+	if err != nil {
+		conn.Close()
+		return nil, err
+	}
+	// set default p2p capabilities
+	conn.caps = []p2p.Cap{
+		{Name: "eth", Version: 64},
+		{Name: "eth", Version: 65},
+	}
+	conn.ourHighestProtoVersion = 65
+	return &conn, nil
+}
+
+// dial66 attempts to dial the given node and perform a handshake,
+// returning the created Conn with additional eth66 capabilities if
+// successful
+func (s *Suite) dial66() (*Conn, error) {
+	conn, err := s.dial()
+	if err != nil {
+		return nil, fmt.Errorf("dial failed: %v", err)
+	}
+	conn.caps = append(conn.caps, p2p.Cap{Name: "eth", Version: 66})
+	conn.ourHighestProtoVersion = 66
+	return conn, nil
+}
+
+// peer performs both the protocol handshake and the status message
+// exchange with the node in order to peer with it.
+func (c *Conn) peer(chain *Chain, status *Status) error {
+	if err := c.handshake(); err != nil {
+		return fmt.Errorf("handshake failed: %v", err)
+	}
+	if _, err := c.statusExchange(chain, status); err != nil {
+		return fmt.Errorf("status exchange failed: %v", err)
+	}
+	return nil
+}
+
+// handshake performs a protocol handshake with the node.
+func (c *Conn) handshake() error {
+	defer c.SetDeadline(time.Time{})
+	c.SetDeadline(time.Now().Add(10 * time.Second))
+	// write hello to client
+	pub0 := crypto.FromECDSAPub(&c.ourKey.PublicKey)[1:]
+	ourHandshake := &Hello{
+		Version: 5,
+		Caps:    c.caps,
+		ID:      pub0,
+	}
+	if err := c.Write(ourHandshake); err != nil {
+		return fmt.Errorf("write to connection failed: %v", err)
+	}
+	// read hello from client
+	switch msg := c.Read().(type) {
+	case *Hello:
+		// set snappy if version is at least 5
+		if msg.Version >= 5 {
+			c.SetSnappy(true)
+		}
+		c.negotiateEthProtocol(msg.Caps)
+		if c.negotiatedProtoVersion == 0 {
+			return fmt.Errorf("unexpected eth protocol version")
+		}
+		return nil
+	default:
+		return fmt.Errorf("bad handshake: %#v", msg)
+	}
+}
+
+// negotiateEthProtocol sets the Conn's eth protocol version to highest
+// advertised capability from peer.
+func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
+	var highestEthVersion uint
+	for _, capability := range caps {
+		if capability.Name != "eth" {
+			continue
+		}
+		if capability.Version > highestEthVersion && capability.Version <= c.ourHighestProtoVersion {
+			highestEthVersion = capability.Version
+		}
+	}
+	c.negotiatedProtoVersion = highestEthVersion
+}
+
+// statusExchange performs a `Status` message exchange with the given node.
+func (c *Conn) statusExchange(chain *Chain, status *Status) (Message, error) {
+	defer c.SetDeadline(time.Time{})
+	c.SetDeadline(time.Now().Add(20 * time.Second))
+
+	// read status message from client
+	var message Message
+loop:
+	for {
+		switch msg := c.Read().(type) {
+		case *Status:
+			if have, want := msg.Head, chain.blocks[chain.Len()-1].Hash(); have != want {
+				return nil, fmt.Errorf("wrong head block in status, want:  %#x (block %d) have %#x",
+					want, chain.blocks[chain.Len()-1].NumberU64(), have)
+			}
+			if have, want := msg.TD.Cmp(chain.TD()), 0; have != want {
+				return nil, fmt.Errorf("wrong TD in status: have %v want %v", have, want)
+			}
+			if have, want := msg.ForkID, chain.ForkID(); !reflect.DeepEqual(have, want) {
+				return nil, fmt.Errorf("wrong fork ID in status: have %v, want %v", have, want)
+			}
+			if have, want := msg.ProtocolVersion, c.ourHighestProtoVersion; have != uint32(want) {
+				return nil, fmt.Errorf("wrong protocol version: have %v, want %v", have, want)
+			}
+			message = msg
+			break loop
+		case *Disconnect:
+			return nil, fmt.Errorf("disconnect received: %v", msg.Reason)
+		case *Ping:
+			c.Write(&Pong{}) // TODO (renaynay): in the future, this should be an error
+			// (PINGs should not be a response upon fresh connection)
+		default:
+			return nil, fmt.Errorf("bad status message: %s", pretty.Sdump(msg))
+		}
+	}
+	// make sure eth protocol version is set for negotiation
+	if c.negotiatedProtoVersion == 0 {
+		return nil, fmt.Errorf("eth protocol version must be set in Conn")
+	}
+	if status == nil {
+		// default status message
+		status = &Status{
+			ProtocolVersion: uint32(c.negotiatedProtoVersion),
+			NetworkID:       chain.chainConfig.ChainID.Uint64(),
+			TD:              chain.TD(),
+			Head:            chain.blocks[chain.Len()-1].Hash(),
+			Genesis:         chain.blocks[0].Hash(),
+			ForkID:          chain.ForkID(),
+		}
+	}
+	if err := c.Write(status); err != nil {
+		return nil, fmt.Errorf("write to connection failed: %v", err)
+	}
+	return message, nil
+}
+
+// createSendAndRecvConns creates two connections, one for sending messages to the
+// node, and one for receiving messages from the node.
+func (s *Suite) createSendAndRecvConns(isEth66 bool) (*Conn, *Conn, error) {
+	var (
+		sendConn *Conn
+		recvConn *Conn
+		err      error
+	)
+	if isEth66 {
+		sendConn, err = s.dial66()
+		if err != nil {
+			return nil, nil, fmt.Errorf("dial failed: %v", err)
+		}
+		recvConn, err = s.dial66()
+		if err != nil {
+			sendConn.Close()
+			return nil, nil, fmt.Errorf("dial failed: %v", err)
+		}
+	} else {
+		sendConn, err = s.dial()
+		if err != nil {
+			return nil, nil, fmt.Errorf("dial failed: %v", err)
+		}
+		recvConn, err = s.dial()
+		if err != nil {
+			sendConn.Close()
+			return nil, nil, fmt.Errorf("dial failed: %v", err)
+		}
+	}
+	return sendConn, recvConn, nil
+}
+
+// readAndServe serves GetBlockHeaders requests while waiting
+// on another message from the node.
+func (c *Conn) readAndServe(chain *Chain, timeout time.Duration) Message {
+	start := time.Now()
+	for time.Since(start) < timeout {
+		c.SetReadDeadline(time.Now().Add(5 * time.Second))
+		switch msg := c.Read().(type) {
+		case *Ping:
+			c.Write(&Pong{})
+		case *GetBlockHeaders:
+			req := *msg
+			headers, err := chain.GetHeaders(req)
+			if err != nil {
+				return errorf("could not get headers for inbound header request: %v", err)
+			}
+			if err := c.Write(headers); err != nil {
+				return errorf("could not write to connection: %v", err)
+			}
+		default:
+			return msg
+		}
+	}
+	return errorf("no message received within %v", timeout)
+}
+
+// readAndServe66 serves eth66 GetBlockHeaders requests while waiting
+// on another message from the node.
+func (c *Conn) readAndServe66(chain *Chain, timeout time.Duration) (uint64, Message) {
+	start := time.Now()
+	for time.Since(start) < timeout {
+		c.SetReadDeadline(time.Now().Add(10 * time.Second))
+
+		reqID, msg := c.Read66()
+
+		switch msg := msg.(type) {
+		case *Ping:
+			c.Write(&Pong{})
+		case *GetBlockHeaders:
+			headers, err := chain.GetHeaders(*msg)
+			if err != nil {
+				return 0, errorf("could not get headers for inbound header request: %v", err)
+			}
+			resp := &eth.BlockHeadersPacket66{
+				RequestId:          reqID,
+				BlockHeadersPacket: eth.BlockHeadersPacket(headers),
+			}
+			if err := c.Write66(resp, BlockHeaders{}.Code()); err != nil {
+				return 0, errorf("could not write to connection: %v", err)
+			}
+		default:
+			return reqID, msg
+		}
+	}
+	return 0, errorf("no message received within %v", timeout)
+}
+
+// headersRequest executes the given `GetBlockHeaders` request.
+func (c *Conn) headersRequest(request *GetBlockHeaders, chain *Chain, isEth66 bool, reqID uint64) (BlockHeaders, error) {
+	defer c.SetReadDeadline(time.Time{})
+	c.SetReadDeadline(time.Now().Add(20 * time.Second))
+	// if on eth66 connection, perform eth66 GetBlockHeaders request
+	if isEth66 {
+		return getBlockHeaders66(chain, c, request, reqID)
+	}
+	if err := c.Write(request); err != nil {
+		return nil, err
+	}
+	switch msg := c.readAndServe(chain, timeout).(type) {
+	case *BlockHeaders:
+		return *msg, nil
+	default:
+		return nil, fmt.Errorf("invalid message: %s", pretty.Sdump(msg))
+	}
+}
+
+// getBlockHeaders66 executes the given `GetBlockHeaders` request over the eth66 protocol.
+func getBlockHeaders66(chain *Chain, conn *Conn, request *GetBlockHeaders, id uint64) (BlockHeaders, error) {
+	// write request
+	packet := eth.GetBlockHeadersPacket(*request)
+	req := &eth.GetBlockHeadersPacket66{
+		RequestId:             id,
+		GetBlockHeadersPacket: &packet,
+	}
+	if err := conn.Write66(req, GetBlockHeaders{}.Code()); err != nil {
+		return nil, fmt.Errorf("could not write to connection: %v", err)
+	}
+	// wait for response
+	msg := conn.waitForResponse(chain, timeout, req.RequestId)
+	headers, ok := msg.(BlockHeaders)
+	if !ok {
+		return nil, fmt.Errorf("unexpected message received: %s", pretty.Sdump(msg))
+	}
+	return headers, nil
+}
+
+// headersMatch returns whether the received headers match the given request
+func headersMatch(expected BlockHeaders, headers BlockHeaders) bool {
+	return reflect.DeepEqual(expected, headers)
+}
+
+// waitForResponse reads from the connection until a response with the expected
+// request ID is received.
+func (c *Conn) waitForResponse(chain *Chain, timeout time.Duration, requestID uint64) Message {
+	for {
+		id, msg := c.readAndServe66(chain, timeout)
+		if id == requestID {
+			return msg
+		}
+	}
+}
+
+// sendNextBlock broadcasts the next block in the chain and waits
+// for the node to propagate the block and import it into its chain.
+func (s *Suite) sendNextBlock(isEth66 bool) error {
+	// set up sending and receiving connections
+	sendConn, recvConn, err := s.createSendAndRecvConns(isEth66)
+	if err != nil {
+		return err
+	}
+	defer sendConn.Close()
+	defer recvConn.Close()
+	if err = sendConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	if err = recvConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	// create new block announcement
+	nextBlock := s.fullChain.blocks[s.chain.Len()]
+	blockAnnouncement := &NewBlock{
+		Block: nextBlock,
+		TD:    s.fullChain.TotalDifficultyAt(s.chain.Len()),
+	}
+	// send announcement and wait for node to request the header
+	if err = s.testAnnounce(sendConn, recvConn, blockAnnouncement); err != nil {
+		return fmt.Errorf("failed to announce block: %v", err)
+	}
+	// wait for client to update its chain
+	if err = s.waitForBlockImport(recvConn, nextBlock, isEth66); err != nil {
+		return fmt.Errorf("failed to receive confirmation of block import: %v", err)
+	}
+	// update test suite chain
+	s.chain.blocks = append(s.chain.blocks, nextBlock)
+	return nil
+}
+
+// testAnnounce writes a block announcement to the node and waits for the node
+// to propagate it.
+func (s *Suite) testAnnounce(sendConn, receiveConn *Conn, blockAnnouncement *NewBlock) error {
+	if err := sendConn.Write(blockAnnouncement); err != nil {
+		return fmt.Errorf("could not write to connection: %v", err)
+	}
+	return s.waitAnnounce(receiveConn, blockAnnouncement)
+}
+
+// waitAnnounce waits for a NewBlock or NewBlockHashes announcement from the node.
+func (s *Suite) waitAnnounce(conn *Conn, blockAnnouncement *NewBlock) error {
+	for {
+		switch msg := conn.readAndServe(s.chain, timeout).(type) {
+		case *NewBlock:
+			if !reflect.DeepEqual(blockAnnouncement.Block.Header(), msg.Block.Header()) {
+				return fmt.Errorf("wrong header in block announcement: \nexpected %v "+
+					"\ngot %v", blockAnnouncement.Block.Header(), msg.Block.Header())
+			}
+			if !reflect.DeepEqual(blockAnnouncement.TD, msg.TD) {
+				return fmt.Errorf("wrong TD in announcement: expected %v, got %v", blockAnnouncement.TD, msg.TD)
+			}
+			return nil
+		case *NewBlockHashes:
+			hashes := *msg
+			if blockAnnouncement.Block.Hash() != hashes[0].Hash {
+				return fmt.Errorf("wrong block hash in announcement: expected %v, got %v", blockAnnouncement.Block.Hash(), hashes[0].Hash)
+			}
+			return nil
+		case *NewPooledTransactionHashes:
+			// ignore tx announcements from previous tests
+			continue
+		default:
+			return fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
+		}
+	}
+}
+
+func (s *Suite) waitForBlockImport(conn *Conn, block *types.Block, isEth66 bool) error {
+	defer conn.SetReadDeadline(time.Time{})
+	conn.SetReadDeadline(time.Now().Add(20 * time.Second))
+	// create request
+	req := &GetBlockHeaders{
+		Origin: eth.HashOrNumber{
+			Hash: block.Hash(),
+		},
+		Amount: 1,
+	}
+	// loop until BlockHeaders response contains desired block, confirming the
+	// node imported the block
+	for {
+		var (
+			headers BlockHeaders
+			err     error
+		)
+		if isEth66 {
+			requestID := uint64(54)
+			headers, err = conn.headersRequest(req, s.chain, eth66, requestID)
+		} else {
+			headers, err = conn.headersRequest(req, s.chain, eth65, 0)
+		}
+		if err != nil {
+			return fmt.Errorf("GetBlockHeader request failed: %v", err)
+		}
+		// if headers response is empty, node hasn't imported block yet, try again
+		if len(headers) == 0 {
+			time.Sleep(100 * time.Millisecond)
+			continue
+		}
+		if !reflect.DeepEqual(block.Header(), headers[0]) {
+			return fmt.Errorf("wrong header returned: wanted %v, got %v", block.Header(), headers[0])
+		}
+		return nil
+	}
+}
+
+func (s *Suite) oldAnnounce(isEth66 bool) error {
+	sendConn, receiveConn, err := s.createSendAndRecvConns(isEth66)
+	if err != nil {
+		return err
+	}
+	defer sendConn.Close()
+	defer receiveConn.Close()
+	if err := sendConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	if err := receiveConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	// create old block announcement
+	oldBlockAnnounce := &NewBlock{
+		Block: s.chain.blocks[len(s.chain.blocks)/2],
+		TD:    s.chain.blocks[len(s.chain.blocks)/2].Difficulty(),
+	}
+	if err := sendConn.Write(oldBlockAnnounce); err != nil {
+		return fmt.Errorf("could not write to connection: %v", err)
+	}
+	// wait to see if the announcement is propagated
+	switch msg := receiveConn.readAndServe(s.chain, time.Second*8).(type) {
+	case *NewBlock:
+		block := *msg
+		if block.Block.Hash() == oldBlockAnnounce.Block.Hash() {
+			return fmt.Errorf("unexpected: block propagated: %s", pretty.Sdump(msg))
+		}
+	case *NewBlockHashes:
+		hashes := *msg
+		for _, hash := range hashes {
+			if hash.Hash == oldBlockAnnounce.Block.Hash() {
+				return fmt.Errorf("unexpected: block announced: %s", pretty.Sdump(msg))
+			}
+		}
+	case *Error:
+		errMsg := *msg
+		// check to make sure error is timeout (propagation didn't come through == test successful)
+		if !strings.Contains(errMsg.String(), "timeout") {
+			return fmt.Errorf("unexpected error: %v", pretty.Sdump(msg))
+		}
+	default:
+		return fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
+	}
+	return nil
+}
+
+func (s *Suite) maliciousHandshakes(t *utesting.T, isEth66 bool) error {
+	var (
+		conn *Conn
+		err  error
+	)
+	if isEth66 {
+		conn, err = s.dial66()
+		if err != nil {
+			return fmt.Errorf("dial failed: %v", err)
+		}
+	} else {
+		conn, err = s.dial()
+		if err != nil {
+			return fmt.Errorf("dial failed: %v", err)
+		}
+	}
+	defer conn.Close()
+	// write hello to client
+	pub0 := crypto.FromECDSAPub(&conn.ourKey.PublicKey)[1:]
+	handshakes := []*Hello{
+		{
+			Version: 5,
+			Caps: []p2p.Cap{
+				{Name: largeString(2), Version: 64},
+			},
+			ID: pub0,
+		},
+		{
+			Version: 5,
+			Caps: []p2p.Cap{
+				{Name: "eth", Version: 64},
+				{Name: "eth", Version: 65},
+			},
+			ID: append(pub0, byte(0)),
+		},
+		{
+			Version: 5,
+			Caps: []p2p.Cap{
+				{Name: "eth", Version: 64},
+				{Name: "eth", Version: 65},
+			},
+			ID: append(pub0, pub0...),
+		},
+		{
+			Version: 5,
+			Caps: []p2p.Cap{
+				{Name: "eth", Version: 64},
+				{Name: "eth", Version: 65},
+			},
+			ID: largeBuffer(2),
+		},
+		{
+			Version: 5,
+			Caps: []p2p.Cap{
+				{Name: largeString(2), Version: 64},
+			},
+			ID: largeBuffer(2),
+		},
+	}
+	for i, handshake := range handshakes {
+		t.Logf("Testing malicious handshake %v\n", i)
+		if err := conn.Write(handshake); err != nil {
+			return fmt.Errorf("could not write to connection: %v", err)
+		}
+		// check that the peer disconnected
+		for i := 0; i < 2; i++ {
+			switch msg := conn.readAndServe(s.chain, 20*time.Second).(type) {
+			case *Disconnect:
+			case *Error:
+			case *Hello:
+				// Discard one hello as Hello's are sent concurrently
+				continue
+			default:
+				return fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
+			}
+		}
+		// dial for the next round
+		if isEth66 {
+			conn, err = s.dial66()
+			if err != nil {
+				return fmt.Errorf("dial failed: %v", err)
+			}
+		} else {
+			conn, err = s.dial()
+			if err != nil {
+				return fmt.Errorf("dial failed: %v", err)
+			}
+		}
+	}
+	return nil
+}
+
+func (s *Suite) maliciousStatus(conn *Conn) error {
+	if err := conn.handshake(); err != nil {
+		return fmt.Errorf("handshake failed: %v", err)
+	}
+	status := &Status{
+		ProtocolVersion: uint32(conn.negotiatedProtoVersion),
+		NetworkID:       s.chain.chainConfig.ChainID.Uint64(),
+		TD:              largeNumber(2),
+		Head:            s.chain.blocks[s.chain.Len()-1].Hash(),
+		Genesis:         s.chain.blocks[0].Hash(),
+		ForkID:          s.chain.ForkID(),
+	}
+	// get status
+	msg, err := conn.statusExchange(s.chain, status)
+	if err != nil {
+		return fmt.Errorf("status exchange failed: %v", err)
+	}
+	switch msg := msg.(type) {
+	case *Status:
+	default:
+		return fmt.Errorf("expected status, got: %#v ", msg)
+	}
+	// wait for disconnect
+	switch msg := conn.readAndServe(s.chain, timeout).(type) {
+	case *Disconnect:
+		return nil
+	case *Error:
+		return nil
+	default:
+		return fmt.Errorf("expected disconnect, got: %s", pretty.Sdump(msg))
+	}
+}
+
+func (s *Suite) hashAnnounce(isEth66 bool) error {
+	// create connections
+	sendConn, recvConn, err := s.createSendAndRecvConns(isEth66)
+	if err != nil {
+		return fmt.Errorf("failed to create connections: %v", err)
+	}
+	defer sendConn.Close()
+	defer recvConn.Close()
+	if err := sendConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	if err := recvConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	// create NewBlockHashes announcement
+	type anno struct {
+		Hash   common.Hash // Hash of one particular block being announced
+		Number uint64      // Number of one particular block being announced
+	}
+	nextBlock := s.fullChain.blocks[s.chain.Len()]
+	announcement := anno{Hash: nextBlock.Hash(), Number: nextBlock.Number().Uint64()}
+	newBlockHash := &NewBlockHashes{announcement}
+	if err := sendConn.Write(newBlockHash); err != nil {
+		return fmt.Errorf("failed to write to connection: %v", err)
+	}
+	// Announcement sent, now wait for a header request
+	var (
+		id             uint64
+		msg            Message
+		blockHeaderReq GetBlockHeaders
+	)
+	if isEth66 {
+		id, msg = sendConn.Read66()
+		switch msg := msg.(type) {
+		case GetBlockHeaders:
+			blockHeaderReq = msg
+		default:
+			return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
+		}
+		if blockHeaderReq.Amount != 1 {
+			return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
+		}
+		if blockHeaderReq.Origin.Hash != announcement.Hash {
+			return fmt.Errorf("unexpected block header requested. Announced:\n %v\n Remote request:\n%v",
+				pretty.Sdump(announcement),
+				pretty.Sdump(blockHeaderReq))
+		}
+		if err := sendConn.Write66(&eth.BlockHeadersPacket66{
+			RequestId: id,
+			BlockHeadersPacket: eth.BlockHeadersPacket{
+				nextBlock.Header(),
+			},
+		}, BlockHeaders{}.Code()); err != nil {
+			return fmt.Errorf("failed to write to connection: %v", err)
+		}
+	} else {
+		msg = sendConn.Read()
+		switch msg := msg.(type) {
+		case *GetBlockHeaders:
+			blockHeaderReq = *msg
+		default:
+			return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
+		}
+		if blockHeaderReq.Amount != 1 {
+			return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
+		}
+		if blockHeaderReq.Origin.Hash != announcement.Hash {
+			return fmt.Errorf("unexpected block header requested. Announced:\n %v\n Remote request:\n%v",
+				pretty.Sdump(announcement),
+				pretty.Sdump(blockHeaderReq))
+		}
+		if err := sendConn.Write(&BlockHeaders{nextBlock.Header()}); err != nil {
+			return fmt.Errorf("failed to write to connection: %v", err)
+		}
+	}
+	// wait for block announcement
+	msg = recvConn.readAndServe(s.chain, timeout)
+	switch msg := msg.(type) {
+	case *NewBlockHashes:
+		hashes := *msg
+		if len(hashes) != 1 {
+			return fmt.Errorf("unexpected new block hash announcement: wanted 1 announcement, got %d", len(hashes))
+		}
+		if nextBlock.Hash() != hashes[0].Hash {
+			return fmt.Errorf("unexpected block hash announcement, wanted %v, got %v", nextBlock.Hash(),
+				hashes[0].Hash)
+		}
+	case *NewBlock:
+		// node should only propagate NewBlock without having requested the body if the body is empty
+		nextBlockBody := nextBlock.Body()
+		if len(nextBlockBody.Transactions) != 0 || len(nextBlockBody.Uncles) != 0 {
+			return fmt.Errorf("unexpected non-empty new block propagated: %s", pretty.Sdump(msg))
+		}
+		if msg.Block.Hash() != nextBlock.Hash() {
+			return fmt.Errorf("mismatched hash of propagated new block: wanted %v, got %v",
+				nextBlock.Hash(), msg.Block.Hash())
+		}
+		// check to make sure header matches header that was sent to the node
+		if !reflect.DeepEqual(nextBlock.Header(), msg.Block.Header()) {
+			return fmt.Errorf("incorrect header received: wanted %v, got %v", nextBlock.Header(), msg.Block.Header())
+		}
+	default:
+		return fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
+	}
+	// confirm node imported block
+	if err := s.waitForBlockImport(recvConn, nextBlock, isEth66); err != nil {
+		return fmt.Errorf("error waiting for node to import new block: %v", err)
+	}
+	// update the chain
+	s.chain.blocks = append(s.chain.blocks, nextBlock)
+	return nil
+}
diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go
index abc6bcddce080b128121a0282343a9792b75488c..bbc955cd7b6070045f4a71bdafa0703a64e23611 100644
--- a/cmd/devp2p/internal/ethtest/suite.go
+++ b/cmd/devp2p/internal/ethtest/suite.go
@@ -17,33 +17,16 @@
 package ethtest
 
 import (
-	"fmt"
-	"net"
-	"strings"
 	"time"
 
-	"github.com/davecgh/go-spew/spew"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/eth/protocols/eth"
 	"github.com/ethereum/go-ethereum/internal/utesting"
-	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/p2p/enode"
-	"github.com/ethereum/go-ethereum/p2p/rlpx"
-	"github.com/stretchr/testify/assert"
 )
 
-var pretty = spew.ConfigState{
-	Indent:                  "  ",
-	DisableCapacities:       true,
-	DisablePointerAddresses: true,
-	SortKeys:                true,
-}
-
-var timeout = 20 * time.Second
-
-// Suite represents a structure used to test the eth
-// protocol of a node(s).
+// Suite represents a structure used to test a node's conformance
+// to the eth protocol.
 type Suite struct {
 	Dest *enode.Node
 
@@ -70,35 +53,37 @@ func (s *Suite) AllEthTests() []utesting.Test {
 	return []utesting.Test{
 		// status
 		{Name: "TestStatus", Fn: s.TestStatus},
-		{Name: "TestStatus_66", Fn: s.TestStatus_66},
+		{Name: "TestStatus66", Fn: s.TestStatus66},
 		// get block headers
 		{Name: "TestGetBlockHeaders", Fn: s.TestGetBlockHeaders},
-		{Name: "TestGetBlockHeaders_66", Fn: s.TestGetBlockHeaders_66},
-		{Name: "TestSimultaneousRequests_66", Fn: s.TestSimultaneousRequests_66},
-		{Name: "TestSameRequestID_66", Fn: s.TestSameRequestID_66},
-		{Name: "TestZeroRequestID_66", Fn: s.TestZeroRequestID_66},
+		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66},
+		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66},
+		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66},
+		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66},
 		// get block bodies
 		{Name: "TestGetBlockBodies", Fn: s.TestGetBlockBodies},
-		{Name: "TestGetBlockBodies_66", Fn: s.TestGetBlockBodies_66},
+		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66},
 		// broadcast
 		{Name: "TestBroadcast", Fn: s.TestBroadcast},
-		{Name: "TestBroadcast_66", Fn: s.TestBroadcast_66},
+		{Name: "TestBroadcast66", Fn: s.TestBroadcast66},
 		{Name: "TestLargeAnnounce", Fn: s.TestLargeAnnounce},
-		{Name: "TestLargeAnnounce_66", Fn: s.TestLargeAnnounce_66},
+		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66},
 		{Name: "TestOldAnnounce", Fn: s.TestOldAnnounce},
-		{Name: "TestOldAnnounce_66", Fn: s.TestOldAnnounce_66},
+		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66},
+		{Name: "TestBlockHashAnnounce", Fn: s.TestBlockHashAnnounce},
+		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66},
 		// malicious handshakes + status
 		{Name: "TestMaliciousHandshake", Fn: s.TestMaliciousHandshake},
 		{Name: "TestMaliciousStatus", Fn: s.TestMaliciousStatus},
-		{Name: "TestMaliciousHandshake_66", Fn: s.TestMaliciousHandshake_66},
-		{Name: "TestMaliciousStatus_66", Fn: s.TestMaliciousStatus_66},
+		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66},
+		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66},
 		// test transactions
 		{Name: "TestTransaction", Fn: s.TestTransaction},
-		{Name: "TestTransaction_66", Fn: s.TestTransaction_66},
+		{Name: "TestTransaction66", Fn: s.TestTransaction66},
 		{Name: "TestMaliciousTx", Fn: s.TestMaliciousTx},
-		{Name: "TestMaliciousTx_66", Fn: s.TestMaliciousTx_66},
-		{Name: "TestLargeTxRequest_66", Fn: s.TestLargeTxRequest_66},
-		{Name: "TestNewPooledTxs_66", Fn: s.TestNewPooledTxs_66},
+		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66},
+		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66},
+		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66},
 	}
 }
 
@@ -109,6 +94,8 @@ func (s *Suite) EthTests() []utesting.Test {
 		{Name: "TestGetBlockBodies", Fn: s.TestGetBlockBodies},
 		{Name: "TestBroadcast", Fn: s.TestBroadcast},
 		{Name: "TestLargeAnnounce", Fn: s.TestLargeAnnounce},
+		{Name: "TestOldAnnounce", Fn: s.TestOldAnnounce},
+		{Name: "TestBlockHashAnnounce", Fn: s.TestBlockHashAnnounce},
 		{Name: "TestMaliciousHandshake", Fn: s.TestMaliciousHandshake},
 		{Name: "TestMaliciousStatus", Fn: s.TestMaliciousStatus},
 		{Name: "TestTransaction", Fn: s.TestTransaction},
@@ -119,90 +106,102 @@ func (s *Suite) EthTests() []utesting.Test {
 func (s *Suite) Eth66Tests() []utesting.Test {
 	return []utesting.Test{
 		// only proceed with eth66 test suite if node supports eth 66 protocol
-		{Name: "TestStatus_66", Fn: s.TestStatus_66},
-		{Name: "TestGetBlockHeaders_66", Fn: s.TestGetBlockHeaders_66},
-		{Name: "TestSimultaneousRequests_66", Fn: s.TestSimultaneousRequests_66},
-		{Name: "TestSameRequestID_66", Fn: s.TestSameRequestID_66},
-		{Name: "TestZeroRequestID_66", Fn: s.TestZeroRequestID_66},
-		{Name: "TestGetBlockBodies_66", Fn: s.TestGetBlockBodies_66},
-		{Name: "TestBroadcast_66", Fn: s.TestBroadcast_66},
-		{Name: "TestLargeAnnounce_66", Fn: s.TestLargeAnnounce_66},
-		{Name: "TestMaliciousHandshake_66", Fn: s.TestMaliciousHandshake_66},
-		{Name: "TestMaliciousStatus_66", Fn: s.TestMaliciousStatus_66},
-		{Name: "TestTransaction_66", Fn: s.TestTransaction_66},
-		{Name: "TestMaliciousTx_66", Fn: s.TestMaliciousTx_66},
-		{Name: "TestLargeTxRequest_66", Fn: s.TestLargeTxRequest_66},
-		{Name: "TestNewPooledTxs_66", Fn: s.TestNewPooledTxs_66},
+		{Name: "TestStatus66", Fn: s.TestStatus66},
+		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66},
+		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66},
+		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66},
+		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66},
+		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66},
+		{Name: "TestBroadcast66", Fn: s.TestBroadcast66},
+		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66},
+		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66},
+		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66},
+		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66},
+		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66},
+		{Name: "TestTransaction66", Fn: s.TestTransaction66},
+		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66},
+		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66},
+		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66},
 	}
 }
 
+var (
+	eth66 = true  // indicates whether suite should negotiate eth66 connection
+	eth65 = false // indicates whether suite should negotiate eth65 connection or below.
+)
+
 // TestStatus attempts to connect to the given node and exchange
-// a status message with it, and then check to make sure
-// the chain head is correct.
+// a status message with it.
 func (s *Suite) TestStatus(t *utesting.T) {
 	conn, err := s.dial()
 	if err != nil {
-		t.Fatalf("could not dial: %v", err)
+		t.Fatalf("dial failed: %v", err)
 	}
 	defer conn.Close()
-	// get protoHandshake
-	conn.handshake(t)
-	// get status
-	switch msg := conn.statusExchange(t, s.chain, nil).(type) {
-	case *Status:
-		t.Logf("got status message: %s", pretty.Sdump(msg))
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
 	}
 }
 
-// TestMaliciousStatus sends a status package with a large total difficulty.
-func (s *Suite) TestMaliciousStatus(t *utesting.T) {
-	conn, err := s.dial()
+// TestStatus66 attempts to connect to the given node and exchange
+// a status message with it on the eth66 protocol.
+func (s *Suite) TestStatus66(t *utesting.T) {
+	conn, err := s.dial66()
 	if err != nil {
-		t.Fatalf("could not dial: %v", err)
+		t.Fatalf("dial failed: %v", err)
 	}
 	defer conn.Close()
-	// get protoHandshake
-	conn.handshake(t)
-	status := &Status{
-		ProtocolVersion: uint32(conn.negotiatedProtoVersion),
-		NetworkID:       s.chain.chainConfig.ChainID.Uint64(),
-		TD:              largeNumber(2),
-		Head:            s.chain.blocks[s.chain.Len()-1].Hash(),
-		Genesis:         s.chain.blocks[0].Hash(),
-		ForkID:          s.chain.ForkID(),
-	}
-	// get status
-	switch msg := conn.statusExchange(t, s.chain, status).(type) {
-	case *Status:
-		t.Logf("%+v\n", msg)
-	default:
-		t.Fatalf("expected status, got: %#v ", msg)
-	}
-	// wait for disconnect
-	switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-	case *Disconnect:
-	case *Error:
-		return
-	default:
-		t.Fatalf("expected disconnect, got: %s", pretty.Sdump(msg))
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
 	}
 }
 
 // TestGetBlockHeaders tests whether the given node can respond to
-// a `GetBlockHeaders` request and that the response is accurate.
+// a `GetBlockHeaders` request accurately.
 func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
 	conn, err := s.dial()
 	if err != nil {
-		t.Fatalf("could not dial: %v", err)
+		t.Fatalf("dial failed: %v", err)
 	}
 	defer conn.Close()
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("handshake(s) failed: %v", err)
+	}
+	// write request
+	req := &GetBlockHeaders{
+		Origin: eth.HashOrNumber{
+			Hash: s.chain.blocks[1].Hash(),
+		},
+		Amount:  2,
+		Skip:    1,
+		Reverse: false,
+	}
+	headers, err := conn.headersRequest(req, s.chain, eth65, 0)
+	if err != nil {
+		t.Fatalf("GetBlockHeaders request failed: %v", err)
+	}
+	// check for correct headers
+	expected, err := s.chain.GetHeaders(*req)
+	if err != nil {
+		t.Fatalf("failed to get headers for given request: %v", err)
+	}
+	if !headersMatch(expected, headers) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
+	}
+}
 
-	conn.handshake(t)
-	conn.statusExchange(t, s.chain, nil)
-
-	// get block headers
+// TestGetBlockHeaders66 tests whether the given node can respond to
+// an eth66 `GetBlockHeaders` request and that the response is accurate.
+func (s *Suite) TestGetBlockHeaders66(t *utesting.T) {
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err = conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	// write request
 	req := &GetBlockHeaders{
 		Origin: eth.HashOrNumber{
 			Hash: s.chain.blocks[1].Hash(),
@@ -211,21 +210,185 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
 		Skip:    1,
 		Reverse: false,
 	}
+	headers, err := conn.headersRequest(req, s.chain, eth66, 33)
+	if err != nil {
+		t.Fatalf("could not get block headers: %v", err)
+	}
+	// check for correct headers
+	expected, err := s.chain.GetHeaders(*req)
+	if err != nil {
+		t.Fatalf("failed to get headers for given request: %v", err)
+	}
+	if !headersMatch(expected, headers) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
+	}
+}
 
-	if err := conn.Write(req); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
+// TestSimultaneousRequests66 sends two simultaneous `GetBlockHeader` requests from
+// the same connection with different request IDs and checks to make sure the node
+// responds with the correct headers per request.
+func (s *Suite) TestSimultaneousRequests66(t *utesting.T) {
+	// create a connection
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	// create two requests
+	req1 := &eth.GetBlockHeadersPacket66{
+		RequestId: uint64(111),
+		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
+			Origin: eth.HashOrNumber{
+				Hash: s.chain.blocks[1].Hash(),
+			},
+			Amount:  2,
+			Skip:    1,
+			Reverse: false,
+		},
+	}
+	req2 := &eth.GetBlockHeadersPacket66{
+		RequestId: uint64(222),
+		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
+			Origin: eth.HashOrNumber{
+				Hash: s.chain.blocks[1].Hash(),
+			},
+			Amount:  4,
+			Skip:    1,
+			Reverse: false,
+		},
+	}
+	// write the first request
+	if err := conn.Write66(req1, GetBlockHeaders{}.Code()); err != nil {
+		t.Fatalf("failed to write to connection: %v", err)
+	}
+	// write the second request
+	if err := conn.Write66(req2, GetBlockHeaders{}.Code()); err != nil {
+		t.Fatalf("failed to write to connection: %v", err)
+	}
+	// wait for responses
+	msg := conn.waitForResponse(s.chain, timeout, req1.RequestId)
+	headers1, ok := msg.(BlockHeaders)
+	if !ok {
+		t.Fatalf("unexpected %s", pretty.Sdump(msg))
+	}
+	msg = conn.waitForResponse(s.chain, timeout, req2.RequestId)
+	headers2, ok := msg.(BlockHeaders)
+	if !ok {
+		t.Fatalf("unexpected %s", pretty.Sdump(msg))
+	}
+	// check received headers for accuracy
+	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*req1.GetBlockHeadersPacket))
+	if err != nil {
+		t.Fatalf("failed to get expected headers for request 1: %v", err)
+	}
+	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*req2.GetBlockHeadersPacket))
+	if err != nil {
+		t.Fatalf("failed to get expected headers for request 2: %v", err)
+	}
+	if !headersMatch(expected1, headers1) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
+	}
+	if !headersMatch(expected2, headers2) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
+	}
+}
+
+// TestSameRequestID66 sends two requests with the same request ID to a
+// single node.
+func (s *Suite) TestSameRequestID66(t *utesting.T) {
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	// create requests
+	reqID := uint64(1234)
+	request1 := &eth.GetBlockHeadersPacket66{
+		RequestId: reqID,
+		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
+			Origin: eth.HashOrNumber{
+				Number: 1,
+			},
+			Amount: 2,
+		},
+	}
+	request2 := &eth.GetBlockHeadersPacket66{
+		RequestId: reqID,
+		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
+			Origin: eth.HashOrNumber{
+				Number: 33,
+			},
+			Amount: 2,
+		},
+	}
+	// write the requests
+	if err = conn.Write66(request1, GetBlockHeaders{}.Code()); err != nil {
+		t.Fatalf("failed to write to connection: %v", err)
+	}
+	if err = conn.Write66(request2, GetBlockHeaders{}.Code()); err != nil {
+		t.Fatalf("failed to write to connection: %v", err)
+	}
+	// wait for responses
+	msg := conn.waitForResponse(s.chain, timeout, reqID)
+	headers1, ok := msg.(BlockHeaders)
+	if !ok {
+		t.Fatalf("unexpected %s", pretty.Sdump(msg))
+	}
+	msg = conn.waitForResponse(s.chain, timeout, reqID)
+	headers2, ok := msg.(BlockHeaders)
+	if !ok {
+		t.Fatalf("unexpected %s", pretty.Sdump(msg))
+	}
+	// check if headers match
+	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*request1.GetBlockHeadersPacket))
+	if err != nil {
+		t.Fatalf("failed to get expected block headers: %v", err)
 	}
+	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*request2.GetBlockHeadersPacket))
+	if err != nil {
+		t.Fatalf("failed to get expected block headers: %v", err)
+	}
+	if !headersMatch(expected1, headers1) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
+	}
+	if !headersMatch(expected2, headers2) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
+	}
+}
 
-	switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-	case *BlockHeaders:
-		headers := *msg
-		for _, header := range headers {
-			num := header.Number.Uint64()
-			t.Logf("received header (%d): %s", num, pretty.Sdump(header.Hash()))
-			assert.Equal(t, s.chain.blocks[int(num)].Header(), header)
-		}
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
+// TestZeroRequestID_66 checks that a message with a request ID of zero is still handled
+// by the node.
+func (s *Suite) TestZeroRequestID66(t *utesting.T) {
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	req := &GetBlockHeaders{
+		Origin: eth.HashOrNumber{
+			Number: 0,
+		},
+		Amount: 2,
+	}
+	headers, err := conn.headersRequest(req, s.chain, eth66, 0)
+	if err != nil {
+		t.Fatalf("failed to get block headers: %v", err)
+	}
+	expected, err := s.chain.GetHeaders(*req)
+	if err != nil {
+		t.Fatalf("failed to get expected block headers: %v", err)
+	}
+	if !headersMatch(expected, headers) {
+		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
 	}
 }
 
@@ -234,12 +397,12 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
 func (s *Suite) TestGetBlockBodies(t *utesting.T) {
 	conn, err := s.dial()
 	if err != nil {
-		t.Fatalf("could not dial: %v", err)
+		t.Fatalf("dial failed: %v", err)
 	}
 	defer conn.Close()
-
-	conn.handshake(t)
-	conn.statusExchange(t, s.chain, nil)
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
 	// create block bodies request
 	req := &GetBlockBodies{
 		s.chain.blocks[54].Hash(),
@@ -248,126 +411,125 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) {
 	if err := conn.Write(req); err != nil {
 		t.Fatalf("could not write to connection: %v", err)
 	}
-
-	switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
+	// wait for response
+	switch msg := conn.readAndServe(s.chain, timeout).(type) {
 	case *BlockBodies:
 		t.Logf("received %d block bodies", len(*msg))
+		if len(*msg) != len(*req) {
+			t.Fatalf("wrong bodies in response: expected %d bodies, "+
+				"got %d", len(*req), len(*msg))
+		}
 	default:
 		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
 	}
 }
 
+// TestGetBlockBodies66 tests whether the given node can respond to
+// a `GetBlockBodies` request and that the response is accurate over
+// the eth66 protocol.
+func (s *Suite) TestGetBlockBodies66(t *utesting.T) {
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err := conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	// create block bodies request
+	req := &eth.GetBlockBodiesPacket66{
+		RequestId: uint64(55),
+		GetBlockBodiesPacket: eth.GetBlockBodiesPacket{
+			s.chain.blocks[54].Hash(),
+			s.chain.blocks[75].Hash(),
+		},
+	}
+	if err := conn.Write66(req, GetBlockBodies{}.Code()); err != nil {
+		t.Fatalf("could not write to connection: %v", err)
+	}
+	// wait for block bodies response
+	msg := conn.waitForResponse(s.chain, timeout, req.RequestId)
+	blockBodies, ok := msg.(BlockBodies)
+	if !ok {
+		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
+	}
+	t.Logf("received %d block bodies", len(blockBodies))
+	if len(blockBodies) != len(req.GetBlockBodiesPacket) {
+		t.Fatalf("wrong bodies in response: expected %d bodies, "+
+			"got %d", len(req.GetBlockBodiesPacket), len(blockBodies))
+	}
+}
+
 // TestBroadcast tests whether a block announcement is correctly
 // propagated to the given node's peer(s).
 func (s *Suite) TestBroadcast(t *utesting.T) {
-	s.sendNextBlock(t)
+	if err := s.sendNextBlock(eth65); err != nil {
+		t.Fatalf("block broadcast failed: %v", err)
+	}
 }
 
-func (s *Suite) sendNextBlock(t *utesting.T) {
-	sendConn, receiveConn := s.setupConnection(t), s.setupConnection(t)
-	defer sendConn.Close()
-	defer receiveConn.Close()
-
-	// create new block announcement
-	nextBlock := len(s.chain.blocks)
-	blockAnnouncement := &NewBlock{
-		Block: s.fullChain.blocks[nextBlock],
-		TD:    s.fullChain.TD(nextBlock + 1),
-	}
-	// send announcement and wait for node to request the header
-	s.testAnnounce(t, sendConn, receiveConn, blockAnnouncement)
-	// wait for client to update its chain
-	if err := receiveConn.waitForBlock(s.fullChain.blocks[nextBlock]); err != nil {
-		t.Fatal(err)
+// TestBroadcast66 tests whether a block announcement is correctly
+// propagated to the given node's peer(s) on the eth66 protocol.
+func (s *Suite) TestBroadcast66(t *utesting.T) {
+	if err := s.sendNextBlock(eth66); err != nil {
+		t.Fatalf("block broadcast failed: %v", err)
 	}
-	// update test suite chain
-	s.chain.blocks = append(s.chain.blocks, s.fullChain.blocks[nextBlock])
 }
 
-// TestMaliciousHandshake tries to send malicious data during the handshake.
-func (s *Suite) TestMaliciousHandshake(t *utesting.T) {
-	conn, err := s.dial()
-	if err != nil {
-		t.Fatalf("could not dial: %v", err)
-	}
-	defer conn.Close()
-	// write hello to client
-	pub0 := crypto.FromECDSAPub(&conn.ourKey.PublicKey)[1:]
-	handshakes := []*Hello{
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: largeString(2), Version: 64},
-			},
-			ID: pub0,
-		},
-		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-			},
-			ID: append(pub0, byte(0)),
-		},
+// TestLargeAnnounce tests the announcement mechanism with a large block.
+func (s *Suite) TestLargeAnnounce(t *utesting.T) {
+	nextBlock := len(s.chain.blocks)
+	blocks := []*NewBlock{
 		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-			},
-			ID: append(pub0, pub0...),
+			Block: largeBlock(),
+			TD:    s.fullChain.TotalDifficultyAt(nextBlock),
 		},
 		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: "eth", Version: 64},
-				{Name: "eth", Version: 65},
-			},
-			ID: largeBuffer(2),
+			Block: s.fullChain.blocks[nextBlock],
+			TD:    largeNumber(2),
 		},
 		{
-			Version: 5,
-			Caps: []p2p.Cap{
-				{Name: largeString(2), Version: 64},
-			},
-			ID: largeBuffer(2),
+			Block: largeBlock(),
+			TD:    largeNumber(2),
 		},
 	}
-	for i, handshake := range handshakes {
-		t.Logf("Testing malicious handshake %v\n", i)
-		// Init the handshake
-		if err := conn.Write(handshake); err != nil {
-			t.Fatalf("could not write to connection: %v", err)
+
+	for i, blockAnnouncement := range blocks {
+		t.Logf("Testing malicious announcement: %v\n", i)
+		conn, err := s.dial()
+		if err != nil {
+			t.Fatalf("dial failed: %v", err)
 		}
-		// check that the peer disconnected
-		timeout := 20 * time.Second
-		// Discard one hello
-		for i := 0; i < 2; i++ {
-			switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-			case *Disconnect:
-			case *Error:
-			case *Hello:
-				// Hello's are send concurrently, so ignore them
-				continue
-			default:
-				t.Fatalf("unexpected: %s", pretty.Sdump(msg))
-			}
+		if err = conn.peer(s.chain, nil); err != nil {
+			t.Fatalf("peering failed: %v", err)
 		}
-		// Dial for the next round
-		conn, err = s.dial()
-		if err != nil {
-			t.Fatalf("could not dial: %v", err)
+		if err = conn.Write(blockAnnouncement); err != nil {
+			t.Fatalf("could not write to connection: %v", err)
 		}
+		// Invalid announcement, check that peer disconnected
+		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) {
+		case *Disconnect:
+		case *Error:
+			break
+		default:
+			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg))
+		}
+		conn.Close()
+	}
+	// Test the last block as a valid block
+	if err := s.sendNextBlock(eth65); err != nil {
+		t.Fatalf("failed to broadcast next block: %v", err)
 	}
 }
 
-// TestLargeAnnounce tests the announcement mechanism with a large block.
-func (s *Suite) TestLargeAnnounce(t *utesting.T) {
+// TestLargeAnnounce66 tests the announcement mechanism with a large
+// block over the eth66 protocol.
+func (s *Suite) TestLargeAnnounce66(t *utesting.T) {
 	nextBlock := len(s.chain.blocks)
 	blocks := []*NewBlock{
 		{
 			Block: largeBlock(),
-			TD:    s.fullChain.TD(nextBlock + 1),
+			TD:    s.fullChain.TotalDifficultyAt(nextBlock),
 		},
 		{
 			Block: s.fullChain.blocks[nextBlock],
@@ -377,174 +539,245 @@ func (s *Suite) TestLargeAnnounce(t *utesting.T) {
 			Block: largeBlock(),
 			TD:    largeNumber(2),
 		},
-		{
-			Block: s.fullChain.blocks[nextBlock],
-			TD:    s.fullChain.TD(nextBlock + 1),
-		},
 	}
 
 	for i, blockAnnouncement := range blocks[0:3] {
 		t.Logf("Testing malicious announcement: %v\n", i)
-		sendConn := s.setupConnection(t)
-		if err := sendConn.Write(blockAnnouncement); err != nil {
+		conn, err := s.dial66()
+		if err != nil {
+			t.Fatalf("dial failed: %v", err)
+		}
+		if err := conn.peer(s.chain, nil); err != nil {
+			t.Fatalf("peering failed: %v", err)
+		}
+		if err := conn.Write(blockAnnouncement); err != nil {
 			t.Fatalf("could not write to connection: %v", err)
 		}
 		// Invalid announcement, check that peer disconnected
-		switch msg := sendConn.ReadAndServe(s.chain, time.Second*8).(type) {
+		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) {
 		case *Disconnect:
 		case *Error:
 			break
 		default:
 			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg))
 		}
-		sendConn.Close()
+		conn.Close()
 	}
 	// Test the last block as a valid block
-	s.sendNextBlock(t)
+	if err := s.sendNextBlock(eth66); err != nil {
+		t.Fatalf("failed to broadcast next block: %v", err)
+	}
 }
 
+// TestOldAnnounce tests the announcement mechanism with an old block.
 func (s *Suite) TestOldAnnounce(t *utesting.T) {
-	sendConn, recvConn := s.setupConnection(t), s.setupConnection(t)
-	defer sendConn.Close()
-	defer recvConn.Close()
-
-	s.oldAnnounce(t, sendConn, recvConn)
+	if err := s.oldAnnounce(eth65); err != nil {
+		t.Fatal(err)
+	}
 }
 
-func (s *Suite) oldAnnounce(t *utesting.T, sendConn, receiveConn *Conn) {
-	oldBlockAnnounce := &NewBlock{
-		Block: s.chain.blocks[len(s.chain.blocks)/2],
-		TD:    s.chain.blocks[len(s.chain.blocks)/2].Difficulty(),
+// TestOldAnnounce66 tests the announcement mechanism with an old block,
+// over the eth66 protocol.
+func (s *Suite) TestOldAnnounce66(t *utesting.T) {
+	if err := s.oldAnnounce(eth66); err != nil {
+		t.Fatal(err)
 	}
+}
 
-	if err := sendConn.Write(oldBlockAnnounce); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
+// TestBlockHashAnnounce sends a new block hash announcement and expects
+// the node to perform a `GetBlockHeaders` request.
+func (s *Suite) TestBlockHashAnnounce(t *utesting.T) {
+	if err := s.hashAnnounce(eth65); err != nil {
+		t.Fatalf("block hash announcement failed: %v", err)
 	}
+}
 
-	switch msg := receiveConn.ReadAndServe(s.chain, time.Second*8).(type) {
-	case *NewBlock:
-		block := *msg
-		if block.Block.Hash() == oldBlockAnnounce.Block.Hash() {
-			t.Fatalf("unexpected: block propagated: %s", pretty.Sdump(msg))
-		}
-	case *NewBlockHashes:
-		hashes := *msg
-		for _, hash := range hashes {
-			if hash.Hash == oldBlockAnnounce.Block.Hash() {
-				t.Fatalf("unexpected: block announced: %s", pretty.Sdump(msg))
-			}
-		}
-	case *Error:
-		errMsg := *msg
-		// check to make sure error is timeout (propagation didn't come through == test successful)
-		if !strings.Contains(errMsg.String(), "timeout") {
-			t.Fatalf("unexpected error: %v", pretty.Sdump(msg))
-		}
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
+// TestBlockHashAnnounce66 sends a new block hash announcement and expects
+// the node to perform a `GetBlockHeaders` request.
+func (s *Suite) TestBlockHashAnnounce66(t *utesting.T) {
+	if err := s.hashAnnounce(eth66); err != nil {
+		t.Fatalf("block hash announcement failed: %v", err)
 	}
 }
 
-func (s *Suite) testAnnounce(t *utesting.T, sendConn, receiveConn *Conn, blockAnnouncement *NewBlock) {
-	// Announce the block.
-	if err := sendConn.Write(blockAnnouncement); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-	s.waitAnnounce(t, receiveConn, blockAnnouncement)
-}
-
-func (s *Suite) waitAnnounce(t *utesting.T, conn *Conn, blockAnnouncement *NewBlock) {
-	switch msg := conn.ReadAndServe(s.chain, timeout).(type) {
-	case *NewBlock:
-		t.Logf("received NewBlock message: %s", pretty.Sdump(msg.Block))
-		assert.Equal(t,
-			blockAnnouncement.Block.Header(), msg.Block.Header(),
-			"wrong block header in announcement",
-		)
-		assert.Equal(t,
-			blockAnnouncement.TD, msg.TD,
-			"wrong TD in announcement",
-		)
-	case *NewBlockHashes:
-		message := *msg
-		t.Logf("received NewBlockHashes message: %s", pretty.Sdump(message))
-		assert.Equal(t, blockAnnouncement.Block.Hash(), message[0].Hash,
-			"wrong block hash in announcement",
-		)
-	default:
-		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
+// TestMaliciousHandshake tries to send malicious data during the handshake.
+func (s *Suite) TestMaliciousHandshake(t *utesting.T) {
+	if err := s.maliciousHandshakes(t, eth65); err != nil {
+		t.Fatal(err)
 	}
 }
 
-func (s *Suite) setupConnection(t *utesting.T) *Conn {
-	// create conn
-	sendConn, err := s.dial()
-	if err != nil {
-		t.Fatalf("could not dial: %v", err)
+// TestMaliciousHandshake66 tries to send malicious data during the handshake.
+func (s *Suite) TestMaliciousHandshake66(t *utesting.T) {
+	if err := s.maliciousHandshakes(t, eth66); err != nil {
+		t.Fatal(err)
 	}
-	sendConn.handshake(t)
-	sendConn.statusExchange(t, s.chain, nil)
-	return sendConn
 }
 
-// dial attempts to dial the given node and perform a handshake,
-// returning the created Conn if successful.
-func (s *Suite) dial() (*Conn, error) {
-	var conn Conn
-	// dial
-	fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", s.Dest.IP(), s.Dest.TCP()))
+// TestMaliciousStatus sends a status package with a large total difficulty.
+func (s *Suite) TestMaliciousStatus(t *utesting.T) {
+	conn, err := s.dial()
 	if err != nil {
-		return nil, err
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+
+	if err := s.maliciousStatus(conn); err != nil {
+		t.Fatal(err)
 	}
-	conn.Conn = rlpx.NewConn(fd, s.Dest.Pubkey())
-	// do encHandshake
-	conn.ourKey, _ = crypto.GenerateKey()
-	_, err = conn.Handshake(conn.ourKey)
+}
+
+// TestMaliciousStatus66 sends a status package with a large total
+// difficulty over the eth66 protocol.
+func (s *Suite) TestMaliciousStatus66(t *utesting.T) {
+	conn, err := s.dial66()
 	if err != nil {
-		return nil, err
+		t.Fatalf("dial failed: %v", err)
 	}
-	// set default p2p capabilities
-	conn.caps = []p2p.Cap{
-		{Name: "eth", Version: 64},
-		{Name: "eth", Version: 65},
+	defer conn.Close()
+
+	if err := s.maliciousStatus(conn); err != nil {
+		t.Fatal(err)
 	}
-	conn.ourHighestProtoVersion = 65
-	return &conn, nil
 }
 
+// TestTransaction sends a valid transaction to the node and
+// checks if the transaction gets propagated.
 func (s *Suite) TestTransaction(t *utesting.T) {
-	tests := []*types.Transaction{
-		getNextTxFromChain(t, s),
-		unknownTx(t, s),
+	if err := s.sendSuccessfulTxs(t, eth65); err != nil {
+		t.Fatal(err)
 	}
-	for i, tx := range tests {
-		t.Logf("Testing tx propagation: %v\n", i)
-		sendSuccessfulTx(t, s, tx)
+}
+
+// TestTransaction66 sends a valid transaction to the node and
+// checks if the transaction gets propagated.
+func (s *Suite) TestTransaction66(t *utesting.T) {
+	if err := s.sendSuccessfulTxs(t, eth66); err != nil {
+		t.Fatal(err)
 	}
 }
 
+// TestMaliciousTx sends several invalid transactions and tests whether
+// the node will propagate them.
 func (s *Suite) TestMaliciousTx(t *utesting.T) {
-	badTxs := []*types.Transaction{
-		getOldTxFromChain(t, s),
-		invalidNonceTx(t, s),
-		hugeAmount(t, s),
-		hugeGasPrice(t, s),
-		hugeData(t, s),
-	}
-	sendConn := s.setupConnection(t)
-	defer sendConn.Close()
-	// set up receiving connection before sending txs to make sure
-	// no announcements are missed
-	recvConn := s.setupConnection(t)
-	defer recvConn.Close()
-
-	for i, tx := range badTxs {
-		t.Logf("Testing malicious tx propagation: %v\n", i)
-		if err := sendConn.Write(&Transactions{tx}); err != nil {
-			t.Fatalf("could not write to connection: %v", err)
+	if err := s.sendMaliciousTxs(t, eth65); err != nil {
+		t.Fatal(err)
+	}
+}
+
+// TestMaliciousTx66 sends several invalid transactions and tests whether
+// the node will propagate them.
+func (s *Suite) TestMaliciousTx66(t *utesting.T) {
+	if err := s.sendMaliciousTxs(t, eth66); err != nil {
+		t.Fatal(err)
+	}
+}
+
+// TestLargeTxRequest66 tests whether a node can fulfill a large GetPooledTransactions
+// request.
+func (s *Suite) TestLargeTxRequest66(t *utesting.T) {
+	// send the next block to ensure the node is no longer syncing and
+	// is able to accept txs
+	if err := s.sendNextBlock(eth66); err != nil {
+		t.Fatalf("failed to send next block: %v", err)
+	}
+	// send 2000 transactions to the node
+	hashMap, txs, err := generateTxs(s, 2000)
+	if err != nil {
+		t.Fatalf("failed to generate transactions: %v", err)
+	}
+	if err = sendMultipleSuccessfulTxs(t, s, txs); err != nil {
+		t.Fatalf("failed to send multiple txs: %v", err)
+	}
+	// set up connection to receive to ensure node is peered with the receiving connection
+	// before tx request is sent
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err = conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	// create and send pooled tx request
+	hashes := make([]common.Hash, 0)
+	for _, hash := range hashMap {
+		hashes = append(hashes, hash)
+	}
+	getTxReq := &eth.GetPooledTransactionsPacket66{
+		RequestId:                   1234,
+		GetPooledTransactionsPacket: hashes,
+	}
+	if err = conn.Write66(getTxReq, GetPooledTransactions{}.Code()); err != nil {
+		t.Fatalf("could not write to conn: %v", err)
+	}
+	// check that all received transactions match those that were sent to node
+	switch msg := conn.waitForResponse(s.chain, timeout, getTxReq.RequestId).(type) {
+	case PooledTransactions:
+		for _, gotTx := range msg {
+			if _, exists := hashMap[gotTx.Hash()]; !exists {
+				t.Fatalf("unexpected tx received: %v", gotTx.Hash())
+			}
 		}
+	default:
+		t.Fatalf("unexpected %s", pretty.Sdump(msg))
+	}
+}
+
+// TestNewPooledTxs_66 tests whether a node will do a GetPooledTransactions
+// request upon receiving a NewPooledTransactionHashes announcement.
+func (s *Suite) TestNewPooledTxs66(t *utesting.T) {
+	// send the next block to ensure the node is no longer syncing and
+	// is able to accept txs
+	if err := s.sendNextBlock(eth66); err != nil {
+		t.Fatalf("failed to send next block: %v", err)
+	}
+
+	// generate 50 txs
+	hashMap, _, err := generateTxs(s, 50)
+	if err != nil {
+		t.Fatalf("failed to generate transactions: %v", err)
+	}
 
+	// create new pooled tx hashes announcement
+	hashes := make([]common.Hash, 0)
+	for _, hash := range hashMap {
+		hashes = append(hashes, hash)
+	}
+	announce := NewPooledTransactionHashes(hashes)
+
+	// send announcement
+	conn, err := s.dial66()
+	if err != nil {
+		t.Fatalf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err = conn.peer(s.chain, nil); err != nil {
+		t.Fatalf("peering failed: %v", err)
+	}
+	if err = conn.Write(announce); err != nil {
+		t.Fatalf("failed to write to connection: %v", err)
+	}
+
+	// wait for GetPooledTxs request
+	for {
+		_, msg := conn.readAndServe66(s.chain, timeout)
+		switch msg := msg.(type) {
+		case GetPooledTransactions:
+			if len(msg) != len(hashes) {
+				t.Fatalf("unexpected number of txs requested: wanted %d, got %d", len(hashes), len(msg))
+			}
+			return
+		// ignore propagated txs from previous tests
+		case *NewPooledTransactionHashes:
+			continue
+		// ignore block announcements from previous tests
+		case *NewBlockHashes:
+			continue
+		case *NewBlock:
+			continue
+		default:
+			t.Fatalf("unexpected %s", pretty.Sdump(msg))
+		}
 	}
-	// check to make sure bad txs aren't propagated
-	waitForTxPropagation(t, s, badTxs, recvConn)
 }
diff --git a/cmd/devp2p/internal/ethtest/transaction.go b/cmd/devp2p/internal/ethtest/transaction.go
index a6166bd2e34c72a52b1693dfee6eb5e71b009353..d2dbe0a7d69bb2774f06e018c8cc9c0e6128cde9 100644
--- a/cmd/devp2p/internal/ethtest/transaction.go
+++ b/cmd/devp2p/internal/ethtest/transaction.go
@@ -17,6 +17,7 @@
 package ethtest
 
 import (
+	"fmt"
 	"math/big"
 	"strings"
 	"time"
@@ -31,58 +32,171 @@ import (
 //var faucetAddr = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
 var faucetKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 
-func sendSuccessfulTx(t *utesting.T, s *Suite, tx *types.Transaction) {
-	sendConn := s.setupConnection(t)
-	defer sendConn.Close()
-	sendSuccessfulTxWithConn(t, s, tx, sendConn)
+func (s *Suite) sendSuccessfulTxs(t *utesting.T, isEth66 bool) error {
+	tests := []*types.Transaction{
+		getNextTxFromChain(s),
+		unknownTx(s),
+	}
+	for i, tx := range tests {
+		if tx == nil {
+			return fmt.Errorf("could not find tx to send")
+		}
+		t.Logf("Testing tx propagation %d: sending tx %v %v %v\n", i, tx.Hash().String(), tx.GasPrice(), tx.Gas())
+		// get previous tx if exists for reference in case of old tx propagation
+		var prevTx *types.Transaction
+		if i != 0 {
+			prevTx = tests[i-1]
+		}
+		// write tx to connection
+		if err := sendSuccessfulTx(s, tx, prevTx, isEth66); err != nil {
+			return fmt.Errorf("send successful tx test failed: %v", err)
+		}
+	}
+	return nil
 }
 
-func sendSuccessfulTxWithConn(t *utesting.T, s *Suite, tx *types.Transaction, sendConn *Conn) {
-	t.Logf("sending tx: %v %v %v\n", tx.Hash().String(), tx.GasPrice(), tx.Gas())
+func sendSuccessfulTx(s *Suite, tx *types.Transaction, prevTx *types.Transaction, isEth66 bool) error {
+	sendConn, recvConn, err := s.createSendAndRecvConns(isEth66)
+	if err != nil {
+		return err
+	}
+	defer sendConn.Close()
+	defer recvConn.Close()
+	if err = sendConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
 	// Send the transaction
-	if err := sendConn.Write(&Transactions{tx}); err != nil {
-		t.Fatal(err)
+	if err = sendConn.Write(&Transactions{tx}); err != nil {
+		return fmt.Errorf("failed to write to connection: %v", err)
+	}
+	// peer receiving connection to node
+	if err = recvConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
 	}
 	// update last nonce seen
 	nonce = tx.Nonce()
-
-	recvConn := s.setupConnection(t)
 	// Wait for the transaction announcement
-	switch msg := recvConn.ReadAndServe(s.chain, timeout).(type) {
-	case *Transactions:
-		recTxs := *msg
-		for _, gotTx := range recTxs {
-			if gotTx.Hash() == tx.Hash() {
-				// Ok
-				return
+	for {
+		switch msg := recvConn.readAndServe(s.chain, timeout).(type) {
+		case *Transactions:
+			recTxs := *msg
+			// if you receive an old tx propagation, read from connection again
+			if len(recTxs) == 1 && prevTx != nil {
+				if recTxs[0] == prevTx {
+					continue
+				}
 			}
-		}
-		t.Fatalf("missing transaction: got %v missing %v", recTxs, tx.Hash())
-	case *NewPooledTransactionHashes:
-		txHashes := *msg
-		for _, gotHash := range txHashes {
-			if gotHash == tx.Hash() {
-				return
+			for _, gotTx := range recTxs {
+				if gotTx.Hash() == tx.Hash() {
+					// Ok
+					return nil
+				}
 			}
+			return fmt.Errorf("missing transaction: got %v missing %v", recTxs, tx.Hash())
+		case *NewPooledTransactionHashes:
+			txHashes := *msg
+			// if you receive an old tx propagation, read from connection again
+			if len(txHashes) == 1 && prevTx != nil {
+				if txHashes[0] == prevTx.Hash() {
+					continue
+				}
+			}
+			for _, gotHash := range txHashes {
+				if gotHash == tx.Hash() {
+					// Ok
+					return nil
+				}
+			}
+			return fmt.Errorf("missing transaction announcement: got %v missing %v", txHashes, tx.Hash())
+		default:
+			return fmt.Errorf("unexpected message in sendSuccessfulTx: %s", pretty.Sdump(msg))
 		}
-		t.Fatalf("missing transaction announcement: got %v missing %v", txHashes, tx.Hash())
-	default:
-		t.Fatalf("unexpected message in sendSuccessfulTx: %s", pretty.Sdump(msg))
 	}
 }
 
+func (s *Suite) sendMaliciousTxs(t *utesting.T, isEth66 bool) error {
+	badTxs := []*types.Transaction{
+		getOldTxFromChain(s),
+		invalidNonceTx(s),
+		hugeAmount(s),
+		hugeGasPrice(s),
+		hugeData(s),
+	}
+	// setup receiving connection before sending malicious txs
+	var (
+		recvConn *Conn
+		err      error
+	)
+	if isEth66 {
+		recvConn, err = s.dial66()
+	} else {
+		recvConn, err = s.dial()
+	}
+	if err != nil {
+		return fmt.Errorf("dial failed: %v", err)
+	}
+	defer recvConn.Close()
+	if err = recvConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	for i, tx := range badTxs {
+		t.Logf("Testing malicious tx propagation: %v\n", i)
+		if err = sendMaliciousTx(s, tx, isEth66); err != nil {
+			return fmt.Errorf("malicious tx test failed:\ntx: %v\nerror: %v", tx, err)
+		}
+	}
+	// check to make sure bad txs aren't propagated
+	return checkMaliciousTxPropagation(s, badTxs, recvConn)
+}
+
+func sendMaliciousTx(s *Suite, tx *types.Transaction, isEth66 bool) error {
+	// setup connection
+	var (
+		conn *Conn
+		err  error
+	)
+	if isEth66 {
+		conn, err = s.dial66()
+	} else {
+		conn, err = s.dial()
+	}
+	if err != nil {
+		return fmt.Errorf("dial failed: %v", err)
+	}
+	defer conn.Close()
+	if err = conn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	// write malicious tx
+	if err = conn.Write(&Transactions{tx}); err != nil {
+		return fmt.Errorf("failed to write to connection: %v", err)
+	}
+	return nil
+}
+
 var nonce = uint64(99)
 
-func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, sendConn *Conn, txs []*types.Transaction) {
+// sendMultipleSuccessfulTxs sends the given transactions to the node and
+// expects the node to accept and propagate them.
+func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, txs []*types.Transaction) error {
 	txMsg := Transactions(txs)
 	t.Logf("sending %d txs\n", len(txs))
 
-	recvConn := s.setupConnection(t)
+	sendConn, recvConn, err := s.createSendAndRecvConns(true)
+	if err != nil {
+		return err
+	}
+	defer sendConn.Close()
 	defer recvConn.Close()
-
+	if err = sendConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
+	if err = recvConn.peer(s.chain, nil); err != nil {
+		return fmt.Errorf("peering failed: %v", err)
+	}
 	// Send the transactions
-	if err := sendConn.Write(&txMsg); err != nil {
-		t.Fatal(err)
+	if err = sendConn.Write(&txMsg); err != nil {
+		return fmt.Errorf("failed to write message to connection: %v", err)
 	}
 	// update nonce
 	nonce = txs[len(txs)-1].Nonce()
@@ -90,7 +204,7 @@ func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, sendConn *Conn, txs []*t
 	recvHashes := make([]common.Hash, 0)
 	// all txs should be announced within 3 announcements
 	for i := 0; i < 3; i++ {
-		switch msg := recvConn.ReadAndServe(s.chain, timeout).(type) {
+		switch msg := recvConn.readAndServe(s.chain, timeout).(type) {
 		case *Transactions:
 			for _, tx := range *msg {
 				recvHashes = append(recvHashes, tx.Hash())
@@ -99,7 +213,7 @@ func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, sendConn *Conn, txs []*t
 			recvHashes = append(recvHashes, *msg...)
 		default:
 			if !strings.Contains(pretty.Sdump(msg), "i/o timeout") {
-				t.Fatalf("unexpected message while waiting to receive txs: %s", pretty.Sdump(msg))
+				return fmt.Errorf("unexpected message while waiting to receive txs: %s", pretty.Sdump(msg))
 			}
 		}
 		// break once all 2000 txs have been received
@@ -112,7 +226,7 @@ func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, sendConn *Conn, txs []*t
 				continue
 			} else {
 				t.Logf("successfully received all %d txs", len(txs))
-				return
+				return nil
 			}
 		}
 	}
@@ -121,13 +235,15 @@ func sendMultipleSuccessfulTxs(t *utesting.T, s *Suite, sendConn *Conn, txs []*t
 		for _, missing := range missingTxs {
 			t.Logf("missing tx: %v", missing.Hash())
 		}
-		t.Fatalf("missing %d txs", len(missingTxs))
+		return fmt.Errorf("missing %d txs", len(missingTxs))
 	}
+	return nil
 }
 
-func waitForTxPropagation(t *utesting.T, s *Suite, txs []*types.Transaction, recvConn *Conn) {
-	// Wait for another transaction announcement
-	switch msg := recvConn.ReadAndServe(s.chain, time.Second*8).(type) {
+// checkMaliciousTxPropagation checks whether the given malicious transactions were
+// propagated by the node.
+func checkMaliciousTxPropagation(s *Suite, txs []*types.Transaction, conn *Conn) error {
+	switch msg := conn.readAndServe(s.chain, time.Second*8).(type) {
 	case *Transactions:
 		// check to see if any of the failing txs were in the announcement
 		recvTxs := make([]common.Hash, len(*msg))
@@ -136,25 +252,20 @@ func waitForTxPropagation(t *utesting.T, s *Suite, txs []*types.Transaction, rec
 		}
 		badTxs, _ := compareReceivedTxs(recvTxs, txs)
 		if len(badTxs) > 0 {
-			for _, tx := range badTxs {
-				t.Logf("received bad tx: %v", tx)
-			}
-			t.Fatalf("received %d bad txs", len(badTxs))
+			return fmt.Errorf("received %d bad txs: \n%v", len(badTxs), badTxs)
 		}
 	case *NewPooledTransactionHashes:
 		badTxs, _ := compareReceivedTxs(*msg, txs)
 		if len(badTxs) > 0 {
-			for _, tx := range badTxs {
-				t.Logf("received bad tx: %v", tx)
-			}
-			t.Fatalf("received %d bad txs", len(badTxs))
+			return fmt.Errorf("received %d bad txs: \n%v", len(badTxs), badTxs)
 		}
 	case *Error:
 		// Transaction should not be announced -> wait for timeout
-		return
+		return nil
 	default:
-		t.Fatalf("unexpected message in sendFailingTx: %s", pretty.Sdump(msg))
+		return fmt.Errorf("unexpected message in sendFailingTx: %s", pretty.Sdump(msg))
 	}
+	return nil
 }
 
 // compareReceivedTxs compares the received set of txs against the given set of txs,
@@ -180,118 +291,129 @@ func compareReceivedTxs(recvTxs []common.Hash, txs []*types.Transaction) (presen
 	return present, missing
 }
 
-func unknownTx(t *utesting.T, s *Suite) *types.Transaction {
-	tx := getNextTxFromChain(t, s)
+func unknownTx(s *Suite) *types.Transaction {
+	tx := getNextTxFromChain(s)
+	if tx == nil {
+		return nil
+	}
 	var to common.Address
 	if tx.To() != nil {
 		to = *tx.To()
 	}
 	txNew := types.NewTransaction(tx.Nonce()+1, to, tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data())
-	return signWithFaucet(t, s.chain.chainConfig, txNew)
+	return signWithFaucet(s.chain.chainConfig, txNew)
 }
 
-func getNextTxFromChain(t *utesting.T, s *Suite) *types.Transaction {
+func getNextTxFromChain(s *Suite) *types.Transaction {
 	// Get a new transaction
-	var tx *types.Transaction
 	for _, blocks := range s.fullChain.blocks[s.chain.Len():] {
 		txs := blocks.Transactions()
 		if txs.Len() != 0 {
-			tx = txs[0]
-			break
+			return txs[0]
 		}
 	}
-	if tx == nil {
-		t.Fatal("could not find transaction")
-	}
-	return tx
+	return nil
 }
 
-func generateTxs(t *utesting.T, s *Suite, numTxs int) (map[common.Hash]common.Hash, []*types.Transaction) {
+func generateTxs(s *Suite, numTxs int) (map[common.Hash]common.Hash, []*types.Transaction, error) {
 	txHashMap := make(map[common.Hash]common.Hash, numTxs)
 	txs := make([]*types.Transaction, numTxs)
 
-	nextTx := getNextTxFromChain(t, s)
+	nextTx := getNextTxFromChain(s)
+	if nextTx == nil {
+		return nil, nil, fmt.Errorf("failed to get the next transaction")
+	}
 	gas := nextTx.Gas()
 
 	nonce = nonce + 1
 	// generate txs
 	for i := 0; i < numTxs; i++ {
-		tx := generateTx(t, s.chain.chainConfig, nonce, gas)
+		tx := generateTx(s.chain.chainConfig, nonce, gas)
+		if tx == nil {
+			return nil, nil, fmt.Errorf("failed to get the next transaction")
+		}
 		txHashMap[tx.Hash()] = tx.Hash()
 		txs[i] = tx
 		nonce = nonce + 1
 	}
-	return txHashMap, txs
+	return txHashMap, txs, nil
 }
 
-func generateTx(t *utesting.T, chainConfig *params.ChainConfig, nonce uint64, gas uint64) *types.Transaction {
+func generateTx(chainConfig *params.ChainConfig, nonce uint64, gas uint64) *types.Transaction {
 	var to common.Address
 	tx := types.NewTransaction(nonce, to, big.NewInt(1), gas, big.NewInt(1), []byte{})
-	return signWithFaucet(t, chainConfig, tx)
+	return signWithFaucet(chainConfig, tx)
 }
 
-func getOldTxFromChain(t *utesting.T, s *Suite) *types.Transaction {
-	var tx *types.Transaction
+func getOldTxFromChain(s *Suite) *types.Transaction {
 	for _, blocks := range s.fullChain.blocks[:s.chain.Len()-1] {
 		txs := blocks.Transactions()
 		if txs.Len() != 0 {
-			tx = txs[0]
-			break
+			return txs[0]
 		}
 	}
-	if tx == nil {
-		t.Fatal("could not find transaction")
-	}
-	return tx
+	return nil
 }
 
-func invalidNonceTx(t *utesting.T, s *Suite) *types.Transaction {
-	tx := getNextTxFromChain(t, s)
+func invalidNonceTx(s *Suite) *types.Transaction {
+	tx := getNextTxFromChain(s)
+	if tx == nil {
+		return nil
+	}
 	var to common.Address
 	if tx.To() != nil {
 		to = *tx.To()
 	}
 	txNew := types.NewTransaction(tx.Nonce()-2, to, tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data())
-	return signWithFaucet(t, s.chain.chainConfig, txNew)
+	return signWithFaucet(s.chain.chainConfig, txNew)
 }
 
-func hugeAmount(t *utesting.T, s *Suite) *types.Transaction {
-	tx := getNextTxFromChain(t, s)
+func hugeAmount(s *Suite) *types.Transaction {
+	tx := getNextTxFromChain(s)
+	if tx == nil {
+		return nil
+	}
 	amount := largeNumber(2)
 	var to common.Address
 	if tx.To() != nil {
 		to = *tx.To()
 	}
 	txNew := types.NewTransaction(tx.Nonce(), to, amount, tx.Gas(), tx.GasPrice(), tx.Data())
-	return signWithFaucet(t, s.chain.chainConfig, txNew)
+	return signWithFaucet(s.chain.chainConfig, txNew)
 }
 
-func hugeGasPrice(t *utesting.T, s *Suite) *types.Transaction {
-	tx := getNextTxFromChain(t, s)
+func hugeGasPrice(s *Suite) *types.Transaction {
+	tx := getNextTxFromChain(s)
+	if tx == nil {
+		return nil
+	}
 	gasPrice := largeNumber(2)
 	var to common.Address
 	if tx.To() != nil {
 		to = *tx.To()
 	}
 	txNew := types.NewTransaction(tx.Nonce(), to, tx.Value(), tx.Gas(), gasPrice, tx.Data())
-	return signWithFaucet(t, s.chain.chainConfig, txNew)
+	return signWithFaucet(s.chain.chainConfig, txNew)
 }
 
-func hugeData(t *utesting.T, s *Suite) *types.Transaction {
-	tx := getNextTxFromChain(t, s)
+func hugeData(s *Suite) *types.Transaction {
+	tx := getNextTxFromChain(s)
+	if tx == nil {
+		return nil
+	}
 	var to common.Address
 	if tx.To() != nil {
 		to = *tx.To()
 	}
 	txNew := types.NewTransaction(tx.Nonce(), to, tx.Value(), tx.Gas(), tx.GasPrice(), largeBuffer(2))
-	return signWithFaucet(t, s.chain.chainConfig, txNew)
+	return signWithFaucet(s.chain.chainConfig, txNew)
 }
 
-func signWithFaucet(t *utesting.T, chainConfig *params.ChainConfig, tx *types.Transaction) *types.Transaction {
+func signWithFaucet(chainConfig *params.ChainConfig, tx *types.Transaction) *types.Transaction {
 	signer := types.LatestSigner(chainConfig)
 	signedTx, err := types.SignTx(tx, signer, faucetKey)
 	if err != nil {
-		t.Fatalf("could not sign tx: %v\n", err)
+		return nil
 	}
 	return signedTx
 }
diff --git a/cmd/devp2p/internal/ethtest/types.go b/cmd/devp2p/internal/ethtest/types.go
index 50a69b94183f1c006616900cc805ba24ec38a9d2..e49ea284e94ce29caaf539d90137b3dc8285ca53 100644
--- a/cmd/devp2p/internal/ethtest/types.go
+++ b/cmd/devp2p/internal/ethtest/types.go
@@ -19,13 +19,8 @@ package ethtest
 import (
 	"crypto/ecdsa"
 	"fmt"
-	"reflect"
-	"time"
 
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth/protocols/eth"
-	"github.com/ethereum/go-ethereum/internal/utesting"
 	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/p2p/rlpx"
 	"github.com/ethereum/go-ethereum/rlp"
@@ -137,6 +132,7 @@ type Conn struct {
 	caps                   []p2p.Cap
 }
 
+// Read reads an eth packet from the connection.
 func (c *Conn) Read() Message {
 	code, rawData, _, err := c.Conn.Read()
 	if err != nil {
@@ -185,32 +181,83 @@ func (c *Conn) Read() Message {
 	return msg
 }
 
-// ReadAndServe serves GetBlockHeaders requests while waiting
-// on another message from the node.
-func (c *Conn) ReadAndServe(chain *Chain, timeout time.Duration) Message {
-	start := time.Now()
-	for time.Since(start) < timeout {
-		c.SetReadDeadline(time.Now().Add(5 * time.Second))
-		switch msg := c.Read().(type) {
-		case *Ping:
-			c.Write(&Pong{})
-		case *GetBlockHeaders:
-			req := *msg
-			headers, err := chain.GetHeaders(req)
-			if err != nil {
-				return errorf("could not get headers for inbound header request: %v", err)
-			}
-
-			if err := c.Write(headers); err != nil {
-				return errorf("could not write to connection: %v", err)
-			}
-		default:
-			return msg
+// Read66 reads an eth66 packet from the connection.
+func (c *Conn) Read66() (uint64, Message) {
+	code, rawData, _, err := c.Conn.Read()
+	if err != nil {
+		return 0, errorf("could not read from connection: %v", err)
+	}
+
+	var msg Message
+	switch int(code) {
+	case (Hello{}).Code():
+		msg = new(Hello)
+	case (Ping{}).Code():
+		msg = new(Ping)
+	case (Pong{}).Code():
+		msg = new(Pong)
+	case (Disconnect{}).Code():
+		msg = new(Disconnect)
+	case (Status{}).Code():
+		msg = new(Status)
+	case (GetBlockHeaders{}).Code():
+		ethMsg := new(eth.GetBlockHeadersPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
 		}
+		return ethMsg.RequestId, GetBlockHeaders(*ethMsg.GetBlockHeadersPacket)
+	case (BlockHeaders{}).Code():
+		ethMsg := new(eth.BlockHeadersPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return ethMsg.RequestId, BlockHeaders(ethMsg.BlockHeadersPacket)
+	case (GetBlockBodies{}).Code():
+		ethMsg := new(eth.GetBlockBodiesPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return ethMsg.RequestId, GetBlockBodies(ethMsg.GetBlockBodiesPacket)
+	case (BlockBodies{}).Code():
+		ethMsg := new(eth.BlockBodiesPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return ethMsg.RequestId, BlockBodies(ethMsg.BlockBodiesPacket)
+	case (NewBlock{}).Code():
+		msg = new(NewBlock)
+	case (NewBlockHashes{}).Code():
+		msg = new(NewBlockHashes)
+	case (Transactions{}).Code():
+		msg = new(Transactions)
+	case (NewPooledTransactionHashes{}).Code():
+		msg = new(NewPooledTransactionHashes)
+	case (GetPooledTransactions{}.Code()):
+		ethMsg := new(eth.GetPooledTransactionsPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return ethMsg.RequestId, GetPooledTransactions(ethMsg.GetPooledTransactionsPacket)
+	case (PooledTransactions{}.Code()):
+		ethMsg := new(eth.PooledTransactionsPacket66)
+		if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return ethMsg.RequestId, PooledTransactions(ethMsg.PooledTransactionsPacket)
+	default:
+		msg = errorf("invalid message code: %d", code)
+	}
+
+	if msg != nil {
+		if err := rlp.DecodeBytes(rawData, msg); err != nil {
+			return 0, errorf("could not rlp decode message: %v", err)
+		}
+		return 0, msg
 	}
-	return errorf("no message received within %v", timeout)
+	return 0, errorf("invalid message: %s", string(rawData))
 }
 
+// Write writes a eth packet to the connection.
 func (c *Conn) Write(msg Message) error {
 	// check if message is eth protocol message
 	var (
@@ -225,135 +272,12 @@ func (c *Conn) Write(msg Message) error {
 	return err
 }
 
-// handshake checks to make sure a `HELLO` is received.
-func (c *Conn) handshake(t *utesting.T) Message {
-	defer c.SetDeadline(time.Time{})
-	c.SetDeadline(time.Now().Add(10 * time.Second))
-
-	// write hello to client
-	pub0 := crypto.FromECDSAPub(&c.ourKey.PublicKey)[1:]
-	ourHandshake := &Hello{
-		Version: 5,
-		Caps:    c.caps,
-		ID:      pub0,
-	}
-	if err := c.Write(ourHandshake); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-	// read hello from client
-	switch msg := c.Read().(type) {
-	case *Hello:
-		// set snappy if version is at least 5
-		if msg.Version >= 5 {
-			c.SetSnappy(true)
-		}
-		c.negotiateEthProtocol(msg.Caps)
-		if c.negotiatedProtoVersion == 0 {
-			t.Fatalf("unexpected eth protocol version")
-		}
-		return msg
-	default:
-		t.Fatalf("bad handshake: %#v", msg)
-		return nil
-	}
-}
-
-// negotiateEthProtocol sets the Conn's eth protocol version
-// to highest advertised capability from peer
-func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
-	var highestEthVersion uint
-	for _, capability := range caps {
-		if capability.Name != "eth" {
-			continue
-		}
-		if capability.Version > highestEthVersion && capability.Version <= c.ourHighestProtoVersion {
-			highestEthVersion = capability.Version
-		}
-	}
-	c.negotiatedProtoVersion = highestEthVersion
-}
-
-// statusExchange performs a `Status` message exchange with the given
-// node.
-func (c *Conn) statusExchange(t *utesting.T, chain *Chain, status *Status) Message {
-	defer c.SetDeadline(time.Time{})
-	c.SetDeadline(time.Now().Add(20 * time.Second))
-
-	// read status message from client
-	var message Message
-loop:
-	for {
-		switch msg := c.Read().(type) {
-		case *Status:
-			if have, want := msg.Head, chain.blocks[chain.Len()-1].Hash(); have != want {
-				t.Fatalf("wrong head block in status, want:  %#x (block %d) have %#x",
-					want, chain.blocks[chain.Len()-1].NumberU64(), have)
-			}
-			if have, want := msg.TD.Cmp(chain.TD(chain.Len())), 0; have != want {
-				t.Fatalf("wrong TD in status: have %v want %v", have, want)
-			}
-			if have, want := msg.ForkID, chain.ForkID(); !reflect.DeepEqual(have, want) {
-				t.Fatalf("wrong fork ID in status: have %v, want %v", have, want)
-			}
-			message = msg
-			break loop
-		case *Disconnect:
-			t.Fatalf("disconnect received: %v", msg.Reason)
-		case *Ping:
-			c.Write(&Pong{}) // TODO (renaynay): in the future, this should be an error
-			// (PINGs should not be a response upon fresh connection)
-		default:
-			t.Fatalf("bad status message: %s", pretty.Sdump(msg))
-		}
-	}
-	// make sure eth protocol version is set for negotiation
-	if c.negotiatedProtoVersion == 0 {
-		t.Fatalf("eth protocol version must be set in Conn")
-	}
-	if status == nil {
-		// write status message to client
-		status = &Status{
-			ProtocolVersion: uint32(c.negotiatedProtoVersion),
-			NetworkID:       chain.chainConfig.ChainID.Uint64(),
-			TD:              chain.TD(chain.Len()),
-			Head:            chain.blocks[chain.Len()-1].Hash(),
-			Genesis:         chain.blocks[0].Hash(),
-			ForkID:          chain.ForkID(),
-		}
-	}
-
-	if err := c.Write(status); err != nil {
-		t.Fatalf("could not write to connection: %v", err)
-	}
-
-	return message
-}
-
-// waitForBlock waits for confirmation from the client that it has
-// imported the given block.
-func (c *Conn) waitForBlock(block *types.Block) error {
-	defer c.SetReadDeadline(time.Time{})
-
-	c.SetReadDeadline(time.Now().Add(20 * time.Second))
-	// note: if the node has not yet imported the block, it will respond
-	// to the GetBlockHeaders request with an empty BlockHeaders response,
-	// so the GetBlockHeaders request must be sent again until the BlockHeaders
-	// response contains the desired header.
-	for {
-		req := &GetBlockHeaders{Origin: eth.HashOrNumber{Hash: block.Hash()}, Amount: 1}
-		if err := c.Write(req); err != nil {
-			return err
-		}
-		switch msg := c.Read().(type) {
-		case *BlockHeaders:
-			for _, header := range *msg {
-				if header.Number.Uint64() == block.NumberU64() {
-					return nil
-				}
-			}
-			time.Sleep(100 * time.Millisecond)
-		default:
-			return fmt.Errorf("invalid message: %s", pretty.Sdump(msg))
-		}
+// Write66 writes an eth66 packet to the connection.
+func (c *Conn) Write66(req eth.Packet, code int) error {
+	payload, err := rlp.EncodeToBytes(req)
+	if err != nil {
+		return err
 	}
+	_, err = c.Conn.Write(uint64(code), payload)
+	return err
 }
diff --git a/cmd/devp2p/internal/v4test/discv4tests.go b/cmd/devp2p/internal/v4test/discv4tests.go
index 140b96bfa56832addb08afb59fb7371ffca756f0..04ad67637a66d482e3c9d97c82f91afec61db0fd 100644
--- a/cmd/devp2p/internal/v4test/discv4tests.go
+++ b/cmd/devp2p/internal/v4test/discv4tests.go
@@ -21,7 +21,6 @@ import (
 	"crypto/rand"
 	"fmt"
 	"net"
-	"reflect"
 	"time"
 
 	"github.com/ethereum/go-ethereum/crypto"
@@ -80,25 +79,57 @@ func BasicPing(t *utesting.T) {
 		To:         te.remoteEndpoint(),
 		Expiration: futureExpiration(),
 	})
-
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if err := te.checkPingPong(pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
 
-// checkPong verifies that reply is a valid PONG matching the given ping hash.
+// checkPingPong verifies that the remote side sends both a PONG with the
+// correct hash, and a PING.
+// The two packets do not have to be in any particular order.
+func (te *testenv) checkPingPong(pingHash []byte) error {
+	var (
+		pings int
+		pongs int
+	)
+	for i := 0; i < 2; i++ {
+		reply, _, err := te.read(te.l1)
+		if err != nil {
+			return err
+		}
+		switch reply.Kind() {
+		case v4wire.PongPacket:
+			if err := te.checkPong(reply, pingHash); err != nil {
+				return err
+			}
+			pongs++
+		case v4wire.PingPacket:
+			pings++
+		default:
+			return fmt.Errorf("expected PING or PONG, got %v %v", reply.Name(), reply)
+		}
+	}
+	if pongs == 1 && pings == 1 {
+		return nil
+	}
+	return fmt.Errorf("expected 1 PING  (got %d) and 1 PONG (got %d)", pings, pongs)
+}
+
+// checkPong verifies that reply is a valid PONG matching the given ping hash,
+// and a PING. The two packets do not have to be in any particular order.
 func (te *testenv) checkPong(reply v4wire.Packet, pingHash []byte) error {
-	if reply == nil || reply.Kind() != v4wire.PongPacket {
-		return fmt.Errorf("expected PONG reply, got %v", reply)
+	if reply == nil {
+		return fmt.Errorf("expected PONG reply, got nil")
+	}
+	if reply.Kind() != v4wire.PongPacket {
+		return fmt.Errorf("expected PONG reply, got %v %v", reply.Name(), reply)
 	}
 	pong := reply.(*v4wire.Pong)
 	if !bytes.Equal(pong.ReplyTok, pingHash) {
 		return fmt.Errorf("PONG reply token mismatch: got %x, want %x", pong.ReplyTok, pingHash)
 	}
-	wantEndpoint := te.localEndpoint(te.l1)
-	if !reflect.DeepEqual(pong.To, wantEndpoint) {
-		return fmt.Errorf("PONG 'to' endpoint mismatch: got %+v, want %+v", pong.To, wantEndpoint)
+	if want := te.localEndpoint(te.l1); !want.IP.Equal(pong.To.IP) || want.UDP != pong.To.UDP {
+		return fmt.Errorf("PONG 'to' endpoint mismatch: got %+v, want %+v", pong.To, want)
 	}
 	if v4wire.Expired(pong.Expiration) {
 		return fmt.Errorf("PONG is expired (%v)", pong.Expiration)
@@ -118,9 +149,7 @@ func PingWrongTo(t *utesting.T) {
 		To:         wrongEndpoint,
 		Expiration: futureExpiration(),
 	})
-
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if err := te.checkPingPong(pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -138,8 +167,7 @@ func PingWrongFrom(t *utesting.T) {
 		Expiration: futureExpiration(),
 	})
 
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if err := te.checkPingPong(pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -160,8 +188,7 @@ func PingExtraData(t *utesting.T) {
 		JunkData2:  []byte{9, 8, 7, 6, 5, 4, 3, 2, 1},
 	})
 
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if err := te.checkPingPong(pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -182,8 +209,7 @@ func PingExtraDataWrongFrom(t *utesting.T) {
 		JunkData2:  []byte{9, 8, 7, 6, 5, 4, 3, 2, 1},
 	}
 	pingHash := te.send(te.l1, &req)
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if err := te.checkPingPong(pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -239,9 +265,9 @@ func BondThenPingWithWrongFrom(t *utesting.T) {
 		To:         te.remoteEndpoint(),
 		Expiration: futureExpiration(),
 	})
-
-	reply, _, _ := te.read(te.l1)
-	if err := te.checkPong(reply, pingHash); err != nil {
+	if reply, _, err := te.read(te.l1); err != nil {
+		t.Fatal(err)
+	} else if err := te.checkPong(reply, pingHash); err != nil {
 		t.Fatal(err)
 	}
 }
diff --git a/cmd/evm/README.md b/cmd/evm/README.md
index cdff41f904c11b01906d72252c8db1487d268baf..d5257069f2711404874d52c469c6bfe410c83e2c 100644
--- a/cmd/evm/README.md
+++ b/cmd/evm/README.md
@@ -4,15 +4,15 @@ The `evm t8n` tool is a stateless state transition utility. It is a utility
 which can
 
 1. Take a prestate, including
-  - Accounts,
-  - Block context information,
-  - Previous blockshashes (*optional)
+- Accounts,
+- Block context information,
+- Previous blockshashes (*optional)
 2. Apply a set of transactions,
 3. Apply a mining-reward (*optional),
 4. And generate a post-state, including
-  - State root, transaction root, receipt root,
-  - Information about rejected transactions,
-  - Optionally: a full or partial post-state dump
+- State root, transaction root, receipt root,
+- Information about rejected transactions,
+- Optionally: a full or partial post-state dump
 
 ## Specification
 
@@ -37,6 +37,8 @@ Command line params that has to be supported are
    --output.result result             Determines where to put the result (stateroot, txroot etc) of the post-state.
                                       `stdout` - into the stdout output
                                       `stderr` - into the stderr output
+   --output.body value                If set, the RLP of the transactions (block body) will be written to this file.
+   --input.txs stdin                  stdin or file name of where to find the transactions to apply. If the file prefix is '.rlp', then the data is interpreted as an RLP list of signed transactions.The '.rlp' format is identical to the output.body format. (default: "txs.json")
    --state.fork value                 Name of ruleset to use.
    --state.chainid value              ChainID to use (default: 1)
    --state.reward value               Mining reward. Set to -1 to disable (default: 0)
@@ -110,7 +112,10 @@ Two resulting files:
   }
  ],
  "rejected": [
-  1
+  {
+   "index": 1,
+   "error": "nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+  }
  ]
 }
 ```
@@ -156,7 +161,10 @@ Output:
    }
   ],
   "rejected": [
-   1
+   {
+    "index": 1,
+    "error": "nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+   }
   ]
  }
 }
@@ -168,9 +176,9 @@ Mining rewards and ommer rewards might need to be added. This is how those are a
 
 - `block_reward` is the block mining reward for the miner (`0xaa`), of a block at height `N`.
 - For each ommer (mined by `0xbb`), with blocknumber `N-delta`
-   - (where `delta` is the difference between the current block and the ommer)
-   - The account `0xbb` (ommer miner) is awarded `(8-delta)/ 8 * block_reward`
-   - The account `0xaa` (block miner) is awarded `block_reward / 32`
+  - (where `delta` is the difference between the current block and the ommer)
+  - The account `0xbb` (ommer miner) is awarded `(8-delta)/ 8 * block_reward`
+  - The account `0xaa` (block miner) is awarded `block_reward / 32`
 
 To make `state_t8n` apply these, the following inputs are required:
 
@@ -220,7 +228,7 @@ Output:
 ### Future EIPS
 
 It is also possible to experiment with future eips that are not yet defined in a hard fork.
-Example, putting EIP-1344 into Frontier: 
+Example, putting EIP-1344 into Frontier:
 ```
 ./evm t8n --state.fork=Frontier+1344 --input.pre=./testdata/1/pre.json --input.txs=./testdata/1/txs.json --input.env=/testdata/1/env.json
 ```
@@ -229,41 +237,102 @@ Example, putting EIP-1344 into Frontier:
 
 The `BLOCKHASH` opcode requires blockhashes to be provided by the caller, inside the `env`.
 If a required blockhash is not provided, the exit code should be `4`:
-Example where blockhashes are provided: 
+Example where blockhashes are provided:
 ```
-./evm t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json --trace
+./evm --verbosity=1 t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace
+INFO [07-27|11:53:40.960] Trie dumping started                     root=b7341d..857ea1
+INFO [07-27|11:53:40.960] Trie dumping complete                    accounts=3 elapsed="103.298µs"
+INFO [07-27|11:53:40.960] Wrote file                               file=alloc.json
+INFO [07-27|11:53:40.960] Wrote file                               file=result.json
+
 ```
+
 ```
 cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2
 ```
 ```
-{"pc":0,"op":96,"gas":"0x5f58ef8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
-{"pc":2,"op":64,"gas":"0x5f58ef5","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x1"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"BLOCKHASH","error":""}
-{"pc":3,"op":0,"gas":"0x5f58ee1","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0xdac58aa524e50956d0c0bae7f3f8bb9d35381365d07804dd5b48a5a297c06af4"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"STOP","error":""}
-{"output":"","gasUsed":"0x17","time":142709}
+{"pc":0,"op":96,"gas":"0x5f58ef8","gasCost":"0x3","memory":"0x","memSize":0,"stack":[],"returnData":"0x","depth":1,"refund":0,"opName":"PUSH1","error":""}
+{"pc":2,"op":64,"gas":"0x5f58ef5","gasCost":"0x14","memory":"0x","memSize":0,"stack":["0x1"],"returnData":"0x","depth":1,"refund":0,"opName":"BLOCKHASH","error":""}
+{"pc":3,"op":0,"gas":"0x5f58ee1","gasCost":"0x0","memory":"0x","memSize":0,"stack":["0xdac58aa524e50956d0c0bae7f3f8bb9d35381365d07804dd5b48a5a297c06af4"],"returnData":"0x","depth":1,"refund":0,"opName":"STOP","error":""}
+{"output":"","gasUsed":"0x17","time":156276}
 ```
 
 In this example, the caller has not provided the required blockhash:
 ```
 ./evm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json --trace
-```
-```
 ERROR(4): getHash(3) invoked, blockhash for that block not provided
 ```
 Error code: 4
+
 ### Chaining
 
 Another thing that can be done, is to chain invocations:
 ```
 ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --output.alloc=stdout | ./evm t8n --input.alloc=stdin --input.env=./testdata/1/env.json --input.txs=./testdata/1/txs.json
-INFO [01-21|22:41:22.963] rejected tx                              index=1 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
-INFO [01-21|22:41:22.966] rejected tx                              index=0 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
-INFO [01-21|22:41:22.967] rejected tx                              index=1 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+INFO [07-27|11:53:41.049] rejected tx                              index=1 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+INFO [07-27|11:53:41.050] Trie dumping started                     root=84208a..ae4e13
+INFO [07-27|11:53:41.050] Trie dumping complete                    accounts=3 elapsed="59.412µs"
+INFO [07-27|11:53:41.050] Wrote file                               file=result.json
+INFO [07-27|11:53:41.051] rejected tx                              index=0 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+INFO [07-27|11:53:41.051] rejected tx                              index=1 hash=0557ba..18d673 from=0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192 error="nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
+INFO [07-27|11:53:41.052] Trie dumping started                     root=84208a..ae4e13
+INFO [07-27|11:53:41.052] Trie dumping complete                    accounts=3 elapsed="45.734µs"
+INFO [07-27|11:53:41.052] Wrote file                               file=alloc.json
+INFO [07-27|11:53:41.052] Wrote file                               file=result.json
 
 ```
-What happened here, is that we first applied two identical transactions, so the second one was rejected. 
+What happened here, is that we first applied two identical transactions, so the second one was rejected.
 Then, taking the poststate alloc as the input for the next state, we tried again to include
 the same two transactions: this time, both failed due to too low nonce.
 
 In order to meaningfully chain invocations, one would need to provide meaningful new `env`, otherwise the
 actual blocknumber (exposed to the EVM) would not increase.
+
+### Transactions in RLP form
+
+It is possible to provide already-signed transactions as input to, using an `input.txs` which ends with the `rlp` suffix.
+The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible
+to use the evm to go from `json` input to `rlp` input.
+
+The following command takes **json** the transactions in `./testdata/13/txs.json` and signs them. After execution, they are output to `signed_txs.rlp`.:
+```
+./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./testdata/13/txs.json --input.env=./testdata/13/env.json --output.result=alloc_jsontx.json --output.body=signed_txs.rlp
+INFO [07-27|11:53:41.124] Trie dumping started                     root=e4b924..6aef61
+INFO [07-27|11:53:41.124] Trie dumping complete                    accounts=3 elapsed="94.284µs"
+INFO [07-27|11:53:41.125] Wrote file                               file=alloc.json
+INFO [07-27|11:53:41.125] Wrote file                               file=alloc_jsontx.json
+INFO [07-27|11:53:41.125] Wrote file                               file=signed_txs.rlp
+
+```
+
+The `output.body` is the rlp-list of transactions, encoded in hex and placed in a string a'la `json` encoding rules:
+```
+cat signed_txs.rlp
+"0xf8d2b86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"
+```
+
+We can use `rlpdump` to check what the contents are:
+```
+rlpdump -hex $(cat signed_txs.rlp | jq -r )
+[
+  02f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904,
+  02f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9,
+]
+```
+Now, we can now use those (or any other already signed transactions), as input, like so:
+```
+./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json
+INFO [07-27|11:53:41.253] Trie dumping started                     root=e4b924..6aef61
+INFO [07-27|11:53:41.253] Trie dumping complete                    accounts=3 elapsed="128.445µs"
+INFO [07-27|11:53:41.253] Wrote file                               file=alloc.json
+INFO [07-27|11:53:41.255] Wrote file                               file=alloc_rlptx.json
+
+```
+
+You might have noticed that the results from these two invocations were stored in two separate files.
+And we can now finally check that they match.
+```
+cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
+"0xe4b924a6adb5959fccf769d5b7bb2f6359e26d1e76a2443c5a91a36d826aef61"
+"0xe4b924a6adb5959fccf769d5b7bb2f6359e26d1e76a2443c5a91a36d826aef61"
+```
diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go
index c3f1b16efc9b585ff936cc7350e8d97493c15796..1ab2f001e267e05c02ac11dccd2efd280deaeedb 100644
--- a/cmd/evm/internal/t8ntool/execution.go
+++ b/cmd/evm/internal/t8ntool/execution.go
@@ -52,7 +52,7 @@ type ExecutionResult struct {
 	LogsHash    common.Hash    `json:"logsHash"`
 	Bloom       types.Bloom    `json:"logsBloom"        gencodec:"required"`
 	Receipts    types.Receipts `json:"receipts"`
-	Rejected    []int          `json:"rejected,omitempty"`
+	Rejected    []*rejectedTx  `json:"rejected,omitempty"`
 }
 
 type ommer struct {
@@ -69,6 +69,7 @@ type stEnv struct {
 	Timestamp   uint64                              `json:"currentTimestamp"  gencodec:"required"`
 	BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
 	Ommers      []ommer                             `json:"ommers,omitempty"`
+	BaseFee     *big.Int                            `json:"currentBaseFee,omitempty"`
 }
 
 type stEnvMarshaling struct {
@@ -77,6 +78,12 @@ type stEnvMarshaling struct {
 	GasLimit   math.HexOrDecimal64
 	Number     math.HexOrDecimal64
 	Timestamp  math.HexOrDecimal64
+	BaseFee    *math.HexOrDecimal256
+}
+
+type rejectedTx struct {
+	Index int    `json:"index"`
+	Err   string `json:"error"`
 }
 
 // Apply applies a set of transactions to a pre-state
@@ -103,7 +110,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		signer      = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number))
 		gaspool     = new(core.GasPool)
 		blockHash   = common.Hash{0x13, 0x37}
-		rejectedTxs []int
+		rejectedTxs []*rejectedTx
 		includedTxs types.Transactions
 		gasUsed     = uint64(0)
 		receipts    = make(types.Receipts, 0)
@@ -120,6 +127,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		GasLimit:    pre.Env.GasLimit,
 		GetHash:     getHash,
 	}
+	// If currentBaseFee is defined, add it to the vmContext.
+	if pre.Env.BaseFee != nil {
+		vmContext.BaseFee = new(big.Int).Set(pre.Env.BaseFee)
+	}
 	// If DAO is supported/enabled, we need to handle it here. In geth 'proper', it's
 	// done in StateProcessor.Process(block, ...), right before transactions are applied.
 	if chainConfig.DAOForkSupport &&
@@ -129,10 +140,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 	}
 
 	for i, tx := range txs {
-		msg, err := tx.AsMessage(signer)
+		msg, err := tx.AsMessage(signer, pre.Env.BaseFee)
 		if err != nil {
-			log.Info("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
-			rejectedTxs = append(rejectedTxs, i)
+			log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
+			rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
 			continue
 		}
 		tracer, err := getTracerFn(txIndex, tx.Hash())
@@ -141,7 +152,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		}
 		vmConfig.Tracer = tracer
 		vmConfig.Debug = (tracer != nil)
-		statedb.Prepare(tx.Hash(), blockHash, txIndex)
+		statedb.Prepare(tx.Hash(), txIndex)
 		txContext := core.NewEVMTxContext(msg)
 		snapshot := statedb.Snapshot()
 		evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
@@ -151,7 +162,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		if err != nil {
 			statedb.RevertToSnapshot(snapshot)
 			log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err)
-			rejectedTxs = append(rejectedTxs, i)
+			rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
 			continue
 		}
 		includedTxs = append(includedTxs, tx)
@@ -186,7 +197,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 			}
 
 			// Set the receipt logs and create the bloom filter.
-			receipt.Logs = statedb.GetLogs(tx.Hash())
+			receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash)
 			receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
 			// These three are non-consensus fields:
 			//receipt.BlockHash
diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go
index a599462cc61dc6861c3d61bddc9e8e9a194169be..626f974a0b0d70b97c2409ef631d6493fdea12d8 100644
--- a/cmd/evm/internal/t8ntool/flags.go
+++ b/cmd/evm/internal/t8ntool/flags.go
@@ -79,8 +79,10 @@ var (
 		Value: "env.json",
 	}
 	InputTxsFlag = cli.StringFlag{
-		Name:  "input.txs",
-		Usage: "`stdin` or file name of where to find the transactions to apply.",
+		Name: "input.txs",
+		Usage: "`stdin` or file name of where to find the transactions to apply. " +
+			"If the file prefix is '.rlp', then the data is interpreted as an RLP list of signed transactions." +
+			"The '.rlp' format is identical to the output.body format.",
 		Value: "txs.json",
 	}
 	RewardFlag = cli.Int64Flag{
diff --git a/cmd/evm/internal/t8ntool/gen_stenv.go b/cmd/evm/internal/t8ntool/gen_stenv.go
index ab5951534e48f9643cce6ef50f4634732bc51998..c7f079c02f49c0a92ff856beb8d435f8db168599 100644
--- a/cmd/evm/internal/t8ntool/gen_stenv.go
+++ b/cmd/evm/internal/t8ntool/gen_stenv.go
@@ -23,6 +23,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
 		Timestamp   math.HexOrDecimal64                 `json:"currentTimestamp"  gencodec:"required"`
 		BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
 		Ommers      []ommer                             `json:"ommers,omitempty"`
+		BaseFee     *math.HexOrDecimal256               `json:"currentBaseFee,omitempty"`
 	}
 	var enc stEnv
 	enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
@@ -32,6 +33,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
 	enc.Timestamp = math.HexOrDecimal64(s.Timestamp)
 	enc.BlockHashes = s.BlockHashes
 	enc.Ommers = s.Ommers
+	enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee)
 	return json.Marshal(&enc)
 }
 
@@ -45,6 +47,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
 		Timestamp   *math.HexOrDecimal64                `json:"currentTimestamp"  gencodec:"required"`
 		BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
 		Ommers      []ommer                             `json:"ommers,omitempty"`
+		BaseFee     *math.HexOrDecimal256               `json:"currentBaseFee,omitempty"`
 	}
 	var dec stEnv
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -76,5 +79,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
 	if dec.Ommers != nil {
 		s.Ommers = dec.Ommers
 	}
+	if dec.BaseFee != nil {
+		s.BaseFee = (*big.Int)(dec.BaseFee)
+	}
 	return nil
 }
diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go
index fedcd12435693eedbf6df2d30f3d934b384877de..8334aa01d4f9714631eef529d78073b5a00ed5dc 100644
--- a/cmd/evm/internal/t8ntool/transition.go
+++ b/cmd/evm/internal/t8ntool/transition.go
@@ -19,11 +19,13 @@ package t8ntool
 import (
 	"crypto/ecdsa"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"math/big"
 	"os"
 	"path"
+	"strings"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
@@ -71,6 +73,7 @@ type input struct {
 	Alloc core.GenesisAlloc `json:"alloc,omitempty"`
 	Env   *stEnv            `json:"env,omitempty"`
 	Txs   []*txWithKey      `json:"txs,omitempty"`
+	TxRlp string            `json:"txsRlp,omitempty"`
 }
 
 func Main(ctx *cli.Context) error {
@@ -142,7 +145,9 @@ func Main(ctx *cli.Context) error {
 	// Figure out the prestate alloc
 	if allocStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector {
 		decoder := json.NewDecoder(os.Stdin)
-		decoder.Decode(inputData)
+		if err := decoder.Decode(inputData); err != nil {
+			return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err))
+		}
 	}
 	if allocStr != stdinSelector {
 		inFile, err := os.Open(allocStr)
@@ -152,7 +157,7 @@ func Main(ctx *cli.Context) error {
 		defer inFile.Close()
 		decoder := json.NewDecoder(inFile)
 		if err := decoder.Decode(&inputData.Alloc); err != nil {
-			return NewError(ErrorJson, fmt.Errorf("Failed unmarshaling alloc-file: %v", err))
+			return NewError(ErrorJson, fmt.Errorf("failed unmarshaling alloc-file: %v", err))
 		}
 	}
 	prestate.Pre = inputData.Alloc
@@ -167,7 +172,7 @@ func Main(ctx *cli.Context) error {
 		decoder := json.NewDecoder(inFile)
 		var env stEnv
 		if err := decoder.Decode(&env); err != nil {
-			return NewError(ErrorJson, fmt.Errorf("Failed unmarshaling env-file: %v", err))
+			return NewError(ErrorJson, fmt.Errorf("failed unmarshaling env-file: %v", err))
 		}
 		inputData.Env = &env
 	}
@@ -180,7 +185,7 @@ func Main(ctx *cli.Context) error {
 	// Construct the chainconfig
 	var chainConfig *params.ChainConfig
 	if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
-		return NewError(ErrorVMConfig, fmt.Errorf("Failed constructing chain configuration: %v", err))
+		return NewError(ErrorVMConfig, fmt.Errorf("failed constructing chain configuration: %v", err))
 	} else {
 		chainConfig = cConf
 		vmConfig.ExtraEips = extraEips
@@ -196,32 +201,67 @@ func Main(ctx *cli.Context) error {
 		}
 		defer inFile.Close()
 		decoder := json.NewDecoder(inFile)
-		if err := decoder.Decode(&txsWithKeys); err != nil {
-			return NewError(ErrorJson, fmt.Errorf("Failed unmarshaling txs-file: %v", err))
+		if strings.HasSuffix(txStr, ".rlp") {
+			var body hexutil.Bytes
+			if err := decoder.Decode(&body); err != nil {
+				return err
+			}
+			var txs types.Transactions
+			if err := rlp.DecodeBytes(body, &txs); err != nil {
+				return err
+			}
+			for _, tx := range txs {
+				txsWithKeys = append(txsWithKeys, &txWithKey{
+					key: nil,
+					tx:  tx,
+				})
+			}
+		} else {
+			if err := decoder.Decode(&txsWithKeys); err != nil {
+				return NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
+			}
 		}
 	} else {
-		txsWithKeys = inputData.Txs
+		if len(inputData.TxRlp) > 0 {
+			// Decode the body of already signed transactions
+			body := common.FromHex(inputData.TxRlp)
+			var txs types.Transactions
+			if err := rlp.DecodeBytes(body, &txs); err != nil {
+				return err
+			}
+			for _, tx := range txs {
+				txsWithKeys = append(txsWithKeys, &txWithKey{
+					key: nil,
+					tx:  tx,
+				})
+			}
+		} else {
+			// JSON encoded transactions
+			txsWithKeys = inputData.Txs
+		}
 	}
 	// We may have to sign the transactions.
 	signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)))
 
 	if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
-		return NewError(ErrorJson, fmt.Errorf("Failed signing transactions: %v", err))
+		return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
+	}
+	// Sanity check, to not `panic` in state_transition
+	if chainConfig.IsLondon(big.NewInt(int64(prestate.Env.Number))) {
+		if prestate.Env.BaseFee == nil {
+			return NewError(ErrorVMConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
+		}
 	}
-
-	// Iterate over all the tests, run them and aggregate the results
-
 	// Run the test and aggregate the result
-	state, result, err := prestate.Apply(vmConfig, chainConfig, txs, ctx.Int64(RewardFlag.Name), getTracer)
+	s, result, err := prestate.Apply(vmConfig, chainConfig, txs, ctx.Int64(RewardFlag.Name), getTracer)
 	if err != nil {
 		return err
 	}
 	body, _ := rlp.EncodeToBytes(txs)
 	// Dump the excution result
 	collector := make(Alloc)
-	state.DumpToCollector(collector, false, false, false, nil, -1)
+	s.DumpToCollector(collector, nil)
 	return dispatchOutput(ctx, baseDir, result, collector, body)
-
 }
 
 // txWithKey is a helper-struct, to allow us to use the types.Transaction along with
@@ -278,7 +318,7 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran
 			// This transaction needs to be signed
 			signed, err := types.SignTx(tx, signer, key)
 			if err != nil {
-				return nil, NewError(ErrorJson, fmt.Errorf("Tx %d: failed to sign tx: %v", i, err))
+				return nil, NewError(ErrorJson, fmt.Errorf("tx %d: failed to sign tx: %v", i, err))
 			}
 			signedTxs = append(signedTxs, signed)
 		} else {
@@ -303,7 +343,7 @@ func (g Alloc) OnAccount(addr common.Address, dumpAccount state.DumpAccount) {
 		}
 	}
 	genesisAccount := core.GenesisAccount{
-		Code:    common.FromHex(dumpAccount.Code),
+		Code:    dumpAccount.Code,
 		Storage: storage,
 		Balance: balance,
 		Nonce:   dumpAccount.Nonce,
@@ -360,6 +400,7 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
 			return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
 		}
 		os.Stdout.Write(b)
+		os.Stdout.Write([]byte("\n"))
 	}
 	if len(stdErrObject) > 0 {
 		b, err := json.MarshalIndent(stdErrObject, "", " ")
@@ -367,6 +408,7 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
 			return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
 		}
 		os.Stderr.Write(b)
+		os.Stderr.Write([]byte("\n"))
 	}
 	return nil
 }
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 8a3e4e0ea253faaf9eb14740ad3de7ff076af6c5..b9c0d17f37c617c8c0894b1f194b2727b9c507d2 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -129,11 +129,6 @@ var (
 		Name:  "noreturndata",
 		Usage: "disable return data output",
 	}
-	EVMInterpreterFlag = cli.StringFlag{
-		Name:  "vm.evm",
-		Usage: "External EVM configuration (default = built-in interpreter)",
-		Value: "",
-	}
 )
 
 var stateTransitionCommand = cli.Command{
@@ -185,7 +180,6 @@ func init() {
 		DisableStackFlag,
 		DisableStorageFlag,
 		DisableReturnDataFlag,
-		EVMInterpreterFlag,
 	}
 	app.Commands = []cli.Command{
 		compileCommand,
diff --git a/cmd/evm/poststate.json b/cmd/evm/poststate.json
deleted file mode 100644
index 9ee17f18d139858580cf20a592bd21365e1c6bde..0000000000000000000000000000000000000000
--- a/cmd/evm/poststate.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "root": "f4157bb27bcb1d1a63001434a249a80948f2e9fe1f53d551244c1dae826b5b23",
-    "accounts": {
-        "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
-            "balance": "4276951709",
-            "nonce": 1,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
-        },
-        "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
-            "balance": "6916764286133345652",
-            "nonce": 172,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
-        },
-        "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
-            "balance": "42500",
-            "nonce": 0,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
-        }
-    }
-}
\ No newline at end of file
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 4063767cb8f48a2035165b1adebb6824a2639fee..e409d2692572cedc5689c2a249fb4c942824d7b2 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -211,9 +211,8 @@ func runCmd(ctx *cli.Context) error {
 		Coinbase:    genesisConfig.Coinbase,
 		BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
 		EVMConfig: vm.Config{
-			Tracer:         tracer,
-			Debug:          ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name),
-			EVMInterpreter: ctx.GlobalString(EVMInterpreterFlag.Name),
+			Tracer: tracer,
+			Debug:  ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name),
 		},
 	}
 
@@ -270,7 +269,7 @@ func runCmd(ctx *cli.Context) error {
 	if ctx.GlobalBool(DumpFlag.Name) {
 		statedb.Commit(true)
 		statedb.IntermediateRoot(true)
-		fmt.Println(string(statedb.Dump(false, false, true)))
+		fmt.Println(string(statedb.Dump(nil)))
 	}
 
 	if memProfilePath := ctx.GlobalString(MemProfileFlag.Name); memProfilePath != "" {
diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go
index c4df936c75ffe2e4f430ec1a3b64a90d7d3dc76d..d8bc4eae8001328d1420c1ad39e643fb4b335f75 100644
--- a/cmd/evm/staterunner.go
+++ b/cmd/evm/staterunner.go
@@ -98,16 +98,16 @@ func stateTestCmd(ctx *cli.Context) error {
 		for _, st := range test.Subtests() {
 			// Run the test and aggregate the result
 			result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true}
-			_, state, err := test.Run(st, cfg, false)
+			_, s, err := test.Run(st, cfg, false)
 			// print state root for evmlab tracing
-			if ctx.GlobalBool(MachineFlag.Name) && state != nil {
-				fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false))
+			if ctx.GlobalBool(MachineFlag.Name) && s != nil {
+				fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(false))
 			}
 			if err != nil {
 				// Test failed, mark as so and dump any state to aid debugging
 				result.Pass, result.Error = false, err.Error()
-				if ctx.GlobalBool(DumpFlag.Name) && state != nil {
-					dump := state.RawDump(false, false, true)
+				if ctx.GlobalBool(DumpFlag.Name) && s != nil {
+					dump := s.RawDump(nil)
 					result.State = &dump
 				}
 			}
diff --git a/cmd/evm/testdata/10/alloc.json b/cmd/evm/testdata/10/alloc.json
new file mode 100644
index 0000000000000000000000000000000000000000..6e98e7513c454a5491bf918c010192bc6cd9dc77
--- /dev/null
+++ b/cmd/evm/testdata/10/alloc.json
@@ -0,0 +1,23 @@
+{
+  "0x1111111111111111111111111111111111111111" : {
+    "balance" : "0x010000000000",
+    "code" : "0xfe",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  },
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+    "balance" : "0x010000000000",
+    "code" : "0x",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  },
+  "0xd02d72e067e77158444ef2020ff2d325f929b363" : {
+    "balance" : "0x01000000000000",
+    "code" : "0x",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  }
+}
\ No newline at end of file
diff --git a/cmd/evm/testdata/10/env.json b/cmd/evm/testdata/10/env.json
new file mode 100644
index 0000000000000000000000000000000000000000..3a82d46a774b49b68c52186878dcb0f567307469
--- /dev/null
+++ b/cmd/evm/testdata/10/env.json
@@ -0,0 +1,12 @@
+{
+  "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+  "currentDifficulty" : "0x020000",
+  "currentNumber" : "0x01",
+  "currentTimestamp" : "0x079e",
+  "previousHash" : "0xcb23ee65a163121f640673b41788ee94633941405f95009999b502eedfbbfd4f",
+  "currentGasLimit" : "0x40000000",
+  "currentBaseFee" : "0x036b",
+  "blockHashes" : {
+    "0" : "0xcb23ee65a163121f640673b41788ee94633941405f95009999b502eedfbbfd4f"
+  }
+}
\ No newline at end of file
diff --git a/cmd/evm/testdata/10/readme.md b/cmd/evm/testdata/10/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..c34be80bb71c4b7d3e17a0f036e3d01cb53c13e1
--- /dev/null
+++ b/cmd/evm/testdata/10/readme.md
@@ -0,0 +1,79 @@
+## EIP-1559 testing
+
+This test contains testcases for EIP-1559, which were reported by Ori as misbehaving. 
+
+```
+[user@work evm]$ dir=./testdata/10 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout 2>&1
+INFO [05-09|22:11:59.436] rejected tx                              index=3 hash=db07bf..ede1e8 from=0xd02d72E067e77158444ef2020Ff2d325f929B363 error="gas limit reached"
+```
+Output:
+```json
+{
+ "alloc": {
+  "0x1111111111111111111111111111111111111111": {
+   "code": "0xfe",
+   "balance": "0x10000000000",
+   "nonce": "0x1"
+  },
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
+   "balance": "0x10000000000",
+   "nonce": "0x1"
+  },
+  "0xd02d72e067e77158444ef2020ff2d325f929b363": {
+   "balance": "0xff5beffffc95",
+   "nonce": "0x4"
+  }
+ },
+ "result": {
+  "stateRoot": "0xf91a7ec08e4bfea88719aab34deabb000c86902360532b52afa9599d41f2bb8b",
+  "txRoot": "0xda925f2306a52fa24c15d5cd212d736ee016415fd8dd0c45fd368de7917d64bb",
+  "receiptRoot": "0x439a25f7fc424c10fb1f89800e4aa1df74156b137239d9ac3eaa7c911c353cd5",
+  "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
+  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+  "receipts": [
+   {
+    "type": "0x2",
+    "root": "0x",
+    "status": "0x0",
+    "cumulativeGasUsed": "0x10000001",
+    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+    "logs": null,
+    "transactionHash": "0x88980f6efcc5358d9c359663e7b9414722d430497637340ea056b076bc206701",
+    "contractAddress": "0x0000000000000000000000000000000000000000",
+    "gasUsed": "0x10000001",
+    "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+    "transactionIndex": "0x0"
+   },
+   {
+    "type": "0x2",
+    "root": "0x",
+    "status": "0x0",
+    "cumulativeGasUsed": "0x20000001",
+    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+    "logs": null,
+    "transactionHash": "0xd7bf3886f4e2aef74d525ae072c680f3846f550254401b67cbfda4a233757582",
+    "contractAddress": "0x0000000000000000000000000000000000000000",
+    "gasUsed": "0x10000000",
+    "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+    "transactionIndex": "0x1"
+   },
+   {
+    "type": "0x2",
+    "root": "0x",
+    "status": "0x0",
+    "cumulativeGasUsed": "0x30000001",
+    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+    "logs": null,
+    "transactionHash": "0x50308296760f01f1eeec7500e9e73cad67469249b1f59e9a9f55e6625a4923db",
+    "contractAddress": "0x0000000000000000000000000000000000000000",
+    "gasUsed": "0x10000000",
+    "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+    "transactionIndex": "0x2"
+   }
+  ],
+  "rejected": [
+   3
+  ]
+ }
+}
+```
diff --git a/cmd/evm/testdata/10/txs.json b/cmd/evm/testdata/10/txs.json
new file mode 100644
index 0000000000000000000000000000000000000000..f7c9baa26da9e7a61faaa4b192b0236f091d19e5
--- /dev/null
+++ b/cmd/evm/testdata/10/txs.json
@@ -0,0 +1,70 @@
+[
+  {
+    "input" : "0x",
+    "gas" : "0x10000001",
+    "nonce" : "0x1",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x7a45f00bcde9036b026cdf1628b023cd8a31a95c62b5e4dbbee2fa7debe668fb",
+    "s" : "0x3cc9d6f2cd00a045b0263f2d6dad7d60938d5d13d061af4969f95928aa934d4a",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : [
+    ]
+  },
+  {
+    "input" : "0x",
+    "gas" : "0x10000000",
+    "nonce" : "0x2",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x4c564b94b0281a8210eeec2dd1fe2e16ff1c1903a8c3a1078d735d7f8208b2af",
+    "s" : "0x56432b2593e6de95db1cb997b7385217aca03f1615327e231734446b39f266d",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : [
+    ]
+  },
+  {
+    "input" : "0x",
+    "gas" : "0x10000000",
+    "nonce" : "0x3",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x2ed2ef52f924f59d4a21e1f2a50d3b1109303ce5e32334a7ece9b46f4fbc2a57",
+    "s" : "0x2980257129cbd3da987226f323d50ba3975a834d165e0681f991b75615605c44",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : [
+    ]
+  },
+  {
+    "input" : "0x",
+    "gas" : "0x10000000",
+    "nonce" : "0x4",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x5df7d7f8f8e15b36fc9f189cacb625040fad10398d08fc90812595922a2c49b2",
+    "s" : "0x565fc1803f77a84d754ffe3c5363ab54a8d93a06ea1bb9d4c73c73a282b35917",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : [
+    ]
+  }
+]
\ No newline at end of file
diff --git a/cmd/evm/testdata/11/alloc.json b/cmd/evm/testdata/11/alloc.json
new file mode 100644
index 0000000000000000000000000000000000000000..86938230fa75dc43891de58d93494f5b60468b05
--- /dev/null
+++ b/cmd/evm/testdata/11/alloc.json
@@ -0,0 +1,25 @@
+{
+    "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+        "balance" : "0x0de0b6b3a7640000",
+        "code" : "0x61ffff5060046000f3",
+        "nonce" : "0x01",
+        "storage" : {
+        }
+    },
+    "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+        "balance" : "0x0de0b6b3a7640000",
+        "code" : "0x",
+        "nonce" : "0x00",
+        "storage" : {
+            "0x00" : "0x00"
+        }
+    },
+    "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+        "balance" : "0x00",
+        "code" : "0x6001600055",
+        "nonce" : "0x00",
+        "storage" : {
+        }
+    }
+}
+
diff --git a/cmd/evm/testdata/11/env.json b/cmd/evm/testdata/11/env.json
new file mode 100644
index 0000000000000000000000000000000000000000..37dedf09475a86ad00fc042f4834464cb9fe2dae
--- /dev/null
+++ b/cmd/evm/testdata/11/env.json
@@ -0,0 +1,12 @@
+{
+    "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+    "currentDifficulty" : "0x020000",
+    "currentNumber" : "0x01",
+    "currentTimestamp" : "0x03e8",
+    "previousHash" : "0xfda4419b3660e99f37e536dae1ab081c180136bb38c837a93e93d9aab58553b2",
+    "currentGasLimit" : "0x0f4240",
+    "blockHashes" : {
+        "0" : "0xfda4419b3660e99f37e536dae1ab081c180136bb38c837a93e93d9aab58553b2"
+    }
+}
+
diff --git a/cmd/evm/testdata/11/readme.md b/cmd/evm/testdata/11/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..d499f8e99fae848e6b06f54a552cb67f560eea23
--- /dev/null
+++ b/cmd/evm/testdata/11/readme.md
@@ -0,0 +1,13 @@
+## Test missing basefee
+
+In this test, the `currentBaseFee` is missing from the env portion. 
+On a live blockchain, the basefee is present in the header, and verified as part of header validation. 
+
+In `evm t8n`, we don't have blocks, so it needs to be added in the `env`instead. 
+
+When it's missing, an error is expected. 
+
+```
+dir=./testdata/11 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout 2>&1>/dev/null
+ERROR(3): EIP-1559 config but missing 'currentBaseFee' in env section
+```
\ No newline at end of file
diff --git a/cmd/evm/testdata/11/txs.json b/cmd/evm/testdata/11/txs.json
new file mode 100644
index 0000000000000000000000000000000000000000..c54b0a1f5b4d78eaff81f2225988478d072d4d94
--- /dev/null
+++ b/cmd/evm/testdata/11/txs.json
@@ -0,0 +1,14 @@
+[
+    {
+        "input" : "0x38600060013960015160005560006000f3",
+        "gas" : "0x61a80",
+        "gasPrice" : "0x1",
+        "nonce" : "0x0",
+        "value" : "0x186a0",
+        "v" : "0x1c",
+        "r" : "0x2e1391fd903387f1cc2b51df083805fb4bbb0d4710a2cdf4a044d191ff7be63e",
+        "s" : "0x7f10a933c42ab74927db02b1db009e923d9d2ab24ac24d63c399f2fe5d9c9b22",
+        "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
+    }
+]
+
diff --git a/cmd/evm/testdata/12/alloc.json b/cmd/evm/testdata/12/alloc.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ed96894fbcad458f046b96eb70201c6d85a6dcd
--- /dev/null
+++ b/cmd/evm/testdata/12/alloc.json
@@ -0,0 +1,11 @@
+{
+    "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+        "balance" : "84000000",
+        "code" : "0x",
+        "nonce" : "0x00",
+        "storage" : {
+            "0x00" : "0x00"
+        }
+    }
+}
+
diff --git a/cmd/evm/testdata/12/env.json b/cmd/evm/testdata/12/env.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ae5465369cc3c1934a99c3b667ed0074a70dc58
--- /dev/null
+++ b/cmd/evm/testdata/12/env.json
@@ -0,0 +1,10 @@
+{
+    "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+    "currentDifficulty" : "0x020000",
+    "currentNumber" : "0x01",
+    "currentTimestamp" : "0x03e8",
+    "previousHash" : "0xfda4419b3660e99f37e536dae1ab081c180136bb38c837a93e93d9aab58553b2",
+    "currentGasLimit" : "0x0f4240",
+    "currentBaseFee" : "0x20"
+}
+
diff --git a/cmd/evm/testdata/12/readme.md b/cmd/evm/testdata/12/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..b0177ecc24b6971ae91d8001479e444b5b9cf736
--- /dev/null
+++ b/cmd/evm/testdata/12/readme.md
@@ -0,0 +1,40 @@
+## Test 1559 balance + gasCap
+
+This test contains an EIP-1559 consensus issue which happened on Ropsten, where
+`geth` did not properly account for the value transfer while doing the check on `max_fee_per_gas * gas_limit`.
+
+Before the issue was fixed, this invocation allowed the transaction to pass into a block:
+```
+dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout
+```
+
+With the fix applied, the result is: 
+```
+dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout
+INFO [07-21|19:03:50.276] rejected tx                              index=0 hash=ccc996..d83435 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
+INFO [07-21|19:03:50.276] Trie dumping started                     root=e05f81..6597a5
+INFO [07-21|19:03:50.276] Trie dumping complete                    accounts=1 elapsed="39.549µs"
+{
+ "alloc": {
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
+   "balance": "0x501bd00"
+  }
+ },
+ "result": {
+  "stateRoot": "0xe05f81f8244a76503ceec6f88abfcd03047a612a1001217f37d30984536597a5",
+  "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+  "receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+  "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
+  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+  "receipts": [],
+  "rejected": [
+   {
+    "index": 0,
+    "error": "insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
+   }
+  ]
+ }
+}
+```
+
+The transaction is rejected. 
\ No newline at end of file
diff --git a/cmd/evm/testdata/12/txs.json b/cmd/evm/testdata/12/txs.json
new file mode 100644
index 0000000000000000000000000000000000000000..cd683f271c726147286e13e7047db44c4e200c94
--- /dev/null
+++ b/cmd/evm/testdata/12/txs.json
@@ -0,0 +1,20 @@
+[
+    {
+        "input" : "0x",
+        "gas" : "0x5208",
+        "nonce" : "0x0",
+        "to" : "0x1111111111111111111111111111111111111111",
+        "value" : "0x20",
+        "v" : "0x0",
+        "r" : "0x0",
+        "s" : "0x0",
+        "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+        "chainId" : "0x1",
+        "type" : "0x2",
+        "maxFeePerGas" : "0xfa0",
+        "maxPriorityFeePerGas" : "0x20",
+        "accessList" : [
+        ]
+    }
+]
+
diff --git a/cmd/evm/testdata/13/alloc.json b/cmd/evm/testdata/13/alloc.json
new file mode 100644
index 0000000000000000000000000000000000000000..6e98e7513c454a5491bf918c010192bc6cd9dc77
--- /dev/null
+++ b/cmd/evm/testdata/13/alloc.json
@@ -0,0 +1,23 @@
+{
+  "0x1111111111111111111111111111111111111111" : {
+    "balance" : "0x010000000000",
+    "code" : "0xfe",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  },
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+    "balance" : "0x010000000000",
+    "code" : "0x",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  },
+  "0xd02d72e067e77158444ef2020ff2d325f929b363" : {
+    "balance" : "0x01000000000000",
+    "code" : "0x",
+    "nonce" : "0x01",
+    "storage" : {
+    }
+  }
+}
\ No newline at end of file
diff --git a/cmd/evm/testdata/13/env.json b/cmd/evm/testdata/13/env.json
new file mode 100644
index 0000000000000000000000000000000000000000..3a82d46a774b49b68c52186878dcb0f567307469
--- /dev/null
+++ b/cmd/evm/testdata/13/env.json
@@ -0,0 +1,12 @@
+{
+  "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+  "currentDifficulty" : "0x020000",
+  "currentNumber" : "0x01",
+  "currentTimestamp" : "0x079e",
+  "previousHash" : "0xcb23ee65a163121f640673b41788ee94633941405f95009999b502eedfbbfd4f",
+  "currentGasLimit" : "0x40000000",
+  "currentBaseFee" : "0x036b",
+  "blockHashes" : {
+    "0" : "0xcb23ee65a163121f640673b41788ee94633941405f95009999b502eedfbbfd4f"
+  }
+}
\ No newline at end of file
diff --git a/cmd/evm/testdata/13/readme.md b/cmd/evm/testdata/13/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..64f52fc9a910e099a7871ba4f02309d7928800be
--- /dev/null
+++ b/cmd/evm/testdata/13/readme.md
@@ -0,0 +1,4 @@
+## Input transactions in RLP form
+
+This testdata folder is used to examplify how transaction input can be provided in rlp form. 
+Please see the README in `evm` folder for how this is performed. 
\ No newline at end of file
diff --git a/cmd/evm/testdata/13/txs.json b/cmd/evm/testdata/13/txs.json
new file mode 100644
index 0000000000000000000000000000000000000000..c45ef1e13d1fa6a46785806221c7b771e29c21a4
--- /dev/null
+++ b/cmd/evm/testdata/13/txs.json
@@ -0,0 +1,34 @@
+[
+  {
+    "input" : "0x",
+    "gas" : "0x84d0",
+    "nonce" : "0x1",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x0",
+    "s" : "0x0",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : []
+  },
+  {
+    "input" : "0x",
+    "gas" : "0x84d0",
+    "nonce" : "0x2",
+    "to" : "0x1111111111111111111111111111111111111111",
+    "value" : "0x0",
+    "v" : "0x0",
+    "r" : "0x0",
+    "s" : "0x0",
+    "secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
+    "chainId" : "0x1",
+    "type" : "0x2",
+    "maxFeePerGas" : "0xfa0",
+    "maxPriorityFeePerGas" : "0x0",
+    "accessList" : []
+  }
+]
\ No newline at end of file
diff --git a/cmd/evm/testdata/9/alloc.json b/cmd/evm/testdata/9/alloc.json
new file mode 100644
index 0000000000000000000000000000000000000000..c14e38e845156e055db5c8cc2337b4e2695b3ad3
--- /dev/null
+++ b/cmd/evm/testdata/9/alloc.json
@@ -0,0 +1,11 @@
+{
+  "0x000000000000000000000000000000000000aaaa": {
+    "balance": "0x03",
+    "code": "0x58585454",
+    "nonce": "0x1"
+  },
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
+    "balance": "0x100000000000000",
+    "nonce": "0x00"
+  }
+}
diff --git a/cmd/evm/testdata/9/env.json b/cmd/evm/testdata/9/env.json
new file mode 100644
index 0000000000000000000000000000000000000000..ec5164b9952eafcf55f76ee0b4c7ef6bdd50d60c
--- /dev/null
+++ b/cmd/evm/testdata/9/env.json
@@ -0,0 +1,8 @@
+{
+  "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+  "currentDifficulty": "0x20000",
+  "currentGasTarget": "0x1000000000",
+  "currentBaseFee": "0x3B9ACA00",
+  "currentNumber": "0x1000000",
+  "currentTimestamp": "0x04"
+}
diff --git a/cmd/evm/testdata/9/readme.md b/cmd/evm/testdata/9/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..88f0f12aaaa5731f0b873c5d7ab4a064457d0358
--- /dev/null
+++ b/cmd/evm/testdata/9/readme.md
@@ -0,0 +1,75 @@
+## EIP-1559 testing
+
+This test contains testcases for EIP-1559, which uses an new transaction type and has a new block parameter. 
+
+### Prestate
+
+The alloc portion contains one contract (`0x000000000000000000000000000000000000aaaa`), containing the 
+following code: `0x58585454`: `PC; PC; SLOAD; SLOAD`.
+
+Essentialy, this contract does `SLOAD(0)` and `SLOAD(1)`.
+
+The alloc also contains some funds on `0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b`. 
+
+## Transactions
+
+There are two transactions, each invokes the contract above. 
+
+1. EIP-1559 ACL-transaction, which contains the `0x0` slot for `0xaaaa`
+2. Legacy transaction
+
+## Execution 
+
+Running it yields: 
+```
+$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --trace && cat trace-* | grep SLOAD
+{"pc":2,"op":84,"gas":"0x48c28","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x1"],"returnStack":null,"returnD
+ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
+{"pc":3,"op":84,"gas":"0x483f4","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":null,"returnDa
+ta":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
+{"pc":2,"op":84,"gas":"0x49cf4","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x1"],"returnStack":null,"returnD
+ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
+{"pc":3,"op":84,"gas":"0x494c0","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":null,"returnD
+ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
+```
+
+We can also get the post-alloc:
+```
+$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout
+{
+ "alloc": {
+  "0x000000000000000000000000000000000000aaaa": {
+   "code": "0x58585454",
+   "balance": "0x3",
+   "nonce": "0x1"
+  },
+  "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
+   "balance": "0xbfc02677a000"
+  },
+  "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
+   "balance": "0xff104fcfea7800",
+   "nonce": "0x2"
+  }
+ }
+}
+```
+
+If we try to execute it on older rules: 
+```
+dir=./testdata/9 && ./evm t8n --state.fork=Berlin --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout
+ERROR(10): Failed signing transactions: ERROR(10): Tx 0: failed to sign tx: transaction type not supported
+```
+
+It fails, due to the `evm t8n` cannot sign them in with the given signer. We can bypass that, however, 
+by feeding it presigned transactions, located in `txs_signed.json`. 
+
+```
+dir=./testdata/9 && ./evm t8n --state.fork=Berlin --input.alloc=$dir/alloc.json --input.txs=$dir/txs_signed.json --input.env=$dir/env.json 
+INFO [05-07|12:28:42.072] rejected tx                              index=0 hash=b4821e..536819 error="transaction type not supported"
+INFO [05-07|12:28:42.072] rejected tx                              index=1 hash=a9c6c6..fa4036 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="nonce too high: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B, tx: 1 state: 0"
+INFO [05-07|12:28:42.073] Wrote file                               file=alloc.json
+INFO [05-07|12:28:42.073] Wrote file                               file=result.json
+```
+
+Number `0` is not applicable, and therefore number `1` has wrong nonce, and both are rejected.
+
diff --git a/cmd/evm/testdata/9/txs.json b/cmd/evm/testdata/9/txs.json
new file mode 100644
index 0000000000000000000000000000000000000000..740abce079d8fee4f646807c6c50a57821b9334a
--- /dev/null
+++ b/cmd/evm/testdata/9/txs.json
@@ -0,0 +1,37 @@
+[
+  {
+    "gas": "0x4ef00",
+    "maxPriorityFeePerGas": "0x2",
+    "maxFeePerGas": "0x12A05F200",
+    "chainId": "0x1",
+    "input": "0x",
+    "nonce": "0x0",
+    "to": "0x000000000000000000000000000000000000aaaa",
+    "value": "0x0",
+    "type" : "0x2",
+    "accessList": [
+      {"address": "0x000000000000000000000000000000000000aaaa",
+        "storageKeys": [
+          "0x0000000000000000000000000000000000000000000000000000000000000000"
+        ]
+      }
+    ],
+    "v": "0x0",
+    "r": "0x0",
+    "s": "0x0",
+    "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
+  },
+  {
+    "gas": "0x4ef00",
+    "gasPrice": "0x12A05F200",
+    "chainId": "0x1",
+    "input": "0x",
+    "nonce": "0x1",
+    "to": "0x000000000000000000000000000000000000aaaa",
+    "value": "0x0",
+    "v": "0x0",
+    "r": "0x0",
+    "s": "0x0",
+    "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
+  }
+]
diff --git a/cmd/evm/transition-test.sh b/cmd/evm/transition-test.sh
index 34c92498559a0f6eb52533c380a59f9c0205e67d..250238d1694a2eb5690671af91b2e539c662bed8 100644
--- a/cmd/evm/transition-test.sh
+++ b/cmd/evm/transition-test.sh
@@ -11,6 +11,8 @@ function showjson(){
 function demo(){
   echo "$ticks"
   echo "$1"
+  $1
+  echo ""
   echo "$ticks"
   echo ""
 }
@@ -152,9 +154,7 @@ echo ""
 echo "The \`BLOCKHASH\` opcode requires blockhashes to be provided by the caller, inside the \`env\`."
 echo "If a required blockhash is not provided, the exit code should be \`4\`:"
 echo "Example where blockhashes are provided: "
-cmd="./evm t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace"
-tick && echo $cmd && tick
-$cmd 2>&1 >/dev/null
+demo "./evm --verbosity=1 t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace"
 cmd="cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2"
 tick && echo $cmd && tick
 echo "$ticks"
@@ -164,13 +164,11 @@ echo ""
 
 echo "In this example, the caller has not provided the required blockhash:"
 cmd="./evm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json  --trace"
-tick && echo $cmd && tick
-tick
-$cmd
+tick && echo $cmd && $cmd
 errc=$?
 tick
 echo "Error code: $errc"
-
+echo ""
 
 echo "### Chaining"
 echo ""
@@ -189,3 +187,28 @@ echo ""
 echo "In order to meaningfully chain invocations, one would need to provide meaningful new \`env\`, otherwise the"
 echo "actual blocknumber (exposed to the EVM) would not increase."
 echo ""
+
+echo "### Transactions in RLP form"
+echo ""
+echo "It is possible to provide already-signed transactions as input to, using an \`input.txs\` which ends with the \`rlp\` suffix."
+echo "The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible"
+echo "to use the evm to go from \`json\` input to \`rlp\` input."
+echo ""
+echo "The following command takes **json** the transactions in \`./testdata/13/txs.json\` and signs them. After execution, they are output to \`signed_txs.rlp\`.:"
+demo "./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./testdata/13/txs.json --input.env=./testdata/13/env.json --output.result=alloc_jsontx.json --output.body=signed_txs.rlp"
+echo "The \`output.body\` is the rlp-list of transactions, encoded in hex and placed in a string a'la \`json\` encoding rules:"
+demo "cat signed_txs.rlp"
+echo "We can use \`rlpdump\` to check what the contents are: "
+echo "$ticks"
+echo "rlpdump -hex \$(cat signed_txs.rlp | jq -r )"
+rlpdump -hex $(cat signed_txs.rlp | jq -r )
+echo "$ticks"
+echo "Now, we can now use those (or any other already signed transactions), as input, like so: "
+demo "./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json"
+
+echo "You might have noticed that the results from these two invocations were stored in two separate files. "
+echo "And we can now finally check that they match."
+echo "$ticks"
+echo "cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot"
+cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
+echo "$ticks"
diff --git a/cmd/faucet/faucet_test.go b/cmd/faucet/faucet_test.go
index 4f3e47084e3fa090e43cfcfb6fccd4bc2ecea901..58a1f22b548dca205ef76bd23107b5d4caf41b75 100644
--- a/cmd/faucet/faucet_test.go
+++ b/cmd/faucet/faucet_test.go
@@ -23,6 +23,8 @@ import (
 )
 
 func TestFacebook(t *testing.T) {
+	// TODO: Remove facebook auth or implement facebook api, which seems to require an API key
+	t.Skipf("The facebook access is flaky, needs to be reimplemented or removed")
 	for _, tt := range []struct {
 		url  string
 		want common.Address
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index f70beaa08dbed7277721e6128e9239141ada0de7..8c460c3b5b6a53e804bba29143a0e1ae65e7a4f5 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -18,6 +18,7 @@ package main
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"os"
 	"runtime"
@@ -27,12 +28,16 @@ import (
 
 	"github.com/ethereum/go-ethereum/cmd/utils"
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/rawdb"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/metrics"
+	"github.com/ethereum/go-ethereum/node"
 	"gopkg.in/urfave/cli.v1"
 )
 
@@ -63,7 +68,6 @@ It expects the genesis file as argument.`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Category: "BLOCKCHAIN COMMANDS",
 		Description: `
@@ -87,11 +91,15 @@ The dumpgenesis command dumps the genesis block configuration in JSON format to
 			utils.MetricsHTTPFlag,
 			utils.MetricsPortFlag,
 			utils.MetricsEnableInfluxDBFlag,
+			utils.MetricsEnableInfluxDBV2Flag,
 			utils.MetricsInfluxDBEndpointFlag,
 			utils.MetricsInfluxDBDatabaseFlag,
 			utils.MetricsInfluxDBUsernameFlag,
 			utils.MetricsInfluxDBPasswordFlag,
 			utils.MetricsInfluxDBTagsFlag,
+			utils.MetricsInfluxDBTokenFlag,
+			utils.MetricsInfluxDBBucketFlag,
+			utils.MetricsInfluxDBOrganizationFlag,
 			utils.TxLookupLimitFlag,
 
 			// bor related flags
@@ -156,20 +164,21 @@ The export-preimages command export hash preimages to an RLP encoded stream`,
 		Action:    utils.MigrateFlags(dump),
 		Name:      "dump",
 		Usage:     "Dump a specific block from storage",
-		ArgsUsage: "[<blockHash> | <blockNum>]...",
+		ArgsUsage: "[? <blockHash> | <blockNum>]",
 		Flags: []cli.Flag{
 			utils.DataDirFlag,
 			utils.CacheFlag,
-			utils.SyncModeFlag,
 			utils.IterativeOutputFlag,
 			utils.ExcludeCodeFlag,
 			utils.ExcludeStorageFlag,
 			utils.IncludeIncompletesFlag,
+			utils.StartKeyFlag,
+			utils.DumpLimitFlag,
 		},
 		Category: "BLOCKCHAIN COMMANDS",
 		Description: `
-The arguments are interpreted as block numbers or hashes.
-Use "ethereum dump 0" to dump the genesis block.`,
+This command dumps out the state for a given block (or latest, if none provided).
+`,
 	}
 )
 
@@ -378,47 +387,85 @@ func exportPreimages(ctx *cli.Context) error {
 	return nil
 }
 
-func dump(ctx *cli.Context) error {
-	stack, _ := makeConfigNode(ctx)
-	defer stack.Close()
-
+func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, ethdb.Database, common.Hash, error) {
 	db := utils.MakeChainDatabase(ctx, stack, true)
-	for _, arg := range ctx.Args() {
-		var header *types.Header
+	var header *types.Header
+	if ctx.NArg() > 1 {
+		return nil, nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg())
+	}
+	if ctx.NArg() == 1 {
+		arg := ctx.Args().First()
 		if hashish(arg) {
 			hash := common.HexToHash(arg)
-			number := rawdb.ReadHeaderNumber(db, hash)
-			if number != nil {
+			if number := rawdb.ReadHeaderNumber(db, hash); number != nil {
 				header = rawdb.ReadHeader(db, hash, *number)
+			} else {
+				return nil, nil, common.Hash{}, fmt.Errorf("block %x not found", hash)
 			}
 		} else {
-			number, _ := strconv.Atoi(arg)
-			hash := rawdb.ReadCanonicalHash(db, uint64(number))
-			if hash != (common.Hash{}) {
-				header = rawdb.ReadHeader(db, hash, uint64(number))
-			}
-		}
-		if header == nil {
-			fmt.Println("{}")
-			utils.Fatalf("block not found")
-		} else {
-			state, err := state.New(header.Root, state.NewDatabase(db), nil)
+			number, err := strconv.Atoi(arg)
 			if err != nil {
-				utils.Fatalf("could not create new state: %v", err)
+				return nil, nil, common.Hash{}, err
 			}
-			excludeCode := ctx.Bool(utils.ExcludeCodeFlag.Name)
-			excludeStorage := ctx.Bool(utils.ExcludeStorageFlag.Name)
-			includeMissing := ctx.Bool(utils.IncludeIncompletesFlag.Name)
-			if ctx.Bool(utils.IterativeOutputFlag.Name) {
-				state.IterativeDump(excludeCode, excludeStorage, !includeMissing, json.NewEncoder(os.Stdout))
+			if hash := rawdb.ReadCanonicalHash(db, uint64(number)); hash != (common.Hash{}) {
+				header = rawdb.ReadHeader(db, hash, uint64(number))
 			} else {
-				if includeMissing {
-					fmt.Printf("If you want to include accounts with missing preimages, you need iterative output, since" +
-						" otherwise the accounts will overwrite each other in the resulting mapping.")
-				}
-				fmt.Printf("%v %s\n", includeMissing, state.Dump(excludeCode, excludeStorage, false))
+				return nil, nil, common.Hash{}, fmt.Errorf("header for block %d not found", number)
 			}
 		}
+	} else {
+		// Use latest
+		header = rawdb.ReadHeadHeader(db)
+	}
+	if header == nil {
+		return nil, nil, common.Hash{}, errors.New("no head block found")
+	}
+	startArg := common.FromHex(ctx.String(utils.StartKeyFlag.Name))
+	var start common.Hash
+	switch len(startArg) {
+	case 0: // common.Hash
+	case 32:
+		start = common.BytesToHash(startArg)
+	case 20:
+		start = crypto.Keccak256Hash(startArg)
+		log.Info("Converting start-address to hash", "address", common.BytesToAddress(startArg), "hash", start.Hex())
+	default:
+		return nil, nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg)
+	}
+	var conf = &state.DumpConfig{
+		SkipCode:          ctx.Bool(utils.ExcludeCodeFlag.Name),
+		SkipStorage:       ctx.Bool(utils.ExcludeStorageFlag.Name),
+		OnlyWithAddresses: !ctx.Bool(utils.IncludeIncompletesFlag.Name),
+		Start:             start.Bytes(),
+		Max:               ctx.Uint64(utils.DumpLimitFlag.Name),
+	}
+	log.Info("State dump configured", "block", header.Number, "hash", header.Hash().Hex(),
+		"skipcode", conf.SkipCode, "skipstorage", conf.SkipStorage,
+		"start", hexutil.Encode(conf.Start), "limit", conf.Max)
+	return conf, db, header.Root, nil
+}
+
+func dump(ctx *cli.Context) error {
+	stack, _ := makeConfigNode(ctx)
+	defer stack.Close()
+
+	conf, db, root, err := parseDumpConfig(ctx, stack)
+	if err != nil {
+		return err
+	}
+	state, err := state.New(root, state.NewDatabase(db), nil)
+	if err != nil {
+		return err
+	}
+	if ctx.Bool(utils.IterativeOutputFlag.Name) {
+		state.IterativeDump(conf, json.NewEncoder(os.Stdout))
+	} else {
+		if conf.OnlyWithAddresses {
+			fmt.Fprintf(os.Stderr, "If you want to include accounts with missing preimages, you need iterative output, since"+
+				" otherwise the accounts will overwrite each other in the resulting mapping.")
+			return fmt.Errorf("incompatible options")
+		}
+		fmt.Println(string(state.Dump(conf)))
 	}
 	return nil
 }
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 9ab5ff6f3dd30e79de0bcd1c068489effbbaaca7..0686f3bc2ca6bc085ef76eadeb4fe5d8085de975 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -31,6 +31,7 @@ import (
 	"github.com/ethereum/go-ethereum/eth/catalyst"
 	"github.com/ethereum/go-ethereum/eth/ethconfig"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
+	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/metrics"
 	"github.com/ethereum/go-ethereum/node"
 	"github.com/ethereum/go-ethereum/params"
@@ -63,7 +64,12 @@ var tomlSettings = toml.Config{
 		return field
 	},
 	MissingField: func(rt reflect.Type, field string) error {
-		link := ""
+		id := fmt.Sprintf("%s.%s", rt.String(), field)
+		if deprecated(id) {
+			log.Warn("Config field is deprecated and won't have an effect", "name", id)
+			return nil
+		}
+		var link string
 		if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
 			link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name())
 		}
@@ -144,8 +150,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
 // makeFullNode loads geth configuration and creates the Ethereum backend.
 func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
 	stack, cfg := makeConfigNode(ctx)
-	if ctx.GlobalIsSet(utils.OverrideBerlinFlag.Name) {
-		cfg.Eth.OverrideBerlin = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideBerlinFlag.Name))
+	if ctx.GlobalIsSet(utils.OverrideLondonFlag.Name) {
+		cfg.Eth.OverrideLondon = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideLondonFlag.Name))
 	}
 	backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
 
@@ -230,4 +236,27 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
 	if ctx.GlobalIsSet(utils.MetricsInfluxDBTagsFlag.Name) {
 		cfg.Metrics.InfluxDBTags = ctx.GlobalString(utils.MetricsInfluxDBTagsFlag.Name)
 	}
+	if ctx.GlobalIsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
+		cfg.Metrics.EnableInfluxDBV2 = ctx.GlobalBool(utils.MetricsEnableInfluxDBV2Flag.Name)
+	}
+	if ctx.GlobalIsSet(utils.MetricsInfluxDBTokenFlag.Name) {
+		cfg.Metrics.InfluxDBToken = ctx.GlobalString(utils.MetricsInfluxDBTokenFlag.Name)
+	}
+	if ctx.GlobalIsSet(utils.MetricsInfluxDBBucketFlag.Name) {
+		cfg.Metrics.InfluxDBBucket = ctx.GlobalString(utils.MetricsInfluxDBBucketFlag.Name)
+	}
+	if ctx.GlobalIsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
+		cfg.Metrics.InfluxDBOrganization = ctx.GlobalString(utils.MetricsInfluxDBOrganizationFlag.Name)
+	}
+}
+
+func deprecated(field string) bool {
+	switch field {
+	case "ethconfig.Config.EVMInterpreter":
+		return true
+	case "ethconfig.Config.EWASMInterpreter":
+		return true
+	default:
+		return false
+	}
 }
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
index 9d8794eb15f507a04db4009b6261d29b8e3975d0..0e156fde9a5096a9a2792db99064745a11f792ba 100644
--- a/cmd/geth/consolecmd.go
+++ b/cmd/geth/consolecmd.go
@@ -134,8 +134,6 @@ func remoteConsole(ctx *cli.Context) error {
 				path = filepath.Join(path, "rinkeby")
 			} else if ctx.GlobalBool(utils.GoerliFlag.Name) {
 				path = filepath.Join(path, "goerli")
-			} else if ctx.GlobalBool(utils.YoloV3Flag.Name) {
-				path = filepath.Join(path, "yolo-v3")
 			}
 		}
 		endpoint = fmt.Sprintf("%s/geth.ipc", path)
@@ -171,7 +169,7 @@ func remoteConsole(ctx *cli.Context) error {
 
 // dialRPC returns a RPC client which connects to the given endpoint.
 // The check for empty endpoint implements the defaulting logic
-// for "geth attach" and "geth monitor" with no argument.
+// for "geth attach" with no argument.
 func dialRPC(endpoint string) (*rpc.Client, error) {
 	if endpoint == "" {
 		endpoint = node.DefaultIPCEndpoint(clientIdentifier)
diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go
index 4c70373e9aff65bb318a5cb1ea455a4b7c50e545..54ada408902bb8c919e1e80340586df406dfbfc4 100644
--- a/cmd/geth/dbcmd.go
+++ b/cmd/geth/dbcmd.go
@@ -75,7 +75,6 @@ Remove blockchain and state databases`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Usage:       "Inspect the storage size for each type of data in the database",
 		Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
@@ -91,7 +90,6 @@ Remove blockchain and state databases`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 	}
 	dbCompactCmd = cli.Command{
@@ -105,7 +103,6 @@ Remove blockchain and state databases`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 			utils.CacheFlag,
 			utils.CacheDatabaseFlag,
 		},
@@ -125,7 +122,6 @@ corruption if it is aborted during execution'!`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Description: "This command looks up the specified database key from the database.",
 	}
@@ -141,7 +137,6 @@ corruption if it is aborted during execution'!`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Description: `This command deletes the specified database key from the database. 
 WARNING: This is a low-level operation which may cause database corruption!`,
@@ -158,7 +153,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Description: `This command sets a given database key to the given value. 
 WARNING: This is a low-level operation which may cause database corruption!`,
@@ -175,7 +169,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Description: "This command looks up the specified database key from the database.",
 	}
@@ -191,7 +184,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
 			utils.RopstenFlag,
 			utils.RinkebyFlag,
 			utils.GoerliFlag,
-			utils.YoloV3Flag,
 		},
 		Description: "This command displays information about the freezer index.",
 	}
diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go
index cbc1b38374685a90d2019797c1115b6cf8e234f8..0563ef3c427102baa9ad8065d600f4a92c159fce 100644
--- a/cmd/geth/genesis_test.go
+++ b/cmd/geth/genesis_test.go
@@ -84,7 +84,7 @@ func TestCustomGenesis(t *testing.T) {
 		runGeth(t, "--datadir", datadir, "init", json).WaitExit()
 
 		// Query the custom genesis block
-		geth := runGeth(t, "--networkid", "1337", "--syncmode=full",
+		geth := runGeth(t, "--networkid", "1337", "--syncmode=full", "--cache", "16",
 			"--datadir", datadir, "--maxpeers", "0", "--port", "0",
 			"--nodiscover", "--nat", "none", "--ipcdisable",
 			"--exec", tt.query, "console")
diff --git a/cmd/geth/les_test.go b/cmd/geth/les_test.go
index 053ce96aa316f9b60652ddf1e2c3f6e1d445803b..151c12c68c665a08e1ca48c8268b13548f2e8b1c 100644
--- a/cmd/geth/les_test.go
+++ b/cmd/geth/les_test.go
@@ -137,14 +137,18 @@ func startGethWithIpc(t *testing.T, name string, args ...string) *gethrpc {
 		name: name,
 		geth: runGeth(t, args...),
 	}
-	// wait before we can attach to it. TODO: probe for it properly
-	time.Sleep(1 * time.Second)
-	var err error
 	ipcpath := ipcEndpoint(ipcName, g.geth.Datadir)
-	if g.rpc, err = rpc.Dial(ipcpath); err != nil {
-		t.Fatalf("%v rpc connect to %v: %v", name, ipcpath, err)
+	// We can't know exactly how long geth will take to start, so we try 10
+	// times over a 5 second period.
+	var err error
+	for i := 0; i < 10; i++ {
+		time.Sleep(500 * time.Millisecond)
+		if g.rpc, err = rpc.Dial(ipcpath); err == nil {
+			return g
+		}
 	}
-	return g
+	t.Fatalf("%v rpc connect to %v: %v", name, ipcpath, err)
+	return nil
 }
 
 func initGeth(t *testing.T) string {
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index bb539e9c750557a8f31482b19ef401b50b9501ff..fe2fe441392fb712baa43a9346078760db8f9fc8 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -68,7 +68,7 @@ var (
 		utils.NoUSBFlag,
 		utils.USBFlag,
 		utils.SmartCardDaemonPathFlag,
-		utils.OverrideBerlinFlag,
+		utils.OverrideLondonFlag,
 		utils.EthashCacheDirFlag,
 		utils.EthashCachesInMemoryFlag,
 		utils.EthashCachesOnDiskFlag,
@@ -120,7 +120,7 @@ var (
 		utils.MiningEnabledFlag,
 		utils.MinerThreadsFlag,
 		utils.MinerNotifyFlag,
-		utils.MinerGasTargetFlag,
+		utils.LegacyMinerGasTargetFlag,
 		utils.MinerGasLimitFlag,
 		utils.MinerGasPriceFlag,
 		utils.MinerEtherbaseFlag,
@@ -140,7 +140,6 @@ var (
 		utils.RopstenFlag,
 		utils.RinkebyFlag,
 		utils.GoerliFlag,
-		utils.YoloV3Flag,
 		utils.VMEnableDebugFlag,
 		utils.NetworkIdFlag,
 		utils.EthStatsURLFlag,
@@ -149,8 +148,7 @@ var (
 		utils.GpoBlocksFlag,
 		utils.GpoPercentileFlag,
 		utils.GpoMaxGasPriceFlag,
-		utils.EWASMInterpreterFlag,
-		utils.EVMInterpreterFlag,
+		utils.GpoIgnoreGasPriceFlag,
 		utils.MinerNotifyFullFlag,
 		configFileFlag,
 		utils.CatalystFlag,
@@ -198,6 +196,10 @@ var (
 		utils.MetricsInfluxDBUsernameFlag,
 		utils.MetricsInfluxDBPasswordFlag,
 		utils.MetricsInfluxDBTagsFlag,
+		utils.MetricsEnableInfluxDBV2Flag,
+		utils.MetricsInfluxDBTokenFlag,
+		utils.MetricsInfluxDBBucketFlag,
+		utils.MetricsInfluxDBOrganizationFlag,
 	}
 )
 
@@ -280,9 +282,6 @@ func prepare(ctx *cli.Context) {
 	case ctx.GlobalIsSet(utils.GoerliFlag.Name):
 		log.Info("Starting Geth on Görli testnet...")
 
-	case ctx.GlobalIsSet(utils.YoloV3Flag.Name):
-		log.Info("Starting Geth on YOLOv3 testnet...")
-
 	case ctx.GlobalIsSet(utils.DeveloperFlag.Name):
 		log.Info("Starting Geth in ephemeral dev mode...")
 
diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go
index 1af458af207ec662d88b753fc0dfc79eb1ea6839..35d027fb16485e8983f58266e436d145bb127d36 100644
--- a/cmd/geth/snapshot.go
+++ b/cmd/geth/snapshot.go
@@ -18,7 +18,9 @@ package main
 
 import (
 	"bytes"
+	"encoding/json"
 	"errors"
+	"os"
 	"time"
 
 	"github.com/ethereum/go-ethereum/cmd/utils"
@@ -142,6 +144,31 @@ verification. The default checking target is the HEAD state. It's basically iden
 to traverse-state, but the check granularity is smaller. 
 
 It's also usable without snapshot enabled.
+`,
+			},
+			{
+				Name:      "dump",
+				Usage:     "Dump a specific block from storage (same as 'geth dump' but using snapshots)",
+				ArgsUsage: "[? <blockHash> | <blockNum>]",
+				Action:    utils.MigrateFlags(dumpState),
+				Category:  "MISCELLANEOUS COMMANDS",
+				Flags: []cli.Flag{
+					utils.DataDirFlag,
+					utils.AncientFlag,
+					utils.RopstenFlag,
+					utils.RinkebyFlag,
+					utils.GoerliFlag,
+					utils.ExcludeCodeFlag,
+					utils.ExcludeStorageFlag,
+					utils.StartKeyFlag,
+					utils.DumpLimitFlag,
+				},
+				Description: `
+This command is semantically equivalent to 'geth dump', but uses the snapshots
+as the backend data source, making this command a lot faster. 
+
+The argument is interpreted as block number or hash. If none is provided, the latest
+block is used.
 `,
 			},
 		},
@@ -430,3 +457,73 @@ func parseRoot(input string) (common.Hash, error) {
 	}
 	return h, nil
 }
+
+func dumpState(ctx *cli.Context) error {
+	stack, _ := makeConfigNode(ctx)
+	defer stack.Close()
+
+	conf, db, root, err := parseDumpConfig(ctx, stack)
+	if err != nil {
+		return err
+	}
+	snaptree, err := snapshot.New(db, trie.NewDatabase(db), 256, root, false, false, false)
+	if err != nil {
+		return err
+	}
+	accIt, err := snaptree.AccountIterator(root, common.BytesToHash(conf.Start))
+	if err != nil {
+		return err
+	}
+	defer accIt.Release()
+
+	log.Info("Snapshot dumping started", "root", root)
+	var (
+		start    = time.Now()
+		logged   = time.Now()
+		accounts uint64
+	)
+	enc := json.NewEncoder(os.Stdout)
+	enc.Encode(struct {
+		Root common.Hash `json:"root"`
+	}{root})
+	for accIt.Next() {
+		account, err := snapshot.FullAccount(accIt.Account())
+		if err != nil {
+			return err
+		}
+		da := &state.DumpAccount{
+			Balance:   account.Balance.String(),
+			Nonce:     account.Nonce,
+			Root:      account.Root,
+			CodeHash:  account.CodeHash,
+			SecureKey: accIt.Hash().Bytes(),
+		}
+		if !conf.SkipCode && !bytes.Equal(account.CodeHash, emptyCode) {
+			da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
+		}
+		if !conf.SkipStorage {
+			da.Storage = make(map[common.Hash]string)
+
+			stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
+			if err != nil {
+				return err
+			}
+			for stIt.Next() {
+				da.Storage[stIt.Hash()] = common.Bytes2Hex(stIt.Slot())
+			}
+		}
+		enc.Encode(da)
+		accounts++
+		if time.Since(logged) > 8*time.Second {
+			log.Info("Snapshot dumping in progress", "at", accIt.Hash(), "accounts", accounts,
+				"elapsed", common.PrettyDuration(time.Since(start)))
+			logged = time.Now()
+		}
+		if conf.Max > 0 && accounts >= conf.Max {
+			break
+		}
+	}
+	log.Info("Snapshot dumping complete", "accounts", accounts,
+		"elapsed", common.PrettyDuration(time.Since(start)))
+	return nil
+}
diff --git a/cmd/geth/testdata/vcheck/vulnerabilities.json b/cmd/geth/testdata/vcheck/vulnerabilities.json
index 36509f95a98ad608b9892b32e1937b4723121004..92de0c9ccc70c288ec3292bb75a8126c420c0eee 100644
--- a/cmd/geth/testdata/vcheck/vulnerabilities.json
+++ b/cmd/geth/testdata/vcheck/vulnerabilities.json
@@ -52,13 +52,16 @@
     "check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$"
   },
   {
-    "name": "GethCrash",
+    "name": "Geth DoS via MULMOD",
     "uid": "GETH-2020-04",
     "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing",
-    "description": "Full details to be disclosed at a later date",
+    "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the geth-dependency.\n",
     "links": [
       "https://blog.ethereum.org/2020/11/12/geth_security_release/",
-      "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m"
+      "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m",
+      "https://github.com/holiman/uint256/releases/tag/v1.1.1",
+      "https://github.com/holiman/uint256/pull/80",
+      "https://github.com/ethereum/go-ethereum/pull/21368"
     ],
     "introduced": "v1.9.16",
     "fixed": "v1.9.18",
@@ -66,5 +69,51 @@
     "severity": "Critical",
     "CVE": "CVE-2020-26242",
     "check": "Geth\\/v1\\.9.(16|17).*$"
+  },
+  {
+    "name": "LES Server DoS via GetProofsV2",
+    "uid": "GETH-2020-05",
+    "summary": "A DoS vulnerability can make a LES server crash.",
+    "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running geth as a light server",
+    "links": [
+      "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q",
+      "https://github.com/ethereum/go-ethereum/pull/21896"
+    ],
+    "introduced": "v1.8.0",
+    "fixed": "v1.9.25",
+    "published": "2020-12-10",
+    "severity": "Medium",
+    "CVE": "CVE-2020-26264",
+    "check": "(Geth\\/v1\\.8\\.*)|(Geth\\/v1\\.9\\.\\d-.*)|(Geth\\/v1\\.9\\.1\\d-.*)|(Geth\\/v1\\.9\\.(20|21|22|23|24)-.*)$"
+  },
+  {
+    "name": "SELFDESTRUCT-recreate consensus flaw",
+    "uid": "GETH-2020-06",
+    "introduced": "v1.9.4",
+    "fixed": "v1.9.20",
+    "summary": "A consensus-vulnerability in Geth could cause a chain split, where vulnerable versions refuse to accept the canonical chain.",
+    "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a  `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn geth, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in geth, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n",
+    "links": [
+      "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4"
+    ],
+    "published": "2020-12-10",
+    "severity": "High",
+    "CVE": "CVE-2020-26265",
+    "check": "(Geth\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Geth\\/v1\\.9\\.1\\d-.*)$"
+  },
+  {
+    "name": "Not ready for London upgrade",
+    "uid": "GETH-2021-01",
+    "summary": "The client is not ready for the 'London' technical upgrade, and will deviate from the canonical chain when the London upgrade occurs (at block '12965000' around August 4, 2021.",
+    "description": "At (or around) August 4, Ethereum will undergo a technical upgrade called 'London'. Clients not upgraded will fail to progress on the canonical chain.",
+    "links": [
+      "https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md",
+      "https://notes.ethereum.org/@timbeiko/ropsten-postmortem"
+    ],
+    "introduced": "v1.10.1",
+    "fixed": "v1.10.6",
+    "published": "2020-12-10",
+    "severity": "High",
+    "check": "(Geth\\/v1\\.10\\.(1|2|3|4|5)-.*)$"
   }
 ]
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index 980794db7358ef5484d54ae5170c0c75bb6926d0..708edcc79325a57b6c8152e3eab9337575c0339e 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -44,7 +44,6 @@ var AppHelpFlagGroups = []flags.FlagGroup{
 			utils.MainnetFlag,
 			utils.GoerliFlag,
 			utils.RinkebyFlag,
-			utils.YoloV3Flag,
 			utils.RopstenFlag,
 			utils.SyncModeFlag,
 			utils.ExitWhenSyncedFlag,
@@ -182,7 +181,6 @@ var AppHelpFlagGroups = []flags.FlagGroup{
 			utils.MinerNotifyFlag,
 			utils.MinerNotifyFullFlag,
 			utils.MinerGasPriceFlag,
-			utils.MinerGasTargetFlag,
 			utils.MinerGasLimitFlag,
 			utils.MinerEtherbaseFlag,
 			utils.MinerExtraDataFlag,
@@ -196,14 +194,13 @@ var AppHelpFlagGroups = []flags.FlagGroup{
 			utils.GpoBlocksFlag,
 			utils.GpoPercentileFlag,
 			utils.GpoMaxGasPriceFlag,
+			utils.GpoIgnoreGasPriceFlag,
 		},
 	},
 	{
 		Name: "VIRTUAL MACHINE",
 		Flags: []cli.Flag{
 			utils.VMEnableDebugFlag,
-			utils.EVMInterpreterFlag,
-			utils.EWASMInterpreterFlag,
 		},
 	},
 	{
@@ -227,6 +224,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
 			utils.LegacyRPCCORSDomainFlag,
 			utils.LegacyRPCVirtualHostsFlag,
 			utils.LegacyRPCApiFlag,
+			utils.LegacyMinerGasTargetFlag,
 		},
 	},
 	{
diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go
index a76ee19a068fbf0dd6b7690dae3176a2b981f6ff..35cfada66fd3f2299b838134b764983222c802d6 100644
--- a/cmd/puppeth/module_dashboard.go
+++ b/cmd/puppeth/module_dashboard.go
@@ -80,12 +80,10 @@ var dashboardContent = `
 								<ul class="nav side-menu">
 									{{if .EthstatsPage}}<li id="stats_menu"><a onclick="load('#stats')"><i class="fa fa-tachometer"></i> Network Stats</a></li>{{end}}
 									{{if .ExplorerPage}}<li id="explorer_menu"><a onclick="load('#explorer')"><i class="fa fa-database"></i> Block Explorer</a></li>{{end}}
-									{{if .WalletPage}}<li id="wallet_menu"><a onclick="load('#wallet')"><i class="fa fa-address-book-o"></i> Browser Wallet</a></li>{{end}}
 									{{if .FaucetPage}}<li id="faucet_menu"><a onclick="load('#faucet')"><i class="fa fa-bath"></i> Crypto Faucet</a></li>{{end}}
 									<li id="connect_menu"><a><i class="fa fa-plug"></i> Connect Yourself</a>
 										<ul id="connect_list" class="nav child_menu">
 											<li><a onclick="$('#connect_menu').removeClass('active'); $('#connect_list').toggle(); load('#geth')">Go Ethereum: Geth</a></li>
-											<li><a onclick="$('#connect_menu').removeClass('active'); $('#connect_list').toggle(); load('#mist')">Go Ethereum: Wallet & Mist</a></li>
 											<li><a onclick="$('#connect_menu').removeClass('active'); $('#connect_list').toggle(); load('#mobile')">Go Ethereum: Android & iOS</a></li>{{if .Ethash}}
 											<li><a onclick="$('#connect_menu').removeClass('active'); $('#connect_list').toggle(); load('#other')">Other Ethereum Clients</a></li>{{end}}
 										</ul>
@@ -186,58 +184,6 @@ var dashboardContent = `
 							</div>
 						</div>
 					</div>
-					<div id="mist" hidden style="padding: 16px;">
-						<div class="page-title">
-							<div class="title_left">
-								<h3>Connect Yourself &ndash; Go Ethereum: Wallet &amp; Mist</h3>
-							</div>
-						</div>
-						<div class="clearfix"></div>
-						<div class="row">
-							<div class="col-md-6">
-								<div class="x_panel">
-									<div class="x_title">
-										<h2><i class="fa fa-credit-card" aria-hidden="true"></i> Desktop wallet <small>Interacts with accounts and contracts</small></h2>
-										<div class="clearfix"></div>
-									</div>
-									<div class="x_content">
-										<p>The Ethereum Wallet is an <a href="https://electron.atom.io/" target="about:blank">Electron</a> based desktop application to manage your Ethereum accounts and funds. Beside the usual account life-cycle operations you would expect to perform, the wallet also provides a means to send transactions from your accounts and to interact with smart contracts deployed on the network.</p>
-										<p>Under the hood the wallet is backed by a go-ethereum full node, meaning that a mid range machine is assumed. Similarly, synchronization is based on <strong>fast-sync</strong>, which will download all blockchain data from the network and make it available to the wallet. Light nodes cannot currently fully back the wallet, but it's a target actively pursued.</p>
-										<br/>
-										<p>To connect with the Ethereum Wallet, you'll need to initialize your private network first via Geth as the wallet does not currently support calling Geth directly. To initialize your local chain, download <a href="/{{.GethGenesis}}"><code>{{.GethGenesis}}</code></a> and run:
-											<pre>geth --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}</pre>
-										</p>
-										<p>With your local chain initialized, you can start the Ethereum Wallet:
-											<pre>ethereumwallet --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}</pre>
-										<p>
-										<br/>
-										<p>You can download the Ethereum Wallet from <a href="https://github.com/ethereum/mist/releases" target="about:blank">https://github.com/ethereum/mist/releases</a>.</p>
-									</div>
-								</div>
-							</div>
-							<div class="col-md-6">
-								<div class="x_panel">
-									<div class="x_title">
-										<h2><i class="fa fa-picture-o" aria-hidden="true"></i> Mist browser <small>Interacts with third party DApps</small></h2>
-										<div class="clearfix"></div>
-									</div>
-									<div class="x_content">
-										<p>The Mist browser is an <a href="https://electron.atom.io/" target="about:blank">Electron</a> based desktop application to load and interact with Ethereum enabled third party web DApps. Beside all the functionality provided by the Ethereum Wallet, Mist is an extended web-browser where loaded pages have access to the Ethereum network via a web3.js provider, and may also interact with users' own accounts (given proper authorization and confirmation of course).</p>
-										<p>Under the hood the browser is backed by a go-ethereum full node, meaning that a mid range machine is assumed. Similarly, synchronization is based on <strong>fast-sync</strong>, which will download all blockchain data from the network and make it available to the wallet. Light nodes cannot currently fully back the wallet, but it's a target actively pursued.</p>
-										<br/>
-										<p>To connect with the Mist browser, you'll need to initialize your private network first via Geth as Mist does not currently support calling Geth directly. To initialize your local chain, download <a href="/{{.GethGenesis}}"><code>{{.GethGenesis}}</code></a> and run:
-											<pre>geth --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}</pre>
-										</p>
-										<p>With your local chain initialized, you can start Mist:
-											<pre>mist --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}</pre>
-										<p>
-										<br/>
-										<p>You can download the Mist browser from <a href="https://github.com/ethereum/mist/releases" target="about:blank">https://github.com/ethereum/mist/releases</a>.</p>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
 					<div id="mobile" hidden style="padding: 16px;">
 						<div class="page-title">
 							<div class="title_left">
@@ -416,7 +362,7 @@ try! node?.start();
 										<div class="clearfix"></div>
 									</div>
 									<div style="display: inline-block; vertical-align: bottom; width: 623px; margin-top: 16px;">
-										<p>Puppeth is a tool to aid you in creating a new Ethereum network down to the genesis block, bootnodes, signers, ethstats server, crypto faucet, wallet browsers, block explorer, dashboard and more; without the hassle that it would normally entail to manually configure all these services one by one.</p>
+										<p>Puppeth is a tool to aid you in creating a new Ethereum network down to the genesis block, bootnodes, signers, ethstats server, crypto faucet,  block explorer, dashboard and more; without the hassle that it would normally entail to manually configure all these services one by one.</p>
 										<p>Puppeth uses ssh to dial in to remote servers, and builds its network components out of docker containers using docker-compose. The user is guided through the process via a command line wizard that does the heavy lifting and topology configuration automatically behind the scenes.</p>
 										<br/>
 										<p>Puppeth is distributed as part of the <a href="https://geth.ethereum.org/downloads/" target="about:blank">Geth &amp; Tools</a> bundles, but can also be installed separately via:<pre>go get github.com/ethereum/go-ethereum/cmd/puppeth</pre></p>
@@ -461,9 +407,6 @@ try! node?.start();
 					case "#explorer":
 						url = "//{{.ExplorerPage}}";
 						break;
-					case "#wallet":
-						url = "//{{.WalletPage}}";
-						break;
 					case "#faucet":
 						url = "//{{.FaucetPage}}";
 						break;
@@ -539,7 +482,7 @@ ADD puppeth.png /dashboard/puppeth.png
 
 EXPOSE 80
 
-CMD ["node", "/server.js"]
+CMD ["node", "./server.js"]
 `
 
 // dashboardComposefile is the docker-compose.yml file required to deploy and
@@ -587,7 +530,6 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
 		"VHost":        config.host,
 		"EthstatsPage": config.ethstats,
 		"ExplorerPage": config.explorer,
-		"WalletPage":   config.wallet,
 		"FaucetPage":   config.faucet,
 	})
 	files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
@@ -615,7 +557,6 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
 		"NetworkTitle":      strings.Title(network),
 		"EthstatsPage":      config.ethstats,
 		"ExplorerPage":      config.explorer,
-		"WalletPage":        config.wallet,
 		"FaucetPage":        config.faucet,
 		"GethGenesis":       network + ".json",
 		"Bootnodes":         conf.bootnodes,
@@ -695,7 +636,6 @@ type dashboardInfos struct {
 
 	ethstats string
 	explorer string
-	wallet   string
 	faucet   string
 }
 
@@ -707,7 +647,6 @@ func (info *dashboardInfos) Report() map[string]string {
 		"Website listener port": strconv.Itoa(info.port),
 		"Ethstats service":      info.ethstats,
 		"Explorer service":      info.explorer,
-		"Wallet service":        info.wallet,
 		"Faucet service":        info.faucet,
 	}
 }
@@ -748,7 +687,6 @@ func checkDashboard(client *sshClient, network string) (*dashboardInfos, error)
 		port:     port,
 		ethstats: infos.envvars["ETHSTATS_PAGE"],
 		explorer: infos.envvars["EXPLORER_PAGE"],
-		wallet:   infos.envvars["WALLET_PAGE"],
 		faucet:   infos.envvars["FAUCET_PAGE"],
 	}, nil
 }
diff --git a/cmd/puppeth/module_ethstats.go b/cmd/puppeth/module_ethstats.go
index 58ecb83951e00be6b458c8532828ac59b9164542..abed4db5fc50e7b2cb702f5bcae4a01e80817b3e 100644
--- a/cmd/puppeth/module_ethstats.go
+++ b/cmd/puppeth/module_ethstats.go
@@ -158,7 +158,7 @@ func checkEthstats(client *sshClient, network string) (*ethstatsInfos, error) {
 	if port != 80 && port != 443 {
 		config += fmt.Sprintf(":%d", port)
 	}
-	// Retrieve the IP blacklist
+	// Retrieve the IP banned list
 	banned := strings.Split(infos.envvars["BANNED"], ",")
 
 	// Run a sanity check to see if the port is reachable
diff --git a/cmd/puppeth/module_wallet.go b/cmd/puppeth/module_wallet.go
deleted file mode 100644
index 336e408903e352d021e4bde376779dd37dfcd381..0000000000000000000000000000000000000000
--- a/cmd/puppeth/module_wallet.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-	"bytes"
-	"fmt"
-	"html/template"
-	"math/rand"
-	"path/filepath"
-	"strconv"
-	"strings"
-
-	"github.com/ethereum/go-ethereum/log"
-)
-
-// walletDockerfile is the Dockerfile required to run a web wallet.
-var walletDockerfile = `
-FROM puppeth/wallet:latest
-
-ADD genesis.json /genesis.json
-
-RUN \
-  echo 'node server.js &'                     > wallet.sh && \
-	echo 'geth --cache 512 init /genesis.json' >> wallet.sh && \
-	echo $'exec geth --networkid {{.NetworkID}} --port {{.NodePort}} --bootnodes {{.Bootnodes}} --ethstats \'{{.Ethstats}}\' --cache=512 --http --http.addr=0.0.0.0 --http.corsdomain "*" --http.vhosts "*"' >> wallet.sh
-
-RUN \
-	sed -i 's/PuppethNetworkID/{{.NetworkID}}/g' dist/js/etherwallet-master.js && \
-	sed -i 's/PuppethNetwork/{{.Network}}/g'     dist/js/etherwallet-master.js && \
-	sed -i 's/PuppethDenom/{{.Denom}}/g'         dist/js/etherwallet-master.js && \
-	sed -i 's/PuppethHost/{{.Host}}/g'           dist/js/etherwallet-master.js && \
-	sed -i 's/PuppethRPCPort/{{.RPCPort}}/g'     dist/js/etherwallet-master.js
-
-ENTRYPOINT ["/bin/sh", "wallet.sh"]
-`
-
-// walletComposefile is the docker-compose.yml file required to deploy and
-// maintain a web wallet.
-var walletComposefile = `
-version: '2'
-services:
-  wallet:
-    build: .
-    image: {{.Network}}/wallet
-    container_name: {{.Network}}_wallet_1
-    ports:
-      - "{{.NodePort}}:{{.NodePort}}"
-      - "{{.NodePort}}:{{.NodePort}}/udp"
-      - "{{.RPCPort}}:8545"{{if not .VHost}}
-      - "{{.WebPort}}:80"{{end}}
-    volumes:
-      - {{.Datadir}}:/root/.ethereum
-    environment:
-      - NODE_PORT={{.NodePort}}/tcp
-      - STATS={{.Ethstats}}{{if .VHost}}
-      - VIRTUAL_HOST={{.VHost}}
-      - VIRTUAL_PORT=80{{end}}
-    logging:
-      driver: "json-file"
-      options:
-        max-size: "1m"
-        max-file: "10"
-    restart: always
-`
-
-// deployWallet deploys a new web wallet container to a remote machine via SSH,
-// docker and docker-compose. If an instance with the specified network name
-// already exists there, it will be overwritten!
-func deployWallet(client *sshClient, network string, bootnodes []string, config *walletInfos, nocache bool) ([]byte, error) {
-	// Generate the content to upload to the server
-	workdir := fmt.Sprintf("%d", rand.Int63())
-	files := make(map[string][]byte)
-
-	dockerfile := new(bytes.Buffer)
-	template.Must(template.New("").Parse(walletDockerfile)).Execute(dockerfile, map[string]interface{}{
-		"Network":   strings.ToTitle(network),
-		"Denom":     strings.ToUpper(network),
-		"NetworkID": config.network,
-		"NodePort":  config.nodePort,
-		"RPCPort":   config.rpcPort,
-		"Bootnodes": strings.Join(bootnodes, ","),
-		"Ethstats":  config.ethstats,
-		"Host":      client.address,
-	})
-	files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
-
-	composefile := new(bytes.Buffer)
-	template.Must(template.New("").Parse(walletComposefile)).Execute(composefile, map[string]interface{}{
-		"Datadir":  config.datadir,
-		"Network":  network,
-		"NodePort": config.nodePort,
-		"RPCPort":  config.rpcPort,
-		"VHost":    config.webHost,
-		"WebPort":  config.webPort,
-		"Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")],
-	})
-	files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
-
-	files[filepath.Join(workdir, "genesis.json")] = config.genesis
-
-	// Upload the deployment files to the remote server (and clean up afterwards)
-	if out, err := client.Upload(files); err != nil {
-		return out, err
-	}
-	defer client.Run("rm -rf " + workdir)
-
-	// Build and deploy the boot or seal node service
-	if nocache {
-		return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
-	}
-	return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
-}
-
-// walletInfos is returned from a web wallet status check to allow reporting
-// various configuration parameters.
-type walletInfos struct {
-	genesis  []byte
-	network  int64
-	datadir  string
-	ethstats string
-	nodePort int
-	rpcPort  int
-	webHost  string
-	webPort  int
-}
-
-// Report converts the typed struct into a plain string->string map, containing
-// most - but not all - fields for reporting to the user.
-func (info *walletInfos) Report() map[string]string {
-	report := map[string]string{
-		"Data directory":         info.datadir,
-		"Ethstats username":      info.ethstats,
-		"Node listener port ":    strconv.Itoa(info.nodePort),
-		"RPC listener port ":     strconv.Itoa(info.rpcPort),
-		"Website address ":       info.webHost,
-		"Website listener port ": strconv.Itoa(info.webPort),
-	}
-	return report
-}
-
-// checkWallet does a health-check against web wallet server to verify whether
-// it's running, and if yes, whether it's responsive.
-func checkWallet(client *sshClient, network string) (*walletInfos, error) {
-	// Inspect a possible web wallet container on the host
-	infos, err := inspectContainer(client, fmt.Sprintf("%s_wallet_1", network))
-	if err != nil {
-		return nil, err
-	}
-	if !infos.running {
-		return nil, ErrServiceOffline
-	}
-	// Resolve the port from the host, or the reverse proxy
-	webPort := infos.portmap["80/tcp"]
-	if webPort == 0 {
-		if proxy, _ := checkNginx(client, network); proxy != nil {
-			webPort = proxy.port
-		}
-	}
-	if webPort == 0 {
-		return nil, ErrNotExposed
-	}
-	// Resolve the host from the reverse-proxy and the config values
-	host := infos.envvars["VIRTUAL_HOST"]
-	if host == "" {
-		host = client.server
-	}
-	// Run a sanity check to see if the devp2p and RPC ports are reachable
-	nodePort := infos.portmap[infos.envvars["NODE_PORT"]]
-	if err = checkPort(client.server, nodePort); err != nil {
-		log.Warn("Wallet devp2p port seems unreachable", "server", client.server, "port", nodePort, "err", err)
-	}
-	rpcPort := infos.portmap["8545/tcp"]
-	if err = checkPort(client.server, rpcPort); err != nil {
-		log.Warn("Wallet RPC port seems unreachable", "server", client.server, "port", rpcPort, "err", err)
-	}
-	// Assemble and return the useful infos
-	stats := &walletInfos{
-		datadir:  infos.volumes["/root/.ethereum"],
-		nodePort: nodePort,
-		rpcPort:  rpcPort,
-		webHost:  host,
-		webPort:  webPort,
-		ethstats: infos.envvars["STATS"],
-	}
-	return stats, nil
-}
diff --git a/cmd/puppeth/wizard_dashboard.go b/cmd/puppeth/wizard_dashboard.go
index b699d7617d0069030608c5363d1635a0e9ed08b2..b64bdca0b98b855cb0282b696aab27390511990c 100644
--- a/cmd/puppeth/wizard_dashboard.go
+++ b/cmd/puppeth/wizard_dashboard.go
@@ -60,7 +60,7 @@ func (w *wizard) deployDashboard() {
 			available[service] = append(available[service], server)
 		}
 	}
-	for _, service := range []string{"ethstats", "explorer", "wallet", "faucet"} {
+	for _, service := range []string{"ethstats", "explorer", "faucet"} {
 		// Gather all the locally hosted pages of this type
 		var pages []string
 		for _, server := range available[service] {
@@ -79,10 +79,6 @@ func (w *wizard) deployDashboard() {
 				if infos, err := checkExplorer(client, w.network); err == nil {
 					port = infos.port
 				}
-			case "wallet":
-				if infos, err := checkWallet(client, w.network); err == nil {
-					port = infos.webPort
-				}
 			case "faucet":
 				if infos, err := checkFaucet(client, w.network); err == nil {
 					port = infos.port
@@ -127,8 +123,6 @@ func (w *wizard) deployDashboard() {
 			infos.ethstats = page
 		case "explorer":
 			infos.explorer = page
-		case "wallet":
-			infos.wallet = page
 		case "faucet":
 			infos.faucet = page
 		}
diff --git a/cmd/puppeth/wizard_ethstats.go b/cmd/puppeth/wizard_ethstats.go
index 58ff3efbe98693acea4d730ff544ad7b676526ec..95cab9da4633ba8fb48be8ab3f435d23927c65f5 100644
--- a/cmd/puppeth/wizard_ethstats.go
+++ b/cmd/puppeth/wizard_ethstats.go
@@ -63,20 +63,20 @@ func (w *wizard) deployEthstats() {
 		fmt.Printf("What should be the secret password for the API? (default = %s)\n", infos.secret)
 		infos.secret = w.readDefaultString(infos.secret)
 	}
-	// Gather any blacklists to ban from reporting
+	// Gather any banned lists to ban from reporting
 	if existed {
 		fmt.Println()
-		fmt.Printf("Keep existing IP %v blacklist (y/n)? (default = yes)\n", infos.banned)
+		fmt.Printf("Keep existing IP %v in the banned list (y/n)? (default = yes)\n", infos.banned)
 		if !w.readDefaultYesNo(true) {
 			// The user might want to clear the entire list, although generally probably not
 			fmt.Println()
-			fmt.Printf("Clear out blacklist and start over (y/n)? (default = no)\n")
+			fmt.Printf("Clear out the banned list and start over (y/n)? (default = no)\n")
 			if w.readDefaultYesNo(false) {
 				infos.banned = nil
 			}
 			// Offer the user to explicitly add/remove certain IP addresses
 			fmt.Println()
-			fmt.Println("Which additional IP addresses should be blacklisted?")
+			fmt.Println("Which additional IP addresses should be in the banned list?")
 			for {
 				if ip := w.readIPAddress(); ip != "" {
 					infos.banned = append(infos.banned, ip)
@@ -85,7 +85,7 @@ func (w *wizard) deployEthstats() {
 				break
 			}
 			fmt.Println()
-			fmt.Println("Which IP addresses should not be blacklisted?")
+			fmt.Println("Which IP addresses should not be in the banned list?")
 			for {
 				if ip := w.readIPAddress(); ip != "" {
 					for i, addr := range infos.banned {
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 4f701fa1c3052e57bac317b17219dd7f94524552..ae5977b3723c2c06592317eea0a02f6388bf95a8 100644
--- a/cmd/puppeth/wizard_genesis.go
+++ b/cmd/puppeth/wizard_genesis.go
@@ -240,8 +240,8 @@ func (w *wizard) manageGenesis() {
 		w.conf.Genesis.Config.BerlinBlock = w.readDefaultBigInt(w.conf.Genesis.Config.BerlinBlock)
 
 		fmt.Println()
-		fmt.Printf("Which block should YOLOv3 come into effect? (default = %v)\n", w.conf.Genesis.Config.YoloV3Block)
-		w.conf.Genesis.Config.YoloV3Block = w.readDefaultBigInt(w.conf.Genesis.Config.YoloV3Block)
+		fmt.Printf("Which block should London come into effect? (default = %v)\n", w.conf.Genesis.Config.LondonBlock)
+		w.conf.Genesis.Config.LondonBlock = w.readDefaultBigInt(w.conf.Genesis.Config.LondonBlock)
 
 		out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", "  ")
 		fmt.Printf("Chain configuration updated:\n\n%s\n", out)
diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go
index 99ca11bb177610b66d117b513ccabfb58b5d5aed..7b5671e6dfa42f3918d529a685fdd0fac50f06fd 100644
--- a/cmd/puppeth/wizard_netstats.go
+++ b/cmd/puppeth/wizard_netstats.go
@@ -141,14 +141,6 @@ func (w *wizard) gatherStats(server string, pubkey []byte, client *sshClient) *s
 	} else {
 		stat.services["explorer"] = infos.Report()
 	}
-	logger.Debug("Checking for wallet availability")
-	if infos, err := checkWallet(client, w.network); err != nil {
-		if err != ErrServiceUnknown {
-			stat.services["wallet"] = map[string]string{"offline": err.Error()}
-		}
-	} else {
-		stat.services["wallet"] = infos.Report()
-	}
 	logger.Debug("Checking for faucet availability")
 	if infos, err := checkFaucet(client, w.network); err != nil {
 		if err != ErrServiceUnknown {
diff --git a/cmd/puppeth/wizard_network.go b/cmd/puppeth/wizard_network.go
index 97302c0df8bba4b0e5d0dd701835df33c3262990..d015e06ebb10ffdbe4b4060a998fa532d7ae1e15 100644
--- a/cmd/puppeth/wizard_network.go
+++ b/cmd/puppeth/wizard_network.go
@@ -175,9 +175,8 @@ func (w *wizard) deployComponent() {
 	fmt.Println(" 2. Bootnode  - Entry point of the network")
 	fmt.Println(" 3. Sealer    - Full node minting new blocks")
 	fmt.Println(" 4. Explorer  - Chain analysis webservice")
-	fmt.Println(" 5. Wallet    - Browser wallet for quick sends")
-	fmt.Println(" 6. Faucet    - Crypto faucet to give away funds")
-	fmt.Println(" 7. Dashboard - Website listing above web-services")
+	fmt.Println(" 5. Faucet    - Crypto faucet to give away funds")
+	fmt.Println(" 6. Dashboard - Website listing above web-services")
 
 	switch w.read() {
 	case "1":
@@ -189,10 +188,8 @@ func (w *wizard) deployComponent() {
 	case "4":
 		w.deployExplorer()
 	case "5":
-		w.deployWallet()
-	case "6":
 		w.deployFaucet()
-	case "7":
+	case "6":
 		w.deployDashboard()
 	default:
 		log.Error("That's not something I can do")
diff --git a/cmd/puppeth/wizard_wallet.go b/cmd/puppeth/wizard_wallet.go
deleted file mode 100644
index ca1ea5bd25915cd5bf60af8ee080c70e596057a2..0000000000000000000000000000000000000000
--- a/cmd/puppeth/wizard_wallet.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"time"
-
-	"github.com/ethereum/go-ethereum/log"
-)
-
-// deployWallet creates a new web wallet based on some user input.
-func (w *wizard) deployWallet() {
-	// Do some sanity check before the user wastes time on input
-	if w.conf.Genesis == nil {
-		log.Error("No genesis block configured")
-		return
-	}
-	if w.conf.ethstats == "" {
-		log.Error("No ethstats server configured")
-		return
-	}
-	// Select the server to interact with
-	server := w.selectServer()
-	if server == "" {
-		return
-	}
-	client := w.servers[server]
-
-	// Retrieve any active node configurations from the server
-	infos, err := checkWallet(client, w.network)
-	if err != nil {
-		infos = &walletInfos{
-			nodePort: 30303, rpcPort: 8545, webPort: 80, webHost: client.server,
-		}
-	}
-	existed := err == nil
-
-	infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", "  ")
-	infos.network = w.conf.Genesis.Config.ChainID.Int64()
-
-	// Figure out which port to listen on
-	fmt.Println()
-	fmt.Printf("Which port should the wallet listen on? (default = %d)\n", infos.webPort)
-	infos.webPort = w.readDefaultInt(infos.webPort)
-
-	// Figure which virtual-host to deploy ethstats on
-	if infos.webHost, err = w.ensureVirtualHost(client, infos.webPort, infos.webHost); err != nil {
-		log.Error("Failed to decide on wallet host", "err", err)
-		return
-	}
-	// Figure out where the user wants to store the persistent data
-	fmt.Println()
-	if infos.datadir == "" {
-		fmt.Printf("Where should data be stored on the remote machine?\n")
-		infos.datadir = w.readString()
-	} else {
-		fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
-		infos.datadir = w.readDefaultString(infos.datadir)
-	}
-	// Figure out which port to listen on
-	fmt.Println()
-	fmt.Printf("Which TCP/UDP port should the backing node listen on? (default = %d)\n", infos.nodePort)
-	infos.nodePort = w.readDefaultInt(infos.nodePort)
-
-	fmt.Println()
-	fmt.Printf("Which port should the backing RPC API listen on? (default = %d)\n", infos.rpcPort)
-	infos.rpcPort = w.readDefaultInt(infos.rpcPort)
-
-	// Set a proper name to report on the stats page
-	fmt.Println()
-	if infos.ethstats == "" {
-		fmt.Printf("What should the wallet be called on the stats page?\n")
-		infos.ethstats = w.readString() + ":" + w.conf.ethstats
-	} else {
-		fmt.Printf("What should the wallet be called on the stats page? (default = %s)\n", infos.ethstats)
-		infos.ethstats = w.readDefaultString(infos.ethstats) + ":" + w.conf.ethstats
-	}
-	// Try to deploy the wallet on the host
-	nocache := false
-	if existed {
-		fmt.Println()
-		fmt.Printf("Should the wallet be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultYesNo(false)
-	}
-	if out, err := deployWallet(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
-		log.Error("Failed to deploy wallet container", "err", err)
-		if len(out) > 0 {
-			fmt.Printf("%s\n", out)
-		}
-		return
-	}
-	// All ok, run a network scan to pick any changes up
-	log.Info("Waiting for node to finish booting")
-	time.Sleep(3 * time.Second)
-
-	w.networkStats()
-}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 9e4c34254cc6f8c1d039881994c87b0a3a70c568..d394a579a60f8cc6d0becf16773517f7edfc4957 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -125,10 +125,6 @@ var (
 		Name:  "keystore",
 		Usage: "Directory for the keystore (default = inside the datadir)",
 	}
-	NoUSBFlag = cli.BoolFlag{
-		Name:  "nousb",
-		Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)",
-	}
 	USBFlag = cli.BoolFlag{
 		Name:  "usb",
 		Usage: "Enable monitoring and management of USB hardware wallets",
@@ -151,10 +147,6 @@ var (
 		Name:  "goerli",
 		Usage: "Görli network: pre-configured proof-of-authority test network",
 	}
-	YoloV3Flag = cli.BoolFlag{
-		Name:  "yolov3",
-		Usage: "YOLOv3 network: pre-configured proof-of-authority shortlived test network.",
-	}
 	RinkebyFlag = cli.BoolFlag{
 		Name:  "rinkeby",
 		Usage: "Rinkeby network: pre-configured proof-of-authority test network",
@@ -184,7 +176,7 @@ var (
 		Name:  "exitwhensynced",
 		Usage: "Exits after block synchronisation completes",
 	}
-	IterativeOutputFlag = cli.BoolFlag{
+	IterativeOutputFlag = cli.BoolTFlag{
 		Name:  "iterative",
 		Usage: "Print streaming JSON iteratively, delimited by newlines",
 	}
@@ -200,6 +192,16 @@ var (
 		Name:  "nocode",
 		Usage: "Exclude contract code (save db lookups)",
 	}
+	StartKeyFlag = cli.StringFlag{
+		Name:  "start",
+		Usage: "Start position. Either a hash or address",
+		Value: "0x0000000000000000000000000000000000000000000000000000000000000000",
+	}
+	DumpLimitFlag = cli.Uint64Flag{
+		Name:  "limit",
+		Usage: "Max number of elements (0 = no limit)",
+		Value: 0,
+	}
 	defaultSyncMode = ethconfig.Defaults.SyncMode
 	SyncModeFlag    = TextMarshalerFlag{
 		Name:  "syncmode",
@@ -233,9 +235,9 @@ var (
 		Usage: "Megabytes of memory allocated to bloom-filter for pruning",
 		Value: 2048,
 	}
-	OverrideBerlinFlag = cli.Uint64Flag{
-		Name:  "override.berlin",
-		Usage: "Manually specify Berlin fork-block, overriding the bundled setting",
+	OverrideLondonFlag = cli.Uint64Flag{
+		Name:  "override.london",
+		Usage: "Manually specify London fork-block, overriding the bundled setting",
 	}
 	// Light server and client settings
 	LightServeFlag = cli.IntFlag{
@@ -438,11 +440,6 @@ var (
 		Name:  "miner.notify.full",
 		Usage: "Notify with pending block headers instead of work packages",
 	}
-	MinerGasTargetFlag = cli.Uint64Flag{
-		Name:  "miner.gastarget",
-		Usage: "Target gas floor for mined blocks",
-		Value: ethconfig.Defaults.Miner.GasFloor,
-	}
 	MinerGasLimitFlag = cli.Uint64Flag{
 		Name:  "miner.gaslimit",
 		Usage: "Target gas ceiling for mined blocks",
@@ -669,10 +666,10 @@ var (
 	}
 
 	// ATM the url is left to the user and deployment to
-	JSpathFlag = cli.StringFlag{
+	JSpathFlag = DirectoryFlag{
 		Name:  "jspath",
 		Usage: "JavaScript root path for `loadScript`",
-		Value: ".",
+		Value: DirectoryString("."),
 	}
 
 	// Gas price oracle settings
@@ -691,6 +688,11 @@ var (
 		Usage: "Maximum gas price will be recommended by gpo",
 		Value: ethconfig.Defaults.GPO.MaxPrice.Int64(),
 	}
+	GpoIgnoreGasPriceFlag = cli.Int64Flag{
+		Name:  "gpo.ignoreprice",
+		Usage: "Gas price below which gpo will ignore transactions",
+		Value: ethconfig.Defaults.GPO.IgnorePrice.Int64(),
+	}
 
 	// Metrics flags
 	MetricsEnabledFlag = cli.BoolFlag{
@@ -749,15 +751,28 @@ var (
 		Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
 		Value: metrics.DefaultConfig.InfluxDBTags,
 	}
-	EWASMInterpreterFlag = cli.StringFlag{
-		Name:  "vm.ewasm",
-		Usage: "External ewasm configuration (default = built-in interpreter)",
-		Value: "",
+
+	MetricsEnableInfluxDBV2Flag = cli.BoolFlag{
+		Name:  "metrics.influxdbv2",
+		Usage: "Enable metrics export/push to an external InfluxDB v2 database",
 	}
-	EVMInterpreterFlag = cli.StringFlag{
-		Name:  "vm.evm",
-		Usage: "External EVM configuration (default = built-in interpreter)",
-		Value: "",
+
+	MetricsInfluxDBTokenFlag = cli.StringFlag{
+		Name:  "metrics.influxdb.token",
+		Usage: "Token to authorize access to the database (v2 only)",
+		Value: metrics.DefaultConfig.InfluxDBToken,
+	}
+
+	MetricsInfluxDBBucketFlag = cli.StringFlag{
+		Name:  "metrics.influxdb.bucket",
+		Usage: "InfluxDB bucket name to push reported metrics to (v2 only)",
+		Value: metrics.DefaultConfig.InfluxDBBucket,
+	}
+
+	MetricsInfluxDBOrganizationFlag = cli.StringFlag{
+		Name:  "metrics.influxdb.organization",
+		Usage: "InfluxDB organization name (v2 only)",
+		Value: metrics.DefaultConfig.InfluxDBOrganization,
 	}
 
 	CatalystFlag = cli.BoolFlag{
@@ -782,9 +797,6 @@ func MakeDataDir(ctx *cli.Context) string {
 		if ctx.GlobalBool(GoerliFlag.Name) {
 			return filepath.Join(path, "goerli")
 		}
-		if ctx.GlobalBool(YoloV3Flag.Name) {
-			return filepath.Join(path, "yolo-v3")
-		}
 		return path
 	}
 	Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@@ -837,8 +849,6 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
 		urls = params.RinkebyBootnodes
 	case ctx.GlobalBool(GoerliFlag.Name):
 		urls = params.GoerliBootnodes
-	case ctx.GlobalBool(YoloV3Flag.Name):
-		urls = params.YoloV3Bootnodes
 	case cfg.BootstrapNodes != nil:
 		return // already set, don't apply defaults.
 	}
@@ -1223,6 +1233,9 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
 	if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
 		cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name)
 	}
+	if ctx.GlobalIsSet(DeveloperFlag.Name) {
+		cfg.UseLightweightKDF = true
+	}
 	if ctx.GlobalIsSet(LightKDFFlag.Name) {
 		cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name)
 	}
@@ -1279,8 +1292,6 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) {
 		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby")
 	case ctx.GlobalBool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir():
 		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
-	case ctx.GlobalBool(YoloV3Flag.Name) && cfg.DataDir == node.DefaultDataDir():
-		cfg.DataDir = filepath.Join(node.DefaultDataDir(), "yolo-v3")
 	}
 }
 
@@ -1288,8 +1299,7 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
 	// If we are running the light client, apply another group
 	// settings for gas oracle.
 	if light {
-		cfg.Blocks = ethconfig.LightClientGPO.Blocks
-		cfg.Percentile = ethconfig.LightClientGPO.Percentile
+		*cfg = ethconfig.LightClientGPO
 	}
 	if ctx.GlobalIsSet(GpoBlocksFlag.Name) {
 		cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name)
@@ -1300,6 +1310,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
 	if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) {
 		cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name))
 	}
+	if ctx.GlobalIsSet(GpoIgnoreGasPriceFlag.Name) {
+		cfg.IgnorePrice = big.NewInt(ctx.GlobalInt64(GpoIgnoreGasPriceFlag.Name))
+	}
 }
 
 func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
@@ -1380,9 +1393,6 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
 	if ctx.GlobalIsSet(MinerExtraDataFlag.Name) {
 		cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name))
 	}
-	if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
-		cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name)
-	}
 	if ctx.GlobalIsSet(MinerGasLimitFlag.Name) {
 		cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name)
 	}
@@ -1395,6 +1405,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
 	if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) {
 		cfg.Noverify = ctx.GlobalBool(MinerNoVerfiyFlag.Name)
 	}
+	if ctx.GlobalIsSet(LegacyMinerGasTargetFlag.Name) {
+		log.Warn("The generic --miner.gastarget flag is deprecated and will be removed in the future!")
+	}
 }
 
 func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) {
@@ -1464,7 +1477,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
 // SetEthConfig applies eth-related command line flags to the config.
 func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
 	// Avoid conflicting network flags
-	CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV3Flag)
+	CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag)
 	CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
 	CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
 	if ctx.GlobalString(GCModeFlag.Name) == "archive" && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 {
@@ -1574,13 +1587,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
 		cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
 	}
 
-	if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
-		cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
-	}
-
-	if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
-		cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
-	}
 	if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) {
 		cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name)
 	}
@@ -1628,15 +1634,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
 		}
 		cfg.Genesis = core.DefaultGoerliGenesisBlock()
 		SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
-	case ctx.GlobalBool(YoloV3Flag.Name):
-		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
-			cfg.NetworkId = new(big.Int).SetBytes([]byte("yolov3x")).Uint64() // "yolov3x"
-		}
-		cfg.Genesis = core.DefaultYoloV3GenesisBlock()
 	case ctx.GlobalBool(DeveloperFlag.Name):
 		if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
 			cfg.NetworkId = 1337
 		}
+		cfg.SyncMode = downloader.FullSync
 		// Create new developer account or reuse existing one
 		var (
 			developer  accounts.Account
@@ -1748,11 +1750,36 @@ func SetupMetrics(ctx *cli.Context) {
 		log.Info("Enabling metrics collection")
 
 		var (
-			enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
-			endpoint     = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
-			database     = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
-			username     = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
-			password     = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
+			enableExport   = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
+			enableExportV2 = ctx.GlobalBool(MetricsEnableInfluxDBV2Flag.Name)
+		)
+
+		if enableExport || enableExportV2 {
+			CheckExclusive(ctx, MetricsEnableInfluxDBFlag, MetricsEnableInfluxDBV2Flag)
+
+			v1FlagIsSet := ctx.GlobalIsSet(MetricsInfluxDBUsernameFlag.Name) ||
+				ctx.GlobalIsSet(MetricsInfluxDBPasswordFlag.Name)
+
+			v2FlagIsSet := ctx.GlobalIsSet(MetricsInfluxDBTokenFlag.Name) ||
+				ctx.GlobalIsSet(MetricsInfluxDBOrganizationFlag.Name) ||
+				ctx.GlobalIsSet(MetricsInfluxDBBucketFlag.Name)
+
+			if enableExport && v2FlagIsSet {
+				Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2")
+			} else if enableExportV2 && v1FlagIsSet {
+				Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1")
+			}
+		}
+
+		var (
+			endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
+			database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
+			username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
+			password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
+
+			token        = ctx.GlobalString(MetricsInfluxDBTokenFlag.Name)
+			bucket       = ctx.GlobalString(MetricsInfluxDBBucketFlag.Name)
+			organization = ctx.GlobalString(MetricsInfluxDBOrganizationFlag.Name)
 		)
 
 		if enableExport {
@@ -1761,6 +1788,12 @@ func SetupMetrics(ctx *cli.Context) {
 			log.Info("Enabling metrics export to InfluxDB")
 
 			go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
+		} else if enableExportV2 {
+			tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name))
+
+			log.Info("Enabling metrics export to InfluxDB (v2)")
+
+			go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap)
 		}
 
 		if ctx.GlobalIsSet(MetricsHTTPFlag.Name) {
@@ -1821,8 +1854,6 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
 		genesis = core.DefaultRinkebyGenesisBlock()
 	case ctx.GlobalBool(GoerliFlag.Name):
 		genesis = core.DefaultGoerliGenesisBlock()
-	case ctx.GlobalBool(YoloV3Flag.Name):
-		genesis = core.DefaultYoloV3GenesisBlock()
 	case ctx.GlobalBool(DeveloperFlag.Name):
 		Fatalf("Developer chains are ephemeral")
 	}
diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go
index fb5fde6576959d15bd6a49eb761bcf96faacda79..627f77475319367f07a1ef3a18088c103c8135d0 100644
--- a/cmd/utils/flags_legacy.go
+++ b/cmd/utils/flags_legacy.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/ethereum/go-ethereum/eth/ethconfig"
 	"github.com/ethereum/go-ethereum/node"
 	"gopkg.in/urfave/cli.v1"
 )
@@ -33,10 +34,17 @@ var ShowDeprecated = cli.Command{
 	Description: "Show flags that have been deprecated and will soon be removed",
 }
 
-var DeprecatedFlags = []cli.Flag{}
+var DeprecatedFlags = []cli.Flag{
+	LegacyMinerGasTargetFlag,
+	NoUSBFlag,
+}
 
 var (
 	// (Deprecated May 2020, shown in aliased flags section)
+	NoUSBFlag = cli.BoolFlag{
+		Name:  "nousb",
+		Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)",
+	}
 	LegacyRPCEnabledFlag = cli.BoolFlag{
 		Name:  "rpc",
 		Usage: "Enable the HTTP-RPC server (deprecated and will be removed June 2021, use --http)",
@@ -66,6 +74,12 @@ var (
 		Usage: "API's offered over the HTTP-RPC interface (deprecated and will be removed June 2021, use --http.api)",
 		Value: "",
 	}
+	// (Deprecated July 2021, shown in aliased flags section)
+	LegacyMinerGasTargetFlag = cli.Uint64Flag{
+		Name:  "miner.gastarget",
+		Usage: "Target gas floor for mined blocks (deprecated)",
+		Value: ethconfig.Defaults.Miner.GasFloor,
+	}
 )
 
 // showDeprecated displays deprecated flags that will be soon removed from the codebase.
@@ -74,7 +88,8 @@ func showDeprecated(*cli.Context) {
 	fmt.Println("The following flags are deprecated and will be removed in the future!")
 	fmt.Println("--------------------------------------------------------------------")
 	fmt.Println()
-	// TODO remove when there are newly deprecated flags
-	fmt.Println("no deprecated flags to show at this time")
+	for _, flag := range DeprecatedFlags {
+		fmt.Println(flag.String())
+	}
 	fmt.Println()
 }
diff --git a/common/debug.go b/common/debug.go
index 61acd8ce70f8b77e4b4ffb581e996d69fef48e03..28c52b4a9cd51cb64f2b5b31f8de9ddf586a8a91 100644
--- a/common/debug.go
+++ b/common/debug.go
@@ -37,8 +37,8 @@ func Report(extra ...interface{}) {
 	fmt.Fprintln(os.Stderr, "#### BUG! PLEASE REPORT ####")
 }
 
-// PrintDepricationWarning prinst the given string in a box using fmt.Println.
-func PrintDepricationWarning(str string) {
+// PrintDeprecationWarning prints the given string in a box using fmt.Println.
+func PrintDeprecationWarning(str string) {
 	line := strings.Repeat("#", len(str)+4)
 	emptyLine := strings.Repeat(" ", len(str))
 	fmt.Printf(`
diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index 4f8393982f401e1ab119ee369e29ab29ff13f42c..d0e23b20c21ca9dffddcfb01ca3004792bd17cb1 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -866,7 +866,7 @@ func (c *Bor) GetCurrentSpan(headerHash common.Hash) (*Span, error) {
 	msgData := (hexutil.Bytes)(data)
 	toAddress := common.HexToAddress(c.config.ValidatorContract)
 	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
-	result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
+	result, err := c.ethAPI.Call(ctx, ethapi.TransactionArgs{
 		Gas:  &gas,
 		To:   &toAddress,
 		Data: &msgData,
@@ -916,7 +916,7 @@ func (c *Bor) GetCurrentValidators(headerHash common.Hash, blockNumber uint64) (
 	msgData := (hexutil.Bytes)(data)
 	toAddress := common.HexToAddress(c.config.ValidatorContract)
 	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
-	result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
+	result, err := c.ethAPI.Call(ctx, ethapi.TransactionArgs{
 		Gas:  &gas,
 		To:   &toAddress,
 		Data: &msgData,
diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go
index abe3d02701582234b879d2bb0d80c2169d204c5a..582358e0cbaed4bf6d396c3c2eaafb75df602797 100644
--- a/consensus/bor/genesis_contracts_client.go
+++ b/consensus/bor/genesis_contracts_client.go
@@ -86,7 +86,7 @@ func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int,
 	msgData := (hexutil.Bytes)(data)
 	toAddress := common.HexToAddress(gc.StateReceiverContract)
 	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
-	result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{
+	result, err := gc.ethAPI.Call(context.Background(), ethapi.TransactionArgs{
 		Gas:  &gas,
 		To:   &toAddress,
 		Data: &msgData,
diff --git a/consensus/clique/api.go b/consensus/clique/api.go
index 8e9a1e7deb6f0d44a3a958a1847f81750a65eb2a..6129b5cc528ce5dce066ef55401957185fe88775 100644
--- a/consensus/clique/api.go
+++ b/consensus/clique/api.go
@@ -17,11 +17,14 @@
 package clique
 
 import (
+	"encoding/json"
 	"fmt"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/consensus"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/rpc"
 )
 
@@ -175,3 +178,51 @@ func (api *API) Status() (*status, error) {
 		NumBlocks:     numBlocks,
 	}, nil
 }
+
+type blockNumberOrHashOrRLP struct {
+	*rpc.BlockNumberOrHash
+	RLP hexutil.Bytes `json:"rlp,omitempty"`
+}
+
+func (sb *blockNumberOrHashOrRLP) UnmarshalJSON(data []byte) error {
+	bnOrHash := new(rpc.BlockNumberOrHash)
+	// Try to unmarshal bNrOrHash
+	if err := bnOrHash.UnmarshalJSON(data); err == nil {
+		sb.BlockNumberOrHash = bnOrHash
+		return nil
+	}
+	// Try to unmarshal RLP
+	var input string
+	if err := json.Unmarshal(data, &input); err != nil {
+		return err
+	}
+	sb.RLP = hexutil.MustDecode(input)
+	return nil
+}
+
+// GetSigner returns the signer for a specific clique block.
+// Can be called with either a blocknumber, blockhash or an rlp encoded blob.
+// The RLP encoded blob can either be a block or a header.
+func (api *API) GetSigner(rlpOrBlockNr *blockNumberOrHashOrRLP) (common.Address, error) {
+	if len(rlpOrBlockNr.RLP) == 0 {
+		blockNrOrHash := rlpOrBlockNr.BlockNumberOrHash
+		var header *types.Header
+		if blockNrOrHash == nil {
+			header = api.chain.CurrentHeader()
+		} else if hash, ok := blockNrOrHash.Hash(); ok {
+			header = api.chain.GetHeaderByHash(hash)
+		} else if number, ok := blockNrOrHash.Number(); ok {
+			header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
+		}
+		return api.clique.Author(header)
+	}
+	block := new(types.Block)
+	if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, block); err == nil {
+		return api.clique.Author(block.Header())
+	}
+	header := new(types.Header)
+	if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, header); err != nil {
+		return common.Address{}, err
+	}
+	return api.clique.Author(header)
+}
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index c62e180faa9141f32931b3042a5573cb41fbc35c..449095e7230f35f6c7db30df8d0374237f94b943 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -20,6 +20,7 @@ package clique
 import (
 	"bytes"
 	"errors"
+	"fmt"
 	"io"
 	"math/big"
 	"math/rand"
@@ -293,6 +294,11 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
 			return errInvalidDifficulty
 		}
 	}
+	// Verify that the gas limit is <= 2^63-1
+	cap := uint64(0x7fffffffffffffff)
+	if header.GasLimit > cap {
+		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
+	}
 	// If all checks passed, validate any special fields for hard forks
 	if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
 		return err
@@ -324,6 +330,22 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
 	if parent.Time+c.config.Period > header.Time {
 		return errInvalidTimestamp
 	}
+	// Verify that the gasUsed is <= gasLimit
+	if header.GasUsed > header.GasLimit {
+		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
+	}
+	if !chain.Config().IsLondon(header.Number) {
+		// Verify BaseFee not present before EIP-1559 fork.
+		if header.BaseFee != nil {
+			return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
+		}
+		if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
+			return err
+		}
+	} else if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil {
+		// Verify the header's EIP-1559 attributes.
+		return err
+	}
 	// Retrieve the snapshot needed to verify this header and cache it
 	snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
 	if err != nil {
@@ -688,7 +710,7 @@ func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API {
 func SealHash(header *types.Header) (hash common.Hash) {
 	hasher := sha3.NewLegacyKeccak256()
 	encodeSigHeader(hasher, header)
-	hasher.Sum(hash[:0])
+	hasher.(crypto.KeccakState).Read(hash[:])
 	return hash
 }
 
@@ -706,7 +728,7 @@ func CliqueRLP(header *types.Header) []byte {
 }
 
 func encodeSigHeader(w io.Writer, header *types.Header) {
-	err := rlp.Encode(w, []interface{}{
+	enc := []interface{}{
 		header.ParentHash,
 		header.UncleHash,
 		header.Coinbase,
@@ -722,8 +744,11 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
 		header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short
 		header.MixDigest,
 		header.Nonce,
-	})
-	if err != nil {
+	}
+	if header.BaseFee != nil {
+		enc = append(enc, header.BaseFee)
+	}
+	if err := rlp.Encode(w, enc); err != nil {
 		panic("can't encode: " + err.Error())
 	}
 }
diff --git a/consensus/clique/clique_test.go b/consensus/clique/clique_test.go
index e33a212a3b7181b66731d0cf12c76796bc44dc6a..1bd32acd3746cdec19116220d03a522ce295e136 100644
--- a/consensus/clique/clique_test.go
+++ b/consensus/clique/clique_test.go
@@ -47,8 +47,9 @@ func TestReimportMirroredState(t *testing.T) {
 	genspec := &core.Genesis{
 		ExtraData: make([]byte, extraVanity+common.AddressLength+extraSeal),
 		Alloc: map[common.Address]core.GenesisAccount{
-			addr: {Balance: big.NewInt(1)},
+			addr: {Balance: big.NewInt(10000000000000000)},
 		},
+		BaseFee: big.NewInt(params.InitialBaseFee),
 	}
 	copy(genspec.ExtraData[extraVanity:], addr[:])
 	genesis := genspec.MustCommit(db)
@@ -65,7 +66,7 @@ func TestReimportMirroredState(t *testing.T) {
 		// We want to simulate an empty middle block, having the same state as the
 		// first one. The last is needs a state change again to force a reorg.
 		if i != 1 {
-			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(addr), common.Address{0x00}, new(big.Int), params.TxGas, nil, nil), signer, key)
+			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(addr), common.Address{0x00}, new(big.Int), params.TxGas, block.BaseFee(), nil), signer, key)
 			if err != nil {
 				panic(err)
 			}
@@ -111,3 +112,16 @@ func TestReimportMirroredState(t *testing.T) {
 		t.Fatalf("chain head mismatch: have %d, want %d", head, 3)
 	}
 }
+
+func TestSealHash(t *testing.T) {
+	have := SealHash(&types.Header{
+		Difficulty: new(big.Int),
+		Number:     new(big.Int),
+		Extra:      make([]byte, 32+65),
+		BaseFee:    new(big.Int),
+	})
+	want := common.HexToHash("0xbd3d1fa43fbc4c5bfcc91b179ec92e2861df3654de60468beb908ff805359e8f")
+	if have != want {
+		t.Errorf("have %x, want %x", have, want)
+	}
+}
diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go
index 039ba919bf8df9db6066ff7f70a5bbf1d145132a..094868ca744dde118fc417bfdb04e23973543efb 100644
--- a/consensus/clique/snapshot_test.go
+++ b/consensus/clique/snapshot_test.go
@@ -19,6 +19,7 @@ package clique
 import (
 	"bytes"
 	"crypto/ecdsa"
+	"math/big"
 	"sort"
 	"testing"
 
@@ -395,6 +396,7 @@ func TestClique(t *testing.T) {
 		// Create the genesis block with the initial set of signers
 		genesis := &core.Genesis{
 			ExtraData: make([]byte, extraVanity+common.AddressLength*len(signers)+extraSeal),
+			BaseFee:   big.NewInt(params.InitialBaseFee),
 		}
 		for j, signer := range signers {
 			copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:])
diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index 249c2f65ebb7a810674fdf32faaf77b6196a9e54..5743387f6c7f90f5bddf9d686d748f232a45e9cc 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -45,6 +45,11 @@ var (
 	maxUncles                     = 2                 // Maximum number of uncles allowed in a single block
 	allowedFutureBlockTimeSeconds = int64(15)         // Max seconds from current time allowed for blocks, before they're considered future blocks
 
+	// calcDifficultyEip3554 is the difficulty adjustment algorithm as specified by EIP 3554.
+	// It offsets the bomb a total of 9.7M blocks.
+	// Specification EIP-3554: https://eips.ethereum.org/EIPS/eip-3554
+	calcDifficultyEip3554 = makeDifficultyCalculator(big.NewInt(9700000))
+
 	// calcDifficultyEip2384 is the difficulty adjustment algorithm as specified by EIP 2384.
 	// It offsets the bomb 4M blocks from Constantinople, so in total 9M blocks.
 	// Specification EIP-2384: https://eips.ethereum.org/EIPS/eip-2384
@@ -210,7 +215,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
 		ancestors[parent] = ancestorHeader
 		// If the ancestor doesn't have any uncles, we don't have to iterate them
 		if ancestorHeader.UncleHash != types.EmptyUncleHash {
-			// Need to add those uncles to the blacklist too
+			// Need to add those uncles to the banned list too
 			ancestor := chain.GetBlock(parent, number)
 			if ancestor == nil {
 				break
@@ -279,16 +284,18 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
 	if header.GasUsed > header.GasLimit {
 		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
 	}
-
-	// Verify that the gas limit remains within allowed bounds
-	diff := int64(parent.GasLimit) - int64(header.GasLimit)
-	if diff < 0 {
-		diff *= -1
-	}
-	limit := parent.GasLimit / params.GasLimitBoundDivisor
-
-	if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
-		return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
+	// Verify the block's gas usage and (if applicable) verify the base fee.
+	if !chain.Config().IsLondon(header.Number) {
+		// Verify BaseFee not present before EIP-1559 fork.
+		if header.BaseFee != nil {
+			return fmt.Errorf("invalid baseFee before fork: have %d, expected 'nil'", header.BaseFee)
+		}
+		if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
+			return err
+		}
+	} else if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil {
+		// Verify the header's EIP-1559 attributes.
+		return err
 	}
 	// Verify that the block number is parent's +1
 	if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
@@ -325,6 +332,8 @@ func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Heade
 	switch {
 	case config.IsCatalyst(next):
 		return big.NewInt(1)
+	case config.IsLondon(next):
+		return calcDifficultyEip3554(time, parent)
 	case config.IsMuirGlacier(next):
 		return calcDifficultyEip2384(time, parent)
 	case config.IsConstantinople(next):
@@ -597,7 +606,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
 func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
 	hasher := sha3.NewLegacyKeccak256()
 
-	rlp.Encode(hasher, []interface{}{
+	enc := []interface{}{
 		header.ParentHash,
 		header.UncleHash,
 		header.Coinbase,
@@ -611,7 +620,11 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
 		header.GasUsed,
 		header.Time,
 		header.Extra,
-	})
+	}
+	if header.BaseFee != nil {
+		enc = append(enc, header.BaseFee)
+	}
+	rlp.Encode(hasher, enc)
 	hasher.Sum(hash[:0])
 	return hash
 }
diff --git a/consensus/ethash/difficulty.go b/consensus/ethash/difficulty.go
index 59c4ac74191f7b2081f2fc26d377c0fa085eb902..66a18059c617e263b3fa1ec3fdb3856294c6be48 100644
--- a/consensus/ethash/difficulty.go
+++ b/consensus/ethash/difficulty.go
@@ -52,8 +52,7 @@ func CalcDifficultyFrontierU256(time uint64, parent *types.Header) *big.Int {
 		- num = block.number
 	*/
 
-	pDiff := uint256.NewInt()
-	pDiff.SetFromBig(parent.Difficulty) // pDiff: pdiff
+	pDiff, _ := uint256.FromBig(parent.Difficulty) // pDiff: pdiff
 	adjust := pDiff.Clone()
 	adjust.Rsh(adjust, difficultyBoundDivisor) // adjust: pDiff / 2048
 
@@ -96,8 +95,7 @@ func CalcDifficultyHomesteadU256(time uint64, parent *types.Header) *big.Int {
 		- num = block.number
 	*/
 
-	pDiff := uint256.NewInt()
-	pDiff.SetFromBig(parent.Difficulty) // pDiff: pdiff
+	pDiff, _ := uint256.FromBig(parent.Difficulty) // pDiff: pdiff
 	adjust := pDiff.Clone()
 	adjust.Rsh(adjust, difficultyBoundDivisor) // adjust: pDiff / 2048
 
diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go
index 1830e672b1ff310601db68419c368de4e0565308..6fa60ef6a8bbd191055a05a60c5012a109281b76 100644
--- a/consensus/ethash/sealer.go
+++ b/consensus/ethash/sealer.go
@@ -140,8 +140,9 @@ func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan s
 	)
 	// Start generating random nonces until we abort or find a good one
 	var (
-		attempts = int64(0)
-		nonce    = seed
+		attempts  = int64(0)
+		nonce     = seed
+		powBuffer = new(big.Int)
 	)
 	logger := ethash.config.Log.New("miner", id)
 	logger.Trace("Started ethash search for new nonces", "seed", seed)
@@ -163,7 +164,7 @@ search:
 			}
 			// Compute the PoW value of this nonce
 			digest, result := hashimotoFull(dataset.dataset, hash, nonce)
-			if new(big.Int).SetBytes(result).Cmp(target) <= 0 {
+			if powBuffer.SetBytes(result).Cmp(target) <= 0 {
 				// Correct nonce found, create a new header with it
 				header = types.CopyHeader(header)
 				header.Nonce = types.EncodeNonce(nonce)
diff --git a/consensus/misc/eip1559.go b/consensus/misc/eip1559.go
new file mode 100644
index 0000000000000000000000000000000000000000..8fca0fdc7092d96b8b1a62f5cced6d01eeeae124
--- /dev/null
+++ b/consensus/misc/eip1559.go
@@ -0,0 +1,93 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package misc
+
+import (
+	"fmt"
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/math"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/params"
+)
+
+// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
+// - gas limit check
+// - basefee check
+func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error {
+	// Verify that the gas limit remains within allowed bounds
+	parentGasLimit := parent.GasLimit
+	if !config.IsLondon(parent.Number) {
+		parentGasLimit = parent.GasLimit * params.ElasticityMultiplier
+	}
+	if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
+		return err
+	}
+	// Verify the header is not malformed
+	if header.BaseFee == nil {
+		return fmt.Errorf("header is missing baseFee")
+	}
+	// Verify the baseFee is correct based on the parent header.
+	expectedBaseFee := CalcBaseFee(config, parent)
+	if header.BaseFee.Cmp(expectedBaseFee) != 0 {
+		return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d",
+			expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed)
+	}
+	return nil
+}
+
+// CalcBaseFee calculates the basefee of the header.
+func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
+	// If the current block is the first EIP-1559 block, return the InitialBaseFee.
+	if !config.IsLondon(parent.Number) {
+		return new(big.Int).SetUint64(params.InitialBaseFee)
+	}
+
+	var (
+		parentGasTarget          = parent.GasLimit / params.ElasticityMultiplier
+		parentGasTargetBig       = new(big.Int).SetUint64(parentGasTarget)
+		baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator)
+	)
+	// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
+	if parent.GasUsed == parentGasTarget {
+		return new(big.Int).Set(parent.BaseFee)
+	}
+	if parent.GasUsed > parentGasTarget {
+		// If the parent block used more gas than its target, the baseFee should increase.
+		gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget)
+		x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
+		y := x.Div(x, parentGasTargetBig)
+		baseFeeDelta := math.BigMax(
+			x.Div(y, baseFeeChangeDenominator),
+			common.Big1,
+		)
+
+		return x.Add(parent.BaseFee, baseFeeDelta)
+	} else {
+		// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
+		gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed)
+		x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
+		y := x.Div(x, parentGasTargetBig)
+		baseFeeDelta := x.Div(y, baseFeeChangeDenominator)
+
+		return math.BigMax(
+			x.Sub(parent.BaseFee, baseFeeDelta),
+			common.Big0,
+		)
+	}
+}
diff --git a/consensus/misc/eip1559_test.go b/consensus/misc/eip1559_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..fd400b6881d1abe301bfeb8f5e83de48189d542d
--- /dev/null
+++ b/consensus/misc/eip1559_test.go
@@ -0,0 +1,132 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package misc
+
+import (
+	"math/big"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/params"
+)
+
+// copyConfig does a _shallow_ copy of a given config. Safe to set new values, but
+// do not use e.g. SetInt() on the numbers. For testing only
+func copyConfig(original *params.ChainConfig) *params.ChainConfig {
+	return &params.ChainConfig{
+		ChainID:             original.ChainID,
+		HomesteadBlock:      original.HomesteadBlock,
+		DAOForkBlock:        original.DAOForkBlock,
+		DAOForkSupport:      original.DAOForkSupport,
+		EIP150Block:         original.EIP150Block,
+		EIP150Hash:          original.EIP150Hash,
+		EIP155Block:         original.EIP155Block,
+		EIP158Block:         original.EIP158Block,
+		ByzantiumBlock:      original.ByzantiumBlock,
+		ConstantinopleBlock: original.ConstantinopleBlock,
+		PetersburgBlock:     original.PetersburgBlock,
+		IstanbulBlock:       original.IstanbulBlock,
+		MuirGlacierBlock:    original.MuirGlacierBlock,
+		BerlinBlock:         original.BerlinBlock,
+		LondonBlock:         original.LondonBlock,
+		CatalystBlock:       original.CatalystBlock,
+		Ethash:              original.Ethash,
+		Clique:              original.Clique,
+	}
+}
+
+func config() *params.ChainConfig {
+	config := copyConfig(params.TestChainConfig)
+	config.LondonBlock = big.NewInt(5)
+	return config
+}
+
+// TestBlockGasLimits tests the gasLimit checks for blocks both across
+// the EIP-1559 boundary and post-1559 blocks
+func TestBlockGasLimits(t *testing.T) {
+	initial := new(big.Int).SetUint64(params.InitialBaseFee)
+
+	for i, tc := range []struct {
+		pGasLimit uint64
+		pNum      int64
+		gasLimit  uint64
+		ok        bool
+	}{
+		// Transitions from non-london to london
+		{10000000, 4, 20000000, true},  // No change
+		{10000000, 4, 20019530, true},  // Upper limit
+		{10000000, 4, 20019531, false}, // Upper +1
+		{10000000, 4, 19980470, true},  // Lower limit
+		{10000000, 4, 19980469, false}, // Lower limit -1
+		// London to London
+		{20000000, 5, 20000000, true},
+		{20000000, 5, 20019530, true},  // Upper limit
+		{20000000, 5, 20019531, false}, // Upper limit +1
+		{20000000, 5, 19980470, true},  // Lower limit
+		{20000000, 5, 19980469, false}, // Lower limit -1
+		{40000000, 5, 40039061, true},  // Upper limit
+		{40000000, 5, 40039062, false}, // Upper limit +1
+		{40000000, 5, 39960939, true},  // lower limit
+		{40000000, 5, 39960938, false}, // Lower limit -1
+	} {
+		parent := &types.Header{
+			GasUsed:  tc.pGasLimit / 2,
+			GasLimit: tc.pGasLimit,
+			BaseFee:  initial,
+			Number:   big.NewInt(tc.pNum),
+		}
+		header := &types.Header{
+			GasUsed:  tc.gasLimit / 2,
+			GasLimit: tc.gasLimit,
+			BaseFee:  initial,
+			Number:   big.NewInt(tc.pNum + 1),
+		}
+		err := VerifyEip1559Header(config(), parent, header)
+		if tc.ok && err != nil {
+			t.Errorf("test %d: Expected valid header: %s", i, err)
+		}
+		if !tc.ok && err == nil {
+			t.Errorf("test %d: Expected invalid header", i)
+		}
+	}
+}
+
+// TestCalcBaseFee assumes all blocks are 1559-blocks
+func TestCalcBaseFee(t *testing.T) {
+	tests := []struct {
+		parentBaseFee   int64
+		parentGasLimit  uint64
+		parentGasUsed   uint64
+		expectedBaseFee int64
+	}{
+		{params.InitialBaseFee, 20000000, 10000000, params.InitialBaseFee}, // usage == target
+		{params.InitialBaseFee, 20000000, 9000000, 987500000},              // usage below target
+		{params.InitialBaseFee, 20000000, 11000000, 1012500000},            // usage above target
+	}
+	for i, test := range tests {
+		parent := &types.Header{
+			Number:   common.Big32,
+			GasLimit: test.parentGasLimit,
+			GasUsed:  test.parentGasUsed,
+			BaseFee:  big.NewInt(test.parentBaseFee),
+		}
+		if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
+			t.Errorf("test %d: have %d  want %d, ", i, have, want)
+		}
+	}
+}
diff --git a/consensus/misc/gaslimit.go b/consensus/misc/gaslimit.go
new file mode 100644
index 0000000000000000000000000000000000000000..25f35300b94d7b8413b3be47dbb13fc0fb0ba4b1
--- /dev/null
+++ b/consensus/misc/gaslimit.go
@@ -0,0 +1,42 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package misc
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/ethereum/go-ethereum/params"
+)
+
+// VerifyGaslimit verifies the header gas limit according increase/decrease
+// in relation to the parent gas limit.
+func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error {
+	// Verify that the gas limit remains within allowed bounds
+	diff := int64(parentGasLimit) - int64(headerGasLimit)
+	if diff < 0 {
+		diff *= -1
+	}
+	limit := parentGasLimit / params.GasLimitBoundDivisor
+	if uint64(diff) >= limit {
+		return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1)
+	}
+	if headerGasLimit < params.MinGasLimit {
+		return errors.New("invalid gas limit below 5000")
+	}
+	return nil
+}
diff --git a/contracts/checkpointoracle/oracle_test.go b/contracts/checkpointoracle/oracle_test.go
index 12184819297c6d1500c8a7780115861fcc9917e3..61dd8aec79b6e515cf5997f71c7b0a87bc36a02e 100644
--- a/contracts/checkpointoracle/oracle_test.go
+++ b/contracts/checkpointoracle/oracle_test.go
@@ -175,7 +175,13 @@ func TestCheckpointRegister(t *testing.T) {
 	sort.Sort(accounts)
 
 	// Deploy registrar contract
-	contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{accounts[0].addr: {Balance: big.NewInt(1000000000)}, accounts[1].addr: {Balance: big.NewInt(1000000000)}, accounts[2].addr: {Balance: big.NewInt(1000000000)}}, 10000000)
+	contractBackend := backends.NewSimulatedBackend(
+		core.GenesisAlloc{
+			accounts[0].addr: {Balance: big.NewInt(10000000000000000)},
+			accounts[1].addr: {Balance: big.NewInt(10000000000000000)},
+			accounts[2].addr: {Balance: big.NewInt(10000000000000000)},
+		}, 10000000,
+	)
 	defer contractBackend.Close()
 
 	transactOpts, _ := bind.NewKeyedTransactorWithChainID(accounts[0].key, big.NewInt(1337))
diff --git a/core/asm/lex_test.go b/core/asm/lex_test.go
index 6b8bd3d740be0c058bbafd0ab7ecd4e6e09fa161..53e05fbbba0ccee827499830f4e145d5b9525fc7 100644
--- a/core/asm/lex_test.go
+++ b/core/asm/lex_test.go
@@ -60,6 +60,10 @@ func TestLexer(t *testing.T) {
 			input:  "0123abc",
 			tokens: []token{{typ: lineStart}, {typ: number, text: "0123"}, {typ: element, text: "abc"}, {typ: eof}},
 		},
+		{
+			input:  "00123abc",
+			tokens: []token{{typ: lineStart}, {typ: number, text: "00123"}, {typ: element, text: "abc"}, {typ: eof}},
+		},
 		{
 			input:  "@foo",
 			tokens: []token{{typ: lineStart}, {typ: label, text: "foo"}, {typ: eof}},
diff --git a/core/asm/lexer.go b/core/asm/lexer.go
index 9eb8f914ac574ee9ccb89696d18d631756a95733..21cc8c46583733592de1f36e0bc4d85b9b672414 100644
--- a/core/asm/lexer.go
+++ b/core/asm/lexer.go
@@ -254,7 +254,7 @@ func lexInsideString(l *lexer) stateFn {
 
 func lexNumber(l *lexer) stateFn {
 	acceptance := Numbers
-	if l.accept("0") || l.accept("xX") {
+	if l.accept("xX") {
 		acceptance = HexadecimalNumbers
 	}
 	l.acceptRun(acceptance)
diff --git a/core/bench_test.go b/core/bench_test.go
index 0c49907e6433c7189119087eb96aaefd91c1fd46..ce288d372e087642b9d8e4c3af978142b268bdee 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -112,7 +112,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
 	from := 0
 	return func(i int, gen *BlockGen) {
 		block := gen.PrevBlock(i - 1)
-		gas := CalcGasLimit(block, block.GasLimit(), block.GasLimit())
+		gas := block.GasLimit()
 		for {
 			gas -= params.TxGas
 			if gas < params.TxGas {
diff --git a/core/block_validator.go b/core/block_validator.go
index 8dbd0f75520e9e9468d7522cb721736af36bab07..3763be0be08dd2a5e1cb5247fd5e80d51ac66910 100644
--- a/core/block_validator.go
+++ b/core/block_validator.go
@@ -103,37 +103,26 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
 }
 
 // CalcGasLimit computes the gas limit of the next block after parent. It aims
-// to keep the baseline gas above the provided floor, and increase it towards the
-// ceil if the blocks are full. If the ceil is exceeded, it will always decrease
-// the gas allowance.
-func CalcGasLimit(parent *types.Block, gasFloor, gasCeil uint64) uint64 {
-	// contrib = (parentGasUsed * 3 / 2) / 1024
-	contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor
-
-	// decay = parentGasLimit / 1024 -1
-	decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1
-
-	/*
-		strategy: gasLimit of block-to-mine is set based on parent's
-		gasUsed value.  if parentGasUsed > parentGasLimit * (2/3) then we
-		increase it, otherwise lower it (or leave it unchanged if it's right
-		at that usage) the amount increased/decreased depends on how far away
-		from parentGasLimit * (2/3) parentGasUsed is.
-	*/
-	limit := parent.GasLimit() - decay + contrib
-	if limit < params.MinGasLimit {
-		limit = params.MinGasLimit
+// to keep the baseline gas close to the provided target, and increase it towards
+// the target if the baseline gas is lower.
+func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 {
+	delta := parentGasLimit/params.GasLimitBoundDivisor - 1
+	limit := parentGasLimit
+	if desiredLimit < params.MinGasLimit {
+		desiredLimit = params.MinGasLimit
 	}
 	// If we're outside our allowed gas range, we try to hone towards them
-	if limit < gasFloor {
-		limit = parent.GasLimit() + decay
-		if limit > gasFloor {
-			limit = gasFloor
+	if limit < desiredLimit {
+		limit = parentGasLimit + delta
+		if limit > desiredLimit {
+			limit = desiredLimit
 		}
-	} else if limit > gasCeil {
-		limit = parent.GasLimit() - decay
-		if limit < gasCeil {
-			limit = gasCeil
+		return limit
+	}
+	if limit > desiredLimit {
+		limit = parentGasLimit - delta
+		if limit < desiredLimit {
+			limit = desiredLimit
 		}
 	}
 	return limit
diff --git a/core/block_validator_test.go b/core/block_validator_test.go
index dfb37b88cf8a06a42aec3eb5761b2550c33b777b..86f9835a01505c708b07b2240c0fd9f5bd424873 100644
--- a/core/block_validator_test.go
+++ b/core/block_validator_test.go
@@ -197,3 +197,35 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) {
 		t.Errorf("verification count too large: have %d, want below %d", verified, 2*threads)
 	}
 }
+
+func TestCalcGasLimit(t *testing.T) {
+	for i, tc := range []struct {
+		pGasLimit uint64
+		max       uint64
+		min       uint64
+	}{
+		{20000000, 20019530, 19980470},
+		{40000000, 40039061, 39960939},
+	} {
+		// Increase
+		if have, want := CalcGasLimit(tc.pGasLimit, 2*tc.pGasLimit), tc.max; have != want {
+			t.Errorf("test %d: have %d want <%d", i, have, want)
+		}
+		// Decrease
+		if have, want := CalcGasLimit(tc.pGasLimit, 0), tc.min; have != want {
+			t.Errorf("test %d: have %d want >%d", i, have, want)
+		}
+		// Small decrease
+		if have, want := CalcGasLimit(tc.pGasLimit, tc.pGasLimit-1), tc.pGasLimit-1; have != want {
+			t.Errorf("test %d: have %d want %d", i, have, want)
+		}
+		// Small increase
+		if have, want := CalcGasLimit(tc.pGasLimit, tc.pGasLimit+1), tc.pGasLimit+1; have != want {
+			t.Errorf("test %d: have %d want %d", i, have, want)
+		}
+		// No change
+		if have, want := CalcGasLimit(tc.pGasLimit, tc.pGasLimit), tc.pGasLimit; have != want {
+			t.Errorf("test %d: have %d want %d", i, have, want)
+		}
+	}
+}
diff --git a/core/blockchain.go b/core/blockchain.go
index 41b9374edd10d3018787df10ab3017a96019119c..87cdaded4165df6371e8a158595a1058a393ddc9 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -1842,8 +1842,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
 		}
 		// If the header is a banned one, straight out abort
 		if BadHashes[block.Hash()] {
-			bc.reportBlock(block, nil, ErrBlacklistedHash)
-			return it.index, ErrBlacklistedHash
+			bc.reportBlock(block, nil, ErrBannedHash)
+			return it.index, ErrBannedHash
 		}
 		// If the block is known (in the middle of the chain), it's a special case for
 		// Clique blocks where they can share state among each other, so importing an
@@ -2486,12 +2486,22 @@ func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
 // GetHeader retrieves a block header from the database by hash and number,
 // caching it if found.
 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
+	// Blockchain might have cached the whole block, only if not go to headerchain
+	if block, ok := bc.blockCache.Get(hash); ok {
+		return block.(*types.Block).Header()
+	}
+
 	return bc.hc.GetHeader(hash, number)
 }
 
 // GetHeaderByHash retrieves a block header from the database by hash, caching it if
 // found.
 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
+	// Blockchain might have cached the whole block, only if not go to headerchain
+	if block, ok := bc.blockCache.Get(hash); ok {
+		return block.(*types.Block).Header()
+	}
+
 	return bc.hc.GetHeaderByHash(hash)
 }
 
diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go
index 8bb39d2607dbc43788309edf72663dbf4ed8c959..aca5546e20485f2878f7b5f2437c8d0b265a4143 100644
--- a/core/blockchain_repair_test.go
+++ b/core/blockchain_repair_test.go
@@ -1770,7 +1770,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
 
 	// Initialize a fresh chain
 	var (
-		genesis = new(Genesis).MustCommit(db)
+		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 		engine  = ethash.NewFullFaker()
 		config  = &CacheConfig{
 			TrieCleanLimit: 256,
diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go
index e99b09cf8cb1c897c993de75dd770ce98ba85c44..27b6be6e13638680fe986bc3676017f7958648f6 100644
--- a/core/blockchain_sethead_test.go
+++ b/core/blockchain_sethead_test.go
@@ -1969,7 +1969,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
 
 	// Initialize a fresh chain
 	var (
-		genesis = new(Genesis).MustCommit(db)
+		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 		engine  = ethash.NewFullFaker()
 		config  = &CacheConfig{
 			TrieCleanLimit: 256,
diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go
index 75c09b421d165092eb700f7504fd45e0b48bdeac..94ec6879b79d2ad9cc14e139ff6ae082a8afd0a7 100644
--- a/core/blockchain_snapshot_test.go
+++ b/core/blockchain_snapshot_test.go
@@ -23,6 +23,7 @@ import (
 	"bytes"
 	"fmt"
 	"io/ioutil"
+	"math/big"
 	"os"
 	"strings"
 	"testing"
@@ -70,7 +71,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
 	}
 	// Initialize a fresh chain
 	var (
-		genesis = new(Genesis).MustCommit(db)
+		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 		engine  = ethash.NewFullFaker()
 		gendb   = rawdb.NewMemoryDatabase()
 
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 5004abd1c7a1e192a9f30faf82ffdb46f085f3cb..4e5df633b7e32f8151163c6a58c6a4e90ac2b87e 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -52,7 +52,7 @@ var (
 func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
 	var (
 		db      = rawdb.NewMemoryDatabase()
-		genesis = new(Genesis).MustCommit(db)
+		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 	)
 
 	// Initialize a fresh chain with only a genesis block
@@ -73,6 +73,10 @@ func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *B
 	return db, blockchain, err
 }
 
+func newGwei(n int64) *big.Int {
+	return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei))
+}
+
 // Test fork of length N starting from block i
 func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
 	// Copy old chain up to #i into a new db
@@ -469,8 +473,8 @@ func testBadHashes(t *testing.T, full bool) {
 
 		_, err = blockchain.InsertHeaderChain(headers, 1)
 	}
-	if !errors.Is(err, ErrBlacklistedHash) {
-		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
+	if !errors.Is(err, ErrBannedHash) {
+		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBannedHash)
 	}
 }
 
@@ -594,10 +598,11 @@ func TestFastVsFullChains(t *testing.T) {
 		gendb   = rawdb.NewMemoryDatabase()
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(1000000000000000)
 		gspec   = &Genesis{
-			Config: params.TestChainConfig,
-			Alloc:  GenesisAlloc{address: {Balance: funds}},
+			Config:  params.TestChainConfig,
+			Alloc:   GenesisAlloc{address: {Balance: funds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
 		}
 		genesis = gspec.MustCommit(gendb)
 		signer  = types.LatestSigner(gspec.Config)
@@ -608,7 +613,7 @@ func TestFastVsFullChains(t *testing.T) {
 		// If the block number is multiple of 3, send a few bonus transactions to the miner
 		if i%3 == 2 {
 			for j := 0; j < i%4+1; j++ {
-				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
+				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
 				if err != nil {
 					panic(err)
 				}
@@ -711,8 +716,12 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
 		gendb   = rawdb.NewMemoryDatabase()
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
-		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
+		funds   = big.NewInt(1000000000000000)
+		gspec   = &Genesis{
+			Config:  params.TestChainConfig,
+			Alloc:   GenesisAlloc{address: {Balance: funds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
+		}
 		genesis = gspec.MustCommit(gendb)
 	)
 	height := uint64(1024)
@@ -833,9 +842,9 @@ func TestChainTxReorgs(t *testing.T) {
 			Config:   params.TestChainConfig,
 			GasLimit: 3141592,
 			Alloc: GenesisAlloc{
-				addr1: {Balance: big.NewInt(1000000)},
-				addr2: {Balance: big.NewInt(1000000)},
-				addr3: {Balance: big.NewInt(1000000)},
+				addr1: {Balance: big.NewInt(1000000000000000)},
+				addr2: {Balance: big.NewInt(1000000000000000)},
+				addr3: {Balance: big.NewInt(1000000000000000)},
 			},
 		}
 		genesis = gspec.MustCommit(db)
@@ -845,8 +854,8 @@ func TestChainTxReorgs(t *testing.T) {
 	// Create two transactions shared between the chains:
 	//  - postponed: transaction included at a later block in the forked chain
 	//  - swapped: transaction included at the same block number in the forked chain
-	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
-	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
+	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
+	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
 
 	// Create two transactions that will be dropped by the forked chain:
 	//  - pastDrop: transaction dropped retroactively from a past block
@@ -862,13 +871,13 @@ func TestChainTxReorgs(t *testing.T) {
 	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
 		switch i {
 		case 0:
-			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
+			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
 
 			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
 			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
 
 		case 2:
-			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
+			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
 
 			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
 			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
@@ -887,18 +896,18 @@ func TestChainTxReorgs(t *testing.T) {
 	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
 		switch i {
 		case 0:
-			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
+			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
 			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
 
 		case 2:
 			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
 			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
 
-			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
+			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
 			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
 
 		case 3:
-			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
+			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
 			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
 		}
 	})
@@ -942,7 +951,7 @@ func TestLogReorgs(t *testing.T) {
 		db      = rawdb.NewMemoryDatabase()
 		// this code generates a log
 		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
-		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
+		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
 		genesis = gspec.MustCommit(db)
 		signer  = types.LatestSigner(gspec.Config)
 	)
@@ -954,7 +963,7 @@ func TestLogReorgs(t *testing.T) {
 	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
 	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
 		if i == 1 {
-			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
+			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
 			if err != nil {
 				t.Fatalf("failed to create tx: %v", err)
 			}
@@ -996,7 +1005,7 @@ func TestLogRebirth(t *testing.T) {
 		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
 		db            = rawdb.NewMemoryDatabase()
-		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
+		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
 		genesis       = gspec.MustCommit(db)
 		signer        = types.LatestSigner(gspec.Config)
 		engine        = ethash.NewFaker()
@@ -1014,7 +1023,7 @@ func TestLogRebirth(t *testing.T) {
 	// This chain contains a single log.
 	chain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
 		if i == 1 {
-			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
+			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
 			if err != nil {
 				t.Fatalf("failed to create tx: %v", err)
 			}
@@ -1030,7 +1039,7 @@ func TestLogRebirth(t *testing.T) {
 	// chain removes one log and adds one.
 	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
 		if i == 1 {
-			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
+			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
 			if err != nil {
 				t.Fatalf("failed to create tx: %v", err)
 			}
@@ -1060,7 +1069,7 @@ func TestSideLogRebirth(t *testing.T) {
 		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
 		db            = rawdb.NewMemoryDatabase()
-		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
+		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
 		genesis       = gspec.MustCommit(db)
 		signer        = types.LatestSigner(gspec.Config)
 		blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
@@ -1087,7 +1096,7 @@ func TestSideLogRebirth(t *testing.T) {
 	// Generate side chain with lower difficulty
 	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
 		if i == 1 {
-			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
+			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
 			if err != nil {
 				t.Fatalf("failed to create tx: %v", err)
 			}
@@ -1132,7 +1141,7 @@ func TestReorgSideEvent(t *testing.T) {
 		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
 		gspec   = &Genesis{
 			Config: params.TestChainConfig,
-			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
+			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
 		}
 		genesis = gspec.MustCommit(db)
 		signer  = types.LatestSigner(gspec.Config)
@@ -1147,7 +1156,7 @@ func TestReorgSideEvent(t *testing.T) {
 	}
 
 	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
-		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
+		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1)
 		if i == 2 {
 			gen.OffsetTime(-9)
 		}
@@ -1353,8 +1362,8 @@ func TestEIP155Transition(t *testing.T) {
 		}
 	})
 	_, err := blockchain.InsertChain(blocks)
-	if err != types.ErrInvalidChainId {
-		t.Error("expected error:", types.ErrInvalidChainId)
+	if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) {
+		t.Errorf("have %v, want %v", have, want)
 	}
 }
 
@@ -1435,7 +1444,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
 	engine := ethash.NewFaker()
 
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
 
 	// Generate a bunch of fork blocks, each side forking from the canonical chain
@@ -1451,7 +1460,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
 	// Import the canonical and fork chain side by side, verifying the current block
 	// and current header consistency
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
@@ -1480,7 +1489,7 @@ func TestTrieForkGC(t *testing.T) {
 	engine := ethash.NewFaker()
 
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
 
 	// Generate a bunch of fork blocks, each side forking from the canonical chain
@@ -1495,7 +1504,7 @@ func TestTrieForkGC(t *testing.T) {
 	}
 	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
@@ -1526,7 +1535,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
 	engine := ethash.NewFaker()
 
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
 	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
@@ -1534,7 +1543,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
 
 	// Import the shared chain and the original canonical one
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
@@ -1698,7 +1707,7 @@ func TestLowDiffLongChain(t *testing.T) {
 	// Generate a canonical chain to act as the main dataset
 	engine := ethash.NewFaker()
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	// We must use a pretty long chain to ensure that the fork doesn't overtake us
 	// until after at least 128 blocks post tip
@@ -1709,7 +1718,7 @@ func TestLowDiffLongChain(t *testing.T) {
 
 	// Import the canonical chain
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
@@ -1752,12 +1761,12 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
 	// Generate a canonical chain to act as the main dataset
 	engine := ethash.NewFaker()
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	// Generate and import the canonical chain
 	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
 		t.Fatalf("failed to create tester chain: %v", err)
@@ -1832,7 +1841,7 @@ func testInsertKnownChainData(t *testing.T, typ string) {
 	engine := ethash.NewFaker()
 
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
 	// A longer chain but total difficulty is lower.
@@ -1852,7 +1861,7 @@ func testInsertKnownChainData(t *testing.T, typ string) {
 	if err != nil {
 		t.Fatalf("failed to create temp freezer db: %v", err)
 	}
-	new(Genesis).MustCommit(chaindb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(chaindb)
 	defer os.RemoveAll(dir)
 
 	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
@@ -1955,7 +1964,7 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error
 	// Generate a canonical chain to act as the main dataset
 	engine := ethash.NewFaker()
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	// Generate and import the canonical chain,
 	// Offset the time, to keep the difficulty low
@@ -1963,7 +1972,7 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error
 		b.SetCoinbase(common.Address{1})
 	})
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
@@ -2075,14 +2084,18 @@ func TestTransactionIndices(t *testing.T) {
 		gendb   = rawdb.NewMemoryDatabase()
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
-		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
+		funds   = big.NewInt(100000000000000000)
+		gspec   = &Genesis{
+			Config:  params.TestChainConfig,
+			Alloc:   GenesisAlloc{address: {Balance: funds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
+		}
 		genesis = gspec.MustCommit(gendb)
 		signer  = types.LatestSigner(gspec.Config)
 	)
 	height := uint64(128)
 	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
-		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
+		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
 		if err != nil {
 			panic(err)
 		}
@@ -2202,14 +2215,14 @@ func TestSkipStaleTxIndicesInFastSync(t *testing.T) {
 		gendb   = rawdb.NewMemoryDatabase()
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(100000000000000000)
 		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
 		genesis = gspec.MustCommit(gendb)
 		signer  = types.LatestSigner(gspec.Config)
 	)
 	height := uint64(128)
 	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
-		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
+		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
 		if err != nil {
 			panic(err)
 		}
@@ -2403,12 +2416,12 @@ func TestSideImportPrunedBlocks(t *testing.T) {
 	// Generate a canonical chain to act as the main dataset
 	engine := ethash.NewFaker()
 	db := rawdb.NewMemoryDatabase()
-	genesis := new(Genesis).MustCommit(db)
+	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 
 	// Generate and import the canonical chain
 	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
 	diskdb := rawdb.NewMemoryDatabase()
-	new(Genesis).MustCommit(diskdb)
+	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
 	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
 	if err != nil {
 		t.Fatalf("failed to create tester chain: %v", err)
@@ -2456,7 +2469,7 @@ func TestDeleteCreateRevert(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(100000000000000000)
 		gspec   = &Genesis{
 			Config: params.TestChainConfig,
 			Alloc: GenesisAlloc{
@@ -2492,11 +2505,11 @@ func TestDeleteCreateRevert(t *testing.T) {
 		b.SetCoinbase(common.Address{1})
 		// One transaction to AAAA
 		tx, _ := types.SignTx(types.NewTransaction(0, aa,
-			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 		// One transaction to BBBB
 		tx, _ = types.SignTx(types.NewTransaction(1, bb,
-			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 	})
 	// Import the canonical chain
@@ -2527,7 +2540,7 @@ func TestDeleteRecreateSlots(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address   = crypto.PubkeyToAddress(key.PublicKey)
-		funds     = big.NewInt(1000000000)
+		funds     = big.NewInt(1000000000000000)
 		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
 		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
 		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
@@ -2604,11 +2617,11 @@ func TestDeleteRecreateSlots(t *testing.T) {
 		b.SetCoinbase(common.Address{1})
 		// One transaction to AA, to kill it
 		tx, _ := types.SignTx(types.NewTransaction(0, aa,
-			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 		// One transaction to BB, to recreate AA
 		tx, _ = types.SignTx(types.NewTransaction(1, bb,
-			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 	})
 	// Import the canonical chain
@@ -2654,7 +2667,7 @@ func TestDeleteRecreateAccount(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(1000000000000000)
 
 		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
 		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
@@ -2684,11 +2697,11 @@ func TestDeleteRecreateAccount(t *testing.T) {
 		b.SetCoinbase(common.Address{1})
 		// One transaction to AA, to kill it
 		tx, _ := types.SignTx(types.NewTransaction(0, aa,
-			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 		// One transaction to AA, to recreate it (but without storage
 		tx, _ = types.SignTx(types.NewTransaction(1, aa,
-			big.NewInt(1), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 	})
 	// Import the canonical chain
@@ -2730,7 +2743,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address   = crypto.PubkeyToAddress(key.PublicKey)
-		funds     = big.NewInt(1000000000)
+		funds     = big.NewInt(1000000000000000)
 		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
 		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
 		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
@@ -2816,9 +2829,9 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
 		values:   map[int]int{1: 1, 2: 2},
 	}
 	var expectations []*expectation
-	var newDestruct = func(e *expectation) *types.Transaction {
+	var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction {
 		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
-			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		nonce++
 		if e.exist {
 			e.exist = false
@@ -2827,9 +2840,9 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
 		t.Logf("block %d; adding destruct\n", e.blocknum)
 		return tx
 	}
-	var newResurrect = func(e *expectation) *types.Transaction {
+	var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction {
 		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
-			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		nonce++
 		if !e.exist {
 			e.exist = true
@@ -2850,16 +2863,16 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
 
 		b.SetCoinbase(common.Address{1})
 		if i%2 == 0 {
-			b.AddTx(newDestruct(exp))
+			b.AddTx(newDestruct(exp, b))
 		}
 		if i%3 == 0 {
-			b.AddTx(newResurrect(exp))
+			b.AddTx(newResurrect(exp, b))
 		}
 		if i%5 == 0 {
-			b.AddTx(newDestruct(exp))
+			b.AddTx(newDestruct(exp, b))
 		}
 		if i%7 == 0 {
-			b.AddTx(newResurrect(exp))
+			b.AddTx(newResurrect(exp, b))
 		}
 		expectations = append(expectations, exp)
 		current = exp
@@ -2932,7 +2945,7 @@ func TestInitThenFailCreateContract(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(1000000000000000)
 		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
 	)
 
@@ -2993,7 +3006,7 @@ func TestInitThenFailCreateContract(t *testing.T) {
 		b.SetCoinbase(common.Address{1})
 		// One transaction to BB
 		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
-			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
+			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
 		b.AddTx(tx)
 		nonce++
 	})
@@ -3047,9 +3060,9 @@ func TestEIP2718Transition(t *testing.T) {
 		// A sender who makes transactions, has some funds
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(1000000000000000)
 		gspec   = &Genesis{
-			Config: params.YoloV3ChainConfig,
+			Config: params.TestChainConfig,
 			Alloc: GenesisAlloc{
 				address: {Balance: funds},
 				// The address 0xAAAA sloads 0x00 and 0x01
@@ -3078,7 +3091,7 @@ func TestEIP2718Transition(t *testing.T) {
 			Nonce:    0,
 			To:       &aa,
 			Gas:      30000,
-			GasPrice: big.NewInt(1),
+			GasPrice: b.header.BaseFee,
 			AccessList: types.AccessList{{
 				Address:     aa,
 				StorageKeys: []common.Hash{{0}},
@@ -3102,9 +3115,163 @@ func TestEIP2718Transition(t *testing.T) {
 	block := chain.GetBlockByNumber(1)
 
 	// Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
-	expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas + vm.GasQuickStep*2 + vm.WarmStorageReadCostEIP2929 + vm.ColdSloadCostEIP2929
+	expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
+		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
 	if block.GasUsed() != expected {
 		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed())
 
 	}
 }
+
+// TestEIP1559Transition tests the following:
+//
+// 1. A transaction whose gasFeeCap is greater than the baseFee is valid.
+// 2. Gas accounting for access lists on EIP-1559 transactions is correct.
+// 3. Only the transaction's tip will be received by the coinbase.
+// 4. The transaction sender pays for both the tip and baseFee.
+// 5. The coinbase receives only the partially realized tip when
+//    gasFeeCap - gasTipCap < baseFee.
+// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
+func TestEIP1559Transition(t *testing.T) {
+	var (
+		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
+
+		// Generate a canonical chain to act as the main dataset
+		engine = ethash.NewFaker()
+		db     = rawdb.NewMemoryDatabase()
+
+		// A sender who makes transactions, has some funds
+		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
+		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
+		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
+		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
+		gspec   = &Genesis{
+			Config: params.AllEthashProtocolChanges,
+			Alloc: GenesisAlloc{
+				addr1: {Balance: funds},
+				addr2: {Balance: funds},
+				// The address 0xAAAA sloads 0x00 and 0x01
+				aa: {
+					Code: []byte{
+						byte(vm.PC),
+						byte(vm.PC),
+						byte(vm.SLOAD),
+						byte(vm.SLOAD),
+					},
+					Nonce:   0,
+					Balance: big.NewInt(0),
+				},
+			},
+		}
+	)
+
+	gspec.Config.BerlinBlock = common.Big0
+	gspec.Config.LondonBlock = common.Big0
+	genesis := gspec.MustCommit(db)
+	signer := types.LatestSigner(gspec.Config)
+
+	blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
+		b.SetCoinbase(common.Address{1})
+
+		// One transaction to 0xAAAA
+		accesses := types.AccessList{types.AccessTuple{
+			Address:     aa,
+			StorageKeys: []common.Hash{{0}},
+		}}
+
+		txdata := &types.DynamicFeeTx{
+			ChainID:    gspec.Config.ChainID,
+			Nonce:      0,
+			To:         &aa,
+			Gas:        30000,
+			GasFeeCap:  newGwei(5),
+			GasTipCap:  big.NewInt(2),
+			AccessList: accesses,
+			Data:       []byte{},
+		}
+		tx := types.NewTx(txdata)
+		tx, _ = types.SignTx(tx, signer, key1)
+
+		b.AddTx(tx)
+	})
+
+	diskdb := rawdb.NewMemoryDatabase()
+	gspec.MustCommit(diskdb)
+
+	chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
+	if err != nil {
+		t.Fatalf("failed to create tester chain: %v", err)
+	}
+	if n, err := chain.InsertChain(blocks); err != nil {
+		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
+	}
+
+	block := chain.GetBlockByNumber(1)
+
+	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
+	expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
+		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
+	if block.GasUsed() != expectedGas {
+		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
+	}
+
+	state, _ := chain.State()
+
+	// 3: Ensure that miner received only the tx's tip.
+	actual := state.GetBalance(block.Coinbase())
+	expected := new(big.Int).Add(
+		new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
+		ethash.ConstantinopleBlockReward,
+	)
+	if actual.Cmp(expected) != 0 {
+		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
+	}
+
+	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
+	actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
+	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
+	if actual.Cmp(expected) != 0 {
+		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
+	}
+
+	blocks, _ = GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *BlockGen) {
+		b.SetCoinbase(common.Address{2})
+
+		txdata := &types.LegacyTx{
+			Nonce:    0,
+			To:       &aa,
+			Gas:      30000,
+			GasPrice: newGwei(5),
+		}
+		tx := types.NewTx(txdata)
+		tx, _ = types.SignTx(tx, signer, key2)
+
+		b.AddTx(tx)
+	})
+
+	if n, err := chain.InsertChain(blocks); err != nil {
+		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
+	}
+
+	block = chain.GetBlockByNumber(2)
+	state, _ = chain.State()
+	effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
+
+	// 6+5: Ensure that miner received only the tx's effective tip.
+	actual = state.GetBalance(block.Coinbase())
+	expected = new(big.Int).Add(
+		new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
+		ethash.ConstantinopleBlockReward,
+	)
+	if actual.Cmp(expected) != 0 {
+		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
+	}
+
+	// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
+	actual = new(big.Int).Sub(funds, state.GetBalance(addr2))
+	expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
+	if actual.Cmp(expected) != 0 {
+		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
+	}
+}
diff --git a/core/bor_fee_log.go b/core/bor_fee_log.go
index c2851750daf48bb04c7a00675296805f90b6d425..1b5e9af29cac354d9aafb983d19bfb463ff48dcc 100644
--- a/core/bor_fee_log.go
+++ b/core/bor_fee_log.go
@@ -42,6 +42,7 @@ func AddTransferLog(
 }
 
 // AddFeeTransferLog adds transfer log into state
+// Deprecating transfer log and will be removed in future fork. PLEASE DO NOT USE this transfer log going forward. Parameters won't get updated as expected going forward with EIP1559
 func AddFeeTransferLog(
 	state vm.StateDB,
 
diff --git a/core/chain_makers.go b/core/chain_makers.go
index e058e5a78e5beabd8338ac4174b8d4be47fea2e3..b113c0d1be9d0e1b94bab7fce6fb8002c012100c 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -102,7 +102,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
 	if b.gasPool == nil {
 		b.SetCoinbase(common.Address{})
 	}
-	b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
+	b.statedb.Prepare(tx.Hash(), len(b.txs))
 	receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
 	if err != nil {
 		panic(err)
@@ -130,6 +130,11 @@ func (b *BlockGen) Number() *big.Int {
 	return new(big.Int).Set(b.header.Number)
 }
 
+// BaseFee returns the EIP-1559 base fee of the block being generated.
+func (b *BlockGen) BaseFee() *big.Int {
+	return new(big.Int).Set(b.header.BaseFee)
+}
+
 // AddUncheckedReceipt forcefully adds a receipts to the block without a
 // backing transaction.
 //
@@ -252,8 +257,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
 	} else {
 		time = parent.Time() + 10 // block time is fixed at 10 seconds
 	}
-
-	return &types.Header{
+	header := &types.Header{
 		Root:       state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())),
 		ParentHash: parent.Hash(),
 		Coinbase:   parent.Coinbase(),
@@ -263,10 +267,18 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
 			Difficulty: parent.Difficulty(),
 			UncleHash:  parent.UncleHash(),
 		}),
-		GasLimit: CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()),
+		GasLimit: parent.GasLimit(),
 		Number:   new(big.Int).Add(parent.Number(), common.Big1),
 		Time:     time,
 	}
+	if chain.Config().IsLondon(header.Number) {
+		header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header())
+		if !chain.Config().IsLondon(parent.Number()) {
+			parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
+			header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
+		}
+	}
+	return header
 }
 
 // makeHeaderChain creates a deterministic chain of headers rooted at parent.
diff --git a/core/dao_test.go b/core/dao_test.go
index b2a9f624a783d72a2474e7a3c188eea8dbea7601..c9c765a3832a3f734210268dc445ded1bbafd02d 100644
--- a/core/dao_test.go
+++ b/core/dao_test.go
@@ -33,7 +33,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
 
 	// Generate a common prefix for both pro-forkers and non-forkers
 	db := rawdb.NewMemoryDatabase()
-	gspec := new(Genesis)
+	gspec := &Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}
 	genesis := gspec.MustCommit(db)
 	prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
 
diff --git a/core/error.go b/core/error.go
index 197dd81567c1fcbc5bfec6cb018aae2360712d20..33cf874d15e469c0bc1f830fa443379d8ca46a2e 100644
--- a/core/error.go
+++ b/core/error.go
@@ -26,8 +26,8 @@ var (
 	// ErrKnownBlock is returned when a block to import is already known locally.
 	ErrKnownBlock = errors.New("block already known")
 
-	// ErrBlacklistedHash is returned if a block to import is on the blacklist.
-	ErrBlacklistedHash = errors.New("blacklisted hash")
+	// ErrBannedHash is returned if a block to import is on the banned list.
+	ErrBannedHash = errors.New("banned hash")
 
 	// ErrNoGenesis is returned when there is no Genesis Block.
 	ErrNoGenesis = errors.New("genesis not found in chain")
@@ -71,4 +71,23 @@ var (
 	// ErrTxTypeNotSupported is returned if a transaction is not supported in the
 	// current network configuration.
 	ErrTxTypeNotSupported = types.ErrTxTypeNotSupported
+
+	// ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a
+	// transaction with a tip higher than the total fee cap.
+	ErrTipAboveFeeCap = errors.New("max priority fee per gas higher than max fee per gas")
+
+	// ErrTipVeryHigh is a sanity error to avoid extremely big numbers specified
+	// in the tip field.
+	ErrTipVeryHigh = errors.New("max priority fee per gas higher than 2^256-1")
+
+	// ErrFeeCapVeryHigh is a sanity error to avoid extremely big numbers specified
+	// in the fee cap field.
+	ErrFeeCapVeryHigh = errors.New("max fee per gas higher than 2^256-1")
+
+	// ErrFeeCapTooLow is returned if the transaction fee cap is less than the
+	// the base fee of the block.
+	ErrFeeCapTooLow = errors.New("max fee per gas less than block base fee")
+
+	// ErrSenderNoEOA is returned if the sender of a transaction is a contract.
+	ErrSenderNoEOA = errors.New("sender not an eoa")
 )
diff --git a/core/evm.go b/core/evm.go
index 4e7e8aeb0ed1b8a0652f8d1a7740ccb4d8787337..4d2c11f4f013ad66f6d18ec1d976b3922db61252 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -37,13 +37,20 @@ type ChainContext interface {
 
 // NewEVMBlockContext creates a new context for use in the EVM.
 func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext {
+	var (
+		beneficiary common.Address
+		baseFee     *big.Int
+	)
+
 	// If we don't have an explicit author (i.e. not mining), extract from the header
-	var beneficiary common.Address
 	if author == nil {
 		beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation
 	} else {
 		beneficiary = *author
 	}
+	if header.BaseFee != nil {
+		baseFee = new(big.Int).Set(header.BaseFee)
+	}
 	return vm.BlockContext{
 		CanTransfer: CanTransfer,
 		Transfer:    Transfer,
@@ -52,6 +59,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
 		BlockNumber: new(big.Int).Set(header.Number),
 		Time:        new(big.Int).SetUint64(header.Time),
 		Difficulty:  new(big.Int).Set(header.Difficulty),
+		BaseFee:     baseFee,
 		GasLimit:    header.GasLimit,
 	}
 }
diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go
index 1bf3406828f063e0d52f2032a90202f87ede36da..f56ce85feeed25495bf64cf427e2e8b7f38c059c 100644
--- a/core/forkid/forkid.go
+++ b/core/forkid/forkid.go
@@ -155,7 +155,7 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
 		for i, fork := range forks {
 			// If our head is beyond this fork, continue to the next (we have a dummy
 			// fork of maxuint64 as the last item to always fail this check eventually).
-			if head > fork {
+			if head >= fork {
 				continue
 			}
 			// Found the first unpassed fork block, check if our current state matches
diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go
index a20598fa9daa8572833a7a9a38f1c954e453f3cf..916bffadc0f5f83ace3e87feadf4a9f88908d9ef 100644
--- a/core/forkid/forkid_test.go
+++ b/core/forkid/forkid_test.go
@@ -61,8 +61,10 @@ func TestCreation(t *testing.T) {
 				{9199999, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}},   // Last Istanbul and first Muir Glacier block
 				{9200000, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}},  // First Muir Glacier block
 				{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
-				{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 0}},        // First Berlin block
-				{20000000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 0}},        // Future Berlin block
+				{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
+				{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
+				{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}},        // First London block
+				{20000000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}},        // Future London block
 			},
 		},
 		// Ropsten test cases
@@ -70,22 +72,24 @@ func TestCreation(t *testing.T) {
 			params.RopstenChainConfig,
 			params.RopstenGenesisHash,
 			[]testcase{
-				{0, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},            // Unsynced, last Frontier, Homestead and first Tangerine block
-				{9, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},            // Last Tangerine block
-				{10, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}},      // First Spurious block
-				{1699999, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}}, // Last Spurious block
-				{1700000, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}}, // First Byzantium block
-				{4229999, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}}, // Last Byzantium block
-				{4230000, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}}, // First Constantinople block
-				{4939393, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}}, // Last Constantinople block
-				{4939394, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}}, // First Petersburg block
-				{6485845, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}}, // Last Petersburg block
-				{6485846, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}}, // First Istanbul block
-				{7117116, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}}, // Last Istanbul block
-				{7117117, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}}, // First Muir Glacier block
-				{9812188, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}}, // Last Muir Glacier block
-				{9812189, ID{Hash: checksumToBytes(0xa157d377), Next: 0}},       // First Berlin block
-				{10000000, ID{Hash: checksumToBytes(0xa157d377), Next: 0}},      // Future Berlin block
+				{0, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},              // Unsynced, last Frontier, Homestead and first Tangerine block
+				{9, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},              // Last Tangerine block
+				{10, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}},        // First Spurious block
+				{1699999, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}},   // Last Spurious block
+				{1700000, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}},   // First Byzantium block
+				{4229999, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}},   // Last Byzantium block
+				{4230000, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}},   // First Constantinople block
+				{4939393, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}},   // Last Constantinople block
+				{4939394, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}},   // First Petersburg block
+				{6485845, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}},   // Last Petersburg block
+				{6485846, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}},   // First Istanbul block
+				{7117116, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}},   // Last Istanbul block
+				{7117117, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}},   // First Muir Glacier block
+				{9812188, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}},   // Last Muir Glacier block
+				{9812189, ID{Hash: checksumToBytes(0xa157d377), Next: 10499401}},  // First Berlin block
+				{10499400, ID{Hash: checksumToBytes(0xa157d377), Next: 10499401}}, // Last Berlin block
+				{10499401, ID{Hash: checksumToBytes(0x7119b6b3), Next: 0}},        // First London block
+				{11000000, ID{Hash: checksumToBytes(0x7119b6b3), Next: 0}},        // Future London block
 			},
 		},
 		// Rinkeby test cases
@@ -106,8 +110,10 @@ func TestCreation(t *testing.T) {
 				{5435344, ID{Hash: checksumToBytes(0xafec6b27), Next: 5435345}}, // Last Petersburg block
 				{5435345, ID{Hash: checksumToBytes(0xcbdb8838), Next: 8290928}}, // First Istanbul block
 				{8290927, ID{Hash: checksumToBytes(0xcbdb8838), Next: 8290928}}, // Last Istanbul block
-				{8290928, ID{Hash: checksumToBytes(0x6910c8bd), Next: 0}},       // First Berlin block
-				{10000000, ID{Hash: checksumToBytes(0x6910c8bd), Next: 0}},      // Future Berlin block
+				{8290928, ID{Hash: checksumToBytes(0x6910c8bd), Next: 8897988}}, // First Berlin block
+				{8897987, ID{Hash: checksumToBytes(0x6910c8bd), Next: 8897988}}, // Last Berlin block
+				{8897988, ID{Hash: checksumToBytes(0x8E29F2F3), Next: 0}},       // First London block
+				{10000000, ID{Hash: checksumToBytes(0x8E29F2F3), Next: 0}},      // Future London block
 			},
 		},
 		// Goerli test cases
@@ -119,8 +125,10 @@ func TestCreation(t *testing.T) {
 				{1561650, ID{Hash: checksumToBytes(0xa3f5ab08), Next: 1561651}}, // Last Petersburg block
 				{1561651, ID{Hash: checksumToBytes(0xc25efa5c), Next: 4460644}}, // First Istanbul block
 				{4460643, ID{Hash: checksumToBytes(0xc25efa5c), Next: 4460644}}, // Last Istanbul block
-				{4460644, ID{Hash: checksumToBytes(0x757a1c47), Next: 0}},       // First Berlin block
-				{5000000, ID{Hash: checksumToBytes(0x757a1c47), Next: 0}},       // Future Berlin block
+				{4460644, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // First Berlin block
+				{5000000, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // Last Berlin block
+				{5062605, ID{Hash: checksumToBytes(0xB8C6299D), Next: 0}},       // First London block
+				{6000000, ID{Hash: checksumToBytes(0xB8C6299D), Next: 0}},       // Future London block
 			},
 		},
 	}
@@ -163,6 +171,10 @@ func TestValidation(t *testing.T) {
 		// neither forks passed at neither nodes, they may mismatch, but we still connect for now.
 		{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: math.MaxUint64}, nil},
 
+		// Local is mainnet exactly on Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote
+		// is simply out of sync, accept.
+		{7280000, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}, nil},
+
 		// Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote
 		// is simply out of sync, accept.
 		{7987396, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}, nil},
@@ -193,11 +205,11 @@ func TestValidation(t *testing.T) {
 		// Local is mainnet Petersburg, remote is Rinkeby Petersburg.
 		{7987396, ID{Hash: checksumToBytes(0xafec6b27), Next: 0}, ErrLocalIncompatibleOrStale},
 
-		// Local is mainnet Berlin, far in the future. Remote announces Gopherium (non existing fork)
+		// Local is mainnet London, far in the future. Remote announces Gopherium (non existing fork)
 		// at some future block 88888888, for itself, but past block for local. Local is incompatible.
 		//
 		// This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).
-		{88888888, ID{Hash: checksumToBytes(0x0eb440f6), Next: 88888888}, ErrLocalIncompatibleOrStale},
+		{88888888, ID{Hash: checksumToBytes(0xb715077d), Next: 88888888}, ErrLocalIncompatibleOrStale},
 
 		// Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing
 		// fork) at block 7279999, before Petersburg. Local is incompatible.
diff --git a/core/gen_genesis.go b/core/gen_genesis.go
index bb8ea1d6a23978a0fff6e6d98d327b6135ecff48..4e0844e889ab4e470790529515a0d5317b4a7a12 100644
--- a/core/gen_genesis.go
+++ b/core/gen_genesis.go
@@ -15,6 +15,7 @@ import (
 
 var _ = (*genesisSpecMarshaling)(nil)
 
+// MarshalJSON marshals as JSON.
 func (g Genesis) MarshalJSON() ([]byte, error) {
 	type Genesis struct {
 		Config     *params.ChainConfig                         `json:"config"`
@@ -29,6 +30,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
 		Number     math.HexOrDecimal64                         `json:"number"`
 		GasUsed    math.HexOrDecimal64                         `json:"gasUsed"`
 		ParentHash common.Hash                                 `json:"parentHash"`
+		BaseFee    *math.HexOrDecimal256                       `json:"baseFeePerGas"`
 	}
 	var enc Genesis
 	enc.Config = g.Config
@@ -48,9 +50,11 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
 	enc.Number = math.HexOrDecimal64(g.Number)
 	enc.GasUsed = math.HexOrDecimal64(g.GasUsed)
 	enc.ParentHash = g.ParentHash
+	enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee)
 	return json.Marshal(&enc)
 }
 
+// UnmarshalJSON unmarshals from JSON.
 func (g *Genesis) UnmarshalJSON(input []byte) error {
 	type Genesis struct {
 		Config     *params.ChainConfig                         `json:"config"`
@@ -65,6 +69,7 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
 		Number     *math.HexOrDecimal64                        `json:"number"`
 		GasUsed    *math.HexOrDecimal64                        `json:"gasUsed"`
 		ParentHash *common.Hash                                `json:"parentHash"`
+		BaseFee    *math.HexOrDecimal256                       `json:"baseFeePerGas"`
 	}
 	var dec Genesis
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -112,5 +117,8 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
 	if dec.ParentHash != nil {
 		g.ParentHash = *dec.ParentHash
 	}
+	if dec.BaseFee != nil {
+		g.BaseFee = (*big.Int)(dec.BaseFee)
+	}
 	return nil
 }
diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go
index 64fb9b9248f9ce447990d3fd1db16ac6a80158d4..a9d47e6ba35522947a312db6fd6261dabc5b0be8 100644
--- a/core/gen_genesis_account.go
+++ b/core/gen_genesis_account.go
@@ -14,6 +14,7 @@ import (
 
 var _ = (*genesisAccountMarshaling)(nil)
 
+// MarshalJSON marshals as JSON.
 func (g GenesisAccount) MarshalJSON() ([]byte, error) {
 	type GenesisAccount struct {
 		Code       hexutil.Bytes               `json:"code,omitempty"`
@@ -36,6 +37,7 @@ func (g GenesisAccount) MarshalJSON() ([]byte, error) {
 	return json.Marshal(&enc)
 }
 
+// UnmarshalJSON unmarshals from JSON.
 func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
 	type GenesisAccount struct {
 		Code       *hexutil.Bytes              `json:"code,omitempty"`
diff --git a/core/genesis.go b/core/genesis.go
index e05e27fe175063fd8b542ceaeb08f82e9bd35a74..c1f226c34a3901e996f1d0fe5a1613de835a6b9a 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -62,6 +62,7 @@ type Genesis struct {
 	Number     uint64      `json:"number"`
 	GasUsed    uint64      `json:"gasUsed"`
 	ParentHash common.Hash `json:"parentHash"`
+	BaseFee    *big.Int    `json:"baseFeePerGas"`
 }
 
 // GenesisAlloc specifies the initial state that is part of the genesis block.
@@ -97,6 +98,7 @@ type genesisSpecMarshaling struct {
 	GasUsed    math.HexOrDecimal64
 	Number     math.HexOrDecimal64
 	Difficulty *math.HexOrDecimal256
+	BaseFee    *math.HexOrDecimal256
 	Alloc      map[common.UnprefixedAddress]GenesisAccount
 }
 
@@ -156,7 +158,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
 	return SetupGenesisBlockWithOverride(db, genesis, nil)
 }
 
-func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideBerlin *big.Int) (*params.ChainConfig, common.Hash, error) {
+func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideLondon *big.Int) (*params.ChainConfig, common.Hash, error) {
 	if genesis != nil && genesis.Config == nil {
 		return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
 	}
@@ -202,8 +204,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
 	}
 	// Get the existing chain configuration.
 	newcfg := genesis.configOrDefault(stored)
-	if overrideBerlin != nil {
-		newcfg.BerlinBlock = overrideBerlin
+	if overrideLondon != nil {
+		newcfg.LondonBlock = overrideLondon
 	}
 	if err := newcfg.CheckConfigForkOrder(); err != nil {
 		return newcfg, common.Hash{}, err
@@ -246,8 +248,6 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
 		return params.RinkebyChainConfig
 	case ghash == params.GoerliGenesisHash:
 		return params.GoerliChainConfig
-	case ghash == params.YoloV3GenesisHash:
-		return params.YoloV3ChainConfig
 	default:
 		return params.AllEthashProtocolChanges
 	}
@@ -259,7 +259,10 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
 	if db == nil {
 		db = rawdb.NewMemoryDatabase()
 	}
-	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
+	statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil)
+	if err != nil {
+		panic(err)
+	}
 	for addr, account := range g.Alloc {
 		statedb.AddBalance(addr, account.Balance)
 		statedb.SetCode(addr, account.Code)
@@ -277,6 +280,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
 		Extra:      g.ExtraData,
 		GasLimit:   g.GasLimit,
 		GasUsed:    g.GasUsed,
+		BaseFee:    g.BaseFee,
 		Difficulty: g.Difficulty,
 		MixDigest:  g.Mixhash,
 		Coinbase:   g.Coinbase,
@@ -288,6 +292,13 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
 	if g.Difficulty == nil {
 		head.Difficulty = params.GenesisDifficulty
 	}
+	if g.Config != nil && g.Config.IsLondon(common.Big0) {
+		if g.BaseFee != nil {
+			head.BaseFee = g.BaseFee
+		} else {
+			head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
+		}
+	}
 	statedb.Commit(false)
 	statedb.Database().TrieDB().Commit(root, true, nil)
 
@@ -331,7 +342,10 @@ func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
 
 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
-	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
+	g := Genesis{
+		Alloc:   GenesisAlloc{addr: {Balance: balance}},
+		BaseFee: big.NewInt(params.InitialBaseFee),
+	}
 	return g.MustCommit(db)
 }
 
@@ -383,29 +397,21 @@ func DefaultGoerliGenesisBlock() *Genesis {
 	}
 }
 
-func DefaultYoloV3GenesisBlock() *Genesis {
-	// Full genesis: https://gist.github.com/holiman/c6ed9269dce28304ad176314caa75e97
-	return &Genesis{
-		Config:     params.YoloV3ChainConfig,
-		Timestamp:  0x6027dd2e,
-		ExtraData:  hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000001041afbcb359d5a8dc58c15b2ff51354ff8a217d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
-		GasLimit:   0x47b760,
-		Difficulty: big.NewInt(1),
-		Alloc:      decodePrealloc(yoloV3AllocData),
-	}
-}
-
 // DeveloperGenesisBlock returns the 'geth --dev' genesis block.
 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
 	// Override the default period to the user requested one
 	config := *params.AllCliqueProtocolChanges
-	config.Clique.Period = period
+	config.Clique = &params.CliqueConfig{
+		Period: period,
+		Epoch:  config.Clique.Epoch,
+	}
 
 	// Assemble and return the genesis with the precompiles and faucet pre-funded
 	return &Genesis{
 		Config:     &config,
 		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
 		GasLimit:   11500000,
+		BaseFee:    big.NewInt(params.InitialBaseFee),
 		Difficulty: big.NewInt(1),
 		Alloc: map[common.Address]GenesisAccount{
 			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
diff --git a/core/genesis_alloc.go b/core/genesis_alloc.go
index 5b0e933d7a3d0b23426d6e0fd904c6836e1c4b51..ee542334b5c8682ede7a9ab14cc3f23b148bbf6e 100644
--- a/core/genesis_alloc.go
+++ b/core/genesis_alloc.go
@@ -25,4 +25,4 @@ const mainnetAllocData = "\xfa\x04]X\u0793\r\x83b\x011\x8e\u0189\x9agT\x06\x908'
 const ropstenAllocData = "\xf9\x03\xa4\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x80\xc2\v\x80\xc2\f\x80\xc2\r\x80\xc2\x0e\x80\xc2\x0f\x80\xc2\x10\x80\xc2\x11\x80\xc2\x12\x80\xc2\x13\x80\xc2\x14\x80\xc2\x15\x80\xc2\x16\x80\xc2\x17\x80\xc2\x18\x80\xc2\x19\x80\xc2\x1a\x80\xc2\x1b\x80\xc2\x1c\x80\xc2\x1d\x80\xc2\x1e\x80\xc2\x1f\x80\xc2 \x80\xc2!\x80\xc2\"\x80\xc2#\x80\xc2$\x80\xc2%\x80\xc2&\x80\xc2'\x80\xc2(\x80\xc2)\x80\xc2*\x80\xc2+\x80\xc2,\x80\xc2-\x80\xc2.\x80\xc2/\x80\xc20\x80\xc21\x80\xc22\x80\xc23\x80\xc24\x80\xc25\x80\xc26\x80\xc27\x80\xc28\x80\xc29\x80\xc2:\x80\xc2;\x80\xc2<\x80\xc2=\x80\xc2>\x80\xc2?\x80\xc2@\x80\xc2A\x80\xc2B\x80\xc2C\x80\xc2D\x80\xc2E\x80\xc2F\x80\xc2G\x80\xc2H\x80\xc2I\x80\xc2J\x80\xc2K\x80\xc2L\x80\xc2M\x80\xc2N\x80\xc2O\x80\xc2P\x80\xc2Q\x80\xc2R\x80\xc2S\x80\xc2T\x80\xc2U\x80\xc2V\x80\xc2W\x80\xc2X\x80\xc2Y\x80\xc2Z\x80\xc2[\x80\xc2\\\x80\xc2]\x80\xc2^\x80\xc2_\x80\xc2`\x80\xc2a\x80\xc2b\x80\xc2c\x80\xc2d\x80\xc2e\x80\xc2f\x80\xc2g\x80\xc2h\x80\xc2i\x80\xc2j\x80\xc2k\x80\xc2l\x80\xc2m\x80\xc2n\x80\xc2o\x80\xc2p\x80\xc2q\x80\xc2r\x80\xc2s\x80\xc2t\x80\xc2u\x80\xc2v\x80\xc2w\x80\xc2x\x80\xc2y\x80\xc2z\x80\xc2{\x80\xc2|\x80\xc2}\x80\xc2~\x80\xc2\u007f\x80\u00c1\x80\x80\u00c1\x81\x80\u00c1\x82\x80\u00c1\x83\x80\u00c1\x84\x80\u00c1\x85\x80\u00c1\x86\x80\u00c1\x87\x80\u00c1\x88\x80\u00c1\x89\x80\u00c1\x8a\x80\u00c1\x8b\x80\u00c1\x8c\x80\u00c1\x8d\x80\u00c1\x8e\x80\u00c1\x8f\x80\u00c1\x90\x80\u00c1\x91\x80\u00c1\x92\x80\u00c1\x93\x80\u00c1\x94\x80\u00c1\x95\x80\u00c1\x96\x80\u00c1\x97\x80\u00c1\x98\x80\u00c1\x99\x80\u00c1\x9a\x80\u00c1\x9b\x80\u00c1\x9c\x80\u00c1\x9d\x80\u00c1\x9e\x80\u00c1\x9f\x80\u00c1\xa0\x80\u00c1\xa1\x80\u00c1\xa2\x80\u00c1\xa3\x80\u00c1\xa4\x80\u00c1\xa5\x80\u00c1\xa6\x80\u00c1\xa7\x80\u00c1\xa8\x80\u00c1\xa9\x80\u00c1\xaa\x80\u00c1\xab\x80\u00c1\xac\x80\u00c1\xad\x80\u00c1\xae\x80\u00c1\xaf\x80\u00c1\xb0\x80\u00c1\xb1\x80\u00c1\xb2\x80\u00c1\xb3\x80\u00c1\xb4\x80\u00c1\xb5\x80\u00c1\xb6\x80\u00c1\xb7\x80\u00c1\xb8\x80\u00c1\xb9\x80\u00c1\xba\x80\u00c1\xbb\x80\u00c1\xbc\x80\u00c1\xbd\x80\u00c1\xbe\x80\u00c1\xbf\x80\u00c1\xc0\x80\u00c1\xc1\x80\u00c1\u0080\u00c1\u00c0\u00c1\u0100\u00c1\u0140\u00c1\u0180\u00c1\u01c0\u00c1\u0200\u00c1\u0240\u00c1\u0280\u00c1\u02c0\u00c1\u0300\u00c1\u0340\u00c1\u0380\u00c1\u03c0\u00c1\u0400\u00c1\u0440\u00c1\u0480\u00c1\u04c0\u00c1\u0500\u00c1\u0540\u00c1\u0580\u00c1\u05c0\u00c1\u0600\u00c1\u0640\u00c1\u0680\u00c1\u06c0\u00c1\u0700\u00c1\u0740\u00c1\u0780\u00c1\u07c0\u00c1\xe0\x80\u00c1\xe1\x80\u00c1\xe2\x80\u00c1\xe3\x80\u00c1\xe4\x80\u00c1\xe5\x80\u00c1\xe6\x80\u00c1\xe7\x80\u00c1\xe8\x80\u00c1\xe9\x80\u00c1\xea\x80\u00c1\xeb\x80\u00c1\xec\x80\u00c1\xed\x80\u00c1\xee\x80\u00c1\xef\x80\u00c1\xf0\x80\u00c1\xf1\x80\u00c1\xf2\x80\u00c1\xf3\x80\u00c1\xf4\x80\u00c1\xf5\x80\u00c1\xf6\x80\u00c1\xf7\x80\u00c1\xf8\x80\u00c1\xf9\x80\u00c1\xfa\x80\u00c1\xfb\x80\u00c1\xfc\x80\u00c1\xfd\x80\u00c1\xfe\x80\u00c1\xff\x80\u3507KT\xa8\xbd\x15)f\xd6?pk\xae\x1f\xfe\xb0A\x19!\xe5\x8d\f\x9f,\x9c\xd0Ft\xed\xea@\x00\x00\x00"
 const rinkebyAllocData = "\xf9\x03\xb7\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xf6\x941\xb9\x8d\x14\x00{\xde\xe67)\x80\x86\x98\x8a\v\xbd1\x18E#\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 const goerliAllocData = "\xf9\x04\x06\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xe0\x94L*\xe4\x82Y5\x05\xf0\x16<\xde\xfc\a>\x81\xc6<\xdaA\a\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\xa8\xe8\xf1G2e\x8eKQ\xe8q\x191\x05:\x8ai\xba\xf2\xb1\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe1\x94\u0665\x17\x9f\t\x1d\x85\x05\x1d<\x98'\x85\xef\xd1E\\\uc199\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe1\x94\u08bdBX\xd2v\x887\xba\xa2j(\xfeq\xdc\a\x9f\x84\u01cbJG\xe3\xc1$H\xf4\xad\x00\x00\x00"
-const yoloV3AllocData = "\xf9\x05o\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xf6\x94\x0e\x89\xe2\xae\xdb\x1c\xfc\u06d4$\xd4\x1a\x1f!\x8fA2s\x81r\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x10A\xaf\xbc\xb3Y\u0568\xdcX\xc1[/\xf5\x13T\xff\x8a!}\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94`\xad\xc0\xf8\x9aA\xaf#|\xe75T\xed\xe1p\xd73\xec\x14\xe0\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94y\x9d2\x9e_X4\x19\x16|\xd7\"\x96$\x85\x92n3\x8fJ\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94|\xf5\xb7\x9b\xfe)\x1ag\xab\x02\xb3\x93\xe4V\xcc\xc4\xc2f\xf7S\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x8a\x8e\xaf\xb1\xcfb\xbf\xbe\xb1t\x17i\xda\xe1\xa9\xddG\x99a\x92\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x8b\xa1\xf1\tU\x1b\xd42\x800\x12dZ\xc16\xdd\xd6M\xbar\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xb0*.\xda\x1b1\u007f\xbd\x16v\x01(\x83k\n\u015bV\x0e\x9d\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xdf\n\x88\xb2\xb6\x8cg7\x13\xa8\xec\x82`\x03go'.5s\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+const calaverasAllocData = "\xf9\x06\x14\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xf6\x94\x0e\x89\xe2\xae\xdb\x1c\xfc\u06d4$\xd4\x1a\x1f!\x8fA2s\x81r\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x10A\xaf\xbc\xb3Y\u0568\xdcX\xc1[/\xf5\x13T\xff\x8a!}\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94#o\xf1\xe9t\x19\xae\x93\xad\x80\xca\xfb\xaa!\"\f]x\xfb}\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94`\xad\xc0\xf8\x9aA\xaf#|\xe75T\xed\xe1p\xd73\xec\x14\xe0\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94y\x9d2\x9e_X4\x19\x16|\xd7\"\x96$\x85\x92n3\x8fJ\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94|\xf5\xb7\x9b\xfe)\x1ag\xab\x02\xb3\x93\xe4V\xcc\xc4\xc2f\xf7S\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x8a\x8e\xaf\xb1\xcfb\xbf\xbe\xb1t\x17i\xda\xe1\xa9\xddG\x99a\x92\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\x8b\xa1\xf1\tU\x1b\xd42\x800\x12dZ\xc16\xdd\xd6M\xbar\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xb0*.\xda\x1b1\u007f\xbd\x16v\x01(\x83k\n\u015bV\x0e\x9d\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xba\xdc\r\xe9\xe0yK\x04\x9b^\xa6<>\x1ei\x8a4v\xc1r\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xf00\v\ue24a\xe2r\xeb4~\x83i\xac\fv\xdfB\xc9?\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x94\xfe;U~\x8f\xb6+\x89\xf4\x91kr\x1b\xe5\\\ub08d\xbds\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 44c1ef253ac7f1b60bf2e1edb58f12ee63506961..52c4384abe4b9a0fda5e0097f9c1053645dddd9b 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -185,10 +185,6 @@ func TestGenesisHashes(t *testing.T) {
 			genesis: DefaultRinkebyGenesisBlock(),
 			hash:    params.RinkebyGenesisHash,
 		},
-		{
-			genesis: DefaultYoloV3GenesisBlock(),
-			hash:    params.YoloV3GenesisHash,
-		},
 	}
 	for i, c := range cases {
 		b := c.genesis.MustCommit(rawdb.NewMemoryDatabase())
diff --git a/core/headerchain.go b/core/headerchain.go
index 1dbf958786d06353bab84d3343fd429790a064bd..7ef7dd43f7042c7bac4c70d911440296dddf30e8 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -165,6 +165,7 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
 	)
 
 	batch := hc.chainDb.NewBatch()
+	parentKnown := true // Set to true to force hc.HasHeader check the first iteration
 	for i, header := range headers {
 		var hash common.Hash
 		// The headers have already been validated at this point, so we already
@@ -178,8 +179,10 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
 		number := header.Number.Uint64()
 		newTD.Add(newTD, header.Difficulty)
 
+		// If the parent was not present, store it
 		// If the header is already known, skip it, otherwise store
-		if !hc.HasHeader(hash, number) {
+		alreadyKnown := parentKnown && hc.HasHeader(hash, number)
+		if !alreadyKnown {
 			// Irrelevant of the canonical status, write the TD and header to the database.
 			rawdb.WriteTd(batch, hash, number, newTD)
 			hc.tdCache.Add(hash, new(big.Int).Set(newTD))
@@ -192,6 +195,7 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
 				firstInserted = i
 			}
 		}
+		parentKnown = alreadyKnown
 		lastHeader, lastHash, lastNumber = header, hash, number
 	}
 
@@ -311,11 +315,11 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int)
 		}
 		// If the header is a banned one, straight out abort
 		if BadHashes[chain[i].ParentHash] {
-			return i - 1, ErrBlacklistedHash
+			return i - 1, ErrBannedHash
 		}
 		// If it's the last header in the cunk, we need to check it too
 		if i == len(chain)-1 && BadHashes[chain[i].Hash()] {
-			return i, ErrBlacklistedHash
+			return i, ErrBannedHash
 		}
 	}
 
@@ -570,7 +574,7 @@ func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, d
 		if parent == nil {
 			parent = hc.genesisHeader
 		}
-		parentHash = hdr.ParentHash
+		parentHash = parent.Hash()
 
 		// Notably, since geth has the possibility for setting the head to a low
 		// height which is even lower than ancient head.
diff --git a/core/headerchain_test.go b/core/headerchain_test.go
index 0aa25efd1f232b08dd99e19c0870598a8aadf218..f3e40b6213f38c5c7e43f48c1fb59b7522fa6861 100644
--- a/core/headerchain_test.go
+++ b/core/headerchain_test.go
@@ -19,6 +19,7 @@ package core
 import (
 	"errors"
 	"fmt"
+	"math/big"
 	"testing"
 	"time"
 
@@ -70,7 +71,7 @@ func testInsert(t *testing.T, hc *HeaderChain, chain []*types.Header, wantStatus
 func TestHeaderInsertion(t *testing.T) {
 	var (
 		db      = rawdb.NewMemoryDatabase()
-		genesis = new(Genesis).MustCommit(db)
+		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 	)
 
 	hc, err := NewHeaderChain(db, params.AllEthashProtocolChanges, ethash.NewFaker(), func() bool { return false })
diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go
index c0c48e0723ba6e0ad84483f9907885ab619ba15d..be50a05001438b7601292adecd16dca5234d5fff 100644
--- a/core/rawdb/accessors_chain_test.go
+++ b/core/rawdb/accessors_chain_test.go
@@ -444,6 +444,7 @@ func TestAncientStorage(t *testing.T) {
 	if err != nil {
 		t.Fatalf("failed to create database with ancient backend")
 	}
+	defer db.Close()
 	// Create a test block
 	block := types.NewBlockWithHeader(&types.Header{
 		Number:      big.NewInt(0),
diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go
index d6dab6808d3a7227d153ffbac688af37eae3f9bb..25a44354bfd30a7c80859778c3cc75ca8b178af3 100644
--- a/core/rawdb/accessors_indexes.go
+++ b/core/rawdb/accessors_indexes.go
@@ -106,7 +106,7 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com
 	}
 	body := ReadBody(db, blockHash, *blockNumber)
 	if body == nil {
-		log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash)
+		log.Error("Transaction referenced missing", "number", *blockNumber, "hash", blockHash)
 		return nil, common.Hash{}, 0, 0
 	}
 	for txIndex, tx := range body.Transactions {
@@ -114,7 +114,7 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com
 			return tx, blockHash, *blockNumber, uint64(txIndex)
 		}
 	}
-	log.Error("Transaction not found", "number", blockNumber, "hash", blockHash, "txhash", hash)
+	log.Error("Transaction not found", "number", *blockNumber, "hash", blockHash, "txhash", hash)
 	return nil, common.Hash{}, 0, 0
 }
 
@@ -137,7 +137,7 @@ func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig)
 			return receipt, blockHash, *blockNumber, uint64(receiptIndex)
 		}
 	}
-	log.Error("Receipt not found", "number", blockNumber, "hash", blockHash, "txhash", hash)
+	log.Error("Receipt not found", "number", *blockNumber, "hash", blockHash, "txhash", hash)
 	return nil, common.Hash{}, 0, 0
 }
 
diff --git a/core/rawdb/database.go b/core/rawdb/database.go
index 6e35ef4327f5ff0ddf72e23b0b26350c6860e2be..237c41cc5ff079e36d1694ce05a1389302e785b8 100644
--- a/core/rawdb/database.go
+++ b/core/rawdb/database.go
@@ -89,6 +89,11 @@ func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) {
 	return nil, errNotSupported
 }
 
+// ReadAncients returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) ReadAncients(kind string, start, max, maxByteSize uint64) ([][]byte, error) {
+	return nil, errNotSupported
+}
+
 // Ancients returns an error as we don't have a backing chain freezer.
 func (db *nofreezedb) Ancients() (uint64, error) {
 	return 0, errNotSupported
@@ -197,7 +202,11 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace st
 	}
 	// Freezer is consistent with the key-value database, permit combining the two
 	if !frdb.readonly {
-		go frdb.freeze(db)
+		frdb.wg.Add(1)
+		go func() {
+			frdb.freeze(db)
+			frdb.wg.Done()
+		}()
 	}
 	return &freezerdb{
 		KeyValueStore: db,
@@ -312,9 +321,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
 		bloomTrieNodes stat
 
 		// Meta- and unaccounted data
-		metadata     stat
-		unaccounted  stat
-		shutdownInfo stat
+		metadata    stat
+		unaccounted stat
 
 		// Totals
 		total common.StorageSize
@@ -351,6 +359,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
 			storageSnaps.Add(size)
 		case bytes.HasPrefix(key, preimagePrefix) && len(key) == (len(preimagePrefix)+common.HashLength):
 			preimages.Add(size)
+		case bytes.HasPrefix(key, configPrefix) && len(key) == (len(configPrefix)+common.HashLength):
+			metadata.Add(size)
 		case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength):
 			bloomBits.Add(size)
 		case bytes.HasPrefix(key, BloomBitsIndexPrefix):
@@ -365,8 +375,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
 			bytes.HasPrefix(key, []byte("bltIndex-")) ||
 			bytes.HasPrefix(key, []byte("bltRoot-")): // Bloomtrie sub
 			bloomTrieNodes.Add(size)
-		case bytes.Equal(key, uncleanShutdownKey):
-			shutdownInfo.Add(size)
 		default:
 			var accounted bool
 			for _, meta := range [][]byte{
@@ -421,7 +429,6 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
 		{"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()},
 		{"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()},
 		{"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()},
-		{"Key-Value store", "Shutdown metadata", shutdownInfo.Size(), shutdownInfo.Count()},
 		{"Ancient store", "Headers", ancientHeadersSize.String(), ancients.String()},
 		{"Ancient store", "Bodies", ancientBodiesSize.String(), ancients.String()},
 		{"Ancient store", "Receipt lists", ancientReceiptsSize.String(), ancients.String()},
diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go
index 12a390fb53fef745046f039e8366a3d95987161b..8c47575ee8b834615b18bf6a852568ae2852b264 100644
--- a/core/rawdb/freezer.go
+++ b/core/rawdb/freezer.go
@@ -84,6 +84,7 @@ type freezer struct {
 	trigger chan chan struct{} // Manual blocking freeze trigger, test determinism
 
 	quit      chan struct{}
+	wg        sync.WaitGroup
 	closeOnce sync.Once
 }
 
@@ -158,6 +159,8 @@ func (f *freezer) Close() error {
 	var errs []error
 	f.closeOnce.Do(func() {
 		close(f.quit)
+		// Wait for any background freezing to stop
+		f.wg.Wait()
 		for _, table := range f.tables {
 			if err := table.Close(); err != nil {
 				errs = append(errs, err)
@@ -190,6 +193,18 @@ func (f *freezer) Ancient(kind string, number uint64) ([]byte, error) {
 	return nil, errUnknownTable
 }
 
+// ReadAncients retrieves multiple items in sequence, starting from the index 'start'.
+// It will return
+//  - at most 'max' items,
+//  - at least 1 item (even if exceeding the maxByteSize), but will otherwise
+//   return as many items as fit into maxByteSize.
+func (f *freezer) ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error) {
+	if table := f.tables[kind]; table != nil {
+		return table.RetrieveItems(start, count, maxBytes)
+	}
+	return nil, errUnknownTable
+}
+
 // Ancients returns the length of the frozen items.
 func (f *freezer) Ancients() (uint64, error) {
 	return atomic.LoadUint64(&f.frozen), nil
@@ -421,7 +436,7 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) {
 		}
 		batch.Reset()
 
-		// Wipe out side chains also and track dangling side chians
+		// Wipe out side chains also and track dangling side chains
 		var dangling []common.Hash
 		for number := first; number < f.frozen; number++ {
 			// Always keep the genesis block in active database
diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go
index 09c09273850429e5afae6939f7e58d52ff0e4e32..7b1eac5835863f5275e4c4ac09cddca8bb9672d4 100644
--- a/core/rawdb/freezer_table.go
+++ b/core/rawdb/freezer_table.go
@@ -70,6 +70,19 @@ func (i *indexEntry) marshallBinary() []byte {
 	return b
 }
 
+// bounds returns the start- and end- offsets, and the file number of where to
+// read there data item marked by the two index entries. The two entries are
+// assumed to be sequential.
+func (start *indexEntry) bounds(end *indexEntry) (startOffset, endOffset, fileId uint32) {
+	if start.filenum != end.filenum {
+		// If a piece of data 'crosses' a data-file,
+		// it's actually in one piece on the second data-file.
+		// We return a zero-indexEntry for the second file as start
+		return 0, end.offset, end.filenum
+	}
+	return start.offset, end.offset, end.filenum
+}
+
 // freezerTable represents a single chained data table within the freezer (e.g. blocks).
 // It consists of a data file (snappy encoded arbitrary data blobs) and an indexEntry
 // file (uncompressed 64 bit indices into the data file).
@@ -546,84 +559,183 @@ func (t *freezerTable) append(item uint64, encodedBlob []byte, wlock bool) (bool
 	return false, nil
 }
 
-// getBounds returns the indexes for the item
-// returns start, end, filenumber and error
-func (t *freezerTable) getBounds(item uint64) (uint32, uint32, uint32, error) {
-	buffer := make([]byte, indexEntrySize)
-	var startIdx, endIdx indexEntry
-	// Read second index
-	if _, err := t.index.ReadAt(buffer, int64((item+1)*indexEntrySize)); err != nil {
-		return 0, 0, 0, err
-	}
-	endIdx.unmarshalBinary(buffer)
-	// Read first index (unless it's the very first item)
-	if item != 0 {
-		if _, err := t.index.ReadAt(buffer, int64(item*indexEntrySize)); err != nil {
-			return 0, 0, 0, err
-		}
-		startIdx.unmarshalBinary(buffer)
-	} else {
+// getIndices returns the index entries for the given from-item, covering 'count' items.
+// N.B: The actual number of returned indices for N items will always be N+1 (unless an
+// error is returned).
+// OBS: This method assumes that the caller has already verified (and/or trimmed) the range
+// so that the items are within bounds. If this method is used to read out of bounds,
+// it will return error.
+func (t *freezerTable) getIndices(from, count uint64) ([]*indexEntry, error) {
+	// Apply the table-offset
+	from = from - uint64(t.itemOffset)
+	// For reading N items, we need N+1 indices.
+	buffer := make([]byte, (count+1)*indexEntrySize)
+	if _, err := t.index.ReadAt(buffer, int64(from*indexEntrySize)); err != nil {
+		return nil, err
+	}
+	var (
+		indices []*indexEntry
+		offset  int
+	)
+	for i := from; i <= from+count; i++ {
+		index := new(indexEntry)
+		index.unmarshalBinary(buffer[offset:])
+		offset += indexEntrySize
+		indices = append(indices, index)
+	}
+	if from == 0 {
 		// Special case if we're reading the first item in the freezer. We assume that
 		// the first item always start from zero(regarding the deletion, we
 		// only support deletion by files, so that the assumption is held).
 		// This means we can use the first item metadata to carry information about
 		// the 'global' offset, for the deletion-case
-		return 0, endIdx.offset, endIdx.filenum, nil
+		indices[0].offset = 0
+		indices[0].filenum = indices[1].filenum
 	}
-	if startIdx.filenum != endIdx.filenum {
-		// If a piece of data 'crosses' a data-file,
-		// it's actually in one piece on the second data-file.
-		// We return a zero-indexEntry for the second file as start
-		return 0, endIdx.offset, endIdx.filenum, nil
-	}
-	return startIdx.offset, endIdx.offset, endIdx.filenum, nil
+	return indices, nil
 }
 
 // Retrieve looks up the data offset of an item with the given number and retrieves
 // the raw binary blob from the data file.
 func (t *freezerTable) Retrieve(item uint64) ([]byte, error) {
-	blob, err := t.retrieve(item)
+	items, err := t.RetrieveItems(item, 1, 0)
 	if err != nil {
 		return nil, err
 	}
-	if t.noCompression {
-		return blob, nil
+	return items[0], nil
+}
+
+// RetrieveItems returns multiple items in sequence, starting from the index 'start'.
+// It will return at most 'max' items, but will abort earlier to respect the
+// 'maxBytes' argument. However, if the 'maxBytes' is smaller than the size of one
+// item, it _will_ return one element and possibly overflow the maxBytes.
+func (t *freezerTable) RetrieveItems(start, count, maxBytes uint64) ([][]byte, error) {
+	// First we read the 'raw' data, which might be compressed.
+	diskData, sizes, err := t.retrieveItems(start, count, maxBytes)
+	if err != nil {
+		return nil, err
 	}
-	return snappy.Decode(nil, blob)
+	var (
+		output     = make([][]byte, 0, count)
+		offset     int // offset for reading
+		outputSize int // size of uncompressed data
+	)
+	// Now slice up the data and decompress.
+	for i, diskSize := range sizes {
+		item := diskData[offset : offset+diskSize]
+		offset += diskSize
+		decompressedSize := diskSize
+		if !t.noCompression {
+			decompressedSize, _ = snappy.DecodedLen(item)
+		}
+		if i > 0 && uint64(outputSize+decompressedSize) > maxBytes {
+			break
+		}
+		if !t.noCompression {
+			data, err := snappy.Decode(nil, item)
+			if err != nil {
+				return nil, err
+			}
+			output = append(output, data)
+		} else {
+			output = append(output, item)
+		}
+		outputSize += decompressedSize
+	}
+	return output, nil
 }
 
-// retrieve looks up the data offset of an item with the given number and retrieves
-// the raw binary blob from the data file. OBS! This method does not decode
-// compressed data.
-func (t *freezerTable) retrieve(item uint64) ([]byte, error) {
+// retrieveItems reads up to 'count' items from the table. It reads at least
+// one item, but otherwise avoids reading more than maxBytes bytes.
+// It returns the (potentially compressed) data, and the sizes.
+func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []int, error) {
 	t.lock.RLock()
 	defer t.lock.RUnlock()
 	// Ensure the table and the item is accessible
 	if t.index == nil || t.head == nil {
-		return nil, errClosed
+		return nil, nil, errClosed
 	}
-	if atomic.LoadUint64(&t.items) <= item {
-		return nil, errOutOfBounds
+	itemCount := atomic.LoadUint64(&t.items) // max number
+	// Ensure the start is written, not deleted from the tail, and that the
+	// caller actually wants something
+	if itemCount <= start || uint64(t.itemOffset) > start || count == 0 {
+		return nil, nil, errOutOfBounds
 	}
-	// Ensure the item was not deleted from the tail either
-	if uint64(t.itemOffset) > item {
-		return nil, errOutOfBounds
+	if start+count > itemCount {
+		count = itemCount - start
 	}
-	startOffset, endOffset, filenum, err := t.getBounds(item - uint64(t.itemOffset))
-	if err != nil {
-		return nil, err
+	var (
+		output     = make([]byte, maxBytes) // Buffer to read data into
+		outputSize int                      // Used size of that buffer
+	)
+	// readData is a helper method to read a single data item from disk.
+	readData := func(fileId, start uint32, length int) error {
+		// In case a small limit is used, and the elements are large, may need to
+		// realloc the read-buffer when reading the first (and only) item.
+		if len(output) < length {
+			output = make([]byte, length)
+		}
+		dataFile, exist := t.files[fileId]
+		if !exist {
+			return fmt.Errorf("missing data file %d", fileId)
+		}
+		if _, err := dataFile.ReadAt(output[outputSize:outputSize+length], int64(start)); err != nil {
+			return err
+		}
+		outputSize += length
+		return nil
 	}
-	dataFile, exist := t.files[filenum]
-	if !exist {
-		return nil, fmt.Errorf("missing data file %d", filenum)
+	// Read all the indexes in one go
+	indices, err := t.getIndices(start, count)
+	if err != nil {
+		return nil, nil, err
 	}
-	// Retrieve the data itself, decompress and return
-	blob := make([]byte, endOffset-startOffset)
-	if _, err := dataFile.ReadAt(blob, int64(startOffset)); err != nil {
-		return nil, err
+	var (
+		sizes      []int               // The sizes for each element
+		totalSize  = 0                 // The total size of all data read so far
+		readStart  = indices[0].offset // Where, in the file, to start reading
+		unreadSize = 0                 // The size of the as-yet-unread data
+	)
+
+	for i, firstIndex := range indices[:len(indices)-1] {
+		secondIndex := indices[i+1]
+		// Determine the size of the item.
+		offset1, offset2, _ := firstIndex.bounds(secondIndex)
+		size := int(offset2 - offset1)
+		// Crossing a file boundary?
+		if secondIndex.filenum != firstIndex.filenum {
+			// If we have unread data in the first file, we need to do that read now.
+			if unreadSize > 0 {
+				if err := readData(firstIndex.filenum, readStart, unreadSize); err != nil {
+					return nil, nil, err
+				}
+				unreadSize = 0
+			}
+			readStart = 0
+		}
+		if i > 0 && uint64(totalSize+size) > maxBytes {
+			// About to break out due to byte limit being exceeded. We don't
+			// read this last item, but we need to do the deferred reads now.
+			if unreadSize > 0 {
+				if err := readData(secondIndex.filenum, readStart, unreadSize); err != nil {
+					return nil, nil, err
+				}
+			}
+			break
+		}
+		// Defer the read for later
+		unreadSize += size
+		totalSize += size
+		sizes = append(sizes, size)
+		if i == len(indices)-2 || uint64(totalSize) > maxBytes {
+			// Last item, need to do the read now
+			if err := readData(secondIndex.filenum, readStart, unreadSize); err != nil {
+				return nil, nil, err
+			}
+			break
+		}
 	}
-	t.readMeter.Mark(int64(len(blob) + 2*indexEntrySize))
-	return blob, nil
+	return output[:outputSize], sizes, nil
 }
 
 // has returns an indicator whether the specified number data
diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go
index 0df28f236d2dc163fab1416a3bc5f8e7b86aabf3..e8a8b5c46309e2c5efa2b808effe6ced617278fd 100644
--- a/core/rawdb/freezer_table_test.go
+++ b/core/rawdb/freezer_table_test.go
@@ -74,7 +74,7 @@ func TestFreezerBasics(t *testing.T) {
 		exp := getChunk(15, y)
 		got, err := f.Retrieve(uint64(y))
 		if err != nil {
-			t.Fatal(err)
+			t.Fatalf("reading item %d: %v", y, err)
 		}
 		if !bytes.Equal(got, exp) {
 			t.Fatalf("test %d, got \n%x != \n%x", y, got, exp)
@@ -692,3 +692,118 @@ func TestAppendTruncateParallel(t *testing.T) {
 		}
 	}
 }
+
+// TestSequentialRead does some basic tests on the RetrieveItems.
+func TestSequentialRead(t *testing.T) {
+	rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
+	fname := fmt.Sprintf("batchread-%d", rand.Uint64())
+	{ // Fill table
+		f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 50, true)
+		if err != nil {
+			t.Fatal(err)
+		}
+		// Write 15 bytes 30 times
+		for x := 0; x < 30; x++ {
+			data := getChunk(15, x)
+			f.Append(uint64(x), data)
+		}
+		f.DumpIndex(0, 30)
+		f.Close()
+	}
+	{ // Open it, iterate, verify iteration
+		f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 50, true)
+		if err != nil {
+			t.Fatal(err)
+		}
+		items, err := f.RetrieveItems(0, 10000, 100000)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if have, want := len(items), 30; have != want {
+			t.Fatalf("want %d items, have %d ", want, have)
+		}
+		for i, have := range items {
+			want := getChunk(15, i)
+			if !bytes.Equal(want, have) {
+				t.Fatalf("data corruption: have\n%x\n, want \n%x\n", have, want)
+			}
+		}
+		f.Close()
+	}
+	{ // Open it, iterate, verify byte limit. The byte limit is less than item
+		// size, so each lookup should only return one item
+		f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 40, true)
+		if err != nil {
+			t.Fatal(err)
+		}
+		items, err := f.RetrieveItems(0, 10000, 10)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if have, want := len(items), 1; have != want {
+			t.Fatalf("want %d items, have %d ", want, have)
+		}
+		for i, have := range items {
+			want := getChunk(15, i)
+			if !bytes.Equal(want, have) {
+				t.Fatalf("data corruption: have\n%x\n, want \n%x\n", have, want)
+			}
+		}
+		f.Close()
+	}
+}
+
+// TestSequentialReadByteLimit does some more advanced tests on batch reads.
+// These tests check that when the byte limit hits, we correctly abort in time,
+// but also properly do all the deferred reads for the previous data, regardless
+// of whether the data crosses a file boundary or not.
+func TestSequentialReadByteLimit(t *testing.T) {
+	rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
+	fname := fmt.Sprintf("batchread-2-%d", rand.Uint64())
+	{ // Fill table
+		f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 100, true)
+		if err != nil {
+			t.Fatal(err)
+		}
+		// Write 10 bytes 30 times,
+		// Splitting it at every 100 bytes (10 items)
+		for x := 0; x < 30; x++ {
+			data := getChunk(10, x)
+			f.Append(uint64(x), data)
+		}
+		f.Close()
+	}
+	for i, tc := range []struct {
+		items uint64
+		limit uint64
+		want  int
+	}{
+		{9, 89, 8},
+		{10, 99, 9},
+		{11, 109, 10},
+		{100, 89, 8},
+		{100, 99, 9},
+		{100, 109, 10},
+	} {
+		{
+			f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 100, true)
+			if err != nil {
+				t.Fatal(err)
+			}
+			items, err := f.RetrieveItems(0, tc.items, tc.limit)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if have, want := len(items), tc.want; have != want {
+				t.Fatalf("test %d: want %d items, have %d ", i, want, have)
+			}
+			for ii, have := range items {
+				want := getChunk(10, ii)
+				if !bytes.Equal(want, have) {
+					t.Fatalf("test %d: data corruption item %d: have\n%x\n, want \n%x\n", i, ii, have, want)
+				}
+			}
+			f.Close()
+		}
+	}
+}
diff --git a/core/rawdb/table.go b/core/rawdb/table.go
index 6e9b17d12b8cffc6480bf8824d3315ce8b111563..75f9380ee8b0f8a363d5bc010b7f3cc35a42a761 100644
--- a/core/rawdb/table.go
+++ b/core/rawdb/table.go
@@ -62,6 +62,12 @@ func (t *table) Ancient(kind string, number uint64) ([]byte, error) {
 	return t.db.Ancient(kind, number)
 }
 
+// ReadAncients is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error) {
+	return t.db.ReadAncients(kind, start, count, maxBytes)
+}
+
 // Ancients is a noop passthrough that just forwards the request to the underlying
 // database.
 func (t *table) Ancients() (uint64, error) {
@@ -131,6 +137,8 @@ func (t *table) Compact(start []byte, limit []byte) error {
 	// If no start was specified, use the table prefix as the first value
 	if start == nil {
 		start = []byte(t.prefix)
+	} else {
+		start = append([]byte(t.prefix), start...)
 	}
 	// If no limit was specified, use the first element not matching the prefix
 	// as the limit
@@ -147,6 +155,8 @@ func (t *table) Compact(start []byte, limit []byte) error {
 				limit = nil
 			}
 		}
+	} else {
+		limit = append([]byte(t.prefix), limit...)
 	}
 	// Range correctly calculated based on table prefix, delegate down
 	return t.db.Compact(start, limit)
diff --git a/core/rlp_test.go b/core/rlp_test.go
index 04daf2fc672e779d24af5a2552a5856ecc010593..3a90811e74614b06085007ce97bacb85c49e63df 100644
--- a/core/rlp_test.go
+++ b/core/rlp_test.go
@@ -40,7 +40,7 @@ func getBlock(transactions int, uncles int, dataSize int) *types.Block {
 		// A sender who makes transactions, has some funds
 		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		address = crypto.PubkeyToAddress(key.PublicKey)
-		funds   = big.NewInt(1000000000)
+		funds   = big.NewInt(1000000000000000)
 		gspec   = &Genesis{
 			Config: params.TestChainConfig,
 			Alloc:  GenesisAlloc{address: {Balance: funds}},
@@ -55,7 +55,7 @@ func getBlock(transactions int, uncles int, dataSize int) *types.Block {
 				// Add transactions and stuff on the last block
 				for i := 0; i < transactions; i++ {
 					tx, _ := types.SignTx(types.NewTransaction(uint64(i), aa,
-						big.NewInt(0), 50000, big.NewInt(1), make([]byte, dataSize)), types.HomesteadSigner{}, key)
+						big.NewInt(0), 50000, b.header.BaseFee, make([]byte, dataSize)), types.HomesteadSigner{}, key)
 					b.AddTx(tx)
 				}
 				for i := 0; i < uncles; i++ {
diff --git a/core/state/dump.go b/core/state/dump.go
index b25da714fd11e8164bbbb57bd5078a5bfb1ab03e..00faa4ed6a6b5b3557e424e0231c2b68dcea6b50 100644
--- a/core/state/dump.go
+++ b/core/state/dump.go
@@ -19,6 +19,7 @@ package state
 import (
 	"encoding/json"
 	"fmt"
+	"time"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
@@ -27,6 +28,16 @@ import (
 	"github.com/ethereum/go-ethereum/trie"
 )
 
+// DumpConfig is a set of options to control what portions of the statewill be
+// iterated and collected.
+type DumpConfig struct {
+	SkipCode          bool
+	SkipStorage       bool
+	OnlyWithAddresses bool
+	Start             []byte
+	Max               uint64
+}
+
 // DumpCollector interface which the state trie calls during iteration
 type DumpCollector interface {
 	// OnRoot is called with the state root
@@ -39,9 +50,9 @@ type DumpCollector interface {
 type DumpAccount struct {
 	Balance   string                 `json:"balance"`
 	Nonce     uint64                 `json:"nonce"`
-	Root      string                 `json:"root"`
-	CodeHash  string                 `json:"codeHash"`
-	Code      string                 `json:"code,omitempty"`
+	Root      hexutil.Bytes          `json:"root"`
+	CodeHash  hexutil.Bytes          `json:"codeHash"`
+	Code      hexutil.Bytes          `json:"code,omitempty"`
 	Storage   map[common.Hash]string `json:"storage,omitempty"`
 	Address   *common.Address        `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode
 	SecureKey hexutil.Bytes          `json:"key,omitempty"`     // If we don't have address, we can output the key
@@ -111,38 +122,50 @@ func (d iterativeDump) OnRoot(root common.Hash) {
 	}{root})
 }
 
-func (s *StateDB) DumpToCollector(c DumpCollector, excludeCode, excludeStorage, excludeMissingPreimages bool, start []byte, maxResults int) (nextKey []byte) {
-	missingPreimages := 0
+// DumpToCollector iterates the state according to the given options and inserts
+// the items into a collector for aggregation or serialization.
+func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []byte) {
+	// Sanitize the input to allow nil configs
+	if conf == nil {
+		conf = new(DumpConfig)
+	}
+	var (
+		missingPreimages int
+		accounts         uint64
+		start            = time.Now()
+		logged           = time.Now()
+	)
+	log.Info("Trie dumping started", "root", s.trie.Hash())
 	c.OnRoot(s.trie.Hash())
 
-	var count int
-	it := trie.NewIterator(s.trie.NodeIterator(start))
+	it := trie.NewIterator(s.trie.NodeIterator(conf.Start))
 	for it.Next() {
 		var data Account
 		if err := rlp.DecodeBytes(it.Value, &data); err != nil {
 			panic(err)
 		}
 		account := DumpAccount{
-			Balance:  data.Balance.String(),
-			Nonce:    data.Nonce,
-			Root:     common.Bytes2Hex(data.Root[:]),
-			CodeHash: common.Bytes2Hex(data.CodeHash),
+			Balance:   data.Balance.String(),
+			Nonce:     data.Nonce,
+			Root:      data.Root[:],
+			CodeHash:  data.CodeHash,
+			SecureKey: it.Key,
 		}
 		addrBytes := s.trie.GetKey(it.Key)
 		if addrBytes == nil {
 			// Preimage missing
 			missingPreimages++
-			if excludeMissingPreimages {
+			if conf.OnlyWithAddresses {
 				continue
 			}
 			account.SecureKey = it.Key
 		}
 		addr := common.BytesToAddress(addrBytes)
 		obj := newObject(s, addr, data)
-		if !excludeCode {
-			account.Code = common.Bytes2Hex(obj.Code(s.db))
+		if !conf.SkipCode {
+			account.Code = obj.Code(s.db)
 		}
-		if !excludeStorage {
+		if !conf.SkipStorage {
 			account.Storage = make(map[common.Hash]string)
 			storageIt := trie.NewIterator(obj.getTrie(s.db).NodeIterator(nil))
 			for storageIt.Next() {
@@ -155,8 +178,13 @@ func (s *StateDB) DumpToCollector(c DumpCollector, excludeCode, excludeStorage,
 			}
 		}
 		c.OnAccount(addr, account)
-		count++
-		if maxResults > 0 && count >= maxResults {
+		accounts++
+		if time.Since(logged) > 8*time.Second {
+			log.Info("Trie dumping in progress", "at", it.Key, "accounts", accounts,
+				"elapsed", common.PrettyDuration(time.Since(start)))
+			logged = time.Now()
+		}
+		if conf.Max > 0 && accounts >= conf.Max {
 			if it.Next() {
 				nextKey = it.Key
 			}
@@ -166,22 +194,24 @@ func (s *StateDB) DumpToCollector(c DumpCollector, excludeCode, excludeStorage,
 	if missingPreimages > 0 {
 		log.Warn("Dump incomplete due to missing preimages", "missing", missingPreimages)
 	}
+	log.Info("Trie dumping complete", "accounts", accounts,
+		"elapsed", common.PrettyDuration(time.Since(start)))
 
 	return nextKey
 }
 
 // RawDump returns the entire state an a single large object
-func (s *StateDB) RawDump(excludeCode, excludeStorage, excludeMissingPreimages bool) Dump {
+func (s *StateDB) RawDump(opts *DumpConfig) Dump {
 	dump := &Dump{
 		Accounts: make(map[common.Address]DumpAccount),
 	}
-	s.DumpToCollector(dump, excludeCode, excludeStorage, excludeMissingPreimages, nil, 0)
+	s.DumpToCollector(dump, opts)
 	return *dump
 }
 
 // Dump returns a JSON string representing the entire state as a single json-object
-func (s *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages bool) []byte {
-	dump := s.RawDump(excludeCode, excludeStorage, excludeMissingPreimages)
+func (s *StateDB) Dump(opts *DumpConfig) []byte {
+	dump := s.RawDump(opts)
 	json, err := json.MarshalIndent(dump, "", "    ")
 	if err != nil {
 		fmt.Println("Dump err", err)
@@ -190,15 +220,15 @@ func (s *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages bool
 }
 
 // IterativeDump dumps out accounts as json-objects, delimited by linebreaks on stdout
-func (s *StateDB) IterativeDump(excludeCode, excludeStorage, excludeMissingPreimages bool, output *json.Encoder) {
-	s.DumpToCollector(iterativeDump{output}, excludeCode, excludeStorage, excludeMissingPreimages, nil, 0)
+func (s *StateDB) IterativeDump(opts *DumpConfig, output *json.Encoder) {
+	s.DumpToCollector(iterativeDump{output}, opts)
 }
 
 // IteratorDump dumps out a batch of accounts starts with the given start key
-func (s *StateDB) IteratorDump(excludeCode, excludeStorage, excludeMissingPreimages bool, start []byte, maxResults int) IteratorDump {
+func (s *StateDB) IteratorDump(opts *DumpConfig) IteratorDump {
 	iterator := &IteratorDump{
 		Accounts: make(map[common.Address]DumpAccount),
 	}
-	iterator.Next = s.DumpToCollector(iterator, excludeCode, excludeStorage, excludeMissingPreimages, start, maxResults)
+	iterator.Next = s.DumpToCollector(iterator, opts)
 	return *iterator
 }
diff --git a/core/state/pruner/bloom.go b/core/state/pruner/bloom.go
index 4aeeb176e888ca2bfdc7a0e06b6cabee29d1984a..1cd03cf5363b1782768f5cb8b5e2f413f492b3d8 100644
--- a/core/state/pruner/bloom.go
+++ b/core/state/pruner/bloom.go
@@ -90,7 +90,7 @@ func (bloom *stateBloom) Commit(filename, tempname string) error {
 		return err
 	}
 	// Ensure the file is synced to disk
-	f, err := os.Open(tempname)
+	f, err := os.OpenFile(tempname, os.O_RDWR, 0666)
 	if err != nil {
 		return err
 	}
diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go
index 3a669085f7480f34762b5cf9d0e2c04e77325ace..a92517b3155fb76b27684ff668b678b38d9290cb 100644
--- a/core/state/snapshot/generate_test.go
+++ b/core/state/snapshot/generate_test.go
@@ -71,7 +71,7 @@ func TestGeneration(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -136,7 +136,7 @@ func TestGenerateExistentState(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -309,7 +309,7 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -361,7 +361,7 @@ func TestGenerateExistentStateWithWrongAccounts(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -406,7 +406,7 @@ func TestGenerateCorruptAccountTrie(t *testing.T) {
 		// Snapshot generation succeeded
 		t.Errorf("Snapshot generated against corrupt account trie")
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(time.Second):
 		// Not generated fast enough, hopefully blocked inside on missing trie node fail
 	}
 	// Signal abortion to the generator and wait for it to tear down
@@ -466,7 +466,7 @@ func TestGenerateMissingStorageTrie(t *testing.T) {
 		// Snapshot generation succeeded
 		t.Errorf("Snapshot generated against corrupt storage trie")
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(time.Second):
 		// Not generated fast enough, hopefully blocked inside on missing trie node fail
 	}
 	// Signal abortion to the generator and wait for it to tear down
@@ -525,7 +525,7 @@ func TestGenerateCorruptStorageTrie(t *testing.T) {
 		// Snapshot generation succeeded
 		t.Errorf("Snapshot generated against corrupt storage trie")
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(time.Second):
 		// Not generated fast enough, hopefully blocked inside on missing trie node fail
 	}
 	// Signal abortion to the generator and wait for it to tear down
@@ -588,7 +588,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -646,7 +646,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -699,7 +699,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -743,7 +743,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -775,7 +775,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(1 * time.Second):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
@@ -822,7 +822,7 @@ func TestGenerateWithIncompleteStorage(t *testing.T) {
 	case <-snap.genPending:
 		// Snapshot generation succeeded
 
-	case <-time.After(250 * time.Millisecond):
+	case <-time.After(3 * time.Second):
 		t.Errorf("Snapshot generation failed")
 	}
 	checkSnapRoot(t, snap, root)
diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go
index cb8ec7a7072c06be16bfdfcf2a0e9e8ad51dd13e..8889fa9fec124b90094911afc4221f43a9a9c264 100644
--- a/core/state/snapshot/snapshot.go
+++ b/core/state/snapshot/snapshot.go
@@ -169,11 +169,17 @@ type Tree struct {
 // store (with a number of memory layers from a journal), ensuring that the head
 // of the snapshot matches the expected one.
 //
-// If the snapshot is missing or the disk layer is broken, the entire is deleted
-// and will be reconstructed from scratch based on the tries in the key-value
-// store, on a background thread. If the memory layers from the journal is not
-// continuous with disk layer or the journal is missing, all diffs will be discarded
-// iff it's in "recovery" mode, otherwise rebuild is mandatory.
+// If the snapshot is missing or the disk layer is broken, the snapshot will be
+// reconstructed using both the existing data and the state trie.
+// The repair happens on a background thread.
+//
+// If the memory layers in the journal do not match the disk layer (e.g. there is
+// a gap) or the journal is missing, there are two repair cases:
+//
+// - if the 'recovery' parameter is true, all memory diff-layers will be discarded.
+//   This case happens when the snapshot is 'ahead' of the state trie.
+// - otherwise, the entire snapshot is considered invalid and will be recreated on
+//   a background thread.
 func New(diskdb ethdb.KeyValueStore, triedb *trie.Database, cache int, root common.Hash, async bool, rebuild bool, recovery bool) (*Tree, error) {
 	// Create a new, empty snapshot tree
 	snap := &Tree{
@@ -469,7 +475,7 @@ func (t *Tree) cap(diff *diffLayer, layers int) *diskLayer {
 		if flattened.memory < aggregatorMemoryLimit {
 			// Accumulator layer is smaller than the limit, so we can abort, unless
 			// there's a snapshot being generated currently. In that case, the trie
-			// will move fron underneath the generator so we **must** merge all the
+			// will move from underneath the generator so we **must** merge all the
 			// partial data down into the snapshot and restart the generation.
 			if flattened.parent.(*diskLayer).genAbort == nil {
 				return nil
diff --git a/core/state/state_object.go b/core/state/state_object.go
index f93f47d5f5b14d34ea558d96dddb8ac4ca2acb5b..38621ffb6159c51edb520258c0e5972f362e1e98 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -450,9 +450,6 @@ func (s *stateObject) setBalance(amount *big.Int) {
 	s.data.Balance = amount
 }
 
-// Return the gas back to the origin. Used by the Virtual machine or Closures
-func (s *stateObject) ReturnGas(gas *big.Int) {}
-
 func (s *stateObject) deepCopy(db *StateDB) *stateObject {
 	stateObject := newObject(db, s.address, s.data)
 	if s.trie != nil {
diff --git a/core/state/state_test.go b/core/state/state_test.go
index 956653146647e14022ee2ddb78042972fda83f7c..0a55d7781fd18c91a85d2b56e0b9d798ccd82474 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -57,28 +57,31 @@ func TestDump(t *testing.T) {
 	s.state.Commit(false)
 
 	// check that DumpToCollector contains the state objects that are in trie
-	got := string(s.state.Dump(false, false, true))
+	got := string(s.state.Dump(nil))
 	want := `{
     "root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2",
     "accounts": {
         "0x0000000000000000000000000000000000000001": {
             "balance": "22",
             "nonce": 0,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
+            "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
+            "key": "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"
         },
         "0x0000000000000000000000000000000000000002": {
             "balance": "44",
             "nonce": 0,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
+            "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
+            "key": "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62"
         },
         "0x0000000000000000000000000000000000000102": {
             "balance": "0",
             "nonce": 0,
-            "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "codeHash": "87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3",
-            "code": "03030303030303"
+            "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "codeHash": "0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3",
+            "code": "0x03030303030303",
+            "key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"
         }
     }
 }`
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 90f4709bfc467018a0757b0e4dd2668aec57dd24..61f0f5b9f6eb2a60549c479d8066cf0a916274ca 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -89,10 +89,10 @@ type StateDB struct {
 	// The refund counter, also used by state transitioning.
 	refund uint64
 
-	thash, bhash common.Hash
-	txIndex      int
-	logs         map[common.Hash][]*types.Log
-	logSize      uint
+	thash   common.Hash
+	txIndex int
+	logs    map[common.Hash][]*types.Log
+	logSize uint
 
 	preimages map[common.Hash][]byte
 
@@ -186,15 +186,18 @@ func (s *StateDB) AddLog(log *types.Log) {
 	s.journal.append(addLogChange{txhash: s.thash})
 
 	log.TxHash = s.thash
-	log.BlockHash = s.bhash
 	log.TxIndex = uint(s.txIndex)
 	log.Index = s.logSize
 	s.logs[s.thash] = append(s.logs[s.thash], log)
 	s.logSize++
 }
 
-func (s *StateDB) GetLogs(hash common.Hash) []*types.Log {
-	return s.logs[hash]
+func (s *StateDB) GetLogs(hash common.Hash, blockHash common.Hash) []*types.Log {
+	logs := s.logs[hash]
+	for _, l := range logs {
+		l.BlockHash = blockHash
+	}
+	return logs
 }
 
 func (s *StateDB) Logs() []*types.Log {
@@ -272,11 +275,6 @@ func (s *StateDB) TxIndex() int {
 	return s.txIndex
 }
 
-// BlockHash returns the current block hash set by Prepare.
-func (s *StateDB) BlockHash() common.Hash {
-	return s.bhash
-}
-
 func (s *StateDB) GetCode(addr common.Address) []byte {
 	stateObject := s.getStateObject(addr)
 	if stateObject != nil {
@@ -333,17 +331,6 @@ func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte,
 	return proof, err
 }
 
-// GetStorageProofByHash returns the Merkle proof for given storage slot.
-func (s *StateDB) GetStorageProofByHash(a common.Address, key common.Hash) ([][]byte, error) {
-	var proof proofList
-	trie := s.StorageTrie(a)
-	if trie == nil {
-		return proof, errors.New("storage trie for requested address does not exist")
-	}
-	err := trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
-	return proof, err
-}
-
 // GetCommittedState retrieves a value from the given account's committed storage trie.
 func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
 	stateObject := s.getStateObject(addr)
@@ -597,7 +584,6 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
 		}
 	}
 	newobj = newObject(s, addr, Account{})
-	newobj.setNonce(0) // sets the object to dirty
 	if prev == nil {
 		s.journal.append(createObjectChange{account: &addr})
 	} else {
@@ -892,11 +878,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
 	return s.trie.Hash()
 }
 
-// Prepare sets the current transaction hash and index and block hash which is
+// Prepare sets the current transaction hash and index which are
 // used when the EVM emits new state logs.
-func (s *StateDB) Prepare(thash, bhash common.Hash, ti int) {
+func (s *StateDB) Prepare(thash common.Hash, ti int) {
 	s.thash = thash
-	s.bhash = bhash
 	s.txIndex = ti
 	s.accessList = newAccessList()
 }
@@ -991,7 +976,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
 // - Add precompiles to access list (2929)
 // - Add the contents of the optional tx access list (2930)
 //
-// This method should only be called if Yolov3/Berlin/2929+2930 is applicable at the current number.
+// This method should only be called if Berlin/2929+2930 is applicable at the current number.
 func (s *StateDB) PrepareAccessList(sender common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) {
 	s.AddAddressToAccessList(sender)
 	if dst != nil {
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index 9524e3730d00d7ae300ba2ced5f2b59962f5bded..e9576d4dc44d312a57073a720b32f9e97e6c35b4 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -126,7 +126,7 @@ func TestIntermediateLeaks(t *testing.T) {
 			t.Errorf("entry missing from the transition database: %x -> %x", key, fvalue)
 		}
 		if !bytes.Equal(fvalue, tvalue) {
-			t.Errorf("the value associate key %x is mismatch,: %x in transition database ,%x in final database", key, tvalue, fvalue)
+			t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue)
 		}
 	}
 	it.Release()
@@ -139,7 +139,7 @@ func TestIntermediateLeaks(t *testing.T) {
 			t.Errorf("extra entry in the transition database: %x -> %x", key, it.Value())
 		}
 		if !bytes.Equal(fvalue, tvalue) {
-			t.Errorf("the value associate key %x is mismatch,: %x in transition database ,%x in final database", key, tvalue, fvalue)
+			t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue)
 		}
 	}
 }
@@ -463,9 +463,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
 		return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
 			state.GetRefund(), checkstate.GetRefund())
 	}
-	if !reflect.DeepEqual(state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) {
+	if !reflect.DeepEqual(state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{})) {
 		return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v",
-			state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{}))
+			state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{}))
 	}
 	return nil
 }
diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go
index ac5e95c5c2c8ebf4d7f57926dafc27a95c44d8db..25c3730e3f7af98cfb6529ff87901109c2796dce 100644
--- a/core/state/trie_prefetcher.go
+++ b/core/state/trie_prefetcher.go
@@ -312,12 +312,11 @@ func (sf *subfetcher) loop() {
 
 				default:
 					// No termination request yet, prefetch the next entry
-					taskid := string(task)
-					if _, ok := sf.seen[taskid]; ok {
+					if _, ok := sf.seen[string(task)]; ok {
 						sf.dups++
 					} else {
 						sf.trie.TryGet(task)
-						sf.seen[taskid] = struct{}{}
+						sf.seen[string(task)] = struct{}{}
 					}
 				}
 			}
diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..35dc7a2c0da4764c1e93cc69910fde590b3d85cc
--- /dev/null
+++ b/core/state/trie_prefetcher_test.go
@@ -0,0 +1,110 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package state
+
+import (
+	"math/big"
+	"testing"
+	"time"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/rawdb"
+)
+
+func filledStateDB() *StateDB {
+	state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
+
+	// Create an account and check if the retrieved balance is correct
+	addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
+	skey := common.HexToHash("aaa")
+	sval := common.HexToHash("bbb")
+
+	state.SetBalance(addr, big.NewInt(42)) // Change the account trie
+	state.SetCode(addr, []byte("hello"))   // Change an external metadata
+	state.SetState(addr, skey, sval)       // Change the storage trie
+	for i := 0; i < 100; i++ {
+		sk := common.BigToHash(big.NewInt(int64(i)))
+		state.SetState(addr, sk, sk) // Change the storage trie
+	}
+	return state
+}
+
+func TestCopyAndClose(t *testing.T) {
+	db := filledStateDB()
+	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
+	skey := common.HexToHash("aaa")
+	prefetcher.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	prefetcher.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	time.Sleep(1 * time.Second)
+	a := prefetcher.trie(db.originalRoot)
+	prefetcher.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	b := prefetcher.trie(db.originalRoot)
+	cpy := prefetcher.copy()
+	cpy.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	cpy.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	c := cpy.trie(db.originalRoot)
+	prefetcher.close()
+	cpy2 := cpy.copy()
+	cpy2.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	d := cpy2.trie(db.originalRoot)
+	cpy.close()
+	cpy2.close()
+	if a.Hash() != b.Hash() || a.Hash() != c.Hash() || a.Hash() != d.Hash() {
+		t.Fatalf("Invalid trie, hashes should be equal: %v %v %v %v", a.Hash(), b.Hash(), c.Hash(), d.Hash())
+	}
+}
+
+func TestUseAfterClose(t *testing.T) {
+	db := filledStateDB()
+	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
+	skey := common.HexToHash("aaa")
+	prefetcher.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	a := prefetcher.trie(db.originalRoot)
+	prefetcher.close()
+	b := prefetcher.trie(db.originalRoot)
+	if a == nil {
+		t.Fatal("Prefetching before close should not return nil")
+	}
+	if b != nil {
+		t.Fatal("Trie after close should return nil")
+	}
+}
+
+func TestCopyClose(t *testing.T) {
+	db := filledStateDB()
+	prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
+	skey := common.HexToHash("aaa")
+	prefetcher.prefetch(db.originalRoot, [][]byte{skey.Bytes()})
+	cpy := prefetcher.copy()
+	a := prefetcher.trie(db.originalRoot)
+	b := cpy.trie(db.originalRoot)
+	prefetcher.close()
+	c := prefetcher.trie(db.originalRoot)
+	d := cpy.trie(db.originalRoot)
+	if a == nil {
+		t.Fatal("Prefetching before close should not return nil")
+	}
+	if b == nil {
+		t.Fatal("Copy trie should return nil")
+	}
+	if c != nil {
+		t.Fatal("Trie after close should return nil")
+	}
+	if d == nil {
+		t.Fatal("Copy trie should not return nil")
+	}
+}
diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go
index 05394321f74bb8593e960771a5968fc224e7ea04..10a1722940b0e4368baa42172a6a0c8262b18a3b 100644
--- a/core/state_prefetcher.go
+++ b/core/state_prefetcher.go
@@ -63,11 +63,11 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
 			return
 		}
 		// Convert the transaction into an executable message and pre-cache its sender
-		msg, err := tx.AsMessage(signer)
+		msg, err := tx.AsMessage(signer, header.BaseFee)
 		if err != nil {
 			return // Also invalid block, bail out
 		}
-		statedb.Prepare(tx.Hash(), block.Hash(), i)
+		statedb.Prepare(tx.Hash(), i)
 		if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
 			return // Ugh, something went horribly wrong, bail out
 		}
diff --git a/core/state_processor.go b/core/state_processor.go
index 40a953f0d4f87d4d390225c2f1e3385f74a64616..d4c77ae41042100d317b4abb105185bf50bb1111 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -18,6 +18,7 @@ package core
 
 import (
 	"fmt"
+	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/consensus"
@@ -57,11 +58,13 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
 // transactions failed to execute due to insufficient gas it will return an error.
 func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
 	var (
-		receipts types.Receipts
-		usedGas  = new(uint64)
-		header   = block.Header()
-		allLogs  []*types.Log
-		gp       = new(GasPool).AddGas(block.GasLimit())
+		receipts    types.Receipts
+		usedGas     = new(uint64)
+		header      = block.Header()
+		blockHash   = block.Hash()
+		blockNumber = block.Number()
+		allLogs     []*types.Log
+		gp          = new(GasPool).AddGas(block.GasLimit())
 	)
 	// Mutate the block and state according to any hard-fork specs
 	if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
@@ -71,12 +74,12 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
 	vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
 	// Iterate over and process the individual transactions
 	for i, tx := range block.Transactions() {
-		msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number))
+		msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
 		if err != nil {
-			return nil, nil, 0, err
+			return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
 		}
-		statedb.Prepare(tx.Hash(), block.Hash(), i)
-		receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv)
+		statedb.Prepare(tx.Hash(), i)
+		receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
 		if err != nil {
 			return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
 		}
@@ -89,7 +92,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
 	return receipts, allLogs, *usedGas, nil
 }
 
-func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
+func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
 	// Create a new context to be used in the EVM environment.
 	txContext := NewEVMTxContext(msg)
 	evm.Reset(txContext, statedb)
@@ -102,10 +105,10 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
 
 	// Update the state with pending changes.
 	var root []byte
-	if config.IsByzantium(header.Number) {
+	if config.IsByzantium(blockNumber) {
 		statedb.Finalise(true)
 	} else {
-		root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
+		root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes()
 	}
 	*usedGas += result.UsedGas
 
@@ -126,10 +129,10 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
 	}
 
 	// Set the receipt logs and create the bloom filter.
-	receipt.Logs = statedb.GetLogs(tx.Hash())
+	receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash)
 	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
-	receipt.BlockHash = statedb.BlockHash()
-	receipt.BlockNumber = header.Number
+	receipt.BlockHash = blockHash
+	receipt.BlockNumber = blockNumber
 	receipt.TransactionIndex = uint(statedb.TxIndex())
 	return receipt, err
 }
@@ -139,12 +142,12 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
 // for the transaction, gas used and an error if the transaction failed,
 // indicating the block was invalid.
 func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
-	msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
+	msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), header.BaseFee)
 	if err != nil {
 		return nil, err
 	}
 	// Create a new context to be used in the EVM environment
 	blockContext := NewEVMBlockContext(header, bc, author)
 	vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
-	return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv)
+	return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
 }
diff --git a/core/state_processor_test.go b/core/state_processor_test.go
index 5976ecc3d4e4f274ee3e6368f1fe75d2a5b1cf2f..13a9eb810df66f9401b8f40be8a98326e8e0fe37 100644
--- a/core/state_processor_test.go
+++ b/core/state_processor_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/consensus"
 	"github.com/ethereum/go-ethereum/consensus/ethash"
+	"github.com/ethereum/go-ethereum/consensus/misc"
 	"github.com/ethereum/go-ethereum/core/rawdb"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/vm"
@@ -38,75 +39,249 @@ import (
 // contain invalid transactions
 func TestStateProcessorErrors(t *testing.T) {
 	var (
-		signer     = types.HomesteadSigner{}
-		testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
-		db         = rawdb.NewMemoryDatabase()
-		gspec      = &Genesis{
-			Config: params.TestChainConfig,
+		config = &params.ChainConfig{
+			ChainID:             big.NewInt(1),
+			HomesteadBlock:      big.NewInt(0),
+			EIP150Block:         big.NewInt(0),
+			EIP155Block:         big.NewInt(0),
+			EIP158Block:         big.NewInt(0),
+			ByzantiumBlock:      big.NewInt(0),
+			ConstantinopleBlock: big.NewInt(0),
+			PetersburgBlock:     big.NewInt(0),
+			IstanbulBlock:       big.NewInt(0),
+			MuirGlacierBlock:    big.NewInt(0),
+			BerlinBlock:         big.NewInt(0),
+			LondonBlock:         big.NewInt(0),
+			Ethash:              new(params.EthashConfig),
 		}
-		genesis       = gspec.MustCommit(db)
-		blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
+		signer     = types.LatestSigner(config)
+		testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	)
-	defer blockchain.Stop()
 	var makeTx = func(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *types.Transaction {
 		tx, _ := types.SignTx(types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data), signer, testKey)
 		return tx
 	}
-	for i, tt := range []struct {
-		txs  []*types.Transaction
-		want string
-	}{
-		{
-			txs: []*types.Transaction{
-				makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
-				makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
+	var mkDynamicTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int) *types.Transaction {
+		tx, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{
+			Nonce:     nonce,
+			GasTipCap: gasTipCap,
+			GasFeeCap: gasFeeCap,
+			Gas:       gasLimit,
+			To:        &to,
+			Value:     big.NewInt(0),
+		}), signer, testKey)
+		return tx
+	}
+	{ // Tests against a 'recent' chain definition
+		var (
+			db    = rawdb.NewMemoryDatabase()
+			gspec = &Genesis{
+				Config: config,
+				Alloc: GenesisAlloc{
+					common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
+						Balance: big.NewInt(1000000000000000000), // 1 ether
+						Nonce:   0,
+					},
+				},
+			}
+			genesis       = gspec.MustCommit(db)
+			blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
+		)
+		defer blockchain.Stop()
+		bigNumber := new(big.Int).SetBytes(common.FromHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"))
+		tooBigNumber := new(big.Int).Set(bigNumber)
+		tooBigNumber.Add(tooBigNumber, common.Big1)
+		for i, tt := range []struct {
+			txs  []*types.Transaction
+			want string
+		}{
+			{ // ErrNonceTooLow
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, big.NewInt(875000000), nil),
+					makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 1 [0x0026256b3939ed97e2c4a6f3fce8ecf83bdcfa6d507c47838c308a1fb0436f62]: nonce too low: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tx: 0 state: 1",
+			},
+			{ // ErrNonceTooHigh
+				txs: []*types.Transaction{
+					makeTx(100, common.Address{}, big.NewInt(0), params.TxGas, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 0 [0xdebad714ca7f363bd0d8121c4518ad48fa469ca81b0a081be3d10c17460f751b]: nonce too high: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tx: 100 state: 0",
+			},
+			{ // ErrGasLimitReached
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(0), 21000000, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 0 [0xbd49d8dadfd47fb846986695f7d4da3f7b2c48c8da82dbc211a26eb124883de9]: gas limit reached",
+			},
+			{ // ErrInsufficientFundsForTransfer
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(1000000000000000000), params.TxGas, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 0 [0x98c796b470f7fcab40aaef5c965a602b0238e1034cce6fb73823042dd0638d74]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 1000018375000000000",
+			},
+			{ // ErrInsufficientFunds
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, big.NewInt(900000000000000000), nil),
+				},
+				want: "could not apply tx 0 [0x4a69690c4b0cd85e64d0d9ea06302455b01e10a83db964d60281739752003440]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 18900000000000000000000",
+			},
+			// ErrGasUintOverflow
+			// One missing 'core' error is ErrGasUintOverflow: "gas uint64 overflow",
+			// In order to trigger that one, we'd have to allocate a _huge_ chunk of data, such that the
+			// multiplication len(data) +gas_per_byte overflows uint64. Not testable at the moment
+			{ // ErrIntrinsicGas
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(0), params.TxGas-1000, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 0 [0xcf3b049a0b516cb4f9274b3e2a264359e2ba53b2fb64b7bda2c634d5c9d01fca]: intrinsic gas too low: have 20000, want 21000",
+			},
+			{ // ErrGasLimitReached
+				txs: []*types.Transaction{
+					makeTx(0, common.Address{}, big.NewInt(0), params.TxGas*1000, big.NewInt(875000000), nil),
+				},
+				want: "could not apply tx 0 [0xbd49d8dadfd47fb846986695f7d4da3f7b2c48c8da82dbc211a26eb124883de9]: gas limit reached",
 			},
-			want: "could not apply tx 1 [0x36bfa6d14f1cd35a1be8cc2322982a595fabc0e799f09c1de3bad7bd5b1f7626]: nonce too low: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tx: 0 state: 1",
-		},
-		{
-			txs: []*types.Transaction{
-				makeTx(100, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
+			{ // ErrFeeCapTooLow
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(0), big.NewInt(0)),
+				},
+				want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0 baseFee: 875000000",
 			},
-			want: "could not apply tx 0 [0x51cd272d41ef6011d8138e18bf4043797aca9b713c7d39a97563f9bbe6bdbe6f]: nonce too high: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tx: 100 state: 0",
-		},
-		{
-			txs: []*types.Transaction{
-				makeTx(0, common.Address{}, big.NewInt(0), 21000000, nil, nil),
+			{ // ErrTipVeryHigh
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, tooBigNumber, big.NewInt(1)),
+				},
+				want: "could not apply tx 0 [0x15b8391b9981f266b32f3ab7da564bbeb3d6c21628364ea9b32a21139f89f712]: max priority fee per gas higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas bit length: 257",
 			},
-			want: "could not apply tx 0 [0x54c58b530824b0bb84b7a98183f08913b5d74e1cebc368515ef3c65edf8eb56a]: gas limit reached",
-		},
-		{
-			txs: []*types.Transaction{
-				makeTx(0, common.Address{}, big.NewInt(1), params.TxGas, nil, nil),
+			{ // ErrFeeCapVeryHigh
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), tooBigNumber),
+				},
+				want: "could not apply tx 0 [0x48bc299b83fdb345c57478f239e89814bb3063eb4e4b49f3b6057a69255c16bd]: max fee per gas higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas bit length: 257",
 			},
-			want: "could not apply tx 0 [0x3094b17498940d92b13baccf356ce8bfd6f221e926abc903d642fa1466c5b50e]: insufficient funds for transfer: address 0x71562b71999873DB5b286dF957af199Ec94617F7",
-		},
-		{
-			txs: []*types.Transaction{
-				makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, big.NewInt(0xffffff), nil),
+			{ // ErrTipAboveFeeCap
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(2), big.NewInt(1)),
+				},
+				want: "could not apply tx 0 [0xf987a31ff0c71895780a7612f965a0c8b056deb54e020bb44fa478092f14c9b4]: max priority fee per gas higher than max fee per gas: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas: 2, maxFeePerGas: 1",
 			},
-			want: "could not apply tx 0 [0xaa3f7d86802b1f364576d9071bf231e31d61b392d306831ac9cf706ff5371ce0]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 0 want 352321515000",
-		},
-		{
-			txs: []*types.Transaction{
-				makeTx(0, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
-				makeTx(1, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
-				makeTx(2, common.Address{}, big.NewInt(0), params.TxGas, nil, nil),
-				makeTx(3, common.Address{}, big.NewInt(0), params.TxGas-1000, big.NewInt(0), nil),
+			{ // ErrInsufficientFunds
+				// Available balance:           1000000000000000000
+				// Effective cost:                   18375000021000
+				// FeeCap * gas:                1050000000000000000
+				// This test is designed to have the effective cost be covered by the balance, but
+				// the extended requirement on FeeCap*gas < balance to fail
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), big.NewInt(50000000000000)),
+				},
+				want: "could not apply tx 0 [0x413603cd096a87f41b1660d3ed3e27d62e1da78eac138961c0a1314ed43bd129]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 1050000000000000000",
 			},
-			want: "could not apply tx 3 [0x836fab5882205362680e49b311a20646de03b630920f18ec6ee3b111a2cf6835]: intrinsic gas too low: have 20000, want 21000",
-		},
-		// The last 'core' error is ErrGasUintOverflow: "gas uint64 overflow", but in order to
-		// trigger that one, we'd have to allocate a _huge_ chunk of data, such that the
-		// multiplication len(data) +gas_per_byte overflows uint64. Not testable at the moment
-	} {
-		block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs)
-		_, err := blockchain.InsertChain(types.Blocks{block})
-		if err == nil {
-			t.Fatal("block imported without errors")
+			{ // Another ErrInsufficientFunds, this one to ensure that feecap/tip of max u256 is allowed
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas, bigNumber, bigNumber),
+				},
+				want: "could not apply tx 0 [0xd82a0c2519acfeac9a948258c47e784acd20651d9d80f9a1c67b4137651c3a24]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 2431633873983640103894990685182446064918669677978451844828609264166175722438635000",
+			},
+		} {
+			block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
+			_, err := blockchain.InsertChain(types.Blocks{block})
+			if err == nil {
+				t.Fatal("block imported without errors")
+			}
+			if have, want := err.Error(), tt.want; have != want {
+				t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want)
+			}
+		}
+	}
+
+	// ErrTxTypeNotSupported, For this, we need an older chain
+	{
+		var (
+			db    = rawdb.NewMemoryDatabase()
+			gspec = &Genesis{
+				Config: &params.ChainConfig{
+					ChainID:             big.NewInt(1),
+					HomesteadBlock:      big.NewInt(0),
+					EIP150Block:         big.NewInt(0),
+					EIP155Block:         big.NewInt(0),
+					EIP158Block:         big.NewInt(0),
+					ByzantiumBlock:      big.NewInt(0),
+					ConstantinopleBlock: big.NewInt(0),
+					PetersburgBlock:     big.NewInt(0),
+					IstanbulBlock:       big.NewInt(0),
+					MuirGlacierBlock:    big.NewInt(0),
+				},
+				Alloc: GenesisAlloc{
+					common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
+						Balance: big.NewInt(1000000000000000000), // 1 ether
+						Nonce:   0,
+					},
+				},
+			}
+			genesis       = gspec.MustCommit(db)
+			blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
+		)
+		defer blockchain.Stop()
+		for i, tt := range []struct {
+			txs  []*types.Transaction
+			want string
+		}{
+			{ // ErrTxTypeNotSupported
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)),
+				},
+				want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: transaction type not supported",
+			},
+		} {
+			block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
+			_, err := blockchain.InsertChain(types.Blocks{block})
+			if err == nil {
+				t.Fatal("block imported without errors")
+			}
+			if have, want := err.Error(), tt.want; have != want {
+				t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want)
+			}
 		}
-		if have, want := err.Error(), tt.want; have != want {
-			t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want)
+	}
+
+	// ErrSenderNoEOA, for this we need the sender to have contract code
+	{
+		var (
+			db    = rawdb.NewMemoryDatabase()
+			gspec = &Genesis{
+				Config: config,
+				Alloc: GenesisAlloc{
+					common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
+						Balance: big.NewInt(1000000000000000000), // 1 ether
+						Nonce:   0,
+						Code:    common.FromHex("0xB0B0FACE"),
+					},
+				},
+			}
+			genesis       = gspec.MustCommit(db)
+			blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
+		)
+		defer blockchain.Stop()
+		for i, tt := range []struct {
+			txs  []*types.Transaction
+			want string
+		}{
+			{ // ErrSenderNoEOA
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)),
+				},
+				want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1",
+			},
+		} {
+			block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
+			_, err := blockchain.InsertChain(types.Blocks{block})
+			if err == nil {
+				t.Fatal("block imported without errors")
+			}
+			if have, want := err.Error(), tt.want; have != want {
+				t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want)
+			}
 		}
 	}
 }
@@ -115,23 +290,25 @@ func TestStateProcessorErrors(t *testing.T) {
 // valid, and no proper post-state can be made. But from the perspective of the blockchain, the block is sufficiently
 // valid to be considered for import:
 // - valid pow (fake), ancestry, difficulty, gaslimit etc
-func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions) *types.Block {
+func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block {
 	header := &types.Header{
 		ParentHash: parent.Hash(),
 		Coinbase:   parent.Coinbase(),
-		Difficulty: engine.CalcDifficulty(&fakeChainReader{params.TestChainConfig}, parent.Time()+10, &types.Header{
+		Difficulty: engine.CalcDifficulty(&fakeChainReader{config}, parent.Time()+10, &types.Header{
 			Number:     parent.Number(),
 			Time:       parent.Time(),
 			Difficulty: parent.Difficulty(),
 			UncleHash:  parent.UncleHash(),
 		}),
-		GasLimit:  CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()),
+		GasLimit:  parent.GasLimit(),
 		Number:    new(big.Int).Add(parent.Number(), common.Big1),
 		Time:      parent.Time() + 10,
 		UncleHash: types.EmptyUncleHash,
 	}
+	if config.IsLondon(header.Number) {
+		header.BaseFee = misc.CalcBaseFee(config, parent.Header())
+	}
 	var receipts []*types.Receipt
-
 	// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
 	// Preferably something unique. So let's use a combo of blocknum + txhash
 	hasher := sha3.NewLegacyKeccak256()
diff --git a/core/state_transition.go b/core/state_transition.go
index d38e78212d1e609ff0bc43c71f0f1c9ad2471ab2..4160c622536633b3a4404f3d5a3bb69a4b366c1b 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -22,11 +22,15 @@ import (
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
+	cmath "github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/params"
 )
 
+var emptyCodeHash = crypto.Keccak256Hash(nil)
+
 /*
 The State Transitioning Model
 
@@ -49,6 +53,8 @@ type StateTransition struct {
 	msg        Message
 	gas        uint64
 	gasPrice   *big.Int
+	gasFeeCap  *big.Int
+	gasTipCap  *big.Int
 	initialGas uint64
 	value      *big.Int
 	data       []byte
@@ -62,11 +68,13 @@ type Message interface {
 	To() *common.Address
 
 	GasPrice() *big.Int
+	GasFeeCap() *big.Int
+	GasTipCap() *big.Int
 	Gas() uint64
 	Value() *big.Int
 
 	Nonce() uint64
-	CheckNonce() bool
+	IsFake() bool
 	Data() []byte
 	AccessList() types.AccessList
 }
@@ -150,13 +158,15 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
 // NewStateTransition initialises and returns a new state transition object.
 func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
 	return &StateTransition{
-		gp:       gp,
-		evm:      evm,
-		msg:      msg,
-		gasPrice: msg.GasPrice(),
-		value:    msg.Value(),
-		data:     msg.Data(),
-		state:    evm.StateDB,
+		gp:        gp,
+		evm:       evm,
+		msg:       msg,
+		gasPrice:  msg.GasPrice(),
+		gasFeeCap: msg.GasFeeCap(),
+		gasTipCap: msg.GasTipCap(),
+		value:     msg.Value(),
+		data:      msg.Data(),
+		state:     evm.StateDB,
 	}
 }
 
@@ -180,8 +190,15 @@ func (st *StateTransition) to() common.Address {
 }
 
 func (st *StateTransition) buyGas() error {
-	mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice)
-	if have, want := st.state.GetBalance(st.msg.From()), mgval; have.Cmp(want) < 0 {
+	mgval := new(big.Int).SetUint64(st.msg.Gas())
+	mgval = mgval.Mul(mgval, st.gasPrice)
+	balanceCheck := mgval
+	if st.gasFeeCap != nil {
+		balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
+		balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
+		balanceCheck.Add(balanceCheck, st.value)
+	}
+	if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
 		return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
 	}
 	if err := st.gp.SubGas(st.msg.Gas()); err != nil {
@@ -195,8 +212,9 @@ func (st *StateTransition) buyGas() error {
 }
 
 func (st *StateTransition) preCheck() error {
-	// Make sure this transaction's nonce is correct.
-	if st.msg.CheckNonce() {
+	// Only check transactions that are not fake
+	if !st.msg.IsFake() {
+		// Make sure this transaction's nonce is correct.
 		stNonce := st.state.GetNonce(st.msg.From())
 		if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
 			return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
@@ -205,6 +223,35 @@ func (st *StateTransition) preCheck() error {
 			return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
 				st.msg.From().Hex(), msgNonce, stNonce)
 		}
+		// Make sure the sender is an EOA
+		if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
+			return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
+				st.msg.From().Hex(), codeHash)
+		}
+	}
+	// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
+	if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
+		// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
+		if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
+			if l := st.gasFeeCap.BitLen(); l > 256 {
+				return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
+					st.msg.From().Hex(), l)
+			}
+			if l := st.gasTipCap.BitLen(); l > 256 {
+				return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
+					st.msg.From().Hex(), l)
+			}
+			if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
+				return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
+					st.msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
+			}
+			// This will panic if baseFee is nil, but basefee presence is verified
+			// as part of header validation.
+			if st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
+				return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
+					st.msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
+			}
+		}
 	}
 	return st.buyGas()
 }
@@ -244,6 +291,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
 	sender := vm.AccountRef(msg.From())
 	homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
 	istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
+	london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber)
 	contractCreation := msg.To() == nil
 
 	// Check clauses 4-5, subtract intrinsic gas if everything is correct
@@ -276,13 +324,24 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
 		st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
 		ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
 	}
-	st.refundGas()
-	st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
 
-	amount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)
+	if !london {
+		// Before EIP-3529: refunds were capped to gasUsed / 2
+		st.refundGas(params.RefundQuotient)
+	} else {
+		// After EIP-3529: refunds are capped to gasUsed / 5
+		st.refundGas(params.RefundQuotientEIP3529)
+	}
+	effectiveTip := st.gasPrice
+	if london {
+		effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
+	}
+	amount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)
+	st.state.AddBalance(st.evm.Context.Coinbase, amount)
 	output1 := new(big.Int).SetBytes(input1.Bytes())
 	output2 := new(big.Int).SetBytes(input2.Bytes())
 
+	// Deprecating transfer log and will be removed in future fork. PLEASE DO NOT USE this transfer log going forward. Parameters won't get updated as expected going forward with EIP1559
 	// add transfer log
 	AddFeeTransferLog(
 		st.state,
@@ -304,9 +363,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
 	}, nil
 }
 
-func (st *StateTransition) refundGas() {
-	// Apply refund counter, capped to half of the used gas.
-	refund := st.gasUsed() / 2
+func (st *StateTransition) refundGas(refundQuotient uint64) {
+	// Apply refund counter, capped to a refund quotient
+	refund := st.gasUsed() / refundQuotient
 	if refund > st.state.GetRefund() {
 		refund = st.state.GetRefund()
 	}
diff --git a/core/tx_journal.go b/core/tx_journal.go
index 41b5156d4ad213b4a6582c24fdf253dd4f89074e..d282126a083ae2695604115df7a7a84544452505 100644
--- a/core/tx_journal.go
+++ b/core/tx_journal.go
@@ -138,7 +138,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro
 		journal.writer = nil
 	}
 	// Generate a new journal with the contents of the current pool
-	replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
+	replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
 	if err != nil {
 		return err
 	}
@@ -158,7 +158,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro
 	if err = os.Rename(journal.path+".new", journal.path); err != nil {
 		return err
 	}
-	sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0755)
+	sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0644)
 	if err != nil {
 		return err
 	}
diff --git a/core/tx_list.go b/core/tx_list.go
index 894640d570c7efd567ad62f91af1c35c1664779b..607838ba37c9ccef37e9c54f2a0c0ac26bededa8 100644
--- a/core/tx_list.go
+++ b/core/tx_list.go
@@ -21,6 +21,7 @@ import (
 	"math"
 	"math/big"
 	"sort"
+	"time"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
@@ -279,15 +280,23 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran
 	// If there's an older better transaction, abort
 	old := l.txs.Get(tx.Nonce())
 	if old != nil {
-		// threshold = oldGP * (100 + priceBump) / 100
+		if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 {
+			return false, nil
+		}
+		// thresholdFeeCap = oldFC  * (100 + priceBump) / 100
 		a := big.NewInt(100 + int64(priceBump))
-		a = a.Mul(a, old.GasPrice())
+		aFeeCap := new(big.Int).Mul(a, old.GasFeeCap())
+		aTip := a.Mul(a, old.GasTipCap())
+
+		// thresholdTip    = oldTip * (100 + priceBump) / 100
 		b := big.NewInt(100)
-		threshold := a.Div(a, b)
-		// Have to ensure that the new gas price is higher than the old gas
-		// price as well as checking the percentage threshold to ensure that
+		thresholdFeeCap := aFeeCap.Div(aFeeCap, b)
+		thresholdTip := aTip.Div(aTip, b)
+
+		// Have to ensure that either the new fee cap or tip is higher than the
+		// old ones as well as checking the percentage threshold to ensure that
 		// this is accurate for low (Wei-level) gas price replacements
-		if old.GasPriceCmp(tx) >= 0 || tx.GasPriceIntCmp(threshold) < 0 {
+		if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 {
 			return false, nil
 		}
 	}
@@ -406,34 +415,54 @@ func (l *txList) LastElement() *types.Transaction {
 }
 
 // priceHeap is a heap.Interface implementation over transactions for retrieving
-// price-sorted transactions to discard when the pool fills up.
-type priceHeap []*types.Transaction
+// price-sorted transactions to discard when the pool fills up. If baseFee is set
+// then the heap is sorted based on the effective tip based on the given base fee.
+// If baseFee is nil then the sorting is based on gasFeeCap.
+type priceHeap struct {
+	baseFee *big.Int // heap should always be re-sorted after baseFee is changed
+	list    []*types.Transaction
+}
 
-func (h priceHeap) Len() int      { return len(h) }
-func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+func (h *priceHeap) Len() int      { return len(h.list) }
+func (h *priceHeap) Swap(i, j int) { h.list[i], h.list[j] = h.list[j], h.list[i] }
 
-func (h priceHeap) Less(i, j int) bool {
-	// Sort primarily by price, returning the cheaper one
-	switch h[i].GasPriceCmp(h[j]) {
+func (h *priceHeap) Less(i, j int) bool {
+	switch h.cmp(h.list[i], h.list[j]) {
 	case -1:
 		return true
 	case 1:
 		return false
+	default:
+		return h.list[i].Nonce() > h.list[j].Nonce()
 	}
-	// If the prices match, stabilize via nonces (high nonce is worse)
-	return h[i].Nonce() > h[j].Nonce()
+}
+
+func (h *priceHeap) cmp(a, b *types.Transaction) int {
+	if h.baseFee != nil {
+		// Compare effective tips if baseFee is specified
+		if c := a.EffectiveGasTipCmp(b, h.baseFee); c != 0 {
+			return c
+		}
+	}
+	// Compare fee caps if baseFee is not specified or effective tips are equal
+	if c := a.GasFeeCapCmp(b); c != 0 {
+		return c
+	}
+	// Compare tips if effective tips and fee caps are equal
+	return a.GasTipCapCmp(b)
 }
 
 func (h *priceHeap) Push(x interface{}) {
-	*h = append(*h, x.(*types.Transaction))
+	tx := x.(*types.Transaction)
+	h.list = append(h.list, tx)
 }
 
 func (h *priceHeap) Pop() interface{} {
-	old := *h
+	old := h.list
 	n := len(old)
 	x := old[n-1]
 	old[n-1] = nil
-	*h = old[0 : n-1]
+	h.list = old[0 : n-1]
 	return x
 }
 
@@ -441,17 +470,29 @@ func (h *priceHeap) Pop() interface{} {
 // contents in a price-incrementing way. It's built opon the all transactions
 // in txpool but only interested in the remote part. It means only remote transactions
 // will be considered for tracking, sorting, eviction, etc.
+//
+// Two heaps are used for sorting: the urgent heap (based on effective tip in the next
+// block) and the floating heap (based on gasFeeCap). Always the bigger heap is chosen for
+// eviction. Transactions evicted from the urgent heap are first demoted into the floating heap.
+// In some cases (during a congestion, when blocks are full) the urgent heap can provide
+// better candidates for inclusion while in other cases (at the top of the baseFee peak)
+// the floating heap is better. When baseFee is decreasing they behave similarly.
 type txPricedList struct {
-	all     *txLookup  // Pointer to the map of all transactions
-	remotes *priceHeap // Heap of prices of all the stored **remote** transactions
-	stales  int        // Number of stale price points to (re-heap trigger)
+	all              *txLookup // Pointer to the map of all transactions
+	urgent, floating priceHeap // Heaps of prices of all the stored **remote** transactions
+	stales           int       // Number of stale price points to (re-heap trigger)
 }
 
+const (
+	// urgentRatio : floatingRatio is the capacity ratio of the two queues
+	urgentRatio   = 4
+	floatingRatio = 1
+)
+
 // newTxPricedList creates a new price-sorted transaction heap.
 func newTxPricedList(all *txLookup) *txPricedList {
 	return &txPricedList{
-		all:     all,
-		remotes: new(priceHeap),
+		all: all,
 	}
 }
 
@@ -460,7 +501,8 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
 	if local {
 		return
 	}
-	heap.Push(l.remotes, tx)
+	// Insert every new transaction to the urgent heap first; Discard will balance the heaps
+	heap.Push(&l.urgent, tx)
 }
 
 // Removed notifies the prices transaction list that an old transaction dropped
@@ -469,58 +511,43 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
 func (l *txPricedList) Removed(count int) {
 	// Bump the stale counter, but exit if still too low (< 25%)
 	l.stales += count
-	if l.stales <= len(*l.remotes)/4 {
+	if l.stales <= (len(l.urgent.list)+len(l.floating.list))/4 {
 		return
 	}
 	// Seems we've reached a critical number of stale transactions, reheap
 	l.Reheap()
 }
 
-// Cap finds all the transactions below the given price threshold, drops them
-// from the priced list and returns them for further removal from the entire pool.
-//
-// Note: only remote transactions will be considered for eviction.
-func (l *txPricedList) Cap(threshold *big.Int) types.Transactions {
-	drop := make(types.Transactions, 0, 128) // Remote underpriced transactions to drop
-	for len(*l.remotes) > 0 {
-		// Discard stale transactions if found during cleanup
-		cheapest := (*l.remotes)[0]
-		if l.all.GetRemote(cheapest.Hash()) == nil { // Removed or migrated
-			heap.Pop(l.remotes)
-			l.stales--
-			continue
-		}
-		// Stop the discards if we've reached the threshold
-		if cheapest.GasPriceIntCmp(threshold) >= 0 {
-			break
-		}
-		heap.Pop(l.remotes)
-		drop = append(drop, cheapest)
-	}
-	return drop
-}
-
 // Underpriced checks whether a transaction is cheaper than (or as cheap as) the
 // lowest priced (remote) transaction currently being tracked.
 func (l *txPricedList) Underpriced(tx *types.Transaction) bool {
+	// Note: with two queues, being underpriced is defined as being worse than the worst item
+	// in all non-empty queues if there is any. If both queues are empty then nothing is underpriced.
+	return (l.underpricedFor(&l.urgent, tx) || len(l.urgent.list) == 0) &&
+		(l.underpricedFor(&l.floating, tx) || len(l.floating.list) == 0) &&
+		(len(l.urgent.list) != 0 || len(l.floating.list) != 0)
+}
+
+// underpricedFor checks whether a transaction is cheaper than (or as cheap as) the
+// lowest priced (remote) transaction in the given heap.
+func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool {
 	// Discard stale price points if found at the heap start
-	for len(*l.remotes) > 0 {
-		head := []*types.Transaction(*l.remotes)[0]
+	for len(h.list) > 0 {
+		head := h.list[0]
 		if l.all.GetRemote(head.Hash()) == nil { // Removed or migrated
 			l.stales--
-			heap.Pop(l.remotes)
+			heap.Pop(h)
 			continue
 		}
 		break
 	}
 	// Check if the transaction is underpriced or not
-	if len(*l.remotes) == 0 {
+	if len(h.list) == 0 {
 		return false // There is no remote transaction at all.
 	}
 	// If the remote transaction is even cheaper than the
 	// cheapest one tracked locally, reject it.
-	cheapest := []*types.Transaction(*l.remotes)[0]
-	return cheapest.GasPriceCmp(tx) >= 0
+	return h.cmp(h.list[0], tx) >= 0
 }
 
 // Discard finds a number of most underpriced transactions, removes them from the
@@ -529,21 +556,36 @@ func (l *txPricedList) Underpriced(tx *types.Transaction) bool {
 // Note local transaction won't be considered for eviction.
 func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool) {
 	drop := make(types.Transactions, 0, slots) // Remote underpriced transactions to drop
-	for len(*l.remotes) > 0 && slots > 0 {
-		// Discard stale transactions if found during cleanup
-		tx := heap.Pop(l.remotes).(*types.Transaction)
-		if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
-			l.stales--
-			continue
+	for slots > 0 {
+		if len(l.urgent.list)*floatingRatio > len(l.floating.list)*urgentRatio || floatingRatio == 0 {
+			// Discard stale transactions if found during cleanup
+			tx := heap.Pop(&l.urgent).(*types.Transaction)
+			if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
+				l.stales--
+				continue
+			}
+			// Non stale transaction found, move to floating heap
+			heap.Push(&l.floating, tx)
+		} else {
+			if len(l.floating.list) == 0 {
+				// Stop if both heaps are empty
+				break
+			}
+			// Discard stale transactions if found during cleanup
+			tx := heap.Pop(&l.floating).(*types.Transaction)
+			if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
+				l.stales--
+				continue
+			}
+			// Non stale transaction found, discard it
+			drop = append(drop, tx)
+			slots -= numSlots(tx)
 		}
-		// Non stale transaction found, discard it
-		drop = append(drop, tx)
-		slots -= numSlots(tx)
 	}
 	// If we still can't make enough room for the new transaction
 	if slots > 0 && !force {
 		for _, tx := range drop {
-			heap.Push(l.remotes, tx)
+			heap.Push(&l.urgent, tx)
 		}
 		return nil, false
 	}
@@ -552,12 +594,32 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
 
 // Reheap forcibly rebuilds the heap based on the current remote transaction set.
 func (l *txPricedList) Reheap() {
-	reheap := make(priceHeap, 0, l.all.RemoteCount())
-
-	l.stales, l.remotes = 0, &reheap
+	start := time.Now()
+	l.stales = 0
+	l.urgent.list = make([]*types.Transaction, 0, l.all.RemoteCount())
 	l.all.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
-		*l.remotes = append(*l.remotes, tx)
+		l.urgent.list = append(l.urgent.list, tx)
 		return true
 	}, false, true) // Only iterate remotes
-	heap.Init(l.remotes)
+	heap.Init(&l.urgent)
+
+	// balance out the two heaps by moving the worse half of transactions into the
+	// floating heap
+	// Note: Discard would also do this before the first eviction but Reheap can do
+	// is more efficiently. Also, Underpriced would work suboptimally the first time
+	// if the floating queue was empty.
+	floatingCount := len(l.urgent.list) * floatingRatio / (urgentRatio + floatingRatio)
+	l.floating.list = make([]*types.Transaction, floatingCount)
+	for i := 0; i < floatingCount; i++ {
+		l.floating.list[i] = heap.Pop(&l.urgent).(*types.Transaction)
+	}
+	heap.Init(&l.floating)
+	reheapTimer.Update(time.Since(start))
+}
+
+// SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not
+// necessary to call right before SetBaseFee when processing a new block.
+func (l *txPricedList) SetBaseFee(baseFee *big.Int) {
+	l.urgent.baseFee = baseFee
+	l.Reheap()
 }
diff --git a/core/tx_pool.go b/core/tx_pool.go
index 5db1d3df329d6a33f0f090eac618d4025eac9256..f6228df2fad4bfa04d577c4f74dc31f69b62e3e6 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/prque"
+	"github.com/ethereum/go-ethereum/consensus/misc"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/event"
@@ -115,6 +116,8 @@ var (
 	queuedGauge  = metrics.NewRegisteredGauge("txpool/queued", nil)
 	localGauge   = metrics.NewRegisteredGauge("txpool/local", nil)
 	slotsGauge   = metrics.NewRegisteredGauge("txpool/slots", nil)
+
+	reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil)
 )
 
 // TxStatus is the current status of a transaction as seen by the pool.
@@ -165,7 +168,7 @@ var DefaultTxPoolConfig = TxPoolConfig{
 	PriceBump:  10,
 
 	AccountSlots: 16,
-	GlobalSlots:  4096,
+	GlobalSlots:  4096 + 1024, // urgent + floating queue capacity with 4:1 ratio
 	AccountQueue: 64,
 	GlobalQueue:  1024,
 
@@ -230,6 +233,7 @@ type TxPool struct {
 
 	istanbul bool // Fork indicator whether we are in the istanbul stage.
 	eip2718  bool // Fork indicator whether we are using EIP-2718 type transactions.
+	eip1559  bool // Fork indicator whether we are using EIP-1559 type transactions.
 
 	currentState  *state.StateDB // Current state in the blockchain head
 	pendingNonces *txNoncer      // Pending state tracking virtual nonces
@@ -426,10 +430,18 @@ func (pool *TxPool) SetGasPrice(price *big.Int) {
 	pool.mu.Lock()
 	defer pool.mu.Unlock()
 
+	old := pool.gasPrice
 	pool.gasPrice = price
-	for _, tx := range pool.priced.Cap(price) {
-		pool.removeTx(tx.Hash(), false)
+	// if the min miner fee increased, remove transactions below the new threshold
+	if price.Cmp(old) > 0 {
+		// pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead
+		drop := pool.all.RemotesBelowTip(price)
+		for _, tx := range drop {
+			pool.removeTx(tx.Hash(), false)
+		}
+		pool.priced.Removed(len(drop))
 	}
+
 	log.Info("Transaction pool price threshold updated", "price", price)
 }
 
@@ -482,16 +494,50 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
 	return pending, queued
 }
 
+// ContentFrom retrieves the data content of the transaction pool, returning the
+// pending as well as queued transactions of this address, grouped by nonce.
+func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
+	pool.mu.RLock()
+	defer pool.mu.RUnlock()
+
+	var pending types.Transactions
+	if list, ok := pool.pending[addr]; ok {
+		pending = list.Flatten()
+	}
+	var queued types.Transactions
+	if list, ok := pool.queue[addr]; ok {
+		queued = list.Flatten()
+	}
+	return pending, queued
+}
+
 // Pending retrieves all currently processable transactions, grouped by origin
 // account and sorted by nonce. The returned transaction set is a copy and can be
 // freely modified by calling code.
-func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
+//
+// The enforceTips parameter can be used to do an extra filtering on the pending
+// transactions and only return those whose **effective** tip is large enough in
+// the next pending execution environment.
+func (pool *TxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) {
 	pool.mu.Lock()
 	defer pool.mu.Unlock()
 
 	pending := make(map[common.Address]types.Transactions)
 	for addr, list := range pool.pending {
-		pending[addr] = list.Flatten()
+		txs := list.Flatten()
+
+		// If the miner requests tip enforcement, cap the lists now
+		if enforceTips && !pool.locals.contains(addr) {
+			for i, tx := range txs {
+				if tx.EffectiveGasTipIntCmp(pool.gasPrice, pool.priced.urgent.baseFee) < 0 {
+					txs = txs[:i]
+					break
+				}
+			}
+		}
+		if len(txs) > 0 {
+			pending[addr] = txs
+		}
 	}
 	return pending, nil
 }
@@ -527,6 +573,10 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
 	if !pool.eip2718 && tx.Type() != types.LegacyTxType {
 		return ErrTxTypeNotSupported
 	}
+	// Reject dynamic fee transactions until EIP-1559 activates.
+	if !pool.eip1559 && tx.Type() == types.DynamicFeeTxType {
+		return ErrTxTypeNotSupported
+	}
 	// Reject transactions over defined size to prevent DOS attacks
 	if uint64(tx.Size()) > txMaxSize {
 		return ErrOversizedData
@@ -540,13 +590,24 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
 	if pool.currentMaxGas < tx.Gas() {
 		return ErrGasLimit
 	}
+	// Sanity check for extremely large numbers
+	if tx.GasFeeCap().BitLen() > 256 {
+		return ErrFeeCapVeryHigh
+	}
+	if tx.GasTipCap().BitLen() > 256 {
+		return ErrTipVeryHigh
+	}
+	// Ensure gasFeeCap is greater than or equal to gasTipCap.
+	if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 {
+		return ErrTipAboveFeeCap
+	}
 	// Make sure the transaction is signed properly.
 	from, err := types.Sender(pool.signer, tx)
 	if err != nil {
 		return ErrInvalidSender
 	}
-	// Drop non-local transactions under our own minimal accepted gas price
-	if !local && tx.GasPriceIntCmp(pool.gasPrice) < 0 {
+	// Drop non-local transactions under our own minimal accepted gas price or tip
+	if !local && tx.GasTipCapIntCmp(pool.gasPrice) < 0 {
 		return ErrUnderpriced
 	}
 	// Ensure the transaction adheres to nonce ordering
@@ -574,8 +635,8 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
 // pending or queued one, it overwrites the previous transaction if its price is higher.
 //
 // If a newly added transaction is marked as local, its sending account will be
-// whitelisted, preventing any associated transaction from being dropped out of the pool
-// due to pricing constraints.
+// be added to the allowlist, preventing any associated transaction from being dropped
+// out of the pool due to pricing constraints.
 func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err error) {
 	// If the transaction is already known, discard it
 	hash := tx.Hash()
@@ -595,10 +656,10 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
 		return false, err
 	}
 	// If the transaction pool is full, discard underpriced transactions
-	if uint64(pool.all.Count()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
+	if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
 		// If the new transaction is underpriced, don't accept it
 		if !isLocal && pool.priced.Underpriced(tx) {
-			log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice())
+			log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
 			underpricedTxMeter.Mark(1)
 			return false, ErrUnderpriced
 		}
@@ -615,7 +676,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
 		}
 		// Kick out the underpriced remote transactions.
 		for _, tx := range drop {
-			log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice())
+			log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
 			underpricedTxMeter.Mark(1)
 			pool.removeTx(tx.Hash(), false)
 		}
@@ -1088,6 +1149,10 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
 	// because of another transaction (e.g. higher gas price).
 	if reset != nil {
 		pool.demoteUnexecutables()
+		if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
+			pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead)
+			pool.priced.SetBaseFee(pendingBaseFee)
+		}
 	}
 	// Ensure pool.queue and pool.pending sizes stay within the configured limits.
 	pool.truncatePending()
@@ -1205,6 +1270,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
 	next := new(big.Int).Add(newHead.Number, big.NewInt(1))
 	pool.istanbul = pool.chainconfig.IsIstanbul(next)
 	pool.eip2718 = pool.chainconfig.IsBerlin(next)
+	pool.eip1559 = pool.chainconfig.IsLondon(next)
 }
 
 // promoteExecutables moves transactions that have become processable from the
@@ -1408,6 +1474,10 @@ func (pool *TxPool) truncateQueue() {
 // demoteUnexecutables removes invalid and processed transactions from the pools
 // executable/pending queue and any subsequent transactions that become unexecutable
 // are moved back into the future queue.
+//
+// Note: transactions are not marked as removed in the priced list because re-heaping
+// is always explicitly triggered by SetBaseFee and it would be unnecessary and wasteful
+// to trigger a re-heap is this function
 func (pool *TxPool) demoteUnexecutables() {
 	// Iterate over all accounts and demote any non-executable transactions
 	for addr, list := range pool.pending {
@@ -1427,7 +1497,6 @@ func (pool *TxPool) demoteUnexecutables() {
 			log.Trace("Removed unpayable pending transaction", "hash", hash)
 			pool.all.Remove(hash)
 		}
-		pool.priced.Removed(len(olds) + len(drops))
 		pendingNofundsMeter.Mark(int64(len(drops)))
 
 		for _, tx := range invalids {
@@ -1709,6 +1778,18 @@ func (t *txLookup) RemoteToLocals(locals *accountSet) int {
 	return migrated
 }
 
+// RemotesBelowTip finds all remote transactions below the given tip threshold.
+func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions {
+	found := make(types.Transactions, 0, 128)
+	t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
+		if tx.GasTipCapIntCmp(threshold) < 0 {
+			found = append(found, tx)
+		}
+		return true
+	}, false, true) // Only iterate remotes
+	return found
+}
+
 // numSlots calculates the number of slots needed for a single transaction.
 func numSlots(tx *types.Transaction) int {
 	return int((tx.Size() + txSlotSize - 1) / txSlotSize)
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index 5d555f5a9cfd31fdb897ff0922faf656f6686d39..e02096fe25ed680bd0b211513d91df34275d614d 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -37,13 +37,23 @@ import (
 	"github.com/ethereum/go-ethereum/trie"
 )
 
-// testTxPoolConfig is a transaction pool configuration without stateful disk
-// sideeffects used during testing.
-var testTxPoolConfig TxPoolConfig
+var (
+	// testTxPoolConfig is a transaction pool configuration without stateful disk
+	// sideeffects used during testing.
+	testTxPoolConfig TxPoolConfig
+
+	// eip1559Config is a chain config with EIP-1559 enabled at block 0.
+	eip1559Config *params.ChainConfig
+)
 
 func init() {
 	testTxPoolConfig = DefaultTxPoolConfig
 	testTxPoolConfig.Journal = ""
+
+	cpy := *params.TestChainConfig
+	eip1559Config = &cpy
+	eip1559Config.BerlinBlock = common.Big0
+	eip1559Config.LondonBlock = common.Big0
 }
 
 type testBlockChain struct {
@@ -87,12 +97,31 @@ func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key
 	return tx
 }
 
+func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
+	tx, _ := types.SignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.DynamicFeeTx{
+		ChainID:    params.TestChainConfig.ChainID,
+		Nonce:      nonce,
+		GasTipCap:  tip,
+		GasFeeCap:  gasFee,
+		Gas:        gaslimit,
+		To:         &common.Address{},
+		Value:      big.NewInt(100),
+		Data:       nil,
+		AccessList: nil,
+	})
+	return tx
+}
+
 func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
+	return setupTxPoolWithConfig(params.TestChainConfig)
+}
+
+func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) {
 	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
 	blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)}
 
 	key, _ := crypto.GenerateKey()
-	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
+	pool := NewTxPool(testTxPoolConfig, config, blockchain)
 
 	return pool, key
 }
@@ -108,7 +137,7 @@ func validateTxPoolInternals(pool *TxPool) error {
 		return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued)
 	}
 	pool.priced.Reheap()
-	priced, remote := pool.priced.remotes.Len(), pool.all.RemoteCount()
+	priced, remote := pool.priced.urgent.Len()+pool.priced.floating.Len(), pool.all.RemoteCount()
 	if priced != remote {
 		return fmt.Errorf("total priced transaction count %d != %d", priced, remote)
 	}
@@ -223,7 +252,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
 	trigger = true
 	<-pool.requestReset(nil, nil)
 
-	_, err := pool.Pending()
+	_, err := pool.Pending(false)
 	if err != nil {
 		t.Fatalf("Could not fetch pending transactions: %v", err)
 	}
@@ -233,6 +262,18 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
 	}
 }
 
+func testAddBalance(pool *TxPool, addr common.Address, amount *big.Int) {
+	pool.mu.Lock()
+	pool.currentState.AddBalance(addr, amount)
+	pool.mu.Unlock()
+}
+
+func testSetNonce(pool *TxPool, addr common.Address, nonce uint64) {
+	pool.mu.Lock()
+	pool.currentState.SetNonce(addr, nonce)
+	pool.mu.Unlock()
+}
+
 func TestInvalidTransactions(t *testing.T) {
 	t.Parallel()
 
@@ -242,19 +283,19 @@ func TestInvalidTransactions(t *testing.T) {
 	tx := transaction(0, 100, key)
 	from, _ := deriveSender(tx)
 
-	pool.currentState.AddBalance(from, big.NewInt(1))
+	testAddBalance(pool, from, big.NewInt(1))
 	if err := pool.AddRemote(tx); !errors.Is(err, ErrInsufficientFunds) {
 		t.Error("expected", ErrInsufficientFunds)
 	}
 
 	balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()))
-	pool.currentState.AddBalance(from, balance)
+	testAddBalance(pool, from, balance)
 	if err := pool.AddRemote(tx); !errors.Is(err, ErrIntrinsicGas) {
 		t.Error("expected", ErrIntrinsicGas, "got", err)
 	}
 
-	pool.currentState.SetNonce(from, 1)
-	pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff))
+	testSetNonce(pool, from, 1)
+	testAddBalance(pool, from, big.NewInt(0xffffffffffffff))
 	tx = transaction(0, 100000, key)
 	if err := pool.AddRemote(tx); !errors.Is(err, ErrNonceTooLow) {
 		t.Error("expected", ErrNonceTooLow)
@@ -278,7 +319,7 @@ func TestTransactionQueue(t *testing.T) {
 
 	tx := transaction(0, 100, key)
 	from, _ := deriveSender(tx)
-	pool.currentState.AddBalance(from, big.NewInt(1000))
+	testAddBalance(pool, from, big.NewInt(1000))
 	<-pool.requestReset(nil, nil)
 
 	pool.enqueueTx(tx.Hash(), tx, false, true)
@@ -289,7 +330,7 @@ func TestTransactionQueue(t *testing.T) {
 
 	tx = transaction(1, 100, key)
 	from, _ = deriveSender(tx)
-	pool.currentState.SetNonce(from, 2)
+	testSetNonce(pool, from, 2)
 	pool.enqueueTx(tx.Hash(), tx, false, true)
 
 	<-pool.requestPromoteExecutables(newAccountSet(pool.signer, from))
@@ -311,7 +352,7 @@ func TestTransactionQueue2(t *testing.T) {
 	tx2 := transaction(10, 100, key)
 	tx3 := transaction(11, 100, key)
 	from, _ := deriveSender(tx1)
-	pool.currentState.AddBalance(from, big.NewInt(1000))
+	testAddBalance(pool, from, big.NewInt(1000))
 	pool.reset(nil, nil)
 
 	pool.enqueueTx(tx1.Hash(), tx1, false, true)
@@ -335,12 +376,45 @@ func TestTransactionNegativeValue(t *testing.T) {
 
 	tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key)
 	from, _ := deriveSender(tx)
-	pool.currentState.AddBalance(from, big.NewInt(1))
+	testAddBalance(pool, from, big.NewInt(1))
 	if err := pool.AddRemote(tx); err != ErrNegativeValue {
 		t.Error("expected", ErrNegativeValue, "got", err)
 	}
 }
 
+func TestTransactionTipAboveFeeCap(t *testing.T) {
+	t.Parallel()
+
+	pool, key := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+
+	tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key)
+
+	if err := pool.AddRemote(tx); err != ErrTipAboveFeeCap {
+		t.Error("expected", ErrTipAboveFeeCap, "got", err)
+	}
+}
+
+func TestTransactionVeryHighValues(t *testing.T) {
+	t.Parallel()
+
+	pool, key := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+
+	veryBigNumber := big.NewInt(1)
+	veryBigNumber.Lsh(veryBigNumber, 300)
+
+	tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key)
+	if err := pool.AddRemote(tx); err != ErrTipVeryHigh {
+		t.Error("expected", ErrTipVeryHigh, "got", err)
+	}
+
+	tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key)
+	if err := pool.AddRemote(tx2); err != ErrFeeCapVeryHigh {
+		t.Error("expected", ErrFeeCapVeryHigh, "got", err)
+	}
+}
+
 func TestTransactionChainFork(t *testing.T) {
 	t.Parallel()
 
@@ -428,7 +502,7 @@ func TestTransactionMissingNonce(t *testing.T) {
 	defer pool.Stop()
 
 	addr := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(addr, big.NewInt(100000000000000))
+	testAddBalance(pool, addr, big.NewInt(100000000000000))
 	tx := transaction(1, 100000, key)
 	if _, err := pool.add(tx, false); err != nil {
 		t.Error("didn't expect error", err)
@@ -452,8 +526,8 @@ func TestTransactionNonceRecovery(t *testing.T) {
 	defer pool.Stop()
 
 	addr := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.SetNonce(addr, n)
-	pool.currentState.AddBalance(addr, big.NewInt(100000000000000))
+	testSetNonce(pool, addr, n)
+	testAddBalance(pool, addr, big.NewInt(100000000000000))
 	<-pool.requestReset(nil, nil)
 
 	tx := transaction(n, 100000, key)
@@ -461,7 +535,7 @@ func TestTransactionNonceRecovery(t *testing.T) {
 		t.Error(err)
 	}
 	// simulate some weird re-order of transactions and missing nonce(s)
-	pool.currentState.SetNonce(addr, n-1)
+	testSetNonce(pool, addr, n-1)
 	<-pool.requestReset(nil, nil)
 	if fn := pool.Nonce(addr); fn != n-1 {
 		t.Errorf("expected nonce to be %d, got %d", n-1, fn)
@@ -478,7 +552,7 @@ func TestTransactionDropping(t *testing.T) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000))
+	testAddBalance(pool, account, big.NewInt(1000))
 
 	// Add some pending and some queued transactions
 	var (
@@ -526,7 +600,7 @@ func TestTransactionDropping(t *testing.T) {
 		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6)
 	}
 	// Reduce the balance of the account, and check that invalidated transactions are dropped
-	pool.currentState.AddBalance(account, big.NewInt(-650))
+	testAddBalance(pool, account, big.NewInt(-650))
 	<-pool.requestReset(nil, nil)
 
 	if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
@@ -592,7 +666,7 @@ func TestTransactionPostponing(t *testing.T) {
 		keys[i], _ = crypto.GenerateKey()
 		accs[i] = crypto.PubkeyToAddress(keys[i].PublicKey)
 
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100))
 	}
 	// Add a batch consecutive pending transactions for validation
 	txs := []*types.Transaction{}
@@ -635,7 +709,7 @@ func TestTransactionPostponing(t *testing.T) {
 	}
 	// Reduce the balance of the account, and check that transactions are reorganised
 	for _, addr := range accs {
-		pool.currentState.AddBalance(addr, big.NewInt(-1))
+		testAddBalance(pool, addr, big.NewInt(-1))
 	}
 	<-pool.requestReset(nil, nil)
 
@@ -696,7 +770,7 @@ func TestTransactionGapFilling(t *testing.T) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	// Keep track of transaction events to ensure all executables get announced
 	events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
@@ -750,7 +824,7 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	// Keep queuing up transactions and make sure all above a limit are dropped
 	for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ {
@@ -805,7 +879,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
 	keys := make([]*ecdsa.PrivateKey, 5)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	local := keys[len(keys)-1]
 
@@ -897,8 +971,8 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
 	local, _ := crypto.GenerateKey()
 	remote, _ := crypto.GenerateKey()
 
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
 
 	// Add the two transactions and ensure they both are queued up
 	if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil {
@@ -1031,7 +1105,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	// Keep track of transaction events to ensure all executables get announced
 	events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
@@ -1081,7 +1155,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 5)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Generate and queue a batch of transactions
 	nonces := make(map[common.Address]uint64)
@@ -1120,7 +1194,7 @@ func TestTransactionAllowedTxSize(t *testing.T) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000000))
+	testAddBalance(pool, account, big.NewInt(1000000000))
 
 	// Compute maximal data size for transactions (lower bound).
 	//
@@ -1184,7 +1258,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
 	// Create a number of test accounts and fund them
 	key, _ := crypto.GenerateKey()
 	addr := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(addr, big.NewInt(1000000))
+	testAddBalance(pool, addr, big.NewInt(1000000))
 
 	txs := types.Transactions{}
 	for j := 0; j < int(config.GlobalSlots)*2; j++ {
@@ -1217,7 +1291,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 5)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Generate and queue a batch of transactions
 	nonces := make(map[common.Address]uint64)
@@ -1267,7 +1341,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 4)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Generate and queue a batch of transactions, both pending and queued
 	txs := types.Transactions{}
@@ -1367,8 +1441,135 @@ func TestTransactionPoolRepricing(t *testing.T) {
 	}
 }
 
+// Tests that setting the transaction pool gas price to a higher value correctly
+// discards everything cheaper (legacy & dynamic fee) than that and moves any
+// gapped transactions back from the pending pool to the queue.
+//
+// Note, local transactions are never allowed to be dropped.
+func TestTransactionPoolRepricingDynamicFee(t *testing.T) {
+	t.Parallel()
+
+	// Create the pool to test the pricing enforcement with
+	pool, _ := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+
+	// Keep track of transaction events to ensure all executables get announced
+	events := make(chan NewTxsEvent, 32)
+	sub := pool.txFeed.Subscribe(events)
+	defer sub.Unsubscribe()
+
+	// Create a number of test accounts and fund them
+	keys := make([]*ecdsa.PrivateKey, 4)
+	for i := 0; i < len(keys); i++ {
+		keys[i], _ = crypto.GenerateKey()
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+	}
+	// Generate and queue a batch of transactions, both pending and queued
+	txs := types.Transactions{}
+
+	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0]))
+	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0]))
+	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0]))
+
+	txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]))
+	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(3), big.NewInt(2), keys[1]))
+	txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(3), big.NewInt(2), keys[1]))
+
+	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(2), keys[2]))
+	txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2]))
+	txs = append(txs, dynamicFeeTx(3, 100000, big.NewInt(2), big.NewInt(2), keys[2]))
+
+	ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[3])
+
+	// Import the batch and that both pending and queued transactions match up
+	pool.AddRemotesSync(txs)
+	pool.AddLocal(ltx)
+
+	pending, queued := pool.Stats()
+	if pending != 7 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7)
+	}
+	if queued != 3 {
+		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
+	}
+	if err := validateEvents(events, 7); err != nil {
+		t.Fatalf("original event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+	// Reprice the pool and check that underpriced transactions get dropped
+	pool.SetGasPrice(big.NewInt(2))
+
+	pending, queued = pool.Stats()
+	if pending != 2 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
+	}
+	if queued != 5 {
+		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5)
+	}
+	if err := validateEvents(events, 0); err != nil {
+		t.Fatalf("reprice event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+	// Check that we can't add the old transactions back
+	tx := pricedTransaction(1, 100000, big.NewInt(1), keys[0])
+	if err := pool.AddRemote(tx); err != ErrUnderpriced {
+		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
+	}
+	tx = dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])
+	if err := pool.AddRemote(tx); err != ErrUnderpriced {
+		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
+	}
+	tx = dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2])
+	if err := pool.AddRemote(tx); err != ErrUnderpriced {
+		t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
+	}
+	if err := validateEvents(events, 0); err != nil {
+		t.Fatalf("post-reprice event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+	// However we can add local underpriced transactions
+	tx = dynamicFeeTx(1, 100000, big.NewInt(1), big.NewInt(1), keys[3])
+	if err := pool.AddLocal(tx); err != nil {
+		t.Fatalf("failed to add underpriced local transaction: %v", err)
+	}
+	if pending, _ = pool.Stats(); pending != 3 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
+	}
+	if err := validateEvents(events, 1); err != nil {
+		t.Fatalf("post-reprice local event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+	// And we can fill gaps with properly priced transactions
+	tx = pricedTransaction(1, 100000, big.NewInt(2), keys[0])
+	if err := pool.AddRemote(tx); err != nil {
+		t.Fatalf("failed to add pending transaction: %v", err)
+	}
+	tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[1])
+	if err := pool.AddRemote(tx); err != nil {
+		t.Fatalf("failed to add pending transaction: %v", err)
+	}
+	tx = dynamicFeeTx(2, 100000, big.NewInt(2), big.NewInt(2), keys[2])
+	if err := pool.AddRemote(tx); err != nil {
+		t.Fatalf("failed to add queued transaction: %v", err)
+	}
+	if err := validateEvents(events, 5); err != nil {
+		t.Fatalf("post-reprice event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+}
+
 // Tests that setting the transaction pool gas price to a higher value does not
-// remove local transactions.
+// remove local transactions (legacy & dynamic fee).
 func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
 	t.Parallel()
 
@@ -1376,14 +1577,14 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
 	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
 	blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
 
-	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
+	pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
 	defer pool.Stop()
 
 	// Create a number of test accounts and fund them
 	keys := make([]*ecdsa.PrivateKey, 3)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
 	}
 	// Create transaction (both pending and queued) with a linearly growing gasprice
 	for i := uint64(0); i < 500; i++ {
@@ -1397,9 +1598,20 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
 		if err := pool.AddLocal(queuedTx); err != nil {
 			t.Fatal(err)
 		}
+
+		// Add pending dynamic fee transaction.
+		pendingTx = dynamicFeeTx(i, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1])
+		if err := pool.AddLocal(pendingTx); err != nil {
+			t.Fatal(err)
+		}
+		// Add queued dynamic fee transaction.
+		queuedTx = dynamicFeeTx(i+501, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1])
+		if err := pool.AddLocal(queuedTx); err != nil {
+			t.Fatal(err)
+		}
 	}
 	pending, queued := pool.Stats()
-	expPending, expQueued := 500, 500
+	expPending, expQueued := 1000, 1000
 	validate := func() {
 		pending, queued = pool.Stats()
 		if pending != expPending {
@@ -1454,7 +1666,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 4)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Generate and queue a batch of transactions, both pending and queued
 	txs := types.Transactions{}
@@ -1560,7 +1772,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 2)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Fill up the entire queue with the same transaction price points
 	txs := types.Transactions{}
@@ -1601,6 +1813,173 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
 	}
 }
 
+// Tests that when the pool reaches its global transaction limit, underpriced
+// transactions (legacy & dynamic fee) are gradually shifted out for more
+// expensive ones and any gapped pending transactions are moved into the queue.
+//
+// Note, local transactions are never allowed to be dropped.
+func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) {
+	t.Parallel()
+
+	pool, _ := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+
+	pool.config.GlobalSlots = 2
+	pool.config.GlobalQueue = 2
+
+	// Keep track of transaction events to ensure all executables get announced
+	events := make(chan NewTxsEvent, 32)
+	sub := pool.txFeed.Subscribe(events)
+	defer sub.Unsubscribe()
+
+	// Create a number of test accounts and fund them
+	keys := make([]*ecdsa.PrivateKey, 4)
+	for i := 0; i < len(keys); i++ {
+		keys[i], _ = crypto.GenerateKey()
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+	}
+
+	// Generate and queue a batch of transactions, both pending and queued
+	txs := types.Transactions{}
+
+	txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0]))
+	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0]))
+	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(1), keys[1]))
+
+	ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[2])
+
+	// Import the batch and that both pending and queued transactions match up
+	pool.AddRemotes(txs) // Pend K0:0, K0:1; Que K1:1
+	pool.AddLocal(ltx)   // +K2:0 => Pend K0:0, K0:1, K2:0; Que K1:1
+
+	pending, queued := pool.Stats()
+	if pending != 3 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
+	}
+	if queued != 1 {
+		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
+	}
+	if err := validateEvents(events, 3); err != nil {
+		t.Fatalf("original event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+
+	// Ensure that adding an underpriced transaction fails
+	tx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])
+	if err := pool.AddRemote(tx); err != ErrUnderpriced { // Pend K0:0, K0:1, K2:0; Que K1:1
+		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
+	}
+
+	// Ensure that adding high priced transactions drops cheap ones, but not own
+	tx = pricedTransaction(0, 100000, big.NewInt(2), keys[1])
+	if err := pool.AddRemote(tx); err != nil { // +K1:0, -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que -
+		t.Fatalf("failed to add well priced transaction: %v", err)
+	}
+
+	tx = pricedTransaction(2, 100000, big.NewInt(3), keys[1])
+	if err := pool.AddRemote(tx); err != nil { // +K1:2, -K0:1 => Pend K0:0 K1:0, K2:0; Que K1:2
+		t.Fatalf("failed to add well priced transaction: %v", err)
+	}
+	tx = dynamicFeeTx(3, 100000, big.NewInt(4), big.NewInt(1), keys[1])
+	if err := pool.AddRemote(tx); err != nil { // +K1:3, -K1:0 => Pend K0:0 K2:0; Que K1:2 K1:3
+		t.Fatalf("failed to add well priced transaction: %v", err)
+	}
+	pending, queued = pool.Stats()
+	if pending != 2 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
+	}
+	if queued != 2 {
+		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
+	}
+	if err := validateEvents(events, 1); err != nil {
+		t.Fatalf("additional event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+	// Ensure that adding local transactions can push out even higher priced ones
+	ltx = dynamicFeeTx(1, 100000, big.NewInt(0), big.NewInt(0), keys[2])
+	if err := pool.AddLocal(ltx); err != nil {
+		t.Fatalf("failed to append underpriced local transaction: %v", err)
+	}
+	ltx = dynamicFeeTx(0, 100000, big.NewInt(0), big.NewInt(0), keys[3])
+	if err := pool.AddLocal(ltx); err != nil {
+		t.Fatalf("failed to add new underpriced local transaction: %v", err)
+	}
+	pending, queued = pool.Stats()
+	if pending != 3 {
+		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
+	}
+	if queued != 1 {
+		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
+	}
+	if err := validateEvents(events, 2); err != nil {
+		t.Fatalf("local event firing failed: %v", err)
+	}
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+}
+
+// Tests whether highest fee cap transaction is retained after a batch of high effective
+// tip transactions are added and vice versa
+func TestDualHeapEviction(t *testing.T) {
+	t.Parallel()
+
+	pool, _ := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+
+	pool.config.GlobalSlots = 10
+	pool.config.GlobalQueue = 10
+
+	var (
+		highTip, highCap *types.Transaction
+		baseFee          int
+	)
+
+	check := func(tx *types.Transaction, name string) {
+		if pool.all.GetRemote(tx.Hash()) == nil {
+			t.Fatalf("highest %s transaction evicted from the pool", name)
+		}
+	}
+
+	add := func(urgent bool) {
+		txs := make([]*types.Transaction, 20)
+		for i := range txs {
+			// Create a test accounts and fund it
+			key, _ := crypto.GenerateKey()
+			testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000000))
+			if urgent {
+				txs[i] = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+1+i)), big.NewInt(int64(1+i)), key)
+				highTip = txs[i]
+			} else {
+				txs[i] = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+200+i)), big.NewInt(1), key)
+				highCap = txs[i]
+			}
+		}
+		pool.AddRemotes(txs)
+		pending, queued := pool.Stats()
+		if pending+queued != 20 {
+			t.Fatalf("transaction count mismatch: have %d, want %d", pending+queued, 10)
+		}
+	}
+
+	add(false)
+	for baseFee = 0; baseFee <= 1000; baseFee += 100 {
+		pool.priced.SetBaseFee(big.NewInt(int64(baseFee)))
+		add(true)
+		check(highCap, "fee cap")
+		add(false)
+		check(highTip, "effective tip")
+	}
+
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+}
+
 // Tests that the pool rejects duplicate transactions.
 func TestTransactionDeduplication(t *testing.T) {
 	t.Parallel()
@@ -1614,7 +1993,7 @@ func TestTransactionDeduplication(t *testing.T) {
 
 	// Create a test account to add transactions with
 	key, _ := crypto.GenerateKey()
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
 
 	// Create a batch of transactions and add a few of them
 	txs := make([]*types.Transaction, 16)
@@ -1685,7 +2064,7 @@ func TestTransactionReplacement(t *testing.T) {
 
 	// Create a test account to add transactions with
 	key, _ := crypto.GenerateKey()
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
 
 	// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
 	price := int64(100)
@@ -1746,6 +2125,116 @@ func TestTransactionReplacement(t *testing.T) {
 	}
 }
 
+// Tests that the pool rejects replacement dynamic fee transactions that don't
+// meet the minimum price bump required.
+func TestTransactionReplacementDynamicFee(t *testing.T) {
+	t.Parallel()
+
+	// Create the pool to test the pricing enforcement with
+	pool, key := setupTxPoolWithConfig(eip1559Config)
+	defer pool.Stop()
+	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
+
+	// Keep track of transaction events to ensure all executables get announced
+	events := make(chan NewTxsEvent, 32)
+	sub := pool.txFeed.Subscribe(events)
+	defer sub.Unsubscribe()
+
+	// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
+	gasFeeCap := int64(100)
+	feeCapThreshold := (gasFeeCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
+	gasTipCap := int64(60)
+	tipThreshold := (gasTipCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
+
+	// Run the following identical checks for both the pending and queue pools:
+	//	1.  Send initial tx => accept
+	//	2.  Don't bump tip or fee cap => discard
+	//	3.  Bump both more than min => accept
+	//	4.  Check events match expected (2 new executable txs during pending, 0 during queue)
+	//	5.  Send new tx with larger tip and gasFeeCap => accept
+	//	6.  Bump tip max allowed so it's still underpriced => discard
+	//	7.  Bump fee cap max allowed so it's still underpriced => discard
+	//	8.  Bump tip min for acceptance => discard
+	//	9.  Bump feecap min for acceptance => discard
+	//	10. Bump feecap and tip min for acceptance => accept
+	//	11. Check events match expected (2 new executable txs during pending, 0 during queue)
+	stages := []string{"pending", "queued"}
+	for _, stage := range stages {
+		// Since state is empty, 0 nonce txs are "executable" and can go
+		// into pending immediately. 2 nonce txs are "happed
+		nonce := uint64(0)
+		if stage == "queued" {
+			nonce = 2
+		}
+
+		// 1.  Send initial tx => accept
+		tx := dynamicFeeTx(nonce, 100000, big.NewInt(2), big.NewInt(1), key)
+		if err := pool.addRemoteSync(tx); err != nil {
+			t.Fatalf("failed to add original cheap %s transaction: %v", stage, err)
+		}
+		// 2.  Don't bump tip or feecap => discard
+		tx = dynamicFeeTx(nonce, 100001, big.NewInt(2), big.NewInt(1), key)
+		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
+			t.Fatalf("original cheap %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
+		}
+		// 3.  Bump both more than min => accept
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(3), big.NewInt(2), key)
+		if err := pool.AddRemote(tx); err != nil {
+			t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err)
+		}
+		// 4.  Check events match expected (2 new executable txs during pending, 0 during queue)
+		count := 2
+		if stage == "queued" {
+			count = 0
+		}
+		if err := validateEvents(events, count); err != nil {
+			t.Fatalf("cheap %s replacement event firing failed: %v", stage, err)
+		}
+		// 5.  Send new tx with larger tip and feeCap => accept
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(gasTipCap), key)
+		if err := pool.addRemoteSync(tx); err != nil {
+			t.Fatalf("failed to add original proper %s transaction: %v", stage, err)
+		}
+		// 6.  Bump tip max allowed so it's still underpriced => discard
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key)
+		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
+			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
+		}
+		// 7.  Bump fee cap max allowed so it's still underpriced => discard
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key)
+		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
+			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
+		}
+		// 8.  Bump tip min for acceptance => accept
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key)
+		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
+			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
+		}
+		// 9.  Bump fee cap min for acceptance => accept
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key)
+		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
+			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
+		}
+		// 10. Check events match expected (3 new executable txs during pending, 0 during queue)
+		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(tipThreshold), key)
+		if err := pool.AddRemote(tx); err != nil {
+			t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err)
+		}
+		// 11. Check events match expected (3 new executable txs during pending, 0 during queue)
+		count = 2
+		if stage == "queued" {
+			count = 0
+		}
+		if err := validateEvents(events, count); err != nil {
+			t.Fatalf("replacement %s event firing failed: %v", stage, err)
+		}
+	}
+
+	if err := validateTxPoolInternals(pool); err != nil {
+		t.Fatalf("pool internal state corrupted: %v", err)
+	}
+}
+
 // Tests that local transactions are journaled to disk, but remote transactions
 // get discarded between restarts.
 func TestTransactionJournaling(t *testing.T)         { testTransactionJournaling(t, false) }
@@ -1781,8 +2270,8 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	local, _ := crypto.GenerateKey()
 	remote, _ := crypto.GenerateKey()
 
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
-	pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
+	testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
 
 	// Add three local and a remote transactions and ensure they are queued up
 	if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil {
@@ -1875,7 +2364,7 @@ func TestTransactionStatusCheck(t *testing.T) {
 	keys := make([]*ecdsa.PrivateKey, 3)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
-		pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
+		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
 	}
 	// Generate and queue a batch of transactions, both pending and queued
 	txs := types.Transactions{}
@@ -1945,7 +2434,7 @@ func benchmarkPendingDemotion(b *testing.B, size int) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	for i := 0; i < size; i++ {
 		tx := transaction(uint64(i), 100000, key)
@@ -1970,7 +2459,7 @@ func benchmarkFuturePromotion(b *testing.B, size int) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	for i := 0; i < size; i++ {
 		tx := transaction(uint64(1+i), 100000, key)
@@ -1998,7 +2487,7 @@ func benchmarkPoolBatchInsert(b *testing.B, size int, local bool) {
 	defer pool.Stop()
 
 	account := crypto.PubkeyToAddress(key.PublicKey)
-	pool.currentState.AddBalance(account, big.NewInt(1000000))
+	testAddBalance(pool, account, big.NewInt(1000000))
 
 	batches := make([]types.Transactions, b.N)
 	for i := 0; i < b.N; i++ {
@@ -2039,13 +2528,13 @@ func BenchmarkInsertRemoteWithAllLocals(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		b.StopTimer()
 		pool, _ := setupTxPool()
-		pool.currentState.AddBalance(account, big.NewInt(100000000))
+		testAddBalance(pool, account, big.NewInt(100000000))
 		for _, local := range locals {
 			pool.AddLocal(local)
 		}
 		b.StartTimer()
 		// Assign a high enough balance for testing
-		pool.currentState.AddBalance(remoteAddr, big.NewInt(100000000))
+		testAddBalance(pool, remoteAddr, big.NewInt(100000000))
 		for i := 0; i < len(remotes); i++ {
 			pool.AddRemotes([]*types.Transaction{remotes[i]})
 		}
diff --git a/core/types/access_list_tx.go b/core/types/access_list_tx.go
index 65ee95adf611d1e82982b989b86b18aaf3e8b207..d8d08b48c5bb872a80679d572e3ee4c9a929f9db 100644
--- a/core/types/access_list_tx.go
+++ b/core/types/access_list_tx.go
@@ -94,7 +94,6 @@ func (tx *AccessListTx) copy() TxData {
 }
 
 // accessors for innerTx.
-
 func (tx *AccessListTx) txType() byte           { return AccessListTxType }
 func (tx *AccessListTx) chainID() *big.Int      { return tx.ChainID }
 func (tx *AccessListTx) protected() bool        { return true }
@@ -102,6 +101,8 @@ func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
 func (tx *AccessListTx) data() []byte           { return tx.Data }
 func (tx *AccessListTx) gas() uint64            { return tx.Gas }
 func (tx *AccessListTx) gasPrice() *big.Int     { return tx.GasPrice }
+func (tx *AccessListTx) gasTipCap() *big.Int    { return tx.GasPrice }
+func (tx *AccessListTx) gasFeeCap() *big.Int    { return tx.GasPrice }
 func (tx *AccessListTx) value() *big.Int        { return tx.Value }
 func (tx *AccessListTx) nonce() uint64          { return tx.Nonce }
 func (tx *AccessListTx) to() *common.Address    { return tx.To }
diff --git a/core/types/block.go b/core/types/block.go
index a3318f8779d6cc85d0be14985623188a93d2f910..360f1eb47c2bc7769532c3061ee34e9c1f573c51 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -82,6 +82,9 @@ type Header struct {
 	Extra       []byte         `json:"extraData"        gencodec:"required"`
 	MixDigest   common.Hash    `json:"mixHash"`
 	Nonce       BlockNonce     `json:"nonce"`
+
+	// BaseFee was added by EIP-1559 and is ignored in legacy headers.
+	BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
 }
 
 // field type overrides for gencodec
@@ -92,6 +95,7 @@ type headerMarshaling struct {
 	GasUsed    hexutil.Uint64
 	Time       hexutil.Uint64
 	Extra      hexutil.Bytes
+	BaseFee    *hexutil.Big
 	Hash       common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
 }
 
@@ -125,6 +129,11 @@ func (h *Header) SanityCheck() error {
 	if eLen := len(h.Extra); eLen > 100*1024 {
 		return fmt.Errorf("too large block extradata: size %d", eLen)
 	}
+	if h.BaseFee != nil {
+		if bfLen := h.BaseFee.BitLen(); bfLen > 256 {
+			return fmt.Errorf("too large base fee: bitlen %d", bfLen)
+		}
+	}
 	return nil
 }
 
@@ -229,6 +238,9 @@ func CopyHeader(h *Header) *Header {
 	if cpy.Number = new(big.Int); h.Number != nil {
 		cpy.Number.Set(h.Number)
 	}
+	if h.BaseFee != nil {
+		cpy.BaseFee = new(big.Int).Set(h.BaseFee)
+	}
 	if len(h.Extra) > 0 {
 		cpy.Extra = make([]byte, len(h.Extra))
 		copy(cpy.Extra, h.Extra)
@@ -289,6 +301,13 @@ func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
 func (b *Block) UncleHash() common.Hash   { return b.header.UncleHash }
 func (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }
 
+func (b *Block) BaseFee() *big.Int {
+	if b.header.BaseFee == nil {
+		return nil
+	}
+	return new(big.Int).Set(b.header.BaseFee)
+}
+
 func (b *Block) Header() *Header { return CopyHeader(b.header) }
 
 // Body returns the non-header content of the block.
diff --git a/core/types/block_test.go b/core/types/block_test.go
index 63904f882c924652f447dfccaaf21c097bfe5ff3..0b9a4def8d2875783ca535ce2806194adcccac1e 100644
--- a/core/types/block_test.go
+++ b/core/types/block_test.go
@@ -68,6 +68,71 @@ func TestBlockEncoding(t *testing.T) {
 	}
 }
 
+func TestEIP1559BlockEncoding(t *testing.T) {
+	blockEnc := common.FromHex("f9030bf901fea083cafc574e1f51ba9dc0568fc617a08ea2429fb384059c972f13b19fa1c8dd55a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a05fe50b260da6308036625b850b5d6ced6d0a9f814c0688bc91ffb7b7a3a54b67a0bc37d79753ad738a6dac4921e57392f145d8887476de3f783dfa7edae9283e52b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4843b9aca00f90106f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1b8a302f8a0018080843b9aca008301e24194095e7baea6a6c7c4c2dfeb977efac326af552d878080f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000080a0fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b0a06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a8c0")
+	var block Block
+	if err := rlp.DecodeBytes(blockEnc, &block); err != nil {
+		t.Fatal("decode error: ", err)
+	}
+
+	check := func(f string, got, want interface{}) {
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("%s mismatch: got %v, want %v", f, got, want)
+		}
+	}
+
+	check("Difficulty", block.Difficulty(), big.NewInt(131072))
+	check("GasLimit", block.GasLimit(), uint64(3141592))
+	check("GasUsed", block.GasUsed(), uint64(21000))
+	check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1"))
+	check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
+	check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
+	check("Hash", block.Hash(), common.HexToHash("c7252048cd273fe0dac09650027d07f0e3da4ee0675ebbb26627cea92729c372"))
+	check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
+	check("Time", block.Time(), uint64(1426516743))
+	check("Size", block.Size(), common.StorageSize(len(blockEnc)))
+	check("BaseFee", block.BaseFee(), new(big.Int).SetUint64(params.InitialBaseFee))
+
+	tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil)
+	tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100"))
+
+	addr := common.HexToAddress("0x0000000000000000000000000000000000000001")
+	accesses := AccessList{AccessTuple{
+		Address: addr,
+		StorageKeys: []common.Hash{
+			{0},
+		},
+	}}
+	to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
+	txdata := &DynamicFeeTx{
+		ChainID:    big.NewInt(1),
+		Nonce:      0,
+		To:         &to,
+		Gas:        123457,
+		GasFeeCap:  new(big.Int).Set(block.BaseFee()),
+		GasTipCap:  big.NewInt(0),
+		AccessList: accesses,
+		Data:       []byte{},
+	}
+	tx2 := NewTx(txdata)
+	tx2, err := tx2.WithSignature(LatestSignerForChainID(big.NewInt(1)), common.Hex2Bytes("fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a800"))
+	if err != nil {
+		t.Fatal("invalid signature error: ", err)
+	}
+
+	check("len(Transactions)", len(block.Transactions()), 2)
+	check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash())
+	check("Transactions[1].Hash", block.Transactions()[1].Hash(), tx2.Hash())
+	check("Transactions[1].Type", block.Transactions()[1].Type(), tx2.Type())
+	ourBlockEnc, err := rlp.EncodeToBytes(&block)
+	if err != nil {
+		t.Fatal("encode error: ", err)
+	}
+	if !bytes.Equal(ourBlockEnc, blockEnc) {
+		t.Errorf("encoded block mismatch:\ngot:  %x\nwant: %x", ourBlockEnc, blockEnc)
+	}
+}
+
 func TestEIP2718BlockEncoding(t *testing.T) {
 	blockEnc := common.FromHex("f90319f90211a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a0e6e49996c7ec59f7a23d22b83239a60151512c65613bf84a0d7da336399ebc4aa0cafe75574d59780665a97fbfd11365c7545aa8f1abf4e5e12e8243334ef7286bb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000820200832fefd882a410845506eb0796636f6f6c65737420626c6f636b206f6e20636861696ea0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4f90101f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1b89e01f89b01800a8301e24194095e7baea6a6c7c4c2dfeb977efac326af552d878080f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000001a03dbacc8d0259f2508625e97fdfc57cd85fdd16e5821bc2c10bdd1a52649e8335a0476e10695b183a87b0aa292a7f4b78ef0c3fbe62aa2c42c84e1d9c3da159ef14c0")
 	var block Block
diff --git a/core/types/dynamic_fee_tx.go b/core/types/dynamic_fee_tx.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6719a40898daab86553fbbdde5858fc4d897a9f
--- /dev/null
+++ b/core/types/dynamic_fee_tx.go
@@ -0,0 +1,104 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/common"
+)
+
+type DynamicFeeTx struct {
+	ChainID    *big.Int
+	Nonce      uint64
+	GasTipCap  *big.Int
+	GasFeeCap  *big.Int
+	Gas        uint64
+	To         *common.Address `rlp:"nil"` // nil means contract creation
+	Value      *big.Int
+	Data       []byte
+	AccessList AccessList
+
+	// Signature values
+	V *big.Int `json:"v" gencodec:"required"`
+	R *big.Int `json:"r" gencodec:"required"`
+	S *big.Int `json:"s" gencodec:"required"`
+}
+
+// copy creates a deep copy of the transaction data and initializes all fields.
+func (tx *DynamicFeeTx) copy() TxData {
+	cpy := &DynamicFeeTx{
+		Nonce: tx.Nonce,
+		To:    tx.To, // TODO: copy pointed-to address
+		Data:  common.CopyBytes(tx.Data),
+		Gas:   tx.Gas,
+		// These are copied below.
+		AccessList: make(AccessList, len(tx.AccessList)),
+		Value:      new(big.Int),
+		ChainID:    new(big.Int),
+		GasTipCap:  new(big.Int),
+		GasFeeCap:  new(big.Int),
+		V:          new(big.Int),
+		R:          new(big.Int),
+		S:          new(big.Int),
+	}
+	copy(cpy.AccessList, tx.AccessList)
+	if tx.Value != nil {
+		cpy.Value.Set(tx.Value)
+	}
+	if tx.ChainID != nil {
+		cpy.ChainID.Set(tx.ChainID)
+	}
+	if tx.GasTipCap != nil {
+		cpy.GasTipCap.Set(tx.GasTipCap)
+	}
+	if tx.GasFeeCap != nil {
+		cpy.GasFeeCap.Set(tx.GasFeeCap)
+	}
+	if tx.V != nil {
+		cpy.V.Set(tx.V)
+	}
+	if tx.R != nil {
+		cpy.R.Set(tx.R)
+	}
+	if tx.S != nil {
+		cpy.S.Set(tx.S)
+	}
+	return cpy
+}
+
+// accessors for innerTx.
+func (tx *DynamicFeeTx) txType() byte           { return DynamicFeeTxType }
+func (tx *DynamicFeeTx) chainID() *big.Int      { return tx.ChainID }
+func (tx *DynamicFeeTx) protected() bool        { return true }
+func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
+func (tx *DynamicFeeTx) data() []byte           { return tx.Data }
+func (tx *DynamicFeeTx) gas() uint64            { return tx.Gas }
+func (tx *DynamicFeeTx) gasFeeCap() *big.Int    { return tx.GasFeeCap }
+func (tx *DynamicFeeTx) gasTipCap() *big.Int    { return tx.GasTipCap }
+func (tx *DynamicFeeTx) gasPrice() *big.Int     { return tx.GasFeeCap }
+func (tx *DynamicFeeTx) value() *big.Int        { return tx.Value }
+func (tx *DynamicFeeTx) nonce() uint64          { return tx.Nonce }
+func (tx *DynamicFeeTx) to() *common.Address    { return tx.To }
+
+func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) {
+	return tx.V, tx.R, tx.S
+}
+
+func (tx *DynamicFeeTx) setSignatureValues(chainID, v, r, s *big.Int) {
+	tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s
+}
diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go
index 4212b8d94d254717abdd07130a9cb1016234c1c0..75e24b34d6a0333d6602e4cded2ca824b9657c87 100644
--- a/core/types/gen_header_json.go
+++ b/core/types/gen_header_json.go
@@ -31,6 +31,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
 		Extra       hexutil.Bytes  `json:"extraData"        gencodec:"required"`
 		MixDigest   common.Hash    `json:"mixHash"`
 		Nonce       BlockNonce     `json:"nonce"`
+		BaseFee     *hexutil.Big   `json:"baseFeePerGas" rlp:"optional"`
 		Hash        common.Hash    `json:"hash"`
 	}
 	var enc Header
@@ -49,6 +50,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
 	enc.Extra = h.Extra
 	enc.MixDigest = h.MixDigest
 	enc.Nonce = h.Nonce
+	enc.BaseFee = (*hexutil.Big)(h.BaseFee)
 	enc.Hash = h.Hash()
 	return json.Marshal(&enc)
 }
@@ -71,6 +73,7 @@ func (h *Header) UnmarshalJSON(input []byte) error {
 		Extra       *hexutil.Bytes  `json:"extraData"        gencodec:"required"`
 		MixDigest   *common.Hash    `json:"mixHash"`
 		Nonce       *BlockNonce     `json:"nonce"`
+		BaseFee     *hexutil.Big    `json:"baseFeePerGas" rlp:"optional"`
 	}
 	var dec Header
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -134,5 +137,8 @@ func (h *Header) UnmarshalJSON(input []byte) error {
 	if dec.Nonce != nil {
 		h.Nonce = *dec.Nonce
 	}
+	if dec.BaseFee != nil {
+		h.BaseFee = (*big.Int)(dec.BaseFee)
+	}
 	return nil
 }
diff --git a/core/types/legacy_tx.go b/core/types/legacy_tx.go
index 41ad44f37985a0935905396e54739cda3a3a8e54..514010ebbd743faa2bad45381e8f0375d04cb94b 100644
--- a/core/types/legacy_tx.go
+++ b/core/types/legacy_tx.go
@@ -91,13 +91,14 @@ func (tx *LegacyTx) copy() TxData {
 }
 
 // accessors for innerTx.
-
 func (tx *LegacyTx) txType() byte           { return LegacyTxType }
 func (tx *LegacyTx) chainID() *big.Int      { return deriveChainId(tx.V) }
 func (tx *LegacyTx) accessList() AccessList { return nil }
 func (tx *LegacyTx) data() []byte           { return tx.Data }
 func (tx *LegacyTx) gas() uint64            { return tx.Gas }
 func (tx *LegacyTx) gasPrice() *big.Int     { return tx.GasPrice }
+func (tx *LegacyTx) gasTipCap() *big.Int    { return tx.GasPrice }
+func (tx *LegacyTx) gasFeeCap() *big.Int    { return tx.GasPrice }
 func (tx *LegacyTx) value() *big.Int        { return tx.Value }
 func (tx *LegacyTx) nonce() uint64          { return tx.Nonce }
 func (tx *LegacyTx) to() *common.Address    { return tx.To }
diff --git a/core/types/receipt.go b/core/types/receipt.go
index e04259b9d89563b537219ac081b5e23b40bb251c..6141740f2f132cf8a0b43038a9719d1a26e73af9 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -141,10 +141,6 @@ func (r *Receipt) EncodeRLP(w io.Writer) error {
 	if r.Type == LegacyTxType {
 		return rlp.Encode(w, data)
 	}
-	// It's an EIP-2718 typed TX receipt.
-	if r.Type != AccessListTxType {
-		return ErrTxTypeNotSupported
-	}
 	buf := encodeBufferPool.Get().(*bytes.Buffer)
 	defer encodeBufferPool.Put(buf)
 	buf.Reset()
@@ -180,7 +176,7 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
 			return errEmptyTypedReceipt
 		}
 		r.Type = b[0]
-		if r.Type == AccessListTxType {
+		if r.Type == AccessListTxType || r.Type == DynamicFeeTxType {
 			var dec receiptRLP
 			if err := rlp.DecodeBytes(b[1:], &dec); err != nil {
 				return err
@@ -346,6 +342,9 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
 	case AccessListTxType:
 		w.WriteByte(AccessListTxType)
 		rlp.Encode(w, data)
+	case DynamicFeeTxType:
+		w.WriteByte(DynamicFeeTxType)
+		rlp.Encode(w, data)
 	default:
 		// For unsupported types, write nothing. Since this is for
 		// DeriveSha, the error will be caught matching the derived hash
diff --git a/core/types/transaction.go b/core/types/transaction.go
index a35e07a5a3161b3c94ee9b814da8a8ed8cce9944..e21cf2bda82654d6bcc1a79e4103ebc597cce3e6 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -26,6 +26,7 @@ import (
 	"time"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/rlp"
 )
@@ -35,6 +36,7 @@ var (
 	ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures")
 	ErrInvalidTxType        = errors.New("transaction type not valid in this context")
 	ErrTxTypeNotSupported   = errors.New("transaction type not supported")
+	ErrGasFeeCapTooLow      = errors.New("fee cap less than base fee")
 	errEmptyTypedTx         = errors.New("empty typed transaction bytes")
 )
 
@@ -42,6 +44,7 @@ var (
 const (
 	LegacyTxType = iota
 	AccessListTxType
+	DynamicFeeTxType
 )
 
 // Transaction is an Ethereum transaction.
@@ -64,7 +67,7 @@ func NewTx(inner TxData) *Transaction {
 
 // TxData is the underlying data of a transaction.
 //
-// This is implemented by LegacyTx and AccessListTx.
+// This is implemented by DynamicFeeTx, LegacyTx and AccessListTx.
 type TxData interface {
 	txType() byte // returns the type ID
 	copy() TxData // creates a deep copy and initializes all fields
@@ -74,6 +77,8 @@ type TxData interface {
 	data() []byte
 	gas() uint64
 	gasPrice() *big.Int
+	gasTipCap() *big.Int
+	gasFeeCap() *big.Int
 	value() *big.Int
 	nonce() uint64
 	to() *common.Address
@@ -177,6 +182,10 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
 		var inner AccessListTx
 		err := rlp.DecodeBytes(b[1:], &inner)
 		return &inner, err
+	case DynamicFeeTxType:
+		var inner DynamicFeeTx
+		err := rlp.DecodeBytes(b[1:], &inner)
+		return &inner, err
 	default:
 		return nil, ErrTxTypeNotSupported
 	}
@@ -260,6 +269,12 @@ func (tx *Transaction) Gas() uint64 { return tx.inner.gas() }
 // GasPrice returns the gas price of the transaction.
 func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) }
 
+// GasTipCap returns the gasTipCap per gas of the transaction.
+func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.gasTipCap()) }
+
+// GasFeeCap returns the fee cap per gas of the transaction.
+func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
+
 // Value returns the ether amount of the transaction.
 func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
 
@@ -291,14 +306,62 @@ func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) {
 	return tx.inner.rawSignatureValues()
 }
 
-// GasPriceCmp compares the gas prices of two transactions.
-func (tx *Transaction) GasPriceCmp(other *Transaction) int {
-	return tx.inner.gasPrice().Cmp(other.inner.gasPrice())
+// GasFeeCapCmp compares the fee cap of two transactions.
+func (tx *Transaction) GasFeeCapCmp(other *Transaction) int {
+	return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap())
 }
 
-// GasPriceIntCmp compares the gas price of the transaction against the given price.
-func (tx *Transaction) GasPriceIntCmp(other *big.Int) int {
-	return tx.inner.gasPrice().Cmp(other)
+// GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap.
+func (tx *Transaction) GasFeeCapIntCmp(other *big.Int) int {
+	return tx.inner.gasFeeCap().Cmp(other)
+}
+
+// GasTipCapCmp compares the gasTipCap of two transactions.
+func (tx *Transaction) GasTipCapCmp(other *Transaction) int {
+	return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap())
+}
+
+// GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap.
+func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int {
+	return tx.inner.gasTipCap().Cmp(other)
+}
+
+// EffectiveGasTip returns the effective miner gasTipCap for the given base fee.
+// Note: if the effective gasTipCap is negative, this method returns both error
+// the actual negative value, _and_ ErrGasFeeCapTooLow
+func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) {
+	if baseFee == nil {
+		return tx.GasTipCap(), nil
+	}
+	var err error
+	gasFeeCap := tx.GasFeeCap()
+	if gasFeeCap.Cmp(baseFee) == -1 {
+		err = ErrGasFeeCapTooLow
+	}
+	return math.BigMin(tx.GasTipCap(), gasFeeCap.Sub(gasFeeCap, baseFee)), err
+}
+
+// EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an
+// error in case the effective gasTipCap is negative
+func (tx *Transaction) EffectiveGasTipValue(baseFee *big.Int) *big.Int {
+	effectiveTip, _ := tx.EffectiveGasTip(baseFee)
+	return effectiveTip
+}
+
+// EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee.
+func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) int {
+	if baseFee == nil {
+		return tx.GasTipCapCmp(other)
+	}
+	return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee))
+}
+
+// EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap.
+func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) int {
+	if baseFee == nil {
+		return tx.GasTipCapIntCmp(other)
+	}
+	return tx.EffectiveGasTipValue(baseFee).Cmp(other)
 }
 
 // Hash returns the transaction hash.
@@ -386,24 +449,44 @@ func (s TxByNonce) Len() int           { return len(s) }
 func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce() < s[j].Nonce() }
 func (s TxByNonce) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
+// TxWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
+type TxWithMinerFee struct {
+	tx       *Transaction
+	minerFee *big.Int
+}
+
+// NewTxWithMinerFee creates a wrapped transaction, calculating the effective
+// miner gasTipCap if a base fee is provided.
+// Returns error in case of a negative effective miner gasTipCap.
+func NewTxWithMinerFee(tx *Transaction, baseFee *big.Int) (*TxWithMinerFee, error) {
+	minerFee, err := tx.EffectiveGasTip(baseFee)
+	if err != nil {
+		return nil, err
+	}
+	return &TxWithMinerFee{
+		tx:       tx,
+		minerFee: minerFee,
+	}, nil
+}
+
 // TxByPriceAndTime implements both the sort and the heap interface, making it useful
 // for all at once sorting as well as individually adding and removing elements.
-type TxByPriceAndTime Transactions
+type TxByPriceAndTime []*TxWithMinerFee
 
 func (s TxByPriceAndTime) Len() int { return len(s) }
 func (s TxByPriceAndTime) Less(i, j int) bool {
 	// If the prices are equal, use the time the transaction was first seen for
 	// deterministic sorting
-	cmp := s[i].GasPrice().Cmp(s[j].GasPrice())
+	cmp := s[i].minerFee.Cmp(s[j].minerFee)
 	if cmp == 0 {
-		return s[i].time.Before(s[j].time)
+		return s[i].tx.time.Before(s[j].tx.time)
 	}
 	return cmp > 0
 }
 func (s TxByPriceAndTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
 
 func (s *TxByPriceAndTime) Push(x interface{}) {
-	*s = append(*s, x.(*Transaction))
+	*s = append(*s, x.(*TxWithMinerFee))
 }
 
 func (s *TxByPriceAndTime) Pop() interface{} {
@@ -418,9 +501,10 @@ func (s *TxByPriceAndTime) Pop() interface{} {
 // transactions in a profit-maximizing sorted order, while supporting removing
 // entire batches of transactions for non-executable accounts.
 type TransactionsByPriceAndNonce struct {
-	txs    map[common.Address]Transactions // Per account nonce-sorted list of transactions
-	heads  TxByPriceAndTime                // Next transaction for each unique account (price heap)
-	signer Signer                          // Signer for the set of transactions
+	txs     map[common.Address]Transactions // Per account nonce-sorted list of transactions
+	heads   TxByPriceAndTime                // Next transaction for each unique account (price heap)
+	signer  Signer                          // Signer for the set of transactions
+	baseFee *big.Int                        // Current base fee
 }
 
 // NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
@@ -428,25 +512,28 @@ type TransactionsByPriceAndNonce struct {
 //
 // Note, the input map is reowned so the caller should not interact any more with
 // if after providing it to the constructor.
-func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce {
+func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions, baseFee *big.Int) *TransactionsByPriceAndNonce {
 	// Initialize a price and received time based heap with the head transactions
 	heads := make(TxByPriceAndTime, 0, len(txs))
 	for from, accTxs := range txs {
-		// Ensure the sender address is from the signer
-		if acc, _ := Sender(signer, accTxs[0]); acc != from {
+		acc, _ := Sender(signer, accTxs[0])
+		wrapped, err := NewTxWithMinerFee(accTxs[0], baseFee)
+		// Remove transaction if sender doesn't match from, or if wrapping fails.
+		if acc != from || err != nil {
 			delete(txs, from)
 			continue
 		}
-		heads = append(heads, accTxs[0])
+		heads = append(heads, wrapped)
 		txs[from] = accTxs[1:]
 	}
 	heap.Init(&heads)
 
 	// Assemble and return the transaction set
 	return &TransactionsByPriceAndNonce{
-		txs:    txs,
-		heads:  heads,
-		signer: signer,
+		txs:     txs,
+		heads:   heads,
+		signer:  signer,
+		baseFee: baseFee,
 	}
 }
 
@@ -455,18 +542,20 @@ func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
 	if len(t.heads) == 0 {
 		return nil
 	}
-	return t.heads[0]
+	return t.heads[0].tx
 }
 
 // Shift replaces the current best head with the next one from the same account.
 func (t *TransactionsByPriceAndNonce) Shift() {
-	acc, _ := Sender(t.signer, t.heads[0])
+	acc, _ := Sender(t.signer, t.heads[0].tx)
 	if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
-		t.heads[0], t.txs[acc] = txs[0], txs[1:]
-		heap.Fix(&t.heads, 0)
-	} else {
-		heap.Pop(&t.heads)
+		if wrapped, err := NewTxWithMinerFee(txs[0], t.baseFee); err == nil {
+			t.heads[0], t.txs[acc] = wrapped, txs[1:]
+			heap.Fix(&t.heads, 0)
+			return
+		}
 	}
+	heap.Pop(&t.heads)
 }
 
 // Pop removes the best transaction, *not* replacing it with the next one from
@@ -486,12 +575,14 @@ type Message struct {
 	amount     *big.Int
 	gasLimit   uint64
 	gasPrice   *big.Int
+	gasFeeCap  *big.Int
+	gasTipCap  *big.Int
 	data       []byte
 	accessList AccessList
-	checkNonce bool
+	isFake     bool
 }
 
-func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, accessList AccessList, checkNonce bool) Message {
+func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool) Message {
 	return Message{
 		from:       from,
 		to:         to,
@@ -499,25 +590,32 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
 		amount:     amount,
 		gasLimit:   gasLimit,
 		gasPrice:   gasPrice,
+		gasFeeCap:  gasFeeCap,
+		gasTipCap:  gasTipCap,
 		data:       data,
 		accessList: accessList,
-		checkNonce: checkNonce,
+		isFake:     isFake,
 	}
 }
 
 // AsMessage returns the transaction as a core.Message.
-func (tx *Transaction) AsMessage(s Signer) (Message, error) {
+func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
 	msg := Message{
 		nonce:      tx.Nonce(),
 		gasLimit:   tx.Gas(),
 		gasPrice:   new(big.Int).Set(tx.GasPrice()),
+		gasFeeCap:  new(big.Int).Set(tx.GasFeeCap()),
+		gasTipCap:  new(big.Int).Set(tx.GasTipCap()),
 		to:         tx.To(),
 		amount:     tx.Value(),
 		data:       tx.Data(),
 		accessList: tx.AccessList(),
-		checkNonce: true,
+		isFake:     false,
+	}
+	// If baseFee provided, set gasPrice to effectiveGasPrice.
+	if baseFee != nil {
+		msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap)
 	}
-
 	var err error
 	msg.from, err = Sender(s, tx)
 	return msg, err
@@ -526,9 +624,11 @@ func (tx *Transaction) AsMessage(s Signer) (Message, error) {
 func (m Message) From() common.Address   { return m.from }
 func (m Message) To() *common.Address    { return m.to }
 func (m Message) GasPrice() *big.Int     { return m.gasPrice }
+func (m Message) GasFeeCap() *big.Int    { return m.gasFeeCap }
+func (m Message) GasTipCap() *big.Int    { return m.gasTipCap }
 func (m Message) Value() *big.Int        { return m.amount }
 func (m Message) Gas() uint64            { return m.gasLimit }
 func (m Message) Nonce() uint64          { return m.nonce }
 func (m Message) Data() []byte           { return m.data }
 func (m Message) AccessList() AccessList { return m.accessList }
-func (m Message) CheckNonce() bool       { return m.checkNonce }
+func (m Message) IsFake() bool           { return m.isFake }
diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go
index e56148555654214447e303b4a09b8b5a0e62751e..aad31a5a97e2e218e14cd65d649b9f7d9234dc9d 100644
--- a/core/types/transaction_marshalling.go
+++ b/core/types/transaction_marshalling.go
@@ -30,15 +30,17 @@ type txJSON struct {
 	Type hexutil.Uint64 `json:"type"`
 
 	// Common transaction fields:
-	Nonce    *hexutil.Uint64 `json:"nonce"`
-	GasPrice *hexutil.Big    `json:"gasPrice"`
-	Gas      *hexutil.Uint64 `json:"gas"`
-	Value    *hexutil.Big    `json:"value"`
-	Data     *hexutil.Bytes  `json:"input"`
-	V        *hexutil.Big    `json:"v"`
-	R        *hexutil.Big    `json:"r"`
-	S        *hexutil.Big    `json:"s"`
-	To       *common.Address `json:"to"`
+	Nonce                *hexutil.Uint64 `json:"nonce"`
+	GasPrice             *hexutil.Big    `json:"gasPrice"`
+	MaxPriorityFeePerGas *hexutil.Big    `json:"maxPriorityFeePerGas"`
+	MaxFeePerGas         *hexutil.Big    `json:"maxFeePerGas"`
+	Gas                  *hexutil.Uint64 `json:"gas"`
+	Value                *hexutil.Big    `json:"value"`
+	Data                 *hexutil.Bytes  `json:"input"`
+	V                    *hexutil.Big    `json:"v"`
+	R                    *hexutil.Big    `json:"r"`
+	S                    *hexutil.Big    `json:"s"`
+	To                   *common.Address `json:"to"`
 
 	// Access list transaction fields:
 	ChainID    *hexutil.Big `json:"chainId,omitempty"`
@@ -79,6 +81,19 @@ func (t *Transaction) MarshalJSON() ([]byte, error) {
 		enc.V = (*hexutil.Big)(tx.V)
 		enc.R = (*hexutil.Big)(tx.R)
 		enc.S = (*hexutil.Big)(tx.S)
+	case *DynamicFeeTx:
+		enc.ChainID = (*hexutil.Big)(tx.ChainID)
+		enc.AccessList = &tx.AccessList
+		enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
+		enc.Gas = (*hexutil.Uint64)(&tx.Gas)
+		enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap)
+		enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap)
+		enc.Value = (*hexutil.Big)(tx.Value)
+		enc.Data = (*hexutil.Bytes)(&tx.Data)
+		enc.To = t.To()
+		enc.V = (*hexutil.Big)(tx.V)
+		enc.R = (*hexutil.Big)(tx.R)
+		enc.S = (*hexutil.Big)(tx.S)
 	}
 	return json.Marshal(&enc)
 }
@@ -191,6 +206,63 @@ func (t *Transaction) UnmarshalJSON(input []byte) error {
 			}
 		}
 
+	case DynamicFeeTxType:
+		var itx DynamicFeeTx
+		inner = &itx
+		// Access list is optional for now.
+		if dec.AccessList != nil {
+			itx.AccessList = *dec.AccessList
+		}
+		if dec.ChainID == nil {
+			return errors.New("missing required field 'chainId' in transaction")
+		}
+		itx.ChainID = (*big.Int)(dec.ChainID)
+		if dec.To != nil {
+			itx.To = dec.To
+		}
+		if dec.Nonce == nil {
+			return errors.New("missing required field 'nonce' in transaction")
+		}
+		itx.Nonce = uint64(*dec.Nonce)
+		if dec.MaxPriorityFeePerGas == nil {
+			return errors.New("missing required field 'maxPriorityFeePerGas' for txdata")
+		}
+		itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas)
+		if dec.MaxFeePerGas == nil {
+			return errors.New("missing required field 'maxFeePerGas' for txdata")
+		}
+		itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas)
+		if dec.Gas == nil {
+			return errors.New("missing required field 'gas' for txdata")
+		}
+		itx.Gas = uint64(*dec.Gas)
+		if dec.Value == nil {
+			return errors.New("missing required field 'value' in transaction")
+		}
+		itx.Value = (*big.Int)(dec.Value)
+		if dec.Data == nil {
+			return errors.New("missing required field 'input' in transaction")
+		}
+		itx.Data = *dec.Data
+		if dec.V == nil {
+			return errors.New("missing required field 'v' in transaction")
+		}
+		itx.V = (*big.Int)(dec.V)
+		if dec.R == nil {
+			return errors.New("missing required field 'r' in transaction")
+		}
+		itx.R = (*big.Int)(dec.R)
+		if dec.S == nil {
+			return errors.New("missing required field 's' in transaction")
+		}
+		itx.S = (*big.Int)(dec.S)
+		withSignature := itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0
+		if withSignature {
+			if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil {
+				return err
+			}
+		}
+
 	default:
 		return ErrTxTypeNotSupported
 	}
diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go
index 126748efeb875e71cf9fe0b33086df465874dd01..1d0d2a4c75e7cce5cb2970811457e049f9a8f29a 100644
--- a/core/types/transaction_signing.go
+++ b/core/types/transaction_signing.go
@@ -40,6 +40,8 @@ type sigCache struct {
 func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
 	var signer Signer
 	switch {
+	case config.IsLondon(blockNumber):
+		signer = NewLondonSigner(config.ChainID)
 	case config.IsBerlin(blockNumber):
 		signer = NewEIP2930Signer(config.ChainID)
 	case config.IsEIP155(blockNumber):
@@ -61,7 +63,10 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
 // have the current block number available, use MakeSigner instead.
 func LatestSigner(config *params.ChainConfig) Signer {
 	if config.ChainID != nil {
-		if config.BerlinBlock != nil || config.YoloV3Block != nil {
+		if config.LondonBlock != nil {
+			return NewLondonSigner(config.ChainID)
+		}
+		if config.BerlinBlock != nil {
 			return NewEIP2930Signer(config.ChainID)
 		}
 		if config.EIP155Block != nil {
@@ -82,7 +87,7 @@ func LatestSignerForChainID(chainID *big.Int) Signer {
 	if chainID == nil {
 		return HomesteadSigner{}
 	}
-	return NewEIP2930Signer(chainID)
+	return NewLondonSigner(chainID)
 }
 
 // SignTx signs the transaction using the given signer and private key.
@@ -165,6 +170,72 @@ type Signer interface {
 	Equal(Signer) bool
 }
 
+type londonSigner struct{ eip2930Signer }
+
+// NewLondonSigner returns a signer that accepts
+// - EIP-1559 dynamic fee transactions
+// - EIP-2930 access list transactions,
+// - EIP-155 replay protected transactions, and
+// - legacy Homestead transactions.
+func NewLondonSigner(chainId *big.Int) Signer {
+	return londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}
+}
+
+func (s londonSigner) Sender(tx *Transaction) (common.Address, error) {
+	if tx.Type() != DynamicFeeTxType {
+		return s.eip2930Signer.Sender(tx)
+	}
+	V, R, S := tx.RawSignatureValues()
+	// DynamicFee txs are defined to use 0 and 1 as their recovery
+	// id, add 27 to become equivalent to unprotected Homestead signatures.
+	V = new(big.Int).Add(V, big.NewInt(27))
+	if tx.ChainId().Cmp(s.chainId) != 0 {
+		return common.Address{}, ErrInvalidChainId
+	}
+	return recoverPlain(s.Hash(tx), R, S, V, true)
+}
+
+func (s londonSigner) Equal(s2 Signer) bool {
+	x, ok := s2.(londonSigner)
+	return ok && x.chainId.Cmp(s.chainId) == 0
+}
+
+func (s londonSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) {
+	txdata, ok := tx.inner.(*DynamicFeeTx)
+	if !ok {
+		return s.eip2930Signer.SignatureValues(tx, sig)
+	}
+	// Check that chain ID of tx matches the signer. We also accept ID zero here,
+	// because it indicates that the chain ID was not specified in the tx.
+	if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 {
+		return nil, nil, nil, ErrInvalidChainId
+	}
+	R, S, _ = decodeSignature(sig)
+	V = big.NewInt(int64(sig[64]))
+	return R, S, V, nil
+}
+
+// Hash returns the hash to be signed by the sender.
+// It does not uniquely identify the transaction.
+func (s londonSigner) Hash(tx *Transaction) common.Hash {
+	if tx.Type() != DynamicFeeTxType {
+		return s.eip2930Signer.Hash(tx)
+	}
+	return prefixedRlpHash(
+		tx.Type(),
+		[]interface{}{
+			s.chainId,
+			tx.Nonce(),
+			tx.GasTipCap(),
+			tx.GasFeeCap(),
+			tx.Gas(),
+			tx.To(),
+			tx.Value(),
+			tx.Data(),
+			tx.AccessList(),
+		})
+}
+
 type eip2930Signer struct{ EIP155Signer }
 
 // NewEIP2930Signer returns a signer that accepts EIP-2930 access list transactions,
@@ -192,8 +263,8 @@ func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) {
 		V = new(big.Int).Sub(V, s.chainIdMul)
 		V.Sub(V, big8)
 	case AccessListTxType:
-		// ACL txs are defined to use 0 and 1 as their recovery id, add
-		// 27 to become equivalent to unprotected Homestead signatures.
+		// AL txs are defined to use 0 and 1 as their recovery
+		// id, add 27 to become equivalent to unprotected Homestead signatures.
 		V = new(big.Int).Add(V, big.NewInt(27))
 	default:
 		return common.Address{}, ErrTxTypeNotSupported
diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go
index 3cece9c2358dd09a195195625d000790f39955c8..58c95071b288196eacf0f75448570d3ff6b80eea 100644
--- a/core/types/transaction_test.go
+++ b/core/types/transaction_test.go
@@ -22,6 +22,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"math/big"
+	"math/rand"
 	"reflect"
 	"testing"
 	"time"
@@ -258,36 +259,77 @@ func TestRecipientNormal(t *testing.T) {
 	}
 }
 
+func TestTransactionPriceNonceSortLegacy(t *testing.T) {
+	testTransactionPriceNonceSort(t, nil)
+}
+
+func TestTransactionPriceNonceSort1559(t *testing.T) {
+	testTransactionPriceNonceSort(t, big.NewInt(0))
+	testTransactionPriceNonceSort(t, big.NewInt(5))
+	testTransactionPriceNonceSort(t, big.NewInt(50))
+}
+
 // Tests that transactions can be correctly sorted according to their price in
 // decreasing order, but at the same time with increasing nonces when issued by
 // the same account.
-func TestTransactionPriceNonceSort(t *testing.T) {
+func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
 	// Generate a batch of accounts to start with
 	keys := make([]*ecdsa.PrivateKey, 25)
 	for i := 0; i < len(keys); i++ {
 		keys[i], _ = crypto.GenerateKey()
 	}
-	signer := HomesteadSigner{}
+	signer := LatestSignerForChainID(common.Big1)
 
 	// Generate a batch of transactions with overlapping values, but shifted nonces
 	groups := map[common.Address]Transactions{}
+	expectedCount := 0
 	for start, key := range keys {
 		addr := crypto.PubkeyToAddress(key.PublicKey)
+		count := 25
 		for i := 0; i < 25; i++ {
-			tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil), signer, key)
+			var tx *Transaction
+			gasFeeCap := rand.Intn(50)
+			if baseFee == nil {
+				tx = NewTx(&LegacyTx{
+					Nonce:    uint64(start + i),
+					To:       &common.Address{},
+					Value:    big.NewInt(100),
+					Gas:      100,
+					GasPrice: big.NewInt(int64(gasFeeCap)),
+					Data:     nil,
+				})
+			} else {
+				tx = NewTx(&DynamicFeeTx{
+					Nonce:     uint64(start + i),
+					To:        &common.Address{},
+					Value:     big.NewInt(100),
+					Gas:       100,
+					GasFeeCap: big.NewInt(int64(gasFeeCap)),
+					GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))),
+					Data:      nil,
+				})
+				if count == 25 && int64(gasFeeCap) < baseFee.Int64() {
+					count = i
+				}
+			}
+			tx, err := SignTx(tx, signer, key)
+			if err != nil {
+				t.Fatalf("failed to sign tx: %s", err)
+			}
 			groups[addr] = append(groups[addr], tx)
 		}
+		expectedCount += count
 	}
 	// Sort the transactions and cross check the nonce ordering
-	txset := NewTransactionsByPriceAndNonce(signer, groups)
+	txset := NewTransactionsByPriceAndNonce(signer, groups, baseFee)
 
 	txs := Transactions{}
 	for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
 		txs = append(txs, tx)
 		txset.Shift()
 	}
-	if len(txs) != 25*25 {
-		t.Errorf("expected %d transactions, found %d", 25*25, len(txs))
+	if len(txs) != expectedCount {
+		t.Errorf("expected %d transactions, found %d", expectedCount, len(txs))
 	}
 	for i, txi := range txs {
 		fromi, _ := Sender(signer, txi)
@@ -303,7 +345,12 @@ func TestTransactionPriceNonceSort(t *testing.T) {
 		if i+1 < len(txs) {
 			next := txs[i+1]
 			fromNext, _ := Sender(signer, next)
-			if fromi != fromNext && txi.GasPrice().Cmp(next.GasPrice()) < 0 {
+			tip, err := txi.EffectiveGasTip(baseFee)
+			nextTip, nextErr := next.EffectiveGasTip(baseFee)
+			if err != nil || nextErr != nil {
+				t.Errorf("error calculating effective tip")
+			}
+			if fromi != fromNext && tip.Cmp(nextTip) < 0 {
 				t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
 			}
 		}
@@ -331,7 +378,7 @@ func TestTransactionTimeSort(t *testing.T) {
 		groups[addr] = append(groups[addr], tx)
 	}
 	// Sort the transactions and cross check the nonce ordering
-	txset := NewTransactionsByPriceAndNonce(signer, groups)
+	txset := NewTransactionsByPriceAndNonce(signer, groups, nil)
 
 	txs := Transactions{}
 	for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
diff --git a/core/vm/access_list_tracer.go b/core/vm/access_list_tracer.go
index b5bc961c84376a69c8f2b73912268ba02178326b..cc5461d1c3104b99802e9de10685fc9277edf7ae 100644
--- a/core/vm/access_list_tracer.go
+++ b/core/vm/access_list_tracer.go
@@ -96,7 +96,7 @@ func (al accessList) equal(other accessList) bool {
 func (al accessList) accessList() types.AccessList {
 	acl := make(types.AccessList, 0, len(al))
 	for addr, slots := range al {
-		tuple := types.AccessTuple{Address: addr}
+		tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}}
 		for slot := range slots {
 			tuple.StorageKeys = append(tuple.StorageKeys, slot)
 		}
diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index 0ccf47b97903a7d547d1dbb0256cd2cff5ead0cc..449cded2a896c28921e2664fa7c848260cd75b62 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -16,17 +16,49 @@
 
 package vm
 
+const (
+	set2BitsMask = uint16(0b1100_0000_0000_0000)
+	set3BitsMask = uint16(0b1110_0000_0000_0000)
+	set4BitsMask = uint16(0b1111_0000_0000_0000)
+	set5BitsMask = uint16(0b1111_1000_0000_0000)
+	set6BitsMask = uint16(0b1111_1100_0000_0000)
+	set7BitsMask = uint16(0b1111_1110_0000_0000)
+)
+
 // bitvec is a bit vector which maps bytes in a program.
 // An unset bit means the byte is an opcode, a set bit means
 // it's data (i.e. argument of PUSHxx).
 type bitvec []byte
 
-func (bits *bitvec) set(pos uint64) {
-	(*bits)[pos/8] |= 0x80 >> (pos % 8)
+var lookup = [8]byte{
+	0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1,
+}
+
+func (bits bitvec) set1(pos uint64) {
+	bits[pos/8] |= lookup[pos%8]
+}
+
+func (bits bitvec) setN(flag uint16, pos uint64) {
+	a := flag >> (pos % 8)
+	bits[pos/8] |= byte(a >> 8)
+	if b := byte(a); b != 0 {
+		//	If the bit-setting affects the neighbouring byte, we can assign - no need to OR it,
+		//	since it's the first write to that byte
+		bits[pos/8+1] = b
+	}
+}
+
+func (bits bitvec) set8(pos uint64) {
+	a := byte(0xFF >> (pos % 8))
+	bits[pos/8] |= a
+	bits[pos/8+1] = ^a
 }
-func (bits *bitvec) set8(pos uint64) {
-	(*bits)[pos/8] |= 0xFF >> (pos % 8)
-	(*bits)[pos/8+1] |= ^(0xFF >> (pos % 8))
+
+func (bits bitvec) set16(pos uint64) {
+	a := byte(0xFF >> (pos % 8))
+	bits[pos/8] |= a
+	bits[pos/8+1] = 0xFF
+	bits[pos/8+2] = ^a
 }
 
 // codeSegment checks if the position is in a code segment.
@@ -40,22 +72,52 @@ func codeBitmap(code []byte) bitvec {
 	// ends with a PUSH32, the algorithm will push zeroes onto the
 	// bitvector outside the bounds of the actual code.
 	bits := make(bitvec, len(code)/8+1+4)
+	return codeBitmapInternal(code, bits)
+}
+
+// codeBitmapInternal is the internal implementation of codeBitmap.
+// It exists for the purpose of being able to run benchmark tests
+// without dynamic allocations affecting the results.
+func codeBitmapInternal(code, bits bitvec) bitvec {
 	for pc := uint64(0); pc < uint64(len(code)); {
 		op := OpCode(code[pc])
-
-		if op >= PUSH1 && op <= PUSH32 {
-			numbits := op - PUSH1 + 1
-			pc++
+		pc++
+		if op < PUSH1 || op > PUSH32 {
+			continue
+		}
+		numbits := op - PUSH1 + 1
+		if numbits >= 8 {
+			for ; numbits >= 16; numbits -= 16 {
+				bits.set16(pc)
+				pc += 16
+			}
 			for ; numbits >= 8; numbits -= 8 {
-				bits.set8(pc) // 8
+				bits.set8(pc)
 				pc += 8
 			}
-			for ; numbits > 0; numbits-- {
-				bits.set(pc)
-				pc++
-			}
-		} else {
-			pc++
+		}
+		switch numbits {
+		case 1:
+			bits.set1(pc)
+			pc += 1
+		case 2:
+			bits.setN(set2BitsMask, pc)
+			pc += 2
+		case 3:
+			bits.setN(set3BitsMask, pc)
+			pc += 3
+		case 4:
+			bits.setN(set4BitsMask, pc)
+			pc += 4
+		case 5:
+			bits.setN(set5BitsMask, pc)
+			pc += 5
+		case 6:
+			bits.setN(set6BitsMask, pc)
+			pc += 6
+		case 7:
+			bits.setN(set7BitsMask, pc)
+			pc += 7
 		}
 	}
 	return bits
diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go
index fd2d744d87f49cbaec29bb630491b1c9ad710bb1..585bb3097f44a1ff87c694ab69528ff5723352ad 100644
--- a/core/vm/analysis_test.go
+++ b/core/vm/analysis_test.go
@@ -47,10 +47,10 @@ func TestJumpDestAnalysis(t *testing.T) {
 		{[]byte{byte(PUSH32)}, 0xFF, 1},
 		{[]byte{byte(PUSH32)}, 0xFF, 2},
 	}
-	for _, test := range tests {
+	for i, test := range tests {
 		ret := codeBitmap(test.code)
 		if ret[test.which] != test.exp {
-			t.Fatalf("expected %x, got %02x", test.exp, ret[test.which])
+			t.Fatalf("test %d: expected %x, got %02x", i, test.exp, ret[test.which])
 		}
 	}
 }
@@ -73,3 +73,23 @@ func BenchmarkJumpdestHashing_1200k(bench *testing.B) {
 	}
 	bench.StopTimer()
 }
+
+func BenchmarkJumpdestOpAnalysis(bench *testing.B) {
+	var op OpCode
+	bencher := func(b *testing.B) {
+		code := make([]byte, 32*b.N)
+		for i := range code {
+			code[i] = byte(op)
+		}
+		bits := make(bitvec, len(code)/8+1+4)
+		b.ResetTimer()
+		codeBitmapInternal(code, bits)
+	}
+	for op = PUSH1; op <= PUSH32; op++ {
+		bench.Run(op.String(), bencher)
+	}
+	op = JUMPDEST
+	bench.Run(op.String(), bencher)
+	op = STOP
+	bench.Run(op.String(), bencher)
+}
diff --git a/core/vm/eips.go b/core/vm/eips.go
index 6bb941d5f9d7e33e3d25ef6f5fdb79a1807df1fa..4070a2db534285f031225de8398bda94d49d7476 100644
--- a/core/vm/eips.go
+++ b/core/vm/eips.go
@@ -25,6 +25,8 @@ import (
 )
 
 var activators = map[int]func(*JumpTable){
+	3529: enable3529,
+	3198: enable3198,
 	2929: enable2929,
 	2200: enable2200,
 	1884: enable1884,
@@ -115,28 +117,28 @@ func enable2929(jt *JumpTable) {
 	jt[SLOAD].constantGas = 0
 	jt[SLOAD].dynamicGas = gasSLoadEIP2929
 
-	jt[EXTCODECOPY].constantGas = WarmStorageReadCostEIP2929
+	jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929
 	jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929
 
-	jt[EXTCODESIZE].constantGas = WarmStorageReadCostEIP2929
+	jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929
 	jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck
 
-	jt[EXTCODEHASH].constantGas = WarmStorageReadCostEIP2929
+	jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929
 	jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck
 
-	jt[BALANCE].constantGas = WarmStorageReadCostEIP2929
+	jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929
 	jt[BALANCE].dynamicGas = gasEip2929AccountCheck
 
-	jt[CALL].constantGas = WarmStorageReadCostEIP2929
+	jt[CALL].constantGas = params.WarmStorageReadCostEIP2929
 	jt[CALL].dynamicGas = gasCallEIP2929
 
-	jt[CALLCODE].constantGas = WarmStorageReadCostEIP2929
+	jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929
 	jt[CALLCODE].dynamicGas = gasCallCodeEIP2929
 
-	jt[STATICCALL].constantGas = WarmStorageReadCostEIP2929
+	jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929
 	jt[STATICCALL].dynamicGas = gasStaticCallEIP2929
 
-	jt[DELEGATECALL].constantGas = WarmStorageReadCostEIP2929
+	jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929
 	jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929
 
 	// This was previously part of the dynamic cost, but we're using it as a constantGas
@@ -144,3 +146,31 @@ func enable2929(jt *JumpTable) {
 	jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150
 	jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
 }
+
+// enable3529 enabled "EIP-3529: Reduction in refunds":
+// - Removes refunds for selfdestructs
+// - Reduces refunds for SSTORE
+// - Reduces max refunds to 20% gas
+func enable3529(jt *JumpTable) {
+	jt[SSTORE].dynamicGas = gasSStoreEIP3529
+	jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529
+}
+
+// enable3198 applies EIP-3198 (BASEFEE Opcode)
+// - Adds an opcode that returns the current block's base fee.
+func enable3198(jt *JumpTable) {
+	// New opcode
+	jt[BASEFEE] = &operation{
+		execute:     opBaseFee,
+		constantGas: GasQuickStep,
+		minStack:    minStack(0, 1),
+		maxStack:    maxStack(0, 1),
+	}
+}
+
+// opBaseFee implements BASEFEE opcode
+func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
+	baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee)
+	scope.Stack.push(baseFee)
+	return nil, nil
+}
diff --git a/core/vm/errors.go b/core/vm/errors.go
index c813aa36af369a356b8f0f1c12cae4fd761881ad..c7cfeae53ce345d68be565990587b1f164071586 100644
--- a/core/vm/errors.go
+++ b/core/vm/errors.go
@@ -34,6 +34,7 @@ var (
 	ErrWriteProtection          = errors.New("write protection")
 	ErrReturnDataOutOfBounds    = errors.New("return data out of bounds")
 	ErrGasUintOverflow          = errors.New("gas uint64 overflow")
+	ErrInvalidCode              = errors.New("invalid code: must not begin with 0xef")
 )
 
 // ErrStackUnderflow wraps an evm error when the items on the stack less
diff --git a/core/vm/evm.go b/core/vm/evm.go
index bd54e855c6b7c30ad626a4f71e6422afdc6a29e7..8964766736fb1af49e180c744aa1c56bec078095 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -17,7 +17,6 @@
 package vm
 
 import (
-	"errors"
 	"math/big"
 	"sync/atomic"
 	"time"
@@ -58,24 +57,6 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
 	return p, ok
 }
 
-// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
-func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
-	for _, interpreter := range evm.interpreters {
-		if interpreter.CanRun(contract.Code) {
-			if evm.interpreter != interpreter {
-				// Ensure that the interpreter pointer is set back
-				// to its current value upon return.
-				defer func(i Interpreter) {
-					evm.interpreter = i
-				}(evm.interpreter)
-				evm.interpreter = interpreter
-			}
-			return interpreter.Run(contract, input, readOnly)
-		}
-	}
-	return nil, errors.New("no compatible interpreter")
-}
-
 // BlockContext provides the EVM with auxiliary information. Once provided
 // it shouldn't be modified.
 type BlockContext struct {
@@ -93,6 +74,7 @@ type BlockContext struct {
 	BlockNumber *big.Int       // Provides information for NUMBER
 	Time        *big.Int       // Provides information for TIME
 	Difficulty  *big.Int       // Provides information for DIFFICULTY
+	BaseFee     *big.Int       // Provides information for BASEFEE
 }
 
 // TxContext provides the EVM with information about a transaction.
@@ -127,11 +109,10 @@ type EVM struct {
 	chainRules params.Rules
 	// virtual machine configuration options used to initialise the
 	// evm.
-	vmConfig Config
+	Config Config
 	// global (to this context) ethereum virtual machine
 	// used throughout the execution of the tx.
-	interpreters []Interpreter
-	interpreter  Interpreter
+	interpreter *EVMInterpreter
 	// abort is used to abort the EVM calling operations
 	// NOTE: must be set atomically
 	abort int32
@@ -143,38 +124,16 @@ type EVM struct {
 
 // NewEVM returns a new EVM. The returned EVM is not thread safe and should
 // only ever be used *once*.
-func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
+func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
 	evm := &EVM{
-		Context:      blockCtx,
-		TxContext:    txCtx,
-		StateDB:      statedb,
-		vmConfig:     vmConfig,
-		chainConfig:  chainConfig,
-		chainRules:   chainConfig.Rules(blockCtx.BlockNumber),
-		interpreters: make([]Interpreter, 0, 1),
-	}
-
-	if chainConfig.IsEWASM(blockCtx.BlockNumber) {
-		// to be implemented by EVM-C and Wagon PRs.
-		// if vmConfig.EWASMInterpreter != "" {
-		//  extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":")
-		//  path := extIntOpts[0]
-		//  options := []string{}
-		//  if len(extIntOpts) > 1 {
-		//    options = extIntOpts[1..]
-		//  }
-		//  evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options))
-		// } else {
-		// 	evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig))
-		// }
-		panic("No supported ewasm interpreter yet.")
-	}
-
-	// vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
-	// as we always want to have the built-in EVM as the failover option.
-	evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
-	evm.interpreter = evm.interpreters[0]
-
+		Context:     blockCtx,
+		TxContext:   txCtx,
+		StateDB:     statedb,
+		Config:      config,
+		chainConfig: chainConfig,
+		chainRules:  chainConfig.Rules(blockCtx.BlockNumber),
+	}
+	evm.interpreter = NewEVMInterpreter(evm, config)
 	return evm
 }
 
@@ -197,7 +156,7 @@ func (evm *EVM) Cancelled() bool {
 }
 
 // Interpreter returns the current interpreter
-func (evm *EVM) Interpreter() Interpreter {
+func (evm *EVM) Interpreter() *EVMInterpreter {
 	return evm.interpreter
 }
 
@@ -206,7 +165,7 @@ func (evm *EVM) Interpreter() Interpreter {
 // the necessary steps to create accounts and reverses the state in case of an
 // execution error or failed value transfer.
 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
-	if evm.vmConfig.NoRecursion && evm.depth > 0 {
+	if evm.Config.NoRecursion && evm.depth > 0 {
 		return nil, gas, nil
 	}
 	// Fail if we're trying to execute above the call depth limit
@@ -223,9 +182,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 	if !evm.StateDB.Exist(addr) {
 		if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
 			// Calling a non existing account, don't do anything, but ping the tracer
-			if evm.vmConfig.Debug && evm.depth == 0 {
-				evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
-				evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
+			if evm.Config.Debug && evm.depth == 0 {
+				evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
+				evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil)
 			}
 			return nil, gas, nil
 		}
@@ -234,10 +193,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 	evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
 
 	// Capture the tracer start/end events in debug mode
-	if evm.vmConfig.Debug && evm.depth == 0 {
-		evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
+	if evm.Config.Debug && evm.depth == 0 {
+		evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
 		defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters
-			evm.vmConfig.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err)
+			evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err)
 		}(gas, time.Now())
 	}
 
@@ -255,7 +214,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 			// The depth-check is already done, and precompiles handled above
 			contract := NewContract(caller, AccountRef(addrCopy), value, gas)
 			contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
-			ret, err = run(evm, contract, input, false)
+			ret, err = evm.interpreter.Run(contract, input, false)
 			gas = contract.Gas
 		}
 	}
@@ -282,7 +241,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 // CallCode differs from Call in the sense that it executes the given address'
 // code with the caller as context.
 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
-	if evm.vmConfig.NoRecursion && evm.depth > 0 {
+	if evm.Config.NoRecursion && evm.depth > 0 {
 		return nil, gas, nil
 	}
 	// Fail if we're trying to execute above the call depth limit
@@ -307,7 +266,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 		// The contract is a scoped environment for this execution context only.
 		contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
 		contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
-		ret, err = run(evm, contract, input, false)
+		ret, err = evm.interpreter.Run(contract, input, false)
 		gas = contract.Gas
 	}
 	if err != nil {
@@ -325,7 +284,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 // DelegateCall differs from CallCode in the sense that it executes the given address'
 // code with the caller as context and the caller is set to the caller of the caller.
 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
-	if evm.vmConfig.NoRecursion && evm.depth > 0 {
+	if evm.Config.NoRecursion && evm.depth > 0 {
 		return nil, gas, nil
 	}
 	// Fail if we're trying to execute above the call depth limit
@@ -342,7 +301,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
 		// Initialise a new contract and make initialise the delegate values
 		contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
 		contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
-		ret, err = run(evm, contract, input, false)
+		ret, err = evm.interpreter.Run(contract, input, false)
 		gas = contract.Gas
 	}
 	if err != nil {
@@ -359,7 +318,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
 // Opcodes that attempt to perform such modifications will result in exceptions
 // instead of performing the modifications.
 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
-	if evm.vmConfig.NoRecursion && evm.depth > 0 {
+	if evm.Config.NoRecursion && evm.depth > 0 {
 		return nil, gas, nil
 	}
 	// Fail if we're trying to execute above the call depth limit
@@ -393,7 +352,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
 		// When an error was returned by the EVM or when setting the creation code
 		// above we revert to the snapshot and consume any gas remaining. Additionally
 		// when we're in Homestead this also counts for code storage gas errors.
-		ret, err = run(evm, contract, input, true)
+		ret, err = evm.interpreter.Run(contract, input, true)
 		gas = contract.Gas
 	}
 	if err != nil {
@@ -452,22 +411,27 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 	contract := NewContract(caller, AccountRef(address), value, gas)
 	contract.SetCodeOptionalHash(&address, codeAndHash)
 
-	if evm.vmConfig.NoRecursion && evm.depth > 0 {
+	if evm.Config.NoRecursion && evm.depth > 0 {
 		return nil, address, gas, nil
 	}
 
-	if evm.vmConfig.Debug && evm.depth == 0 {
-		evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value)
+	if evm.Config.Debug && evm.depth == 0 {
+		evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value)
 	}
 	start := time.Now()
 
-	ret, err := run(evm, contract, nil, false)
+	ret, err := evm.interpreter.Run(contract, nil, false)
 
 	// Check whether the max code size has been exceeded, assign err if the case.
 	if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
 		err = ErrMaxCodeSizeExceeded
 	}
 
+	// Reject code starting with 0xEF if EIP-3541 is enabled.
+	if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon {
+		err = ErrInvalidCode
+	}
+
 	// if the contract creation ran successfully and no errors were returned
 	// calculate the gas required to store the code. If the code could not
 	// be stored due to not enough gas set an error and let it be handled
@@ -491,8 +455,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 		}
 	}
 
-	if evm.vmConfig.Debug && evm.depth == 0 {
-		evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
+	if evm.Config.Debug && evm.depth == 0 {
+		evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
 	}
 	return ret, address, contract.Gas, err
 }
diff --git a/core/vm/gen_structlog.go b/core/vm/gen_structlog.go
index ac04afe8b7530b107de94bce1bbe57814b099432..365f3b7914267762c109b162036c3e665919d228 100644
--- a/core/vm/gen_structlog.go
+++ b/core/vm/gen_structlog.go
@@ -4,11 +4,11 @@ package vm
 
 import (
 	"encoding/json"
-	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/common/math"
+	"github.com/holiman/uint256"
 )
 
 var _ = (*structLogMarshaling)(nil)
@@ -22,8 +22,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
 		GasCost       math.HexOrDecimal64         `json:"gasCost"`
 		Memory        hexutil.Bytes               `json:"memory"`
 		MemorySize    int                         `json:"memSize"`
-		Stack         []*math.HexOrDecimal256     `json:"stack"`
-		ReturnStack   []math.HexOrDecimal64       `json:"returnStack"`
+		Stack         []uint256.Int               `json:"stack"`
 		ReturnData    hexutil.Bytes               `json:"returnData"`
 		Storage       map[common.Hash]common.Hash `json:"-"`
 		Depth         int                         `json:"depth"`
@@ -39,12 +38,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
 	enc.GasCost = math.HexOrDecimal64(s.GasCost)
 	enc.Memory = s.Memory
 	enc.MemorySize = s.MemorySize
-	if s.Stack != nil {
-		enc.Stack = make([]*math.HexOrDecimal256, len(s.Stack))
-		for k, v := range s.Stack {
-			enc.Stack[k] = (*math.HexOrDecimal256)(v)
-		}
-	}
+	enc.Stack = s.Stack
 	enc.ReturnData = s.ReturnData
 	enc.Storage = s.Storage
 	enc.Depth = s.Depth
@@ -64,7 +58,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
 		GasCost       *math.HexOrDecimal64        `json:"gasCost"`
 		Memory        *hexutil.Bytes              `json:"memory"`
 		MemorySize    *int                        `json:"memSize"`
-		Stack         []*math.HexOrDecimal256     `json:"stack"`
+		Stack         []uint256.Int               `json:"stack"`
 		ReturnData    *hexutil.Bytes              `json:"returnData"`
 		Storage       map[common.Hash]common.Hash `json:"-"`
 		Depth         *int                        `json:"depth"`
@@ -94,10 +88,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
 		s.MemorySize = *dec.MemorySize
 	}
 	if dec.Stack != nil {
-		s.Stack = make([]*big.Int, len(dec.Stack))
-		for k, v := range dec.Stack {
-			s.Stack[k] = (*big.Int)(v)
-		}
+		s.Stack = dec.Stack
 	}
 	if dec.ReturnData != nil {
 		s.ReturnData = *dec.ReturnData
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 3277674ee825c7200bae633922c51fbef00af4a2..6c8c6e6e6fa1b3fd4f7b391a7bef8cd02d2e23e8 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -244,7 +244,7 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
 	interpreter.hasher.Read(interpreter.hasherBuf[:])
 
 	evm := interpreter.evm
-	if evm.vmConfig.EnablePreimageRecording {
+	if evm.Config.EnablePreimageRecording {
 		evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
 	}
 
@@ -669,6 +669,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
 	}
 	stack.push(&temp)
 	if err == nil || err == ErrExecutionReverted {
+		ret = common.CopyBytes(ret)
 		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 	}
 	scope.Contract.Gas += returnGas
@@ -703,6 +704,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
 	}
 	stack.push(&temp)
 	if err == nil || err == ErrExecutionReverted {
+		ret = common.CopyBytes(ret)
 		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 	}
 	scope.Contract.Gas += returnGas
@@ -730,6 +732,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
 	}
 	stack.push(&temp)
 	if err == nil || err == ErrExecutionReverted {
+		ret = common.CopyBytes(ret)
 		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 	}
 	scope.Contract.Gas += returnGas
@@ -757,6 +760,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
 	}
 	stack.push(&temp)
 	if err == nil || err == ErrExecutionReverted {
+		ret = common.CopyBytes(ret)
 		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 	}
 	scope.Contract.Gas += returnGas
diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go
index d17ccfab89eed7d6bf0537a761819cd863890a0c..560d26a0b8d4391238b84d731053e899eb690d0d 100644
--- a/core/vm/instructions_test.go
+++ b/core/vm/instructions_test.go
@@ -96,7 +96,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
 		pc             = uint64(0)
-		evmInterpreter = env.interpreter.(*EVMInterpreter)
+		evmInterpreter = env.interpreter
 	)
 
 	for i, test := range tests {
@@ -194,7 +194,7 @@ func TestAddMod(t *testing.T) {
 	var (
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
-		evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+		evmInterpreter = NewEVMInterpreter(env, env.Config)
 		pc             = uint64(0)
 	)
 	tests := []struct {
@@ -234,7 +234,7 @@ func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcas
 		env         = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack       = newstack()
 		pc          = uint64(0)
-		interpreter = env.interpreter.(*EVMInterpreter)
+		interpreter = env.interpreter
 	)
 	result := make([]TwoOperandTestcase, len(args))
 	for i, param := range args {
@@ -283,7 +283,7 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
 	var (
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
-		evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+		evmInterpreter = NewEVMInterpreter(env, env.Config)
 	)
 
 	env.interpreter = evmInterpreter
@@ -518,7 +518,7 @@ func TestOpMstore(t *testing.T) {
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
 		mem            = NewMemory()
-		evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+		evmInterpreter = NewEVMInterpreter(env, env.Config)
 	)
 
 	env.interpreter = evmInterpreter
@@ -542,7 +542,7 @@ func BenchmarkOpMstore(bench *testing.B) {
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
 		mem            = NewMemory()
-		evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+		evmInterpreter = NewEVMInterpreter(env, env.Config)
 	)
 
 	env.interpreter = evmInterpreter
@@ -563,16 +563,16 @@ func BenchmarkOpSHA3(bench *testing.B) {
 		env            = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
 		stack          = newstack()
 		mem            = NewMemory()
-		evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+		evmInterpreter = NewEVMInterpreter(env, env.Config)
 	)
 	env.interpreter = evmInterpreter
 	mem.Resize(32)
 	pc := uint64(0)
-	start := uint256.NewInt()
+	start := new(uint256.Int)
 
 	bench.ResetTimer()
 	for i := 0; i < bench.N; i++ {
-		stack.pushN(*uint256.NewInt().SetUint64(32), *start)
+		stack.pushN(*uint256.NewInt(32), *start)
 		opSha3(&pc, evmInterpreter, &ScopeContext{mem, stack, nil})
 	}
 }
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 1022c355c10cf12a6a55811e18066ccaa04e79c1..9fb83799c98c8b8b16a2bf86c2de60f7a7eae144 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -30,38 +30,14 @@ type Config struct {
 	Debug                   bool   // Enables debugging
 	Tracer                  Tracer // Opcode logger
 	NoRecursion             bool   // Disables call, callcode, delegate call and create
+	NoBaseFee               bool   // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
 	EnablePreimageRecording bool   // Enables recording of SHA3/keccak preimages
 
 	JumpTable [256]*operation // EVM instruction table, automatically populated if unset
 
-	EWASMInterpreter string // External EWASM interpreter options
-	EVMInterpreter   string // External EVM interpreter options
-
 	ExtraEips []int // Additional EIPS that are to be enabled
 }
 
-// Interpreter is used to run Ethereum based contracts and will utilise the
-// passed environment to query external sources for state information.
-// The Interpreter will run the byte code VM based on the passed
-// configuration.
-type Interpreter interface {
-	// Run loops and evaluates the contract's code with the given input data and returns
-	// the return byte-slice and an error if one occurred.
-	Run(contract *Contract, input []byte, static bool) ([]byte, error)
-	// CanRun tells if the contract, passed as an argument, can be
-	// run by the current interpreter. This is meant so that the
-	// caller can do something like:
-	//
-	// ```golang
-	// for _, interpreter := range interpreters {
-	//   if interpreter.CanRun(contract.code) {
-	//     interpreter.Run(contract.code, input)
-	//   }
-	// }
-	// ```
-	CanRun([]byte) bool
-}
-
 // ScopeContext contains the things that are per-call, such as stack and memory,
 // but not transients like pc and gas
 type ScopeContext struct {
@@ -98,6 +74,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
 	if cfg.JumpTable[STOP] == nil {
 		var jt JumpTable
 		switch {
+		case evm.chainRules.IsLondon:
+			jt = londonInstructionSet
 		case evm.chainRules.IsBerlin:
 			jt = berlinInstructionSet
 		case evm.chainRules.IsIstanbul:
@@ -284,7 +262,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
 		// if the operation clears the return data (e.g. it has returning data)
 		// set the last return to the result of the operation.
 		if operation.returns {
-			in.returnData = common.CopyBytes(res)
+			in.returnData = res
 		}
 
 		switch {
@@ -300,9 +278,3 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
 	}
 	return nil, nil
 }
-
-// CanRun tells if the contract, passed as an argument, can be
-// run by the current interpreter.
-func (in *EVMInterpreter) CanRun(code []byte) bool {
-	return true
-}
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index bb1800ea9197cad0751cc94ea51845ee98e043df..329ad77cbf835a2dab46d24bd77330d249358f9c 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -57,11 +57,21 @@ var (
 	constantinopleInstructionSet   = newConstantinopleInstructionSet()
 	istanbulInstructionSet         = newIstanbulInstructionSet()
 	berlinInstructionSet           = newBerlinInstructionSet()
+	londonInstructionSet           = newLondonInstructionSet()
 )
 
 // JumpTable contains the EVM opcodes supported at a given fork.
 type JumpTable [256]*operation
 
+// newLondonInstructionSet returns the frontier, homestead, byzantium,
+// contantinople, istanbul, petersburg, berlin and london instructions.
+func newLondonInstructionSet() JumpTable {
+	instructionSet := newBerlinInstructionSet()
+	enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
+	enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
+	return instructionSet
+}
+
 // newBerlinInstructionSet returns the frontier, homestead, byzantium,
 // contantinople, istanbul, petersburg and berlin instructions.
 func newBerlinInstructionSet() JumpTable {
diff --git a/core/vm/logger.go b/core/vm/logger.go
index 9ccaafc77227ec075ac6ad8d25a06014eecf9796..900a5e58543aabe2a13b6aa8b25eac954782e96f 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -29,6 +29,7 @@ import (
 	"github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/params"
+	"github.com/holiman/uint256"
 )
 
 // Storage represents a contract's storage.
@@ -66,7 +67,7 @@ type StructLog struct {
 	GasCost       uint64                      `json:"gasCost"`
 	Memory        []byte                      `json:"memory"`
 	MemorySize    int                         `json:"memSize"`
-	Stack         []*big.Int                  `json:"stack"`
+	Stack         []uint256.Int               `json:"stack"`
 	ReturnData    []byte                      `json:"returnData"`
 	Storage       map[common.Hash]common.Hash `json:"-"`
 	Depth         int                         `json:"depth"`
@@ -76,7 +77,6 @@ type StructLog struct {
 
 // overrides for gencodec
 type structLogMarshaling struct {
-	Stack       []*math.HexOrDecimal256
 	Gas         math.HexOrDecimal64
 	GasCost     math.HexOrDecimal64
 	Memory      hexutil.Bytes
@@ -135,6 +135,14 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
 	return logger
 }
 
+// Reset clears the data held by the logger.
+func (l *StructLogger) Reset() {
+	l.storage = make(map[common.Address]Storage)
+	l.output = make([]byte, 0)
+	l.logs = l.logs[:0]
+	l.err = nil
+}
+
 // CaptureStart implements the Tracer interface to initialize the tracing operation.
 func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
 }
@@ -157,16 +165,16 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
 		copy(mem, memory.Data())
 	}
 	// Copy a snapshot of the current stack state to a new buffer
-	var stck []*big.Int
+	var stck []uint256.Int
 	if !l.cfg.DisableStack {
-		stck = make([]*big.Int, len(stack.Data()))
+		stck = make([]uint256.Int, len(stack.Data()))
 		for i, item := range stack.Data() {
-			stck[i] = new(big.Int).Set(item.ToBig())
+			stck[i] = item
 		}
 	}
 	// Copy a snapshot of the current storage to a new container
 	var storage Storage
-	if !l.cfg.DisableStorage {
+	if !l.cfg.DisableStorage && (op == SLOAD || op == SSTORE) {
 		// initialise new changed values storage container for this contract
 		// if not present.
 		if l.storage[contract.Address()] == nil {
@@ -179,16 +187,16 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
 				value   = env.StateDB.GetState(contract.Address(), address)
 			)
 			l.storage[contract.Address()][address] = value
-		}
-		// capture SSTORE opcodes and record the written entry in the local storage.
-		if op == SSTORE && stack.len() >= 2 {
+			storage = l.storage[contract.Address()].Copy()
+		} else if op == SSTORE && stack.len() >= 2 {
+			// capture SSTORE opcodes and record the written entry in the local storage.
 			var (
 				value   = common.Hash(stack.data[stack.len()-2].Bytes32())
 				address = common.Hash(stack.data[stack.len()-1].Bytes32())
 			)
 			l.storage[contract.Address()][address] = value
+			storage = l.storage[contract.Address()].Copy()
 		}
-		storage = l.storage[contract.Address()].Copy()
 	}
 	var rdata []byte
 	if !l.cfg.DisableReturnData {
@@ -238,7 +246,7 @@ func WriteTrace(writer io.Writer, logs []StructLog) {
 		if len(log.Stack) > 0 {
 			fmt.Fprintln(writer, "Stack:")
 			for i := len(log.Stack) - 1; i >= 0; i-- {
-				fmt.Fprintf(writer, "%08d  %x\n", len(log.Stack)-i-1, math.PaddedBigBytes(log.Stack[i], 32))
+				fmt.Fprintf(writer, "%08d  %s\n", len(log.Stack)-i-1, log.Stack[i].Hex())
 			}
 		}
 		if len(log.Memory) > 0 {
@@ -314,7 +322,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
 		// format stack
 		var a []string
 		for _, elem := range stack.data {
-			a = append(a, fmt.Sprintf("%v", elem.String()))
+			a = append(a, elem.Hex())
 		}
 		b := fmt.Sprintf("[%v]", strings.Join(a, ","))
 		fmt.Fprintf(t.out, "%10v |", b)
diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go
index e54be08596e6f840fe05a30bcfdf87f7285dec7e..5210f479fe61b0bdf073fb049bab0310bfac2c71 100644
--- a/core/vm/logger_json.go
+++ b/core/vm/logger_json.go
@@ -57,7 +57,6 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
 		Gas:           gas,
 		GasCost:       cost,
 		MemorySize:    memory.Len(),
-		Storage:       nil,
 		Depth:         depth,
 		RefundCounter: env.StateDB.GetRefund(),
 		Err:           err,
@@ -66,12 +65,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
 		log.Memory = memory.Data()
 	}
 	if !l.cfg.DisableStack {
-		//TODO(@holiman) improve this
-		logstack := make([]*big.Int, len(stack.Data()))
-		for i, item := range stack.Data() {
-			logstack[i] = item.ToBig()
-		}
-		log.Stack = logstack
+		log.Stack = stack.data
 	}
 	if !l.cfg.DisableReturnData {
 		log.ReturnData = rData
@@ -87,8 +81,9 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration,
 		Time    time.Duration       `json:"time"`
 		Err     string              `json:"error,omitempty"`
 	}
+	var errMsg string
 	if err != nil {
-		l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()})
+		errMsg = err.Error()
 	}
-	l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""})
+	l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, errMsg})
 }
diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go
index 9c936af36ab1af5743184557d84ae724bf617336..730d8374bb914678a3e5b997e5beb403141d7043 100644
--- a/core/vm/logger_test.go
+++ b/core/vm/logger_test.go
@@ -30,7 +30,6 @@ type dummyContractRef struct {
 	calledForEach bool
 }
 
-func (dummyContractRef) ReturnGas(*big.Int)          {}
 func (dummyContractRef) Address() common.Address     { return common.Address{} }
 func (dummyContractRef) Value() *big.Int             { return new(big.Int) }
 func (dummyContractRef) SetCode(common.Hash, []byte) {}
@@ -60,8 +59,8 @@ func TestStoreCapture(t *testing.T) {
 			Contract: contract,
 		}
 	)
-	scope.Stack.push(uint256.NewInt().SetUint64(1))
-	scope.Stack.push(uint256.NewInt())
+	scope.Stack.push(uint256.NewInt(1))
+	scope.Stack.push(new(uint256.Int))
 	var index common.Hash
 	logger.CaptureState(env, 0, SSTORE, 0, 0, scope, nil, 0, nil)
 	if len(logger.storage[contract.Address()]) == 0 {
diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go
index b0adf37d0c2698b788a2c2af7b2be0f6270ed04f..286307ae91aea9f269522b8d9ddb7b8def5f12b9 100644
--- a/core/vm/opcodes.go
+++ b/core/vm/opcodes.go
@@ -103,6 +103,7 @@ const (
 	GASLIMIT
 	CHAINID     OpCode = 0x46
 	SELFBALANCE OpCode = 0x47
+	BASEFEE     OpCode = 0x48
 )
 
 // 0x50 range - 'storage' and execution.
@@ -280,6 +281,7 @@ var opCodeToString = map[OpCode]string{
 	GASLIMIT:    "GASLIMIT",
 	CHAINID:     "CHAINID",
 	SELFBALANCE: "SELFBALANCE",
+	BASEFEE:     "BASEFEE",
 
 	// 0x50 range - 'storage' and execution.
 	POP: "POP",
@@ -432,6 +434,7 @@ var stringToOp = map[string]OpCode{
 	"CALLDATASIZE":   CALLDATASIZE,
 	"CALLDATACOPY":   CALLDATACOPY,
 	"CHAINID":        CHAINID,
+	"BASEFEE":        BASEFEE,
 	"DELEGATECALL":   DELEGATECALL,
 	"STATICCALL":     STATICCALL,
 	"CODESIZE":       CODESIZE,
diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go
index c56941899ed1b505e79f24672b1425dc83af2bbe..483226eefad8426771938e2990d80384a9cb1db7 100644
--- a/core/vm/operations_acl.go
+++ b/core/vm/operations_acl.go
@@ -24,91 +24,75 @@ import (
 	"github.com/ethereum/go-ethereum/params"
 )
 
-const (
-	ColdAccountAccessCostEIP2929 = uint64(2600) // COLD_ACCOUNT_ACCESS_COST
-	ColdSloadCostEIP2929         = uint64(2100) // COLD_SLOAD_COST
-	WarmStorageReadCostEIP2929   = uint64(100)  // WARM_STORAGE_READ_COST
-)
-
-// gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
-//
-// When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys.
-// If it is not, charge an additional COLD_SLOAD_COST gas, and add the pair to accessed_storage_keys.
-// Additionally, modify the parameters defined in EIP 2200 as follows:
-//
-// Parameter 	Old value 	New value
-// SLOAD_GAS 	800 	= WARM_STORAGE_READ_COST
-// SSTORE_RESET_GAS 	5000 	5000 - COLD_SLOAD_COST
-//
-//The other parameters defined in EIP 2200 are unchanged.
-// see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified
-func gasSStoreEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
-	// If we fail the minimum gas availability invariant, fail (0)
-	if contract.Gas <= params.SstoreSentryGasEIP2200 {
-		return 0, errors.New("not enough gas for reentrancy sentry")
-	}
-	// Gas sentry honoured, do the actual gas calculation based on the stored value
-	var (
-		y, x    = stack.Back(1), stack.peek()
-		slot    = common.Hash(x.Bytes32())
-		current = evm.StateDB.GetState(contract.Address(), slot)
-		cost    = uint64(0)
-	)
-	// Check slot presence in the access list
-	if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent {
-		cost = ColdSloadCostEIP2929
-		// If the caller cannot afford the cost, this change will be rolled back
-		evm.StateDB.AddSlotToAccessList(contract.Address(), slot)
-		if !addrPresent {
-			// Once we're done with YOLOv2 and schedule this for mainnet, might
-			// be good to remove this panic here, which is just really a
-			// canary to have during testing
-			panic("impossible case: address was not present in access list during sstore op")
+func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
+	return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+		// If we fail the minimum gas availability invariant, fail (0)
+		if contract.Gas <= params.SstoreSentryGasEIP2200 {
+			return 0, errors.New("not enough gas for reentrancy sentry")
 		}
-	}
-	value := common.Hash(y.Bytes32())
+		// Gas sentry honoured, do the actual gas calculation based on the stored value
+		var (
+			y, x    = stack.Back(1), stack.peek()
+			slot    = common.Hash(x.Bytes32())
+			current = evm.StateDB.GetState(contract.Address(), slot)
+			cost    = uint64(0)
+		)
+		// Check slot presence in the access list
+		if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent {
+			cost = params.ColdSloadCostEIP2929
+			// If the caller cannot afford the cost, this change will be rolled back
+			evm.StateDB.AddSlotToAccessList(contract.Address(), slot)
+			if !addrPresent {
+				// Once we're done with YOLOv2 and schedule this for mainnet, might
+				// be good to remove this panic here, which is just really a
+				// canary to have during testing
+				panic("impossible case: address was not present in access list during sstore op")
+			}
+		}
+		value := common.Hash(y.Bytes32())
 
-	if current == value { // noop (1)
-		// EIP 2200 original clause:
-		//		return params.SloadGasEIP2200, nil
-		return cost + WarmStorageReadCostEIP2929, nil // SLOAD_GAS
-	}
-	original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
-	if original == current {
-		if original == (common.Hash{}) { // create slot (2.1.1)
-			return cost + params.SstoreSetGasEIP2200, nil
+		if current == value { // noop (1)
+			// EIP 2200 original clause:
+			//		return params.SloadGasEIP2200, nil
+			return cost + params.WarmStorageReadCostEIP2929, nil // SLOAD_GAS
 		}
-		if value == (common.Hash{}) { // delete slot (2.1.2b)
-			evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200)
+		original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
+		if original == current {
+			if original == (common.Hash{}) { // create slot (2.1.1)
+				return cost + params.SstoreSetGasEIP2200, nil
+			}
+			if value == (common.Hash{}) { // delete slot (2.1.2b)
+				evm.StateDB.AddRefund(clearingRefund)
+			}
+			// EIP-2200 original clause:
+			//		return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2)
+			return cost + (params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929), nil // write existing slot (2.1.2)
 		}
-		// EIP-2200 original clause:
-		//		return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2)
-		return cost + (params.SstoreResetGasEIP2200 - ColdSloadCostEIP2929), nil // write existing slot (2.1.2)
-	}
-	if original != (common.Hash{}) {
-		if current == (common.Hash{}) { // recreate slot (2.2.1.1)
-			evm.StateDB.SubRefund(params.SstoreClearsScheduleRefundEIP2200)
-		} else if value == (common.Hash{}) { // delete slot (2.2.1.2)
-			evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200)
+		if original != (common.Hash{}) {
+			if current == (common.Hash{}) { // recreate slot (2.2.1.1)
+				evm.StateDB.SubRefund(clearingRefund)
+			} else if value == (common.Hash{}) { // delete slot (2.2.1.2)
+				evm.StateDB.AddRefund(clearingRefund)
+			}
 		}
-	}
-	if original == value {
-		if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
-			// EIP 2200 Original clause:
-			//evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200)
-			evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - WarmStorageReadCostEIP2929)
-		} else { // reset to original existing slot (2.2.2.2)
-			// EIP 2200 Original clause:
-			//	evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200)
-			// - SSTORE_RESET_GAS redefined as (5000 - COLD_SLOAD_COST)
-			// - SLOAD_GAS redefined as WARM_STORAGE_READ_COST
-			// Final: (5000 - COLD_SLOAD_COST) - WARM_STORAGE_READ_COST
-			evm.StateDB.AddRefund((params.SstoreResetGasEIP2200 - ColdSloadCostEIP2929) - WarmStorageReadCostEIP2929)
+		if original == value {
+			if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
+				// EIP 2200 Original clause:
+				//evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200)
+				evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.WarmStorageReadCostEIP2929)
+			} else { // reset to original existing slot (2.2.2.2)
+				// EIP 2200 Original clause:
+				//	evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200)
+				// - SSTORE_RESET_GAS redefined as (5000 - COLD_SLOAD_COST)
+				// - SLOAD_GAS redefined as WARM_STORAGE_READ_COST
+				// Final: (5000 - COLD_SLOAD_COST) - WARM_STORAGE_READ_COST
+				evm.StateDB.AddRefund((params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929) - params.WarmStorageReadCostEIP2929)
+			}
 		}
+		// EIP-2200 original clause:
+		//return params.SloadGasEIP2200, nil // dirty update (2.2)
+		return cost + params.WarmStorageReadCostEIP2929, nil // dirty update (2.2)
 	}
-	// EIP-2200 original clause:
-	//return params.SloadGasEIP2200, nil // dirty update (2.2)
-	return cost + WarmStorageReadCostEIP2929, nil // dirty update (2.2)
 }
 
 // gasSLoadEIP2929 calculates dynamic gas for SLOAD according to EIP-2929
@@ -124,9 +108,9 @@ func gasSLoadEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
 		// If the caller cannot afford the cost, this change will be rolled back
 		// If he does afford it, we can skip checking the same thing later on, during execution
 		evm.StateDB.AddSlotToAccessList(contract.Address(), slot)
-		return ColdSloadCostEIP2929, nil
+		return params.ColdSloadCostEIP2929, nil
 	}
-	return WarmStorageReadCostEIP2929, nil
+	return params.WarmStorageReadCostEIP2929, nil
 }
 
 // gasExtCodeCopyEIP2929 implements extcodecopy according to EIP-2929
@@ -146,7 +130,7 @@ func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memo
 		evm.StateDB.AddAddressToAccessList(addr)
 		var overflow bool
 		// We charge (cold-warm), since 'warm' is already charged as constantGas
-		if gas, overflow = math.SafeAdd(gas, ColdAccountAccessCostEIP2929-WarmStorageReadCostEIP2929); overflow {
+		if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow {
 			return 0, ErrGasUintOverflow
 		}
 		return gas, nil
@@ -168,7 +152,7 @@ func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *Stack, mem *Mem
 		// If the caller cannot afford the cost, this change will be rolled back
 		evm.StateDB.AddAddressToAccessList(addr)
 		// The warm storage read cost is already charged as constantGas
-		return ColdAccountAccessCostEIP2929 - WarmStorageReadCostEIP2929, nil
+		return params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929, nil
 	}
 	return 0, nil
 }
@@ -180,7 +164,7 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc {
 		warmAccess := evm.StateDB.AddressInAccessList(addr)
 		// The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so
 		// the cost to charge for cold access, if any, is Cold - Warm
-		coldCost := ColdAccountAccessCostEIP2929 - WarmStorageReadCostEIP2929
+		coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929
 		if !warmAccess {
 			evm.StateDB.AddAddressToAccessList(addr)
 			// Charge the remaining difference here already, to correctly calculate available
@@ -212,25 +196,49 @@ var (
 	gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall)
 	gasStaticCallEIP2929   = makeCallVariantGasCallEIP2929(gasStaticCall)
 	gasCallCodeEIP2929     = makeCallVariantGasCallEIP2929(gasCallCode)
+	gasSelfdestructEIP2929 = makeSelfdestructGasFn(true)
+	// gasSelfdestructEIP3529 implements the changes in EIP-2539 (no refunds)
+	gasSelfdestructEIP3529 = makeSelfdestructGasFn(false)
+
+	// gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
+	//
+	// When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys.
+	// If it is not, charge an additional COLD_SLOAD_COST gas, and add the pair to accessed_storage_keys.
+	// Additionally, modify the parameters defined in EIP 2200 as follows:
+	//
+	// Parameter 	Old value 	New value
+	// SLOAD_GAS 	800 	= WARM_STORAGE_READ_COST
+	// SSTORE_RESET_GAS 	5000 	5000 - COLD_SLOAD_COST
+	//
+	//The other parameters defined in EIP 2200 are unchanged.
+	// see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified
+	gasSStoreEIP2929 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP2200)
+
+	// gasSStoreEIP2539 implements gas cost for SSTORE according to EPI-2539
+	// Replace `SSTORE_CLEARS_SCHEDULE` with `SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST` (4,800)
+	gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529)
 )
 
-func gasSelfdestructEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
-	var (
-		gas     uint64
-		address = common.Address(stack.peek().Bytes20())
-	)
-	if !evm.StateDB.AddressInAccessList(address) {
-		// If the caller cannot afford the cost, this change will be rolled back
-		evm.StateDB.AddAddressToAccessList(address)
-		gas = ColdAccountAccessCostEIP2929
-	}
-	// if empty and transfers value
-	if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
-		gas += params.CreateBySelfdestructGas
-	}
-	if !evm.StateDB.HasSuicided(contract.Address()) {
-		evm.StateDB.AddRefund(params.SelfdestructRefundGas)
+// makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-2539
+func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
+	gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+		var (
+			gas     uint64
+			address = common.Address(stack.peek().Bytes20())
+		)
+		if !evm.StateDB.AddressInAccessList(address) {
+			// If the caller cannot afford the cost, this change will be rolled back
+			evm.StateDB.AddAddressToAccessList(address)
+			gas = params.ColdAccountAccessCostEIP2929
+		}
+		// if empty and transfers value
+		if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
+			gas += params.CreateBySelfdestructGas
+		}
+		if refundsEnabled && !evm.StateDB.HasSuicided(contract.Address()) {
+			evm.StateDB.AddRefund(params.SelfdestructRefundGas)
+		}
+		return gas, nil
 	}
-	return gas, nil
-
+	return gasFunc
 }
diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go
index 6c4c72eeaca5718e1b7756becdff9a60c0773ca0..dcb0974284548ba17710b96bffcfb37c66e5508c 100644
--- a/core/vm/runtime/env.go
+++ b/core/vm/runtime/env.go
@@ -35,6 +35,7 @@ func NewEnv(cfg *Config) *vm.EVM {
 		Time:        cfg.Time,
 		Difficulty:  cfg.Difficulty,
 		GasLimit:    cfg.GasLimit,
+		BaseFee:     cfg.BaseFee,
 	}
 
 	return vm.NewEVM(blockContext, txContext, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 72601441d500ed4f3fad04756d64bde8128b8f80..103ce3e175ffbec560f7fcc335aa14f2786a314b 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -43,6 +43,7 @@ type Config struct {
 	Value       *big.Int
 	Debug       bool
 	EVMConfig   vm.Config
+	BaseFee     *big.Int
 
 	State     *state.StateDB
 	GetHashFn func(n uint64) common.Hash
@@ -66,7 +67,7 @@ func setDefaults(cfg *Config) {
 			IstanbulBlock:       new(big.Int),
 			MuirGlacierBlock:    new(big.Int),
 			BerlinBlock:         new(big.Int),
-			YoloV3Block:         nil,
+			LondonBlock:         new(big.Int),
 		}
 	}
 
@@ -93,6 +94,9 @@ func setDefaults(cfg *Config) {
 			return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String())))
 		}
 	}
+	if cfg.BaseFee == nil {
+		cfg.BaseFee = big.NewInt(params.InitialBaseFee)
+	}
 }
 
 // Execute executes the code using the input as call data during the execution.
diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go
index 8f83cccad9d139e1e044313f0fbeb67a5e6b915a..fa1b199a3484a834ec5b01ca068b9a38f3d910e3 100644
--- a/crypto/secp256k1/curve.go
+++ b/crypto/secp256k1/curve.go
@@ -35,15 +35,8 @@ package secp256k1
 import (
 	"crypto/elliptic"
 	"math/big"
-	"unsafe"
 )
 
-/*
-#include "libsecp256k1/include/secp256k1.h"
-extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
-*/
-import "C"
-
 const (
 	// number of bits in a big.Word
 	wordBits = 32 << (uint64(^big.Word(0)) >> 63)
@@ -133,7 +126,18 @@ func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.
 
 // Add returns the sum of (x1,y1) and (x2,y2)
 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+	// If one point is at infinity, return the other point.
+	// Adding the point at infinity to any point will preserve the other point.
+	if x1.Sign() == 0 && y1.Sign() == 0 {
+		return x2, y2
+	}
+	if x2.Sign() == 0 && y2.Sign() == 0 {
+		return x1, y1
+	}
 	z := new(big.Int).SetInt64(1)
+	if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 {
+		return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z))
+	}
 	return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
 }
 
@@ -242,41 +246,6 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int,
 	return x3, y3, z3
 }
 
-func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
-	// Ensure scalar is exactly 32 bytes. We pad always, even if
-	// scalar is 32 bytes long, to avoid a timing side channel.
-	if len(scalar) > 32 {
-		panic("can't handle scalars > 256 bits")
-	}
-	// NOTE: potential timing issue
-	padded := make([]byte, 32)
-	copy(padded[32-len(scalar):], scalar)
-	scalar = padded
-
-	// Do the multiplication in C, updating point.
-	point := make([]byte, 64)
-	readBits(Bx, point[:32])
-	readBits(By, point[32:])
-
-	pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
-	scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
-	res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
-
-	// Unpack the result and clear temporaries.
-	x := new(big.Int).SetBytes(point[:32])
-	y := new(big.Int).SetBytes(point[32:])
-	for i := range point {
-		point[i] = 0
-	}
-	for i := range padded {
-		scalar[i] = 0
-	}
-	if res != 1 {
-		return nil, nil
-	}
-	return x, y
-}
-
 // ScalarBaseMult returns k*G, where G is the base point of the group and k is
 // an integer in big-endian form.
 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
diff --git a/crypto/secp256k1/panic_cb.go b/crypto/secp256k1/panic_cb.go
index 6d59a1d247ea0f0eedb6c5851d483f1f859a8d8e..5da2bea376e47c88b2252c33daba24465efd6088 100644
--- a/crypto/secp256k1/panic_cb.go
+++ b/crypto/secp256k1/panic_cb.go
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be found in
 // the LICENSE file.
 
+// +build !gofuzz
+// +build cgo
+
 package secp256k1
 
 import "C"
diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go
new file mode 100644
index 0000000000000000000000000000000000000000..f28a1c7826877cfa9aea7d604b58eed1eba88791
--- /dev/null
+++ b/crypto/secp256k1/scalar_mult_cgo.go
@@ -0,0 +1,57 @@
+// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+// +build !gofuzz
+// +build cgo
+
+package secp256k1
+
+import (
+	"math/big"
+	"unsafe"
+)
+
+/*
+
+#include "libsecp256k1/include/secp256k1.h"
+
+extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
+
+*/
+import "C"
+
+func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
+	// Ensure scalar is exactly 32 bytes. We pad always, even if
+	// scalar is 32 bytes long, to avoid a timing side channel.
+	if len(scalar) > 32 {
+		panic("can't handle scalars > 256 bits")
+	}
+	// NOTE: potential timing issue
+	padded := make([]byte, 32)
+	copy(padded[32-len(scalar):], scalar)
+	scalar = padded
+
+	// Do the multiplication in C, updating point.
+	point := make([]byte, 64)
+	readBits(Bx, point[:32])
+	readBits(By, point[32:])
+
+	pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
+	scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
+	res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
+
+	// Unpack the result and clear temporaries.
+	x := new(big.Int).SetBytes(point[:32])
+	y := new(big.Int).SetBytes(point[32:])
+	for i := range point {
+		point[i] = 0
+	}
+	for i := range padded {
+		scalar[i] = 0
+	}
+	if res != 1 {
+		return nil, nil
+	}
+	return x, y
+}
diff --git a/crypto/secp256k1/scalar_mult_nocgo.go b/crypto/secp256k1/scalar_mult_nocgo.go
new file mode 100644
index 0000000000000000000000000000000000000000..55756b5be84929ce830ca848b80729c37e4f9245
--- /dev/null
+++ b/crypto/secp256k1/scalar_mult_nocgo.go
@@ -0,0 +1,13 @@
+// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+// +build gofuzz !cgo
+
+package secp256k1
+
+import "math/big"
+
+func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
+	panic("ScalarMult is not available when secp256k1 is built without cgo")
+}
diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go
index 9a7c06d7ce7253f2d773b366ef21fcc762cac692..a1bcf7796e9ede68a6a7d69681ab1ab98f7f935b 100644
--- a/crypto/secp256k1/secp256.go
+++ b/crypto/secp256k1/secp256.go
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be found in
 // the LICENSE file.
 
+// +build !gofuzz
+// +build cgo
+
 // Package secp256k1 wraps the bitcoin secp256k1 C library.
 package secp256k1
 
diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go
index 1fe84509e76fd9e66f7a726e01e10f7da429b3da..84336029801053411c5e1a6f42ba46dcbe3866de 100644
--- a/crypto/signature_cgo.go
+++ b/crypto/signature_cgo.go
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-// +build !nacl,!js,cgo
+// +build !nacl,!js,cgo,!gofuzz
 
 package crypto
 
diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go
index 067d32e13ce16105153abd7b6a417237591a3207..77c8a1db0be24bcf6794ddeeb6a7089d067db0e2 100644
--- a/crypto/signature_nocgo.go
+++ b/crypto/signature_nocgo.go
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-// +build nacl js !cgo
+// +build nacl js !cgo gofuzz
 
 package crypto
 
diff --git a/eth/api.go b/eth/api.go
index 7387459c94e02fa127e860935883ee2768ac6db4..0f57128d755b417ba09d41b73abc4084411ed4a3 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -129,6 +129,12 @@ func (api *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
 	return true
 }
 
+// SetGasLimit sets the gaslimit to target towards during mining.
+func (api *PrivateMinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool {
+	api.e.Miner().SetGasCeil(uint64(gasLimit))
+	return true
+}
+
 // SetEtherbase sets the etherbase of the miner
 func (api *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool {
 	api.e.SetEtherbase(etherbase)
@@ -264,12 +270,16 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI {
 
 // DumpBlock retrieves the entire state of the database at a given block.
 func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
+	opts := &state.DumpConfig{
+		OnlyWithAddresses: true,
+		Max:               AccountRangeMaxResults, // Sanity limit over RPC
+	}
 	if blockNr == rpc.PendingBlockNumber {
 		// If we're dumping the pending state, we need to request
 		// both the pending block as well as the pending state from
 		// the miner and operate on those
 		_, stateDb := api.eth.miner.Pending()
-		return stateDb.RawDump(false, false, true), nil
+		return stateDb.RawDump(opts), nil
 	}
 	var block *types.Block
 	if blockNr == rpc.LatestBlockNumber {
@@ -284,7 +294,7 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error
 	if err != nil {
 		return state.Dump{}, err
 	}
-	return stateDb.RawDump(false, false, true), nil
+	return stateDb.RawDump(opts), nil
 }
 
 // PrivateDebugAPI is the collection of Ethereum full node APIs exposed over
@@ -332,7 +342,7 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs,
 		} else {
 			blockRlp = fmt.Sprintf("0x%x", rlpBytes)
 		}
-		if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true); err != nil {
+		if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.engine); err != nil {
 			blockJSON = map[string]interface{}{"error": err.Error()}
 		}
 		results = append(results, &BadBlockArgs{
@@ -386,10 +396,17 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta
 		return state.IteratorDump{}, errors.New("either block number or block hash must be specified")
 	}
 
+	opts := &state.DumpConfig{
+		SkipCode:          nocode,
+		SkipStorage:       nostorage,
+		OnlyWithAddresses: !incompletes,
+		Start:             start,
+		Max:               uint64(maxResults),
+	}
 	if maxResults > AccountRangeMaxResults || maxResults <= 0 {
-		maxResults = AccountRangeMaxResults
+		opts.Max = AccountRangeMaxResults
 	}
-	return stateDb.IteratorDump(nocode, nostorage, incompletes, start, maxResults), nil
+	return stateDb.IteratorDump(opts), nil
 }
 
 // StorageRangeResult is the result of a debug_storageRangeAt API call.
diff --git a/eth/api_backend.go b/eth/api_backend.go
index 7ac1f82a863ab6ee5d0c0191086d624e007836e0..49de70e21069ee92d257e3b2f7807298c0debe27 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -133,6 +133,10 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r
 	return nil, errors.New("invalid arguments; neither block nor hash specified")
 }
 
+func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
+	return b.eth.miner.PendingBlockAndReceipts()
+}
+
 func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
 	// Pending state is only known by the miner
 	if number == rpc.PendingBlockNumber {
@@ -231,7 +235,7 @@ func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
 }
 
 func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
-	pending, err := b.eth.txPool.Pending()
+	pending, err := b.eth.txPool.Pending(false)
 	if err != nil {
 		return nil, err
 	}
@@ -263,6 +267,10 @@ func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions,
 	return b.eth.TxPool().Content()
 }
 
+func (b *EthAPIBackend) TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
+	return b.eth.TxPool().ContentFrom(addr)
+}
+
 func (b *EthAPIBackend) TxPool() *core.TxPool {
 	return b.eth.TxPool()
 }
@@ -275,8 +283,12 @@ func (b *EthAPIBackend) Downloader() *downloader.Downloader {
 	return b.eth.Downloader()
 }
 
-func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
-	return b.gpo.SuggestPrice(ctx)
+func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
+	return b.gpo.SuggestTipCap(ctx)
+}
+
+func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
+	return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
 }
 
 func (b *EthAPIBackend) ChainDb() ethdb.Database {
diff --git a/eth/api_test.go b/eth/api_test.go
index b44eed40bcd240056b733d9cac603e545ef141b0..39a1d5846004c1000d6cca0158f5def8d3ab11da 100644
--- a/eth/api_test.go
+++ b/eth/api_test.go
@@ -34,7 +34,13 @@ import (
 var dumper = spew.ConfigState{Indent: "    "}
 
 func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
-	result := statedb.IteratorDump(true, true, false, start.Bytes(), requestedNum)
+	result := statedb.IteratorDump(&state.DumpConfig{
+		SkipCode:          true,
+		SkipStorage:       true,
+		OnlyWithAddresses: false,
+		Start:             start.Bytes(),
+		Max:               uint64(requestedNum),
+	})
 
 	if len(result.Accounts) != expectedNum {
 		t.Fatalf("expected %d results, got %d", expectedNum, len(result.Accounts))
@@ -131,12 +137,17 @@ func TestEmptyAccountRange(t *testing.T) {
 	t.Parallel()
 
 	var (
-		statedb  = state.NewDatabase(rawdb.NewMemoryDatabase())
-		state, _ = state.New(common.Hash{}, statedb, nil)
+		statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
+		st, _   = state.New(common.Hash{}, statedb, nil)
 	)
-	state.Commit(true)
-	state.IntermediateRoot(true)
-	results := state.IteratorDump(true, true, true, (common.Hash{}).Bytes(), AccountRangeMaxResults)
+	st.Commit(true)
+	st.IntermediateRoot(true)
+	results := st.IteratorDump(&state.DumpConfig{
+		SkipCode:          true,
+		SkipStorage:       true,
+		OnlyWithAddresses: true,
+		Max:               uint64(AccountRangeMaxResults),
+	})
 	if bytes.Equal(results.Next, (common.Hash{}).Bytes()) {
 		t.Fatalf("Empty results should not return a second page")
 	}
diff --git a/eth/backend.go b/eth/backend.go
index d8ecda58a8a763415531c9a4b9ff17d27a83a105..54b8c2e75d9f5ff1776bd525c144e6002493bff1 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -132,7 +132,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
 	if err != nil {
 		return nil, err
 	}
-	chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideBerlin)
+	chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon)
 	if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
 		return nil, genesisErr
 	}
@@ -192,8 +192,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
 	var (
 		vmConfig = vm.Config{
 			EnablePreimageRecording: config.EnablePreimageRecording,
-			EWASMInterpreter:        config.EWASMInterpreter,
-			EVMInterpreter:          config.EVMInterpreter,
 		}
 		cacheConfig = &core.CacheConfig{
 			TrieCleanLimit:      config.TrieCleanCache,
@@ -213,6 +211,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
 	}
 	eth.engine.VerifyHeader(eth.blockchain, eth.blockchain.CurrentHeader(), true) // TODO think on it
 
+	// BOR changes
+	eth.APIBackend.gpo.ProcessCache()
+	// BOR changes
+
 	// Rewind the chain in case of an incompatible config upgrade.
 	if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
 		log.Warn("Rewinding chain to upgrade configuration", "err", compat)
diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go
index d7e2af1c1a5d547f24c0039cf052ae8715c21b30..2622c4a148f6bd18da05db4ed0fd3399f7303cb2 100644
--- a/eth/catalyst/api.go
+++ b/eth/catalyst/api.go
@@ -24,6 +24,7 @@ import (
 	"time"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/consensus/misc"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
@@ -79,8 +80,10 @@ type blockExecutionEnv struct {
 
 func (env *blockExecutionEnv) commitTransaction(tx *types.Transaction, coinbase common.Address) error {
 	vmconfig := *env.chain.GetVMConfig()
+	snap := env.state.Snapshot()
 	receipt, err := core.ApplyTransaction(env.chain.Config(), env.chain, &coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, vmconfig)
 	if err != nil {
+		env.state.RevertToSnapshot(snap)
 		return err
 	}
 	env.txs = append(env.txs, tx)
@@ -125,7 +128,7 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
 		time.Sleep(wait)
 	}
 
-	pending, err := pool.Pending()
+	pending, err := pool.Pending(true)
 	if err != nil {
 		return nil, err
 	}
@@ -143,6 +146,9 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
 		Extra:      []byte{},
 		Time:       params.Timestamp,
 	}
+	if config := api.eth.BlockChain().Config(); config.IsLondon(header.Number) {
+		header.BaseFee = misc.CalcBaseFee(config, parent.Header())
+	}
 	err = api.eth.Engine().Prepare(bc, header)
 	if err != nil {
 		return nil, err
@@ -155,7 +161,7 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
 
 	var (
 		signer       = types.MakeSigner(bc.Config(), header.Number)
-		txHeap       = types.NewTransactionsByPriceAndNonce(signer, pending)
+		txHeap       = types.NewTransactionsByPriceAndNonce(signer, pending, nil)
 		transactions []*types.Transaction
 	)
 	for {
@@ -172,7 +178,7 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
 		from, _ := types.Sender(signer, tx)
 
 		// Execute the transaction
-		env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount)
+		env.state.Prepare(tx.Hash(), env.tcount)
 		err = env.commitTransaction(tx, coinbase)
 		switch err {
 		case core.ErrGasLimitReached:
@@ -244,7 +250,7 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
 	return txs, nil
 }
 
-func insertBlockParamsToBlock(params executableData) (*types.Block, error) {
+func insertBlockParamsToBlock(config *chainParams.ChainConfig, parent *types.Header, params executableData) (*types.Block, error) {
 	txs, err := decodeTransactions(params.Transactions)
 	if err != nil {
 		return nil, err
@@ -266,6 +272,9 @@ func insertBlockParamsToBlock(params executableData) (*types.Block, error) {
 		GasUsed:     params.GasUsed,
 		Time:        params.Timestamp,
 	}
+	if config.IsLondon(number) {
+		header.BaseFee = misc.CalcBaseFee(config, parent)
+	}
 	block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
 	return block, nil
 }
@@ -278,11 +287,10 @@ func (api *consensusAPI) NewBlock(params executableData) (*newBlockResponse, err
 	if parent == nil {
 		return &newBlockResponse{false}, fmt.Errorf("could not find parent %x", params.ParentHash)
 	}
-	block, err := insertBlockParamsToBlock(params)
+	block, err := insertBlockParamsToBlock(api.eth.BlockChain().Config(), parent.Header(), params)
 	if err != nil {
 		return nil, err
 	}
-
 	_, err = api.eth.BlockChain().InsertChainWithoutSealVerification(block)
 	return &newBlockResponse{err == nil}, err
 }
diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go
index b8a6e43fcd13bdbf3b3271285cb17378af21e6d6..f8550fa59b7c2a25997b8c77e384eb0f319f9320 100644
--- a/eth/catalyst/api_test.go
+++ b/eth/catalyst/api_test.go
@@ -38,7 +38,7 @@ var (
 	// testAddr is the Ethereum address of the tester account.
 	testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
 
-	testBalance = big.NewInt(2e10)
+	testBalance = big.NewInt(2e15)
 )
 
 func generateTestChain() (*core.Genesis, []*types.Block) {
@@ -49,6 +49,7 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
 		Alloc:     core.GenesisAlloc{testAddr: {Balance: testBalance}},
 		ExtraData: []byte("test genesis"),
 		Timestamp: 9000,
+		BaseFee:   big.NewInt(params.InitialBaseFee),
 	}
 	generate := func(i int, g *core.BlockGen) {
 		g.OffsetTime(5)
@@ -78,6 +79,7 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block,
 		IstanbulBlock:       big.NewInt(0),
 		MuirGlacierBlock:    big.NewInt(0),
 		BerlinBlock:         big.NewInt(0),
+		LondonBlock:         big.NewInt(0),
 		CatalystBlock:       big.NewInt(0),
 		Ethash:              new(params.EthashConfig),
 	}
@@ -86,6 +88,7 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block,
 		Alloc:     core.GenesisAlloc{testAddr: {Balance: testBalance}},
 		ExtraData: []byte("test genesis"),
 		Timestamp: 9000,
+		BaseFee:   big.NewInt(params.InitialBaseFee),
 	}
 	generate := func(i int, g *core.BlockGen) {
 		g.OffsetTime(5)
@@ -110,7 +113,7 @@ func TestEth2AssembleBlock(t *testing.T) {
 
 	api := newConsensusAPI(ethservice)
 	signer := types.NewEIP155Signer(ethservice.BlockChain().Config().ChainID)
-	tx, err := types.SignTx(types.NewTransaction(0, blocks[8].Coinbase(), big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
+	tx, err := types.SignTx(types.NewTransaction(0, blocks[8].Coinbase(), big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, testKey)
 	if err != nil {
 		t.Fatalf("error signing transaction, err=%v", err)
 	}
@@ -203,7 +206,7 @@ func TestEth2NewBlock(t *testing.T) {
 		if err != nil || !success.Valid {
 			t.Fatalf("Failed to insert forked block #%d: %v", i, err)
 		}
-		lastBlock, err = insertBlockParamsToBlock(p)
+		lastBlock, err = insertBlockParamsToBlock(ethservice.BlockChain().Config(), lastBlock.Header(), p)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index 6f59b29a5e9a405eb77233df79992322898f76c7..1767506a33e624fa0ac693340e4c7a86cfa1ad0d 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -47,16 +47,6 @@ var (
 	MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request
 	MaxStateFetch   = 384 // Amount of node state values to allow fetching per request
 
-	rttMinEstimate   = 2 * time.Second  // Minimum round-trip time to target for download requests
-	rttMaxEstimate   = 20 * time.Second // Maximum round-trip time to target for download requests
-	rttMinConfidence = 0.1              // Worse confidence factor in our estimated RTT value
-	ttlScaling       = 3                // Constant scaling factor for RTT -> TTL conversion
-	ttlLimit         = time.Minute      // Maximum TTL allowance to prevent reaching crazy timeouts
-
-	qosTuningPeers   = 5    // Number of peers to tune based on (best peers)
-	qosConfidenceCap = 10   // Number of peers above which not to modify RTT confidence
-	qosTuningImpact  = 0.25 // Impact that a new tuning target has on the previous value
-
 	maxQueuedHeaders            = 32 * 1024                         // [eth/62] Maximum number of headers to queue for import (DOS protection)
 	maxHeadersProcess           = 2048                              // Number of header download results to import at once into the chain
 	maxResultsProcess           = 2048                              // Number of content download results to import at once into the chain
@@ -96,13 +86,6 @@ var (
 )
 
 type Downloader struct {
-	// WARNING: The `rttEstimate` and `rttConfidence` fields are accessed atomically.
-	// On 32 bit platforms, only 64-bit aligned fields can be atomic. The struct is
-	// guaranteed to be so aligned, so take advantage of that. For more information,
-	// see https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
-	rttEstimate   uint64 // Round trip time to target for download requests
-	rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops)
-
 	mode uint32         // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode
 	mux  *event.TypeMux // Event multiplexer to announce sync operation events
 
@@ -232,8 +215,6 @@ func New(checkpoint uint64, stateDb ethdb.Database, stateBloom *trie.SyncBloom,
 		checkpoint:     checkpoint,
 		queue:          newQueue(blockCacheMaxItems, blockCacheInitialItems),
 		peers:          newPeerSet(),
-		rttEstimate:    uint64(rttMaxEstimate),
-		rttConfidence:  uint64(1000000),
 		blockchain:     chain,
 		lightchain:     lightchain,
 		dropPeer:       dropPeer,
@@ -252,7 +233,6 @@ func New(checkpoint uint64, stateDb ethdb.Database, stateBloom *trie.SyncBloom,
 		},
 		trackStateReq: make(chan *stateReq),
 	}
-	go dl.qosTuner()
 	go dl.stateFetcher()
 	return dl
 }
@@ -310,8 +290,6 @@ func (d *Downloader) RegisterPeer(id string, version uint, peer Peer) error {
 		logger.Error("Failed to register sync peer", "err", err)
 		return err
 	}
-	d.qosReduceConfidence()
-
 	return nil
 }
 
@@ -487,7 +465,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
 	}
 	if mode == FastSync && pivot == nil {
 		// If no pivot block was returned, the head is below the min full block
-		// threshold (i.e. new chian). In that case we won't really fast sync
+		// threshold (i.e. new chain). In that case we won't really fast sync
 		// anyway, but still need a valid pivot block to avoid some code hitting
 		// nil panics on an access.
 		pivot = d.blockchain.CurrentBlock().Header()
@@ -670,7 +648,7 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty
 	}
 	go p.peer.RequestHeadersByHash(latest, fetch, fsMinFullBlocks-1, true)
 
-	ttl := d.requestTTL()
+	ttl := d.peers.rates.TargetTimeout()
 	timeout := time.After(ttl)
 	for {
 		select {
@@ -703,7 +681,7 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty
 				return head, nil, nil
 			}
 			// At this point we have 2 headers in total and the first is the
-			// validated head of the chian. Check the pivot number and return,
+			// validated head of the chain. Check the pivot number and return,
 			pivot := headers[1]
 			if pivot.Number.Uint64() != head.Number.Uint64()-uint64(fsMinFullBlocks) {
 				return nil, nil, fmt.Errorf("%w: remote pivot %d != requested %d", errInvalidChain, pivot.Number, head.Number.Uint64()-uint64(fsMinFullBlocks))
@@ -853,7 +831,7 @@ func (d *Downloader) findAncestorSpanSearch(p *peerConnection, mode SyncMode, re
 	// Wait for the remote response to the head fetch
 	number, hash := uint64(0), common.Hash{}
 
-	ttl := d.requestTTL()
+	ttl := d.peers.rates.TargetTimeout()
 	timeout := time.After(ttl)
 
 	for finished := false; !finished; {
@@ -942,7 +920,7 @@ func (d *Downloader) findAncestorBinarySearch(p *peerConnection, mode SyncMode,
 		// Split our chain interval in two, and request the hash to cross check
 		check := (start + end) / 2
 
-		ttl := d.requestTTL()
+		ttl := d.peers.rates.TargetTimeout()
 		timeout := time.After(ttl)
 
 		go p.peer.RequestHeadersByNumber(check, 1, 0, false)
@@ -1035,7 +1013,7 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64) error {
 	getHeaders := func(from uint64) {
 		request = time.Now()
 
-		ttl = d.requestTTL()
+		ttl = d.peers.rates.TargetTimeout()
 		timeout.Reset(ttl)
 
 		if skeleton {
@@ -1050,7 +1028,7 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64) error {
 		pivoting = true
 		request = time.Now()
 
-		ttl = d.requestTTL()
+		ttl = d.peers.rates.TargetTimeout()
 		timeout.Reset(ttl)
 
 		d.pivotLock.RLock()
@@ -1262,12 +1240,12 @@ func (d *Downloader) fillHeaderSkeleton(from uint64, skeleton []*types.Header) (
 			pack := packet.(*headerPack)
 			return d.queue.DeliverHeaders(pack.peerID, pack.headers, d.headerProcCh)
 		}
-		expire  = func() map[string]int { return d.queue.ExpireHeaders(d.requestTTL()) }
+		expire  = func() map[string]int { return d.queue.ExpireHeaders(d.peers.rates.TargetTimeout()) }
 		reserve = func(p *peerConnection, count int) (*fetchRequest, bool, bool) {
 			return d.queue.ReserveHeaders(p, count), false, false
 		}
 		fetch    = func(p *peerConnection, req *fetchRequest) error { return p.FetchHeaders(req.From, MaxHeaderFetch) }
-		capacity = func(p *peerConnection) int { return p.HeaderCapacity(d.requestRTT()) }
+		capacity = func(p *peerConnection) int { return p.HeaderCapacity(d.peers.rates.TargetRoundTrip()) }
 		setIdle  = func(p *peerConnection, accepted int, deliveryTime time.Time) {
 			p.SetHeadersIdle(accepted, deliveryTime)
 		}
@@ -1293,9 +1271,9 @@ func (d *Downloader) fetchBodies(from uint64) error {
 			pack := packet.(*bodyPack)
 			return d.queue.DeliverBodies(pack.peerID, pack.transactions, pack.uncles)
 		}
-		expire   = func() map[string]int { return d.queue.ExpireBodies(d.requestTTL()) }
+		expire   = func() map[string]int { return d.queue.ExpireBodies(d.peers.rates.TargetTimeout()) }
 		fetch    = func(p *peerConnection, req *fetchRequest) error { return p.FetchBodies(req) }
-		capacity = func(p *peerConnection) int { return p.BlockCapacity(d.requestRTT()) }
+		capacity = func(p *peerConnection) int { return p.BlockCapacity(d.peers.rates.TargetRoundTrip()) }
 		setIdle  = func(p *peerConnection, accepted int, deliveryTime time.Time) { p.SetBodiesIdle(accepted, deliveryTime) }
 	)
 	err := d.fetchParts(d.bodyCh, deliver, d.bodyWakeCh, expire,
@@ -1317,9 +1295,9 @@ func (d *Downloader) fetchReceipts(from uint64) error {
 			pack := packet.(*receiptPack)
 			return d.queue.DeliverReceipts(pack.peerID, pack.receipts)
 		}
-		expire   = func() map[string]int { return d.queue.ExpireReceipts(d.requestTTL()) }
+		expire   = func() map[string]int { return d.queue.ExpireReceipts(d.peers.rates.TargetTimeout()) }
 		fetch    = func(p *peerConnection, req *fetchRequest) error { return p.FetchReceipts(req) }
-		capacity = func(p *peerConnection) int { return p.ReceiptCapacity(d.requestRTT()) }
+		capacity = func(p *peerConnection) int { return p.ReceiptCapacity(d.peers.rates.TargetRoundTrip()) }
 		setIdle  = func(p *peerConnection, accepted int, deliveryTime time.Time) {
 			p.SetReceiptsIdle(accepted, deliveryTime)
 		}
@@ -2031,78 +2009,3 @@ func (d *Downloader) deliver(destCh chan dataPack, packet dataPack, inMeter, dro
 		return errNoSyncActive
 	}
 }
-
-// qosTuner is the quality of service tuning loop that occasionally gathers the
-// peer latency statistics and updates the estimated request round trip time.
-func (d *Downloader) qosTuner() {
-	for {
-		// Retrieve the current median RTT and integrate into the previoust target RTT
-		rtt := time.Duration((1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT()))
-		atomic.StoreUint64(&d.rttEstimate, uint64(rtt))
-
-		// A new RTT cycle passed, increase our confidence in the estimated RTT
-		conf := atomic.LoadUint64(&d.rttConfidence)
-		conf = conf + (1000000-conf)/2
-		atomic.StoreUint64(&d.rttConfidence, conf)
-
-		// Log the new QoS values and sleep until the next RTT
-		log.Debug("Recalculated downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL())
-		select {
-		case <-d.quitCh:
-			return
-		case <-time.After(rtt):
-		}
-	}
-}
-
-// qosReduceConfidence is meant to be called when a new peer joins the downloader's
-// peer set, needing to reduce the confidence we have in out QoS estimates.
-func (d *Downloader) qosReduceConfidence() {
-	// If we have a single peer, confidence is always 1
-	peers := uint64(d.peers.Len())
-	if peers == 0 {
-		// Ensure peer connectivity races don't catch us off guard
-		return
-	}
-	if peers == 1 {
-		atomic.StoreUint64(&d.rttConfidence, 1000000)
-		return
-	}
-	// If we have a ton of peers, don't drop confidence)
-	if peers >= uint64(qosConfidenceCap) {
-		return
-	}
-	// Otherwise drop the confidence factor
-	conf := atomic.LoadUint64(&d.rttConfidence) * (peers - 1) / peers
-	if float64(conf)/1000000 < rttMinConfidence {
-		conf = uint64(rttMinConfidence * 1000000)
-	}
-	atomic.StoreUint64(&d.rttConfidence, conf)
-
-	rtt := time.Duration(atomic.LoadUint64(&d.rttEstimate))
-	log.Debug("Relaxed downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL())
-}
-
-// requestRTT returns the current target round trip time for a download request
-// to complete in.
-//
-// Note, the returned RTT is .9 of the actually estimated RTT. The reason is that
-// the downloader tries to adapt queries to the RTT, so multiple RTT values can
-// be adapted to, but smaller ones are preferred (stabler download stream).
-func (d *Downloader) requestRTT() time.Duration {
-	return time.Duration(atomic.LoadUint64(&d.rttEstimate)) * 9 / 10
-}
-
-// requestTTL returns the current timeout allowance for a single download request
-// to finish under.
-func (d *Downloader) requestTTL() time.Duration {
-	var (
-		rtt  = time.Duration(atomic.LoadUint64(&d.rttEstimate))
-		conf = float64(atomic.LoadUint64(&d.rttConfidence)) / 1000000.0
-	)
-	ttl := time.Duration(ttlScaling) * time.Duration(float64(rtt)/conf)
-	if ttl > ttlLimit {
-		ttl = ttlLimit
-	}
-	return ttl
-}
diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go
index b3b6cc95a0ccb10e17e98f0d5ad43aa4bdb1778c..066a366315a7628798ac8e16600c05680e205677 100644
--- a/eth/downloader/peer.go
+++ b/eth/downloader/peer.go
@@ -21,7 +21,6 @@ package downloader
 
 import (
 	"errors"
-	"math"
 	"math/big"
 	"sort"
 	"sync"
@@ -32,11 +31,11 @@ import (
 	"github.com/ethereum/go-ethereum/eth/protocols/eth"
 	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/p2p/msgrate"
 )
 
 const (
-	maxLackingHashes  = 4096 // Maximum number of entries allowed on the list or lacking items
-	measurementImpact = 0.1  // The impact a single measurement has on a peer's final throughput value.
+	maxLackingHashes = 4096 // Maximum number of entries allowed on the list or lacking items
 )
 
 var (
@@ -54,18 +53,12 @@ type peerConnection struct {
 	receiptIdle int32 // Current receipt activity state of the peer (idle = 0, active = 1)
 	stateIdle   int32 // Current node data activity state of the peer (idle = 0, active = 1)
 
-	headerThroughput  float64 // Number of headers measured to be retrievable per second
-	blockThroughput   float64 // Number of blocks (bodies) measured to be retrievable per second
-	receiptThroughput float64 // Number of receipts measured to be retrievable per second
-	stateThroughput   float64 // Number of node data pieces measured to be retrievable per second
-
-	rtt time.Duration // Request round trip time to track responsiveness (QoS)
-
 	headerStarted  time.Time // Time instance when the last header fetch was started
 	blockStarted   time.Time // Time instance when the last block (body) fetch was started
 	receiptStarted time.Time // Time instance when the last receipt fetch was started
 	stateStarted   time.Time // Time instance when the last node data fetch was started
 
+	rates   *msgrate.Tracker         // Tracker to hone in on the number of items retrievable per second
 	lacking map[common.Hash]struct{} // Set of hashes not to request (didn't have previously)
 
 	peer Peer
@@ -133,11 +126,6 @@ func (p *peerConnection) Reset() {
 	atomic.StoreInt32(&p.receiptIdle, 0)
 	atomic.StoreInt32(&p.stateIdle, 0)
 
-	p.headerThroughput = 0
-	p.blockThroughput = 0
-	p.receiptThroughput = 0
-	p.stateThroughput = 0
-
 	p.lacking = make(map[common.Hash]struct{})
 }
 
@@ -212,93 +200,72 @@ func (p *peerConnection) FetchNodeData(hashes []common.Hash) error {
 // requests. Its estimated header retrieval throughput is updated with that measured
 // just now.
 func (p *peerConnection) SetHeadersIdle(delivered int, deliveryTime time.Time) {
-	p.setIdle(deliveryTime.Sub(p.headerStarted), delivered, &p.headerThroughput, &p.headerIdle)
+	p.rates.Update(eth.BlockHeadersMsg, deliveryTime.Sub(p.headerStarted), delivered)
+	atomic.StoreInt32(&p.headerIdle, 0)
 }
 
 // SetBodiesIdle sets the peer to idle, allowing it to execute block body retrieval
 // requests. Its estimated body retrieval throughput is updated with that measured
 // just now.
 func (p *peerConnection) SetBodiesIdle(delivered int, deliveryTime time.Time) {
-	p.setIdle(deliveryTime.Sub(p.blockStarted), delivered, &p.blockThroughput, &p.blockIdle)
+	p.rates.Update(eth.BlockBodiesMsg, deliveryTime.Sub(p.blockStarted), delivered)
+	atomic.StoreInt32(&p.blockIdle, 0)
 }
 
 // SetReceiptsIdle sets the peer to idle, allowing it to execute new receipt
 // retrieval requests. Its estimated receipt retrieval throughput is updated
 // with that measured just now.
 func (p *peerConnection) SetReceiptsIdle(delivered int, deliveryTime time.Time) {
-	p.setIdle(deliveryTime.Sub(p.receiptStarted), delivered, &p.receiptThroughput, &p.receiptIdle)
+	p.rates.Update(eth.ReceiptsMsg, deliveryTime.Sub(p.receiptStarted), delivered)
+	atomic.StoreInt32(&p.receiptIdle, 0)
 }
 
 // SetNodeDataIdle sets the peer to idle, allowing it to execute new state trie
 // data retrieval requests. Its estimated state retrieval throughput is updated
 // with that measured just now.
 func (p *peerConnection) SetNodeDataIdle(delivered int, deliveryTime time.Time) {
-	p.setIdle(deliveryTime.Sub(p.stateStarted), delivered, &p.stateThroughput, &p.stateIdle)
-}
-
-// setIdle sets the peer to idle, allowing it to execute new retrieval requests.
-// Its estimated retrieval throughput is updated with that measured just now.
-func (p *peerConnection) setIdle(elapsed time.Duration, delivered int, throughput *float64, idle *int32) {
-	// Irrelevant of the scaling, make sure the peer ends up idle
-	defer atomic.StoreInt32(idle, 0)
-
-	p.lock.Lock()
-	defer p.lock.Unlock()
-
-	// If nothing was delivered (hard timeout / unavailable data), reduce throughput to minimum
-	if delivered == 0 {
-		*throughput = 0
-		return
-	}
-	// Otherwise update the throughput with a new measurement
-	if elapsed <= 0 {
-		elapsed = 1 // +1 (ns) to ensure non-zero divisor
-	}
-	measured := float64(delivered) / (float64(elapsed) / float64(time.Second))
-
-	*throughput = (1-measurementImpact)*(*throughput) + measurementImpact*measured
-	p.rtt = time.Duration((1-measurementImpact)*float64(p.rtt) + measurementImpact*float64(elapsed))
-
-	p.log.Trace("Peer throughput measurements updated",
-		"hps", p.headerThroughput, "bps", p.blockThroughput,
-		"rps", p.receiptThroughput, "sps", p.stateThroughput,
-		"miss", len(p.lacking), "rtt", p.rtt)
+	p.rates.Update(eth.NodeDataMsg, deliveryTime.Sub(p.stateStarted), delivered)
+	atomic.StoreInt32(&p.stateIdle, 0)
 }
 
 // HeaderCapacity retrieves the peers header download allowance based on its
 // previously discovered throughput.
 func (p *peerConnection) HeaderCapacity(targetRTT time.Duration) int {
-	p.lock.RLock()
-	defer p.lock.RUnlock()
-
-	return int(math.Min(1+math.Max(1, p.headerThroughput*float64(targetRTT)/float64(time.Second)), float64(MaxHeaderFetch)))
+	cap := p.rates.Capacity(eth.BlockHeadersMsg, targetRTT)
+	if cap > MaxHeaderFetch {
+		cap = MaxHeaderFetch
+	}
+	return cap
 }
 
 // BlockCapacity retrieves the peers block download allowance based on its
 // previously discovered throughput.
 func (p *peerConnection) BlockCapacity(targetRTT time.Duration) int {
-	p.lock.RLock()
-	defer p.lock.RUnlock()
-
-	return int(math.Min(1+math.Max(1, p.blockThroughput*float64(targetRTT)/float64(time.Second)), float64(MaxBlockFetch)))
+	cap := p.rates.Capacity(eth.BlockBodiesMsg, targetRTT)
+	if cap > MaxBlockFetch {
+		cap = MaxBlockFetch
+	}
+	return cap
 }
 
 // ReceiptCapacity retrieves the peers receipt download allowance based on its
 // previously discovered throughput.
 func (p *peerConnection) ReceiptCapacity(targetRTT time.Duration) int {
-	p.lock.RLock()
-	defer p.lock.RUnlock()
-
-	return int(math.Min(1+math.Max(1, p.receiptThroughput*float64(targetRTT)/float64(time.Second)), float64(MaxReceiptFetch)))
+	cap := p.rates.Capacity(eth.ReceiptsMsg, targetRTT)
+	if cap > MaxReceiptFetch {
+		cap = MaxReceiptFetch
+	}
+	return cap
 }
 
 // NodeDataCapacity retrieves the peers state download allowance based on its
 // previously discovered throughput.
 func (p *peerConnection) NodeDataCapacity(targetRTT time.Duration) int {
-	p.lock.RLock()
-	defer p.lock.RUnlock()
-
-	return int(math.Min(1+math.Max(1, p.stateThroughput*float64(targetRTT)/float64(time.Second)), float64(MaxStateFetch)))
+	cap := p.rates.Capacity(eth.NodeDataMsg, targetRTT)
+	if cap > MaxStateFetch {
+		cap = MaxStateFetch
+	}
+	return cap
 }
 
 // MarkLacking appends a new entity to the set of items (blocks, receipts, states)
@@ -330,16 +297,20 @@ func (p *peerConnection) Lacks(hash common.Hash) bool {
 // peerSet represents the collection of active peer participating in the chain
 // download procedure.
 type peerSet struct {
-	peers        map[string]*peerConnection
+	peers map[string]*peerConnection
+	rates *msgrate.Trackers // Set of rate trackers to give the sync a common beat
+
 	newPeerFeed  event.Feed
 	peerDropFeed event.Feed
-	lock         sync.RWMutex
+
+	lock sync.RWMutex
 }
 
 // newPeerSet creates a new peer set top track the active download sources.
 func newPeerSet() *peerSet {
 	return &peerSet{
 		peers: make(map[string]*peerConnection),
+		rates: msgrate.NewTrackers(log.New("proto", "eth")),
 	}
 }
 
@@ -371,30 +342,15 @@ func (ps *peerSet) Reset() {
 // average of all existing peers, to give it a realistic chance of being used
 // for data retrievals.
 func (ps *peerSet) Register(p *peerConnection) error {
-	// Retrieve the current median RTT as a sane default
-	p.rtt = ps.medianRTT()
-
 	// Register the new peer with some meaningful defaults
 	ps.lock.Lock()
 	if _, ok := ps.peers[p.id]; ok {
 		ps.lock.Unlock()
 		return errAlreadyRegistered
 	}
-	if len(ps.peers) > 0 {
-		p.headerThroughput, p.blockThroughput, p.receiptThroughput, p.stateThroughput = 0, 0, 0, 0
-
-		for _, peer := range ps.peers {
-			peer.lock.RLock()
-			p.headerThroughput += peer.headerThroughput
-			p.blockThroughput += peer.blockThroughput
-			p.receiptThroughput += peer.receiptThroughput
-			p.stateThroughput += peer.stateThroughput
-			peer.lock.RUnlock()
-		}
-		p.headerThroughput /= float64(len(ps.peers))
-		p.blockThroughput /= float64(len(ps.peers))
-		p.receiptThroughput /= float64(len(ps.peers))
-		p.stateThroughput /= float64(len(ps.peers))
+	p.rates = msgrate.NewTracker(ps.rates.MeanCapacities(), ps.rates.MedianRoundTrip())
+	if err := ps.rates.Track(p.id, p.rates); err != nil {
+		return err
 	}
 	ps.peers[p.id] = p
 	ps.lock.Unlock()
@@ -413,6 +369,7 @@ func (ps *peerSet) Unregister(id string) error {
 		return errNotRegistered
 	}
 	delete(ps.peers, id)
+	ps.rates.Untrack(id)
 	ps.lock.Unlock()
 
 	ps.peerDropFeed.Send(p)
@@ -453,10 +410,8 @@ func (ps *peerSet) HeaderIdlePeers() ([]*peerConnection, int) {
 	idle := func(p *peerConnection) bool {
 		return atomic.LoadInt32(&p.headerIdle) == 0
 	}
-	throughput := func(p *peerConnection) float64 {
-		p.lock.RLock()
-		defer p.lock.RUnlock()
-		return p.headerThroughput
+	throughput := func(p *peerConnection) int {
+		return p.rates.Capacity(eth.BlockHeadersMsg, time.Second)
 	}
 	return ps.idlePeers(eth.ETH65, eth.ETH66, idle, throughput)
 }
@@ -467,10 +422,8 @@ func (ps *peerSet) BodyIdlePeers() ([]*peerConnection, int) {
 	idle := func(p *peerConnection) bool {
 		return atomic.LoadInt32(&p.blockIdle) == 0
 	}
-	throughput := func(p *peerConnection) float64 {
-		p.lock.RLock()
-		defer p.lock.RUnlock()
-		return p.blockThroughput
+	throughput := func(p *peerConnection) int {
+		return p.rates.Capacity(eth.BlockBodiesMsg, time.Second)
 	}
 	return ps.idlePeers(eth.ETH65, eth.ETH66, idle, throughput)
 }
@@ -481,10 +434,8 @@ func (ps *peerSet) ReceiptIdlePeers() ([]*peerConnection, int) {
 	idle := func(p *peerConnection) bool {
 		return atomic.LoadInt32(&p.receiptIdle) == 0
 	}
-	throughput := func(p *peerConnection) float64 {
-		p.lock.RLock()
-		defer p.lock.RUnlock()
-		return p.receiptThroughput
+	throughput := func(p *peerConnection) int {
+		return p.rates.Capacity(eth.ReceiptsMsg, time.Second)
 	}
 	return ps.idlePeers(eth.ETH65, eth.ETH66, idle, throughput)
 }
@@ -495,86 +446,56 @@ func (ps *peerSet) NodeDataIdlePeers() ([]*peerConnection, int) {
 	idle := func(p *peerConnection) bool {
 		return atomic.LoadInt32(&p.stateIdle) == 0
 	}
-	throughput := func(p *peerConnection) float64 {
-		p.lock.RLock()
-		defer p.lock.RUnlock()
-		return p.stateThroughput
+	throughput := func(p *peerConnection) int {
+		return p.rates.Capacity(eth.NodeDataMsg, time.Second)
 	}
 	return ps.idlePeers(eth.ETH65, eth.ETH66, idle, throughput)
 }
 
 // idlePeers retrieves a flat list of all currently idle peers satisfying the
 // protocol version constraints, using the provided function to check idleness.
-// The resulting set of peers are sorted by their measure throughput.
-func (ps *peerSet) idlePeers(minProtocol, maxProtocol uint, idleCheck func(*peerConnection) bool, throughput func(*peerConnection) float64) ([]*peerConnection, int) {
+// The resulting set of peers are sorted by their capacity.
+func (ps *peerSet) idlePeers(minProtocol, maxProtocol uint, idleCheck func(*peerConnection) bool, capacity func(*peerConnection) int) ([]*peerConnection, int) {
 	ps.lock.RLock()
 	defer ps.lock.RUnlock()
 
-	idle, total := make([]*peerConnection, 0, len(ps.peers)), 0
-	tps := make([]float64, 0, len(ps.peers))
+	var (
+		total = 0
+		idle  = make([]*peerConnection, 0, len(ps.peers))
+		tps   = make([]int, 0, len(ps.peers))
+	)
 	for _, p := range ps.peers {
 		if p.version >= minProtocol && p.version <= maxProtocol {
 			if idleCheck(p) {
 				idle = append(idle, p)
-				tps = append(tps, throughput(p))
+				tps = append(tps, capacity(p))
 			}
 			total++
 		}
 	}
+
 	// And sort them
-	sortPeers := &peerThroughputSort{idle, tps}
+	sortPeers := &peerCapacitySort{idle, tps}
 	sort.Sort(sortPeers)
 	return sortPeers.p, total
 }
 
-// medianRTT returns the median RTT of the peerset, considering only the tuning
-// peers if there are more peers available.
-func (ps *peerSet) medianRTT() time.Duration {
-	// Gather all the currently measured round trip times
-	ps.lock.RLock()
-	defer ps.lock.RUnlock()
-
-	rtts := make([]float64, 0, len(ps.peers))
-	for _, p := range ps.peers {
-		p.lock.RLock()
-		rtts = append(rtts, float64(p.rtt))
-		p.lock.RUnlock()
-	}
-	sort.Float64s(rtts)
-
-	median := rttMaxEstimate
-	if qosTuningPeers <= len(rtts) {
-		median = time.Duration(rtts[qosTuningPeers/2]) // Median of our tuning peers
-	} else if len(rtts) > 0 {
-		median = time.Duration(rtts[len(rtts)/2]) // Median of our connected peers (maintain even like this some baseline qos)
-	}
-	// Restrict the RTT into some QoS defaults, irrelevant of true RTT
-	if median < rttMinEstimate {
-		median = rttMinEstimate
-	}
-	if median > rttMaxEstimate {
-		median = rttMaxEstimate
-	}
-	return median
-}
-
-// peerThroughputSort implements the Sort interface, and allows for
-// sorting a set of peers by their throughput
-// The sorted data is with the _highest_ throughput first
-type peerThroughputSort struct {
+// peerCapacitySort implements sort.Interface.
+// It sorts peer connections by capacity (descending).
+type peerCapacitySort struct {
 	p  []*peerConnection
-	tp []float64
+	tp []int
 }
 
-func (ps *peerThroughputSort) Len() int {
+func (ps *peerCapacitySort) Len() int {
 	return len(ps.p)
 }
 
-func (ps *peerThroughputSort) Less(i, j int) bool {
+func (ps *peerCapacitySort) Less(i, j int) bool {
 	return ps.tp[i] > ps.tp[j]
 }
 
-func (ps *peerThroughputSort) Swap(i, j int) {
+func (ps *peerCapacitySort) Swap(i, j int) {
 	ps.p[i], ps.p[j] = ps.p[j], ps.p[i]
 	ps.tp[i], ps.tp[j] = ps.tp[j], ps.tp[i]
 }
diff --git a/eth/downloader/peer_test.go b/eth/downloader/peer_test.go
deleted file mode 100644
index 4bf0e200bb12a3361e018b21064d0cd0518f0108..0000000000000000000000000000000000000000
--- a/eth/downloader/peer_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-package downloader
-
-import (
-	"sort"
-	"testing"
-)
-
-func TestPeerThroughputSorting(t *testing.T) {
-	a := &peerConnection{
-		id:               "a",
-		headerThroughput: 1.25,
-	}
-	b := &peerConnection{
-		id:               "b",
-		headerThroughput: 1.21,
-	}
-	c := &peerConnection{
-		id:               "c",
-		headerThroughput: 1.23,
-	}
-
-	peers := []*peerConnection{a, b, c}
-	tps := []float64{a.headerThroughput,
-		b.headerThroughput, c.headerThroughput}
-	sortPeers := &peerThroughputSort{peers, tps}
-	sort.Sort(sortPeers)
-	if got, exp := sortPeers.p[0].id, "a"; got != exp {
-		t.Errorf("sort fail, got %v exp %v", got, exp)
-	}
-	if got, exp := sortPeers.p[1].id, "c"; got != exp {
-		t.Errorf("sort fail, got %v exp %v", got, exp)
-	}
-	if got, exp := sortPeers.p[2].id, "b"; got != exp {
-		t.Errorf("sort fail, got %v exp %v", got, exp)
-	}
-
-}
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
index ac7edc2c68a7b484f6832fd7a91d1038440084b2..04ec12cfa9e7cef851c1dacaa223846bc7e8379e 100644
--- a/eth/downloader/queue.go
+++ b/eth/downloader/queue.go
@@ -40,10 +40,10 @@ const (
 )
 
 var (
-	blockCacheMaxItems     = 8192             // Maximum number of blocks to cache before throttling the download
-	blockCacheInitialItems = 2048             // Initial number of blocks to start fetching, before we know the sizes of the blocks
-	blockCacheMemory       = 64 * 1024 * 1024 // Maximum amount of memory to use for block caching
-	blockCacheSizeWeight   = 0.1              // Multiplier to approximate the average block size based on past ones
+	blockCacheMaxItems     = 8192              // Maximum number of blocks to cache before throttling the download
+	blockCacheInitialItems = 2048              // Initial number of blocks to start fetching, before we know the sizes of the blocks
+	blockCacheMemory       = 256 * 1024 * 1024 // Maximum amount of memory to use for block caching
+	blockCacheSizeWeight   = 0.1               // Multiplier to approximate the average block size based on past ones
 )
 
 var (
@@ -783,8 +783,9 @@ func (q *queue) DeliverHeaders(id string, headers []*types.Header, headerProcCh
 func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, uncleLists [][]*types.Header) (int, error) {
 	q.lock.Lock()
 	defer q.lock.Unlock()
+	trieHasher := trie.NewStackTrie(nil)
 	validate := func(index int, header *types.Header) error {
-		if types.DeriveSha(types.Transactions(txLists[index]), trie.NewStackTrie(nil)) != header.TxHash {
+		if types.DeriveSha(types.Transactions(txLists[index]), trieHasher) != header.TxHash {
 			return errInvalidBody
 		}
 		if types.CalcUncleHash(uncleLists[index]) != header.UncleHash {
@@ -808,8 +809,9 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, uncleLi
 func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt) (int, error) {
 	q.lock.Lock()
 	defer q.lock.Unlock()
+	trieHasher := trie.NewStackTrie(nil)
 	validate := func(index int, header *types.Header) error {
-		if types.DeriveSha(types.Receipts(receiptList[index]), trie.NewStackTrie(nil)) != header.ReceiptHash {
+		if types.DeriveSha(types.Receipts(receiptList[index]), trieHasher) != header.ReceiptHash {
 			return errInvalidReceipt
 		}
 		return nil
diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go
index f43ad67a4184a35c7d54fc2d786c51c86f7efed9..cde5f306a2c07a83ef3ff86c24f33f11d0aea595 100644
--- a/eth/downloader/queue_test.go
+++ b/eth/downloader/queue_test.go
@@ -35,7 +35,7 @@ import (
 
 var (
 	testdb  = rawdb.NewMemoryDatabase()
-	genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
+	genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000000000))
 )
 
 // makeChain creates a chain of n blocks starting at and including parent.
@@ -48,7 +48,7 @@ func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Bloc
 		// Add one tx to every secondblock
 		if !empty && i%2 == 0 {
 			signer := types.MakeSigner(params.TestChainConfig, block.Number())
-			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
+			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
 			if err != nil {
 				panic(err)
 			}
diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go
index ff84a3a8f015073030964df11afaff6a9862d464..6c53e5577a87bcb727f12f204ee19f9a75841a3b 100644
--- a/eth/downloader/statesync.go
+++ b/eth/downloader/statesync.go
@@ -433,8 +433,8 @@ func (s *stateSync) assignTasks() {
 	peers, _ := s.d.peers.NodeDataIdlePeers()
 	for _, p := range peers {
 		// Assign a batch of fetches proportional to the estimated latency/bandwidth
-		cap := p.NodeDataCapacity(s.d.requestRTT())
-		req := &stateReq{peer: p, timeout: s.d.requestTTL()}
+		cap := p.NodeDataCapacity(s.d.peers.rates.TargetRoundTrip())
+		req := &stateReq{peer: p, timeout: s.d.peers.rates.TargetTimeout()}
 
 		nodes, _, codes := s.fillTasks(cap, req)
 
diff --git a/eth/downloader/testchain_test.go b/eth/downloader/testchain_test.go
index 2d7b4d1f1035ba21ab63bda8397fad1c4f0678aa..b9865f7e032b324c7066600223f8dfa567c4af22 100644
--- a/eth/downloader/testchain_test.go
+++ b/eth/downloader/testchain_test.go
@@ -35,7 +35,7 @@ var (
 	testKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
 	testDB      = rawdb.NewMemoryDatabase()
-	testGenesis = core.GenesisBlockForTesting(testDB, testAddress, big.NewInt(1000000000))
+	testGenesis = core.GenesisBlockForTesting(testDB, testAddress, big.NewInt(1000000000000000))
 )
 
 // The common prefix of all test chains:
@@ -127,7 +127,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool)
 		// Include transactions to the miner to make blocks more interesting.
 		if parent == tc.genesis && i%22 == 0 {
 			signer := types.MakeSigner(params.TestChainConfig, block.Number())
-			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
+			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
 			if err != nil {
 				panic(err)
 			}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index a17f28c14fdf12ca2a56ba7208d58e6ef5c2f79a..8a34f731335927226a104dfd1ea62f213f042a1b 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -43,21 +43,27 @@ import (
 
 // FullNodeGPO contains default gasprice oracle settings for full node.
 var FullNodeGPO = gasprice.Config{
-	Blocks:     20,
-	Percentile: 60,
-	MaxPrice:   gasprice.DefaultMaxPrice,
+	Blocks:           20,
+	Percentile:       60,
+	MaxHeaderHistory: 1024,
+	MaxBlockHistory:  1024,
+	MaxPrice:         gasprice.DefaultMaxPrice,
+	IgnorePrice:      gasprice.DefaultIgnorePrice,
 }
 
 // LightClientGPO contains default gasprice oracle settings for light client.
 var LightClientGPO = gasprice.Config{
-	Blocks:     2,
-	Percentile: 60,
-	MaxPrice:   gasprice.DefaultMaxPrice,
+	Blocks:           2,
+	Percentile:       60,
+	MaxHeaderHistory: 300,
+	MaxBlockHistory:  5,
+	MaxPrice:         gasprice.DefaultMaxPrice,
+	IgnorePrice:      gasprice.DefaultIgnorePrice,
 }
 
 // Defaults contains default settings for use on the Ethereum main net.
 var Defaults = Config{
-	SyncMode: downloader.FastSync,
+	SyncMode: downloader.SnapSync,
 	Ethash: ethash.Config{
 		CacheDir:         "ethash",
 		CachesInMem:      2,
@@ -79,13 +85,12 @@ var Defaults = Config{
 	TrieTimeout:             60 * time.Minute,
 	SnapshotCache:           102,
 	Miner: miner.Config{
-		GasFloor: 8000000,
 		GasCeil:  8000000,
 		GasPrice: big.NewInt(params.GWei),
 		Recommit: 3 * time.Second,
 	},
 	TxPool:      core.DefaultTxPoolConfig,
-	RPCGasCap:   25000000,
+	RPCGasCap:   50000000,
 	GPO:         FullNodeGPO,
 	RPCTxFeeCap: 1, // 1 ether
 }
@@ -182,12 +187,6 @@ type Config struct {
 	// Miscellaneous options
 	DocRoot string `toml:"-"`
 
-	// Type of the EWASM interpreter ("" for default)
-	EWASMInterpreter string
-
-	// Type of the EVM interpreter ("" for default)
-	EVMInterpreter string
-
 	// RPCGasCap is the global gas cap for eth-call variants.
 	RPCGasCap uint64
 
@@ -209,6 +208,7 @@ type Config struct {
 
 	// Berlin block override (TODO: remove after the fork)
 	OverrideBerlin *big.Int `toml:",omitempty"`
+	OverrideLondon *big.Int `toml:",omitempty"`
 
 	// Bor logs flag
 	BorLogs bool
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
index ca93b2ad00c6246066da4ff0b9f44865d940d9cf..2310dd44997b612b17d646410365edd3393cbfbc 100644
--- a/eth/ethconfig/gen_config.go
+++ b/eth/ethconfig/gen_config.go
@@ -3,6 +3,7 @@
 package ethconfig
 
 import (
+	"math/big"
 	"time"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -53,12 +54,11 @@ func (c Config) MarshalTOML() (interface{}, error) {
 		GPO                     gasprice.Config
 		EnablePreimageRecording bool
 		DocRoot                 string `toml:"-"`
-		EWASMInterpreter        string
-		EVMInterpreter          string
-		RPCGasCap               uint64                         `toml:",omitempty"`
-		RPCTxFeeCap             float64                        `toml:",omitempty"`
+		RPCGasCap               uint64
+		RPCTxFeeCap             float64
 		Checkpoint              *params.TrustedCheckpoint      `toml:",omitempty"`
 		CheckpointOracle        *params.CheckpointOracleConfig `toml:",omitempty"`
+		OverrideLondon          *big.Int                       `toml:",omitempty"`
 	}
 	var enc Config
 	enc.Genesis = c.Genesis
@@ -97,12 +97,11 @@ func (c Config) MarshalTOML() (interface{}, error) {
 	enc.GPO = c.GPO
 	enc.EnablePreimageRecording = c.EnablePreimageRecording
 	enc.DocRoot = c.DocRoot
-	enc.EWASMInterpreter = c.EWASMInterpreter
-	enc.EVMInterpreter = c.EVMInterpreter
 	enc.RPCGasCap = c.RPCGasCap
 	enc.RPCTxFeeCap = c.RPCTxFeeCap
 	enc.Checkpoint = c.Checkpoint
 	enc.CheckpointOracle = c.CheckpointOracle
+	enc.OverrideLondon = c.OverrideLondon
 	return &enc, nil
 }
 
@@ -145,12 +144,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
 		GPO                     *gasprice.Config
 		EnablePreimageRecording *bool
 		DocRoot                 *string `toml:"-"`
-		EWASMInterpreter        *string
-		EVMInterpreter          *string
-		RPCGasCap               *uint64                        `toml:",omitempty"`
-		RPCTxFeeCap             *float64                       `toml:",omitempty"`
+		RPCGasCap               *uint64
+		RPCTxFeeCap             *float64
 		Checkpoint              *params.TrustedCheckpoint      `toml:",omitempty"`
 		CheckpointOracle        *params.CheckpointOracleConfig `toml:",omitempty"`
+		OverrideLondon          *big.Int                       `toml:",omitempty"`
 	}
 	var dec Config
 	if err := unmarshal(&dec); err != nil {
@@ -264,12 +262,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
 	if dec.DocRoot != nil {
 		c.DocRoot = *dec.DocRoot
 	}
-	if dec.EWASMInterpreter != nil {
-		c.EWASMInterpreter = *dec.EWASMInterpreter
-	}
-	if dec.EVMInterpreter != nil {
-		c.EVMInterpreter = *dec.EVMInterpreter
-	}
 	if dec.RPCGasCap != nil {
 		c.RPCGasCap = *dec.RPCGasCap
 	}
@@ -282,5 +274,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
 	if dec.CheckpointOracle != nil {
 		c.CheckpointOracle = dec.CheckpointOracle
 	}
+	if dec.OverrideLondon != nil {
+		c.OverrideLondon = dec.OverrideLondon
+	}
 	return nil
 }
diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go
index 3177a877edf3f5e1e538d4794637d52b9fcf3ea0..45983c97ce6474582ca0aea46f43493dd8bcfef2 100644
--- a/eth/fetcher/block_fetcher.go
+++ b/eth/fetcher/block_fetcher.go
@@ -833,15 +833,17 @@ func (f *BlockFetcher) importBlocks(peer string, block *types.Block) {
 // internal state.
 func (f *BlockFetcher) forgetHash(hash common.Hash) {
 	// Remove all pending announces and decrement DOS counters
-	for _, announce := range f.announced[hash] {
-		f.announces[announce.origin]--
-		if f.announces[announce.origin] <= 0 {
-			delete(f.announces, announce.origin)
+	if announceMap, ok := f.announced[hash]; ok {
+		for _, announce := range announceMap {
+			f.announces[announce.origin]--
+			if f.announces[announce.origin] <= 0 {
+				delete(f.announces, announce.origin)
+			}
+		}
+		delete(f.announced, hash)
+		if f.announceChangeHook != nil {
+			f.announceChangeHook(hash, false)
 		}
-	}
-	delete(f.announced, hash)
-	if f.announceChangeHook != nil {
-		f.announceChangeHook(hash, false)
 	}
 	// Remove any pending fetches and decrement the DOS counters
 	if announce := f.fetching[hash]; announce != nil {
diff --git a/eth/fetcher/block_fetcher_test.go b/eth/fetcher/block_fetcher_test.go
index a6eef71da0380ae792131fb9b9aa4a14d8395ace..b6d1125b565375284cc681175fc4fde7fa6f4f7d 100644
--- a/eth/fetcher/block_fetcher_test.go
+++ b/eth/fetcher/block_fetcher_test.go
@@ -38,8 +38,8 @@ var (
 	testdb       = rawdb.NewMemoryDatabase()
 	testKey, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	testAddress  = crypto.PubkeyToAddress(testKey.PublicKey)
-	genesis      = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
-	unknownBlock = types.NewBlock(&types.Header{GasLimit: params.GenesisGasLimit}, nil, nil, nil, trie.NewStackTrie(nil))
+	genesis      = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000000000))
+	unknownBlock = types.NewBlock(&types.Header{GasLimit: params.GenesisGasLimit, BaseFee: big.NewInt(params.InitialBaseFee)}, nil, nil, nil, trie.NewStackTrie(nil))
 )
 
 // makeChain creates a chain of n blocks starting at and including parent.
@@ -53,7 +53,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
 		// If the block number is multiple of 3, send a bonus transaction to the miner
 		if parent == genesis && i%3 == 0 {
 			signer := types.MakeSigner(params.TestChainConfig, block.Number())
-			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
+			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
 			if err != nil {
 				panic(err)
 			}
@@ -698,6 +698,7 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
 	badBodyFetcher := tester.makeBodyFetcher("bad", blocks, 0)
 
 	imported := make(chan interface{})
+	announced := make(chan interface{})
 	tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
 		if light {
 			if header == nil {
@@ -712,9 +713,23 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
 		}
 	}
 	// Announce a block with a bad number, check for immediate drop
+	tester.fetcher.announceChangeHook = func(hash common.Hash, b bool) {
+		announced <- nil
+	}
 	tester.fetcher.Notify("bad", hashes[0], 2, time.Now().Add(-arriveTimeout), badHeaderFetcher, badBodyFetcher)
+	verifyAnnounce := func() {
+		for i := 0; i < 2; i++ {
+			select {
+			case <-announced:
+				continue
+			case <-time.After(1 * time.Second):
+				t.Fatal("announce timeout")
+				return
+			}
+		}
+	}
+	verifyAnnounce()
 	verifyImportEvent(t, imported, false)
-
 	tester.lock.RLock()
 	dropped := tester.drops["bad"]
 	tester.lock.RUnlock()
@@ -722,11 +737,11 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
 	if !dropped {
 		t.Fatalf("peer with invalid numbered announcement not dropped")
 	}
-
 	goodHeaderFetcher := tester.makeHeaderFetcher("good", blocks, -gatherSlack)
 	goodBodyFetcher := tester.makeBodyFetcher("good", blocks, 0)
 	// Make sure a good announcement passes without a drop
 	tester.fetcher.Notify("good", hashes[0], 1, time.Now().Add(-arriveTimeout), goodHeaderFetcher, goodBodyFetcher)
+	verifyAnnounce()
 	verifyImportEvent(t, imported, true)
 
 	tester.lock.RLock()
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
index 898f25246be0fa615a0cb60bd3881751812380e0..fa2c21306d7bc6afb635f79ed28becec14a36834 100644
--- a/eth/filters/filter_system_test.go
+++ b/eth/filters/filter_system_test.go
@@ -175,7 +175,7 @@ func TestBlockSubscription(t *testing.T) {
 		db          = rawdb.NewMemoryDatabase()
 		backend     = &testBackend{db: db}
 		api         = NewPublicFilterAPI(backend, false, deadline)
-		genesis     = new(core.Genesis).MustCommit(db)
+		genesis     = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
 		chain, _    = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
 		chainEvents = []core.ChainEvent{}
 	)
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
index 3fc77bbc4dc55dce0727817581adff180960ee16..fd25013cc65517090835c446a527a00e8ceb786b 100644
--- a/eth/filters/filter_test.go
+++ b/eth/filters/filter_test.go
@@ -127,7 +127,7 @@ func TestFilters(t *testing.T) {
 				},
 			}
 			gen.AddUncheckedReceipt(receipt)
-			gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil))
+			gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, gen.BaseFee(), nil))
 		case 2:
 			receipt := types.NewReceipt(nil, false, 0)
 			receipt.Logs = []*types.Log{
@@ -137,7 +137,7 @@ func TestFilters(t *testing.T) {
 				},
 			}
 			gen.AddUncheckedReceipt(receipt)
-			gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil))
+			gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, gen.BaseFee(), nil))
 
 		case 998:
 			receipt := types.NewReceipt(nil, false, 0)
@@ -148,7 +148,7 @@ func TestFilters(t *testing.T) {
 				},
 			}
 			gen.AddUncheckedReceipt(receipt)
-			gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil))
+			gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, gen.BaseFee(), nil))
 		case 999:
 			receipt := types.NewReceipt(nil, false, 0)
 			receipt.Logs = []*types.Log{
@@ -158,7 +158,7 @@ func TestFilters(t *testing.T) {
 				},
 			}
 			gen.AddUncheckedReceipt(receipt)
-			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, big.NewInt(999), nil))
+			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
 		}
 	})
 	for i, block := range chain {
diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go
new file mode 100644
index 0000000000000000000000000000000000000000..970dfd4467a579973e13102fd2ba9025bb9d6405
--- /dev/null
+++ b/eth/gasprice/feehistory.go
@@ -0,0 +1,310 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package gasprice
+
+import (
+	"context"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"math"
+	"math/big"
+	"sort"
+	"sync/atomic"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/consensus/misc"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/rpc"
+)
+
+var (
+	errInvalidPercentile = errors.New("invalid reward percentile")
+	errRequestBeyondHead = errors.New("request beyond head block")
+)
+
+const (
+	// maxBlockFetchers is the max number of goroutines to spin up to pull blocks
+	// for the fee history calculation (mostly relevant for LES).
+	maxBlockFetchers = 4
+)
+
+// blockFees represents a single block for processing
+type blockFees struct {
+	// set by the caller
+	blockNumber uint64
+	header      *types.Header
+	block       *types.Block // only set if reward percentiles are requested
+	receipts    types.Receipts
+	// filled by processBlock
+	results processedFees
+	err     error
+}
+
+// processedFees contains the results of a processed block and is also used for caching
+type processedFees struct {
+	reward               []*big.Int
+	baseFee, nextBaseFee *big.Int
+	gasUsedRatio         float64
+}
+
+// txGasAndReward is sorted in ascending order based on reward
+type (
+	txGasAndReward struct {
+		gasUsed uint64
+		reward  *big.Int
+	}
+	sortGasAndReward []txGasAndReward
+)
+
+func (s sortGasAndReward) Len() int { return len(s) }
+func (s sortGasAndReward) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+func (s sortGasAndReward) Less(i, j int) bool {
+	return s[i].reward.Cmp(s[j].reward) < 0
+}
+
+// processBlock takes a blockFees structure with the blockNumber, the header and optionally
+// the block field filled in, retrieves the block from the backend if not present yet and
+// fills in the rest of the fields.
+func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
+	chainconfig := oracle.backend.ChainConfig()
+	if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
+		bf.results.baseFee = new(big.Int)
+	}
+	if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
+		bf.results.nextBaseFee = misc.CalcBaseFee(chainconfig, bf.header)
+	} else {
+		bf.results.nextBaseFee = new(big.Int)
+	}
+	bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
+	if len(percentiles) == 0 {
+		// rewards were not requested, return null
+		return
+	}
+	if bf.block == nil || (bf.receipts == nil && len(bf.block.Transactions()) != 0) {
+		log.Error("Block or receipts are missing while reward percentiles are requested")
+		return
+	}
+
+	bf.results.reward = make([]*big.Int, len(percentiles))
+	if len(bf.block.Transactions()) == 0 {
+		// return an all zero row if there are no transactions to gather data from
+		for i := range bf.results.reward {
+			bf.results.reward[i] = new(big.Int)
+		}
+		return
+	}
+
+	sorter := make(sortGasAndReward, len(bf.block.Transactions()))
+	for i, tx := range bf.block.Transactions() {
+		reward, _ := tx.EffectiveGasTip(bf.block.BaseFee())
+		sorter[i] = txGasAndReward{gasUsed: bf.receipts[i].GasUsed, reward: reward}
+	}
+	sort.Sort(sorter)
+
+	var txIndex int
+	sumGasUsed := sorter[0].gasUsed
+
+	for i, p := range percentiles {
+		thresholdGasUsed := uint64(float64(bf.block.GasUsed()) * p / 100)
+		for sumGasUsed < thresholdGasUsed && txIndex < len(bf.block.Transactions())-1 {
+			txIndex++
+			sumGasUsed += sorter[txIndex].gasUsed
+		}
+		bf.results.reward[i] = sorter[txIndex].reward
+	}
+}
+
+// resolveBlockRange resolves the specified block range to absolute block numbers while also
+// enforcing backend specific limitations. The pending block and corresponding receipts are
+// also returned if requested and available.
+// Note: an error is only returned if retrieving the head header has failed. If there are no
+// retrievable blocks in the specified range then zero block count is returned with no error.
+func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) {
+	var (
+		headBlock       rpc.BlockNumber
+		pendingBlock    *types.Block
+		pendingReceipts types.Receipts
+	)
+	// query either pending block or head header and set headBlock
+	if lastBlock == rpc.PendingBlockNumber {
+		if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil {
+			lastBlock = rpc.BlockNumber(pendingBlock.NumberU64())
+			headBlock = lastBlock - 1
+		} else {
+			// pending block not supported by backend, process until latest block
+			lastBlock = rpc.LatestBlockNumber
+			blocks--
+			if blocks == 0 {
+				return nil, nil, 0, 0, nil
+			}
+		}
+	}
+	if pendingBlock == nil {
+		// if pending block is not fetched then we retrieve the head header to get the head block number
+		if latestHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err == nil {
+			headBlock = rpc.BlockNumber(latestHeader.Number.Uint64())
+		} else {
+			return nil, nil, 0, 0, err
+		}
+	}
+	if lastBlock == rpc.LatestBlockNumber {
+		lastBlock = headBlock
+	} else if pendingBlock == nil && lastBlock > headBlock {
+		return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
+	}
+	// ensure not trying to retrieve before genesis
+	if rpc.BlockNumber(blocks) > lastBlock+1 {
+		blocks = int(lastBlock + 1)
+	}
+	return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, nil
+}
+
+// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
+// The range can be specified either with absolute block numbers or ending with the latest
+// or pending block. Backends may or may not support gathering data from the pending block
+// or blocks older than a certain age (specified in maxHistory). The first block of the
+// actually processed range is returned to avoid ambiguity when parts of the requested range
+// are not available or when the head has changed during processing this request.
+// Three arrays are returned based on the processed blocks:
+// - reward: the requested percentiles of effective priority fees per gas of transactions in each
+//   block, sorted in ascending order and weighted by gas used.
+// - baseFee: base fee per gas in the given block
+// - gasUsedRatio: gasUsed/gasLimit in the given block
+// Note: baseFee includes the next block after the newest of the returned range, because this
+// value can be derived from the newest block.
+func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
+	if blocks < 1 {
+		return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks
+	}
+	maxFeeHistory := oracle.maxHeaderHistory
+	if len(rewardPercentiles) != 0 {
+		maxFeeHistory = oracle.maxBlockHistory
+	}
+	if blocks > maxFeeHistory {
+		log.Warn("Sanitizing fee history length", "requested", blocks, "truncated", maxFeeHistory)
+		blocks = maxFeeHistory
+	}
+	for i, p := range rewardPercentiles {
+		if p < 0 || p > 100 {
+			return common.Big0, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p)
+		}
+		if i > 0 && p < rewardPercentiles[i-1] {
+			return common.Big0, nil, nil, nil, fmt.Errorf("%w: #%d:%f > #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p)
+		}
+	}
+	var (
+		pendingBlock    *types.Block
+		pendingReceipts []*types.Receipt
+		err             error
+	)
+	pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
+	if err != nil || blocks == 0 {
+		return common.Big0, nil, nil, nil, err
+	}
+	oldestBlock := lastBlock + 1 - uint64(blocks)
+
+	var (
+		next    = oldestBlock
+		results = make(chan *blockFees, blocks)
+	)
+	percentileKey := make([]byte, 8*len(rewardPercentiles))
+	for i, p := range rewardPercentiles {
+		binary.LittleEndian.PutUint64(percentileKey[i*8:(i+1)*8], math.Float64bits(p))
+	}
+	for i := 0; i < maxBlockFetchers && i < blocks; i++ {
+		go func() {
+			for {
+				// Retrieve the next block number to fetch with this goroutine
+				blockNumber := atomic.AddUint64(&next, 1) - 1
+				if blockNumber > lastBlock {
+					return
+				}
+
+				fees := &blockFees{blockNumber: blockNumber}
+				if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() {
+					fees.block, fees.receipts = pendingBlock, pendingReceipts
+					fees.header = fees.block.Header()
+					oracle.processBlock(fees, rewardPercentiles)
+					results <- fees
+				} else {
+					cacheKey := struct {
+						number      uint64
+						percentiles string
+					}{blockNumber, string(percentileKey)}
+
+					if p, ok := oracle.historyCache.Get(cacheKey); ok {
+						fees.results = p.(processedFees)
+						results <- fees
+					} else {
+						if len(rewardPercentiles) != 0 {
+							fees.block, fees.err = oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNumber))
+							if fees.block != nil && fees.err == nil {
+								fees.receipts, fees.err = oracle.backend.GetReceipts(ctx, fees.block.Hash())
+								fees.header = fees.block.Header()
+							}
+						} else {
+							fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
+						}
+						if fees.header != nil && fees.err == nil {
+							oracle.processBlock(fees, rewardPercentiles)
+							if fees.err == nil {
+								oracle.historyCache.Add(cacheKey, fees.results)
+							}
+						}
+						// send to results even if empty to guarantee that blocks items are sent in total
+						results <- fees
+					}
+				}
+			}
+		}()
+	}
+	var (
+		reward       = make([][]*big.Int, blocks)
+		baseFee      = make([]*big.Int, blocks+1)
+		gasUsedRatio = make([]float64, blocks)
+		firstMissing = blocks
+	)
+	for ; blocks > 0; blocks-- {
+		fees := <-results
+		if fees.err != nil {
+			return common.Big0, nil, nil, nil, fees.err
+		}
+		i := int(fees.blockNumber - oldestBlock)
+		if fees.results.baseFee != nil {
+			reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio
+		} else {
+			// getting no block and no error means we are requesting into the future (might happen because of a reorg)
+			if i < firstMissing {
+				firstMissing = i
+			}
+		}
+	}
+	if firstMissing == 0 {
+		return common.Big0, nil, nil, nil, nil
+	}
+	if len(rewardPercentiles) != 0 {
+		reward = reward[:firstMissing]
+	} else {
+		reward = nil
+	}
+	baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing]
+	return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, nil
+}
diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c259eb0acf7626410b8138cb54d6b47bcb20e6e0
--- /dev/null
+++ b/eth/gasprice/feehistory_test.go
@@ -0,0 +1,89 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package gasprice
+
+import (
+	"context"
+	"errors"
+	"math/big"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/rpc"
+)
+
+func TestFeeHistory(t *testing.T) {
+	var cases = []struct {
+		pending             bool
+		maxHeader, maxBlock int
+		count               int
+		last                rpc.BlockNumber
+		percent             []float64
+		expFirst            uint64
+		expCount            int
+		expErr              error
+	}{
+		{false, 1000, 1000, 10, 30, nil, 21, 10, nil},
+		{false, 1000, 1000, 10, 30, []float64{0, 10}, 21, 10, nil},
+		{false, 1000, 1000, 10, 30, []float64{20, 10}, 0, 0, errInvalidPercentile},
+		{false, 1000, 1000, 1000000000, 30, nil, 0, 31, nil},
+		{false, 1000, 1000, 1000000000, rpc.LatestBlockNumber, nil, 0, 33, nil},
+		{false, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
+		{true, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
+		{false, 20, 2, 100, rpc.LatestBlockNumber, nil, 13, 20, nil},
+		{false, 20, 2, 100, rpc.LatestBlockNumber, []float64{0, 10}, 31, 2, nil},
+		{false, 20, 2, 100, 32, []float64{0, 10}, 31, 2, nil},
+		{false, 1000, 1000, 1, rpc.PendingBlockNumber, nil, 0, 0, nil},
+		{false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
+		{true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
+		{true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
+	}
+	for i, c := range cases {
+		config := Config{
+			MaxHeaderHistory: c.maxHeader,
+			MaxBlockHistory:  c.maxBlock,
+		}
+		backend := newTestBackend(t, big.NewInt(16), c.pending)
+		oracle := NewOracle(backend, config)
+
+		first, reward, baseFee, ratio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent)
+
+		expReward := c.expCount
+		if len(c.percent) == 0 {
+			expReward = 0
+		}
+		expBaseFee := c.expCount
+		if expBaseFee != 0 {
+			expBaseFee++
+		}
+
+		if first.Uint64() != c.expFirst {
+			t.Fatalf("Test case %d: first block mismatch, want %d, got %d", i, c.expFirst, first)
+		}
+		if len(reward) != expReward {
+			t.Fatalf("Test case %d: reward array length mismatch, want %d, got %d", i, expReward, len(reward))
+		}
+		if len(baseFee) != expBaseFee {
+			t.Fatalf("Test case %d: baseFee array length mismatch, want %d, got %d", i, expBaseFee, len(baseFee))
+		}
+		if len(ratio) != c.expCount {
+			t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio))
+		}
+		if err != c.expErr && !errors.Is(err, c.expErr) {
+			t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err)
+		}
+	}
+}
diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go
index 560722bec09f91645510d5fd2768416ed499e160..0fa6c295913bdd45064b8a5770e9d1f4b59975e7 100644
--- a/eth/gasprice/gasprice.go
+++ b/eth/gasprice/gasprice.go
@@ -23,42 +23,56 @@ import (
 	"sync"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/params"
 	"github.com/ethereum/go-ethereum/rpc"
+	lru "github.com/hashicorp/golang-lru"
 )
 
 const sampleNumber = 3 // Number of transactions sampled in a block
 
-var DefaultMaxPrice = big.NewInt(500 * params.GWei)
+var (
+	DefaultMaxPrice    = big.NewInt(500 * params.GWei)
+	DefaultIgnorePrice = big.NewInt(2 * params.Wei)
+)
 
 type Config struct {
-	Blocks     int
-	Percentile int
-	Default    *big.Int `toml:",omitempty"`
-	MaxPrice   *big.Int `toml:",omitempty"`
+	Blocks           int
+	Percentile       int
+	MaxHeaderHistory int
+	MaxBlockHistory  int
+	Default          *big.Int `toml:",omitempty"`
+	MaxPrice         *big.Int `toml:",omitempty"`
+	IgnorePrice      *big.Int `toml:",omitempty"`
 }
 
 // OracleBackend includes all necessary background APIs for oracle.
 type OracleBackend interface {
 	HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
 	BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
+	GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
+	PendingBlockAndReceipts() (*types.Block, types.Receipts)
 	ChainConfig() *params.ChainConfig
+	SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
 }
 
 // Oracle recommends gas prices based on the content of recent
 // blocks. Suitable for both light and full clients.
 type Oracle struct {
-	backend   OracleBackend
-	lastHead  common.Hash
-	lastPrice *big.Int
-	maxPrice  *big.Int
-	cacheLock sync.RWMutex
-	fetchLock sync.Mutex
-
-	checkBlocks int
-	percentile  int
+	backend     OracleBackend
+	lastHead    common.Hash
+	lastPrice   *big.Int
+	maxPrice    *big.Int
+	ignorePrice *big.Int
+	cacheLock   sync.RWMutex
+	fetchLock   sync.Mutex
+
+	checkBlocks, percentile           int
+	maxHeaderHistory, maxBlockHistory int
+	historyCache                      *lru.Cache
 }
 
 // NewOracle returns a new gasprice oracle which can recommend suitable
@@ -83,47 +97,79 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
 		maxPrice = DefaultMaxPrice
 		log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice)
 	}
+	ignorePrice := params.IgnorePrice
+	if ignorePrice == nil || ignorePrice.Int64() <= 0 {
+		ignorePrice = DefaultIgnorePrice
+		log.Warn("Sanitizing invalid gasprice oracle ignore price", "provided", params.IgnorePrice, "updated", ignorePrice)
+	} else if ignorePrice.Int64() > 0 {
+		log.Info("Gasprice oracle is ignoring threshold set", "threshold", ignorePrice)
+	}
+
+	cache, _ := lru.New(2048)
+
 	return &Oracle{
-		backend:     backend,
-		lastPrice:   params.Default,
-		maxPrice:    maxPrice,
-		checkBlocks: blocks,
-		percentile:  percent,
+		backend:          backend,
+		lastPrice:        params.Default,
+		maxPrice:         maxPrice,
+		ignorePrice:      ignorePrice,
+		checkBlocks:      blocks,
+		percentile:       percent,
+		maxHeaderHistory: params.MaxHeaderHistory,
+		maxBlockHistory:  params.MaxBlockHistory,
+		historyCache:     cache,
 	}
 }
 
-// SuggestPrice returns a gasprice so that newly created transaction can
-// have a very high chance to be included in the following blocks.
-func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
-	head, _ := gpo.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
+func (oracle *Oracle) ProcessCache() {
+	headEvent := make(chan core.ChainHeadEvent, 1)
+	oracle.backend.SubscribeChainHeadEvent(headEvent)
+	go func() {
+		var lastHead common.Hash
+		for ev := range headEvent {
+			if ev.Block.ParentHash() != lastHead {
+				oracle.historyCache.Purge()
+			}
+			lastHead = ev.Block.Hash()
+		}
+	}()
+}
+
+// SuggestTipCap returns a tip cap so that newly created transaction can have a
+// very high chance to be included in the following blocks.
+//
+// Note, for legacy transactions and the legacy eth_gasPrice RPC call, it will be
+// necessary to add the basefee to the returned number to fall back to the legacy
+// behavior.
+func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
+	head, _ := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
 	headHash := head.Hash()
 
 	// If the latest gasprice is still available, return it.
-	gpo.cacheLock.RLock()
-	lastHead, lastPrice := gpo.lastHead, gpo.lastPrice
-	gpo.cacheLock.RUnlock()
+	oracle.cacheLock.RLock()
+	lastHead, lastPrice := oracle.lastHead, oracle.lastPrice
+	oracle.cacheLock.RUnlock()
 	if headHash == lastHead {
-		return lastPrice, nil
+		return new(big.Int).Set(lastPrice), nil
 	}
-	gpo.fetchLock.Lock()
-	defer gpo.fetchLock.Unlock()
+	oracle.fetchLock.Lock()
+	defer oracle.fetchLock.Unlock()
 
 	// Try checking the cache again, maybe the last fetch fetched what we need
-	gpo.cacheLock.RLock()
-	lastHead, lastPrice = gpo.lastHead, gpo.lastPrice
-	gpo.cacheLock.RUnlock()
+	oracle.cacheLock.RLock()
+	lastHead, lastPrice = oracle.lastHead, oracle.lastPrice
+	oracle.cacheLock.RUnlock()
 	if headHash == lastHead {
-		return lastPrice, nil
+		return new(big.Int).Set(lastPrice), nil
 	}
 	var (
 		sent, exp int
 		number    = head.Number.Uint64()
-		result    = make(chan getBlockPricesResult, gpo.checkBlocks)
+		result    = make(chan results, oracle.checkBlocks)
 		quit      = make(chan struct{})
-		txPrices  []*big.Int
+		results   []*big.Int
 	)
-	for sent < gpo.checkBlocks && number > 0 {
-		go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit)
+	for sent < oracle.checkBlocks && number > 0 {
+		go oracle.getBlockValues(ctx, types.MakeSigner(oracle.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, oracle.ignorePrice, result, quit)
 		sent++
 		exp++
 		number--
@@ -132,86 +178,107 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
 		res := <-result
 		if res.err != nil {
 			close(quit)
-			return lastPrice, res.err
+			return new(big.Int).Set(lastPrice), res.err
 		}
 		exp--
 		// Nothing returned. There are two special cases here:
 		// - The block is empty
 		// - All the transactions included are sent by the miner itself.
-		// In these cases, use the latest calculated price for samping.
-		if len(res.prices) == 0 {
-			res.prices = []*big.Int{lastPrice}
+		// In these cases, use the latest calculated price for sampling.
+		if len(res.values) == 0 {
+			res.values = []*big.Int{lastPrice}
 		}
 		// Besides, in order to collect enough data for sampling, if nothing
 		// meaningful returned, try to query more blocks. But the maximum
 		// is 2*checkBlocks.
-		if len(res.prices) == 1 && len(txPrices)+1+exp < gpo.checkBlocks*2 && number > 0 {
-			go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit)
+		if len(res.values) == 1 && len(results)+1+exp < oracle.checkBlocks*2 && number > 0 {
+			go oracle.getBlockValues(ctx, types.MakeSigner(oracle.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, oracle.ignorePrice, result, quit)
 			sent++
 			exp++
 			number--
 		}
-		txPrices = append(txPrices, res.prices...)
+		results = append(results, res.values...)
 	}
 	price := lastPrice
-	if len(txPrices) > 0 {
-		sort.Sort(bigIntArray(txPrices))
-		price = txPrices[(len(txPrices)-1)*gpo.percentile/100]
-	}
-	if price.Cmp(gpo.maxPrice) > 0 {
-		price = new(big.Int).Set(gpo.maxPrice)
-	}
-	gpo.cacheLock.Lock()
-	gpo.lastHead = headHash
-	gpo.lastPrice = price
-	gpo.cacheLock.Unlock()
-	return price, nil
+	if len(results) > 0 {
+		sort.Sort(bigIntArray(results))
+		price = results[(len(results)-1)*oracle.percentile/100]
+	}
+	if price.Cmp(oracle.maxPrice) > 0 {
+		price = new(big.Int).Set(oracle.maxPrice)
+	}
+	oracle.cacheLock.Lock()
+	oracle.lastHead = headHash
+	oracle.lastPrice = price
+	oracle.cacheLock.Unlock()
+
+	return new(big.Int).Set(price), nil
 }
 
-type getBlockPricesResult struct {
-	prices []*big.Int
+type results struct {
+	values []*big.Int
 	err    error
 }
 
-type transactionsByGasPrice []*types.Transaction
+type txSorter struct {
+	txs     []*types.Transaction
+	baseFee *big.Int
+}
 
-func (t transactionsByGasPrice) Len() int           { return len(t) }
-func (t transactionsByGasPrice) Swap(i, j int)      { t[i], t[j] = t[j], t[i] }
-func (t transactionsByGasPrice) Less(i, j int) bool { return t[i].GasPriceCmp(t[j]) < 0 }
+func newSorter(txs []*types.Transaction, baseFee *big.Int) *txSorter {
+	return &txSorter{
+		txs:     txs,
+		baseFee: baseFee,
+	}
+}
+
+func (s *txSorter) Len() int { return len(s.txs) }
+func (s *txSorter) Swap(i, j int) {
+	s.txs[i], s.txs[j] = s.txs[j], s.txs[i]
+}
+func (s *txSorter) Less(i, j int) bool {
+	// It's okay to discard the error because a tx would never be
+	// accepted into a block with an invalid effective tip.
+	tip1, _ := s.txs[i].EffectiveGasTip(s.baseFee)
+	tip2, _ := s.txs[j].EffectiveGasTip(s.baseFee)
+	return tip1.Cmp(tip2) < 0
+}
 
 // getBlockPrices calculates the lowest transaction gas price in a given block
 // and sends it to the result channel. If the block is empty or all transactions
 // are sent by the miner itself(it doesn't make any sense to include this kind of
 // transaction prices for sampling), nil gasprice is returned.
-func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, result chan getBlockPricesResult, quit chan struct{}) {
-	block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
+func (oracle *Oracle) getBlockValues(ctx context.Context, signer types.Signer, blockNum uint64, limit int, ignoreUnder *big.Int, result chan results, quit chan struct{}) {
+	block, err := oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
 	if block == nil {
 		select {
-		case result <- getBlockPricesResult{nil, err}:
+		case result <- results{nil, err}:
 		case <-quit:
 		}
 		return
 	}
-	blockTxs := block.Transactions()
-	txs := make([]*types.Transaction, len(blockTxs))
-	copy(txs, blockTxs)
-	sort.Sort(transactionsByGasPrice(txs))
+	// Sort the transaction by effective tip in ascending sort.
+	txs := make([]*types.Transaction, len(block.Transactions()))
+	copy(txs, block.Transactions())
+	sorter := newSorter(txs, block.BaseFee())
+	sort.Sort(sorter)
 
 	var prices []*big.Int
-	for _, tx := range txs {
-		if tx.GasPriceIntCmp(common.Big1) <= 0 {
+	for _, tx := range sorter.txs {
+		tip, _ := tx.EffectiveGasTip(block.BaseFee())
+		if ignoreUnder != nil && tip.Cmp(ignoreUnder) == -1 {
 			continue
 		}
 		sender, err := types.Sender(signer, tx)
 		if err == nil && sender != block.Coinbase() {
-			prices = append(prices, tx.GasPrice())
+			prices = append(prices, tip)
 			if len(prices) >= limit {
 				break
 			}
 		}
 	}
 	select {
-	case result <- getBlockPricesResult{prices, nil}:
+	case result <- results{prices, nil}:
 	case <-quit:
 	}
 }
diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go
index 4fd2df10e2bd0bae974a6d506bd0c59b394d578e..feecfddec73080dca379ef6a0425ffe1f7de31ce 100644
--- a/eth/gasprice/gasprice_test.go
+++ b/eth/gasprice/gasprice_test.go
@@ -29,33 +29,73 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/params"
 	"github.com/ethereum/go-ethereum/rpc"
 )
 
+const testHead = 32
+
 type testBackend struct {
-	chain *core.BlockChain
+	chain   *core.BlockChain
+	pending bool // pending block available
 }
 
 func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
+	if number > testHead {
+		return nil, nil
+	}
 	if number == rpc.LatestBlockNumber {
-		return b.chain.CurrentBlock().Header(), nil
+		number = testHead
+	}
+	if number == rpc.PendingBlockNumber {
+		if b.pending {
+			number = testHead + 1
+		} else {
+			return nil, nil
+		}
 	}
 	return b.chain.GetHeaderByNumber(uint64(number)), nil
 }
 
 func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
+	if number > testHead {
+		return nil, nil
+	}
 	if number == rpc.LatestBlockNumber {
-		return b.chain.CurrentBlock(), nil
+		number = testHead
+	}
+	if number == rpc.PendingBlockNumber {
+		if b.pending {
+			number = testHead + 1
+		} else {
+			return nil, nil
+		}
 	}
 	return b.chain.GetBlockByNumber(uint64(number)), nil
 }
 
+func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
+	return b.chain.GetReceiptsByHash(hash), nil
+}
+
+func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
+	if b.pending {
+		block := b.chain.GetBlockByNumber(testHead + 1)
+		return block, b.chain.GetReceiptsByHash(block.Hash())
+	}
+	return nil, nil
+}
+
 func (b *testBackend) ChainConfig() *params.ChainConfig {
 	return b.chain.Config()
 }
 
-func newTestBackend(t *testing.T) *testBackend {
+func (b *testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
+	return nil
+}
+
+func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
 	var (
 		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		addr   = crypto.PubkeyToAddress(key.PublicKey)
@@ -65,14 +105,44 @@ func newTestBackend(t *testing.T) *testBackend {
 		}
 		signer = types.LatestSigner(gspec.Config)
 	)
+	if londonBlock != nil {
+		gspec.Config.LondonBlock = londonBlock
+		signer = types.LatestSigner(gspec.Config)
+	} else {
+		gspec.Config.LondonBlock = nil
+	}
 	engine := ethash.NewFaker()
 	db := rawdb.NewMemoryDatabase()
 	genesis, _ := gspec.Commit(db)
 
 	// Generate testing blocks
-	blocks, _ := core.GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *core.BlockGen) {
+	blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) {
 		b.SetCoinbase(common.Address{1})
-		tx, err := types.SignTx(types.NewTransaction(b.TxNonce(addr), common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
+
+		var tx *types.Transaction
+		if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
+			txdata := &types.DynamicFeeTx{
+				ChainID:   gspec.Config.ChainID,
+				Nonce:     b.TxNonce(addr),
+				To:        &common.Address{},
+				Gas:       30000,
+				GasFeeCap: big.NewInt(100 * params.GWei),
+				GasTipCap: big.NewInt(int64(i+1) * params.GWei),
+				Data:      []byte{},
+			}
+			tx = types.NewTx(txdata)
+		} else {
+			txdata := &types.LegacyTx{
+				Nonce:    b.TxNonce(addr),
+				To:       &common.Address{},
+				Gas:      21000,
+				GasPrice: big.NewInt(int64(i+1) * params.GWei),
+				Value:    big.NewInt(100),
+				Data:     []byte{},
+			}
+			tx = types.NewTx(txdata)
+		}
+		tx, err := types.SignTx(tx, signer, key)
 		if err != nil {
 			t.Fatalf("failed to create tx: %v", err)
 		}
@@ -81,12 +151,12 @@ func newTestBackend(t *testing.T) *testBackend {
 	// Construct testing chain
 	diskdb := rawdb.NewMemoryDatabase()
 	gspec.Commit(diskdb)
-	chain, err := core.NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
+	chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
 	if err != nil {
 		t.Fatalf("Failed to create local chain, %v", err)
 	}
 	chain.InsertChain(blocks)
-	return &testBackend{chain: chain}
+	return &testBackend{chain: chain, pending: pending}
 }
 
 func (b *testBackend) CurrentHeader() *types.Header {
@@ -97,22 +167,33 @@ func (b *testBackend) GetBlockByNumber(number uint64) *types.Block {
 	return b.chain.GetBlockByNumber(number)
 }
 
-func TestSuggestPrice(t *testing.T) {
+func TestSuggestTipCap(t *testing.T) {
 	config := Config{
 		Blocks:     3,
 		Percentile: 60,
 		Default:    big.NewInt(params.GWei),
 	}
-	backend := newTestBackend(t)
-	oracle := NewOracle(backend, config)
-
-	// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
-	got, err := oracle.SuggestPrice(context.Background())
-	if err != nil {
-		t.Fatalf("Failed to retrieve recommended gas price: %v", err)
+	var cases = []struct {
+		fork   *big.Int // London fork number
+		expect *big.Int // Expected gasprice suggestion
+	}{
+		{nil, big.NewInt(params.GWei * int64(30))},
+		{big.NewInt(0), big.NewInt(params.GWei * int64(30))},  // Fork point in genesis
+		{big.NewInt(1), big.NewInt(params.GWei * int64(30))},  // Fork point in first block
+		{big.NewInt(32), big.NewInt(params.GWei * int64(30))}, // Fork point in last block
+		{big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
 	}
-	expect := big.NewInt(params.GWei * int64(30))
-	if got.Cmp(expect) != 0 {
-		t.Fatalf("Gas price mismatch, want %d, got %d", expect, got)
+	for _, c := range cases {
+		backend := newTestBackend(t, c.fork, false)
+		oracle := NewOracle(backend, config)
+
+		// The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
+		got, err := oracle.SuggestTipCap(context.Background())
+		if err != nil {
+			t.Fatalf("Failed to retrieve recommended gas price: %v", err)
+		}
+		if got.Cmp(c.expect) != 0 {
+			t.Fatalf("Gas price mismatch, want %d, got %d", c.expect, got)
+		}
 	}
 }
diff --git a/eth/handler.go b/eth/handler.go
index 3f10750abf5e596b7151e368317c7fb271707aba..aff4871afa42683033f300bcf19eaef374645e4e 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -66,7 +66,7 @@ type txPool interface {
 
 	// Pending should return pending transactions.
 	// The slice should be modifiable by the caller.
-	Pending() (map[common.Address]types.Transactions, error)
+	Pending(enforceTips bool) (map[common.Address]types.Transactions, error)
 
 	// SubscribeNewTxsEvent should return an event subscription of
 	// NewTxsEvent and send events to the given channel.
@@ -287,7 +287,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
 		peer.Log().Error("Ethereum peer registration failed", "err", err)
 		return err
 	}
-	defer h.removePeer(peer.ID())
+	defer h.unregisterPeer(peer.ID())
 
 	p := h.peers.peer(peer.ID())
 	if p == nil {
@@ -354,9 +354,16 @@ func (h *handler) runSnapExtension(peer *snap.Peer, handler snap.Handler) error
 	return handler(peer)
 }
 
-// removePeer unregisters a peer from the downloader and fetchers, removes it from
-// the set of tracked peers and closes the network connection to it.
+// removePeer requests disconnection of a peer.
 func (h *handler) removePeer(id string) {
+	peer := h.peers.peer(id)
+	if peer != nil {
+		peer.Peer.Disconnect(p2p.DiscUselessPeer)
+	}
+}
+
+// unregisterPeer removes a peer from the downloader, fetchers and main peer set.
+func (h *handler) unregisterPeer(id string) {
 	// Create a custom logger to avoid printing the entire id
 	var logger log.Logger
 	if len(id) < 16 {
@@ -384,8 +391,6 @@ func (h *handler) removePeer(id string) {
 	if err := h.peers.unregisterPeer(id); err != nil {
 		logger.Error("Ethereum peer removal failed", "err", err)
 	}
-	// Hard disconnect at the networking layer
-	peer.Peer.Disconnect(p2p.DiscUselessPeer)
 }
 
 func (h *handler) Start(maxPeers int) {
diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go
index 1d38e3b66663fa55c28fa97d838160af7ad2a12c..038de469908ecf5d17cc822beed64cf5be30470f 100644
--- a/eth/handler_eth_test.go
+++ b/eth/handler_eth_test.go
@@ -144,8 +144,8 @@ func testForkIDSplit(t *testing.T, protocol uint) {
 	defer p2pNoFork.Close()
 	defer p2pProFork.Close()
 
-	peerNoFork := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pNoFork, nil)
-	peerProFork := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil)
+	peerNoFork := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pNoFork), p2pNoFork, nil)
+	peerProFork := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pProFork), p2pProFork, nil)
 	defer peerNoFork.Close()
 	defer peerProFork.Close()
 
@@ -206,8 +206,8 @@ func testForkIDSplit(t *testing.T, protocol uint) {
 	defer p2pNoFork.Close()
 	defer p2pProFork.Close()
 
-	peerNoFork = eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pNoFork, nil)
-	peerProFork = eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil)
+	peerNoFork = eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pNoFork), p2pNoFork, nil)
+	peerProFork = eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pProFork), p2pProFork, nil)
 	defer peerNoFork.Close()
 	defer peerProFork.Close()
 
@@ -257,8 +257,8 @@ func testRecvTransactions(t *testing.T, protocol uint) {
 	defer p2pSrc.Close()
 	defer p2pSink.Close()
 
-	src := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pSrc, handler.txpool)
-	sink := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pSink, handler.txpool)
+	src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool)
+	sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool)
 	defer src.Close()
 	defer sink.Close()
 
@@ -319,8 +319,8 @@ func testSendTransactions(t *testing.T, protocol uint) {
 	defer p2pSrc.Close()
 	defer p2pSink.Close()
 
-	src := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pSrc, handler.txpool)
-	sink := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pSink, handler.txpool)
+	src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool)
+	sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool)
 	defer src.Close()
 	defer sink.Close()
 
@@ -407,8 +407,8 @@ func testTransactionPropagation(t *testing.T, protocol uint) {
 		defer sourcePipe.Close()
 		defer sinkPipe.Close()
 
-		sourcePeer := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{byte(i)}, "", nil), sourcePipe, source.txpool)
-		sinkPeer := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{0}, "", nil), sinkPipe, sink.txpool)
+		sourcePeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{byte(i)}, "", nil, sourcePipe), sourcePipe, source.txpool)
+		sinkPeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{0}, "", nil, sinkPipe), sinkPipe, sink.txpool)
 		defer sourcePeer.Close()
 		defer sinkPeer.Close()
 
@@ -490,6 +490,8 @@ func TestCheckpointChallenge(t *testing.T) {
 }
 
 func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpoint bool, timeout bool, empty bool, match bool, drop bool) {
+	t.Parallel()
+
 	// Reduce the checkpoint handshake challenge timeout
 	defer func(old time.Duration) { syncChallengeTimeout = old }(syncChallengeTimeout)
 	syncChallengeTimeout = 250 * time.Millisecond
@@ -513,20 +515,26 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo
 		handler.handler.checkpointNumber = number
 		handler.handler.checkpointHash = response.Hash()
 	}
-	// Create a challenger peer and a challenged one
+
+	// Create a challenger peer and a challenged one.
 	p2pLocal, p2pRemote := p2p.MsgPipe()
 	defer p2pLocal.Close()
 	defer p2pRemote.Close()
 
-	local := eth.NewPeer(eth.ETH65, p2p.NewPeer(enode.ID{1}, "", nil), p2pLocal, handler.txpool)
-	remote := eth.NewPeer(eth.ETH65, p2p.NewPeer(enode.ID{2}, "", nil), p2pRemote, handler.txpool)
+	local := eth.NewPeer(eth.ETH65, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pLocal), p2pLocal, handler.txpool)
+	remote := eth.NewPeer(eth.ETH65, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pRemote), p2pRemote, handler.txpool)
 	defer local.Close()
 	defer remote.Close()
 
-	go handler.handler.runEthPeer(local, func(peer *eth.Peer) error {
-		return eth.Handle((*ethHandler)(handler.handler), peer)
-	})
-	// Run the handshake locally to avoid spinning up a remote handler
+	handlerDone := make(chan struct{})
+	go func() {
+		defer close(handlerDone)
+		handler.handler.runEthPeer(local, func(peer *eth.Peer) error {
+			return eth.Handle((*ethHandler)(handler.handler), peer)
+		})
+	}()
+
+	// Run the handshake locally to avoid spinning up a remote handler.
 	var (
 		genesis = handler.chain.Genesis()
 		head    = handler.chain.CurrentBlock()
@@ -535,12 +543,13 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo
 	if err := remote.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil {
 		t.Fatalf("failed to run protocol handshake")
 	}
-	// Connect a new peer and check that we receive the checkpoint challenge
+
+	// Connect a new peer and check that we receive the checkpoint challenge.
 	if checkpoint {
 		if err := remote.ExpectRequestHeadersByNumber(response.Number.Uint64(), 1, 0, false); err != nil {
 			t.Fatalf("challenge mismatch: %v", err)
 		}
-		// Create a block to reply to the challenge if no timeout is simulated
+		// Create a block to reply to the challenge if no timeout is simulated.
 		if !timeout {
 			if empty {
 				if err := remote.SendBlockHeaders([]*types.Header{}); err != nil {
@@ -557,11 +566,13 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo
 			}
 		}
 	}
+
 	// Wait until the test timeout passes to ensure proper cleanup
 	time.Sleep(syncChallengeTimeout + 300*time.Millisecond)
 
-	// Verify that the remote peer is maintained or dropped
+	// Verify that the remote peer is maintained or dropped.
 	if drop {
+		<-handlerDone
 		if peers := handler.handler.peers.len(); peers != 0 {
 			t.Fatalf("peer count mismatch: have %d, want %d", peers, 0)
 		}
@@ -608,8 +619,8 @@ func testBroadcastBlock(t *testing.T, peers, bcasts int) {
 		defer sourcePipe.Close()
 		defer sinkPipe.Close()
 
-		sourcePeer := eth.NewPeer(eth.ETH65, p2p.NewPeer(enode.ID{byte(i)}, "", nil), sourcePipe, nil)
-		sinkPeer := eth.NewPeer(eth.ETH65, p2p.NewPeer(enode.ID{0}, "", nil), sinkPipe, nil)
+		sourcePeer := eth.NewPeer(eth.ETH65, p2p.NewPeerPipe(enode.ID{byte(i)}, "", nil, sourcePipe), sourcePipe, nil)
+		sinkPeer := eth.NewPeer(eth.ETH65, p2p.NewPeerPipe(enode.ID{0}, "", nil, sinkPipe), sinkPipe, nil)
 		defer sourcePeer.Close()
 		defer sinkPeer.Close()
 
@@ -676,8 +687,8 @@ func testBroadcastMalformedBlock(t *testing.T, protocol uint) {
 	defer p2pSrc.Close()
 	defer p2pSink.Close()
 
-	src := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pSrc, source.txpool)
-	sink := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pSink, source.txpool)
+	src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, source.txpool)
+	sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, source.txpool)
 	defer src.Close()
 	defer sink.Close()
 
diff --git a/eth/handler_test.go b/eth/handler_test.go
index a90ef5c348aa4af2efaa00cc91dedfd3f8d52858..090bd9239c2e227f0e7564b2b6cf0197ff530870 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -91,7 +91,7 @@ func (p *testTxPool) AddRemotes(txs []*types.Transaction) []error {
 }
 
 // Pending returns all the transactions known to the pool
-func (p *testTxPool) Pending() (map[common.Address]types.Transactions, error) {
+func (p *testTxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) {
 	p.lock.RLock()
 	defer p.lock.RUnlock()
 
diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go
index 2dd2446e3d2784ed745acbbe1e900d8e89385b09..473be3f9b77e53732b6bf4e555efc396aaa19053 100644
--- a/eth/protocols/eth/handler_test.go
+++ b/eth/protocols/eth/handler_test.go
@@ -66,7 +66,7 @@ func newTestBackendWithGenerator(blocks int, generator func(int, *core.BlockGen)
 	db := rawdb.NewMemoryDatabase()
 	(&core.Genesis{
 		Config: params.TestChainConfig,
-		Alloc:  core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}},
+		Alloc:  core.GenesisAlloc{testAddr: {Balance: big.NewInt(100_000_000_000_000_000)}},
 	}).MustCommit(db)
 
 	chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
@@ -408,13 +408,13 @@ func testGetNodeData(t *testing.T, protocol uint) {
 		switch i {
 		case 0:
 			// In block 1, the test bank sends account #1 some ether.
-			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testKey)
+			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
 			block.AddTx(tx)
 		case 1:
 			// In block 2, the test bank sends some more ether to account #1.
 			// acc1Addr passes it on to account #2.
-			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
-			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
+			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
+			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, acc1Key)
 			block.AddTx(tx1)
 			block.AddTx(tx2)
 		case 2:
@@ -524,13 +524,13 @@ func testGetBlockReceipts(t *testing.T, protocol uint) {
 		switch i {
 		case 0:
 			// In block 1, the test bank sends account #1 some ether.
-			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testKey)
+			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
 			block.AddTx(tx)
 		case 1:
 			// In block 2, the test bank sends some more ether to account #1.
 			// acc1Addr passes it on to account #2.
-			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
-			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
+			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
+			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, acc1Key)
 			block.AddTx(tx1)
 			block.AddTx(tx2)
 		case 2:
diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go
index 62c018ef8e16aa470c5260ccf5a1fe51ebbd5f6f..de1b0ed1ee7f2cbd773e1ed1d3ac233fadc527c8 100644
--- a/eth/protocols/eth/protocol.go
+++ b/eth/protocols/eth/protocol.go
@@ -155,19 +155,19 @@ func (hn *HashOrNumber) EncodeRLP(w io.Writer) error {
 // DecodeRLP is a specialized decoder for HashOrNumber to decode the contents
 // into either a block hash or a block number.
 func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error {
-	_, size, _ := s.Kind()
-	origin, err := s.Raw()
-	if err == nil {
-		switch {
-		case size == 32:
-			err = rlp.DecodeBytes(origin, &hn.Hash)
-		case size <= 8:
-			err = rlp.DecodeBytes(origin, &hn.Number)
-		default:
-			err = fmt.Errorf("invalid input size %d for origin", size)
-		}
+	_, size, err := s.Kind()
+	switch {
+	case err != nil:
+		return err
+	case size == 32:
+		hn.Number = 0
+		return s.Decode(&hn.Hash)
+	case size <= 8:
+		hn.Hash = common.Hash{}
+		return s.Decode(&hn.Number)
+	default:
+		return fmt.Errorf("invalid input size %d for origin", size)
 	}
-	return err
 }
 
 // BlockHeadersPacket represents a block header response.
diff --git a/eth/protocols/snap/range.go b/eth/protocols/snap/range.go
index dd380ff47148dea2943ab10ff4a6d46a7b4fdf1b..2627cb954b8fb69442a00058ed2707e66c747f0d 100644
--- a/eth/protocols/snap/range.go
+++ b/eth/protocols/snap/range.go
@@ -42,15 +42,15 @@ func newHashRange(start common.Hash, num uint64) *hashRange {
 	step256.SetFromBig(step)
 
 	return &hashRange{
-		current: uint256.NewInt().SetBytes32(start[:]),
+		current: new(uint256.Int).SetBytes32(start[:]),
 		step:    step256,
 	}
 }
 
 // Next pushes the hash range to the next interval.
 func (r *hashRange) Next() bool {
-	next := new(uint256.Int)
-	if overflow := next.AddOverflow(r.current, r.step); overflow {
+	next, overflow := new(uint256.Int).AddOverflow(r.current, r.step)
+	if overflow {
 		return false
 	}
 	r.current = next
@@ -65,16 +65,17 @@ func (r *hashRange) Start() common.Hash {
 // End returns the last hash in the current interval.
 func (r *hashRange) End() common.Hash {
 	// If the end overflows (non divisible range), return a shorter interval
-	next := new(uint256.Int)
-	if overflow := next.AddOverflow(r.current, r.step); overflow {
+	next, overflow := new(uint256.Int).AddOverflow(r.current, r.step)
+	if overflow {
 		return common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
 	}
-	return new(uint256.Int).Sub(next, uint256.NewInt().SetOne()).Bytes32()
+	return next.SubUint64(next, 1).Bytes32()
 }
 
 // incHash returns the next hash, in lexicographical order (a.k.a plus one)
 func incHash(h common.Hash) common.Hash {
-	a := uint256.NewInt().SetBytes32(h[:])
-	a.Add(a, uint256.NewInt().SetOne())
+	var a uint256.Int
+	a.SetBytes32(h[:])
+	a.AddUint64(&a, 1)
 	return common.Hash(a.Bytes32())
 }
diff --git a/eth/protocols/snap/range_test.go b/eth/protocols/snap/range_test.go
index 23273e50bf100e84054c5ab5155f9b826e31629f..c6dc8fb718ae469b02ea1d7f4b21423ebfe7311c 100644
--- a/eth/protocols/snap/range_test.go
+++ b/eth/protocols/snap/range_test.go
@@ -53,7 +53,7 @@ func TestHashRanges(t *testing.T) {
 			head:   common.HexToHash("0x2000000000000000000000000000000000000000000000000000000000000000"),
 			chunks: 2,
 			starts: []common.Hash{
-				common.Hash{},
+				{},
 				common.HexToHash("0x9000000000000000000000000000000000000000000000000000000000000000"),
 			},
 			ends: []common.Hash{
diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go
index e283473207fd30259c1d55e3801eeba1eba376c4..646df03887f1ee82eb3da517107b0abcdf9706ea 100644
--- a/eth/protocols/snap/sync.go
+++ b/eth/protocols/snap/sync.go
@@ -37,6 +37,7 @@ import (
 	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/light"
 	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/p2p/msgrate"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/trie"
 	"golang.org/x/crypto/sha3"
@@ -51,14 +52,15 @@ var (
 )
 
 const (
-	// maxRequestSize is the maximum number of bytes to request from a remote peer.
-	maxRequestSize = 128 * 1024
+	// minRequestSize is the minimum number of bytes to request from a remote peer.
+	// This number is used as the low cap for account and storage range requests.
+	// Bytecode and trienode are limited inherently by item count (1).
+	minRequestSize = 64 * 1024
 
-	// maxStorageSetRequestCount is the maximum number of contracts to request the
-	// storage of in a single query. If this number is too low, we're not filling
-	// responses fully and waste round trip times. If it's too high, we're capping
-	// responses and waste bandwidth.
-	maxStorageSetRequestCount = maxRequestSize / 1024
+	// maxRequestSize is the maximum number of bytes to request from a remote peer.
+	// This number is used as the high cap for account and storage range requests.
+	// Bytecode and trienode are limited more explicitly by the caps below.
+	maxRequestSize = 512 * 1024
 
 	// maxCodeRequestCount is the maximum number of bytecode blobs to request in a
 	// single query. If this number is too low, we're not filling responses fully
@@ -74,7 +76,7 @@ const (
 	// a single query. If this number is too low, we're not filling responses fully
 	// and waste round trip times. If it's too high, we're capping responses and
 	// waste bandwidth.
-	maxTrieRequestCount = 256
+	maxTrieRequestCount = maxRequestSize / 512
 )
 
 var (
@@ -85,10 +87,6 @@ var (
 	// storageConcurrency is the number of chunks to split the a large contract
 	// storage trie into to allow concurrent retrievals.
 	storageConcurrency = 16
-
-	// requestTimeout is the maximum time a peer is allowed to spend on serving
-	// a single network request.
-	requestTimeout = 15 * time.Second // TODO(karalabe): Make it dynamic ala fast-sync?
 )
 
 // ErrCancelled is returned from snap syncing if the operation was prematurely
@@ -105,8 +103,9 @@ var ErrCancelled = errors.New("sync cancelled")
 // is only included to allow the runloop to match a response to the task being
 // synced without having yet another set of maps.
 type accountRequest struct {
-	peer string // Peer to which this request is assigned
-	id   uint64 // Request ID of this request
+	peer string    // Peer to which this request is assigned
+	id   uint64    // Request ID of this request
+	time time.Time // Timestamp when the request was sent
 
 	deliver chan *accountResponse // Channel to deliver successful response on
 	revert  chan *accountRequest  // Channel to deliver request failure on
@@ -142,8 +141,9 @@ type accountResponse struct {
 // is only included to allow the runloop to match a response to the task being
 // synced without having yet another set of maps.
 type bytecodeRequest struct {
-	peer string // Peer to which this request is assigned
-	id   uint64 // Request ID of this request
+	peer string    // Peer to which this request is assigned
+	id   uint64    // Request ID of this request
+	time time.Time // Timestamp when the request was sent
 
 	deliver chan *bytecodeResponse // Channel to deliver successful response on
 	revert  chan *bytecodeRequest  // Channel to deliver request failure on
@@ -173,8 +173,9 @@ type bytecodeResponse struct {
 // is only included to allow the runloop to match a response to the task being
 // synced without having yet another set of maps.
 type storageRequest struct {
-	peer string // Peer to which this request is assigned
-	id   uint64 // Request ID of this request
+	peer string    // Peer to which this request is assigned
+	id   uint64    // Request ID of this request
+	time time.Time // Timestamp when the request was sent
 
 	deliver chan *storageResponse // Channel to deliver successful response on
 	revert  chan *storageRequest  // Channel to deliver request failure on
@@ -218,8 +219,9 @@ type storageResponse struct {
 // is only included to allow the runloop to match a response to the task being
 // synced without having yet another set of maps.
 type trienodeHealRequest struct {
-	peer string // Peer to which this request is assigned
-	id   uint64 // Request ID of this request
+	peer string    // Peer to which this request is assigned
+	id   uint64    // Request ID of this request
+	time time.Time // Timestamp when the request was sent
 
 	deliver chan *trienodeHealResponse // Channel to deliver successful response on
 	revert  chan *trienodeHealRequest  // Channel to deliver request failure on
@@ -252,8 +254,9 @@ type trienodeHealResponse struct {
 // is only included to allow the runloop to match a response to the task being
 // synced without having yet another set of maps.
 type bytecodeHealRequest struct {
-	peer string // Peer to which this request is assigned
-	id   uint64 // Request ID of this request
+	peer string    // Peer to which this request is assigned
+	id   uint64    // Request ID of this request
+	time time.Time // Timestamp when the request was sent
 
 	deliver chan *bytecodeHealResponse // Channel to deliver successful response on
 	revert  chan *bytecodeHealRequest  // Channel to deliver request failure on
@@ -396,6 +399,7 @@ type Syncer struct {
 	peers    map[string]SyncPeer // Currently active peers to download from
 	peerJoin *event.Feed         // Event feed to react to peers joining
 	peerDrop *event.Feed         // Event feed to react to peers dropping
+	rates    *msgrate.Trackers   // Message throughput rates for peers
 
 	// Request tracking during syncing phase
 	statelessPeers map[string]struct{} // Peers that failed to deliver state data
@@ -452,6 +456,7 @@ func NewSyncer(db ethdb.KeyValueStore) *Syncer {
 		peers:    make(map[string]SyncPeer),
 		peerJoin: new(event.Feed),
 		peerDrop: new(event.Feed),
+		rates:    msgrate.NewTrackers(log.New("proto", "snap")),
 		update:   make(chan struct{}, 1),
 
 		accountIdlers:  make(map[string]struct{}),
@@ -484,6 +489,7 @@ func (s *Syncer) Register(peer SyncPeer) error {
 		return errors.New("already registered")
 	}
 	s.peers[id] = peer
+	s.rates.Track(id, msgrate.NewTracker(s.rates.MeanCapacities(), s.rates.MedianRoundTrip()))
 
 	// Mark the peer as idle, even if no sync is running
 	s.accountIdlers[id] = struct{}{}
@@ -509,6 +515,7 @@ func (s *Syncer) Unregister(id string) error {
 		return errors.New("not registered")
 	}
 	delete(s.peers, id)
+	s.rates.Untrack(id)
 
 	// Remove status markers, even if no sync is running
 	delete(s.statelessPeers, id)
@@ -851,10 +858,24 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac
 	s.lock.Lock()
 	defer s.lock.Unlock()
 
-	// If there are no idle peers, short circuit assignment
-	if len(s.accountIdlers) == 0 {
+	// Sort the peers by download capacity to use faster ones if many available
+	idlers := &capacitySort{
+		ids:  make([]string, 0, len(s.accountIdlers)),
+		caps: make([]int, 0, len(s.accountIdlers)),
+	}
+	targetTTL := s.rates.TargetTimeout()
+	for id := range s.accountIdlers {
+		if _, ok := s.statelessPeers[id]; ok {
+			continue
+		}
+		idlers.ids = append(idlers.ids, id)
+		idlers.caps = append(idlers.caps, s.rates.Capacity(id, AccountRangeMsg, targetTTL))
+	}
+	if len(idlers.ids) == 0 {
 		return
 	}
+	sort.Sort(sort.Reverse(idlers))
+
 	// Iterate over all the tasks and try to find a pending one
 	for _, task := range s.tasks {
 		// Skip any tasks already filling
@@ -864,20 +885,15 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac
 		// Task pending retrieval, try to find an idle peer. If no such peer
 		// exists, we probably assigned tasks for all (or they are stateless).
 		// Abort the entire assignment mechanism.
-		var idle string
-		for id := range s.accountIdlers {
-			// If the peer rejected a query in this sync cycle, don't bother asking
-			// again for anything, it's either out of sync or already pruned
-			if _, ok := s.statelessPeers[id]; ok {
-				continue
-			}
-			idle = id
-			break
-		}
-		if idle == "" {
+		if len(idlers.ids) == 0 {
 			return
 		}
-		peer := s.peers[idle]
+		var (
+			idle = idlers.ids[0]
+			peer = s.peers[idle]
+			cap  = idlers.caps[0]
+		)
+		idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
 
 		// Matched a pending task to an idle peer, allocate a unique request id
 		var reqid uint64
@@ -895,6 +911,7 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac
 		req := &accountRequest{
 			peer:    idle,
 			id:      reqid,
+			time:    time.Now(),
 			deliver: success,
 			revert:  fail,
 			cancel:  cancel,
@@ -903,8 +920,9 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac
 			limit:   task.Last,
 			task:    task,
 		}
-		req.timeout = time.AfterFunc(requestTimeout, func() {
+		req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
 			peer.Log().Debug("Account range request timed out", "reqid", reqid)
+			s.rates.Update(idle, AccountRangeMsg, 0, 0)
 			s.scheduleRevertAccountRequest(req)
 		})
 		s.accountReqs[reqid] = req
@@ -915,7 +933,13 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac
 			defer s.pend.Done()
 
 			// Attempt to send the remote request and revert if it fails
-			if err := peer.RequestAccountRange(reqid, root, req.origin, req.limit, maxRequestSize); err != nil {
+			if cap > maxRequestSize {
+				cap = maxRequestSize
+			}
+			if cap < minRequestSize { // Don't bother with peers below a bare minimum performance
+				cap = minRequestSize
+			}
+			if err := peer.RequestAccountRange(reqid, root, req.origin, req.limit, uint64(cap)); err != nil {
 				peer.Log().Debug("Failed to request account range", "err", err)
 				s.scheduleRevertAccountRequest(req)
 			}
@@ -931,10 +955,24 @@ func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan *
 	s.lock.Lock()
 	defer s.lock.Unlock()
 
-	// If there are no idle peers, short circuit assignment
-	if len(s.bytecodeIdlers) == 0 {
+	// Sort the peers by download capacity to use faster ones if many available
+	idlers := &capacitySort{
+		ids:  make([]string, 0, len(s.bytecodeIdlers)),
+		caps: make([]int, 0, len(s.bytecodeIdlers)),
+	}
+	targetTTL := s.rates.TargetTimeout()
+	for id := range s.bytecodeIdlers {
+		if _, ok := s.statelessPeers[id]; ok {
+			continue
+		}
+		idlers.ids = append(idlers.ids, id)
+		idlers.caps = append(idlers.caps, s.rates.Capacity(id, ByteCodesMsg, targetTTL))
+	}
+	if len(idlers.ids) == 0 {
 		return
 	}
+	sort.Sort(sort.Reverse(idlers))
+
 	// Iterate over all the tasks and try to find a pending one
 	for _, task := range s.tasks {
 		// Skip any tasks not in the bytecode retrieval phase
@@ -948,20 +986,15 @@ func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan *
 		// Task pending retrieval, try to find an idle peer. If no such peer
 		// exists, we probably assigned tasks for all (or they are stateless).
 		// Abort the entire assignment mechanism.
-		var idle string
-		for id := range s.bytecodeIdlers {
-			// If the peer rejected a query in this sync cycle, don't bother asking
-			// again for anything, it's either out of sync or already pruned
-			if _, ok := s.statelessPeers[id]; ok {
-				continue
-			}
-			idle = id
-			break
-		}
-		if idle == "" {
+		if len(idlers.ids) == 0 {
 			return
 		}
-		peer := s.peers[idle]
+		var (
+			idle = idlers.ids[0]
+			peer = s.peers[idle]
+			cap  = idlers.caps[0]
+		)
+		idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
 
 		// Matched a pending task to an idle peer, allocate a unique request id
 		var reqid uint64
@@ -976,17 +1009,21 @@ func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan *
 			break
 		}
 		// Generate the network query and send it to the peer
-		hashes := make([]common.Hash, 0, maxCodeRequestCount)
+		if cap > maxCodeRequestCount {
+			cap = maxCodeRequestCount
+		}
+		hashes := make([]common.Hash, 0, cap)
 		for hash := range task.codeTasks {
 			delete(task.codeTasks, hash)
 			hashes = append(hashes, hash)
-			if len(hashes) >= maxCodeRequestCount {
+			if len(hashes) >= cap {
 				break
 			}
 		}
 		req := &bytecodeRequest{
 			peer:    idle,
 			id:      reqid,
+			time:    time.Now(),
 			deliver: success,
 			revert:  fail,
 			cancel:  cancel,
@@ -994,8 +1031,9 @@ func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan *
 			hashes:  hashes,
 			task:    task,
 		}
-		req.timeout = time.AfterFunc(requestTimeout, func() {
+		req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
 			peer.Log().Debug("Bytecode request timed out", "reqid", reqid)
+			s.rates.Update(idle, ByteCodesMsg, 0, 0)
 			s.scheduleRevertBytecodeRequest(req)
 		})
 		s.bytecodeReqs[reqid] = req
@@ -1020,10 +1058,24 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 	s.lock.Lock()
 	defer s.lock.Unlock()
 
-	// If there are no idle peers, short circuit assignment
-	if len(s.storageIdlers) == 0 {
+	// Sort the peers by download capacity to use faster ones if many available
+	idlers := &capacitySort{
+		ids:  make([]string, 0, len(s.storageIdlers)),
+		caps: make([]int, 0, len(s.storageIdlers)),
+	}
+	targetTTL := s.rates.TargetTimeout()
+	for id := range s.storageIdlers {
+		if _, ok := s.statelessPeers[id]; ok {
+			continue
+		}
+		idlers.ids = append(idlers.ids, id)
+		idlers.caps = append(idlers.caps, s.rates.Capacity(id, StorageRangesMsg, targetTTL))
+	}
+	if len(idlers.ids) == 0 {
 		return
 	}
+	sort.Sort(sort.Reverse(idlers))
+
 	// Iterate over all the tasks and try to find a pending one
 	for _, task := range s.tasks {
 		// Skip any tasks not in the storage retrieval phase
@@ -1037,20 +1089,15 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 		// Task pending retrieval, try to find an idle peer. If no such peer
 		// exists, we probably assigned tasks for all (or they are stateless).
 		// Abort the entire assignment mechanism.
-		var idle string
-		for id := range s.storageIdlers {
-			// If the peer rejected a query in this sync cycle, don't bother asking
-			// again for anything, it's either out of sync or already pruned
-			if _, ok := s.statelessPeers[id]; ok {
-				continue
-			}
-			idle = id
-			break
-		}
-		if idle == "" {
+		if len(idlers.ids) == 0 {
 			return
 		}
-		peer := s.peers[idle]
+		var (
+			idle = idlers.ids[0]
+			peer = s.peers[idle]
+			cap  = idlers.caps[0]
+		)
+		idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
 
 		// Matched a pending task to an idle peer, allocate a unique request id
 		var reqid uint64
@@ -1067,9 +1114,17 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 		// Generate the network query and send it to the peer. If there are
 		// large contract tasks pending, complete those before diving into
 		// even more new contracts.
+		if cap > maxRequestSize {
+			cap = maxRequestSize
+		}
+		if cap < minRequestSize { // Don't bother with peers below a bare minimum performance
+			cap = minRequestSize
+		}
+		storageSets := cap / 1024
+
 		var (
-			accounts = make([]common.Hash, 0, maxStorageSetRequestCount)
-			roots    = make([]common.Hash, 0, maxStorageSetRequestCount)
+			accounts = make([]common.Hash, 0, storageSets)
+			roots    = make([]common.Hash, 0, storageSets)
 			subtask  *storageTask
 		)
 		for account, subtasks := range task.SubTasks {
@@ -1096,7 +1151,7 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 				accounts = append(accounts, acccount)
 				roots = append(roots, root)
 
-				if len(accounts) >= maxStorageSetRequestCount {
+				if len(accounts) >= storageSets {
 					break
 				}
 			}
@@ -1109,6 +1164,7 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 		req := &storageRequest{
 			peer:     idle,
 			id:       reqid,
+			time:     time.Now(),
 			deliver:  success,
 			revert:   fail,
 			cancel:   cancel,
@@ -1122,8 +1178,9 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 			req.origin = subtask.Next
 			req.limit = subtask.Last
 		}
-		req.timeout = time.AfterFunc(requestTimeout, func() {
+		req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
 			peer.Log().Debug("Storage request timed out", "reqid", reqid)
+			s.rates.Update(idle, StorageRangesMsg, 0, 0)
 			s.scheduleRevertStorageRequest(req)
 		})
 		s.storageReqs[reqid] = req
@@ -1138,7 +1195,7 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st
 			if subtask != nil {
 				origin, limit = req.origin[:], req.limit[:]
 			}
-			if err := peer.RequestStorageRanges(reqid, root, accounts, origin, limit, maxRequestSize); err != nil {
+			if err := peer.RequestStorageRanges(reqid, root, accounts, origin, limit, uint64(cap)); err != nil {
 				log.Debug("Failed to request storage", "err", err)
 				s.scheduleRevertStorageRequest(req)
 			}
@@ -1157,10 +1214,24 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai
 	s.lock.Lock()
 	defer s.lock.Unlock()
 
-	// If there are no idle peers, short circuit assignment
-	if len(s.trienodeHealIdlers) == 0 {
+	// Sort the peers by download capacity to use faster ones if many available
+	idlers := &capacitySort{
+		ids:  make([]string, 0, len(s.trienodeHealIdlers)),
+		caps: make([]int, 0, len(s.trienodeHealIdlers)),
+	}
+	targetTTL := s.rates.TargetTimeout()
+	for id := range s.trienodeHealIdlers {
+		if _, ok := s.statelessPeers[id]; ok {
+			continue
+		}
+		idlers.ids = append(idlers.ids, id)
+		idlers.caps = append(idlers.caps, s.rates.Capacity(id, TrieNodesMsg, targetTTL))
+	}
+	if len(idlers.ids) == 0 {
 		return
 	}
+	sort.Sort(sort.Reverse(idlers))
+
 	// Iterate over pending tasks and try to find a peer to retrieve with
 	for len(s.healer.trieTasks) > 0 || s.healer.scheduler.Pending() > 0 {
 		// If there are not enough trie tasks queued to fully assign, fill the
@@ -1186,20 +1257,15 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai
 		// Task pending retrieval, try to find an idle peer. If no such peer
 		// exists, we probably assigned tasks for all (or they are stateless).
 		// Abort the entire assignment mechanism.
-		var idle string
-		for id := range s.trienodeHealIdlers {
-			// If the peer rejected a query in this sync cycle, don't bother asking
-			// again for anything, it's either out of sync or already pruned
-			if _, ok := s.statelessPeers[id]; ok {
-				continue
-			}
-			idle = id
-			break
-		}
-		if idle == "" {
+		if len(idlers.ids) == 0 {
 			return
 		}
-		peer := s.peers[idle]
+		var (
+			idle = idlers.ids[0]
+			peer = s.peers[idle]
+			cap  = idlers.caps[0]
+		)
+		idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
 
 		// Matched a pending task to an idle peer, allocate a unique request id
 		var reqid uint64
@@ -1214,10 +1280,13 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai
 			break
 		}
 		// Generate the network query and send it to the peer
+		if cap > maxTrieRequestCount {
+			cap = maxTrieRequestCount
+		}
 		var (
-			hashes   = make([]common.Hash, 0, maxTrieRequestCount)
-			paths    = make([]trie.SyncPath, 0, maxTrieRequestCount)
-			pathsets = make([]TrieNodePathSet, 0, maxTrieRequestCount)
+			hashes   = make([]common.Hash, 0, cap)
+			paths    = make([]trie.SyncPath, 0, cap)
+			pathsets = make([]TrieNodePathSet, 0, cap)
 		)
 		for hash, pathset := range s.healer.trieTasks {
 			delete(s.healer.trieTasks, hash)
@@ -1226,13 +1295,14 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai
 			paths = append(paths, pathset)
 			pathsets = append(pathsets, [][]byte(pathset)) // TODO(karalabe): group requests by account hash
 
-			if len(hashes) >= maxTrieRequestCount {
+			if len(hashes) >= cap {
 				break
 			}
 		}
 		req := &trienodeHealRequest{
 			peer:    idle,
 			id:      reqid,
+			time:    time.Now(),
 			deliver: success,
 			revert:  fail,
 			cancel:  cancel,
@@ -1241,8 +1311,9 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai
 			paths:   paths,
 			task:    s.healer,
 		}
-		req.timeout = time.AfterFunc(requestTimeout, func() {
+		req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
 			peer.Log().Debug("Trienode heal request timed out", "reqid", reqid)
+			s.rates.Update(idle, TrieNodesMsg, 0, 0)
 			s.scheduleRevertTrienodeHealRequest(req)
 		})
 		s.trienodeHealReqs[reqid] = req
@@ -1267,10 +1338,24 @@ func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fai
 	s.lock.Lock()
 	defer s.lock.Unlock()
 
-	// If there are no idle peers, short circuit assignment
-	if len(s.bytecodeHealIdlers) == 0 {
+	// Sort the peers by download capacity to use faster ones if many available
+	idlers := &capacitySort{
+		ids:  make([]string, 0, len(s.bytecodeHealIdlers)),
+		caps: make([]int, 0, len(s.bytecodeHealIdlers)),
+	}
+	targetTTL := s.rates.TargetTimeout()
+	for id := range s.bytecodeHealIdlers {
+		if _, ok := s.statelessPeers[id]; ok {
+			continue
+		}
+		idlers.ids = append(idlers.ids, id)
+		idlers.caps = append(idlers.caps, s.rates.Capacity(id, ByteCodesMsg, targetTTL))
+	}
+	if len(idlers.ids) == 0 {
 		return
 	}
+	sort.Sort(sort.Reverse(idlers))
+
 	// Iterate over pending tasks and try to find a peer to retrieve with
 	for len(s.healer.codeTasks) > 0 || s.healer.scheduler.Pending() > 0 {
 		// If there are not enough trie tasks queued to fully assign, fill the
@@ -1296,20 +1381,15 @@ func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fai
 		// Task pending retrieval, try to find an idle peer. If no such peer
 		// exists, we probably assigned tasks for all (or they are stateless).
 		// Abort the entire assignment mechanism.
-		var idle string
-		for id := range s.bytecodeHealIdlers {
-			// If the peer rejected a query in this sync cycle, don't bother asking
-			// again for anything, it's either out of sync or already pruned
-			if _, ok := s.statelessPeers[id]; ok {
-				continue
-			}
-			idle = id
-			break
-		}
-		if idle == "" {
+		if len(idlers.ids) == 0 {
 			return
 		}
-		peer := s.peers[idle]
+		var (
+			idle = idlers.ids[0]
+			peer = s.peers[idle]
+			cap  = idlers.caps[0]
+		)
+		idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
 
 		// Matched a pending task to an idle peer, allocate a unique request id
 		var reqid uint64
@@ -1324,18 +1404,22 @@ func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fai
 			break
 		}
 		// Generate the network query and send it to the peer
-		hashes := make([]common.Hash, 0, maxCodeRequestCount)
+		if cap > maxCodeRequestCount {
+			cap = maxCodeRequestCount
+		}
+		hashes := make([]common.Hash, 0, cap)
 		for hash := range s.healer.codeTasks {
 			delete(s.healer.codeTasks, hash)
 
 			hashes = append(hashes, hash)
-			if len(hashes) >= maxCodeRequestCount {
+			if len(hashes) >= cap {
 				break
 			}
 		}
 		req := &bytecodeHealRequest{
 			peer:    idle,
 			id:      reqid,
+			time:    time.Now(),
 			deliver: success,
 			revert:  fail,
 			cancel:  cancel,
@@ -1343,8 +1427,9 @@ func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fai
 			hashes:  hashes,
 			task:    s.healer,
 		}
-		req.timeout = time.AfterFunc(requestTimeout, func() {
+		req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
 			peer.Log().Debug("Bytecode heal request timed out", "reqid", reqid)
+			s.rates.Update(idle, ByteCodesMsg, 0, 0)
 			s.scheduleRevertBytecodeHealRequest(req)
 		})
 		s.bytecodeHealReqs[reqid] = req
@@ -2142,6 +2227,7 @@ func (s *Syncer) OnAccounts(peer SyncPeer, id uint64, hashes []common.Hash, acco
 		return nil
 	}
 	delete(s.accountReqs, id)
+	s.rates.Update(peer.ID(), AccountRangeMsg, time.Since(req.time), int(size))
 
 	// Clean up the request timeout timer, we'll see how to proceed further based
 	// on the actual delivered content
@@ -2253,6 +2339,7 @@ func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error
 		return nil
 	}
 	delete(s.bytecodeReqs, id)
+	s.rates.Update(peer.ID(), ByteCodesMsg, time.Since(req.time), len(bytecodes))
 
 	// Clean up the request timeout timer, we'll see how to proceed further based
 	// on the actual delivered content
@@ -2361,6 +2448,7 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo
 		return nil
 	}
 	delete(s.storageReqs, id)
+	s.rates.Update(peer.ID(), StorageRangesMsg, time.Since(req.time), int(size))
 
 	// Clean up the request timeout timer, we'll see how to proceed further based
 	// on the actual delivered content
@@ -2487,6 +2575,7 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error
 		return nil
 	}
 	delete(s.trienodeHealReqs, id)
+	s.rates.Update(peer.ID(), TrieNodesMsg, time.Since(req.time), len(trienodes))
 
 	// Clean up the request timeout timer, we'll see how to proceed further based
 	// on the actual delivered content
@@ -2581,6 +2670,7 @@ func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) e
 		return nil
 	}
 	delete(s.bytecodeHealReqs, id)
+	s.rates.Update(peer.ID(), ByteCodesMsg, time.Since(req.time), len(bytecodes))
 
 	// Clean up the request timeout timer, we'll see how to proceed further based
 	// on the actual delivered content
@@ -2756,3 +2846,24 @@ func estimateRemainingSlots(hashes int, last common.Hash) (uint64, error) {
 	}
 	return space.Uint64() - uint64(hashes), nil
 }
+
+// capacitySort implements the Sort interface, allowing sorting by peer message
+// throughput. Note, callers should use sort.Reverse to get the desired effect
+// of highest capacity being at the front.
+type capacitySort struct {
+	ids  []string
+	caps []int
+}
+
+func (s *capacitySort) Len() int {
+	return len(s.ids)
+}
+
+func (s *capacitySort) Less(i, j int) bool {
+	return s.caps[i] < s.caps[j]
+}
+
+func (s *capacitySort) Swap(i, j int) {
+	s.ids[i], s.ids[j] = s.ids[j], s.ids[i]
+	s.caps[i], s.caps[j] = s.caps[j], s.caps[i]
+}
diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go
index a1cc3581a85cc60afc36a84a10d62ed4b43b6eed..023fc8ee0058200c8d66933170b7807557ab9757 100644
--- a/eth/protocols/snap/sync_test.go
+++ b/eth/protocols/snap/sync_test.go
@@ -796,12 +796,6 @@ func TestMultiSyncManyUseless(t *testing.T) {
 
 // TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
 func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
-	// We're setting the timeout to very low, to increase the chance of the timeout
-	// being triggered. This was previously a cause of panic, when a response
-	// arrived simultaneously as a timeout was triggered.
-	defer func(old time.Duration) { requestTimeout = old }(requestTimeout)
-	requestTimeout = time.Millisecond
-
 	var (
 		once   sync.Once
 		cancel = make(chan struct{})
@@ -838,6 +832,11 @@ func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
 		mkSource("noStorage", true, false, true),
 		mkSource("noTrie", true, true, false),
 	)
+	// We're setting the timeout to very low, to increase the chance of the timeout
+	// being triggered. This was previously a cause of panic, when a response
+	// arrived simultaneously as a timeout was triggered.
+	syncer.rates.OverrideTTLLimit = time.Millisecond
+
 	done := checkStall(t, term)
 	if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
 		t.Fatalf("sync failed: %v", err)
@@ -848,10 +847,6 @@ func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
 
 // TestMultiSyncManyUnresponsive contains one good peer, and many which doesn't respond at all
 func TestMultiSyncManyUnresponsive(t *testing.T) {
-	// We're setting the timeout to very low, to make the test run a bit faster
-	defer func(old time.Duration) { requestTimeout = old }(requestTimeout)
-	requestTimeout = time.Millisecond
-
 	var (
 		once   sync.Once
 		cancel = make(chan struct{})
@@ -888,6 +883,9 @@ func TestMultiSyncManyUnresponsive(t *testing.T) {
 		mkSource("noStorage", true, false, true),
 		mkSource("noTrie", true, true, false),
 	)
+	// We're setting the timeout to very low, to make the test run a bit faster
+	syncer.rates.OverrideTTLLimit = time.Millisecond
+
 	done := checkStall(t, term)
 	if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
 		t.Fatalf("sync failed: %v", err)
diff --git a/eth/state_accessor.go b/eth/state_accessor.go
index 84cfaf4d738d80b5390d7506221662b66262e729..eb178311f30b7d011f46d70ef557531cd2995fcd 100644
--- a/eth/state_accessor.go
+++ b/eth/state_accessor.go
@@ -162,7 +162,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec
 	signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
 	for idx, tx := range block.Transactions() {
 		// Assemble the transaction call message and return if the requested offset
-		msg, _ := tx.AsMessage(signer)
+		msg, _ := tx.AsMessage(signer, block.BaseFee())
 		txContext := core.NewEVMTxContext(msg)
 		context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
 		if idx == txIndex {
@@ -170,7 +170,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec
 		}
 		// Not yet the searched for transaction, execute on top of the current state
 		vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
-		statedb.Prepare(tx.Hash(), block.Hash(), idx)
+		statedb.Prepare(tx.Hash(), idx)
 		if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
 			return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
 		}
diff --git a/eth/sync.go b/eth/sync.go
index 4520ec68794c7ed27de0ad10015c1dfe22d82a39..ab114b59f3e1fa21a1f8a29b0d90fd67c12f1652 100644
--- a/eth/sync.go
+++ b/eth/sync.go
@@ -54,7 +54,7 @@ func (h *handler) syncTransactions(p *eth.Peer) {
 	//
 	// TODO(karalabe): Figure out if we could get away with random order somehow
 	var txs types.Transactions
-	pending, _ := h.txpool.Pending()
+	pending, _ := h.txpool.Pending(false)
 	for _, batch := range pending {
 		txs = append(txs, batch...)
 	}
diff --git a/eth/tracers/api.go b/eth/tracers/api.go
index aaa6783e52156f22611fedd84fef1684bb91f1b0..a97d5cc659928e4468b5eb694bfc7ff357d45a19 100644
--- a/eth/tracers/api.go
+++ b/eth/tracers/api.go
@@ -178,13 +178,6 @@ type StdTraceConfig struct {
 	TxHash common.Hash
 }
 
-// txTraceContext is the contextual infos about a transaction before it gets run.
-type txTraceContext struct {
-	index int         // Index of the transaction within the block
-	hash  common.Hash // Hash of the transaction
-	block common.Hash // Hash of the block containing the transaction
-}
-
 // txTraceResult is the result of a single transaction trace.
 type txTraceResult struct {
 	Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer
@@ -271,11 +264,11 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config
 				blockCtx := core.NewEVMBlockContext(task.block.Header(), api.chainContext(localctx), nil)
 				// Trace all the transactions contained within
 				for i, tx := range task.block.Transactions() {
-					msg, _ := tx.AsMessage(signer)
-					txctx := &txTraceContext{
-						index: i,
-						hash:  tx.Hash(),
-						block: task.block.Hash(),
+					msg, _ := tx.AsMessage(signer, task.block.BaseFee())
+					txctx := &Context{
+						BlockHash: task.block.Hash(),
+						TxIndex:   i,
+						TxHash:    tx.Hash(),
 					}
 					res, err := api.traceTx(localctx, msg, txctx, blockCtx, task.statedb, config)
 					if err != nil {
@@ -523,11 +516,11 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
 			defer pend.Done()
 			// Fetch and execute the next transaction trace tasks
 			for task := range jobs {
-				msg, _ := txs[task.index].AsMessage(signer)
-				txctx := &txTraceContext{
-					index: task.index,
-					hash:  txs[task.index].Hash(),
-					block: blockHash,
+				msg, _ := txs[task.index].AsMessage(signer, block.BaseFee())
+				txctx := &Context{
+					BlockHash: blockHash,
+					TxIndex:   task.index,
+					TxHash:    txs[task.index].Hash(),
 				}
 				res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config)
 				if err != nil {
@@ -545,8 +538,8 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
 		jobs <- &txTraceTask{statedb: statedb.Copy(), index: i}
 
 		// Generate the next state snapshot fast without tracing
-		msg, _ := tx.AsMessage(signer)
-		statedb.Prepare(tx.Hash(), block.Hash(), i)
+		msg, _ := tx.AsMessage(signer, block.BaseFee())
+		statedb.Prepare(tx.Hash(), i)
 		vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{})
 		if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
 			failed = err
@@ -630,7 +623,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
 	for i, tx := range block.Transactions() {
 		// Prepare the trasaction for un-traced execution
 		var (
-			msg, _    = tx.AsMessage(signer)
+			msg, _    = tx.AsMessage(signer, block.BaseFee())
 			txContext = core.NewEVMTxContext(msg)
 			vmConf    vm.Config
 			dump      *os.File
@@ -660,7 +653,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
 		}
 		// Execute the transaction and flush any traces to disk
 		vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf)
-		statedb.Prepare(tx.Hash(), block.Hash(), i)
+		statedb.Prepare(tx.Hash(), i)
 		_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
 		if writer != nil {
 			writer.Flush()
@@ -728,10 +721,10 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
 	if err != nil {
 		return nil, err
 	}
-	txctx := &txTraceContext{
-		index: int(index),
-		hash:  hash,
-		block: blockHash,
+	txctx := &Context{
+		BlockHash: blockHash,
+		TxIndex:   int(index),
+		TxHash:    hash,
 	}
 	return api.traceTx(ctx, msg, txctx, vmctx, statedb, config)
 }
@@ -740,7 +733,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
 // created during the execution of EVM if the given transaction was added on
 // top of the provided block and returns them as a JSON object.
 // You can provide -2 as a block number to trace on top of the pending block.
-func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) {
+func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) {
 	// Try to retrieve the specified block
 	var (
 		err   error
@@ -772,7 +765,10 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHa
 		}
 	}
 	// Execute the trace
-	msg := args.ToMessage(api.backend.RPCGasCap())
+	msg, err := args.ToMessage(api.backend.RPCGasCap(), block.BaseFee())
+	if err != nil {
+		return nil, err
+	}
 	vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
 
 	var traceConfig *TraceConfig
@@ -784,13 +780,13 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHa
 			Reexec:    config.Reexec,
 		}
 	}
-	return api.traceTx(ctx, msg, new(txTraceContext), vmctx, statedb, traceConfig)
+	return api.traceTx(ctx, msg, new(Context), vmctx, statedb, traceConfig)
 }
 
 // traceTx configures a new tracer according to the provided configuration, and
 // executes the given message in the provided environment. The return value will
 // be tracer dependent.
-func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTraceContext, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
+func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
 	// Assemble the structured logger or the JavaScript tracer
 	var (
 		tracer    vm.Tracer
@@ -807,7 +803,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac
 			}
 		}
 		// Constuct the JavaScript tracer to execute with
-		if tracer, err = New(*config.Tracer, txContext); err != nil {
+		if tracer, err = New(*config.Tracer, txctx); err != nil {
 			return nil, err
 		}
 		// Handle timeouts and RPC cancellations
@@ -827,10 +823,10 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac
 		tracer = vm.NewStructLogger(config.LogConfig)
 	}
 	// Run the transaction with tracing enabled.
-	vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer})
+	vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true})
 
 	// Call Prepare to clear out the statedb access list
-	statedb.Prepare(txctx.hash, txctx.block, txctx.index)
+	statedb.Prepare(txctx.TxHash, txctx.TxIndex)
 
 	result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
 	if err != nil {
diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go
index 4c0240cd2c5b3ace879414e061a3f2552fa58fa9..9afd59d596bc2231f2d252adf3911d6165e53d1a 100644
--- a/eth/tracers/api_test.go
+++ b/eth/tracers/api_test.go
@@ -161,7 +161,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
 	// Recompute transactions up to the target index.
 	signer := types.MakeSigner(b.chainConfig, block.Number())
 	for idx, tx := range block.Transactions() {
-		msg, _ := tx.AsMessage(signer)
+		msg, _ := tx.AsMessage(signer, block.BaseFee())
 		txContext := core.NewEVMTxContext(msg)
 		context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
 		if idx == txIndex {
@@ -192,13 +192,13 @@ func TestTraceCall(t *testing.T) {
 		// Transfer from account[0] to account[1]
 		//    value: 1000 wei
 		//    fee:   0 wei
-		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
+		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key)
 		b.AddTx(tx)
 	}))
 
 	var testSuite = []struct {
 		blockNumber rpc.BlockNumber
-		call        ethapi.CallArgs
+		call        ethapi.TransactionArgs
 		config      *TraceCallConfig
 		expectErr   error
 		expect      interface{}
@@ -206,7 +206,7 @@ func TestTraceCall(t *testing.T) {
 		// Standard JSON trace upon the genesis, plain transfer.
 		{
 			blockNumber: rpc.BlockNumber(0),
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &accounts[0].addr,
 				To:    &accounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -223,7 +223,7 @@ func TestTraceCall(t *testing.T) {
 		// Standard JSON trace upon the head, plain transfer.
 		{
 			blockNumber: rpc.BlockNumber(genBlocks),
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &accounts[0].addr,
 				To:    &accounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -240,7 +240,7 @@ func TestTraceCall(t *testing.T) {
 		// Standard JSON trace upon the non-existent block, error expects
 		{
 			blockNumber: rpc.BlockNumber(genBlocks + 1),
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &accounts[0].addr,
 				To:    &accounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -252,7 +252,7 @@ func TestTraceCall(t *testing.T) {
 		// Standard JSON trace upon the latest block
 		{
 			blockNumber: rpc.LatestBlockNumber,
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &accounts[0].addr,
 				To:    &accounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -269,7 +269,7 @@ func TestTraceCall(t *testing.T) {
 		// Standard JSON trace upon the pending block
 		{
 			blockNumber: rpc.PendingBlockNumber,
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &accounts[0].addr,
 				To:    &accounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -306,7 +306,7 @@ func TestTraceCall(t *testing.T) {
 	}
 }
 
-func TestOverridenTraceCall(t *testing.T) {
+func TestOverriddenTraceCall(t *testing.T) {
 	t.Parallel()
 
 	// Initialize test accounts
@@ -322,14 +322,14 @@ func TestOverridenTraceCall(t *testing.T) {
 		// Transfer from account[0] to account[1]
 		//    value: 1000 wei
 		//    fee:   0 wei
-		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
+		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key)
 		b.AddTx(tx)
 	}))
 	randomAccounts, tracer := newAccounts(3), "callTracer"
 
 	var testSuite = []struct {
 		blockNumber rpc.BlockNumber
-		call        ethapi.CallArgs
+		call        ethapi.TransactionArgs
 		config      *TraceCallConfig
 		expectErr   error
 		expect      *callTrace
@@ -337,7 +337,7 @@ func TestOverridenTraceCall(t *testing.T) {
 		// Succcessful call with state overriding
 		{
 			blockNumber: rpc.PendingBlockNumber,
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &randomAccounts[0].addr,
 				To:    &randomAccounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -361,7 +361,7 @@ func TestOverridenTraceCall(t *testing.T) {
 		// Invalid call without state overriding
 		{
 			blockNumber: rpc.PendingBlockNumber,
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From:  &randomAccounts[0].addr,
 				To:    &randomAccounts[1].addr,
 				Value: (*hexutil.Big)(big.NewInt(1000)),
@@ -369,7 +369,7 @@ func TestOverridenTraceCall(t *testing.T) {
 			config: &TraceCallConfig{
 				Tracer: &tracer,
 			},
-			expectErr: core.ErrInsufficientFundsForTransfer,
+			expectErr: core.ErrInsufficientFunds,
 			expect:    nil,
 		},
 		// Successful simple contract call
@@ -390,7 +390,7 @@ func TestOverridenTraceCall(t *testing.T) {
 		//  }
 		{
 			blockNumber: rpc.PendingBlockNumber,
-			call: ethapi.CallArgs{
+			call: ethapi.TransactionArgs{
 				From: &randomAccounts[0].addr,
 				To:   &randomAccounts[2].addr,
 				Data: newRPCBytes(common.Hex2Bytes("8381f58a")), // call number()
@@ -417,24 +417,24 @@ func TestOverridenTraceCall(t *testing.T) {
 			},
 		},
 	}
-	for _, testspec := range testSuite {
+	for i, testspec := range testSuite {
 		result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
 		if testspec.expectErr != nil {
 			if err == nil {
-				t.Errorf("Expect error %v, get nothing", testspec.expectErr)
+				t.Errorf("test %d: want error %v, have nothing", i, testspec.expectErr)
 				continue
 			}
 			if !errors.Is(err, testspec.expectErr) {
-				t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
+				t.Errorf("test %d: error mismatch, want %v, have %v", i, testspec.expectErr, err)
 			}
 		} else {
 			if err != nil {
-				t.Errorf("Expect no error, get %v", err)
+				t.Errorf("test %d: want no error, have %v", i, err)
 				continue
 			}
 			ret := new(callTrace)
 			if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
-				t.Fatalf("failed to unmarshal trace result: %v", err)
+				t.Fatalf("test %d: failed to unmarshal trace result: %v", i, err)
 			}
 			if !jsonEqual(ret, testspec.expect) {
 				// uncomment this for easier debugging
@@ -462,7 +462,7 @@ func TestTraceTransaction(t *testing.T) {
 		// Transfer from account[0] to account[1]
 		//    value: 1000 wei
 		//    fee:   0 wei
-		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
+		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key)
 		b.AddTx(tx)
 		target = tx.Hash()
 	}))
@@ -496,7 +496,7 @@ func TestTraceBlock(t *testing.T) {
 		// Transfer from account[0] to account[1]
 		//    value: 1000 wei
 		//    fee:   0 wei
-		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
+		tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key)
 		b.AddTx(tx)
 	}))
 
diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go
index ba6592537300a62b81910f4e18938e842c7ffd51..2c52761f5e4d671a5a8d7698612746dc42d0b6ae 100644
--- a/eth/tracers/tracer.go
+++ b/eth/tracers/tracer.go
@@ -310,12 +310,22 @@ type Tracer struct {
 
 	interrupt uint32 // Atomic flag to signal execution interruption
 	reason    error  // Textual reason for the interruption
+
+	activePrecompiles []common.Address // Updated on CaptureStart based on given rules
+}
+
+// Context contains some contextual infos for a transaction execution that is not
+// available from within the EVM object.
+type Context struct {
+	BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call)
+	TxIndex   int         // Index of the transaction within a block (zero if dangling tx or call)
+	TxHash    common.Hash // Hash of the transaction being traced (zero if dangling call)
 }
 
 // New instantiates a new tracer instance. code specifies a Javascript snippet,
 // which must evaluate to an expression returning an object with 'step', 'fault'
 // and 'result' functions.
-func New(code string, txCtx vm.TxContext) (*Tracer, error) {
+func New(code string, ctx *Context) (*Tracer, error) {
 	// Resolve any tracers by name and assemble the tracer object
 	if tracer, ok := tracer(code); ok {
 		code = tracer
@@ -334,8 +344,14 @@ func New(code string, txCtx vm.TxContext) (*Tracer, error) {
 		depthValue:      new(uint),
 		refundValue:     new(uint),
 	}
-	tracer.ctx["gasPrice"] = txCtx.GasPrice
+	if ctx.BlockHash != (common.Hash{}) {
+		tracer.ctx["blockHash"] = ctx.BlockHash
 
+		if ctx.TxHash != (common.Hash{}) {
+			tracer.ctx["txIndex"] = ctx.TxIndex
+			tracer.ctx["txHash"] = ctx.TxHash
+		}
+	}
 	// Set up builtins for this environment
 	tracer.vm.PushGlobalGoFunction("toHex", func(ctx *duktape.Context) int {
 		ctx.PushString(hexutil.Encode(popSlice(ctx)))
@@ -400,8 +416,14 @@ func New(code string, txCtx vm.TxContext) (*Tracer, error) {
 		return 1
 	})
 	tracer.vm.PushGlobalGoFunction("isPrecompiled", func(ctx *duktape.Context) int {
-		_, ok := vm.PrecompiledContractsIstanbul[common.BytesToAddress(popSlice(ctx))]
-		ctx.PushBoolean(ok)
+		addr := common.BytesToAddress(popSlice(ctx))
+		for _, p := range tracer.activePrecompiles {
+			if p == addr {
+				ctx.PushBoolean(true)
+				return 1
+			}
+		}
+		ctx.PushBoolean(false)
 		return 1
 	})
 	tracer.vm.PushGlobalGoFunction("slice", func(ctx *duktape.Context) int {
@@ -505,7 +527,7 @@ func (jst *Tracer) Stop(err error) {
 
 // call executes a method on a JS object, catching any errors, formatting and
 // returning them as error objects.
-func (jst *Tracer) call(method string, args ...string) (json.RawMessage, error) {
+func (jst *Tracer) call(noret bool, method string, args ...string) (json.RawMessage, error) {
 	// Execute the JavaScript call and return any error
 	jst.vm.PushString(method)
 	for _, arg := range args {
@@ -519,7 +541,21 @@ func (jst *Tracer) call(method string, args ...string) (json.RawMessage, error)
 		return nil, errors.New(err)
 	}
 	// No error occurred, extract return value and return
-	return json.RawMessage(jst.vm.JsonEncode(-1)), nil
+	if noret {
+		return nil, nil
+	}
+	// Push a JSON marshaller onto the stack. We can't marshal from the out-
+	// side because duktape can crash on large nestings and we can't catch
+	// C++ exceptions ourselves from Go. TODO(karalabe): Yuck, why wrap?!
+	jst.vm.PushString("(JSON.stringify)")
+	jst.vm.Eval()
+
+	jst.vm.Swap(-1, -2)
+	if code = jst.vm.Pcall(1); code != 0 {
+		err := jst.vm.SafeToString(-1)
+		return nil, errors.New(err)
+	}
+	return json.RawMessage(jst.vm.SafeToString(-1)), nil
 }
 
 func wrapError(context string, err error) error {
@@ -536,11 +572,16 @@ func (jst *Tracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
 	jst.ctx["to"] = to
 	jst.ctx["input"] = input
 	jst.ctx["gas"] = gas
+	jst.ctx["gasPrice"] = env.TxContext.GasPrice
 	jst.ctx["value"] = value
 
 	// Initialize the context
 	jst.ctx["block"] = env.Context.BlockNumber.Uint64()
 	jst.dbWrapper.db = env.StateDB
+	// Update list of precompiles based on current block
+	rules := env.ChainConfig().Rules(env.Context.BlockNumber)
+	jst.activePrecompiles = vm.ActivePrecompiles(rules)
+
 	// Compute intrinsic gas
 	isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
 	isIstanbul := env.ChainConfig().IsIstanbul(env.Context.BlockNumber)
@@ -578,7 +619,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
 		*jst.errorValue = err.Error()
 	}
 
-	if _, err := jst.call("step", "log", "db"); err != nil {
+	if _, err := jst.call(true, "step", "log", "db"); err != nil {
 		jst.err = wrapError("step", err)
 	}
 }
@@ -592,7 +633,7 @@ func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
 	jst.errorValue = new(string)
 	*jst.errorValue = err.Error()
 
-	if _, err := jst.call("fault", "log", "db"); err != nil {
+	if _, err := jst.call(true, "fault", "log", "db"); err != nil {
 		jst.err = wrapError("fault", err)
 	}
 }
@@ -632,6 +673,13 @@ func (jst *Tracer) GetResult() (json.RawMessage, error) {
 		case *big.Int:
 			pushBigInt(val, jst.vm)
 
+		case int:
+			jst.vm.PushInt(val)
+
+		case common.Hash:
+			ptr := jst.vm.PushFixedBuffer(32)
+			copy(makeSlice(ptr, 32), val[:])
+
 		default:
 			panic(fmt.Sprintf("unsupported type: %T", val))
 		}
@@ -640,7 +688,7 @@ func (jst *Tracer) GetResult() (json.RawMessage, error) {
 	jst.vm.PutPropString(jst.stateObject, "ctx")
 
 	// Finalize the trace and return the results
-	result, err := jst.call("result", "ctx", "db")
+	result, err := jst.call(false, "result", "ctx", "db")
 	if err != nil {
 		jst.err = wrapError("result", err)
 	}
diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go
index 7cda2e533064b16d60785cc5203022af3321c132..d2d3e57c4a57aecf50eaaefb1ef3263247bf11fd 100644
--- a/eth/tracers/tracer_test.go
+++ b/eth/tracers/tracer_test.go
@@ -39,7 +39,6 @@ func (account) SetBalance(*big.Int)                                 {}
 func (account) SetNonce(uint64)                                     {}
 func (account) Balance() *big.Int                                   { return nil }
 func (account) Address() common.Address                             { return common.Address{} }
-func (account) ReturnGas(*big.Int)                                  {}
 func (account) SetCode(common.Hash, []byte)                         {}
 func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
 
@@ -59,8 +58,8 @@ func testCtx() *vmContext {
 	return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
 }
 
-func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
-	env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
+func runTrace(tracer *Tracer, vmctx *vmContext, chaincfg *params.ChainConfig) (json.RawMessage, error) {
+	env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Debug: true, Tracer: tracer})
 	var (
 		startGas uint64 = 10000
 		value           = big.NewInt(0)
@@ -78,22 +77,25 @@ func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) {
 }
 
 func TestTracer(t *testing.T) {
-	execTracer := func(code string) []byte {
+	execTracer := func(code string) ([]byte, string) {
 		t.Helper()
-		ctx := &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
-		tracer, err := New(code, ctx.txCtx)
+		tracer, err := New(code, new(Context))
 		if err != nil {
 			t.Fatal(err)
 		}
-		ret, err := runTrace(tracer, ctx)
+		ret, err := runTrace(tracer, &vmContext{
+			blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)},
+			txCtx:    vm.TxContext{GasPrice: big.NewInt(100000)},
+		}, params.TestChainConfig)
 		if err != nil {
-			t.Fatal(err)
+			return nil, err.Error() // Stringify to allow comparison without nil checks
 		}
-		return ret
+		return ret, ""
 	}
 	for i, tt := range []struct {
 		code string
 		want string
+		fail string
 	}{
 		{ // tests that we don't panic on bad arguments to memory access
 			code: "{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}",
@@ -116,10 +118,13 @@ func TestTracer(t *testing.T) {
 		}, { // tests intrinsic gas
 			code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed+'.'+ctx.intrinsicGas; }}",
 			want: `"100000.6.21000"`,
+		}, { // tests too deep object / serialization crash
+			code: "{step: function() {}, fault: function() {}, result: function() { var o={}; var x=o; for (var i=0; i<1000; i++){	o.foo={}; o=o.foo; } return x; }}",
+			fail: "RangeError: json encode recursion limit    in server-side tracer function 'result'",
 		},
 	} {
-		if have := execTracer(tt.code); tt.want != string(have) {
-			t.Errorf("testcase %d: expected return value to be %s got %s\n\tcode: %v", i, tt.want, string(have), tt.code)
+		if have, err := execTracer(tt.code); tt.want != string(have) || tt.fail != err {
+			t.Errorf("testcase %d: expected return value to be '%s' got '%s', error to be '%s' got '%s'\n\tcode: %v", i, tt.want, string(have), tt.fail, err, tt.code)
 		}
 	}
 }
@@ -128,25 +133,21 @@ func TestHalt(t *testing.T) {
 	t.Skip("duktape doesn't support abortion")
 
 	timeout := errors.New("stahp")
-	vmctx := testCtx()
-	tracer, err := New("{step: function() { while(1); }, result: function() { return null; }}", vmctx.txCtx)
+	tracer, err := New("{step: function() { while(1); }, result: function() { return null; }}", new(Context))
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	go func() {
 		time.Sleep(1 * time.Second)
 		tracer.Stop(timeout)
 	}()
-
-	if _, err = runTrace(tracer, vmctx); err.Error() != "stahp    in server-side tracer function 'step'" {
+	if _, err = runTrace(tracer, testCtx(), params.TestChainConfig); err.Error() != "stahp    in server-side tracer function 'step'" {
 		t.Errorf("Expected timeout error, got %v", err)
 	}
 }
 
 func TestHaltBetweenSteps(t *testing.T) {
-	vmctx := testCtx()
-	tracer, err := New("{step: function() {}, fault: function() {}, result: function() { return null; }}", vmctx.txCtx)
+	tracer, err := New("{step: function() {}, fault: function() {}, result: function() { return null; }}", new(Context))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -154,7 +155,6 @@ func TestHaltBetweenSteps(t *testing.T) {
 	scope := &vm.ScopeContext{
 		Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0),
 	}
-
 	tracer.CaptureState(env, 0, 0, 0, 0, scope, nil, 0, nil)
 	timeout := errors.New("stahp")
 	tracer.Stop(timeout)
@@ -178,12 +178,14 @@ func TestNoStepExec(t *testing.T) {
 	}
 	execTracer := func(code string) []byte {
 		t.Helper()
-		ctx := &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
-		tracer, err := New(code, ctx.txCtx)
+		tracer, err := New(code, new(Context))
 		if err != nil {
 			t.Fatal(err)
 		}
-		ret, err := runEmptyTrace(tracer, ctx)
+		ret, err := runEmptyTrace(tracer, &vmContext{
+			blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)},
+			txCtx:    vm.TxContext{GasPrice: big.NewInt(100000)},
+		})
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -203,3 +205,34 @@ func TestNoStepExec(t *testing.T) {
 		}
 	}
 }
+
+func TestIsPrecompile(t *testing.T) {
+	chaincfg := &params.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP150Hash: common.Hash{}, EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(300), LondonBlock: big.NewInt(0), CatalystBlock: nil, Ethash: new(params.EthashConfig), Clique: nil}
+	chaincfg.ByzantiumBlock = big.NewInt(100)
+	chaincfg.IstanbulBlock = big.NewInt(200)
+	chaincfg.BerlinBlock = big.NewInt(300)
+	txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
+	tracer, err := New("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", new(Context))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	blockCtx := vm.BlockContext{BlockNumber: big.NewInt(150)}
+	res, err := runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
+	if err != nil {
+		t.Error(err)
+	}
+	if string(res) != "false" {
+		t.Errorf("Tracer should not consider blake2f as precompile in byzantium")
+	}
+
+	tracer, _ = New("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", new(Context))
+	blockCtx = vm.BlockContext{BlockNumber: big.NewInt(250)}
+	res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
+	if err != nil {
+		t.Error(err)
+	}
+	if string(res) != "true" {
+		t.Errorf("Tracer should consider blake2f as precompile in istanbul")
+	}
+}
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
index 9dc4c696311c0ef444cce6ade6cb19b7f313a3c4..8fbbf154b431c35a417fc67a7b9b57da37be6e96 100644
--- a/eth/tracers/tracers_test.go
+++ b/eth/tracers/tracers_test.go
@@ -173,13 +173,13 @@ func TestPrestateTracerCreate2(t *testing.T) {
 	_, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc, false)
 
 	// Create the tracer, the EVM environment and run it
-	tracer, err := New("prestateTracer", txContext)
+	tracer, err := New("prestateTracer", new(Context))
 	if err != nil {
 		t.Fatalf("failed to create call tracer: %v", err)
 	}
 	evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
 
-	msg, err := tx.AsMessage(signer)
+	msg, err := tx.AsMessage(signer, nil)
 	if err != nil {
 		t.Fatalf("failed to prepare transaction for tracing: %v", err)
 	}
@@ -248,13 +248,13 @@ func TestCallTracer(t *testing.T) {
 			_, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false)
 
 			// Create the tracer, the EVM environment and run it
-			tracer, err := New("callTracer", txContext)
+			tracer, err := New("callTracer", new(Context))
 			if err != nil {
 				t.Fatalf("failed to create call tracer: %v", err)
 			}
 			evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
 
-			msg, err := tx.AsMessage(signer)
+			msg, err := tx.AsMessage(signer, nil)
 			if err != nil {
 				t.Fatalf("failed to prepare transaction for tracing: %v", err)
 			}
@@ -300,3 +300,81 @@ func jsonEqual(x, y interface{}) bool {
 	}
 	return reflect.DeepEqual(xTrace, yTrace)
 }
+
+func BenchmarkTransactionTrace(b *testing.B) {
+	key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+	from := crypto.PubkeyToAddress(key.PublicKey)
+	gas := uint64(1000000) // 1M gas
+	to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
+	signer := types.LatestSignerForChainID(big.NewInt(1337))
+	tx, err := types.SignNewTx(key, signer,
+		&types.LegacyTx{
+			Nonce:    1,
+			GasPrice: big.NewInt(500),
+			Gas:      gas,
+			To:       &to,
+		})
+	if err != nil {
+		b.Fatal(err)
+	}
+	txContext := vm.TxContext{
+		Origin:   from,
+		GasPrice: tx.GasPrice(),
+	}
+	context := vm.BlockContext{
+		CanTransfer: core.CanTransfer,
+		Transfer:    core.Transfer,
+		Coinbase:    common.Address{},
+		BlockNumber: new(big.Int).SetUint64(uint64(5)),
+		Time:        new(big.Int).SetUint64(uint64(5)),
+		Difficulty:  big.NewInt(0xffffffff),
+		GasLimit:    gas,
+	}
+	alloc := core.GenesisAlloc{}
+	// The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns
+	// the address
+	loop := []byte{
+		byte(vm.JUMPDEST), //  [ count ]
+		byte(vm.PUSH1), 0, // jumpdestination
+		byte(vm.JUMP),
+	}
+	alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{
+		Nonce:   1,
+		Code:    loop,
+		Balance: big.NewInt(1),
+	}
+	alloc[from] = core.GenesisAccount{
+		Nonce:   1,
+		Code:    []byte{},
+		Balance: big.NewInt(500000000000000),
+	}
+	_, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc, false)
+	// Create the tracer, the EVM environment and run it
+	tracer := vm.NewStructLogger(&vm.LogConfig{
+		Debug: false,
+		//DisableStorage: true,
+		//DisableMemory: true,
+		//DisableReturnData: true,
+	})
+	evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Debug: true, Tracer: tracer})
+	msg, err := tx.AsMessage(signer, nil)
+	if err != nil {
+		b.Fatalf("failed to prepare transaction for tracing: %v", err)
+	}
+	b.ResetTimer()
+	b.ReportAllocs()
+
+	for i := 0; i < b.N; i++ {
+		snap := statedb.Snapshot()
+		st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
+		_, err = st.TransitionDb()
+		if err != nil {
+			b.Fatal(err)
+		}
+		statedb.RevertToSnapshot(snap)
+		if have, want := len(tracer.StructLogs()), 244752; have != want {
+			b.Fatalf("trace wrong, want %d steps, have %d", want, have)
+		}
+		tracer.Reset()
+	}
+}
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 40d66b6f72f91012e6bfca2affff64d9279584af..8d904a77257bf757311632fd23fe0c7ff0b44a72 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -293,17 +293,6 @@ func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*
 	return r, err
 }
 
-func toBlockNumArg(number *big.Int) string {
-	if number == nil {
-		return "latest"
-	}
-	pending := big.NewInt(-1)
-	if number.Cmp(pending) == 0 {
-		return "pending"
-	}
-	return hexutil.EncodeBig(number)
-}
-
 type rpcProgress struct {
 	StartingBlock hexutil.Uint64
 	CurrentBlock  hexutil.Uint64
@@ -471,8 +460,6 @@ func (ec *Client) PendingTransactionCount(ctx context.Context) (uint, error) {
 	return uint(num), err
 }
 
-// TODO: SubscribePendingTransactions (needs server side)
-
 // Contract Calling
 
 // CallContract executes a message call transaction, which is directly executed in the VM
@@ -511,6 +498,16 @@ func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
 	return (*big.Int)(&hex), nil
 }
 
+// SuggestGasTipCap retrieves the currently suggested gas tip cap after 1559 to
+// allow a timely execution of a transaction.
+func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
+	var hex hexutil.Big
+	if err := ec.c.CallContext(ctx, &hex, "eth_maxPriorityFeePerGas"); err != nil {
+		return nil, err
+	}
+	return (*big.Int)(&hex), nil
+}
+
 // EstimateGas tries to estimate the gas needed to execute a specific transaction based on
 // the current pending state of the backend blockchain. There is no guarantee that this is
 // the true gas limit requirement as other transactions may be added or removed by miners,
@@ -536,6 +533,17 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er
 	return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
 }
 
+func toBlockNumArg(number *big.Int) string {
+	if number == nil {
+		return "latest"
+	}
+	pending := big.NewInt(-1)
+	if number.Cmp(pending) == 0 {
+		return "pending"
+	}
+	return hexutil.EncodeBig(number)
+}
+
 func toCallArg(msg ethereum.CallMsg) interface{} {
 	arg := map[string]interface{}{
 		"from": msg.From,
diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go
index 9fa5bf87a493729309b965893fa5113be10cf358..a958c1e32ad104527a6808f178a1658a4e4c71f0 100644
--- a/ethclient/ethclient_test.go
+++ b/ethclient/ethclient_test.go
@@ -184,7 +184,7 @@ func TestToFilterArg(t *testing.T) {
 var (
 	testKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	testAddr    = crypto.PubkeyToAddress(testKey.PublicKey)
-	testBalance = big.NewInt(2e10)
+	testBalance = big.NewInt(2e15)
 )
 
 func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
@@ -220,6 +220,7 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
 		Alloc:     core.GenesisAlloc{testAddr: {Balance: testBalance}},
 		ExtraData: []byte("test genesis"),
 		Timestamp: 9000,
+		BaseFee:   big.NewInt(params.InitialBaseFee),
 	}
 	generate := func(i int, g *core.BlockGen) {
 		g.OffsetTime(5)
@@ -457,9 +458,17 @@ func testStatusFunctions(t *testing.T, client *rpc.Client) {
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	if gasPrice.Cmp(big.NewInt(1000000000)) != 0 {
+	if gasPrice.Cmp(big.NewInt(1875000000)) != 0 { // 1 gwei tip + 0.875 basefee after a 1 gwei fee empty block
 		t.Fatalf("unexpected gas price: %v", gasPrice)
 	}
+	// SuggestGasTipCap (should suggest 1 Gwei)
+	gasTipCap, err := ec.SuggestGasTipCap(context.Background())
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	if gasTipCap.Cmp(big.NewInt(1000000000)) != 0 {
+		t.Fatalf("unexpected gas tip cap: %v", gasTipCap)
+	}
 }
 
 func testCallContract(t *testing.T, client *rpc.Client) {
@@ -467,11 +476,10 @@ func testCallContract(t *testing.T, client *rpc.Client) {
 
 	// EstimateGas
 	msg := ethereum.CallMsg{
-		From:     testAddr,
-		To:       &common.Address{},
-		Gas:      21000,
-		GasPrice: big.NewInt(1),
-		Value:    big.NewInt(1),
+		From:  testAddr,
+		To:    &common.Address{},
+		Gas:   21000,
+		Value: big.NewInt(1),
 	}
 	gas, err := ec.EstimateGas(context.Background(), msg)
 	if err != nil {
@@ -560,7 +568,7 @@ func sendTransaction(ec *Client) error {
 		return err
 	}
 	// Create transaction
-	tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1), 22000, big.NewInt(1), nil)
+	tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1), 22000, big.NewInt(params.InitialBaseFee), nil)
 	signer := types.LatestSignerForChainID(chainID)
 	signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
 	if err != nil {
diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go
new file mode 100644
index 0000000000000000000000000000000000000000..538e23727dbbbd7a51b1d095bdb8137374a38cdd
--- /dev/null
+++ b/ethclient/gethclient/gethclient.go
@@ -0,0 +1,235 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// Package gethclient provides an RPC client for geth-specific APIs.
+package gethclient
+
+import (
+	"context"
+	"math/big"
+	"runtime"
+	"runtime/debug"
+
+	"github.com/ethereum/go-ethereum"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/p2p"
+	"github.com/ethereum/go-ethereum/rpc"
+)
+
+// Client is a wrapper around rpc.Client that implements geth-specific functionality.
+//
+// If you want to use the standardized Ethereum RPC functionality, use ethclient.Client instead.
+type Client struct {
+	c *rpc.Client
+}
+
+// New creates a client that uses the given RPC client.
+func New(c *rpc.Client) *Client {
+	return &Client{c}
+}
+
+// CreateAccessList tries to create an access list for a specific transaction based on the
+// current pending state of the blockchain.
+func (ec *Client) CreateAccessList(ctx context.Context, msg ethereum.CallMsg) (*types.AccessList, uint64, string, error) {
+	type accessListResult struct {
+		Accesslist *types.AccessList `json:"accessList"`
+		Error      string            `json:"error,omitempty"`
+		GasUsed    hexutil.Uint64    `json:"gasUsed"`
+	}
+	var result accessListResult
+	if err := ec.c.CallContext(ctx, &result, "eth_createAccessList", toCallArg(msg)); err != nil {
+		return nil, 0, "", err
+	}
+	return result.Accesslist, uint64(result.GasUsed), result.Error, nil
+}
+
+// AccountResult is the result of a GetProof operation.
+type AccountResult struct {
+	Address      common.Address  `json:"address"`
+	AccountProof []string        `json:"accountProof"`
+	Balance      *big.Int        `json:"balance"`
+	CodeHash     common.Hash     `json:"codeHash"`
+	Nonce        uint64          `json:"nonce"`
+	StorageHash  common.Hash     `json:"storageHash"`
+	StorageProof []StorageResult `json:"storageProof"`
+}
+
+// StorageResult provides a proof for a key-value pair.
+type StorageResult struct {
+	Key   string   `json:"key"`
+	Value *big.Int `json:"value"`
+	Proof []string `json:"proof"`
+}
+
+// GetProof returns the account and storage values of the specified account including the Merkle-proof.
+// The block number can be nil, in which case the value is taken from the latest known block.
+func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []string, blockNumber *big.Int) (*AccountResult, error) {
+
+	type storageResult struct {
+		Key   string       `json:"key"`
+		Value *hexutil.Big `json:"value"`
+		Proof []string     `json:"proof"`
+	}
+
+	type accountResult struct {
+		Address      common.Address  `json:"address"`
+		AccountProof []string        `json:"accountProof"`
+		Balance      *hexutil.Big    `json:"balance"`
+		CodeHash     common.Hash     `json:"codeHash"`
+		Nonce        hexutil.Uint64  `json:"nonce"`
+		StorageHash  common.Hash     `json:"storageHash"`
+		StorageProof []storageResult `json:"storageProof"`
+	}
+
+	var res accountResult
+	err := ec.c.CallContext(ctx, &res, "eth_getProof", account, keys, toBlockNumArg(blockNumber))
+	// Turn hexutils back to normal datatypes
+	storageResults := make([]StorageResult, 0, len(res.StorageProof))
+	for _, st := range res.StorageProof {
+		storageResults = append(storageResults, StorageResult{
+			Key:   st.Key,
+			Value: st.Value.ToInt(),
+			Proof: st.Proof,
+		})
+	}
+	result := AccountResult{
+		Address:      res.Address,
+		AccountProof: res.AccountProof,
+		Balance:      res.Balance.ToInt(),
+		Nonce:        uint64(res.Nonce),
+		CodeHash:     res.CodeHash,
+		StorageHash:  res.StorageHash,
+	}
+	return &result, err
+}
+
+// OverrideAccount specifies the state of an account to be overridden.
+type OverrideAccount struct {
+	Nonce     uint64                      `json:"nonce"`
+	Code      []byte                      `json:"code"`
+	Balance   *big.Int                    `json:"balance"`
+	State     map[common.Hash]common.Hash `json:"state"`
+	StateDiff map[common.Hash]common.Hash `json:"stateDiff"`
+}
+
+// CallContract executes a message call transaction, which is directly executed in the VM
+// of the node, but never mined into the blockchain.
+//
+// blockNumber selects the block height at which the call runs. It can be nil, in which
+// case the code is taken from the latest known block. Note that state from very old
+// blocks might not be available.
+//
+// overrides specifies a map of contract states that should be overwritten before executing
+// the message call.
+// Please use ethclient.CallContract instead if you don't need the override functionality.
+func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int, overrides *map[common.Address]OverrideAccount) ([]byte, error) {
+	var hex hexutil.Bytes
+	err := ec.c.CallContext(
+		ctx, &hex, "eth_call", toCallArg(msg),
+		toBlockNumArg(blockNumber), toOverrideMap(overrides),
+	)
+	return hex, err
+}
+
+// GCStats retrieves the current garbage collection stats from a geth node.
+func (ec *Client) GCStats(ctx context.Context) (*debug.GCStats, error) {
+	var result debug.GCStats
+	err := ec.c.CallContext(ctx, &result, "debug_gcStats")
+	return &result, err
+}
+
+// MemStats retrieves the current memory stats from a geth node.
+func (ec *Client) MemStats(ctx context.Context) (*runtime.MemStats, error) {
+	var result runtime.MemStats
+	err := ec.c.CallContext(ctx, &result, "debug_memStats")
+	return &result, err
+}
+
+// SetHead sets the current head of the local chain by block number.
+// Note, this is a destructive action and may severely damage your chain.
+// Use with extreme caution.
+func (ec *Client) SetHead(ctx context.Context, number *big.Int) error {
+	return ec.c.CallContext(ctx, nil, "debug_setHead", toBlockNumArg(number))
+}
+
+// GetNodeInfo retrieves the node info of a geth node.
+func (ec *Client) GetNodeInfo(ctx context.Context) (*p2p.NodeInfo, error) {
+	var result p2p.NodeInfo
+	err := ec.c.CallContext(ctx, &result, "admin_nodeInfo")
+	return &result, err
+}
+
+// SubscribePendingTransactions subscribes to new pending transactions.
+func (ec *Client) SubscribePendingTransactions(ctx context.Context, ch chan<- common.Hash) (*rpc.ClientSubscription, error) {
+	return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions")
+}
+
+func toBlockNumArg(number *big.Int) string {
+	if number == nil {
+		return "latest"
+	}
+	pending := big.NewInt(-1)
+	if number.Cmp(pending) == 0 {
+		return "pending"
+	}
+	return hexutil.EncodeBig(number)
+}
+
+func toCallArg(msg ethereum.CallMsg) interface{} {
+	arg := map[string]interface{}{
+		"from": msg.From,
+		"to":   msg.To,
+	}
+	if len(msg.Data) > 0 {
+		arg["data"] = hexutil.Bytes(msg.Data)
+	}
+	if msg.Value != nil {
+		arg["value"] = (*hexutil.Big)(msg.Value)
+	}
+	if msg.Gas != 0 {
+		arg["gas"] = hexutil.Uint64(msg.Gas)
+	}
+	if msg.GasPrice != nil {
+		arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
+	}
+	return arg
+}
+
+func toOverrideMap(overrides *map[common.Address]OverrideAccount) interface{} {
+	if overrides == nil {
+		return nil
+	}
+	type overrideAccount struct {
+		Nonce     hexutil.Uint64              `json:"nonce"`
+		Code      hexutil.Bytes               `json:"code"`
+		Balance   *hexutil.Big                `json:"balance"`
+		State     map[common.Hash]common.Hash `json:"state"`
+		StateDiff map[common.Hash]common.Hash `json:"stateDiff"`
+	}
+	result := make(map[common.Address]overrideAccount)
+	for addr, override := range *overrides {
+		result[addr] = overrideAccount{
+			Nonce:     hexutil.Uint64(override.Nonce),
+			Code:      override.Code,
+			Balance:   (*hexutil.Big)(override.Balance),
+			State:     override.State,
+			StateDiff: override.StateDiff,
+		}
+	}
+	return &result
+}
diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c0b9d0c2d09930ca7739864266ee601b83cb2d31
--- /dev/null
+++ b/ethclient/gethclient/gethclient_test.go
@@ -0,0 +1,305 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package gethclient
+
+import (
+	"bytes"
+	"context"
+	"math/big"
+	"testing"
+
+	"github.com/ethereum/go-ethereum"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/consensus/ethash"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/core/rawdb"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/eth"
+	"github.com/ethereum/go-ethereum/eth/ethconfig"
+	"github.com/ethereum/go-ethereum/ethclient"
+	"github.com/ethereum/go-ethereum/node"
+	"github.com/ethereum/go-ethereum/params"
+	"github.com/ethereum/go-ethereum/rpc"
+)
+
+var (
+	testKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+	testAddr    = crypto.PubkeyToAddress(testKey.PublicKey)
+	testBalance = big.NewInt(2e15)
+)
+
+func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
+	// Generate test chain.
+	genesis, blocks := generateTestChain()
+	// Create node
+	n, err := node.New(&node.Config{})
+	if err != nil {
+		t.Fatalf("can't create new node: %v", err)
+	}
+	// Create Ethereum Service
+	config := &ethconfig.Config{Genesis: genesis}
+	config.Ethash.PowMode = ethash.ModeFake
+	ethservice, err := eth.New(n, config)
+	if err != nil {
+		t.Fatalf("can't create new ethereum service: %v", err)
+	}
+	// Import the test chain.
+	if err := n.Start(); err != nil {
+		t.Fatalf("can't start test node: %v", err)
+	}
+	if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
+		t.Fatalf("can't import test blocks: %v", err)
+	}
+	return n, blocks
+}
+
+func generateTestChain() (*core.Genesis, []*types.Block) {
+	db := rawdb.NewMemoryDatabase()
+	config := params.AllEthashProtocolChanges
+	genesis := &core.Genesis{
+		Config:    config,
+		Alloc:     core.GenesisAlloc{testAddr: {Balance: testBalance}},
+		ExtraData: []byte("test genesis"),
+		Timestamp: 9000,
+	}
+	generate := func(i int, g *core.BlockGen) {
+		g.OffsetTime(5)
+		g.SetExtra([]byte("test"))
+	}
+	gblock := genesis.ToBlock(db)
+	engine := ethash.NewFaker()
+	blocks, _ := core.GenerateChain(config, gblock, engine, db, 1, generate)
+	blocks = append([]*types.Block{gblock}, blocks...)
+	return genesis, blocks
+}
+
+func TestGethClient(t *testing.T) {
+	backend, _ := newTestBackend(t)
+	client, err := backend.Attach()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer backend.Close()
+	defer client.Close()
+
+	tests := map[string]struct {
+		test func(t *testing.T)
+	}{
+		"TestAccessList": {
+			func(t *testing.T) { testAccessList(t, client) },
+		},
+		"TestGetProof": {
+			func(t *testing.T) { testGetProof(t, client) },
+		},
+		"TestGCStats": {
+			func(t *testing.T) { testGCStats(t, client) },
+		},
+		"TestMemStats": {
+			func(t *testing.T) { testMemStats(t, client) },
+		},
+		"TestGetNodeInfo": {
+			func(t *testing.T) { testGetNodeInfo(t, client) },
+		},
+		"TestSetHead": {
+			func(t *testing.T) { testSetHead(t, client) },
+		},
+		"TestSubscribePendingTxs": {
+			func(t *testing.T) { testSubscribePendingTransactions(t, client) },
+		},
+		"TestCallContract": {
+			func(t *testing.T) { testCallContract(t, client) },
+		},
+	}
+	t.Parallel()
+	for name, tt := range tests {
+		t.Run(name, tt.test)
+	}
+}
+
+func testAccessList(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	// Test transfer
+	msg := ethereum.CallMsg{
+		From:     testAddr,
+		To:       &common.Address{},
+		Gas:      21000,
+		GasPrice: big.NewInt(765625000),
+		Value:    big.NewInt(1),
+	}
+	al, gas, vmErr, err := ec.CreateAccessList(context.Background(), msg)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	if vmErr != "" {
+		t.Fatalf("unexpected vm error: %v", vmErr)
+	}
+	if gas != 21000 {
+		t.Fatalf("unexpected gas used: %v", gas)
+	}
+	if len(*al) != 0 {
+		t.Fatalf("unexpected length of accesslist: %v", len(*al))
+	}
+	// Test reverting transaction
+	msg = ethereum.CallMsg{
+		From:     testAddr,
+		To:       nil,
+		Gas:      100000,
+		GasPrice: big.NewInt(1000000000),
+		Value:    big.NewInt(1),
+		Data:     common.FromHex("0x608060806080608155fd"),
+	}
+	al, gas, vmErr, err = ec.CreateAccessList(context.Background(), msg)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	if vmErr == "" {
+		t.Fatalf("wanted vmErr, got none")
+	}
+	if gas == 21000 {
+		t.Fatalf("unexpected gas used: %v", gas)
+	}
+	if len(*al) != 1 || al.StorageKeys() != 1 {
+		t.Fatalf("unexpected length of accesslist: %v", len(*al))
+	}
+	// address changes between calls, so we can't test for it.
+	if (*al)[0].Address == common.HexToAddress("0x0") {
+		t.Fatalf("unexpected address: %v", (*al)[0].Address)
+	}
+	if (*al)[0].StorageKeys[0] != common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000081") {
+		t.Fatalf("unexpected storage key: %v", (*al)[0].StorageKeys[0])
+	}
+}
+
+func testGetProof(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	ethcl := ethclient.NewClient(client)
+	result, err := ec.GetProof(context.Background(), testAddr, []string{}, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(result.Address[:], testAddr[:]) {
+		t.Fatalf("unexpected address, want: %v got: %v", testAddr, result.Address)
+	}
+	// test nonce
+	nonce, _ := ethcl.NonceAt(context.Background(), result.Address, nil)
+	if result.Nonce != nonce {
+		t.Fatalf("invalid nonce, want: %v got: %v", nonce, result.Nonce)
+	}
+	// test balance
+	balance, _ := ethcl.BalanceAt(context.Background(), result.Address, nil)
+	if result.Balance.Cmp(balance) != 0 {
+		t.Fatalf("invalid balance, want: %v got: %v", balance, result.Balance)
+	}
+}
+
+func testGCStats(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	_, err := ec.GCStats(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func testMemStats(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	stats, err := ec.MemStats(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+	if stats.Alloc == 0 {
+		t.Fatal("Invalid mem stats retrieved")
+	}
+}
+
+func testGetNodeInfo(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	info, err := ec.GetNodeInfo(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if info.Name == "" {
+		t.Fatal("Invalid node info retrieved")
+	}
+}
+
+func testSetHead(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	err := ec.SetHead(context.Background(), big.NewInt(0))
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func testSubscribePendingTransactions(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	ethcl := ethclient.NewClient(client)
+	// Subscribe to Transactions
+	ch := make(chan common.Hash)
+	ec.SubscribePendingTransactions(context.Background(), ch)
+	// Send a transaction
+	chainID, err := ethcl.ChainID(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Create transaction
+	tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1), 22000, big.NewInt(1), nil)
+	signer := types.LatestSignerForChainID(chainID)
+	signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
+	if err != nil {
+		t.Fatal(err)
+	}
+	signedTx, err := tx.WithSignature(signer, signature)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Send transaction
+	err = ethcl.SendTransaction(context.Background(), signedTx)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Check that the transaction was send over the channel
+	hash := <-ch
+	if hash != signedTx.Hash() {
+		t.Fatalf("Invalid tx hash received, got %v, want %v", hash, signedTx.Hash())
+	}
+}
+
+func testCallContract(t *testing.T, client *rpc.Client) {
+	ec := New(client)
+	msg := ethereum.CallMsg{
+		From:     testAddr,
+		To:       &common.Address{},
+		Gas:      21000,
+		GasPrice: big.NewInt(1000000000),
+		Value:    big.NewInt(1),
+	}
+	// CallContract without override
+	if _, err := ec.CallContract(context.Background(), msg, big.NewInt(0), nil); err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	// CallContract with override
+	override := OverrideAccount{
+		Nonce: 1,
+	}
+	mapAcc := make(map[common.Address]OverrideAccount)
+	mapAcc[testAddr] = override
+	if _, err := ec.CallContract(context.Background(), msg, big.NewInt(0), &mapAcc); err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+}
diff --git a/ethdb/database.go b/ethdb/database.go
index e90f023fbdfc06c92c05b425d7ba5e07f06608ad..4ccfe0f7fd523e6bd8b7004b3d2bc030bd37e715 100644
--- a/ethdb/database.go
+++ b/ethdb/database.go
@@ -76,6 +76,13 @@ type AncientReader interface {
 	// Ancient retrieves an ancient binary blob from the append-only immutable files.
 	Ancient(kind string, number uint64) ([]byte, error)
 
+	// ReadAncients retrieves multiple items in sequence, starting from the index 'start'.
+	// It will return
+	//  - at most 'count' items,
+	//  - at least 1 item (even if exceeding the maxBytes), but will otherwise
+	//   return as many items as fit into maxBytes.
+	ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error)
+
 	// Ancients returns the ancient item numbers in the ancient store.
 	Ancients() (uint64, error)
 
diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go
index c7acb9481c547bf28878fbe97437f66df02796db..148359110c04802239cae4b1bbb4727905332c34 100644
--- a/ethstats/ethstats.go
+++ b/ethstats/ethstats.go
@@ -24,7 +24,6 @@ import (
 	"fmt"
 	"math/big"
 	"net/http"
-	"regexp"
 	"runtime"
 	"strconv"
 	"strings"
@@ -78,7 +77,7 @@ type fullNodeBackend interface {
 	Miner() *miner.Miner
 	BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
 	CurrentBlock() *types.Block
-	SuggestPrice(ctx context.Context) (*big.Int, error)
+	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
 }
 
 // Service implements an Ethereum netstats reporting daemon that pushes local
@@ -144,21 +143,43 @@ func (w *connWrapper) Close() error {
 	return w.conn.Close()
 }
 
+// parseEthstatsURL parses the netstats connection url.
+// URL argument should be of the form <nodename:secret@host:port>
+// If non-erroring, the returned slice contains 3 elements: [nodename, pass, host]
+func parseEthstatsURL(url string) (parts []string, err error) {
+	err = fmt.Errorf("invalid netstats url: \"%s\", should be nodename:secret@host:port", url)
+
+	hostIndex := strings.LastIndex(url, "@")
+	if hostIndex == -1 || hostIndex == len(url)-1 {
+		return nil, err
+	}
+	preHost, host := url[:hostIndex], url[hostIndex+1:]
+
+	passIndex := strings.LastIndex(preHost, ":")
+	if passIndex == -1 {
+		return []string{preHost, "", host}, nil
+	}
+	nodename, pass := preHost[:passIndex], ""
+	if passIndex != len(preHost)-1 {
+		pass = preHost[passIndex+1:]
+	}
+
+	return []string{nodename, pass, host}, nil
+}
+
 // New returns a monitoring service ready for stats reporting.
 func New(node *node.Node, backend backend, engine consensus.Engine, url string) error {
-	// Parse the netstats connection url
-	re := regexp.MustCompile("([^:@]*)(:([^@]*))?@(.+)")
-	parts := re.FindStringSubmatch(url)
-	if len(parts) != 5 {
-		return fmt.Errorf("invalid netstats url: \"%s\", should be nodename:secret@host:port", url)
+	parts, err := parseEthstatsURL(url)
+	if err != nil {
+		return err
 	}
 	ethstats := &Service{
 		backend: backend,
 		engine:  engine,
 		server:  node.Server(),
-		node:    parts[1],
-		pass:    parts[3],
-		host:    parts[4],
+		node:    parts[0],
+		pass:    parts[1],
+		host:    parts[2],
 		pongCh:  make(chan struct{}),
 		histCh:  make(chan []uint64, 1),
 	}
@@ -332,7 +353,7 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core
 // it, if they themselves are requests it initiates a reply, and lastly it drops
 // unknown packets.
 func (s *Service) readLoop(conn *connWrapper) {
-	// If the read loop exists, close the connection
+	// If the read loop exits, close the connection
 	defer conn.Close()
 
 	for {
@@ -759,8 +780,11 @@ func (s *Service) reportStats(conn *connWrapper) error {
 		sync := fullBackend.Downloader().Progress()
 		syncing = fullBackend.CurrentHeader().Number.Uint64() >= sync.HighestBlock
 
-		price, _ := fullBackend.SuggestPrice(context.Background())
+		price, _ := fullBackend.SuggestGasTipCap(context.Background())
 		gasprice = int(price.Uint64())
+		if basefee := fullBackend.CurrentHeader().BaseFee; basefee != nil {
+			gasprice += int(basefee.Uint64())
+		}
 	} else {
 		sync := s.backend.Downloader().Progress()
 		syncing = s.backend.CurrentHeader().Number.Uint64() >= sync.HighestBlock
diff --git a/ethstats/ethstats_test.go b/ethstats/ethstats_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..92cec50c4d31525ec3b80fcde280637adb90bc49
--- /dev/null
+++ b/ethstats/ethstats_test.go
@@ -0,0 +1,67 @@
+package ethstats
+
+import (
+	"strconv"
+	"testing"
+)
+
+func TestParseEthstatsURL(t *testing.T) {
+	cases := []struct {
+		url              string
+		node, pass, host string
+	}{
+		{
+			url:  `"debug meowsbits":mypass@ws://mordor.dash.fault.dev:3000`,
+			node: "debug meowsbits", pass: "mypass", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `"debug @meowsbits":mypass@ws://mordor.dash.fault.dev:3000`,
+			node: "debug @meowsbits", pass: "mypass", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `"debug: @meowsbits":mypass@ws://mordor.dash.fault.dev:3000`,
+			node: "debug: @meowsbits", pass: "mypass", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `name:@ws://mordor.dash.fault.dev:3000`,
+			node: "name", pass: "", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `name@ws://mordor.dash.fault.dev:3000`,
+			node: "name", pass: "", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `:mypass@ws://mordor.dash.fault.dev:3000`,
+			node: "", pass: "mypass", host: "ws://mordor.dash.fault.dev:3000",
+		},
+		{
+			url:  `:@ws://mordor.dash.fault.dev:3000`,
+			node: "", pass: "", host: "ws://mordor.dash.fault.dev:3000",
+		},
+	}
+
+	for i, c := range cases {
+		parts, err := parseEthstatsURL(c.url)
+		if err != nil {
+			t.Fatal(err)
+		}
+		node, pass, host := parts[0], parts[1], parts[2]
+
+		// unquote because the value provided will be used as a CLI flag value, so unescaped quotes will be removed
+		nodeUnquote, err := strconv.Unquote(node)
+		if err == nil {
+			node = nodeUnquote
+		}
+
+		if node != c.node {
+			t.Errorf("case=%d mismatch node value, got: %v ,want: %v", i, node, c.node)
+		}
+		if pass != c.pass {
+			t.Errorf("case=%d mismatch pass value, got: %v ,want: %v", i, pass, c.pass)
+		}
+		if host != c.host {
+			t.Errorf("case=%d mismatch host value, got: %v ,want: %v", i, host, c.host)
+		}
+	}
+
+}
diff --git a/go.mod b/go.mod
index 28e0db5d6fd7c93c78d824809aa5a12f2c61a565..ecc1a957fea9a330048e08e6b6144811a909ddeb 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
 	github.com/Azure/azure-storage-blob-go v0.7.0
 	github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
 	github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
-	github.com/VictoriaMetrics/fastcache v1.5.7
+	github.com/VictoriaMetrics/fastcache v1.6.0
 	github.com/aws/aws-sdk-go-v2 v1.2.0
 	github.com/aws/aws-sdk-go-v2/config v1.1.1
 	github.com/aws/aws-sdk-go-v2/credentials v1.1.1
@@ -18,6 +18,7 @@ require (
 	github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f
 	github.com/davecgh/go-spew v1.1.1
 	github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea
+	github.com/deepmap/oapi-codegen v1.8.2 // indirect
 	github.com/dlclark/regexp2 v1.2.0 // indirect
 	github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
 	github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498
@@ -29,23 +30,25 @@ require (
 	github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect
 	github.com/go-stack/stack v1.8.0
 	github.com/golang/protobuf v1.4.3
-	github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3
+	github.com/golang/snappy v0.0.3
 	github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa
 	github.com/google/uuid v1.1.5
 	github.com/gorilla/websocket v1.4.2
 	github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29
 	github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
 	github.com/holiman/bloomfilter/v2 v2.0.3
-	github.com/holiman/uint256 v1.1.1
-	github.com/huin/goupnp v1.0.1-0.20210310174557-0ca763054c88
+	github.com/holiman/uint256 v1.2.0
+	github.com/huin/goupnp v1.0.2
 	github.com/influxdata/influxdb v1.8.3
+	github.com/influxdata/influxdb-client-go/v2 v2.4.0
+	github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
 	github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
 	github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
 	github.com/julienschmidt/httprouter v1.2.0
 	github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356
 	github.com/kylelemons/godebug v1.1.0 // indirect
-	github.com/mattn/go-colorable v0.1.0
-	github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035
+	github.com/mattn/go-colorable v0.1.8
+	github.com/mattn/go-isatty v0.0.12
 	github.com/naoina/go-stringutil v0.1.0 // indirect
 	github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
 	github.com/olekukonko/tablewriter v0.0.5
@@ -61,12 +64,14 @@ require (
 	github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
 	github.com/xsleonard/go-merkle v1.1.0
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
+	golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
-	golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988
-	golang.org/x/text v0.3.4
-	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
+	golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912
+	golang.org/x/text v0.3.6
+	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
 	gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
 	gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
 	gopkg.in/urfave/cli.v1 v1.20.0
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gotest.tools v2.2.0+incompatible // indirect
 )
diff --git a/go.sum b/go.sum
index b04a899c9fd01e6d73aa03cccc6b9419d7a790c4..fa1f86c9f4b8e58e3169c82e5ba8313bf2e807b8 100644
--- a/go.sum
+++ b/go.sum
@@ -45,8 +45,8 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
-github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
+github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
+github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
 github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -104,6 +104,7 @@ github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/
 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
 github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
 github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -111,6 +112,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
+github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
+github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
@@ -136,8 +140,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
+github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
+github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
 github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
+github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
@@ -147,6 +155,8 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
 github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug=
 github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -176,8 +186,9 @@ github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg=
-github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
@@ -200,6 +211,7 @@ github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M=
@@ -210,19 +222,24 @@ github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuW
 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
 github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
-github.com/holiman/uint256 v1.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw=
-github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
+github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huin/goupnp v1.0.1-0.20210310174557-0ca763054c88 h1:bcAj8KroPf552TScjFPIakjH2/tdIrIH8F+cc4v4SRo=
-github.com/huin/goupnp v1.0.1-0.20210310174557-0ca763054c88/go.mod h1:nNs7wvRfN1eKaMknBydLNQU6146XQim8t4h+q90biWo=
+github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI=
+github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
 github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
 github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8=
 github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
+github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k=
+github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=
 github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk=
 github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE=
+github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
+github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM=
+github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
 github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
 github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
 github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
@@ -263,18 +280,27 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
+github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
 github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
-github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
 github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw=
 github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 h1:USWjF42jDCSEeikX/G1g40ZWnsPXN5WkZ4jMHZWyBK4=
-github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
@@ -361,6 +387,7 @@ github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs=
@@ -373,6 +400,9 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF
 github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
 github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
 github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
 github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg=
@@ -393,6 +423,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -426,7 +458,6 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -441,10 +472,13 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -466,6 +500,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -473,33 +508,46 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988 h1:EjgCl+fVlIaPJSori0ikSz3uV0DOHKWOJFpv1sAAhBM=
+golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU=
+golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
 golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -595,8 +643,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
diff --git a/graphql/graphql.go b/graphql/graphql.go
index b1af7675bdf5326b6f57f67541ba767d53931b49..d35994234ea576cd0ad82d05ad086c1511590caf 100644
--- a/graphql/graphql.go
+++ b/graphql/graphql.go
@@ -21,16 +21,16 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"math/big"
 	"strconv"
 	"time"
 
 	"github.com/ethereum/go-ethereum"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
-	"github.com/ethereum/go-ethereum/core/rawdb"
+	"github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/eth/filters"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/rpc"
@@ -93,7 +93,11 @@ func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) {
 	if err != nil {
 		return hexutil.Big{}, err
 	}
-	return hexutil.Big(*state.GetBalance(a.address)), nil
+	balance := state.GetBalance(a.address)
+	if balance == nil {
+		return hexutil.Big{}, fmt.Errorf("failed to load balance %x", a.address)
+	}
+	return hexutil.Big(*balance), nil
 }
 
 func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) {
@@ -178,8 +182,9 @@ type Transaction struct {
 // resolve returns the internal transaction object, fetching it if needed.
 func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) {
 	if t.tx == nil {
-		tx, blockHash, _, index := rawdb.ReadTransaction(t.backend.ChainDb(), t.hash)
-		if tx != nil {
+		// Try to return an already finalized transaction
+		tx, blockHash, _, index, err := t.backend.GetTransaction(ctx, t.hash)
+		if err == nil && tx != nil {
 			t.tx = tx
 			blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false)
 			t.block = &Block{
@@ -187,9 +192,10 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) {
 				numberOrHash: &blockNrOrHash,
 			}
 			t.index = index
-		} else {
-			t.tx = t.backend.GetPoolTransaction(t.hash)
+			return t.tx, nil
 		}
+		// No finalized transaction, try to retrieve it from the pool
+		t.tx = t.backend.GetPoolTransaction(t.hash)
 	}
 	return t.tx, nil
 }
@@ -219,7 +225,65 @@ func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) {
 	if err != nil || tx == nil {
 		return hexutil.Big{}, err
 	}
-	return hexutil.Big(*tx.GasPrice()), nil
+	switch tx.Type() {
+	case types.AccessListTxType:
+		return hexutil.Big(*tx.GasPrice()), nil
+	case types.DynamicFeeTxType:
+		if t.block != nil {
+			if baseFee, _ := t.block.BaseFeePerGas(ctx); baseFee != nil {
+				// price = min(tip, gasFeeCap - baseFee) + baseFee
+				return (hexutil.Big)(*math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee.ToInt()), tx.GasFeeCap())), nil
+			}
+		}
+		return hexutil.Big(*tx.GasPrice()), nil
+	default:
+		return hexutil.Big(*tx.GasPrice()), nil
+	}
+}
+
+func (t *Transaction) EffectiveGasPrice(ctx context.Context) (*hexutil.Big, error) {
+	tx, err := t.resolve(ctx)
+	if err != nil || tx == nil {
+		return nil, err
+	}
+	header, err := t.block.resolveHeader(ctx)
+	if err != nil || header == nil {
+		return nil, err
+	}
+	if header.BaseFee == nil {
+		return (*hexutil.Big)(tx.GasPrice()), nil
+	}
+	return (*hexutil.Big)(math.BigMin(new(big.Int).Add(tx.GasTipCap(), header.BaseFee), tx.GasFeeCap())), nil
+}
+
+func (t *Transaction) MaxFeePerGas(ctx context.Context) (*hexutil.Big, error) {
+	tx, err := t.resolve(ctx)
+	if err != nil || tx == nil {
+		return nil, err
+	}
+	switch tx.Type() {
+	case types.AccessListTxType:
+		return nil, nil
+	case types.DynamicFeeTxType:
+		return (*hexutil.Big)(tx.GasFeeCap()), nil
+	default:
+		return nil, nil
+	}
+}
+
+func (t *Transaction) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) {
+	tx, err := t.resolve(ctx)
+	if err != nil || tx == nil {
+		return nil, err
+	}
+	switch tx.Type() {
+	case types.AccessListTxType:
+		return nil, nil
+	case types.DynamicFeeTxType:
+		return (*hexutil.Big)(tx.GasTipCap()), nil
+	default:
+		return nil, nil
+	}
 }
 
 func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) {
@@ -227,6 +291,9 @@ func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) {
 	if err != nil || tx == nil {
 		return hexutil.Big{}, err
 	}
+	if tx.Value() == nil {
+		return hexutil.Big{}, fmt.Errorf("invalid transaction value %x", t.hash)
+	}
 	return hexutil.Big(*tx.Value()), nil
 }
 
@@ -518,6 +585,17 @@ func (b *Block) GasUsed(ctx context.Context) (Long, error) {
 	return Long(header.GasUsed), nil
 }
 
+func (b *Block) BaseFeePerGas(ctx context.Context) (*hexutil.Big, error) {
+	header, err := b.resolveHeader(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if header.BaseFee == nil {
+		return nil, nil
+	}
+	return (*hexutil.Big)(header.BaseFee), nil
+}
+
 func (b *Block) Parent(ctx context.Context) (*Block, error) {
 	// If the block header hasn't been fetched, and we'll need it, fetch it.
 	if b.numberOrHash == nil && b.header == nil {
@@ -651,7 +729,11 @@ func (b *Block) TotalDifficulty(ctx context.Context) (hexutil.Big, error) {
 		}
 		h = header.Hash()
 	}
-	return hexutil.Big(*b.backend.GetTd(ctx, h)), nil
+	td := b.backend.GetTd(ctx, h)
+	if td == nil {
+		return hexutil.Big{}, fmt.Errorf("total difficulty not found %x", b.hash)
+	}
+	return hexutil.Big(*td), nil
 }
 
 // BlockNumberArgs encapsulates arguments to accessors that specify a block number.
@@ -834,12 +916,14 @@ func (b *Block) Account(ctx context.Context, args struct {
 // CallData encapsulates arguments to `call` or `estimateGas`.
 // All arguments are optional.
 type CallData struct {
-	From     *common.Address // The Ethereum address the call is from.
-	To       *common.Address // The Ethereum address the call is to.
-	Gas      *hexutil.Uint64 // The amount of gas provided for the call.
-	GasPrice *hexutil.Big    // The price of each unit of gas, in wei.
-	Value    *hexutil.Big    // The value sent along with the call.
-	Data     *hexutil.Bytes  // Any data sent with the call.
+	From                 *common.Address // The Ethereum address the call is from.
+	To                   *common.Address // The Ethereum address the call is to.
+	Gas                  *hexutil.Uint64 // The amount of gas provided for the call.
+	GasPrice             *hexutil.Big    // The price of each unit of gas, in wei.
+	MaxFeePerGas         *hexutil.Big    // The max price of each unit of gas, in wei (1559).
+	MaxPriorityFeePerGas *hexutil.Big    // The max tip of each unit of gas, in wei (1559).
+	Value                *hexutil.Big    // The value sent along with the call.
+	Data                 *hexutil.Bytes  // Any data sent with the call.
 }
 
 // CallResult encapsulates the result of an invocation of the `call` accessor.
@@ -862,7 +946,7 @@ func (c *CallResult) Status() Long {
 }
 
 func (b *Block) Call(ctx context.Context, args struct {
-	Data ethapi.CallArgs
+	Data ethapi.TransactionArgs
 }) (*CallResult, error) {
 	if b.numberOrHash == nil {
 		_, err := b.resolve(ctx)
@@ -870,7 +954,7 @@ func (b *Block) Call(ctx context.Context, args struct {
 			return nil, err
 		}
 	}
-	result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, vm.Config{}, 5*time.Second, b.backend.RPCGasCap())
+	result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap())
 	if err != nil {
 		return nil, err
 	}
@@ -887,7 +971,7 @@ func (b *Block) Call(ctx context.Context, args struct {
 }
 
 func (b *Block) EstimateGas(ctx context.Context, args struct {
-	Data ethapi.CallArgs
+	Data ethapi.TransactionArgs
 }) (Long, error) {
 	if b.numberOrHash == nil {
 		_, err := b.resolveHeader(ctx)
@@ -937,10 +1021,10 @@ func (p *Pending) Account(ctx context.Context, args struct {
 }
 
 func (p *Pending) Call(ctx context.Context, args struct {
-	Data ethapi.CallArgs
+	Data ethapi.TransactionArgs
 }) (*CallResult, error) {
 	pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
-	result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, vm.Config{}, 5*time.Second, p.backend.RPCGasCap())
+	result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, 5*time.Second, p.backend.RPCGasCap())
 	if err != nil {
 		return nil, err
 	}
@@ -957,7 +1041,7 @@ func (p *Pending) Call(ctx context.Context, args struct {
 }
 
 func (p *Pending) EstimateGas(ctx context.Context, args struct {
-	Data ethapi.CallArgs
+	Data ethapi.TransactionArgs
 }) (Long, error) {
 	pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
 	gas, err := ethapi.DoEstimateGas(ctx, p.backend, args.Data, pendingBlockNr, p.backend.RPCGasCap())
@@ -1107,8 +1191,22 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria
 }
 
 func (r *Resolver) GasPrice(ctx context.Context) (hexutil.Big, error) {
-	price, err := r.backend.SuggestPrice(ctx)
-	return hexutil.Big(*price), err
+	tipcap, err := r.backend.SuggestGasTipCap(ctx)
+	if err != nil {
+		return hexutil.Big{}, err
+	}
+	if head := r.backend.CurrentHeader(); head.BaseFee != nil {
+		tipcap.Add(tipcap, head.BaseFee)
+	}
+	return (hexutil.Big)(*tipcap), nil
+}
+
+func (r *Resolver) MaxPriorityFeePerGas(ctx context.Context) (hexutil.Big, error) {
+	tipcap, err := r.backend.SuggestGasTipCap(ctx)
+	if err != nil {
+		return hexutil.Big{}, err
+	}
+	return (hexutil.Big)(*tipcap), nil
 }
 
 func (r *Resolver) ChainID(ctx context.Context) (hexutil.Big, error) {
diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go
index 2404ff45fa94ce6a8a483da65740bb6c25cc7fa2..4e0f099e42089d89dd05445b3f3b563a97168d0d 100644
--- a/graphql/graphql_test.go
+++ b/graphql/graphql_test.go
@@ -176,7 +176,7 @@ func TestGraphQLBlockSerializationEIP2718(t *testing.T) {
 	}{
 		{
 			body: `{"query": "{block {number transactions { from { address } to { address } value hash type accessList { address storageKeys } index}}}"}`,
-			want: `{"data":{"block":{"number":1,"transactions":[{"from":{"address":"0x71562b71999873db5b286df957af199ec94617f7"},"to":{"address":"0x0000000000000000000000000000000000000dad"},"value":"0x64","hash":"0x4f7b8d718145233dcf7f29e34a969c63dd4de8715c054ea2af022b66c4f4633e","type":0,"accessList":[],"index":0},{"from":{"address":"0x71562b71999873db5b286df957af199ec94617f7"},"to":{"address":"0x0000000000000000000000000000000000000dad"},"value":"0x32","hash":"0x9c6c2c045b618fe87add0e49ba3ca00659076ecae00fd51de3ba5d4ccf9dbf40","type":1,"accessList":[{"address":"0x0000000000000000000000000000000000000dad","storageKeys":["0x0000000000000000000000000000000000000000000000000000000000000000"]}],"index":1}]}}}`,
+			want: `{"data":{"block":{"number":1,"transactions":[{"from":{"address":"0x71562b71999873db5b286df957af199ec94617f7"},"to":{"address":"0x0000000000000000000000000000000000000dad"},"value":"0x64","hash":"0xd864c9d7d37fade6b70164740540c06dd58bb9c3f6b46101908d6339db6a6a7b","type":0,"accessList":[],"index":0},{"from":{"address":"0x71562b71999873db5b286df957af199ec94617f7"},"to":{"address":"0x0000000000000000000000000000000000000dad"},"value":"0x32","hash":"0x19b35f8187b4e15fb59a9af469dca5dfa3cd363c11d372058c12f6482477b474","type":1,"accessList":[{"address":"0x0000000000000000000000000000000000000dad","storageKeys":["0x0000000000000000000000000000000000000000000000000000000000000000"]}],"index":1}]}}}`,
 			code: 200,
 		},
 	} {
@@ -275,7 +275,7 @@ func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) {
 	// create backend
 	key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	address := crypto.PubkeyToAddress(key.PublicKey)
-	funds := big.NewInt(1000000000)
+	funds := big.NewInt(1000000000000000)
 	dad := common.HexToAddress("0x0000000000000000000000000000000000000dad")
 
 	ethConf := &ethconfig.Config{
@@ -297,6 +297,7 @@ func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) {
 					Balance: big.NewInt(0),
 				},
 			},
+			BaseFee: big.NewInt(params.InitialBaseFee),
 		},
 		Ethash: ethash.Config{
 			PowMode: ethash.ModeFake,
@@ -321,14 +322,14 @@ func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) {
 		To:       &dad,
 		Value:    big.NewInt(100),
 		Gas:      50000,
-		GasPrice: big.NewInt(1),
+		GasPrice: big.NewInt(params.InitialBaseFee),
 	})
 	envelopTx, _ := types.SignNewTx(key, signer, &types.AccessListTx{
 		ChainID:  ethConf.Genesis.Config.ChainID,
 		Nonce:    uint64(1),
 		To:       &dad,
 		Gas:      30000,
-		GasPrice: big.NewInt(1),
+		GasPrice: big.NewInt(params.InitialBaseFee),
 		Value:    big.NewInt(50),
 		AccessList: types.AccessList{{
 			Address:     dad,
diff --git a/graphql/schema.go b/graphql/schema.go
index d792bb91537da046542b9a48eadb34f4e7dea624..811c11f6cd06c8fcbdc2568beaaeab2b5a9ec33d 100644
--- a/graphql/schema.go
+++ b/graphql/schema.go
@@ -94,6 +94,10 @@ const schema string = `
         value: BigInt!
         # GasPrice is the price offered to miners for gas, in wei per unit.
         gasPrice: BigInt!
+        # MaxFeePerGas is the maximum fee per gas offered to include a transaction, in wei. 
+		maxFeePerGas: BigInt
+        # MaxPriorityFeePerGas is the maximum miner tip per gas offered to include a transaction, in wei. 
+		maxPriorityFeePerGas: BigInt
         # Gas is the maximum amount of gas this transaction can consume.
         gas: Long!
         # InputData is the data supplied to the target of the transaction.
@@ -114,6 +118,13 @@ const schema string = `
         # this transaction. If the transaction has not yet been mined, this field
         # will be null.
         cumulativeGasUsed: Long
+        # EffectiveGasPrice is actual value per gas deducted from the sender's
+        # account. Before EIP-1559, this is equal to the transaction's gas price.
+        # After EIP-1559, it is baseFeePerGas + min(maxFeePerGas - baseFeePerGas,
+        # maxPriorityFeePerGas). Legacy transactions and EIP-2930 transactions are
+        # coerced into the EIP-1559 format by setting both maxFeePerGas and
+        # maxPriorityFeePerGas as the transaction's gas price.
+        effectiveGasPrice: BigInt
         # CreatedContract is the account that was created by a contract creation
         # transaction. If the transaction was not a contract creation transaction,
         # or it has not yet been mined, this field will be null.
@@ -176,6 +187,8 @@ const schema string = `
         gasLimit: Long!
         # GasUsed is the amount of gas that was used executing transactions in this block.
         gasUsed: Long!
+        # BaseFeePerGas is the fee perunit of gas burned by the protocol in this block.
+		baseFeePerGas: BigInt
         # Timestamp is the unix timestamp at which this block was mined.
         timestamp: Long!
         # LogsBloom is a bloom filter that can be used to check if a block may
@@ -231,6 +244,10 @@ const schema string = `
         gas: Long
         # GasPrice is the price, in wei, offered for each unit of gas.
         gasPrice: BigInt
+        # MaxFeePerGas is the maximum fee per gas offered, in wei. 
+		maxFeePerGas: BigInt
+        # MaxPriorityFeePerGas is the maximum miner tip per gas offered, in wei. 
+		maxPriorityFeePerGas: BigInt
         # Value is the value, in wei, sent along with the call.
         value: BigInt
         # Data is the data sent to the callee.
@@ -319,6 +336,9 @@ const schema string = `
         # GasPrice returns the node's estimate of a gas price sufficient to
         # ensure a transaction is mined in a timely fashion.
         gasPrice: BigInt!
+        # MaxPriorityFeePerGas returns the node's estimate of a gas tip sufficient
+        # to ensure a transaction is mined in a timely fashion.
+        maxPriorityFeePerGas: BigInt!
         # Syncing returns information on the current synchronisation state.
         syncing: SyncState
         # ChainID returns the current chain ID for transaction replay protection.
diff --git a/interfaces.go b/interfaces.go
index debc5f6c052426a0c155e6f1dabc10655ad13d34..87c5ca0b7d82ddab1074cc28ec5f34253ed6a0d3 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -113,12 +113,14 @@ type ChainSyncReader interface {
 
 // CallMsg contains parameters for contract calls.
 type CallMsg struct {
-	From     common.Address  // the sender of the 'transaction'
-	To       *common.Address // the destination contract (nil for contract creation)
-	Gas      uint64          // if 0, the call executes with near-infinite gas
-	GasPrice *big.Int        // wei <-> gas exchange ratio
-	Value    *big.Int        // amount of wei sent along with the call
-	Data     []byte          // input data, usually an ABI-encoded contract method invocation
+	From      common.Address  // the sender of the 'transaction'
+	To        *common.Address // the destination contract (nil for contract creation)
+	Gas       uint64          // if 0, the call executes with near-infinite gas
+	GasPrice  *big.Int        // wei <-> gas exchange ratio
+	GasFeeCap *big.Int        // EIP-1559 fee cap per gas.
+	GasTipCap *big.Int        // EIP-1559 tip per gas.
+	Value     *big.Int        // amount of wei sent along with the call
+	Data      []byte          // input data, usually an ABI-encoded contract method invocation
 
 	AccessList types.AccessList // EIP-2930 access list.
 }
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 7f708bf436aa07a354e44faa6f5b43ca34b471e6..0c4e0170160823dddaf2605e75d0b68e37090db3 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -17,7 +17,6 @@
 package ethapi
 
 import (
-	"bytes"
 	"context"
 	"errors"
 	"fmt"
@@ -33,8 +32,10 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/common/math"
+	"github.com/ethereum/go-ethereum/consensus"
 	"github.com/ethereum/go-ethereum/consensus/clique"
 	"github.com/ethereum/go-ethereum/consensus/ethash"
+	"github.com/ethereum/go-ethereum/consensus/misc"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/rawdb"
 	"github.com/ethereum/go-ethereum/core/state"
@@ -60,10 +61,59 @@ func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI {
 	return &PublicEthereumAPI{b}
 }
 
-// GasPrice returns a suggestion for a gas price.
+// GasPrice returns a suggestion for a gas price for legacy transactions.
 func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) {
-	price, err := s.b.SuggestPrice(ctx)
-	return (*hexutil.Big)(price), err
+	tipcap, err := s.b.SuggestGasTipCap(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if head := s.b.CurrentHeader(); head.BaseFee != nil {
+		tipcap.Add(tipcap, head.BaseFee)
+	}
+	return (*hexutil.Big)(tipcap), err
+}
+
+// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
+func (s *PublicEthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) {
+	tipcap, err := s.b.SuggestGasTipCap(ctx)
+	if err != nil {
+		return nil, err
+	}
+	return (*hexutil.Big)(tipcap), err
+}
+
+type feeHistoryResult struct {
+	OldestBlock  *hexutil.Big     `json:"oldestBlock"`
+	Reward       [][]*hexutil.Big `json:"reward,omitempty"`
+	BaseFee      []*hexutil.Big   `json:"baseFeePerGas,omitempty"`
+	GasUsedRatio []float64        `json:"gasUsedRatio"`
+}
+
+func (s *PublicEthereumAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) {
+	oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, int(blockCount), lastBlock, rewardPercentiles)
+	if err != nil {
+		return nil, err
+	}
+	results := &feeHistoryResult{
+		OldestBlock:  (*hexutil.Big)(oldest),
+		GasUsedRatio: gasUsed,
+	}
+	if reward != nil {
+		results.Reward = make([][]*hexutil.Big, len(reward))
+		for i, w := range reward {
+			results.Reward[i] = make([]*hexutil.Big, len(w))
+			for j, v := range w {
+				results.Reward[i][j] = (*hexutil.Big)(v)
+			}
+		}
+	}
+	if baseFee != nil {
+		results.BaseFee = make([]*hexutil.Big, len(baseFee))
+		for i, v := range baseFee {
+			results.BaseFee[i] = (*hexutil.Big)(v)
+		}
+	}
+	return results, nil
 }
 
 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
@@ -107,12 +157,12 @@ func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransac
 		"queued":  make(map[string]map[string]*RPCTransaction),
 	}
 	pending, queue := s.b.TxPoolContent()
-
+	curHeader := s.b.CurrentHeader()
 	// Flatten the pending transactions
 	for account, txs := range pending {
 		dump := make(map[string]*RPCTransaction)
 		for _, tx := range txs {
-			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx)
+			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
 		}
 		content["pending"][account.Hex()] = dump
 	}
@@ -120,13 +170,36 @@ func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransac
 	for account, txs := range queue {
 		dump := make(map[string]*RPCTransaction)
 		for _, tx := range txs {
-			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx)
+			dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
 		}
 		content["queued"][account.Hex()] = dump
 	}
 	return content
 }
 
+// ContentFrom returns the transactions contained within the transaction pool.
+func (s *PublicTxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction {
+	content := make(map[string]map[string]*RPCTransaction, 2)
+	pending, queue := s.b.TxPoolContentFrom(addr)
+	curHeader := s.b.CurrentHeader()
+
+	// Build the pending transactions
+	dump := make(map[string]*RPCTransaction, len(pending))
+	for _, tx := range pending {
+		dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
+	}
+	content["pending"] = dump
+
+	// Build the queued transactions
+	dump = make(map[string]*RPCTransaction, len(queue))
+	for _, tx := range queue {
+		dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
+	}
+	content["queued"] = dump
+
+	return content
+}
+
 // Status returns the number of pending and queued transaction in the pool.
 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint {
 	pending, queue := s.b.Stats()
@@ -352,9 +425,9 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool {
 // signTransaction sets defaults and signs the given transaction
 // NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
 // and release it after the transaction has been submitted to the tx pool
-func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) {
+func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) {
 	// Look up the wallet containing the requested signer
-	account := accounts.Account{Address: args.From}
+	account := accounts.Account{Address: args.from()}
 	wallet, err := s.am.Find(account)
 	if err != nil {
 		return nil, err
@@ -370,18 +443,18 @@ func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArg
 }
 
 // SendTransaction will create a transaction from the given arguments and
-// tries to sign it with the key associated with args.From. If the given passwd isn't
-// able to decrypt the key it fails.
-func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
+// tries to sign it with the key associated with args.From. If the given
+// passwd isn't able to decrypt the key it fails.
+func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) {
 	if args.Nonce == nil {
 		// Hold the addresse's mutex around signing to prevent concurrent assignment of
 		// the same nonce to multiple accounts.
-		s.nonceLock.LockAddr(args.From)
-		defer s.nonceLock.UnlockAddr(args.From)
+		s.nonceLock.LockAddr(args.from())
+		defer s.nonceLock.UnlockAddr(args.from())
 	}
 	signed, err := s.signTransaction(ctx, &args, passwd)
 	if err != nil {
-		log.Warn("Failed transaction send attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err)
+		log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
 		return common.Hash{}, err
 	}
 	return SubmitTransaction(ctx, s.b, signed)
@@ -391,25 +464,29 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
 // tries to sign it with the key associated with args.From. If the given passwd isn't
 // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast
 // to other nodes
-func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) {
+func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) {
 	// No need to obtain the noncelock mutex, since we won't be sending this
 	// tx into the transaction pool, but right back to the user
+	if args.From == nil {
+		return nil, fmt.Errorf("sender not specified")
+	}
 	if args.Gas == nil {
 		return nil, fmt.Errorf("gas not specified")
 	}
-	if args.GasPrice == nil {
-		return nil, fmt.Errorf("gasPrice not specified")
+	if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) {
+		return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
 	}
 	if args.Nonce == nil {
 		return nil, fmt.Errorf("nonce not specified")
 	}
-	// Before actually sign the transaction, ensure the transaction fee is reasonable.
-	if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil {
+	// Before actually signing the transaction, ensure the transaction fee is reasonable.
+	tx := args.toTransaction()
+	if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
 		return nil, err
 	}
 	signed, err := s.signTransaction(ctx, &args, passwd)
 	if err != nil {
-		log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err)
+		log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
 		return nil, err
 	}
 	data, err := signed.MarshalBinary()
@@ -474,7 +551,7 @@ func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Byt
 
 // SignAndSendTransaction was renamed to SendTransaction. This method is deprecated
 // and will be removed in the future. It primary goal is to give clients time to update.
-func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
+func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) {
 	return s.SendTransaction(ctx, args, passwd)
 }
 
@@ -643,6 +720,7 @@ type AccountResult struct {
 	StorageHash  common.Hash     `json:"storageHash"`
 	StorageProof []StorageResult `json:"storageProof"`
 }
+
 type StorageResult struct {
 	Key   string       `json:"key"`
 	Value *hexutil.Big `json:"value"`
@@ -839,58 +917,6 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
 	return res[:], state.Error()
 }
 
-// CallArgs represents the arguments for a call.
-type CallArgs struct {
-	From       *common.Address   `json:"from"`
-	To         *common.Address   `json:"to"`
-	Gas        *hexutil.Uint64   `json:"gas"`
-	GasPrice   *hexutil.Big      `json:"gasPrice"`
-	Value      *hexutil.Big      `json:"value"`
-	Data       *hexutil.Bytes    `json:"data"`
-	AccessList *types.AccessList `json:"accessList"`
-}
-
-// ToMessage converts CallArgs to the Message type used by the core evm
-func (args *CallArgs) ToMessage(globalGasCap uint64) types.Message {
-	// Set sender address or use zero address if none specified.
-	var addr common.Address
-	if args.From != nil {
-		addr = *args.From
-	}
-
-	// Set default gas & gas price if none were set
-	gas := globalGasCap
-	if gas == 0 {
-		gas = uint64(math.MaxUint64 / 2)
-	}
-	if args.Gas != nil {
-		gas = uint64(*args.Gas)
-	}
-	if globalGasCap != 0 && globalGasCap < gas {
-		log.Debug("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
-		gas = globalGasCap
-	}
-	gasPrice := new(big.Int)
-	if args.GasPrice != nil {
-		gasPrice = args.GasPrice.ToInt()
-	}
-	value := new(big.Int)
-	if args.Value != nil {
-		value = args.Value.ToInt()
-	}
-	var data []byte
-	if args.Data != nil {
-		data = *args.Data
-	}
-	var accessList types.AccessList
-	if args.AccessList != nil {
-		accessList = *args.AccessList
-	}
-
-	msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, accessList, false)
-	return msg
-}
-
 // OverrideAccount indicates the overriding fields of account during the execution
 // of a message call.
 // Note, state and stateDiff can't be specified at the same time. If state is
@@ -943,7 +969,7 @@ func (diff *StateOverride) Apply(state *state.StateDB) error {
 	return nil
 }
 
-func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, vmCfg vm.Config, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
+func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
 	defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
 
 	state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
@@ -966,8 +992,11 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
 	defer cancel()
 
 	// Get a new instance of the EVM.
-	msg := args.ToMessage(globalGasCap)
-	evm, vmError, err := b.GetEVM(ctx, msg, state, header, nil)
+	msg, err := args.ToMessage(globalGasCap, header.BaseFee)
+	if err != nil {
+		return nil, err
+	}
+	evm, vmError, err := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true})
 	if err != nil {
 		return nil, err
 	}
@@ -1031,8 +1060,8 @@ func (e *revertError) ErrorData() interface{} {
 //
 // Note, this function doesn't make and changes in the state/blockchain and is
 // useful to execute and retrieve values.
-func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) {
-	result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, vm.Config{}, 5*time.Second, s.b.RPCGasCap())
+func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) {
+	result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, 5*time.Second, s.b.RPCGasCap())
 	if err != nil {
 		return nil, err
 	}
@@ -1043,7 +1072,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
 	return result.Return(), result.Err
 }
 
-func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) {
+func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) {
 	// Binary search the gas requirement, as it may be higher than the amount used
 	var (
 		lo  uint64 = params.TxGas - 1
@@ -1068,8 +1097,19 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
 		}
 		hi = block.GasLimit()
 	}
+	// Normalize the max fee per gas the call is willing to spend.
+	var feeCap *big.Int
+	if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
+		return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	} else if args.GasPrice != nil {
+		feeCap = args.GasPrice.ToInt()
+	} else if args.MaxFeePerGas != nil {
+		feeCap = args.MaxFeePerGas.ToInt()
+	} else {
+		feeCap = common.Big0
+	}
 	// Recap the highest gas limit with account's available balance.
-	if args.GasPrice != nil && args.GasPrice.ToInt().BitLen() != 0 {
+	if feeCap.BitLen() != 0 {
 		state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
 		if err != nil {
 			return 0, err
@@ -1082,7 +1122,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
 			}
 			available.Sub(available, args.Value.ToInt())
 		}
-		allowance := new(big.Int).Div(available, args.GasPrice.ToInt())
+		allowance := new(big.Int).Div(available, feeCap)
 
 		// If the allowance is larger than maximum uint64, skip checking
 		if allowance.IsUint64() && hi > allowance.Uint64() {
@@ -1091,7 +1131,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
 				transfer = new(hexutil.Big)
 			}
 			log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
-				"sent", transfer.ToInt(), "gasprice", args.GasPrice.ToInt(), "fundable", allowance)
+				"sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance)
 			hi = allowance.Uint64()
 		}
 	}
@@ -1106,7 +1146,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
 	executable := func(gas uint64) (bool, *core.ExecutionResult, error) {
 		args.Gas = (*hexutil.Uint64)(&gas)
 
-		result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap)
+		result, err := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap)
 		if err != nil {
 			if errors.Is(err, core.ErrIntrinsicGas) {
 				return true, nil, nil // Special case, raise gas limit
@@ -1154,7 +1194,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
 
 // EstimateGas returns an estimate of the amount of gas needed to execute the
 // given transaction against the current pending block.
-func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) {
+func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) {
 	bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
 	if blockNrOrHash != nil {
 		bNrOrHash = *blockNrOrHash
@@ -1180,7 +1220,7 @@ type StructLogRes struct {
 	Gas     uint64             `json:"gas"`
 	GasCost uint64             `json:"gasCost"`
 	Depth   int                `json:"depth"`
-	Error   error              `json:"error,omitempty"`
+	Error   string             `json:"error,omitempty"`
 	Stack   *[]string          `json:"stack,omitempty"`
 	Memory  *[]string          `json:"memory,omitempty"`
 	Storage *map[string]string `json:"storage,omitempty"`
@@ -1196,12 +1236,12 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
 			Gas:     trace.Gas,
 			GasCost: trace.GasCost,
 			Depth:   trace.Depth,
-			Error:   trace.Err,
+			Error:   trace.ErrorString(),
 		}
 		if trace.Stack != nil {
 			stack := make([]string, len(trace.Stack))
 			for i, stackValue := range trace.Stack {
-				stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32))
+				stack[i] = stackValue.Hex()
 			}
 			formatted[index].Stack = &stack
 		}
@@ -1224,8 +1264,9 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
 }
 
 // RPCMarshalHeader converts the given header to the RPC output .
-func RPCMarshalHeader(head *types.Header) map[string]interface{} {
-	return map[string]interface{}{
+func RPCMarshalHeader(head *types.Header, engine consensus.Engine) map[string]interface{} {
+	miner, _ := engine.Author(head)
+	result := map[string]interface{}{
 		"number":           (*hexutil.Big)(head.Number),
 		"hash":             head.Hash(),
 		"parentHash":       head.ParentHash,
@@ -1234,7 +1275,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
 		"sha3Uncles":       head.UncleHash,
 		"logsBloom":        head.Bloom,
 		"stateRoot":        head.Root,
-		"miner":            head.Coinbase,
+		"miner":            miner,
 		"difficulty":       (*hexutil.Big)(head.Difficulty),
 		"extraData":        hexutil.Bytes(head.Extra),
 		"size":             hexutil.Uint64(head.Size()),
@@ -1244,13 +1285,19 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
 		"transactionsRoot": head.TxHash,
 		"receiptsRoot":     head.ReceiptHash,
 	}
+
+	if head.BaseFee != nil {
+		result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee)
+	}
+
+	return result
 }
 
 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
 // transaction hashes.
-func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
-	fields := RPCMarshalHeader(block.Header())
+func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, engine consensus.Engine) (map[string]interface{}, error) {
+	fields := RPCMarshalHeader(block.Header(), engine)
 	fields["size"] = hexutil.Uint64(block.Size())
 
 	if inclTx {
@@ -1285,7 +1332,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i
 // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
 // a `PublicBlockchainAPI`.
 func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} {
-	fields := RPCMarshalHeader(header)
+	fields := RPCMarshalHeader(header, s.b.Engine())
 	fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash()))
 	return fields
 }
@@ -1293,7 +1340,7 @@ func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *type
 // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
 // a `PublicBlockchainAPI`.
 func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
-	fields, err := RPCMarshalBlock(b, inclTx, fullTx)
+	fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.Engine())
 	if err != nil {
 		return nil, err
 	}
@@ -1310,6 +1357,8 @@ type RPCTransaction struct {
 	From             common.Address    `json:"from"`
 	Gas              hexutil.Uint64    `json:"gas"`
 	GasPrice         *hexutil.Big      `json:"gasPrice"`
+	GasFeeCap        *hexutil.Big      `json:"maxFeePerGas,omitempty"`
+	GasTipCap        *hexutil.Big      `json:"maxPriorityFeePerGas,omitempty"`
 	Hash             common.Hash       `json:"hash"`
 	Input            hexutil.Bytes     `json:"input"`
 	Nonce            hexutil.Uint64    `json:"nonce"`
@@ -1326,7 +1375,7 @@ type RPCTransaction struct {
 
 // newRPCTransaction returns a transaction that will serialize to the RPC
 // representation, with the given location metadata set (if available).
-func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction {
+func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction {
 	// Determine the signer. For replay-protected transactions, use the most permissive
 	// signer, because we assume that signers are backwards-compatible with old
 	// transactions. For non-protected transactions, the homestead signer signer is used
@@ -1337,7 +1386,6 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
 	} else {
 		signer = types.HomesteadSigner{}
 	}
-
 	from, _ := types.Sender(signer, tx)
 	v, r, s := tx.RawSignatureValues()
 	result := &RPCTransaction{
@@ -1359,17 +1407,36 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
 		result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
 		result.TransactionIndex = (*hexutil.Uint64)(&index)
 	}
-	if tx.Type() == types.AccessListTxType {
+	switch tx.Type() {
+	case types.AccessListTxType:
 		al := tx.AccessList()
 		result.Accesses = &al
 		result.ChainID = (*hexutil.Big)(tx.ChainId())
+	case types.DynamicFeeTxType:
+		al := tx.AccessList()
+		result.Accesses = &al
+		result.ChainID = (*hexutil.Big)(tx.ChainId())
+		result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
+		result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
+		// if the transaction has been mined, compute the effective gas price
+		if baseFee != nil && blockHash != (common.Hash{}) {
+			// price = min(tip, gasFeeCap - baseFee) + baseFee
+			price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
+			result.GasPrice = (*hexutil.Big)(price)
+		} else {
+			result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
+		}
 	}
 	return result
 }
 
 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
-func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction {
-	return newRPCTransaction(tx, common.Hash{}, 0, 0)
+func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction {
+	var baseFee *big.Int
+	if current != nil {
+		baseFee = misc.CalcBaseFee(config, current)
+	}
+	return newRPCTransaction(tx, common.Hash{}, 0, 0, baseFee)
 }
 
 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
@@ -1378,7 +1445,7 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransacti
 	if index >= uint64(len(txs)) {
 		return nil
 	}
-	return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index)
+	return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee())
 }
 
 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
@@ -1412,7 +1479,7 @@ type accessListResult struct {
 
 // CreateAccessList creates a EIP-2930 type AccessList for the given transaction.
 // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state.
-func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args SendTxArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) {
+func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) {
 	bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
 	if blockNrOrHash != nil {
 		bNrOrHash = *blockNrOrHash
@@ -1431,7 +1498,7 @@ func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args SendTxA
 // AccessList creates an access list for the given transaction.
 // If the accesslist creation fails an error is returned.
 // If the transaction itself fails, an vmErr is returned.
-func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args SendTxArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) {
+func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) {
 	// Retrieve the execution context
 	db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
 	if db == nil || err != nil {
@@ -1449,21 +1516,15 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
 	if args.To != nil {
 		to = *args.To
 	} else {
-		to = crypto.CreateAddress(args.From, uint64(*args.Nonce))
-	}
-	var input []byte
-	if args.Input != nil {
-		input = *args.Input
-	} else if args.Data != nil {
-		input = *args.Data
+		to = crypto.CreateAddress(args.from(), uint64(*args.Nonce))
 	}
 	// Retrieve the precompiles since they don't need to be added to the access list
 	precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number))
 
 	// Create an initial tracer
-	prevTracer := vm.NewAccessListTracer(nil, args.From, to, precompiles)
+	prevTracer := vm.NewAccessListTracer(nil, args.from(), to, precompiles)
 	if args.AccessList != nil {
-		prevTracer = vm.NewAccessListTracer(*args.AccessList, args.From, to, precompiles)
+		prevTracer = vm.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles)
 	}
 	for {
 		// Retrieve the current access list to expand
@@ -1481,11 +1542,16 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
 		}
 		// Copy the original db so we don't modify it
 		statedb := db.Copy()
-		msg := types.NewMessage(args.From, args.To, uint64(*args.Nonce), args.Value.ToInt(), uint64(*args.Gas), args.GasPrice.ToInt(), input, accessList, false)
+		// Set the accesslist to the last al
+		args.AccessList = &accessList
+		msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee)
+		if err != nil {
+			return nil, 0, nil, err
+		}
 
 		// Apply the transaction with the access list tracer
-		tracer := vm.NewAccessListTracer(accessList, args.From, to, precompiles)
-		config := vm.Config{Tracer: tracer, Debug: true}
+		tracer := vm.NewAccessListTracer(accessList, args.from(), to, precompiles)
+		config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true}
 		vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, &config)
 		if err != nil {
 			return nil, 0, nil, err
@@ -1605,7 +1671,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, has
 	}
 
 	if tx != nil {
-		resultTx := newRPCTransaction(tx, blockHash, blockNumber, index)
+		resultTx := newRPCTransaction(tx, blockHash, blockNumber, index, nil)
 		if borTx {
 			// newRPCTransaction calculates hash based on RLP of the transaction data.
 			// In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash
@@ -1616,7 +1682,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, has
 
 	// No finalized transaction, try to retrieve it from the pool
 	if tx := s.b.GetPoolTransaction(hash); tx != nil {
-		return newRPCPendingTransaction(tx), nil
+		return newRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil
 	}
 
 	// Transaction unknown, return as such
@@ -1689,7 +1755,17 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
 		"logsBloom":         receipt.Bloom,
 		"type":              hexutil.Uint(tx.Type()),
 	}
-
+	// Assign the effective gas price paid
+	if !s.b.ChainConfig().IsLondon(bigblock) {
+		fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
+	} else {
+		header, err := s.b.HeaderByHash(ctx, blockHash)
+		if err != nil {
+			return nil, err
+		}
+		gasPrice := new(big.Int).Add(header.BaseFee, tx.EffectiveGasTipValue(header.BaseFee))
+		fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64())
+	}
 	// Assign receipt status or post state.
 	if len(receipt.PostState) > 0 {
 		fields["root"] = hexutil.Bytes(receipt.PostState)
@@ -1719,123 +1795,6 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti
 	return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
 }
 
-// SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool.
-type SendTxArgs struct {
-	From     common.Address  `json:"from"`
-	To       *common.Address `json:"to"`
-	Gas      *hexutil.Uint64 `json:"gas"`
-	GasPrice *hexutil.Big    `json:"gasPrice"`
-	Value    *hexutil.Big    `json:"value"`
-	Nonce    *hexutil.Uint64 `json:"nonce"`
-	// We accept "data" and "input" for backwards-compatibility reasons. "input" is the
-	// newer name and should be preferred by clients.
-	Data  *hexutil.Bytes `json:"data"`
-	Input *hexutil.Bytes `json:"input"`
-
-	// For non-legacy transactions
-	AccessList *types.AccessList `json:"accessList,omitempty"`
-	ChainID    *hexutil.Big      `json:"chainId,omitempty"`
-}
-
-// setDefaults fills in default values for unspecified tx fields.
-func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error {
-	if args.GasPrice == nil {
-		price, err := b.SuggestPrice(ctx)
-		if err != nil {
-			return err
-		}
-		args.GasPrice = (*hexutil.Big)(price)
-	}
-	if args.Value == nil {
-		args.Value = new(hexutil.Big)
-	}
-	if args.Nonce == nil {
-		nonce, err := b.GetPoolNonce(ctx, args.From)
-		if err != nil {
-			return err
-		}
-		args.Nonce = (*hexutil.Uint64)(&nonce)
-	}
-	if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) {
-		return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`)
-	}
-	if args.To == nil {
-		// Contract creation
-		var input []byte
-		if args.Data != nil {
-			input = *args.Data
-		} else if args.Input != nil {
-			input = *args.Input
-		}
-		if len(input) == 0 {
-			return errors.New(`contract creation without any data provided`)
-		}
-	}
-	// Estimate the gas usage if necessary.
-	if args.Gas == nil {
-		// For backwards-compatibility reason, we try both input and data
-		// but input is preferred.
-		input := args.Input
-		if input == nil {
-			input = args.Data
-		}
-		callArgs := CallArgs{
-			From:       &args.From, // From shouldn't be nil
-			To:         args.To,
-			GasPrice:   args.GasPrice,
-			Value:      args.Value,
-			Data:       input,
-			AccessList: args.AccessList,
-		}
-		pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
-		estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap())
-		if err != nil {
-			return err
-		}
-		args.Gas = &estimated
-		log.Trace("Estimate gas usage automatically", "gas", args.Gas)
-	}
-	if args.ChainID == nil {
-		id := (*hexutil.Big)(b.ChainConfig().ChainID)
-		args.ChainID = id
-	}
-	return nil
-}
-
-// toTransaction converts the arguments to a transaction.
-// This assumes that setDefaults has been called.
-func (args *SendTxArgs) toTransaction() *types.Transaction {
-	var input []byte
-	if args.Input != nil {
-		input = *args.Input
-	} else if args.Data != nil {
-		input = *args.Data
-	}
-	var data types.TxData
-	if args.AccessList == nil {
-		data = &types.LegacyTx{
-			To:       args.To,
-			Nonce:    uint64(*args.Nonce),
-			Gas:      uint64(*args.Gas),
-			GasPrice: (*big.Int)(args.GasPrice),
-			Value:    (*big.Int)(args.Value),
-			Data:     input,
-		}
-	} else {
-		data = &types.AccessListTx{
-			To:         args.To,
-			ChainID:    (*big.Int)(args.ChainID),
-			Nonce:      uint64(*args.Nonce),
-			Gas:        uint64(*args.Gas),
-			GasPrice:   (*big.Int)(args.GasPrice),
-			Value:      (*big.Int)(args.Value),
-			Data:       input,
-			AccessList: *args.AccessList,
-		}
-	}
-	return types.NewTx(data)
-}
-
 // SubmitTransaction is a helper function that submits tx to txPool and logs a message.
 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) {
 	// If the transaction fee cap is already specified, ensure the
@@ -1868,9 +1827,9 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
 
 // SendTransaction creates a transaction for the given argument, sign it and submit it to the
 // transaction pool.
-func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
+func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) {
 	// Look up the wallet containing the requested signer
-	account := accounts.Account{Address: args.From}
+	account := accounts.Account{Address: args.from()}
 
 	wallet, err := s.b.AccountManager().Find(account)
 	if err != nil {
@@ -1880,8 +1839,8 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
 	if args.Nonce == nil {
 		// Hold the addresse's mutex around signing to prevent concurrent assignment of
 		// the same nonce to multiple accounts.
-		s.nonceLock.LockAddr(args.From)
-		defer s.nonceLock.UnlockAddr(args.From)
+		s.nonceLock.LockAddr(args.from())
+		defer s.nonceLock.UnlockAddr(args.from())
 	}
 
 	// Set some sanity defaults and terminate on failure
@@ -1898,9 +1857,10 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
 	return SubmitTransaction(ctx, s.b, signed)
 }
 
-// FillTransaction fills the defaults (nonce, gas, gasPrice) on a given unsigned transaction,
-// and returns it to the caller for further processing (signing + broadcast)
-func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) {
+// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields)
+// on a given unsigned transaction, and returns it to the caller for further
+// processing (signing + broadcast).
+func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) {
 	// Set some sanity defaults and terminate on failure
 	if err := args.setDefaults(ctx, s.b); err != nil {
 		return nil, err
@@ -1958,12 +1918,12 @@ type SignTransactionResult struct {
 // SignTransaction will sign the given transaction with the from account.
 // The node needs to have the private key of the account corresponding with
 // the given from address and it needs to be unlocked.
-func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) {
+func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) {
 	if args.Gas == nil {
 		return nil, fmt.Errorf("gas not specified")
 	}
-	if args.GasPrice == nil {
-		return nil, fmt.Errorf("gasPrice not specified")
+	if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) {
+		return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
 	}
 	if args.Nonce == nil {
 		return nil, fmt.Errorf("nonce not specified")
@@ -1972,18 +1932,19 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen
 		return nil, err
 	}
 	// Before actually sign the transaction, ensure the transaction fee is reasonable.
-	if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil {
+	tx := args.toTransaction()
+	if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil {
 		return nil, err
 	}
-	tx, err := s.sign(args.From, args.toTransaction())
+	signed, err := s.sign(args.from(), tx)
 	if err != nil {
 		return nil, err
 	}
-	data, err := tx.MarshalBinary()
+	data, err := signed.MarshalBinary()
 	if err != nil {
 		return nil, err
 	}
-	return &SignTransactionResult{data, tx}, nil
+	return &SignTransactionResult{data, signed}, nil
 }
 
 // PendingTransactions returns the transactions that are in the transaction pool
@@ -1999,11 +1960,12 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
 			accounts[account.Address] = struct{}{}
 		}
 	}
+	curHeader := s.b.CurrentHeader()
 	transactions := make([]*RPCTransaction, 0, len(pending))
 	for _, tx := range pending {
 		from, _ := types.Sender(s.signer, tx)
 		if _, exists := accounts[from]; exists {
-			transactions = append(transactions, newRPCPendingTransaction(tx))
+			transactions = append(transactions, newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()))
 		}
 	}
 	return transactions, nil
@@ -2011,7 +1973,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
 
 // Resend accepts an existing transaction and a new gas price and limit. It will remove
 // the given transaction from the pool and reinsert it with the new gas price and limit.
-func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) {
+func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) {
 	if sendArgs.Nonce == nil {
 		return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec")
 	}
@@ -2040,7 +2002,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
 	for _, p := range pending {
 		wantSigHash := s.signer.Hash(matchTx)
 		pFrom, err := types.Sender(s.signer, p)
-		if err == nil && pFrom == sendArgs.From && s.signer.Hash(p) == wantSigHash {
+		if err == nil && pFrom == sendArgs.from() && s.signer.Hash(p) == wantSigHash {
 			// Match. Re-sign and send the transaction.
 			if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 {
 				sendArgs.GasPrice = gasPrice
@@ -2048,7 +2010,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
 			if gasLimit != nil && *gasLimit != 0 {
 				sendArgs.Gas = gasLimit
 			}
-			signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction())
+			signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction())
 			if err != nil {
 				return common.Hash{}, err
 			}
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index e8c263f717cfca06f89215582657c3b3e136e604..c19f5a5b1b9995a7bab9e65a58b1117f9defdb5d 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -41,7 +41,8 @@ import (
 type Backend interface {
 	// General Ethereum API
 	Downloader() *downloader.Downloader
-	SuggestPrice(ctx context.Context) (*big.Int, error)
+	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
+	FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error)
 	ChainDb() ethdb.Database
 	AccountManager() *accounts.Manager
 	ExtRPCEnabled() bool
@@ -76,6 +77,7 @@ type Backend interface {
 	GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
 	Stats() (pending int, queued int)
 	TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
+	TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions)
 	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
 
 	// Filter API
diff --git a/internal/ethapi/bor_api.go b/internal/ethapi/bor_api.go
index adcfe390262f31890f0eefb3458104563f5ebbc3..a9351f076fef4a1a4685fbdeda5485c975184c21 100644
--- a/internal/ethapi/bor_api.go
+++ b/internal/ethapi/bor_api.go
@@ -31,7 +31,7 @@ func (s *PublicBlockChainAPI) appendRPCMarshalBorTransaction(ctx context.Context
 		if borTx != nil {
 			formattedTxs := fields["transactions"].([]interface{})
 			if fullTx {
-				marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex)
+				marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex, nil)
 				// newRPCTransaction calculates hash based on RLP of the transaction data.
 				// In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash
 				marshalledTx.Hash = txHash
diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go
new file mode 100644
index 0000000000000000000000000000000000000000..52811b2a9a216ab50851bbf5b4281b22ba0413ed
--- /dev/null
+++ b/internal/ethapi/transaction_args.go
@@ -0,0 +1,294 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package ethapi
+
+import (
+	"bytes"
+	"context"
+	"errors"
+	"fmt"
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
+	"github.com/ethereum/go-ethereum/common/math"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/rpc"
+)
+
+// TransactionArgs represents the arguments to construct a new transaction
+// or a message call.
+type TransactionArgs struct {
+	From                 *common.Address `json:"from"`
+	To                   *common.Address `json:"to"`
+	Gas                  *hexutil.Uint64 `json:"gas"`
+	GasPrice             *hexutil.Big    `json:"gasPrice"`
+	MaxFeePerGas         *hexutil.Big    `json:"maxFeePerGas"`
+	MaxPriorityFeePerGas *hexutil.Big    `json:"maxPriorityFeePerGas"`
+	Value                *hexutil.Big    `json:"value"`
+	Nonce                *hexutil.Uint64 `json:"nonce"`
+
+	// We accept "data" and "input" for backwards-compatibility reasons.
+	// "input" is the newer name and should be preferred by clients.
+	// Issue detail: https://github.com/ethereum/go-ethereum/issues/15628
+	Data  *hexutil.Bytes `json:"data"`
+	Input *hexutil.Bytes `json:"input"`
+
+	// Introduced by AccessListTxType transaction.
+	AccessList *types.AccessList `json:"accessList,omitempty"`
+	ChainID    *hexutil.Big      `json:"chainId,omitempty"`
+}
+
+// from retrieves the transaction sender address.
+func (arg *TransactionArgs) from() common.Address {
+	if arg.From == nil {
+		return common.Address{}
+	}
+	return *arg.From
+}
+
+// data retrieves the transaction calldata. Input field is preferred.
+func (arg *TransactionArgs) data() []byte {
+	if arg.Input != nil {
+		return *arg.Input
+	}
+	if arg.Data != nil {
+		return *arg.Data
+	}
+	return nil
+}
+
+// setDefaults fills in default values for unspecified tx fields.
+func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
+	if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
+		return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	}
+	// After london, default to 1559 unless gasPrice is set
+	head := b.CurrentHeader()
+	// If user specifies both maxPriorityfee and maxFee, then we do not
+	// need to consult the chain for defaults. It's definitely a London tx.
+	if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil {
+		// In this clause, user left some fields unspecified.
+		if b.ChainConfig().IsLondon(head.Number) && args.GasPrice == nil {
+			if args.MaxPriorityFeePerGas == nil {
+				tip, err := b.SuggestGasTipCap(ctx)
+				if err != nil {
+					return err
+				}
+				args.MaxPriorityFeePerGas = (*hexutil.Big)(tip)
+			}
+			if args.MaxFeePerGas == nil {
+				gasFeeCap := new(big.Int).Add(
+					(*big.Int)(args.MaxPriorityFeePerGas),
+					new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
+				)
+				args.MaxFeePerGas = (*hexutil.Big)(gasFeeCap)
+			}
+			if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
+				return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
+			}
+		} else {
+			if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
+				return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
+			}
+			if args.GasPrice == nil {
+				price, err := b.SuggestGasTipCap(ctx)
+				if err != nil {
+					return err
+				}
+				if b.ChainConfig().IsLondon(head.Number) {
+					// The legacy tx gas price suggestion should not add 2x base fee
+					// because all fees are consumed, so it would result in a spiral
+					// upwards.
+					price.Add(price, head.BaseFee)
+				}
+				args.GasPrice = (*hexutil.Big)(price)
+			}
+		}
+	} else {
+		// Both maxPriorityfee and maxFee set by caller. Sanity-check their internal relation
+		if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
+			return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
+		}
+	}
+	if args.Value == nil {
+		args.Value = new(hexutil.Big)
+	}
+	if args.Nonce == nil {
+		nonce, err := b.GetPoolNonce(ctx, args.from())
+		if err != nil {
+			return err
+		}
+		args.Nonce = (*hexutil.Uint64)(&nonce)
+	}
+	if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) {
+		return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`)
+	}
+	if args.To == nil && len(args.data()) == 0 {
+		return errors.New(`contract creation without any data provided`)
+	}
+	// Estimate the gas usage if necessary.
+	if args.Gas == nil {
+		// These fields are immutable during the estimation, safe to
+		// pass the pointer directly.
+		callArgs := TransactionArgs{
+			From:                 args.From,
+			To:                   args.To,
+			GasPrice:             args.GasPrice,
+			MaxFeePerGas:         args.MaxFeePerGas,
+			MaxPriorityFeePerGas: args.MaxPriorityFeePerGas,
+			Value:                args.Value,
+			Data:                 args.Data,
+			AccessList:           args.AccessList,
+		}
+		pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
+		estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap())
+		if err != nil {
+			return err
+		}
+		args.Gas = &estimated
+		log.Trace("Estimate gas usage automatically", "gas", args.Gas)
+	}
+	if args.ChainID == nil {
+		id := (*hexutil.Big)(b.ChainConfig().ChainID)
+		args.ChainID = id
+	}
+	return nil
+}
+
+// ToMessage converts the transaction arguments to the Message type used by the
+// core evm. This method is used in calls and traces that do not require a real
+// live transaction.
+func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
+	// Reject invalid combinations of pre- and post-1559 fee styles
+	if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
+		return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
+	}
+	// Set sender address or use zero address if none specified.
+	addr := args.from()
+
+	// Set default gas & gas price if none were set
+	gas := globalGasCap
+	if gas == 0 {
+		gas = uint64(math.MaxUint64 / 2)
+	}
+	if args.Gas != nil {
+		gas = uint64(*args.Gas)
+	}
+	if globalGasCap != 0 && globalGasCap < gas {
+		log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
+		gas = globalGasCap
+	}
+	var (
+		gasPrice  *big.Int
+		gasFeeCap *big.Int
+		gasTipCap *big.Int
+	)
+	if baseFee == nil {
+		// If there's no basefee, then it must be a non-1559 execution
+		gasPrice = new(big.Int)
+		if args.GasPrice != nil {
+			gasPrice = args.GasPrice.ToInt()
+		}
+		gasFeeCap, gasTipCap = gasPrice, gasPrice
+	} else {
+		// A basefee is provided, necessitating 1559-type execution
+		if args.GasPrice != nil {
+			// User specified the legacy gas field, convert to 1559 gas typing
+			gasPrice = args.GasPrice.ToInt()
+			gasFeeCap, gasTipCap = gasPrice, gasPrice
+		} else {
+			// User specified 1559 gas feilds (or none), use those
+			gasFeeCap = new(big.Int)
+			if args.MaxFeePerGas != nil {
+				gasFeeCap = args.MaxFeePerGas.ToInt()
+			}
+			gasTipCap = new(big.Int)
+			if args.MaxPriorityFeePerGas != nil {
+				gasTipCap = args.MaxPriorityFeePerGas.ToInt()
+			}
+			// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
+			gasPrice = new(big.Int)
+			if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
+				gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap)
+			}
+		}
+	}
+	value := new(big.Int)
+	if args.Value != nil {
+		value = args.Value.ToInt()
+	}
+	data := args.data()
+	var accessList types.AccessList
+	if args.AccessList != nil {
+		accessList = *args.AccessList
+	}
+	msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true)
+	return msg, nil
+}
+
+// toTransaction converts the arguments to a transaction.
+// This assumes that setDefaults has been called.
+func (args *TransactionArgs) toTransaction() *types.Transaction {
+	var data types.TxData
+	switch {
+	case args.MaxFeePerGas != nil:
+		al := types.AccessList{}
+		if args.AccessList != nil {
+			al = *args.AccessList
+		}
+		data = &types.DynamicFeeTx{
+			To:         args.To,
+			ChainID:    (*big.Int)(args.ChainID),
+			Nonce:      uint64(*args.Nonce),
+			Gas:        uint64(*args.Gas),
+			GasFeeCap:  (*big.Int)(args.MaxFeePerGas),
+			GasTipCap:  (*big.Int)(args.MaxPriorityFeePerGas),
+			Value:      (*big.Int)(args.Value),
+			Data:       args.data(),
+			AccessList: al,
+		}
+	case args.AccessList != nil:
+		data = &types.AccessListTx{
+			To:         args.To,
+			ChainID:    (*big.Int)(args.ChainID),
+			Nonce:      uint64(*args.Nonce),
+			Gas:        uint64(*args.Gas),
+			GasPrice:   (*big.Int)(args.GasPrice),
+			Value:      (*big.Int)(args.Value),
+			Data:       args.data(),
+			AccessList: *args.AccessList,
+		}
+	default:
+		data = &types.LegacyTx{
+			To:       args.To,
+			Nonce:    uint64(*args.Nonce),
+			Gas:      uint64(*args.Gas),
+			GasPrice: (*big.Int)(args.GasPrice),
+			Value:    (*big.Int)(args.Value),
+			Data:     args.data(),
+		}
+	}
+	return types.NewTx(data)
+}
+
+// ToTransaction converts the arguments to a transaction.
+// This assumes that setDefaults has been called.
+func (args *TransactionArgs) ToTransaction() *types.Transaction {
+	return args.toTransaction()
+}
diff --git a/internal/jsre/deps/bindata.go b/internal/jsre/deps/bindata.go
index a6545b7140d91c11c24a8321326dc96b327915e3..97e167eb68cb747bfe1d5f8f133d4fc7ff862d66 100644
--- a/internal/jsre/deps/bindata.go
+++ b/internal/jsre/deps/bindata.go
@@ -1,12 +1,14 @@
-// Package deps Code generated by go-bindata. (@generated) DO NOT EDIT.
+// Code generated by go-bindata. DO NOT EDIT.
 // sources:
-// bignumber.js
-// web3.js
+// bignumber.js (17.314kB)
+// web3.js (401.802kB)
+
 package deps
 
 import (
 	"bytes"
 	"compress/gzip"
+	"crypto/sha256"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -37,8 +39,9 @@ func bindataRead(data []byte, name string) ([]byte, error) {
 }
 
 type asset struct {
-	bytes []byte
-	info  os.FileInfo
+	bytes  []byte
+	info   os.FileInfo
+	digest [sha256.Size]byte
 }
 
 type bindataFileInfo struct {
@@ -48,32 +51,21 @@ type bindataFileInfo struct {
 	modTime time.Time
 }
 
-// Name return file name
 func (fi bindataFileInfo) Name() string {
 	return fi.name
 }
-
-// Size return file size
 func (fi bindataFileInfo) Size() int64 {
 	return fi.size
 }
-
-// Mode return file mode
 func (fi bindataFileInfo) Mode() os.FileMode {
 	return fi.mode
 }
-
-// ModTime return file modify time
 func (fi bindataFileInfo) ModTime() time.Time {
 	return fi.modTime
 }
-
-// IsDir return file whether a directory
 func (fi bindataFileInfo) IsDir() bool {
-	return fi.mode&os.ModeDir != 0
+	return false
 }
-
-// Sys return file is sys mode
 func (fi bindataFileInfo) Sys() interface{} {
 	return nil
 }
@@ -94,11 +86,11 @@ func bignumberJs() (*asset, error) {
 	}
 
 	info := bindataFileInfo{name: "bignumber.js", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
-	a := &asset{bytes: bytes, info: info}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5b, 0x75, 0xfc, 0x15, 0x5e, 0x7d, 0x27, 0x1a, 0x9a, 0xb5, 0xfb, 0x16, 0x90, 0xf4, 0x93, 0xac, 0xcb, 0x6c, 0x9c, 0xcd, 0x68, 0xe6, 0xd0, 0x3a, 0xcf, 0xa3, 0x83, 0x5c, 0x20, 0x34, 0x66, 0x45}}
 	return a, nil
 }
 
-var _web3Js = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x7b\x13\x39\xd2\x38\x0e\xbf\xcf\xa7\x50\xfc\xdc\x0f\xb6\x49\x63\xe7\x34\x0c\xd3\x99\x0c\x1b\x02\x33\x64\x6f\x20\x5c\x40\x76\x76\xef\x6c\x96\xab\xed\x96\x6d\x0d\xed\x6e\xff\xba\xdb\x09\x19\x92\xef\xfe\xbf\x54\x3a\x1f\xfa\xe0\x24\xcc\x69\x93\x17\xe0\x96\x4a\xa7\x52\xa9\x54\x2a\x95\xaa\x72\xfc\xff\x96\x24\xc7\xfb\xbd\xc9\x32\x1d\x97\x24\x4b\x11\xee\x95\x41\x1a\xe4\xfd\x2f\x32\xa5\xe8\x65\xc1\xb2\xff\x85\x4c\x7a\xeb\xe9\x69\x76\xc6\x7e\x95\xf0\xeb\x3c\xca\x51\xb4\x5f\x5e\x2e\x70\x36\x41\xa2\xae\xfd\x8e\x28\xda\x79\xf0\x80\x27\xee\xd1\x32\xcb\x07\x0f\xa2\x7e\x8e\xcb\x65\x9e\xa2\xa8\x97\x05\xeb\x9b\x7d\x9a\x4e\x44\x1a\xe1\x69\xb4\xd6\xc9\x7e\x8a\x2f\xd0\x8b\x3c\xcf\xf2\x5e\xe7\x30\x4a\xd3\xac\x44\x13\x92\xc6\x68\x9e\xc5\xcb\x04\xa3\x6e\x67\x23\xdb\xe8\x74\x3b\xfd\xbd\x72\x96\x67\x17\x68\x32\x18\x67\x31\xde\xef\xbc\x3e\x7e\x7e\xf2\xea\xc5\xc7\x37\xc7\x1f\x3e\xfe\x78\x7c\xf2\xe6\x79\x27\x98\x5c\xd3\xfa\x92\x7d\xda\xf7\xfd\x2f\xf8\xf3\x22\xcb\xcb\x22\xfc\x72\x7d\xbd\x47\xc7\x70\xba\x79\x36\x18\x47\x49\xd2\x4b\x06\x3c\x2b\x10\xbd\xef\x61\x36\xc0\x74\x1f\x00\xb7\xce\x4e\xf1\xd9\x1e\xef\x6a\xd1\x4b\x9f\xa6\x21\xee\x5f\x07\x49\xa0\x4a\xe2\x80\xe1\xee\x9a\x43\xd1\x26\x45\x26\xf4\x82\xb4\xc2\xd5\x24\xcb\x7b\x14\x3a\xdb\xdf\xdc\xcb\xbe\xcf\x07\x09\x4e\xa7\xe5\x6c\x2f\xdb\xd8\xe8\x17\xbd\x9c\x22\x5e\x76\xe3\xba\xdf\xfb\xb2\x15\x9e\xca\x2e\xf3\x2a\x02\x86\xa5\x80\xb7\xdd\xff\xb2\xc6\x12\x44\x67\xf6\x4f\xd7\x10\xfa\xb2\x86\x10\x42\x9d\x71\x96\x16\x65\x94\x96\x9d\x10\x95\xf9\x12\x07\x2c\x95\xa4\x8b\x65\x59\x74\x42\x74\x0a\xdf\x02\x1a\xf2\xd2\x68\x8e\x3b\x21\xea\x7c\xcc\x2e\x52\x9c\x77\x02\x95\x43\x47\x47\x73\xa2\x38\xce\x71\x51\x74\x78\xce\x35\xfc\x7f\xc6\xab\x16\xc5\xe1\x7f\x9e\x96\x2d\xcb\xe6\xf6\xb2\x8f\x5a\x11\xa3\xbd\xd1\x65\x89\x8b\x9d\x6d\x7f\x7b\x02\x48\x62\x7a\x0d\xa1\xeb\xe0\x4e\x10\x70\xa3\xfe\xc8\xe1\x68\xd8\x6b\x87\x80\x95\x51\xfd\x47\x1d\xfa\x38\x4b\x4b\x9c\x96\xb7\x1e\xfc\x9f\x72\xde\xe9\x8c\xfd\x61\xa6\x7d\x12\x25\xc5\x6f\x37\xf4\x1c\x17\x38\x3f\xf7\xad\xfa\x3f\xfa\xa4\x15\xcb\xd1\x3b\x3c\x25\x45\x99\x47\xff\x05\x93\x17\xd4\xd5\x81\x2f\x8e\x6f\xc5\xf7\xcb\x3c\x4a\x8b\x89\x97\xf5\xfd\x59\x70\x90\x5b\xa4\xb0\x3a\x12\x0a\x5c\xbe\xaf\x27\xa9\x3b\xc3\x85\xdd\xf4\x6f\xd2\xe8\x57\x9e\x80\xa8\x0d\xe2\xeb\x2a\x58\xe4\x64\x1e\xe5\x97\xde\x7e\x64\x59\xd2\x38\x79\x07\xbc\xad\x3f\x2f\x0a\xcd\x3d\xb8\xb6\x9a\x2a\x24\x1c\x56\x6e\xe3\x7f\x24\x24\x78\x7b\x1f\x93\x22\xbb\x48\x6f\xd1\xf3\x28\xcd\xd2\xcb\x79\xb6\x2c\x56\xe8\x3a\x49\x63\xfc\x19\xc7\xc6\xde\x75\x67\x13\xab\x2a\xd7\xba\x63\xd6\x7e\x41\xd2\xdb\x30\xee\x83\x25\x60\xe2\x45\x1a\xe3\xb8\x63\xa1\x09\x9f\x53\x42\xf8\x0b\xe0\x68\x44\xe2\xb8\x1d\x8e\x6e\x56\xff\x79\x94\x2c\xbd\xdd\x5f\x92\xb4\xdc\xfe\xe6\x71\xfd\x14\xbc\xc1\x17\xcf\xc8\xef\x88\xfc\x5b\xad\xb9\xc3\x59\x94\x4e\x7f\x4f\xd2\xb9\x13\xca\xa9\xa8\x5b\x93\xea\x6b\xa9\xc6\x8b\x99\xb7\x6c\x37\x6a\x44\xd0\xda\xd9\xda\xda\x75\xf0\xe5\xfa\x2c\xd8\xfe\xdd\x0e\xfd\x7f\xa1\x33\xef\xef\x24\x3b\x4e\x96\x69\x7c\x63\x52\xb9\xf5\xc6\x75\x7f\xec\xfd\x73\x1f\x7b\xef\x0f\x7d\x7f\xe4\x33\x87\x77\xf0\xfc\xbc\xf0\x47\x93\x36\xbf\xee\x66\xae\xf6\xaa\x9d\x3b\xdb\xab\x56\x9d\xf7\x49\x9e\xcd\x6f\x39\xed\x65\x76\xcb\xa3\xe6\xed\x04\xbe\xdf\x77\xdd\xfc\x11\xf0\x47\xd2\x98\xe4\x78\x5c\x1e\x79\xf7\xcc\x15\x7a\x72\xbb\x89\x20\xe3\x68\xf1\xe1\x77\x9d\x0c\x3f\x26\xdb\x9d\x76\xf1\x22\x2b\x48\xdd\x41\x7d\x11\x5d\x46\xa3\x04\x9b\x42\xc1\xef\xc2\x95\xaa\x68\xee\x4e\x8e\x5f\xb7\xa3\x81\x03\x31\xde\xe7\x26\x3e\x7f\xfb\x93\xcc\x9d\x20\xa9\xa2\xee\x76\x74\xf6\x3b\xa0\xff\x0f\x8b\xf5\xbb\x38\x3f\xde\x98\x4f\x7e\x6d\xac\xdb\x4c\xef\x1e\xed\x2d\xd1\x7e\xeb\x8d\xeb\x6b\xcf\xec\x91\x67\x4b\xab\x93\xe3\x76\xdb\xc8\x71\x60\xbc\x81\xf6\x85\x85\x43\xaf\x3b\x18\x4e\xb2\x7c\x1e\x95\x25\xce\x8b\x6e\x7f\x0f\x00\xde\x67\x09\x89\x49\x79\xf9\xe1\x72\x81\x4d\x58\xda\x3e\x85\x5a\x1b\x3e\x7c\xb8\x86\x1e\x1a\x90\x5c\xe7\x8e\x48\x81\x22\xb4\xc8\xb3\x8c\x02\xa3\x72\x16\x95\x28\xc7\x0b\x7a\xc8\x4a\xcb\x02\xf1\xb9\x43\x34\x93\xd6\x70\x54\xa2\x79\x54\x8e\x67\xb8\x08\xe9\x27\xcf\xd6\x7e\x9e\x9e\xe9\x1f\xbb\xc6\xd7\x99\x99\xb9\x63\x7d\x9f\x9d\x3e\x3e\x3b\x3d\x0b\xd0\x60\x30\x58\x43\x0f\x87\xce\xd8\x44\x8f\xf7\x91\xb4\xa6\xe9\xf5\xf9\x14\x97\x33\x52\x0c\x3e\xc2\xc2\xf8\x51\x20\x88\x02\x0e\x18\xba\x8e\x68\xc6\x51\x5a\xee\x69\xc0\x6c\xdf\xf6\x41\x1f\x43\x0e\x6f\x6e\x6f\xed\x7a\x6f\x6d\xcd\xd3\x8f\xc1\x22\xcf\x4a\x86\xb5\x7d\x94\xe2\x0b\xa3\xaf\xbd\x2f\xd7\xfd\xbd\xfa\x52\x03\x90\x5e\xf2\xe5\xb8\xcc\x68\xe3\x1e\xd8\xa6\x76\x07\xa4\xe0\x73\xae\x10\x42\xc9\x51\x20\x85\xdb\xb5\xac\xaf\xd3\xc4\x01\xcc\x5b\x6f\xc8\xb1\xdd\xfb\xf7\x69\xef\x74\xf3\xd1\x77\x67\x0f\xfb\xff\x3e\xeb\x3f\x1d\xf6\xd9\x38\xcd\x83\x43\x65\xb7\xae\x83\x2f\x1d\x9d\x14\x3b\xe1\x77\x41\x87\xd1\x5b\x27\xdc\xda\xbd\x3e\x0b\xbe\xf9\x9d\xc9\xfb\x59\x96\x25\x0d\xb4\x3d\xa2\x20\x15\x84\x4d\xf3\xc4\xff\x8c\x4a\xe1\xd7\xae\xfa\x79\xa6\x25\xef\xe8\x1f\x4d\x64\x0c\x3d\xbb\x29\x0d\xd3\xc2\xab\x10\x31\x83\xb7\x29\x98\xa6\xae\x48\xbe\x66\x91\x1a\xda\x65\x2d\xd6\x95\xbd\x09\xd5\xfe\x87\xa2\xd6\xa4\xd9\x87\xff\xd3\x8a\x68\x79\x7f\x9a\x29\xf6\xf1\xef\x4d\xb1\x74\x0f\x93\x24\x5b\xfa\x69\xb6\x9c\x61\x04\x9b\x1d\x10\xee\xc0\x47\xb9\x34\x57\xfe\xe0\x74\x09\x3f\x77\xb5\xdf\x67\x7a\xc6\x8e\xf1\x65\xd2\x2f\xe2\x5b\xab\xfc\xf9\xc4\xa8\x87\x17\xf5\x50\x39\x74\xf2\xc6\x64\x4e\x4b\xaf\x44\xe7\xac\x80\x43\xe8\x34\x79\x55\x4a\x37\xcb\xd4\x91\x3a\x6b\xb4\xb6\xf4\xcd\x88\x9d\x56\xc2\x48\xfd\xcb\x56\x70\xdd\xbf\x19\xe1\xf3\xde\x35\x53\xfe\xb7\x6d\x28\x7f\xf8\x10\x3a\xfc\x61\x46\x0a\x34\x21\x09\xa6\x94\xba\x88\xf2\x12\x65\x13\x74\x81\x47\x3b\x83\x5f\x8a\xc1\x1a\x80\xf0\x2f\x0a\x30\xc9\x31\x46\x45\x36\x29\x2f\xa2\x1c\x87\xe8\x32\x5b\xa2\x71\x94\xa2\x1c\xc7\xa4\x28\x73\x32\x5a\x96\x18\x91\x12\x45\x69\x3c\xcc\x72\x34\xcf\x62\x32\xb9\x84\x3a\x48\x89\x96\x69\x8c\x73\x20\xf8\x12\xe7\xf3\x82\xb6\x43\x3f\x7e\x7a\x73\x82\x5e\xe1\xa2\xc0\x39\xfa\x09\xa7\x38\x8f\x12\xf4\x76\x39\x4a\xc8\x18\xbd\x22\x63\x9c\x16\x18\x45\x05\x5a\xd0\x94\x62\x86\x63\x34\xba\xe4\x54\x84\xd1\x8f\xb4\x33\xef\x79\x67\xd0\x8f\xd9\x32\x8d\x23\x3a\xe6\x00\x61\x52\xce\x70\x8e\xce\x71\x5e\xd0\x19\xda\x11\x6d\xf1\x1a\x03\x94\xe5\x50\x4b\x2f\x2a\xe9\x18\x72\x94\x2d\x68\xc1\x3e\x8a\xd2\x4b\x94\x44\xa5\x2a\xeb\xa2\x40\x8d\x34\x46\x24\x85\x6a\x67\x99\x58\xd9\xa4\x44\x17\x24\x49\xd0\x08\xa3\x65\x81\x27\xcb\x84\x09\x8e\xa3\x65\x89\x7e\x3e\xfa\xf0\xf2\xf8\xe4\x03\x3a\x78\xf3\x2f\xf4\xf3\xc1\xbb\x77\x07\x6f\x3e\xfc\x6b\x0f\x5d\x90\x72\x96\x2d\x4b\x44\x25\x4a\xa8\x8b\xcc\x17\x09\xc1\x31\xba\x88\xf2\x3c\x4a\xcb\x4b\x94\x4d\xa0\x8a\xd7\x2f\xde\x1d\xbe\x3c\x78\xf3\xe1\xe0\xd9\xd1\xab\xa3\x0f\xff\x42\x59\x8e\x7e\x3c\xfa\xf0\xe6\xc5\xfb\xf7\xe8\xc7\xe3\x77\xe8\x00\xbd\x3d\x78\xf7\xe1\xe8\xf0\xe4\xd5\xc1\x3b\xf4\xf6\xe4\xdd\xdb\xe3\xf7\x2f\x06\x08\xbd\xc7\xb4\x63\x18\x6a\x68\x46\xf4\x04\xe6\x2c\xc7\x28\xc6\x65\x44\x12\x31\xff\xff\xca\x96\xa8\x98\x65\xcb\x24\x46\xb3\xe8\x1c\xa3\x1c\x8f\x31\x39\xc7\x31\x8a\xd0\x38\x5b\x5c\xb6\x9e\x48\xa8\x2c\x4a\xb2\x74\x0a\xc3\x96\x54\x86\xd0\xd1\x04\xa5\x59\x19\xa0\x02\x63\xf4\xfd\xac\x2c\x17\xe1\x70\x78\x71\x71\x31\x98\xa6\xcb\x41\x96\x4f\x87\x09\xab\xa0\x18\xfe\x30\x58\x7b\x38\x14\xcc\xf6\x6f\x40\xb6\xe3\x2c\xc6\xf9\xe0\x17\x60\x91\x7f\x8b\x96\xe5\x2c\xcb\xd1\xeb\x28\xc7\x9f\xd0\xff\x66\x25\xbe\x20\xe3\x5f\xd1\xf7\x73\xfa\xfd\x37\x5c\xce\x62\x7c\x3e\x18\x67\xf3\x1f\x00\x38\x8e\x4a\x8c\xb6\x37\xb7\xbe\x01\x86\xd7\xbc\x15\xd4\x08\xb0\x5a\x19\x2e\x8f\xf9\xf6\x0e\x2e\x29\x68\xc0\x74\x17\xf4\x41\x1e\xa5\xa5\x09\x48\xd2\xd2\x07\x77\xe2\x00\x2e\x2b\x20\x9f\x5f\xa6\xd1\x9c\x8c\x05\x1b\xd7\x4a\xc4\x2c\x07\x78\x94\xaf\xe4\xfb\x32\x27\xe9\xd4\x2c\x53\x40\x9a\x0f\xfa\x1d\x8e\xac\x31\xe6\x38\xf2\x8e\xf1\xc4\x05\x5d\x56\xc1\x7a\xba\x2d\xfb\x0b\xc0\xa4\xe0\x03\x34\x38\x73\xa1\x55\x11\xc0\x0e\xcb\xf9\xb4\xb0\x10\xd7\xf2\x07\xb2\x0a\xd8\x46\x18\xf0\xd5\x95\x3c\x3d\xa2\x0a\xe8\x83\x3c\x8f\x2e\x19\x38\x63\xe2\x96\x28\x70\x48\xe9\x53\x93\x00\xf8\x4a\x62\x1c\x22\x46\x65\x86\x70\x4a\x69\x78\x18\x63\xfa\x9f\x6c\x85\x32\xe3\x88\xb1\x49\xca\x95\xb8\x5c\x6b\x6e\xcc\xac\x6e\x7d\xc4\x14\xac\x30\x77\x66\x48\x42\xfb\x50\x43\x61\x74\x11\x78\xff\x1c\x97\xb3\x2c\xf6\x74\x8b\x29\xd7\xb3\x7c\x8e\x98\xe4\x92\x19\x33\xb2\x86\xd8\x1a\xe4\xc5\x3f\xf2\x99\xe1\x59\xe8\x6f\xd0\x7b\xf4\x85\x11\xcf\xb5\x14\xcb\xff\xc6\x30\x5f\xa0\x2f\x7a\x65\xd7\x90\x05\x6f\x15\x0a\xf4\x05\xde\x35\x5c\x23\xfe\x49\x28\x6f\x60\x12\x11\x25\x43\xe8\x0b\xdd\x89\x28\xbb\x07\x84\x18\xc8\xd0\x76\x6a\xbd\x4b\x0e\x8e\x04\x8a\x28\x36\x0b\x53\xbc\xd3\xb0\x36\x98\x90\xa4\xc4\x79\x4f\x2b\xdb\xd7\x74\x10\x9c\x8a\x4a\x2e\x14\x08\x22\x00\x9d\x42\xff\x74\xf3\x6c\x8f\xf1\x4f\x32\x41\xbd\x75\xbd\x11\xbd\x0e\xf6\x40\x83\x3d\xe5\xe8\x92\xf4\x3c\x4a\x48\xac\x68\x80\xd6\xb8\x1e\xa2\x2e\xda\x40\x7a\xe5\x6b\xba\xac\xa1\xd7\x6c\x52\x60\x05\xa5\xa1\x45\x12\x91\x94\xd1\x97\x35\x8d\x0c\xe0\x2d\xcf\xa9\x9e\x45\x9e\x7e\x3c\xfa\x05\x8f\xcb\x6b\xab\x42\x31\xc9\xaa\x1c\xab\x36\xb6\xe0\xaa\xa7\x4e\xeb\x86\x33\x73\x01\x2b\x6f\x09\x5c\x30\x69\x5a\xb1\xa2\x77\x4a\x81\xcf\x02\x74\x0a\xe0\x67\xfd\x76\xa8\x49\x48\x01\x12\x10\x5b\x7c\xd5\xd8\x29\x74\x34\x00\x0b\x60\xd8\xf1\xa5\x2f\x54\x81\x2a\xc4\x38\xcd\xb6\xc2\x4d\xe1\x2e\x7d\x8e\x9d\xa2\x8a\xbe\x0b\x41\xe0\x53\x5c\xea\x2b\xb0\xe0\x9c\x83\x93\x2c\x2d\xc6\xfb\x46\x4b\x18\x35\x0c\xe6\xd1\xa2\x57\xc5\x63\x41\x2b\xe7\x59\x23\x06\xef\x64\x35\xf7\x58\x4f\x4f\xa1\xc8\x19\x63\xcf\xe2\x4b\xae\x22\xad\x3f\x7c\x9f\x3a\x9e\x4c\x0a\x5c\x3a\x9d\xca\x71\xbc\x1c\x63\xad\x5f\xd1\x78\x1c\xa0\x86\xce\x01\x76\xca\xa8\x24\xe3\xb7\x51\x5e\xbe\x82\x97\x44\x56\xcd\x03\x3b\xbf\xe7\xe9\xa7\xa8\x2b\xa7\x4c\x09\xc7\xef\xdd\x2a\x5f\x47\xe5\x6c\x30\x49\xb2\x2c\xef\xf5\x9c\x16\x37\xd0\xce\x56\x1f\x0d\xd1\xce\x76\x1f\x3d\x44\x3b\xdb\x7c\xd0\x1a\xfa\xa2\xf1\x18\x6d\xa0\x9e\xdc\x74\x0c\xac\x57\xa0\x10\x3d\xd5\xf6\x2e\x84\x76\xb6\x51\x68\x24\x54\x74\x56\xa0\x3e\x40\x9b\x3a\xf6\x73\x5c\x2c\x93\x52\x50\x0f\x9b\xc1\xd7\xcb\xa4\x24\x3f\x93\x72\xc6\xe6\x44\x50\xa0\xd1\xb7\x40\xd2\x51\x60\xce\xa0\xa8\x9c\x8f\x90\xd5\x6f\x9e\xf8\xfc\xa4\x6f\xb5\xea\x5b\x03\x2d\x7b\xa0\xad\x11\x39\xbc\x4e\x67\x4f\x2d\x1c\x9c\x4c\xf8\x88\x79\x67\xf9\xae\x90\xe5\x2f\xa2\xf1\xac\x67\x33\x26\xa2\xd3\x16\xe5\xfa\x95\xf3\xa5\xe6\xea\xac\xaf\x17\x62\x08\x81\xae\x6c\xb8\xda\xce\x9e\xd9\x7d\xb1\x8e\x34\x22\x94\x6b\x97\x52\x31\x4e\x26\x1c\xc4\x9e\x23\xe8\x80\xdb\x25\x81\x27\xf8\xb0\x27\x4b\x6f\xc2\x5c\x8a\x1b\xfb\x08\xf3\x67\x78\x68\x88\xb6\x15\xe8\x35\xc2\x49\x81\xad\xe1\x0d\x87\x28\xce\xd2\x6e\x89\xa2\x38\x46\xbc\x54\x99\x99\x55\x0e\x10\x29\xbb\x05\x8a\x92\x1c\x47\xf1\x25\x1a\x67\xcb\xb4\xc4\x71\x05\x96\xbe\xd2\x38\xaf\xd5\x22\x1c\x0e\xd1\x87\xe3\xe7\xc7\x21\x9a\x90\xe9\x32\xc7\x88\x1e\xd8\x52\x5c\xd0\x13\x20\x3d\xa5\x5d\x16\x26\xb3\xfa\x2d\x88\xe4\x8f\x33\xc9\xe6\x64\x60\x1d\x81\x02\x2b\x15\xcb\x5c\xa2\x35\xc7\x93\x08\xd4\x31\x17\xb3\x2c\xc1\xac\x87\x24\x9d\xae\x37\x30\x82\x1a\x1e\x60\x73\x7e\x3e\xe8\x00\x65\xce\xca\x37\x16\xb9\x98\x93\x46\x51\xdf\xb3\xc5\xf5\x5c\xd5\x98\x46\x40\xac\x61\x74\x11\x29\xb2\x2e\x70\xe9\xcc\x29\x23\xab\x37\xd1\x1c\xdb\xfb\x90\xca\xd1\xe5\x4c\xb7\xac\x67\xf3\xa9\xdf\xcf\x54\xc5\x9e\x3a\x25\x5f\xe4\x18\x54\x52\xad\xf8\xab\x19\xb6\xa8\x64\x91\xe3\x73\x92\x2d\x0b\xd9\xa1\xed\x3d\x8a\x12\x92\x22\x92\x96\x4e\x89\x26\xfc\x6b\xfd\xf5\x35\x48\xff\x26\x59\x8e\xe0\x91\x30\x41\xfb\x68\x6b\x0f\x11\xf4\xbd\x18\x80\x78\x2f\x8c\xc8\xc6\x46\x55\x71\xfa\x67\xf5\x79\x63\x1f\x6d\xf4\x04\x0e\x08\x7a\x84\xb6\xce\xa8\x84\x8f\xae\xae\xd0\xe6\x5e\x65\x25\x35\xac\x9c\xd3\xc3\x06\x22\xe8\x61\xd5\xcc\x6d\xd8\xbd\xa0\xc2\x41\x15\xdb\x17\x7f\xd7\x4e\xaa\x99\x72\xdd\xef\xf5\xad\x29\x1c\x0e\xd1\x84\xe4\x45\x89\x70\x82\xe7\x38\x2d\xe9\xf9\x8a\xa1\x29\x40\xc5\x27\xb2\x40\xa4\x5c\x65\xca\x0d\xec\x6f\xfa\xb0\x4f\xf1\x57\x3b\x03\xf0\x74\x3e\x8e\x09\x6d\x24\x4a\xe4\x22\xe7\xf8\x74\xf8\x8f\x8b\x6f\x3f\x5f\x54\xa4\x53\xc1\x20\x4e\x09\xda\x40\x5b\x67\x82\x4f\xa0\x0d\xe4\x74\xc3\x83\xf6\x46\x04\x5b\xcc\xcf\x03\xc9\xb7\x4a\x0f\xed\x33\xaa\xb8\x31\xeb\xf9\x43\x33\x15\x2a\x6c\x99\x98\xba\xe5\xe2\x6f\xa0\x4c\x54\xc5\x90\x36\xeb\x18\x12\x6a\x45\xd3\x8d\x1c\x65\x38\x44\xe3\x28\x19\x2f\x93\xa8\xc4\x42\xf0\xa1\x47\x3e\xde\x17\x44\x4a\x3c\xbf\x05\x3b\xa2\xac\xe8\xf4\x4f\xc4\x94\xfa\x36\xec\xf5\x4a\xfb\xca\x2d\x27\xe4\xf7\x63\x30\x3a\x73\xf9\xea\xbc\x05\x39\xda\x22\xde\x8f\x06\x6d\x08\xd7\x45\xf2\x9b\xc9\xac\x46\x63\xc4\x20\x5b\x6b\x8c\x44\xba\xbc\xd5\x94\x2a\x11\xbf\x2e\xa9\x5a\x0f\xa2\x35\xec\x11\xff\xa0\x7e\x9f\x8e\x48\x2b\xa6\x74\x44\x0c\x1a\x64\x9b\x36\x68\xa9\x55\x12\x55\x20\xa4\x4a\x47\x54\x8d\x10\x5e\x02\x4e\x18\xd0\x9a\x42\x4c\xbd\x86\x48\x1f\xa2\xef\x74\x6c\xe0\x66\x75\x05\x91\x28\xc5\xa8\x58\x87\x67\x44\x5c\x78\x4f\xe1\xd6\x71\xff\x8e\x35\x4a\x6c\xc8\x3d\x18\x99\x58\x5f\x4a\x2d\x62\xe8\x45\x44\x8d\x4a\xc3\x54\xa7\x72\x50\xa3\x6a\xd4\x33\xe8\x18\x65\x1c\x88\x96\xb9\xeb\x91\xb6\x51\x47\xc9\x93\xa8\x4f\x0e\xe6\x5d\xab\x64\x92\xc3\x21\x2a\x96\x73\x76\x43\xe7\xd9\xa5\xb8\x88\x28\xe1\x79\x75\xa7\xe4\x8c\x72\x45\xf9\x05\x5b\x92\x8f\xff\x88\xe6\x4d\x44\x08\x69\xd3\x41\xc1\x70\x88\x72\x3c\xcf\xce\xe1\x1a\x13\x8d\x97\x79\x4e\xe5\x53\x29\x9c\x66\x90\xcc\xbb\x49\x0a\xe8\xb9\xa7\xb7\xc5\x2a\x1a\x3f\x81\xcc\xd6\x9a\x3f\x63\x64\xe8\x91\x53\x7f\x6b\x4a\x7b\x6f\xad\xc3\x8a\x6b\x1d\xef\xa9\x55\xf0\x38\x0f\x95\x95\xd6\x95\x83\x20\x2b\xba\x83\xe9\x97\x24\xe6\xfd\x05\xeb\x2d\x6d\x6b\xcc\x6f\x99\x74\x53\x0b\xe8\x7d\x8f\xd9\xab\xda\x26\x18\xfc\x5a\xb4\xd7\x0f\xbc\xd9\xcf\xb2\x2c\xa9\xca\xa3\x42\x48\x45\xd6\x49\x4d\x9e\x7e\xb9\x59\xd9\x6c\x5d\x26\xe3\xc2\x55\xb9\xef\x70\x54\xd9\xe3\x13\x96\xb9\x46\x09\xc2\xb5\xdf\x00\xd4\x49\x9b\x0d\x61\x38\x1b\xee\x06\x1d\x76\xf7\xdb\x09\xbf\x81\x9f\xb4\x6f\x9d\xf0\x31\xfd\xad\x5f\xc7\x76\xc2\x27\x81\xcf\xd6\x83\xa4\x65\x27\xdc\xda\xa4\x3f\x73\x1c\x25\x9d\x70\x6b\x9b\xfe\x66\xb7\xb2\x9d\x70\x6b\x87\x7e\x2d\x19\x14\x34\xb0\xe4\x60\x8f\xaf\xcf\x82\x27\xbf\xa5\x5d\x54\xc3\x35\xf4\xcd\xac\x89\xf4\x4a\x56\x31\x2a\x32\xcb\xd9\xb6\x45\x7a\xee\x8a\x26\x46\xfe\xa2\x35\x96\x46\x66\x4f\xda\xd4\x75\x0b\xbb\xa3\x0a\x63\xa3\x56\x8d\x6a\x57\xe2\xde\xe9\x12\x6c\x27\x5f\xe2\x16\x26\x4c\xd6\xb0\x9b\x2d\x99\xbe\xbb\xb7\x64\xba\xb7\x64\xfa\x6f\xb1\x64\x52\x0b\xe1\xae\xcc\x99\x9e\x91\xe9\x9b\xe5\x7c\x04\xac\x50\x72\xe7\x11\x99\xa6\x90\x38\xf8\x45\x72\xf2\x65\x49\x12\xd3\xbe\x66\x30\x84\x34\xf6\xaf\x00\x1b\x7b\x41\xc6\x59\x3a\x21\x8e\x31\x90\x38\x99\x69\xbb\x02\x9c\x5d\x60\x5b\x10\x03\x67\xbc\xba\x40\xc0\xef\x11\x3c\xd8\xa0\xe7\x2c\xca\xb7\x94\x95\x2c\x2c\x05\x3a\x37\xa0\x9c\x79\x48\x71\xcc\x20\x49\x81\x52\x3c\x8d\x4a\x72\x8e\x03\xc1\x89\xe0\xe2\xa8\xbc\xc8\xba\x05\x1a\x67\xf3\x85\x90\x56\xa1\x14\x9d\x5b\x59\x72\x92\x64\x51\x49\xd2\x29\x5a\x64\x24\x2d\x03\x76\x1d\x4a\xc9\x3e\xce\x2e\x52\xeb\x4c\x67\xaa\x49\xdc\xe3\xdb\x15\xc3\xf2\x95\xc4\xf7\xb5\x18\x0b\x5d\x4a\x29\xc6\x31\x9c\xa2\x47\x6a\x8e\x63\xbf\x31\x0c\x20\xed\x5a\xda\xf9\x98\xed\x1a\x0c\x18\xea\x17\x5c\x58\xb6\x3b\x60\x73\xd1\x1b\x0f\x5e\x7c\x78\xf9\xf1\xd9\xd1\x4f\x6f\x4e\x5e\x3f\x7b\xf1\xee\xe3\xbb\xe3\x93\x37\xcf\x8f\xde\xfc\xf4\xf1\xf5\xf1\xf3\x17\xda\x19\x4e\x6a\xe2\x60\x26\x07\x8b\x28\x7e\x85\x27\x65\x8f\x7d\x95\xd9\x87\x8b\xac\x38\x94\x58\xe4\x6d\x0e\xca\x8c\x8b\x4b\x5b\x8f\xfb\x01\x7a\xbc\x6b\xde\xf0\xe8\xbb\x25\x0c\xa7\xc7\x1a\x31\x0d\x30\xcc\x89\x17\x87\xdf\x0a\x9c\x3f\x93\x67\x63\xf3\xd0\xbc\x2a\x0e\x5d\xa9\xc3\xc0\xa2\x07\x21\x65\xf6\x12\x7f\x16\xe3\x2e\x96\xa3\xa2\xcc\x7b\xdb\x1a\xfe\x12\xeb\x6a\x9f\x15\x17\x5a\xee\x0d\xf4\x78\xa7\x8f\x86\x3a\x8a\x6c\x74\xbf\x23\xd3\x59\xc9\x8b\x05\x28\x41\x0f\xbf\x32\x3e\xf9\x0e\x7c\xa7\x68\xad\x94\xe9\x6e\x8d\x5d\x71\x3c\x33\xd1\x2a\xb5\x73\xbf\xdb\x0c\x58\x6a\x53\xd6\x58\x7f\xc0\xd6\xfc\x06\x6a\x9e\xa0\x26\x4e\xc7\x24\xf9\xea\x15\xf1\x5e\xe4\xdf\x76\xee\xa4\x71\x67\xfb\x59\x9b\xe4\xd9\xfc\xa4\x9c\x3c\xb9\x9f\x38\xcf\xc4\xf1\x77\x46\x55\x8c\x8c\xbf\x42\x12\x93\x46\xbf\x71\x94\xae\xce\xc8\xec\x27\x47\xd5\x73\xd6\xdd\xbc\xdd\x5f\x17\x6d\xf0\xea\xd1\x53\x84\xba\x5b\x5d\x14\xa2\xee\x66\xf7\xf6\x3c\xaa\x09\x93\xf4\xc4\x4a\x4b\xfd\x83\xc2\x15\x88\x0a\xc6\xf3\x65\x52\x12\x26\x54\x8e\x2e\xd1\xf6\x7f\xe6\x54\x3c\x97\x36\x74\x11\xad\xb9\xc4\x53\x9c\xd7\x6c\x25\xef\x78\xad\x4d\xfb\xf7\xaa\x33\xc2\x6d\x99\x2b\x66\x84\xa3\xc9\xa2\x3e\x8a\x35\xd9\xa2\xdc\x5c\xc9\x1c\x17\x56\xd6\x76\x7f\xb0\xc8\x2e\x7a\x5b\xdb\x4f\xfa\x7d\x13\xa5\x87\x33\x3c\xfe\x84\xc8\xc4\xc0\xa9\x26\x16\x59\x88\x28\xc8\x34\xc5\xf1\x51\xf1\x46\x65\x3b\x8a\x68\x59\xc7\x0c\x7f\xe6\x3d\x36\x91\x21\x88\x16\x0e\x7d\xd0\x76\x69\x4a\x62\x19\x3d\xb2\x5c\x10\x2a\x86\x47\x49\xa1\xac\x96\xed\xd6\x1b\xf1\xe5\xc3\x90\x60\x37\x9b\x01\xda\xea\x07\x68\xeb\xb1\x26\x8f\x6c\xf7\x8d\xdc\x3e\xda\xdf\xdf\xa7\x24\xeb\xa5\xc2\x9c\xb2\x8f\x47\x51\x02\x9d\x42\x4c\x75\xa0\x2e\x3c\x98\xa8\xe9\x12\x11\x53\x24\xd8\x42\xa0\x41\x1e\x8e\x1d\x2c\xc5\x99\x12\x0c\x6b\xda\x95\xc2\x21\x2c\x0b\x32\x45\x4c\x4e\xb7\xe8\x4d\x76\xc1\xc0\x9f\x61\x14\x4b\x81\xd9\x3c\xee\xb3\xde\x68\xba\xcc\x5e\x1f\x5d\x5d\xa1\xce\x66\x87\xeb\x88\x87\x43\x34\x96\x54\x44\x85\x67\x31\x91\xb2\x75\x06\x44\x4a\x36\xd1\x52\xd2\x76\x85\x6c\x71\x7f\x6b\xcd\x33\x9f\x5b\x8f\x0a\xd2\x33\xbf\x6c\x4a\xe7\x24\x5d\xda\xab\xa0\x3b\xb9\xe5\x5f\x17\xea\x16\x95\x6f\xc9\xeb\xb1\x16\x1d\xba\x01\x05\x2d\xeb\x49\xe8\xa4\x96\x86\x7c\xd4\x83\x57\x22\x1f\xde\xbc\x4b\x38\x27\x77\x41\x39\x5f\x07\x65\x9c\xe5\x57\xa1\xcc\xe1\xdd\x8d\x28\x03\x8c\x69\x22\xb1\x89\x22\xde\x9c\x8b\x22\x87\x99\xfb\x2c\xce\xad\xc5\xc8\x61\x06\x31\x39\x27\x31\x8e\x9f\x5d\xd6\xf0\xf0\x9b\x50\x53\x03\x6e\x4e\xee\x1a\x39\xcb\x4a\xec\x9c\xac\x8c\x9e\x93\xdb\xe0\xc7\xbd\x85\x65\x55\x4b\x14\x55\x49\x5c\xea\xc1\x74\x6b\xbc\x88\x9d\xcd\x9c\x8b\x4a\x1c\xf1\xa6\x5d\x14\x39\xf2\x99\x0f\x43\x9e\xe5\x05\xfb\xd5\x2d\x05\xb6\xad\x2e\x7a\xca\xb6\x66\xee\x19\x63\x35\x6c\x56\x9e\x1c\xb5\x77\xb9\x35\x7b\x5f\x82\x27\x0a\x71\x54\x82\xa8\x39\xdb\x38\xa2\x47\x1a\xcd\x31\x7b\xe0\x43\x7f\x59\x22\x18\x87\xa1\x75\xca\x1a\x3c\x98\x77\x0e\xa1\xd0\x46\x80\x74\x65\x39\x2d\xc4\x9f\x58\xa3\x7d\x54\xf5\x52\xf7\x61\x7f\xa8\x1d\x69\x0a\xf2\x2b\xe7\x89\x05\xdc\x52\xf1\xf2\xa7\x5b\x67\xa6\x28\xdc\xdd\xfc\x4c\x45\x66\x77\x72\x07\x45\x42\xc6\x98\x4a\x26\xdb\xe8\x21\x54\xb7\x22\x9d\x37\xcc\x8c\x7e\x0a\xbf\xb3\x09\x5a\x15\xfd\x95\xaa\x00\x67\x93\x91\x47\x44\x8b\x0f\x30\xc4\xf1\x4b\x30\x1b\x73\x8f\x77\xfb\x7c\x0f\x2f\x33\x0e\xdf\x47\x0f\xc5\xa9\xd2\x37\x03\x56\x45\x4c\x3a\x7c\xbc\x1b\xf0\xf6\x57\x9b\x82\x9a\x53\x39\x1b\xbe\xe7\x58\x7e\xa7\xd8\x8f\x8a\x31\x21\x75\xf8\xf7\x1c\xe7\x7f\x43\xcc\x0b\xad\x0e\x68\x07\xda\xe1\x7f\xb5\x09\x50\xee\x69\xaa\x66\xe0\x40\x39\xb0\xa9\x98\x82\x4a\xde\x5e\x81\x72\x59\xa1\x8b\x6d\x9f\x03\x9b\x15\xa4\x29\x03\x77\x9d\xcd\xcf\x1d\xb4\x81\xf8\x19\x07\xd0\xce\x7e\x4b\xb3\x82\xdd\xcd\x00\xe9\x49\x55\x3e\x03\xbe\x08\xd3\x0f\xed\xac\x19\x5a\xdf\x81\x0d\x03\x2b\x36\x74\x52\x1c\x38\x7d\x81\x87\x55\x19\x4e\x29\x86\xcc\xd0\x4d\x72\xfb\x91\x65\x49\x68\x27\x38\x50\x54\x02\x09\xed\x04\x1d\x4a\x8a\x65\xa1\x9d\xe0\x42\x9d\x38\x60\x27\x5e\x38\xbd\x51\x95\xe2\xa9\xcf\x05\x3c\xf1\x43\xea\x83\x55\x29\x1e\x38\x1d\xdb\x5a\x92\x0b\xe9\x9b\x1e\x37\xc7\x2d\x67\x4e\x90\x9e\xe6\xc2\x72\xaa\x0f\xbd\xeb\xee\x5a\x5c\xeb\x9a\x97\x43\x9d\x70\xeb\x49\xd0\x31\x2f\x95\x3a\xe1\x36\x58\x30\xc0\xc2\xe8\x84\x5b\x5b\x41\x47\xbf\x9a\xea\x84\xe6\xe7\xf5\x59\xb0\xb5\xf9\x3b\xbb\x74\x39\x62\xb6\xf1\x35\x3e\x88\x48\x5a\x56\xb9\x20\xe2\xb7\x57\x24\x2d\x99\x77\x16\xfa\x63\x57\xfe\x3a\x53\x89\x3b\xda\x6f\xcb\x79\x0b\x49\x4b\xe6\xba\x85\xa4\xe5\xe3\x5d\x09\xf6\x44\x55\xb4\xfd\xcd\xe3\x8a\xba\x28\x7c\x83\x2b\x23\xfb\x68\xf8\x15\xbd\x71\x01\xb8\x6d\x86\x70\x94\x96\x2b\x5a\x5e\x18\x25\x6a\x0c\x2e\xa0\xb9\x9a\x92\x37\x32\xaf\x20\x69\x29\x44\xc5\xa7\x37\x72\xe9\xc2\x7a\xd5\x6c\x06\xb1\xd5\x2a\x8a\xdd\xbd\x1d\xc4\xbd\x1d\xc4\x9f\xd7\x0e\x02\x29\x43\x08\x26\x2a\xdd\x91\x0d\x44\x0b\xd3\x06\x9b\xd5\x33\xd3\x85\x0c\x0c\xd2\x95\xe7\x8e\x81\x47\x42\xbd\x98\xe1\x54\xbe\x57\x0c\x98\xed\x37\x15\xc0\xa5\x03\x07\x21\x59\x0e\xbd\xb6\x11\x96\xfa\xdb\x7e\x9e\x08\x9c\x54\xc8\x8f\xec\xff\xab\x2b\xd4\xed\x6a\x7c\x36\x13\x2f\x17\xd8\x8f\x3d\xed\xa9\x21\x49\x79\xeb\xad\x3d\x7e\x4c\x71\xa9\x9b\xfc\x82\x01\x79\xb7\x10\x0f\x41\x81\x97\xd0\x4a\x0c\x6b\x77\x25\xdf\x33\x63\x57\x53\x8a\x16\x6a\x26\x55\xab\x5e\x19\xea\x89\x3e\xf6\x0d\x83\x76\x40\x8f\x6e\xd0\x6e\x37\x52\x6b\x8a\x06\x56\xfe\xc6\xb1\x43\xbf\x7e\x6c\x8d\x8c\x71\x8e\x29\x31\x89\xf5\x60\xba\x65\x61\xe4\x1e\x93\xc9\x04\x83\x41\x32\x43\xb9\x75\x2e\xb9\x90\xef\x42\xf4\xe3\x88\x40\x09\x9f\x25\x61\xbb\x9c\x7a\x0f\x21\xe6\xd1\x85\x6e\x87\xbe\x7e\x44\x0b\xc6\x61\x64\x2f\xaa\x51\x79\xe1\x7f\x33\x6b\xd2\x5d\xe5\xad\x9e\x22\x48\x49\xaa\xab\x60\x34\x9b\x8f\x48\xea\x7a\xb8\x29\xb3\x29\xa6\xdc\x9d\xd6\x80\xa7\x03\xb6\xa8\xa2\xc5\x02\xa7\xb0\x96\xa2\x94\xbd\x81\xb0\xb0\xcb\x6b\x6b\xba\x87\xe1\x8c\x69\x46\xc6\x94\x3d\x89\x5e\x35\x17\xe6\x17\xa8\xd9\x84\xc3\xc2\x3e\x54\x8b\x5a\x31\xbc\x26\xbd\x5f\x1d\x5a\xa5\xde\x82\x5d\x99\xec\xa1\x66\xec\x8e\xa3\x24\xe1\xf8\x15\xd7\x38\x6c\x44\xb3\x48\x2d\xdd\x82\xfc\xca\x9d\x0b\xc2\x75\xdd\x2c\x2a\x02\xfa\xbf\x20\x34\x70\xff\xeb\xb9\xb7\xd3\xf1\x2d\x6d\x41\xfd\x3a\xd3\x5a\xd4\xf8\xbd\x33\xf9\x16\x2e\x5f\x15\xeb\xfb\xfb\x20\x5d\x4c\x48\x6a\xbd\x55\x6a\x42\x82\xf2\x5a\xc4\xab\xe2\x37\xcc\xb6\xd2\x80\xe5\x1e\x14\xcf\xaa\x8f\xfe\x4c\xe3\xeb\x6a\x68\x5a\x2c\x33\xa3\xf6\xba\x41\xaf\xc3\xa8\x95\x0b\x80\x3e\x7a\x8a\xba\x5d\x14\xb6\x33\xc8\xd2\x50\xe6\x35\xcb\x5a\x01\x6f\x94\xf7\x33\xe5\x84\x94\x19\x7d\xcf\xbd\x94\xfe\xc2\x8f\x33\xb1\xf7\x88\x5b\xe1\x48\x67\xf8\xd1\x5c\x27\x32\x20\xf1\x5a\x2c\xaa\xc6\xbc\x28\x04\xbf\x4a\x36\xfe\x7c\xfe\x99\xe4\xf2\xda\x43\xec\xca\x0f\x55\xd0\x1d\x9f\xb0\xde\xea\xa8\x33\xb6\xb5\x0a\xdc\x69\x9b\x92\x1f\x79\x22\x21\x12\x97\xf0\x2d\xb0\x88\xe7\x8b\xf2\x52\x57\x09\xb6\xd8\x44\x1b\x57\xa1\x49\x8f\x1a\x7b\x0a\x41\xfa\x58\x01\x37\xc2\xe3\x54\xa5\xaf\x29\x2f\x26\x6a\x07\xc2\xab\x6c\x1a\x83\x71\xb1\xb2\xe1\x11\x0b\x6e\x32\x0e\xf5\x18\xaf\xda\x3f\xd4\x2b\x52\x94\xce\xcb\xbf\x53\x63\x34\x67\x1e\xa7\x50\xb5\xa3\x57\x35\xbb\xdb\x8b\x7c\x17\x24\x6e\xea\x97\x8b\x98\x59\xb6\xf2\x77\x70\x52\x15\x59\x66\xa5\xf6\xd6\x95\x15\x16\xc2\x11\xf3\x3b\x84\x8c\xb7\x7d\xf2\x09\x21\x07\x35\x9f\x15\x19\x7b\x9b\x5c\x8f\x6c\xfb\xaa\x58\x90\xf6\xed\x97\xed\x2c\xc4\x6c\x1e\xed\xeb\x3d\x56\xb0\xfa\x30\x36\xf6\x5d\x45\x3f\x7f\xad\xe5\xbe\xd0\x62\x90\x4a\x04\xea\x65\xfa\xab\x5b\xf9\x6a\x6e\x38\x14\xd3\x8d\xcf\x71\x7e\x59\xce\xc0\x17\x89\x56\x8f\x8e\x1d\xd7\xf1\x94\xb0\x48\x73\xf0\x63\xbc\xd4\xf5\xdf\x50\x48\xdf\x4b\x77\xda\x84\xab\x74\xbe\x0e\x50\xb7\x2b\x94\xef\x35\x4a\x8a\xb7\x6c\x96\x2c\x9d\x9e\x54\xdf\x5d\x9f\x05\x5b\xad\x62\xed\x7d\x45\x9d\x1c\xdc\x46\xd7\x2b\xe5\x72\x0a\x52\xa1\x95\x13\x66\x66\xf4\x7f\xa6\x2a\x83\x5f\xbb\xea\xe7\x99\x96\xbc\xa3\x7f\x58\xba\x39\x9a\xc6\x94\x73\xf4\x97\xd0\xce\xd1\xdf\x4f\xb4\xea\x34\xfd\x9c\x53\x63\x0b\x0d\x9d\x73\xf7\xbe\x8a\x8a\x8e\x16\x5e\x45\x47\xc7\xe0\x6d\x25\x1d\x4d\x5d\x51\x4b\x67\x16\xa9\x51\xd3\xb1\x16\xeb\xca\xde\x44\x51\x47\x71\x5b\xa1\xa8\x6b\xe7\x28\x9f\x77\xab\x85\xa2\xae\x55\x34\xaf\xaf\xf5\xb8\xce\x73\xfb\xb7\x0a\x79\xb0\xe2\xab\x10\x88\x28\x61\x93\x08\x4b\x5f\x91\x48\xec\x42\x35\x64\x22\xda\xad\x2f\x7f\x23\x9d\x2e\x93\xa4\xda\xbc\x99\xf3\xb4\x77\xb7\xaf\xe5\xe4\x28\x5b\xd0\xdd\xdd\x47\x1f\xa9\x7d\xbf\xe3\xe1\xc3\x9a\x8b\x5b\x52\xb4\xf7\x6d\x3b\xc6\x79\x19\x91\xd4\xef\xdf\xd6\x41\x24\xbb\x4d\x6a\x20\x6a\x06\x34\x30\xd3\xeb\xc9\x9a\x17\xb1\x32\x1a\xbd\x41\x94\x38\x9f\xd3\x23\x3f\x99\x40\xcd\x66\xbf\x63\xee\xb5\x16\x4d\xc9\x39\x4e\x85\x49\x8b\x79\xa4\xae\x72\x97\x6b\xd9\xbf\xb0\x63\xb6\xb2\xb8\x05\x2c\xb3\xca\x9d\x76\xfd\xf6\xb7\x3a\x44\xfb\x25\xc2\x9c\xd3\x76\x4a\xaf\x70\x9c\x9d\xe3\x3c\xbf\xc8\x49\x59\x62\x30\xf7\x62\xbd\xea\xa0\x0d\xe8\x7d\x6b\xdc\x5d\x80\x96\xbd\xd0\x1f\xf2\x83\x15\x84\x3a\x8a\x92\x94\xa3\xb0\x74\xfd\x0e\xdb\x6f\xed\x5b\x21\xd3\xd5\x4a\x5a\xcd\x29\xad\x6d\x05\xde\x3c\x2e\x04\xfc\x18\x1c\x0e\x41\x15\x1e\xcd\xe9\xaa\x00\xaf\x87\x5c\x9b\x45\xc7\x4b\x39\x01\x66\x77\x0c\x09\xf9\x84\x51\x84\x0a\x92\x4e\x13\x2c\xfd\x70\x01\xe4\xc0\x30\x89\x06\x0a\x66\x6e\x66\x98\x5b\x0e\xd6\xda\xd5\x15\x3a\xed\x9e\x6e\x9d\x75\xcf\xfa\x52\x18\x6c\x70\x03\xc0\xbb\x67\xe2\x9d\x7e\xe9\xae\x0d\x2b\x44\x77\x66\x03\xc5\x50\x01\xb6\x0a\x5b\x01\x7a\x04\xf6\xd8\x9b\xd0\x97\x2d\xdd\x11\x8d\xea\x90\x23\xc8\x0a\x47\x0d\x81\x70\xed\x50\x75\x5a\x10\x0e\x1d\x1e\x0a\x40\xd5\xc0\x70\x88\xa2\x24\x41\xa3\xa8\x20\x63\xe6\xff\x00\x1e\x0b\xec\x6c\x73\x05\x4e\x92\xd1\x93\xb1\xe8\x4d\x80\x76\xb6\x9b\x8c\x4e\xcc\x85\xcd\x39\x9a\x38\x81\x0b\x5d\x24\xc2\x53\x10\x20\x21\x28\xd4\xe9\x59\x07\xed\xff\x00\xeb\x53\xa5\xed\xb2\xc4\x5a\x65\xda\x81\xa8\x6d\x55\x0e\x30\xc3\x95\x3d\xab\x59\xed\x7a\xab\x95\x34\xab\xdc\x7e\x19\x0e\x61\x1c\xa2\xdb\xb3\xb6\x51\xad\xc8\x83\x07\x48\xff\x3e\xd5\x7e\x6b\x2e\xe0\xce\xc4\xae\x2b\x23\x63\x0c\xa7\x37\x9a\x1b\xbe\x7c\xeb\xa6\x46\xcc\x82\x39\x37\x7c\xc2\xcc\xa9\xd1\x3c\xae\xdd\x72\x66\xac\x7e\xd5\x4c\x8c\xd6\xe6\xd7\x9e\x97\xbb\x9c\x18\xd3\xf5\x89\x62\xa4\xda\x4c\xc0\xd9\xa8\x03\xb6\x08\xdb\x0c\xe9\xec\x90\xd4\xe1\xc6\x0a\x5b\x7c\x2a\xb6\x76\x25\xe0\xf6\xd9\xe9\x0e\x07\x15\x69\x0c\x44\x42\x6c\x9d\x59\x09\xea\xdb\xdd\x1d\x00\xab\x37\xd8\x1e\xf4\xb1\xf0\x21\x36\xef\x09\x5a\x63\x77\x34\x91\x64\x82\x7a\x5a\x96\xc6\x21\x6d\x7e\x7c\xc3\x89\x05\x86\xed\x7b\x0d\xb1\x55\x33\xe5\x7c\x93\x10\xa7\x6a\xdf\x3c\xc3\xbc\xf9\xa6\xba\x23\xe3\xef\x39\x13\xce\x3f\x3b\xc6\xbc\x1b\x15\x9d\x9a\x95\xeb\xd3\xad\xbc\xaf\xb5\x9a\x67\x99\xc1\x86\xc2\xf3\x2b\xe7\xd7\xf0\xa2\x58\xb9\xdb\x73\x6f\x45\x49\x54\x94\xe8\xf4\x8c\x0a\x13\xac\xde\x1b\x4d\xfb\xba\x7f\xde\xe5\x1c\x80\x9c\x85\x1c\x1f\x4b\x70\xa0\x51\x2f\xa1\xe0\x53\xd2\x40\x1b\x22\xa9\x31\x8e\xd5\x8e\x30\x92\x03\xdb\x37\x4d\x68\x74\x89\x62\x3c\x89\x96\x09\x28\x42\x8b\x25\x95\x53\xe5\xc6\xdc\xe1\x6e\x6a\x02\x1e\xe6\xd1\x9e\x45\xe3\x18\x75\x03\x06\xac\x76\xc4\x15\x45\xe1\x96\xa7\xb7\x4a\xa3\x7a\xe1\xab\x5d\xe8\x88\xb5\x25\x52\xd8\x6b\x04\x28\x9e\x93\xf2\x69\x87\x52\x7c\x80\x3a\x74\x11\xd0\xff\xce\x3a\x67\x8a\xda\x39\x84\x96\x06\x85\xd2\x65\x62\x3f\x7b\xd0\x66\xb3\x15\xda\x6c\x07\x73\x56\x7f\x1b\x16\x82\xeb\xa4\xca\x59\x09\x6c\x6f\xe0\xce\xf2\xd8\xac\x17\x70\xc3\x4b\x87\x63\x8c\x97\xfe\x0b\xab\xde\x22\x62\xce\xad\x7a\xff\x3e\x65\xa7\xf1\x7f\x9f\xf5\x9b\x45\x04\xae\xbc\x95\xde\x1e\xaa\xef\x1d\xac\x30\x16\x02\xba\x3d\xeb\x10\x6f\x4f\xdd\xbb\x2c\x0b\x67\x9e\x4b\x0b\x7e\x8f\x6e\x6f\x0c\x5e\x7f\xd4\xe6\xad\x0c\x77\x85\x2a\x9c\xa0\xda\x6c\xa1\xc1\x1b\xac\xb4\xff\xd6\x8d\x89\xf7\x50\xe5\x9f\xdf\x31\xaa\xeb\x57\x16\x27\x13\xdd\x9f\x2c\x67\x65\x4e\x21\xf9\x32\xf9\xf4\xcc\xe7\x44\x7c\xb0\x58\x16\xb3\x9e\xe3\x99\x54\xbc\xd4\x16\x6e\x46\xdd\x9a\xe9\x58\x5c\x9f\xeb\xe7\x3e\x07\xa0\x7a\x4b\x9a\x1f\xcf\xde\x79\x80\x74\xff\xb2\x96\x7b\xd2\x5b\x39\xf5\xe5\x13\xa8\x3b\xf3\xbd\xf5\xfc\x41\xd7\x1d\xa9\x83\x23\xfe\xb7\x9f\x3f\x9f\x47\xd6\x06\x4f\xac\x95\x13\x41\x67\x13\x5c\xa5\xd6\xcc\xc7\xca\xb3\xb1\xe6\xdc\x11\x5a\xba\x23\x63\x49\x6a\x1e\x6d\xdb\xf8\x04\x65\xf7\xa3\x93\x3c\x9b\x7b\xcd\x0d\x18\x94\x8f\xb7\x8c\xec\x07\x3b\x96\x81\x90\x61\x19\xb4\xc2\x83\x29\xc1\xd4\x58\xcb\x2d\x58\x14\x1f\x88\xce\xa2\x0c\x7f\x9a\x0d\xac\xea\xab\xf0\x2a\xd8\x9b\xf4\x1b\x4b\x26\xe8\xf2\x27\x3e\xd0\x3d\x21\xe8\x70\x74\x3d\x44\xdb\x60\xfc\xd0\x17\x1e\x9d\x39\xf2\xaa\x16\x51\x6d\x9d\x7a\xf3\x4e\xc5\xbe\x15\x05\x05\xde\x97\xec\x8e\x5d\x2f\xbd\x81\x76\x98\xd3\x7b\xb6\xdb\x16\x14\xa4\x40\xd1\xa4\xc4\xb9\x5c\x24\x7a\x7f\x6f\xb4\x56\xfd\x65\x7c\xbe\xbb\x15\xe7\xa8\xf0\xd9\x8d\x6a\xb1\xc7\x43\xc7\xbc\xa9\xaa\x5f\xf7\xeb\x51\xe9\x46\xda\x8e\x79\x53\xcb\x68\x5a\x72\x1a\xf4\xb0\xbe\x6f\x14\x76\x63\xbf\x1e\xa6\x15\xa3\x32\x1d\xce\x6a\xd3\xbe\x81\xc8\xdd\x72\xad\x3f\xc4\x1e\xa2\xff\xb5\xa4\x7e\x61\x90\xda\xf2\xef\x0f\x45\xfc\xf7\xb4\xaf\xfd\xfd\x2e\xb4\x8f\xbc\xa4\xaf\x07\x68\xbc\x29\xe9\xdb\x61\xc4\x56\xdc\x54\x1c\x62\xb5\xeb\x6f\xb7\xb3\x98\xbd\x58\xa5\x7e\x3e\x7f\x5e\x7a\x4b\x1c\xfa\xf2\xaf\xbf\xea\x25\xbc\xe0\xb7\x7e\xae\x91\x6a\x53\xf7\x7b\x68\x0b\x6d\x98\xbd\xeb\x33\x9f\x4c\x2c\x92\x98\x67\xea\x99\x07\x62\xeb\xd2\xcd\x78\xb0\x5d\xe3\xcf\xde\xc0\xb5\x65\xf1\x65\x70\xb1\xb5\x15\xc7\xa6\xcf\xb9\x5c\x59\xdb\x7d\x53\xad\xea\xbd\x48\xb4\xba\xde\x78\xc1\x5b\x7d\xb5\x2b\xdf\xc4\x5d\x9f\x05\x5b\xbf\x77\xe8\xfd\x93\xe6\x67\x6f\xcb\x9a\x77\x6f\xdc\x13\x09\xfc\xcf\x6c\x5d\x96\xea\xe9\xdb\x52\x7b\xfb\xb6\xd4\x1f\xac\x2d\x3d\xaf\xdf\x96\xf2\xf9\xdb\x52\x7b\xff\xb6\xd4\x1e\xc0\x2d\xcd\x17\x70\x4e\x8d\x2d\x2c\x6c\x1c\xff\x28\x5f\xf1\x11\xdc\x89\xf7\x15\xdc\xc9\xea\xcf\xe0\x4e\xda\xbe\x83\x3b\x71\x1f\xc2\x9d\xdc\xc1\x4b\xb8\xe5\xad\x9f\xc2\x9d\xb4\x7e\x0b\xf7\x7b\xc7\xf5\x3f\x69\x61\x71\xb6\xac\x33\x39\x13\xae\x55\xd8\x0f\x4e\x9c\x9a\xd5\xd9\x52\x37\x3b\x5b\x1a\x56\x62\x4b\x9f\xe1\xd9\x52\x59\x9e\x2d\x75\xd3\xb3\xa5\x6e\x7b\xb6\xb4\x8c\xcf\x3c\xf5\xb6\x59\x1c\xbf\xa9\xfd\xd9\x89\xdf\x00\xed\xe4\x06\x16\x68\x27\xad\x4d\xd0\x4e\x3c\x36\x68\x76\xe9\x9b\xad\x91\x1a\x33\xb4\xb6\x8b\xa4\xbd\x21\xda\xb7\x6d\x56\x49\x77\x59\x60\x50\xcc\x8e\xcb\x2e\x0b\xc8\x37\xcd\x10\x4e\xcf\x51\x9c\x61\xb0\x56\x80\xd7\x81\x51\x1a\x83\x0f\x5b\xf4\xcf\xd7\xaf\x5e\x96\xe5\xe2\x1d\xfe\x7f\x4b\x5c\x94\x6b\x20\x98\x5d\x2e\x70\x36\xb1\x72\x98\x1f\x1b\xf9\x7e\xa3\x2b\xf0\xc2\x1b\x1e\xd8\xd0\xe8\xcb\xf5\xde\x9a\x11\x2c\xb2\x12\xd2\x4c\x00\x49\xfd\x97\x62\x46\x77\x1f\x32\x4d\xb3\x1c\x87\x09\x49\xf1\xda\x35\xb3\x58\xa5\x78\x68\xe5\xed\xfe\xfe\xe5\xec\xfd\xcb\xd9\x3f\xf1\xcb\x59\xf6\x6a\x96\xdb\xb0\x19\xcf\x66\xd9\x86\x83\x6e\xf6\x7a\x96\xef\x7d\x27\x25\x49\xa0\x4e\xa6\xcf\x84\xb5\xc3\x9e\x27\x39\x60\xa4\xbc\x94\x2c\x51\x15\x19\x27\x51\x51\xa0\x53\x28\x72\xc6\xbb\xc9\x32\x14\x13\x66\x55\xad\x0d\xe1\xde\x08\x56\x29\x57\xae\x52\x0e\x82\x6a\x9c\x59\xb7\xf7\x73\x0e\x90\xb4\xa6\x93\x37\x47\x1f\xde\xd3\xb3\x35\x4c\x42\xf7\x02\x93\x2e\x23\xcd\xee\x27\xed\xf7\x6b\xed\xf7\x4f\xda\xef\xe2\xd7\x68\x94\x89\x8f\x09\x49\x53\x7c\x29\xbf\xf0\xbc\xcc\xe0\x29\xa3\x48\x59\x90\xb1\x99\x90\x46\xa9\x99\x30\x27\xe3\xdc\x4e\x49\x12\xe2\x14\x32\xe0\x0d\x50\xf1\x61\x14\x99\xe6\x51\x1a\xcb\xa1\x18\x59\x3f\x19\x5f\x1f\x8c\xaf\xb7\xc6\xd7\x0b\xe3\xeb\xff\x8c\xaf\x7f\x19\x5f\x6f\x8c\xaf\xe7\xc6\xd7\x3f\x8c\xaf\x13\xf6\xb5\x76\x56\xed\xba\x86\xce\xd1\xdb\x83\xe7\x74\x8a\x43\xb4\xb3\x1d\xc8\xc4\xf7\x47\x3f\xbd\x39\xf8\x70\xf2\xee\xc5\xc7\x57\x2f\xde\xfc\xf4\xe1\x65\x88\x76\x55\x26\xcc\x6a\xa8\x7e\xaa\x9c\x0a\xca\x09\xd1\x17\x64\x25\x28\x3f\xea\x90\xf1\xf1\xf9\xf1\xcf\x6f\xd0\xb5\xaa\xe9\xed\xf1\xab\x57\x14\xfa\xc3\xd1\xeb\x17\xc7\x27\x1f\x42\xb4\xb5\xb9\xb9\x39\xe4\x3d\xe4\x37\xde\xcf\x92\x6c\xfc\x29\x44\x5d\xca\x3a\x8b\xb2\x6b\xe4\x1d\x8c\x21\x94\x71\xa8\xde\x36\xb2\x07\x18\x74\x3f\x6f\xf2\x7d\x72\x1f\x0a\xe3\x7e\x23\xfb\xab\x6f\x64\x6b\xd2\x05\x44\x31\x8b\x76\xee\xca\x03\xc4\x61\x7e\xb9\x28\xb3\xbf\xbf\xd7\x37\x87\x31\xa4\x3d\x52\x11\x30\x68\x83\x5e\x80\x21\xcd\xe9\x7a\xa3\x3b\xb9\xee\x1b\x80\xe2\x0a\xfd\x81\x2a\x4f\x42\x0f\x1e\x88\xdc\x81\xf0\x17\xc1\xc4\xe4\x19\xfe\xdc\xb5\x5f\xd1\x19\x9e\xbf\x7e\x40\xdb\xb4\xb4\xed\xfd\x78\x5b\xb8\x8b\x34\x8b\x23\x71\x19\x2e\x2f\xf8\x2d\xff\xec\xc8\x7a\x6d\xc7\x40\x05\x8e\x68\xe7\x06\x2f\xf1\xe7\x01\x68\x2f\xb9\xe7\x5e\x9f\x8d\x11\xc5\x8a\x18\xb6\x6a\x9d\x9d\xe8\x98\xfa\x2d\x44\xdb\xdf\x3c\x66\x25\xb5\xc7\xc9\xe2\xcd\x19\x65\x79\x12\xc7\x9d\xf0\x9b\xef\x82\x8e\x89\xf2\x4e\xf8\x64\xf3\xfa\x2c\xd8\x6e\xe5\xf3\xe9\x9e\xef\xdd\xf3\xbd\x3f\x2f\xdf\x53\x6c\x8f\xbd\xf3\xbf\x03\xbe\x67\xc9\xee\xab\x8b\xee\x1e\xc9\x5d\x14\xf4\x09\xee\x2b\x45\x1b\xb2\x79\xed\x60\xc8\xd9\xbd\x0a\x47\x34\x79\xa2\x03\xd0\x6f\x29\xc2\x2f\x53\x52\xbe\x8e\x16\x52\x5c\xec\x0a\x89\x3a\x64\x3c\xa8\xbb\x29\x64\x4d\x2a\xb5\x87\x8a\x2d\x76\xb7\x0c\x39\x3f\xd4\x32\x36\x37\x65\xa1\xff\xad\xc9\x1b\x45\xa3\x51\x34\xc5\xb2\x25\x3d\x4f\x13\xfe\x43\x3b\x6f\xee\xa9\x53\xcb\x7e\x5d\x9f\x9d\x64\xe7\x38\x89\xc6\xa2\x59\x3b\x5b\x9d\x31\x42\x5f\xf6\xd4\x5f\xb9\x06\xf1\x53\x23\x44\x31\x8b\xd2\x34\x4b\x8d\x71\x9b\x10\xea\x5c\x13\xd6\x40\x34\xb4\x02\x27\xab\xd0\x03\xa1\xa3\x52\x9d\x97\xc2\x7a\xa0\xa6\x9a\xf8\xd9\x2d\xf4\x02\x19\x95\xc9\xf3\x98\x3d\x36\x0f\xa0\x7f\x88\x26\xa0\x41\xae\x1e\x38\x0d\xf4\x93\x09\xeb\x03\xd5\xe7\x1a\x4e\x7d\xb5\x15\xeb\xfd\x6d\x55\xb7\x5e\x7d\xdb\x02\x5a\x99\x72\x85\x32\xb4\x98\xdf\xd8\x4a\x39\x62\x58\x44\x31\x37\x25\x05\x53\xcf\xcf\x0b\x3c\xa6\x9b\x97\x34\xcf\xd7\x8d\xae\xb8\xf7\x14\x9f\xe5\x94\xaa\x62\x84\x29\x5c\xcc\x23\x72\x59\x36\x58\xe3\x59\x94\x47\xe3\x12\xe7\x85\x50\xf1\xc3\xbd\x3c\x2f\xad\xed\x23\xde\x36\xc8\x34\x0d\x34\x5b\x68\xb4\xb9\xe6\x77\xfb\x41\xa6\xb3\x12\x09\x8f\xb4\x96\x77\x5f\x3e\x06\x43\xda\x64\x20\x01\xf4\xae\x08\xa0\x1d\x8f\x8f\x21\x66\x21\x02\x30\x10\x94\x16\x5e\xab\xca\x1b\xe2\xad\xfe\xe0\x97\x8c\xa4\x10\xac\x01\x3d\x85\x3a\x50\x88\x3a\x9b\x9d\x3e\xda\xe0\xc0\x15\x86\x6f\x37\x9e\x0b\x08\xd8\xf3\x67\x9f\x0c\x18\xc4\x8a\xb3\xc1\x7b\xb8\xc1\x3c\x2e\xdf\x74\x5e\xaa\x0c\x11\x4d\x47\x34\xb0\x75\x82\x19\x22\x04\xf3\x70\x7d\x4c\x5b\xf3\xc2\xbc\x35\xd7\xcc\x0a\x49\x69\x25\x7e\x64\xe9\xfe\xa8\x3d\x8e\x92\x68\xe3\xca\xec\x90\x79\x20\x39\x61\x5b\xbb\x14\xe9\x67\x2c\xde\xf3\x70\x88\x7e\x24\x69\x8c\xd8\xe3\x2e\xde\x51\x19\xaf\x99\x4a\x14\x9d\x8e\xba\xc9\x07\xdb\x97\x00\x42\x48\xcd\xf0\x67\x61\xc2\x2c\xcf\x5c\x34\x8d\x9d\x7a\xe8\x89\xa3\xfa\xac\x44\xab\xd9\xd6\xdf\xbd\x80\x71\x0d\xb7\xa9\xd9\x43\x64\x63\x7f\x5b\x07\x17\xb1\x90\x75\xdb\x0e\xd5\x54\x8f\xd0\x76\x78\xe8\x0b\xd9\xc2\x04\xf5\x58\x91\xfd\x7d\xb4\xd9\x37\x4e\x69\xa3\x1c\x47\x9f\x14\x28\x1d\xe5\xc6\x3e\xe2\xaf\xca\xe9\x0c\x1e\xce\xa2\xfc\x30\x8b\x31\xd4\xe0\x3d\x84\xd1\xc9\x16\xe6\x38\x45\x99\xb7\xa3\x10\x36\x69\x2b\x91\xc8\x01\x2d\xf2\xdb\xd1\x08\x34\xf7\xdf\x43\x24\x37\x99\xf9\xa2\xac\x7a\x9d\x6e\x4e\xb6\xc7\xc7\x7c\x6f\x91\xe3\x09\xf9\xcc\x82\x68\x6d\x7e\xee\xd3\x59\x00\xae\xe1\x77\x6f\xcf\xa3\xbd\x55\xcf\xbe\xd7\x76\x19\x8e\xa0\x51\x02\xdc\xbc\x36\x98\x80\x2f\xca\xa7\xe1\x6b\x9f\xbb\x5d\xe7\xdd\xd0\xa9\x82\x52\x3c\xc7\x3c\x9b\x7d\x58\x0e\xdc\x6c\x9b\x2d\x07\x31\x23\xb4\x25\x45\x1d\x93\x2c\xb7\x4d\xe8\x8a\x32\xaf\x8a\x88\xaf\xcd\x28\x85\x1a\xf3\xb9\x39\x28\x7b\xe4\x66\x2b\x1d\xac\x13\x79\x70\x70\xc3\x6b\x9b\x02\xa1\xfd\xdd\xd8\x47\xa9\xd8\x17\xbe\x47\xdb\xe8\x29\x3d\xd9\xa0\x0d\x44\xf7\x83\xd4\x47\x13\xdc\x85\xfc\x0c\x7f\xbe\x4b\xd2\xb0\x62\x0e\xd8\xb4\xd1\xc0\x1a\x7e\x33\xe2\x70\x78\x86\x46\x1d\xbf\x0d\x05\xfc\x6e\xd3\x6a\x79\x2c\x9d\x2c\x93\x44\xa2\x61\x88\xcf\x71\x5a\xb2\x87\x02\xc0\xf2\x7f\x29\xb2\x14\x45\x23\x62\xf3\x78\xe1\x36\xf1\x43\xf6\xe3\x32\x49\xec\x37\x94\xe2\x31\x01\x2d\xfd\x88\x95\x76\x1f\x43\xb1\x86\x9d\x76\x15\x63\x77\xdb\x30\x04\x29\x5a\xb9\xae\x3a\xa5\xdf\x03\x30\xa1\x20\x69\x8c\x3f\x1f\x4f\x7a\xdd\x5e\xb7\x0f\xbe\x21\x1f\x6d\x79\x9e\x43\x4a\x78\xc7\x4e\xb0\xbc\x5c\x60\xde\x1c\x00\x01\x15\x99\xfe\xcc\x7a\xa4\xff\x45\x84\x10\x1e\x50\xf8\x3d\x74\xcd\x45\x31\xd3\xf2\x4f\xb6\x82\x36\x50\xb7\x47\x67\x4e\xd6\xbe\x81\xba\xfd\x6e\xab\xb5\x17\x93\x62\x91\x44\x97\x6c\x5e\xc0\xc7\x68\x5a\x52\xd9\x56\x62\xc3\x7e\xb3\xf6\x19\xb2\x9f\xb3\x62\x75\x2f\x5c\x69\x6d\xe6\xe4\xfb\x97\x97\xd1\x03\xba\xa5\x59\x14\x83\xa7\x03\x11\x6f\xf1\xb2\xc7\xcd\xea\xfa\xe8\xd1\x0f\x32\x51\x4e\xab\xdb\xb7\xda\x87\xcf\xd2\x66\xd3\x99\x59\x03\xcd\x1c\x8c\x4d\x36\x7a\x6a\xbf\x69\xe5\xef\xc1\xe8\x9a\x51\xce\x46\x86\x43\x35\xd0\xec\x1c\xe7\x49\x16\xc5\x38\x96\x8a\x60\xcf\x9a\xd0\x07\xf0\x41\x11\x49\xd5\x9b\xc6\x21\xfa\x70\xfc\xfc\x38\x44\xf3\xe8\x13\xa8\x86\x49\x7a\xbe\x4c\x52\x9c\x47\xa3\x04\xdf\xe5\x00\xd5\x69\xc0\x7e\xbd\xbb\x85\x1e\x21\x2d\xbb\xdf\x1f\xe4\x78\x91\x44\x63\xdc\xeb\xa2\x2e\x38\x75\xa3\xa7\x85\x8e\x19\x24\x32\x4b\xcf\x71\x5e\x16\x2a\xe4\x26\xc8\x7d\x31\x1e\x93\x79\x94\xd8\x4c\x96\xa4\x7e\x66\x5f\x66\xcf\x59\x01\x97\xf2\x6a\xc3\x67\x9a\x6e\x0d\x99\x80\xc7\x6b\x6a\x0c\x00\x59\x66\x6e\x7c\x4c\x19\x7e\xa6\xcd\x18\x1b\x65\x5b\xca\x13\xef\x6a\x5c\x5a\x5d\xf5\xc1\x59\x53\xa1\x25\x75\xc7\xe7\x09\xcd\xcd\xd5\xa7\xe6\x8e\x62\x1c\xf6\x19\x40\x82\x8b\xe2\xc3\x2c\x4a\x7b\x9b\xe0\x44\xf6\x11\xb3\x3a\xe7\xd6\xfb\x9c\xb0\xb6\xfa\x10\xbe\x55\xcb\x31\xb0\x78\xb0\x04\x37\xcd\x1c\x95\x51\x7a\xc9\x1d\xef\x70\x77\xa4\x69\x35\x5a\x07\x1c\xaf\x07\x69\xcc\xd4\xff\x8c\x86\xc8\xe4\xb2\xe0\x8e\xd4\x0b\x34\xc2\x93\x2c\xc7\x03\x87\xae\x5e\xf2\xa3\x43\x3d\xee\xaf\xf8\x1e\xd4\x40\x5a\x2f\x61\x9f\x37\x90\x2f\xd7\xef\x43\x6e\x2a\x36\x8f\x3e\xb3\xb0\x95\x9f\x49\x79\x19\xa2\x27\xa0\xc2\x16\xbb\x0e\x29\xb8\x4b\x63\x28\xda\xb7\x37\x19\x6d\x92\x7b\x1b\x14\x62\xcf\x28\xaa\x4f\x67\x7d\x61\xab\x2c\x37\xa4\x3b\xa7\xb4\x43\x4f\x21\x0c\x69\x5d\x6f\x15\x10\x5f\xe9\xef\xef\x8f\xdf\x0c\x24\x96\x59\x7b\xca\x81\x25\xb8\x8e\x2d\x50\x64\x47\xf3\x0c\xd0\x22\x2a\x0a\xca\xbb\xca\x59\x9e\x2d\xa7\x33\x73\x05\xc8\x81\x70\x5a\x83\x5a\xdd\xcb\x49\xc5\xd5\x1e\xc1\x69\xc9\x23\xf3\x56\x8e\x58\x00\xf0\xb7\x1d\x66\x75\x0d\xb5\x9d\x0b\xfb\x51\xad\x02\xd4\x5b\x27\xc5\x8f\x24\x25\x25\xb6\x90\x6e\x75\x03\x24\x44\xad\x13\xa6\x94\xe5\x76\x54\x5b\x17\xef\xf8\xa6\xc2\xd6\x01\x3d\x2f\xa5\xc0\xfd\xd1\xcf\xd8\x16\xa4\xa6\xb8\x84\x88\xc5\xc7\x93\x93\x94\x78\xb5\x5d\x50\xb6\x9c\x61\xfe\x43\x2e\x38\x54\x66\x81\xd4\x4e\x49\x87\xe8\xde\xa8\x8d\xb2\x1f\xb2\x9a\x1e\xeb\x4c\x1f\x8a\x80\xdb\xae\x02\xe1\x3c\xcf\x72\xe1\x92\x86\xf5\xb8\x40\x69\x56\xa2\x71\x96\xe7\x78\x5c\x86\x17\x72\xdd\x98\xbd\x36\x16\x10\x2d\x28\x48\x60\xc9\x32\xe1\xbf\xa7\xf0\xdf\xa0\xcc\x5e\x65\x17\x38\x3f\x8c\x0a\xdc\x03\xe6\xc2\xf4\xbd\x8a\x8f\x51\xa8\x7f\xf0\x5b\x66\x7e\x75\x73\x4a\xff\x3f\x53\x47\x71\x0d\x44\xf7\xfb\xad\x13\x1e\xf3\x44\x96\xe2\x0b\xf4\x82\x8e\xaa\xd7\x85\xab\x5e\xe8\x08\xd8\xaa\xfe\xbb\x5b\x22\xfc\x99\x14\x65\x11\xa0\x45\x82\xa3\x02\xc4\x62\x18\x79\x96\x4a\x54\x4d\xb2\x24\xc9\x2e\x48\x3a\x85\x92\x05\xe5\x82\xd6\x32\xe2\x3d\x0c\xc0\xbf\x42\xa0\x9e\x7d\xd4\x44\x89\x95\xbd\x07\xef\x57\xa6\x57\xe1\xe8\x13\x86\x45\xc8\x18\x3e\x5c\x46\x13\xb0\xa7\x95\x4c\x96\x91\x00\x65\xb5\xe0\xab\x82\x4d\x3c\x43\x2d\xa7\xac\xb7\x59\x51\x90\x51\xc2\xa6\x10\x5c\x68\x70\xa3\xbe\xf7\x47\x54\xbe\xcc\x4b\xf6\x93\x8a\xd4\x02\x5b\x2f\x26\x13\x32\xbd\xe4\x1f\xc7\x82\x94\x1e\xa1\x4f\xb4\x79\xf6\xa7\xae\xab\xe0\x93\xdf\x6c\x31\xb0\xb9\x02\x93\x97\x4b\xec\x53\x5c\x45\x31\xb8\xa9\x82\x93\xf7\x3f\xec\x93\x5f\x18\xa9\x3c\x56\xe0\xd1\x23\xb9\x30\xd5\x3d\x0e\x2b\xf0\x6b\x34\xca\x8c\x3c\x4f\x09\x71\x0f\xc3\x06\x00\xd7\x37\x7a\x1e\x2b\xa1\xf5\x42\x2b\xcc\x3e\x39\x16\x34\x10\x64\x41\x68\x1f\x70\x99\xc2\x11\x82\x15\x0e\xa7\xda\xef\x52\xfc\xb6\x45\x0a\xc6\x17\xac\x93\xef\x95\x94\xd3\x19\x39\x8c\xa3\x94\x9e\x0c\x22\xc9\x9a\x79\x3a\xd7\x95\x65\x39\x8a\xd0\xcb\x17\xff\x84\x43\xb8\x90\xd6\xee\x8c\xa1\xc8\x7d\x56\x1c\xed\x7e\x9e\x61\xe1\x67\x2f\xd2\xae\x72\x79\x14\x14\x2d\x58\x00\x5d\x4f\x51\x81\x2e\x30\x5d\x20\xca\xc1\x8a\x18\xc6\x9a\x26\x0d\xfd\x8c\x8d\x23\xb9\x18\xa7\xce\x52\x98\xa8\x43\x6b\x16\x4c\x42\x17\x8a\x58\x09\x3d\x6a\xac\xc9\xa9\x18\x77\xb2\xe4\x21\x7d\x1b\xe6\x15\xa0\xa7\x46\x23\xa1\xfe\xa5\x49\x56\x8d\xcb\x37\x62\x38\xf6\xac\xe0\x0b\x4c\xee\x17\xec\x7f\xcb\x12\x2f\xb3\xba\x05\xae\x9d\x17\x7e\xb3\xa5\x4e\x57\xdb\xef\xb8\xd8\x01\x21\x77\xb3\xd4\x4b\x32\xc7\xc5\xef\xb1\xcc\x53\xae\x5c\xa4\x8b\x5b\xaa\xaa\x0a\x76\xcc\x87\x2d\x1a\x49\x5b\x16\x87\x1c\x64\x4f\x5a\x11\x85\x22\x03\x71\x77\x48\xe7\x5e\xd1\x82\x59\x9b\xf4\x72\xa5\x2a\x50\x00\x12\xff\xba\xf1\x8d\x35\x0b\x0d\xe7\x9f\x6f\xa8\x10\x08\xcb\x5e\x94\xe7\x3f\xae\xae\xd0\xe6\x9e\xf7\x70\xc3\xeb\x75\x0e\x27\x2c\xdd\x38\x11\x71\x9c\x8b\x9e\x3c\x78\x80\xf8\x6f\x9f\xd0\x4f\x9b\xb4\x73\xf5\x13\x86\xcf\x07\x9a\x21\x8b\xf1\xc2\x52\x27\xb2\xf9\xb9\x1b\x74\xbb\xfa\x85\x8b\xe5\x29\xcd\x57\x5a\x27\x94\x4a\x99\x2e\x15\xb1\x63\x3d\xa4\x22\xe9\x84\x81\x89\x28\x1e\xf2\x28\xc6\xcd\x26\x01\xb6\xbc\xc8\xba\x05\x1a\xcb\x98\x2e\x0e\x69\x99\x21\x5f\xda\xd0\x57\x05\xd5\x68\x87\x64\xb3\x4e\x53\xe1\x65\x90\x0c\x05\x1f\x69\x94\xe5\x5b\xb0\xf0\xe4\xbb\xa7\x79\xad\x93\x05\x74\x95\x44\xe3\xd4\x75\x26\xb7\xfc\xeb\xc0\x2c\x0f\x16\xc9\xb2\x50\x5d\xe0\xdf\x5e\xf7\x86\x12\xc8\xd4\x24\xcd\xf0\xf8\x53\x21\x8e\x4d\x8c\x47\x8a\x6b\xce\x82\x3f\x96\x4b\x2e\xc1\x8f\xaf\x37\x1a\x31\x23\xf9\xb1\x37\x12\xb1\x19\x53\x58\x6b\x80\xae\xff\x48\xc1\xeb\x8e\xed\x20\xb8\x12\x9f\x39\xab\x6e\x63\xe2\x78\xa5\x96\x06\x6d\xf8\x9f\xcd\xcf\xa7\x9b\x8f\xbe\x8b\x1e\x4d\xce\xbe\xec\x6e\x5e\xff\xcf\x90\x0c\x4a\x5c\x94\x12\x7c\x85\xb1\xd7\x0c\xf9\xeb\x0c\xb6\xc5\x30\xe1\xfc\x3f\xfc\x4f\x6f\xf3\x73\xff\x69\xed\x38\x75\xfa\x1b\x0e\x55\xac\x2c\x16\x0d\x0b\x7a\xc7\x3c\x08\x73\xa3\xc3\x39\xbc\xe3\xa5\xfb\xb1\x36\x6a\x93\x7e\xb9\x23\x40\x64\xba\xaa\xf0\x76\xc6\xec\x0b\x65\x73\x1a\xd8\xc1\xa3\x1f\xbd\x60\x56\x97\x21\x74\x57\xb7\x00\x67\xc7\xc5\x9c\xfe\x3b\x8e\x16\x05\xc8\x0e\x49\x82\xc4\x77\xa0\x7b\x68\xb4\x7b\xcc\x1c\xcf\x6b\x1d\x36\x1a\x38\x96\xdb\x3b\xc3\x0e\x8e\xc6\x33\x34\x8e\x0a\xa7\x1a\x52\x30\x42\x59\xce\xf9\x0c\x69\xd4\xc4\x56\x59\x7b\x9a\x62\x6d\x15\xcb\xf9\x1c\xc7\x95\xe4\x65\x35\x77\xc7\x64\x66\xd5\x5e\x47\x6e\xc3\x21\x1b\x8f\x85\x9b\x48\x96\xe4\xbf\x9c\x1d\x48\xe9\x43\x38\xc4\xcb\xa8\x00\x67\x34\xb3\x68\x47\x34\x62\xea\x52\x84\xb4\xe3\x73\xf8\xb2\xbb\x09\x77\x94\xc8\xa2\x10\x70\xde\x5d\xce\x50\x82\xe1\x39\xb5\x16\x81\x6f\xb1\xc0\x39\xed\xad\x98\x86\x14\xa2\x17\x4e\x09\x0b\x70\x17\x15\x78\x1e\x2d\xe8\x74\x6c\x19\x9a\xbe\x9e\xb4\x60\xd0\x3a\x0d\x6e\xd9\xb6\x1e\xf7\xd1\x0f\xe8\x5b\xba\x9d\xf3\xac\x53\x72\x36\x28\xb3\x13\xda\x10\xd7\x05\xad\xef\xef\x6b\x99\x40\xf4\xf5\x15\x7e\xbf\xef\xa9\x51\xd7\x2e\x59\x35\x56\xf8\x0a\xd7\x96\xa5\x62\xf9\x06\xe3\x57\xf1\x17\x24\x95\xbe\xe6\x47\x3d\x41\x8d\x15\xa4\x58\x66\x77\x49\x8a\x42\x7b\x2d\xf7\xe5\x15\x28\x51\xd3\x19\x4b\xea\xb3\x5f\x5d\xf3\x76\xba\x5d\x4e\x4a\x2e\x99\x1a\xf8\xbd\x11\xd1\x6a\x40\x63\xa7\xf7\xb4\xa2\x1a\x32\x16\xbd\xd0\xae\xdd\x6d\x92\x06\xa6\x37\x53\xa6\x7f\x94\x48\xbf\xa3\x07\x9f\x09\x73\xa0\x2f\x6e\xe2\x24\x85\x1b\x04\xdc\x44\xbf\x26\x05\xd9\xfd\xdf\xd8\xaf\x24\x6e\x8d\xbc\x6c\x46\xda\x58\x53\x2d\x69\x5a\x25\x4d\xc9\x53\x49\x9a\x06\x1b\x2d\x33\x2a\x51\x92\x18\x6d\x6f\x32\x9f\x41\x8f\xf8\x05\x21\x6b\x93\xbd\x4f\xd8\xfc\x8c\x98\x71\x87\x6b\xdc\xd5\x48\xc9\xfe\xdb\x7e\xee\x7d\x40\xe7\xda\xd2\x80\xab\x1d\xfd\x5a\xe2\x8c\x77\xe3\x13\x4e\x75\x05\x3e\x34\x19\x9e\xed\xb6\x75\x1b\xad\xa7\x22\x7e\xf9\xe5\xab\xcf\x84\x10\xa1\x17\xe1\x4a\x49\xd6\xa8\x5e\x53\x05\x68\x77\xd3\x7f\x4b\x20\x1c\x11\x8b\xd3\x74\xa1\xa4\xdc\xe6\x20\x9b\xde\x93\xa4\xef\xea\xcb\x08\xbc\xc9\x36\x32\xdf\x19\x10\xf5\x58\x37\x2c\xb9\x50\xf4\x2d\x2d\xca\x28\x1d\x53\x2e\xa2\x0a\x5f\x5d\x49\xa4\xf1\xc2\xf0\x7a\x0d\x7e\x19\x8e\x33\xbc\xa9\xcc\x36\x02\x78\x91\xac\xb2\xdb\x16\x51\xe2\x3c\xdc\x84\xa5\xf7\x8e\x71\x51\x4b\x14\x79\x42\x24\x79\xf1\xc3\x59\x2b\xef\x19\x8c\x86\xf5\xad\x7b\x77\xe8\x61\x7d\x69\x8d\x1b\xd1\xe3\x66\xec\xfc\xa8\x8c\x48\x56\xc5\x8f\x28\x7a\x23\x0c\x89\x12\xdd\x96\x23\xa2\x7d\x2a\x9b\x87\xc3\xba\x7e\x83\xc1\x1c\xf3\xbe\xb5\x5c\x0c\x54\xbc\x48\x97\x49\x02\x51\x12\x7a\xee\x0a\x01\xc3\x6d\x50\x61\x78\xc6\xce\xef\x6b\x5b\x8e\x7c\xc4\x3a\xdb\x82\x1d\x30\xc0\x9b\x30\x03\x96\x74\xa3\x89\xe4\xdd\x6b\x3b\x1a\x70\x01\xd8\x3c\x16\x27\xa2\x46\xcb\x91\xb8\x51\x31\x5a\xb2\x34\x28\x58\x3b\x06\xfb\x38\xc2\xf6\x51\xb0\x91\xcb\x04\xd5\x99\x83\xf8\x7b\x61\xae\x2b\x65\x81\x50\x3b\x06\x5a\xcc\x7e\x35\x20\x5d\x27\xe5\x97\xee\x3e\xb5\xbe\x0e\x37\x93\xec\x19\xae\x32\x66\xbd\x46\x63\x08\xfb\xd4\xc3\x9e\xbd\x4d\x3f\x90\xae\x32\xea\x88\x8f\xfb\x05\x9d\x40\xbc\x9c\xa3\x51\x92\x8d\x3f\xa1\x19\x8e\x62\x9c\xd3\x8f\x6c\x6e\x5b\x6d\x90\xe2\x19\x4d\xf6\x09\x0d\x33\xfc\x59\xfa\x45\x87\xb2\x68\x42\x92\xd2\x56\x66\x7a\x08\x16\x60\x0d\xf7\xc3\x34\xa5\xf6\xa4\xff\xcd\xd6\xb6\x3a\xea\x33\xf0\x06\xbc\x54\x1f\xd4\x59\x5d\x7a\x55\xbe\x73\xba\x0b\xe5\x8b\x38\xac\xce\xd9\x6b\x6e\x3f\x6e\x30\x33\x49\x46\xc5\xbc\x05\x19\xbb\xf3\xf0\x81\x26\x37\xcd\x43\x29\x81\x6a\x26\x00\x6a\x32\x26\x00\x8a\xd5\x4e\xc0\xe3\x5d\x85\x7f\x06\x7d\x63\xfc\x43\x55\x7a\x4d\x3e\xf4\x3b\x40\x37\xc2\x7e\x85\xe3\x11\x2e\xf2\x85\xe2\x47\x20\x52\xe1\xd1\x4f\x28\x7f\xb1\x74\x10\x0c\x43\xf6\x9f\x48\xe1\x16\x24\xa1\xfa\xc9\x72\x34\xeb\x92\x50\xff\x10\xe5\x4e\xca\xc9\x93\x90\xff\x2f\xd2\xc0\x5e\x25\x14\x3f\x54\x3d\x0c\x56\xfc\x52\xe9\x1c\x5e\xfe\xe4\xf5\xb8\x46\xb7\xa1\x2f\x91\x41\xbb\xb6\x9c\xa1\x27\xcd\x80\x15\x66\x93\xa1\x9d\x20\xc6\xf1\x33\x86\x51\xfc\x8c\xb5\x31\x40\x1a\xff\x21\xe0\xa4\xb4\x18\xea\x1f\x22\xd7\x54\x59\x87\x4e\x8a\xc4\x1a\x13\xd4\x43\xf5\x93\xe5\x68\xd2\x71\xa8\x7f\x88\x5c\xe3\x24\x12\xda\x09\x02\x4a\xcb\xb7\x72\xac\xa3\x7b\xe8\x26\x89\x1e\x3a\x90\x4e\x92\xa8\x53\x08\x63\xa1\xf6\x5b\xef\x6f\x3a\x0d\xe5\x2f\x91\xce\xf6\xd4\x50\xfe\x92\xa3\x67\xeb\x3d\x54\x3f\xe5\x98\xe8\x2e\x19\x8a\x1f\x22\x95\x6e\x58\x21\xff\x5f\xd6\x41\xf9\x5d\x28\x7e\x88\x54\x60\x1b\xa1\xf8\x11\xc0\x02\x63\x0e\xea\xf8\xab\xee\x4e\xb8\xf5\x5d\x50\xeb\xdf\x26\xe8\x2c\xcb\xc9\x93\x4e\xf8\xe4\x9b\xeb\xb3\x60\x7b\xab\x8d\xc7\x07\x73\x09\xef\xb3\x05\xdc\xe1\x8e\x0e\x3a\x21\xea\x6c\x0e\xb6\x37\x07\x5b\x9d\xb5\x6b\xe1\x0a\x6e\xbb\x55\xa4\xe2\x7b\x4f\x12\xf7\x9e\x24\xfe\x0a\x9e\x24\x78\x2d\x6b\xae\x2f\xb8\xbf\xe3\xc9\x24\xc7\x97\xe8\x67\x92\x8c\x3f\x61\xf4\xfd\x2f\x78\x32\xb1\xdd\x49\xb4\xf4\x18\x07\x60\x24\x4a\xd1\x31\x95\xb8\x23\x80\x22\x51\xea\x82\xfd\x18\x8d\x28\xd8\x3f\xb2\x29\x4e\x8a\x12\x27\x09\xce\xd1\xf7\x13\x48\x74\x81\x7f\x8a\xce\xd1\xcf\x59\x16\xa3\xef\xa7\x95\x6e\x2e\x76\x95\x7b\x1f\xee\x0b\xf2\x75\x94\x46\x53\xd3\xf7\xc4\x60\x48\xb1\x30\xcc\x19\xc0\x9c\x01\x08\x1f\x13\x47\x23\x38\x1c\xd9\xc0\x64\x14\xa5\x02\xe4\x05\x98\xf1\xdb\x10\x4c\xf2\x2a\x86\xb8\x9c\x09\xc0\xe7\xcf\x6a\xe0\xe2\x91\xf4\x37\x3b\xab\xab\xaf\x98\xc9\xfa\xde\x80\x67\xf2\x2a\xc0\x14\x97\x02\xf0\x2d\xce\x0b\x78\x4a\x55\x0d\xbd\xe0\x20\xb2\x13\x17\x51\x3e\xaf\xeb\x06\xcd\x97\xc0\xb8\x2c\x21\x6a\x93\x0b\x5f\xf0\x2c\x01\x2a\xb8\x8a\x01\x29\xd8\x05\x3d\x51\x29\xe7\x1e\x24\xb1\x2a\xd4\xc2\xca\x57\xfb\x08\x61\x40\xc2\x1b\x13\x7f\xb8\x81\xd3\xd8\xd3\x37\x96\x21\xc0\x9e\xc1\x89\xc9\x85\x1a\xd1\x74\x89\xc9\x3c\x5b\xe0\xbc\xbc\xf4\xc0\x2d\x78\x96\x00\x7d\x59\x96\x8b\xb7\x79\x76\x4e\x62\x2f\xb9\xd1\x85\xba\xe0\xd9\x92\xd8\x16\xe3\x9a\x12\x64\x31\xb6\x0b\xb4\xf3\x68\xb8\xb6\x26\x65\xf5\x9f\xf1\x68\x07\xf5\x44\x35\xa6\x57\xde\xdc\x5e\x21\x29\xbe\xb0\x96\x8d\x2a\xa9\x39\xe8\xe5\xa1\x56\xb5\x9e\x0b\x28\x0d\x08\xb3\xb7\x2e\xf8\x82\x2e\x17\x70\xd4\xaf\x57\x11\x8f\x78\xe6\xf3\x67\x4e\x5e\x31\x13\x25\xdf\xcf\xdc\x92\x29\xac\x01\x9a\xfb\x06\x97\x4e\xee\x42\x11\x3e\x05\x11\xeb\xc0\x81\x1b\xfd\xfa\xab\x68\x83\xd2\xb5\xdb\x07\x45\xe0\x00\xc4\x3f\x7b\x3a\x8c\xa2\x6c\x75\xd4\x88\x16\x24\x94\x9b\x21\xff\x9f\x1d\x39\xf4\x4e\x72\x6c\x15\x46\x51\x9d\x7c\x42\xe3\x2b\x90\x30\x1a\xbd\x84\xfa\x87\xd3\xc4\x47\xb9\x06\xd8\x0f\x67\x80\x1c\xa0\xa7\xda\xe7\xe4\x4c\x70\x11\x6a\xbf\x7b\xcc\x98\xe7\xba\xbf\x47\x25\xa6\xe1\x10\x5c\xf0\x16\x18\xa9\x31\x64\x6c\x27\x06\x9f\x40\x6b\x94\xdc\x3c\xe3\x6b\x1a\x5b\xe5\xb8\xa8\xd0\x28\xea\x14\xf1\x34\xb1\x4e\x79\x7a\xcc\xe0\x66\x1a\xd7\x0b\xaf\x4c\xda\x9e\xbe\xe4\x98\x05\x8b\x50\xbd\xf8\x84\xf1\xe2\xa8\x78\x7f\x99\x8e\x49\x3a\xad\xed\x0a\x94\xb5\xe0\xdb\x51\xa0\xa7\x23\x3a\x5f\x78\xa6\xec\x57\x2c\x28\xf1\x0c\x86\xb9\x93\x82\x2f\x0f\x8c\x78\x32\x2b\xa0\xe0\xdb\x03\xc7\xdf\x5d\x0b\x30\xfa\xe9\x40\xe9\x4f\x70\x19\xa0\x4c\xf1\xc2\x1a\x75\x8a\x04\x4f\xdb\xea\x3d\x95\x68\x9e\xa7\x78\x6b\xb5\xa1\xb5\x34\x4f\xdd\x3a\x2e\x45\xed\x75\x38\x65\x26\x8e\x02\xf2\x67\xec\x1f\x99\x0e\xc5\xbf\x1d\x38\xdd\xb4\x85\x41\xca\x14\x0f\xac\x7b\x2b\x2c\xca\x1c\xda\xb7\x85\x4e\x9f\xab\xca\x3a\x39\x9e\x76\x8f\x9e\x1d\xbc\xd1\x1a\xa3\x9f\x0e\x94\x72\x4f\xc3\xc0\xf8\xb7\x0f\x4e\x78\x4e\x91\x80\x90\x40\x77\x31\x7b\xe1\xb3\xad\x5f\x7f\xc9\xcd\x2e\x85\x4c\xef\x8a\xe6\x75\x1d\xdc\x49\xdb\x90\x55\xd7\xa7\x31\xc9\x41\x55\x3c\x8e\x16\xf0\xfa\x42\xbb\xc0\xf4\xcc\xe8\xd1\xe1\xc1\x5b\x63\xed\xd3\x72\xba\x85\x1c\x61\xa2\x24\x5d\xbe\x54\xaa\x64\xf9\xc6\x63\x4f\x0a\x31\xe0\xcd\x88\x95\x0d\x0e\x65\x24\xff\xad\x8b\x38\x7a\x2a\x79\x37\xec\x75\x5c\x1c\xe9\x99\x77\xce\x29\xe8\x60\xba\x62\x4f\x4a\xb3\x18\x77\x03\x03\x62\x0a\x66\x21\x21\xea\x52\xa1\xe3\xe3\x38\x21\x38\x2d\xff\xc1\xc0\xbb\xea\x4e\xba\x1f\xdc\xa4\x35\x5c\x5e\x64\xf9\xa7\xaa\x06\x53\x5c\x7e\xe4\xa0\x16\x88\x19\x30\x20\xb4\x57\xf9\x2d\xbb\x85\xb9\x42\xbb\xaa\x5f\xb8\x9c\x7d\x84\xb9\x1e\x67\xc9\x3f\x7e\x87\xfe\x5d\xcc\x48\xb1\x90\xbe\x91\x9d\xee\x15\xb3\xd9\xad\xd1\x06\x3f\xcf\xbc\x7b\x09\x29\x0e\xb3\x34\x65\x3e\x9b\xb4\xe5\xd6\x37\x68\xaf\xe7\xdd\x2e\x1f\x3c\xf0\x6e\xa3\x7a\x95\xbd\xbe\x7f\x07\x63\x5e\x0a\x84\x4c\x5e\x49\xf3\x60\x1c\x0a\x91\x13\xb8\x44\xe3\xd5\xdb\xd2\xba\x85\x37\x51\xfd\x84\xc0\x54\x4e\xc6\xc1\xa2\x13\x6e\x6f\xd2\x24\xfd\x48\xd2\x09\xb7\xb7\x68\x9a\x3a\x0e\x74\xc2\xed\x5d\x99\xc2\x44\xa7\x4e\xb8\xfd\x44\x26\xe9\xc2\x7d\x27\xdc\xd9\x96\x19\x74\x85\x77\xc2\x9d\x1d\x95\xa0\x84\xfa\x4e\xb8\xa3\x2a\x55\xc7\xc2\x4e\xb8\xf3\xad\x93\x8c\xcb\x59\x27\xdc\x79\xe2\xa4\xa7\xb8\xec\x84\x3b\xdf\x39\xe9\x42\x10\xee\x84\xbb\x9b\x4e\x66\x31\x9b\x75\xc2\xdd\x2d\x37\x9d\xca\xc2\x9d\x70\x57\x75\x5f\x9c\x71\x3a\xe1\xee\x37\x32\xd1\x3c\x38\x77\xc2\xdd\xc7\x32\x4b\x48\x2d\x9d\x70\xf7\xdb\x7a\xdd\xde\xf5\x59\xb0\xbd\x73\xaf\x79\xbb\xd7\xbc\xfd\xb7\x68\xde\xa2\x24\x01\x07\x13\xb7\xf3\xe3\xaa\x29\xb8\x1c\x55\x88\x4f\x17\x22\xc2\xc4\xbc\x38\x67\x16\xfd\x9a\x8e\x01\x7a\x23\xe0\x54\xd0\x98\xa6\xe8\x48\xae\x9e\xc6\xab\xa8\xf9\x11\x2e\x77\xad\xca\x20\x4d\x40\x5c\xb0\xd8\x47\x26\x88\x60\x45\x3c\x53\x7a\x77\x3d\x48\x12\x63\x28\xa6\x60\x64\x1e\xad\x02\xb8\xa9\x0f\x90\x65\x5a\x56\xa1\xf4\x30\x13\xf4\x23\xf2\x2f\xec\x72\x9e\xfe\xa7\x27\x3b\xe6\x92\x6c\x13\x72\x7a\x58\x1f\xe6\xdb\x92\x5a\x85\x3f\xf0\x7d\xf9\xeb\xea\x0a\xe2\xdf\x20\xdb\xef\x03\x4d\x84\xd4\xd3\x2e\x95\x42\x21\xae\x40\x37\x40\xdd\x32\x63\x3f\xcf\x06\x0c\xcd\x5a\xbc\xc3\x89\xe7\x36\x94\x37\x73\x3a\x39\x03\x03\x17\x69\x1f\xca\x6f\x48\xfb\x9e\xa0\xd9\x56\x35\xb4\x3f\xb4\xf8\xbe\x46\x3c\xcc\x85\x0e\x74\x84\x9d\x97\x54\x10\x3c\xd5\xa0\xb0\x59\x50\x0f\xb7\xc0\x17\x85\xc2\xab\x81\x67\xf3\x75\x97\xee\x9d\xa2\x0e\xe3\x9e\xa8\xc5\x71\x54\x46\x62\x04\xf4\xf7\x80\xfe\x83\xf6\xb5\xdf\x57\x57\x60\x14\x2b\x01\xe0\x2a\xb9\x10\x20\xfc\xeb\xea\x4a\x45\xdf\x04\x6d\x23\x6d\x5a\xdc\x91\x6b\x80\xa7\x9b\x67\x83\x82\x32\x04\xe9\x62\x9d\x42\xcf\xb9\x80\xa3\x28\xcc\x9d\xae\x5f\x3c\xd3\xa5\xb7\xb2\xcf\x4d\x6d\xb9\x74\xe7\x5e\xda\xf6\x7e\x91\xef\xd3\xfb\xa7\x9b\x67\xda\xc3\xab\x75\x68\xbf\x8f\xbe\xc0\x63\x87\x28\x4d\xb3\x12\x4d\x48\x1a\xb3\x7e\x91\x74\xca\x1a\x7a\x2a\x9b\x1f\x67\x69\x91\x25\x78\x70\x11\xe5\x69\xaf\xab\x97\x60\xde\x72\x28\x2b\x4e\xb2\x69\x57\x33\x7d\xe5\x3d\xa6\xa8\x70\x3c\x2e\x61\xce\x86\xf4\xc8\x5c\x30\x77\x3d\xdf\xea\x0c\x58\xb7\x02\x93\x20\xcc\x23\x14\xd4\x28\x9c\x1d\xc2\x14\xb7\x58\x8e\x9f\xf1\x98\x4a\x00\x9e\xf5\x18\x80\x47\xa6\x51\x34\xfe\x24\x63\x88\x82\x2b\x02\x7e\xd8\x15\xd7\xad\xbd\x28\x9f\x2e\xe1\x2d\xc8\xa9\xfc\xa5\x79\xe3\x31\x8d\xd0\x45\x8d\x10\xfb\xb9\xb6\x98\xee\x37\xae\xe7\x40\xd0\x89\xdf\x32\xfd\x58\x28\xb6\x91\x2e\x93\xc4\x41\x77\x26\x28\x8d\x7b\xbf\x53\x07\x60\x01\x31\xd1\xa2\xac\x31\xcd\x2c\x60\x72\x30\x22\xa6\xd2\x50\x13\xbf\x19\x67\xef\x65\x01\x1c\x94\xba\x81\x97\xb1\x06\x82\xbd\xd3\xc3\x56\xaf\x1f\xa8\x86\x34\x0c\x37\xcf\x54\x54\x96\xd1\x78\xf6\x21\x3b\x14\x8e\xb0\xf4\x29\x13\xde\xb1\xf4\x33\xb7\x9a\x5a\x36\x6e\xf6\xe9\x0c\x47\x14\x1d\x44\x49\x22\xf7\x13\x0e\x5c\x71\xa6\x70\xba\x29\x0f\x18\x9e\x13\x86\xf7\x88\x01\xa4\xda\x09\xb7\x41\xba\x67\xab\xbe\x13\x6e\x83\xec\xae\xc7\x6c\xdb\x01\x60\x6b\x23\xec\x84\xbb\x3b\x54\x64\xde\xbd\x17\x99\xef\x45\xe6\xbf\xb6\xc8\xac\x85\x7b\x81\xb3\xf7\x5d\xc5\x7b\xf9\x7b\x91\xa5\xf9\x62\x6c\xca\x9b\xbf\xb0\x44\x79\x75\x98\xe7\x99\x2d\x02\xb3\x34\x29\x89\xba\x2a\x0a\x3a\x58\x43\xc8\x74\x64\x4c\x40\xc7\xc7\x4a\x49\x93\x67\x14\x3c\xb0\x77\x83\xa3\xc0\x28\x8e\x85\x4f\x47\xca\x8e\x79\x61\x70\x93\x0d\x5d\xe3\x09\x96\x45\x60\x14\xc7\x1e\x1b\x5b\xc4\xc7\xcf\x0a\x95\xca\xba\x75\xb8\x06\xe3\xd4\x59\x71\x1c\xfb\x64\x6e\xdf\xc0\x0b\x16\x15\x5c\x40\x34\x8e\x48\x30\xed\xba\xfe\x73\x18\x6f\xd7\x7c\xfb\xb9\xe9\x5d\x40\xe2\xd7\xe8\xa6\x3b\x05\xea\x9e\x28\x8d\x99\x9a\x49\xc0\x06\x5a\xdd\x38\xcf\x03\x2e\x89\x16\xae\x4c\xcc\xc8\x87\xfd\xe2\xc2\xa2\x02\xe0\xf8\xd1\x5d\x4c\x4a\x54\x06\x08\x5e\xb7\x57\xbc\x5f\xe3\x55\x9e\x02\xcc\x99\x7e\x3c\xa8\x14\xd8\x59\x91\x8a\x6a\xa9\x58\x23\xfa\xc3\x2b\x1d\x38\xb2\x8f\x5d\x60\x9d\x2f\xa2\x01\x29\xfe\x11\x25\x24\x7e\x87\x8b\x45\x96\x16\x98\x37\xe5\xbc\xbd\x73\xc6\xe0\x6f\xaf\xc7\xd6\xd8\xe0\x28\x3d\xf7\xd6\xba\xe7\x54\x7a\xed\xf6\xaf\xb2\x72\xe6\xb3\xc9\x19\x2c\xdb\x73\xc1\x37\x84\x2f\x83\x37\x3e\xe0\x7d\x00\xaf\x11\x7a\x82\x13\xc5\x5e\x4d\x85\x3c\xdf\x20\xbf\x28\x01\x94\xa5\xf4\x93\x6c\xf0\x9d\x70\x1b\xf4\x68\x7c\x45\x76\xc2\x1d\xb0\x7a\x6b\x15\xe5\xfb\x7e\xc3\xbf\xdf\xf0\xff\xbc\x1b\xbe\xda\xef\xa5\x58\x7e\x47\x2a\xb2\x96\xba\x2a\x7a\xe2\xc9\x2d\xb0\x82\xcb\xfa\x43\xc8\x5c\x55\x9d\x26\xe0\xb4\x77\x53\xba\x1e\x4c\x3c\x88\xe2\xd0\x07\xda\x21\x44\x03\x93\x1a\x43\x23\xe4\xb8\x6f\xff\x64\xea\x25\xfd\x91\x19\x6c\xf3\xf6\x33\x65\x06\x77\xa8\xc0\xde\x0a\x28\x29\x17\x80\xb1\xef\x35\x12\xbe\x9c\xcd\x54\x6f\x03\xdc\xdb\xaf\xbf\x6a\xf3\xa9\xe7\x88\x04\xbc\x9c\x75\xab\x13\x8d\x88\x47\x0d\xa2\xf9\x7d\x46\x96\xa3\x65\x16\xe0\x7b\x7f\x1f\x75\xb5\x3e\x75\xd1\x83\x07\x86\x23\x67\xed\xdc\xcc\x9a\x35\xbc\xfd\x5f\xf7\xad\x6d\xb8\xae\x41\x8f\x6b\x68\xd4\x83\xc4\x8a\xed\x1a\xf2\x98\xc7\x68\xcf\xce\x60\x55\x44\xc1\x0a\x4f\xd3\x40\x7b\xfc\xf0\xce\x10\xca\x40\x25\x1a\x35\x2d\x8f\xd0\x5e\xb5\x90\x1e\x65\x40\x2f\xee\x2a\x8a\x1d\xad\xbd\x2f\x9b\xa2\x38\x16\x34\x5c\xa8\x63\xb8\x4e\x1b\x22\xed\x5a\xd6\x54\x49\x4f\x8c\x54\xfc\x55\xd6\x9e\xec\xd5\x71\xfd\xe6\x84\xa2\xbd\x42\x5c\x65\xf6\x75\x4d\x95\xd4\xfe\xc8\xfe\x7c\xc4\xe5\x4c\xa8\x9b\x55\x27\x4d\xaf\x17\x8d\xaa\xd4\x89\xa3\xe6\x50\x08\x50\xaa\xd2\x16\xf3\xca\xb8\x45\xab\x49\x65\xfc\xe6\xee\x66\xd4\xae\xaf\x59\x51\x23\x18\xde\x5d\xcc\x2d\xe3\xbd\x96\x5a\x99\x73\x56\xae\x6d\x94\x3c\xd6\x9c\x3c\x57\x6f\xc5\x3a\x56\x39\x9d\x07\x49\x52\x3b\x5d\x00\xc4\x2f\x7a\x56\x26\x30\xa6\x0a\x6d\xe8\xe0\xea\xd4\x66\x3c\x0a\x74\x95\x6a\x55\xd4\x56\x47\x6e\xd2\x51\x0e\xd8\xfe\x89\x49\x9f\xe2\xb2\xe0\xc6\x2b\xc9\x25\x8a\xf1\x22\xc9\x2e\x71\x2c\x4c\x04\xe1\xf9\xe0\x78\x16\x91\xd4\x7e\xae\x06\xb5\xfd\x98\xe5\xa2\x47\x1e\xdf\x03\xe2\xc0\xea\x23\x49\xb1\x2e\xaf\xa5\x6a\x71\xcd\x70\x91\x7b\x22\x2e\x37\xd4\xb3\xb6\x8a\x16\x75\x83\x07\xd1\x92\xa6\xb0\x54\xe4\x0b\x01\x9b\x21\x92\x8c\xa3\xe6\xfd\x11\xa2\x94\xef\x8b\x87\x65\x90\x3f\x1c\xa2\x8b\x88\x30\x75\x39\x88\x5c\x8b\x52\xa9\x60\xc5\x4d\x99\x39\xef\x7c\x29\xc8\x80\xd1\xaa\x63\xb8\x6f\x7a\x5e\x5e\xc7\xf0\x34\xd9\x68\xdf\xde\x95\xa0\xbf\x1b\x1b\x7b\xe6\xb1\x69\x38\x44\x45\x99\x2d\x98\xae\x96\xa4\x53\x14\x4d\x68\x57\xbe\xd9\x64\x73\x55\xa0\x5e\x49\xe6\x38\x5b\x96\x7d\xe7\xe8\xc8\x10\xf0\x03\xfa\x66\xd3\x7b\x58\x64\xbd\x1f\xd0\xda\x7f\xe6\x95\xab\x98\x0a\x7d\xf4\xe5\xda\x73\xa6\xb3\x11\xc8\x1e\xec\x79\xcf\xa1\x72\x46\xbc\xa7\x4d\x75\xf2\x53\x8e\x81\x25\x63\x82\xfb\x92\x88\xad\x8c\x31\x25\x6c\x70\x12\x3c\xa2\x12\xf3\x32\x8d\x6d\x0c\x74\x7d\x87\x4f\x9c\x68\x0e\x45\xf4\x3f\xc7\x1d\xf1\x8d\x5b\xa5\xcb\x4f\xaf\x59\xfa\x13\x71\xb1\x66\x50\xcd\x14\x97\x1f\x54\x53\xef\x18\xa9\x29\x8e\xa2\x75\xe3\x65\x54\xcc\x74\xa2\x0a\x04\x61\xf6\xfd\x47\x78\x32\xe9\x71\x00\x3f\xb5\x79\x0b\x79\x3b\x08\x21\x8c\x78\x5d\x83\xb1\xb9\x00\xcd\x1e\x41\x9c\x23\x7f\x77\xc4\x5f\x95\xf7\xf6\xc7\xd2\x7b\x7b\xd5\x1f\x99\xf4\x4c\x8a\xbb\xba\x42\xeb\xd0\x62\x6d\x31\x24\x59\xb7\x87\x36\xf5\xbf\x9b\x2c\x01\xfd\xaf\xe5\x72\xb0\x87\x94\xc5\x5a\x88\xe8\x9d\xda\x99\x11\x7f\xc3\xa1\xbc\xe7\x4b\xb2\xa9\x46\xb5\x70\xac\x10\x6c\x7c\xbd\xdb\x6f\x68\x1e\x19\xa2\x9a\xe4\xa8\x15\x53\xdd\xa2\xb2\xe1\x10\xb1\xcd\x4a\x88\x0b\x51\x1a\x23\x7e\x33\x82\xa2\x69\x44\x52\xbe\x72\x2e\x30\x8f\xf0\xd7\xf0\xe7\x97\x3d\xed\x0d\xb0\xa1\x06\x5b\xd6\x71\xb6\xff\x86\x21\x8d\x99\x53\x36\x7e\x29\x48\xb7\x04\xba\x3b\x16\x78\x9c\xa5\x31\xa2\x0c\xb7\xb1\x12\x8d\x74\x9b\x89\x15\x19\x1c\x11\x74\x61\x6d\x3b\xec\xf5\x62\x74\xc7\x1d\xd2\x7d\xb7\x6b\xa2\x04\x3f\xd1\x6a\x9c\xb2\x28\xb3\x1c\xc7\xd2\x8f\x3b\x93\x40\x40\xe3\x33\x8d\x0a\x14\xcd\xe9\x86\x34\xf0\xf2\x6b\xfb\xaf\x92\x7f\xdb\x7f\x1e\xf7\xf2\x77\xd1\xc5\xfa\x1e\x5e\x57\xe6\x56\x71\x0c\xb7\x84\x0d\xa9\x69\x27\xdb\x1e\x28\xb4\x2b\x06\x41\xe8\x3f\x46\xf4\x98\x7d\x29\x7d\x69\x58\x52\x9c\x05\xd6\x70\x68\xb0\x2b\xd5\x0f\x0c\x70\xaa\x8a\x46\xc4\xb8\x5c\x60\x2f\x8a\xb0\x38\xbe\x43\x5a\x34\x22\x68\x9f\x42\x0a\x39\xeb\x21\xd3\x84\x36\x8f\x49\x9d\x90\x52\x14\x69\xa2\x29\x2f\x2e\x6a\x11\x63\x4b\xf1\x85\x4c\x12\x63\x4a\x2f\xaf\x75\x62\xb0\x74\x23\x5b\xc2\xa6\x20\x4a\xfa\x2b\x16\xdd\xae\x29\x6a\xcb\xc1\x86\x64\xc1\x7d\x9d\x08\x45\x71\xec\x94\xf6\x49\xca\x1c\x42\x4a\xcb\xea\xf8\x27\x92\x64\x5b\x6a\xe2\xa1\xd0\x50\x4d\x04\x45\xa9\xef\xfa\x05\xd5\x6c\xd1\xdf\x8a\x1a\xe8\x9f\xfc\xc1\xa4\x6b\x79\x8a\xd4\xe9\xaf\x27\xe8\x20\x90\xb3\xaf\x73\xb0\xe1\x90\xc5\x56\x54\x56\x16\x46\xa5\xca\x56\xe2\xcb\xf5\x1e\x05\x16\x58\x5a\x37\xdb\xe6\x88\xd1\x2a\x86\x33\x6e\x0e\x6f\x71\x80\x90\xf5\x47\x09\x09\x19\x63\xb8\x6a\x50\xf6\x1a\x56\xf8\x3f\x9f\xed\x08\xd8\x7f\x54\x5b\x8c\x20\xc7\x6a\xa4\x18\x2c\xb2\x85\xe1\x60\xce\xec\x5e\x12\x15\x25\x87\x74\xaa\xf6\x77\x87\x11\x52\x8f\x16\x04\xe7\x45\xeb\xf2\xc5\x09\x04\xa2\x85\x74\xbb\x4f\x0a\x85\x0d\x5d\xa2\x0d\x71\xe0\x01\x8b\x4a\xf2\x03\xda\xb4\x6b\xe3\x33\x2d\x68\xff\x40\xac\xe5\x66\x2d\x80\xf8\xbb\x95\x4a\x50\x43\x93\xc5\x2c\x85\x3a\x4d\x9a\xda\xe9\xc3\x5a\x37\xbb\x3c\x58\x44\x97\xd1\x28\xc1\xbe\xee\xb9\xc7\x01\x66\x3f\x55\xe0\x34\x56\x11\xa9\xd2\x2c\x7d\xc4\x2b\xd1\xd1\x61\x6f\x13\xd7\x55\x53\x0f\xbe\xfd\x28\x67\xf4\xab\x60\x7b\x62\xa9\x04\x30\x62\xad\x56\x31\x41\x60\xfb\xb6\xb1\xcf\x2a\xda\x33\x27\xb1\xf2\x46\x50\x3f\xd1\x1a\x3a\x00\x21\xf7\x45\x71\x6a\x6b\x09\x62\x8c\x2e\xa2\x42\x0a\x94\x6b\x26\xae\xd8\xd2\x86\xab\x57\xed\x08\xa3\x0c\xb3\xac\xfb\xd7\x59\x54\xcc\x7c\x48\xa7\xbd\xc6\x79\x5e\x75\x13\xa9\x5f\x39\xfa\xee\x15\xeb\x24\x1e\x2a\x8e\xc6\x31\xbb\xf6\xd2\xb8\x2e\xed\x89\xbf\xad\x8a\x63\x17\xda\x87\x32\x15\xc2\x57\xa5\x84\x38\x21\x79\x51\x56\x0b\x88\x2b\xca\x78\x15\x1a\x10\x9f\xda\xc3\x77\xfd\x6a\x7c\x35\x39\xbe\x84\x48\x9b\x6c\xe0\x4d\xf3\x6c\x35\xd6\x16\xe5\x8d\xa8\x5e\x65\xe8\x7e\x9e\x26\x75\xf2\x0c\x88\xeb\xca\x38\x76\xc5\x26\x48\xcf\xb7\xcf\x99\x5d\x29\x24\xf1\x4f\xc3\x00\xed\xc6\x82\x97\xad\x35\x6b\xd2\xce\x7a\x36\x75\x5e\xd3\xb5\x29\x03\x4d\x64\xfd\xc3\xb5\xe1\xd0\xda\x81\x8d\x0b\x1c\xe5\xf1\x58\x53\x5f\x5a\x95\xf7\xd8\xbe\x3c\x1c\x1a\xae\x74\x2b\xe3\x4e\x8f\xc7\xe0\x15\x37\x63\x81\x9a\x48\x3a\xad\x91\xcd\x4c\x35\xb6\x39\x72\x36\x89\xd7\x2e\x27\xd2\xc5\xa1\x3a\x51\x08\x7d\xd1\xa4\xae\xb6\x12\xd1\x04\xa5\x99\xaa\x81\xb2\xb7\x45\x54\x14\x38\x0e\x68\x15\xca\xf5\x1d\x85\x28\xb4\x25\x6d\xf2\x32\x49\x78\x30\x03\x16\x3a\x0d\x73\x48\x9f\xef\x54\xd3\x66\x15\xad\x2c\x43\x29\x4b\x79\xa5\xad\x2c\x67\x9a\x6b\x49\x08\x56\x03\x21\xc2\x84\x51\x81\xec\x52\x20\x0a\x8c\xf0\x38\x5a\x16\x98\x9e\xc4\xe3\x2c\x2d\xd1\x45\x94\x82\x4d\x52\xb1\xc8\x48\xc2\x6e\xc3\xd3\x12\xe7\x93\x68\x2c\x7d\x63\xb7\x38\x89\xb7\x39\x6d\xdb\xdb\x54\x33\x3f\x44\x8e\x7b\x5d\xb9\xa6\xb5\xb5\xf9\x13\x2e\x99\xb3\x66\xba\x3f\x06\xe8\x62\x46\xc6\x33\x30\x1a\xa0\xcb\xbb\xcc\xf8\x36\x86\x16\xc9\xb2\x68\xbe\x7a\xe5\x7c\xa0\x61\x7e\x15\xf3\xf0\x1b\x32\x35\x88\xb0\xab\xcb\xa9\xb2\x58\xb3\xfc\x78\x1b\xd9\xb1\x5a\x6e\xd4\x8c\x95\x6f\x24\xc7\xd4\xc9\x30\xe6\x4b\x87\x01\x33\x48\x6f\xcf\x7c\x3d\xa7\x1e\xef\x71\xb7\xc5\xf5\x79\x15\x6b\x72\x0e\xc3\xde\x53\x70\xc5\x4b\x16\xdf\x79\xd8\xdd\xfd\x94\x5d\x38\xc3\x9f\xfb\x78\x05\x79\x0e\xd3\x5e\xb3\x25\x8b\x6e\xf7\xa4\xf9\xb3\x69\x2b\xd1\x09\xbf\xad\xb2\x80\x96\x16\x0d\x9d\x70\x7b\xc7\x35\x89\xe6\x23\xef\x84\x3b\x5b\xd7\x67\xc1\xf6\xe3\x7b\xd3\xa7\x7b\xd3\xa7\xbf\xb6\xe9\x93\x66\xeb\xcc\x4d\x20\xef\xc0\xd8\xb9\xc2\x8d\x25\x37\xae\x64\xef\xb2\x8e\x27\xe2\xce\xf9\x20\x9f\x16\x61\x85\xe6\x46\x93\xf1\xf8\x09\x96\x57\xa2\xc7\xbe\x13\xdb\x09\x65\x9f\xa2\x52\xa4\x9b\x38\x01\x9f\x0f\x7c\x7d\x78\xf7\xf6\x90\x31\xf7\xdb\x74\x80\xc5\x5b\x02\x56\x8b\xe1\x01\x63\x99\xa1\x77\x6f\x0f\xf9\x3d\x81\xbf\x03\xfc\x39\x3a\x38\x51\x54\x2d\xcf\xb2\x42\xbf\xfd\x72\x1b\x3f\x3c\x7e\xf3\xe6\xc5\xe1\x87\xa3\xe3\x37\xe8\xc5\xbb\x77\xc7\xef\x42\x74\x28\xd5\xbf\x63\x56\x25\x3b\xd1\xc7\x18\x75\x37\x10\xad\x0f\x6d\x74\x07\xfe\x3e\x28\x8f\x37\x6d\xc7\x2e\xdf\xd9\x33\x25\x42\x49\x57\x0f\x61\x95\xf9\x9b\x10\x86\xb4\x21\xb2\x8d\x82\xb5\x61\xc2\xb3\x34\x5c\x14\xd1\x14\xa3\x7d\xb4\xbe\xce\x5f\x1a\xd2\x6d\x9d\xff\x1e\xb0\x90\xb1\x4e\xca\x40\x14\x7b\x8a\xbc\xc9\x21\x92\xd3\xf5\xf7\xf7\xc7\x6f\x60\x56\x72\xd9\x25\x4f\x98\x55\xde\x37\xe7\x2d\x99\xc2\x01\xaf\xda\x1c\xad\x9a\xcd\x0f\xec\xba\x5a\x1f\xef\xbc\x68\x3b\xa5\x1f\x8e\x5e\xbf\x38\x3e\xf9\x10\x22\x7e\xe9\x4d\x89\x8b\x76\x72\x5e\xa0\x0d\xd4\xa5\xff\x45\xe3\x19\xe5\x18\x5d\x23\xa0\x0d\x77\x23\xf9\xed\xfd\x6e\x75\xbf\x5b\xfd\xb5\x77\x2b\x6d\xb3\x82\x57\x97\x7f\x54\x2b\xdd\xf6\x8f\xd9\x5b\xbd\xa1\xbf\xc3\xa7\xec\xc2\xe7\x10\x5d\xff\xf2\x70\xa6\x47\x64\x2a\x8c\x63\x08\x7f\x63\x0b\x6d\xa9\xc3\x82\x6d\x84\xfc\xb5\xdf\xc1\x2f\x84\x29\xaf\xa6\x48\xd7\xf3\x59\xe8\x0a\x54\xf3\x1c\xb9\xc8\xd2\x7e\xc3\x13\x7a\x2d\x33\xcd\xd2\xcb\x79\xb6\x94\x2d\xca\x84\x8a\xd3\x9b\x40\xda\x14\x0b\x5c\xe1\x98\xc9\x03\x10\xc4\xc0\x09\xd6\xc4\xd3\xe4\xf1\xec\x59\x96\x25\xd7\x10\x5e\x35\x06\x17\xe4\x6c\x93\xc0\x0c\x32\xd6\x66\x07\xde\x87\xe0\xd8\x70\x98\x2e\x4e\x7c\x10\x8c\x80\x2e\x4a\x5e\xfb\x70\xcd\x98\x26\xdd\xfb\x16\x85\x30\x1d\x47\xb1\x7a\xed\x00\x0c\x1a\xf2\xdd\x2b\x11\xe2\x11\x15\xc8\x80\xd7\x04\xf7\x1b\xfc\x77\x85\xb9\xab\xbf\xbc\xb2\x57\xae\xbc\x21\xd6\xb1\xcd\xe8\x33\x66\x2e\xc0\xc1\x8b\x91\x85\xeb\x58\x79\x07\xf7\x46\x0b\xf2\x56\x50\x8d\x3a\xad\xba\x3a\x27\x41\x8c\x12\x5d\x07\xe5\x3d\x45\xaf\xed\x47\x07\x2b\xd4\x33\xb4\x92\xfb\x33\xaf\x19\x97\x5e\xb4\x9e\x1e\x56\x1a\x91\xf0\xa4\x7e\xa3\xe1\x14\x64\x9a\x46\xe5\x32\xb7\x87\xa3\xa7\x57\x8d\x47\x87\xa9\x1e\x8f\x84\xaa\x1b\x10\x38\x30\x68\xdf\x7f\xfe\xc2\x41\x90\x37\xe7\x48\x51\x1a\x4b\xd5\x52\x99\x41\x50\xe2\x09\x49\xa3\xc4\x6f\xf5\xcc\xea\xf0\xd9\x94\xea\xeb\xda\xca\xe2\xd5\x1b\x48\x11\x79\xf8\x1c\xe7\x97\xe5\x8c\x69\xac\xe7\x23\x02\x2c\x23\x63\x51\xa2\xa1\x6f\x3c\xcc\x42\x2d\xb6\x3c\xae\x41\x78\x77\x1c\xcf\x76\x72\x71\xcb\x5f\xda\x23\xc0\x7b\x07\x22\xca\x5d\x87\xf4\xcf\xd1\xe4\x59\x44\xe8\x35\xd7\xad\x9d\xc7\xed\x27\xaf\x9c\x3d\x6c\xe5\xbe\x05\x99\x9f\x4e\x41\xed\xbd\xbe\xab\xd2\xe4\xf3\xf4\x41\x74\xec\xb6\x2c\x5d\x0b\x61\x51\xcb\xcf\xc1\xf1\x32\x0f\xa6\xcd\xcb\x9f\x12\x08\x31\x65\x19\x03\x70\x20\x7d\xfe\x28\xdd\xa8\xe4\x74\x99\x24\x15\x2f\x5c\x94\x66\x11\xb9\x97\xff\xa6\x42\x18\xea\xab\x0a\xcc\x08\x99\xd6\x68\xce\x6b\x6e\xfb\x39\xf6\x9d\xb7\x31\x3d\xb6\x7d\x05\xe8\xdc\xbe\x39\xef\xdb\xb1\xf5\x56\xaa\x0d\xfa\xde\x40\x71\x26\x91\x8c\xb3\x74\x1c\x95\x3d\x63\xf6\xfb\xd5\x7e\x6c\x2a\xb9\x1e\x77\x62\x53\xcd\xf5\xec\xdd\x16\x57\x71\xb8\x98\xdd\x3d\xb8\x3c\x8c\x73\x05\x6e\x38\x04\x27\x04\x56\x4b\x2c\x9b\x7d\xf0\x00\xf4\x0d\x66\x2f\xea\xb7\xe9\x6a\xe7\x3b\x80\x83\x3b\xf4\xbe\x13\xe5\x53\x6b\x75\x29\xf1\xf1\xa9\x51\x32\xd4\xbf\xb8\x67\x9e\x2d\xcd\x13\x0a\x1f\x1f\xbf\x7f\x91\xf5\xda\x2f\xb5\xd8\x64\xa2\x2f\x52\x4a\xd3\xeb\xdb\xee\xef\xd1\x95\xf9\x4b\x46\xd2\x5e\xa7\xe3\x56\x2e\x1f\xc5\x31\x72\x63\x78\xd2\xaf\x37\x40\x36\xec\xd1\x65\xde\x0f\xf4\x1e\xe9\x57\x35\x69\x56\x1e\x19\x7d\x95\x28\xf4\xf8\x1b\x52\xc0\x2d\xdb\x86\x57\x0b\xfd\xc0\x6a\x45\x6f\x5f\x6e\x24\x1a\xd7\xce\x96\xe5\x62\x59\xbe\xca\xa6\x8a\x5d\x73\x5f\x3c\xda\x6a\x11\xce\x7f\x98\x9f\x19\x4d\x2c\x33\xc1\x14\xb7\x86\x31\xd9\x6e\xa0\x18\x0c\xbb\xe5\x32\xf8\x69\x8e\xe3\xe5\x18\x6b\x73\x15\x8d\xc7\x01\xe2\xae\x28\x75\x7e\x12\x8d\xc7\xa7\x3c\x99\xf1\x44\x8a\x14\xfe\x2d\xa8\xfc\xa9\x39\x65\x83\x62\x46\x26\x65\xaf\x8f\x42\x07\xa3\x22\xcb\x51\x5a\x45\xe3\xb1\xd0\x52\x31\x63\x6f\x46\xda\x38\xc1\x25\x16\xe3\x50\x4e\x92\xcc\x74\x46\x55\x37\x60\x19\xda\xfd\x15\x7f\x57\xc2\x97\x36\xdd\xea\x99\x18\x57\xe9\x58\xe1\xae\xe4\x22\xa3\xe1\x7a\xe1\xc7\xe3\xb8\xc1\x96\x7e\xfe\xe8\x1e\x99\xb6\x9b\x3d\x32\xd5\x15\xdf\xaa\xb6\xb1\x33\x2b\x40\x86\x04\x68\xf8\x7e\xb0\xc5\x0e\xdb\xed\x93\x23\x50\xfe\xa1\xfc\x3f\x55\xd2\xb2\x6e\xfa\xdf\xe2\x51\xa3\xf5\xaa\xcd\xfb\xa2\xb1\x96\x1a\xbf\x96\xb3\x29\x0a\x6a\x9e\x5c\xab\x38\xa0\xb0\x2f\x84\x96\x4e\x35\x80\x33\x83\x7a\x7d\x00\xba\xff\x2a\x45\x14\x5e\xd0\x53\xc9\xee\x59\xdb\x67\x95\x03\x30\xac\x26\xbc\x77\xc2\x06\x2e\x35\x8f\x58\x75\x57\xc2\x4d\x7e\xb2\x6e\xe8\x1a\xeb\x49\x1b\x05\xfc\x6d\x7d\x5d\x0e\xfd\xba\xc9\xd7\x8c\x06\x3d\xfa\xbf\xfa\x40\x22\x7a\x0c\x91\xb5\xe1\x10\x7d\x38\x7e\x7e\x1c\xa2\x1c\x33\x83\xac\x00\x15\x19\x37\x9d\x91\x57\x5c\xca\x16\x27\x62\x9a\xae\x01\x2d\x47\xca\x6e\x81\x52\x3c\xc6\x45\x11\xe5\x97\x74\xb1\x40\x04\xec\x82\x92\x5b\x17\xfc\x15\x83\xb7\x68\x74\x91\xe5\x9f\x98\x94\x37\x5f\x26\x25\x59\x24\x5a\x24\x07\x33\x76\x8a\xdf\xbd\xd1\xf0\x21\xf2\xda\x72\x7f\x23\x4c\xb9\x59\x1d\xa6\x19\x83\x68\xde\xb0\x21\x55\x8d\xe1\x98\x6d\x1c\xe6\xc9\x44\x96\x1a\x08\x1c\xf9\x1c\xd8\xac\xd3\xce\x9d\xba\xb0\x67\xbe\xf3\x43\x15\xac\xc5\x4e\x91\x63\xdf\x68\xf6\x93\xfb\x73\xf2\xd5\xd4\x60\x06\xe9\xad\xa7\xf2\x08\xa5\xea\xe7\x04\x6f\x8f\xc9\x01\xf0\x1c\xb9\x59\x8e\x0f\x1b\x2c\x47\x32\x3d\x6e\xd2\x63\x76\xd1\x63\xf9\xc9\x8b\x15\xb8\xb4\x22\xc5\xf8\x7c\x5c\xd5\x1e\xc4\xea\xa7\x9b\xe0\x9a\xf1\x2a\x18\xcf\x90\xab\xe8\x05\xa9\x20\x27\x97\x2b\x0f\x5b\x16\xbc\x83\x81\x23\xcd\x6e\x14\x7f\x1e\x18\xec\x48\x7d\xec\x21\x01\x20\xb8\x10\xfc\xbf\x27\x52\x25\xcb\x61\x3f\x64\xba\xc6\x68\xc4\x4f\x53\x8e\xc4\x9f\xf9\xf3\x6e\x97\x9b\x33\x34\x28\xcf\x44\x15\xfc\xb9\x82\x23\x77\xc2\x1d\xf0\x60\xa4\x3b\x0d\xa7\x8c\xf9\xbb\xfb\x9b\xd1\xfb\x9b\xd1\xbf\xf6\xcd\x28\xbf\x16\xe5\x4f\x7e\xff\x2b\xe2\xeb\xdd\xa9\xc7\x70\x38\x04\x3c\x44\x87\x59\x7a\x8e\x29\x2b\x8a\x78\xc8\x63\x38\x07\xc3\x59\x00\xe2\x16\x8b\x40\x2e\x94\x80\xa3\xa4\xc8\x50\x94\x24\xd9\x45\xc1\xc2\xb3\x83\xa2\xae\x18\xac\xd1\x8a\x84\xe0\xff\x9a\x7c\xc6\xf1\x35\xcb\x5a\x73\xef\x35\xd6\xf8\x8d\x6a\x99\xd9\x41\x8e\xb9\xca\x52\x1e\x38\x7b\xa6\x4a\x14\x5d\x5d\x89\x00\xe9\x2a\xa3\x2b\x75\xa8\xdd\xbe\xad\x0c\x60\x67\x39\x2e\x22\x31\xc5\x2c\xeb\x43\x4f\xe8\x17\x8d\x86\x98\x1e\xe2\x78\x02\xaa\xe6\x3e\xd4\xbe\xe9\xd4\x09\x90\x9c\xef\xeb\x2f\x5a\x8d\x3b\x23\x11\x44\x49\xb6\x03\x47\x2e\x2a\x6a\x52\x4e\x2b\x2e\x7f\x6c\x4b\xd8\x4c\xea\xf7\xf9\x61\x2b\xa0\x93\x70\x8e\x73\x32\x01\xbf\x1e\x39\x1e\x47\x94\xe3\x68\x81\x6a\x1e\x3c\x40\x49\xf4\xeb\x25\x4a\xb2\x28\x46\xf1\x65\x1a\xcd\xc9\x18\x65\x29\x2e\xa0\x35\x3e\x21\xaa\x21\x1e\xcc\x3a\x93\x7a\x02\x80\x12\xf6\xf5\xa2\x71\x07\x8a\xce\xd6\x14\x97\xc7\xf2\x90\xec\xf1\xe0\x4c\x27\x46\x09\xac\x4d\xee\x01\x74\x65\x02\x9f\x12\x71\x4c\xae\xbe\xf5\x30\x34\xfd\x95\x57\x2f\x2c\xbb\xb8\x20\x10\xaf\x44\xeb\x15\x02\x1d\x44\x81\xd9\x09\x3a\x74\x5e\x56\x31\xe1\x7d\x99\x63\xae\x5e\x0c\xe0\x02\x6f\xcc\x56\x07\x3b\x1c\xcf\xf0\x67\x9f\xda\x40\x69\x4d\xad\x04\xcb\x13\x65\x8b\x22\x86\xe6\x93\x87\xd5\xae\x54\xca\x5b\x0a\x7f\x11\x84\xfb\x29\x0f\x4f\x4e\xab\xe2\x8b\xac\x8f\x42\xb1\xde\x38\x98\x2b\x2b\xf9\xae\x09\x3c\xcf\xeb\xa0\x9b\xa1\xd5\xed\xc0\x81\xa3\x4b\x40\x41\xd1\x2f\x17\xa6\xcc\xf4\x7a\xdc\xfc\x48\x44\x65\x16\x40\x91\x1e\x93\xd9\x6e\x0d\xee\xaf\xc2\x95\xae\xb5\x06\xb2\x5c\xdf\xd7\xbb\x9b\xd4\xc8\x4b\x99\xfa\x29\xed\xa0\xc3\x28\xb0\x98\x51\x0a\xf4\x20\xdc\x22\x75\xa1\xaa\x39\x88\x63\xf6\x2c\x42\x2a\xd1\xa2\x34\x46\x05\x2e\x0b\xb4\x5c\x40\x06\x3f\x8d\x00\xcb\x20\x25\xce\xe9\xde\x91\x9d\x73\x61\x8b\xbb\x31\x1d\xac\xad\x69\x4f\x23\x5e\x65\xd3\xe2\xa0\x7c\x5f\x46\x79\xb9\x66\x6b\x1a\x0b\x9c\x4c\x64\xe2\xc4\x7d\xbf\xcc\x59\xb8\x59\x8b\x11\x27\x0c\x27\x13\xc7\x87\x8f\x78\x64\x37\xc5\x25\xd3\x67\xd1\xc2\xd6\x4b\x3b\xd0\x2f\xa8\x61\x16\xd0\x3d\x24\x4e\x9e\x16\xcf\xa0\xad\x0c\x7c\x8c\x03\x32\xa6\xb8\xec\x59\x6f\x7e\xb8\x25\xa3\x73\xca\x19\x0e\x51\x9c\xa5\x5d\xfe\x4a\x94\xf6\x91\xa3\x0d\xcc\x26\xe1\xa2\x5b\x24\x0a\xb3\x23\xf0\x84\x31\x18\x0c\xd0\x2f\x4b\xe6\x08\x98\xb6\x49\x79\xaf\x73\x5e\xae\x78\x18\x59\xf3\x28\xf2\xda\x7e\x01\x6b\xad\x74\x39\x0c\xff\x19\x93\x65\x7a\x0f\xa6\xcc\x90\xb3\xe9\x99\x26\x7b\xbc\x63\x9a\x7d\x1a\xfd\x6b\xf6\xc3\xfa\xf5\x48\x77\x91\x25\x09\x23\x1f\x3f\xd9\x72\xda\x54\x60\x36\x5d\x4a\x95\x08\xa8\x6d\xd3\xd7\xd2\x0c\xd7\x20\x96\xac\x82\x5c\xf8\x8c\x66\xce\x9c\x0a\x23\x0b\x4a\x7a\x62\xac\xbe\x49\xf0\x3d\x9b\xf2\xd1\x44\xd6\xfa\x24\xdf\x96\x3a\x6e\x46\x19\xca\x4c\x19\x86\xa6\x94\xd7\x4f\xad\x04\x55\x49\x28\x0a\xb9\xa4\x73\x2b\xf4\xdc\x8e\x48\x2b\xf5\x01\xd0\x27\xdb\x19\x35\x65\x3c\x6f\xb3\x24\xa1\x7c\x46\xf5\x84\xd1\x60\xc8\x8a\xd0\x73\x1a\x9e\xe3\xb4\x84\x23\xe7\x80\x52\x1c\x0c\x4d\xed\x25\x0b\x6e\x68\x7f\xca\x30\x05\xe4\x78\x14\x9f\x05\xe2\x8a\xca\x48\x0e\x14\x31\xf2\x1c\xdd\x8d\x11\x53\x10\x03\xfd\xd2\xcd\x5a\x44\x2d\x74\x48\xdc\x92\xc9\x02\xe4\x84\xf7\x10\xcb\xcd\x73\x3b\x10\xf0\xd3\xd4\x61\x8e\x61\x4c\x60\xaf\x7d\xe8\x79\xe8\x08\xcc\x8e\x69\xb0\xb5\x0b\x57\x03\x1f\x9a\x86\x6f\x15\x55\x59\xa5\xae\xab\x52\xd9\xe3\x57\xaa\x99\x9d\xd1\x6c\x09\x50\xa5\xc7\xf8\x4a\x6b\x4c\x25\x6c\x2a\x31\xd8\x12\x7d\x35\x68\x07\x0d\x66\x82\x06\x29\x66\xde\x7d\x32\x26\x57\x08\xb7\xac\x91\x19\x7c\xcb\x3d\xac\xca\x57\x6c\xcf\xc9\xd2\xaf\x9d\xe4\xef\xca\x7e\x0f\x52\x7c\xc1\x6f\x9d\x74\x1c\xe8\xbe\xc2\x18\x93\x24\xb1\xe1\x1a\xcf\xcf\x1c\x1b\x96\x7d\x6f\x3c\xf2\x88\xb9\xe3\x51\x23\x1f\x44\x9c\x23\xf3\x73\x61\x0d\xf5\x5a\x0e\x49\x5d\xf6\x52\x53\xd6\xdf\x8d\x7a\xbd\xb3\xb1\xb4\x29\x11\xc4\xae\x1f\x40\xdd\x55\x43\x8e\xe1\x92\x81\x9e\x39\x16\x38\x8d\xc1\xc0\x4d\x4e\x72\x54\x80\xa2\x25\x2d\x28\x85\x4a\x5f\x30\xaa\xa2\x6c\x02\xc0\xb4\x10\x95\x7a\xfa\x4c\xb9\x22\x5b\x5f\xa6\x51\x51\x90\x69\x8a\xe3\x81\xdb\x47\x9b\xa2\x7c\x3c\xd9\x37\x3b\x52\xc6\x1a\x8f\x1a\x26\xc8\xdb\x8c\x6e\x32\xa6\x8d\x44\xd9\x13\xa3\x44\x97\x0e\xa3\x24\xc7\x51\x7c\xa9\xde\xab\x2b\x41\xb1\xb8\x3d\xa5\x99\x82\xac\x90\x5e\x9b\xc6\x45\x26\x3d\xab\x35\xe9\x03\x6e\xd3\xf5\xc8\xa5\x56\x26\xe3\xe2\x3e\xb7\x90\x54\x8a\x2e\x33\x3e\x36\x32\x9f\xe3\x98\x44\x25\x4e\x2e\xed\x66\x39\xb9\x8f\xdb\xd2\xb6\x29\x9d\x40\xf5\xbd\x0a\x4f\x13\x3e\xaf\x55\xba\x26\x9b\xb1\x7c\xba\xfd\xb0\xc1\x68\x77\xb9\x17\x4e\x94\x0e\x7b\x33\x37\x79\x1b\x33\xec\xd3\xfa\x21\xd4\x31\x06\x73\xd4\x47\x63\xcd\x13\xbf\x2e\x75\x07\xa2\xe1\x5a\xbb\x13\xbe\x6e\x3b\x10\x7d\xdf\x6d\x1e\x8f\x23\x39\x64\x0b\x21\x38\x98\x03\x69\xe0\xef\xf0\xb4\x7c\x9e\x9d\x0b\x95\x26\x8a\x8a\xcb\x74\x2c\x0f\x3f\x3e\xc1\xc8\xc7\xb7\x97\x29\xbc\x9d\x36\x10\xa0\xc9\x18\x16\xb6\x1c\xde\xa5\x1b\xc2\xaf\x52\xb3\x21\xf8\x3b\x18\x9d\x5a\x21\xdb\x7d\xce\x13\x1c\x99\xc2\x6b\x72\x22\x4b\xda\x42\xb9\xb5\xa3\x56\xd8\x51\x0e\x87\xe8\x68\xa2\x38\x23\x29\xe4\xbb\xbe\x4b\xcc\xdd\xaf\x20\x52\x22\xe5\xa5\x4b\x95\xbb\x98\x61\x30\xc6\xe0\xa3\xef\x23\xc6\x54\x0b\x44\x4a\x93\xad\x7a\x37\x6a\x87\xd8\xe5\x32\xf3\xed\x1e\x3e\xf4\xf3\x1a\xed\x09\xd5\xf7\x63\x88\x90\xe2\xe1\x6f\x5f\xd1\x3f\x8f\x25\x8f\xe7\xd8\xb6\xde\x4b\xb2\x69\x55\xbb\xc8\x62\x4c\x35\x67\x0b\xa8\x25\xa4\x7b\x42\x85\x3b\x3e\x7f\xc0\x12\x13\xc4\x39\x00\xd8\x03\x6b\x4f\x47\x8e\x9b\x29\x2e\x88\x1f\x3d\x67\x09\x21\xa7\xb1\x5e\x7f\xc0\x76\xe4\x71\x24\x1c\x16\x82\x5b\x15\x1c\x23\xba\xba\x67\x79\x96\x66\xcb\x42\x7a\x2f\xe4\x86\x01\x74\xb7\xb7\x3d\x11\xb1\x6a\xb8\xb0\xdb\xf5\x9a\xd7\x82\x53\x89\x4c\x59\xe9\xb5\x21\x20\xd7\x86\x8e\xd6\xd0\x3c\x87\xb7\x98\xb7\xeb\x06\x7e\xec\x5c\x91\x32\xdc\x3a\xb1\xdf\x6a\x2e\x48\xaf\xcf\x82\x9d\xcd\x36\x57\xa0\xdd\x65\xc1\xf4\xe2\xe3\xb2\xbb\x76\x7f\x21\x7a\x7f\x21\xfa\x27\xbe\x10\x55\x4f\x45\x35\x95\xf5\x4d\xde\x8b\x72\xe0\x15\x6e\x32\x7d\xb1\xdf\x5a\x3f\x31\x4d\x27\x64\xea\x85\x63\x59\x02\xf0\x68\x14\x59\x31\x5d\xc8\x28\x4a\x3d\x71\x5a\x40\x9b\xcc\x02\x4d\x31\x1b\x69\x76\x99\x39\x22\x53\xee\xc1\xc0\xb2\x62\x64\x40\xcf\xc8\xd4\x52\xea\xeb\xd6\x8c\x4c\xe3\x7c\xc5\x20\xae\x24\xec\xb5\xe9\xb4\x4a\xa5\xeb\x96\xb8\xa0\x67\xac\x68\xc3\x90\x8a\x58\xef\xbc\xcf\xd0\xca\x4c\x96\x15\x60\x7b\x52\x09\x44\x8a\xb7\x39\xe6\xd7\xa0\xda\xed\x84\x51\xf7\x48\xa5\x5b\x0d\x8c\xf4\x12\xf4\x20\xc1\xbd\xdf\xa3\xab\x2b\x37\x8f\x9f\x4d\xfd\x99\x38\xca\x13\x42\x8b\x6a\x5d\x4b\x17\xcb\xf2\x39\x9e\x44\xcb\xc4\x7b\x71\xd2\xd4\x47\xba\x23\xdb\xed\xc8\x2b\x5f\x6f\xf4\x16\x4a\x32\x83\x58\x6b\xd1\xe3\x7b\xaa\xfa\x1e\x47\xef\x82\x35\x8a\xdf\xa2\xfb\xf6\x8b\x2e\x26\xa0\xd0\x5a\x2a\xe6\xd8\x68\xd4\x53\xa1\x96\xed\xc1\x83\xa0\xad\x97\xf8\xb3\x67\xe4\x7c\x55\xb1\xc1\x16\x9a\x51\x64\x36\x41\x91\xe1\x1a\x30\x4a\x63\x71\x53\x5a\xc0\x4d\x09\xb3\x0b\xa0\xeb\xee\xe5\x8b\x7f\x5a\xcb\x0d\xea\xa0\x72\xb1\x77\xa1\x09\x5d\xbe\xe1\x62\xd7\x31\x7c\x17\x57\xe4\x42\xdb\xef\xd6\xe9\x0d\xfc\xfd\xc5\xb8\x3c\x86\xeb\x3f\xed\x0a\x16\x3e\xaf\xae\x2c\x1a\x3a\x18\x43\xd8\x05\xcd\xf1\x99\x0e\xef\xf1\xb8\x25\xaa\x85\x3e\x71\x37\x54\xfe\xab\x47\x53\x0e\xd2\xab\x2e\x33\x1e\x2f\x9a\x94\x68\x4e\xa6\x33\x26\x38\x4a\xe7\xc5\x5c\x49\xe5\xb4\x5c\x66\x8d\xed\x96\x99\xd9\xea\x69\x77\x1a\x15\x6f\x73\x32\xc6\xdd\x00\xd1\xdf\xf4\x3f\x98\x3e\xfa\x23\xcd\xd2\x31\xf6\xbd\x4e\xfc\x84\x2f\x6b\xde\x27\x7e\xc2\x97\x6d\x5f\x28\x42\x4d\x0e\x0e\x59\x0d\xfb\x9a\x3d\xc5\x73\x3c\x26\xf3\x28\xe9\xe9\x00\xee\x0b\x31\xf3\x12\xf5\x6b\x13\xb1\xe6\x4a\xf3\xae\x69\xd9\x57\xf5\xdd\x93\xf4\x4d\xa9\xf6\x9e\x5e\x7f\x4b\x7a\xe5\x42\x8c\x43\xb0\x70\x5f\x2a\x62\xff\x70\x6a\xf5\x8a\x36\xad\xe9\xf4\xb3\x29\xce\xf0\xf4\x35\x43\x86\x69\xa4\xcc\xf2\x73\xff\x8b\xd4\xe4\x7d\x1e\xe8\xdb\xdf\xba\x38\x4d\x2b\x0d\x96\x09\x20\x3d\x5a\x64\x02\x7f\x26\x80\x7c\xb3\x41\xd3\x35\x5c\xc0\xeb\x30\x7f\xf5\x0e\x94\xb7\x0d\x1b\x4a\x28\xeb\x3e\x0f\x80\xa4\xfc\x85\x20\x4b\x41\x4e\xa3\xc2\x0f\x37\x8d\x0a\x03\x0a\xc8\x57\x03\x55\xa2\x9d\x96\xaf\x4a\x08\xe3\x35\x2f\xb8\xfe\x54\x56\x9c\xa4\x3f\xaf\x4c\x4a\x22\xca\xcc\x4d\x48\x8a\x07\xbc\xa9\xa5\x2c\x19\x7f\x69\x15\xf2\xb2\x2b\xb6\xdc\xae\xe8\x81\x73\x54\xa0\x9c\x06\x7a\xf3\x41\xb9\x73\xe6\x81\x52\x94\x27\x32\x5b\x90\x5f\x25\x68\x75\x93\x15\x84\x28\xe3\xb9\x2c\xe7\xcb\x24\x2a\xc9\x39\xfe\x29\x2a\x4e\x0a\x78\x97\x56\x55\x95\x03\x6b\xd5\x35\x6d\xac\x61\x2a\xcb\x89\xc1\x9b\xa6\x06\x02\x2e\xc9\xa6\xb6\xe5\x9e\xca\xd0\xa2\xd1\x38\xaa\x25\xd0\x0f\x79\x15\x4b\x9e\xd7\xad\x14\xb6\x49\x8b\xc4\x5b\x6a\xb5\x00\x60\x76\xdb\x93\x3c\x48\xdd\xb5\x54\x0e\x15\xb6\xa0\x71\xb3\x26\xdd\x3e\x05\x6a\x90\x06\x2a\xc3\x21\x92\xae\x7d\xc0\xc7\x1d\x3f\xbd\x22\xc4\x9a\xa2\xf3\xf3\x8a\xcc\x49\xe9\x99\x42\x13\x80\xe3\x4a\x26\x56\xcc\xbb\x91\x6f\x94\x29\xc8\xaf\x3e\x26\xa8\x32\x0d\xe8\x92\xcc\x71\x51\x46\xf3\x45\x65\x11\x09\xa1\xd6\x15\xcb\x48\xab\x56\xae\x91\x5d\x55\xad\x3c\x1a\x6b\x9d\x89\xc9\x64\x42\xc6\xcb\x04\x9e\x67\xb8\x3c\xd4\x06\x32\x07\x92\x95\x51\xf2\xbc\x4d\x05\x16\xa4\x2e\x24\x99\x6b\x86\x83\xab\x65\x6e\xae\x1c\x37\xdb\x15\x41\x48\x89\xe7\x7d\xfb\x61\x96\x63\x1d\x07\x50\xee\x3d\xa4\xb1\xbe\x7c\x9b\x39\x2b\xd8\xb4\xd0\x46\xec\x68\xdd\x62\x99\x25\xd9\xd4\xbb\x9e\xf4\xb5\xed\x5b\x4d\x49\x36\x55\x5a\x14\x77\x49\x41\xbd\xc6\xb2\xd2\x2b\xd4\x17\x95\xa6\xbd\x26\x13\xfa\x65\xf0\x75\x39\x4e\x2b\xc3\x43\x63\x76\xd1\x3d\xbd\x4e\x87\x71\x1b\x15\xb7\xd8\x01\xbc\x95\x18\x4d\x24\xd9\xd4\x53\xb5\x48\xad\xa8\x52\x16\x32\x85\x4e\xd0\xc8\x37\x1f\x90\x2e\x66\xa4\xa0\x7c\x71\x91\x15\xe5\x0d\x4e\x48\x6f\xb3\xa2\x5e\x30\x70\x23\xe9\xd4\xf2\x4f\xb7\x52\x7d\xa2\x69\x27\x75\xe6\x49\xbf\x07\x8b\xe8\x12\xcc\xe3\xf7\x0d\x6d\x87\x9e\xc5\x91\x0c\x49\x65\x99\x78\xc5\x78\x91\xa9\xc3\x5e\x64\xf9\xa7\x0f\xd9\xdb\x3c\x3b\xc7\xd5\x65\x34\x20\xbd\xec\x22\x27\x59\x4e\x34\x8e\xe2\x14\x14\x10\x9a\x83\xf8\x89\x1e\x3f\xc8\x30\x88\x65\xac\x85\x75\x92\x79\xcb\xd0\x79\x8a\x96\x8e\xf6\x8d\xaf\xa7\xe8\x54\xfb\x3c\x43\xa1\xbc\x8d\xbe\x56\xad\x32\x55\x2a\xd3\xaa\x26\x49\x76\x01\xaf\x03\xc4\x31\xb6\xae\xfa\x7a\x6b\x76\x16\x01\x8f\x12\x13\xca\xd2\xe4\x92\xb9\xf5\x2f\x0d\x23\x7b\x61\xe8\xce\x0c\xda\x7d\xef\x33\x84\xb5\x3b\x0a\xed\xb7\x17\xba\x9d\xbb\x7d\xe2\xa2\x7d\x6c\xc5\xbb\xa4\x5a\x1f\xe8\x9f\x1b\x1b\x7a\xb9\x59\x13\xa5\xfb\xc9\xda\x54\x0f\xd7\x13\x36\xa7\x6b\xc0\x2f\xfe\xbc\x20\xf9\xa5\x67\xc5\x6b\xb9\x3a\xb9\x15\xcc\x0b\x88\x17\x9a\xe6\x55\x2d\x01\x0b\xd4\xb3\x00\x80\xb2\x7d\xb2\x84\x05\xd1\xdf\xf3\xad\xca\x77\xd1\x85\x20\x19\x9e\xe2\x05\xd3\xaa\x3f\x28\xc6\x84\xd8\xcb\x57\x94\xd1\x77\xdb\xbf\x17\x1c\x71\x12\x4e\xc5\xd1\x50\xab\x42\x35\x00\x6e\x71\x21\x96\x95\x8f\x39\x0c\x87\xab\xac\x08\x58\x9b\xfa\x6a\xac\x5c\x8c\x6a\xb9\xdd\x62\x25\x59\xda\x5c\x86\xa2\x76\xf4\x2f\x99\xaa\xad\x80\xf1\x05\xbd\xd0\xad\x35\x08\xbb\x8d\x49\xf1\x05\x5c\xcc\xf4\xcc\x90\xc8\xa0\xb1\x1e\x45\xe9\x80\x14\xff\x88\x12\x12\xf7\x20\x64\x01\x4f\x79\x4e\x72\x3c\x2e\x7b\x3e\x75\x35\xf7\x0c\x05\x80\xbc\xc6\x5e\xdf\xd1\x85\xeb\x82\x8e\x8a\x24\x23\x7a\xe0\xa9\xd6\x70\x3e\xe6\xa9\xa8\x45\x15\xbc\x67\x66\x4d\xfc\xda\xd5\x32\x05\xe0\xee\xa1\x05\x6c\x57\x84\x76\x56\x0b\xfd\xfd\x65\x3a\x26\xa9\x5f\x5a\xe1\xfe\x98\xb5\x0b\x84\x75\x33\x09\xb9\xee\x69\x0c\xf1\x0c\x9c\xd9\x80\x2d\x19\x49\xa7\x70\xd4\xf0\x9e\xf0\x5c\x30\xd3\x25\x10\xf7\xce\xd3\x50\x81\x0e\x65\x96\x9f\x91\xe9\x0c\x17\x4d\xe5\x75\x28\x8d\x76\x78\xee\xa7\x34\xbb\x48\xdf\x97\x51\x69\x47\xea\xb7\x73\xab\x1b\xd0\xab\xd8\xb3\x6b\x58\x2c\x93\x04\xc7\x4d\x55\xe8\x50\x15\x87\x4e\xe5\x25\xa8\xc2\x11\x7c\xd3\x3d\x58\xd8\x08\x11\xa8\x7a\x6a\x2a\x68\x28\x69\x5c\x91\x84\x9e\x34\x0d\xd6\x77\x36\x08\xab\xb3\xb4\x92\x36\x2f\x09\xfd\xc9\x5a\x09\x63\xe7\x0b\x3d\x69\x0c\xb6\xea\x16\x35\xac\xcc\xd1\xcb\xf9\x07\x54\x9d\x57\x51\xd6\x56\x4b\x79\xaa\xb0\x41\x8c\xde\x1b\x87\xff\xd0\x9b\xaa\xc3\xeb\xa7\x9a\xd0\x93\xa6\xc3\x5a\x68\xf4\x24\xea\xd0\x36\x17\x0a\x2b\xd2\x19\xf7\x32\x4c\x6f\xd8\x7d\x42\x27\xdc\x7a\x52\xe5\x50\x86\xb2\xf0\x4e\xb8\xb3\x73\x7d\x16\xec\x6c\xdd\x3b\x23\xb8\xb7\xbd\xf9\xaf\xb1\xbd\xe1\x94\x7e\x17\x51\x45\x56\x73\xc1\xde\xd2\xe0\x86\x05\x3d\x31\x2d\x69\x58\xda\x57\xf0\xe5\xde\xde\xfb\x7a\x94\x24\x43\x2b\x3e\x21\x3c\xab\xb4\xa3\x9b\xb8\x3e\xd9\x85\x6d\xb0\x1b\xc8\xa9\xc6\x17\xbb\x2f\x92\xd3\x47\xb6\xb9\x71\x5f\xe1\x7a\x08\xd3\xd5\xfd\x78\xab\x4a\xf9\xee\xa0\xd7\xca\x92\x6e\x57\x2d\x84\x3f\x8b\xe0\x58\x07\x75\x8a\x6f\x1d\x46\x84\x38\xe5\x20\xfc\x53\x87\xb8\x13\x3f\xf2\x74\x7f\xb0\x27\xc3\xf0\x38\x08\xd7\xc0\xea\x25\x8e\x7e\xb2\xc8\xa7\x85\x2e\xeb\xde\x20\x70\xaf\x90\xf1\x55\x94\x33\x78\xce\x0f\xbc\x9e\xbd\x1d\xc9\xa7\x05\x73\x16\xbf\xce\x85\xb7\x76\x1d\xd6\x85\xb1\xda\x4e\xeb\xdd\xfb\xc1\x21\x25\x91\xa3\xc7\x6c\xe3\x8f\xd4\xdc\xc1\xf9\xc7\x66\x3f\x41\xaf\x11\x13\x7b\x0a\x0f\x2d\x11\x51\x17\x99\x4d\x8f\x25\xeb\x0b\x3f\x44\x0a\x34\xce\xf2\xdc\xf5\x0c\x08\x27\xa0\xa8\xc4\x07\xf9\xb4\xf0\x05\x6b\x53\xd1\xa2\x1f\xa2\xbf\xc1\x09\xaa\x40\x5f\xe0\xfc\x74\x4d\xdb\x23\x25\x37\xcd\x37\x9c\x07\x7a\xa6\x4a\x6f\xa7\x72\x8e\xd4\x21\x97\x41\x01\x8a\x1c\x13\x81\x48\x21\x9e\x9e\xf1\x99\x3d\x37\x28\x84\x0c\xaf\x1c\xb0\x79\x82\x2f\x38\x15\x84\x89\x6e\xb5\x11\xbc\xe0\xca\xa3\x4b\xf1\x1e\x89\xcf\xdd\x7a\xcf\x89\xe1\x17\xf5\xa5\x67\x69\x7a\x2e\x76\x54\xf4\xd6\x8d\x01\x07\x67\x5e\x62\x6b\xe1\xd5\xa5\x84\x51\xc6\x2a\x60\x3d\x86\x84\xb3\xba\xc0\x8e\x20\xc4\xf5\xfd\xfd\x2a\x42\x36\x1f\xa0\xd0\xb3\x2f\x0f\xa3\x55\x13\xec\xaa\xe7\xbc\x0b\xaf\xf3\xa4\x2a\x94\x32\x60\x92\xa2\x93\x8a\x11\x0b\x20\x7b\xcb\xc0\x3c\xe4\xe5\x6c\x1a\xca\x83\x72\x85\x57\xd5\x28\x91\xad\x2a\x0b\x9d\x5a\xca\x93\xed\xd7\x92\x9d\x11\x3d\x72\x75\x86\xb1\x2a\xbf\x30\x83\x3e\x56\x44\x95\xbc\x56\xdc\x5c\x5f\x3e\x3d\x4f\x88\xc7\x32\xf3\x3b\x70\x37\x42\x40\xee\xa3\x0a\xe7\xec\x3e\x1f\xdf\xfc\xf9\x81\x36\x5c\x23\xb6\x64\x8d\x49\x4c\x45\xf0\x11\x81\xfa\x9b\x05\x59\xf0\x16\xaf\x9d\xf7\x1b\x85\x5a\xe0\x5e\xa2\x37\x03\xf4\x44\x68\x83\x6a\x9a\x58\xa6\x8b\x68\xfc\xe9\x98\xe9\xa1\x0d\xa3\x2f\x48\x32\x74\x43\x66\x92\xea\x82\xe9\x2d\x47\x54\xc5\x7e\x48\xd2\xdb\x47\xdb\xe8\xa9\x48\x14\x8e\xac\x91\x38\x07\xaa\x97\xdd\xd2\xfd\x74\x95\x1f\x6b\x5d\xc8\x09\x78\x71\x73\x46\xb9\x2e\x45\xf7\xc2\x2b\x43\x98\x9d\x6e\x9e\xa1\xd0\xe7\x6b\xf9\x10\x22\xf8\x46\x5a\xd0\x64\x81\x2c\x3b\x2c\x73\x94\x24\xfa\xe2\x1e\x0c\x06\x62\x7d\x1f\xda\x65\xad\xcd\xc7\xf1\x72\x72\xc4\xb6\x3b\x88\xce\x2a\x40\xe9\x6e\x14\xc9\x1a\x02\x33\xfa\xba\x48\x66\x2e\xbd\xe0\x09\x99\x38\x74\x45\xc6\x23\x9f\x28\x8d\x4d\x57\x18\x02\x8c\x85\x2f\x66\x27\x23\x5a\x07\x8b\xfd\x46\xc1\x39\xda\xbc\xb4\xcb\x67\x15\xc2\xaf\x36\x51\x2d\xf4\xaa\x2a\xc4\xed\x2a\xf1\x6b\xfd\xfb\xa6\x90\xc1\x2c\x23\x3a\xb9\xc7\xc0\x41\x46\xc9\x7f\xdc\xf3\xad\x21\x16\xea\xec\x07\xbc\xf7\x9a\xd2\x97\x5e\x44\x17\x7f\xec\x62\x4a\xa1\xcf\x3c\xee\x0a\x2e\x2d\xe0\xd4\xb5\xfc\xba\xef\x45\xa5\xd2\xd1\x4a\xc6\x87\xcb\x19\x43\x02\xaf\x3a\x30\xba\xe6\xbe\x9f\x82\x52\xfa\x12\xee\x19\xeb\x41\xf3\x19\xed\xbc\x78\x6c\xd3\x60\xe0\xfa\x29\x71\x79\x80\xe6\xa5\x44\x18\xc6\x1b\x6f\xd9\x03\x66\x5c\xb1\x67\xfa\x86\x65\x9d\xc6\xb1\xe3\x07\xbb\xcc\x2f\xad\xe7\x5f\x1a\x28\xbc\xf8\xaa\x1e\x2f\x32\x9e\xa8\x8d\xe1\x8d\x70\xcf\xf1\x34\xc2\x28\x7e\x1f\x61\xaf\x8f\x13\xbb\xf3\xa2\x75\x4d\x92\xa9\xdd\x28\xda\x9c\x2b\xed\x6d\xc3\x2c\xd2\xb8\x2b\x58\x2d\xfc\xa9\x96\x5a\xe3\x9a\x11\x24\xc5\x01\xb9\x45\xe2\x0f\x68\x13\x0e\x35\xc6\x59\xd3\x95\x0e\xf5\xc0\x8f\x51\xca\x9e\xdb\xa6\x31\x77\xc9\x07\x91\x3b\xd3\x47\xe2\xa0\xea\x84\x30\x6d\x58\xae\x46\xd8\x2e\xba\x6e\xac\x79\xe8\x99\xb7\x78\xbc\xba\x46\xf0\xf6\xfe\xd2\x71\x51\x92\x79\x54\xe2\x9f\x22\x50\x20\x36\x51\x95\x06\xde\x44\x51\x7a\xcd\x77\x41\x4d\x5f\x9f\x3a\xda\xcd\x90\x36\xae\xa6\xd9\xf1\x80\x56\xcd\xcc\x3b\xd1\x0c\x16\x11\xa0\x58\xcc\x78\xae\x0b\xe4\xf2\x81\x3f\x3a\xbc\xbb\xb3\xda\xd5\x34\xcd\x55\x53\x0c\xf9\x9b\xcd\x53\x2b\xc4\x8b\x1b\x5d\xbe\x32\x6b\x02\xae\x7b\xa5\xe6\x5b\xc4\x91\xd3\x8b\x0a\x3c\x6b\x64\x5f\x8b\xb0\xdf\x36\xa8\x9c\xac\xff\x46\x71\xe5\x64\xa1\x55\x07\xf9\x35\x83\xcc\x29\x1d\x0d\x1d\x60\xbe\x18\x0b\xef\x45\x05\x3b\x35\x37\x31\x22\x0e\x5d\x6d\x95\x52\x33\x2e\x5e\xf6\x8f\xcd\x95\x90\x11\x6c\x43\x80\xe9\x62\x8a\x11\x33\x42\x9f\x13\xd7\xdd\x97\xa5\x71\x7d\x0a\x3e\x44\x3f\xd2\x1e\x77\x51\xc8\x3e\xac\x9d\xa4\x1b\x38\xc2\x4b\xa8\xdc\x6c\xc9\x3c\xe9\x20\x8c\x0f\xe7\x4c\x65\xb1\x8e\x0b\xf7\x93\x8c\x41\x36\x12\x83\x88\x8e\x51\xb5\xfd\xc8\xb8\x33\xf5\x5b\x8f\x27\x44\x8c\x3e\xc1\xa5\x21\xe8\xac\x9b\xd8\x51\xd6\x38\xb0\xcd\x97\xba\x0c\x25\x5c\x2c\xa8\xb4\xaa\xad\xc2\x42\xe7\x20\x5a\x2c\x92\x4b\xee\xf0\xa5\x15\x61\xf5\x6d\x33\x36\xb6\x05\x58\xcd\xd0\xc4\x1b\xd5\xdd\x30\x0f\x3c\x8c\x8a\x62\x3c\x2a\x92\xca\xad\x43\xa8\x78\x26\xec\x6b\x45\x51\x11\xe9\x6a\xc5\xeb\x1e\x6f\x2a\xc1\xf9\x61\x53\x61\xb8\x0a\xd0\x95\x9a\xbd\x93\x5f\x55\xdc\x14\x91\xd8\x48\x54\x52\x65\x31\xb5\x5b\x0b\x4f\x2d\xf4\xf3\x4f\x19\x42\x46\x94\x05\x02\x27\xf9\x78\x99\x44\xf9\xfa\xfa\xfa\x7a\x7d\xe0\x18\x41\x41\x7b\x77\x12\x3a\x86\x69\x7f\x3b\xe1\xf6\x63\xbf\x1f\x8e\xed\xfb\xdb\xff\xfb\xdb\xff\xbf\xf6\xed\x3f\xbf\xfa\xa7\xb0\x22\xb4\x8f\x3f\x20\xc1\xef\x16\x6a\xc0\x67\x59\x50\x6f\x08\xb0\x36\x1c\x42\xe8\xa2\x28\xa7\xa4\x4c\x77\xb0\x65\x61\x0e\x91\x12\x5c\x4c\x26\x13\x9c\xe3\xb4\x44\x38\x3d\x2f\xa0\xd0\x28\xcf\x2e\x0a\x9c\xaf\x69\x7e\x19\x2f\x48\x1a\x67\x17\xa0\xb1\xd0\x1c\xf6\xa3\x07\x0f\x78\xce\xe0\x9f\xaf\x5f\xbd\x2c\xcb\x05\x77\xf9\xc9\xb8\xa6\x99\x86\xf6\xfd\xb0\xc0\xfa\xb8\xbf\x79\x32\x4d\x33\xca\x08\x12\x92\x62\xda\x93\x34\x8b\xf1\x9a\xe6\xe4\xc9\xa9\x51\x0e\xfc\xf3\x3c\xa1\x23\xe3\x1b\x5b\xb7\xdf\xb6\x91\x6b\x86\xc9\x7f\xbe\x7c\xb7\x6d\x54\x37\xcb\xb7\xbb\xfd\xca\x52\x42\x72\xa0\x2d\xbc\x15\xc8\x74\x4d\x22\x40\x7e\xa2\xa2\x3d\x78\x39\x64\x3e\x91\x69\x2f\xa5\x01\x84\x51\x5e\xdf\xf2\x67\x59\x51\x06\xa8\x24\x73\x9c\x2d\xcb\x80\x56\x98\x07\xa0\x64\xbe\xc8\x72\xee\x76\x02\x36\x13\x0a\x87\xf6\x11\xfc\x77\x75\x85\xba\x9c\xd8\x93\x6c\x1c\x25\x34\x31\x7c\xf2\xcd\xee\x37\x10\x1f\x94\xed\x3d\xac\x42\xba\x13\xf2\x5f\x57\x57\x68\x53\x66\xd3\x66\xd0\x3e\xb4\x26\xd3\x44\xa3\x68\x5f\xb6\xdf\x28\x3c\x2d\x72\xbc\x80\x80\x5b\xf8\xc2\x9a\x32\x4b\x76\xe2\x80\xef\xb4\xb3\x8c\x16\x5e\x1e\x47\xe9\x35\xdc\xb1\xb2\xf8\xf2\x6c\xce\x15\x96\xb9\x77\x3d\xed\xc0\x67\xb6\x65\xb8\x70\xd1\x31\xad\xc9\x5d\x66\x07\xcc\x8b\x40\x5a\x3d\x43\x35\xbb\x41\x61\x84\x44\x79\x18\xdc\x00\xaa\x6c\x84\x94\x78\x05\x43\x7e\xf9\x6e\x5b\x85\xe7\x64\x92\x96\x86\x79\x6d\x22\x28\x8c\xe1\xc3\xcc\xaa\xc8\x18\x0f\xab\x12\xe4\x61\x51\x6b\xb6\xc0\x69\xaf\xfb\xf6\xf8\xfd\x07\x11\x51\x90\x11\x0e\xeb\xdc\xde\x9a\xe6\x10\x0d\xe6\xf6\xc1\x03\x73\x52\x8d\x43\xdf\x12\x0c\x6a\xba\xcf\xa2\x82\x8c\x51\x17\x6d\x40\x17\x9e\x2d\x29\x7b\xd0\xaa\xd8\x40\xdd\x50\x5e\x15\xca\x7a\x06\x65\xc6\x1f\xad\x75\x47\x51\x81\x1f\xef\x76\xad\xf1\x2b\x77\xc0\x2f\x71\x14\xe3\xbc\xd7\x3d\x00\xbe\x4a\x7e\x8d\xd8\x69\x0b\xda\x67\x23\xac\x29\x44\xe5\x63\x9c\x96\x8f\xe8\x41\xbb\x1b\xa0\x2e\x95\xfc\xc9\x18\xaa\x18\xfe\x52\x08\xb5\xa3\xbc\xb1\xe2\x53\xd6\x40\xae\x2c\x70\xc4\x65\x3a\xd6\x0e\xd5\xb6\x26\xd9\x77\xf1\xbc\xd0\xae\xaf\xfd\x21\x82\xeb\x48\xaf\xb0\x43\xc6\x09\x5d\x9a\x4d\x72\x82\x66\x4c\x5a\xe5\x31\x67\x81\x1e\x95\x76\x5f\x61\x2e\x8d\x7b\xf0\x20\x82\x05\x03\x21\x93\x4b\x59\x3f\x47\xb2\x50\xe4\xeb\xde\x7e\x7d\xd6\x00\x87\x59\x9a\x62\xfe\x6c\x41\x50\x98\xa2\x44\xe3\x72\x51\xb4\x2e\xfc\xee\x7f\xc0\x9f\x4b\xa7\x83\x1c\x56\x7b\xad\xc1\xad\xe3\xcd\x6e\xd5\x75\xe9\x1d\xaf\xbf\xe7\x6b\x50\x5f\x25\xed\x43\xc0\x02\x0d\x44\x0d\x44\x70\x20\x39\x4e\x0d\x25\xf0\xac\x1f\x9d\xa0\x0b\xa8\xcc\xc9\x74\x8a\x73\x16\x29\x86\xce\x3e\x88\x2d\xd2\xed\x23\xc5\x41\x13\xc1\x40\x0f\x7c\x54\x63\x06\x7c\x6d\x43\x3f\x60\xbc\xb2\x67\x70\x93\x14\x5c\xf4\x16\x65\x54\xe2\xf1\x2c\x4a\xa7\x7e\x05\x02\x33\xef\x17\x88\x8f\xe2\x4b\x30\xac\x87\x1b\xe1\x5d\xca\x61\x6c\x96\xb7\x6e\x06\x6c\x6d\x41\x31\x0a\x50\xdc\x2a\x69\x91\x80\xec\xcb\xac\x06\x8a\x82\x33\x99\xf7\xd6\x4a\xde\x58\xad\x48\x5b\x48\xbf\xda\xb2\x2f\xb6\x8c\x96\xe9\x59\xf0\xda\x42\xb1\xda\x08\x5c\xcc\x9a\x95\x15\x03\xb5\xf4\x3e\xb0\x52\x3d\x7d\xf3\xe0\x0b\xf9\x6e\x39\x80\xdd\x85\x3a\x26\xc0\x57\x9a\xbe\xae\xd4\x65\x79\x72\x49\xe9\x9d\xbd\x2d\x85\xc5\x45\xa9\xba\x62\x6d\x91\x82\xd7\x8f\x4d\x66\x2a\x85\x00\xa1\xe0\xb4\x85\x01\x7a\x7e\x48\xbb\x25\x9a\x44\x24\xc1\xf1\x00\x1d\xd3\x73\xda\x05\xa1\x67\x8f\x08\x82\x3b\x55\xaf\x26\xad\x4d\xcf\x5c\x28\x7c\x4a\x7d\x86\x0c\x22\x40\xe2\x10\x7d\x27\xff\x84\xbe\x8f\xee\x3e\xf9\x62\x1c\xa2\xee\xf6\x60\x53\x2a\x0f\x85\xfe\xb1\x9b\xe2\xf2\x63\x42\x8a\x12\xa7\x24\x9d\xca\x6c\xa9\x3d\x3c\x33\x0c\xba\x84\x82\x2b\x67\x91\xaa\x5c\xf2\x15\x56\x85\x74\x90\x6a\x12\x1c\x75\x81\x3e\x74\xa1\x2a\x30\x4e\xfb\x54\xcc\xed\x84\x4f\xe8\x2f\x43\x7e\xee\x84\x5b\xdf\xd2\x93\xff\xce\xfd\xc9\xff\xfe\xe4\xff\x17\x3f\xf9\x2b\xc3\x7f\x78\xb4\x78\x47\x46\xff\xd2\x90\x53\x3f\x55\x8e\xc8\x94\xd9\xe0\x0e\x7e\x61\x27\x74\x76\x0f\x12\xbf\xc2\x13\x73\x43\x90\x21\xfb\x2e\xb5\x87\x73\xc6\xc6\xc9\x20\x18\xbb\xb8\x98\xd1\xde\xf7\x4c\x03\xad\xef\x59\x61\xf4\x10\x6d\xbb\x2f\xef\xc0\xe2\x8f\x4a\xf1\xe6\xfb\x43\x54\x1b\x37\xff\x2d\x3f\xd5\x45\x29\x3a\x7a\x76\xf0\x86\x4f\x72\x8c\xbe\xfb\x16\x8d\xb3\xf9\x62\xc9\xc3\x65\x8c\x2e\xd1\x3c\x3b\x27\xe9\x54\x0b\x0a\xb5\x8b\xc6\xb3\x28\x87\xbd\x80\xdd\xcc\xc6\xcc\x94\x4a\x98\xab\x0b\xe8\x04\xb3\x47\x0b\x65\x46\x1b\x64\xb8\x2a\x50\xef\x00\xed\xa3\xad\xcd\x00\x3d\xa3\xff\x6f\x05\x68\x30\x18\x04\xe8\xff\xd0\x3e\xda\xf9\xa6\x4f\x0f\x3b\xa8\x58\xe0\x31\x99\x10\xb6\x90\x8e\xde\x1f\x6f\xed\x3c\xde\x7a\x6c\x9b\x98\x91\x22\x83\x74\x3e\x0e\xd7\x39\xe8\x35\x7b\x13\x4b\x3b\x42\x07\x68\x5e\xad\xe9\x37\xcb\x5c\x92\x8a\x05\x18\x77\x6d\x60\xd6\x6f\xc6\xe7\x1f\x45\xa9\x3e\x8f\x74\x44\xdd\x83\xee\x80\xa2\xe5\x30\x8b\xf1\x41\xd9\xdb\xd4\xb4\xd6\x74\x6c\xdd\xff\x73\xb2\x19\x03\x64\xef\x76\x81\x58\xcb\xec\x64\xb1\xc0\xf9\x61\x54\x28\x55\xb6\x96\x5d\x2c\x47\x45\x99\xf7\x76\xfb\xe2\x45\x2e\x4f\xd8\x0c\x76\xad\x1b\x33\x96\xbb\x48\x48\xd9\xeb\x76\xfb\xe6\x63\xe5\xb4\x6f\x5a\x57\x8d\xb3\x98\x0e\x2e\xf5\x75\x5e\xc8\x87\x00\xf3\xc3\x3e\x3a\xa0\x02\x21\x7c\x7c\xbf\x8f\xfe\xaf\xef\xb8\x72\xf7\xcc\x2c\x9f\x58\x03\x52\xfa\x06\x8d\x31\x7a\x84\x0e\xd0\x06\xda\xda\xd4\xec\x8c\x7c\xee\xcd\x45\x08\x49\xdb\x86\xe9\xba\x3f\xf8\x25\x23\x29\x1d\xa6\x6d\xa9\x38\x5e\x82\xe3\x54\x98\xe2\xd7\xc7\xcf\x29\x61\x6f\x6d\x0a\xa6\xc4\x2d\xfc\x80\xf2\x3d\x14\xf7\xed\xe6\xe3\x5d\x9b\xe0\xe6\x59\xfc\xdd\xb7\x5b\x9b\x55\x84\x66\xd2\x97\x72\x47\xcb\xa8\x89\x17\xae\xa5\xa2\x1c\xcf\x23\x92\x32\xdd\x11\xcd\x53\x77\x8f\xdc\xb9\x8b\xc9\x1e\x38\xb0\xb2\x5b\xde\xee\x5b\x6e\x6b\x80\x59\x09\x30\x69\xf1\xfa\x9d\x61\x22\xa7\x9a\x04\x59\xfb\x28\x2d\x99\x47\x9c\x00\x6d\x6d\xf6\xd1\xff\x9f\x62\x6d\xc3\xa9\x85\x39\xc5\xe1\xe6\xe7\xbe\x17\xb8\xb2\x2e\x59\x52\xd5\x67\xcc\x53\xf3\x3b\x24\x66\x82\x0e\xeb\x80\x1b\xfc\xc3\x85\x3a\x24\xf0\xb7\x0e\x9c\x7d\x8a\xf9\xf2\x4f\xce\x50\x77\x5a\xec\x9f\x04\x6e\x09\xad\x96\x9c\xdb\x55\x27\x58\x68\x53\x3f\x31\xc4\x92\x59\xce\xc5\xeb\x1c\x8b\xa8\x28\xcc\x81\xcc\x71\xfa\x1e\x69\x59\x42\x8c\xa6\x43\xb8\x96\x6c\x4d\xd7\x8a\xd1\x9c\x81\x56\x63\x93\xcf\x80\xa8\x78\x26\x7c\x06\x68\x2f\x15\x78\x50\x47\xb4\xf5\x58\x63\x61\xa3\xa8\xc0\x3b\x8f\xd1\x3e\x94\x51\xea\xa1\x9d\xc7\x86\x09\x40\x1c\x63\xa6\x59\x84\x3d\xb0\xc7\x0a\x05\x68\xeb\x1b\x53\x12\x96\xfd\x7c\x36\x8a\xd2\x1e\x2b\x66\x32\x3f\x6b\x31\x73\xb7\x24\xda\xc2\x7d\x46\x87\x5e\x66\xc6\xee\x45\xa7\x0f\x81\x27\xcd\xfc\x52\xac\x68\xa6\x4c\x02\x7b\xdd\xb7\xcc\xa5\x7f\x9a\x95\x5c\x28\xfb\x9e\xfc\xd0\x99\x82\x44\xc2\xdc\xdd\x4c\x14\x52\x8b\x59\xc4\xa4\x35\xd8\xdf\x3e\x8f\x93\x65\x41\xce\x65\x04\x42\x32\x22\x09\x29\xa5\x80\x33\x8a\xd2\x4f\xc3\x51\x1e\xa5\xe3\x19\x2a\x70\x7e\x4e\xc6\x62\x03\x8c\x98\x63\xcf\xce\xf7\x43\xf2\xc3\xc0\xa6\x21\x19\x0d\xa0\x10\xbb\xd0\x04\xe7\x74\x1b\x8a\x92\x69\x96\x93\x72\x36\x47\x31\x2e\xc6\x39\x19\x31\xb6\xc4\xe5\x1f\x9c\x0e\x2e\xc8\x27\xb2\xc0\x31\x89\x40\x08\xa2\x5f\xc3\xa3\xb4\xc4\x79\x1a\xb1\xa7\x13\x1f\x9f\x45\xe9\xa7\x8f\xdc\xab\xe8\x47\x36\xaf\xff\xbf\x9f\xf8\x48\xd3\xe9\x47\x3a\xc4\x8f\xf0\x96\xe8\x63\x4c\xa6\xc4\x79\xca\x21\xa6\xc6\x47\x91\x23\xb1\xa7\x8a\x19\x10\x3e\x63\xca\xcc\xb3\xcd\xb6\xa0\xd5\x67\xf6\x8a\x1c\x59\x6c\x91\xcf\xe8\x21\xdb\xa7\xba\xff\x7c\xd1\xdd\x5b\xf3\xf2\x4c\xce\x63\x7b\xd6\xce\xdd\xd3\x2b\xd8\x40\xdd\x4d\x10\x95\xa0\x15\xdd\xdc\x85\xa2\xe3\x39\xc5\x06\xda\x47\x3d\x26\x4e\xf5\xbe\x7b\x82\x1e\xa9\x26\xfa\xe2\xd9\xc0\xa3\x6d\x6b\xbf\x95\x5e\x37\xcc\xa6\xb4\x3a\x79\x83\x0d\x6a\x2b\xce\x44\x34\x5c\x01\x61\xb3\x38\xd0\x24\x2d\x4a\x52\x2e\x4b\xe1\x1b\x97\xc4\x38\x2d\xe9\xa6\x65\xfb\x4f\x67\xb5\x1c\xa5\x31\xc9\xb1\x69\xc0\x60\xbe\xb1\x29\x02\x21\xcb\xca\x47\x36\xf0\x6a\xaa\xa3\xb5\xd4\x81\xa6\x3a\xaa\xad\xce\x2a\xbc\xc8\xec\x89\xd7\x5f\xae\x79\x04\x36\x39\x43\xf7\xc5\x87\x97\x74\x1e\xc4\xeb\x16\x1d\x03\x5a\xaa\xec\x5b\xdf\xe2\xd7\x59\x1d\xbf\x16\x4f\xe9\x18\x72\x79\x90\x65\x52\xb0\x97\x72\x3a\x1f\x77\xe4\x4e\xf0\xa0\x52\x29\x6f\xca\xbd\xc8\xa3\xf8\x10\x0a\x0f\xf6\x9c\x8e\xb5\x24\x85\xce\x23\xcd\x3f\x4b\xad\x9c\x40\x74\x3f\x2f\x84\x91\x95\x2e\xfc\x29\x27\x2f\x8d\xba\x72\x89\x05\xe8\x7a\xe5\xeb\x41\x7d\xcc\xca\xb9\xbe\x77\x54\x01\xca\x3c\x5a\x1b\x18\x9b\xae\xad\x71\x47\x69\x51\xc2\xf0\x3f\xff\x7c\x71\xba\xf9\xe8\xbb\xb3\x2f\xdb\xd7\xbd\x17\x1f\x5e\xd2\xdf\x07\x8f\xfe\xef\xec\xcb\xd6\xce\xf5\x95\xfc\xd8\xd9\x0c\x76\xb6\xae\xfb\xff\x33\x1c\x94\xa0\x04\x95\x1b\xb8\xf1\x2e\xaf\x8a\x31\x68\xe0\xec\x79\xde\xd6\x8a\x08\xe3\x4f\x30\xe1\xf4\xef\x45\xdb\x73\xb5\x04\xef\x06\x6f\xcf\xdd\x95\x64\x21\x4e\x0d\x4a\x7f\xdc\xb3\xb3\x0b\xe1\xda\xfd\x79\xdf\xdc\x70\xd8\x13\x44\xd2\x8a\x81\x1b\xdc\xe7\x6e\x86\xee\x65\x23\xad\x06\xbf\xbd\xd9\xca\x6a\x93\x89\x94\x74\xa4\xc5\x72\x4e\x01\x4f\x0a\x7e\x7c\x98\x67\xf1\xa3\xef\xbe\x7d\xb4\xb5\x29\xb3\xe1\x8c\x0b\xbd\x1b\x67\x09\xea\x1d\xbd\x3f\x1e\x1e\xbd\x38\x44\xf4\xdc\x10\x6e\x6f\x6e\xee\xf4\x6d\x9e\xac\x55\xeb\x9e\x42\xb5\x5c\x67\xe0\x22\xaf\xe5\xb0\xf9\x99\x70\x3b\x40\xdb\xed\x6c\x55\x75\xa6\x6a\x6c\x29\x08\x4f\x07\xe8\x9f\xef\x5e\xfc\xe4\x38\x12\x94\x05\xfc\xa3\xa9\xac\xd1\x9d\x54\x0d\xb2\x69\x78\x8a\x00\x7a\xe0\x65\xce\x19\xf2\xb7\x01\xda\xed\xa3\x10\x75\xbb\xad\xc6\x3d\x4e\x08\x3c\x24\x93\x1d\x04\xe5\x13\x49\xed\xf1\x51\x2c\xfc\x74\xf0\x8f\xe3\x1f\xff\x75\xfc\xee\x7f\xed\x59\x85\x3a\x2a\xe6\xd4\xae\xdf\x3b\xb9\x0c\xe8\xd6\x63\xdf\xda\x5a\x7d\xe4\x7c\x35\xf9\xcf\x25\xee\xc1\xc3\x1d\x9a\x53\x81\x33\xbc\xc8\x73\x0e\xd1\xef\x9d\xf8\xe0\x7c\x0e\xc8\x8c\x43\x87\x3b\xe0\x5d\xed\x10\x5b\x79\x94\x11\xe7\x0f\x79\x4a\x31\x4e\xa8\xec\x8c\x62\x9e\x67\xb6\x1e\xf7\x03\xb4\xbd\x29\x5d\x9c\x19\x52\x9e\x40\xaf\x35\x48\x51\xb8\xdd\x02\xad\xf0\x4a\x75\x04\x59\x4c\xa9\xaf\xeb\x15\x3b\xa1\xf9\x79\x7d\x16\xec\xec\xde\xab\xf1\xef\xd5\xf8\x7f\x71\x35\x3e\x57\xe1\x2f\xc6\xf5\xf6\x7b\xb7\xb0\xb8\xeb\xa8\x48\x73\x9d\xbd\x95\x22\x64\x35\xd8\xe9\x31\x3d\xd3\x62\xec\xb5\x04\x5b\x44\xe5\x2c\x40\x29\x36\xac\xbf\x3f\x82\xe6\xc2\x79\x78\x2a\xae\xaa\xf5\x18\xbd\xc2\x6b\x01\xb7\xd7\x01\x1b\x1f\xfa\x1f\x4b\x55\x59\x63\x79\xc3\x0b\x5c\xb1\x14\x09\xbd\x2f\x14\x3a\x54\xe5\xa5\x2b\x4a\xab\xd8\x20\x4b\x7b\x5d\x18\x55\x57\x8f\x69\xd9\x37\xec\xa7\x8b\x8c\x32\x31\xf6\x96\xf0\xe8\xed\x21\x52\xf7\xca\xec\x85\x61\x37\x40\x7a\x28\xf8\x8f\x8c\x0d\xf2\x0b\xef\x9e\xed\x0c\xd3\xdb\x83\x34\xd6\xdb\xd7\x9a\xaf\xac\x0c\xad\xc9\x37\x06\xaf\x8e\xde\x7f\x78\xf1\x06\x56\xd0\xe1\xf1\x9b\x37\x2f\x0e\x3f\x1c\x1d\xbf\x41\xef\x5e\xbc\x7f\x7b\xfc\xe6\xfd\x8b\xf7\x95\xad\xc6\x51\x19\xe9\xcd\xd2\x6f\x7d\x73\x1a\x3e\xe4\x66\x84\xf3\xe8\xf3\x38\x9b\x2f\x12\xfc\x99\x94\x97\x21\x7a\x0c\x94\x65\xf5\x10\x74\xa1\xd2\x0e\x81\x56\xa5\xf6\x9b\xbe\x27\xa0\x09\xb7\x39\xf8\x62\xc6\x23\x86\x83\x5f\x6c\xdb\x4e\xf0\xee\xb0\x38\xcd\xc0\x5f\x62\x74\x31\x23\xe3\x19\x9a\x47\xe5\x78\xc6\xc5\x57\xb6\x09\x51\x86\x16\x1b\xe5\x3c\xf1\x03\xa0\x69\x7f\xc0\x62\xb8\x8e\x72\x7a\x0b\x16\x08\xfe\x70\xa2\x64\xd2\xfb\xe8\x27\xe4\x53\x78\x1b\x47\xe2\x33\xd7\x1d\xba\x2c\x4c\xc7\xca\xc1\xf6\x1c\x28\x3b\xf4\x73\x65\x48\x54\xa8\x86\xf7\xdd\xae\xe8\xda\xc1\xe2\x84\xe4\xd8\xf0\x08\x60\xa3\xab\x6a\x3c\x74\x28\x9e\xd6\x6b\xc0\x55\x7c\x56\xdd\xb4\x45\xfd\xc5\x38\xc1\x25\xae\xab\xc1\x1e\x8c\x8d\x1b\xfd\x15\xf6\xcf\x74\xd7\x02\x42\xe4\x04\xc1\xea\x03\xe5\x0e\xb3\x95\x4a\x99\xb3\x1c\x94\x31\x57\xcb\xa4\x1c\xac\xad\x09\x61\xd0\x24\xe1\x35\x5b\xed\x01\x2f\x32\xa9\xf0\xa7\x78\x9e\x26\x1e\x99\x85\x75\xcf\xaa\xfa\xaa\xb2\xd9\x60\x60\xc9\x6b\xff\x60\x9e\xcd\x95\x83\x5e\xb1\xc4\x9f\xbf\x78\x74\xf8\xf2\xe4\xcd\xff\xbe\x78\x27\xeb\x89\xf1\x78\xb6\x4c\x3f\xe1\x98\xbf\x2a\x61\x2f\x46\xf9\xdf\x20\xc7\x8b\x24\x1a\xe3\xde\xf0\xdf\xd7\xa7\xff\x4e\xff\x9d\x9f\x3d\xfd\xf7\x97\xe1\x34\xe8\x5e\x5f\x3d\x7a\x74\xf5\xa5\xdb\x07\xd7\xc2\x5f\xbc\xf0\xff\x3e\x13\x25\x4e\x79\x99\x33\x5a\xe8\x54\x94\x3a\x3b\xf5\x97\xb3\x4b\x19\x85\x2a\xca\xa8\xb6\xb4\x96\x64\x43\x5a\x19\x7e\xcd\x47\xb3\xbb\x82\x93\x1a\x18\x70\xd7\x2c\x20\x5e\xe3\x2f\xc3\x21\xdc\x81\x62\xee\x0e\x03\x3c\x6d\x40\x05\x6b\x0e\xe9\xd3\xbc\x43\x9a\x65\xae\x5c\xee\x77\xc6\x82\x41\x1b\x88\xbd\x7f\x35\x44\x75\x79\x67\x6d\x71\x32\xd7\xa9\x81\xcf\x16\x0c\xfa\xae\x95\xe2\xd6\x34\xcc\x98\x66\xcd\x5d\x7c\xaa\x33\xfb\x76\x67\x90\x11\xe6\x9d\x1b\x72\x81\xeb\xbb\x74\x8c\x13\x70\xa8\x2f\x1e\x71\x1a\x65\xc6\x09\x8e\x72\x61\xc2\x65\xb5\xc2\x93\xad\x05\xed\x07\x02\x5f\x0d\xa5\xa8\xc8\xb7\xc7\x99\xe5\xed\xbd\x4e\xff\xab\xb5\xab\xe4\x38\xd3\xe1\xaf\x03\xb4\xb5\xb9\xb9\x89\x1e\xb2\xcb\x19\xcf\x5d\xab\xd7\xf1\x03\xbc\xdb\x03\xec\x08\x7c\x51\x0e\x52\x60\x4e\x2f\x2c\x28\x0a\x7f\xd7\xb7\x3a\xaa\xdc\x19\xb3\x48\x04\xa2\xfd\x70\xcb\x4a\xa7\xc3\x8c\x45\xb0\xb8\xde\xa6\xdd\x9e\xa5\xad\xd7\xc1\xb9\xf3\x1f\xca\x23\x7f\xe2\x5b\x68\x14\xc7\x85\x1e\xf0\x99\x5b\x39\xb8\xd2\x18\x53\x0f\x07\x6b\x6c\xc3\x15\x07\x03\x7e\xd6\x26\xcc\x5d\x3d\xe7\x7a\x73\x11\xbd\xde\xe0\xbe\x47\x31\x2b\x15\xe5\x39\x39\xc7\x3a\xc3\x8d\x62\x39\x7b\xa2\xbd\x1a\x0e\xeb\x81\x36\xbc\xd5\xfb\x6d\x4a\x35\x99\x42\xbc\x56\x27\x31\xba\xba\x12\x5f\xa7\x9b\x67\x72\xcb\x84\x2b\x6c\xd6\x37\x05\xcd\x13\xcc\x12\x2c\x51\x97\xe8\xbc\x9b\x17\xda\x97\xbd\xa9\x93\x78\x29\xe8\x40\x36\x2c\xea\x16\xbb\x9a\x58\x47\xfa\x4a\x65\x61\xe1\xb9\x59\x0a\x13\xcb\xe1\xf4\x05\x1a\x77\xba\xbf\xc7\x1a\x9a\x39\x11\xd7\xa0\xd6\xb5\xef\x94\x47\xfb\x49\x96\xf7\x28\x5e\x3e\xe1\x4b\x76\x52\xf4\x0d\xc0\x74\x02\xd3\xf3\x03\x0d\x66\x51\x71\x7c\x91\xbe\x85\x90\x47\xe5\x25\x84\xb4\xb3\xb8\x40\x05\x7a\x3e\xe1\xcb\xb3\x6a\xdb\xce\x6e\x96\xa2\xa3\xb7\x87\x5d\x3b\x16\x3b\x97\x2d\x6a\xea\x74\xcc\x2c\xd4\x32\x39\xd4\x7d\x10\x72\x77\xe3\x48\x3b\x6e\x90\x02\x15\x25\x61\xc1\x48\x48\xac\x11\xb5\x6e\x16\x5a\x89\x70\xbf\x1d\x67\xaf\xfa\xb4\x24\xe4\x00\xba\x7b\xe4\x98\xf7\x23\x60\x54\x60\xf6\x6a\x9a\xa5\x98\x6b\x9e\x7a\xeb\x1f\x6d\xb1\xff\x22\x27\x25\xf8\x4b\xb1\xb8\x91\x06\x62\x1d\xa1\x3e\xba\x67\x28\xe1\x62\x70\xbd\xaa\x76\xae\x40\xf2\x0e\xbd\xee\x05\xc1\x9a\x4e\x3f\x56\xbd\xf8\xbd\xf6\x74\x05\x19\x9b\xec\x9e\xc1\xb9\x57\x40\x91\x40\x53\x33\x96\x90\xe7\x08\xd5\x78\xd6\x14\xbd\x8c\xb5\x67\xbf\xbe\x51\xd5\x58\x3c\xdf\x4c\x6c\x90\x54\xad\x4b\x0d\xe6\x50\x1a\xf7\x51\x64\xfd\xf9\xf6\x49\xcb\xec\x8e\x6b\x13\xad\x33\x8a\xe3\x8e\xe7\x5f\xd9\x12\xac\xac\xd5\x6b\xb3\x4e\x77\xc3\x66\xb7\x1b\xdd\x0e\x2a\x74\xc3\xec\x81\x6e\xa7\xad\xf8\x20\xbc\xd8\xca\x4a\x54\x2c\x17\x8b\x2c\x2f\x41\xb7\xc6\x6e\x6a\xdf\x1e\x22\xa9\x55\xe9\x1a\x8e\x20\xab\x09\xb3\xf5\x4b\x85\x9b\x2c\xc6\x66\x2a\x5b\x89\xc2\xbc\xc7\x7a\xa0\xa9\x5a\x0b\x7a\xcd\xa1\xae\xbd\x9b\x56\x7a\xbb\x71\xf5\xb8\x0a\x83\x8e\x93\xf6\x8a\x57\xda\xd7\x67\xc1\xce\x37\xf7\x2a\xdd\x7b\x95\xee\x7f\x85\x4a\x97\x3f\xac\xb8\xd5\x73\xec\x83\x28\xcf\x52\xf4\xbf\xcb\x79\x74\x4e\x0a\xf4\x7d\x44\x3f\xff\xf6\x89\x7d\x0e\xe6\xd8\xab\xee\x1d\x0e\xd1\x51\x4a\x4a\x12\x25\xe4\x57\x8c\xfe\xce\x7a\x41\x09\x35\x42\x05\x58\x62\x09\x83\x1b\x18\x28\x5d\xaa\x86\x93\xf3\x01\x68\x75\x45\x31\x11\x45\x84\x07\xa0\x3a\x8a\x43\xb4\xd9\x74\xf3\xc6\xac\x3d\xe8\xf0\x6d\xb7\xba\x5e\x33\x13\xaf\x3b\x5d\xf5\x0a\x4d\xc4\xba\x9a\x08\x84\x42\x4b\xca\xa0\xc7\xe3\x84\x97\xbd\x4e\x09\x34\x55\xcf\x44\x54\x23\xb2\x84\xef\x5d\xaf\x1b\x22\x6d\x04\xb4\x3d\xa7\xf7\xc3\x35\x8e\x9e\x0a\x57\xbc\xac\xad\x80\x37\x66\x38\x4d\x65\x59\xfd\x2a\xd5\xb2\x68\xd2\x31\xe6\x91\x66\xbb\xeb\x5d\x2d\xea\x54\x14\x9f\xd3\x33\xaa\x98\x1d\x74\xf4\x1c\x72\x44\xef\xe4\xa4\x6d\x6c\x54\xf9\x19\xf2\xbf\xfe\x61\x6f\x85\x9c\x6a\x54\xb6\x78\x1e\xc4\x47\x2a\xd3\xc5\xbb\x20\xf6\x3f\x3d\x30\x89\x17\x42\xed\x0d\x2f\x04\x0e\xe4\xe1\x51\x18\x10\xf9\x4d\x75\xa4\xb2\xae\x29\xf2\x99\xe7\x65\xb6\xd5\x80\xdf\x3c\x43\xa0\xc1\x6a\xcf\x8a\x09\xcc\x12\xad\xcb\x50\xe6\xd3\x47\xd3\x39\x73\xa0\xa7\xb2\xed\x01\x3e\xc7\xf9\x65\x4f\x78\x43\x7e\x4f\xd2\x69\x82\x5f\x33\x84\xf7\x51\x88\xbc\x19\xaa\x26\x3e\xad\xb2\x23\x7e\x70\x3e\x81\xf2\xa0\x25\x85\x77\x41\x37\x9a\x05\x91\x48\x63\x14\x69\xd8\x16\xf1\x0c\x31\x3f\xfb\xfb\xfb\x8c\x6a\x74\x20\xee\x76\x41\xc0\xd2\x33\x37\x05\x63\xd7\xba\x5d\x5f\x75\x5c\x86\xb5\x7c\x4a\x0e\x87\x2c\x34\x9f\x4c\xe2\x5e\xd9\x75\xe6\x22\xd6\x63\x2b\x7f\xf2\x8c\x11\x8d\xe0\x3d\x5a\x03\x3b\x7a\x46\x81\xaa\x5d\x7c\xf3\x8e\x5b\xfc\x85\xd5\x55\x30\xa6\xca\xab\x12\x02\x4e\xdc\x07\xe5\x11\x5f\x14\x3d\xc1\x7b\xfa\x68\x42\x70\x12\x5b\xa6\x07\xbc\x15\xa3\xa7\x16\xcf\xd1\x3b\x68\x31\x1e\xd6\x35\x8b\x0c\x45\xb2\x15\xf5\x41\x90\x85\xeb\x08\xcb\x61\x6f\x02\x76\x20\x58\x9b\xf8\xe6\x2c\xce\xd4\xc3\x3b\xb2\x22\xaf\x8f\xcb\x89\x54\x0c\x7c\x7c\x2f\x06\xde\x8b\x81\x7f\x6d\x31\x50\xbd\xcf\x63\x8b\xe6\xae\x5e\xe8\xdd\xcd\xdd\x3d\x05\x79\x2d\xd4\x8d\x95\xc6\xca\x70\x4e\xe4\x91\x5a\x84\x15\x32\xfd\xd4\x4e\x91\xdc\xe5\x9a\xc8\xa5\x9f\xc6\xc5\x3d\xf0\x3c\x95\xaf\x24\x83\x4d\x0d\x0c\x7c\xf2\xeb\x41\x09\x95\x21\xb4\x9e\xa1\x95\x60\x9e\x9e\x7d\x45\xac\x1c\x43\xe9\x0a\x1a\x83\xd7\x51\x1a\x4d\xb1\x7a\x9d\x4f\x59\x16\x43\x85\xa1\x0a\x10\x2e\x3c\x14\xb8\xb6\xdf\xcf\x0d\x0c\x39\x15\xe7\xf3\x06\xfb\xf7\x18\x53\x0e\x43\x52\xd3\xbf\xa7\x25\xfe\x8d\xa2\x82\xf9\x5c\xa8\x8a\x44\x31\xc5\xe0\xa5\xd2\xb3\x49\x99\x9e\xe6\x6d\xc7\xa2\xa2\x4d\xb3\x3d\x20\x31\x07\x11\xbc\x8d\xca\x58\x13\x86\x3b\x51\x2d\x7c\x8e\x24\x0e\x69\xc7\x27\x7c\x19\x16\x54\xb0\x91\x29\x4d\x6e\x8e\x99\x33\x4e\x75\x49\xc1\x43\x73\xf0\x6d\x57\x8e\x73\x80\x5e\x53\x56\x4e\x70\xc1\x83\x48\x03\x3e\x1c\x2f\x94\x86\x67\xcf\xd6\x78\x13\x83\xba\x7a\xb3\x4c\x12\xe5\x18\x23\xa0\x52\x24\xfe\x4c\xe0\xda\xcc\x87\xbb\x3f\x66\xfc\xa1\x3b\x0b\xbb\x83\xd6\xbe\x56\xdc\x1d\x07\x93\xad\xa2\xed\xd8\x01\x4e\x64\x28\x19\xf3\x20\x86\x1a\xc2\xc7\xbc\x7b\x7b\xc8\x23\x4c\xd4\xc7\x8e\x51\x68\xe3\xae\x5e\x19\xe1\x01\xd2\xe5\x89\xd3\x46\x13\x03\x3d\xa2\x90\x2e\x96\x0c\xa2\x93\x49\x1e\x74\x68\xb5\xd4\x62\x63\xdd\xc3\x5d\x2b\x28\xc8\xf7\xb8\xd1\x53\xda\x92\x21\xa5\xd3\xc5\x00\x41\x90\xec\xba\x10\x52\xe8\xa9\xfa\xcd\xa8\x1b\x8a\x9c\x51\x76\xa0\x7d\x36\x78\xd6\x77\xb0\xce\xf8\xbd\x8c\x5e\xab\x63\xde\x45\x3c\x73\xc0\x5b\x7f\x56\x34\xdd\x11\x57\xe0\xde\x13\x23\xc5\x0c\x96\xab\xa3\xd0\xde\xac\xc0\xd9\x0c\x1c\x7b\x9e\x7a\x01\x64\x55\xde\xd8\x24\x1c\x17\xbe\x90\x45\xe2\xfd\x94\xa0\xc3\x15\x22\x17\x45\x62\xdd\xb6\x42\x42\xbb\x18\x44\xba\x3b\x56\xbe\x8f\xd8\x5e\x92\x57\x76\xbe\xcc\xe5\x09\x00\xd6\x96\x81\x0e\x08\x79\x46\x80\x21\x79\x4c\xf1\x6b\x41\x84\x3a\x03\x34\x4b\x15\xca\x8c\x3a\xb7\xca\xba\x8a\xc3\x41\x95\x70\x91\xcb\xf0\x69\x4a\x5b\xa3\x5f\x74\x74\xd1\x0c\x31\xb4\xd1\x92\x24\x31\x20\x8c\x0f\x8a\x66\x3a\xfe\x6d\x81\xe1\x7f\x38\x7e\x7e\xbc\xbe\xbe\x0e\xe2\x7d\xb7\x40\xcb\x69\x72\x39\xe0\x51\xc4\xe8\x81\x60\x59\xd0\x3d\xb1\x94\xad\xa4\x9a\x4b\x59\xfa\x5b\xd8\xd5\xc8\x1b\x12\xca\x38\x20\x43\xbe\xb7\xde\x32\x22\x3d\x8d\x7e\x39\xa5\xd9\xa7\x9b\x67\x67\x54\xec\xd2\x3f\xaf\xae\xa4\xdd\xa6\x0d\xca\x7e\x6c\x41\x19\x3a\x96\x3d\xff\x55\x91\x55\x3b\x40\x22\x8d\x0b\x3b\xe8\x95\x88\xaa\xba\x45\x95\x97\xea\xca\xe8\x94\x85\x40\x49\xfd\xcf\xb2\x90\xe3\xe7\x9b\xcb\xef\xea\x34\xbc\x8a\x1f\x68\x64\x45\xb0\xf0\x85\x2a\x30\xce\xea\xd0\x96\x29\x51\xaa\x8b\x29\x75\x3f\x63\xc4\x62\x91\xe6\x75\x1e\xd3\x3c\xbb\x61\x06\xcf\xdb\xd1\x99\x99\x34\x8a\xb4\x0c\x68\xbc\xe1\x54\xcc\xee\x1a\xd5\x54\x0f\xc1\xbe\x86\xe2\xa4\x42\xb3\xda\x7a\x7a\x16\x61\xae\x70\xda\xec\xce\x51\x70\xc8\x65\x8e\xe1\x86\xf4\xdd\xdb\x43\xe9\x81\x89\x99\xb2\x8c\xa3\x54\x0a\x9b\x24\xe5\x4a\x17\xbf\xaf\xa7\xdc\xf5\xf5\x38\x18\x0c\xae\xf5\xf8\x6e\xb6\x2f\x3d\xa5\xc9\x14\x45\x3d\x9c\xb4\xc9\xa7\x7d\xa5\xbb\xf9\x55\x88\x50\xd0\x80\xe9\x93\x5e\x9f\xb5\x2a\x44\xf3\x92\x15\x8a\x9d\xd7\xc2\x06\xa6\xed\xf5\xdf\xb7\xf7\x7a\x9f\x7b\xbd\xcf\x5f\x5b\xef\xc3\x95\x3e\xf1\xe8\x16\x37\x7f\x3e\xbd\x8f\xd4\xd6\xe8\x8a\x1f\xc6\x9c\xa4\x46\xe7\xf9\x33\x83\x8f\xd0\x61\x98\x2e\x3f\x1c\x4d\x05\x8c\xd4\x4a\xde\xab\x09\x14\xb6\xa6\xe4\xa5\xa2\xe7\xb1\xe9\xe7\x17\x5c\xe8\x0b\xb2\xa4\x2b\x4b\x0e\xea\xd1\x9a\xb5\x9d\x85\x03\x39\x6a\x97\x9e\xaf\x83\x96\xbe\x59\xed\xf2\xd5\x01\x8b\x16\xcb\x52\x3e\x5e\x4b\xf1\x05\xc7\x66\x4f\x6d\x97\x54\xe8\x08\x51\x57\xc2\x59\x71\x34\x42\xd4\x8d\x47\x1f\x7d\xb9\x42\x4c\xdc\x91\x7d\x92\x8d\x4e\x71\xbb\x46\x25\x9c\xb7\x51\x5f\xae\x68\x74\xdb\x6d\x74\xb1\x2c\x5f\xe2\xcf\xcd\xc3\x7c\x89\x3f\x57\x8d\xd1\xcc\xaa\x1f\x60\x73\x5b\x0c\xa8\x6a\x68\xfe\xb6\xac\x71\xf1\xcd\xe8\x54\xc1\x89\x89\x08\x14\x92\x03\x3e\xf4\x80\x77\x0b\x80\xcf\x2a\x76\xae\xe7\xcf\xd4\xae\xc5\x68\xa7\x13\xee\xc0\x16\xf5\xe4\x7e\x8b\xba\xdf\xa2\xfe\xda\x5b\x94\xba\x9a\xc0\xe5\xec\x46\xf7\x12\x1c\xf8\x6e\x5f\x25\x56\x44\xff\xf7\x85\xff\xf7\x5d\x82\xf8\xef\x41\x1a\xb6\x4d\x0a\x22\xcc\x91\x2d\xa0\x05\x4f\x16\x60\xe3\xaa\xf6\xc6\x59\x3a\x21\x53\x01\xa6\x85\xc2\xd1\xa1\x45\x64\x15\x01\x76\xc1\x9f\xad\x19\x17\x34\x3c\x51\xc0\xfc\xc8\x42\x81\x5b\xc8\x80\x44\x01\x72\x54\xbc\xbf\x4c\xc7\x6c\x8b\xd1\xa1\x0a\x96\x2a\xc0\x28\x2b\xce\xb1\x0d\xc4\x53\x65\x5d\xcc\x41\x91\x0e\x41\x46\x51\x2a\xb2\x99\xd7\x43\xa7\x3f\x22\x59\x0a\x21\xe0\x33\xad\xcd\x9d\x81\xd4\x79\xf3\x37\x82\xa0\x04\xdc\x3c\xeb\xa3\x07\x0f\x10\xff\x3d\x00\x9d\xe0\xf1\xa4\xd7\xdd\xfc\xdc\x65\xae\x4b\x36\xfb\xe8\x29\xea\xe0\x72\x46\x77\x0f\x08\x4c\xfa\xec\xf2\x65\x54\xcc\x3a\x28\xb4\x93\x99\x46\xb7\xa3\xa4\x04\x2d\xfe\xd3\x8f\x79\x36\x7f\xf6\x1b\xf4\xb4\xcb\xbb\xa4\x85\x15\x7a\x76\x09\x0d\xd3\x4e\x1f\xa4\xf1\x11\x2d\x27\xa3\x79\x79\x21\xd9\x38\x24\xac\x1a\xcf\x32\x1d\x27\xf8\x37\x1a\xc0\x09\x6d\xab\xa1\xeb\x3a\x4c\x65\xa7\xc5\xfc\x68\xe3\x3c\xcc\x96\x69\xab\x6b\xa6\x3b\x18\x87\xb7\x6d\x46\x42\xfa\x50\x2a\xc0\xd8\xa8\x9c\x29\xf8\x0d\xfb\x7f\x22\x1b\xd4\x26\xc3\x99\x04\x1d\xc0\xe8\xb3\xec\xde\x8b\x72\x76\xd7\x07\x84\xd6\x87\x83\x3b\x3a\x1b\x40\x00\xe0\xea\xb3\x01\x53\x7d\x30\x2e\x4e\xb0\xb7\x47\x0b\xbd\x33\x8b\x86\x7e\x2c\x6e\xd0\x05\xed\x8e\x9b\x71\x57\xe6\xff\x02\xe9\x1e\xba\x8f\x9e\x1d\xbc\xb1\x82\x91\x71\x9e\xca\xb4\x32\xec\x01\x2d\xd7\xcd\x5c\xaf\xad\xb1\xde\x0d\x98\x65\x94\x7c\x4b\xf3\xa2\x9c\x29\x6d\x50\x80\xba\x7a\xe8\xe6\x6e\xc0\x87\x39\xc5\x65\x58\xa1\xf3\x14\xbe\x4a\x07\x7a\x41\x3e\x92\x80\xeb\xe9\x8c\xc2\xe7\x51\x62\x44\x19\x1b\x58\x81\xb3\xcf\xa3\xc4\x71\x46\x22\xd3\xae\xd7\x00\x3d\x2b\x0d\x85\xfb\xf9\xbb\xc9\x60\x78\xd1\x9b\x0c\x87\x17\x6d\x39\xa0\x36\x67\x51\xca\x5d\xa2\x04\x2c\x37\x1b\x4f\x4e\x1c\xd0\x3d\x3d\x09\x36\xe5\xe4\xcb\x23\x94\x66\xcd\x69\x5c\xe1\x85\xe8\x54\x09\x54\xec\x7a\x8f\xbb\xd1\xfc\x51\xdd\xe6\xd9\x10\x7a\xe4\x73\xc6\x4f\x24\xb0\x16\x3a\xd2\xba\xc7\x0a\xf5\x6a\x58\x9e\xf4\x59\x23\x81\x2a\x8e\xcd\x59\x1e\x4d\xf1\x41\xd9\xe6\xe4\xcc\x41\x2b\x71\xe4\x83\x90\x87\xda\x1a\x2c\xb1\x75\xc7\x38\x76\x99\xc1\xc9\x72\x15\xb4\x78\x07\xc6\x9d\x3b\x36\x8c\x89\x42\x55\x0e\xc7\xca\xfc\xed\xe7\xdb\x3b\x30\xb1\xea\x9b\xe8\x99\xb1\x23\x6b\x68\x52\x64\xbc\xdd\xb0\x7c\xbd\x0d\x9c\x25\xae\xec\x5f\xe9\xe2\x45\xd7\xab\xd1\x2f\x6d\xa2\x9e\x76\x61\xff\x6d\xc6\x04\x80\x39\x98\x90\x12\xdd\xd7\xc0\x84\x46\xca\xb7\x18\x74\xb0\x56\x41\xd9\xf3\x05\x49\xd8\xe1\xad\x91\xbc\x39\x68\x0d\x8d\xbb\x10\x02\x0f\x9b\xd5\xf4\x67\xcb\x6b\x2d\xe9\xd1\x2e\xe6\x74\xab\x4e\x64\x75\x3b\xb8\x75\xcb\x89\xaa\x9b\x1b\x31\x85\xcf\xf1\x98\xcc\xa3\xa4\x1a\x15\x4a\x0a\x6c\x89\x04\x55\xa0\x82\x28\xff\xb8\x03\x36\x85\xa7\x86\xc1\x56\xc7\x4a\xae\x38\x82\x81\x7c\x5d\x3b\xe8\xe6\x15\xa4\x55\x58\xcf\x3c\x3e\x78\x4e\xa8\x2b\x8d\x49\x96\x72\x06\x57\x75\xf8\xfd\x23\x71\x9a\x9b\xe0\xe9\x1d\x1e\x63\xb2\x68\x41\xe6\x6e\x99\x36\x04\xe0\x82\xde\x96\x02\x78\x8d\xad\x07\xd8\x72\x15\x37\x72\x31\xcf\xe0\x6c\xc0\x36\x14\xc0\xc4\xa2\x3b\x12\x10\x1b\x97\x37\x3d\x20\xbd\x8b\x2e\xda\x2f\x71\xb7\x80\x1f\x11\xb5\x70\x6d\x38\x1b\xc5\x83\x47\x16\x72\x43\x4b\x37\xf5\xb6\x55\x57\x6f\xde\x4f\x7b\xa6\x7c\x6b\xcc\x37\x0e\x32\x4d\x57\x18\x87\x09\x5d\x31\x8e\x4a\xa0\xaf\x3c\x8e\x16\x9d\xaf\xee\xf1\x9d\xcb\xda\x15\x84\xc3\x8d\xbb\xea\x3a\x0a\x81\xff\xbd\x1d\xb5\x72\x6e\xd2\x51\xba\x17\xdc\xd9\x89\xc0\x8c\x90\x5e\x37\x26\x0d\xd2\x3f\x34\x3f\xc0\x4d\x28\xc6\x18\xe1\xad\xb8\xd2\x98\xc9\xa7\x22\xae\x79\xd3\xb4\x31\xe8\x81\x08\x76\x5e\x31\x85\x66\x9d\xbe\xb1\x56\x76\xe4\xd5\xab\x57\x2d\xfb\x90\x54\x52\x90\xac\x69\xa5\x96\xdf\xe3\x7c\x81\x1b\xb7\x27\x89\x01\x06\x5d\x8f\x00\x07\xa6\xa6\x17\xc5\x72\x34\x27\xe5\xcf\x59\xde\x24\x25\x29\xc0\x8a\x95\xee\xcb\xaf\xbf\xfa\x6e\xd1\x2a\x87\xaa\xdc\x8a\x2b\xda\xb3\x8e\x38\xce\xf5\xb7\x52\xfc\x04\x7a\x9a\x54\x74\x18\xa9\x87\x59\x6c\x82\xc1\x12\x36\x52\x40\xf6\xb7\x0a\xf1\x03\x98\x5b\xd2\x16\x1f\x5c\x08\x75\x94\x30\xf2\xb4\x82\x55\xe9\x52\x30\xad\x02\xe0\xb2\x53\x55\xb6\xd5\xa8\x69\xd0\xab\x31\x12\x95\xe8\x8a\x01\x5a\x9e\xb9\x5f\x99\x85\x2a\x4b\x68\xcd\x9b\x2b\xda\xc9\x78\xf5\xea\x95\x0b\xcc\xa8\x5f\xab\x52\x12\xa6\x31\x68\x9a\x00\xdf\xdc\xc2\x81\xc5\x64\x93\xca\xee\x3a\x1f\xcd\x8a\x8e\x28\xe9\x4a\xad\xab\x69\x3a\x2a\x17\x2e\x49\x47\x51\xa1\x2b\x2a\x78\x07\x80\x51\xf2\x75\xcb\x61\x24\xc8\x75\x3f\x58\xa1\x8d\x39\x49\x4d\xeb\x16\xa7\x05\x0e\x71\xc3\xfa\x67\x51\x31\xcb\xa3\xb2\x76\x0c\x15\x30\xad\x76\x86\xd5\x7b\x24\x6e\x67\x6b\x3a\xe4\x07\x69\x3e\x67\xf0\xeb\x60\xf3\x70\xb1\x7a\x0f\xa7\x51\xf1\x36\x27\xe3\x5a\x9c\x55\xc0\xdc\x58\x09\xbc\x7a\x2f\x79\xd8\xa1\xa2\xae\x97\x12\xe6\x86\x6d\x8c\xb4\x2b\xb4\x9a\x66\xaa\xc1\xbe\x12\x0d\x89\x98\x0c\xff\x60\xb6\x36\x75\x7d\xb3\x41\xb5\x16\x75\x16\x62\x5c\xbb\x0c\xc6\xca\x8e\x41\xbb\xd2\x1c\x11\xe3\xc5\x42\x34\x2e\xb3\x5c\x88\x3f\xc2\xf2\x01\xcc\x88\x03\x44\x61\x0d\x5b\x62\x0e\xed\x6b\x6c\x22\x2c\x1d\x9c\xa7\xa8\x81\xf6\xdc\x8e\x41\x1d\xe6\x18\x2c\x95\xe0\xf1\xd8\xa1\x65\x4e\xaf\xc5\x29\x62\xd6\x13\xaa\x1e\x8a\x0a\x11\x6e\xde\xba\xb1\x0b\x84\x39\xc6\x00\x97\xb3\x5e\x3f\x70\x49\xf6\x55\x36\xd5\x64\xe3\x76\x5d\xf2\x0d\x54\x19\x62\xd4\xbb\xd0\x17\xd8\xef\xf1\x02\x83\x69\x92\x8d\xa2\x64\x40\x91\x3a\x88\xdc\x64\x1e\xf3\xcc\xd7\x24\x19\x47\x8b\x37\x37\x6d\x96\x16\x76\x1a\x65\x89\x75\x4d\x6a\x56\x29\xaa\x41\xfb\xe9\x83\x1e\x53\x4a\x14\xe8\xf9\xa7\xa7\xc9\x1b\xd5\x8b\x72\xa6\xec\xf9\x2c\xc3\x9c\x4e\xb8\xf5\x24\xe8\x38\x06\x42\xdc\x40\x5d\x59\xe6\x74\xc2\xed\x6f\x20\x81\xcd\x69\x27\xdc\xfe\x8e\x7d\x4a\x5a\xe8\x84\x3b\xac\x08\x19\x45\x69\x27\xdc\xd9\x09\x4c\xf3\x41\xf8\xe4\x48\xea\x84\xbb\xbb\xf0\x2d\xcc\x88\x3a\xe1\x2e\xab\x9e\x73\xf6\x4e\xb8\xcb\xba\x25\x2e\x7b\x3b\xe1\x2e\x6d\x50\x18\x01\x75\xc2\xdd\x9d\xeb\xb3\x60\xe7\xbb\x7b\x7b\xc4\x7b\x7b\xc4\xbf\xb6\x3d\x62\x95\x31\xe2\xad\x6d\xe6\xdb\x9b\x09\xb6\xb0\x01\x04\xb8\x37\xb8\xfc\x9a\x26\xf6\x90\xda\x6c\xb2\xa2\x8c\xeb\x6f\x62\xb3\xd2\xc2\xa4\x7e\x38\x1c\x2a\x9f\x34\x3e\x3f\x37\x3c\x60\x23\x65\xf1\x50\x1d\xfe\xff\xd8\x7b\xf7\xb5\xb6\x91\x65\x71\xf4\xef\xe4\x29\x7a\xe6\x77\xd6\xc4\x0e\x02\x7c\x87\x90\x30\x7b\x13\x03\x81\x95\x10\xf8\x01\x99\x99\xb5\xf9\x98\x7c\xb2\xd5\xc6\x4a\x6c\xc9\x5b\x92\xc1\x64\xc2\x7a\x9f\xf3\x1c\xe7\xc5\xce\xd7\xd5\x17\xf5\x55\x96\xb9\x64\x32\xb3\x60\xed\x9d\xb1\xa4\xee\xea\xea\xee\xea\xea\xea\xea\xba\x64\x43\xe4\x4f\x42\x09\xf7\x07\x3a\x90\x98\xc9\xe8\x35\x81\x47\xcd\x58\x7f\x5b\xe1\x0a\xe3\x44\xd7\x8d\x1b\xad\xb8\x0a\x2d\x20\xf0\xc9\xe2\x97\xb1\xa9\xbd\xc7\x99\x65\x53\x53\x37\x2f\x79\x77\xb9\x39\xf7\x5a\xb5\xc7\xdd\xe2\x71\xb7\xf8\x7b\xef\x16\xdf\xa9\xf5\xfa\xfd\x19\x9a\x97\xb4\x83\xcf\x4d\x39\x8f\x70\x92\xc6\x91\x3f\x7a\xb4\xe7\x7c\x68\x7b\xce\x9b\x72\x16\x7e\x11\xbe\xca\xcd\x06\x8b\xf4\xc3\x79\x41\x53\x45\x3c\x61\xb3\xfa\xd1\x5a\xe8\x0e\x37\x94\xe1\x98\x6c\x04\xc7\xfe\xd5\x5b\x3c\xef\xe6\x42\x2e\xfa\xcc\x7b\xfa\xe4\x89\x8e\x9b\x51\xa0\xc0\x33\xad\xfc\x4d\x9c\xd9\x8e\xf8\x20\x19\xee\x3d\x79\x52\xf2\x6e\xba\xf4\x15\x1c\xee\x1f\xe3\x7e\x7c\x49\x83\x43\x15\xdd\x59\xf1\x72\x56\x5c\xd5\xaf\x05\x03\x32\x8d\x46\x71\xff\x73\x39\x4a\x51\xca\x16\x10\x8b\xab\x5c\x19\x83\xc7\x72\xe3\xe6\x1c\xbd\x7b\xbe\xf9\xce\xe7\x7e\xee\xf5\xf7\x22\xd7\x9c\xb6\x6b\x63\x67\x97\xca\xcf\x4f\xb9\xd9\x29\x9e\x9b\x45\xee\x32\xf5\xb9\xd1\x90\xb7\x49\xd6\xac\x61\xa9\x11\x69\xf1\xe6\x6f\x15\x0a\x92\x6e\x4f\x38\x55\xbb\x6e\x3b\x9c\x97\x22\x12\x38\x59\xde\x7d\xb8\xf3\xc1\xd6\x1c\xb5\x70\x3e\x1d\x72\x61\x87\x58\x6e\xca\xe5\x7c\xbb\xcd\x85\x73\x8b\x8a\x48\xd3\x0a\xe9\x72\x7a\xfd\x51\x4e\x7f\x94\xd3\xff\xde\x72\x3a\x13\xd2\xd3\xa1\x43\xab\x33\x47\xfc\xc6\x09\x9e\x8e\x09\xe8\x9f\xe7\x28\x81\xfa\x71\x82\x57\xc2\x58\x95\xd3\xd7\x4a\x07\x4e\x28\xe9\x68\x39\xcf\x5f\x13\x0a\x9d\x0c\x87\x0f\xae\x1d\xfa\x7e\xe4\x71\xc2\x1d\x4f\x86\xca\xed\x06\xbe\x62\x41\xa7\x77\xbf\xc5\x85\x4e\x3a\x9c\x7f\xa1\x93\x0e\xe1\x42\x87\x0a\x2e\x8b\xdc\xdb\x14\xc9\xf9\xee\xcd\xc9\x10\x0f\xa4\xad\xe9\xd2\x7a\x53\xc7\x44\x84\x74\x38\xfc\x68\x2f\xa0\x1a\x85\x20\x8b\x2e\xab\xa8\xd1\x30\x1a\xc4\xee\x16\x2d\x5f\xef\xd6\x5c\x8a\xb3\x03\x7f\xc6\x88\xe0\x24\xfc\xa2\x5f\x0e\x4b\x6d\xcf\x2b\xaa\x5a\xfd\xdc\x06\x91\x30\x3a\x8a\x7f\x2d\x46\xc0\x56\xe4\x6e\x0d\x8f\xfd\xe4\xf3\x69\x32\x4d\x33\x1c\x1c\x61\xe3\x32\x58\x6a\xbe\xb8\xe0\xdd\x90\x88\x30\x91\xe9\x8e\xfc\xb0\xa0\x7d\x67\x99\xbb\x51\x80\x1f\x04\x47\x49\x78\xe9\x67\x98\x1e\x09\x1d\xad\x17\x15\xbb\x5b\xdf\x69\xd2\xaf\xb9\xdd\x2f\x2a\x76\x37\x04\x86\x7e\x3a\xb7\x75\x67\x99\xbb\x35\x7d\x81\x33\xba\xa1\x17\x8e\x7d\x41\xa9\xbb\x37\x5f\x62\xee\x8b\x8a\xdd\x99\xee\x4f\xae\xc7\x85\x8d\xbb\x8a\xdc\x99\xea\xe7\x35\xec\x2a\x72\xd7\x21\x27\x72\x5c\x86\x29\xe8\xdd\x24\x1e\x1f\xf9\x69\x7a\x15\x27\x41\xd1\xf8\x97\xac\x73\xe7\x75\x30\x6f\x4c\x5c\x45\xee\x4c\x86\xf3\x1a\x76\x15\xb9\x0f\xd6\x33\xaf\xed\x82\x52\xf6\xe6\xc5\xc3\xea\x2a\x4a\xa7\x3d\xb8\x79\xa3\x29\x8d\xa7\x51\xfe\x3c\x0e\xd3\x34\x8c\x2e\x9e\x96\xc6\x76\x12\xa7\xfa\xd5\x95\x84\xa5\xe5\xab\x45\x4f\x81\x8a\xf5\x8e\x68\xfe\x2d\xd7\xc9\x70\x28\x25\x10\xd3\x6c\x2f\x94\x53\xb4\x66\x19\xd1\x6a\x3c\x9e\xa1\x1f\xcf\xd0\x7f\xef\x33\x74\x7e\xd7\xd5\xfb\xf2\x45\xbb\xeb\xda\x1a\xe1\x19\x7a\x8d\x13\x7c\x91\x7e\xf1\xd3\x2f\x21\x7a\xe5\x8f\xf0\xec\xbf\x93\x6c\x90\xae\x0c\xa7\xea\x71\xb8\xc3\xa2\x99\x1e\xe3\x01\x4e\x70\xd4\xc7\x1b\x88\xb4\x9f\x6e\xac\xae\x5e\x84\xd9\x70\xda\x5b\xe9\xc7\xe3\x55\x7e\xea\x5e\xbd\x88\x97\xc5\xef\xde\x28\xee\xad\xa6\x57\x7e\x32\x5e\x0d\xa3\x0c\x27\x91\x3f\x5a\x25\x5d\xc2\xb3\x8c\xff\x77\xe5\x22\xfe\x3f\xef\x9a\xcd\x07\xbe\x1a\xcb\xef\xbb\x4e\x08\x36\x7f\xf3\xc3\x35\xfc\xf8\x4b\x5c\x76\x51\xcb\x57\x9c\x5d\xc5\xc9\xe7\x63\x0c\xa1\x6a\x8b\x14\xe5\x7a\x71\x53\x5b\xde\xfb\xf2\xe5\x63\x41\xa9\xbb\xf8\xe6\x5d\x47\xfd\x9d\xc8\xef\x8d\xf0\x3c\x2c\xa5\x92\x76\x04\xed\x05\xee\x82\xdb\x95\x3f\x29\x89\x5b\x5e\xd2\x81\x9b\xb5\xc0\x1d\x70\x0b\xe2\xab\x88\x45\x21\x2e\x42\x8c\x17\xb3\x63\x65\xf9\x5a\xde\xdd\xd4\x81\xd8\x74\x52\x02\x2d\x5a\xc8\x8e\x94\xf1\xed\xce\x28\x25\x38\x4b\x42\x7c\x39\x2f\x02\x04\x2f\x66\x47\xcb\xf2\xf5\x2e\xa4\x95\x91\xdd\x6e\x0e\x51\x91\x32\x0e\x72\xd2\x3e\xdd\x79\x88\x2e\x70\x09\x77\x66\x3b\x2e\xea\x87\x3b\x8c\x09\xcd\xde\x30\x27\x46\xaa\x1d\x07\xf5\xc3\x9d\x47\x83\x25\x6c\x29\x46\x86\x16\xb2\xe3\x63\x7c\xe3\x28\xb5\x4a\xa1\x54\x70\xab\x6b\xa8\x38\x75\xb6\x2c\xdd\xfe\xe5\xfc\x50\x7a\x99\x33\xa2\xfc\x25\xe7\x03\xd2\x8d\xe3\x44\x7d\xe6\xd4\x2f\x01\x22\x24\x98\x3f\x5e\x60\xe9\x62\x72\x32\x95\x1e\x24\x59\xfc\x41\xaf\x19\x87\xe1\xa5\xd3\x37\x86\xcc\x09\x7c\x77\x9e\x21\x8b\x61\x5b\x94\xb2\x0a\x6c\xf8\xee\x38\x5e\x59\xce\x57\x44\x58\xb2\x05\xbb\xb5\xde\x4b\x36\x1f\xcf\x54\x8f\x67\xaa\xbf\xf7\x99\x8a\x1d\xa8\xf8\x05\xd1\xb7\x8d\xd2\x7e\x1b\xc3\x6a\xee\x1d\xe5\x4f\x42\x2e\x8c\xd3\x14\x7f\xd9\xb0\xc8\x02\x8d\x5e\x97\x15\x46\xa5\xe4\xa5\xb3\xeb\x09\x91\x0f\x58\x04\xca\x97\x4f\x25\x06\x1e\x66\xfd\x61\x85\x7c\xd7\x73\x8b\xf4\xfd\x14\xa3\x67\x84\xe2\xd3\xec\xd9\x86\xf2\x09\x26\x2b\xb9\x48\x57\xd2\x61\x38\xc8\x2a\x5a\x42\x11\x64\x24\x07\xac\x99\x05\x18\x4b\x06\xf7\xb5\x08\x5f\xd1\x08\x54\xf4\x42\xf6\xa5\x05\x8d\x09\x8e\x82\x30\xba\x78\x70\x3c\x8e\x68\x3b\xb2\x0d\x91\x0d\x29\x16\x3a\xd0\xc4\x46\x03\x67\x54\xa6\x09\x56\x6e\x24\xe9\x40\x94\x9a\x6f\x49\xc8\xa0\xe9\x32\x82\x42\x0a\x16\xd9\xc9\x22\x55\x47\x61\x94\x66\xfe\x68\x54\xaa\x65\xad\xb4\xdd\xd7\xdd\x5d\xa8\x00\x8f\x0b\x9c\xbd\x8b\x2f\x4a\x04\x14\x23\xa5\x9c\x3e\xf6\xb4\x45\xad\x48\x41\xab\x93\x78\x6e\x1c\x0e\x52\x64\x4e\x7b\xdd\xa1\x1f\x5d\xe0\x12\x4d\xda\x84\x0f\x0a\x42\x36\xc9\x52\x46\x4f\x11\x84\x48\xc7\xa4\x46\xe2\xd1\x48\x96\x07\x16\xe6\x37\xe9\x70\xb8\x02\xac\xd1\x60\x37\xe9\xd0\x64\x37\x6e\xf1\x69\xce\x2d\x8d\x41\x06\xc8\xb8\xa5\x51\x2c\x09\xee\x55\x4d\xef\x26\x46\x64\xd3\xd4\x3f\x1c\x22\x26\xe9\x22\xe3\x9a\x82\x36\xcb\x70\xd0\x8b\xde\xad\x79\x8d\x8c\xef\xa1\x6d\x99\xf4\x0c\x49\x94\xe2\x80\xb3\xe1\x06\xf9\x87\x02\x4b\x87\xc3\x0d\xf2\x0f\x15\x5e\x6d\x09\x19\x5a\xad\x47\x91\xf4\x51\x24\xfd\x9b\x8b\xa4\xb9\x9e\x9f\xfb\x58\xdf\x53\xb6\x68\xea\x1f\x7e\x8c\x2f\xc8\x3c\xfb\xc9\x56\x2f\x74\xe4\x25\x48\x57\xdf\xa8\x45\x21\xd1\x3f\x57\xcf\x87\x7d\x7f\x22\x03\x71\xc1\xd8\xef\x6e\x1d\x99\x10\x24\x4c\x98\x23\x3a\xb3\x5e\x46\x9b\xe8\x59\x6d\xd6\xef\x04\x2f\x82\x46\x3f\x68\xb5\x5e\xf8\x6b\xed\x56\xbf\xf5\xa2\xd5\xe8\xb4\x70\x7d\xbd\xf6\xa2\xdf\xae\xe1\x66\x2b\xe8\xb4\xda\x9d\x46\xef\x59\x8e\x8b\x0d\x8c\x5f\xf7\xeb\xf5\x7a\xaf\x5f\x5b\x6b\xf5\x5f\xf4\x07\xfe\xda\x7a\x7d\x50\xeb\x37\xd7\x71\xa7\xd9\x0b\xda\xf5\xfe\x8b\x7a\x6f\xdd\x1f\xd4\x6a\xcf\xdc\xbc\x89\xe2\xb8\x21\x49\xba\x7e\x2f\xdc\xb0\x0c\x62\xce\x09\x99\x1b\xfc\x86\xb5\x7f\x74\xa7\xa7\x85\x09\xda\x06\x64\x7d\x5c\x2d\x70\xcd\xee\x52\xa8\x0a\xc7\x2c\x9e\xc5\x1f\x37\xea\xde\x8f\x73\xe6\xe9\xc7\x8d\x06\x61\xb6\xed\x47\x66\xfb\xc8\x6c\xff\xde\xcc\x36\xe7\xb5\x5c\xf9\xa5\x31\xdb\x22\xc3\xe4\x41\x12\x7f\xc1\x63\x3f\x5a\x09\xf0\xcf\xdf\x2a\x9d\xbf\x7e\x41\x7a\x97\x74\xfd\x54\x91\x28\x7d\xa7\x2f\x94\x8c\x04\x5a\x89\x54\x2f\x71\x9b\xdc\xfb\x8b\x67\xf8\x2f\xc8\xd6\xcf\xc7\xe2\xe1\xf3\xf5\x97\xcd\xf1\x7d\xe7\x14\xdf\x96\x2e\x15\x24\xf9\xb6\x85\x6e\xd1\x46\xf8\xbf\x6c\x6f\x69\x5d\x48\xb7\xfd\x9d\xa4\xd7\x76\xf6\xfb\x9e\x12\x6c\xff\xb0\x49\x09\x47\x7b\x45\x36\x94\x41\x18\xe1\xe0\x2e\x19\xb8\x79\xe6\xd8\x2c\x46\x2c\x6d\x75\x9e\xce\x1a\xd2\x71\x8b\xc3\xb6\x48\xc8\xba\x82\x0e\xc8\xc6\x16\xe2\x94\x51\x12\x0c\x93\x36\x96\x5a\x0e\xec\xb9\xd9\xf4\xf9\xb8\xee\xb2\x91\xfa\xfa\x7e\x3a\x1a\xdd\x48\xc6\xee\xe1\x00\xe1\x59\x98\x42\x71\xeb\x90\x6b\x2d\x16\xe6\x94\xe7\x19\x6c\x78\x6b\x34\x87\x8d\x9c\x77\x7f\x19\xd5\xcf\xab\x8e\x34\xf3\x2b\x93\x78\x52\xa9\x42\xde\x6a\x76\xef\x45\xf8\x3f\xac\x27\x18\xad\x1f\x64\xe1\x46\x1d\x6e\x6a\xdf\x90\x63\x96\xc5\x76\x52\x54\xed\x20\x5c\xc4\xc8\x5e\xf1\x5e\x38\xa9\xb1\x7c\xfa\x6e\xa8\x23\x44\x49\xc4\x13\x94\xe4\xe9\xbc\xdf\xe0\xac\x22\x9d\xce\x71\x34\x1d\xe3\xc4\xef\x8d\xf0\x06\xca\x92\x29\x36\x55\x7f\xfe\x18\xa7\x85\xa9\xba\xa5\x7c\xde\x50\x18\x94\xb7\x48\xca\xe1\x9d\xce\x49\xe2\x9d\x6a\x59\xbc\x53\x47\x1a\x6f\xbd\xc8\x4b\x45\x23\x26\x9a\xaf\xf3\xec\xfd\xb4\x13\xf6\xec\x2e\x71\xef\x93\x07\xe5\x3d\x3a\x64\xac\x2f\x04\xbe\x9f\x5e\x47\xfd\x37\xb0\xdf\x10\x91\x17\xba\x50\x3d\x57\x72\xa2\x6f\xb1\x22\x15\xc9\x4d\x43\xab\xa6\x4c\x12\x80\x50\x59\x06\xdc\x2e\xa3\x25\xc0\x61\xa5\x3f\xf4\x93\xad\xac\x52\xab\xae\x64\xf1\x87\xc9\x04\x27\x5d\x3f\xc5\x95\x2a\xff\x0c\x59\x95\x2b\xf5\xaa\x73\xe3\xe1\x33\xeb\xce\x3c\x9a\x6f\xdc\x79\x1a\x55\x1e\x11\x8d\xd7\xb8\x20\x1d\x32\x57\x8c\x10\x50\x94\x04\xdb\xe2\xad\x2d\xc5\xb6\xaa\xe8\xe1\x99\xed\x45\x15\xba\xdd\x4b\x1a\x9b\x3c\x15\x77\x51\x07\xf9\xa8\x2f\xd6\xcb\xfc\xae\xdf\x1d\x04\x0c\xe5\x66\x4e\xd6\x0e\xd1\xb4\xe7\x0b\xf6\xaa\x64\x7a\x74\x35\x25\xba\x7d\xb0\xcd\xa4\xe8\x37\x6a\xf6\xf2\x0b\x9c\x2d\x98\xbc\xfc\x02\xbb\xb6\x93\xef\x3b\x77\xb9\x85\x38\xca\x67\x2f\xd7\xcd\xe6\x36\x64\x79\xd4\x54\x92\x9f\x9d\xab\xea\x75\x32\x4d\xac\x8a\xb6\x59\x95\x4c\x84\x2e\x4f\xd9\x43\xa5\x43\xe7\x03\x24\x1d\xcc\xb5\x98\x3d\xe4\x88\xdd\x79\x3c\x62\x3f\x1e\xb1\xff\xde\x47\x6c\x49\x9f\xc9\x38\xc4\x98\xb1\x74\xf5\xa4\xfd\x4f\x3c\x18\x24\xf8\x1a\xfd\x1a\x8e\xfa\x9f\x31\x7a\xf5\x09\x0f\x06\xae\x68\x3d\x0b\x85\xf6\x39\xf0\x13\x72\x84\x3f\xf4\xa3\x3e\xf6\xa1\xac\x2d\xa8\xcf\x2d\xe2\x00\xb1\x2a\x6f\xfc\x4b\xf4\x6b\x1c\x07\xe8\xd5\x85\xf3\x90\xdf\xca\x0f\xf9\xff\x64\xdc\x54\x71\x1e\x66\x2c\xb6\x28\xa5\xad\x25\x50\x9d\x9e\x85\xd6\x96\x82\x16\x27\x49\xac\x05\x0f\x5a\xa5\xef\xa8\x0d\x02\xdd\x76\xf6\xb3\x67\x29\xd9\x18\x27\x71\x94\x86\xbd\x11\x25\xb0\x89\x0f\x4e\x24\x68\xcc\xee\x7c\xc8\x5e\x34\x49\xe2\xcb\x30\xc0\x49\x2a\x6a\xf9\xa3\x34\x36\xab\xc6\xa3\x11\xa9\x4a\xa8\x8d\x5b\x8f\xa3\x28\x0e\xe8\xd7\x30\xea\xc7\x63\x19\x32\x01\xc6\x72\x0a\xd0\x2b\xd7\x2c\x1c\x63\xb2\xd8\xc2\x14\xd5\x51\x8a\xfb\x71\x14\xc0\xee\x18\x46\x17\x23\x9c\xc5\x11\x0c\x27\xe9\x5e\xc1\x41\x9f\xa3\xaa\x1c\xf7\xf9\x4b\xb4\x29\xba\x22\xe9\x19\x48\xdb\xa0\x01\xbe\x91\x5e\x72\x5c\x64\xad\x83\xf3\xf0\x47\x24\x94\x61\x12\x47\xf1\x34\x1d\x5d\x43\x18\x0c\xc7\x3e\x4c\x3e\x59\xce\x23\x28\xf0\x33\xdf\x79\x42\x56\x7b\xab\xa8\x3c\xa2\x40\xe9\x3c\x01\x23\x9f\xd4\x7e\x50\x7a\xaf\x24\x37\x8c\xa3\x34\x26\x5b\x17\x21\x8a\x0a\x25\x8d\x95\xfd\xe8\xd2\x1f\x85\xc1\x11\x2b\x5f\x91\x65\x1e\xee\x85\x0d\x83\x21\x49\xf8\xea\x1e\xcf\xc8\x7c\x25\x8b\x8f\xe8\x3b\x40\x69\x85\xf6\xde\x83\x6e\x32\x63\x0b\xe9\xfc\xc2\x4e\xe5\x9b\xea\x5c\x51\x61\x96\x81\xe6\x57\xe5\xd0\x29\xde\x48\x98\xfe\x42\xd0\x3d\xa6\x54\x88\x85\xa0\x26\x75\x33\x1b\x26\xf1\x15\x52\xbb\xa7\x97\x57\xba\xc3\xba\x49\x3f\xad\x94\x3a\xf9\xfb\x0b\xcd\x3e\x48\xb3\x85\x24\xa0\x9f\x4b\x85\xf4\x33\x9f\x18\x00\xb8\x41\x11\x52\xf0\xdc\x52\xb4\xc1\x53\x67\x4a\xb2\x71\x11\x75\xdc\x0f\x21\x98\x73\x4f\xe5\x7e\x06\xb2\x84\x3c\x4f\x3a\x85\x93\x44\x17\xf1\x2d\xbd\xa9\xea\xe6\x36\xe4\x4f\x81\xb3\x08\x8d\xcd\x1f\x32\xa3\xb6\xdc\xbe\x21\xe4\xb2\x6c\xaf\x0a\x09\xea\xc1\x39\xdd\xc7\x06\x1b\x35\x16\x9d\x0c\x48\x81\xd7\xe4\xbb\x45\xc9\x44\xeb\xdd\x07\x61\x42\x0b\xdf\x19\x61\x02\x4e\x32\x75\x72\x26\x73\x3b\x52\x4c\xef\x81\x16\x55\x1a\xe4\x7a\x36\x98\x8d\x0a\x6f\xe5\x4e\xa4\x97\xce\xa3\x3d\xa5\x43\x82\xe8\xd0\x9c\xed\x0f\x67\x62\x5f\x25\xd2\x26\x3f\x13\x32\x91\xcf\xa0\xb8\x8c\x4f\x95\x5d\x35\x57\x48\x4b\xa2\xae\xba\xeb\x3b\xb7\xfb\x79\x3b\x77\x46\x8e\x54\x4c\x70\xd1\x11\x25\xdf\x8e\xc4\xa7\xb9\x1c\x9b\xc6\xfe\xbf\x01\x68\xfb\xc1\xdc\x25\x63\xf9\x2a\xcc\x92\x38\x26\x59\x1c\xc4\xa8\x3f\xc2\x7e\x34\x9d\xa0\x08\xe0\x93\x01\x16\xc7\xf6\xa2\xa1\x92\xb0\xb7\xac\x3c\x8a\xa4\x1c\x10\x45\x34\xae\x8e\x25\x11\x8e\xce\x68\xe9\x73\x22\x24\x91\xea\x1b\x88\x02\x09\x83\x0d\x03\xd0\x86\x0d\xe4\x46\xfe\xf3\x86\xe7\xc4\x5e\x5d\xd5\x47\x5f\x61\x00\x4c\x00\x53\x77\x73\x86\x50\x45\xac\xf0\x39\x93\x1b\x4f\x84\x50\x4a\x44\x50\x66\x46\x0b\xa7\x9b\x8b\x90\x1c\xe9\x42\x5d\x77\x4c\xea\x58\xe6\xdc\x98\xdb\xc2\x91\x17\x20\x54\x22\x85\xba\xbc\x43\xd4\xb2\xcc\x32\xc8\x2f\xa5\xe1\xc9\xf1\x67\xa3\x53\x61\x1a\xd5\xcf\xf8\x3a\xad\xe4\x75\xab\x5c\xcb\x0b\xc9\xe2\xd1\x4f\x3f\x21\xd7\x18\x12\x62\x4a\x4e\xe9\xfb\x8a\x52\xe8\xa5\x3a\xce\xba\x00\x5c\x30\xde\xf9\xee\x93\x60\xc2\x0b\x88\xfc\xcf\x87\x7d\x8c\xfb\x43\x3f\x0a\xd3\x31\x3f\x86\x16\x33\x07\x00\x50\x3c\xbc\xb4\x0d\x79\x60\x3f\x63\x3c\x11\xf9\x03\x78\x67\x57\x9f\x7f\x4a\x87\x61\x44\x1a\x9a\xf5\xe3\xf1\x64\x84\x67\x61\x76\xbd\xd1\x86\x23\x19\x29\x40\x08\xa2\x42\x36\x87\xcf\xf8\x9a\x6a\x0a\xc4\x68\x4a\xe3\xb5\xba\x8a\x12\x3c\x8e\x2f\x31\xf2\x47\x23\xe8\x55\xea\x21\x3c\xeb\xe3\x49\x06\x62\x3f\x7b\x25\x97\xcf\x86\xf8\x1a\x45\x98\x8e\x48\x0f\xb3\xfa\x01\xe9\xf1\xd4\x1f\x8d\xae\x51\xef\x1a\x86\x8c\x0c\x0f\x4b\x05\x00\x34\xf3\x2b\xd9\x90\xc2\xe8\xa2\x52\x95\xf6\x81\xca\x0f\x4a\xef\xd0\xd7\xaf\x04\xdf\x95\x30\x0a\xf0\xec\x70\x50\x01\x37\x45\x42\x6c\x1f\x9f\x55\x61\xf2\x97\xeb\xfa\x06\x21\x51\xd8\x67\x7c\x7d\xbe\x22\x56\xa2\x6e\x0e\x6d\x52\x24\x29\x6f\x98\x26\xff\x85\xc9\x13\x4e\x99\x64\xde\xfb\xd4\x36\x17\xc5\x51\x19\x9e\x40\x4d\x6a\x8b\x68\x92\x59\x0c\x9b\x2a\x50\x07\x15\xa2\x0e\x01\x67\xe9\x4c\x8a\x33\xa5\xf7\x04\xb0\xa4\x8a\xf4\x50\x7f\x65\xe7\x74\xef\xe3\xd1\xe1\xbb\x77\xfb\xef\xdf\x7c\x3c\xdd\x3f\xd8\x39\xfc\x70\x2a\x1f\x8f\xca\xcc\x80\x29\x54\x29\x12\xd3\x83\x1c\x1d\x4d\x99\x8c\xe0\xb5\xed\x67\x3e\xda\x44\x67\xe7\x2f\xd5\xf7\xfb\xe0\x6e\xcc\x5f\x97\x5b\xaa\x02\xe0\xca\x64\x9a\x0e\x2b\x3a\xdd\x33\x11\x4f\x29\xbd\x1f\xa4\xb4\xf0\x67\x7c\x5d\x35\xc6\x20\x07\xb8\xc0\xe0\x95\x12\x37\x05\x64\xd6\x28\x5f\x52\x63\x7f\xa2\x30\xc9\x10\xc8\x16\x18\x0a\x90\x18\x21\x4d\x75\x98\x0e\xfc\x89\xa4\xba\x90\xf4\xda\xaa\xa7\x38\x15\x5c\x81\x6b\x54\xff\xd0\xc7\xe0\xc0\x9f\x9c\x41\xb5\x10\xb6\x78\x3e\x32\x67\x50\xfc\x5c\xf2\x48\x17\x8d\x2b\x7e\xf3\x68\x61\x99\x39\x56\xa5\x66\x25\xbc\xc9\xe9\xe1\xf6\xe1\x06\x27\x32\x34\x8a\x2f\xfe\x4b\x97\xaa\x63\x87\x5c\x7d\x57\x49\xba\x84\xb2\x20\xb5\x1e\x1d\xd9\xb7\x95\xb1\x3f\xa9\xb8\x8c\x15\xf8\x1f\xd8\x2f\x06\xf9\x28\x93\xb1\x67\x47\xbd\x30\x90\x1d\x6f\x04\x45\x7c\xc6\x28\x9d\x26\xa0\x27\xe6\xcc\x2a\x4c\x51\x9a\x85\x84\x1e\x28\x27\xc7\x01\xf2\x07\xe0\x20\x94\x24\xe1\xa5\x3f\xd2\xf6\x5a\x05\x26\x19\x10\x70\xfb\xa7\x4b\x23\x0c\xce\x75\x14\xf3\x2e\xad\xf4\x73\x7b\x00\xb5\x8e\xf8\xe2\x74\x98\xe1\xba\x13\xf9\xd3\x0d\xc2\x23\xa6\x67\xb6\xd4\x18\xf8\xa3\x14\xcb\xb7\x6c\xcc\xed\x69\xee\x98\x8a\x74\xfe\xac\x4d\x74\x0b\x18\x64\x5e\x60\xc6\xa5\x45\xeb\x38\xfc\xbf\x34\xc6\xf3\x07\xa8\x59\x62\x1c\xcb\x2b\x06\x90\x42\x61\x52\x2f\xa1\xa2\x3a\x4a\xda\x62\x77\x0f\x93\x8a\x8b\x5b\xcf\x80\xe4\x4b\x4e\x57\xc6\xa5\x63\x3d\xa8\x86\x7a\xe3\xa5\xa5\x5e\x32\x53\x57\x30\x85\xf4\x8f\x1b\x0d\x08\xed\xc3\x94\xe1\x3f\x6e\x34\xc1\x0d\x75\xad\xcc\x1d\x19\x8b\xb9\x89\xb3\x2c\x8c\x2e\xec\x9e\xbd\xc0\x98\x02\x29\x73\x2d\xda\x14\x3e\x6b\x2f\x8d\x12\x79\xa4\x67\x61\x1f\xe4\x0a\x5a\xc4\x1a\x65\xfd\x26\x28\xaf\x3f\x5e\xeb\x3d\x5e\xeb\xfd\xcd\xaf\xf5\x58\x44\x5f\x76\x6a\xb9\x4d\x54\xdf\x79\xe6\xb0\x8e\xdc\x17\x5a\xea\x8b\x45\x0c\x67\xf9\x92\xae\xb3\xc3\xc1\x56\x10\xa4\x30\x74\x62\x77\xf3\x23\x50\x4b\xa5\x68\x4a\xc5\x2f\xe6\xf4\xe6\x11\xe1\x2b\xcc\x20\x52\x1e\x82\xa4\x00\x74\x53\xa5\xbb\xfd\xd3\xa7\xf2\xf9\x80\x9d\xcf\x9e\xea\x4a\x22\xb2\x6d\x3e\x65\xd7\x56\x52\x39\x89\x57\xd1\x38\x3d\xdc\x95\x8e\x94\x8b\x23\xe6\x70\xa5\x70\x34\x26\x37\x91\xb1\xb7\xa8\x1a\x5d\x42\x11\xdd\xb7\x79\x4f\x53\xcb\x66\x61\xb3\xc7\xe1\x7f\xea\xbe\xa5\x6f\x4f\x2e\xdd\xa5\xb0\x10\xe4\x81\x88\x00\xe5\x9f\x7e\x02\xdc\xa9\x62\x2a\x8c\x2e\x80\x1b\x57\x15\x88\xfc\xfa\x62\x5e\x4a\x53\x0a\x51\xf6\x52\xbe\x6d\x27\x85\x34\x34\xf2\x53\x68\xe6\x24\x23\x93\xfd\xc3\xe6\xa6\x31\xd0\xfc\xcf\x78\xb1\xba\x4a\x33\xb7\x2b\x24\x05\x4b\x2d\x4b\xa6\x44\x66\x4b\xd2\x0c\xa5\x31\xb5\x73\x9c\x4c\x80\x75\xc3\xd9\xd9\x8f\xae\x33\x72\xe0\xf7\x50\x0f\x0f\x08\x03\xa0\x4b\x9c\x5f\xa1\xc2\x68\x50\x25\xa3\xf6\x17\x0e\x2a\x3f\x58\xb0\xfe\xe9\x27\x64\x1b\xf9\xaa\x51\x1f\x99\xd7\x0d\x04\x55\x8b\x7b\xb4\xb3\xb3\x31\xe5\x9b\x11\x9e\x65\xa8\x7b\xf4\x01\xf5\xaf\xfb\x23\xec\x89\x6e\xc2\xb0\x8b\xcd\x06\x7a\x02\x5d\x66\x36\x4b\x93\x24\xee\x13\x9e\x95\xd2\xd1\x31\x5a\x91\x8e\xc1\x62\x99\xd8\xe6\xc2\xd2\x11\x46\x1a\x7a\xa9\x1b\x0f\xd5\xca\xf4\xcf\x32\xac\x94\x14\x5c\xa2\x99\x64\x0c\xf6\x54\x00\xd0\xcd\xd8\x24\x5d\x6c\xc5\xb4\x83\x72\xa4\xfb\xd5\x2d\xa1\x6e\xbc\x5c\x08\xdf\x0f\xbc\x9c\x4d\xb0\xf7\xb2\x0e\x89\xea\x0c\x80\xb3\x90\x75\xc2\xed\x24\xf7\xad\x69\x39\x9d\xb9\x36\x8b\x4d\xe6\x35\xf9\x0f\xc9\xba\xa6\x7d\x22\x47\x4b\xca\xa9\x25\xca\x85\x97\x96\xa4\x72\x62\xbd\x4a\x27\x7d\xf8\xe0\x07\x81\xb0\xed\x92\xf2\x7e\x8a\xef\xfa\xf4\x48\x07\x07\x89\xc5\x72\xe3\x2d\x78\x2f\xd9\x8a\x53\x81\x4e\x8c\x84\x6c\xe9\x9b\xb7\x5b\x68\xb1\x18\x0e\xf2\x57\xaa\x56\x2a\x67\x41\xa0\x55\xd0\x90\x2f\x85\x84\x3c\x8b\x6e\x89\xd6\x20\x30\xa1\x72\xae\x48\x73\x50\x2d\x18\x6d\xab\x54\x2b\x10\x72\x1b\xb0\x11\x59\x5d\xcd\x76\x41\x64\xdf\xc7\x1c\xa5\x8f\xb2\xef\xdf\x5d\xf6\xcd\x4d\xda\x78\xc2\xde\xfb\xf2\xd1\xdd\xef\xf9\x91\x2a\xed\x86\x3d\x5f\xb8\xde\xe2\x19\x55\x57\x17\xb9\xee\x9e\x8c\xfd\x24\xdb\x61\x05\x73\xb7\x5b\xe7\xd5\x18\xa8\x95\xa0\x59\xde\x17\x4d\xe7\x2d\xbd\x16\x97\x60\x27\x59\x12\x46\x17\x37\xe0\xda\x62\x7b\x4f\xa4\xe5\x9e\x1f\xc9\x9f\x7e\xf1\x47\x53\x7c\x83\x2e\xc9\x7f\xd8\x75\x08\x81\x3c\xc0\x09\x9e\x73\x43\xea\xa9\xe6\x05\x10\xa4\x86\xe1\xa4\x8a\xc5\xd9\xd0\x03\x8c\x88\xb4\xee\xd1\x96\xcc\x2d\x0c\xd4\x6e\x74\x94\x21\xdb\x74\xcf\x8f\x2a\x59\x5c\x65\xaa\x22\xd0\xe1\x90\xcf\x5c\xe5\x53\xb1\x58\x11\x91\x7a\x90\x26\xa2\xf2\x2c\xa4\xea\x1b\x0a\x91\xf9\xe9\x3e\x33\xf5\xc7\x0c\xe2\x76\x98\x10\x59\xcc\xe6\x10\xc3\x7b\x74\x1a\x33\xcf\x5e\xb9\x3b\x50\x9d\x41\xaf\x54\xcd\xae\xf1\xf6\x84\x1c\x03\xdd\xb0\x49\xba\xe0\x22\x21\x3c\xa5\x71\x36\x94\x53\x82\x57\xaa\xd0\x08\xc3\x36\x4a\xb3\x30\x9b\x52\x81\xcb\x34\xff\x0a\xf0\x24\x4e\xc3\x4c\xc6\x92\xc1\x15\xe8\x01\x98\xfe\x28\xc4\x51\xa6\x5b\x62\x94\x6e\xd8\x30\xb1\xe0\xa9\xc6\xcd\x11\x5c\x14\x23\x73\xfc\xb8\x0a\xbe\xf0\x2a\x59\x90\xde\x60\x1a\x05\x60\x13\xd9\xc7\x49\xe6\x87\x62\xfa\x1d\xcb\x47\x4c\xec\x62\xeb\xe8\xc1\x97\x90\xc0\xeb\x16\x6b\x89\x8d\x3c\x99\x4d\x2d\xe3\x97\x24\xdb\x0a\xef\xf5\x2c\xce\x25\x5a\x02\x7a\x83\x36\x20\xd1\xe6\x68\x8a\x37\xe8\x7f\xb8\x98\xab\x25\x7b\x77\xce\x0a\x9b\xfc\x7c\x52\x20\xae\x7d\xd8\x47\x9c\x13\x22\xce\x21\x51\x65\x3c\x4d\x33\xd8\xea\xf0\x18\x47\x99\xa0\x9b\xde\x75\x86\xd3\x66\xa3\xca\x84\xf1\x1f\xaa\xda\x44\xb2\x72\xf7\x3e\x7d\xa9\x31\x7f\xbc\x3a\xa5\x54\x34\x8d\xc2\xff\x9d\x62\x14\x06\x38\xca\xc2\x41\xa8\x72\xe2\x52\x73\xcd\x47\xa7\xc4\x0c\x43\x93\x76\xae\xe9\xc3\xae\x23\xed\x41\x2f\x75\x22\xe0\x63\x5c\xf1\x7b\x61\x75\xc5\xcf\x08\x63\x5d\xe1\xe3\xcb\x41\xff\x71\x57\x22\x30\x64\x55\x3e\x8a\xd6\x20\x08\xe6\x7e\xf8\xe3\x46\x93\x88\xae\x3c\x71\xff\xcd\xb9\xd7\x2e\x95\x2a\x99\x69\x77\xdb\xa5\xf2\xb5\xbd\x94\x95\xf0\x31\x91\x2f\x06\x7e\x3f\x8b\x93\x6b\x8f\x2a\x94\xc9\xc0\x3e\x21\x6c\x9a\x88\xfa\xf1\x00\x89\xde\x6c\x6e\xa2\x1f\x69\x40\xa6\x1f\xa1\xcc\x93\xd5\x55\xd4\x8d\xc7\xe3\x38\xfa\xe7\xc9\xd3\x27\x4f\x8c\xce\xe7\xbf\x58\x03\x1c\xa7\xca\x8f\x64\x18\x12\xfc\x63\xd5\x43\xd2\x2b\x1c\xf5\x97\x7b\x7e\x8a\x3b\x2d\xed\xc3\x38\x68\xeb\x45\x2f\x27\x9f\x83\x81\xf6\xb2\x1f\x4e\x86\x38\x59\xa6\x90\xab\x2f\x9f\x3e\xb9\x79\xfa\x04\x8f\x52\x8c\xa4\xce\x50\x85\x39\xed\x0b\x1f\x86\x1f\xd1\x4f\x3f\xb1\x0f\x2b\xfe\x38\x10\x7d\xdb\x3a\xd8\x7e\xfa\xe4\x09\xfd\x50\x39\xe3\x38\x7b\x48\x45\x15\x9e\x09\x86\xf4\x03\x45\x0c\x7e\xcb\xf8\x9c\x8b\x51\x96\x11\x63\x0d\xd1\x68\x18\xa8\xd2\x4b\xe2\xab\x14\x27\xd5\xa7\x4f\x9e\x88\x11\x8b\xe3\x6c\xa5\x9b\x5c\x4f\xb2\xf8\x9f\x27\xb4\xea\x0d\x9c\x9e\xe4\xed\x47\x7c\x47\x7f\x3c\x7d\xfa\xa4\xa2\x1e\xc7\x9e\x20\xaa\x11\x39\x19\xc6\x49\xd6\x9f\x66\x29\x7d\x43\x96\x4d\x17\x6d\x22\x5e\xf7\xa5\xf4\xfa\xe3\x28\xec\x91\x4f\x2b\xa3\xb0\x27\xbd\x07\x65\x58\x17\x3a\x45\xbe\x92\x52\x2b\xd2\x3b\x05\x82\x3f\xba\x88\x01\x04\xf9\xf1\xf2\xa9\xc0\xe2\x5d\x1c\x7f\x9e\x4e\x50\xe6\xf7\x46\x58\xc2\xe4\xe4\xf5\xe1\x6f\xec\xcc\x27\xde\xed\xbf\xff\xe5\xa3\xed\xfd\xc9\x87\xd7\x1f\x0f\xf6\x7f\xfb\x58\x73\x7d\xa8\xbb\x3e\x34\x5c\x1f\x9a\xd6\xb6\x5d\xed\xc8\x1f\x8d\xb6\xe4\x8f\x46\x7b\xf2\x47\xde\xa6\x18\x9a\x6e\x3c\x9e\x90\x83\xe2\xc8\x1c\x22\xdb\x94\x6a\xb5\x82\x78\xda\x23\x52\x3f\xa9\x95\x17\x00\x16\x2b\x63\x81\x64\x4b\x85\x10\xa2\x09\xa2\x10\xbd\x42\x8d\x76\xe7\x25\x0a\x97\x96\x14\xf0\x42\x46\x44\xaf\x50\xbd\xb1\x6e\x7c\x23\x7f\xc1\x59\x78\x8e\x36\x09\x8c\x57\xa8\xfe\x52\xfd\x4e\xaf\x52\x0b\x6a\x55\x68\xb5\x2a\xfa\x1d\xd5\x66\xf5\x7a\x4f\xaf\x9f\x3f\xde\x3c\x55\x7a\xfd\xab\x3f\xfa\x8c\xde\xec\x56\x1a\xbf\xaf\x57\xd5\xde\xce\x68\x84\x44\xf5\x5d\xa8\xbd\x5c\x68\x04\xa4\x41\x4e\x7b\xf1\x4c\xfd\x08\x86\x06\xa4\xcd\x59\x88\x7e\x47\x95\x59\xde\x21\xf6\xbb\x21\xfd\x6e\x4a\xbf\x5b\x55\xad\xb3\x00\xa5\x92\xce\xd0\xcf\x3f\xff\x8c\xd6\xa1\x64\x3a\x43\x3f\xa1\xda\x6c\x30\xa0\x03\xd4\x69\x6a\x55\xc8\xea\x38\x9b\x91\x81\x4c\x67\xda\x27\xbe\x78\xce\x52\xf8\x3e\x7b\xf9\xd4\xd9\xa9\xf1\x74\x94\x85\x93\x51\xd8\x07\x2d\x81\xd9\xbd\x19\x21\xe3\xe0\x6c\x76\xfe\xd2\xf2\xad\x45\xbf\x35\xac\x1f\xd7\xe9\xc7\xd6\x79\x41\xeb\xe9\xb4\x87\x40\xbe\xf1\xd0\x38\x9c\xa1\x7e\x3c\x9a\x8e\xa3\x54\xa1\x7e\x19\x26\x91\x14\x2a\x01\xf4\xea\x39\xa1\x99\x5a\x9d\x8f\x14\x7b\xac\xd5\x6b\x35\x7d\x68\xc5\x4a\xa6\x83\x55\xc9\x60\x62\x5a\x55\xf4\x95\xfc\xa6\xe3\xed\xa8\x52\x97\xab\xd4\x3b\x52\x95\x7a\xc7\x55\xa7\x21\xd7\x59\xaf\xa2\xbc\x4e\xc3\x98\x75\xc1\x0d\x68\x9d\xac\x60\xa4\xc2\xe8\x52\x1e\x2d\xf2\x58\x7a\xc4\x66\xeb\xd2\xf8\x30\xf2\x6c\xb1\x57\x35\xfe\xa2\xa1\x0c\x69\xe1\x88\x2a\xfc\x91\xd1\x58\x99\x61\x55\x58\xa7\x52\x6f\xce\xd8\x2a\x6c\x55\xa9\x38\x67\x80\x15\x96\xcb\x2a\x16\x8d\x32\x5c\x16\x80\x1e\x18\x27\x26\x27\xfc\x61\x66\x65\x82\x8c\x01\x6c\x2e\xc0\x01\xa1\x4a\x03\xfd\x8e\x82\x33\xf2\xbf\xd9\x3a\xfa\x1d\xcd\x1a\xe7\xe7\xfa\x42\x82\xb2\x21\xfa\x7d\x13\x0a\xce\x42\xa3\x80\xc2\x24\xe1\xe7\x0d\x9c\x69\xc5\xbe\x72\x94\xe0\x3e\xed\x5c\x80\x8e\xfb\x71\xc4\x36\x98\x7c\x57\x3a\xee\x1e\xbe\x27\x7b\x44\x6d\x56\xab\x79\xa8\x36\xab\xd5\xe1\xdf\x06\xfc\xdb\x82\x7f\xd7\x3d\xa0\x05\xf2\x6f\x03\xfe\x6d\xc1\xbf\xeb\xf0\x6f\xbd\x47\xfe\x6d\x76\xf2\xcd\xec\xf9\x73\x86\xd4\x73\xb4\xb5\x73\x42\xe3\xb1\x23\x2a\x0e\x21\x22\x10\x24\x61\x36\x1c\xaf\xf0\x32\xab\x39\x2a\xa4\xf4\x26\x13\x1f\x56\xe8\x83\x24\x61\xac\xe0\x59\x46\xa3\x07\x88\x2e\x7f\x0c\xe2\x63\x9c\xe2\x6c\x03\x39\xb6\x48\x36\x08\x27\x9f\xc3\x09\xb3\xfc\x8d\x07\x28\x3a\x8e\xe1\x34\x36\xf4\x53\xd4\xc3\x38\x02\xef\x00\x76\xbf\xe5\x47\x01\x98\xf0\x05\x61\x80\xa2\x38\x63\x66\x98\x26\x29\xd0\x64\x2e\x1c\x12\x37\x17\xfd\xf8\x19\x5f\x1f\x25\x61\x9c\x1c\x53\x0b\xe0\xcd\xcd\xfc\xbd\x95\x74\xb8\x59\x98\x36\xa7\x66\x07\x54\xf1\x8d\xff\x71\x83\xc3\x4d\x7b\xf3\xf9\x5b\x0b\x7f\xfe\x8c\xaf\x7f\x8d\x13\x30\x62\xfc\x8c\xaf\x57\xae\xc8\x6f\x7b\xb1\x93\xf0\x0b\x66\xa5\xd2\xf0\xe2\x35\x61\x40\x68\x15\xb5\x8a\x96\x91\xf0\x03\x48\x60\x80\x4c\xb0\x7c\xe4\x38\x8e\xf9\x33\x6f\x70\x09\x75\x4a\xb5\x40\xfa\x9f\xf6\x87\x98\x1c\x3f\x10\x11\xa1\x2d\x7d\x48\x8f\xe3\x2b\x02\xbb\xc2\x9b\x59\x22\xbb\xf4\xf3\xc2\x3e\xc8\x70\xed\xc3\xc2\x1b\x95\xc6\x59\x7a\x77\xa6\x2f\xd5\xdc\x44\x94\xa0\x43\x45\x0f\xfa\xf3\x15\xc3\x90\x3d\x5b\xa4\x10\xc4\xc8\x4e\x94\xa7\x83\x64\x2d\x47\xfe\x24\x54\xce\xa0\xce\x39\x1d\x59\x98\x71\xf6\xc6\xc2\x6a\xdc\x0c\x0b\x49\xfb\x89\x01\x1c\xa2\xe9\xe8\x43\x29\xa3\xfd\x03\x43\xfc\x1f\x02\x71\x27\xe6\x6c\x16\x8e\xe3\x0c\x11\x92\x74\x17\xca\xe4\x3d\x40\xdd\x02\x0a\x21\x9f\x4c\x7b\x65\x20\x83\xf8\xc4\x61\x9e\x4b\x7b\x1b\x7c\xc8\x77\x2a\x26\xa3\x9d\x4b\xbb\x98\x5c\x62\x5d\x29\x00\x98\x32\xc8\xec\xf5\x1c\x6c\x0f\xc2\x19\xb0\xed\x22\x6c\x7f\xdf\x04\x26\x7e\xc6\x06\x79\x35\xa7\x8e\xaf\xa8\xc6\x50\xb7\x4c\x36\xca\x27\x1c\x48\x8b\xad\xbb\x9f\x51\x87\xf0\x33\x6d\xc2\xd0\xe6\x26\x6a\xcd\x9b\xb4\xef\x6e\x68\xed\x7d\x76\x8c\xb8\x6b\xcd\x18\xb4\xce\x86\xe4\x1c\xfd\x4e\x64\x09\x73\x11\xcd\xe5\xe6\xb2\x4c\x57\xcc\x66\xc2\xe8\xf2\xad\x85\xd3\x18\xaf\xdd\xcc\x86\x14\xcd\xf9\x8d\x78\xca\x59\x0e\x7f\xe5\xe0\x3a\x32\xc3\x62\x7c\x74\x59\xd4\xb1\x11\x2f\x1c\x19\x79\x33\xff\x28\x20\x1a\x27\x3b\xb9\x5f\xce\xd4\xb2\x82\x9b\x87\xf8\x2b\xd4\x02\x47\x16\xfa\x50\x44\xfb\xea\x5c\x9c\x71\x08\x4c\xd2\x5c\xb0\x23\x05\xc0\x54\xa1\x5b\x5d\x43\x84\x14\x55\xe1\xda\xb1\x94\xce\xd1\xef\xee\xc5\xe9\xf8\x53\x85\x6f\xfb\x0a\xd4\x11\x68\x9e\xa9\x4b\xd1\x3e\x07\x4e\x49\xd6\x93\xa6\x07\x47\xfd\xe4\x7a\x42\x2d\x63\x65\x39\xef\xc0\x43\xf1\x60\x90\xe2\xcc\x98\x19\xba\x46\x82\xb8\x2b\xea\xe5\x85\x3d\x73\xaf\xf6\xf2\x13\x62\xfe\xb3\x9e\xff\x6c\xe4\x3f\x9b\x1e\xb0\x18\xf9\x94\xa1\xe0\x1a\xe0\x45\x71\x25\x5c\xf3\xca\x9f\xa0\x46\x14\x80\xec\xd9\xca\x86\x0e\x21\x86\xd0\xf7\xc1\x19\x05\x43\xe4\x17\x7d\x48\x95\x6f\x6a\xd9\x66\x41\xd9\xa6\xf5\x48\x54\x66\x08\x55\x5a\xf5\x54\x02\x55\x1f\xeb\xea\x63\x43\x7d\x6c\x7a\x42\x61\x61\x6c\xde\xab\xab\x68\x9f\x9c\x7c\xbf\x8b\x31\xb2\x4f\xba\x32\x4c\xd6\x59\xf7\xd0\xdd\xc8\xcd\x46\x34\xec\x40\x50\x5a\xb2\xb6\x0c\xec\x1b\xcc\x62\x85\xc2\x85\x24\x15\xd5\x09\xa6\x16\x1d\x57\x4d\x1a\xac\x73\x78\xfd\xbb\xc2\x6c\x6b\x36\x0d\x50\x5a\xd7\xa7\x43\xab\x65\xcc\x0f\xd4\x6a\xa8\xb5\x1a\x7a\x2d\xab\xb6\x29\x6d\xea\xd3\xa9\xd5\x6a\xda\xd4\x50\x6f\xb5\xb3\x83\xfd\xe8\x2f\x6f\x81\xb6\x13\xc3\xb1\xe5\x8c\x23\xf6\x5f\x3a\xaa\x9b\xa8\xfe\x92\xfd\x7c\xc5\x67\x88\xbd\x70\xec\xbb\x30\xc7\xe1\x20\x03\x4a\xf7\x1c\x8a\xb2\xc2\x89\xe3\xa8\x67\x64\xf2\x24\x75\x4d\x4d\x48\x5e\xbf\x4b\x8a\xae\x4a\x5a\x37\xe4\xae\xdf\x25\xa5\x56\x25\x6d\xe8\x52\xd7\xef\x92\xfe\x2a\x6d\x4a\xaf\x8d\x6d\x78\x69\xc9\xb6\x01\x00\x72\x75\x15\xb9\xba\x03\xb9\xc6\x1c\xe4\x9a\x85\xc8\xd5\x6e\x89\x5c\x43\x45\xae\xe1\x40\xae\x39\x07\xb9\x5a\x21\x72\xf5\x5b\x22\xd7\x54\x91\x6b\x3a\x90\xab\xcd\x41\xae\x5e\x88\x5c\x63\x2e\x72\x56\xd2\xfd\x30\x01\x1b\xa2\x34\xf3\x33\x6c\x16\x00\x76\x92\xd5\x2c\x1d\x03\x96\x91\xe9\x7a\x34\xf8\x42\xe6\x22\x6b\xd8\xbe\x90\x81\xc8\x74\xed\xb8\x55\x89\x62\x5d\x4f\x73\x78\x1f\x2c\x9f\x0a\x3d\x79\x48\x6b\x47\x3f\xb5\x58\x96\x8f\x7e\x6c\x31\x57\x90\x72\x6e\xc9\x97\x50\xb5\x1c\x25\x88\xf5\xc3\xb1\xab\xbb\xb1\x33\xd7\x8f\x81\x9d\xb1\x84\x54\xec\x6a\xb7\xc1\xae\x21\x61\xd7\x70\x63\x67\x2e\x20\x03\x3b\x63\x0d\xa9\xd8\xd5\x6f\x83\x5d\x53\xc2\xae\xe9\xc6\xce\x5c\x41\x06\x76\xc6\x22\x52\xb1\x6b\xcc\xc7\xce\xa4\x56\xcc\x03\x5b\xdb\xe5\x12\xba\x0d\x5b\xd6\x91\x2e\xe4\x18\xcb\x49\xdd\x5c\x2d\xab\xca\x10\x7d\x9a\x2e\xd9\x87\x1d\x85\x37\x50\xa3\xdd\x59\x6d\x36\x98\x06\xba\x6a\x53\x05\x73\x89\x45\x08\x48\x29\x73\x1c\x66\xaa\xe1\x67\x29\xcb\xf7\x84\x20\x85\xf7\xc0\xef\x63\xa1\x23\x16\x40\xfe\x1b\xcf\xfc\xf1\x44\x9c\x94\xf3\x0f\x7c\x4e\x29\xac\x0c\xcf\x32\xe9\x76\x7b\x65\x6b\xe7\x64\x85\x9d\x23\x2a\x63\x6e\x91\xfe\x19\x5f\x7b\xa8\x3f\xb8\x10\xd2\x7c\x0e\x65\x32\xf2\x09\x12\xb3\x0c\xe9\x50\x98\x84\x5f\xc9\xdb\xb1\x01\x62\x3a\xed\xae\x45\x89\xfd\x91\x46\x4d\xdd\xc3\xa3\x09\x4e\x2a\x5b\x3b\xf4\x5a\x9f\xea\xec\x9f\x3e\x61\x36\x2b\x72\x93\x2f\x9f\x3e\x85\x08\xb8\x60\x40\xa2\x58\x15\x6c\xb4\x1b\x1e\xb7\x4b\xd8\x68\x83\xed\x88\x64\x99\xb0\xd1\x6e\x79\xb9\x49\xc2\x46\x1b\x5c\x18\xc7\x41\xfb\xc7\x8d\x4e\xfd\xe6\xdc\x6b\x37\xee\x64\x2d\xf2\x2d\xcd\x44\x1e\xcc\x98\xe3\x1b\x9a\x65\xd0\x95\xf0\x1c\x31\x03\x0a\xd2\x3c\xea\xc7\xe3\x49\x1c\x41\xc8\x75\xf2\x6d\xf5\xe9\x13\x31\xef\xa3\xb0\xb7\xc2\x8a\x7e\xfd\x2a\x1b\x00\x08\xa7\xcf\x7b\x36\xee\xf0\x53\x9c\x5b\x75\xf8\x29\x96\xbe\xfd\x1a\x27\x01\xb8\xa5\x8b\x02\xe2\x8d\x0c\x61\x3a\x00\x7b\x31\xa0\xf5\x2d\x7e\xcb\x93\xc3\xb4\x7e\x56\x30\xc3\xe0\x59\xd5\x25\x0b\x55\x7a\xff\x21\x1b\xac\x03\x14\x1c\xf5\x57\xc8\x83\x86\x75\xa7\x25\xbe\xd2\xc7\x22\x43\x14\xf1\x65\xe7\x72\xf2\x76\x7b\x37\xbf\x6c\xa2\xcf\xd6\x1b\xac\x5e\x4a\xcd\xf3\xc8\xb2\xe2\xb7\x58\x19\x1e\x4f\x46\x7e\x66\x63\x50\x22\xc8\xf4\x1f\x11\x0b\xc8\xc3\x35\xa8\xe0\x54\x20\x78\x1d\xe8\xfd\xc2\x2f\x78\x85\x07\x98\xdc\x40\x2d\x54\xa9\x37\xd6\x51\x2f\xcc\xd2\x6a\x11\xc0\xf0\xd2\x02\x6f\xff\x97\xdb\x82\xfb\xb8\xf3\xbe\xfb\xf1\xb7\xdd\xc3\xe3\x83\x8f\x07\x87\xdb\x3b\x68\x0b\x42\x1b\x64\x7e\x94\xa1\x04\x4f\x12\x9c\xe2\x28\x0b\xa3\x0b\xae\x88\x21\x64\x38\x8e\x83\xbc\xef\x56\x98\xdb\x3b\xa5\x60\x32\x76\x6a\xc0\x94\x2e\x05\x35\x93\x23\xf1\x68\xa7\x28\xcb\x25\x61\x3e\x9b\x14\xdd\x2e\xb8\x7d\x4f\x13\x30\x78\x10\x39\x3e\xe4\x22\x4a\x71\xa9\x77\x82\xee\xc9\x1c\xa0\xd3\x21\x26\xa3\x9e\xc5\x68\xca\xdc\x04\x08\x0b\x40\xa4\x30\x80\x56\x40\xae\xe6\x0f\xfd\xc1\xc5\x06\x90\x2e\xc7\xb5\x2a\xef\xa8\x06\xb6\xb0\x5d\xa4\x14\x36\x23\xbf\x30\x72\x4d\x86\x0d\x7d\x6a\x8f\x29\xe1\x4e\x48\x8f\x20\xff\x19\x5f\xaf\x58\xcb\x72\xcf\xd0\xfe\xe0\x02\x55\x0e\xa1\x15\x7f\x54\x85\x3a\x7d\xdb\xe0\x95\x1c\x03\xb5\x2d\x1e\x47\x94\x4e\xe8\x0d\x21\x11\xde\x3b\x42\x28\xfd\xa2\x3e\x91\x73\x45\xd8\x77\x7f\x57\xa5\x04\xb3\x00\x52\xa4\x05\x79\x8f\xe7\x57\xcf\x2b\x74\x9b\xde\xa1\xc3\x1c\x27\x15\x76\x79\x06\x43\xe8\xa1\x3f\x50\x78\xb9\x81\xc2\xcb\x9c\x37\xde\x28\xa6\x07\xca\x7c\xab\x90\x36\x94\xb0\x50\x4c\x72\xd0\x35\x00\x72\xe2\x10\x5a\x9f\xdd\x38\xab\x6b\xd5\x22\x7b\xe8\x12\x5a\x49\x7a\x72\x2c\xc4\x47\x7a\xba\x5f\x7a\xda\xc6\xf7\x45\x4f\x02\xd2\xdd\xe8\x49\xe5\xd3\xb7\xa0\xa7\xfd\x28\xcc\x42\x7f\x14\x7e\xc1\x29\xf2\x51\x84\xaf\x46\xd7\x0c\xc3\x80\x0d\xc7\x7c\x5a\xe2\xbb\xc6\x6c\x10\x27\xe3\x83\x38\xc0\x68\x87\xfa\xaa\x41\x98\xe6\x9c\xd3\xc5\x89\x4c\xa7\x60\x5d\x0d\x6e\x7e\x9c\x6a\xc5\x26\x63\x27\xc3\xef\x8e\x64\xef\x8d\xac\x2a\xe6\x07\x1b\xa7\xb8\x25\xc1\x85\x51\xa8\x58\xd8\x88\x69\x92\xc8\xc5\xa2\xa2\xde\x9a\x4c\x08\x2d\xc0\x68\xf1\x6c\xd3\xa9\xe5\x9a\x81\x0c\xf1\xa6\xf8\xc9\x37\x45\x4a\x83\xe6\xa9\x38\x23\x92\x33\x35\xac\x8f\x93\x31\x9d\x76\xdf\xa6\xbb\xa1\xf4\x9d\x93\xd4\x66\x4e\x5e\x2f\x6d\x25\xa9\x1d\x0d\xd8\xca\x58\xcf\xe2\x21\x25\x74\xea\x01\x60\xeb\x07\xd8\x17\x55\x4a\x2f\x1c\xb0\xd1\x51\xf9\x30\xc4\x72\x48\x45\x4b\xa0\x3d\xbb\x23\xf9\xb0\x25\x68\xe2\xa6\xcc\x70\x52\xc6\x88\x8a\x1a\x15\x05\x7e\xe6\xa3\x1e\xc8\x5e\x6a\x09\x87\x3c\x06\xa0\x69\xa6\x0b\xee\xed\xac\x03\x3e\xc2\x09\xcc\x65\x3f\x8e\xfa\x09\xce\xf0\x32\x1b\x8e\x51\x7c\xa1\x30\x65\xe9\x5e\xea\x78\xb1\xb1\x86\x78\x1a\x80\x39\x75\x6f\x61\x3c\x05\x07\x12\x4b\xc1\xc1\x02\x9b\xde\xd7\x94\xb9\xc2\x10\xa0\x4c\xd9\x49\x78\x03\x6f\x83\x35\x20\x81\x2f\xb1\x73\x49\xfc\x49\xc0\xa2\x41\xb3\x58\x30\x82\x30\xba\xb8\x07\x6e\x92\x77\x7e\x93\x93\x07\x83\x5f\x79\x46\xda\x7c\xa6\x92\x49\x99\x7a\x57\x1c\x73\x27\x85\xb1\x92\x1b\x5a\x94\x57\x3a\x74\x0e\xee\x81\xa3\xc0\x36\xfb\x3e\x7c\x91\xab\xdb\x68\x8a\xb6\x87\xfc\x4b\x3f\x1c\xf9\xbd\x11\xa6\x66\x88\xa9\x7b\x5b\xfc\xc8\x3b\x53\x9a\xaa\x76\xc3\x88\x6d\x7c\x85\xfb\x14\x83\xab\xee\x33\xef\xe3\x8c\x79\x47\xd3\xa0\x69\x14\x52\xbe\x6b\xa0\x30\x45\x78\x30\xc0\xfd\x2c\xbc\xc4\xa3\x6b\xe4\xa3\x00\xa7\x59\x32\x85\x67\x0f\x25\xd8\x0f\x96\xe3\xa8\x8f\x4b\xed\x33\x65\xa9\x17\xd0\x78\x28\x1a\xa6\xc0\x1f\x9a\x92\xf9\x48\x56\xca\x13\xb1\xa8\xb2\x28\xf5\x8b\x8a\xf3\xc9\x9f\x17\x2d\x4f\xff\xbb\xf9\x5c\x4c\xa1\x90\x5a\x22\x1c\x14\x02\x40\x85\xab\x45\x29\x6a\xb9\x28\x59\x80\x21\x43\x3c\x24\x82\x2a\x5b\x70\x38\x60\xf1\x32\x39\xa7\xde\x95\x26\xc4\xba\xf8\xcc\xda\x73\x95\xcd\xf5\xc6\xfa\x6a\xb3\x21\x7f\xa2\x2a\x11\xdb\x17\x4d\x0e\xda\x40\x75\xe5\xab\x2a\xff\x6e\xa0\x46\x99\xb3\x53\x6a\x55\x65\xfb\xf3\x15\xd9\xc8\xb9\x36\xf9\xa9\x85\x8d\xf4\xe9\x10\x4b\x42\x01\x4b\xb4\xe5\xa3\x21\x68\x8d\x89\x90\x59\x62\x29\x72\x11\x76\x2b\xe2\xf8\x40\x80\x01\xbe\xac\x89\xd0\xc4\xd6\xb5\xa5\x43\xdf\xe0\xb0\xc4\xac\xbd\x4d\x95\xa7\xa6\x23\x37\x64\x5b\xe7\x2a\x53\xea\x6d\x38\xfd\xa6\xc8\x9f\xf8\x94\xe2\x11\xee\x67\xb4\xe1\x93\x2c\xf1\x33\x7c\x71\x5d\x71\x99\x6b\x4b\xda\x67\x10\x17\x37\xd1\x33\xca\x4a\x9f\x39\xcd\xc3\xd8\x6c\x1c\xf9\x69\x4a\xd8\xc4\x6b\x3f\xc5\x81\xe2\x31\x27\xff\x15\x1b\x87\x31\x50\x27\x38\x81\x03\x17\xd9\xd5\xdc\x90\x8a\x17\xb9\x9e\xdb\x8f\xdd\x67\x14\xd8\xa8\xbb\x90\x62\xe4\x24\x33\x36\xf3\x86\xa5\xc8\x6e\x34\x0f\x02\x66\x9f\x07\x71\x71\x43\x51\xf4\x90\xfb\x02\x47\x1f\x03\xcf\x61\xe9\xc9\xc8\x7e\xc3\xe8\xbf\x76\x9f\x73\x27\xb4\xd5\x9b\x22\x0f\x15\xde\x18\xe9\x98\x5b\x26\x54\x67\xdb\x32\x97\xac\x54\x99\x86\xd7\x7e\xf5\xa6\xea\xb0\xd3\x2c\xc1\xfe\xf8\x56\xaa\x6c\x90\xa1\x98\xf2\x59\xb6\xc1\x6f\x36\x96\x7b\x21\x35\xd8\x56\x4f\x34\x54\x3a\x81\x30\xd6\x92\x66\xba\x8e\x2a\xcd\x86\xaa\x98\x96\x14\xbe\x27\x80\x9f\xa6\xf6\xd5\x5f\x16\x78\x84\xec\x5a\xf6\x5a\xdb\x0e\xcb\x45\xc4\x89\x9f\xc0\x71\xcb\x26\x20\x9a\xdb\x1b\x1c\x6f\x72\xeb\x2a\x2e\x34\xfe\xf0\xc3\xb3\xc1\x68\x9a\x0e\x9f\x95\xdb\xe6\x28\x14\xd7\x46\x27\x86\x79\x03\xd5\x8b\xe6\x15\xce\xb5\x90\xd5\x74\x22\xdf\x96\xca\xca\xf3\x8f\x63\x7a\xf6\xed\xae\xb0\x1f\x7f\xdc\xcc\xa7\x10\xc5\x63\x07\xea\x19\x54\x22\xb5\x21\xdd\x6e\xb2\x83\xb6\xe1\x1c\xcc\xde\xcb\x4a\xef\x22\x05\xbd\xac\xa2\x1c\xf3\xe4\x5c\xb9\x7c\xbd\xf0\x6e\xba\xa5\xf6\xc8\xaa\x10\xd4\x33\xcb\xe4\x0a\x7e\xa0\xea\x6f\xb0\x1f\xf2\x99\xe2\xdb\x1d\xe8\x61\xbb\xaf\xbb\x86\x2a\x9a\x73\x94\xf0\x92\x7a\xed\xdc\x46\xf3\x9c\xc3\x28\xd4\x15\x8a\xba\x5c\xd1\x24\xd5\xbb\x95\xc6\x59\x4c\x67\x7e\x40\xfa\xcf\x9c\xce\x5c\x13\xbc\xe0\x74\x5a\x15\xbf\x25\xa7\x53\xd4\xbd\xc3\x74\x16\x29\x7c\xcb\x5d\x1d\x7c\xd3\xe9\xbc\xf3\x74\x15\x2c\x81\x39\xf3\xa5\xeb\x4d\x0b\x26\x89\x6e\x26\x42\xcf\xdb\xb7\x89\x75\xcc\xea\xfa\x12\x6d\xa2\xf0\x52\x9e\xad\xa2\x2d\x82\xed\x98\x34\xae\x74\x77\xe8\x87\x11\xa4\x3c\x71\xdd\xb5\xbe\x06\xbb\x81\x8f\xbc\xf3\x68\xd3\x1d\x7c\x40\x57\xb1\x29\x3b\x08\xa9\x6b\x10\x83\x34\x34\x79\x63\xda\x2e\x21\xee\x44\x5f\x16\x71\x94\xd7\x5d\xbe\x1d\x68\x27\x21\xa9\x09\x65\xee\x48\xaf\x5e\x77\x2d\x7b\x8f\x09\x9e\x36\x71\x24\xc2\x7f\x66\x5c\x8d\x41\xa9\xd4\xcf\x98\x51\xf7\x8a\x5e\xc7\x80\xa1\xd1\x2c\x95\x8e\x84\x56\x84\x09\x4b\x31\x97\x91\x90\xca\x09\x91\xf5\x86\x84\xd9\x65\x11\x20\xec\xe7\xd5\x10\xb3\xc8\xfb\x14\x3f\x08\xe4\x99\x96\x40\xce\x5c\x18\xf6\x82\xe4\x0f\xa6\x92\x89\x3a\xd4\x1b\x00\xd2\xe3\x41\x17\x84\x6b\x83\x2e\xcb\xca\x93\x81\x72\x15\xa0\x61\x26\xaf\x42\x71\xda\x42\x5b\x1d\x60\x91\x7e\x43\x22\x2f\x24\x87\xe1\x6c\x2e\xc4\x0a\x4d\x8e\x78\xe5\x30\x67\xfd\xed\xf0\x18\xce\xcb\x8c\xe8\xcc\x32\xb3\x38\x81\x7e\xe5\x8a\x6e\x0f\x29\xfd\xf2\xf2\x66\x6d\x42\x3f\xc3\x43\xf6\x75\xa9\xe8\xa3\x6b\xc5\xec\x18\x8f\x31\x48\xe1\xb0\xbb\x52\x12\x60\x57\x51\x70\xda\x07\x87\x76\x78\x6d\x56\xe7\x12\x2c\xbe\xe4\x61\xe7\x29\x33\xa5\xf9\xe4\x39\xde\xc2\x14\xd0\xd9\x01\xd9\x73\x67\xee\xba\x0d\x70\x89\x75\x2b\xf6\xa9\xc7\x75\xfb\xb8\x6e\xd1\xed\xd7\xed\x5d\x56\x07\x58\x08\x0f\xc3\x74\xe1\xb5\x61\xc5\x84\x51\x34\x70\x91\xdf\x0e\x8f\x9d\x1c\x40\xf6\x20\x33\x38\xc0\x5d\xd9\x8e\x15\xb3\xd3\x7c\x68\x7a\xb8\x1f\x8f\xd9\xd2\x21\x6c\x21\x8c\xa7\x69\x79\xe6\x21\x06\xab\x2c\x7b\x10\xa4\xc4\xbb\x51\x71\xe2\xbe\x90\x07\x14\x88\x48\x5c\x5a\xb2\x79\xf8\x0f\xe3\x38\xc5\x68\x1c\xce\x88\x2c\x64\xe9\x1f\x78\x82\x9a\x42\x1a\x92\x09\x91\x49\x61\x2e\xb2\x8b\x2f\x41\x3a\x25\x27\x9d\x74\xda\x4b\xf1\xff\x4e\x71\x94\x59\x55\x0c\x48\x15\xed\xa4\xac\x1e\xea\x28\x3a\x55\x83\x32\x4a\xda\xac\xcc\x57\xf5\x93\x9d\xcd\x86\x95\x2d\x46\x52\xbe\xda\xac\x91\x92\xc8\x1f\x4c\x60\x6e\x3d\x1e\x9e\xa3\xdf\x37\x69\xbd\xb3\xb0\x30\x74\x49\xfe\x9b\x9b\x40\xbf\xee\xb2\xf2\x4a\x40\x13\x49\xb4\x3d\xf2\x83\x80\x4c\xe0\x1c\x05\xc8\x04\xb2\x5c\x75\x57\xe8\x7f\xed\xea\x8f\xa3\xb7\xdd\x13\xf4\x7f\xda\xab\x6b\x68\xc2\x80\xa6\x4c\x97\x67\x83\x79\xf4\xb9\x9f\xae\x81\x9c\x3c\xf1\x83\x15\xfe\x54\x20\x1b\x1f\xf9\xfc\xfa\x79\x9a\xf2\xd0\xf9\x22\x10\x0a\x33\x57\x86\xb8\xc9\x02\x8f\x85\xec\xaf\x00\xb2\x7c\xfb\x4c\xd0\xb2\x56\xb2\xeb\xf1\x58\x08\x28\xe9\x3e\x12\x00\xa5\x22\x98\x25\x19\x14\x08\x67\xf9\xc0\xc7\x66\x71\xf8\x12\xe3\x4a\x7e\xe5\xd7\x6b\x9e\x16\x37\x4b\xb9\x60\xf6\x03\xfd\x72\xed\xd6\x0c\x44\x54\xa3\xb1\x4e\x36\xa5\xf1\x72\xc5\x0c\x99\x46\x99\xa0\x1d\xf0\x2b\x32\xa1\x46\x8c\x60\x0d\xa0\xf4\xc5\x32\x4d\x39\x2d\x22\xac\xfc\x43\x2b\x60\x6b\x96\xde\x0b\xf1\x76\xcd\xd0\x0b\x34\xd3\x1b\x7c\x25\xf4\x02\x11\x50\x14\x2c\x72\x5f\x17\xe3\x3d\x73\x70\x31\xde\x83\x5b\x8b\xf2\x76\x2e\x66\x85\x48\xa5\xc5\xe1\x0b\x72\xf6\xa3\xb6\x89\x42\xb4\xe4\x72\xcb\x97\xa1\xd3\x30\xf7\xd2\x9b\x02\xe9\x55\xc3\x0e\x6d\xe6\xb6\xef\xfc\xf0\x2f\x83\xf6\x54\x94\x6c\x66\x08\x5b\x41\x60\x1f\x04\x98\xeb\x7e\x1c\xf5\xfd\x8c\xc3\x2c\xad\x81\xf9\x10\x4d\x04\x43\x81\x25\x3b\xf4\x03\x1a\xc8\x88\x2d\xd4\x6f\xc3\x65\xa6\x91\xce\x67\xbe\x09\x47\x80\x66\x4b\x5c\xb9\x43\x39\x9d\x25\xd8\xf8\xc0\x1b\x9c\x29\x89\x8b\xa5\x45\x0c\x31\x60\xd1\xc8\x4f\x33\x78\x9e\xbf\xa6\x73\xf1\xfa\xac\xa2\x2e\xe7\x65\x54\xaf\x52\x17\xb3\x73\xe6\x0c\x66\xf3\x24\xa6\x82\x83\x9b\x62\x72\x70\x9b\xfa\x1a\x94\x36\x53\xba\x6d\x2e\xa8\xe7\xff\x33\x2e\x82\x6c\x2e\x0a\xf6\x9b\x05\xdb\xad\x42\xd1\x3d\xd0\xfd\x19\xfd\x1f\xc4\x01\xbe\xa1\xea\xc1\x53\x71\x5a\xa3\x97\x22\x70\x92\x90\xba\xd3\x7d\xdd\x75\x41\x61\x73\x75\x23\xe8\x8b\xc0\xd2\x85\x0d\x13\x22\x90\xbc\x83\xc0\xc1\x8f\x80\x0d\x80\x64\x38\xa9\x11\x38\xc1\x14\x30\xf3\xb4\x53\x1d\x6d\xdb\x68\xe2\x46\xf1\x46\x58\xc0\x30\x90\x4e\xb4\xfa\xb1\x2b\x59\x1f\x16\xdb\x00\x16\x04\x38\x53\xed\x43\x2d\x7e\x9c\x20\x37\x93\x11\x50\xd4\xa2\x48\x55\xec\x92\xef\x63\xb0\xfd\x74\xe0\x9f\x4f\xac\x79\x18\x30\x6c\x49\xb9\xa4\xad\x1a\x97\x38\x4f\x0c\x04\x2a\x6c\x89\xa0\xd1\x80\x53\xb9\x76\x37\x63\x97\xf6\x57\x9f\x17\x37\xaf\x5a\xaf\x54\xd1\xf3\xd5\x85\x31\x10\xaa\x16\xc7\x59\xe6\x2d\xc6\x13\xe4\x67\x68\x84\x09\x17\x8c\x23\xbe\x02\x58\x96\x0f\x6a\x09\x0a\xfb\x35\x30\x5c\x93\x6f\x21\x71\xbe\x19\x87\x11\x35\x12\x65\x87\x78\x23\x5c\xa2\xfa\xc8\x2a\xd1\xe9\x93\xf0\xa7\x84\x34\x06\xfb\x63\x7a\xe4\x0d\x2f\xd1\x4f\x3f\x59\xf5\xf1\x7a\xa0\x8e\xa3\x5b\xe9\x32\x72\x4c\x54\x65\x8a\xf3\x7c\xae\x37\x5b\xf6\x4a\xda\x2d\x92\xe6\x22\x89\x30\x94\x66\xaf\x2c\x04\xcd\x9b\xbb\x5f\x42\x5e\x5d\x25\x07\x19\x9a\xee\xcb\x25\x72\x81\xbc\xce\x4c\xbf\x40\x02\x87\xdf\x73\x75\x10\xfc\x2a\x9e\xda\x08\xba\x4e\xc9\xb7\xba\x8c\x7f\xb8\x65\xf5\xb0\x78\x5b\xdb\x03\xc9\x6f\xce\x0c\x50\xf9\xc8\xd6\xde\x3c\xcb\xbf\x3b\x5a\x2a\x80\xe9\x1d\x93\x3d\xec\x66\x28\xa8\x1f\x8f\x46\x98\xd2\x7f\x3c\xe0\xa2\x01\x88\x9a\x18\x72\xe9\x15\x89\x1e\x92\x28\x2a\x39\x79\x93\x6d\x34\xf1\xaf\xa4\x57\x56\xbf\x44\xbb\xeb\x07\x75\x40\x17\x42\x4a\x99\xda\xf9\xc5\x23\x64\x78\x60\x5c\x90\xd6\x27\xeb\xd3\x30\xc7\x75\x01\x4a\xfd\x11\xc5\x1e\x7e\x00\x30\x50\x49\xfa\x34\xfc\x28\x4e\xc2\x4b\x2a\xab\x70\x8e\x61\x05\xc8\xaf\x52\x73\x39\x5f\xb2\x1c\x34\x63\xad\x96\x93\x6b\x6e\xd3\xb3\x62\xf9\xa6\x3f\xc4\xe3\xdb\xc1\xb5\x0b\x9c\x4c\x65\x0e\x16\xd3\x03\x09\x9e\x15\x04\xcd\xc9\x78\x93\xe7\x6c\xa4\xa7\x18\x2a\x62\xf1\xb7\xba\x18\xd6\x8f\xa3\x4b\x9c\x64\x8a\x0c\x4b\xb3\xdd\x71\x63\x4a\xb0\xf8\xa4\xd6\x7f\x6e\xb7\xd5\x23\x5a\x45\x75\x5e\x15\x2f\x4b\xda\xc3\xcc\x77\xb1\x52\x51\x9b\x7f\xac\x13\xde\x4d\x32\x3e\x9a\x9d\xa8\x1f\x89\x24\x56\x93\x38\x4d\xc3\xde\x08\xbb\x57\xac\xa5\xa9\xc5\x9c\x9b\xf2\x81\x32\xed\x41\xe9\x37\x7e\x02\xff\xc3\x80\x82\x84\xfa\x9c\xac\xe0\x0d\xe9\x77\xee\xf0\x64\xad\xf4\x19\x5f\x6f\xa8\x7e\x51\xd6\x62\x9a\xa7\x94\xbd\x10\x59\xc6\x1b\xf0\xef\x9c\x82\x62\x55\x6e\x98\xee\x5c\xf6\x1a\x4c\x84\xd7\x2d\x13\xec\x85\x85\x5c\xaf\x1e\x9d\xdf\x76\x4f\xd6\xec\x15\x24\x16\xde\xb2\x97\x10\x0b\x47\x02\x4a\xdf\xad\x1c\x4e\x70\x74\x72\xf2\xce\xa8\x56\xde\x99\x4c\x9e\x7e\xbb\xe0\x35\x0e\x67\xfb\x91\x5a\xae\xb4\xe9\x11\x5d\xc5\xe9\x62\xcb\x18\x39\xd7\x8d\xc9\x4a\x34\xdf\x40\x07\x37\x21\x87\x3a\x37\x70\x6e\x60\xcb\xbd\x32\x60\x57\x80\xdf\xe1\x20\xd4\xd7\x78\x01\x1c\x48\x02\x96\xd2\x0c\x60\x90\x3d\x0e\xe7\x5e\x94\x39\xc6\x51\x4c\xdf\x68\x0c\x90\xe5\xec\xc7\x45\xdc\xa3\xec\x92\xa6\xc8\x8b\x6b\x3a\xb6\xb6\x97\xd0\xb3\x67\x76\xdf\x0a\x6b\xf9\x95\x2c\xa6\xf9\x86\x5c\xae\x1c\x73\x6a\x39\x48\xd5\x49\x98\xbc\xa2\x4c\x9c\x62\x6c\x5c\x56\x55\x79\x09\xf4\xf5\x2b\x25\xd7\xbc\xce\x0a\x9f\xc4\x6b\x7e\xec\x35\x74\x34\x56\x39\x89\x52\xd9\xbc\x7b\x0d\xda\x0e\x5c\x6d\x88\x9f\xf6\xdb\x0d\xd6\x73\x1b\x71\xda\x40\xb3\xe2\x22\x95\x31\xec\x5e\xea\x20\x16\x5f\x77\x88\x55\xe7\xbb\x97\x5c\xc4\x9b\x59\xee\xc7\xe3\x89\x9f\xc1\xf6\x52\x76\x19\xca\xdb\x82\xb6\x89\x49\xe2\x4f\xd9\x3d\xd1\xb6\xfc\x6e\x83\xdc\x7d\x19\x0e\xc6\xb4\xed\x13\x4e\xde\x0e\x42\x96\xa8\xcb\xc5\x1b\x15\xfa\x16\xc5\x4b\x73\xdf\x39\x6a\x19\x39\xd2\x92\xb2\x04\xf3\x2f\xb6\x40\x8d\x44\xdc\xd5\x2a\x90\x77\xb6\x63\x2c\xf4\xd7\x3c\xc4\x92\xe2\x4e\x55\xcb\x95\x14\xad\xc6\xd0\xde\x9f\xd5\x66\xed\x66\xa7\xde\xe9\xaf\x41\x62\x83\x4e\xbb\xd3\x6a\x0f\xda\x83\xf3\x2a\x57\xc5\x03\x68\xfe\x90\xf7\xc3\x71\x8e\x2c\x81\x82\x73\x2c\x1c\x87\x2f\x51\x37\x67\x64\x34\xac\xcd\xe2\x7b\x5e\xd1\x1a\x93\xfd\x95\x16\x15\x1e\xf9\x3a\xc9\xe9\xf4\xd6\x4b\x46\x8d\xd9\xc0\x17\xf4\x2d\xd6\xf0\xfd\x06\x70\x30\x85\x51\x6d\xe9\x4d\xfc\x24\xc5\x15\x65\xa1\x16\x5c\x4c\x26\xa9\xa2\xf8\xc9\xab\x59\xbd\x12\x48\x71\x44\x63\x78\xcd\x59\x74\x94\x30\x0c\x64\x8a\xd4\xab\x45\x10\xf9\x65\x9c\x74\x18\x66\x49\x21\x0c\x70\xa7\x38\xcd\xa8\x6d\x83\x3f\xb2\x2c\x50\x0d\xe6\x59\xed\x1c\x6d\x6e\xa2\x7c\xed\xa1\x9f\x7e\xd2\xdb\x3d\xab\xb3\x32\x7c\x4d\xba\x54\x50\x3b\x33\x7a\x81\x61\xb6\x8c\x54\x0e\x63\x2c\x7e\xad\x45\x66\xca\xd3\xf0\x50\xab\x5a\x60\x5d\x17\x5f\xb2\x23\x3a\x5c\x05\xe5\x30\xcc\xf2\x06\xfc\x09\x34\x50\xd3\x6f\xad\x8d\xe2\xca\xad\x4e\xbd\x53\x8e\x51\x58\x8f\x46\x8e\x63\x90\x27\x9d\x4e\x54\xd1\xbc\xf0\xae\x88\x2f\xc2\xab\xc4\x9f\x4c\x40\x8e\xf4\x33\xd6\xbc\xac\x32\x41\x3e\xd9\xe9\x53\xc9\x2b\xad\x70\xf5\x2a\xae\x3e\x86\x2b\x5b\xee\xf0\x63\xfb\x54\xd6\x81\xe4\xd6\x97\x3d\x42\xe8\xe1\x32\x7e\x91\x54\xcf\x75\x04\x72\x6f\x59\x67\xa9\x43\x68\x14\x50\xaa\x11\x07\x8c\xfc\x62\xc7\x72\x70\x2a\x0a\x11\xa5\x7b\x2f\x02\x42\x1b\x86\xa8\x26\x4d\x6c\x61\x50\x29\x76\xed\x40\xe6\x8d\x79\xd3\xdd\xc5\x43\x35\x57\x3e\x59\x8e\x3a\x05\xde\xe7\xac\x69\x6a\x83\xc2\x7e\xe7\x7e\xe7\x7f\x91\x18\x2e\xf6\x2d\x6c\xeb\xcf\xdd\xc0\xc8\xb2\xb4\x6b\x54\xcc\x65\x25\xfc\x2b\x4d\x6d\x84\xe2\x6a\xe9\x38\x85\x3d\x5c\x83\x79\x90\x1a\x5d\x9d\xf0\x4d\x1b\xf7\xc4\x6a\x73\x48\x03\x05\xca\x0e\x8b\x73\xac\xdb\x8b\xf5\x76\x21\x74\x16\x8a\x9e\xb3\x63\xb3\x5f\x97\xa2\x1b\xc4\xb9\xf3\x89\x2d\x00\x9a\xd5\x67\xd5\x10\x4b\x72\xcf\x0c\x11\x20\x81\x75\xf6\x36\x92\x49\x17\xfa\x97\xc3\x84\x2b\x60\x03\x0a\xb3\x37\x22\x1c\x57\x38\xe6\xba\xf6\xa3\xf2\xdb\x69\xd1\xa6\xad\xec\xaf\x66\x41\xae\x5a\xb4\x7c\x22\x64\x25\xfa\xb6\x12\x5e\x5a\x8a\x48\x3a\x42\x46\x2f\x66\x19\xaa\x15\xcc\x01\xc1\x85\xa8\x59\x4c\xe8\x03\xf3\x92\xec\x95\xa5\xb0\xa4\x0b\xd4\x2d\xac\x2d\xa5\x25\xbd\x20\x21\xbd\x81\xe5\xb8\x76\x53\xfa\xd8\xc2\xee\xa1\x53\x31\x71\x42\xf1\x25\x5f\xcb\xa0\x07\xdb\x9e\x64\x02\x10\x3b\x94\x76\xd1\x24\x3d\x42\x6a\xef\xbf\xe2\x3e\xa5\x05\x68\x11\x91\x8e\xbf\xc1\xde\x94\x47\x55\x9e\xcf\xa6\xb9\xf7\xbc\x85\x4d\x73\xb2\x63\x61\x14\x24\x8f\xfa\x5b\xb3\xec\xfb\x46\x51\xdf\x97\xee\x71\x4b\x71\xc6\x2e\x70\x44\x18\xf8\x06\xbb\x0a\xd3\x38\x48\xaa\x05\x79\x31\x69\x80\xe5\x9d\x82\xdd\x7e\xc3\xf9\x55\x46\x3e\xe7\x26\xb6\xe6\x18\xa7\x30\x37\x0c\x79\xf2\x94\x4d\x4c\x89\xba\x48\x87\x25\xdf\x9b\x24\x26\xa3\x28\x7c\xac\xdb\x84\x68\x62\x61\x6d\x8c\x95\xad\xe9\x63\xa5\xde\xbf\x80\x8e\xc9\x4f\xd3\xe9\x18\x07\xea\x7d\xa2\x3f\x4a\xb0\x1f\x5c\x4b\xfb\x9d\x72\x20\x9b\x46\x34\x6d\x65\x89\x88\x66\x8b\xb1\x3d\x3b\xff\x5a\xe8\xd0\x44\x18\x17\x98\xa8\x27\x29\x5e\x98\xd7\xbb\xf5\x45\xd3\x68\x51\x58\x7f\xa2\xc4\x6d\x90\x3c\x55\x21\x1d\x72\x2a\x40\x82\xf8\xed\x3c\xe0\xa3\xa1\x53\x92\x57\x0f\xab\x6c\x4b\xe5\xcd\x62\xd7\xc8\x8b\x70\x4e\x08\x1b\x6e\x13\x42\xd9\x93\xb9\x54\xf5\x8b\x0d\x54\xa8\x1d\x65\xd0\x0a\x94\xa2\x86\x66\xc2\x7a\x43\xf2\xd6\x6e\x22\x31\xef\xca\xe4\x73\x30\x80\xfb\x12\xfa\xdf\xe2\xcb\x92\x79\x56\x18\xe6\x85\xc9\x5b\x0a\x9d\xb4\x52\xee\x9e\x64\x9b\x80\x87\x3b\x7d\xd2\x18\x59\xcb\xfb\xbf\x70\x85\xc1\x84\xc5\x0b\x2a\xaf\x8e\xe5\x35\x98\xe5\x05\x7b\x00\x39\x85\x34\x03\x80\x8b\xbd\x42\xf2\x40\xe5\x98\xda\x56\x84\x11\xb3\xe4\x65\x76\x00\xcc\x64\xe6\x02\x47\x60\xcc\x5b\x0c\x4d\x44\x29\x77\x00\xa3\xa1\xb3\x8b\x61\x99\x3a\x03\x50\x61\x49\x42\xd2\x16\xea\xb4\xc0\xe4\x18\x3e\x70\xfb\xd9\xfd\x01\x8a\xc7\x21\x91\x11\x3c\xe4\xd3\x4f\x57\xe1\x68\x84\x7a\x58\x34\x18\xa0\xc4\x8f\x82\x78\x3c\xba\xbe\xa7\xc3\x3d\xb5\x9a\x60\xc3\xe4\xa1\xfd\x5f\x3c\x98\x52\xd2\xf8\x37\xe0\x42\x74\x92\x03\x93\x05\x49\xd4\xb8\x82\x67\xb8\x3f\xcd\x70\xe5\x19\x8f\x46\xf5\xcc\x63\x89\x3b\x3c\x66\xbe\xe5\x10\x8b\xee\x09\xba\x87\x9e\x91\xe1\x20\xff\xff\xcc\x7d\x66\xa6\x60\x64\xee\xc6\xa9\xd9\xe3\x24\xea\x31\xea\xa2\x8a\x4d\xbb\x51\x3f\x9d\x66\x36\xcb\x0e\x45\xf5\x0f\xce\xab\x24\x43\x89\x4c\xe1\x54\x3a\xad\x55\x23\xad\xb9\xc5\xad\x8e\x2e\x6d\x69\x5d\x9b\xd2\x0a\x8d\x37\x4b\x13\x0f\xe4\x0a\x5c\x11\xe3\x2e\x4f\x83\xcc\x16\xd2\x4d\x75\x85\x25\xf2\x96\xc6\x03\xf0\xb7\x06\xac\x25\xb4\x99\x15\x63\x00\x76\xd3\x86\x9a\x5c\x24\x83\x66\x0a\x72\x9e\x4c\x96\x8f\x39\x7a\x6e\xea\xb3\x95\xd4\xd0\x79\x0a\x67\xbb\xb3\xd4\x31\x13\xa5\x16\x3c\x8c\xe7\x47\x6a\x21\x45\xdf\x4e\xab\x6d\xd3\x0c\x28\x2a\xee\x80\xf1\x65\xce\xf2\x34\x96\xec\x09\x58\x0e\xf1\xeb\xf6\xfa\x70\x4b\x94\x38\xa1\x10\xb7\x7f\xb3\x69\xb8\x1e\x50\x3f\xfe\x76\x7b\xf7\x06\x91\xed\x93\x5b\x50\xda\x76\xe1\x5c\xca\xe3\xcc\xb6\x78\x8b\x5b\x48\x2b\x6e\xe9\xb0\xdb\xf9\xe1\x73\x30\xd8\x90\xb6\x67\x89\x42\x16\x54\x8f\x33\x97\xaa\x45\xf6\xe5\xef\x43\x5f\x5e\x28\x1d\x7c\x07\xea\x88\xbf\x88\xda\xdc\xb2\xf8\x4a\x69\x92\x9f\xf1\xa1\x76\x85\x95\x7d\xf8\x86\x3d\xf4\xc7\x03\x6b\xb0\xf3\xed\xe8\x1b\x29\x1c\xb4\xdd\x35\xce\x5c\xca\x5d\x9b\xec\x42\xc0\x13\xb1\x85\x8b\x2b\x12\xf6\x74\x78\x85\x8c\xc1\x9e\xe9\xb6\xe7\xf2\xee\xa4\x62\x2c\xed\x9b\xd1\xa5\x15\xd8\x62\x15\x0c\x56\xac\x21\x09\x9c\x8a\x79\x45\x5f\xe2\xbe\xce\x90\x03\x40\x18\xf3\xa3\xb6\x2f\xe9\xf1\x0d\x34\x0e\xc2\x19\x4d\x06\x02\x15\xac\x43\x2a\x9d\xad\xa9\x61\xa6\x02\xdd\xa5\x37\xb1\x9e\xf8\xee\xa0\x0f\xfe\x13\xf8\xf1\x3d\x2b\x88\xbf\x77\xc6\xfc\x3d\xea\x89\x6d\xcc\x70\x51\x45\xf1\x9d\x18\xe3\xbd\xa3\x68\x2a\x8a\xef\x8b\x71\x97\xd4\x13\x7f\x73\xde\xfd\xcd\x95\xc5\xdf\x7e\xab\xf0\x14\xdb\x1e\xc7\x09\xed\xfe\xf6\x8e\x52\xfa\x70\xf7\xfd\x85\x6d\xeb\x90\xc7\xb7\xe4\xee\x51\xa4\x20\xcf\x55\x79\x22\xd3\xa5\x9c\xd2\x92\xe5\xaf\xbc\x39\xf7\xda\xcd\xef\x35\x29\xe5\xbd\xe7\xa0\x5c\x34\xf7\xa4\x92\x73\xd2\x40\xcc\x4c\x3f\xa9\xa5\x9d\xe4\x15\x1d\x89\x27\x41\x3f\x9a\x03\x17\x3f\xd5\xe4\x93\x07\x7e\x36\xf4\x90\x25\x05\x65\x7e\xbc\x7e\x17\xf7\xfd\x11\x9a\xc4\xa3\xeb\x41\x38\x42\xf1\x00\xd1\x4d\x8b\x9d\xe2\x2d\x47\x5e\x16\xdb\x7e\x53\x2d\xa8\x35\xac\x30\x26\xf1\x7a\x97\xbc\xbf\x79\x69\xc6\x0e\x92\x6c\x2d\x7b\x9f\x0c\xa6\x06\x36\x82\xd3\x1e\x99\x41\x9d\x88\x77\x57\x26\x49\x9c\xc5\xe4\x13\xda\x24\xa7\x0f\xbd\x00\xab\x87\x36\x51\x84\xaf\x08\x02\xc5\x10\xa2\xe9\x68\xe4\x58\x28\x02\x83\x7c\x99\x48\xf1\x8e\x6c\x91\x3c\xf9\x9c\x14\x2b\xb9\x9d\x8a\xed\x77\x61\x2f\xf1\x93\xeb\x79\x3a\x72\x29\x3f\xa8\x13\x14\x64\x0b\x65\x5a\x4f\x22\x5c\xf0\x2e\xfb\x23\x14\x46\x43\x9c\x84\x4a\x00\x57\x25\xa2\x83\x9e\x67\xd4\x8c\x30\x6a\x4e\x67\x89\xb0\x7f\x3c\xc6\x30\xb8\xc7\x09\x3f\x83\xa1\x9f\x71\x84\x58\x28\x0f\x2a\x06\x19\xa7\x4a\x84\x8a\xe2\x00\x72\xb9\x2b\xbe\xc4\x49\x12\x06\x38\x45\x47\x54\x21\x12\xe2\x94\x32\xf0\xc9\x35\x0a\x23\x96\xcd\x38\x47\xa0\x44\x0b\x7a\xae\x86\xd3\x45\x01\x18\x32\x97\xa3\xdc\x22\x51\x03\xc9\x44\x1d\x5c\x9f\x52\x12\x56\xa4\x9b\x02\x93\x44\xd9\x5f\x2c\xc4\xa3\x60\x03\x3d\x83\x4c\x59\xcf\x74\xc3\x11\x7b\x9b\xe4\x6f\x8c\xb3\x61\x1c\x14\xfa\xc8\x4b\xa5\xf5\x18\xf9\x36\xc7\x33\x84\xcc\x70\x86\x14\x7d\xc5\x20\x9b\xcf\xab\x33\x88\xe1\xc4\xbf\x8a\xcc\x2f\x12\x23\x21\xc2\x42\x9e\x56\xcf\x65\x4e\xbc\x35\xbd\x18\xe3\xc8\x62\x3a\x4c\x76\x94\x62\x2c\x50\xce\x7c\xd8\xb9\x2b\x2f\x6f\x4d\xff\x60\x45\x80\x99\x49\x71\xd7\xaf\x50\x38\x96\x26\x76\x9c\x7e\xe0\x4d\x0e\xfd\xf4\xf0\x2a\x62\x64\x7f\x5d\x79\x46\x6a\x3e\xab\x0a\x9f\x27\xf2\x08\x9b\x20\x2f\x4f\x5e\xcc\xed\x07\xad\x55\x38\xdd\x96\x5a\xff\x4f\x3a\x9d\x10\x51\x2b\x0a\xb3\x15\x9f\x08\xa7\x6c\xeb\xf3\x93\x8b\x29\x19\x5d\xeb\x78\x20\x4b\x06\x85\x82\x71\xca\x3d\x6e\x93\x67\x29\xca\x39\x7a\x48\x95\xc2\x7c\xd2\xe9\x2a\x35\x21\xc8\x1d\x54\xf6\x03\xc7\xb6\x83\xb8\x62\x7c\x80\x13\x1c\xf5\x49\x03\x30\xce\x13\x7d\xbd\x1a\xc3\xc0\xe4\x62\x1b\x40\xe7\x3e\x83\x6c\xa9\x31\x6c\x4c\x75\x07\x56\x4a\x2a\x33\x4d\xaa\xf2\x9e\x46\x74\x1c\x60\x02\xe9\xaa\x35\x43\xa0\x6e\xf1\xf9\xc8\x33\xd8\x54\xaa\xe2\x1a\x8e\x88\xd2\x10\x52\x0e\x80\x54\xaa\x7f\x65\x5e\xc9\x23\x96\xa3\x4d\xc6\x36\xf9\x9d\xc5\x5c\x5e\x44\xcb\x15\x73\x3c\xb3\x11\x58\x72\x79\x9c\x6c\x73\xe5\xf2\x08\xea\xd2\x1a\xe1\xef\xd4\x75\xe2\xa4\x1a\x5e\xfc\x36\x64\x53\xe4\xae\xee\x98\x2b\x74\xc8\x98\x19\x4b\x12\x00\x24\x05\x26\xf4\x41\x80\xd2\x78\x8c\x69\xea\x29\x74\x35\xc4\x11\xba\x8e\xa7\x89\x30\xb3\xf7\x89\x38\x4b\x81\xdf\x73\xec\xdc\xbb\xee\x82\xba\xa3\x73\xd1\x5e\x86\x28\x03\x58\x59\x31\x47\x46\x0c\xfd\x2d\xb7\xbb\xb9\x68\x94\x9a\xd3\x6e\x3c\x21\xc2\xce\x24\x97\x7b\x98\xbc\x73\x07\x71\x4a\x02\x06\x1a\x26\x45\xa6\x1a\x83\x26\xf2\x9e\xa7\x94\xad\x4e\xba\x7f\x96\x95\x5f\x6e\x39\xee\xd0\x88\x72\x89\x2d\xfa\x67\x5d\xe3\x22\xe2\x21\xbf\x6c\x7b\xef\x8f\xc1\x68\x62\x4e\x3d\xc4\xb6\xea\xbc\x98\xbe\x59\xcb\x00\xab\x85\x5b\x2c\x99\xce\x33\xb9\xf8\x39\xda\x94\xda\x57\x3f\x2d\x90\xba\xc8\xb1\xc9\xee\xa0\xab\x38\x7a\x96\x51\xf9\x99\xbb\x3b\x4a\xc1\x0b\x47\x71\x3c\x41\x7e\x2f\xbe\xb4\x6c\x83\xc5\x5d\x7e\xc6\xa1\x3d\x73\x77\x18\xb8\xa8\x68\x55\xee\xa7\x78\x5b\x22\xaf\x56\xa9\xc5\x23\x0e\x27\xd0\x53\xb0\x7f\x59\x64\xdd\xd8\x36\xbe\xfe\x28\x8e\xf0\x03\x70\x3c\x80\x8b\x36\xf3\x3d\x04\x5e\x94\xd8\xc9\x48\xb1\xb9\x1b\x99\x9c\x8b\x44\x15\x8e\x38\x3f\xb5\xda\x93\xd9\xcf\xc8\xd6\xdb\xfd\x08\xf9\xe0\x79\xab\xc5\x22\x2c\x8c\x2c\x64\xc4\x79\x2f\x06\x61\x0b\x4f\x23\x8c\x1f\xd4\x70\x88\x69\x78\x11\x85\x83\xb0\xef\x47\x19\x0b\x28\x19\xd2\xde\x03\x48\xda\x8e\xed\x98\xfc\xab\xe4\x41\x4c\xcf\xca\xf2\x9b\x7b\x08\x1b\x63\x36\xaf\x93\x85\x23\x0c\xbe\x6c\x7a\x35\x67\xac\x91\xd5\x2c\x4c\x8c\x94\x76\x83\x31\x77\xd0\xf0\xbd\xa5\x7a\x91\xfd\xb3\x95\x8d\xdd\xb0\x85\x71\x68\xff\xcb\x03\x38\xab\xcd\x6a\xb5\x5a\xbd\xd6\xa8\x35\x3d\x54\x9b\xd5\x5a\xb5\x76\xad\x53\x5b\x3b\x7f\x30\xc0\x1e\xea\x94\x0e\xbd\xc2\xc2\xd7\xf1\x19\x31\x56\xec\x15\x73\x08\x86\xe5\xca\x1f\xe8\x7f\xbf\x7e\x85\x98\xbd\x9a\xa8\x31\x40\x15\x31\xbd\x3f\x6c\x5a\x14\x85\xf2\x1f\x40\x95\x8c\x86\xf8\xcf\xd2\xc6\xa4\x3a\x00\x4a\x1e\x23\x1c\x5d\x64\x43\x6a\x7a\xe4\xe4\x22\xe5\x63\xc6\xe4\x0b\x65\xb1\x48\x31\x3b\x51\x3f\x0e\x08\xbd\x63\xfa\x43\x27\x77\x78\x5d\x1c\xfb\x53\x10\x00\x8e\xfa\x2b\x7b\x78\xe6\x6e\x73\x5e\x00\x99\x52\xab\x7d\xe1\xe0\x2e\x39\xb1\x96\x88\xec\x62\x89\x6b\x30\x2f\xac\x8b\xa5\x8a\x32\x24\x1f\xb2\xc1\xfa\x42\xd1\x5c\xd8\x54\x38\x63\xb9\xf0\xa9\xfa\xfa\x15\xed\xe1\x59\x61\xf8\x96\x39\x04\xd4\xf7\x33\x1c\xb1\x3d\x5f\xa5\x20\x07\xf3\x77\x13\x92\x74\x0f\x9b\x0f\xf8\x29\xe3\x86\x12\x65\x42\x9a\xdf\x45\xef\x75\xcb\xe2\x52\x86\x36\x04\x76\x75\x1e\x3f\x43\xbc\x69\xb8\x53\x9a\x41\x49\x9d\x29\xd1\xc0\xce\x8b\x85\x23\x21\x03\xfb\xab\xc1\xb0\x2c\xbe\x8a\xd9\xd0\x17\xa1\x0e\x72\x12\x73\x97\x0e\xd3\x93\x9c\xc7\x28\x3c\xc7\x01\xfc\x44\x65\x49\x14\x7e\x5e\xc7\xe8\x54\x77\xe4\x8f\x27\x08\xcf\x20\x92\x64\x2f\xd4\x3b\x47\xef\x55\x49\x19\xf3\xb6\x81\xde\xa7\xf6\x6d\x41\x52\x14\xc4\xff\xe1\x08\x94\x0e\xf5\x89\x48\x1a\x61\xd8\x6a\x91\x9f\x21\x1f\x65\xe1\xd8\x22\x71\xdb\x42\xb2\xcb\xdd\x75\x27\x85\x90\x07\x87\x14\x45\x9b\x04\x3d\x36\x0b\x67\x21\x8f\x8a\x4d\xfe\x53\x69\xb4\xd0\x32\xaa\x84\x14\xe3\xe7\x68\xbd\x5a\x15\xd1\xb2\x9d\x52\x3c\x85\xa3\xf6\x78\x09\x85\x22\xdc\xf6\xd7\xcd\xbc\xe9\x57\xaf\x78\x1b\x96\xf2\xa2\xd1\x12\x82\xbf\x73\x5b\x92\xc7\x94\x2e\xae\x3b\x8d\xa9\x3b\xca\x7d\xd9\xee\x6f\x22\x73\xb0\xcb\x64\x0c\x36\xa9\x50\x6c\xb6\x4b\x9b\x2a\x9a\xb6\x1c\x2b\x7e\x18\xf9\x3d\xfd\xe4\x21\x1d\x00\xca\xb2\x53\x1a\x83\x83\x08\x81\x8a\x60\x18\x66\x77\x15\x05\xf3\xc5\x29\x56\x97\x83\x49\x91\xcf\x65\x43\xf7\x5a\x58\x93\x29\x47\xd9\xe2\x22\x39\x99\x8c\x9d\x61\x58\x44\xb5\x33\x01\x83\xc7\x99\xdf\x84\xa5\x43\xff\x80\xf4\x9b\x0d\x42\xfa\xa9\xc2\x17\x2c\x04\xaf\x88\x52\x9b\xe8\xc0\xcf\x86\x2b\x7d\x1c\x8e\xf2\x9a\xab\x68\x81\x88\x44\xf6\xf3\x6f\xa9\x9d\xc7\x61\x8e\x64\x1c\x7f\x6f\x6b\xf7\xc9\x8e\xbb\x32\x2d\x18\xe7\x5d\x95\x16\xe6\x9d\x73\x65\xb0\x70\x52\xa3\xb8\xca\xd1\xcf\xcd\x93\xf3\x8a\x49\x23\xcc\xfc\xbe\xe6\x34\xa9\x23\xf5\x16\x9f\x02\x49\x6c\x18\x84\xa3\x11\x0f\x3b\xcb\xdc\x24\xe0\xbc\x35\x5f\x28\xe1\x87\xb9\xc8\x76\xe8\x95\x41\x39\x5d\x7c\x4a\xcd\x32\x83\x54\x8a\x50\xee\xcb\xf8\xac\xc4\x11\x8c\xb9\x82\xd4\xdd\x27\x2d\x5a\x42\x26\x93\xc8\x7e\xc4\x92\xd9\x83\x79\xa0\x22\x5f\x13\xf5\x86\x7c\xfc\xf1\xca\x1d\x65\xfe\xe3\x15\xda\x24\xff\x3a\x12\xa8\x8d\x3f\x7e\x21\xdb\xcc\xac\xe9\x07\xb8\xb3\xde\xd3\xc3\xaf\x8b\x62\x7e\xfa\x19\xc9\x9c\xa3\xe0\x9e\xa0\xc4\xdd\x1d\x6d\xb5\x52\x9b\xbd\xa8\x75\x5e\xa0\xe7\xa4\x0b\x5f\x60\x4f\xdf\xdd\xdd\xdd\xad\xa2\x25\xfa\xe2\xe7\x9f\x51\x6d\x56\xaf\xc1\x76\x4f\x10\x70\x6c\xf7\xb4\x8b\x95\xda\xac\xd5\x69\xd7\x28\xb0\x2b\x1d\xd8\x55\x59\x60\x30\xbc\x38\x9d\x82\xa7\x4f\x05\xd0\x78\xf5\x8a\xd6\x44\x4b\x08\x46\xba\xb0\x3e\xab\xbb\xba\x09\x75\xd8\x5f\x71\xd9\xa5\x4d\x54\x5b\x69\x3b\xcb\xc0\x98\xb2\xa2\xcf\xa9\xbd\x0d\xa7\xb6\x2a\xfa\x19\xad\xb4\xd1\x7f\xa1\x3a\xda\x40\xcb\xf5\x32\x22\x8a\xc1\x39\x54\x71\xc3\x43\x49\xdf\xef\x0f\x31\xcb\xae\x33\x5f\xe0\x20\x35\x3f\x12\x7a\x4c\x2a\x15\x5a\x95\x1c\x95\x14\x24\xc9\x6e\x22\x0d\x86\xfd\x8a\x89\x56\xdd\x44\x1f\x93\x0a\x2d\x0f\x04\xb9\xd6\x5b\xb3\xf4\xe9\x2a\xcf\xe1\x53\x11\xe5\x73\xf8\xe8\x2b\xaa\x95\x0c\x6b\x1e\xe1\x2b\xc9\xd9\x09\x6e\x1d\x99\x02\x24\xe2\xe9\x7b\x9e\x68\x23\x69\x77\x3e\x65\x47\xfb\x79\x86\x34\x38\xea\x83\x21\x0d\xfd\xaf\xdd\x90\x66\x0f\xcf\x4c\x4d\x80\x0d\x1c\x29\xb8\x49\x81\xae\xd0\xdf\xe5\xe2\x6f\xea\xea\x8b\x21\x9e\x95\x56\x61\x94\x38\x79\x2e\x18\x55\xb3\x54\xeb\xf7\xc5\xc8\x87\x78\x66\x86\xd0\x64\xe3\x27\x1d\xed\xe7\x27\x12\xb2\x06\xce\xbc\xed\x31\xf5\xaa\xf4\xc9\x33\x5d\xf4\x18\x49\x67\xdd\x04\x34\xc4\xb3\xee\xd0\x4f\x4a\xe7\xd9\x4a\xe7\x1e\xe8\x20\x47\x5a\x48\x0f\x72\x57\x77\x3c\xc4\x71\xec\xd8\x1a\x07\xb0\x04\x48\xab\x9a\xab\x7d\xea\x9d\xaa\x8d\xdf\xd9\xaa\x92\x76\x6a\x83\xe2\xba\x0e\x06\x21\xc0\x7d\x8a\xc3\xa8\xf2\xec\xd9\x2d\x22\x6e\x4a\x14\x4e\xd7\xdb\x22\x9a\x1e\xbe\x52\x28\xe1\x96\x5f\x30\x0e\xe1\xe9\xcf\x97\x9a\xf8\x62\xa3\x36\xdb\x62\x3d\x96\x8f\x94\x49\xab\x2c\x96\x28\x85\xd6\x79\xc7\x8f\x2e\xf4\x91\x1d\x65\x16\x59\x35\x57\x8b\xa4\xa6\x93\x1b\x65\x5b\x68\xa3\x20\x3f\x26\x5d\x2d\x4d\xd0\x4c\x40\xa7\xf7\xa3\x8c\x75\x76\x25\x9d\xf6\xd2\x2c\xa9\x84\x1e\x6a\x54\x3d\x48\xc2\x97\xab\x2c\xc8\x8a\x5a\xaf\xda\x1c\x70\x17\xde\xf3\x94\x61\x5a\x45\x8d\xb2\xee\xb3\xef\xfc\x2c\x8c\xea\xe5\x36\x2d\x56\x96\xef\x5b\xe2\xf1\x76\x5b\x17\xab\xfe\xe7\xed\x5e\x65\x11\xb8\xaf\x35\x35\x82\xf6\xec\x7b\x18\xc5\xe5\x3f\x6a\x1b\xa3\xc3\xf1\x1d\xef\x64\x12\x82\x74\x47\xa2\x53\xb7\x32\x48\xe2\x31\x79\xdb\x8d\x03\x0c\x9b\x54\xd9\x0d\x49\x06\x78\x87\x3d\x49\xa1\xdb\xdb\x6f\x4b\x82\x1c\x17\x5a\x0c\xdf\xf5\xe6\xc4\x56\x11\xdd\x9f\xe4\xe5\x56\x7e\x8b\x12\xb5\x16\xdb\xa5\x44\x35\xb1\x51\x89\x37\x0f\xbd\x57\x69\x4d\xcf\xcb\xe5\x1c\x4a\x5a\xf4\xbc\xb7\x2b\x7d\x46\xd0\x5b\x59\x25\xe4\x6b\x42\xdf\xaa\xec\xba\xc5\x85\xb7\x2a\x0d\xe1\xb2\x3b\xd5\x87\xd3\xdd\xe5\xf5\x72\x1b\xd5\x87\x6c\xb0\x2e\xb6\x29\xf6\x70\xbb\x4d\x8a\x36\xfa\xe7\xed\x51\x25\xdb\xbf\xaf\x95\x35\xcd\x06\xeb\xf6\x0d\x8a\x8c\xe2\x43\x6e\x4f\x59\x72\x5d\x60\x60\x14\x60\x72\x44\xff\x70\xbc\xdf\xe5\x9e\x4e\x15\x9c\xf6\xfd\x09\xae\x14\x6c\x9c\x26\x5b\x46\x7d\x3f\xeb\x0f\x51\xc5\x4c\x1f\x0d\x28\x0c\x93\xf8\x0a\xe8\x16\x32\xae\x54\x9e\x1d\xf8\xa3\x41\x9c\x8c\x71\xc0\xa6\x21\xf0\x33\xdf\x4c\x41\xb7\x38\x03\x97\x27\xf5\xf6\xfc\x9b\xcd\xd5\x22\x64\xf2\x5d\x33\x6f\xa0\x30\xca\xba\x73\x32\x2c\xcf\xb8\x59\x1d\x97\x31\x80\xb2\x35\x4c\x23\x46\x3d\xd4\x42\x40\xa1\x2b\x0e\xa7\x5a\x3a\x00\x8d\x48\xc1\x0b\xb9\x30\x71\xc0\xb2\x99\x49\x5e\xe8\xce\x4c\xbc\x92\x9d\xec\xb5\x94\x12\x6d\x3c\x4d\x33\xd4\xc3\x28\x24\x23\x3a\xc6\x51\x46\xf3\xac\xf9\x70\xbd\x9e\xe0\x4c\x78\x2c\x94\xca\xed\xab\xe5\xe9\x54\x95\xfb\x34\xc7\x21\x75\xad\xca\x13\xc4\x7f\xc6\x93\x0c\x4d\xa3\x09\x4f\x1a\xa8\x66\x07\x95\x6c\x5a\x6a\x16\xee\xfb\x9a\x8d\x03\x64\x1a\xdc\x12\xa3\x20\xbc\xc4\x5c\x9f\x4b\x9a\xc1\x41\x76\x57\x66\xcd\xa3\x8d\xf4\x33\x96\x44\x9b\x25\x31\xcd\x62\x14\x66\x29\xf7\x8a\x41\x84\x82\xef\x7a\xc7\xd4\xb3\x22\x4f\x13\xe2\xba\x2f\x99\x4a\x65\xdd\x65\xe6\x7d\x08\xac\x94\x6d\x36\x03\x90\x81\x93\x79\x2a\x6a\x3b\xab\xce\x94\x68\xf9\x68\xdb\xcf\x7c\x2e\xac\xd7\xca\x4a\x9a\x5b\x41\x90\x42\x1b\x3c\x2f\xb8\x63\xa4\x19\x2d\x94\xdf\x14\x45\x90\x05\x23\xf3\x38\x33\x76\x41\x74\xcd\x33\x27\x00\xca\x2f\xa9\x4f\x89\x2f\x59\x50\x52\x7b\x62\xe0\x78\x0f\x33\x99\x1f\x29\x3a\x95\x67\x26\xbf\x2f\x55\x6f\xfe\xde\xc8\x4a\x96\x49\x66\x6e\xba\xd7\xe7\xe9\xe8\xe4\x80\xa2\xd2\x00\xb1\x60\xa2\x2a\x28\xd9\xc7\x19\xc8\x68\x4e\x9c\x48\x46\x6b\x12\x53\x06\x0c\xe7\x47\x4a\xdb\x82\xae\xb9\xc8\x97\x9b\x12\xd9\x80\x19\x44\xbb\xb4\xa9\x26\x49\x2f\x4b\xc1\x3c\xd7\x69\x8a\xfc\x4b\x3f\x1c\x41\xc4\x2e\xca\x17\x80\xd9\xb9\xa9\xe6\x54\x72\x56\x09\xa3\xcb\xf8\x33\x4e\xf5\x24\xc3\x15\x96\x1c\xd8\x43\x57\xc3\xb0\x3f\xb4\xb2\xea\xde\x75\x01\xab\x36\x5b\xe5\x0b\xa5\x17\xc7\x23\xec\x47\x37\x28\x88\x77\x47\xd3\x74\x88\x7e\x1d\xe2\x8c\xc6\x33\xe1\xb9\x68\xc1\x5d\x6b\xe2\x27\xc0\x28\xd8\xab\x9c\x6b\x0b\x76\x7d\x8b\x70\x20\x82\xd3\xc3\x88\xdf\x7d\x9b\x17\x00\xb7\x29\x21\xb9\xd6\x0c\x4f\x95\xeb\x8a\xcb\xb1\x20\x18\x7b\xa6\x60\x35\xd6\x2a\x2d\xaa\x2c\x3e\x3a\xe0\x0b\xea\x4c\xd8\x12\xc9\x89\xdb\xa2\x2d\x21\xaf\xb9\x71\x1a\x8c\xac\x4b\xad\x42\x3e\x4a\x86\x66\x2e\xba\xe7\xc5\x73\x59\x61\x53\x4b\xc9\x5c\x54\x98\x43\xcf\x6b\xdb\x23\xfa\x75\xe3\x69\x94\x71\xfa\xb2\x30\x13\x02\x34\xa2\x89\x84\x8f\x21\x6e\xf1\xa6\x8a\xff\xaa\xd6\xe4\x4b\x93\x17\xb9\x86\x9c\x61\x70\x1c\x4f\xa3\x00\x4d\x27\xd4\xa1\xb0\x3f\x9a\x06\x58\xa3\x7b\xb3\x9a\x86\x51\x6e\xe4\x22\x7f\x28\x1f\xdb\x56\x60\x11\xc4\x57\x91\x8c\x47\x1c\x8d\xae\xd1\x60\x2a\x16\xa5\x25\x92\xfe\xea\x2a\x1a\xe1\x94\x3a\x55\xda\x65\x2d\xe0\x1b\x09\x1e\xfb\x61\xa4\x0a\x57\xe5\xfa\x35\xf6\x67\x15\xa5\x5f\x70\x71\x8a\x96\x6d\x99\xd9\xbd\xf9\x57\xaa\x62\xce\xa9\xe6\xc1\x35\xe5\x40\xc9\x1c\x0f\xa5\xf5\xe7\x48\x22\x40\x17\x3d\x01\x6d\x38\xc9\x89\x7c\x55\xfb\x18\x46\x15\xb9\xc9\xe7\xa8\xe5\x29\x74\x66\x33\x9f\xe4\x19\xbc\x6d\x44\x42\xe8\x4e\x02\x58\xec\xb6\x45\xf9\x3c\x55\xb3\xb0\xdf\xaf\xe4\x11\x10\x6f\x97\xa4\xf5\xe4\x34\x9a\x20\x98\xe1\x84\x9c\x26\xc5\xc6\xb0\x9c\x1f\x10\xc0\x19\xd2\x5e\x91\x71\x17\x75\x0f\x12\x5c\xc5\x96\xab\xde\x35\xc7\x48\x49\x81\x95\x33\x7c\x98\x72\xb3\xa8\xc2\x7d\x65\x16\xa6\x27\xc3\x92\x47\xd4\x82\x86\xc2\xc9\xd0\xf2\xa6\x3c\xd3\xf3\xa9\x92\xc7\x16\x2d\xc2\xd6\xad\x70\x52\xf1\xf7\xe4\xa6\xef\x6a\xec\x56\x3a\x0b\x65\xa1\x93\xd7\x1d\xad\xdc\x1c\xbb\xe1\x9f\x64\xf2\xf6\xd1\xd8\x10\x73\x4c\xac\x33\x56\x68\xf1\xa6\xf2\x30\x71\xd2\x74\x64\xa2\xe7\x67\xf0\xa1\x9f\x42\x86\x5c\xe7\x89\x7b\x6e\x2a\xf2\x9c\x5d\xcb\x3e\x50\x74\xd2\x19\x74\x1a\x76\x0d\xa7\x28\x8e\xa4\xa3\x70\xbd\x83\x2a\xed\x7a\x03\x2c\x59\xab\x96\x63\xf1\x1e\xad\xcc\x8f\xc1\xe2\xd1\x7e\x1e\xbe\x97\xa8\xaf\x45\x19\xc8\x0a\x03\xa6\x16\xb9\x9a\xd1\x41\x58\x20\x27\xf9\x6d\xa3\xdb\x91\x86\x10\x0d\x91\x3c\x2f\xc8\x5d\x69\x1b\x12\x31\x07\x4a\xe8\xb6\x93\xbd\xad\x46\xbb\x63\x77\x12\x2b\x4a\x75\x7d\xeb\x08\x6b\x3c\xb6\x5a\xf9\x30\x6b\x27\x58\x84\xf7\x70\x6b\x08\x4c\x35\xc4\x1c\x4b\xec\x5c\x93\xc2\x17\xce\xfd\xab\x4c\x18\xbd\xdc\x87\x8a\x04\x10\x96\x55\x3c\x6a\x09\xc7\x4a\x02\xd0\x0a\xf3\x32\xa5\x06\x7d\x6f\x66\xc3\x61\xd9\x98\xf9\x86\x7c\xbc\xd8\x58\x7f\x98\x04\xc0\x32\xe4\xc1\xa6\x69\xf9\xcb\x67\xec\x73\x46\x10\xa6\xc0\xf5\x38\xc2\xa5\x5d\x88\x28\x2b\x62\xfe\x43\x73\x97\xf7\x02\x73\x3e\x05\xbc\x2a\xcf\x18\x52\x36\x5d\x8a\x5a\x72\xbe\xea\x84\x16\x94\x09\x45\x19\x03\xc7\x7a\x74\x68\x24\x98\xc2\x46\x85\x60\x21\x0f\x36\xbe\x44\x48\x27\xf8\xda\x40\x49\xe7\x58\x53\xfc\xbd\x37\xdf\x89\x5d\x96\xe4\x26\x15\xb8\x38\x19\x24\x7a\x1f\x03\xca\x7e\x46\xf3\xc5\xb3\x9a\x79\xcc\x50\x14\xa6\x08\x0f\x06\xb8\x9f\x85\x97\x78\x74\x8d\x7c\x14\xe0\x34\x4b\xa6\xf0\xec\x81\x9c\xbe\x1c\x47\x7d\x5c\x2a\xca\x68\x49\x0a\x55\x12\x3d\x00\x4a\x79\x40\x6e\x28\xb1\xb8\xe6\x82\x0c\xc2\x3d\xed\x0c\x68\x93\x93\xa3\x48\x26\xe4\x50\x4b\x38\x4a\x17\x11\x7a\x41\xb5\xf9\x54\xcf\x8b\x2e\x44\xf7\xbb\x96\xf1\x35\x0f\x44\xc5\x60\xd0\xbc\xb5\x32\x4f\x80\x5f\x80\xb3\x4a\x23\xc4\x99\xec\xae\x34\x0f\xd6\xc5\x43\xca\xbb\x16\x8f\x94\xfc\xae\x5d\x6f\xac\x36\x1b\xe5\xc4\xfc\x94\x69\x7c\x94\xf8\xf7\x3e\x9b\xb4\x67\x22\x70\x52\x18\x65\x38\x19\x48\xd6\xc2\xc8\xb9\x2a\x38\x7f\x65\x5d\xe7\x54\x4b\xb7\x5b\x16\x1f\xd1\x47\x43\x3c\x9a\xe0\x84\x88\x3f\x25\x16\xc1\x2e\xc3\x8d\xf9\x06\xeb\x28\x7f\x83\x7b\x3c\x2a\x33\xe9\x4e\x15\xb4\xab\x2b\x1f\x69\xaf\xf6\xa0\x4b\x15\x9b\xb0\xe5\xd6\xcf\xc9\x55\x15\xe3\x41\x00\xed\xba\xdf\x33\xd6\x85\x3d\x00\x2e\x52\xcf\x8b\x6c\x25\xc2\x61\x51\xcd\x22\x96\x67\xb8\x54\x29\x7c\xf1\x63\xa3\x95\x9e\x08\x4b\xde\x3b\xd8\xea\xde\x3f\x3d\x11\x11\x9a\x07\xa5\x20\x2d\x30\xba\xfa\x4b\xd0\xd4\xde\xd8\xef\x97\xa2\xab\xb1\xdf\xbf\x0b\x6d\x89\xea\x77\xa2\xaf\xcf\xd8\xae\x42\x92\xe8\xab\xfb\x11\xd0\x22\xf3\x40\x89\x8c\x36\x42\xeb\x2e\x46\x6c\x85\xc7\x5f\xa1\x49\x9a\xe3\xc3\x40\xb0\x01\x27\x06\xf6\x23\xf7\x62\xe0\x99\x5a\x20\xa4\xef\x81\x9f\x0d\x69\x58\xdf\x27\xfc\x3d\x1b\xe6\x97\x79\xa4\xdf\x9b\x73\xaf\xdd\xfa\x5e\xc3\xfb\x32\x64\x2a\x3c\x1c\x71\xf5\xde\xe3\xfd\x72\xc8\x8b\xc6\xfd\x15\x18\xca\xf1\x7f\x5d\x41\x7f\xc5\x77\x08\xfe\x6b\x0b\xa0\x6b\x5e\x51\xf0\xa8\xb1\xf9\x94\x49\x04\x20\x45\x83\x95\xde\x17\x84\xa7\x51\x6a\x4b\x2e\x30\xae\x30\xb2\x9d\x56\x39\x13\x2d\x56\x96\x1b\x69\x89\xc7\xdb\x99\x69\xb1\xea\x7f\x9e\x9d\x56\x59\x04\xee\x8b\x53\xf6\xa0\x3d\xbb\xa9\x16\xc5\xe5\x6f\x60\x4b\x6c\x94\x1f\xfb\x13\x21\x1c\x8e\xfd\xc9\xe2\xb1\x17\x2c\x2e\xe2\x26\x08\x97\x55\x26\x1d\xf3\xdb\x1a\x2c\xa3\xa5\x4d\xd4\x74\xdb\x2c\x5f\x67\xb8\x6e\x31\x5a\xa6\x7f\x2e\xd3\x65\xfa\xe7\x34\x60\xe6\x80\x1b\x39\xe0\x4a\x88\x96\x50\xbd\x6a\xb1\x89\xe6\x5f\xca\x58\x46\x73\xc0\x4d\x0d\x70\xc3\x09\xb8\x61\x05\x6c\x87\x9c\x25\xe1\x64\x04\x57\x2f\x15\x3a\x2c\xaf\x5e\x81\xdf\xc4\x57\xfa\xdc\x20\xcf\xeb\xe4\x11\x50\xb0\x41\x11\x53\xf1\x89\x4e\x45\xe5\x13\x7a\x45\x5a\xff\xe9\x27\x04\xd8\x7c\x42\xcf\x51\x6d\x65\xad\x2d\xcd\x50\xf5\x25\xfa\x54\x10\xee\x42\x9a\x7b\x6a\x0b\x3e\xf6\x27\x60\x33\xbb\x95\x55\x2a\x1c\x61\xe8\x74\x07\x3d\x47\x95\x26\x5a\x46\x9f\xaa\xac\xa7\xcd\x81\xd5\xdb\xc9\x88\xcf\x60\x2a\x2e\x82\x80\xa7\xfb\x36\xa9\x91\x7d\x20\x28\xa1\x4d\x24\xa1\xd3\x31\x9c\x49\x20\xb6\x5e\x5e\xdc\x6e\x1c\x3c\x0c\x47\x18\x55\xe4\x7e\xb2\x70\x01\xae\x58\x23\xd6\x61\x91\x9b\x59\xbc\xcf\x8c\xb3\xca\x50\xef\x60\x27\xaf\xf0\xe4\xdb\xdb\x59\x0a\x56\xbb\x10\xa3\xff\xae\x4d\x2d\xd9\x0e\x41\xed\x7a\xe4\xad\xa4\xbc\xb9\xa5\xa8\xb5\xe0\xe6\x20\xea\x09\x43\x79\xf1\x46\x18\xca\xcf\xe7\xfb\x46\x89\x04\x5f\xe2\x24\xc5\x07\x52\xc1\xfc\x95\x2d\xae\xd9\x0f\xf9\x67\x27\x75\x17\x02\xb5\x6d\x01\xfc\x4f\xe7\x3f\x84\xfd\x90\x15\xca\x3a\x58\xc8\x69\xd4\x86\xcf\xf8\xc2\x66\xb6\xf9\x9f\xaa\xe7\x68\x13\x7d\x2a\x17\xab\xd3\xc2\x52\xf6\x2f\xa2\x38\xc1\xdf\x8c\xab\x48\x20\xf7\xa3\x00\xfc\x9c\xf3\xe9\x0e\xc9\x9b\xc3\xc1\x3c\x9e\x21\xb5\x43\x61\xfc\xb0\xb9\x89\x96\xeb\x73\x78\x92\x4c\x61\x72\xed\x5b\x31\x62\xab\x48\x90\x88\xb4\x97\x29\x7e\x17\xc7\x93\x7c\x49\x78\x3a\x0e\x9e\x34\xa3\x8a\xc8\xa1\xdd\x78\xfa\x93\x0d\xf4\x6c\xeb\x75\x77\x7b\x67\xf7\xcd\xde\xfe\x3f\xdf\xbe\x3b\x78\x7f\x78\xf4\x7f\x8f\x4f\x4e\x3f\xfc\xf2\xeb\x6f\xff\xfa\x1f\xbf\xd7\x0f\xf0\xe0\x62\x18\x7e\xfa\x3c\x1a\x47\xf1\xe4\x7f\x93\x34\x9b\x5e\x5e\xcd\xae\xbf\xd4\xea\x8d\x66\xab\xdd\x59\x5b\x7f\xb1\xb4\xba\xc9\x22\xdc\x8a\xa3\x9d\x58\xb4\x0b\xa3\x9a\x0f\xb1\xc3\x2b\x25\xb7\xdc\x50\x2c\x4c\x6d\xa2\x90\xd6\x8e\xcd\x4d\x85\xcc\x74\xe8\xd8\x6f\x98\x63\x57\x4a\x84\x24\x69\x79\xe4\xd4\x24\x3b\xb0\xa0\x65\x54\xaf\x9e\x83\xf7\x4a\x2e\x30\x35\x4c\xe2\xe2\x40\x1b\x65\x80\x56\xcf\xf9\x06\x2f\x8b\x61\x16\xa8\x54\x20\x8a\x94\xc8\x3d\x5f\x89\x30\x03\xe8\x7f\xa5\x2d\xca\xbe\x35\x51\x71\xf0\x1e\xc4\x86\x78\x69\x49\xf9\x20\xc8\x56\xfc\x60\x14\x69\xc4\x96\xb4\x86\x45\xb8\xc9\x73\xf7\xe8\x87\x7c\x69\x8f\x78\xe9\xcc\xec\xd3\x7e\x3c\xfa\x3f\x1e\xfd\xc5\xd1\xff\xc3\xe9\xee\x72\xbd\x83\x5e\xef\x94\x76\xd0\xaa\x77\x5e\xef\xc8\x3e\x5a\xf5\x8e\xfa\x04\x5f\x6f\xef\xb4\x45\x91\xf9\x73\x1d\xb7\x4a\xe2\x70\x8f\xce\x5b\xf5\x8e\xd3\x7b\xab\xde\xf9\x1b\x68\x04\xca\x1f\xd6\x61\x30\xee\x72\x56\xb7\xfb\xfb\x83\x65\x54\x1c\xe0\xa3\x38\x8c\x32\x97\x93\x71\xbd\xe3\x70\x32\xb6\x1e\xa6\x73\x4c\xdd\x5e\xc6\xa2\xc9\xb2\xae\xc6\x12\xd0\x3b\x9c\xa0\x74\x22\xbe\x93\xb3\x1a\xd0\xe6\xa2\x6b\xe3\xbb\x3e\x46\xd1\x55\x25\x5c\xd6\xf8\xe2\x5b\xc8\x67\x0d\x2a\x2d\xe6\x6b\xcc\x6b\x09\xf9\x96\xbf\x78\x68\x4f\x63\xb5\xe1\x72\x8e\xc6\x75\x90\x7d\x04\x86\xaa\x9b\x31\x11\x81\xf2\xc5\xd2\x20\x8b\x45\x0b\xc2\xe6\xa6\x70\x97\x94\xa3\x8d\xce\xf3\xf2\xa1\x30\x18\x59\xbe\x2b\xb1\x87\x49\xfb\xd4\xbb\x3b\xef\x53\xef\xbe\x83\x7d\xaa\x0c\x0e\xf7\xbd\x4f\x59\x97\xd3\xbb\x9d\xc7\x6d\x4a\xfc\xdd\xdb\x36\x95\x5e\xf9\x93\x9d\x28\x08\xfd\xa8\xb2\xe8\x8e\x65\x3b\x92\x7f\xff\x5b\xd6\xbb\x87\xd9\xb2\xca\x2c\x93\xef\x7f\xcb\x7a\xb7\xa3\x6d\x5a\x8f\x3b\x96\xb1\x63\x49\x2b\x66\xa1\xcd\xeb\x9b\xee\x5e\x62\x5e\x24\x6c\x09\x20\xa5\x8f\x3c\x1a\x3e\x7c\x61\x77\x27\x74\x71\xd7\x6a\xe4\xff\xe1\x62\x85\x7e\x24\xdd\x67\x5f\xe9\xb7\x7c\xf9\xcf\x53\x17\x00\x61\xb9\xb5\x05\x9d\x3b\x69\x0b\x58\x8e\xda\x6f\xa9\x34\xf0\x90\xf4\x2a\x1d\xfa\x75\xed\xd5\x70\xec\xf7\x1f\x50\xb5\xe0\x21\xde\x2c\xfc\x82\xd6\xfe\x0e\xea\x06\x23\x5f\xec\x2d\x54\x11\x8a\x11\x8b\xf4\xe5\x60\xbb\x0d\x35\xc1\xe4\xe6\x60\xbb\x6d\x93\xf1\xc0\xc4\xf9\x33\xbe\xa6\x59\xb0\xa9\x1d\xac\xe8\x2b\x38\xff\xfa\x51\xc6\x93\x78\xc7\xc9\x98\xda\x68\xef\xfc\x72\xf4\x11\x36\xdd\xd3\xf8\x2d\xce\x85\x41\x74\x75\x75\xb5\x12\x4f\x70\x94\xa6\xa3\x95\x38\xb9\x58\x0d\xe2\x7e\xba\x0a\x49\xb8\xe3\x55\xad\xce\x30\x1b\x8f\x2c\x8a\x90\x9d\xcb\xc9\xdb\xed\xdd\x1c\x6d\xf1\x5c\x32\x18\xc2\x7c\x1f\x10\x6d\x8f\x33\xbc\x5f\x58\xca\x73\xd8\xa3\xc8\xc0\xa4\xe4\x21\x8c\xb8\xdb\x8b\x14\xee\x39\x77\x75\x69\xa1\x4a\xbd\xb1\xae\x78\xba\x18\xf0\x1d\x46\x6a\x72\x58\x0c\x3d\x41\xca\xc1\x76\x7b\x1e\xb6\x61\xc6\x6c\x91\xf5\x20\xd5\xd2\x87\x2c\x46\x13\x6a\x75\x2a\x7b\xe7\x38\x76\x38\xc3\x2f\x46\xdb\x1d\xd8\xf0\x6c\xa0\x7a\x63\x1d\x4c\x48\x95\xaf\xb4\x73\x80\xb9\xf6\x25\xc7\x47\x69\xfb\xe6\xd6\x6e\x37\x0e\xa2\x7d\x68\x3f\x1c\x2c\x35\x7a\x0f\x66\xd6\x9f\x83\x81\xe1\x7d\x43\x69\x7e\x4e\x8a\xa6\xf9\x15\xff\xc8\xe7\x6a\x5d\xcb\xe7\x77\x5b\x30\x9e\x3a\x8d\xb5\x5a\x4d\x07\xbc\xa0\x77\xd0\x5c\xbf\x9f\x72\xf2\xee\x36\xa4\xf0\x27\x34\x42\xa8\x02\x12\x61\xfb\x90\x81\x95\x2c\xda\xdb\x58\xe9\xf3\xba\x34\x16\x80\x0d\x50\x41\xe5\xd4\x1f\x65\x68\x0b\xfe\xb3\xb8\x58\x0c\xd4\x45\xc9\xfb\x3e\xc8\x0b\x93\xcd\xe3\x73\x30\x58\xa1\x6e\x11\xb8\xc2\x3b\xe3\x01\x7e\x05\x79\x6b\xa0\xb8\x92\xdf\x51\xad\xb9\x90\xc0\xab\x4e\xb1\x45\xbc\x25\x2b\x9d\x71\x0f\xb3\xb6\xf0\x52\x23\xe4\xc1\x4c\x94\xf3\xd5\x61\x85\xe5\x72\x0b\x83\xd0\x02\x74\x88\xdf\xc2\xd8\xd8\x52\xa2\x2d\x72\x46\xce\x81\x09\x9f\x60\xf1\xc6\x79\x5c\xe6\x7b\x0c\xed\x11\x7b\xb2\x94\x93\x98\x38\x2d\x9a\xbf\xb0\x60\xf9\x86\x6d\x4c\x04\xbc\xfa\x91\x19\xb3\x68\xb8\x72\x83\x96\x57\x1c\x1f\xeb\x51\x80\x88\x71\xe0\x39\xe0\xbc\x60\x56\x5d\x96\x68\xd9\xf9\xd7\xca\x48\x0e\xc6\x90\x3b\x81\x30\x28\x9c\xd8\x24\xa3\x60\x83\x5e\xd5\xe6\x85\x3f\x9d\x59\x82\xd0\x84\x18\x38\xf3\xb3\x72\x50\xaa\xd3\x83\x92\x34\xd0\x85\x69\x7f\x34\xec\x05\xb2\xce\x51\xb0\x61\x6c\x19\x2a\xf3\x9d\x44\x56\x2c\x66\x8c\xb5\x0d\x6d\x94\xa5\x5a\x92\x8e\x86\xd3\x9f\x25\xda\x85\x08\x30\xc7\xeb\x95\xb5\xb9\x2e\xc5\x83\x65\xbf\xe3\x5b\xf1\xde\x05\xf9\xee\x3d\x7a\xdf\x5a\xfc\xca\xa4\xde\x94\xe7\xe6\x52\x25\x45\xbb\x21\xbd\x57\xb9\x7b\xfe\x01\x29\x5c\x5d\x6c\xda\x74\xbf\x76\x71\xf6\xc5\xaa\x79\xc8\x21\x36\xdc\x05\x4c\xa1\xd8\x20\x54\xc8\xb9\xac\xef\xda\x73\x4c\x17\x16\x36\xec\xaa\xc4\x02\x8e\x2b\xc5\xfb\xdd\xcd\xcb\x82\xe3\x3b\x85\x66\x3f\xbb\x7b\xfc\xf0\xb9\xd1\x5e\xf7\xf8\x91\x74\x63\x6d\x8d\x9c\xe9\xd7\xfe\xd2\x67\xfa\x7e\x38\x19\xe2\x64\xf9\x81\x4d\x04\xe0\xf4\x2e\x37\xf5\xe7\x1c\xe2\xcd\xcc\x9d\xf7\x72\x9a\xef\x42\xc7\x8e\x08\xc7\x49\xc5\xa1\x5d\x7e\xe9\x36\x21\x10\xef\xb5\x4c\x18\x4a\x0d\x72\x86\xf3\x33\xa8\x44\x7f\x72\x46\xcc\x2a\xee\xc2\xcb\x8c\x45\x55\xa0\x45\x16\x48\xa7\x41\x4e\x37\x74\x6e\x32\x3c\xcb\xc8\x29\xd2\x67\xcf\x68\x42\xfb\xc4\x7c\xb3\x78\xaa\x0d\x3f\xc0\xfd\x70\xec\x8f\x46\xd7\x2c\x0d\x68\x50\xfa\xe6\x46\x1e\x95\x1b\xd6\x0a\x1b\xb8\x53\x81\x86\xda\xec\xe2\xc9\x38\x6e\x83\xdf\x83\xa6\xe7\xc8\xa7\x44\xba\xd5\x91\x3b\xbf\xd8\xc5\x8e\x52\xd3\xe1\xa8\x25\x97\x59\xc9\x67\x37\x4f\x20\xb1\x87\x67\xb7\xcc\x04\x61\x19\x5e\x89\x7c\xe4\xfb\x86\x05\xa7\x53\xbb\x79\x08\xa3\xc9\x34\xbb\xcb\x9c\x72\xf2\x50\x89\xee\x16\x74\x76\x5f\xc4\xd1\xd7\x18\x85\x85\x3e\x6e\x9d\x54\x02\x46\xcb\x1e\xc2\x26\x9f\x9c\x4d\x94\xb7\x41\x2b\xbc\xb4\x52\x4f\x57\xa1\x1e\xae\x11\xc8\x01\x6d\xc8\x40\x6f\xec\xba\x79\xf7\x4e\x9b\x77\x57\xdb\x6d\xa5\x0d\x62\xa3\xdd\xf0\x34\xe5\xf9\xfa\xa3\xa9\xdd\xdf\x5d\xf7\xed\xda\x1d\x8d\x48\xe6\x45\x9a\x70\xf3\x90\x02\x0e\xc0\x42\xe3\x6a\x4d\x44\x45\x4a\x6c\xca\x8e\xaa\xf7\x93\x90\x1e\x5c\x5e\xe7\x72\xbc\xd2\x4a\xe2\x92\xaa\x28\x22\xab\x83\xf3\x32\xee\x27\x38\xbb\x27\xa5\x12\x91\x7f\xf7\xec\x81\x83\xa0\x97\x8c\x4d\xd8\x3c\x91\xa9\xa3\x6f\x59\x8d\xa1\xec\x1c\xec\x08\x10\x6c\xd5\x19\x09\x7d\x11\xf5\x51\x10\x8f\xba\x87\x7b\x81\xb7\xdb\x7d\xc6\x97\x85\x03\xd3\x9c\xf0\xb2\xf4\x50\x25\x45\x97\xd5\xc7\xc9\x6e\x88\x5f\xa0\x98\xa2\x1d\x7d\x2d\xc5\xc5\x64\x5d\x2f\x8a\x8c\xa9\x55\xe2\xfa\x02\x1d\x96\x3d\x4a\xe6\xd6\x68\x14\x5f\x21\x3f\xe9\x85\x59\xe2\x27\xd7\x88\xa9\x97\x3e\xe3\x6b\x4b\xdc\xc1\xcf\xb2\x46\xe2\x67\x6b\xc3\x05\x03\xa5\xab\x5b\xca\x8d\xd6\x1c\x67\x48\x82\x52\x81\x1b\x24\xc4\x7f\x03\xdd\x46\x9c\xa0\x30\x8a\x70\x02\xd1\x67\xe3\x69\x06\x02\x84\x1e\x85\x0f\x62\x26\x52\x1d\x23\x25\x43\xf6\x40\x5b\x31\x02\xd2\x71\x8d\x9f\x5c\x23\xb4\xd4\x58\x84\x04\x62\x49\x2b\x19\x17\xe9\x23\x43\xa9\x60\x28\x15\x34\x1a\xfb\xed\xf0\x18\xe6\x93\x5e\x03\x4e\xfc\x00\xf5\xe3\x28\xcd\xfc\x48\x6f\xde\x9a\x44\x4a\x9d\x63\xb7\x62\x4d\xe0\x7d\x16\x9e\xa3\xdf\x37\x51\x6d\xd6\xee\xd3\xff\xd9\xdc\x61\x8c\xc2\xcd\x0e\xfd\x5f\xb1\x66\x2c\xd6\x74\x62\xa1\xf6\x6c\xa3\xc8\x3f\x21\x0e\x19\xec\x40\x0f\x11\x85\x4c\x30\xf1\x7b\x89\x44\x56\x90\xaf\xcc\xc6\x8c\x2d\x03\x09\x9d\xb6\xf1\x71\x87\x9e\x54\xd5\x17\xe7\x0b\xe6\x76\x11\xc8\x60\x98\xbf\x9b\xf8\x63\x07\x5b\x5d\x16\x7d\x0c\xf0\x0a\x61\x89\x15\x46\x42\x59\x70\xca\xcb\x04\x22\x33\x4a\xdf\x7f\x30\x32\x99\x24\x78\x2b\x73\x83\x8f\x3d\x54\xf4\x30\x18\xea\xff\xf4\xe8\x61\x73\xc4\xd4\x45\x44\x44\xc2\x43\x73\x1a\x9a\x1b\x41\xcc\x5d\x63\x6e\x14\x31\x77\xd5\x07\x8a\x24\x76\x77\x6e\xd7\xa5\xea\x69\x18\x6f\xcb\x7e\x4c\xa4\x8b\x3d\x7b\x70\xb4\xc2\x80\x63\x85\x1c\x53\x1e\x2b\x0d\x68\x2e\xa1\x70\x49\x83\x5f\x32\x09\x54\xaa\xce\x90\x63\x63\xbf\x6f\xbf\x24\x12\x07\x7f\x87\x11\xdc\x8b\xbf\xb4\xc2\x7c\xd6\x69\x2d\x5b\x5e\x8f\xc2\xde\x32\x41\x25\x00\xdb\xd6\x54\xfb\x8a\xa3\xfe\x32\xd8\x34\x5a\xde\x53\x37\x4b\xed\xc3\x38\x68\xcf\x37\xbe\x4b\x87\x7e\xa3\xad\x83\x24\x2f\x1b\x3a\xb8\x74\xe8\xb7\xeb\x0d\xf3\x65\x73\xdd\x52\xb2\xa9\xbd\x4a\xc2\x09\x1e\x07\xf5\x4e\xcd\x6a\xfb\xa7\xbc\x9a\xf4\x3e\x07\x03\xbd\x1d\x7c\x39\xf9\x1c\x0c\x8a\xee\x1d\xd4\xae\xc7\x01\x5e\xee\x0f\x7a\xd6\xd7\x59\xe2\x78\xbd\x7c\x31\xf2\x83\xb1\x1f\xd9\x3e\xc7\x76\x60\xb8\xaf\xbf\x9e\xf8\xc1\xb2\x1f\xa5\xe1\xec\x45\x43\x1f\x04\xf2\x29\x4c\xe3\x7a\xad\xde\xd0\x47\x9c\x7d\x7a\xb1\xf6\x62\x4d\x9f\x21\xf2\xe9\x0b\x4e\x62\xe6\x7a\x6d\xf9\x1a\x39\xbe\x51\x1d\xd9\xf2\x10\xcf\xb4\x0f\x3e\xd6\x89\x8b\xc6\xdd\x08\x8c\xf7\x49\x5f\x9f\xdc\xc4\xef\xf5\xc2\xcc\xfa\x72\x79\x84\x2f\xfc\xfe\xf5\x43\xdf\x01\x89\xd5\x03\x4f\xfa\xa2\x81\x97\xf9\x5a\x11\x8f\x6c\x89\xc0\x33\x59\x19\x9a\x59\x28\x5b\x07\xe2\x77\xa3\x25\x7e\x13\xaa\xe7\xbf\x09\xb1\x8b\xdf\xf4\x57\x4e\xda\xb9\x7d\x29\xfc\x62\x84\x4c\x31\xa0\xf4\x6b\xdc\x61\x51\x74\x38\xb5\x4a\x4f\x59\xa2\x3e\x09\xda\xcc\xdf\xc6\x4a\x0d\x42\x89\xb4\x59\x99\x00\xc5\x1b\x41\x77\xf2\x1b\x4a\x6e\xe2\x8d\x4c\x65\xe2\x65\xa4\xbe\x92\x68\x0a\x9e\x09\x29\xc1\x8f\x9c\x82\xe8\xa8\xf4\xd9\x40\x31\x7a\x91\x7e\x73\x32\x59\x54\x11\xa9\x28\x20\x65\x5e\xbb\xb8\x62\xd2\x1d\x8a\x8d\x75\x69\xa3\x5d\xf7\x8a\xb5\xc9\x9e\x4a\x57\x1b\xed\x96\xa7\x10\xde\x46\xbb\xed\xe5\x13\xbf\xd1\xee\x78\xea\xe8\x6d\xb4\xd7\xf4\x1b\x61\x9d\x94\x37\x3a\x35\x8f\x51\xeb\x46\x07\xf0\x11\x94\xb2\xd1\x69\x78\x32\xad\x6c\x74\x5a\x9e\x8d\x5a\x36\x3a\x4d\x4f\xa6\x90\x8d\x4e\xdb\x93\xe9\x67\xa3\x03\x78\x29\x34\xb3\xd1\x59\xf3\x74\xaa\xd9\xe8\xac\x7b\x3a\xdd\x6c\x74\x5e\x78\x06\x91\x6c\xac\xd5\x3c\x0b\x39\x6d\xac\x01\xfe\x6c\x49\x6c\xac\x01\xf6\x8c\x34\x36\xd6\x5a\x9e\x41\x1c\x1b\x6b\x80\x38\x21\xa3\x8d\x35\xc0\x39\x5f\x67\x1b\x6b\x1d\xf9\x02\xdd\xcb\x97\xec\xc6\x1a\xbf\x5a\x27\x8b\x79\x63\xed\x85\xc7\x97\xea\xc6\x7a\xcd\xcb\x97\xf0\xc6\x7a\xdd\xcb\x17\xf7\xc6\x3a\xa0\x93\x53\xf0\xc6\x3a\x34\x2e\x18\xcd\xc6\x7a\xeb\xe6\xdc\xeb\xd4\x1e\x2f\x0f\xfe\xfc\xcb\x83\xee\x10\xf7\x3f\x93\x4e\xc1\x4a\xa1\x6e\x40\x34\xcd\x59\x3a\x9d\x90\x81\xc1\x2c\x3e\xb5\xd4\x6f\x90\xe3\x69\x48\x73\xf4\xc3\x26\x7a\xc6\x21\x3f\xb3\x58\x84\x08\x27\x8d\x7b\xbc\xae\x28\x34\xc7\x17\xed\x1c\xe3\x01\x4e\x30\x1c\xf4\x92\xf0\x02\xce\x64\x61\x14\x66\x39\x98\x74\x3a\xc1\x09\xa8\xae\x37\xb5\xf4\x1c\x12\x94\xad\xe9\xc5\x18\x47\x99\x56\x00\x65\x31\x1a\xfa\x51\x30\xc2\xca\xb8\xc9\xb0\x7b\x56\xc8\x8a\x4d\x0d\x54\x35\xdd\x01\x25\xdd\x37\x8d\x25\x4f\x4d\xa0\xc2\x28\x5b\x97\x34\xf4\x03\xb9\xbe\x50\x4c\xa8\xb3\x63\x1e\xf3\xf3\x1a\x54\x09\xff\x81\x40\x85\x17\x32\x36\xca\x21\xc2\x8a\x58\x4c\xd3\x7f\x01\xa4\xcb\x10\x5f\xb9\x50\x74\x36\x2f\x21\xbc\xcf\x51\x40\x5f\xbf\xaa\xe5\x39\xc1\x01\x96\xa0\x33\xe6\xd5\x7f\x20\x6b\x4e\xd8\x8e\xc0\xa2\xb3\x03\x37\xaa\x56\x8d\x56\x9c\x58\xd5\x3b\x76\xb4\xdc\x2d\x2d\x56\x63\x3f\xca\x9a\x8d\x45\x9b\x58\xac\xc6\xee\x28\xf6\x6f\x53\xa5\xd3\x82\xf7\x79\xf9\x5b\x92\xd2\x0a\xa5\x60\x0f\xc9\xaf\xae\x33\x7c\x08\xc9\x81\x8c\xd7\xb6\xbc\xcb\x0a\xfd\xed\xd1\x45\x97\xb7\x55\x66\x45\xe4\xa5\x17\x53\x21\xe4\xd0\x5e\x0b\xdc\xd0\xa6\x1d\x67\x8b\x66\x61\x67\xc6\xb2\xaf\x5e\x67\x36\xe3\xe7\x85\xdc\x05\x6d\xa8\x2c\x92\x4f\x3b\xaf\x7f\x16\x9e\xdf\x2a\x79\x76\x6e\xce\x1d\x7e\xc1\x54\x55\x9b\x3b\x8e\xaa\x45\x05\x63\xcd\x53\x5b\x78\x88\xb9\x11\xda\x3a\xa2\xcc\xb7\x35\xeb\x19\x19\x4d\xf2\x9a\xc0\x43\x11\x91\xfa\x64\x66\x6e\xb6\xeb\x4f\x26\xa3\x6b\xd6\xb0\x9f\x5c\x4c\x09\x0b\x4f\x8b\xfc\x15\x19\xbf\x5e\x99\x24\x71\x16\x13\x1c\x65\xce\x5d\x64\x38\xa1\xef\x3e\x76\x05\x4b\xa7\xfe\x28\xeb\xfc\x39\xb2\x0e\x04\x8c\xfe\x13\xe2\x12\x59\x73\x2a\x95\x30\x91\x80\x2d\x96\xde\xe3\xa1\x2c\xd7\xad\x93\x2a\xa7\x8c\x59\x48\x25\xa9\xea\x52\xbb\xf9\xb3\x49\x7a\x2e\xbe\xd2\x69\xd9\xb9\xc8\x29\x61\x13\x9b\x74\xf8\x56\xfc\x5e\x4a\x7f\xa4\x61\xc4\x82\xb1\x12\x96\x51\x9b\xd5\x6b\xec\xaf\x8a\xbe\xaa\x69\x7c\xd9\xf2\xaa\x54\xad\x16\xea\x07\xdb\x6d\xcd\x9a\xc2\x66\x00\xa2\x7b\x4d\xa2\x4d\x36\xaa\x16\x03\x10\x9e\xf6\xa6\xf0\x76\x2c\xd7\x04\xdb\x73\x15\x9f\x99\x9c\xb4\x36\xeb\xac\xb5\xda\x8d\x66\xad\xee\xa1\xda\x0c\x0f\xfa\x81\xdf\x5b\x7f\x61\xc9\xab\x58\x9b\xbd\x58\xef\xf9\x41\x7f\x80\x3d\x18\x98\x66\xa3\xdd\x5a\xeb\xa8\xe5\xce\x9d\x37\x62\x5a\x1a\x3d\xb9\x17\x07\x22\x93\x9e\x6d\xef\xba\xf2\x27\x08\x83\x7b\xf5\xfc\x3d\xa4\xde\x71\xef\x18\xee\xeb\x6b\x3e\x1b\x14\x89\x8f\x04\x1e\x4f\x2f\x88\x42\x47\x04\xde\x83\x8f\x52\xe9\x83\x33\xfe\x70\x6e\x73\x09\x91\x3e\x13\x82\x33\x0b\x90\xbf\x4a\xa5\x22\xc1\xa4\x9e\xe2\xe8\x2b\x92\x5f\xc2\x5e\xd7\xaa\x6a\x3e\xe2\xe8\x6b\x49\x80\x8d\x56\xd5\x02\x10\x42\x19\x2b\x2e\xe9\x26\xb8\xbb\x19\x87\xec\x29\x37\x14\xf6\xeb\x7e\x65\x48\x6b\x48\x1a\x53\xb4\x84\x6a\xba\xf8\xa0\x94\xae\x6b\xa5\xeb\x85\xa5\x1b\x5a\xe9\x46\x61\xe9\xa6\x56\xba\x59\x58\xba\xa5\x95\x6e\x15\x96\x6e\x6b\xa5\xdb\x85\xa5\x3b\x5a\xe9\x4e\x61\xe9\x35\xad\xf4\x5a\x61\xe9\x75\xad\xf4\x7a\x61\xe9\x17\x5a\xe9\x17\xc5\xb3\x53\xd3\x66\x67\xce\x64\xd6\xb5\xe2\xc5\xb3\x59\x6f\x68\xc5\x8b\xa7\xb3\xde\xd4\x8a\x17\xcf\x67\xbd\xa5\x15\x2f\x9e\xd0\x7a\x5b\x2b\xde\x36\xb8\xc1\xea\x2a\x61\xc8\x9f\xc3\xe8\x82\x54\x0d\xfd\x51\xcf\x26\x36\xfb\x64\x1b\x38\xb3\x0e\x54\x0f\x3e\x59\x07\xa5\x0f\x9f\xac\x03\x10\xc0\xa7\xa6\x0d\x9d\x6e\x7e\x07\xad\x7e\x23\x48\xec\xee\x56\x7c\x0f\xf5\x3c\xd4\xf7\x50\xe0\x49\x0b\xd4\x43\x68\xcd\x23\x5b\x68\xed\x5c\xe7\x0d\x01\xad\x17\x78\x48\x54\xcd\x47\xc8\x43\xa8\xde\xf0\xd0\xe9\x59\xdd\xa8\xd7\xa7\xf5\x68\x4b\xb4\x6a\xbe\x68\x49\xbd\x35\x52\xaf\x61\xd4\xeb\xd1\x7a\x02\x49\x5f\xaa\xd7\xf4\x10\x6a\x40\x7b\x4d\xa3\x5e\x51\xff\x5a\xa2\x7f\xad\x85\xfa\xd7\x16\xfd\x6b\x2f\xd4\xbf\x8e\xe8\x5f\x67\xa1\xfe\xad\x89\xfe\xad\x2d\xd4\xbf\x75\xd1\xbf\xf5\x85\xfa\xf7\x42\xf4\xef\xc5\x42\xfd\xab\xd7\x3c\xd6\xbf\xba\x49\x30\x45\x1d\xac\xd7\x3d\xd6\xc1\xba\x49\x31\x45\x3d\x24\x58\xd2\x1e\xd6\x4d\x92\x29\x24\xd1\xa6\xc7\x49\xd4\xa4\x99\xc2\x3e\xb6\x44\x1f\x4d\xa2\x29\xec\x63\x5b\xf4\x11\xa8\xc6\xec\xe4\x9b\x37\x8e\x4e\x7a\x08\xb5\x69\x27\x4d\xba\x09\x68\x45\x6b\x27\x09\xbd\xbd\xa0\x15\x4d\xc2\xe9\xd3\x8a\xf6\x4e\xd6\x3d\x44\x3a\x7a\x7a\x56\x37\x29\xa7\x47\x2b\x5a\x3b\x49\x38\x46\xa3\x06\x15\x4d\xd2\x29\xea\x63\x5b\xf4\xb1\x61\xe7\x35\xae\x3e\x12\x9a\xa3\x7d\x6c\xd8\x99\x8d\xb3\x8f\x6d\xde\xc7\x86\x9d\xdb\xb8\xfa\xd8\x12\x7d\x6c\xd8\xd9\x8d\xab\x8f\x2f\xf2\x3e\xda\xf9\x8d\xb3\x8f\x2d\xd1\x47\x3b\xc3\x71\xf5\x91\x30\x46\xd6\x47\x3b\xc7\x71\xf5\x71\x3d\xef\xa3\x9d\xe5\x38\x69\xb5\xe9\xf1\x3e\xda\x79\x8e\xab\x8f\x0d\x41\xab\x0d\x3b\xd3\x71\xf5\x71\x4d\xf4\xb1\x69\x67\x3a\xae\x3e\x92\xe5\x4f\xfb\xd8\xac\xdb\x17\xe4\xde\x9e\x9b\x58\x5b\x80\x6b\xd3\xce\x75\xf6\xf6\xec\x9d\x24\xc3\x4a\xd6\xd6\xe9\x59\xd3\xce\x75\xf6\xf6\x0a\x16\x64\x07\x2a\xda\xb9\xce\xde\x9e\xa3\x93\x2d\x0f\x35\x9a\x50\xd1\x24\x9d\xa2\x3e\xd6\xf3\x3e\xda\x99\x8e\xab\x8f\xad\xbc\x8f\x76\xa6\xe3\xea\x23\x4c\x24\xed\xa3\x9d\xe9\x38\xfb\x58\x13\x7d\xb4\x33\x1d\x67\x1f\x9b\x1e\xeb\x63\xcb\xce\x74\x5c\x7d\xac\x89\x3e\xb6\xec\x4c\xc7\xd5\xc7\xa6\xe8\x63\xcb\xce\x74\x5c\x7d\x24\xac\x9c\xf6\xb1\x65\x67\x3a\xae\x3e\xbe\x10\xf3\xd8\xb2\x33\x1d\x57\x1f\xc9\xf2\x60\x7d\xb4\x33\x1d\x27\xad\xb6\x39\xad\xb6\xec\x4c\xc7\xd5\xc7\x46\xde\xc7\x35\xfb\x82\xdc\xdf\x77\x0b\xaa\x1d\xda\x49\x3b\xd7\xd9\xdf\xb7\x77\x12\x68\x0e\x78\x40\xcb\xce\x75\xf6\xf7\x0b\xc4\x80\x36\x88\x80\x76\xae\xb3\xbf\x6f\xef\x24\xe1\x1d\x0d\x18\xd6\xb6\x5d\xd4\x71\xf5\x91\xcc\x07\xed\x63\xdb\xce\x74\x5c\x7d\x6c\x8a\x3e\xb6\xed\x4c\xc7\xd9\xc7\x9a\xe8\xa3\x9d\xe9\xb8\xfa\x58\xcf\xfb\x68\x67\x3a\xae\x3e\xae\x8b\x79\x6c\xdb\x99\x8e\xab\x8f\x40\x73\xb4\x8f\x76\xa6\xe3\xea\x23\x88\xe4\xb4\x8f\x76\xa6\xe3\xec\x63\xd3\xe3\x7d\xb4\x33\x1d\x57\x1f\x5b\xa2\x8f\x1d\x3b\xd3\x71\xf6\xb1\xce\xfb\xd8\xb1\x33\x1d\x57\x1f\x1b\xa2\x8f\x1d\x3b\xd3\x71\xf5\xf1\x85\x98\xc7\x4e\xd3\x5c\x90\x70\x8d\x92\xe1\x64\x8c\x83\xd0\xcf\x98\x53\x19\xb8\x2b\xa8\xe5\xc8\x11\x17\x6d\xa2\x0a\xfc\x77\x09\xf9\xba\x86\x95\x96\xa9\xb3\x32\x75\x52\xa6\x67\x2f\xd3\x60\x65\x1a\xa4\x4c\xdf\x5e\xa6\xc9\xca\x34\x49\x99\xc0\xd0\xe6\x6a\xaa\xca\x5d\x8b\xa5\xee\x82\x01\x6d\x21\x53\xba\xc8\xa6\xeb\x67\xbe\xed\x60\xee\x67\xbe\x08\xe5\xe3\x67\xbe\x5b\x39\x16\xbd\x0e\xb3\xf4\x34\xce\xfc\x91\x80\x19\x6d\xfb\x99\x4f\x3d\x48\x9e\xa3\x75\x0b\x74\xa8\xf3\x0e\x0f\x32\x0e\x5d\x78\x9c\x40\x79\xa3\x33\xce\x94\x57\x02\xcd\xb3\x1c\xe4\xcf\x3f\xff\x8c\xda\x70\xf1\x56\x9b\xad\xd7\xf2\xfb\xb6\xbc\xc4\x3f\x50\xb3\x61\x10\x87\xda\x97\x3d\xb4\x89\x40\xed\x3e\x18\xc5\x71\x52\x91\x3a\xb9\xaa\xe8\xde\x5d\x9d\x83\xb2\xef\xd0\xa6\xf4\xa4\x2f\x1c\x81\x7a\xa5\x52\xc9\x71\x5b\x42\x9d\x16\xcd\x97\xf6\x02\x82\x89\xb6\xaa\x54\x61\x63\xd7\xcf\xf2\xaa\x0c\xe7\x5c\x39\x2b\xbf\x2d\xaf\x9d\x35\xc1\x31\xd5\xac\x0e\x6e\x9e\x6e\xd6\xe0\x12\x8b\x74\xb6\x55\xa6\xb3\xef\xac\x9d\x7d\x77\xdb\xce\xbe\xb3\x76\xf6\x5d\xd9\xce\x9a\xbd\x95\x9d\xa8\x2a\xa2\xfb\x3c\xd8\x14\xe4\xd4\xb3\xfb\x0f\x82\xc1\x3b\x75\x63\x00\x1f\x45\x9b\x27\x55\x61\x5e\xf9\x39\xde\x90\x8a\xce\xdb\x42\xbe\x7b\xcc\x30\xde\xe9\xfd\xb6\xd0\xbd\x87\xe3\x8a\x0b\x15\x5d\xff\x0b\x4c\xe0\x0a\x63\xef\xcc\x7e\x77\xb1\xc7\x6e\xc9\x2a\x95\x3d\xe5\x5a\x62\x6f\xe1\xfb\x08\x4a\x0b\x7b\xca\x5d\xc4\x9e\xf3\x12\x62\xfe\x8d\xc3\x31\xcb\x0d\x0c\x73\xc8\x22\xf0\x04\x30\xa6\x6a\xd1\x12\xc9\xca\xc1\x0d\xa1\x90\xd5\x83\x82\x15\x9c\x32\xc5\x0d\x1d\x3c\xe6\xd7\xff\xc6\xc6\x0b\x9f\x3f\x1a\xb4\xe0\xf2\xae\xe4\x11\x34\xc8\x57\xbb\x87\x03\xfd\x25\x90\xd4\x54\x5f\x33\x0f\xa5\x1e\x52\xaf\xd0\x80\x4f\xa2\x4d\xe4\xa3\x25\x54\xa9\xf4\xd0\x4f\x74\x73\xac\xfc\x9b\xfc\x0c\xaa\x84\x0d\xcc\xd0\x12\xca\xa4\xf6\x44\xc0\xe2\x88\x4c\x53\x4a\x57\x2a\x8d\x53\xde\x6c\xa0\x65\x94\x56\xa1\x5a\x4f\x33\x7a\x13\x58\x69\xe7\xff\x72\x58\xc1\x76\x5c\xe9\xa3\x9f\xd0\xbf\x1f\x06\x2b\xed\x10\x34\x17\xab\x1e\xfa\x1d\xf5\xd1\xef\x04\xb1\xfb\x47\x46\x13\x00\xe7\x22\x43\x10\xa9\xf4\xd0\xd7\x7b\x1e\x1c\xf9\xb6\xfa\xc4\x95\x26\x7d\x6e\xe2\xfd\x32\x41\xd6\xb8\x9f\x98\xe6\xa2\x08\xab\xc1\x04\xe3\x70\x16\x73\x94\xbe\x6d\x58\x33\xb6\x2e\x85\x91\xcb\xc1\x76\xdb\xe2\xfb\x55\x5c\xde\x74\xf8\xca\xe3\x8b\x29\x97\xf9\x6a\x46\xfe\x83\xed\xb6\xd5\x64\xc0\x39\x09\x73\x72\xd5\xdf\xd7\x14\xdc\x2a\xb4\xc3\xfc\x89\x93\xbd\xfc\xee\x63\xe2\xa8\x53\x99\x98\x88\xbd\xb1\xdf\x27\x93\xa1\x64\x86\x37\xe7\x83\x15\x33\xe7\x24\xcf\x66\x4f\xe7\xa5\x30\x03\x3b\x8b\x6c\xed\xb0\x80\x6a\xfc\xa5\x5d\xcc\xfe\xfe\x31\xd9\xe8\x62\x7b\xce\xe2\x0c\xa1\x5d\x8c\x83\x9e\xdf\xff\xcc\xe2\x6a\x8e\xe3\x00\x96\x14\xa1\x19\x31\xdf\xf0\xb2\xbb\xfb\x9a\x88\x40\x16\xf1\x00\xcc\x9c\xe0\xab\x62\x2d\x07\x16\x2e\xb4\x95\x03\x02\x80\x19\xf3\x88\x55\xdf\xdd\x7d\xbd\xb2\x13\xd1\x58\xe5\x60\x40\xb5\xfb\xda\x62\xf0\x33\x71\x98\xcb\x30\x33\xc3\x02\x93\x19\xb7\x68\xca\x42\x50\x71\x81\x84\x3e\xda\xee\x99\xa5\x50\x1e\xb4\x90\x1c\xca\x43\x2d\xcf\x63\x94\xbf\xc5\xd7\x69\x96\x60\x7f\xbc\x15\x05\xac\x77\x16\xeb\xc8\x98\x99\xc5\x0a\x70\x1e\x6b\xc0\x26\x64\x1f\xe3\x31\x86\x20\xe3\x60\x8c\x49\xe7\x89\xc5\xca\x04\xff\xf9\x08\xcf\x32\xfa\xda\x2e\xbe\xe3\xcb\xd7\x2c\x66\x2a\xb4\xbe\x92\x8e\xc2\x3e\xae\x70\x14\xc4\x4d\xbd\xc0\xc5\x66\x3f\xa9\xcc\xda\x36\xfe\xbb\xcc\xda\x1d\x46\x17\x0c\x87\x87\x61\xba\xf0\xd8\x7e\x33\xba\x39\xcd\x3b\xd4\xc3\xfd\x78\xcc\xbc\xee\x09\x41\x84\xf1\x34\x2d\x47\x32\xa2\x8b\xa5\xc4\xf1\x82\xde\x54\xe6\x76\x41\xf3\x8d\x30\x0f\x6c\x70\xde\xbb\xcc\x83\xb5\x5c\xbe\x54\x8d\xc6\xe5\x70\xcc\xb4\xf9\xfc\x33\x64\x76\xbd\xb4\x1e\x69\x44\x69\xb4\x89\xc2\x4b\x36\x85\x35\xc7\x4a\x8c\x2f\x31\xda\xff\x05\xce\x9f\xe9\xb4\x97\xe2\xff\x9d\xe2\x28\x2b\x38\x3d\x03\xbe\xc2\x81\x61\xae\x01\xb4\x8e\x8f\x36\x21\xe6\x24\x90\x3f\x46\xe5\x98\x0e\x34\x14\xac\x08\x20\x1e\x52\xbb\xb2\xba\x8a\xd8\x8c\xe4\xef\xac\xd9\x72\x8b\xa3\xc6\x50\xd3\xf3\xdc\x42\x10\x22\xc1\x88\x46\xe1\x1c\x6d\xd0\x0b\xc3\x82\x8b\x13\xbb\xaf\x8b\x0c\xae\xf9\xa6\xb3\x48\x9c\xba\x4e\xf3\x51\xf8\xf8\xde\x85\x0f\xf4\xdf\x93\x04\xa7\x38\xb9\xc4\x54\x0c\x89\xa7\x44\x94\x97\xc4\x0f\x50\x63\xf8\x59\xd8\x1b\x31\x0e\x8c\xb6\x13\xf4\x3a\x09\xfd\x08\xbd\xa1\xee\x99\x68\x10\x8e\x30\x8e\xfa\x2b\x7d\x00\xc1\x43\x3e\x43\x04\x6c\x8d\x7e\x4e\x8f\xa1\xc8\x3f\xfd\x08\xed\x25\xd3\xde\x35\xfa\x34\x24\xff\x59\xb9\xc2\xbd\xff\xbe\x18\xfb\xe1\x68\xa5\x1f\x8f\xed\xf2\xce\xe9\x31\x6f\xae\x40\xec\x91\x0b\x95\x96\x7e\x9e\xe4\xf9\x5e\xa2\x3e\x39\x28\xd0\x94\x49\x4f\x9f\x3c\x21\x83\x0e\xa4\x27\xd2\x21\x81\x92\x88\x2a\x85\xaa\x30\xeb\xf4\xd7\x1f\x68\x75\x35\xbe\xc4\xc9\x60\x14\x5f\x91\x3a\xb0\xf1\xd5\x79\x3a\x50\x52\xaf\xde\xa9\xfe\x44\xca\xbe\x14\x9f\x1b\xf2\xe7\x75\xfd\x6b\x93\xed\x61\xac\x31\xc0\x13\x50\x21\x60\x45\xbb\xab\xab\x88\x37\x8b\x7a\x75\x52\x04\x50\x86\xa6\x6b\x2f\x45\x95\x46\x5e\x45\x94\x79\x02\x08\xd0\x42\xb4\x54\x53\x2d\xc5\x8a\x3d\x01\x54\x58\xb9\x1b\xf8\x97\x10\xa4\x5c\x62\x69\xa9\xd7\x94\xbe\xc3\x3f\xbc\x0c\x2d\xb2\xb4\xd4\x6b\xbc\x7c\xea\x2e\xb0\xb4\xd4\xab\xb3\xef\xe4\x5f\xe8\x38\x6f\x14\x1e\x96\x36\xa1\xe7\xaf\x5e\xb1\x7c\x90\xf2\xeb\x06\x55\x01\x2a\x6f\x19\x42\x66\x4b\xa2\x5a\x6d\x56\xab\x33\xad\x5f\x5e\x94\x71\x3d\x52\x88\xbc\xbc\xd1\xa9\x83\x2d\x8f\x4a\x9f\xfe\x57\xa5\x11\xf6\x92\xde\x20\x71\x52\xca\x5f\x56\x19\xc1\x48\x53\xb0\xba\x8a\xc8\x2e\x01\x37\x31\x28\x94\x16\x12\x5d\x3c\xc6\x4a\x7b\x96\x22\x80\x97\xa2\x38\x1a\x5d\xd3\xe5\xb8\xfd\xeb\xe1\xf1\x36\xfa\x84\x5e\xa1\x75\x80\xc9\x1b\xac\xdb\xb0\xa0\x77\x71\x6a\x67\xd9\x37\xde\x5f\xbe\x96\x94\xb3\x80\x58\x57\x2b\x8e\xd7\x7f\xa2\xcc\xb9\xa8\xc8\x69\x14\xd7\x64\x18\xb3\x55\xc6\x13\x45\xb3\x7c\xc0\x0c\xd4\x8b\x24\x1e\xe4\x96\x7a\x40\x68\xb0\x37\x52\x2c\x03\xa1\x5b\xc8\x41\x68\xbe\x2c\xc4\xa5\x03\x42\xd8\x26\xcd\x53\x56\xf4\x44\x17\x8d\xd8\x67\x09\x57\x55\xf5\xbc\x88\x50\x84\x1c\x82\x11\xba\x9d\x70\x84\x16\x14\x90\x90\x2a\xcf\x99\x87\xae\x9c\xee\xe5\xb3\x97\x58\x1a\x2f\x35\xc9\x4a\x14\x97\x04\x2c\xa7\x88\x25\x15\x5e\x40\xd2\x6a\x3d\x4a\x5a\xdf\xbb\xa4\xe5\x90\xaf\x1c\xea\x9d\xd3\xe3\x62\x39\x67\x51\xf5\x8e\x85\xa5\xeb\xbc\xfc\x91\x89\xff\xfd\x98\x78\xe1\x69\xf6\x01\x58\xf6\x7e\xd4\x4f\x30\x44\x6e\x60\xc0\x35\x90\x4c\x0e\xc9\x27\x77\x19\x51\x63\x1a\xc7\x17\xb8\x2d\xff\x8a\x6a\x7f\xa9\xcd\xa1\xec\xae\x30\xff\xbc\x4d\xca\x2c\xb0\x0b\xb4\x1f\x77\x81\xbf\xc4\x2e\xb0\x33\xc2\xfd\x2c\x89\xa3\xb0\x8f\xba\x71\x80\x7b\x71\x3c\x5f\xe1\xbf\xd3\x2d\x52\xf8\xd3\xaf\x0b\xed\x08\x3b\x5d\x55\xe1\x4f\x9e\xef\x6b\x07\x90\x59\xbb\xca\x40\xd4\x7a\x45\x5a\x4c\x82\x8f\xb2\x90\x1e\x0a\xbf\x00\xdf\x0a\x3f\x9e\x7a\xa9\x3b\x5f\x6f\x06\x65\x16\x58\xc7\x7f\xed\xe4\xc8\xff\x39\xeb\xf8\x70\x9a\x4d\xa6\x59\xf9\x4b\xbb\xc3\xc2\x4b\xbb\xc3\xc5\x2f\xed\x74\xa9\xee\x50\xbb\xc4\x3b\xfc\x73\xaf\x83\x1e\x5c\xaa\x33\x75\xf3\xe2\xcd\xfd\x4a\x76\x05\x0d\x7d\x2f\xd2\xdd\xdf\xe9\x84\x7d\xa8\x5d\x6b\xba\x84\xa8\xc3\x12\x97\x16\x87\x0b\x5e\x5a\x3c\x66\xb1\xfb\x6b\x30\xdf\xad\xf7\x27\xfb\xe8\xb7\x95\x17\x8d\x26\x37\x10\x47\x69\x46\x96\xf7\xc5\xb5\xc1\x7d\x27\x7e\xb0\xb2\x15\xa5\xe1\x6f\xa4\xb4\xc8\x05\x37\xf1\x03\x99\xfd\x05\x7e\xe6\x4b\x17\xa1\xae\x0b\xd0\x54\xbd\x01\x25\xb5\x4e\x72\x83\x5f\xc5\x00\xf8\xa5\x5a\xb4\xa7\xa7\x15\xe9\xb9\x12\x8a\x00\x51\x4c\xa3\x4c\xf4\x4c\x0b\x66\x05\xb6\x78\x47\xf4\x9b\x01\x8c\xbe\x58\x56\x31\xfb\x87\xf6\xdd\x68\x8d\xc6\xb4\x19\xf9\x29\x8d\x9c\x85\x26\x71\x1a\xaa\x1e\xf8\xa4\x51\xf2\x9d\xd4\x3f\x8a\x79\x67\x45\x0b\x4b\x1a\x46\xcb\xa8\xae\x35\x72\xe4\x07\xf9\x33\x0c\x94\xc8\x36\xa2\xbe\xa6\xac\x44\x6e\x2b\x0f\xa9\xa5\x36\x92\x87\xd4\x92\x4b\xdb\x82\x6b\xa9\x96\xd9\x4b\x1a\x20\x6e\x87\xc8\x2d\x70\xa7\x91\x85\x38\x74\x8a\x78\x83\x33\x29\xe1\xbc\x32\x55\x54\x81\x2f\x46\xb3\x78\xe6\xa4\x3e\x57\x54\x34\x97\xc9\xf1\x97\xf5\x3d\xbf\x08\x92\x50\x60\xfb\x8a\xe1\x21\xa1\x81\x71\xf4\xf6\xe9\x93\x1b\x2b\xdf\xe4\xcb\x65\xf6\xa2\xd1\x5c\x88\x77\xde\x2d\x31\xd9\x23\xef\xfc\x56\xbc\x73\xff\xe4\x10\x41\x48\xdc\x72\xac\x73\x9f\x05\xd0\xbd\x2b\xeb\xfc\xd3\xd9\x61\xbe\x24\xe6\xf0\x43\x0b\xab\xa2\xe9\x00\xec\x11\xe8\x56\x12\x3f\x0a\xe2\x71\xc5\xe0\x80\xd5\xea\x8a\x26\x29\x15\xc3\x61\xa9\xc3\xce\x0c\x2e\xd7\x68\x9d\x7b\x04\xdc\x23\xa3\xd2\x19\x15\x27\xce\x85\x18\xd5\x5f\x3b\xf3\xc2\x7f\x14\xa3\x5a\xdd\xdf\xe9\xa2\x17\x6b\x2f\xd6\x96\xeb\x88\xd1\x06\x3a\xc0\xd9\x30\x0e\x50\xc3\xc5\xad\x20\xb4\xf7\x6d\xb9\xd5\x56\x10\x50\xff\x41\x75\x41\x94\xe0\x02\x7c\xf5\x92\xda\xf4\x8f\x2f\x5a\xa5\x81\xff\xc1\x49\x0c\xb9\xc3\xb2\x21\x46\x09\x4e\x25\xbe\xa8\x74\x84\x94\x63\x3d\x26\xcf\x06\xde\xb7\xe2\x05\x6c\x21\x7e\x61\x38\xa8\xab\xd1\xd9\x3c\x80\xa6\xf0\xec\x0b\x3b\x8e\x30\x1a\xc7\x09\xa6\xc2\xe3\xf2\x32\xf4\xcd\x35\x8a\x7c\xbd\x2f\x2f\x97\x5c\xe0\x30\x9f\x8b\x2c\xf0\xb5\xbb\x45\x39\x7f\x5c\xe0\xdf\xec\x14\x87\xa2\x38\x9e\x94\x13\x43\xde\x73\x72\x74\xae\x6c\x41\xec\xee\x35\x91\x17\x29\xa2\x39\xd1\xd4\x42\x44\x77\xb7\x70\xb3\x8f\x44\xf7\xad\x88\xee\x7f\x24\xe6\x57\x4c\x72\x12\x0f\xfc\x13\x85\xdf\xd2\x07\x67\xf9\x7c\x6b\x08\xc0\x95\x4a\xb1\x08\x5c\x45\x5f\xbf\xea\xaf\x6e\xb5\xc5\xd8\x7b\x3c\x3f\xae\xc0\xea\x2a\xfa\x40\xe0\xab\xf5\x42\x23\x52\x00\x68\x16\x44\x99\xab\x61\x38\xc2\xa8\xf2\x43\x25\xf7\xb5\xce\x63\x70\x83\xc7\xa1\x11\x73\x5b\x98\x70\x1a\x8a\xcc\x50\x6c\x49\x48\x55\x51\xea\x8e\xdd\x10\x8f\xb7\xcc\xee\x25\x51\xd0\x42\xbc\xe4\xaf\xed\xb8\x65\xc9\xd1\x45\x93\x64\x3d\x2c\x5f\xc9\x33\x21\x41\x6b\x7f\x7e\x9e\x8f\x87\x4d\x12\x5e\x2e\x26\xb6\x11\xf3\x5a\x7c\x39\xd9\xdb\xaa\xe7\xb1\x9e\xc9\x93\xf4\xd1\x4c\x04\x6e\x73\x10\x3d\xf2\xd3\x94\x2c\xe4\x65\x82\x5a\x80\xde\xe2\x6b\xb4\x8d\x93\xf0\x92\xe6\x84\xdc\xe5\x83\xd2\x28\x8e\x39\x7d\xf4\xfa\xed\xf6\x6e\x23\x6f\x4d\x3c\x97\x4c\x3c\xde\x8d\xa3\x41\x78\x31\x65\x99\x28\x63\xc8\x0a\x99\x16\xe5\x97\x4c\xe2\x09\x4e\xb2\x6b\xf4\x07\x3d\x16\x83\x37\x29\x30\xdf\xd3\x21\xcd\x71\x9c\x92\x87\x30\x62\xe9\x02\xb2\x58\xf8\xd2\xac\xa0\x6d\x3c\xf0\xa7\xa3\x6c\x03\xb5\x50\xa5\xde\x58\x87\x44\xca\x55\x17\x7c\x47\x42\x73\x9c\xf0\x44\xe6\x39\x38\x32\xfe\xf3\xd0\x0c\x33\x96\x3c\x33\x05\x50\xf9\xa1\x5e\xfa\x90\xc5\x68\x82\x93\x41\x9c\x8c\x25\xe0\x0a\x64\x29\xfd\x63\x7f\x70\xb1\xe1\x1a\x65\x44\x2f\xbe\x4e\x20\xe6\x4c\xbd\xb1\xbe\xda\x6c\x68\x21\xb8\x69\x57\x28\xea\xda\xa7\x1c\x21\xa5\xf1\x9b\x6a\x51\x42\xd2\xa2\x04\xf2\x64\x56\x82\x9c\xb4\xf8\x7a\x9b\x9f\x45\xf4\x10\xf8\xdc\x0d\xe9\xaa\x9c\x31\x94\x8c\x5f\xdf\x46\x37\xdc\xdf\x6c\x10\x27\x70\x8a\xc9\x1b\xbd\x87\xc4\xa0\x9f\x83\x81\x91\x34\x9e\x52\x3b\x3f\x3d\x2a\x66\x58\x8b\x54\xfc\x23\x9f\xac\x75\x9a\x7e\xf2\xce\x60\x3c\x75\x1a\x6b\xb5\x9a\x0e\xb8\x20\x7b\x7d\x7f\x70\x61\x37\xbc\x20\x13\xb1\x29\x7e\x72\xc2\x23\xc5\x5d\xc1\x30\xcc\xf5\x0e\xd7\x15\xd4\x83\xae\x2c\x0b\xba\x4d\xbe\xd9\x09\x83\x0d\xd4\xc2\x1f\x56\x4a\x56\x4e\xfd\x51\x86\xb6\xe0\x3f\x8b\x27\xa2\xe5\x6e\x34\x92\x5f\xfb\x5d\xc8\x8e\x26\x52\x0f\x06\x2b\x2c\x2a\x49\x85\x77\xc6\x03\xfc\x9c\x93\xca\x8a\xcb\xf3\xaa\xd5\x5c\x28\xb7\x8b\x3a\xf5\x56\x03\xc2\x30\x73\x24\x85\x65\x5e\xf6\xe0\xbb\xcf\x68\x95\x90\x0f\xe5\x41\x9e\x98\x1d\xbb\x59\xa2\x3b\x41\x39\xc8\xa6\x74\xb0\x69\xba\x79\x43\x9f\x63\x0b\xf5\x04\x72\xf2\x7e\x14\xe0\x99\xad\xc6\x59\x6d\xc6\x14\x40\x96\x68\x9d\x73\x42\x74\x09\x54\x84\xb0\x2c\xde\x38\xf3\xd7\xe7\xd8\xf0\x4a\xf9\x1b\x67\x25\xbe\xe5\x6d\x92\x59\x59\x61\x4f\x36\x23\x8c\x7c\x6b\xa1\x45\xf3\x17\x73\x8c\x2c\xd4\x8f\x4c\x50\xd7\x3a\xc8\xe3\x22\xbd\xe2\xf8\x58\x8d\x0b\x44\x27\x59\x9e\x63\x9e\x2c\x1b\x28\x30\x4f\xe3\x9b\xf7\x5a\x9f\x33\xc4\x32\x7a\xe7\xa9\x81\xcd\xef\xf3\xb3\x31\x00\x7c\x65\x88\xad\xa3\x6b\x16\x17\x59\x8c\xf2\x57\xac\xe3\x0e\x44\xf6\xc5\x18\xdb\x41\x87\x72\x34\x3b\x06\xd6\x82\x85\x62\xcb\x51\xa7\xb6\x1c\xd2\xf4\x39\x8d\x39\x10\xf0\x73\xa5\x09\x18\x3d\x31\xd2\xf2\x47\xdb\x58\x97\x19\x6f\x34\x2f\x14\x94\xad\xb3\x7c\xf4\xe5\x77\xf6\x80\x55\x52\x13\xbf\x1d\x1e\xab\xdd\x01\xd7\x29\x8b\xc7\xb5\x31\x6e\x9f\xa8\x0d\xcc\x27\x6e\x03\x23\xcd\xe6\x4b\xf4\xa9\x60\xf4\xc8\x5f\x5e\xe3\xec\x13\x98\xc3\x18\x1d\x39\xfb\xa4\x9b\xc5\xf0\xbf\x1b\xf3\xb5\x1e\x70\x8a\xfc\x49\xcc\x81\xe9\xa6\xa1\x51\xdb\x94\x68\x4c\xe2\xac\x76\xbe\xb4\x54\x6c\x52\x24\x01\x97\x8e\xbe\x9c\x6f\x58\x82\x98\xb1\xbd\x2c\xaf\x57\x64\x40\x29\x1f\x23\xee\xb4\xa1\x97\x09\x36\x53\xb8\x91\x2f\xb8\x89\xdf\x97\x68\x19\xa6\xb6\x74\xfb\xf3\xa3\xd7\x58\x44\x83\x7b\x08\x62\x43\x45\x04\x21\x19\x52\xa1\xd0\x25\x26\x2c\x56\xcd\x43\x0e\xd9\xf4\x2e\x60\x0a\x65\xd3\x3c\xc8\x8e\x38\x4a\xba\x04\x18\x0f\xe9\x82\x2a\x1b\x76\x55\x2c\x26\x85\xe6\x08\x4f\x37\x45\xb6\x68\x14\x9a\x3d\x50\x8f\x9e\x42\x97\xe7\x84\xbd\x39\xf7\xd6\xfe\xda\x3e\xf4\x0b\xa4\x75\x9f\x9f\x1c\xfd\x61\x75\x47\xce\xf4\xda\xae\xac\xd7\x7f\x07\xed\xd2\x09\x18\x67\x76\xb9\xf1\x2e\x55\x22\xc9\x2f\x8b\xf4\x48\x02\x8f\x63\x3c\x4d\xfd\xde\x08\xb3\x70\x60\x12\x3a\x27\x48\x4e\xb5\x48\xa1\xe8\x6f\xde\x20\x35\xc3\x9a\xb4\x2d\x1c\x43\x36\x65\xc4\x0c\x6d\x99\x8d\xb1\xa9\x49\x12\xe5\x21\xc6\x4a\x98\x22\x1f\xd1\x04\xcc\xe8\x12\x27\x29\x44\x2d\x1b\xfa\x19\x8a\xf0\xc5\x08\xf7\x33\x1c\x10\x36\xdc\x67\x29\x55\x33\xa6\xf0\xc9\x62\x34\x0a\xb3\x6c\x84\x97\x69\x80\xcb\x15\x15\x28\x4e\x92\x38\x41\x41\x8c\xd3\xe8\x59\x86\xfc\xc1\x00\xf7\x69\x5d\x8a\xd4\xb3\x14\xa5\xb8\x3f\x4d\xc2\xec\xda\x13\x15\x7b\xd3\x0c\x85\x19\x54\xe2\x35\xc2\x2c\x15\x01\x15\xc2\x51\x98\x31\x27\x6e\x9a\xd7\x35\x24\xfc\x79\x8c\x23\xba\x1f\xa4\x36\x45\x19\x1d\x90\x77\xb4\x73\x42\x5d\xa6\xbd\x95\xe7\xef\xb6\x49\xdb\x8a\x0f\x29\x6f\x65\x33\x68\xe7\x01\x23\xb7\xde\x86\x53\xc3\x65\xd1\x69\x21\x64\x27\x34\xb2\x7b\x61\xe7\x39\xed\x37\xd1\x2e\xf9\x65\x49\x1c\xf7\xf6\xac\x76\xee\xa1\xca\xdb\xb3\xe6\x39\x0b\x16\x80\xbe\x92\x47\x76\x15\x50\xef\x54\x2d\x49\xe4\xde\x9e\xd5\x69\xa5\x9a\x5a\xa9\x59\x5c\xa9\x41\x2b\xd5\xd5\x4a\xb5\xe2\x4a\x4d\x5a\xa9\xa1\x56\xaa\x8b\x4a\x6a\x1d\x5b\x76\x24\x63\xc8\xb8\x97\xa1\x6b\xd0\xba\x62\xd0\xba\xf6\x41\x33\xf1\x91\x86\x8b\xf5\x89\x5e\x98\x0c\x06\x3c\xed\x20\x45\x9a\x06\x59\xad\xd5\xc8\x17\x5b\x7f\xcd\x89\x68\xaa\x90\xeb\x56\xc8\x8d\x52\x90\x6b\xce\x81\x97\x60\x68\x90\x9b\xa5\x20\xd7\x5d\xb3\xe3\x49\x30\x34\xc8\x35\x0d\xf2\xfc\x89\xec\xfa\x49\x72\x8d\x7a\x7a\x3a\x55\x3a\x55\x3d\x1a\xff\xc2\xd4\x64\x64\x74\xf2\x09\xeb\x49\xaf\xd3\x0c\x8f\xd1\x20\x9e\x26\x28\x0b\xc7\xfa\xdc\x2f\x18\x94\x37\xc2\xb3\xec\x84\xac\x3e\x77\xfc\x58\x4b\xc4\xdb\x83\x38\x08\x07\xd7\x94\x13\x52\x3a\x2c\x81\xc5\xba\x1b\x8b\xee\x19\x75\x1c\xf8\xed\x0c\x52\x5e\x42\xb4\x15\x23\x53\x9c\x2d\x49\xee\x2f\x28\xc5\xd9\x74\xa2\x7e\x28\xf0\xe8\x98\x7f\xd8\xdf\xff\x85\xba\x76\x14\x9d\xf0\xf7\x7f\xf9\x58\x43\x9b\x68\xff\x17\x33\x35\x9a\x54\xa4\x4e\x8b\xd4\xad\xd1\x8c\xe5\x25\x0d\x53\x99\x4e\x7b\x97\x98\x88\x0a\xae\xa3\x7f\x8d\x06\x3f\x86\xb6\x69\xf4\xe3\xaf\x88\x3e\xb9\xa2\x1f\xcb\xc5\x59\x98\x63\x51\x3e\xbf\x0e\xb5\x87\x39\x16\xcd\x36\x44\xb3\x75\xa5\xd9\xfa\xbc\x66\xeb\x6a\xb3\xf5\xc5\x9a\x85\x30\x3a\x61\x8d\x2f\x41\x02\x24\x6c\xa8\x2b\xd0\x55\xb5\x09\x55\x1b\x7c\x31\x43\xd5\x9a\xba\x4c\x1d\x33\xc2\xc8\xba\x88\xb5\x22\xa0\xd6\x1a\x3d\xd7\xeb\xb1\xfd\xe9\xc7\x3a\xfd\x58\xb7\x7e\x6c\xd0\x8f\x0d\xeb\xc7\x26\xfd\xd8\xb4\x7e\x6c\x15\xb5\xd9\x2e\x6a\xb3\x53\xd4\xe6\x9a\x68\xb3\x40\x23\x55\x8a\xf3\xa0\xc5\xb9\x0f\x2a\xc7\x81\x90\xa9\xa4\x90\xfd\x88\xee\x25\xb9\xab\x53\x79\x2d\x49\x1f\xa5\x38\xb3\x5a\xc4\xde\x3b\xf7\xf6\x0e\x83\x9b\x7b\x99\x01\x17\x52\x4b\x9f\xd0\x50\x43\xbf\x01\x11\xa2\xca\x6f\x64\xee\xf9\x2a\x81\x67\xb1\xf7\xbe\xd4\x2b\xd6\x69\xc5\x06\xab\xb8\xa6\x55\x6c\x3b\x2b\x36\x68\xc5\x16\xab\x58\xd7\x2a\xae\x39\x2b\x36\x69\xc5\xce\xb9\x40\x4d\xa9\x58\xcf\x2b\xde\x69\x17\x2b\x8a\x52\x4f\x11\xe1\xb1\xe3\x4f\x58\x4a\x76\x16\x3c\x1e\x1e\x6f\x13\x3d\x9e\xc3\x61\x0c\x4e\xc0\xb1\xc5\x8f\xb7\xe2\x6b\x75\xc2\x43\x52\x8e\x5e\xe1\x4d\x77\x52\xec\x45\x27\x53\xbf\xb0\xe3\xc9\x6f\x6e\xf3\x8f\xe1\x25\xfd\xd2\x69\xad\x36\x1b\xba\x5a\x4e\x2c\x13\x41\xb0\x95\x92\xae\x50\xca\xfa\x50\xbe\x48\x22\xa8\x66\xf0\x73\xe2\x5f\x62\x14\x8f\x02\x27\xab\x5d\x40\x7e\xe8\x7e\xa4\x93\xdb\xd5\xe3\x1d\x2a\x2d\x76\xfd\x51\x7f\x3a\x22\x2b\x2c\xc2\x57\xce\x66\xbb\x2c\x11\x4c\x97\x26\x82\xa9\xcd\x5a\x41\x13\xfe\x0f\x2d\x71\x09\x4d\xcf\xd7\xd2\x65\x79\x61\xba\x34\x2f\x4c\x6d\xc6\x6a\x34\x21\xa6\x7c\x97\x0b\xa8\xb5\x2a\x7a\x85\x2a\xdd\x8f\xd2\xf3\x7f\xa1\x3a\xda\x40\xb5\xaa\x09\xb1\xc1\x20\x36\x28\x44\x06\xb0\xc5\x20\xd6\x35\x88\xf5\x12\x10\x9b\x0c\x62\xd3\xe8\x56\x85\xb6\xa3\x40\x6c\x94\x80\xd8\x62\x10\x5b\xd6\x5e\x37\x35\x88\xcd\x12\x10\xdb\x0c\x62\xdb\xda\xeb\x96\x06\xb1\x55\x02\x62\x87\x41\xec\x58\x7b\xdd\xd6\x20\xb6\x4b\x40\x5c\x63\x10\xd7\xac\xbd\xee\x68\x10\x3b\x73\x21\xe6\x62\x3f\x05\xaa\x54\x5f\xd3\xab\xeb\xde\x31\x82\xa6\xc9\xee\x73\xb1\x7c\x87\x45\x44\x4a\x5d\xcc\x80\x57\x87\xa4\x6b\x5d\x4b\x12\x0e\x9e\x2e\x3f\x99\xf6\x33\x34\x0c\x2f\x86\xc8\x8f\x02\x34\x8a\xaf\x90\x9f\x5c\x4c\x21\xfc\x0b\xb8\x39\xff\xef\xd4\x4f\x8c\xc4\x3d\xd0\x80\x8f\x36\x49\x2b\x5c\x8a\xb3\x28\x0f\x2e\x7a\xb4\x08\xdd\x25\xac\xc7\x27\xde\x67\x05\x83\x04\xa7\xd3\x51\x86\xe2\x41\x51\xf3\x43\xba\x05\x54\x2e\x7c\xf4\x1c\x5d\xf8\xd4\x75\xa5\xbe\x56\x45\x4b\x88\xbe\xea\xb1\x57\x6d\x78\xd5\x83\x57\x36\x24\x47\x14\x90\xd4\x15\x7a\x24\x7c\x8e\x2e\x66\x30\xc3\x55\x20\x08\x5e\x40\x88\x9d\x52\x01\x5b\x22\x18\xd2\xa1\xdf\x0e\x8f\x11\x84\x93\x94\x3f\xbe\xa1\x1c\xee\x62\x88\x7e\x47\x17\xa3\xb2\x4c\xce\xae\x54\xf9\x8d\xb1\xb8\x37\x94\xc5\x55\x2a\x6f\xf2\xed\x9b\xec\x64\x6f\x24\xb1\xa0\xca\x0a\x74\xd4\x02\x9d\xbc\x80\x4e\xcf\xbf\x31\x6e\xf8\x86\x72\xc3\x0a\x6d\x26\xdf\x6f\xdf\x70\xfe\x07\xfb\xed\x12\x22\xad\x99\x30\x1a\x0c\x46\x83\xc3\xa8\xab\x08\xd4\x0d\x0c\x6b\x6a\x81\x5a\x11\x86\x4d\x06\xbd\xc9\xa1\x37\x54\x0c\x1b\x1a\x86\x75\x0b\x86\x2d\x06\xa3\xc5\x61\x34\x55\x04\x9a\x06\x86\x0d\xb5\x40\xa3\x08\xc3\x36\x83\xde\xe6\xd0\x5b\x2a\x86\x2d\x0d\xc3\xa6\x05\xc3\x0e\x83\xd1\xe1\x30\xda\x2a\x02\x6d\x03\xc3\x96\x5a\xa0\x55\x84\xe1\x1a\x83\xbe\x76\xae\x90\x88\xc0\xb0\xa3\x61\xd8\x56\x30\x2c\x95\xf8\x23\xe5\x49\x27\x84\xae\xb5\x44\xda\x89\x79\xd7\x5d\x14\x56\x86\x67\x99\x7c\xef\x24\x6b\x52\x79\x28\x05\x25\x8d\x03\xbd\x2d\x32\xef\xaf\x26\x23\x9f\x60\x33\xcb\x90\x13\x1c\x8b\x33\x53\xc9\x5b\xb6\x41\x14\x17\x57\x45\x4a\x5d\x35\x79\x87\x5c\xb2\x5a\x74\x07\x25\x17\x2c\x6d\x8c\xec\xa9\x77\x23\x1b\xed\x96\x97\x5f\x8a\x6c\xb4\x3b\x1e\xbb\x2b\xd9\xe8\xd4\x6f\xce\xbd\xb5\xbf\x76\x24\xc2\xc7\xfb\xaa\xc7\xfb\xaa\x07\xbb\xaf\xd2\x96\x78\x7e\x9f\xa3\xdf\xe4\xfc\xb5\xee\x70\xee\x2b\x2b\xdc\x5b\x71\x34\x7f\xab\x1e\xcd\xdf\xde\xf6\x68\xfe\x56\x3d\x9a\xbf\x2d\x3a\x9a\xcf\x53\x30\x3f\xde\x54\x3d\xde\x54\x3d\xde\x54\x29\x5f\x1e\x6f\xaa\x1e\x6f\xaa\x1e\x6f\xaa\xf2\x66\x1f\x6f\xaa\xf4\x8f\x8f\x37\x55\x8e\xc7\xc7\x9b\xaa\xc7\x9b\xaa\xc7\x9b\x2a\xf8\x7b\xbc\xa9\x2a\xa7\xc4\x7d\xbc\xa9\x7a\xbc\xa9\x7a\xbc\xa9\x92\xfe\x1e\x6f\xaa\x1e\x6f\xaa\x1e\x6f\xaa\x1e\x6f\xaa\xfe\x93\x6f\xaa\xee\xed\x8e\xea\x76\xb7\x53\x65\xee\xa5\x4a\xdc\x48\x3d\xd4\x5d\xd4\x5f\x3b\x1f\xca\xe3\x5d\xd4\xdf\xff\x2e\x4a\xbe\x3b\xea\xb6\xe6\x3a\x3a\xc9\x37\x47\xdd\x96\x74\x6d\x04\x0f\x0f\x7f\x67\x44\xbd\x34\xc5\xad\x91\x3d\xa8\x00\xf7\xd0\x2e\xba\x56\x02\x37\x4e\xd9\xa3\x58\x8a\x99\x6e\xea\x2b\xa2\x30\x43\x69\x2f\x9e\x99\x70\x4e\x04\x3a\x27\xf2\x35\x1d\xff\xb3\x49\x93\x8d\x76\xc7\x7d\x28\x67\x87\xee\x70\xbe\x1a\xf7\x2d\xbe\xb6\xe9\x71\xd5\x16\x3d\xee\x3f\x3e\xb7\x61\x36\x28\x64\x08\x78\x54\x89\x10\xfd\x43\x1e\x27\x87\xea\x90\x55\x22\x5b\x1b\x1f\xfb\x33\x05\x90\x19\x09\x4d\xf9\x6c\x04\x45\xb3\x9d\xfd\x49\x2f\x2a\x9f\xd0\x12\x1d\x9f\x25\xde\x68\x15\xfd\x03\x7a\xe5\x88\xa5\x70\xe5\x4f\xec\x38\xc3\xbe\x61\x6a\x08\xa4\x09\x38\xb1\x3b\xc6\x93\xd7\x64\xc6\xe7\x4f\x4f\xd7\xaa\xe2\x67\x59\x35\x04\xd1\x7c\x62\x59\x66\x05\xa0\x3b\xab\xe5\xb8\x26\x04\xb4\x20\x46\xfe\x75\x32\x3d\x76\x95\xa1\xd2\xb2\x70\x72\x6e\xb4\x3b\x0e\x85\x48\xcd\xa9\x0c\xb1\x36\x5a\x56\x31\x22\xad\x27\x4d\x31\x92\x0f\x5a\xa8\x7d\xf9\x94\x0f\xe7\xdc\x0c\xf0\xa0\x1c\x54\xab\x7f\x96\xf1\xd4\xe6\x43\xac\xa6\x88\x2e\xa3\x88\xaa\xd4\x22\xcb\x22\x0a\x41\x83\x4e\x13\xc6\x31\xaa\x54\xbe\x2b\x24\xec\x20\x5c\x2b\xd1\x16\x10\xac\x9b\x58\x73\x42\x55\xdf\xab\x9d\xfd\x4a\xea\x56\xd8\x9a\x22\x55\x18\x5e\xe7\x79\x5e\x83\x48\xcf\x63\xa0\x1d\x9f\x3e\x40\x1c\x14\xcb\x8d\x56\x4e\xea\xa1\x71\x76\x27\x63\xa1\xcc\x15\x13\xcb\x14\xec\xbe\x57\xb9\xb7\xdb\xba\x0f\xa1\xb7\xdb\x5a\x58\xe2\x35\xf7\x58\x4d\xdc\xed\xb6\xac\xb1\x2d\xe0\x86\x26\xc4\xc1\x2d\x76\xf8\xed\x24\x9e\x28\xbb\x3c\x7b\x01\x83\xf0\x0d\xa2\xe2\x05\xa4\x39\x35\xd0\x9c\xa6\xe7\x27\x13\x4f\x4a\x89\x50\x73\xa8\xfe\xa2\x21\x83\xd5\x63\xcd\x11\xd4\xa5\xa8\x5f\xda\x2a\x26\xa0\x36\x54\x10\x6a\xc4\xb8\x52\x42\x0c\x69\x83\x17\x2c\xbe\xc3\x20\xe3\x59\xb0\x81\x0b\xc3\x17\x82\x17\xd9\xc5\x7f\x86\xcd\x7c\x79\xd9\xba\x87\x2f\xc0\xee\xd1\x9c\x04\x48\xdf\xd1\x6a\x23\x43\x74\x3f\x2b\x0e\x20\x2d\xbe\xea\x18\xcd\x17\xaf\x3c\x52\xa8\xf8\xa4\xd9\x6d\x3d\xd4\x31\xf3\x6e\xe9\xfa\xbe\xe5\xf9\xf2\xc1\x4e\x81\xdf\x36\x88\x33\x61\x55\x38\xc5\xc9\x25\x7e\xfa\xa4\xd2\xaf\xa2\x46\xad\xde\x40\xbd\x6b\xd4\xfd\xff\xfe\xdf\x20\x09\xfb\xe8\x00\xa7\x51\x38\x5a\x41\x5b\xa3\x11\x4a\xc2\x8b\x61\x96\x22\x56\x3e\x58\x79\xfa\xf4\xc9\x31\x0e\xc2\x34\x4b\xc2\xde\x14\xe0\xfb\x51\x00\x41\x79\xc2\x08\xa5\xf1\x34\xe9\x63\x78\xd3\x0b\x23\x3f\xb9\x26\xec\x60\x9c\x7a\x2c\x4a\x43\x02\xff\x8d\xa7\x19\x1a\x03\x4f\xef\x03\x67\xf5\x90\x9f\x60\x34\xc1\xc9\x38\xcc\x32\x1c\xa0\x49\x12\x5f\x86\x01\x0e\x68\xd0\x09\xb2\x4e\x07\xf1\x68\x14\x5f\x85\xd1\x05\xea\xc7\x51\x10\xd2\x35\x4c\x2a\x8d\x71\xb6\xc1\x56\xfc\x32\x52\xd1\x4a\x41\x31\x4c\xf1\xe9\xc7\x01\x46\xe3\x69\x9a\x91\x8d\xda\x0f\x23\x00\xea\xf7\xe2\x4b\xf2\x69\x72\x0d\x5d\x44\x51\x9c\x85\x7d\xec\xd1\xb8\x42\xa3\x30\x05\xcd\xb2\xdc\x5e\x14\x68\xc8\x04\x61\xda\x1f\xf9\xe1\x18\x27\x2b\x2e\x1c\xc2\x48\x1e\x08\x8e\xc3\x24\x89\x83\x69\x1f\xdf\x3b\x1a\x88\x75\x2d\x88\xfb\x53\x11\x07\x83\xd4\x58\x8d\x13\x16\x23\x63\xec\x67\x38\x09\xfd\x51\x9a\x0f\x33\xcc\x0d\x54\x93\x50\x27\xf3\x7c\xba\xb7\x7f\x82\x4e\x0e\x77\x4f\x7f\xdd\x3a\xde\x41\xfb\x27\xe8\xe8\xf8\xf0\x97\xfd\xed\x9d\x6d\xf4\xfa\x5f\xe8\x74\x6f\x07\x75\x0f\x8f\xfe\x75\xbc\xff\x66\xef\x14\xed\x1d\xbe\xdb\xde\x39\x3e\x41\x5b\xef\xb7\x51\xf7\xf0\xfd\xe9\xf1\xfe\xeb\x0f\xa7\x87\xc7\x27\xe8\xc7\xad\x13\xb4\x7f\xf2\x23\x7c\xd8\x7a\xff\x2f\xb4\xf3\xdb\xd1\xf1\xce\xc9\x09\x3a\x3c\x46\xfb\x07\x47\xef\xf6\x77\xb6\xd1\xaf\x5b\xc7\xc7\x5b\xef\x4f\xf7\x77\x4e\x3c\xb4\xff\xbe\xfb\xee\xc3\xf6\xfe\xfb\x37\x1e\x7a\xfd\xe1\x14\xbd\x3f\x3c\x45\xef\xf6\x0f\xf6\x4f\x77\xb6\xd1\xe9\xa1\x07\x8d\x9a\xd5\xd0\xe1\x2e\x3a\xd8\x39\xee\xee\x6d\xbd\x3f\xdd\x7a\xbd\xff\x6e\xff\xf4\x5f\xd0\xde\xee\xfe\xe9\x7b\xd2\xd6\xee\xe1\x31\xda\x42\x47\x5b\xc7\xa7\xfb\xdd\x0f\xef\xb6\x8e\xd1\xd1\x87\xe3\xa3\xc3\x93\x1d\x44\xba\xb5\xbd\x7f\xd2\x7d\xb7\xb5\x7f\xb0\xb3\xbd\x82\xf6\xdf\xa3\xf7\x87\x68\xe7\x97\x9d\xf7\xa7\xe8\x64\x6f\xeb\xdd\x3b\x6b\x2f\x09\xee\x4a\x1f\x5f\xef\xa0\x77\xfb\x5b\xaf\xdf\xed\xd0\x96\xde\xff\x0b\x6d\xef\x1f\xef\x74\x4f\x49\x77\xf2\x5f\xdd\xfd\xed\x9d\xf7\xa7\x5b\xef\x3c\x74\x72\xb4\xd3\xdd\x27\x3f\x76\x7e\xdb\x39\x38\x7a\xb7\x75\xfc\x2f\x8f\xc1\x3c\xd9\xf9\xbf\x1f\x76\xde\x9f\xee\x6f\xbd\x43\xdb\x5b\x07\x5b\x6f\x76\x4e\x50\x65\xce\x90\x1c\x1d\x1f\x76\x3f\x1c\xef\x1c\x10\x9c\x0f\x77\xd1\xc9\x87\xd7\x27\xa7\xfb\xa7\x1f\x4e\x77\xd0\x9b\xc3\xc3\x6d\x18\xe8\x93\x9d\xe3\x5f\xf6\xbb\x3b\x27\x2f\xd1\xbb\xc3\x13\x18\xad\x0f\x27\x3b\x1e\xda\xde\x3a\xdd\x82\x86\x8f\x8e\x0f\x77\xf7\x4f\x4f\x5e\x92\xdf\xaf\x3f\x9c\xec\xc3\xa0\xed\xbf\x3f\xdd\x39\x3e\xfe\x70\x74\xba\x7f\xf8\xbe\x8a\xf6\x0e\x7f\xdd\xf9\x65\xe7\x18\x75\xb7\x3e\x9c\xec\x6c\xc3\xe8\x1e\xbe\x87\xae\x9e\xee\xed\x1c\x1e\xff\x8b\x00\x25\x63\x00\x83\xef\xa1\x5f\xf7\x76\x4e\xf7\x76\x8e\xc9\x80\xc2\x48\x6d\x91\x21\x38\x39\x3d\xde\xef\x9e\xca\xc5\x0e\x8f\xd1\xe9\xe1\xf1\xa9\xd4\x47\xf4\x7e\xe7\xcd\xbb\xfd\x37\x3b\xef\xbb\x3b\xe4\xeb\x21\x81\xf2\xeb\xfe\xc9\x4e\x15\x6d\x1d\xef\x9f\x90\x02\xfb\xb4\xd9\x5f\xb7\xfe\x85\x0e\x3f\x40\x97\xc9\x1c\x7d\x38\xd9\xa1\x3f\x25\x8a\xf5\x60\x26\xd1\xfe\x2e\xda\xda\xfe\x65\x9f\xa0\xcd\x0a\x1f\x1d\x9e\x9c\xec\x33\x3a\x81\x21\xeb\xee\xb1\xe1\x5e\x79\xfa\xe4\xf9\xaa\xaa\xf3\x3a\xf0\xb3\xe1\xfd\xea\xbd\xca\x45\x9d\xa6\x81\x8f\x45\x11\xfa\x58\xca\x3a\x1b\x2e\xec\xfc\x28\x4b\x51\xe6\xf7\xb8\xc4\x42\xaa\x7c\xfc\x32\xb2\x06\xdb\xcc\xe5\xa8\x9a\x87\x50\xdd\x43\xa8\xe1\x21\xd4\xf4\x10\x6a\x79\x08\xb5\x3d\x84\x3a\x1e\x42\x6b\x1e\x42\xeb\x1e\x42\x2f\x3c\x54\xaf\x79\xa8\x5e\xf7\x50\xbd\xe1\xa1\x7a\xd3\x43\xf5\x96\x87\xea\x6d\xc9\xc2\x72\x8d\xd6\x25\xdf\x08\x3c\x52\x9e\xc0\xa8\xb7\x29\x5c\x52\x0f\xda\x7a\xc1\xe0\x37\x18\x8c\x3a\xb4\x91\xc3\x69\xb2\xb6\x5a\x0c\x97\x17\x0c\xc6\xba\x84\xe7\x1a\x83\xd5\x61\xb8\xd4\x29\xcc\xba\x1c\x6b\xb9\xce\xea\x72\x5c\x6a\x14\x06\xe0\xc1\xf1\x6c\x52\x58\x04\x7e\x5d\xee\xb7\x0c\xa7\xc5\xea\xb6\x19\xee\x6b\x0c\x46\x43\xc2\xb3\xce\x60\xad\x33\x5c\x58\xbf\xeb\xcd\xf3\xea\x4b\x79\x2e\x92\x39\x73\xc1\xf1\x58\x93\xc6\xaa\xc1\x60\x72\x9c\x3b\xea\x78\x40\xdf\x9a\x5a\xdf\x3b\xac\x4e\x33\x87\x05\x75\xdb\x39\xce\x1c\x06\x1f\x0f\x68\xab\xae\xf5\x1d\x0a\xb5\xa5\x0e\xae\x31\x04\x3b\xf9\xe0\x0a\x20\x0d\x69\xa0\x29\xb2\x39\xa0\x75\x56\x47\x1a\x2c\x98\x98\x76\x3e\xb8\x02\x46\x53\x1a\x68\x8a\xac\x84\x50\x83\x8d\x6c\x4d\x02\xc6\x47\x63\x4d\xcc\x9e\xa0\x50\xc4\x46\x87\x22\xab\xce\x46\x3a\x6f\x65\x50\x14\xd9\x58\x01\x7a\x72\x4b\x9c\xb6\x9a\xd2\x78\x76\xf2\x6f\x0a\x4d\xaf\x79\xf0\x09\x86\x8a\xd3\xeb\x8b\x9c\xf6\x38\x4d\xd5\xdb\xd2\xb0\xae\xb1\xb2\xca\x7c\xd4\x73\x22\x10\x73\xf1\x82\x15\xe4\xc4\xb3\x2e\x95\xe1\x88\xaf\xc1\x6f\xf9\x2c\x25\xd6\x72\x2b\xaf\xca\xdb\x17\x6b\x5e\x5e\x13\xeb\x0a\xc8\x1c\x14\x5f\x9f\xed\x9c\xf6\x45\x3f\x1b\x39\x0a\x62\x9c\x18\xc9\x50\xb8\x48\x9b\x92\x79\x0b\x84\x21\xa6\x0c\x7e\x3b\x47\x00\xfa\xb9\x96\x2f\x44\x68\xb0\xc5\x10\xe9\x68\x48\x37\xd5\xc1\x17\x9d\xae\xe7\x70\xc4\xd8\x89\x05\x0d\xdf\x15\x38\x82\x81\xd4\xa5\x41\xea\xe4\xed\x8a\x85\xc7\x16\x70\xbd\x69\x99\x0f\xd1\x01\x0d\x71\x0e\x48\x2c\xb8\x86\xf4\xdf\xb6\x58\xc5\xea\x00\xb5\x2d\xe5\x5a\xea\xcc\x88\x99\xcc\x3b\x85\xea\x75\x74\xae\x64\xc9\xfe\x38\x24\x2b\xc4\x32\x1f\x48\x84\x6a\xae\x79\xa8\x36\x6b\x6f\xad\x37\xd6\x5e\xbc\x78\x41\x7e\x77\x76\xb6\x5f\xec\xbc\xde\xaa\x93\xdf\xeb\xbb\xf5\xd7\xaf\xbb\xdb\x5d\xf2\x7b\xeb\x45\xbb\xb9\xbb\xdd\xda\x51\xe7\x7b\x98\x38\x1b\x68\xd7\xb6\x1a\xeb\xaf\x77\x3a\xd0\x40\xb7\xb5\xbd\x5d\x6f\xb4\xa0\x81\xed\xb5\x5a\x73\x67\xb7\x49\x7e\xaf\x6d\x75\xb6\xd7\x3a\x3b\xd0\x30\x47\xe8\xdc\xaa\x0f\x38\xde\x3f\xda\x39\xd8\xae\x77\x6a\x10\x7e\x7f\x8e\x0e\x49\x94\xcd\xb5\x48\xd2\x2b\xba\x2b\xdf\xf6\xae\x88\x2a\x13\x01\x09\x47\x10\xec\xce\x5a\xab\xdd\x68\xd6\x60\x04\x77\x76\xbb\xdb\x5b\xaf\xd7\xa1\x83\x2f\xd6\x5f\x6f\x6d\x77\x77\x77\xc8\xef\x7a\xad\xd9\x68\xb7\xd6\x60\x70\xba\xcd\xed\xc6\x4e\x7d\xb7\x76\xee\x54\x8d\x97\x55\xca\x5b\x15\xbb\xa5\xbd\x94\xea\x05\x37\x35\xf3\xcd\xf1\x29\x16\xa0\x7b\xcd\xcd\x22\x1d\xd7\x37\x07\x1f\xa5\xd2\xfc\xf2\xe0\xa3\x69\xc8\x84\x8a\xee\x54\xa4\x7a\x68\x13\x55\xcc\x02\x88\x1a\x80\x4a\x8d\xe5\x86\x0f\xd2\xcb\xc5\x8c\x4a\x0d\x80\xcc\xae\x54\x03\x68\x5a\x97\x9a\xe0\x0a\x54\x63\x68\x9e\xad\xf3\x1e\x12\xf7\x0f\x84\x14\x9d\x57\x8e\xc0\x00\x3e\x0e\x47\xee\x02\x09\x14\x48\x9c\x05\x40\xfc\xfc\xf8\xc5\x0d\x01\x64\xa2\x8f\x5f\xdc\x10\x60\x9b\xfe\x98\xba\x21\xc0\xa6\xf1\x31\x4d\xec\x11\xad\x57\x57\xc9\x2a\xfb\x4c\x0e\xcd\x97\x7e\x12\x12\xe9\xd8\x72\x49\xeb\x8f\x3c\xd4\x1b\x79\xa8\x3f\xf2\x50\x30\xf2\x10\x1e\x59\x1a\xf2\x13\x0f\xf5\x12\x0f\xf5\x13\x0f\x05\x89\x87\x70\xa2\x37\xe6\x13\x54\x7c\x82\xf0\x9e\xe9\x32\xd2\x4b\x20\xe8\x38\x7c\xac\xeb\x1f\xfb\xe4\x63\x9f\x7e\x6c\xe8\x1f\x03\xf2\x31\xa0\x1f\x9b\xfa\x47\x38\x30\x60\xfa\xb1\xa5\x7f\x14\x69\xaa\x7d\x35\x2f\x35\xef\x92\x7e\x2b\x68\x35\x25\x84\xff\x2e\x6d\xa2\xba\x75\x6d\x67\x64\xf9\xf8\x23\xb4\x94\xaf\xa9\xa5\x2f\xa3\xb3\xf0\xfc\xbc\xfa\xd5\xe6\xc4\x00\x5e\x3b\xaf\xea\x9d\xea\x1f\x4f\x9f\xa8\xac\x91\xb4\x81\x06\xf5\x4a\x6f\xe4\xf5\x47\x5e\x30\xaa\xa2\x25\x34\x1c\xd9\x7d\x6f\x6e\x90\x50\xc8\x85\xaf\x9a\x0d\xaa\x6a\xb3\x40\x6b\xe8\xd0\x8c\x91\x37\xa0\xb5\xd6\x9d\xd0\x9a\x3a\x34\x63\xaa\x0c\x68\x9d\x96\x13\x5a\x4b\x87\x66\xcc\xad\x04\xed\x8f\xd5\x55\x06\x71\xbd\xe6\x84\xd8\xd6\x21\x1a\x04\x81\xec\x61\xd2\xc9\x24\x66\xd6\xe9\x22\x5f\x50\x12\x67\xa3\x4a\xe6\xa5\x64\x5a\x6d\x4e\x1b\x40\x03\xd9\x12\x1e\xd9\xa7\x1c\x56\x84\xb1\xa4\xc8\x1f\xd0\x6d\x60\xfb\x02\xe4\x0e\xed\x92\x35\x59\xb7\xba\x01\xc1\x7a\xe9\xd9\x6a\xc3\x32\x33\x6e\x12\x05\xaa\x7e\x82\x96\x24\x6a\x4d\x6e\x4f\xad\xed\x4a\x2f\xf1\xfa\x89\x17\x24\x30\xe2\xc9\xdd\xa8\xb5\xa5\x43\xbb\x2b\xb5\xaa\xd0\xee\x44\xad\x0d\x1d\xda\x9d\xa9\xb5\xae\x43\xbc\x67\x6a\x4d\xe0\xd6\xba\x80\x5c\x13\x07\xb9\x02\x47\x4d\x6c\xe4\x0a\x8c\xd8\xf6\x05\x58\x34\x25\xd7\xc4\x49\xae\xb0\x01\xd8\x6a\xc3\xd6\x60\x5a\x68\xe8\xac\x7c\x5f\x4e\xc7\x00\x32\x24\x58\xfd\x6a\x12\x26\xf9\x67\x13\x55\xf6\xa8\x69\x6e\x9f\x70\xe6\xc0\xd2\xd3\x3d\x66\xc2\xbb\x47\xcd\x6f\x03\x52\xce\x36\x22\x7b\xcc\x4c\x77\x8f\x1a\xd2\x62\x52\xce\xb7\x96\x6b\xb2\x72\x60\x2c\x0b\x3b\x42\xcf\x5a\xae\xc5\xca\x81\x61\x72\x8f\x94\xeb\x5b\xcb\x81\x01\xb3\x32\x2c\xba\x58\xbb\xcb\x52\x6b\xdc\xc1\x3c\x2b\xf0\x33\x5f\x08\x43\xe4\xc1\xb2\xf1\xcf\x4f\xc3\xc8\x4b\x46\xaf\xc3\x2c\x3d\x8d\x33\xe0\x78\x14\x66\xb4\xed\x67\x3e\xb5\xda\x7a\x8e\xd6\x2d\xd0\xa1\xce\x3b\x3c\xc8\x8c\xa4\x8d\x50\xde\xe8\xcc\x56\x10\x98\x59\x88\x11\xcb\xb7\x48\x8d\x99\x72\x90\x44\x9a\x6c\x9f\xa3\xaf\x9b\x34\xb1\x70\x6e\x23\x21\x4a\xfc\x03\x35\x1b\x3a\xb5\xe6\x90\x2a\x95\x4a\x5e\x74\x09\x11\xfe\x40\x40\xbe\xa8\x12\x50\x2d\xb2\x6e\xeb\x2d\x87\x00\xcd\xab\xd2\xe1\xc8\x85\x67\xe9\x65\x79\xe1\xd9\x00\xc6\x04\x67\x0d\xd8\x3c\xc1\xd9\xd6\x51\x39\x4f\x47\x9e\x0f\x93\xe7\xd8\x01\xe3\x18\x4b\xda\x8e\xd5\x55\x38\x09\x22\xc8\xee\x42\x1d\xb2\xac\x86\x53\x13\x7a\xf2\x32\xb3\xb9\x14\x93\x25\xac\x6e\x59\x46\xb7\x10\xce\x1e\xda\x44\xb2\xf8\x7e\xb7\xf3\x5b\xbb\xd4\xf1\xcd\x7e\x22\xdb\x83\xa3\xd8\x9e\xc5\x99\x04\x15\x9d\xc1\xf6\x84\xbb\xde\x9e\x72\xbc\xda\x5b\xf8\x5c\x45\x29\x64\x4f\x39\x53\xed\x39\x0f\x53\xf3\x4d\xe1\x8e\xe9\x4d\x38\x9d\x5c\x96\xc1\x22\x80\xc1\x56\x8b\xb2\x1b\x73\x6d\x82\x14\x36\xd5\x1f\xc5\x51\x31\x83\x02\x53\x02\x52\x2a\xd7\x2e\xc0\xa3\xdb\x0c\x82\x7e\xfe\x68\x10\x09\xad\x67\xd2\x1a\x43\x13\xbe\x2a\x76\x51\xf0\xf3\x86\xde\xfe\x23\xd9\x22\x6e\x50\xaf\xcc\x3c\x74\xed\xa1\x2f\xb6\x34\x1f\x95\xca\x0c\x3c\x3b\xaf\xe1\xdf\x2f\x79\xb6\xf6\x1b\x03\x4e\xa3\x18\x4e\x65\x56\xfd\xa9\x72\x5d\xa5\xee\xe4\xff\x26\x0f\x5f\xaa\xd5\xea\x4b\x17\xb4\xe6\x5c\x68\x04\xd0\xbf\x09\xc4\x1c\x35\x07\xac\xd6\x7c\x58\x3f\x01\x04\xc0\xed\xba\xfa\x53\xe5\xdf\x80\x9c\x1b\x62\xbb\xcc\x98\x91\x41\xfb\x9a\x83\x72\xc0\x02\x51\x62\xe6\x45\x56\x48\xb3\x57\xaf\x22\xc0\x6a\xf6\xf3\xcf\x3f\x57\x9a\x8d\xe5\x48\x46\x8a\xfe\x28\xb4\x86\xe1\xc6\x30\x34\x0f\x5c\x39\x63\x18\x67\xb6\x1f\x66\xdf\x02\x36\x4f\xfc\x77\x16\xff\xff\xec\xbd\x7d\x77\xd4\x38\xd2\x28\xfe\xf7\xf0\x29\xb4\xfb\x3b\x0b\x1d\xd2\x49\x2c\xf9\x4d\x06\x32\xbf\xcb\x64\xe0\x61\xee\xc0\xc0\x81\xcc\x85\xe7\x70\x60\x56\xb6\xe5\xb4\x87\x4e\x77\x9e\x6e\x87\x24\xbb\xc3\x9e\xfb\x35\xee\xd7\xbb\x9f\xe4\x1e\x95\x64\x5b\xb6\x25\xb9\x3b\x84\x79\x76\x76\xc9\x9e\x65\xba\xdb\xa5\xaa\x52\xbd\xa9\xac\x97\x92\x8c\x4c\x43\x34\x96\xfb\x79\x2c\xd0\xd7\xbd\x98\x47\x79\x46\xbb\x93\xa5\x9e\xc0\x9b\xdc\x51\x2c\xde\x31\xec\xc2\xb1\xb7\xba\xa8\xb9\x35\x6d\xb7\x19\x4e\x0e\xf6\xb6\xda\xd4\x00\x9b\x6d\x55\xaa\x95\xf3\xe4\xd9\xc3\xa3\xdf\x41\x35\x8e\xe6\x1f\xf8\x15\x34\x5d\xf3\x6c\xc5\x2b\xcb\xdd\x49\x16\x85\xc2\x95\x83\x37\xa8\x50\x79\x91\x61\xa3\x9a\x27\xa7\x2c\x6b\xd5\xa3\x6f\xb1\x32\x68\xa8\x03\x3c\xd4\xd2\x29\xcb\x0c\x9a\xfa\xe6\x93\x5c\x07\xb6\x6c\x8d\xaa\x21\xcd\xb7\x13\x7d\x7a\x37\x8d\xe3\xaf\x5b\x9c\xfe\x15\x8e\xac\x7c\xe9\xa5\xfb\x5e\x61\x35\x8d\xb0\xb5\x64\xda\xab\x27\x0f\xf7\xf0\x06\x2b\x19\xc3\xbb\xaa\x6f\x72\xfd\xe2\x10\x4e\x9f\xb6\x4b\x18\xe5\xa2\xac\x26\x86\x02\x54\xdd\x25\x0d\x5e\x64\x39\x4b\x69\x62\xa8\xcd\xe4\x5d\x26\x34\x65\x79\x56\xf0\xce\x1a\x87\x09\x30\xf3\x73\xc2\x71\xe1\x75\x9f\x7d\xfe\x12\x88\x2d\x43\x37\x27\xdf\xc3\x19\xf4\x01\x82\x4d\xe6\x9e\xcd\xd3\xc5\xe2\x51\x6a\x9e\x2c\x86\x84\xd1\x3c\x55\x0c\xaf\xab\xe6\x89\x62\xf1\x88\x37\xd3\xc4\x03\x4e\xad\xf3\xc4\xd6\x39\x61\xcb\xdb\x02\xcc\xfb\x20\x79\xc2\xd4\x52\x0b\xe6\xb5\x4c\xfc\xbb\x25\x30\xba\x67\x4f\xeb\xbf\x7a\x42\xc9\x8c\xa8\x3e\xe7\xf0\xfa\x6d\x89\xf6\x90\xff\x0e\xbd\x57\x1f\x69\xfb\x11\x07\xda\xe7\xc8\x76\x77\xa4\x62\x69\xb2\x80\xc3\xb1\xf2\xdd\x12\x5e\x1f\x7c\x6c\x2e\x53\x63\x7e\x13\x82\xa9\xa5\x09\x13\x48\x42\x40\xc2\xe4\x9b\x4c\x0c\x07\x64\x39\xda\x05\x42\xb6\x89\x46\xf4\x00\x11\xcf\x2a\x35\x98\x36\x9b\x4c\x52\x74\x1b\x65\x32\xcf\x15\x1f\x73\xc0\xec\x5d\x86\x4c\xae\xc2\x8e\x4c\xf1\xa1\x07\x28\x18\x23\x91\xa2\xf7\x28\x43\xef\x51\x2e\x31\x47\x3c\x4f\x78\xca\x4c\x45\x87\x7a\x98\xa3\x2d\x98\x97\xbc\x8b\x4f\x99\xea\xc5\x1e\xf2\x2e\x63\x8f\x07\x81\x4f\x02\x3b\xad\x83\xbb\x0d\x39\xea\xed\xa0\xbb\x07\x1b\xf7\x45\xe0\xf7\xc3\x24\xf7\x39\xe9\xcf\xf2\x20\x8b\x4a\x85\xbf\xe4\xa6\xe9\x3e\x74\x88\x32\xd3\x14\x1f\x02\x92\x0f\x1e\x20\xdf\x53\xbd\x04\xf5\x1b\xef\x16\x45\x87\xc8\xc4\x07\xdb\xec\xb4\xd6\x46\x93\x81\x6a\x12\xad\x9e\x6c\x63\xfd\x13\xde\xa8\x33\x11\x08\x13\x86\x83\xca\x27\xa8\x33\x09\x08\x93\x85\x99\x19\xc6\xd7\x27\x0a\x73\x33\x4c\xa0\x4f\x12\xf2\x3e\xcc\xd7\x09\xbe\x7f\xd6\x09\x3e\x91\x0b\xef\x17\xf3\xe5\x72\xa5\xcf\xb9\x1d\xc0\x40\xad\xfe\x3e\x8b\x08\xd4\x42\x68\x31\x8f\xcc\xd3\x0d\xa6\xe9\xbe\xd0\x0c\xdd\x96\xf3\x40\xc6\xe9\xba\x3f\xe2\x6c\xd0\xd7\x29\x84\xc1\x64\x80\x48\x9f\xb7\x9a\x3d\x80\x06\xae\x89\x83\x6e\x42\xde\x9d\x33\x10\xcf\xbe\x4e\x17\xdc\xe8\x74\x01\xe8\x63\x83\x99\x02\xb3\x5a\xda\x49\x02\xa5\x1a\xfb\xb1\x29\x01\x60\x9f\x16\xa0\x7f\xe8\x02\x1b\xeb\x19\x23\x61\xf4\xa5\x6b\x63\x28\x2a\xff\x3e\xd3\x07\x83\xe9\x01\xfd\x1d\x9e\x84\x51\xe7\x2d\x5e\x3b\x85\xdd\x9f\x15\x20\x24\xd8\x6c\x5e\x40\x00\x76\x70\xc2\x77\x89\xfc\x77\x9d\x1b\xc8\xb0\x17\x26\x3c\xa7\xe2\x95\xdf\x8f\xe2\x2c\x0f\xbd\x18\x3e\x7b\xb1\x97\xe7\x18\x3e\x17\xb1\xc7\xc3\xc4\x37\xcf\x19\x14\x45\xe6\x79\xa9\x0f\x93\x0b\x11\x0d\x29\x0e\xb1\xfc\x1c\x14\x09\x2d\x18\x20\x48\x79\xc1\x82\x82\x05\x5b\x4c\x17\x6c\x94\x79\x6a\x61\x5f\x89\x4e\x6b\xe9\x38\x45\x0b\x11\xb5\x49\x67\xf6\x0e\x87\xc9\x8b\x65\x61\xe9\xeb\x10\x3d\x32\xe2\x12\x12\x6c\x3b\x48\x8b\x26\x23\xc3\x74\xc7\x3b\x06\x03\x35\x21\xe6\x43\xec\x5f\x87\xea\xcf\x18\xaa\x85\x56\x36\x1b\xac\x8d\xca\xe9\x0c\xd7\x52\x41\xce\x01\x9b\x90\xfe\x51\x67\xed\x5c\xb3\x1a\x8e\xee\xc5\x89\x18\xc0\x93\xaf\xf3\xfa\xff\x3d\x03\xf3\x1f\xef\x58\xde\x0f\xf2\x12\x87\xf2\x6f\xcd\xa9\x5c\xb4\x5a\x9e\x2f\x72\x94\x75\xcf\xeb\x69\x3d\x78\xd2\xbf\x3a\xe5\xc7\xee\x32\x40\x3d\x51\xcb\x5b\x1c\xf2\x89\x29\x83\x41\xfa\x92\x72\xb9\x7e\xb1\x2a\x4f\xf9\x64\x61\x1c\xc6\xd6\xff\xb5\xaa\x7e\xaa\xdf\xf3\xc5\x97\xc9\xa2\xff\x9e\xd9\x4c\x04\x4b\x75\xa2\x43\x44\xee\xd7\x9f\x1f\x1c\x4a\x0c\xf5\x0f\x8e\xb9\xe1\x3f\x4d\x16\xe8\x2f\x0a\x6c\xc7\x3a\x5f\xa8\x7c\xb4\x60\xf3\x35\x1f\xdf\x15\xd8\x9f\x1f\xab\xdf\xc7\x57\xe7\xdd\x37\x5c\x83\x58\x4e\x78\xf5\x78\xc5\xe0\x33\x9b\x7f\x57\x56\x6b\x83\x80\x9a\x25\xfc\x05\xda\x43\x93\x05\x54\xf6\xdc\x41\x77\x3b\x93\x1f\xfd\x99\x2c\x8d\x56\x3d\x4b\xad\x57\x66\x87\xdf\x40\x21\xbd\xfa\x3d\x17\xb3\x72\xce\xd1\x44\x3d\x7b\x80\xd4\x96\xcc\xbe\x14\x5b\x6d\x5a\x05\xdd\xa0\xa0\x56\x29\x3f\x79\x2b\x81\xa0\xec\xe8\x40\x10\x60\x0b\x67\xcb\x8b\xc9\x62\x8a\x30\x3a\x40\x64\x67\x83\x8a\xed\x08\x6e\x42\xd9\x06\xad\xbf\x63\x2c\x9e\x2d\x51\xec\xee\x8e\x4c\x85\x2e\x3a\x10\x75\x86\x34\x69\x71\x5e\x7f\x8d\x4d\x24\xde\x9b\x65\xd3\xc3\x0c\xfd\x8b\xaf\xb4\x3d\xd9\x5f\xcf\xcb\x8c\x4f\xbc\x9d\xaf\xab\x5e\x1b\xaf\x7a\x0d\x1e\x15\xf0\x28\x34\x3d\x3a\x81\x47\x83\x05\x23\xc8\x59\xe0\x51\xfc\xd9\xcb\x68\x91\xa3\xd6\xfd\xef\xbd\x8c\x76\xc2\x4e\x4f\x99\x77\xd9\x2c\xa6\xe1\x81\x50\x86\xd0\xb0\xd1\x78\x52\xb7\x7c\xf0\x00\x11\xb9\xe8\x55\xff\xf2\xed\xb7\xdf\xa2\x78\x67\x07\xa1\xf7\x66\x4c\xdd\xbf\x0e\x26\x1c\x0c\x30\x61\xba\xb3\xb3\x19\xa6\x6e\x3b\xdf\x18\x5e\x3a\x3d\xc1\x6d\xbf\x8d\x9b\xe4\xbb\xc0\x5a\xb7\xb1\x64\x56\xeb\x36\xbe\xac\xeb\x4d\x6f\xc8\x6c\x17\x93\x3f\xc4\x94\x6c\xd9\xed\xba\x9d\xf9\x4e\x02\xd4\x1a\x8e\x52\xe2\xae\xea\x39\x14\xf9\x55\x3d\xdc\x75\x2e\x98\xda\x56\x3f\x33\x38\xd5\x38\xe1\xe8\x36\x2a\x60\xb3\xdb\x3f\xc4\xc7\x13\xdb\x15\x2e\xa7\x0c\x2a\xcc\x31\x74\x1b\xa5\x00\xce\xe4\xea\xe0\x7b\xa4\xd6\x09\x4d\xfc\x43\xb2\x52\x9e\x08\xc6\x9b\xa5\x56\xb5\xd8\xa6\xd6\x5a\xe5\xd6\x3f\xf9\x04\x27\xda\x13\xec\x77\x1e\x75\x1a\x99\xc7\xb6\x86\x18\xdc\x53\x33\xe1\x60\xe3\xb2\x72\x32\x87\x76\x91\xc2\x28\x9f\x60\xed\x09\xc6\xfa\xa3\x58\xee\x6c\x95\x8f\x48\x68\x1e\xf1\x60\x01\x59\x50\x9a\xa1\xdd\x9a\xec\xae\x10\xea\xae\xbc\xe8\xcd\xba\x78\x0c\x0d\x09\x3a\xac\x05\xb3\x2b\x44\x6b\xa2\x20\x02\xd7\x89\x01\x81\x88\x75\xfd\x3a\xed\xe2\x4f\x84\x47\x53\xfa\x05\xb5\x33\xe1\xb6\x04\x6c\x5a\xe6\x43\x23\x4b\xa4\xfd\x6a\xeb\x68\x64\x39\x74\x52\x09\x41\x54\xc4\x44\xeb\xdf\x65\x69\x54\xc2\x84\x0a\x06\x4a\x86\x17\x66\x98\x48\xc1\x40\x49\xf0\x13\x33\x4c\xac\x60\xc0\xe7\x67\x5f\x97\x61\xbf\x2e\xc3\x7e\x5d\x86\x1d\x66\x9b\x5f\x97\x61\xff\x29\xe7\x78\xc3\x68\xeb\x39\xde\x30\x1a\x9d\xe3\xd5\xdf\xd9\x86\x73\xbc\x61\xf4\x75\x8e\xf7\xc6\xe7\x78\xc3\x68\xd3\x39\x5e\x93\x72\xba\x73\xbc\xa0\x20\xf7\xa6\xed\x66\xed\xcc\xbc\x34\x4b\xbd\x3f\xf4\xd2\xec\x65\x14\xfc\x2e\x17\x17\x34\x74\xbe\xce\x02\x77\x67\x81\x2f\x23\x58\x53\xdd\xbf\x8c\x02\xed\xf7\x37\x51\xa0\xaa\x74\x03\xc4\xbe\x56\x27\x7a\xab\x9a\x6e\x5a\xff\x5e\x3e\x79\xfe\xcb\xf3\xc7\x8f\x5f\x3d\x3a\x7e\xd5\x9f\x2d\x7e\xf1\xc3\x2f\x3f\xfc\xf4\xfd\xa3\x37\x8f\x86\xb7\x72\xbf\x7c\xfe\xf3\x4f\xdf\xff\x72\xf4\xfc\xa7\x57\xc7\x0f\x7f\x6a\x5a\x6a\xe4\xe4\xb4\xf2\xd1\x66\xd3\xca\x5a\x8b\xd5\x6c\x59\x17\x6d\xe9\xcd\x49\xd7\xa4\xc5\xdb\x35\x9e\xa2\x2b\x5b\xa9\xf2\x4a\x4e\x89\x54\xe8\x01\x22\xc1\x7d\x54\x19\xa6\x44\xb4\x3e\xbf\xbd\x44\xbb\x28\x44\x77\xd1\x95\x3c\x3d\x58\xd5\x87\x34\xe1\x13\xd9\x81\x99\x4a\xf4\x17\x14\x0d\x72\x11\x48\x03\xf9\xc5\x1b\x74\x88\xae\xd0\x5f\x50\x68\xca\x12\xf9\xc5\x7f\x0a\xac\x04\xdd\x45\x82\x8e\x2f\xe8\xec\x18\x80\x2f\xe5\xb4\xdc\x9b\xde\xcf\x57\xf2\xe7\xff\xb4\x4c\x05\x6b\x62\x3b\x2b\x51\x09\xd7\x09\x18\x84\xd6\x48\xe6\x52\x4a\xe6\x52\x1e\xd0\xbc\x34\x08\xa6\x01\x95\xd2\x45\x57\x12\xf4\xca\x32\xad\xd4\x1a\x48\x57\x8c\x57\x70\xc1\xcf\xb0\xd7\x42\xae\xfd\xae\x7f\x1a\xed\x5b\x6f\x95\xa3\x6b\x0d\x4f\x1f\xbf\x7a\x29\x78\xbd\xf4\xb0\xc9\x18\xf4\x7b\x27\x2c\xf3\x63\x02\x0c\x48\xd4\xc6\xfa\x6c\x7d\xd1\xb3\x2d\x23\xd8\xd3\x1a\xcc\x22\x42\x75\xf3\xc4\xaf\xe8\x01\x8a\xef\xa3\x5f\x1d\x33\x73\xd0\x07\x38\x9a\x6a\xae\x8a\x52\x93\x4f\xcb\xea\xc5\x72\x0d\x75\x5c\x85\x55\xc1\x65\xb9\xbf\xee\xa0\x3d\x64\xda\x4d\x5d\x23\xd7\x1b\x3d\x40\xaa\x5e\x84\x09\x58\xfc\x0d\x3a\xf8\xfe\x10\x01\x19\x0d\x8b\x85\x56\x77\x47\xb5\x4e\xf5\xdb\x43\x20\x6b\xdf\x5c\x3d\xa0\xfc\x4c\xa3\xdc\x41\xb5\x67\x78\xef\x69\x18\xd8\x6c\x6a\x49\x33\xac\x05\xbf\xac\xc0\x80\x46\xd4\x42\xed\x3b\xd1\x0f\x0e\xd0\x8b\x55\x79\x5a\x56\xe5\x47\x8e\xce\x96\xf3\xab\xc5\xf2\xb4\x64\x73\xb4\xfc\xc8\x57\xe8\x3f\x1e\x4f\xc8\xce\x3d\x74\xf9\x9e\xa2\x5d\x74\xf9\x3e\x82\x7f\x43\xf8\x37\x10\x61\xc6\x8c\x52\x59\xb4\x24\x2f\xcf\x0f\xbc\x47\xde\x65\xec\xd8\x32\x6f\x61\x4e\x61\x38\x34\xda\xc7\xc8\xa2\x57\x2f\xc0\xcb\x39\x3e\x35\xfc\xd4\x05\xc6\xfa\x3a\x9b\x0e\xec\x67\x67\xdb\xd5\x94\x35\xf8\x4f\xc5\x4f\xcf\x96\x2b\xb6\xba\xea\xdc\x44\x27\x5c\xe0\x58\x1f\x88\xac\xab\x94\xc6\x5b\x67\xcc\xde\x7f\x6c\xec\xd9\x18\xdf\xbd\xb5\x1d\x7f\xb3\x95\x1d\xbf\xb3\xae\xe3\xbb\x56\x75\x6e\xfe\x2a\x81\xe5\x79\x75\x76\x5e\x3d\x85\x57\xeb\x0e\x2c\x82\x24\x3d\xe7\xeb\x72\xc5\x73\xed\xa2\x81\xb4\xac\xd6\x75\x41\x68\xd9\xb8\xf3\xb6\x50\x37\x7e\xbe\x98\xd7\x6a\xd2\x6a\x70\xb3\x15\xbf\x87\x08\x09\xa6\x88\x84\xd1\x14\xf9\x34\x98\xa2\x10\x93\x7e\x63\x75\x67\xc1\x3d\xf1\x4c\x7f\xd4\xbf\xb4\xa0\x7e\x69\xb6\xde\x5b\xa0\xf7\xae\x87\xed\x1a\xf7\x17\xc0\x4c\x2d\xdc\x84\x58\xbf\x7b\xd7\xdf\xde\xbe\xb3\x44\xfb\x0d\x4c\x4d\xfc\x01\x1e\x69\x72\x0b\x7e\xd1\x98\x1d\x2c\xc2\x8d\x95\x12\x00\x4e\x9a\xdb\x7a\x61\x04\x88\x3c\x0f\xed\x21\x31\xd0\x36\x37\x25\xe8\x92\x10\xd9\x8b\x4f\xbe\xd4\x8a\x9e\x61\x62\xce\x20\x34\xe3\xe4\x59\xdd\x89\xa7\x6c\x01\x73\x3f\xbd\xae\x1d\x20\x62\x9a\x43\x4b\xd7\xcb\x55\x3a\x2e\xff\x1e\xfa\xcf\xa9\x24\xf8\x8c\x94\xa8\xbb\x28\x26\x64\x6d\x9d\x36\x7f\x46\xe0\x0e\xfa\x3e\xb8\x88\xf5\xae\x62\x16\xd6\x2b\xa8\x05\x79\x67\x3d\x41\xd2\x29\x24\x48\xae\x53\x41\x90\x74\x4a\x07\x92\xeb\xd7\x0c\x54\x0c\xe3\x31\x8e\x71\x97\x65\x7c\x2d\x9e\x71\x97\x69\xbc\x0d\xd7\x46\x3d\x48\xe3\x6a\xa6\x46\xca\x45\xb5\x94\xd6\x6c\xd6\xf4\x9c\xc1\x64\x5e\xed\xce\x06\x51\x08\x88\x7d\xb8\x6f\xf6\xfd\x21\xc8\xc5\x06\x33\x5f\x5e\x20\x05\x33\xbe\x1a\xf1\x52\x0c\xb0\x6b\x8b\x0f\xc8\x44\x19\xfc\x40\x7e\x94\x49\x2f\x7c\xb6\xbb\xc0\xf1\x8c\x57\x6c\xf8\x64\x8b\xb7\x06\x0d\xd9\xb3\x52\xbc\x82\xcc\xcf\x4f\x17\xd0\x39\x83\x5b\xd5\x12\xac\xd3\xec\x29\x6a\x33\x69\x23\xf0\x96\xef\x24\x3a\x8d\x8e\x96\xda\x37\x14\x0b\x21\xf1\x57\xa7\x9e\x8d\xf6\x5c\xb0\x4f\x35\xd8\xf9\xf2\xc2\x9a\x97\x5a\xa5\x75\x6c\xcc\x73\x4c\x3d\x39\x16\x5a\x38\x7e\x7b\x69\xe3\xfd\xf8\x52\xda\xda\x21\xf4\xc0\x0e\x04\xc6\x76\x08\xac\x6f\xb6\xfb\xe6\x7a\x66\xe0\x08\xab\x6d\x8f\x02\xe8\xd2\x44\xe8\x25\x80\xd7\x43\xd7\x62\xf9\xf1\x25\x6e\xc1\xf1\x26\xe0\xd2\xbe\x8e\x2f\xb1\x4b\x8f\x0a\xf6\x69\x03\x0b\x7a\x74\x9a\xf7\xfa\x7c\x05\x1e\x25\xaf\x13\x11\xa6\x3e\x6e\xe5\xc7\x97\x81\x8a\x05\x68\x32\x51\xbc\x35\x47\x83\x15\x7d\x75\x3e\xd8\xf6\x7a\x03\xd8\x9e\x36\xd8\x64\xd4\x90\xd8\x9e\xf6\xb0\x3d\x1b\xc7\xf6\xbb\x3a\x55\x27\x14\x3a\xec\x13\xf5\x43\xa2\xc5\x4c\xd1\x56\x6f\x7b\x2f\x67\x4b\xf4\xa2\x74\x58\xb6\x20\x59\xdf\xf9\x88\xef\x6b\x5f\x65\x2a\xd7\x7c\xff\x6c\x93\xef\x48\xae\x41\xeb\x32\x63\x01\x24\x2d\x68\x2c\x20\xd5\xd0\x4f\x5b\x68\x7b\x48\x82\xc1\x62\xb6\x7c\x2e\xb3\x94\xc3\xce\x7c\x98\xce\x97\xb5\xb3\x2f\x97\x90\xe8\x39\x42\xbc\x78\x81\x6e\x49\x8c\x4e\x3c\x68\xbe\x32\xa9\x3b\xfd\xe0\x41\xcb\x24\x98\x76\xdd\x3f\xb8\x4a\xd3\x27\x68\x4f\x7b\x6e\x33\x74\xd4\x75\x9d\x06\x87\x11\xf9\xb3\x2d\x91\x77\xe7\x3c\xda\xee\x6e\x34\xe3\xd1\xef\xb2\xe2\x4a\x43\x03\xb3\x1d\x43\xe6\xa2\xe0\xda\x3d\x7f\x36\x42\xe3\xe9\x96\x34\x5c\x63\xdb\x8a\x2d\xd6\x67\xcb\xb5\xd3\x4a\x20\xfc\xbe\x28\x9f\x4a\xc7\x38\x7e\xab\x4d\x28\xb6\x76\x68\x1d\xf3\x64\xc3\x4d\x06\x3e\x05\x39\x36\xfa\x59\xe3\xc7\x59\x89\x58\x05\x43\x20\xc4\x4b\x73\x4e\x78\xec\x41\x1f\x8c\x45\x5b\x9b\x97\x23\xaf\x09\x00\x46\xb8\x63\xaf\xee\x8e\x84\xb6\xb9\xfc\xb1\x57\x77\x46\xc1\x59\xc6\xad\x83\x03\x74\x34\x73\x05\xbf\xcd\x87\xf5\x6b\x0e\x19\xe3\xa1\x11\x69\xe1\xab\x8e\xc3\xcd\xb8\x32\x62\xdc\xdb\x85\xd4\xba\xd5\x71\x63\x70\x9b\x37\xb9\xc4\x4d\xa3\x89\x96\x84\xec\x6c\x32\x00\x4a\x04\xa4\x87\x80\x0c\x10\x38\xa5\x28\x72\x8f\xd5\xf2\xc2\x21\xc4\xb9\xe6\x0d\xc7\xad\x6b\xbc\x47\x93\x7f\x28\xf6\xe5\x0f\xb7\x6b\x66\xe0\xab\x2b\x7e\xcc\x35\xaf\x39\x6e\x5d\x48\xc7\x08\x3f\xb4\x18\xe7\xcb\x8b\xcf\x9f\xa0\xfd\x61\x69\x7a\x23\x19\xe8\xdb\xea\x69\x9d\x69\x48\x31\xbe\xf5\x26\x33\xe1\xf9\xe8\x4b\x5b\x07\x8b\xcd\x11\x3b\xf9\x4a\xb7\x85\x70\x49\xc7\x62\xc7\x3f\xd7\xb6\x28\xc3\x24\xcd\x8d\xef\x8a\x1a\xc0\x37\x33\x3e\xa2\xdd\x70\x1a\xe8\x2e\x4c\x5e\x0d\xe7\x81\xae\xbb\x97\x0a\x5f\x67\x2b\x15\x6c\x92\xca\x78\x39\xef\xee\x77\xc2\x3b\xe8\xa0\xcb\xff\x0e\xba\xdb\xff\x01\x88\xc3\x02\x4d\xb3\x9b\xeb\x9f\x64\x13\xd4\x67\xcf\xe1\xe9\xd3\x8c\x35\xf3\xc6\x39\x48\x74\x60\x54\xbd\x0e\x52\xcf\x02\x0e\x71\x1e\x18\x37\xd3\xbd\xfa\xaf\x73\xce\xff\xc6\x87\x48\x67\x6c\x3d\xab\x8d\x7b\xa3\xbb\xe8\x07\x5c\x7c\xce\x64\xe1\xf8\x9c\xd0\xe6\x29\xbd\x2d\x9d\xdf\x7e\x0e\xb1\xa5\x67\x9f\x95\xd3\x52\x43\x35\x31\xa7\x27\x9c\x5b\xcd\xcd\x69\xa8\xd4\xf4\x9c\x8e\xea\xba\xf3\x8a\xad\x28\xdc\x9d\x78\x3a\xe8\xc4\xd3\xeb\x76\xe2\xe9\xa0\x13\x4f\xb7\xeb\x84\x59\x55\xd2\x74\x95\x93\x55\x4b\xb4\xe2\xd5\xaa\xe4\x1f\xb9\x61\x03\x22\x52\x87\xbb\x65\x3c\x38\x3b\x5f\xcf\x6a\x36\x4c\x22\x32\x40\x3e\x1b\x42\x7e\x7e\x79\x62\xc3\xe9\xa1\x86\xf4\x74\xe8\xc2\xd6\xf3\x44\x37\xb4\x6b\xd2\x1e\xbf\xd4\x16\x4a\x43\x38\x6b\x0e\x3b\x6d\x10\x21\x36\x5c\xcc\xa9\x3f\xb6\xfb\x33\x9d\x62\xff\xba\x5d\xf3\x9a\xdb\x35\xfd\x6d\x37\x6b\xfa\x63\x5b\x35\x7d\xc7\x46\x4d\xff\xeb\x36\xcd\x9b\xde\xa6\xe9\x6f\xb8\x49\xd3\xa0\x96\xce\x16\x4d\x7f\x93\x0d\x9a\xbe\xfd\x18\x7e\xb3\xf1\xf0\x1e\x0d\x3e\xbd\x9b\x52\xfc\x2f\xb2\x5d\xb3\x5f\x60\x27\xc4\xe4\x77\xdb\xc3\x59\x97\xdb\x11\x34\xff\x58\xe5\x76\xae\xb5\xdb\x52\x3d\x6e\x77\x7b\xd6\x30\x5b\x15\xe4\x09\x31\xe9\x6c\x0b\x09\x31\xb1\x6e\x33\xa1\x1b\x16\xe4\x11\x80\x9d\xad\x26\x54\x55\xb5\x08\x31\xb9\xb1\x23\xc4\x7a\xf7\xad\x35\x79\x06\x9b\x1c\xbc\xcb\x2c\x4d\xd3\x24\x0f\xf3\xa9\x56\xb0\x67\x67\x6a\x82\x8c\x48\xc2\x48\x42\x98\x5e\xce\x67\xc7\x50\xb7\xc7\xd0\x34\xc1\x61\xe2\xe1\x90\xe9\xd5\x7f\xcc\x44\x70\x48\x0a\x9e\xc9\x9a\x41\x75\x6d\xa0\x0d\x89\x44\xb1\xef\x93\x28\x92\x65\x85\x54\xe5\x20\x33\x11\xca\xd3\x20\x60\x34\xd6\xeb\x0a\x6d\x48\x24\x4f\xbd\x8c\x70\x2f\xd7\xcb\x10\x99\x89\x04\x71\x1a\x06\x14\xe7\x7a\x91\xa2\x5e\x6a\x7a\xd3\x55\x8a\x84\x3d\x5d\xb3\x4a\x11\x8e\xbe\x96\x29\xba\xa1\x9c\x88\x6e\x5d\xa6\x48\x34\x19\xcb\x8b\xf4\x98\x31\xcc\x8c\xe8\xd7\x32\x45\x37\x9f\x1b\xd1\x4d\xcb\x14\x19\x95\xd3\xcd\x8f\xe8\x68\x99\x22\x9f\xba\xcb\x14\x89\x61\xfc\x1e\x25\xa6\x6c\x89\xfc\x8b\x64\x4b\xff\xd2\x87\x5b\x6e\xf6\x60\xcb\x17\x3a\xb2\x72\xfd\x24\x4a\x3e\x6a\xba\xab\x10\xfd\x52\xef\xe0\x35\xdc\x75\xd3\xdd\xe4\xbb\xcf\xce\xce\xe6\x57\x13\xf5\xe3\x14\xb1\xd5\xc9\xf9\x29\x5f\x54\xeb\xfe\x9d\x3c\xfa\xf1\x99\x96\x1f\x28\xa5\xd4\x92\xe8\x91\xf7\x2e\x03\x42\x19\x29\x12\xc8\x2b\xf2\x98\x50\xc6\x09\xd9\x99\x0e\xe1\x62\xec\xc7\x41\x90\x40\x99\x41\xe2\xf3\x22\x0a\xb3\x5c\x4f\x0d\x06\x0d\xd2\x30\xf3\x8a\x34\x2b\xe0\x02\x84\x2c\xc8\xfd\x94\x14\x26\xc4\x3c\x49\xc3\x3c\x65\x21\xdc\x9e\x8d\x69\x92\xa7\x69\xe6\x44\xec\x27\x61\x94\x91\x30\x85\x74\xc6\x0f\x68\x1a\xfa\xd4\x84\x38\x4c\x0a\x8c\x71\x01\x1c\xa7\x91\x17\xe6\x1e\x4e\x9c\x88\x13\xe2\x17\x94\x30\xb8\x72\x9b\x15\x38\x09\x8a\x24\x35\x21\x66\x29\xce\x42\x9e\x03\xc7\x39\x8b\x72\x8a\x31\x75\x22\xce\xa9\x17\x33\x26\x65\xcc\x7c\xcf\xf7\x48\x60\x94\x31\x26\xd4\x0f\x53\x79\x67\x44\x10\xc6\x5e\x54\xa4\xdc\x89\x98\x04\x3e\xa6\x61\x0a\x77\x47\x04\x9c\x07\x29\xa1\x99\x51\x14\xa1\x97\xc5\x79\x06\x17\x88\xe7\x61\x51\xa4\x01\x27\x4e\xc4\x31\x49\x79\x98\xc7\x20\x8a\x82\xc4\x29\x4d\x22\xa3\xf2\xa8\x97\xf3\x14\xcb\xcb\x2b\xfc\x14\x47\x49\x94\x62\xb7\x8c\xd3\x3c\xf3\x22\x59\xa1\x92\x84\x59\x8c\x89\x1f\x9a\x10\x67\x38\x49\x0b\x2c\x19\xc8\x8a\x28\x21\x51\x12\x38\x11\xf3\x20\x49\xa3\x24\x03\xd9\x25\xbc\xc0\x01\xcb\x8d\x32\xe6\x45\xca\x83\x98\xc2\x35\xe2\x3e\x0d\x0a\x12\x72\xdf\x89\xd8\x2b\x32\x9c\xe4\x19\x34\xa0\x29\xcd\xf2\x30\x35\x72\x4c\x02\x2f\x63\x38\xcb\xe0\x92\xf6\x98\x65\x49\x16\x85\x6e\xe5\xe5\x3c\x21\x59\x04\x0e\x12\x26\x24\xf5\x48\x6c\x44\x1c\xb0\x38\xa0\x01\x83\x77\x84\x88\xb3\x88\x07\xd4\xcd\x71\x98\xa5\x1e\x4b\x72\xe0\x24\xcd\x03\x5c\xa4\x79\x60\x74\xe9\xa8\x48\x28\xcd\x01\x31\xf5\x31\x0e\xfd\xd4\xcd\x71\x42\x7d\x1e\xe2\x90\x80\x4b\xf3\x28\xca\x0b\x66\x76\x10\xea\xe3\x2c\x8a\x20\xc3\x27\x79\x1a\xf8\x04\x7b\xee\x58\xe1\x79\x3e\x89\x33\x2a\xef\x7c\x2f\x52\x82\x7d\xa3\xb9\xa5\x45\x98\xc4\x45\xa6\xea\x9b\xf2\xc2\xe3\xdc\x6d\x15\x59\xc4\x3d\x2f\x2d\xc0\xf0\xfd\x9c\x51\x5a\x64\x46\xab\xc8\x43\x16\x27\x38\x00\xc4\x89\xef\x31\x16\x13\xb7\x28\xbc\x28\x63\x91\x1f\xca\xeb\x5d\x3c\xcf\xa7\xc4\xec\x20\x38\x20\x09\x49\xe4\xbb\x97\xc7\x3c\x1e\xf1\xd8\x2d\x0a\x12\xa7\xb1\xc7\x28\x04\x97\x20\xca\x09\x29\x0a\xa3\x4b\x13\x8e\x85\x98\x40\x64\x61\x46\xa2\x2c\x21\x91\x13\x71\x90\x93\x2c\xca\x0b\xb0\x8a\x90\x65\x01\x61\x3c\x37\xc6\x0a\xdf\xa7\x5e\x8e\x41\x64\x49\x9e\x84\xa9\x9f\x17\x4e\xc4\x51\xe8\xb1\xd8\x0f\x03\xe9\x20\xac\x88\xfc\x9c\x9b\xcd\x2d\x62\x1e\x4b\x21\x6e\xfb\x59\x1c\xa7\x84\xb9\xc3\x26\xc5\x19\xc9\x12\x22\xa3\x5b\xcc\x73\xc6\x79\x64\x42\x9c\x90\x98\x90\x4c\x8a\x0c\x07\x94\xf8\xa1\x9f\x3a\x11\x33\x92\x16\x9c\x32\x19\x67\xb3\x02\x7b\x7e\x64\x74\x10\x46\x31\x8b\xa2\x00\x38\x4e\xb3\x80\xf8\x9e\xe7\x8e\x6e\x19\x09\x52\x9a\xc6\x1e\xc4\x59\xaf\xa0\x49\x9c\x60\x63\x74\x8b\xa3\x2c\xc4\x0c\x64\xec\x45\x61\x90\x72\xdf\x6d\x15\x39\x4e\x08\xa7\x38\x01\xc4\x11\x2f\x42\x82\x8d\x63\x5e\x1e\x25\x89\x17\x11\xd0\x45\x18\x46\x21\x4b\x46\x3c\xaf\x08\x3c\xee\x87\x52\x76\x61\x1c\x63\xe2\x11\x66\xb4\x63\x2f\x62\xcc\x93\x3d\xf3\x49\x9a\xe6\x38\x75\x2b\x0f\x27\x2c\xc8\x30\x86\xb0\x99\xd2\x9c\xe4\x5e\x66\xe4\x18\x73\x3f\x8e\x32\x4f\xda\x31\x0e\x30\x4b\x43\x77\x74\x23\x71\x40\xe3\x38\x00\x3b\xce\x0b\xca\x79\x9a\x24\x26\xc4\x7e\x90\x7a\x69\x96\x42\xcf\x38\x4e\xd2\x80\x8e\x98\x9b\x9f\xe0\xcc\xcb\x52\x50\x4a\x16\x66\x49\xc8\x22\xdf\x18\x8f\x79\x4e\x19\x0b\x20\x6c\x72\x3f\xc0\x94\x65\x6e\x73\x0b\xd3\x24\xcb\x58\x50\xc8\x91\x21\xf2\xb9\x1f\x1b\x11\x47\x94\xf0\xa8\x90\xc1\x2a\x8f\x52\x92\x52\xe6\x16\x45\x1c\xd0\x82\x12\x0e\x0e\x12\xe6\xbc\x48\x89\x39\x56\xc4\x94\x85\x91\x2f\x47\x9a\xc0\xc7\x31\x29\x22\xb7\x55\xd0\x20\xa3\x31\xc5\x32\x13\xc2\x85\xc7\xd2\xd8\x18\x36\x69\x96\xc5\x1e\x91\xca\xc3\x2c\x0a\xfc\x84\xbb\x73\xb7\xc4\x4b\x79\x51\x14\x4c\x66\x91\x91\x8f\x39\x31\x5a\x05\x0b\x42\x2f\xca\x38\x78\x5e\xce\x29\x49\x73\xee\xce\xdd\x52\x5e\x24\xcc\x2f\xe4\xc8\x40\xb2\x28\x4e\xb0\x39\xaf\x88\x62\x1c\xd3\x42\x0e\x61\x7e\x4c\x42\x9f\xb8\x95\x97\x31\x12\xfb\x3c\x03\x19\x73\x46\xa2\x08\x27\x46\x19\xe7\x98\x46\x29\x95\x43\x13\x11\x86\x44\xba\x93\x80\xc3\x44\x84\xe5\x2c\xce\x73\x70\x90\x2c\xe7\x1e\x4f\xb1\x31\x6c\x16\x61\x9c\x07\x45\x5c\xa8\x41\x97\xe7\x38\x76\xdb\xb1\x17\x15\x5e\x14\xcb\x7c\x21\x26\x38\x8e\x8a\xd4\xe8\xd2\x1e\x8b\xfc\x38\xcf\xc0\x41\x18\xc9\x68\x42\x99\x7b\x04\xc1\xd8\x2f\x12\xea\x05\x6a\xe2\x2e\xf1\x72\x66\xe4\x18\xa7\x31\xf6\x52\x5f\xc6\x63\x1f\x67\x41\x8c\xdd\x32\x26\x34\x4f\xe3\xb8\x08\xa5\x55\x78\x41\x9c\x53\x63\x3c\xf6\x49\xc6\x58\x1a\x83\x55\x04\x5e\x16\x93\x20\x71\x3b\x88\x9f\x25\x3c\xe5\x1e\x88\x02\x87\x59\x92\xf2\xd4\xa8\xbc\xc0\xc7\x79\x14\x67\xd0\xb3\x24\xc3\x9e\x97\x07\x6e\x3b\x0e\xb2\x2c\xcc\x03\x99\x78\x67\xa9\xcf\x03\x92\x1a\x87\x26\x91\xae\x90\x24\x81\x60\x55\x64\x51\x18\x73\x11\x5e\x5d\xb1\xa2\xc8\xd2\xa8\x60\x72\x90\x64\x79\x54\x30\x6e\xe4\x38\xca\x82\x00\x27\x14\x10\x07\x2c\x88\x43\x8a\x63\x35\x89\xfa\xce\x71\x6c\xb5\x7d\x2f\x7c\x7d\xdd\x13\xaa\xb6\x6b\xd0\x5e\x77\x4e\xa8\xfe\x72\xbd\x13\xaa\x21\x26\x9b\x2d\x1d\x18\x96\x23\x6e\xbe\xfa\xe8\x75\x97\x0e\x22\xe6\x25\xbc\x9e\x70\xf7\xd3\x2c\x4b\x3c\xcb\xd2\x41\x9a\x46\x31\xe3\x72\xf8\xa5\x41\xc6\x58\xdc\x4d\x5d\x1c\x44\xfc\x2c\xe2\x85\x1f\x43\x24\x2b\x78\x12\x14\x54\x44\x32\x13\x24\x0b\x83\xa2\x08\x7d\xf0\x82\xb0\xc0\xb9\x1f\x15\x9b\xce\xea\x87\xd8\xe3\x21\x91\xc1\x87\xe5\x3c\xa2\x24\xb7\x2c\x1d\x24\xa9\x17\x46\x54\x1a\x24\x49\x7d\x1e\x65\xb8\xd8\x90\x08\x2e\xa8\x9f\x27\xd2\xe6\x8b\x34\xc0\x69\x1e\x59\x7a\x12\xa6\xdc\xcb\x72\x99\x06\x61\x3f\xe6\x04\xc7\xc9\x36\x4b\x07\x37\x7d\x8e\x74\x93\xd2\xb0\x00\xe7\xd9\x2b\xbf\x3e\xc1\xf6\xd2\xaf\x4f\x88\xbd\xf6\xeb\x13\xdf\x5e\xfc\xf5\x49\x60\xaf\xfe\xfa\x24\xb4\x97\x7f\x7d\x12\xd9\xeb\xbf\x3e\x89\x2d\x05\x60\x65\x07\xa1\x3c\xac\x71\x1f\xb8\x7c\x3e\x97\xcf\x87\x87\x3d\xa4\x0c\xa0\xb9\xf1\x08\x94\x7c\x3e\x97\xcf\x2d\xcd\x09\x34\x27\xd6\xe6\x64\x2e\x9f\x5b\x9a\xfb\xd0\xdc\xb7\x36\xf7\xe7\xf2\xb9\xa5\x79\x00\xcd\x03\x6b\xf3\x60\x2e\x9f\x5b\x9a\x87\xd0\x3c\xb4\x36\x0f\xe7\xf2\xb9\xa5\x79\x04\xcd\x23\x6b\xf3\x68\x2e\x9f\x5b\x9a\xc7\xd0\x3c\xb6\x36\x8f\xe7\xf2\xb9\x61\x5b\xdf\x86\x45\x8f\xa5\x65\x98\x90\x33\x69\x14\xfd\x8a\x7b\xb0\xe5\x56\x1a\x84\xa9\x55\x2a\x6d\xc1\xd4\x2a\x93\x76\x60\x6a\x95\x49\x13\x30\xb5\xca\xa5\xfa\x4d\xad\x72\xa9\x79\x53\x2b\x2e\xb5\x6e\x6a\xc5\xa5\xc2\x4d\xad\x0a\xa9\x6c\x53\xab\x42\xea\xd9\xd4\xea\x44\xea\xd8\xd4\xea\x44\xaa\xd7\xd4\x6a\x26\x55\x6b\x6a\x35\x93\x5a\x9d\x9b\xea\x0e\xba\x8e\xee\x6e\x78\x1d\xaa\xb5\x9e\x76\x4d\xff\x75\x29\x6b\x0f\xdb\x8e\x9b\x3f\x82\x11\xbc\x5e\x3e\x1b\x82\x6c\x50\x28\x5a\x92\x11\x22\x78\x5d\xd6\xa7\x0d\xf4\xaa\xd1\xe8\x2e\x22\xef\x00\xd2\x5c\xcb\xb5\xc5\x31\x97\x38\xd4\xf9\x82\x3e\x0e\x38\x35\x7f\xad\x0a\xd4\x07\x07\xe8\x3f\xa0\x1a\xb1\x9d\x78\x5d\xd2\x79\xab\x0a\xd5\x97\xb3\xa6\xce\xf1\xe5\xd8\x59\x3c\x05\x36\xd7\x5a\xb8\xcf\xe3\x49\xa8\x59\xa7\x0a\xf6\x4c\x16\xff\xd5\x8b\x57\xcf\xa1\x44\x71\x5d\x0e\xb8\x03\x47\x07\x70\xb0\xe9\xf5\x3d\xea\x82\xc5\xae\x13\xa6\x12\x72\xde\xe1\x62\x3e\xe4\x62\x66\xe2\x62\x3e\xe4\x62\xa6\x73\xd1\x85\x8b\x87\x70\x96\x4a\xc6\xba\x4a\x2d\x35\x73\x3e\x6a\xb5\xb7\xb7\x29\xbe\xdd\x6a\x14\x6f\xa6\x51\xdc\x6a\x14\x6f\xa4\x51\x3c\xeb\x14\xf8\x9e\xd5\x55\xb8\xb5\xc2\xdc\x73\x55\xab\x5b\x13\x12\x56\x12\xee\x82\xc1\x3e\xe6\x44\x53\x69\x8d\x2f\x1a\x55\x29\x9e\x77\xd8\x98\x1b\xd8\x98\x99\xd8\x98\x0f\xd8\x98\x75\xd8\xe8\x22\x8c\x06\xf8\x48\xe4\xd4\xe9\x56\xb5\xc3\x5d\xa1\x24\x6e\xd5\x1e\xbb\xd4\xfe\xba\x8c\x65\xe4\x32\x0e\xcc\x3d\xc8\xb9\x82\x74\x9c\x09\x97\x90\x38\xd2\x02\x89\xf5\x56\xe8\x1a\x56\x32\x80\x8d\x99\x45\x1f\x76\x5e\xc3\x8e\xf2\xd0\x46\x9a\xb9\x10\x5a\x19\xf7\x47\xae\x2e\x78\x1b\xca\x66\x12\x7c\x06\x35\xdb\x04\x1e\xa1\x49\x6f\x07\x3d\xa8\xbd\xb3\xf9\xe5\xff\x47\x18\xdd\x43\x83\x6d\xd3\x43\x3e\xc4\xbf\xb5\x06\xc7\xd9\x10\xff\xee\x36\xde\x62\xe1\x02\x5f\x97\x0b\x90\xe2\x86\x3c\x48\xed\x0c\x39\x90\x9a\x18\xd0\x37\x23\x6d\x47\xc5\xd7\xa5\x4d\xbd\xed\xa8\xf7\xba\x34\x31\x67\xaf\x89\xaf\x8a\xe2\xcf\xd0\x6d\x54\xcc\x54\x59\x7c\xf1\xc5\x7c\x8e\x4f\xb6\x91\xbe\xcf\xe7\xa2\xcd\x5c\xb5\x11\x5f\x4e\xe6\x8e\x62\xfa\x33\xa8\xa6\x2f\x50\xa7\x92\x0e\x7c\xce\xe4\xe7\x54\x7d\xb6\x37\x9f\x43\x73\x41\x25\x95\x24\xe1\x73\x26\x3f\xa7\xea\xb3\xbb\x24\xff\x4c\xd6\xe4\x57\x01\x47\x8e\x2b\x6c\x2e\xcb\x4b\xef\xc8\xe2\x07\x6c\x56\x57\xec\x57\x0f\x3b\x35\xfb\x67\xda\x2d\x12\xac\x1e\x75\x9c\x95\xf9\xe1\x6d\x6a\xd2\x20\x52\x34\x67\x5d\x9a\xf3\x0e\xcd\x59\x97\xe6\x5c\xa7\x39\xdb\x84\x26\x96\xfd\xe4\x6a\x68\x90\xe7\x4d\xb8\x1c\x14\x68\x5d\xf6\x7f\x56\x5f\x5a\xa1\x3d\x0c\xda\x87\x82\xa6\x5f\x3f\x93\x65\xb8\xdd\x34\x65\x3f\x15\x70\x4d\x73\xd6\xa5\x39\xef\xd0\x9c\x75\x69\xce\x75\x9a\xb3\x96\xa6\x31\xeb\x1c\xbf\x87\xc0\xcc\xeb\x8f\x50\x7d\xe9\x47\xfb\x61\xaa\x1f\xc1\x79\x7f\x2c\x5d\xc7\xa8\x7e\x84\x60\xf0\x63\x69\x0b\xa1\x1f\xe1\xa2\x04\x01\x33\x9b\x37\x2c\x9a\x9c\x52\x02\x0a\x82\xb3\xb6\x2f\x32\x5c\x54\x58\x0f\x17\xb3\x4d\x62\x55\x4b\x56\xfc\x2b\x24\xe2\xa6\x59\x01\xa9\x6c\x66\x22\x98\x5d\x8b\xe2\x8f\xc6\xd0\xd3\xa7\xf8\x63\x69\xa2\xf8\x63\x79\x1d\x8a\xe6\x60\xd7\xa7\xf8\xda\x48\xf1\xb5\x89\xa2\xd9\xda\xfa\x97\x57\x58\x48\xc2\xe4\x45\xed\xf6\x00\x68\xe5\x0e\xe6\x41\xea\xa8\xb4\x2b\xc3\x23\xb0\x48\x74\x16\x6b\x5c\x9b\xb1\xf9\xf3\x59\xce\x2a\x8e\x2e\xdc\x6f\xfa\xe2\x0f\xde\x37\x8d\xf6\x0d\xaf\x9b\x27\x26\xb6\x61\x00\x2a\x4c\x6d\xe0\xc5\xb6\x30\xb5\x81\x77\x68\x6e\x6a\x03\xaf\xd0\xdc\xd4\x06\x5e\xc9\x27\xf9\x1c\xae\xef\x98\xdb\xee\xef\x80\x77\xfa\x49\x3e\x03\x28\x29\x3a\xae\x4b\x2e\x1f\x08\xcd\x7a\x13\x88\xc0\x94\x99\x78\x84\x29\x85\xcc\xc4\x23\xcc\x5e\xa4\xa6\x36\x30\x79\x91\x9a\xda\xc0\x3c\x09\x33\xb5\x81\x69\x92\xc1\x6d\x06\xe2\x0f\xa6\x5d\x26\xd2\xd4\x2b\x62\x15\x06\x4c\xdc\x4c\xa4\x1c\x84\x65\xed\xb6\x23\x8e\x94\x46\x35\x4c\x76\x6e\xf4\xb2\x12\x6d\xce\x10\x32\x83\x27\x60\xff\x6c\x90\x0d\x3c\x69\x8a\x51\x4c\x9e\x80\xdd\x33\xc9\xec\x13\x4f\xe7\x96\x0d\x99\xed\xe3\xd1\x66\x19\x25\x41\x10\x51\x3a\x24\x88\x5b\x82\x20\x9e\x54\x11\xec\x44\x82\x74\x9c\xa0\x36\x2f\x29\x09\x12\x08\xb1\x43\x82\xa4\x25\x48\x66\xf5\xb8\x34\x01\x78\x2d\xbc\x8e\x13\xd4\x66\x32\x25\x41\x5f\x10\xcc\x87\x04\xfd\x96\xa0\x2f\x68\xe5\x8a\xa0\x3f\xe2\x0e\x7d\x3c\xda\xdc\xa7\x24\x18\x08\x82\x7c\x48\x30\x68\x09\x06\x82\x16\x57\x04\x03\x9d\x20\x1f\x27\xa8\xcd\x96\x4a\x82\xa1\x20\x58\x0c\x09\x86\x2d\xc1\x50\xd0\x2a\x14\xc1\x50\x27\x58\x8c\x13\xd4\xe6\x57\x25\xc1\x08\x5e\x2a\x86\x04\xa3\x96\x20\x64\xef\x27\x8a\x60\xd4\x79\x89\x18\x27\xa8\xcd\xc8\x4a\x82\xb1\x20\x38\x1b\x12\x8c\x5b\x82\xf0\xda\xa4\xc6\x64\x01\xef\x4a\x02\x3e\xfb\xec\xc5\xd7\x4b\x71\x6e\xee\x52\x1c\x2c\x92\x7b\x75\xb3\x99\x40\x06\x75\x58\x7c\xef\xa6\xaf\xc5\x31\x93\xc1\xff\x94\x17\xe3\x1c\x2d\x17\x1f\xf9\x4a\x56\xf9\x45\xd5\x12\xf9\x64\x2f\x2d\x2b\x91\xa0\xe4\x88\xc1\xfe\xec\x94\x17\xcb\x15\x57\xdb\xa9\x07\x5a\xd3\xce\x9a\x68\x6b\x77\xd5\xf2\x8d\x4f\x6e\xe2\x22\x9e\x3f\xea\x15\x3c\x3a\x9f\x4d\x7d\x90\x7b\x08\x7b\x24\x38\xf0\x55\x9d\xe2\xaf\xa7\x9b\xac\x47\x95\x42\x4c\xb6\x3d\xdd\x24\x9a\x8c\x9c\x6e\xea\x6c\x6b\x18\x9c\x6e\x0a\x31\xf9\x7a\xba\xe9\xa6\x4f\x37\x09\xad\x6c\x76\xba\xc9\xa8\x9c\xce\xe9\x26\xa9\x20\xe7\xe9\x26\x79\x8e\x76\xc3\xd3\xdf\xfe\x1f\xfa\x3c\x13\x5f\x64\x7b\x29\x5b\xf3\x28\xe8\x3d\x38\xcd\xc3\x3e\xe8\xc7\xb3\x0f\x79\xd1\xfb\x31\x2b\xcf\x66\x7c\xf5\xbb\x1c\x89\xd2\x58\x85\xef\x82\x43\xf9\x40\x32\x06\x9f\x75\x7e\xfe\x15\x8e\x4e\xbd\xde\xe8\x4e\x20\xd8\x3c\x73\x04\x5d\x6f\xe0\xb4\xdf\xc6\x8f\x42\x1d\x1c\xa0\x17\x7c\x75\x0a\xa3\xe8\xd1\x6c\x59\x66\x1c\xe1\xfe\xb5\x29\xa2\xf9\x8b\x23\xdc\x3d\xbb\x14\xc6\x53\x14\x24\x53\x14\xe0\x29\xf2\xfd\x29\x22\xe1\x14\xe1\x78\x8a\x92\x29\x42\x58\xdb\x6a\x14\xd2\x29\x0a\xbd\x29\x0a\xc8\x14\xf9\xc1\x14\x91\x68\x8a\x30\x9d\x22\xec\x4d\x11\xd1\xe1\x92\x29\x0a\xf1\x14\x05\xfe\x14\xf9\xe1\x14\x91\x78\x8a\x70\x32\x45\x58\xe0\xd7\xe0\x22\x6f\x8a\x42\x32\x45\x41\x30\x45\x7e\x34\x45\x91\x3f\x45\x61\x38\x45\x41\x3c\x45\x7e\xa2\x01\xfa\x78\x8a\x88\x3f\x45\x38\x9c\xa2\x78\x8a\x50\x44\xa6\x28\x0c\xa6\x28\x80\xab\x05\x74\x40\xc1\x09\x99\x22\x1c\x4c\x51\x24\x00\xf1\x14\x85\xfe\x14\x05\xe1\x14\xf9\xb1\x06\x48\x92\x29\x22\x78\x8a\xb0\x20\x39\x45\x88\xd0\x29\x22\xde\x14\x61\xc1\x8e\x04\x7b\xe7\x90\x2b\x31\xcb\x95\x74\xe5\x2a\xb8\x10\x72\x14\xfd\x26\xe2\xf3\x14\xa1\x50\xe7\x56\x11\x16\xdd\x12\xdc\x02\x43\x9e\xce\xa5\xaf\x04\x27\xb8\x12\x00\xd1\x14\xe9\xdd\xc5\x91\x94\x87\x10\x30\x70\xef\x77\x15\x21\x14\x2a\x04\x2c\xe4\xe7\xc7\x52\xb0\x61\xd8\x93\x57\xe0\x29\x6d\x85\x52\xfb\x81\x4e\x41\xa8\x46\x98\x86\x2f\x54\x1a\x49\xb5\x87\xba\x0e\x85\x0a\x84\x3d\x08\xbb\x10\x3a\x14\x82\xad\xb3\x9a\xce\x8d\x50\xe7\xa7\xe7\x73\x06\xd7\xa4\x88\xa4\x72\x3d\x2b\x8b\xc1\x0d\x4f\xe0\x05\x3f\x1c\xff\xf2\xea\xc9\x0f\x8f\xe5\x9d\x52\x42\x62\x64\x8a\xa0\xf3\x42\x42\x54\x58\xa4\x52\x13\x48\x57\x59\x2a\x56\xea\x24\xca\x7a\x41\x20\x54\xa7\xff\xea\xbb\xe7\x6f\xf8\x1a\xb1\x45\xae\x6a\xa3\x9f\x81\x4a\xe5\x7d\x1a\x06\x3e\x04\xfc\x2f\x2f\xba\xfa\xec\xa5\x94\xde\xa5\x77\x0f\x5e\x46\x28\xf1\xbc\x69\xff\x59\xfd\xae\x20\x41\x0c\x00\xa4\x03\x40\x3d\x8f\x0c\x40\x7c\x0d\x64\xf8\x34\xd0\x9f\x1a\x08\x84\x5d\x02\xc4\x40\x20\xea\x32\x69\x02\x89\x7b\xfd\x30\x10\xa2\x1d\x46\x86\x28\x92\x3e\x95\x21\x0a\xa6\x83\x98\x00\xd2\xbe\xb4\x86\x20\x59\x8f\xcc\x00\x20\xef\x77\x65\x08\xc2\x35\x90\x21\x85\xa2\xcb\xe5\xb0\x39\x75\xb5\xc6\x74\x54\x1f\x84\x8e\x10\xf0\xe9\x88\x55\x05\x7d\x22\x06\xbb\xa0\x6e\xbb\x89\xe8\xa8\x61\xc6\xd4\x65\x98\x94\x8e\xea\x3b\xa1\x23\xfa\x66\x7d\x26\x0c\x26\xd1\x27\x33\xe4\x24\xa3\xa3\x1a\xcf\xe9\x88\xd5\x70\xea\xb6\xee\xa2\x4f\xc3\xa0\x79\xab\xba\x54\x94\xc0\x66\x41\x12\xed\xa9\x45\x99\x7e\x07\xc4\x48\x3d\xe8\x62\x31\xf5\x31\xd4\x41\x8c\x36\xa1\xf3\x69\x78\x1e\x77\xd9\x70\xf8\x06\x76\x98\x7f\xd2\xe7\xd4\x1a\x28\xb0\x43\xa3\x69\xb7\x33\x06\xab\xe8\x74\xc6\x1a\x27\xb0\xc3\x7e\x79\x0f\xc4\x16\x2a\xb0\x39\x14\xd0\x51\x51\x60\x3a\x2a\x0a\x42\x47\x55\xef\x53\xb7\xda\x82\x1e\x0a\x5b\xac\x70\x89\x3b\xa2\x2e\x13\x8e\xe9\x88\x32\x28\x1d\x91\x64\x42\x47\x4d\x8b\x51\xb7\x42\xd3\xbe\xbc\x0d\x83\x47\x9f\xca\x10\x24\xa7\x2e\x95\x72\x3a\xe2\x42\x45\x5f\xa3\xfa\x1d\x55\xd3\xb1\x2c\x23\xf0\x3c\x1a\x78\xd8\x1a\x41\x14\x8c\x35\xcd\x68\x14\x68\x8b\x20\x35\x11\xcf\x44\x24\xe8\x12\x31\xc2\x84\x5d\x3c\x46\x66\xa2\x2e\x1e\x23\x4c\xdc\xc2\x18\xa8\xe8\xc1\xd6\xd8\x3c\xe9\x93\x30\x20\x61\xfd\xee\xd8\x13\x0e\x45\xc8\x80\x24\xeb\x08\xd6\x00\x90\xb7\x00\xd6\x00\x22\x59\x30\x34\x2e\xfa\x5a\xb1\xe6\x5d\x4e\x61\x62\x3a\xd2\x0b\x42\x5d\xd2\xf6\xfb\x24\x4c\xb6\x41\x7b\x7a\x37\xd9\x06\x1d\x17\x78\x44\x47\x0c\x35\xa6\xe3\x86\x4a\xe9\x88\x52\x12\xea\x50\x0a\xa3\x6e\x5f\x4a\xfb\x1c\xd8\x03\x89\xd3\x55\x72\x3a\x62\xc4\xbc\x2f\x53\x7b\x3c\xb1\x5a\x90\xfe\x02\x62\x78\x8a\x37\x70\x7b\x4c\x36\x70\x26\xec\x6f\xe0\xf8\x38\xd8\xc0\x9e\x71\xe8\x74\x7d\x1c\x8d\xb9\x24\x8e\x47\x82\xa1\x9e\x82\x9b\x31\x24\x63\xe1\x12\xb3\x31\xbf\xc7\xe9\x06\xd1\x12\x67\x63\x81\x0c\xe7\x1b\x04\x4b\xcc\x37\x08\x65\xb8\xe8\x6b\xc8\x68\x2e\x63\xa1\x02\xe3\x31\x0f\xc5\x64\x03\x07\xc1\xfe\x88\x97\xe1\x60\x93\xc0\x16\x6e\x10\x76\x70\xe4\x8c\x6e\x38\xde\x20\x2c\x61\xba\x81\x2f\xe2\x64\x03\xaf\xc7\x6c\x83\x68\x8a\xd3\xb1\x08\x86\x33\x57\x08\xc3\xf9\x58\x58\xe0\x1b\x84\x51\x5c\xf4\x22\xd4\x36\xa9\x0a\xf6\x02\x4b\x30\x32\xb3\x4c\x3a\x52\xc1\xd6\x14\x45\xe2\x36\x61\x0f\xb4\xe7\x9e\xe1\x79\xd8\x53\xce\x10\x22\xea\x08\xcd\x44\x23\xee\x40\x8c\x0f\xc7\xf6\xdc\xa4\xa5\x62\xcb\x4c\xea\x9e\xda\xb2\x92\x96\x8b\x21\x9f\x59\x4f\x9a\x43\x88\xbc\x23\x2d\x5b\x6a\x02\x18\x2c\x69\x89\x6a\x6b\x96\x80\xab\x7b\x98\x8e\xb1\x4f\xa8\xdd\x50\x7c\x3a\x66\x28\x01\x1d\x53\x74\x48\xdd\x9d\x8f\xa8\xdb\x94\x62\xed\xf9\xf0\x29\xa5\x76\xd1\x25\xd4\x25\x3a\x46\xc7\xcc\x2b\xa5\x6e\x27\xc8\xa8\xdb\x74\x72\x3a\x66\x18\x9c\x8e\x39\x41\x41\xc7\x4c\xbc\x93\x56\x58\x8c\x00\x8f\xb8\x2b\x26\x23\x16\x8a\xfd\xd1\x90\x81\x03\xa7\xa5\xe2\x70\xd4\xe1\x71\x34\x1a\x35\x70\xec\x8a\xc4\x74\xd4\x13\x71\x32\x1a\x32\x30\x73\x78\x23\x4e\x47\xc2\x05\xce\x46\xa3\x16\xd6\xc3\x81\x81\x04\x1f\x89\xbd\xb8\x18\x0d\x49\x2a\xb5\x70\x76\x13\x3b\xfd\x0a\x93\xf1\xd0\xe2\x3b\x22\x07\x0e\x46\xdc\x1a\x87\xa3\xb1\x05\x47\x4e\x07\xc6\xf1\x68\x6c\xc3\x74\x24\xf8\xe0\x64\xd4\x03\x31\x1b\x09\x03\x38\x1d\x8d\x81\x38\x1b\x0d\x05\x38\x1f\x8d\x47\x98\x3b\x82\x1d\x2e\xba\xd1\x68\x9b\xfc\x81\x7a\x92\xa4\x39\xb6\xd4\xd9\x27\xf6\x02\x4b\x2a\x51\x33\x6d\x78\xee\xb7\x18\x02\xb3\x21\x06\x76\x23\x0a\xbb\x12\x31\xe7\x10\x4d\x72\x6c\x22\x1f\x7b\x9d\xf4\xcf\x3e\x7e\xd6\x2b\x2a\xe6\x0c\xa2\xd5\xad\x39\x7f\x90\xcf\xcd\xb9\x43\x2b\x3e\xdb\x0a\x4a\x2b\x1e\x03\x8e\x5c\xf3\x52\x4b\xe6\x50\x9b\xb7\x39\x77\x68\x15\x6c\xe9\xbf\x53\xbf\x98\xda\xbb\x47\xe8\x18\xf3\x3e\x1d\x13\x40\x40\xdd\x2a\x0e\xe9\x58\x17\x22\x6a\xb5\x9f\x98\x8e\x19\x1f\xa5\x2e\xf9\x25\x5d\xe2\xb6\x24\xc2\x61\x1d\x29\x75\x69\x2f\xa3\x63\xd6\x97\x53\xb7\xfd\x72\xea\x76\xbf\x82\x8e\x79\x08\xf6\x46\x5c\x04\xe3\x11\x2f\xc4\x64\xd4\x0d\xb1\xef\x1a\x29\x9c\x16\x8e\xc3\x51\x17\xc1\x91\x37\xa6\x27\x1c\x8f\x46\x32\x4c\x47\xbd\x05\x27\xa3\xe1\x02\xb3\xd1\x80\x87\xd3\x91\x98\x89\xb3\xd1\xb8\x81\xf3\x91\xb0\x84\xb9\x23\x2e\xe1\xc2\x19\x36\x64\xf6\xe0\xee\x03\x1e\xf5\x4b\x4c\xec\x8e\x89\xfd\x11\xb7\xc7\xc1\x88\xe1\xe3\x70\xd4\x77\x70\x34\x1e\xdd\x62\x47\x78\xc3\x74\xdc\x79\x12\x67\xfc\xc0\x6c\x34\xfe\xe1\x74\x34\x88\xe2\xcc\x19\x44\x70\x3e\x1a\xa5\x30\x1f\x09\x53\xb8\xe8\xc6\x91\xed\x92\x07\x63\x4c\xa9\xf9\xb5\xad\x90\x34\xdc\x18\x53\x86\x7b\xda\x76\x0d\x63\xc6\xa0\x00\x60\x3e\xc5\x98\x37\x34\x39\x9f\xe1\x79\x54\x23\xb0\x01\xc4\x2d\x83\x86\xa7\xba\xce\x6d\x29\x43\xcb\x9f\x25\x67\x68\x7b\x68\xa0\x90\xb6\x0c\x9a\x59\xc8\x3a\x00\xa6\x81\xc3\xea\x7b\x5c\x57\x8e\x01\x75\xd1\x11\x8e\x79\xce\xc1\xd5\x1e\xd3\x11\xe1\x12\xea\xd9\x0c\xc7\xa7\x6e\xc3\x09\xa8\xcb\x70\x42\x3a\x62\x17\x11\x1d\x91\x5a\x4c\x47\x4c\x8f\xd2\x11\xd5\x26\xd4\x26\x77\x46\x47\x74\x9a\x52\xb7\xd5\x66\x74\xc4\x6a\x72\x3a\xa2\x39\x4e\xdd\x86\x5b\x50\x97\xd9\x63\xcf\xe9\xb6\x18\x7b\x56\xbd\x62\x32\xe6\xd3\xd8\x1f\xf3\x49\x1c\x8c\x78\x35\x0e\xc7\x9c\x02\x47\x63\x91\x03\xc7\x23\xbe\xdd\x8c\x7b\x56\x35\xe2\x64\xcc\x81\x30\x1b\x89\x8f\x38\x1d\x8b\x20\x38\x73\x46\x28\x9c\x8f\x45\x18\xcc\xed\x83\x73\x31\x12\x21\x20\x3f\x70\xeb\x0a\x8f\x58\x1a\x26\x23\x9e\x8e\xfd\x31\x67\xc6\xc1\x98\xb3\xe2\x70\x2c\x54\x45\xf6\x50\x84\xe3\xb1\x60\x81\xa9\xdb\x5d\x92\x31\x87\xc7\xcc\x1a\x2c\x70\x3a\xe6\xcb\x38\x1b\x09\x17\x38\x77\x06\x4b\xcc\xc7\x42\x19\x2e\x7a\x01\x67\x9b\xac\x40\xb1\x4d\x4d\x51\xa4\xc6\x69\xca\x0b\x64\x5b\x62\xee\xb3\xdf\x3e\x27\x26\xdc\x41\x2b\x11\x23\xfe\x50\xef\x8f\x29\x2b\x68\x9e\x0e\x71\xc7\x1d\x83\xb6\x8e\x8a\xc6\x6c\x40\x63\x6a\x88\x98\xd5\x64\x8d\x2c\xa7\xca\x40\x4d\x19\x80\x26\xab\xe1\xf3\x5c\x43\x3b\x7c\xca\x9b\xbe\x0e\x9f\x15\x1d\x29\x9b\x7a\xea\x54\x12\xa6\x6e\x25\x11\x6a\xe9\x91\x4f\x5d\xda\x09\xa8\xab\x3f\x21\x75\x5b\x5d\x44\xdd\x96\x11\x53\xbb\x3c\x28\x75\xd9\x45\x42\xed\xf6\xcc\xa8\x5b\xf5\x29\x75\xeb\x30\xa3\x16\x9b\xca\xa9\x5b\x45\x9c\xba\x6c\xaa\xa0\x6e\x53\xc6\xde\x88\x1f\x61\x3c\x62\x7c\x98\x8c\x78\x2a\xf6\x1d\x06\x88\x03\xa7\x9f\xe2\x70\xc4\x15\x71\xe4\x8d\xc4\xa0\xd8\xe9\x73\x4d\x06\x6b\xe1\x3d\xb1\x46\x6d\x66\xf3\x56\x9c\x8e\x84\x36\x9c\x39\xe2\x22\xce\x47\x62\x08\xe6\x23\x3e\x8b\x0b\x67\x70\x13\x23\xba\x85\x71\xec\x34\x25\x4c\x9c\x4e\x8b\xfd\x11\xbf\xc4\xc1\x88\x63\xe2\xd0\xe1\x99\x38\x1a\x89\x35\x38\x1e\x0d\x56\x23\x9e\x84\x93\x11\x1f\xc5\xcc\x11\x00\x70\xea\x8c\x5a\x38\x73\x86\x16\x9c\xdb\xfc\x1f\xf3\x31\x17\x2e\xba\xa1\x67\xfb\xa1\xdb\x60\x23\x35\xab\x81\x87\x0d\x43\xb7\x4a\x35\x0c\x83\xb6\x42\x6a\x6a\x16\x34\x49\x8e\xe9\x69\x68\xe9\x7e\x24\x51\x1a\xc6\xe8\x36\x65\x1a\x3e\xa5\x5a\x07\x4c\xc3\x74\xd3\xf7\x61\x53\xa6\x19\xf9\xf0\x69\xaa\x75\xc2\xf4\xaa\xae\xe5\x71\x86\x61\x5a\xca\x6d\x88\x95\xb7\x72\x33\xbd\xa4\x6b\x99\xef\xb0\xa7\x2e\x31\x60\x6a\x16\x2a\xa1\x2e\xfd\xfa\xd4\xd5\xc7\x80\x3a\x0c\x27\xa4\x2e\xe1\x45\xd4\xd5\x93\x98\xda\xc4\x43\xa9\xc3\xac\x12\xea\x52\x35\xa3\x2e\x8d\xa4\xd4\x61\x08\x19\xb5\x99\x79\x4e\x5d\x96\xcc\xa9\xd9\x62\x0b\xea\x50\x32\xf6\x9c\x5a\xc6\xd8\xe9\xae\xc4\xe9\xaf\xd8\x77\xfa\x0a\x0e\x5c\xee\x80\x43\xa7\x2b\xe1\xc8\xe9\x10\x38\x76\x45\x04\x35\xde\x18\x1f\x25\xce\x68\x81\x99\xcb\x63\x70\x6a\x09\x1a\x38\xb3\x05\xd9\xdc\xe9\xb9\x98\x3b\x83\x02\x2e\xac\x11\x11\x7b\x4e\xad\x63\xa7\x23\x62\xe2\xf6\x6e\xdf\x62\x69\x38\x70\x3a\x1a\x0e\x5d\x2e\x8c\x23\xab\x1f\xe2\xd8\x19\x19\x30\x75\x7a\x3f\x4e\x9c\xbe\x88\x99\x25\x58\xe1\xd4\xe9\x6e\x38\x73\x45\x07\x9c\x5b\xbd\x18\x73\x67\xe4\xc0\x85\x16\x1c\xb6\x19\x53\xa9\x18\xe0\x89\x01\x61\x23\x9c\x61\x3c\xbe\xd7\x2e\x6e\x0c\xc3\xb1\x6c\x37\x0c\xc4\x0a\x9f\xe1\x51\x28\xf1\x11\x23\x1f\x51\xf3\xd0\x14\x84\x15\x27\xe6\x71\x86\x7a\x66\xfe\x93\xa6\xdf\xa6\x10\x2c\xf9\x34\x3d\x4a\x1b\xa4\x06\x3e\xb3\x7b\xf2\xb0\xc7\x30\xfc\x9a\xed\x84\x37\x42\x34\xb4\x29\x14\x13\x86\x47\xf5\xa2\x92\xb5\xe7\xf2\x31\x76\xc9\x54\xc1\x10\x97\xfe\x15\x8c\xef\xd2\xb5\xfa\x3d\x70\x09\x5b\xc1\x84\x76\xb1\x2a\x88\x68\xb4\xcf\xb1\xc5\xb4\xd4\x63\xea\x92\xa8\x82\x49\x6c\x5a\x52\xcf\x99\xdd\x4a\x15\x44\xea\xb2\x47\x05\x93\x99\x55\xae\x9e\xe6\x2e\x33\x52\x30\xdc\x65\xa2\x0a\xa6\xb0\x7b\x68\x9d\x11\x1b\x1d\x1b\xbb\x7a\x80\x89\x45\xc8\xd8\xb7\x59\x1c\x0e\x5c\xcc\xe2\xd0\xa5\x16\x1c\xb9\x84\x81\x63\x47\x17\x6d\xf1\x37\xb1\xab\x10\x33\x97\xa5\xe2\xd4\x19\x0f\x33\x97\x47\xe1\xdc\x6e\xdf\x98\xdb\x8c\x0e\x17\xe3\xde\xd5\xbe\xdc\x58\x21\xb0\x3b\x16\x60\x32\x6e\x70\xd8\x1f\xf3\x3e\x1c\x38\xbd\x0f\x87\xe3\x41\xa0\x56\xb6\xb3\xbb\xf1\x78\x50\xc2\x74\x3c\xb8\xe1\x64\x3c\x1a\xd4\xe6\xe0\xf2\x32\x69\x14\xd6\xa7\xd9\x58\x58\x93\x86\xe1\xe0\x93\x8f\x45\x9c\xda\x48\x80\x8a\x36\xb2\xcb\x8f\x7a\x5d\x83\x67\x6c\xfd\x61\x8d\xaa\x19\xab\xd0\x9a\xcf\x79\x56\x41\x3d\xa2\x57\xdf\x3d\x7f\x83\xca\xc5\x59\x7d\x4d\x44\x53\xd1\xe0\xd9\xc3\x57\xbd\x8b\x8b\xdb\x83\x89\x53\xd4\x6e\xfc\x87\x0b\x14\xd5\x17\xf8\xac\xbe\x4c\xf5\x86\x9e\xfa\x55\x02\xc8\x2f\xf5\x67\xf1\x65\xaa\xf5\xa7\xcf\xb9\x56\x55\xe9\xfb\x47\xaf\x64\x61\x2c\x24\x0b\xbf\xb8\xef\xa8\x12\xd0\xcd\x05\x55\xf2\x8b\x56\x25\xe5\xba\x57\x54\xb9\x4b\xeb\x7d\xe0\x57\x4d\x09\xb0\x0f\xfc\xca\x50\xfa\xee\x03\xbf\xaa\xeb\xea\x7d\xe0\x57\xe6\xb2\x7a\x82\x86\x54\x51\x18\xa1\xb4\xac\xd6\x88\x65\xd9\x72\x95\x97\x8b\x13\x54\x2d\xd1\x8b\x23\x6c\xc4\xfb\x5d\x09\xa5\x80\xde\xf6\x6b\x20\x9b\xee\x0e\x09\x23\xfb\xdd\x21\x2d\xba\x17\x4b\x81\xf0\xc5\x11\x7e\x5b\xbe\x43\x7b\x08\x1b\x6a\x94\x2a\xba\xb2\x3c\xff\xa4\xee\xdd\xdb\xb6\xbd\x2a\xc7\x27\xfe\x33\xf1\x31\xda\xd3\x50\x43\x1d\xbe\x1d\x74\x7b\x80\xd8\x50\xb0\xf4\xe1\x7a\xcd\x4f\xd3\x39\x47\x38\x42\xeb\xf3\xf4\x03\xbf\x32\x88\x7f\x7d\x9e\xfe\xc8\xaf\xd6\x8d\x0a\xda\xef\x76\xa1\x2c\x5e\x01\x90\x14\x4d\xfd\xe5\x01\xc2\x51\xf3\xcd\x7e\xc5\xca\x11\x54\x9c\x52\xfc\x98\x05\xb9\xae\xb1\x2b\x5e\xde\x2a\xa4\xef\x14\x53\x46\xbc\xee\xab\x5b\xd2\xb2\x7a\x05\x55\x51\x0e\xb5\x22\x28\x0d\x5e\x1b\x4a\x69\x50\x01\x35\x1a\x14\x19\xb6\x31\x59\x0d\x09\xec\x56\xd3\xa5\x53\xac\x96\xa7\x10\x60\xe6\xbc\xa8\x10\xa1\xe0\x19\x82\xb2\xb9\xa1\x14\xce\xdb\x49\x89\x0e\xe4\xdd\x10\x1e\x14\x70\xac\x8d\x6b\x32\x79\x71\x44\x94\x0d\xee\xa0\xdd\x46\x02\x3b\xe8\x2f\x88\xd0\x77\x50\xe3\x11\x6c\xab\x44\x7f\x81\x3b\x2e\x36\x66\x6f\x55\x9e\xcc\x36\xe7\x2f\x80\xf2\x9d\x2d\x93\x3b\x1d\x2e\x09\x85\xc7\x92\x57\xb4\x8b\x48\x60\x61\x78\xc7\xc0\xf1\x80\xac\xa9\xb2\xbf\xe8\x40\xb9\xc8\x38\xe2\x2c\x9b\x29\xb3\x43\xe5\x1a\xb1\xb3\xb3\x79\xc9\x73\xa1\x4b\xb6\x40\xfc\xf2\x8c\x2d\x72\x9e\xd7\x75\x19\x21\xbc\x4f\x8d\xd8\x84\x08\x14\x9a\x8c\x2d\x50\xca\x51\xba\x5a\x7e\xe0\x0b\x54\x2e\xaa\x25\xa2\xb2\x28\xf0\x1a\xad\x33\x36\x97\xe8\x25\xca\xb5\x19\xdb\xc5\xac\xcc\x66\x88\xcd\xe7\xcb\x8b\x35\xa0\x16\x78\xab\xa5\x40\x7b\xbe\xe6\x39\xba\x28\xab\xd9\xf2\xbc\x92\x0c\xae\xcb\xe5\x62\x88\x45\x09\x1a\xca\x6b\x4e\xda\x2f\x0f\x1e\xa8\x6b\x65\xda\x9f\x44\x40\xf1\xb1\x49\x72\x1d\xcb\xc5\xd2\x72\x63\xb7\xe1\x2a\xb4\x10\xc4\xda\xcf\x10\xb3\x26\xa5\x54\xe2\x5d\x24\xb4\xef\x9b\x55\x65\xeb\x47\xac\xf7\x23\x7e\xa7\x0a\x7b\xfe\xa6\xff\x04\x97\x02\x0c\xae\xda\x31\x44\xc0\x23\x59\xf8\x12\x95\x8b\x8f\x7c\xb5\xe6\xf6\x28\x58\x2e\x3e\xbe\xea\x05\xc2\xce\x4f\x1b\x0d\x10\xd8\x31\x40\xb4\xd8\x74\x89\xad\xdf\xe2\x50\x18\x74\x1f\xfb\xa7\xce\x84\x43\xfb\x85\x2f\xb2\xd5\xd5\x59\xb5\xc5\x55\x80\xaa\x62\xed\xf2\xa8\x69\xd7\x02\x4f\xbb\x21\xdf\x5a\x42\x37\xe7\x5f\x82\x6a\x2b\x11\x57\xed\xde\x23\x37\xe5\x69\x2d\x48\x53\xd2\xf1\x1f\xbc\xd2\xf3\xb4\x2e\x73\x73\x40\xaa\x5d\x8d\xd5\xd7\x81\x04\x5b\xf5\xc1\xe0\xe6\x2c\x43\xf6\xf1\xc3\xa2\xac\x4a\x36\xd7\x4b\x5f\x75\x61\xf8\x65\x36\x63\x8b\x13\xfe\xf4\x65\x5b\x16\x55\x56\x1e\xf3\x2e\xbd\x42\xfe\xaf\x6f\xd2\xe6\x36\xf2\x7e\x6a\x78\x63\x2d\x0a\x6b\x9b\x97\x4f\xf5\x36\x04\xe8\xf8\xea\x6f\xb3\x36\x54\xf2\xe6\x15\x85\xf8\xff\x86\xbc\x41\x9b\x50\xfd\x19\x2b\xd3\xba\xae\x6a\x93\xe5\xc3\xc0\xa3\xe4\x47\xe9\x55\xf0\x79\xfc\xda\x36\xc3\x48\x64\xcc\x27\x00\x9d\xed\xda\x8b\xc6\x30\x74\x3b\xb1\xc0\xae\xba\xb0\x2b\x05\x6b\x64\xf2\x31\x2f\xd7\x15\x9f\x37\x56\x6c\xc6\x58\x40\xe7\x37\x4b\x2d\xa8\x3b\x40\x17\x62\xa0\x95\xa5\xd6\xde\x96\xef\xde\x4e\x26\x8a\xdb\xf7\x6d\xb8\x16\x89\x64\xf3\xea\x02\xdf\xa1\xac\xb6\x49\x34\x86\x80\xdd\x73\xa4\x95\x4d\x52\x3d\x4f\x9a\xd7\x6c\x14\xe3\x01\xfc\xe7\x45\xbe\x44\xeb\x0b\x76\x26\xd3\x8f\x39\x5b\x57\xd2\x18\x86\x21\xbc\x72\xab\xac\xc7\x6c\x57\x61\x2e\xc7\xaf\x0c\x36\x0c\x15\xc5\xb7\x75\xf5\x81\x6b\xdc\x98\x0b\x5e\xc7\xd5\xaf\x13\x52\x46\x42\x97\xe1\x8d\xac\x42\xcb\xf3\x6a\x10\x81\x9b\x90\xeb\x56\x59\x27\xe4\xda\x75\xd6\x19\x32\x3e\xf0\x2b\x59\x02\x3a\x0a\x0e\x7c\xa2\x3f\x29\x3f\x5a\x1e\x68\x75\xa3\x23\x63\xd5\xe8\x03\xf4\x4a\x58\xa0\x7a\x09\x58\x2d\xd7\xeb\x36\x4d\x87\x9a\x87\x90\x10\xc3\x6b\xa9\x6c\xd1\x0c\x54\xad\xe0\x26\xf5\x78\x75\xca\xd6\x1f\x3a\x2e\x5b\xdb\xee\x64\xd2\x31\x51\xe1\x88\xf5\xe8\xfa\xbe\xd3\x75\xe1\xb4\x02\x8b\x26\x82\x8e\xc9\xbe\x07\x9b\xfd\xc6\x68\xf8\xe2\x99\xc8\xa8\x24\x66\x05\x55\xfb\xdd\x80\xed\x97\x4f\x37\x67\x7b\x65\x67\x7b\xee\x66\x7b\xee\x60\x7b\xb5\x01\xdb\xce\x22\xd2\xeb\xba\x8a\xb4\x9c\xfe\xd8\xac\x8e\xf4\x58\x11\x66\x89\xab\xe2\x97\x95\x5e\x8a\xf9\xfb\x47\xaf\xf6\x55\x82\xd6\xa9\xc5\x3c\x45\x59\x71\x62\x28\xae\x7d\x36\x67\x82\x89\xcb\x0a\xf5\xb1\xa8\x84\x6b\xd2\xd2\x31\x21\x6a\x2a\x3b\x0f\x27\x6a\xba\x45\xb7\xbf\x7f\xf4\xca\x58\x71\xfb\x78\x55\x9e\xcd\xf9\xde\x76\x53\x44\xb2\x51\x67\xa2\x48\xff\xe9\x8f\x33\x5d\xa4\x26\x22\x04\xdb\x25\x54\x28\xcd\xfa\xd7\x03\xa9\x2c\x96\xaf\x31\x3a\x14\x70\xfb\x52\xaa\x8f\xa4\x8e\x97\xab\x49\x7b\xcf\xba\xba\x38\xbe\x26\xbd\xbf\x9e\x97\x19\x9f\x78\x53\x44\x76\x06\x77\x61\x34\x68\xc9\x35\xd1\x92\x29\x0a\x1c\x68\xfd\x6b\xa2\x0d\xa6\x28\xda\xb1\x5f\xa4\x71\xed\x77\x0f\xbe\xc6\xfb\x7a\x63\xad\x85\x55\x32\xfb\xfa\x3b\xc7\x06\x0d\xfc\x0d\x28\xdc\xcc\x3b\x8d\xa0\xb5\x25\x73\x64\xdb\xee\xe3\x0d\x28\x98\x47\x3d\x9c\x90\x1b\x1b\xf6\xfe\x49\xc2\x6a\x13\x5d\x6e\x20\xb8\xb6\xb8\xb6\x0c\xb1\xb6\x10\xd7\x0d\xb4\x0d\x94\xb3\x7e\x7e\x03\xd5\x2b\xa1\xaf\x15\x66\xbf\x17\x92\x69\xaf\xaa\xbe\x56\xdc\xfd\x5e\x18\x4c\xdb\xaa\xee\xf7\xc2\x68\xaa\x8a\xbd\xdf\x8b\xf0\xa7\x77\x53\x1a\x7c\x56\xc1\xfd\xdf\xb3\xd2\xfe\x17\xab\x87\xff\xdf\x53\xd9\x1e\x6e\x2a\x28\x17\x3c\xbf\xd9\x12\xf7\xdf\xb1\x35\x6f\xab\xd6\xb3\x35\xd7\x9e\xbd\xf1\x89\xb3\x02\xfe\xd0\x97\x2f\xa3\x00\x2d\xd8\x29\x5f\x9f\xe9\x5e\x7a\xa0\xb3\x21\x40\x04\x1b\xf2\xbf\x7f\xff\x64\x42\xf3\x10\x45\x41\x73\x85\x8d\x09\xcd\x9b\x28\x10\x7c\x00\x53\x97\x51\xb0\xaf\xbe\x08\xfe\x0d\x99\x41\x8b\x5a\xa2\x57\xd3\x29\xe5\xdf\xf8\x1a\x31\xb4\xe0\x17\xf3\x2b\x24\x7d\x2d\x37\x11\xd6\x03\x0a\xea\xdc\xe6\xb1\x38\x3f\x4d\xf9\xea\x13\x82\x5b\xa5\xe0\x56\x15\xf1\xc1\x27\x90\xce\xef\x3b\x9b\xcc\x97\x17\xd0\x42\xfc\xd7\xd4\xa0\xdb\xb8\x1b\xdd\x86\x00\xb5\x5c\x2e\x5b\xb9\xd4\x11\xa1\x16\x4f\x3d\x30\xcb\xd5\x3f\x8f\x78\x3e\xbc\x95\x05\x5e\xe8\x45\x5e\x77\xbe\xb3\x96\x34\x84\xf8\x45\xd9\xc9\xa8\x44\x0f\xa7\x82\x6b\xf3\x18\xa6\xee\xd7\x32\xdc\xea\x09\x8f\x45\x6f\x0f\x51\xf7\xf6\x6d\xfd\xcd\xbc\xaf\xa9\xef\xca\xea\xa2\x5c\x73\xf4\xd3\xf3\xe3\x35\x60\x18\x53\x4c\x7d\x51\x8a\x32\x90\x4f\xe8\xa1\xd0\xaf\x90\xcb\x1e\x08\x46\x8d\x24\xac\xa8\xf8\x0a\x2d\xf8\x09\xab\xca\xc5\xc9\x0d\x08\x1e\x50\x71\x21\x78\xa5\x82\xfd\xc5\xb2\x9a\x58\xa5\x7a\x70\x80\x16\xcb\xd1\x4c\x15\xee\x64\x91\x02\xfd\x47\x23\xdd\xfb\x46\x30\x29\xd8\x7f\xd4\x42\x36\xa4\xa4\x4a\x32\x4a\x30\xb5\x35\xb4\xea\xbc\xdf\xe1\xae\x93\x01\xd8\xb4\xf2\xf0\xa7\xef\x35\xad\xc0\x72\x02\x8c\xdb\x67\x6c\x0d\xcb\x0b\x1b\xf9\x50\xa3\x29\xc0\x21\x5c\xa2\x51\x56\xb5\x14\x24\x6a\xbc\x37\xac\xfc\x87\x3f\x7d\x7f\x33\xaa\x97\x6b\x3b\xad\xe2\xd9\x22\x9f\xb0\xc5\xb2\x9a\xf1\x95\x62\xc4\x65\x06\x6c\x91\xeb\x66\x20\x7a\x38\x62\x0a\xad\x9f\xdd\x96\x02\x19\xb3\x8a\xc6\xf3\x14\xfc\xef\x66\x1f\xcf\x5f\x7e\x69\xf3\x78\xfe\xf2\x0b\x59\xc7\xf3\x97\x37\x63\x1c\xcb\x55\xc7\x36\x96\xab\x2d\x4c\x63\xb9\xba\xb6\x65\xfc\xb6\xa5\x65\xfc\xf6\x3b\x5b\xc6\x9b\x2f\x6f\x1a\x6f\xbe\x98\x6d\xbc\xb9\x29\xe3\xb8\xec\x59\xc7\xe5\x56\xe6\x71\xf9\x19\xf6\xf1\x7e\x4b\xfb\x78\xff\x3b\xd9\x07\x2c\xca\xeb\x96\xb1\x90\x33\xa3\xea\x85\x70\xce\x8b\x6a\xf3\xac\x6c\x01\x36\x21\xbf\xa1\x65\xd1\x60\x82\x2b\x6c\x6e\xca\x18\x00\xd9\xcd\x98\x03\xa0\xea\x18\x04\xfc\xf2\x74\x42\x42\x97\x1d\x48\x20\xdd\x14\x16\x26\x3b\x10\xaf\x40\x0b\xf4\x00\xf9\xc4\xb6\xd2\xa5\x59\xca\xa4\x35\x95\x07\x0f\xd0\x02\x96\xc8\x1b\x63\x90\x5b\x87\x08\xda\x43\x0b\xe3\x65\xf5\x66\x13\x12\x78\x86\xb6\xf6\x09\xd5\x2f\x4f\x6e\x86\x74\x34\x93\x05\xda\x33\xdc\x18\x3a\x20\xdd\x5f\xea\x12\xe4\xfe\x3b\xad\x17\xa6\xf2\xff\xed\xcc\xf7\xe5\xc4\xfe\x72\x51\x5b\xef\xcb\x1b\xb2\x5e\xa9\xf7\xae\xa5\x6a\xc6\x5b\xdb\xf3\x06\xc6\x3b\x88\x98\x80\xea\x1a\xf6\xab\x79\x41\x83\x67\xdc\x80\x15\xf9\xdf\xdd\x82\x5f\x2e\x2b\x56\xf1\x2f\x1d\x80\x57\x40\xe5\xa6\x4c\x18\xb0\xdd\x8c\x09\x4b\xc6\x74\x13\x5e\x2d\x47\xe3\xaf\x00\x19\xb5\x5f\xd5\x23\xb0\x03\x15\xd5\x17\x3b\x22\x1d\x6c\x7f\x79\x39\x89\x82\x81\x59\x7e\xae\xc2\x6e\x28\xe6\xfc\xb1\x34\x36\x12\x72\x04\xc4\xf6\x0a\x7b\x39\x50\xd8\xd3\xeb\x28\xec\x61\x9e\x7f\xe9\xcc\x97\xe5\xf9\x17\xca\x7c\xe5\x95\xdf\x37\xf1\xce\x9c\xf7\xde\x99\xf3\xad\xde\x99\xf3\x8d\xdf\x99\xfb\x23\xc2\x6e\x93\xc8\xc2\x86\x51\x73\xf2\x9b\xb1\xd5\xea\x4a\x34\xab\xc7\x10\x79\x31\x7c\x67\x58\x69\xaf\x87\x37\xe3\x18\x26\x52\xbb\x6d\xce\x8d\x76\x25\x0d\xc5\xc3\xe7\x46\x74\xf9\xcd\xbc\xba\xf2\x70\xa1\xae\x00\x5f\x16\xfa\xdc\xe6\xda\x74\xc3\xf1\x6a\x79\xc6\x57\xd5\x15\xfa\xbb\xba\x62\x18\x00\xc1\xbc\x1a\x14\x83\x69\x45\x65\x20\xeb\x7d\x13\x9e\x3a\xac\x34\x77\xa2\x77\xa3\xcb\xba\x3c\x59\x94\x45\x99\xb1\x45\x85\x52\x78\x5e\x2e\x34\xdf\x00\xa2\x8e\xd9\xdf\x76\x5e\xba\x66\xa6\xfe\xe5\x06\xe6\x81\x87\x1c\xd8\xdd\xb1\x23\xae\xc9\xf3\x33\x61\x96\x6c\xbe\xd3\x91\xfd\xa8\xe0\x90\x31\x20\x37\x92\xd3\xd0\x6e\x24\x44\xde\x55\xf3\x67\xf8\xea\x85\x2e\xea\x7e\x2f\x3a\x6b\xbe\x5d\x9f\xfd\x4c\x64\x6f\x07\xed\xc5\xdf\xb6\xd3\xda\xd3\x6d\xb1\x60\x8a\x13\xcc\x70\x0a\x67\x6a\x32\x9c\x63\x8e\x8b\x9d\x01\x92\x77\xff\x46\x5d\x9d\x22\xec\x6d\xbc\x3c\x00\x46\x37\x6d\xcc\x76\x10\x96\x2f\xd4\xe6\x09\x08\x8b\xf5\x17\xf9\xdf\xdf\x7e\x33\x1c\xc0\x10\x79\x7f\xe3\x03\x7f\x3a\x44\xc3\x55\x30\xfd\x4f\x8e\xcd\x35\xf8\x61\xc3\x46\x7f\x2f\xa0\x35\x69\xef\x23\x90\x3e\x34\xe7\x8b\x93\x6a\x86\xee\x22\xba\xe1\x56\xea\x7e\xa0\x39\x5a\x2e\x3e\xf2\x55\xfd\x6a\xa8\x85\x61\x15\x1f\xc4\xa0\x5d\x9f\x0e\xd8\x28\xf0\xd4\xa3\x76\xa3\xdd\xce\xca\xdc\x27\x74\xdc\x0d\xa2\x77\xd6\x28\x67\x15\x43\x6c\xbd\x25\x9d\x8d\x67\xb2\xba\x2b\x85\x97\x5a\x80\xde\xaf\x96\x6f\x7c\x62\x5f\x0a\x81\xc7\x9f\xb1\x67\x47\xd1\xea\x1a\x95\x61\xe7\x4e\x0d\xf7\x54\x2a\xb3\x61\xb2\x56\xaf\x69\x17\x8f\x54\x9b\x01\x97\xec\xee\xc6\x9b\xf7\xbb\xb4\xdd\x27\xbd\xda\x25\xbc\xba\xd5\xdb\xc1\x16\x7e\xf1\x57\xf3\xb0\x7f\x76\xbe\x9e\x4d\xea\x44\x4a\xe4\x08\xa6\xf7\x4a\x33\x74\x2f\x97\x40\x86\x7d\xb2\x75\x2a\xa2\x29\xb8\x8e\x20\x35\xce\x69\xd7\x6d\xac\x1b\x49\x06\x5e\x01\x68\x84\x49\x66\xcb\x33\x18\x24\x2d\x63\x3f\x1a\x4d\x5b\x1b\xb3\xe7\x28\x9b\x2f\x17\xae\x37\x95\x4d\x4d\x1a\xf0\xf4\x6d\x19\x7e\xb4\xdb\x32\x3c\x76\xda\xb2\x8e\x19\xb2\x14\xc9\x6e\xb3\xf3\xd5\xb4\xd3\xf5\x08\xe0\xff\x0c\x86\xfd\x67\x29\x99\x21\xd2\x3a\x96\x4a\x7c\xc3\x30\x5b\xef\x1a\xb3\x13\x80\x33\x4c\xf5\xc2\xba\x4c\x4e\x2c\x64\x1a\x17\xba\xe8\xf8\xcf\xa8\x1b\x5c\x6c\xe2\x03\x17\xca\xe4\x6b\xf4\x6f\xcb\x77\x26\xb1\xdb\x4d\x15\x80\x3b\xeb\xcb\x4d\x7a\x6c\xdd\x37\xd3\xdb\x2d\xa3\xb6\xc6\x7c\x7a\x37\xa5\xe1\x26\xfb\x5d\x0e\xee\xfe\x09\xcd\xaa\xea\x6c\x7d\xef\xe0\xe0\xb4\x9a\xad\xf7\x53\x7e\x70\x5e\x15\xf4\xd7\x35\xfa\x48\xf6\xf1\x3e\x41\xe9\x15\xfa\x1f\xa7\xac\x9a\x95\x6c\x2d\x2c\xa6\xdd\x20\x03\xbb\x42\xe4\x66\x8f\x83\x03\xf4\x3d\xaf\xe4\x71\x38\xce\x85\xb8\x4b\x96\xce\xf9\x1a\xfd\x55\x51\xfa\xeb\xad\x6f\x60\x1b\xff\x8a\xf3\x47\xcd\xfe\x97\xc1\x4e\x1a\x74\x47\x2a\xef\x0e\xba\x7d\xbb\xfe\xf9\xbe\x1d\x3d\xfa\xab\xec\x8e\x86\xfc\x19\xfc\xd0\xe2\x3e\x55\xdf\xbb\xa8\xd5\xaf\xb7\x6f\x1b\xf6\xe7\x1c\x76\x98\x6c\x80\x9d\x6c\x9c\xc0\xce\x99\xbf\x4e\xe5\x6e\xfc\x9f\x96\x39\xdf\xff\x75\x8d\x96\x2b\xf4\x9d\xdc\x4a\x53\x16\x25\xcf\x51\xb6\xcc\xf9\x14\xb0\xb0\x45\x8e\xce\xd7\x1c\x95\x95\x18\xd7\xfe\x2a\xe4\xa8\xf5\x41\xed\xc3\x69\xfa\x70\xa2\xbe\x77\xfb\x20\x7f\xbd\x2f\xf7\x24\xb5\xcd\xf6\x1b\xe8\x43\x1d\xd9\x6f\xbf\x69\xdf\xf6\x2f\xca\x45\x2e\xde\x2e\x3b\x30\x72\xeb\x90\xe0\x05\xe9\x3f\xc3\x66\x9f\x5b\xdf\x1c\xdc\xdd\xbb\xb1\xbf\xbb\x07\xb7\x64\x6f\xd7\xd5\xaa\x5c\x9c\x3c\x5e\x2d\x4f\x8f\x66\x6c\x75\xb4\xcc\x85\xe6\x5e\xc1\x8f\xfb\x85\xf6\xab\x12\xfe\x31\xfb\xc0\x17\x52\xc6\x7d\x93\x3d\x3b\x5f\x5c\x09\xf9\xde\xfa\xa6\x89\x60\xe7\xd9\x9a\xe4\x5c\xfc\x38\x91\x74\x64\x07\x61\x69\x13\x36\xdf\xd7\x43\x20\xfc\x94\x2d\xcf\x17\x15\x5f\xa9\x99\x4b\xf8\x69\x5e\xc7\x0a\xd9\xbc\x0d\x16\xf0\x14\xce\x33\xd6\x5f\xf8\x65\xb5\x62\xe2\xcb\xc5\xac\x9c\x73\x34\xa9\xb1\x3d\x50\x48\x24\xe9\x6f\xa0\x4d\x8b\x30\x53\xdd\x7b\x58\xd5\x0d\x76\x77\x85\xab\x7f\x03\x3a\x95\xc0\xdf\x1e\x22\xef\xf2\x7b\xea\x79\x42\xe7\xf2\xa7\x07\xf0\xd3\x77\x8f\x1f\x8b\x9f\x2c\x94\x84\xb8\xe0\x75\x7d\x7d\xbe\x5a\x2d\x4f\x58\xc5\xa7\x60\x75\xd5\x8c\xaf\x38\x9c\xf3\x44\x0b\x7e\x59\x21\xc1\x02\xcb\x2a\xbe\x82\x46\xd0\x8d\x4d\xf8\x03\x06\x27\x12\xfc\x36\xf2\x2e\x1f\x1f\x79\xde\x8e\xb0\x50\xef\xf2\x7b\xf8\xf8\x77\x11\x9c\xe7\xcb\x8b\x96\x3e\x34\xfb\x46\x4a\x5e\x0e\xe5\x13\xd5\x45\x81\xc0\x7f\xfc\x78\x07\x8e\x66\x7a\x3b\x68\x17\x69\x98\xe1\xc1\x6e\x5d\x71\x48\x51\x6f\xb3\x60\xd5\xd5\xf3\xc5\x29\xab\xb2\x19\xcf\x5b\x7a\xf7\xd1\x72\x31\xbf\x42\xec\xec\x8c\x43\xbf\xcb\x35\x38\x20\x3a\x5f\x94\xd5\x54\xbc\x68\x66\x6c\xcd\xe1\x6d\x53\x08\xa2\xc1\xd4\xc0\x08\x21\x55\xf5\xbe\xa8\x06\xab\x18\xea\x99\xf6\xf5\x8c\x95\xab\x61\xcf\xa0\x5f\x8a\xd7\x6f\x94\xe8\xf6\xf6\x14\xef\xb7\xfa\x1d\xb0\xb4\x14\x80\xe2\xff\x2a\xde\x4b\xa8\xda\x1b\xaf\xe3\x0c\x7c\x01\xce\x00\xa3\x70\xeb\x0b\x8d\x95\xcb\xbc\xa5\x6b\xe4\xe5\x22\xe7\x97\xe8\x10\xed\x61\xa3\xd9\x37\x7e\x74\xe7\x8e\x66\xfc\xbb\xbb\xb2\x99\xc5\xf8\x81\xce\x5b\x00\x79\xd7\x37\x76\x61\x4a\x8f\x85\xc6\xa5\x64\xe4\xaf\x7b\x87\xb5\xfa\xef\x6b\xf2\x42\xbb\x87\x86\xf8\x51\x23\xfa\xf6\x5b\x84\xbd\xda\x80\xd0\x6f\xca\x87\x94\x4a\x6a\x4e\xa4\xb1\xa2\xdf\x50\xc7\x0e\x1b\xe1\x6f\x40\x08\x10\xda\x94\xd4\x08\x3f\x9b\xf1\xec\xc3\xab\x8c\xcd\xd9\xea\x7f\x89\x56\x13\xa1\x87\x17\xcb\x72\x21\x77\x53\x83\x00\x9a\x9f\xba\x1e\xdf\xfe\x2c\xbd\xbe\x15\x4e\x35\x5b\x2d\x2f\xd0\xa3\xd5\x6a\xb9\x9a\x40\xaf\xee\x3c\x15\xa9\x50\x6b\x9a\x3f\xef\xde\x41\xbb\x2d\x82\xfd\x6a\x29\x23\xeb\x04\x47\x3b\xfb\xd5\xf2\xe7\xb3\x33\xbe\x3a\x62\x6b\x3e\xd9\x41\xbb\x12\x81\x30\xf9\xc5\xb2\x12\x06\x0e\xcc\x4a\xb9\xdc\x11\x0f\xeb\x8e\x7e\xfa\x02\x23\x41\x2b\x27\xc8\xaa\x45\x26\xde\x8a\x63\x2a\x97\xd9\xd4\xe0\x24\xa5\x6c\xd0\xc6\x44\x17\xe0\xb7\x75\x1b\xa9\x51\x98\xaa\xbc\xa4\xde\x4e\x5f\x2f\xd2\x21\x8e\xea\x86\x26\xb5\x68\x68\x6f\x2b\xe3\x7c\xfc\x98\xaa\x58\xa7\xc2\x1c\xde\x4b\xaf\x2a\x8e\xd6\xfc\xbf\xce\xf9\x22\x83\x40\x67\x67\xb4\xa5\x51\x9b\x0e\x0c\x84\x57\xa7\xe9\x72\xde\x38\x92\x8d\x32\xf5\xba\x94\xc9\x90\x72\x83\x69\x5c\x48\x91\x14\x10\x56\x02\x3a\xf2\x1a\x96\x9a\x8d\xc7\x06\x26\x20\x0c\xeb\x4c\xf8\x43\x26\x1c\x06\x7f\x7f\x4b\x26\x31\x91\x5c\x7a\x8a\xcb\x47\x5e\x07\xc5\xee\xa1\xc5\x6a\xa2\x0d\x3a\xf3\xc8\x1b\x74\x26\xf8\x2c\x89\x62\xaa\x98\x8d\x25\xb3\x8f\x37\x64\x16\x93\x6d\x3b\xd5\x42\x9a\xb8\xea\x76\xb4\xeb\x01\x8d\x6d\x02\x86\xbe\x4b\x88\xd4\x5f\x8d\x13\xfd\xa4\xa9\x41\x2a\x52\xf7\x61\x72\x35\xc8\x9a\x5a\xf8\xd1\x41\xa5\x01\xad\x7f\x10\x4a\x90\xd1\x6a\xc3\xc1\xa5\xed\xb1\x4e\x58\x1f\x65\x34\x94\xbb\x87\x0e\xd7\xef\x45\xf4\xb6\xd9\x97\x4a\x84\x1b\xd9\xaf\x38\xcb\x8f\x96\x8b\xaa\x5c\x9c\xc3\xe1\x59\xd0\x7e\x1b\x8a\x04\x27\x3f\x40\xdf\xbf\x3d\x04\xb6\x8e\x44\x62\x61\x18\x0d\xee\xfc\xb0\xf8\xc8\xe6\x65\x0e\x40\x52\xda\x77\x54\xb7\x1a\x79\x77\xa9\x20\x89\x10\x26\x0a\xde\x36\x74\xde\x29\x37\x11\x4d\x9b\x1f\x77\x77\x45\x32\x5e\x47\xa8\x1e\x9a\xdb\x32\x8c\xc8\x44\x50\x44\xc9\xbf\x6b\xc1\xd0\x08\xed\x3f\x6e\x18\x3b\x38\x40\x3f\x14\xe8\x82\x23\x91\xaf\x9d\x9f\x21\x91\xa9\x4e\x51\x59\xfd\xdf\xff\xfd\x7f\xea\x61\x49\x47\x01\x1c\xdf\xb2\xf4\x7c\x00\x78\x67\x10\xfc\xa5\xf5\xbe\x02\x2f\x98\xb4\x56\x2e\x80\xb1\x6e\x86\x44\xff\xe2\xeb\x5f\x02\x83\xf9\x0e\x75\xf5\x19\xaa\xea\x62\x3a\x1c\x6a\x5d\x49\xb6\x60\x73\x38\xfc\xd0\xc8\xf1\x25\x67\x39\x2a\xca\xd5\xba\xaa\xa5\x04\xdd\xda\x5e\xcd\xc3\xd1\x0d\x4d\x16\xcb\xa1\x78\xd7\x3b\xb5\x4d\x48\x42\xb7\x95\xfe\x55\x64\xd5\x78\x6d\xe4\x5b\xf3\x3a\x1c\xc3\x7a\x78\x1e\xd5\x06\x75\x54\xa3\x02\xb5\xa0\x43\x8b\xc3\xdc\xef\xc7\x03\x1d\x19\x96\xaf\x19\x50\x73\xa7\xd1\xae\x29\x01\x6b\xac\xb7\x35\x5f\x2d\x46\x75\x13\xf8\x2d\x4c\xb0\x4e\xeb\x65\xdf\xfd\xbe\x6c\x4f\xd9\x15\x2a\x17\xd9\xfc\x1c\x5e\x42\xc4\xcb\x85\xfe\x4a\x63\x92\xf2\xe3\x5a\x3a\x8f\xb6\x90\x0e\x98\xf2\xf5\x04\xe8\xa9\xf7\x34\x02\x7b\x93\x24\x2d\x5d\xa0\xbe\x4d\xa0\x1e\x24\x2f\x52\x60\x63\xf9\xc1\x97\x94\xf9\x70\x84\xef\x4b\x94\x2a\x89\x3e\xbe\x59\x89\x42\xc8\xb8\xa6\xd0\x63\x10\xba\x77\xd9\x17\xbb\x77\xe9\x1d\xed\xa0\xdf\x40\x22\x13\xc9\x83\xfc\xb5\xd1\x47\x60\xd5\x07\xbc\x51\x19\xde\x31\xb0\xa7\xbf\x82\x99\x35\x51\xcb\xd3\xa8\x85\x9f\x8f\x1f\xef\x51\x94\xc3\x4c\x19\xcf\x9b\xc8\x5b\x87\x4d\x75\x02\xab\xf9\x0e\x01\x4d\xfb\x0e\xf1\xe7\x7e\x2f\x27\x51\xb9\x46\x3b\x1a\x4b\xfe\x1a\x7c\xdd\x94\x44\x03\xab\xa3\x1a\x50\xd1\x03\xa0\x96\x94\x68\x31\xb6\x9d\xfd\xe9\xa4\x3b\xed\x3c\x51\x75\x7a\xa6\x65\x23\x93\xea\xf4\x0c\x1d\xf6\xc6\x92\x1d\xf4\xa7\xc3\x43\x19\x94\xfb\xd9\x89\x5a\xc4\xa8\x4e\xcf\xfa\x79\x86\xf6\x82\xde\x42\xef\x7c\xc9\xc9\x37\x21\x56\x74\x08\x0c\xde\xf9\xc8\x57\xeb\x72\xb9\xb8\x73\x0f\xdd\x81\x49\xdf\x3b\x53\xf1\xab\xe4\xe7\xce\x3d\x2d\x2b\x84\xdf\x65\x77\xd5\xef\xf2\xcb\xad\x6f\x3e\xa9\x49\xba\x57\xcb\x53\x8e\x1e\x3e\xfb\x1e\xa5\xe7\xe5\x3c\x47\xcb\xb3\xaa\x3c\x2d\xff\xc6\x57\xeb\x29\x9a\x97\x1f\x38\x5a\xed\xff\xba\x9e\xca\x57\x62\x98\x69\x5f\x9f\xf1\xac\x2c\xca\x4c\x38\x6f\x5e\x82\xc2\xcf\x58\x55\xf1\xd5\x62\x0d\xf8\xa0\x51\x35\xe3\xa8\x58\xce\xe7\xcb\x8b\x72\x71\x72\x4f\xce\x79\x0a\xf3\xeb\x9d\x8b\x44\x77\x6a\xa3\xb9\x23\x27\x77\x3b\x00\xfb\xec\x34\xef\xcd\xa2\x36\x47\x24\xc5\xb3\x5b\xdf\x48\x75\xa9\x43\x93\xcd\x34\x77\x77\x00\x13\x7d\x06\xdd\x81\x72\xda\xb7\x8b\xde\xac\xf1\x9f\xb4\xef\xfb\x8b\x65\xce\x8f\xaf\xce\x78\x9b\xcc\xb5\x73\xd5\xea\xc5\xa3\x5c\xe8\xf3\xc6\x2f\xcb\xc5\xc9\xf2\x7f\xbe\x42\x1f\xbd\x7d\xba\xef\xc1\xeb\x79\xdb\x42\x3b\x4b\xda\x30\xa3\x42\x63\x8d\x89\xad\x2e\x66\x6c\xde\xc3\x14\xef\x7b\x7b\x72\x22\x66\x55\xef\x8d\x92\xa7\x18\xd5\x6f\x33\xb6\x7e\x7e\xb1\x78\x51\x6f\x81\x39\x54\x40\xfb\xdd\xdf\x01\xbc\x59\x22\x81\xaa\x71\x52\x28\x75\xc4\xe8\x82\xcb\xf5\x21\xf1\x1c\x0e\x12\xef\x08\xd9\xe8\xb2\x7a\xfb\x41\x16\x30\x14\x10\xf0\xb9\x33\xf9\xd5\xeb\xd7\xcb\x59\xb9\x58\x8a\x5e\x31\x74\xc1\x53\xa4\x0e\xaa\xaa\x59\xeb\x7d\x65\xd0\x4a\x26\x9f\x6e\xa9\x23\xaa\xb0\x6c\xf2\x69\xfa\xf7\x4f\xef\xa6\x34\xda\x64\x49\x64\x70\x62\xf7\xcd\xb3\xa7\x4f\xaa\xea\xec\xa5\x18\x32\xd6\x55\x83\xed\xcf\x69\x79\x22\x37\xb3\xec\xff\xba\xfe\xf3\x26\x98\xef\x9c\xaf\x39\xbc\xb0\x65\xd5\x9d\xfb\xb7\x86\x84\xbe\x2b\x4f\x7e\x02\x84\xf7\x45\x87\x7f\x5d\xcf\x44\x50\x2e\x4f\x16\xcb\x15\xbf\x37\x2f\x17\xfc\x56\x43\xfa\x82\xa7\xfe\x46\x24\x85\x92\x5e\xf3\x54\x8e\x4d\xf2\x98\xf1\x9d\xfd\x83\x79\x99\x1e\x08\x14\x22\x38\xdf\x3a\x38\x40\xf9\x72\x51\xa1\xe5\x47\xbe\x5a\x95\x39\xaf\x17\x1c\xea\xf5\x8d\x5b\xda\x11\x64\xb5\x72\x20\x02\xdc\x9d\x66\x43\x03\xac\x47\x74\x00\xf6\x25\xc9\x2e\x94\x30\x10\x58\x26\xd3\x41\x80\xb9\xfb\xb7\x3e\x19\xa4\x21\x9f\xa8\x85\xad\x9a\xe3\x3f\xdf\x23\xe4\xd3\x3b\x21\x85\xe9\x5b\x29\x85\x77\x3b\xb7\x0e\x0e\xfe\x3f\xb4\x5e\x9e\xaf\x32\xfe\x8c\x9d\x9d\x95\x8b\x93\x9f\x5f\x3e\x3d\x14\x0f\xf7\xe6\xb0\x89\xf4\xd7\xf5\xfe\x29\x3b\xbb\xf5\xff\x02\x00\x00\xff\xff\x64\xb1\xb4\x44\x52\x1f\x06\x00")
+var _web3Js = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x7b\x13\x39\xd2\x38\x0e\xbf\xcf\xa7\x50\xfc\xdc\x0f\xb6\x89\xb1\x73\x60\x18\xc6\x99\x0c\x1b\x02\x33\x64\x6f\x20\x5c\x40\x76\x76\xef\x6c\x96\xab\xed\x96\xed\x1e\xda\xdd\xfe\x75\xb7\x73\x18\x92\xef\xfe\xbf\x54\x3a\x95\x0e\x7d\x70\x12\xe6\xb4\xc9\x0b\x70\x4b\xa5\x53\xa9\x54\x2a\x95\x4a\x55\x19\xfd\x7f\xcb\x28\xa3\x7b\x9d\xc9\x32\x19\x17\x51\x9a\x10\xda\x29\x7a\x49\x2f\xeb\x7e\x51\x29\x79\x27\xed\x2d\xbb\x5f\xa2\x49\x67\x3d\x39\x49\x4f\xf9\xaf\x02\x7e\x9d\x05\x19\x09\xf6\x8a\xcb\x05\x4d\x27\x44\xd6\xb5\xd7\x92\x45\x5b\x0f\x1e\x88\xc4\x5d\x56\x66\xf9\xe0\x41\xd0\xcd\x68\xb1\xcc\x12\x12\x74\xd2\xde\xfa\x66\x97\xa5\x47\x32\x2d\x12\x69\xac\xd6\xc9\x5e\x42\xcf\xc9\xcb\x2c\x4b\xb3\x4e\xeb\x20\x48\x92\xb4\x20\x93\x28\x09\xc9\x3c\x0d\x97\x31\x25\xed\xd6\x46\xba\xd1\x6a\xb7\xba\xbb\xc5\x2c\x4b\xcf\xc9\xa4\x3f\x4e\x43\xba\xd7\x7a\x73\xf4\xe2\xf8\xf5\xcb\x4f\x6f\x8f\x3e\x7e\xfa\xf1\xe8\xf8\xed\x8b\x56\x6f\x72\xcd\xea\x8b\xf7\x58\xdf\xf7\xbe\xd0\x8b\x45\x9a\x15\xf9\xf0\xcb\xf5\xf5\x2e\x1b\xc3\xc9\xe6\x69\x7f\x1c\xc4\x71\x27\xee\x8b\xac\x9e\xec\x7d\x87\xf2\x01\x26\x7b\x00\xb8\x75\x7a\x42\x4f\x77\x45\x57\xf3\x4e\xf2\x2c\x19\xd2\xee\x75\x2f\xee\xe9\x92\xb4\xc7\x71\x77\x2d\xa0\x58\x93\x32\x13\x7a\x11\x35\xc2\xd5\x24\xcd\x3a\x0c\x3a\xdd\xdb\xdc\x4d\xbf\xcf\xfa\x31\x4d\xa6\xc5\x6c\x37\xdd\xd8\xe8\xe6\x9d\x8c\x21\x5e\x75\xe3\xba\xdb\xf9\xb2\x35\x3c\x51\x5d\x16\x55\xf4\x38\x96\x7a\xa2\xed\xee\x97\x35\x9e\x20\x3b\xb3\x77\xb2\x46\xc8\x97\x35\x42\x08\x69\x8d\xd3\x24\x2f\x82\xa4\x68\x0d\x49\x91\x2d\x69\x8f\xa7\x46\xc9\x62\x59\xe4\xad\x21\x39\x81\x6f\x09\x0d\x79\x49\x30\xa7\xad\x21\x69\x7d\x4a\xcf\x13\x9a\xb5\x7a\x3a\x87\x8d\x8e\xe5\x04\x61\x98\xd1\x3c\x6f\x89\x9c\x6b\xf8\xff\x54\x54\x2d\x8b\xc3\xff\x22\x2d\x5d\x16\xf5\xed\xa5\x9f\x50\x11\xa3\xbd\xd1\x65\x41\xf3\x9d\x6d\x7f\x7b\x12\x48\x61\x7a\x8d\x90\xeb\xde\x9d\x20\xe0\x46\xfd\x51\xc3\x41\xd8\x6b\x86\x80\x95\x51\xfd\x47\x1d\xfa\x38\x4d\x0a\x9a\x14\xb7\x1e\xfc\x9f\x72\xde\xd9\x8c\xfd\x61\xa6\x7d\x12\xc4\xf9\x6f\x37\xf4\x8c\xe6\x34\x3b\xf3\xad\xfa\x3f\xfa\xa4\xe5\xcb\xd1\x7b\x3a\x8d\xf2\x22\x0b\xfe\x0b\x26\xaf\x57\x55\x07\x3d\x3f\xba\x15\xdf\x2f\xb2\x20\xc9\x27\x5e\xd6\xf7\x67\xc1\x41\x66\x91\xc2\xea\x48\xc8\x69\xf1\xa1\x9a\xa4\xee\x0c\x17\x76\xd3\xbf\x49\xa3\x5f\x79\x02\x82\x26\x88\xaf\xaa\x60\x91\x45\xf3\x20\xbb\xf4\xf6\x23\x4d\xe3\xda\xc9\xdb\x17\x6d\xfd\x79\x51\x68\xee\xc1\x95\xd5\x94\x21\xe1\xa0\x74\x1b\xff\x23\x21\xc1\xdb\xfb\x30\xca\xd3\xf3\xe4\x16\x3d\x0f\x92\x34\xb9\x9c\xa7\xcb\x7c\x85\xae\x47\x49\x48\x2f\x68\x68\xec\x5d\x77\x36\xb1\xba\x72\xd4\x1d\xb3\xf6\xf3\x28\xb9\x0d\xe3\xde\x5f\x02\x26\x5e\x26\x21\x0d\x5b\x16\x9a\xe8\x19\x23\x84\xbf\x00\x8e\x46\x51\x18\x36\xc3\xd1\xcd\xea\x3f\x0b\xe2\xa5\xb7\xfb\xcb\x28\x29\xb6\xbf\x79\x52\x3d\x05\x6f\xe9\xf9\xf3\xe8\x77\x44\xfe\xad\xd6\xdc\xc1\x2c\x48\xa6\xbf\x27\xe9\xdc\x09\xe5\x94\xd4\x8d\xa4\xfa\x4a\xaa\xf1\x62\xe6\x1d\xdf\x8d\x6a\x11\xb4\x76\xba\xb6\x76\xdd\xfb\x72\x7d\xda\xdb\xfe\xdd\x0e\xfd\x7f\xa1\x33\xef\xef\x24\x3b\x4e\x96\x49\x78\x63\x52\xb9\xf5\xc6\x75\x7f\xec\xfd\x73\x1f\x7b\xef\x0f\x7d\x7f\xe4\x33\x87\x77\xf0\xe2\xbc\xf0\x47\x93\x36\xbf\xee\x66\xae\xf7\xaa\x9d\x3b\xdb\xab\x56\x9d\xf7\x49\x96\xce\x6f\x39\xed\x45\x7a\xcb\xa3\xe6\xed\x04\xbe\xdf\x77\xdd\xfc\x11\xf0\x17\x25\x61\x94\xd1\x71\x71\xe8\xdd\x33\x57\xe8\xc9\xed\x26\x22\x1a\x07\x8b\x8f\xbf\xeb\x64\xf8\x31\xd9\xec\xb4\x4b\x17\x69\x1e\x55\x1d\xd4\x17\xc1\x65\x30\x8a\xa9\x29\x14\xfc\x2e\x5c\xa9\x8c\xe6\xee\xe4\xf8\x75\x3b\x1a\xd8\x97\xe3\x7d\x61\xe2\xf3\xb7\x3f\xc9\xdc\x09\x92\x4a\xea\x6e\x46\x67\xbf\x03\xfa\xff\xb0\x58\xbf\x8b\xf3\xe3\x8d\xf9\xe4\xd7\xc6\xba\xcd\xf4\xee\xd1\xde\x10\xed\xb7\xde\xb8\xbe\xf6\xcc\x1e\x7a\xb6\xb4\x2a\x39\xee\x71\x13\x39\x0e\x8c\x37\xc8\x9e\xb4\x70\xe8\xb4\xfb\x83\x49\x9a\xcd\x83\xa2\xa0\x59\xde\xee\xee\x02\xc0\x87\x34\x8e\xc2\xa8\xb8\xfc\x78\xb9\xa0\x26\x2c\x6b\x9f\x41\xad\x0d\x1e\x3e\x5c\x23\x0f\x0d\x48\xa1\x73\x27\x51\x4e\x02\xb2\xc8\xd2\x94\x01\x93\x62\x16\x14\x24\xa3\x0b\x76\xc8\x4a\x8a\x9c\x88\xb9\x23\x2c\x93\xd5\x70\x58\x90\x79\x50\x8c\x67\x34\x1f\xb2\x4f\x91\x8d\x7e\x9e\x9c\xe2\x8f\xc7\xc6\xd7\xa9\x99\xb9\x63\x7d\x9f\x9e\x3c\x39\x3d\x39\xed\x91\x7e\xbf\xbf\x46\x1e\x0e\x9c\xb1\xc9\x1e\xef\x11\x65\x4d\xd3\xe9\x8a\x29\x2e\x66\x51\xde\xff\x04\x0b\xe3\x47\x89\x20\x06\xd8\xe7\xe8\x3a\x64\x19\x87\x49\xb1\x8b\x80\xf9\xbe\xed\x83\x3e\x82\x1c\xd1\xdc\xee\xda\xf5\xee\xda\x9a\xa7\x1f\xfd\x45\x96\x16\x1c\x6b\x7b\x24\xa1\xe7\x46\x5f\x3b\x5f\xae\xbb\xbb\xd5\xa5\xfa\x20\xbd\x64\xcb\x71\x91\xb2\xc6\x3d\xb0\x75\xed\xf6\xa3\x5c\xcc\xb9\x46\x08\x23\x47\x89\x14\x61\xd7\xb2\xbe\xce\x12\xfb\x30\x6f\x9d\x81\xc0\x76\xe7\xdf\x27\x9d\x93\xcd\x47\xdf\x9d\x3e\xec\xfe\xfb\xb4\xfb\x6c\xd0\xe5\xe3\x34\x0f\x0e\xa5\xdd\xba\xee\x7d\x69\x61\x52\x6c\x0d\xbf\xeb\xb5\x38\xbd\xb5\x86\x5b\x8f\xaf\x4f\x7b\xdf\xfc\xce\xe4\xfd\x3c\x4d\xe3\x1a\xda\x1e\x31\x90\x12\xc2\x66\x79\xf2\x7f\x4e\xa5\xf0\xeb\xb1\xfe\x79\x8a\x92\x77\xf0\x47\x1d\x19\x43\xcf\x6e\x4a\xc3\xac\xf0\x2a\x44\xcc\xe1\x6d\x0a\x66\xa9\x2b\x92\xaf\x59\xa4\x82\x76\x79\x8b\x55\x65\x6f\x42\xb5\xff\x61\xa8\x35\x69\xf6\xe1\xff\x34\x22\x5a\xd1\x9f\x7a\x8a\x7d\xf2\x7b\x53\x2c\xdb\xc3\x14\xc9\x16\x7e\x9a\x2d\x66\x94\xc0\x66\x07\x84\xdb\xf7\x51\x2e\xcb\x55\x3f\x04\x5d\xc2\xcf\xc7\xe8\xf7\x29\xce\xd8\x31\xbe\x4c\xfa\x25\x62\x6b\x55\x3f\x9f\x1a\xf5\x88\xa2\x1e\x2a\x87\x4e\xde\x98\xcc\x59\xe9\x95\xe8\x9c\x17\x70\x08\x9d\x25\xaf\x4a\xe9\x66\x99\x2a\x52\xe7\x8d\x56\x96\xbe\x19\xb1\xb3\x4a\x38\xa9\x7f\xd9\xea\x5d\x77\x6f\x46\xf8\xa2\x77\xf5\x94\xff\x6d\x13\xca\x1f\x3c\x84\x0e\x7f\x9c\x45\x39\x99\x44\x31\x65\x94\xba\x08\xb2\x82\xa4\x13\x72\x4e\x47\x3b\xfd\x5f\xf2\xfe\x1a\x80\x88\x2f\x06\x30\xc9\x28\x25\x79\x3a\x29\xce\x83\x8c\x0e\xc9\x65\xba\x24\xe3\x20\x21\x19\x0d\xa3\xbc\xc8\xa2\xd1\xb2\xa0\x24\x2a\x48\x90\x84\x83\x34\x23\xf3\x34\x8c\x26\x97\x50\x47\x54\x90\x65\x12\xd2\x0c\x08\xbe\xa0\xd9\x3c\x67\xed\xb0\x8f\x9f\xde\x1e\x93\xd7\x34\xcf\x69\x46\x7e\xa2\x09\xcd\x82\x98\xbc\x5b\x8e\xe2\x68\x4c\x5e\x47\x63\x9a\xe4\x94\x04\x39\x59\xb0\x94\x7c\x46\x43\x32\xba\x14\x54\x44\xc9\x8f\xac\x33\x1f\x44\x67\xc8\x8f\xe9\x32\x09\x03\x36\xe6\x1e\xa1\x51\x31\xa3\x19\x39\xa3\x59\xce\x66\x68\x47\xb6\x25\x6a\xec\x91\x34\x83\x5a\x3a\x41\xc1\xc6\x90\x91\x74\xc1\x0a\x76\x49\x90\x5c\x92\x38\x28\x74\x59\x17\x05\x7a\xa4\x21\x89\x12\xa8\x76\x96\xca\x95\x1d\x15\xe4\x3c\x8a\x63\x32\xa2\x64\x99\xd3\xc9\x32\xe6\x82\xe3\x68\x59\x90\x9f\x0f\x3f\xbe\x3a\x3a\xfe\x48\xf6\xdf\xfe\x8b\xfc\xbc\xff\xfe\xfd\xfe\xdb\x8f\xff\xda\x25\xe7\x51\x31\x4b\x97\x05\x61\x12\x25\xd4\x15\xcd\x17\x71\x44\x43\x72\x1e\x64\x59\x90\x14\x97\x24\x9d\x40\x15\x6f\x5e\xbe\x3f\x78\xb5\xff\xf6\xe3\xfe\xf3\xc3\xd7\x87\x1f\xff\x45\xd2\x8c\xfc\x78\xf8\xf1\xed\xcb\x0f\x1f\xc8\x8f\x47\xef\xc9\x3e\x79\xb7\xff\xfe\xe3\xe1\xc1\xf1\xeb\xfd\xf7\xe4\xdd\xf1\xfb\x77\x47\x1f\x5e\xf6\x09\xf9\x40\x59\xc7\x28\xd4\x50\x8f\xe8\x09\xcc\x59\x46\x49\x48\x8b\x20\x8a\xe5\xfc\xff\x2b\x5d\x92\x7c\x96\x2e\xe3\x90\xcc\x82\x33\x4a\x32\x3a\xa6\xd1\x19\x0d\x49\x40\xc6\xe9\xe2\xb2\xf1\x44\x42\x65\x41\x9c\x26\x53\x18\xb6\xa2\x32\x42\x0e\x27\x24\x49\x8b\x1e\xc9\x29\x25\xdf\xcf\x8a\x62\x31\x1c\x0c\xce\xcf\xcf\xfb\xd3\x64\xd9\x4f\xb3\xe9\x20\xe6\x15\xe4\x83\x1f\xfa\x6b\x0f\x07\x92\xd9\xfe\x0d\xc8\x76\x9c\x86\x34\xeb\xff\x02\x2c\xf2\x6f\xc1\xb2\x98\xa5\x19\x79\x13\x64\xf4\x33\xf9\xdf\xb4\xa0\xe7\xd1\xf8\x57\xf2\xfd\x9c\x7d\xff\x8d\x16\xb3\x90\x9e\xf5\xc7\xe9\xfc\x07\x00\x0e\x83\x82\x92\xed\xcd\xad\x6f\x80\xe1\xd5\x6f\x05\x15\x02\x2c\x2a\x23\xe4\x31\xdf\xde\x21\x24\x05\x04\xcc\x76\x41\x1f\xe4\x61\x52\x98\x80\x51\x52\xf8\xe0\x8e\x1d\xc0\x65\x09\xe4\x8b\xcb\x24\x98\x47\x63\xc9\xc6\x51\x89\x90\xe7\x00\x8f\xf2\x95\xfc\x50\x64\x51\x32\x35\xcb\xe4\x90\xe6\x83\x7e\x4f\x03\x6b\x8c\x19\x0d\xbc\x63\x3c\x76\x41\x97\x65\xb0\x9e\x6e\xab\xfe\x02\x70\x94\x8b\x01\x1a\x9c\x39\x47\x55\xf4\x60\x87\x15\x7c\x5a\x5a\x88\xa3\xfc\xbe\xaa\x02\xb6\x11\x0e\x7c\x75\xa5\x4e\x8f\xa4\x04\x7a\x3f\xcb\x82\x4b\x0e\xce\x99\xb8\x25\x0a\x1c\x30\xfa\x44\x12\x80\x58\x49\x9c\x43\x84\xa4\x48\x09\x4d\x18\x0d\x0f\x42\xca\xfe\x53\xad\x30\x66\x1c\x70\x36\xc9\xb8\x92\x90\x6b\xcd\x8d\x99\xd7\x8d\x47\xcc\xc0\x72\x73\x67\x86\x24\xb2\x07\x35\xe4\x46\x17\x81\xf7\xcf\x69\x31\x4b\x43\x4f\xb7\xb8\x72\x3d\xcd\xe6\x84\x4b\x2e\xa9\x31\x23\x6b\x84\xaf\x41\x51\xfc\x93\x98\x19\x91\x45\xfe\x06\xbd\x27\x5f\x38\xf1\x5c\x2b\xb1\xfc\x6f\x1c\xf3\x39\xf9\x82\x2b\xbb\x86\x2c\x78\xab\x90\x93\x2f\xf0\xae\xe1\x9a\x88\xcf\x88\xf1\x06\x2e\x11\x31\x32\x84\xbe\xb0\x9d\x88\xb1\x7b\x40\x88\x81\x0c\xb4\x53\xe3\x2e\x39\x38\x92\x28\x62\xd8\xcc\x4d\xf1\x0e\x61\xad\x3f\x89\xe2\x82\x66\x1d\x54\xb6\x8b\x74\x10\x82\x8a\x0a\x21\x14\x48\x22\x00\x9d\x42\xf7\x64\xf3\x74\x97\xf3\xcf\x68\x42\x3a\xeb\xb8\x11\x5c\x07\x7f\xa0\xc1\x9f\x72\xb4\xa3\xe4\x2c\x88\xa3\x50\xd3\x00\xab\x71\x7d\x48\xda\x64\x83\xe0\xca\xd7\xb0\xac\x81\x6b\x36\x29\xb0\x84\xd2\xc8\x22\x0e\xa2\x84\xd3\x97\x35\x8d\x1c\xe0\x9d\xc8\x29\x9f\x45\x91\x7e\x34\xfa\x85\x8e\x8b\x6b\xab\x42\x39\xc9\xba\x1c\xaf\x36\xb4\xe0\xca\xa7\x0e\x75\xc3\x99\xb9\x1e\x2f\x6f\x09\x5c\x30\x69\xa8\x58\xde\x39\x61\xc0\xa7\x3d\x72\x02\xe0\xa7\xdd\x66\xa8\x89\xa3\x1c\x24\x20\xbe\xf8\xca\xb1\x93\x63\x34\x00\x0b\xe0\xd8\xf1\xa5\x2f\x74\x81\x32\xc4\x38\xcd\x36\xc2\x4d\xee\x2e\x7d\x81\x9d\xbc\x8c\xbe\x73\x49\xe0\x53\x5a\xe0\x15\x98\x0b\xce\x21\x48\x96\x15\x13\x7d\x63\x25\x8c\x1a\xfa\xf3\x60\xd1\x29\xe3\xb1\xa0\x95\xf3\xac\x11\x83\x77\xf2\x9a\x3b\xbc\xa7\x27\x50\xe4\x94\xb3\x67\xf9\xa5\x56\x11\xea\x8f\xd8\xa7\x8e\x26\x93\x9c\x16\x4e\xa7\x32\x1a\x2e\xc7\x14\xf5\x2b\x18\x8f\x7b\xa4\xa6\x73\x80\x9d\x22\x28\xa2\xf1\xbb\x20\x2b\x5e\xc3\x4b\x22\xab\xe6\xbe\x9d\xdf\xf1\xf4\x53\xd6\x95\x31\xa6\x44\xc3\x0f\x6e\x95\x6f\x82\x62\xd6\x9f\xc4\x69\x9a\x75\x3a\x4e\x8b\x1b\x64\x67\xab\x4b\x06\x64\x67\xbb\x4b\x1e\x92\x9d\x6d\x31\x68\x84\xbe\x60\x3c\x26\x1b\xa4\xa3\x36\x1d\x03\xeb\x25\x28\x24\xcf\xd0\xde\x45\xc8\xce\x36\x19\x1a\x09\x25\x9d\x95\xa8\xef\x91\x4d\x8c\xfd\x8c\xe6\xcb\xb8\x90\xd4\xc3\x67\xf0\xcd\x32\x2e\xa2\x9f\xa3\x62\xc6\xe7\x44\x52\xa0\xd1\xb7\x9e\xa2\xa3\x9e\x39\x83\xb2\x72\x31\x42\x5e\xbf\x79\xe2\xf3\x93\xbe\xd5\xaa\x6f\x0d\x34\xec\x01\x5a\x23\x6a\x78\xad\xd6\xae\x5e\x38\x34\x9e\x88\x11\x8b\xce\x8a\x5d\x21\xcd\x5e\x06\xe3\x59\xc7\x66\x4c\x11\xa6\x2d\xc6\xf5\x4b\xe7\x4b\xcf\xd5\x69\x17\x17\xe2\x08\x81\xae\x6c\xb8\xda\xce\x8e\xd9\x7d\xb9\x8e\x10\x11\xaa\xb5\xcb\xa8\x98\xc6\x13\x01\x62\xcf\x11\x74\xc0\xed\x92\xc4\x13\x7c\xd8\x93\x85\x9b\x30\x97\xe2\xc6\x1e\xa1\xe2\x19\x1e\x19\x90\x6d\x0d\x7a\x4d\x68\x9c\x53\x6b\x78\x83\x01\x09\xd3\xa4\x5d\x90\x20\x0c\x89\x28\x55\xa4\x66\x95\x7d\x12\x15\xed\x9c\x04\x71\x46\x83\xf0\x92\x8c\xd3\x65\x52\xd0\xb0\x04\x4b\x5f\x69\x9c\xd7\x7a\x11\x0e\x06\xe4\xe3\xd1\x8b\xa3\x21\x99\x44\xd3\x65\x46\x09\x3b\xb0\x25\x34\x67\x27\x40\x76\x4a\xbb\xcc\x4d\x66\xf5\x5b\x10\xc9\x1f\x67\x92\xcd\xc9\xa0\x18\x81\x12\x2b\x25\xcb\x5c\xa1\x35\xa3\x93\x00\xd4\x31\xe7\xb3\x34\xa6\xbc\x87\x51\x32\x5d\xaf\x61\x04\x15\x3c\xc0\xe6\xfc\x62\xd0\x3d\x92\x3a\x2b\xdf\x58\xe4\x72\x4e\x6a\x45\x7d\xcf\x16\xd7\x71\x55\x63\x88\x80\x78\xc3\xe4\x3c\xd0\x64\x9d\xd3\xc2\x99\x53\x4e\x56\x6f\x83\x39\xb5\xf7\x21\x9d\x83\xe5\x4c\xb7\xac\x67\xf3\xa9\xde\xcf\x74\xc5\x9e\x3a\x15\x5f\x14\x18\xd4\x52\xad\xfc\xab\x18\xb6\xac\x64\x91\xd1\xb3\x28\x5d\xe6\xaa\x43\xdb\xbb\x0c\x25\x51\x42\xa2\xa4\x70\x4a\xd4\xe1\x1f\xf5\xd7\xd7\x20\xfb\x9b\xa4\x19\x81\x47\xc2\x11\xd9\x23\x5b\xbb\x24\x22\xdf\xcb\x01\xc8\xf7\xc2\x24\xda\xd8\x28\x2b\xce\xfe\xac\x3e\x6f\xec\x91\x8d\x8e\xc4\x41\x44\x1e\x91\xad\x53\x26\xe1\x93\xab\x2b\xb2\xb9\x5b\x5a\x49\x05\x2b\x17\xf4\xb0\x41\x22\xf2\xb0\x6c\xe6\x36\xec\x5e\x30\xe1\xa0\x8c\xed\xcb\xbf\x6b\x27\xd5\x4c\xb9\xee\x76\xba\xd6\x14\x0e\x06\x64\x12\x65\x79\x41\x68\x4c\xe7\x34\x29\xd8\xf9\x8a\xa3\xa9\x47\xf2\xcf\xd1\x82\x44\xc5\x2a\x53\x6e\x60\x7f\xd3\x87\x7d\x86\xbf\xca\x19\x80\xa7\xf3\x61\x18\xb1\x46\x82\x58\x2d\x72\x81\x4f\x87\xff\xb8\xf8\xf6\xf3\x45\x4d\x3a\x25\x0c\xe2\x24\x22\x1b\x64\xeb\x54\xf2\x09\xb2\x41\x9c\x6e\x78\xd0\x5e\x8b\x60\x8b\xf9\x79\x20\xc5\x56\xe9\xa1\x7d\x4e\x15\x37\x66\x3d\x7f\x68\xa6\xc2\x84\x2d\x13\x53\xb7\x5c\xfc\x35\x94\x49\xca\x18\xd2\x66\x15\x43\x22\x8d\x68\xba\x96\xa3\x0c\x06\x64\x1c\xc4\xe3\x65\x1c\x14\x54\x0a\x3e\xec\xc8\x27\xfa\x42\xa2\x82\xce\x6f\xc1\x8e\x18\x2b\x3a\xf9\x13\x31\xa5\xae\x0d\x7b\xbd\xd2\xbe\x72\xcb\x09\xf9\xfd\x18\x0c\x66\x2e\x5f\x9d\xb7\x10\x47\x5b\x24\xfa\x51\xa3\x0d\x11\xba\x48\x71\x33\x99\x56\x68\x8c\x38\x64\x63\x8d\x91\x4c\x57\xb7\x9a\x4a\x25\xe2\xd7\x25\x95\xeb\x41\x50\xc3\x1e\xf1\x0f\xea\xf7\xe9\x88\x50\x31\xad\x23\xe2\xd0\x20\xdb\x34\x41\x4b\xa5\x92\xa8\x04\x21\x65\x3a\xa2\x72\x84\x88\x12\x70\xc2\x80\xd6\x34\x62\xaa\x35\x44\x78\x88\xbe\xd3\xb1\x81\x9b\xd5\x15\x44\xb2\x14\xa7\x62\x0c\xcf\x89\x38\xf7\x9e\xc2\xad\xe3\xfe\x1d\x6b\x94\xf8\x90\x3b\x30\x32\xb9\xbe\xb4\x5a\xc4\xd0\x8b\xc8\x1a\xb5\x86\xa9\x4a\xe5\xa0\x47\x55\xab\x67\xc0\x18\xe5\x1c\x88\x95\xb9\xeb\x91\x36\x51\x47\xa9\x93\xa8\x4f\x0e\x16\x5d\x2b\x65\x92\x83\x01\xc9\x97\x73\x7e\x43\xe7\xd9\xa5\x84\x88\xa8\xe0\x45\x75\x27\xd1\x29\xe3\x8a\xea\x0b\xb6\x24\x1f\xff\x91\xcd\x9b\x88\x90\xd2\xa6\x83\x82\xc1\x80\x64\x74\x9e\x9e\xc1\x35\x26\x19\x2f\xb3\x8c\xc9\xa7\x4a\x38\x4d\x21\x59\x74\x33\xca\xa1\xe7\x9e\xde\xe6\xab\x68\xfc\x24\x32\x1b\x6b\xfe\x8c\x91\x91\x47\x4e\xfd\x8d\x29\xed\x83\xb5\x0e\x4b\xae\x75\xbc\xa7\x56\xc9\xe3\x3c\x54\x56\x58\x57\x0e\x92\xac\xd8\x0e\x86\x2f\x49\xcc\xfb\x0b\xde\x5b\xd6\xd6\x58\xdc\x32\x61\x53\x0b\xe8\x7d\x87\xdb\xab\xda\x26\x18\xe2\x5a\xb4\xd3\xed\x79\xb3\x9f\xa7\x69\x5c\x96\xc7\x84\x90\x92\xac\xe3\x8a\x3c\x7c\xb9\x59\xda\x6c\x55\x26\xe7\xc2\x65\xb9\xef\x69\x50\xda\xe3\x63\x9e\xb9\xc6\x08\xc2\xb5\xdf\x00\xd4\x29\x9b\x0d\x69\x38\x3b\x7c\xdc\x6b\xf1\xbb\xdf\xd6\xf0\x1b\xf8\xc9\xfa\xd6\x1a\x3e\x61\xbf\xf1\x75\x6c\x6b\xf8\xb4\xe7\xb3\xf5\x88\x92\xa2\x35\xdc\xda\x64\x3f\x33\x1a\xc4\xad\xe1\xd6\x36\xfb\xcd\x6f\x65\x5b\xc3\xad\x1d\xf6\xb5\xe4\x50\xd0\xc0\x52\x80\x3d\xb9\x3e\xed\x3d\xfd\x2d\xed\xa2\x6a\xae\xa1\x6f\x66\x4d\x84\x2b\x59\xc5\xa8\xc8\x2c\x67\xdb\x16\xe1\xdc\x15\x4d\x8c\xfc\x45\x2b\x2c\x8d\xcc\x9e\x34\xa9\xeb\x16\x76\x47\x25\xc6\x46\x8d\x1a\x45\x57\xe2\xde\xe9\x92\x6c\x27\x5b\xd2\x06\x26\x4c\xd6\xb0\xeb\x2d\x99\xbe\xbb\xb7\x64\xba\xb7\x64\xfa\x6f\xb1\x64\xd2\x0b\xe1\xae\xcc\x99\x9e\x47\xd3\xb7\xcb\xf9\x08\x58\xa1\xe2\xce\xa3\x68\x9a\x40\x62\xff\x17\xc5\xc9\x97\x45\x14\x9b\xf6\x35\xfd\x01\xa4\xf1\x7f\x25\xd8\xd8\x0b\x32\x4e\x93\x49\xe4\x18\x03\xc9\x93\x19\xda\x15\xe0\xec\x02\xdb\x82\x1c\x38\xe7\xd5\x39\x01\x7e\x4f\xe0\xc1\x06\x3b\x67\x31\xbe\xa5\xad\x64\x61\x29\xb0\xb9\x01\xe5\xcc\x43\x86\x63\x0e\x19\xe5\x24\xa1\xd3\xa0\x88\xce\x68\x4f\x72\x22\xb8\x38\x2a\xce\xd3\x76\x4e\xc6\xe9\x7c\x21\xa5\x55\x28\xc5\xe6\x56\x95\x9c\xc4\x69\x50\x44\xc9\x94\x2c\xd2\x28\x29\x7a\xfc\x3a\x94\x91\x7d\x98\x9e\x27\xd6\x99\xce\x54\x93\xb8\xc7\xb7\x2b\x8e\xe5\x2b\x85\xef\x6b\x39\x16\xb6\x94\x12\x4a\x43\x38\x45\x8f\xf4\x1c\x87\x7e\x63\x18\x40\xda\xb5\xb2\xf3\x31\xdb\x35\x18\x30\xd4\x2f\xb9\xb0\x6a\xb7\xcf\xe7\xa2\x33\xee\xbf\xfc\xf8\xea\xd3\xf3\xc3\x9f\xde\x1e\xbf\x79\xfe\xf2\xfd\xa7\xf7\x47\xc7\x6f\x5f\x1c\xbe\xfd\xe9\xd3\x9b\xa3\x17\x2f\xd1\x19\x4e\x69\xe2\x60\x26\xfb\x8b\x20\x7c\x4d\x27\x45\x87\x7f\x15\xe9\xc7\xf3\x34\x3f\x50\x58\x14\x6d\xf6\x8b\x54\x88\x4b\x5b\x4f\xba\x3d\xf2\xe4\xb1\x79\xc3\x83\x77\x4b\x18\x4e\x87\x37\x62\x1a\x60\x98\x13\x2f\x0f\xbf\x25\x38\x7f\xae\xce\xc6\xe6\xa1\x79\x55\x1c\xba\x52\x87\x81\x45\x0f\x42\x8a\xf4\x15\xbd\x90\xe3\xce\x97\xa3\xbc\xc8\x3a\xdb\x08\x7f\xb1\x75\xb5\xcf\x8b\x4b\x2d\xf7\x06\x79\xb2\xd3\x25\x03\x8c\x22\x1b\xdd\xef\xa3\xe9\xac\x10\xc5\x7a\x24\x26\x0f\xbf\x32\x3e\xc5\x0e\x7c\xa7\x68\x2d\x95\xe9\x6e\x8d\x5d\x79\x3c\x33\xd1\xaa\xb4\x73\xbf\xdb\x0c\x58\x6a\x53\xde\x58\xb7\xcf\xd7\xfc\x06\xa9\x9f\xa0\x3a\x4e\xc7\x25\xf9\xf2\x15\xf1\x41\xe6\xdf\x76\xee\x94\x71\x67\xf3\x59\x9b\x64\xe9\xfc\xb8\x98\x3c\xbd\x9f\x38\xcf\xc4\x89\x77\x46\x65\x8c\x4c\xbc\x42\x92\x93\xc6\xbe\x69\x90\xac\xce\xc8\xec\x27\x47\xe5\x73\xd6\xde\xbc\xdd\x5f\x9b\x6c\x88\xea\xc9\x33\x42\xda\x5b\x6d\x32\x24\xed\xcd\xf6\xed\x79\x54\x1d\x26\xd9\x89\x95\x95\xfa\x07\x83\xcb\x09\x13\x8c\xe7\xcb\xb8\x88\xb8\x50\x39\xba\x24\xdb\xff\x99\x33\xf1\x5c\xd9\xd0\x05\xac\xe6\x82\x4e\x69\x56\xb1\x95\xbc\x17\xb5\xd6\xed\xdf\xab\xce\x88\xb0\x65\x2e\x99\x11\x81\x26\x8b\xfa\x18\xd6\x54\x8b\x6a\x73\x8d\xe6\x34\xb7\xb2\xb6\xbb\xfd\x45\x7a\xde\xd9\xda\x7e\xda\xed\x9a\x28\x3d\x98\xd1\xf1\x67\x12\x4d\x0c\x9c\x22\xb1\xc8\x42\x44\x1e\x4d\x13\x1a\x1e\xe6\x6f\x75\xb6\xa3\x88\x56\x75\xcc\xe8\x85\xe8\xb1\x89\x0c\x49\xb4\x70\xe8\x83\xb6\x0b\x53\x12\x4b\xd9\x91\xe5\x3c\x62\x62\x78\x10\xe7\xda\x6a\xd9\x6e\xbd\x16\x5f\x3e\x0c\x49\x76\xb3\xd9\x23\x5b\xdd\x1e\xd9\x7a\x82\xe4\x91\xed\xae\x91\xdb\x25\x7b\x7b\x7b\x8c\x64\xbd\x54\x98\x31\xf6\xf1\x28\x88\xa1\x53\x84\xab\x0e\xf4\x85\x07\x17\x35\x5d\x22\xe2\x8a\x04\x5b\x08\x34\xc8\xc3\xb1\x83\x65\x38\xd3\x82\x61\x45\xbb\x4a\x38\x84\x65\x11\x4d\x09\x97\xd3\x2d\x7a\x53\x5d\x30\xf0\x67\x18\xc5\x32\x60\x3e\x8f\x7b\xbc\x37\x48\x97\xd9\xe9\x92\xab\x2b\xd2\xda\x6c\x09\x1d\xf1\x60\x40\xc6\x8a\x8a\x98\xf0\x2c\x27\x52\xb5\xce\x81\x60\x96\x95\x98\xed\x4a\xd8\xf2\xf2\xd6\x9a\x64\x31\xb1\x1e\xfd\xa3\x67\x72\xf9\x7c\xce\xa3\x64\x69\x2f\x81\xf6\xe4\x96\x7f\x6d\xa8\x5b\x56\xbe\xa5\xee\xc6\x1a\x74\xe8\x06\xe4\xb3\xac\xa6\x9f\xe3\x4a\x02\xf2\x91\x0e\x5d\x89\x76\x44\xf3\x2e\xd5\x1c\xdf\x05\xd9\x7c\x1d\x94\x09\x7e\x5f\x86\x32\x87\x71\xd7\xa2\x0c\x30\x86\xe4\x61\x13\x45\xa2\x39\x17\x45\x0e\x27\xf7\x99\x9b\x5b\x2b\x51\xc0\xf4\xc3\xe8\x2c\x0a\x69\xf8\xfc\xb2\x82\x81\xdf\x84\x9a\x6a\x70\x73\x7c\xd7\xc8\x59\x96\x62\xe7\x78\x65\xf4\x1c\xdf\x06\x3f\xee\x15\x2c\xaf\x5a\xa1\xa8\x4c\xdc\xd2\xaf\xa5\x1b\xe3\x45\x6e\x6b\xe6\x5c\x94\xe2\x48\x34\xed\xa2\xc8\x11\xce\x7c\x18\xf2\x2c\x2f\xd8\xac\x6e\x29\xad\x6d\xb5\xc9\x33\xbe\x2f\x0b\xb7\x18\xab\x61\xb3\xf4\xd8\x88\x1e\xe5\x56\x6c\x7c\x31\x9d\x68\xc4\x31\xf1\xa1\xe2\x60\xe3\xc8\x1d\x49\x30\xa7\xfc\x75\x0f\xfb\x65\xc9\x5f\x02\x86\xd5\xa9\x6a\xf0\x60\xde\x39\x81\x42\x1b\x3d\x82\x35\xe5\xac\x90\x78\x5f\x4d\xf6\x48\xd9\x33\xdd\x87\xdd\x01\x3a\xcf\xe4\xd1\xaf\x82\x27\xe6\x70\x45\x25\xca\x9f\x6c\x9d\x9a\x72\x70\x7b\xf3\x82\xc9\xcb\xee\xe4\xf6\xf3\x38\x1a\x53\x26\x96\x6c\x93\x87\x50\xdd\x8a\x74\x5e\x33\x33\xf8\x08\x7e\x67\x13\xb4\x2a\xfa\x4b\xf5\x00\xce\x26\xa3\xce\x87\x16\x1f\xe0\x88\x13\x37\x60\x36\xe6\x9e\x3c\xee\x8a\x3d\xbc\x48\x05\x7c\x97\x3c\x94\x47\x4a\xdf\x0c\x58\x15\x71\xd1\xf0\xc9\xe3\x9e\x68\x7f\xb5\x29\xa8\x38\x92\xf3\xe1\x7b\xce\xe4\x77\x8a\xfd\x20\x1f\x47\x51\x15\xfe\x3d\x67\xf9\xdf\x10\xf3\x52\xa5\x03\xaa\x81\x66\xf8\x5f\x6d\x02\xb4\x6f\x9a\xb2\x19\xd8\xd7\xde\x6b\x4a\xa6\xa0\x94\xb7\x97\xa0\x5c\x55\xe8\x62\xdb\xe7\xbd\x66\x05\x69\xca\xc0\x5d\x6b\xf3\xa2\x45\x36\x88\x38\xe0\x00\xda\xf9\x6f\x65\x53\xf0\x78\xb3\x47\x70\x52\x99\xc3\x80\x2f\xd2\xee\x03\x1d\x34\x87\xd6\x77\xcf\x86\x81\x15\x3b\x74\x52\x1c\x38\xbc\xc0\x87\x65\x19\x4e\x29\x8e\xcc\xa1\x9b\xe4\xf6\x23\x4d\xe3\xa1\x9d\xe0\x40\x31\x09\x64\x68\x27\x60\x28\x25\x96\x0d\xed\x04\x17\xea\xd8\x01\x3b\xf6\xc2\xe1\x46\x75\x8a\xa7\x3e\x17\xf0\xd8\x0f\x89\x07\xab\x53\x3c\x70\x18\xdb\x28\xc9\x85\xf4\x4d\x8f\x9b\xe3\x96\x33\x27\x08\xa7\xb9\xb0\x82\xea\x87\xde\x75\x77\x2d\xef\x74\xcd\x9b\xa1\xd6\x70\xeb\x69\xaf\x65\xde\x28\xb5\x86\xdb\x60\xbe\x00\x0b\xa3\x35\xdc\xda\xea\xb5\xf0\xbd\x54\x6b\x68\x7e\x5e\x9f\xf6\xb6\x36\x7f\x67\x7f\x2e\x87\xdc\x30\xbe\xc2\x01\x51\x94\x14\x65\xfe\x87\xc4\xd5\x55\x94\x14\xdc\x35\x0b\xfb\xf1\x58\xfd\x3a\xd5\x89\x3b\xe8\xb7\xe5\xb9\x25\x4a\x0a\xee\xb7\x25\x4a\x8a\x27\x8f\x15\xd8\x53\x5d\xd1\xf6\x37\x4f\x4a\xea\x62\xf0\x35\x7e\x8c\xec\xa3\xe1\x57\x74\xc5\x05\xe0\xb6\x0d\xc2\x61\x52\xac\x68\x76\x61\x94\xa8\xb0\xb6\x80\xe6\x2a\x4a\xde\xc8\xb6\x22\x4a\x0a\x29\x2a\x3e\xbb\x91\x3f\x17\xde\xab\x7a\x1b\x88\xad\x46\x21\xec\xee\x8d\x20\xee\x8d\x20\xfe\xbc\x46\x10\x44\x5b\x41\x70\x51\xe9\x8e\x0c\x20\x1a\xd8\x35\xd8\xac\x9e\xdb\x2d\xa4\x60\x8d\xae\xdd\x76\xf4\x3d\x12\xea\xf9\x8c\x26\xea\xb1\x62\x8f\x1b\x7e\x33\x01\x5c\x79\x6f\x90\x92\xe5\xc0\x6b\x18\x61\xe9\xbe\xed\xb7\x89\xc0\x49\xa5\xfc\xc8\xff\xbf\xba\x22\xed\x36\xe2\xb3\xa9\x7c\xb6\xc0\x7f\xec\xa2\x77\x86\x51\x22\x5a\x6f\xec\xee\x63\x4a\x0b\x6c\xef\x0b\xd6\xe3\xed\x5c\xbe\x02\x05\x5e\xc2\x2a\x31\x4c\xdd\xb5\x7c\xcf\x2d\x5d\x4d\x29\x5a\xaa\x99\x74\xad\xb8\x32\xd2\x91\x7d\xec\x1a\xd6\xec\x80\x1e\x6c\xcd\x6e\x37\x52\x69\x87\x06\x26\xfe\xc6\xb1\x03\xdf\x3d\x36\x46\xc6\x38\xa3\x8c\x98\xe4\x7a\x30\x7d\xb2\x70\x72\x0f\xa3\xc9\x84\x82\x35\x32\x47\xb9\x75\x2e\x39\x57\x8f\x42\xf0\x71\x44\xa2\x44\xcc\x92\x34\x5c\x4e\xbc\x87\x10\xf3\xe8\xc2\xb6\x43\x5f\x3f\x82\x05\xe7\x30\xaa\x17\xe5\xa8\x3c\xf7\x3f\x98\x35\xe9\xae\xf4\x4a\x4f\x13\xa4\x22\xd5\x55\x30\x9a\xce\x47\x51\xe2\xba\xb7\x29\xd2\x29\x65\xdc\x9d\xd5\x40\xa7\x7d\xbe\xa8\x82\xc5\x82\x26\xb0\x96\x82\x84\x3f\x80\xb0\xb0\x2b\x6a\xab\xbb\x84\x11\x8c\x69\x16\x8d\x19\x7b\x92\xbd\xaa\x2f\x2c\x6e\x4f\xd3\x89\x80\x85\x7d\xa8\x12\xb5\x72\x78\x75\x7a\xbf\x2a\xb4\x2a\xbd\x05\xbf\x32\xd9\x25\xf5\xd8\x1d\x07\x71\x2c\xf0\x2b\xef\x70\xf8\x88\x66\x81\x5e\xba\x79\xf4\xab\xf0\x2c\x08\x77\x75\xb3\x20\xef\xb1\xff\x25\xa1\x81\xef\x5f\xcf\xa5\x1d\xc6\xb7\x32\x04\xf5\xeb\x4c\x2b\x51\xe3\x77\xcd\xe4\x5b\xb8\x62\x55\xac\xef\xed\x81\x74\x31\x89\x12\xeb\xa1\x52\x1d\x12\xb4\xcb\x22\x51\x95\xb8\x5e\xb6\x95\x06\x3c\x77\x3f\x7f\x5e\x7e\xf4\xe7\x1a\x5f\x57\x43\xd3\x60\x99\x19\xb5\x57\x0d\x7a\x1d\x46\xad\xdf\xff\x77\xc9\x33\xd2\x6e\x93\x61\x33\x6b\x2c\x84\x32\xaf\x4d\xd6\x0a\x78\x63\xbc\x9f\x2b\x27\x94\xcc\xe8\x7b\xeb\xa5\xf5\x17\x7e\x9c\xc9\xbd\x47\x5e\x09\x07\x98\xe1\x07\x73\x4c\x64\x40\xe2\x95\x58\xd4\x8d\x79\x51\x08\x4e\x95\x6c\xfc\xf9\x9c\x33\xa9\xe5\xb5\x4b\xf8\x95\x1f\x29\xa1\x3b\x31\x61\x9d\xd5\x51\x67\x6c\x6b\x25\xb8\x43\x9b\x92\x1f\x79\x32\x21\x90\x37\xf0\x0d\xb0\x48\xe7\x8b\xe2\x12\xab\x04\x1b\x6c\xa2\xb5\xab\xd0\xa4\x47\xc4\x9e\x86\x20\x7d\xac\x80\x1b\xe9\x6e\xaa\xd4\xd1\x94\x17\x13\x95\x03\x11\x55\xd6\x8d\xc1\xb8\x58\xd9\xf0\x88\x05\x37\x19\x87\x7e\x89\x57\xee\x1c\xea\x75\x94\x17\xce\xb3\xbf\x13\x63\x34\xa7\x1e\x8f\x50\x95\xa3\xd7\x35\xbb\xdb\x8b\x7a\x14\x24\xaf\xe9\x97\x8b\x90\x9b\xb5\x8a\x47\x70\x4a\x15\x59\xa4\x05\x7a\xe8\xca\x0b\x4b\xe1\x88\x3b\x1d\x22\xc6\xc3\x3e\xf5\x7e\x50\x80\x9a\x6f\x8a\x8c\xbd\x4d\xad\x47\xbe\x7d\x95\x2c\x48\xfb\xf6\xcb\xf6\x14\x62\x36\x4f\xf6\x70\x8f\x35\x2c\x1e\xc6\xc6\x9e\xab\xe8\x17\x4f\xb5\xdc\xe7\x59\x1c\x52\x8b\x40\x9d\x14\x3f\xb9\x55\x4f\xe6\x06\x03\x39\xdd\xf4\x8c\x66\x97\xc5\x0c\x1c\x91\xa0\x7a\x30\x76\x5c\xaf\x53\xd2\x1c\xcd\xc1\x8f\xf1\x4c\xd7\x7f\x43\xa1\x1c\x2f\xdd\x69\x13\xae\xd2\xf9\xba\x47\xda\x6d\xa9\x7c\xaf\x50\x52\xbc\xe3\xb3\x64\xe9\xf4\x94\xfa\xee\xfa\xb4\xb7\xd5\x28\xd0\xde\x57\xd4\xc9\xc1\x6d\x74\xb5\x52\x2e\x63\x20\x25\x5a\x39\x69\x63\xc6\xfe\xe7\xaa\x32\xf8\xf5\x58\xff\x3c\x45\xc9\x3b\xf8\xc3\xd2\xcd\xb1\x34\xae\x9c\x63\xbf\xa4\x76\x8e\xfd\x7e\x8a\xaa\x43\xfa\x39\xa7\xc6\x06\x1a\x3a\xe7\xee\x7d\x15\x15\x1d\x2b\xbc\x8a\x8e\x8e\xc3\xdb\x4a\x3a\x96\xba\xa2\x96\xce\x2c\x52\xa1\xa6\xe3\x2d\x56\x95\xbd\x89\xa2\x8e\xe1\xb6\x44\x51\xd7\xcc\x4b\xbe\xe8\x56\x03\x45\x5d\xa3\x50\x5e\x5f\xeb\x65\x9d\xe7\xf6\x6f\x15\xf2\xe0\xc5\x57\x21\x10\x59\xc2\x26\x11\x9e\xbe\x22\x91\xd8\x85\x2a\xc8\x44\xb6\x5b\x5d\xfe\x46\x3a\x5d\x2e\x49\x35\x79\x30\xe7\x69\xef\x6e\x9f\xca\xa9\x51\x36\xa0\xbb\xbb\x0f\x3d\x52\xf9\x78\xc7\xc3\x87\x91\x7f\xdb\x28\x6f\xee\xd8\x76\x4c\xb3\x22\x88\x12\xbf\x73\x5b\x07\x91\xfc\x36\xa9\x86\xa8\x39\x50\xdf\x4c\xaf\x26\x6b\x51\xc4\xca\xa8\x75\x05\x51\xd0\x6c\xce\x8e\xfc\xd1\x04\x6a\x36\xfb\x1d\x0a\x97\xb5\x64\x1a\x9d\xd1\x44\x9a\xb4\x98\x47\xea\x32\x5f\xb9\x96\xfd\x0b\x3f\x66\x6b\x73\x5b\xc0\x32\xaf\xdc\x69\xd7\x6f\x7c\x8b\x21\x9a\x2f\x11\xee\x99\xb6\x55\x78\x85\xe3\xf4\x8c\x66\xd9\x79\x16\x15\x05\x05\x73\x2f\xde\xab\x16\xd9\x80\xde\x37\xc6\xdd\x39\x68\xd9\x73\xfc\x8a\x1f\xac\x20\xf4\x51\x34\x4a\x04\x0a\x0b\xd7\xe9\xb0\xfd\xd0\xbe\x11\x32\x5d\xad\xa4\xd5\x9c\xd6\xda\x96\xe0\xcd\xe3\x3f\xc0\x8f\xc1\xc1\x00\x54\xe1\xc1\x9c\xad\x0a\x70\x79\x28\xb4\x59\x6c\xbc\x8c\x13\x50\x7e\xc7\x10\x47\x9f\x29\x09\x48\x1e\x25\xd3\x98\x2a\x27\x5c\x00\xd9\x37\xec\xa1\x81\x82\xb9\x8f\x19\xee\x93\x83\xb7\x76\x75\x45\x4e\xda\x27\x5b\xa7\xed\xd3\xae\x12\x06\x6b\x7c\x00\x88\xee\x99\x78\x67\x5f\xd8\xaf\x61\x89\xe8\xce\x6d\xa0\x38\x2a\xc0\x56\x61\xab\x47\x1e\x81\x31\xf6\x26\xf4\x65\x0b\x7b\xa1\xd1\x1d\x72\x04\x59\xe9\xa5\xa1\x27\xfd\x3a\x94\x9d\x16\xa4\x37\x87\x87\x12\x50\x37\x30\x18\x90\x20\x8e\xc9\x28\xc8\xa3\x31\x77\x7e\x00\x2f\x05\x76\xb6\x85\x02\x27\x4e\xd9\xc9\x58\xf6\xa6\x47\x76\xb6\xeb\x8c\x4e\xcc\x85\x2d\x38\x9a\x3c\x81\x4b\x5d\x24\xa1\x53\x10\x20\x21\x22\xd4\xc9\x69\x8b\xec\xfd\x00\xeb\x53\xa7\x3d\xe6\x89\x95\xca\xb4\x7d\x59\xdb\xaa\x1c\x60\x46\x4b\x7b\x56\xb1\xda\x71\xab\xa5\x34\xab\x7d\x7e\x19\xde\x60\x1c\xa2\xdb\xb5\xb6\x51\x54\xe4\xc1\x03\x82\xbf\x4f\xd0\x6f\xe4\xff\xed\x54\xee\xba\x2a\x2c\xc6\x60\x7a\xa3\xb9\x11\xcb\xb7\x6a\x6a\xe4\x2c\x98\x73\x23\x26\xcc\x9c\x1a\xe4\x6e\xed\x96\x33\x63\xf5\xab\x62\x62\x50\x9b\x5f\x7b\x5e\xee\x72\x62\x4c\xbf\x27\x9a\x91\xa2\x99\x80\xb3\x51\x0b\x6c\x11\xb6\x39\xd2\xf9\x21\xa9\x25\x8c\x15\xb6\xc4\x54\x6c\x3d\x56\x80\xdb\xa7\x27\x3b\x02\x54\xa6\x71\x10\x05\xb1\x75\x6a\x25\xe8\x6f\x77\x77\x00\xac\xde\x60\x7b\xc0\x63\x11\x43\xac\xdf\x13\x50\x63\x77\x34\x91\xd1\x84\x74\x50\x16\xe2\x90\x36\x3f\xbe\xe1\xc4\x02\xc3\xf6\xbd\x86\xd8\xaa\x98\x72\xb1\x49\xc8\x53\xb5\x6f\x9e\x61\xde\x7c\x53\xdd\x52\xc1\xf7\x9c\x09\x17\x9f\x2d\x63\xde\x8d\x8a\x4e\xcc\xca\xf1\x74\x6b\xd7\x6b\x8d\xe6\x59\x65\xf0\xa1\x88\xfc\xd2\xf9\x35\x5c\x28\x96\xee\xf6\xc2\x55\x51\x1c\xe4\x05\x39\x39\x65\xc2\x04\xaf\xf7\x46\xd3\xbe\xee\x9f\x77\x35\x07\x20\x67\x11\xc7\xc1\x12\x1c\x68\xf4\x33\x28\xf8\x54\x34\xd0\x84\x48\x2a\x8c\x63\xd1\x11\x46\x71\x60\xfb\xa6\x89\x8c\x2e\x49\x48\x27\xc1\x32\x06\x45\x68\xbe\x64\x72\xaa\xda\x98\x5b\xc2\x47\x4d\x4f\xc4\x78\xb4\x67\xd1\x38\x46\xdd\x80\x01\xeb\x1d\x71\x45\x51\xb8\xe1\xe9\xad\xd4\xa8\x5e\x3a\x6a\x97\x3a\x62\xb4\x44\x72\x7b\x8d\x00\xc5\x0b\x52\x3e\x69\x31\x8a\xef\x91\x16\x5b\x04\xec\xbf\xd3\xd6\xa9\xa6\x76\x01\x81\xd2\xa0\x50\xb2\x8c\xed\x67\x0f\x68\x36\x1b\xa1\xcd\xf6\x2e\x67\xf5\xb7\x66\x21\xb8\x1e\xaa\x9c\x95\xc0\xf7\x06\xe1\x29\x8f\xcf\x7a\x0e\x37\xbc\x6c\x38\xc6\x78\xd9\xbf\xb0\xea\x2d\x22\x16\xdc\xaa\xf3\xef\x13\x7e\x1a\xff\xf7\x69\xb7\x5e\x44\x10\xca\x5b\xe5\xea\xa1\xfc\xde\xc1\x8a\x61\x21\xa1\x9b\xb3\x0e\xf9\xf0\xd4\xbd\xcb\xb2\x70\xe6\xb9\xb4\x10\xf7\xe8\xf6\xc6\xe0\x75\x46\x6d\xde\xca\x08\x3f\xa8\xd2\x03\xaa\xcd\x16\x6a\x5c\xc1\x2a\xfb\x6f\x6c\x4c\xbc\x4b\x4a\xff\xfc\x5e\x51\x5d\xa7\xb2\x34\x9e\x60\x67\xb2\x82\x95\x39\x85\xd4\xb3\xe4\x93\x53\x9f\x07\xf1\xfe\x62\x99\xcf\x3a\x8e\x5b\x52\xf9\x4c\x5b\xfa\x18\x75\x6b\x66\x63\x71\x1d\xae\x9f\xf9\xbc\x7f\xe2\x96\x90\x13\xcf\xce\x59\x8f\x60\xe7\xb2\x96\x6f\xd2\x5b\x79\xf4\x15\x13\x88\x3d\xf9\xde\x7a\xfe\xa0\xeb\x8e\xd4\x21\x10\xff\xdb\xcf\x9f\xcf\x1d\x6b\x8d\x1b\xd6\xd2\x89\x60\xb3\x09\x7e\x52\x2b\xe6\x63\xe5\xd9\x58\x73\xee\x08\x2d\xdd\x91\xb1\x24\x91\x3b\xdb\x26\x0e\x41\xf9\xfd\xe8\x24\x4b\xe7\x5e\x73\x03\x0e\xe5\xe3\x2d\x23\xfb\xc1\x8e\x65\x20\x64\x58\x06\xad\xf0\x60\x4a\x32\x35\xde\x72\x03\x16\x25\x06\x82\x59\x94\xe1\x4c\xb3\x86\x55\x7d\x15\x5e\x05\x7b\x13\xbe\xb1\xe4\x82\xae\x78\xe2\x03\xdd\x93\x82\x8e\x40\xd7\x43\xb2\x0d\xc6\x0f\x5d\xe9\xce\x59\x20\xaf\x6c\x11\x55\xd6\x89\x9b\x77\x2a\xf6\xad\x28\x28\xf0\xa1\xe0\x77\xec\xb8\xf4\x06\xd9\xe1\x1e\xef\xf9\x6e\x9b\x33\x90\x9c\x04\x93\x82\x66\x6a\x91\xe0\xfe\xde\x68\xad\xfa\xcb\xf8\x1c\x77\x6b\xce\x51\xe2\xb0\x9b\x54\x62\x4f\xc4\x8d\x79\x5b\x56\x3f\x76\xea\x51\xea\x43\xda\x0e\x78\x53\xc9\x68\x1a\x72\x1a\xf2\xb0\xba\x6f\x0c\x76\x63\xaf\x1a\xa6\x11\xa3\x32\xbd\xcd\xa2\x69\xdf\x20\xd1\xdd\x72\xad\x3f\xc4\x1e\x82\xff\x1a\x52\xbf\x34\x48\x6d\xf8\xf7\x87\x22\xfe\x7b\xda\x47\x7f\xbf\x0b\xed\x13\x2f\xe9\xe3\xe8\x8c\x37\x25\x7d\x3b\x86\xd8\x8a\x9b\x8a\x43\xac\x76\xfd\xcd\x76\x16\xb3\x17\xab\xd4\x2f\xe6\xcf\x4b\x6f\xb1\x43\x5f\xfe\xf5\x57\xbe\x84\x17\xe2\xd6\xcf\x35\x52\xad\xeb\x7e\x87\x6c\x91\x0d\xb3\x77\x5d\xee\x90\x89\x87\x11\xf3\x4c\x3d\x77\x3f\x6c\x5d\xba\x19\x0f\xb6\x2b\x9c\xd9\x1b\xb8\xb6\x2c\xbe\x0c\x2e\xb6\xb6\xe2\xd8\xf0\x9c\xab\x95\xb5\xdd\x35\xd5\xaa\xde\x8b\x44\xab\xeb\xb5\x17\xbc\xe5\x57\xbb\xea\x4d\xdc\xf5\x69\x6f\xeb\xf7\x8e\xbb\x7f\x5c\xff\xec\x6d\x59\xf1\xee\x4d\x78\x22\x81\xff\xb9\xad\xcb\x52\x3f\x7d\x5b\xa2\xb7\x6f\x4b\xfc\x60\x6d\xe9\x79\xfd\xb6\x54\xcf\xdf\x96\xe8\xfd\xdb\x12\x3d\x80\x5b\x9a\x2f\xe0\x9c\x1a\x1b\x58\xd8\x38\xfe\x51\xbe\xe2\x23\xb8\x63\xef\x2b\xb8\xe3\xd5\x9f\xc1\x1d\x37\x7d\x07\x77\xec\x3e\x84\x3b\xbe\x83\x97\x70\xcb\x5b\x3f\x85\x3b\x6e\xfc\x16\xee\xf7\x0e\xea\x7f\xdc\xc0\xe2\x6c\x59\x65\x72\x26\x5d\xab\xf0\x1f\x82\x38\x91\xd5\xd9\x12\x9b\x9d\x2d\x0d\x2b\xb1\xa5\xcf\xf0\x6c\xa9\x2d\xcf\x96\xd8\xf4\x6c\x89\x6d\xcf\x96\x96\xf1\x99\xa7\xde\x26\x8b\xe3\x37\xb5\x3f\x3b\xf6\x1b\xa0\x1d\xdf\xc0\x02\xed\xb8\xb1\x09\xda\xb1\xc7\x06\xcd\x2e\x7d\xb3\x35\x52\x61\x86\xd6\x74\x91\x34\x37\x44\xfb\xb6\xc9\x2a\x69\x2f\x73\x0a\x8a\xd9\x71\xd1\xe6\xd1\xf8\xa6\x29\xa1\xc9\x19\x09\x53\x0a\xd6\x0a\xf0\x3a\x30\x48\x42\x70\x60\x4b\xfe\xf9\xe6\xf5\xab\xa2\x58\xbc\xa7\xff\x6f\x49\xf3\x62\x0d\x04\xb3\xcb\x05\x4d\x27\x56\x0e\xf7\x63\xa3\xde\x6f\xb4\x25\x5e\x44\xc3\x7d\x1b\x9a\x7c\xb9\xde\x5d\x33\x22\x45\x96\x42\x9a\x09\x20\xa9\xff\x92\xcf\xd8\xee\x13\x4d\x93\x34\xa3\xc3\x38\x4a\xe8\xda\x35\xb7\x58\x65\x78\x68\xe4\xea\xfe\xfe\xe5\xec\xfd\xcb\xd9\x3f\xf1\xcb\x59\xfe\x6a\x56\xd8\xb0\x19\xcf\x66\xf9\x86\x43\x6e\xf6\x7a\x56\xec\x7d\xc7\x45\x14\x43\x9d\x5c\x9f\x09\x6b\x87\x3f\x4f\x72\xc0\xa2\xe2\x52\xb1\x44\x5d\x64\x1c\x07\x79\x4e\x4e\xa0\xc8\xa9\xe8\x26\xcf\xd0\x4c\x98\x57\xb5\x36\x80\x7b\x23\x58\xa5\x42\xb9\xca\x38\x08\xa9\xf0\x64\xdd\xdc\xc9\x39\x40\xb2\x9a\x8e\xdf\x1e\x7e\xfc\xc0\xce\xd6\x30\x09\xed\x73\x1a\xb5\x39\x69\xb6\x3f\xa3\xdf\x6f\xd0\xef\x9f\xd0\xef\xfc\xd7\x60\x94\xca\x8f\x49\x94\x24\xf4\x52\x7d\xd1\x79\x91\xc2\x53\x46\x99\xb2\x88\xc6\x66\x42\x12\x24\x66\xc2\x3c\x1a\x67\x76\x4a\x1c\x47\x4e\x21\x03\xde\x00\x95\x1f\x46\x91\x69\x16\x24\xa1\x1a\x8a\x91\xf5\x93\xf1\xf5\xd1\xf8\x7a\x67\x7c\xbd\x34\xbe\xfe\xcf\xf8\xfa\x97\xf1\xf5\xd6\xf8\x7a\x61\x7c\xfd\xc3\xf8\x3a\xe6\x5f\x6b\xa7\xe5\xae\x6b\xd8\x1c\xbd\xdb\x7f\xc1\xa6\x78\x48\x76\xb6\x7b\x2a\xf1\xc3\xe1\x4f\x6f\xf7\x3f\x1e\xbf\x7f\xf9\xe9\xf5\xcb\xb7\x3f\x7d\x7c\x35\x24\x8f\x75\x26\xcc\xea\x50\xff\xd4\x39\x25\x94\x33\x24\x5f\x88\x95\xa0\x9d\xa8\x43\xc6\xa7\x17\x47\x3f\xbf\x25\xd7\xba\xa6\x77\x47\xaf\x5f\x33\xe8\x8f\x87\x6f\x5e\x1e\x1d\x7f\x1c\x92\xad\xcd\xcd\xcd\x81\xe8\xa1\xb8\xf1\x7e\x1e\xa7\xe3\xcf\x43\xd2\x66\xac\x33\x2f\xda\x46\xde\xfe\x18\xe2\x18\x0f\xf5\xdb\x46\xfe\x00\x83\xed\xe7\x75\xbe\x4f\xee\xe3\x60\xdc\x6f\x64\x7f\xf5\x8d\x6c\x4d\xb9\x80\xc8\x67\xc1\xce\x5d\x79\x80\x38\xc8\x2e\x17\x45\xfa\xf7\x0f\x78\x73\x18\x43\xda\x23\x1d\xfe\x82\x35\xe8\x05\x18\xb0\x9c\xb6\x37\xb4\x93\xeb\xbe\x01\x28\x2e\xc7\x0f\x54\x45\x12\x79\xf0\x40\xe6\xf6\xa5\xbf\x08\x2e\x26\xcf\xe8\x45\xdb\x7e\x45\x67\x78\xfe\xfa\x81\x6c\xb3\xd2\xb6\xeb\xe3\x6d\xe9\x2e\xd2\x2c\x4e\xe4\x65\xb8\xba\xe0\xb7\x9c\xb3\x13\xeb\xb5\x1d\x07\x95\x38\x62\x9d\xeb\xbf\xa2\x17\x7d\xd0\x5e\x0a\xcf\xbd\x3e\x1b\x23\x86\x15\x39\x6c\xdd\x3a\x3f\xd1\x71\xf5\xdb\x90\x6c\x7f\xf3\x84\x97\x44\x8f\x93\xe5\x9b\x33\xc6\xf2\x14\x8e\x5b\xc3\x6f\xbe\xeb\xb5\x4c\x94\xb7\x86\x4f\x37\xaf\x4f\x7b\xdb\x8d\x7c\x3e\xdd\xf3\xbd\x7b\xbe\xf7\xe7\xe5\x7b\x9a\xed\xf1\x77\xfe\x77\xc0\xf7\x2c\xd9\x7d\x75\xd1\xdd\x23\xb9\xcb\x82\x3e\xc1\x7d\xa5\x50\x43\x36\xaf\xed\x0f\x04\xbb\xd7\xb1\x88\x26\x4f\x31\x00\xfb\x56\x22\xfc\x32\x89\x8a\x37\xc1\x42\x89\x8b\x6d\x29\x51\x0f\x39\x0f\x6a\x6f\x4a\x59\x93\x49\xed\x43\xcd\x16\xdb\x5b\x86\x9c\x3f\x44\x19\x9b\x9b\xaa\xd0\xff\x56\xe4\x8d\x82\xd1\x28\x98\x52\xd5\x12\xce\x43\xc2\xff\xd0\xce\x9b\x7b\xea\x44\xd9\x6f\xaa\xb3\xe3\xf4\x8c\xc6\xc1\x58\x36\x6b\x67\xeb\x33\xc6\xd0\x97\x3d\xf5\x57\x8e\x20\x7e\xaa\x85\xc8\x67\x41\x92\xa4\x89\x31\x6e\x13\x42\x9f\x6b\x86\x15\x10\x35\xad\xc0\xc9\x6a\xe8\x81\xc0\xa8\xd4\xe7\xa5\x61\x35\x50\x5d\x4d\xe2\xec\x36\xf4\x02\x19\x95\xa9\xf3\x98\x3d\x36\x0f\xa0\x7f\x88\x26\xa0\x41\xae\x1e\x38\x04\xfa\xd9\x84\xf5\x81\xe2\xb9\x86\x53\x5f\x65\xc5\xb8\xbf\x8d\xea\xc6\xd5\x37\x2d\x80\xca\x14\x2b\x94\x61\xc5\xfc\xc6\x56\xda\x11\xc3\x22\x08\x85\x29\x29\x98\x7a\x5e\x2c\xe8\x98\x6d\x5e\xca\x3c\x1f\x1b\x5d\x09\xef\x29\x3e\xcb\x29\x5d\xc5\x88\x32\xb8\x50\x84\xe3\xb2\x6c\xb0\xc6\xb3\x20\x0b\xc6\x05\xcd\x72\xa9\xe2\x87\x7b\x79\x51\x1a\xed\x23\xde\x36\xa2\x69\xd2\x43\xb6\xd0\x64\x73\xcd\xef\xf6\x23\x9a\xce\x0a\x22\x3d\xd2\x5a\xde\x7d\xc5\x18\x0c\x69\x93\x83\xf4\xa0\x77\x79\x0f\xda\xf1\xf8\x18\xe2\x16\x22\x00\x03\x11\x69\xe1\xb5\xaa\xba\x21\xde\xea\xf6\x7f\x49\xa3\x04\x82\x35\x90\x67\x50\x07\x19\x92\xd6\x66\xab\x4b\x36\x04\x70\x89\xe1\xdb\x8d\xe7\x02\xa2\xf5\xfc\xd9\x27\x03\x06\xb1\xe2\x6c\x88\x1e\x6e\x70\x8f\xcb\x37\x9d\x97\x32\x43\x44\xd3\x11\x0d\x6c\x9d\x60\x86\x08\x91\x3c\x5c\x1f\xd3\xd6\xbc\x70\x6f\xcd\x15\xb3\x12\x25\xac\x12\x3f\xb2\xb0\x3f\x6a\x8f\xa3\x24\xd6\xb8\x36\x3b\xe4\x1e\x48\x8e\xf9\xd6\xae\x44\xfa\x19\x0f\xf6\x3c\x18\x90\x1f\xa3\x24\x24\xfc\x71\x97\xe8\xa8\x0a\xd6\xcc\x24\x8a\x56\x4b\xdf\xe4\x83\xed\x4b\x0f\xe2\x47\xcd\xe8\x85\x34\x61\x56\x67\x2e\x96\xc6\x4f\x3d\xec\xc4\x51\x7e\x56\x62\xd5\x6c\xe3\x77\x2f\x60\x5c\x23\x6c\x6a\x76\x49\xb4\xb1\xb7\x8d\xc1\x65\x20\x64\x6c\xdb\xa1\x9b\xea\x44\xac\x1d\x11\xfa\x42\xb5\x30\x21\x1d\x5e\x64\x6f\x8f\x6c\x76\x8d\x53\xda\x28\xa3\xc1\x67\x0d\xca\x46\xb9\xb1\x47\xc4\xab\x72\x36\x83\x07\xb3\x20\x3b\x48\x43\x0a\x35\x78\x0f\x61\x6c\xb2\xa5\x39\x4e\x5e\x64\xcd\x28\x84\x4f\xda\x4a\x24\xb2\xcf\x8a\xfc\x76\x34\x02\xcd\xfd\xf7\x10\xc9\x4d\x66\x3e\x2f\xca\x5e\xa7\x9b\x93\xed\xf1\x31\xdf\x59\x64\x74\x12\x5d\xf0\x08\x5a\x9b\x17\x5d\x36\x0b\xc0\x35\xfc\xee\xed\x45\xa8\xb7\xf2\xd9\xf7\xda\x2e\xc3\x11\x34\x88\x81\x9b\x57\x06\x13\xf0\x85\xf8\x34\x7c\xed\x0b\xb7\xeb\xa2\x1b\x98\x2a\x18\xc5\x0b\xcc\xf3\xd9\x87\xe5\x20\xcc\xb6\xf9\x72\x90\x33\xc2\x5a\xd2\xd4\x31\x49\x33\xdb\x84\x2e\x2f\xb2\xb2\x70\xf8\x68\x46\x19\xd4\x58\xcc\xcd\x7e\xd1\x89\x6e\xb6\xd2\xc1\x3a\x51\x44\x06\x37\xbc\xb6\x69\x10\xd6\xdf\x8d\x3d\x92\xc8\x7d\xe1\x7b\xb2\x4d\x9e\xb1\x93\x0d\xd9\x20\x6c\x3f\x48\x7c\x34\x21\x5c\xc8\xcf\xe8\xc5\x5d\x92\x86\x15\x73\xc0\xa6\x8d\x1a\xd6\xf0\x9b\x11\x87\xc3\x33\x10\x75\xfc\x36\x14\xf0\xbb\x4d\xab\xe5\xb1\x74\xb2\x8c\x63\x85\x86\x01\x3d\xa3\x49\xc1\x1f\x0a\x00\xcb\xff\x25\x4f\x13\x12\x8c\x22\x9b\xc7\x4b\xb7\x89\x1f\xd3\x1f\x97\x71\x6c\xbf\xa1\x94\x8f\x09\x58\xe9\x47\xbc\xb4\xfb\x18\x8a\x37\xec\xb4\xab\x19\xbb\xdb\x86\x21\x48\xb1\xca\xb1\xea\x94\x7d\xf7\xc1\x84\x22\x4a\x42\x7a\x71\x34\xe9\xb4\x3b\xed\x2e\xf8\x86\x7c\xb4\xe5\x79\x0e\xa9\xe0\x1d\x3b\xc1\xe2\x72\x41\x45\x73\x00\x04\x54\x64\xfa\x33\xeb\x44\xdd\x2f\x32\x7e\x70\x9f\xc1\xef\x92\x6b\x21\x8a\x99\x96\x7f\xaa\x15\xb2\x41\xda\x1d\x36\x73\xaa\xf6\x0d\xd2\xee\xb6\x1b\xad\xbd\x30\xca\x17\x71\x70\xc9\xe7\x05\x7c\x8c\x26\x05\x93\x6d\x15\x36\xec\x37\x6b\x17\x90\xfd\x82\x17\xab\x7a\xe1\xca\x6a\x33\x27\xdf\xbf\xbc\x8c\x1e\xb0\x2d\xcd\xa2\x18\x3a\xed\xcb\x60\x8b\x97\x1d\x61\x56\xd7\x25\x8f\x7e\x50\x89\x6a\x5a\xdd\xbe\x55\x3e\x7c\x56\x36\x9b\xce\xcc\x1a\x68\x16\x60\x7c\xb2\xc9\x33\xfb\x4d\xab\x78\x0f\xc6\xd6\x8c\x76\x36\x32\x18\xe8\x81\xa6\x67\x34\x8b\xd3\x20\xa4\xa1\x52\x04\x7b\xd6\x04\x1e\xc0\x47\x4d\x24\x65\x6f\x1a\x07\xe4\xe3\xd1\x8b\xa3\x21\x99\x07\x9f\x41\x35\x1c\x25\x67\xcb\x38\xa1\x59\x30\x8a\xe9\x5d\x0e\x50\x9f\x06\xec\xd7\xbb\x5b\xe4\x11\x41\xd9\xdd\x6e\x3f\xa3\x8b\x38\x18\xd3\x4e\x9b\xb4\xc1\xa9\x1b\x3b\x2d\xb4\xcc\x08\x91\x69\x72\x46\xb3\x22\xd7\xf1\x36\x41\xee\x0b\xe9\x38\x9a\x07\xb1\xcd\x64\xa3\xc4\xcf\xec\x8b\xf4\x05\x2f\xe0\x52\x5e\x65\xec\x4c\xd3\xad\x21\x17\xf0\x44\x4d\xb5\xd1\x1f\x8b\xd4\x0d\x8e\xa9\xc2\xcf\x34\x19\x63\xad\x6c\xcb\x78\xe2\x5d\x8d\x0b\xd5\x55\x1d\x99\x35\x91\x5a\x52\x77\x7c\x9e\xb8\xdc\x42\x7d\x6a\xee\x28\xc6\x61\x9f\x03\xc4\x34\xcf\x3f\xce\x82\xa4\xb3\x09\x4e\x64\x1f\x71\xab\x73\x61\xbd\x2f\x08\x6b\xab\x0b\xb1\x5b\x51\x8e\x81\xc5\xfd\x25\xb8\x69\x16\xa8\x0c\x92\x4b\xe1\x78\x47\xb8\x23\x4d\xca\xd1\xda\x17\x78\xdd\x4f\x42\xae\xfe\xe7\x34\x14\x4d\x2e\x73\xe1\x48\x3d\x27\x23\x3a\x49\x33\xda\x77\xe8\xea\x95\x38\x3a\x54\xe3\xfe\x4a\xec\x41\x35\xa4\xf5\x0a\xf6\x79\x03\xf9\x6a\xfd\x3e\x14\xa6\x62\xf3\xe0\x82\x87\xad\xbc\x88\x8a\xcb\x21\x79\x0a\x2a\x6c\xb9\xeb\x44\xb9\x70\x69\x0c\x45\xbb\xf6\x26\x83\x26\xb9\xb3\xc1\x20\x76\x8d\xa2\x78\x3a\xab\x0b\x5b\x65\x85\x21\xdd\x19\xa3\x1d\x76\x0a\xe1\x48\x6b\x7b\xab\x80\xf8\x4a\x7f\xff\x70\xf4\xb6\xaf\xb0\xcc\xdb\xd3\x0e\x2c\xc1\x75\x6c\x4e\x02\x3b\x94\x67\x8f\x2c\x82\x3c\x67\xbc\xab\x98\x65\xe9\x72\x3a\x33\x57\x80\x1a\x88\xa0\x35\xa8\xd5\xbd\x9c\xd4\x5c\xed\x11\x9c\x96\x3c\x32\x6f\xe9\x88\x25\x80\x78\xdb\x61\x56\x57\x53\xdb\x99\xb4\x1f\x45\x15\x90\xce\x7a\x94\xff\x18\x25\x51\x41\x2d\xa4\x5b\xdd\x00\x09\x11\x75\xc2\x94\xb2\xdc\x8e\xa2\x75\xf1\x5e\x6c\x2a\x7c\x1d\xb0\xf3\x52\x02\xdc\x9f\xfc\x4c\x6d\x41\x6a\x4a\x0b\x08\x57\x7c\x34\x39\x4e\x22\xaf\xb6\x0b\xca\x16\x33\x2a\x7e\xa8\x05\x47\x8a\xb4\xa7\xb4\x53\xca\x21\xba\x37\x6a\xa3\xea\x87\xaa\xa6\xc3\x3b\xd3\x85\x22\xe0\xb6\x2b\x27\x34\xcb\xd2\x4c\xba\xa4\xe1\x3d\xce\x49\x92\x16\x64\x9c\x66\x19\x1d\x17\xc3\x73\xb5\x6e\xcc\x5e\x1b\x0b\x88\x15\x94\x24\xb0\xe4\x99\xf0\xdf\x33\xf8\xaf\x5f\xa4\xaf\xd3\x73\x9a\x1d\x04\x39\xed\x00\x73\xe1\xfa\x5e\xcd\xc7\x18\xd4\x3f\xc4\x2d\xb3\xb8\xba\x39\x61\xff\x9f\xea\xa3\x38\x02\xc1\x7e\xbf\x31\xe1\x71\x4f\x64\x09\x3d\x27\x2f\xd9\xa8\x3a\x6d\xb8\xea\x85\x8e\x80\xad\xea\xbf\xdb\x05\xa1\x17\x51\x5e\xe4\x3d\xb2\x88\x69\x90\x83\x58\x0c\x23\x4f\x13\x85\xaa\x49\x1a\xc7\xe9\x79\x94\x4c\xa1\x64\xce\xb8\xa0\xb5\x8c\x44\x0f\x7b\xe0\x5f\xa1\xa7\x9f\x7d\x54\x44\x89\x55\xbd\x07\xef\x57\xa6\x57\xe1\xe0\x33\x85\x45\xc8\x19\x3e\x5c\x46\x47\x60\x4f\xab\x98\x2c\x27\x01\xc6\x6a\xc1\x57\x05\x9f\x78\x8e\x5a\x41\x59\xef\xd2\x3c\x8f\x46\x31\x9f\x42\x70\xa1\x21\x8c\xfa\x3e\x1c\x32\xf9\x32\x2b\xf8\x4f\x26\x52\x4b\x6c\xbd\x9c\x4c\xa2\xe9\xa5\xf8\x38\x92\xa4\xf4\x88\x7c\x66\xcd\xf3\x3f\x7d\x5d\x05\x9f\xe2\x66\x8b\x83\xcd\x35\x98\xba\x5c\xe2\x9f\xf2\x2a\x8a\xc3\x4d\x35\x9c\xba\xff\xe1\x9f\xe2\xc2\x48\xe7\xf1\x02\x8f\x1e\xa9\x85\xa9\xef\x71\x78\x81\x5f\x83\x51\x6a\xe4\x79\x4a\xc8\x7b\x18\x3e\x00\xb8\xbe\xc1\x79\xbc\x04\xea\x05\x2a\xcc\x3f\x05\x16\x10\x08\xb1\x20\xd0\x07\x5c\xa6\x08\x84\x50\x8d\xc3\x29\xfa\x5d\xc8\xdf\xb6\x48\xc1\xf9\x82\x75\xf2\xbd\x52\x72\x3a\x27\x87\x71\x90\xb0\x93\x41\xa0\x58\xb3\x48\x17\xba\xb2\x34\x23\x01\x79\xf5\xf2\x9f\x70\x08\x97\xd2\xda\x9d\x31\x14\xb5\xcf\xca\xa3\xdd\xcf\x33\x2a\xfd\xec\x05\xe8\x2a\x57\x44\x41\x41\xc1\x02\xd8\x7a\x0a\x72\x72\x4e\xd9\x02\xd1\x0e\x56\xe4\x30\xd6\x90\x34\xf4\x33\x35\x8e\xe4\x72\x9c\x98\xa5\x70\x51\x87\xd5\x2c\x99\x04\x16\x8a\x78\x09\x1c\x35\xd6\xe4\x54\x9c\x3b\x59\xf2\x10\xde\x86\x45\x05\xe4\x99\xd1\xc8\x10\x7f\x21\xc9\xaa\x76\xf9\x06\x1c\xc7\x9e\x15\x7c\x4e\xa3\xfb\x05\xfb\xdf\xb2\xc4\x8b\xb4\x6a\x81\xa3\xf3\xc2\x6f\xb6\xd4\xd9\x6a\xfb\x1d\x17\x3b\x20\xe4\x6e\x96\x7a\x11\xcd\x69\xfe\x7b\x2c\xf3\x44\x28\x17\xd9\xe2\x56\xaa\xaa\x9c\x1f\xf3\xd9\x16\x4d\x94\x29\x8b\x43\x0d\xaa\x23\x8d\x68\x42\x53\x81\xbc\x3a\x64\x53\xaf\x49\xc1\xac\x4d\x39\xb9\xd2\x15\x68\x00\x85\x7e\x6c\x7b\x63\x4d\x42\xcd\xf1\xe7\x1b\x26\x03\xc2\xaa\x97\xe5\xc5\x8f\xab\x2b\xb2\xb9\xeb\x3d\xdb\x88\x7a\x9d\xb3\x09\x4f\x37\x0e\x44\x02\xe5\xb2\x27\x0f\x1e\x10\xf1\xdb\x27\xf3\xb3\x26\xed\x5c\x7c\xc0\xf0\xb9\x40\x33\x44\x31\x51\x58\xa9\x44\x36\x2f\xda\xbd\x76\x1b\xdf\xb7\x58\x8e\xd2\x7c\xa5\x31\x9d\x94\x8a\x74\x89\x0c\x1d\xeb\xa1\x14\x45\x27\x1c\x4c\x06\xf1\x50\x27\x31\x61\x35\x09\xb0\xc5\x79\xda\xce\xc9\x58\x85\x74\x71\x48\xcb\x8c\xf8\xd2\x84\xbe\x4a\xa8\x06\x9d\x91\xcd\x3a\x4d\x7d\x97\x41\x32\x0c\x7c\x84\x28\xcb\xb7\x5e\xe1\xc5\x77\x07\x39\xad\x53\x05\xb0\x46\xa2\x76\xea\x5a\x93\x5b\xfe\xb5\x60\x96\xfb\x8b\x78\x99\xeb\x2e\x88\x6f\xaf\x77\x43\x05\x64\x2a\x92\x66\x74\xfc\x39\x97\xa7\x26\xce\x22\xe5\x2d\x67\x2e\xde\xca\xc5\x97\xe0\xc6\xd7\x1b\x8c\x98\x93\xfc\xd8\x1b\x88\xd8\x0c\x29\x8c\x1a\x60\xeb\x3f\x40\x05\xb0\x63\x3b\x08\xae\x24\xa6\xce\xaa\xdc\x98\x39\x51\xde\xd2\xa0\x0d\xfe\xb3\x79\x71\xb2\xf9\xe8\xbb\xe0\xd1\xe4\xf4\xcb\xe3\xcd\xeb\xff\x19\x44\xfd\x82\xe6\x85\x02\x5f\x61\xf0\x15\x63\xfe\x4a\xa3\x6d\x30\x4e\x50\x00\x0c\xfe\xd3\xd9\xbc\xe8\x3e\xab\x1c\x28\xa6\xc0\xc1\x40\x07\xcb\xe2\xe1\xb0\xa0\x7b\xdc\x85\xb0\xb0\x3a\x9c\xc3\x43\x5e\xb6\x21\xa3\x61\x9b\x14\x2c\x3c\x01\x12\xd3\x57\x85\xb7\x33\x66\x5f\x18\xa3\x43\x60\xfb\x8f\x7e\xf4\x82\x59\x5d\x86\xd8\x5d\xed\x1c\xbc\x1d\xe7\x73\xf6\xef\x38\x58\xe4\x20\x3c\x88\xdf\x3d\xec\x9e\xd1\xee\x2d\xf7\x3a\x8f\x3a\x6b\x54\x7e\xa4\xf6\x76\x8e\x19\x1a\x8c\x67\x64\x1c\xe4\x4e\x35\x51\xce\xa9\x64\x39\x17\xb3\x83\x48\x89\xaf\xb1\xe6\x04\xc5\xdb\xca\x97\xf3\x39\x0d\x4b\x69\xcb\x6a\xee\xae\x69\xcc\xaa\xbe\x8a\xd6\x06\x03\x3e\x20\x0b\x39\x81\x2a\x29\x7e\x39\x1b\x90\xd6\x86\x08\x88\x57\x41\x0e\xae\x68\x66\xc1\x8e\x6c\xc4\xd4\xa4\x48\x59\xc7\xe7\xee\xe5\xf1\x26\xdc\x50\x12\x8b\x3c\xc0\x75\x77\x31\x23\x31\x85\xc7\xd4\x28\xfe\xde\x62\x41\x33\xd6\x5b\x39\x0f\x09\xc4\x2e\x9c\x46\x3c\xbc\x5d\x90\xd3\x79\xb0\x60\xf3\xb1\x65\xe8\xf9\x3a\xca\x7e\x01\x75\x1a\x9c\xb2\x6d\x3d\xe9\x92\x1f\xc8\xb7\x6c\x37\x17\x59\x27\xd1\x69\xbf\x48\x8f\x59\x43\x42\x13\xb4\xbe\xb7\x87\x32\x81\xe2\xab\x2b\xfc\x7e\xcf\x53\x23\xd6\x2d\x59\x35\x96\x78\x0a\x47\x6b\x52\x73\x7c\x83\xef\xeb\xe8\x0b\x8a\x4c\xdf\x88\x83\x9e\x24\xc7\x12\x5a\x2c\xd2\x3b\xa5\x45\xa9\xbc\x56\xfb\xf2\x0a\xa4\x88\x54\xc6\x8a\xfc\xec\x47\xd7\xa2\x9d\x76\x5b\xd0\x92\x4b\xa7\x06\x82\x6f\x44\xb5\x08\x68\xec\xf4\x9e\x55\x54\x41\xc7\xb2\x17\xe8\xd6\xdd\xa6\x69\x60\x79\x33\x6d\xf9\xc7\xa8\xf4\x3b\x76\xee\x99\x70\xff\xf9\xf2\x22\x4e\x91\xb8\x41\xc1\x75\x04\x6c\x92\x90\xdd\xff\x8d\xbd\x52\xea\x46\xf4\x65\xb3\xd2\xda\x9a\x2a\x69\xd3\x2a\x69\x4a\x9e\x5a\xd2\x34\x18\x69\x91\x32\x89\x32\x0a\xc9\xf6\x26\x77\x19\xf4\x48\xdc\x0f\xf2\x36\xf9\xf3\x84\xcd\x0b\xc2\x6d\x3b\x5c\xdb\xae\x5a\x52\xf6\x5f\xf6\x0b\xe7\x03\x98\x6f\x2b\xfb\xad\x66\xf4\x6b\x49\x33\xde\x6d\x4f\xfa\xd4\x95\xf8\x40\x32\x3c\xdf\x6b\xab\xb6\x59\x4f\x45\xe2\xee\xcb\x57\x9f\x09\x21\x23\x2f\xc2\x8d\x92\xaa\x51\x3f\xa6\xea\x91\xc7\x9b\xfe\x4b\x02\xe9\x87\x58\x1e\xa6\x73\x2d\xe5\xd6\xc7\xd8\xf4\x9e\x24\x7d\x37\x5f\x46\xdc\x4d\xbe\x93\xf9\xce\x80\xa4\xc3\xbb\x61\x89\x85\xb2\x6f\x49\x5e\x04\xc9\x98\x71\x11\x5d\xf8\xea\x4a\x21\x4d\x14\x86\xc7\x6b\xf0\xcb\xf0\x9b\xe1\x4d\xe5\xa6\x11\xc0\x8b\x54\x95\xed\xa6\x88\x92\xe7\xe1\x3a\x2c\x7d\x70\x6c\x8b\x1a\xa2\xc8\x13\x21\xc9\x8b\x1f\xc1\x5a\x45\xcf\x60\x34\xbc\x6f\xed\xbb\x43\x0f\xef\x4b\x63\xdc\xc8\x1e\xd7\x63\xe7\x47\x6d\x43\xb2\x2a\x7e\x64\xd1\x1b\x61\x48\x96\x68\x37\x1c\x11\xeb\x53\x51\x3f\x1c\xde\xf5\x1b\x0c\xe6\x48\xf4\xad\xe1\x62\x60\xf2\x45\xb2\x8c\x63\x08\x92\xd0\x71\x57\x08\xd8\x6d\x83\x0a\xc3\x33\x76\x71\x5d\xdb\x70\xe4\x23\xde\xd9\x06\xec\x80\x03\xde\x84\x19\xf0\xa4\x1b\x4d\xa4\xe8\x5e\xd3\xd1\x80\x07\xc0\xfa\xb1\x38\x01\x35\x1a\x8e\xc4\x0d\x8a\xd1\x90\xa5\x41\xc1\xca\x31\xd8\x07\x12\xbe\x8f\x82\x89\x5c\x2a\xa9\xce\x1c\xc4\xdf\x73\x73\x5d\x69\x03\x84\xca\x31\xb0\x62\xf6\xa3\x01\xe5\x39\x29\xbb\x74\xf7\xa9\xf5\x75\xb8\x98\xe4\xaf\x70\xb5\x2d\xeb\x35\x19\x43\xd4\xa7\x0e\xf5\xec\x6d\xf8\x38\xba\xca\xa8\x03\x31\xee\x97\x6c\x02\xe9\x72\x4e\x46\x71\x3a\xfe\x4c\x66\x34\x08\x69\xc6\x3e\xd2\xb9\x6d\xb4\x11\xe5\xcf\x59\xb2\x4f\x68\x98\xd1\x0b\xe5\x16\x1d\xca\x92\x49\x14\x17\xb6\x32\xd3\x43\xb0\x00\x6b\x78\x1f\x66\x29\x95\xe7\xfc\x6f\xb6\xb6\xf5\x41\x9f\x83\xd7\xe0\xa5\xfc\x98\xce\xeb\xc2\x55\xf9\x4e\xe9\x2e\x94\x2f\xe0\xb0\x3e\x69\xaf\xb9\xfd\xb8\xc1\xcc\xc4\x29\x13\xf3\x16\xd1\xd8\x9d\x87\x8f\x2c\xb9\x6e\x1e\x0a\x05\x54\x31\x01\x50\x93\x31\x01\x50\xac\x72\x02\x9e\x3c\xd6\xf8\xe7\xd0\x37\xc6\x3f\x54\x85\x6b\xf2\xa1\xdf\x01\xba\x11\xf6\x4b\xfc\x8e\x08\x91\x6f\x28\x7f\xf4\x64\x2a\xbc\xf9\x19\xaa\x5f\x3c\x1d\x04\xc3\x21\xff\x4f\xa6\x08\x03\x92\xa1\xfe\xc9\x73\x90\x71\xc9\x10\x7f\xc8\x72\xc7\xc5\xe4\xe9\x50\xfc\x2f\xd3\xc0\x5c\x65\x28\x7f\xe8\x7a\x38\xac\xfc\xa5\xd3\x05\xbc\xfa\x29\xea\x71\x6d\x6e\x87\xbe\x44\x0e\xed\x9a\x72\x0e\x3d\x69\x06\xac\xb4\x9a\x1c\xda\x09\x72\x1c\x3f\x53\x18\xc5\xcf\x14\x8d\x01\xd2\xc4\x0f\x09\xa7\xa4\xc5\x21\xfe\x90\xb9\xa6\xca\x7a\xe8\xa4\x28\xac\x71\x41\x7d\xa8\x7f\xf2\x1c\x24\x1d\x0f\xf1\x87\xcc\x35\x4e\x22\x43\x3b\x41\x42\xa1\x7c\x2b\xc7\x3a\xba\x0f\xdd\x24\xd9\x43\x07\xd2\x49\x92\x75\x4a\x61\x6c\x88\x7e\xe3\xfe\x26\xd3\xa1\xfa\x25\xd3\xf9\x9e\x3a\x54\xbf\xd4\xe8\xf9\x7a\x1f\xea\x9f\x6a\x4c\x6c\x97\x1c\xca\x1f\x32\x95\x6d\x58\x43\xf1\xbf\xaa\x83\xf1\xbb\xa1\xfc\x21\x53\x81\x6d\x0c\xe5\x8f\x1e\x2c\x30\xee\x9f\x4e\x3c\xea\x6e\x0d\xb7\xbe\xeb\x55\xba\xb7\xe9\xb5\x96\xc5\xe4\x69\x6b\xf8\xf4\x9b\xeb\xd3\xde\xf6\x56\x13\x87\x0f\xe6\x12\xde\xe3\x0b\xb8\x25\xfc\x1c\xb4\x86\xa4\xb5\xd9\xdf\xde\xec\x6f\xb5\xd6\xae\xa5\x27\xb8\xed\x46\x81\x8a\xef\x1d\x49\xdc\x3b\x92\xf8\x2b\x38\x92\x10\xb5\xac\xb9\xae\xe0\xfe\x4e\x27\x93\x8c\x5e\x92\x9f\xa3\x78\xfc\x99\x92\xef\x7f\xa1\x93\x89\xed\x4d\xa2\xa1\xc3\x38\x00\x8b\x82\x84\x1c\x31\x89\x3b\x00\xa8\x28\x48\x5c\xb0\x1f\x83\x11\x03\xfb\x47\x3a\xa5\x71\x5e\xd0\x38\xa6\x19\xf9\x7e\x02\x89\x2e\xf0\x4f\xc1\x19\xf9\x39\x4d\x43\xf2\xfd\xb4\xd4\xcb\xc5\x63\xed\xdd\x47\xb8\x82\x7c\x13\x24\xc1\xd4\x74\x3d\xd1\x1f\x30\x2c\x0c\x32\x0e\x30\xe7\x00\xd2\xc5\xc4\xe1\x08\x0e\x47\x36\x70\x34\x0a\x12\x09\xf2\x12\xac\xf8\x6d\x08\x2e\x79\xe5\x03\x5a\xcc\x24\xe0\x8b\xe7\x15\x70\xe1\x48\xb9\x9b\x9d\x55\xd5\x97\xcf\x54\x7d\x6f\xc1\x31\x79\x19\x60\x42\x0b\x09\xf8\x8e\x66\x39\xbc\xa4\x2a\x87\x5e\x08\x10\xd5\x89\xf3\x20\x9b\x57\x75\x83\xe5\x2b\x60\x5a\x14\x10\xb4\xc9\x85\xcf\x45\x96\x04\x95\x5c\xc5\x80\x94\xec\x82\x9d\xa8\xb4\x6f\x8f\x28\xb6\x2a\x44\x51\xe5\xcb\x5d\x84\x70\x20\xe9\x8c\x49\xbc\xdb\xa0\x49\xe8\xe9\x1b\xcf\x90\x60\xcf\xe1\xc4\xe4\x42\x8d\x58\xba\xc2\x64\x96\x2e\x68\x56\x5c\x7a\xe0\x16\x22\x4b\x82\xbe\x2a\x8a\xc5\xbb\x2c\x3d\x8b\x42\x2f\xb9\xb1\x85\xba\x10\xd9\x8a\xd8\x16\xe3\x8a\x12\xd1\x62\x6c\x17\x68\xe6\xd0\x70\x6d\x4d\xc9\xea\x3f\xd3\xd1\x0e\xe9\xc8\x6a\x4c\xa7\xbc\x99\xbd\x42\x12\x7a\x6e\x2d\x1b\x5d\x12\xf9\xe7\x15\x91\x56\x51\xcf\x25\x14\x02\xa2\xfc\xa9\x0b\x3d\x67\xcb\x05\xfc\xf4\xe3\x2a\xc2\x91\xc8\x7c\xf1\xdc\xc9\xcb\x67\xb2\xe4\x87\x99\x5b\x32\x81\x35\xc0\x72\xdf\xd2\xc2\xc9\x5d\x68\xc2\x67\x20\x72\x1d\x38\x70\xa3\x5f\x7f\x95\x6d\x30\xba\x76\xfb\xa0\x09\x1c\x80\xc4\x67\x07\xc3\x68\xca\xd6\x47\x8d\x60\x11\x0d\xd5\x66\x28\xfe\xe7\x47\x0e\xdc\x49\x81\xad\xdc\x28\x8a\xc9\x67\x68\x7c\xf5\x14\x0c\xa2\x97\x21\xfe\x70\x9a\xf8\xa4\xd6\x00\xff\xe1\x0c\x50\x00\x74\x74\xfb\x82\x9c\x23\x9a\x0f\xd1\xef\x0e\x37\xe6\xb9\xee\xee\x32\x89\x69\x30\x00\x0f\xbc\x39\x25\x7a\x0c\x29\xdf\x89\xc1\x25\xd0\x1a\x23\x37\xcf\xf8\xea\xc6\x56\x3a\x2e\x26\x34\xca\x3a\x65\x38\x4d\x8a\x29\x0f\x87\x0c\xae\xa7\x71\x5c\x78\x65\xd2\xf6\xf4\x25\xa3\x3c\x56\x84\xee\xc5\x67\x4a\x17\x87\xf9\x87\xcb\x64\x1c\x25\xd3\xca\xae\x40\x59\x0b\xbe\x19\x05\x7a\x3a\x82\xf9\xc2\x73\x6d\xbf\x62\x41\xc9\x57\x30\xdc\x9b\x14\x7c\x79\x60\xe4\x8b\x59\x09\x05\xdf\x1e\x38\xf1\xec\x5a\x82\xb1\x4f\x07\x0a\xbf\xc0\xe5\x80\x2a\xc5\x0b\x6b\xd4\x29\x13\x3c\x6d\xeb\xe7\x54\xb2\x79\x91\xe2\xad\xd5\x86\x46\x69\x9e\xba\x31\x2e\x65\xed\x55\x38\xe5\x16\x8e\x12\xf2\x67\xea\x1f\x19\x86\x12\xdf\x0e\x1c\x36\x6c\xe1\x90\x2a\xc5\x03\xeb\xde\x0a\xcb\x32\x07\xf6\x6d\xa1\xd3\xe7\xb2\xb2\x4e\x8e\xa7\xdd\xc3\xe7\xfb\x6f\x51\x63\xec\xd3\x81\xd2\xde\x69\x38\x98\xf8\xf6\xc1\x49\xc7\x29\x0a\x10\x12\xd8\x2e\x66\x2f\x7c\xbe\xf5\xe3\x87\xdc\xfc\x52\xc8\x74\xae\x68\x5e\xd7\xc1\x9d\xb4\x0d\x59\x76\x7d\x1a\x46\x19\xa8\x8a\xc7\xc1\x02\x1e\x5f\xa0\x0b\x4c\xcf\x8c\x1e\x1e\xec\xbf\x33\xd6\x3e\x2b\x87\x2d\xe4\x22\x2e\x4a\xb2\xe5\xcb\xa4\x4a\x9e\x6f\xbc\xf5\x64\x10\x7d\xd1\x8c\x5c\xd9\xe0\x4f\x46\xf1\xdf\xaa\x80\xa3\x27\x8a\x77\xc3\x5e\x27\xc4\x91\x8e\x79\xe7\x9c\x80\x0e\xa6\x2d\xf7\xa4\x24\x0d\x69\xbb\x67\x40\x4c\xc1\x2e\x64\x48\xda\x4c\xe8\xf8\x34\x8e\x23\x9a\x14\xff\xe0\xe0\x6d\x7d\x27\xdd\xed\xdd\xa4\x35\x5a\x9c\xa7\xd9\xe7\xb2\x06\x13\x5a\x7c\x12\xa0\x16\x88\x19\x2f\x60\x68\xaf\xf2\x5b\x76\x8b\x0a\x85\x76\x59\xbf\x68\x31\xfb\x04\x73\x3d\x4e\xe3\x7f\xfc\x0e\xfd\x3b\x9f\x45\xf9\x42\xb9\x46\x76\xba\x97\xcf\x66\xb7\x46\x1b\xfc\x3c\xf5\xee\x25\x51\x7e\x90\x26\x09\x77\xd9\x84\x96\x5b\xd7\xa0\xbd\x8e\x77\xbb\x7c\xf0\xc0\xbb\x8d\xe2\x2a\x3b\x5d\xff\x0e\xc6\x9d\x14\x48\x99\xbc\x94\xe6\xc1\x38\x14\x02\x27\x08\x89\xc6\xab\xb7\x65\x75\x4b\x67\xa2\xf8\x84\xc0\x55\x4e\xc6\xc1\xa2\x35\xdc\xde\x64\x49\xf8\x48\xd2\x1a\x6e\x6f\xb1\x34\x7d\x1c\x68\x0d\xb7\x1f\xab\x14\x2e\x3a\xb5\x86\xdb\x4f\x55\x12\x16\xee\x5b\xc3\x9d\x6d\x95\xc1\x56\x78\x6b\xb8\xb3\xa3\x13\xb4\x50\xdf\x1a\xee\xe8\x4a\xf5\xb1\xb0\x35\xdc\xf9\xd6\x49\xa6\xc5\xac\x35\xdc\x79\xea\xa4\x27\xb4\x68\x0d\x77\xbe\x73\xd2\xa5\x20\xdc\x1a\x3e\xde\x74\x32\xf3\xd9\xac\x35\x7c\xbc\xe5\xa6\x33\x59\xb8\x35\x7c\xac\xbb\x2f\xcf\x38\xad\xe1\xe3\x6f\x54\xa2\x79\x70\x6e\x0d\x1f\x3f\x51\x59\x52\x6a\x69\x0d\x1f\x7f\x5b\xad\xdb\xbb\x3e\xed\x6d\xef\xdc\x6b\xde\xee\x35\x6f\xff\x2d\x9a\xb7\x20\x8e\xc1\xbf\xc4\xed\xdc\xb8\x22\x05\x97\xa3\x0a\xf1\xe9\x42\x64\x94\x98\x97\x67\xdc\xa2\x1f\xe9\x18\xa0\x37\x12\x4e\xc7\x8c\xa9\x0b\x8e\xe4\xea\x69\xbc\x8a\x9a\x1f\xe1\x72\xd7\xaa\x0c\xd2\x24\xc4\x39\x0f\x7d\x64\x82\x48\x56\x24\x32\x95\x73\xd7\xfd\x38\x36\x86\x62\x0a\x46\xe6\xd1\xaa\x07\x37\xf5\x3d\x62\x99\x96\x95\x28\x3d\xcc\x04\x7c\x44\xfe\x85\x5f\xce\xb3\xff\x70\xb2\x63\x2e\xc9\x37\x21\xa7\x87\xd5\x51\xbe\x2d\xa9\x55\xba\x03\xdf\x53\xbf\xae\xae\x20\xfc\x0d\xb1\xdd\x3e\xb0\x44\x48\x3d\x69\x33\x29\x14\xc2\x0a\xb4\x7b\xa4\x5d\xa4\xfc\xe7\x69\x9f\xa3\x19\x85\x3b\x9c\x78\x6e\x43\x45\x33\x27\x93\x53\x30\x70\x51\xf6\xa1\xe2\x86\xb4\xeb\x89\x99\x6d\x55\xc3\xfa\xc3\x8a\xef\x21\xe2\xe1\x1e\x74\xa0\x23\xfc\xbc\xa4\x63\xe0\xe9\x06\xa5\xcd\x82\x7e\xb7\x05\xae\x28\x34\x5e\x0d\x3c\x9b\x8f\xbb\xb0\x73\x8a\x2a\x8c\x7b\x82\x16\x87\x41\x11\xc8\x11\xb0\xdf\x7d\xf6\x0f\xd9\x43\xbf\xaf\xae\xc0\x28\x56\x01\xc0\x55\x72\x2e\x41\xc4\xd7\xd5\x95\x0e\xbe\x09\xda\x46\xd6\xb4\xbc\x23\x47\x80\x27\x9b\xa7\xfd\x9c\x31\x04\xe5\x61\x9d\x41\xcf\x85\x80\xa3\x29\xcc\x9d\xae\x5f\x3c\xd3\x85\x5b\xd9\x13\xa6\xb6\x42\xba\x73\x2f\x6d\x3b\xbf\xa8\xe7\xe9\xdd\x93\xcd\x53\xf4\xf0\x6a\x1d\xda\xef\x92\x2f\xf0\xd4\x21\x48\x92\xb4\x20\x93\x28\x09\x79\xbf\xa2\x64\xca\x1b\x7a\xa6\x9a\x1f\xa7\x49\x9e\xc6\xb4\x7f\x1e\x64\x49\xa7\x8d\x4b\x70\x67\x39\x8c\x15\xc7\xe9\xb4\x8d\x4c\x5f\x45\x8f\x19\x2a\x1c\x87\x4b\x54\xb0\x21\x1c\x98\x0b\xe6\xae\xe3\x5b\x9d\x3d\xde\xad\x9e\x49\x10\xe6\x11\x0a\x6a\x94\xbe\x0e\x61\x8a\x1b\x2c\xc7\x0b\x3a\x66\x12\x80\x67\x3d\xf6\xc0\x21\xd3\x28\x18\x7f\x56\x21\x44\xc1\x13\x81\x38\xec\xca\xeb\xd6\x4e\x90\x4d\x97\xf0\x12\xe4\x44\xfd\x42\xce\x78\x4c\x2b\x74\x59\x23\x84\x7e\xae\x2c\x86\xdd\xc6\x75\x1c\x08\x36\xf1\x5b\xa6\x1b\x0b\xcd\x36\x92\x65\x1c\x3b\xe8\x4e\x25\xa5\x09\xe7\x77\xfa\x00\x2c\x21\x26\x28\xc8\x1a\xd7\xcc\x02\x26\xfb\xa3\xc8\x54\x1a\x22\xf1\x9b\x73\xf6\x4e\xda\x83\x83\x52\xbb\xe7\x65\xac\x3d\xc9\xde\xd9\x61\xab\xd3\xed\xe9\x86\x10\x86\xeb\x67\x2a\x28\x8a\x60\x3c\xfb\x98\x1e\x48\x3f\x58\x78\xca\xa4\x73\x2c\x7c\xe6\xd6\x53\xcb\xc7\xcd\x3f\x9d\xe1\xc8\xa2\xfd\x20\x8e\xd5\x7e\x22\x80\x4b\xce\x14\x4e\x37\xd5\x01\xc3\x73\xc2\xf0\x1e\x31\x80\x54\x5b\xc3\x6d\x90\xee\xf9\xaa\x6f\x0d\xb7\x41\x76\xc7\x21\xdb\x76\x00\xd8\xda\x08\x5b\xc3\xc7\x3b\x4c\x64\x7e\x7c\x2f\x32\xdf\x8b\xcc\x7f\x6d\x91\x19\x45\x7b\x81\xb3\xf7\x5d\x85\x7b\xf9\x7b\x9e\x26\xd9\x62\x6c\xca\x9b\xbf\xf0\x44\x75\x75\x98\x65\xa9\x2d\x02\xf3\x34\x25\x89\xba\x2a\x0a\x36\x58\x43\xc8\x74\x64\x4c\x40\xc7\xa7\x52\x49\x53\x64\xe4\x22\xae\x77\x8d\x9f\xc0\x20\x0c\xa5\x4b\x47\xc6\x8e\x45\x61\xf0\x92\x0d\x5d\x13\x09\x96\x45\x60\x10\x86\x1e\x1b\x5b\x22\xc6\xcf\x0b\x15\xda\xba\x75\xb0\x06\xe3\xc4\xac\x38\x0c\x7d\x32\xb7\x6f\xe0\x39\x0f\x0a\x2e\x21\x6a\x47\x24\x99\x76\x55\xff\x05\x8c\xb7\x6b\xbe\xfd\xdc\x74\x2e\xa0\xf0\x6b\x74\xd3\x9d\x02\x7d\x4f\x94\x84\x5c\xcd\x24\x61\x7b\xa8\x6e\x9a\x65\x3d\x21\x89\xe6\xae\x4c\xcc\xc9\x87\xff\x12\xc2\xa2\x06\x10\xf8\xc1\x1e\x26\x15\x2a\x7b\x04\x5e\xb7\x97\x3c\x60\x13\x55\x9e\x00\xcc\x29\x3e\x1e\x94\x0a\xec\xbc\x48\x49\xb5\x4c\xac\x91\xfd\x11\x95\xf6\x1d\xd9\xc7\x2e\xb0\x2e\x16\x51\x3f\xca\xff\x11\xc4\x51\xf8\x9e\xe6\x8b\x34\xc9\xa9\x68\xca\x79\x7c\xe7\x8c\xc1\xdf\x5e\x87\xaf\xb1\xfe\x61\x72\xe6\xad\x75\xd7\xa9\xf4\xda\xed\x5f\x69\xe5\xdc\x65\x93\x33\x58\xbe\xe7\x82\x6b\x08\x5f\x86\x68\xbc\x2f\xfa\x00\x4e\x23\x70\x82\x13\xc4\x5e\x4f\x85\x3a\xdf\x10\xbf\x28\x01\x94\xa5\xf5\x93\x7c\xf0\xad\xe1\x36\xe8\xd1\xc4\x8a\x6c\x0d\x77\xc0\xea\xad\x51\x90\xef\xfb\x0d\xff\x7e\xc3\xff\xf3\x6e\xf8\x7a\xbf\x57\x62\xf9\x1d\xa9\xc8\x1a\xea\xaa\xd8\x89\x27\xb3\xc0\x72\x21\xeb\x0f\x20\x73\x55\x75\x9a\x84\x43\xef\xa6\xb0\x1e\x4c\x3e\x88\x12\xd0\xfb\xe8\x10\x82\xc0\x94\xc6\xd0\x88\x38\xee\xdb\x3f\xb9\x7a\x09\x3f\x32\x83\x6d\xde\x7e\xa7\xcc\xe1\x0e\x34\xd8\x3b\x09\xa5\xe4\x02\x30\xf6\xbd\x26\xd2\x95\xb3\x99\xea\x6d\x40\x38\xfb\xf5\x57\x6d\x3e\xf5\x1c\x45\x3d\x51\xce\xba\xd5\x09\x46\x91\x47\x0d\x82\xdc\x3e\x13\xcb\xcf\x32\x8f\xef\xbd\xb7\x47\xda\xa8\x4f\x6d\xf2\xe0\x81\xe1\xc7\x19\x9d\x9b\x79\xb3\x86\xb3\xff\xeb\xae\xb5\x0d\x57\x35\xe8\xf1\x0c\x4d\x3a\x90\x58\xb2\x5d\x43\x1e\x77\x18\xed\xd9\x19\xac\x8a\x18\x58\xee\x69\x1a\x68\x4f\x1c\xde\x39\x42\x39\xa8\x42\x23\xd2\xf2\x48\xed\x55\x03\xe9\x51\xc5\xf3\x12\x9e\xa2\xf8\xd1\xda\xfb\xb2\x29\x08\x43\x49\xc3\xb9\x3e\x86\x63\xda\x90\x69\xd7\xaa\xa6\x52\x7a\xe2\xa4\xe2\xaf\xb2\xf2\x64\xaf\x8f\xeb\x37\x27\x14\xf4\x0a\x71\x95\xd9\xc7\x9a\x2a\xa5\xfd\x51\xfd\xf9\x44\x8b\x99\x54\x37\xeb\x4e\x9a\x7e\x2f\x6a\x55\xa9\x13\x47\xcd\xa1\x11\xa0\x55\xa5\x0d\xe6\x95\x73\x8b\x46\x93\xca\xf9\xcd\xdd\xcd\xa8\x5d\x5f\xbd\xa2\x46\x32\xbc\xbb\x98\x5b\xce\x7b\x2d\xb5\xb2\xe0\xac\x42\xdb\xa8\x78\xac\x39\x79\xae\xde\x8a\x77\xac\x74\x3a\xf7\xe3\xb8\x72\xba\x00\x48\x5c\xf4\xac\x4c\x60\x5c\x15\x5a\xd3\xc1\xd5\xa9\xcd\x78\x14\xe8\x2a\xd5\xca\xa8\xad\x8a\xdc\x94\x9b\x1c\xb0\xfd\x93\x93\x3e\xa5\x45\x2e\x8c\x57\xe2\x4b\x12\xd2\x45\x9c\x5e\xd2\x50\x9a\x08\xc2\xf3\xc1\xf1\x2c\x88\x12\xfb\xb9\x1a\xd4\xf6\x63\x9a\xc9\x1e\x79\x7c\x0f\xc8\x03\xab\x8f\x24\xe5\xba\xbc\x56\xaa\xc5\x35\xc3\x43\xee\xb1\xbc\xdc\xd0\xcf\xda\x4a\x5a\xc4\x06\x0f\xb2\x25\xa4\xb0\xd4\xe4\x0b\xf1\x9a\x21\x90\x8c\xa3\xe6\xfd\x11\x82\x94\xef\xc9\x87\x65\x90\x3f\x18\x90\xf3\x20\xe2\xea\x72\x10\xb9\x16\x85\x56\xc1\xca\x9b\x32\x73\xde\xc5\x52\x50\xf1\xa2\x75\xc7\x68\xd7\x74\xbc\xbc\x4e\xe1\x69\xb2\xd1\xbe\xbd\x2b\x41\x7f\x37\x36\x76\xcd\x63\xd3\x60\x40\xf2\x22\x5d\x70\x5d\x6d\x94\x4c\x49\x30\x61\x5d\xf9\x66\x93\xcf\x55\x4e\x3a\x45\x34\xa7\xe9\xb2\xe8\x3a\x47\x47\x8e\x80\x1f\xc8\x37\x9b\xde\xc3\x22\xef\x7d\x9f\xd5\xfe\xb3\xa8\x5c\x87\x54\xe8\x92\x2f\xd7\x9e\x33\x9d\x8d\x40\xfe\x60\xcf\x7b\x0e\x55\x33\xe2\x3d\x6d\xea\x93\x9f\xf6\x0b\xac\x18\x13\xdc\x97\x04\x7c\x65\x8c\x19\x61\x83\x8f\xe0\x11\x93\x98\x97\x49\x68\x63\xa0\xed\x3b\x7c\xd2\x18\x39\x14\xc1\x7f\x8e\x37\xe2\x1b\xb7\xca\x96\x1f\xae\x59\xf9\x13\x71\xb1\x66\x50\xcd\x94\x16\x1f\x75\x53\xef\x39\xa9\x69\x8e\x82\xba\xf1\x2a\xc8\x67\x98\xa8\x7a\x92\x30\xbb\xfe\x23\x7c\x34\xe9\x08\x00\x3f\xb5\x79\x0b\x79\x3b\x08\x11\x8c\x44\x5d\xfd\xb1\xb9\x00\xcd\x1e\x41\x98\x23\x7f\x77\xe4\x5f\x99\xf3\xf6\x27\xca\x79\x7b\xd9\x5f\x34\xe9\x98\x14\x77\x75\x45\xd6\xa1\xc5\xca\x62\x44\xb1\x6e\x0f\x6d\xe2\xbf\x9b\x2c\x01\xfc\xd7\x70\x39\xd8\x43\x4a\x43\x14\x21\x7a\xa7\x72\x66\xe4\xdf\x60\xa0\xee\xf9\xe2\x74\x8a\xa8\x16\x8e\x15\x92\x8d\xaf\xb7\xbb\x35\xcd\x13\x43\x54\x53\x1c\xb5\x64\xaa\x1b\x54\x36\x18\x10\xbe\x59\x49\x71\x21\x48\x42\x22\x6e\x46\x48\x30\x0d\xa2\x44\xac\x9c\x73\x2a\x02\xfc\xd5\xfc\xf9\x65\x4f\x7b\x03\xac\xa9\xc1\x96\x75\x9c\xed\xbf\x66\x48\x63\xee\x96\x4d\x5c\x0a\xb2\x2d\x81\xed\x8e\x39\x1d\xa7\x49\x48\x18\xc3\xad\xad\x04\x91\x6e\x3d\xb1\x12\x83\x23\x82\x2e\xac\x69\x87\xbd\x5e\x8c\xee\xb8\x43\xd8\x75\x3b\x12\x25\xc4\x89\x16\x71\xca\xbc\x48\x33\x1a\x2a\x37\xee\x5c\x02\x01\x8d\xcf\x34\xc8\x49\x30\x67\x1b\x52\xdf\xcb\xaf\xed\xbf\x52\xfe\x6d\xff\x79\xbc\xcb\xdf\x45\x17\xab\x7b\x78\x5d\x9a\x5b\xc6\x31\xdc\x12\x36\x24\xd2\x4e\x36\x3d\x50\xa0\x2b\x06\x49\xe8\x3f\x06\xec\x98\x7d\xa9\x7c\x69\x58\x52\x9c\x05\x56\x73\x68\xb0\x2b\xc5\x07\x06\x38\x55\x05\xa3\xc8\xb8\x5c\xe0\x2f\x8a\xa8\x3c\xbe\x43\x5a\x30\x8a\xc8\x1e\x83\x94\x72\xd6\x43\xae\x09\xad\x1f\x93\x3e\x21\x25\x24\x40\xa2\xa9\x28\x2e\x6b\x91\x63\x4b\xe8\xb9\x4a\x92\x63\x4a\x2e\xaf\x31\x31\x58\xba\x91\x2d\x69\x53\x10\xc4\xdd\x15\x8b\x6e\x57\x14\xb5\xe5\x60\x43\xb2\x10\xbe\x4e\xa4\xa2\x38\x74\x4a\xfb\x24\x65\x01\xa1\xa4\x65\x7d\xfc\x93\x49\xaa\x2d\x3d\xf1\x50\x68\xa0\x27\x82\xa1\xd4\x77\xfd\x42\x2a\xb6\xe8\x6f\x65\x0d\xec\x4f\xfd\xe0\xd2\xb5\x3a\x45\x62\xfa\xeb\x48\x3a\xe8\xa9\xd9\xc7\x1c\x6c\x30\xe0\xa1\x15\xb5\x95\x85\x51\xa9\xb6\x95\xf8\x72\xbd\xcb\x80\x25\x96\xd6\xcd\xb6\x05\x62\x50\xc5\x70\xc6\xcd\xe0\x2d\x0e\x10\x32\x7e\x94\x10\x47\x63\x0a\x57\x0d\xda\x5e\xc3\x8a\xfe\xe7\xb3\x1d\x01\xfb\x8f\x72\x8b\x11\xe2\x58\x8d\xe4\xfd\x45\xba\x30\x1c\xcc\x99\xdd\x8b\x83\xbc\x10\x90\x4e\xd5\xfe\xee\x70\x42\xea\xb0\x82\xe0\xbc\x68\x5d\xbd\x38\x81\x38\xb4\x90\x6e\xf7\x49\xa3\xb0\xa6\x4b\xac\x21\x01\xdc\xe7\x41\x49\x7e\x20\x9b\x76\x6d\x62\xa6\x25\xed\xef\xcb\xb5\x5c\xaf\x05\x90\x7f\xb7\x52\x09\x22\x34\x59\xcc\x52\xaa\xd3\x94\xa9\x1d\x1e\xd6\xba\xd9\xe5\xfe\x22\xb8\x0c\x46\x31\xf5\x75\xcf\x3d\x0e\x70\xfb\xa9\x9c\x26\xa1\x0e\x48\x95\xa4\xc9\x23\x51\x09\x46\x87\xbd\x4d\x5c\x97\x4d\x3d\xf8\xf6\x63\x9c\xd1\xaf\x82\xed\xc8\xa5\xd2\x83\x11\xa3\x5a\xe5\x04\x81\xed\xdb\xc6\x1e\xaf\x68\xd7\x9c\xc4\xd2\x1b\x41\x7c\xa2\x35\x74\x00\x52\xee\x83\x58\x08\xa6\x96\x20\xa4\xe4\x3c\xc8\x95\x40\xb9\x66\xe2\x8a\x2f\x6d\xb8\x7a\x45\x47\x18\x6d\x98\x65\xdd\xbf\xce\x82\x7c\xe6\x43\x3a\xeb\x35\xcd\xb2\xb2\x9b\x48\x7c\xe5\xe8\xbb\x57\xac\x92\x78\x98\x38\x1a\x86\xfc\xda\x0b\x71\x5d\xd6\x13\x7f\x5b\x25\xc7\x2e\xb2\x07\x65\x4a\x84\xaf\x52\x09\x71\x12\x65\x79\x51\x2e\x20\xae\x28\xe3\x95\x68\x40\x7c\x6a\x0f\xdf\xf5\xab\xf1\x55\xe7\xf8\x12\x02\x6d\xf2\x81\xd7\xcd\xb3\xd5\x58\x53\x94\xd7\xa2\x7a\x95\xa1\xfb\x79\x9a\xd2\xc9\x73\x20\xa1\x2b\x13\xd8\x95\x9b\x20\x3b\xdf\xbe\xe0\x76\xa5\x90\x24\x3e\x0d\x03\xb4\x1b\x0b\x5e\xb6\xd6\xac\x4e\x3b\xeb\xd9\xd4\x45\x4d\xd7\xa6\x0c\x34\x51\xf5\x0f\xd6\x06\x03\x6b\x07\x36\x2e\x70\xb4\xcb\x63\xa4\xbe\xb4\x2a\xef\xf0\x7d\x79\x30\x30\x7c\xe9\x96\x86\x9d\x1e\x8f\xc1\x2d\x6e\xca\xe3\x34\x45\xc9\xb4\x42\x36\x33\xd5\xd8\xe6\xc8\xf9\x24\x5e\xbb\x9c\x08\x8b\x43\x55\xa2\x10\xf9\x82\xa4\xae\xa6\x12\xd1\x84\x24\xa9\xae\x81\xb1\xb7\x45\x90\xe7\x34\xec\xb1\x2a\xb4\xeb\x3b\x06\x91\xa3\x25\x6d\xf2\x32\x45\x78\x30\x03\x16\x3a\x0d\x73\x48\x9f\xef\x54\xd3\x66\x95\xac\x2c\x43\x69\x4b\x79\xad\xad\x2c\x66\xc8\xb5\x24\xc4\xaa\x81\x08\x61\xd2\xa8\x40\x75\xa9\x27\x0b\x8c\xe8\x38\x58\xe6\x94\x9d\xc4\xc3\x34\x69\x17\xe4\x3c\x48\xc0\x28\x29\x5f\xa4\x51\xcc\xaf\xc3\x93\x82\x66\x93\x60\xac\xbc\x63\x37\x38\x8a\x37\x39\x6e\xdb\xfb\x54\x3d\x43\x24\x8e\x7f\x5d\xb5\xa8\xd1\xe2\xfc\x89\x16\xdc\x5d\x33\xdb\x20\x7b\xe4\x7c\x16\x8d\x67\x60\x35\xc0\xd6\x77\x91\x8a\x7d\x8c\x2c\xe2\x65\x5e\x7f\xf7\x2a\x18\x41\xcd\x04\x6b\xee\xe1\xb7\x64\xaa\x91\x61\x57\x17\x54\x55\xb1\x7a\x01\xf2\x36\xc2\x63\xb9\xe0\x88\xac\x95\x6f\x24\xc8\x54\x09\x31\xe6\x53\x87\x3e\xb7\x48\x6f\xce\x7d\x3d\xc7\x1e\xef\x79\xb7\xc1\xfd\x79\x19\x6f\x72\x4e\xc3\xde\x63\x70\xc9\x53\x16\xdf\x81\xd8\xdd\xfe\xb4\x61\x38\xc7\x9f\xfb\x7a\x85\x78\x4e\xd3\x5e\xbb\x25\x8b\x6e\x77\x95\xfd\xb3\x69\x2c\xd1\x1a\x7e\x5b\x66\x02\xad\x4c\x1a\x5a\xc3\xed\x1d\xd7\x26\x5a\x8c\xbc\x35\xdc\xd9\xba\x3e\xed\x6d\x3f\xb9\xb7\x7d\xba\xb7\x7d\xfa\x6b\xdb\x3e\x21\x63\x67\x61\x03\x79\x07\xd6\xce\x25\x7e\x2c\x85\x75\x25\x7f\x98\x75\x34\x91\x97\xce\xfb\xd9\x34\x1f\x96\xa8\x6e\x90\x90\x27\x8e\xb0\xa2\x12\x1c\xfb\x4e\x6e\x27\x8c\x7d\xca\x4a\x09\xb6\x71\x02\x3e\xdf\xf3\xf5\xe1\xfd\xbb\x03\xce\xdc\x6f\xd3\x01\x1e\x70\x09\x58\x2d\x85\x17\x8c\x45\x4a\xde\xbf\x3b\x10\x17\x05\xfe\x0e\x88\xf7\xe8\xe0\x45\x51\xb7\x3c\x4b\x73\x7c\xfd\xe5\x36\x7e\x70\xf4\xf6\xed\xcb\x83\x8f\x87\x47\x6f\xc9\xcb\xf7\xef\x8f\xde\x0f\xc9\x81\xd2\xff\x8e\x79\x95\xfc\x48\x1f\x52\xd2\xde\x20\xac\x3e\xb2\xd1\xee\xfb\xfb\xa0\x5d\xde\x34\x1d\xbb\x7a\x68\xcf\xb5\x08\x05\x5b\x3d\x11\xaf\xcc\xdf\x84\xb4\xa4\x1d\x12\xdb\x2a\x18\x0d\x13\xde\xa5\xd1\x3c\x0f\xa6\x94\xec\x91\xf5\x75\xf1\xd4\x90\x6d\xeb\xe2\x77\x9f\x87\x8c\x75\x52\xfa\xb2\xd8\x33\xe2\x4d\x1e\x12\x35\x5d\x7f\xff\x70\xf4\x16\x66\x25\x53\x5d\xf2\x84\x59\x15\x7d\x73\x1e\x93\x69\x1c\x88\xaa\xcd\xd1\xea\xd9\xfc\xc8\xef\xab\xf1\x78\xe7\x79\xd3\x29\xfd\x78\xf8\xe6\xe5\xd1\xf1\xc7\x21\x11\xb7\xde\x8c\xb8\x58\x27\xe7\x39\xd9\x20\x6d\xf6\x5f\x30\x9e\x31\x8e\xd1\x36\x62\xda\x08\x3f\x92\xdf\xde\xef\x56\xf7\xbb\xd5\x5f\x7b\xb7\x42\x9b\x15\x3c\xbb\xfc\xa3\x9a\xe9\x36\x7f\xcd\xde\xe8\x11\xfd\x1d\xbe\x65\x97\x4e\x87\xd8\xfa\x57\x87\x33\x1c\x93\x29\x37\x8e\x21\xe2\x91\x2d\xb4\xa5\x0f\x0b\xb6\x15\xf2\xd7\x7e\x08\xbf\x90\xb6\xbc\x48\x93\x8e\xf3\x79\xec\x0a\x52\xf1\x1e\x39\x4f\x93\x6e\xcd\x1b\x7a\x94\x99\xa4\xc9\xe5\x3c\x5d\xaa\x16\x55\x42\xc9\xe9\x4d\x22\x6d\x4a\x25\xae\x68\xc8\xe5\x01\x88\x62\xe0\x84\x6b\x12\x69\xea\x78\xf6\x3c\x4d\xe3\x6b\x08\xaf\x1a\x82\x0f\x72\xbe\x49\x50\x0e\x19\xa2\xd9\x81\x07\x22\x34\x34\x3c\xa6\xcb\x13\x1f\x44\x23\x60\x8b\x52\xd4\x3e\x58\x33\xa6\x09\xbb\xdf\x62\x10\xa6\xe7\x28\x5e\xaf\x1d\x81\x01\x21\xdf\xbd\x13\x89\x3c\xa2\x42\xd4\x17\x35\xc1\x05\x87\xf8\x5d\x62\xef\xea\x2f\xaf\x0d\x96\x4b\xaf\x88\x31\xb6\x39\x7d\x86\xdc\x07\x38\xb8\x31\xb2\x70\x1d\x6a\xf7\xe0\xde\x70\x41\xde\x0a\xca\x51\x87\xaa\xab\xf2\x12\xc4\x29\xd1\xf5\x50\xde\xd1\xf4\xda\x7c\x74\xb0\x42\x3d\x43\x2b\x84\x43\xf3\x8a\x71\xe1\xa2\xd5\xf4\xb0\xd2\x88\xa4\x2b\xf5\x1b\x0d\x27\x8f\xa6\x49\x50\x2c\x33\x7b\x38\x38\xbd\x6c\x3c\x18\xa6\x7c\x3c\x0a\xaa\x6a\x40\xe0\xc1\xa0\x79\xff\xc5\x13\x07\x49\xde\x82\x23\x05\x49\xa8\x54\x4b\x45\x0a\x41\x89\x27\x51\x12\xc4\x7e\xb3\x67\x5e\x87\xcf\xa8\x14\xaf\x6b\x2b\x4b\x54\x6f\x20\x45\xe6\xd1\x33\x9a\x5d\x16\x33\xae\xb2\x9e\x8f\x22\x60\x19\x29\x8f\x12\x0d\x7d\x13\x71\x16\x2a\xb1\xe5\xf1\x0d\x22\xba\xe3\xb8\xb6\x53\x8b\x5b\xfd\x42\xaf\x00\xef\x3d\x88\x68\x7f\x1d\xca\x41\x47\x9d\x6b\x11\xa9\xd7\x5c\xb7\x76\x1e\xb7\x9f\xa2\x72\xfe\xb2\x55\x38\x17\xe4\x8e\x3a\x25\xb5\x77\xba\xae\x4a\x53\xcc\xd3\x47\xd9\xb1\xdb\xb2\x74\x14\xc3\xa2\x92\x9f\x83\xe7\x65\x11\x4c\x5b\x94\x3f\x89\x20\xc6\x94\x65\x0d\x20\x80\xf0\xfc\x31\xba\xd1\xc9\xc9\x32\x8e\x4b\x9e\xb8\x68\xcd\x22\x71\x6f\xff\x4d\x85\x30\xd4\x57\x16\x9a\x11\x32\xad\xd1\x9c\x55\x5c\xf7\x0b\xec\x3b\x8f\x63\x3a\x7c\xfb\xea\x91\x33\xfb\xea\xbc\x6b\x07\xd7\x5b\xa9\x36\xe8\x7b\x0d\xc5\x99\x44\x32\x4e\x93\x71\x50\x74\x8c\xd9\xef\x96\x3b\xb2\x29\xe5\x7a\xc2\x8b\x4d\x39\xd7\xb3\x77\x5b\x5a\xc6\xe1\x42\x7e\xf7\xe0\xf2\x30\xc1\x15\x84\xe5\x10\x9c\x10\x78\x2d\xa1\x6a\xf6\xc1\x03\xd0\x37\x98\xbd\xa8\xde\xa6\xcb\xbd\xef\x00\x0e\xee\xd0\xfd\x4e\x90\x4d\xad\xd5\xa5\xc5\xc7\x67\x46\xc9\x21\xfe\x12\xae\x79\xb6\x90\x2b\x14\x31\x3e\x71\xff\xa2\xea\xb5\x9f\x6a\xf1\xc9\x24\x5f\x94\x94\x86\xeb\xdb\xee\xee\xb2\x95\xf9\x4b\x1a\x25\x9d\x56\xcb\xad\x5c\xbd\x8a\xe3\xe4\xc6\xf1\x84\xaf\x37\x40\x36\xec\xb0\x65\xde\xed\xe1\x1e\xe1\xab\x9a\x24\x2d\x0e\x8d\xbe\x2a\x14\x7a\x1c\x0e\x69\xe0\x86\x6d\xc3\xb3\x85\x6e\xcf\x6a\x05\xb7\xaf\x36\x12\xc4\xb5\xd3\x65\xb1\x58\x16\xaf\xd3\xa9\x66\xd7\xc2\x19\x0f\x5a\x2d\xd2\xfb\x0f\x77\x34\x83\xc4\x32\x13\x4c\x73\x6b\x18\x93\xed\x07\x8a\xc3\xf0\x5b\x2e\x83\x9f\x66\x34\x5c\x8e\x29\x9a\xab\x60\x3c\xee\x11\xe1\x8b\x12\xf3\x93\x60\x3c\x3e\x11\xc9\x9c\x27\x32\xa4\x88\x6f\x49\xe5\xcf\xcc\x29\xeb\xe7\xb3\x68\x52\x74\xba\x64\xe8\x60\x54\x66\x39\x4a\xab\x60\x3c\x96\x5a\x2a\x6e\xed\xcd\x49\x9b\xc6\xb4\xa0\x72\x1c\xda\x4b\x92\x99\xce\xa9\xea\x06\x2c\x03\xdd\x5f\x89\x87\x25\x62\x69\xb3\xad\x9e\x8b\x71\xa5\x9e\x15\xee\x4a\x2e\x32\x1a\xae\x16\x7e\x3c\x9e\x1b\x6c\xe9\xe7\x8f\xee\x92\x69\xbb\xde\x25\x53\x55\xf1\xad\x72\x23\x3b\xb3\x02\x62\x48\x80\x86\xf3\x07\x5b\xec\xb0\xfd\x3e\x39\x02\xe5\x1f\xca\x01\x54\x29\x2d\x63\xdb\xff\x06\xaf\x1a\xad\x67\x6d\xde\x27\x8d\x95\xd4\xf8\xb5\xbc\x4d\x31\x50\xf3\xe4\x5a\xc6\x01\xa5\x81\x21\xb4\x74\x82\x00\x4e\x0d\xea\xf5\x01\x60\x07\x56\x9a\x28\xbc\xa0\x27\x8a\xdd\xf3\xb6\x4f\x4b\x07\x60\x58\x4d\x78\xef\x84\x0d\x5c\x22\x97\x58\x55\x57\xc2\x75\x8e\xb2\x6e\xe8\x1b\xeb\x69\x13\x05\xfc\x6d\x9d\x5d\x0e\xfc\xba\xc9\x37\x9c\x06\x3d\xfa\xbf\xea\x48\x22\x38\x88\xc8\xda\x60\x40\x3e\x1e\xbd\x38\x1a\x92\x8c\x72\x8b\xac\x1e\xc9\x53\x61\x3a\xa3\xae\xb8\xb4\x31\x4e\xc0\x35\x5d\x7d\x56\x2e\x2a\xda\x39\x49\xe8\x98\xe6\x79\x90\x5d\xb2\xc5\x02\x21\xb0\x73\x46\x6e\x6d\x70\x58\x0c\xee\xa2\xc9\x79\x9a\x7d\xe6\x52\xde\x7c\x19\x17\xd1\x22\x46\xa1\x1c\xcc\xe0\x29\x7e\xff\x46\x83\x87\xc4\x6b\xcc\xfd\x8d\xb4\xe5\xe6\x75\x98\x66\x0c\xb2\x79\xc3\x88\x54\x37\x46\x43\xbe\x71\x98\x27\x13\x55\xaa\x2f\x71\xe4\xf3\x60\xb3\xce\x3a\x77\xe2\xc2\x9e\xfa\xce\x0f\x65\xb0\x16\x3b\x25\x8e\x81\xa3\xd9\x4f\xe1\xd0\xc9\x57\x53\x8d\x1d\xa4\xb7\x9e\xd2\x23\x94\xae\x5f\x10\xbc\x3d\x26\x07\xc0\x73\xe4\xe6\x39\x3e\x6c\xf0\x1c\xc5\xf4\x84\x49\x8f\xd9\x45\x8f\xe9\xa7\x28\x96\xd3\xc2\x0a\x15\xe3\x73\x72\x55\x79\x10\xab\x9e\xee\x88\x56\x8c\x57\xc3\x78\x86\x5c\x46\x2f\x44\x47\x39\xb9\x5c\x79\xd8\xaa\xe0\x1d\x0c\x9c\x20\xc3\x51\x7a\xd1\x37\xd8\x91\xfe\xd8\x25\x12\x40\x72\x21\xf8\x7f\x57\xa6\x2a\x96\xc3\x7f\xa8\x74\xc4\x68\xe4\x4f\x53\x8e\xa4\x17\xe2\x7d\xb7\xcb\xcd\x39\x1a\xb4\x6b\xa2\x12\xfe\x5c\xc2\x91\x5b\xc3\x1d\x70\x61\x84\xbd\x86\x33\xc6\xfc\xdd\xfd\xcd\xe8\xfd\xcd\xe8\x5f\xfb\x66\x54\x5c\x8b\x8a\x37\xbf\xff\x15\x01\xf6\xee\xd4\x65\x38\x1c\x02\x1e\x92\x83\x34\x39\xa3\x8c\x15\x05\x22\xe6\x31\x9c\x83\xe1\x2c\x00\x81\x8b\x65\x24\x17\x46\xc0\x41\x9c\xa7\x24\x88\xe3\xf4\x3c\xe7\xf1\xd9\x41\x51\x97\xf7\xd7\x58\x45\x52\xf0\x7f\x13\x5d\xd0\xf0\x9a\x67\xad\xb9\xf7\x1a\x6b\xe2\x46\xb5\x48\xed\x28\xc7\x42\x65\xa9\x0e\x9c\x1d\x53\x25\x4a\xae\xae\x64\x84\x74\x9d\xd1\x56\x3a\xd4\x76\xd7\x56\x06\xf0\xb3\x9c\x10\x91\xb8\x62\x96\xf7\xa1\x23\xf5\x8b\x46\x43\x5c\x0f\x71\x34\x01\x55\x73\x17\x6a\xdf\x74\xea\x04\x48\xc1\xf7\xf1\x93\x56\xe3\xce\x48\x46\x51\x52\xed\xc0\x91\x8b\x89\x9a\x8c\xd3\xca\xcb\x1f\xdb\x12\x36\x55\xfa\x7d\x71\xd8\xea\xb1\x49\x38\xa3\x59\x34\x01\xc7\x1e\x19\x1d\x07\x8c\xe3\xa0\x48\x35\x0f\x1e\x90\x38\xf8\xf5\x92\xc4\x69\x10\x92\xf0\x32\x09\xe6\xd1\x98\xa4\x09\xcd\xa1\x35\x31\x21\xba\x21\x11\xcd\x3a\x55\x7a\x02\x80\x92\x06\xf6\xb2\x71\x07\x8a\xcd\xd6\x94\x16\x47\xea\x90\xec\x71\xe1\xcc\x26\x46\x0b\xac\x75\xfe\x01\xb0\x32\x41\x4c\x89\x3c\x26\x97\xdf\x7a\x18\x9a\xfe\xd2\xab\x17\x9e\x9d\x9f\x47\x10\xb0\x04\xf5\x8a\x80\x0e\x22\xa7\xfc\x04\x3d\x74\x9e\x56\x71\xe1\x7d\x99\x51\xa1\x5e\xec\xc1\x05\xde\x98\xaf\x0e\x7e\x38\x9e\xd1\x0b\x9f\xda\x40\x6b\x4d\xad\x04\xcb\x15\x65\x83\x22\x86\xe6\x53\xc4\xd5\x2e\x55\xca\x5b\x0a\x7f\x19\x85\xfb\x99\x88\x4f\xce\xaa\x12\x8b\xac\x4b\x86\x72\xbd\x09\x30\x57\x56\xf2\x5d\x13\x78\xde\xd7\x41\x37\x87\x56\xb7\x7b\x0e\x1c\x5b\x02\x1a\x8a\x7d\xb9\x30\x45\x8a\xeb\x71\xf3\x03\x19\x96\x59\x02\x05\x38\x28\xb3\xdd\x1a\xdc\x5f\x0d\x57\xba\xd6\xea\xab\x72\x5d\x5f\xef\x6e\x52\xa3\x28\x65\xea\xa7\xd0\x41\x87\x53\x60\x3e\x63\x14\xe8\x41\xb8\x45\xea\x52\x55\xb3\x1f\x86\xfc\x59\x84\x52\xa2\x05\x49\x48\x72\x5a\xe4\x64\xb9\x80\x0c\x71\x1a\x01\x96\x11\x15\x34\x63\x7b\x47\x7a\x26\x84\x2d\xe1\xc7\xb4\xbf\xb6\x86\x9e\x46\xbc\x4e\xa7\xf9\x7e\xf1\xa1\x08\xb2\x62\xcd\xd6\x34\xe6\x34\x9e\xa8\xc4\x89\xfb\x80\x59\xb0\x70\xb3\x16\x23\x50\x18\x8d\x27\x8e\x13\x1f\xf9\xca\x6e\x4a\x0b\xae\xcf\x62\x85\xad\xa7\x76\xa0\x5f\xd0\xc3\xcc\xa1\x7b\x44\x9e\x3c\x2d\x9e\xc1\x5a\xe9\xfb\x18\x07\x64\x4c\x69\xd1\xb1\x1e\xfd\x08\x4b\x46\xe7\x94\x33\x18\x88\x17\x34\xf0\x4c\x94\xf5\x51\xa0\x0d\xcc\x26\xe1\xa2\x5b\x26\x4a\xb3\x23\x70\x85\xd1\xef\xf7\xc9\x2f\x4b\xee\x09\x98\xb5\xc9\x78\xaf\x73\x5e\x2e\x79\x19\x59\xf1\x2a\xf2\xda\x7e\x02\x6b\xad\x74\x35\x0c\xff\x19\x93\x67\x7a\x0f\xa6\xdc\x90\xb3\xee\x9d\x26\x7f\xbc\x63\x9a\x7d\x1a\xfd\xab\x77\xc4\xfa\xf5\x48\x77\x91\xc6\x31\x27\x1f\x3f\xd9\x0a\xda\xd4\x60\x36\x5d\x2a\x95\x08\xa8\x6d\x93\x37\xca\x0c\xd7\x20\x96\xb4\x84\x5c\xc4\x8c\xa6\xce\x9c\x4a\x23\x0b\x46\x7a\x72\xac\xbe\x49\xf0\x3d\x9b\xf2\xd1\x44\xda\xf8\x24\xdf\x94\x3a\x6e\x46\x19\xda\x4c\x19\x86\xa6\x95\xd7\xcf\xac\x04\x5d\xc9\x50\x16\x72\x49\xe7\x56\xe8\xb9\x1d\x91\x96\xea\x03\xa0\x4f\xb6\x37\x6a\xc6\x78\xde\xa5\x71\xcc\xf8\x8c\xee\x09\xa7\xc1\x21\x2f\xc2\xce\x69\x74\x4e\x93\x02\x8e\x9c\x7d\x46\x71\x30\x34\xbd\x97\x2c\x84\xa1\xfd\x09\xc7\x14\x90\xe3\x61\x78\xda\x93\x57\x54\x46\x72\x4f\x13\xa3\xc8\xc1\x7e\x8c\xb8\x82\x18\xe8\x97\x6d\xd6\x32\x6c\xa1\x43\xe2\x96\x4c\xd6\x23\x4e\x7c\x0f\xb9\xdc\x3c\xb7\x03\x3d\x71\x9a\x3a\xc8\x28\x8c\x09\xec\xb5\x0f\x3c\x2f\x1d\x81\xd9\x71\x0d\x36\xba\x70\x35\xf0\x81\x34\x7c\xab\xa8\xca\x4a\x75\x5d\xa5\xca\x1e\xbf\x52\xcd\xec\x0c\xb2\x25\x20\xa5\x2e\xe3\x4b\xad\x31\xb5\xb0\xa9\xc5\x60\x4b\xf4\x45\xd0\x0e\x1a\xcc\x04\x04\x29\x67\xde\x7d\x32\xa6\x56\x88\xb0\xac\x51\x19\x62\xcb\x3d\x28\xcb\xd7\x6c\xcf\xc9\xc2\xd7\x4e\xea\x77\x69\xbf\xfb\x09\x3d\x17\xb7\x4e\x18\x07\xd8\x59\x18\x67\x92\x51\x68\xf8\xc6\xf3\x33\xc7\x9a\x65\xdf\x19\x8f\x3c\x62\xee\x78\x54\xcb\x07\x89\xe0\xc8\xe2\x5c\x58\x41\xbd\x96\x47\x52\x97\xbd\x54\x94\xf5\x77\xa3\x5a\xef\x6c\x2c\x6d\x46\x04\xa1\xeb\x08\x10\xfb\x6a\xc8\x28\x5c\x32\xb0\x33\xc7\x82\x26\x21\x18\xb8\xa9\x49\x0e\x72\x50\xb4\x24\x39\xa3\x50\xe5\x0c\x46\x57\x94\x4e\x00\x98\x15\x62\x52\x4f\x97\x2b\x57\x54\xeb\xcb\x24\xc8\xf3\x68\x9a\xd0\xb0\xef\xf6\xd1\xa6\x28\x1f\x4f\xf6\xcd\x8e\x92\xb1\xc6\xa3\x9a\x09\xf2\x36\x83\x4d\xc6\xd0\x48\xb4\x3d\x31\x89\xb1\x74\x18\xc4\x19\x0d\xc2\x4b\xfd\x60\x5d\x0b\x8a\xf9\xed\x29\xcd\x14\x64\xa5\xf4\x5a\x37\xae\x68\xd2\xb1\x5a\x53\x4e\xe0\x36\x5d\x97\x5c\x7a\x65\x72\x2e\xee\xf3\x0b\xc9\xa4\xe8\x22\x15\x63\x8b\xe6\x73\x1a\x46\x41\x41\xe3\x4b\xbb\x59\x41\xee\xe3\xa6\xb4\x6d\x4a\x27\x50\x7d\xa7\xc4\xd5\x84\xcf\x6d\x15\xd6\x64\x73\x96\xcf\xb6\x1f\x3e\x18\x74\x97\x7b\xee\x84\xe9\xb0\x37\x73\x93\xb7\x71\xc3\x3e\xd4\x0f\xa9\x8e\x31\x98\x23\x1e\x8d\x35\x4f\xe2\xba\xd4\x1d\x08\xc2\x35\xba\x13\xbe\x6e\x3a\x10\xbc\xef\xd6\x8f\xc7\x91\x1c\xd2\x85\x14\x1c\xcc\x81\xd4\xf0\x77\x78\x5a\x3e\x4f\xcf\xa4\x4a\x93\x04\xf9\x65\x32\x56\x87\x1f\x9f\x60\xe4\xe3\xdb\xcb\x04\xde\x4e\x1b\x08\x40\x32\x86\x85\x2d\x87\x77\x61\x43\xf8\x55\x6a\x36\x04\x7f\x07\xa3\x53\x2b\x66\xbb\xcf\x7b\x82\x23\x53\x78\x4d\x4e\x54\x49\x5b\x28\xb7\x76\xd4\x12\x3b\xca\xc1\x80\x1c\x4e\x34\x67\x8c\x72\xf5\xae\xef\x92\x0a\xff\x2b\x24\x2a\x88\x76\xd3\xa5\xcb\x9d\xcf\x28\x18\x63\x88\xd1\x77\x09\x67\xaa\x39\x89\x0a\x93\xad\x7a\x37\x6a\x87\xd8\xd5\x32\xf3\xed\x1e\x3e\xf4\x8b\x1a\xed\x09\xc5\xfb\x31\x84\x48\xf1\xf0\xb7\xaf\xe8\xa0\xc7\x92\xc7\x33\x6a\x5b\xef\xc5\xe9\xb4\xac\x5d\x62\x31\xa6\x8a\xb3\x05\xd4\x32\x64\x7b\x42\x89\x3f\x3e\x7f\xc4\x12\x13\xc4\x39\x00\xd8\x03\x6b\x4e\x47\x8e\x9f\x29\x21\x88\x1f\xbe\xe0\x09\x43\x41\x63\x9d\x6e\x9f\xef\xc8\xe3\x40\x7a\x2c\x04\xbf\x2a\x34\x24\x6c\x75\xcf\xb2\x34\x49\x97\xb9\x72\x5f\x28\x0c\x03\xd8\x6e\x6f\xbb\x22\xe2\xd5\x08\x61\xb7\xed\x35\xaf\x05\xa7\x12\xa9\xb6\xd2\x6b\x42\x40\xae\x0d\x1d\xab\xa1\x7e\x0e\x6f\x31\x6f\xd7\x35\xfc\xd8\xb9\x22\xe5\xb8\x75\x82\xbf\x55\x5c\x90\x5e\x9f\xf6\x76\x36\x9b\x5c\x81\xb6\x97\x39\xd7\x8b\x8f\x8b\xf6\xda\xfd\x85\xe8\xfd\x85\xe8\x9f\xf8\x42\x54\x3f\x15\x45\x2a\xeb\x9b\xbc\x17\x15\xc0\x2b\xdc\x64\xfa\x82\xbf\x35\x7e\x62\x9a\x4c\xa2\xa9\x17\x8e\x67\x49\xc0\xc3\x51\x60\x05\x75\x89\x46\x41\xe2\x09\xd4\x02\xda\x64\x1e\x69\x8a\xdb\x48\xf3\xcb\xcc\x51\x34\x15\x1e\x0c\x2c\x2b\x46\x0e\xf4\x3c\x9a\x5a\x4a\x7d\x6c\xcd\xc8\x35\xce\x57\x1c\xe2\x4a\xc1\x5e\x9b\x5e\xab\x74\x3a\xb6\xc4\x05\x3d\x63\x49\x1b\x86\x54\xc4\x7b\xe7\x7d\x86\x56\xa4\xaa\xac\x04\xdb\x55\x4a\xa0\x28\x7f\x97\x51\x71\x0d\x8a\x6e\x27\x8c\xba\x47\x3a\xdd\x6a\x60\x84\x4b\xb0\x83\x84\x70\x7f\x4f\xae\xae\xdc\x3c\x71\x36\xf5\x67\xd2\x20\x8b\x23\x56\x14\x75\x2d\x59\x2c\x8b\x17\x74\x12\x2c\x63\xef\xc5\x49\x5d\x1f\xd9\x8e\x6c\xb7\xa3\xae\x7c\xbd\xe1\x5b\x18\xc9\xf4\x43\xd4\xa2\xc7\xf7\x54\xf9\x3d\x0e\xee\x82\x35\x8a\xdf\xa2\xfb\xf6\x8b\x2e\x2e\xa0\xb0\x5a\x4a\xe6\xd8\x68\xd4\x53\x21\xca\xf6\xe0\x41\xd2\xd6\x2b\x7a\xe1\x19\xb9\x58\x55\x7c\xb0\x39\x32\x8a\x4c\x27\x24\x30\x7c\x03\x82\xe3\x49\x65\x47\xa0\xec\x02\xd8\xba\x7b\xf5\xf2\x9f\xd6\x72\x83\x3a\x98\x5c\xec\x5d\x68\x52\x97\x6f\xf8\xd8\x75\x0c\xdf\xe5\x15\xb9\xd4\xf6\xbb\x75\x7a\x23\x7f\x7f\x31\x2e\x8f\xe1\xfa\x0f\x5d\xc1\xc2\xe7\xd5\x95\x45\x43\xfb\x63\x88\xbb\x80\x1c\x9f\x61\x78\x8f\xc7\x2d\x59\x2d\xf4\x49\xb8\xa1\xf2\x5f\x3d\x9a\x72\x10\xae\xba\x48\x45\xc0\xe8\xa8\x20\xf3\x68\x3a\xe3\x82\xa3\xf2\x5e\x2c\x94\x54\x4e\xcb\x45\x5a\xdb\x6e\x91\x9a\xad\x9e\xb4\xe7\xc1\xc5\x8f\x94\xbe\xa3\xd9\x4f\x41\xde\xee\x11\xf6\xfd\x2e\x8b\xd2\x2c\x2a\x2e\x8d\xf4\x69\x90\xbf\xcb\xa2\x31\x15\xbf\xd9\x7f\x30\xcd\xec\x47\x92\x26\x63\xea\x7b\xc5\xf8\x99\x5e\x56\xbc\x63\xfc\x4c\x2f\x9b\xbe\x64\x84\x9a\x1c\x5c\xf3\x1a\xf6\x90\xdd\xc5\x0b\x3a\x8e\xe6\x41\xdc\xc1\x00\xee\x4b\x32\xf3\xb2\xf5\x6b\x13\x3b\xf2\xb9\x79\xd7\x34\xef\xab\xfa\xee\x49\xff\xa6\xd4\x7d\x4f\xd7\x7f\x44\xba\x16\x42\x91\x43\xd8\x70\xff\x2a\x83\x09\x09\xaa\xf6\x8a\x4a\x8d\xe9\xf9\xc2\x14\x8f\x44\xfa\x9a\x21\x13\xd5\x52\x70\x71\xd1\xfd\xa2\x34\x83\x17\x7d\xbc\x9d\xae\xcb\xd3\xb9\xd6\x88\x99\x00\xca\x43\x46\x2a\xf1\x67\x02\xa8\x37\x20\x2c\x1d\xe1\x02\x5e\x9b\xf9\xab\x77\xa0\xbc\x6d\xd8\x50\x52\xf9\x77\xd1\x07\x92\xf2\x17\x82\x2c\x0d\x39\x0d\x72\x3f\xdc\x34\xc8\x0d\x28\x20\x5f\x04\xaa\x45\x45\x94\x6f\x0c\x15\xaf\x0d\x93\x50\x35\x55\xdb\x60\x25\xf5\x63\x18\xc3\xcf\xa7\x6a\xc9\x59\x75\xd5\x2d\xba\xe0\xe5\x2d\x3b\xb0\x46\x0f\x8a\x8b\xbe\x34\xfc\xf3\x56\x80\x9f\x19\x4b\x2d\xc4\xc5\xca\xcb\x46\x86\xe8\xb9\xc9\xf2\x11\xd1\x82\x2a\x57\x91\x0a\x5e\xb5\xca\x52\xb2\x2b\xb6\x5c\xd6\xe0\xa8\x43\x3a\xca\x50\xcd\xda\xf2\x41\xb9\xf4\xe9\x81\xd2\xa4\x27\x33\x1b\x2c\xb5\x52\xd0\xf2\x26\x4b\x16\x9d\x0a\x86\xb3\x9c\x2f\xe3\xa0\x88\xce\xe8\x4f\x41\x7e\x9c\xc3\x9b\xbe\xb2\xaa\x1c\x58\xab\xae\x69\x6d\x0d\x53\xa3\x1c\x1a\x3b\x9d\x4c\xe8\x58\xd4\xcc\x57\x6e\xc9\x72\x28\x2f\xe0\xa3\xe7\x52\x68\x7b\x51\x9a\xd6\x22\xb2\x58\x9c\x4e\x6d\xe3\x4b\x9d\x81\x22\x0a\x39\xda\x41\x50\xf1\x79\x75\x83\x9e\x07\xca\x0c\xb6\x4e\x11\x28\x5a\x6a\xb4\x0e\x81\xc8\x9a\xaf\x3c\x38\x38\x55\x2e\x36\xa8\xb0\xc1\x52\x33\x6b\xc2\x26\x46\x50\x83\xf6\xd9\x4d\x94\x73\x26\xf0\x52\x28\xf4\x0f\xf8\x68\xd8\x1f\x05\x39\xad\xe5\x8d\x3e\x50\x1f\x19\x78\xe0\x0c\x02\xe0\xf9\xd3\x20\x7f\x1d\xcd\xa3\xc2\x43\xbf\x26\x80\x28\xab\x12\x4b\x88\xde\xc8\x37\xca\xe4\xd1\xaf\xbe\xdd\x4e\x67\x1a\xd0\x45\x34\xa7\x79\x11\xcc\x17\xa5\x45\x14\x84\x5e\x58\x3c\x23\x29\x63\x5b\x46\x76\x59\xb5\x4a\xa7\x82\x3a\x13\x46\x93\x49\x34\x5e\xc6\xf0\xae\xa7\x0c\xd3\x1a\xc8\x1c\x48\x5a\x04\xf1\x8b\x26\x15\x58\x90\x58\x6a\x36\x57\xaa\x00\xd7\x3c\xce\x5c\xaf\x6e\xb6\x2b\x6b\x46\x05\x9d\x77\xed\x17\x7d\x8e\x59\x25\x40\xb9\x17\xd8\xc6\xaa\xf6\x49\x6d\xbc\x60\xdd\xf2\x1e\x71\x9d\x4c\x83\xc5\x1d\xa7\x53\xef\x2a\xc6\x1c\xc5\xb7\x86\xe3\x74\xaa\xd5\x6f\xee\x42\x86\x7a\x8d\xc5\x8c\x2b\xc4\x4b\x19\x5d\x7b\x44\x13\xf6\x65\x6c\x6a\x6a\x9c\x56\x86\x87\xc6\xec\xa2\xbb\xb8\x4e\x67\xd7\x32\x2a\x6e\xb0\xfd\x79\x2b\x31\x9a\x88\xd3\xa9\xa7\x6a\x99\x5a\x52\xa5\x2a\x64\x9e\x2e\xe0\x2a\xa7\xfe\xc4\x7c\x3e\x8b\x72\xc6\x8d\x17\x69\x5e\xdc\xe0\xc8\xfc\x2e\xcd\xab\xa5\x22\x37\x06\x53\x25\xd7\x76\x2b\xc5\x13\xcd\x3a\xa9\xcc\x42\x07\x03\xe8\x74\x7f\x11\x5c\xc2\xbb\x8a\x3d\x43\x4d\x86\xb3\x04\x92\x21\xa9\x28\x62\xef\x79\x4d\x66\x62\xd8\xf3\x34\xfb\xfc\x31\x7d\x97\xa5\x67\xb4\xbc\x0c\x02\xc2\x65\x17\x42\xe2\x2d\x2f\x28\x21\x50\x68\x81\x09\x8e\x3c\x65\x58\x52\x73\xd6\xc2\x3b\xc9\xdd\xac\x60\x9e\x82\xd2\xc9\x9e\xf1\xf5\x8c\x9c\xa0\xcf\x53\x32\x54\x66\x0c\xd7\xba\x55\xae\x83\xe7\xea\xf8\x38\x4e\xcf\xe1\x59\x89\xd4\x6b\x54\x55\x5f\xfd\x0c\x82\xc7\x4e\x64\xc4\x44\xd2\x24\xbe\xe4\x01\x21\x0a\xe3\x75\x86\x7c\x21\xc1\x5f\x42\xf8\x1e\xf6\xc8\x67\x12\x64\x68\x3f\xda\xc1\x0f\x24\xec\xa3\x35\xeb\x63\x23\xde\xa5\xee\x83\x80\xfe\x85\x95\xaa\x97\x9b\xd5\x51\xba\x9f\xac\xcd\x7b\x85\x6a\xc2\x16\x74\x0d\xf8\xa5\x17\x8b\x28\xbb\xf4\xac\x78\x94\x8b\xc9\x2d\xe7\xee\x63\xbc\xd0\x2c\xaf\x6c\x09\x58\xa0\x9e\x05\x00\x94\xed\x93\x25\x2c\x88\xee\xae\x6f\x55\xbe\x0f\xce\x25\xc9\x88\x14\x2f\x18\xaa\x7e\x3f\x1f\x47\x91\xbd\x7c\x65\x19\xbc\xdb\xfe\x3d\x17\x88\x53\x70\x48\x9a\xd3\xeb\x50\x35\x00\xfe\x94\x21\x0a\x9a\x8f\x39\x0c\x06\xab\xac\x08\x58\x9b\x78\x35\x96\x2e\x46\xbd\xdc\x6e\xb1\x92\xac\x6b\x00\x8e\xa2\x66\xf4\xaf\x98\xaa\xad\x91\xf3\x85\x4b\xc1\x66\x3e\x11\xbf\xc6\x4b\xe8\x39\xdc\xe8\x75\xcc\x60\xda\x70\xd5\x31\x0a\x92\x7e\x94\xff\x23\x88\xa3\xb0\x03\xb1\x2e\x44\xca\x8b\x28\xa3\xe3\xa2\xe3\xbb\xe7\x10\x2e\xc5\x00\x50\xd4\xd8\xe9\x3a\x97\x28\x58\xd0\xd1\x31\x88\x64\x0f\x3c\xd5\x1a\x5e\xeb\x3c\x15\x35\xa8\x42\xf4\xcc\xac\x89\xab\x27\x6c\x1b\x12\xe1\x57\x5c\xc2\xb6\x65\x50\x70\xbd\xd0\x3f\x5c\x26\xe3\x28\xf1\x4b\x2b\xc2\x91\x37\xba\x79\x5a\x37\x93\x88\xeb\xd7\xc8\x10\xcf\xc0\x0b\x12\x18\x21\x46\xc9\x14\x0e\x38\xde\xe3\xad\x0b\x66\xfa\x92\x12\x6e\x9d\x6a\x2a\xc0\x50\x66\xf9\x59\x34\x9d\xd1\xbc\xae\x3c\x86\x42\xb4\x23\x72\x3f\x27\xe9\x79\xf2\xa1\x08\x0a\xea\xf3\x2b\x88\x72\xcb\x1b\xc0\x55\xec\xda\x35\x2c\x96\x71\x4c\xc3\xba\x2a\x30\x54\xc9\x51\x57\xbb\x97\x2a\x89\x20\x50\x77\x81\x3a\xac\x85\xe8\xe9\x7a\x2a\x2a\xa8\x29\x69\xdc\xad\x0d\x3d\x69\x08\xd6\x77\x36\x18\x96\x67\xa1\x92\x36\x2f\x19\xfa\x93\x51\x09\x63\xe7\x1b\x7a\xd2\x38\x6c\xd9\xf5\xfb\xb0\x34\x07\x97\xf3\x0f\xa8\x3c\xaf\xa4\xac\xad\x93\xf3\x54\x61\x83\x18\xbd\x37\x54\x0e\x43\x6f\x2a\x86\xc7\xa7\x9a\xa1\x27\x0d\xc3\x5a\x68\xf4\x24\x62\x68\x9b\x0b\x0d\x4b\xd2\x39\xf7\x32\x6c\xb6\xf8\x05\x53\x6b\xb8\xf5\xb4\xcc\x13\x11\x63\xe1\xad\xe1\xce\xce\xf5\x69\x6f\x67\xeb\xde\x8b\xc5\xbd\xd1\xd6\x7f\x8d\xd1\x96\xa0\xf4\xbb\x08\x47\xb3\x9a\xef\xfe\x86\x96\x5a\x3c\x5a\x8e\x69\x82\xc5\xd3\xbe\x42\x10\x80\xe6\x6e\xfb\x83\x38\x1e\x58\x91\x2d\xe1\x3d\xae\x1d\x16\xc7\x75\xe6\x2f\x8d\xca\xdd\x08\x60\x15\x4e\xfc\x7d\x21\xc0\x3e\xf1\xcd\x4d\x38\x99\xc7\xc1\x6f\x57\x77\x00\xaf\x2b\x15\xbb\x03\xae\x95\x27\xdd\xae\x5a\x88\x9b\x17\xc0\xb1\x0e\xea\x94\xdf\x18\x46\x06\xc7\x15\x20\xe2\x13\x43\xdc\x49\x00\x02\xb6\x3f\xd8\x93\x61\xb8\xaa\x04\xbb\x00\xfd\x84\x0b\x9f\x2c\xb2\x69\x8e\x65\xdd\x1b\x84\x7c\x96\x32\xbe\x0e\x8f\x07\x7e\x20\x80\xd7\xf3\x47\x47\xd9\x34\xe7\x51\x06\xd6\x85\xf0\xd6\xac\xc3\x58\x18\xab\xec\x34\xee\xde\x0f\x0e\x29\xc9\x1c\x1c\xec\x4f\xbc\x6e\x74\x07\xe7\x1f\x9b\xed\xbb\xa0\x42\x4c\xec\x68\x3c\x34\x44\x44\x55\x48\x3f\x1c\x85\xd8\x17\xb7\x2a\xca\xc9\x38\xcd\x32\xd7\xa5\x24\x9c\x80\x82\x82\xee\x67\xd3\xdc\x17\xe5\x4f\xc7\x19\x7f\x48\xfe\x06\x27\xa8\x9c\x7c\x81\xf3\xd3\x35\x6b\x2f\x2a\xc4\x9b\x0e\xc3\xeb\xa4\x67\xaa\x70\x3b\xa5\x73\xa4\x0f\xb9\x1c\x0a\x50\xe4\xd8\x82\x04\x1a\xf1\xec\x8c\xcf\x1f\x02\x80\x42\xc8\x70\xe7\x02\x9b\x27\x38\x11\xd4\xd1\xbb\xd8\x56\x1b\xc0\xd3\xbf\x2c\xb8\xcc\xd7\x8c\xb9\x5b\xef\x38\xc1\x1f\x83\xae\x72\x49\xce\xce\xc5\x8e\x8a\xde\xba\x31\x10\xe0\xdc\xbd\x70\x25\xbc\xbe\x94\x30\xca\x58\x05\xac\x57\xb4\x70\x56\x97\xd8\x91\x84\xb8\xbe\xb7\x57\x46\xc8\xe6\xcb\x25\x76\xf6\x15\xf1\xd7\x2a\xa2\xa4\x75\x1c\x87\x02\x55\x2e\x78\xa5\x52\x06\x6c\x94\x30\xa9\x18\x41\x24\xd2\x77\x1c\xcc\x43\x5e\xce\xa6\xa1\x5d\x6f\x97\xb8\xe3\x0d\x62\xd5\xaa\x36\xd9\xaa\xa4\x3c\xd5\x7e\x25\xd9\x19\x61\x47\x57\x67\x18\xab\xf2\x0b\x33\x5a\x68\x49\x38\xd2\x6b\xcd\xcd\xf1\xf2\xe9\x78\x62\x83\x16\xa9\xdf\xf3\xbf\x11\x3b\x74\x8f\x94\x78\xf5\xf7\x39\x87\x17\xef\x56\xd0\x70\x8d\xa0\xa4\x15\xb6\x4f\x25\x51\x6b\x24\xea\x6f\x16\x9d\xc3\x5b\xbc\x72\xde\x6f\x14\xa3\x43\xb8\x17\xdf\xec\x91\xa7\x52\x1b\x54\xd1\xc4\x32\x59\x04\xe3\xcf\x47\x5c\x0f\x6d\x58\x01\x42\x92\xa1\x1b\x32\x93\x74\x17\x4c\x37\x4b\xb2\x2a\xfe\x43\x91\xde\x1e\xd9\x26\xcf\x64\xa2\xf4\x80\x4e\xe4\x39\x50\xbb\x04\x50\x7e\xcb\xcb\x1c\xa0\x63\x21\xa7\x27\x8a\x9b\x33\x2a\x74\x29\xd8\x7d\xb3\x8a\x7d\x77\xb2\x79\x4a\x86\x3e\x27\xdd\x07\x10\xfb\x39\x40\xe1\xb6\x25\xb2\xec\x80\xde\x41\x1c\xe3\xc5\xdd\xef\xf7\xe5\xfa\x3e\xb0\xcb\x5a\x9b\x8f\xe3\x1e\xe7\x90\x6f\x77\x10\xd6\x57\x82\xb2\xdd\x28\x50\x35\xf4\xcc\xb8\xfd\x32\x99\xfb\x82\x83\xb7\x87\xf2\xd0\x15\x18\xaf\xc3\x82\x24\x34\x7d\xa8\x48\x30\x1e\xf8\x9a\x9f\x8c\x58\x1d\x3c\x68\x20\x03\x17\x68\xf3\xd2\xae\x98\x55\x88\xdb\x5b\x47\xb5\xd0\xab\xb2\xd8\xc8\xab\x04\x3e\xf6\xef\x9b\x52\x06\xb3\xac\x25\xd5\x1e\x03\x07\x19\x2d\xff\x09\x97\xc9\x86\x58\x88\xd9\x0f\xb8\x7d\x36\xa5\x2f\x5c\x04\x8b\x3f\x76\x31\xad\xd0\xe7\xae\x9a\x25\x97\x96\x70\xfa\x5a\x7e\xdd\xf7\x14\x57\xeb\x68\x15\xe3\xa3\xc5\x8c\x23\x41\x54\xdd\x33\xba\xe6\x3e\xbc\x83\x52\x78\x09\x77\x8c\xf5\x80\x9c\x8d\x3b\x4f\x65\x9b\x34\xd8\x73\x1d\xdc\xb8\x3c\x00\xb9\xb7\x91\x2f\x2a\x0c\x27\x08\x3d\x6e\x5c\xb1\x6b\x3a\x15\xe6\x9d\xa6\xa1\xe3\x40\xbd\xc8\x2e\xad\x77\x83\x08\x14\x9e\x0a\x96\x8f\x97\x18\x6f\x1b\xc7\xf0\xb8\xbc\xe3\xb8\xa8\xe1\x14\xbf\x47\xa8\xd7\x39\x8e\xdd\x79\xd9\x3a\x92\x64\x2a\x37\x8a\x26\xe7\x4a\x7b\xdb\x30\x8b\xd4\xee\x0a\x56\x0b\x7f\xaa\xa5\x56\xbb\x66\x24\x49\x09\x40\x61\x8e\xf9\x03\xd9\x84\x43\x8d\x71\xd6\x74\xa5\x43\x1c\x31\x34\x48\xf8\x3b\xed\x24\x14\xbe\x1c\x21\xe4\x6b\xf2\x48\x1e\x54\x9d\xd8\xb7\x35\xcb\xd5\x88\xf7\xc6\xd6\x8d\x35\x0f\x1d\xf3\x16\x4f\x54\x57\x0b\xde\xdc\xd1\x3e\xcd\x8b\x68\x1e\x14\xf4\xa7\x00\x14\x88\x75\x54\x85\xc0\xeb\x28\x0a\xd7\x7c\x17\xd4\xf4\xf5\xa9\xa3\xd9\x0c\xa1\x71\xd5\xcd\x8e\x07\xb4\x6c\x66\xde\xcb\x66\xa8\x0c\x1d\x06\x21\x50\xa4\x2e\x50\xc8\x07\x78\x2a\xa6\xb4\x78\x61\x87\xf6\x91\x3b\xab\x5d\x4d\xdd\x5c\x89\xba\xee\x78\x9e\x1a\x21\x5e\xde\xe8\x8a\x95\x59\x11\xa9\xdf\x2b\x35\xdf\x22\x00\x21\x2e\x2a\xf1\x8c\xc8\xbe\x12\x61\xbf\x6d\x34\x42\x55\xff\x8d\x02\x12\xaa\x42\xab\x0e\xf2\x6b\x46\x27\xd4\x3a\x1a\x36\xc0\x6c\x31\x96\x6e\xaf\x72\x7e\x6a\xae\x63\x44\x02\xba\xdc\x2a\xa5\x62\x5c\xa2\xec\x1f\x9b\x2b\x11\x23\x4a\x8b\x04\xc3\x62\x8a\x11\x6c\x04\xcf\x89\xeb\x27\xce\xd2\xb8\x3e\x03\xe7\xb3\x9f\x58\x8f\xdb\x64\xc8\x3f\xac\x9d\xa4\xdd\x73\x84\x97\xa1\xf6\xcf\xa6\xf2\x94\x67\x39\x31\x9c\x53\x9d\xc5\x3b\x2e\xfd\x96\x72\x06\x59\x4b\x0c\x32\xac\x4a\xd9\xf6\xa3\x02\x16\x55\x6f\x3d\x9e\xd8\x42\x78\x82\x0b\x43\xd0\x59\x37\xb1\xa3\xad\x71\x60\x9b\x2f\xb0\x0c\x25\x7d\x73\xe8\xb4\xb2\xad\xc2\x42\x67\x3f\x58\x2c\xe2\x4b\xe1\x29\xa8\x11\x61\x75\x6d\x33\x36\xbe\x05\x58\xcd\xb0\xc4\x1b\xd5\x5d\x33\x0f\x22\xfe\x8e\x66\x3c\x3a\x04\xcf\xad\x63\xef\x78\x26\xec\x6b\x85\xdf\x91\xe9\x7a\xc5\x63\x57\x49\xa5\xe0\xe2\xb0\xa9\x31\x5c\x06\xe8\x4a\xcd\xde\xc9\x2f\x2b\x6e\x8a\x48\x7c\x24\x3a\xa9\xb4\x98\xde\xad\xa5\x8b\x1f\xf6\xf9\xa7\x8c\x3d\x24\xcb\x02\x81\x47\xd9\x78\x19\x07\xd9\xfa\xfa\xfa\x7a\x75\xc4\x21\x49\x41\xbb\x77\x12\x73\x88\x6b\x7f\x5b\xc3\xed\x27\x7e\x07\x2e\xdb\xf7\xb7\xff\xf7\xb7\xff\x7f\xed\xdb\x7f\x71\xf5\xcf\x60\x65\x4c\x28\x7f\x24\x8b\xdf\x2d\x46\x85\xcf\xb2\xa0\xda\x10\x60\x6d\x30\x80\x98\x57\x41\xc6\x48\x99\xed\x60\xcb\xdc\x1c\x22\x23\xb8\x30\x9a\x4c\x68\x46\x93\x82\xd0\xe4\x2c\x87\x42\xa3\x2c\x3d\xcf\x69\xb6\x86\x1c\x7a\x9e\x47\x49\x98\x9e\x83\xc6\x02\x45\x7a\x20\x0f\x1e\x88\x9c\xfe\x3f\xdf\xbc\x7e\x55\x14\x0b\xe1\x2b\x96\x73\x4d\x33\x8d\xec\xf9\x61\x81\xf5\x89\x40\x05\xd1\x34\x49\x19\x23\x88\xa3\x84\xb2\x9e\x24\x69\x48\xd7\x90\x77\x30\xa7\x46\x35\xf0\x8b\x79\xcc\x46\x26\x36\xb6\x76\xb7\x69\x23\xd7\x1c\x93\xff\x7c\xf5\x7e\xdb\xa8\x6e\x96\x6d\xb7\xbb\xa5\xa5\xa4\xe4\xc0\x5a\x78\x27\x91\xe9\x9a\x44\x80\xfc\xc4\x44\x7b\x70\x8f\xc9\x9d\x69\xb3\x5e\x2a\x03\x08\xa3\x3c\xde\xf2\x67\x69\x5e\xf4\x48\x11\xcd\x69\xba\x2c\x7a\xac\xc2\xac\x07\x4a\xe6\xf3\x34\x13\x8f\xd1\x60\x33\x61\x70\x64\x8f\xc0\x7f\x57\x57\xa4\x2d\x88\x3d\x4e\xc7\x41\xcc\x12\x87\x4f\xbf\x79\xfc\x0d\x04\x96\xe5\x7b\x0f\xaf\x90\xed\x84\xe2\xd7\xd5\x15\xd9\x54\xd9\xac\x19\xb2\x07\xad\xa9\x34\xd9\x28\xd9\x53\xed\xd7\x0a\x4f\x8b\x8c\x2e\x20\x52\x1b\x3d\xb7\xa6\xcc\x92\x9d\x04\xe0\x7b\x74\x96\x11\x92\xd3\xf3\x34\x8d\x69\x90\x5c\xc3\x1d\x2b\xdb\x9f\xa5\x04\xa3\xb1\x2c\xdc\x32\xa2\x03\x9f\xd9\x96\xe1\xfb\x07\x63\x1a\xc9\x5d\x66\x07\xcc\x8b\x40\x56\x3d\x47\x35\xbf\x41\xe1\x84\xc4\x78\x18\xdc\x00\xea\x6c\x42\xb4\x78\x05\x43\x7e\xf5\x7e\x5b\xc7\x75\xe5\x92\x16\xc2\x3c\x9a\x08\x06\x63\x38\xbf\xb3\x2a\x32\xc6\xc3\xab\x04\x79\x58\xd6\x9a\x2e\x68\xd2\x69\xbf\x3b\xfa\xf0\x51\x86\xa2\xe4\x84\xc3\x3b\xb7\xbb\x86\x3c\xe9\xc1\xdc\x3e\x78\x60\x4e\xaa\x71\xe8\x5b\x82\x41\x4d\xfb\x79\x90\x47\x63\xd2\x26\x1b\xd0\x85\xe7\x4b\xc6\x1e\x50\x15\x1b\xa4\x3d\x54\x57\x85\xaa\x9e\x7e\x91\x8a\x47\x6b\xed\x51\x90\xd3\x27\x8f\xdb\xd6\xf8\xb5\x1f\xe9\x57\x34\x08\x69\xd6\x69\xef\x03\x5f\x8d\x7e\x0d\xf8\x69\x0b\xda\xe7\x23\xac\x28\xc4\xe4\x63\x9a\x14\x8f\xd8\x41\xbb\xdd\x23\x6d\x26\xf9\x47\x63\xa8\x62\xf0\x4b\x2e\xd5\x8e\xea\xc6\x4a\x4c\x59\x0d\xb9\xf2\x88\x23\x97\xc9\x18\x1d\xaa\x6d\x4d\xb2\xef\xe2\x79\x81\xae\xaf\xfd\xb1\xa5\xab\x48\x2f\xb7\x63\x0d\x4a\x5d\x9a\x4d\x72\x92\x66\x4c\x5a\x15\xc1\x8a\x81\x1e\xb5\x76\x5f\x63\x2e\x09\x3b\xf0\x20\x82\x47\x91\x89\x26\x97\xaa\x7e\x81\x64\xa9\xc8\xc7\x6e\xa2\x7d\xd6\x00\x07\x69\x92\x50\xf1\x6c\x41\x52\x98\xa6\x44\xe3\x72\x51\xb6\x2e\x03\x36\x7c\xa4\x17\x85\xd3\x41\x01\x8b\x5e\x6b\x08\xeb\x78\xb3\x5b\x55\x5d\x7a\x2f\xea\xef\xf8\x1a\xc4\xab\xa4\x79\xec\x60\xa0\x81\xa0\x86\x08\xf6\x15\xc7\xa9\xa0\x04\x91\xf5\xa3\x13\xad\x83\x14\x59\x34\x9d\xd2\x8c\x87\x18\x62\xb3\x0f\x62\x8b\xf2\x17\xca\x70\x50\x47\x30\xd0\x03\x1f\xd5\x98\x91\x82\x9b\xd0\x0f\x18\xaf\xec\x1a\xdc\x24\x01\xdf\xce\x79\x11\x14\x74\x3c\x0b\x92\xa9\x5f\x81\xc0\xcd\xfb\x25\xe2\x83\xf0\x12\x0c\xeb\xe1\x46\xf8\x31\xe3\x30\x36\xcb\x5b\x37\x23\xfd\x36\xa0\x18\x0d\x28\x6f\x95\x50\x08\x29\xfb\x32\xab\x86\xa2\xe0\x4c\xe6\xbd\xb5\x52\x37\x56\x2b\xd2\x16\xc1\x57\x5b\xf6\xc5\x96\xd1\x32\x3b\x0b\x5e\x5b\x28\xd6\x1b\x81\x8b\x59\xb3\xb2\xbc\xaf\x97\xde\x47\x5e\xaa\x83\x37\x0f\xb1\x90\xef\x96\x03\xd8\x5d\xa8\x62\x02\x62\xa5\xe1\x75\xa5\x2f\xcb\xe3\x4b\x46\xef\xfc\x6d\x29\x2c\x2e\x46\xd5\x25\x6b\x2b\xca\x45\xfd\xd4\x64\xa6\x4a\x08\x90\x0a\x4e\x5b\x18\x60\xe7\x87\xa4\x5d\x90\x49\x10\xc5\x34\xec\x93\x23\x76\x4e\x3b\x8f\xd8\xd9\x23\x80\xa8\x60\xe5\xab\x09\xb5\xe9\x99\x0b\x8d\x4f\xa5\xcf\x50\xd1\x27\xa2\x70\x48\xbe\x53\x7f\x52\xdf\xc7\x76\x9f\x6c\x31\x1e\x92\xf6\x76\x7f\x53\x29\x0f\xa5\xfe\xb1\x9d\xd0\xe2\x53\x1c\xe5\x05\x4d\xa2\x64\xaa\xb2\x95\xf6\xf0\xd4\x30\xe8\x92\x0a\xae\x8c\x87\x38\x73\xc9\x57\x5a\x15\xb2\x41\xea\x49\x70\xd4\x05\x78\xe8\x52\x55\x60\x9c\xf6\x99\x98\xdb\x1a\x3e\x65\xbf\x0c\xf9\xb9\x35\xdc\xfa\x96\x9d\xfc\x77\xee\x4f\xfe\xf7\x27\xff\xbf\xf8\xc9\x5f\x1b\xfe\xc3\xa3\xc5\x3b\x32\xfa\x57\x86\x9c\xf8\x54\x39\x8a\xa6\xdc\x06\xb7\xff\x0b\x3f\xa1\xf3\x7b\x90\xf0\x35\x9d\x98\x1b\x82\x8a\xf5\x78\x89\x1e\xce\x19\x1b\x27\x87\xe0\xec\xe2\x7c\xc6\x7a\xdf\x31\x0d\xb4\xbe\xe7\x85\xc9\x43\xb2\xed\xbe\xbc\x03\x8b\x3f\x26\xc5\x9b\xef\x0f\x89\xff\x45\x9c\x60\xee\xef\xc4\xa9\x2e\x48\xc8\xe1\xf3\xfd\xb7\x62\x92\x43\xf2\xdd\xb7\x64\x9c\xce\x17\x4b\x11\x67\x65\x74\x49\xe6\xe9\x59\x94\x4c\x51\x34\xb1\xc7\x64\x3c\x0b\x32\xd8\x0b\xf8\xcd\x6c\xc8\x4d\xa9\xa4\xb9\xba\x84\x8e\x29\x7f\xb4\x50\xa4\xac\x41\x8e\xab\x9c\x74\xf6\xc9\x1e\xd9\xda\xec\x91\xe7\xec\xff\xad\x1e\xe9\xf7\xfb\x3d\xf2\x7f\x64\x8f\xec\x7c\xd3\x65\x87\x1d\x92\x2f\xe8\x38\x9a\x44\x7c\x21\x1d\x7e\x38\xda\xda\x79\xb2\xf5\xc4\x36\x31\x8b\xf2\x14\xd2\xc5\x38\x5c\xaf\xb2\xd7\xfc\x4d\x2c\xeb\x08\x1b\xa0\x79\xb5\x86\x6f\x96\x85\x24\x15\x4a\x30\xe1\xda\xc0\xac\xdf\x98\x50\x56\x31\x9e\x47\x36\xa2\xf6\x7e\xbb\xcf\xd0\x72\x90\x86\x74\xbf\xe8\x6c\x22\xad\x35\x1b\x5b\xfb\xff\x9c\x6c\xce\x00\xf9\xbb\x5d\x20\xd6\x22\x3d\x5e\x2c\x68\x76\x10\xe4\x5a\x95\x8d\xb2\xf3\xe5\x28\x2f\xb2\xce\xe3\xae\x7c\x91\x2b\x12\x36\x7b\x8f\xad\x1b\x33\x9e\xbb\x88\xa3\xa2\xd3\x6e\x77\xcd\xc7\xca\x49\xd7\xb4\xae\x1a\xa7\x21\x1b\x5c\xe2\xeb\xbc\x94\x0f\x01\xe6\x87\x3d\xb2\xcf\x04\x42\xf8\xf8\x7e\x8f\xfc\x5f\xd7\x89\x01\xe0\x99\x59\x31\xb1\x06\xa4\x72\x2a\x1b\x52\xf2\x88\xec\x93\x0d\xb2\xb5\x89\xec\x8c\x7c\x7e\xf1\x65\xec\x51\xdb\x86\xe9\xba\xdb\xff\x25\x8d\x12\x36\x4c\xdb\x52\x71\xbc\x04\x8f\xbb\x30\xc5\x6f\x8e\x5e\x30\xc2\xde\xda\x94\x4c\x49\x58\xf8\x01\xe5\x7b\x28\xee\xdb\xcd\x27\x8f\x6d\x82\x9b\xa7\xe1\x77\xdf\x6e\x6d\x96\x11\x9a\x49\x5f\xda\x8f\x31\xa7\x26\x51\xb8\x92\x8a\x32\x3a\x0f\xa2\x84\xeb\x8e\x58\x9e\xbe\x7b\x14\xce\x5d\x4c\xf6\x20\x80\xb5\xdd\xf2\x76\xd7\x72\x5b\x03\xcc\x4a\x82\x29\x8b\xd7\xef\x0c\x13\x39\xdd\x24\xc8\xda\x87\x49\xc1\x3d\xe2\xf4\xc8\xd6\x66\x97\xfc\xff\x19\xd6\x36\x9c\x5a\xb8\x53\x1c\x61\x7e\xee\x7b\x81\xab\xea\x52\x25\x75\x7d\xc6\x3c\xd5\xbf\x43\xe2\x26\xe8\xb0\x0e\x84\xc1\x3f\x5c\xa8\x43\x82\x78\xeb\x20\xd8\xa7\x9c\x2f\xff\xe4\x0c\xb0\xb7\x6b\xff\x24\x08\x4b\x68\xbd\xe4\xdc\xae\x3a\x51\x66\xeb\xfa\x49\x21\x08\xd1\x72\x2e\x5f\xe7\x58\x44\xc5\x60\xf6\x55\x8e\xd3\xf7\x00\x65\x49\x31\x9a\x0d\xe1\x5a\xb1\x35\xac\x15\x63\x39\x7d\x54\x63\x9d\xcf\x80\x20\x7f\x2e\x7d\x06\xa0\x97\x0a\x22\x1a\x28\xd9\x7a\x82\x58\xd8\x28\xc8\xe9\xce\x13\xb2\x07\x65\xb4\x7a\x68\xe7\x89\x61\x02\x10\x86\x94\x6b\x16\x61\x0f\xec\xf0\x42\x3d\xb2\xf5\x8d\x29\x09\xab\x7e\x3e\x1f\x05\x49\x87\x17\x33\x99\x9f\xb5\x98\x85\x5b\x12\xb4\x70\x9f\xb3\xa1\x17\xa9\xb1\x7b\xb1\xe9\x23\xe0\x5a\x35\xbb\x94\x2b\x9a\x2b\x93\xc0\x5e\xf7\x1d\x8f\x05\x91\xa4\x85\x10\xca\xbe\x8f\x7e\x68\x4d\x41\x22\xe1\xee\x6e\x26\x1a\xa9\xf9\x2c\xe0\xd2\x1a\xec\x6f\x17\xe3\x78\x99\x47\x67\x2a\x74\x65\x34\x8a\xe2\xa8\x50\x02\xce\x28\x48\x3e\x0f\x46\x59\x90\x8c\x67\x24\xa7\xd9\x59\x34\x96\x1b\x60\xc0\x3d\xbd\xb6\xbe\x1f\x44\x3f\xf4\x6d\x1a\x52\x61\x24\x72\xb9\x0b\x4d\x68\xc6\xb6\xa1\x20\x9e\xa6\x59\x54\xcc\xe6\x24\xa4\xf9\x38\x8b\x46\x9c\x2d\x09\xf9\x87\x26\xfd\xf3\xe8\x73\xb4\xa0\x61\x14\x80\x10\xc4\xbe\x06\x87\x49\x41\xb3\x24\xe0\x4f\x27\x3e\x3d\x0f\x92\xcf\x9f\x84\x9b\xd9\x4f\x7c\x5e\xff\x7f\x3f\x89\x91\x26\xd3\x4f\x6c\x88\x9f\xe0\x2d\xd1\xa7\x30\x9a\x46\xce\x53\x0e\x39\x35\x3e\x8a\x1c\xc9\x3d\x55\xce\x80\xf4\x19\x53\xa4\x9e\x6d\xb6\x01\xad\x3e\xb7\x57\xe4\xc8\x62\x8b\x62\x46\x0f\xf8\x3e\xd5\xfe\xe7\xcb\xf6\xee\x9a\x97\x67\x0a\x1e\xdb\xb1\x76\xee\x0e\xae\x60\x83\xb4\x37\x41\x54\x82\x56\xb0\xb9\x0b\x43\xc7\x0b\x86\x0d\xb2\x47\x3a\x5c\x9c\xea\x7c\xf7\x94\x3c\xd2\x4d\x74\xe5\xb3\x81\x47\xdb\xd6\x7e\xab\xbc\x6e\x98\x4d\xa1\x3a\x45\x83\x35\x6a\x2b\xc1\x44\x10\xae\x80\xb0\x79\x00\xf1\x28\xc9\x8b\xa8\x58\x16\xd2\x59\x72\x14\xd2\xa4\x60\x9b\x96\xed\x78\x9f\xd7\x72\x98\x84\x51\x46\x4d\x03\x06\xf3\x8d\x4d\xde\x93\xb2\xac\x7a\x64\x03\xaf\xa6\x5a\xa8\xa5\x16\x34\xd5\xd2\x6d\xb5\x56\xe1\x45\x66\x4f\xbc\x0e\x94\xcd\x23\xb0\xc9\x19\xda\x2f\x3f\xbe\x62\xf3\x20\x5f\xb7\x60\x0c\xa0\x54\xd5\xb7\xae\xc5\xaf\xd3\x2a\x7e\x2d\x9f\xd2\x71\xe4\x8a\xe8\xdc\x51\xce\x5f\xca\x61\x3e\xee\xc8\x9d\xe0\x41\xa5\x54\xde\x54\x7b\x91\x47\xf1\x21\x15\x1e\xfc\x39\x1d\x6f\x49\x09\x9d\x87\xc8\x3f\x4b\xa5\x9c\x10\x61\x3f\x2f\x11\x27\x2b\x2c\xfc\x69\x27\x2f\xb5\xba\x72\x85\x05\xe8\x7a\xe9\xeb\x41\x3c\x66\x1d\x95\xc1\x3b\xaa\x1e\x49\x3d\x5a\x1b\x18\x1b\xd6\xd6\xb8\xa3\xb4\x28\x61\xf0\x9f\x7f\xbe\x3c\xd9\x7c\xf4\xdd\xe9\x97\xed\xeb\xce\xcb\x8f\xaf\xd8\xef\xfd\x47\xff\x77\xfa\x65\x6b\xe7\xfa\x4a\x7d\xec\x6c\xf6\x76\xb6\xae\xbb\xff\x33\xe8\x17\xa0\x04\x55\x1b\xb8\xf1\x2e\xaf\x8c\x31\x20\x70\xfe\x3c\x6f\x6b\x45\x84\x89\x27\x98\x70\xfa\xf7\xa2\xed\x85\x5e\x82\x77\x83\xb7\x17\xee\x4a\xb2\x10\xa7\x07\x85\x1f\xf7\xec\x3c\x86\x38\xff\xfe\xbc\x6f\x6e\x38\xec\x09\x89\x92\x92\x81\x1b\xdc\xe7\x6e\x86\xee\x65\x23\x8d\x06\xbf\xbd\xd9\xc8\x6a\x93\x8b\x94\x6c\xa4\xf9\x72\xce\x00\x8f\x73\x71\x7c\x98\xa7\xe1\xa3\xef\xbe\x7d\xb4\xb5\xa9\xb2\xe1\x8c\x0b\xbd\x1b\xa7\x31\xe9\x1c\x7e\x38\x1a\x1c\xbe\x3c\x20\xec\xdc\x30\xdc\xde\xdc\xdc\xe9\xda\x3c\x19\x55\xeb\x9e\x42\x51\xae\x33\x70\x99\xd7\x70\xd8\xe2\x4c\xb8\xdd\x23\xdb\xcd\x6c\x55\x31\x53\x35\xb6\x14\x42\xa7\x7d\xf2\xcf\xf7\x2f\x7f\x72\x1c\x09\xaa\x02\xfe\xd1\x94\xd6\xe8\x4e\x2a\x82\xac\x1b\x9e\x26\x80\x0e\x78\x99\x73\x86\xfc\x6d\x8f\x3c\xee\x92\x21\x69\xb7\x1b\x8d\x7b\x1c\x47\xf0\x90\x4c\x75\x10\x94\x4f\x51\x62\x8f\x8f\x61\xe1\xa7\xfd\x7f\x1c\xfd\xf8\xaf\xa3\xf7\xff\x6b\xcf\x2a\xd4\x51\x32\xa7\x76\xfd\xde\xc9\xe5\x40\xb7\x1e\xfb\xd6\xd6\xea\x23\x17\xab\xc9\x7f\x2e\x71\x0f\x1e\xee\xd0\x9c\x0a\x9c\xe1\x05\x9e\x73\x08\xbe\x77\x12\x83\xf3\x39\x20\x33\x0e\x1d\xee\x80\x1f\xa3\x43\x6c\xe9\x51\x46\x9e\x3f\xd4\x29\xc5\x38\xa1\xf2\x33\x8a\x79\x9e\xd9\x7a\xd2\xed\x91\xed\x4d\xe5\xe2\xcc\x90\xf2\x24\x7a\xad\x41\xca\xc2\xcd\x16\x68\x89\x57\xaa\x43\xc8\xe2\x4a\x7d\xac\x57\x6c\x0d\xcd\xcf\xeb\xd3\xde\xce\xe3\x7b\x35\xfe\xbd\x1a\xff\x2f\xae\xc6\x17\x2a\xfc\xc5\xb8\xda\x7e\xef\x16\x16\x77\x2d\x1d\xa2\xb0\xb5\xbb\x52\x68\xb5\x1a\x3b\x3d\xae\x67\x5a\x8c\xbd\x96\x60\x8b\xa0\x98\xf5\x48\x42\x0d\xeb\xef\x4f\xa0\xb9\x70\x1e\x9e\xca\xab\x6a\x1c\xdc\x59\x7a\x2d\x10\xf6\x3a\x60\xe3\xc3\xfe\xe3\xa9\x3a\x6b\xac\x6e\x78\x81\x2b\x16\x32\xa1\xf3\x85\x41\x0f\x75\x79\xe5\x8a\xd2\x2a\xd6\x4f\x93\x4e\x1b\x46\xd5\xc6\xc1\x50\xbb\x86\xfd\x74\x9e\x32\x26\xc6\xdf\x12\x1e\xbe\x3b\x20\xfa\x5e\x99\xbf\x30\x6c\xf7\x08\x45\xac\xf7\x13\x67\x83\xe2\xc2\xbb\x63\x3b\xc3\xf4\xf6\x20\x09\x71\xfb\xa8\xf9\xd2\xca\xc8\x9a\x7a\x63\xf0\xfa\xf0\xc3\xc7\x97\x6f\x61\x05\x1d\x1c\xbd\x7d\xfb\xf2\xe0\xe3\xe1\xd1\x5b\xf2\xfe\xe5\x87\x77\x47\x6f\x3f\xbc\xfc\x50\xda\x6a\x18\x14\x01\x6e\x96\x7d\xe3\xcd\x69\xf0\x50\x98\x11\xce\x83\x8b\x71\x3a\x5f\xc4\xf4\x22\x2a\x2e\x87\xe4\x09\x50\x96\xd5\x43\xd0\x85\x2a\x3b\x04\x56\x95\xde\x6f\xba\x9e\xc8\x35\xc2\xe6\xe0\x8b\x19\xc8\x1a\x0e\x7e\xa1\x6d\x3b\x21\xba\xc3\x03\x7c\x03\x7f\x09\xc9\xf9\x2c\x1a\xcf\xc8\x3c\x28\xc6\x33\x21\xbe\xf2\x4d\x88\x31\xb4\xd0\x28\xe7\x89\x5a\x00\x4d\xfb\x23\x5d\xc3\x75\x94\xd3\x5b\xb0\x40\xf0\xc7\xa1\x8d\x26\x9d\x4f\x7e\x42\x3e\x81\xb7\x71\x51\x78\xea\xba\x43\x57\x85\xd9\x58\x05\xd8\xae\x03\x65\xc7\x0c\x2f\x8d\xa5\x0b\xd5\x88\xbe\xdb\x15\x5d\x3b\x58\x9c\x44\x19\x35\x3c\x02\xd8\xe8\x2a\x1b\x0f\x1b\x8a\xa7\xf5\x0a\x70\x1d\xd8\x17\x9b\xb6\xe8\xbf\x90\xc6\xb4\xa0\x55\x35\xd8\x83\xb1\x71\x83\x5f\x61\xff\xcc\x76\x2d\x20\x44\x41\x10\xbc\x3e\x50\xee\x70\x5b\xa9\x84\x3b\xcb\x21\x29\x77\xb5\x1c\x15\xfd\xb5\x35\x29\x0c\x9a\x24\xbc\x66\xab\x3d\xe0\x45\x26\x13\xfe\x34\xcf\x43\xe2\x91\x59\x18\x7b\x56\xc5\xab\xca\x66\x83\x3d\x4b\x5e\xfb\x07\xf7\x6c\xae\x1d\xf4\xca\x25\xfe\xe2\xe5\xa3\x83\x57\xc7\x6f\xff\xf7\xe5\x7b\x55\x4f\x48\xc7\xb3\x65\xf2\x99\x86\xe2\x55\x09\x7f\x31\x2a\xfe\xfa\x19\x5d\xc4\xc1\x98\x76\x06\xff\xbe\x3e\xf9\x77\xf2\xef\xec\xf4\xd9\xbf\xbf\x0c\xa6\xbd\xf6\xf5\xd5\xa3\x47\x57\x5f\xda\x5d\x70\x2d\xfc\xc5\x0b\xff\xef\x53\x59\xe2\x44\x94\x39\x65\x85\x4e\x64\xa9\xd3\x13\x7f\x39\xbb\x94\x51\xa8\xa4\x8c\x6e\x0b\xb5\xa4\x1a\x42\x65\xc4\x35\x1f\xcb\x6e\x4b\x4e\x6a\x60\xc0\x5d\xb3\x80\x78\xc4\x5f\x06\x03\xb8\x03\xa5\xc2\x1d\x06\x78\xda\x80\x0a\xd6\x1c\xd2\x67\x79\x07\x2c\xcb\x5c\xb9\xc2\xef\x8c\x05\x43\x36\x08\x7f\xff\x6a\x88\xea\xea\xce\xda\xe2\x64\xae\x53\x03\x9f\x2d\x18\xf4\x1d\x95\x12\xd6\x34\xdc\x98\x66\xcd\x5d\x7c\xba\x33\x7b\x76\x67\xc4\xd0\xc1\xe7\xae\xb2\xa0\x06\xd7\x77\xc9\x98\xc6\xe0\x50\x5f\x3e\xe2\x34\xca\x8c\x63\x1a\x64\xd2\x84\xcb\x6a\x45\x24\x5b\x0b\xda\x0f\x04\xbe\x1a\x0a\x59\x91\x6f\x8f\x33\xcb\xdb\x7b\x1d\xfe\xab\xb4\xab\x14\x38\xc3\xf0\xd7\x3d\xb2\xb5\xb9\xb9\x49\x1e\xf2\xcb\x19\xcf\x5d\xab\xd7\xf1\x03\xbc\xdb\x03\xec\x48\x7c\x31\x0e\x92\x53\x41\x2f\x3c\x16\x8b\x78\xd7\xb7\x3a\xaa\xdc\x19\xb3\x48\x04\xc2\xfd\x08\xcb\x4a\xa7\xc3\x9c\x45\xf0\x80\xf0\xa6\xdd\x9e\xa5\xad\xc7\xe0\xc2\xf9\x0f\xe3\x91\x3f\x89\x2d\x34\x08\xc3\x1c\x47\x0a\x17\x56\x0e\xae\x34\xc6\xd5\xc3\xbd\x35\xbe\xe1\xca\x83\x81\x38\x6b\x47\xdc\x5d\xbd\xe0\x7a\xb0\x1b\xcb\x5b\x21\x95\x7a\x18\xf2\x52\x41\x96\x45\x67\x14\x33\xdc\x20\x54\xb3\x27\xdb\xab\xe0\xb0\x1e\x68\xc3\x5b\xbd\xdf\xa6\x14\xc9\x14\xf2\xb5\x7a\x14\x92\xab\x2b\xf9\x75\xb2\x79\xaa\xb6\x4c\xb8\xc2\xe6\x7d\xd3\xd0\x22\xc1\x2c\xc1\x13\xb1\x44\xe7\xdd\xbc\xc8\x9e\xea\x4d\x95\xc4\xcb\x40\xfb\xaa\x61\x59\xb7\xdc\xd5\xe4\x3a\xc2\x2b\x95\x9c\xcf\xa8\xf4\x3b\x10\x72\xb1\x1c\x4e\x5f\xa0\x71\x67\xfb\x7b\x88\xd0\x2c\x88\xb8\x02\xb5\xae\x7d\xa7\x3a\xda\x4f\xd2\xac\xc3\xf0\xf2\x99\x5e\xf2\x93\xa2\x6f\x00\xa6\x13\x98\x8e\x1f\xa8\x3f\x0b\xf2\xa3\xf3\xe4\x1d\x04\x5a\x2a\x2e\x21\x76\xa1\xc5\x05\x4a\xd0\xf3\x99\x5e\x9e\x96\xdb\x76\xb6\xd3\x84\x1c\xbe\x3b\x68\xdb\x41\xfc\x85\x6c\x51\x51\xa7\x63\x66\xa1\x97\xc9\x01\xf6\x41\x28\xdc\x8d\x13\x74\xdc\x88\x72\x92\x17\x11\x0f\x46\x12\x85\x88\xa8\xb1\x59\x68\x29\xc2\xfd\x76\x9c\x9d\xf2\xd3\x92\x94\x03\xd8\xee\x91\x51\xd1\x8f\x1e\xa7\x02\xb3\x57\xd3\x34\xa1\x42\xf3\xd4\x59\xff\x64\x8b\xfd\xe7\x59\x54\x80\xbf\x14\x8b\x1b\x21\x10\xeb\x08\xf5\xc9\x3d\x43\x49\x17\x83\xeb\x65\xb5\x0b\x05\x92\x77\xe8\x55\x2f\x08\xd6\x30\xfd\x58\xf5\xd2\x0f\xe8\xe9\x0a\x31\x36\xd9\x5d\x83\x73\xaf\x80\x22\x89\xa6\x7a\x2c\x11\xcf\x11\xaa\xf6\xac\x29\x7b\x19\xa2\x67\xbf\xbe\x51\x55\x58\x3c\xdf\x4c\x6c\x50\x54\x8d\xa5\x06\x73\x28\xb5\xfb\x28\xb1\xfe\x7c\xfb\xa4\x65\x76\x27\xb4\x89\xd6\x19\xc5\x71\xc7\xf3\xaf\x74\x09\x56\xd6\xfa\xb5\x59\xab\xbd\x61\xb3\xdb\x8d\x76\x8b\xe4\xd8\x30\xbb\x8f\xed\xb4\x35\x1f\x84\x17\x5b\x69\x41\xf2\xe5\x62\x91\x66\x05\xe8\xd6\xf8\x4d\xed\xbb\x03\xa2\xb4\x2a\x6d\xc3\x11\x64\x39\x61\x36\x7e\xa9\x70\x93\xc5\x58\x4f\x65\x2b\x51\x98\xf7\x58\x0f\x34\x55\x69\x41\x8f\x1c\xea\xda\xbb\x69\xa9\xb7\x1b\x57\x8f\xab\x31\xe8\x38\x69\x2f\x79\xa5\x7d\x7d\xda\xdb\xf9\xe6\x5e\xa5\x7b\xaf\xd2\xfd\xaf\x50\xe9\x8a\x87\x15\xb7\x7a\x8e\xbd\x1f\x64\x69\x42\xfe\x77\x39\x0f\xce\xa2\x9c\x7c\x1f\xb0\xcf\xbf\x7d\xe6\x9f\xfd\x39\xf5\xaa\x7b\x07\x03\x72\x98\x44\x45\x14\xc4\xd1\xaf\x94\xfc\x9d\xf7\x82\x11\x6a\x40\x72\xb0\xc4\x92\x06\x37\x30\x50\xb6\x54\x0d\x27\xe7\x7d\xd0\xea\xca\x62\x32\x8a\x88\x08\x40\x75\x18\x0e\xc9\x66\xdd\xcd\x1b\xb7\xf6\x60\xc3\xb7\xdd\xea\x7a\xcd\x4c\xbc\xee\x74\xf5\x2b\x34\x19\xeb\x6a\x22\x11\x0a\x2d\x69\x83\x1e\x8f\x13\x5e\xfe\x3a\xa5\x87\x54\x3d\x13\x59\x8d\xcc\x92\xbe\x77\xbd\x6e\x88\xd0\x08\x58\x7b\x4e\xef\x07\x6b\x02\x3d\x25\xae\x78\x79\x5b\x3d\xd1\x98\xe1\x34\x95\x67\x75\xcb\x54\xcb\xb2\x49\xc7\x98\x47\x99\xed\xae\xb7\x51\xd4\xa9\x20\x3c\x63\x67\x54\x39\x3b\xe4\xf0\x05\xe4\xc8\xde\xa9\x49\xdb\xd8\x28\xf3\x33\xe4\x7f\xfd\xc3\xdf\x0a\x39\xd5\xe8\x6c\xf9\x3c\x48\x8c\x54\xa5\xcb\x77\x41\xfc\x7f\x76\x60\x92\x2f\x84\x9a\x1b\x5e\x48\x1c\xa8\xc3\xa3\x34\x20\xf2\x9b\xea\x28\x65\x5d\x5d\xe4\x33\xcf\xcb\x6c\xab\x01\xbf\x79\x86\x44\x83\xd5\x9e\x15\x10\x99\x27\x5a\x97\xa1\xdc\xa7\x0f\xd2\x39\x0b\xa0\x67\xaa\xed\x3e\x3d\xa3\xd9\x65\x47\x7a\x43\xfe\x10\x25\xd3\x98\xbe\xe1\x08\xef\x92\x21\xf1\x66\xe8\x9a\xc4\xb4\xaa\x8e\xf8\xc1\xc5\x04\xaa\x83\x96\x12\xde\x25\xdd\x20\x0b\x22\x99\xc6\x29\xd2\xb0\x2d\x12\x19\x72\x7e\xf6\xf6\xf6\x38\xd5\x60\x20\xe1\x76\x41\xc2\xb2\x33\x37\x03\xe3\xd7\xba\x6d\x5f\x75\x42\x86\xb5\x7c\x4a\x0e\x06\x3c\x34\x9f\x4a\x12\x5e\xd9\x31\x73\x91\xeb\xb1\x91\x3f\x79\xce\x88\x46\xf0\x1e\xad\x86\x1d\x3d\x67\x40\xe5\x2e\xbe\x45\xc7\x2d\xfe\xc2\xeb\xca\x39\x53\x15\x55\x49\x01\x27\xec\x82\xf2\x48\x2c\x8a\x8e\xe4\x3d\x5d\x32\x89\x68\x1c\x5a\xa6\x07\xa2\x15\xa3\xa7\x16\xcf\xc1\x1d\xb4\x18\x0f\xef\x9a\x45\x86\x32\xd9\x8a\xfa\x20\xc9\xc2\x75\x84\xe5\xb0\x37\x09\xdb\x97\xac\x4d\x7e\x0b\x16\x67\xea\xe1\x1d\x59\x51\xd4\x27\xe4\x44\x26\x06\x3e\xb9\x17\x03\xef\xc5\xc0\xbf\xb6\x18\xa8\xdf\xe7\xf1\x45\x73\x57\x2f\xf4\xee\xe6\xee\x9e\x81\xbc\x91\xea\xc6\x52\x63\x65\x38\x27\x8a\x48\x2d\xd2\x0a\x99\x7d\xa2\x53\xa4\x70\xb9\x26\x73\xd9\xa7\x71\x71\x0f\x3c\x4f\xe7\x6b\xc9\x60\x13\x81\x81\x4f\x7e\x1c\x94\x50\x1b\x42\xe3\x0c\x54\x82\x7b\x7a\xf6\x15\xb1\x72\x0c\xa5\x2b\x68\x0c\xde\x04\x49\x30\xa5\xfa\x75\x3e\x63\x59\x1c\x15\x86\x2a\x40\xba\xf0\xd0\xe0\x68\xbf\x9f\x1b\x18\x72\x2a\xce\xe6\x35\xf6\xef\x21\x65\x1c\x26\x4a\x4c\xff\x9e\x96\xf8\x37\x0a\x72\xee\x73\xa1\x2c\x12\xc5\x94\x82\x97\x4a\xcf\x26\x65\x7a\x9a\xb7\x1d\x8b\xca\x36\xcd\xf6\x80\xc4\x1c\x44\x88\x36\x4a\x63\x4d\x18\xee\x44\x51\xf8\x1c\x45\x1c\xca\x8e\x4f\xfa\x32\xcc\x99\x60\xa3\x52\xea\xdc\x1c\x73\x67\x9c\xfa\x92\x42\x84\xe6\x10\xdb\xae\x1a\x67\x9f\xbc\x61\xac\x3c\xa2\xb9\x08\x22\x0d\xf8\x70\xbc\x50\x1a\x9e\x3d\x1b\xe3\x4d\x0e\xea\xea\xed\x32\x8e\xb5\x63\x8c\x1e\x93\x22\xe9\x45\x04\xd7\x66\x3e\xdc\xfd\x31\xe3\x0f\xdd\x59\xd8\x1d\xb2\xf6\xb5\xe2\xee\x38\x98\x6c\x14\x6d\xc7\x0e\x70\xa2\x42\xc9\x98\x07\x31\x52\x13\x3e\xe6\xfd\xbb\x03\x11\x61\xa2\x3a\x76\x8c\x46\x9b\x70\xf5\xca\x09\x0f\x90\xae\x4e\x9c\x36\x9a\x38\xe8\x21\x83\x74\xb1\x64\x10\x9d\x4a\xf2\xa0\x03\xd5\x52\x89\x8d\x75\x0f\x77\x2d\xa1\x20\xdf\xe3\x46\x4f\x69\x4b\x86\x54\x4e\x17\x7b\x04\x82\x64\x57\x85\x90\x22\xcf\xf4\x6f\x4e\xdd\x50\xe4\x94\xb1\x03\xf4\x59\xe3\x59\xdf\xc1\x3a\xe7\xf7\x2a\x7a\x2d\xc6\xbc\x8b\x78\xee\x80\xb7\xfa\xac\x68\xba\x23\x2e\xc1\xbd\x27\x46\x8a\x19\x2c\x17\xa3\xd0\xde\xac\xc0\xd9\x0c\x1c\x7b\x9e\x79\x01\x54\x55\xde\xd8\x24\x02\x17\xbe\x90\x45\xf2\xfd\x94\xa4\xc3\x15\x22\x17\x05\x72\xdd\x36\x42\x42\xb3\x18\x44\xd8\x1d\xab\xd8\x47\x6c\x2f\xc9\x2b\x3b\x5f\x16\xf2\x04\x00\xa3\x65\x80\x01\x21\xcf\x08\x30\xa4\x8e\x29\x7e\x2d\x88\x54\x67\x80\x66\xa9\x44\x99\x51\xe5\x56\x19\xab\x38\x1c\x54\x49\x17\xb9\x1c\x9f\xa6\xb4\x35\xfa\x05\xa3\x8b\x65\xc8\xa1\x8d\x96\x51\x1c\x02\xc2\xc4\xa0\x58\xa6\xe3\xdf\x16\x18\xfe\xc7\xa3\x17\x47\xeb\xeb\xeb\x20\xde\xb7\x73\xb2\x9c\xc6\x97\x7d\x11\x45\x8c\x1d\x08\x96\x39\xdb\x13\x0b\xd5\x4a\x82\x5c\xca\xb2\xdf\xd2\xae\x46\xdd\x90\x30\xc6\x01\x19\xea\xbd\xf5\x96\x11\xe9\x69\xf4\xcb\x09\xcb\x3e\xd9\x3c\x3d\x65\x62\x17\xfe\xbc\xba\x52\x76\x9b\x36\x28\xff\xb1\x05\x65\xd8\x58\x76\xfd\x57\x45\x56\xed\x00\x49\x10\x17\x76\xd0\xab\x10\x55\x76\x8b\xaa\x2e\xd5\xb5\xd1\x29\x0f\x81\x92\xf8\x9f\x65\x11\xc7\xcf\xb7\x90\xdf\xf5\x69\x78\x15\x3f\xd0\xc4\x8a\x60\xe1\x0b\x55\x60\x9c\xd5\xa1\x2d\x53\xa2\xd4\x17\x53\xfa\x7e\xc6\x88\xc5\xa2\xcc\xeb\x3c\xa6\x79\x76\xc3\x1c\x5e\xb4\x83\x99\x99\x32\x8a\xb4\x0c\x68\xbc\xe1\x54\xcc\xee\x1a\xd5\x94\x0f\xc1\xbe\x86\x12\xa4\xc2\xb2\x9a\x7a\x7a\x96\x61\xae\x68\x52\xef\xce\x51\x72\xc8\x65\x46\xe1\x86\xf4\xfd\xbb\x03\xe5\x81\x89\x9b\xb2\x8c\x83\x44\x09\x9b\x51\x22\x94\x2e\x7e\x5f\x4f\x99\xeb\xeb\xb1\xdf\xef\x5f\xe3\xf8\x6e\xb6\x2f\x3d\xad\xc9\x94\x45\x3d\x9c\xb4\xce\xa7\x7d\xa9\xbb\xf9\x55\x88\x50\xd2\x80\xe9\x93\x1e\xcf\x5a\x19\xa2\x45\xc9\x12\xc5\xce\x1b\x69\x03\xd3\xf4\xfa\xef\xdb\x7b\xbd\xcf\xbd\xde\xe7\xaf\xad\xf7\x11\x4a\x9f\x70\x74\x8b\x9b\x3f\x9f\xde\x47\x69\x6b\xb0\xe2\x87\x33\x27\xa5\xd1\x79\xf1\xdc\xe0\x23\x6c\x18\xa6\xcb\x0f\x47\x53\x01\x23\xb5\x92\x77\x2b\x02\x85\xad\x69\x79\x29\xef\x78\x6c\xfa\xc5\x05\x17\xf9\x42\x2c\xe9\xca\x92\x83\x3a\xac\x66\xb4\xb3\x08\x20\x47\xed\xd2\xf1\x75\xd0\xd2\x37\xeb\x5d\xbe\x3c\x60\xd1\x62\x59\xa8\xc7\x6b\x09\x3d\x17\xd8\xec\xe8\xed\x92\x09\x1d\x43\xd2\x56\x70\x56\x1c\x8d\x21\x69\x87\xa3\x4f\xbe\x5c\x29\x26\xee\xa8\x3e\xa9\x46\xa7\xb4\x59\xa3\x0a\xce\xdb\xa8\x2f\x57\x36\xba\xed\x36\xba\x58\x16\xaf\xe8\x45\xfd\x30\x5f\xd1\x8b\xb2\x31\x9a\x59\xd5\x03\xac\x6f\x8b\x03\x95\x0d\xcd\xdf\x96\x35\x2e\xb1\x19\x9d\x68\x38\x39\x11\x3d\x8d\xe4\x9e\x18\x7a\x4f\x74\x0b\x80\x4f\x4b\x76\xae\x17\xcf\xf5\xae\xc5\x69\xa7\x35\xdc\x81\x2d\xea\xe9\xfd\x16\x75\xbf\x45\xfd\xb5\xb7\x28\x7d\x35\x41\x8b\xd9\x8d\xee\x25\x04\xf0\xdd\xbe\x4a\x2c\x89\xfe\xef\x0b\xff\xef\xbb\x04\xf1\xdf\x83\xd4\x6c\x9b\x0c\x44\x9a\x23\x5b\x40\x0b\x91\x2c\xc1\xc6\x65\xed\x8d\xd3\x64\x12\x4d\x25\x18\x0a\x85\x83\xa1\x65\x64\x15\x09\x76\x2e\x9e\xad\x19\x17\x34\x22\x51\xc2\xfc\xc8\x43\x81\x5b\xc8\x80\x44\x09\x72\x98\x7f\xb8\x4c\xc6\x7c\x8b\xc1\x50\x39\x4f\x95\x60\x8c\x15\x67\xd4\x06\x12\xa9\xaa\x2e\xee\xa0\x08\x43\x44\xa3\x20\x91\xd9\xdc\xeb\xa1\xd3\x1f\x99\xac\x84\x10\xf0\x99\xd6\xe4\xce\x40\xe9\xbc\xc5\x1b\x41\x50\x02\x6e\x9e\x76\xc9\x83\x07\x44\xfc\xee\x83\x4e\xf0\x68\xd2\x69\x6f\x5e\xb4\xb9\xeb\x92\xcd\x2e\x79\x46\x5a\xb4\x98\xb1\xdd\x03\x02\x93\x3e\xbf\x7c\x15\xe4\xb3\x16\x19\xda\xc9\x5c\xa3\xdb\xd2\x52\x02\x8a\xff\xf4\x63\x96\xce\x9f\xff\x06\x3d\x6d\x8b\x2e\xa1\xb0\x42\xcf\x2f\xa1\x61\xd6\xe9\xfd\x24\x3c\x64\xe5\x54\x34\x2f\x2f\x24\x1f\x87\x82\xd5\xe3\x59\x26\xe3\x98\xfe\x46\x03\x38\x66\x6d\xd5\x74\x1d\xc3\x94\x76\x5a\xce\x0f\x1a\xe7\x41\xba\x4c\x1a\x5d\x33\xdd\xc1\x38\xbc\x6d\x73\x12\xc2\x43\x29\x01\xe3\xa3\x72\xa6\xe0\x37\xec\xff\xb1\x6a\x10\x4d\x86\x33\x09\x18\xc0\xe8\xb3\xea\xde\xcb\x62\x76\xd7\x07\x84\xc6\x87\x83\x3b\x3a\x1b\x40\x00\xe0\xf2\xb3\x01\x57\x7d\x70\x2e\x1e\x51\x6f\x8f\x16\xb8\x33\x8b\x9a\x7e\x2c\x6e\xd0\x05\x74\xc7\xcd\xb9\x2b\xf7\x7f\x41\xb0\x87\xee\xc3\xe7\xfb\x6f\xad\x60\x64\x82\xa7\x72\xad\x0c\x7f\x40\x2b\x74\x33\xd7\x6b\x6b\xbc\x77\x7d\x6e\x19\xa5\xde\xd2\xbc\x2c\x66\x5a\x1b\xd4\x23\x6d\x1c\xba\xb9\xdd\x13\xc3\x9c\xd2\x62\x58\xa2\xf3\x94\xbe\x4a\xfb\xb8\xa0\x18\x49\x4f\xe8\xe9\x8c\xc2\x67\x41\x6c\x44\x19\xeb\x5b\x81\xb3\xcf\x82\xd8\x71\x46\xa2\xd2\xae\xd7\x00\x3d\x2b\x0d\x45\xf8\xf9\xbb\xc9\x60\x44\xd1\x9b\x0c\x47\x14\x6d\x38\xa0\x26\x67\x51\xc6\x5d\x82\x18\x2c\x37\x6b\x4f\x4e\x02\xd0\x3d\x3d\x49\x36\xe5\xe4\xab\x23\x14\xb2\xe6\x34\xae\xf0\x86\xe4\x44\x0b\x54\xfc\x7a\x4f\xb8\xd1\xfc\x51\xdf\xe6\xd9\x10\x38\xf2\x39\xe7\x27\x0a\x18\x85\x8e\xb4\xee\xb1\x86\xb8\x1a\x9e\xa7\x7c\xd6\x28\xa0\x92\x63\x73\x9a\x05\x53\xba\x5f\x34\x39\x39\x0b\xd0\x52\x1c\xf9\x20\xd4\xa1\xb6\x02\x4b\x7c\xdd\x71\x8e\x5d\xa4\x70\xb2\x5c\x05\x2d\xde\x81\x09\xe7\x8e\x35\x63\x62\x50\xa5\xc3\xb1\x32\x7f\xfb\xf9\xf6\x0e\x4c\xae\xfa\x3a\x7a\xe6\xec\xc8\x1a\x9a\x12\x19\x6f\x37\x2c\x5f\x6f\x7b\xce\x12\xd7\xf6\xaf\x6c\xf1\x92\xeb\xd5\xe8\x97\x35\x51\x4d\xbb\xb0\xff\xd6\x63\x02\xc0\x1c\x4c\x28\x89\xee\x6b\x60\x02\x91\xf2\x2d\x06\xdd\x5b\x2b\xa1\xec\xf9\x22\x8a\xf9\xe1\xad\x96\xbc\x05\x68\x05\x8d\xbb\x10\x12\x0f\x9b\xe5\xf4\x67\xcb\x6b\x0d\xe9\xd1\x2e\xe6\x74\xab\x4a\x64\x75\x3b\xb8\x75\xcb\x89\xaa\x9a\x1b\x39\x85\x2f\xe8\x38\x9a\x07\x71\x39\x2a\xb4\x14\xd8\x10\x09\xba\x40\x09\x51\xfe\x71\x07\x6c\x0a\x4f\x35\x83\x2d\x8f\x95\x5c\x72\x04\x03\xf9\xba\x72\xd0\xf5\x2b\x08\x55\x58\xcd\x3c\x3e\x7a\x4e\xa8\x2b\x8d\x49\x95\x72\x06\x57\x76\xf8\xfd\x23\x71\x9a\x9b\xe0\xe9\x3d\x1d\xd3\x68\xd1\x80\xcc\xdd\x32\x4d\x08\xc0\x05\xbd\x2d\x05\x88\x1a\x1b\x0f\xb0\xe1\x2a\xae\xe5\x62\x9e\xc1\xd9\x80\x4d\x28\x80\x8b\x45\x77\x24\x20\xd6\x2e\x6f\x76\x40\x7a\x1f\x9c\x37\x5f\xe2\x6e\x01\x3f\x22\x2a\xe1\x9a\x70\x36\x86\x07\x8f\x2c\xe4\x86\x96\xae\xeb\x6d\xa3\xae\xde\xbc\x9f\xf6\x4c\xf9\xd6\x98\x6f\x1c\xd1\x34\x59\x61\x1c\x26\x74\xc9\x38\x4a\x81\xbe\xf2\x38\x1a\x74\xbe\xbc\xc7\x77\x2e\x6b\x97\x10\x8e\x30\xee\xaa\xea\x28\x04\xfe\xf7\x76\xd4\xca\xb9\x49\x47\xd9\x5e\x70\x67\x27\x02\x33\x42\x7a\xd5\x98\x10\xa4\x7f\x68\x7e\x80\x9b\x50\x8c\x31\xc2\x5b\x71\xa5\x31\x97\x4f\x65\x5c\xf3\xba\x69\xe3\xd0\x7d\x19\xec\xbc\x64\x0a\xcd\x3a\x7d\x63\x2d\xed\xc8\xeb\xd7\xaf\x1b\xf6\x21\x2e\xa5\x20\x55\xd3\x4a\x2d\x7f\xa0\xd9\x82\xd6\x6e\x4f\x0a\x03\x1c\xba\x1a\x01\x0e\x4c\x45\x2f\xf2\xe5\x68\x1e\x15\x3f\xa7\x59\x9d\x94\xa4\x01\x4b\x56\xba\x2f\xbf\xfa\xea\xbb\x41\xab\x02\xaa\x74\x2b\x2e\x69\xcf\x3a\xe2\x38\xd7\xdf\x5a\xf1\xd3\xc3\x69\x4a\xd1\x61\xa4\x1e\xa4\xa1\x09\x06\x4b\xd8\x48\x01\xd9\xdf\x2a\x24\x0e\x60\x6e\x49\x5b\x7c\x70\x21\xf4\x51\xc2\xc8\x43\x05\xcb\xd2\x95\x60\x5a\x06\x20\x64\xa7\xb2\x6c\xab\x51\xd3\xa0\x17\x31\x12\x9d\xe8\x8a\x01\x28\xcf\xdc\xaf\xcc\x42\xa5\x25\x50\xf3\xe6\x8a\x76\x32\x5e\xbf\x7e\xed\x02\x73\xea\x47\x55\x2a\xc2\x34\x06\xcd\x12\xe0\x5b\x58\x38\xf0\x98\x6c\x4a\xd9\x5d\xe5\xa3\x59\xd3\x11\x23\x5d\xa5\x75\x35\x4d\x47\xd5\xc2\x8d\x92\x51\x90\x63\x45\x85\xe8\x00\x30\x4a\xb1\x6e\x05\x8c\x02\xb9\xee\xf6\x56\x68\x63\x1e\x25\xa6\x75\x8b\xd3\x82\x80\xb8\x61\xfd\xb3\x20\x9f\x65\x41\x51\x39\x86\x12\x98\x46\x3b\xc3\xea\x3d\x92\xb7\xb3\x15\x1d\xf2\x83\xd4\x9f\x33\xc4\x75\xb0\x79\xb8\x58\xbd\x87\xd3\x20\x7f\x97\x45\xe3\x4a\x9c\x95\xc0\xdc\x58\x09\xbc\x7a\x2f\x45\xd8\xa1\xbc\xaa\x97\x0a\xe6\x86\x6d\x8c\xd0\x15\x5a\x45\x33\xe5\x60\x5f\x89\x86\x64\x4c\x86\x7f\x70\x5b\x9b\xaa\xbe\xd9\xa0\xa8\x45\xcc\x42\x8c\x6b\x97\xfe\x58\xdb\x31\xa0\x2b\xcd\x51\x64\xbc\x58\x08\xc6\x45\x9a\x49\xf1\x47\x5a\x3e\x80\x19\x71\x8f\x30\x58\xc3\x96\x58\x40\xfb\x1a\x9b\x48\x4b\x07\xe7\x29\x6a\x0f\x3d\xb7\xe3\x50\x07\x19\x05\x4b\x25\x78\x3c\x76\x60\x99\xd3\xa3\x38\x45\xdc\x7a\x42\xd7\xc3\x50\x21\xc3\xcd\x5b\x37\x76\x3d\x69\x8e\xd1\xa7\xc5\xac\xd3\xed\xb9\x24\xfb\x3a\x9d\x22\xd9\xb8\x59\x97\x7c\x03\xd5\x86\x18\xd5\x2e\xf4\x25\xf6\x3b\xa2\x40\x7f\x1a\xa7\xa3\x20\xee\x33\xa4\xf6\x03\x37\x59\xc4\x3c\xf3\x35\x19\x8d\x83\xc5\xdb\x9b\x36\xcb\x0a\x3b\x8d\xf2\xc4\xaa\x26\x91\x55\x8a\x6e\xd0\x7e\xfa\x80\x63\x4a\xc9\x02\x1d\xff\xf4\xd4\x79\xa3\x7a\x59\xcc\xb4\x3d\x9f\x65\x98\xd3\x1a\x6e\x3d\xed\xb5\x1c\x03\x21\x61\xa0\xae\x2d\x73\x5a\xc3\xed\x6f\x20\x81\xcf\x69\x6b\xb8\xfd\x1d\xff\x54\xb4\xd0\x1a\xee\xf0\x22\xd1\x28\x48\x5a\xc3\x9d\x9d\x9e\x69\x3e\xf8\xff\xb1\xf7\xee\xfb\x6d\xdb\xcc\xa2\xe8\xdf\xc9\x53\xa0\xdd\xe7\x6b\xa4\x98\xb6\x75\xb7\xa3\xc4\x5d\xcb\x91\xed\xd8\x2b\x71\xec\x6d\x3b\x6d\xbf\xed\x9f\xeb\x1f\x25\x42\x16\x1b\x89\xd4\x22\x29\x5f\xd2\x78\xbf\xcf\x79\x8e\xf3\x62\xe7\x87\xc1\x85\xb8\x52\x94\x2f\x69\xda\x65\x7f\x6b\xa5\x22\x09\x0c\x06\xc0\x60\x30\x18\xcc\x05\x1e\xd9\x20\xfd\xd8\x6d\xb5\xe0\x99\x9b\x11\xfd\xd8\x6d\x51\xf0\x8c\xb3\xff\xd8\x6d\x51\xb4\xf8\x65\xef\x8f\xdd\x16\x69\x90\x1b\x01\xfd\xd8\x6d\x35\x6f\xcf\xbc\xe6\xab\x27\x7b\xc4\x27\x7b\xc4\x7f\xb6\x3d\xa2\xcb\x18\xf1\xde\x36\xf3\xe5\xcd\x04\x4b\xd8\x00\x42\xb9\x8f\x38\x7b\x4c\x13\x7b\x78\x3b\xdf\x64\x25\x37\xae\xbf\x8b\xcd\x4a\x09\x93\xfa\xd5\xd5\xd5\x3c\x26\x8d\x2d\xce\x0d\x4b\xd8\x48\x58\x3c\x80\xc3\xd9\x08\xf9\xd3\x50\xc2\xfd\x91\x0e\x24\x66\x32\x7a\x4d\xe0\x51\x33\xd6\xdf\x55\xb8\xc2\x38\xd1\x75\xe3\x46\x2b\xae\x42\x0b\x08\x7c\xb2\xf8\x65\x6c\x6a\x1f\x71\x66\xd9\xd4\xd4\xcd\x4b\xde\x5d\x6e\xcf\xbc\x56\xed\x69\xb7\x78\xda\x2d\xfe\xd9\xbb\xc5\x77\x6a\xbd\xfe\x70\x86\xe6\x25\xed\xe0\x73\x53\xce\x43\x9c\xa4\x71\xe4\x8f\x9f\xec\x39\x1f\xdb\x9e\xf3\xb6\x9c\x85\x5f\x84\xaf\x72\xb3\xc1\x22\xfd\x70\x5e\xd0\x54\x11\x4f\xd9\xac\x9e\x5b\x0b\xdd\xe3\x86\x32\x9c\x90\x8d\xe0\xc8\xbf\x7a\x8f\xe7\xdd\x5c\xc8\x45\x5f\x78\xcf\x9f\x3d\xd3\x71\x33\x0a\x14\x78\xa6\x95\xbf\x89\x33\xdb\x11\x1f\x24\xc3\xbd\x67\xcf\x4a\xde\x4d\x97\xbe\x82\xc3\x83\x23\x3c\x88\x2f\x69\x70\xa8\xa2\x3b\x2b\x5e\xce\x8a\xab\xfa\xb5\x60\x40\x66\xd1\x38\x1e\x7c\x2e\x47\x29\x4a\xd9\x02\x62\x71\x95\x2b\x63\xf0\x58\x6e\xdc\x9c\xa3\xf7\xc0\x37\xdf\xf9\xdc\xcf\xbd\xfe\x5e\xe4\x9a\xd3\x76\x6d\xec\xec\x52\xf9\xf9\x29\x37\x3b\xc5\x73\xb3\xc8\x5d\xa6\x3e\x37\x1a\xf2\x36\xc9\x9a\x35\x2c\x35\x22\x2d\xde\xfc\xad\x42\x41\xd2\xed\x09\xa7\x6a\xd7\x6d\x87\xf3\x52\x44\x02\x27\xcb\xbb\x8f\x77\x3e\xd8\x9c\xa3\x16\xce\xa7\x43\x2e\xec\x10\xcb\x4d\xb9\x9c\x6f\xb7\xb9\x70\x6e\x51\x11\x69\x5a\x21\x5d\x4e\xaf\x3f\xc9\xe9\x4f\x72\xfa\x3f\x5b\x4e\x67\x42\x7a\x3a\x72\x68\x75\xe6\x88\xdf\x38\xc1\xb3\x09\x01\xfd\xf3\x1c\x25\xd0\x20\x4e\xf0\x4a\x18\xab\x72\xfa\x5a\xe9\xc0\x09\x25\x1d\x2d\xe7\xf9\x6b\x42\xa1\xe3\xd1\xe8\xd1\xb5\x43\xdf\x8f\x3c\x4e\xb8\xe3\xf1\x48\xb9\xdd\xc0\x57\x2c\xe8\xf4\xce\xb7\xb8\xd0\x49\x47\xf3\x2f\x74\xd2\x11\x5c\xe8\x50\xc1\x65\x91\x7b\x9b\x22\x39\xdf\xbd\x39\x19\xe2\x81\xb4\x35\x5d\x5a\x6f\xea\x98\x88\x90\x8e\x46\xe7\xf6\x02\xaa\x51\x08\xb2\xe8\xb2\x8a\x1a\x0d\xa3\x61\xec\x6e\xd1\xf2\xf5\x7e\xcd\xa5\x38\xdb\xf7\xaf\x19\x11\x1c\x87\x5f\xf4\xcb\x61\xa9\xed\x79\x45\x55\xab\x9f\xbb\x20\x12\x46\x87\xf1\xaf\xc5\x08\xd8\x8a\xdc\xaf\xe1\x89\x9f\x7c\x3e\x49\x66\x69\x86\x83\x43\x6c\x5c\x06\x4b\xcd\x17\x17\xbc\x1f\x12\x11\x26\x32\xdd\xa1\x1f\x16\xb4\xef\x2c\x73\x3f\x0a\xf0\x83\xe0\x30\x09\x2f\xfd\x0c\xd3\x23\xa1\xa3\xf5\xa2\x62\xf7\xeb\x3b\x4d\xfa\x35\xb7\xfb\x45\xc5\xee\x87\xc0\xc8\x4f\xe7\xb6\xee\x2c\x73\xbf\xa6\x2f\x70\x46\x37\xf4\xc2\xb1\x2f\x28\x75\xff\xe6\x4b\xcc\x7d\x51\xb1\x7b\xd3\xfd\xf1\xcd\xa4\xb0\x71\x57\x91\x7b\x53\xfd\xbc\x86\x5d\x45\xee\x3b\xe4\x44\x8e\xcb\x30\x05\xbd\x93\xc4\x93\x43\x3f\x4d\xaf\xe2\x24\x28\x1a\xff\x92\x75\xee\xbd\x0e\xe6\x8d\x89\xab\xc8\xbd\xc9\x70\x5e\xc3\xae\x22\x0f\xc1\x7a\xe6\xb5\x5d\x50\xca\xde\xbc\x78\x58\x5d\x45\xe9\xac\x0f\x37\x6f\x34\xa5\xf1\x2c\xca\x9f\x27\x61\x9a\x86\xd1\xc5\xf3\xd2\xd8\x4e\xe3\x54\xbf\xba\x92\xb0\xb4\x7c\xb5\xe8\x29\x50\xb1\xde\x11\xcd\xbf\xe5\x3a\x1e\x8d\xa4\x04\x62\x9a\xed\x85\x72\x8a\xd6\x2c\x23\x5a\x8d\xa7\x33\xf4\xd3\x19\xfa\x9f\x7d\x86\xce\xef\xba\xfa\x5f\xbe\x68\x77\x5d\x9b\x63\x7c\x8d\xde\xe2\x04\x5f\xa4\x5f\xfc\xf4\x4b\x88\xde\xf8\x63\x7c\xfd\x9f\x49\x36\x4c\x57\x46\x33\xf5\x38\xdc\x61\xd1\x4c\x8f\xf0\x10\x27\x38\x1a\xe0\x2e\x22\xed\xa7\xdd\xd5\xd5\x8b\x30\x1b\xcd\xfa\x2b\x83\x78\xb2\xca\x4f\xdd\xab\x17\xf1\xb2\xf8\xdd\x1f\xc7\xfd\xd5\xf4\xca\x4f\x26\xab\x61\x94\xe1\x24\xf2\xc7\xab\xa4\x4b\xf8\x3a\xe3\xff\x5d\xb9\x88\xff\xd7\x87\x66\xf3\x91\xaf\xc6\xf2\xfb\xae\x63\x82\xcd\x3f\xfc\x70\x0d\x3f\xfe\x16\x97\x5d\xd4\xf2\x15\x67\x57\x71\xf2\xf9\x08\x43\xa8\xda\x22\x45\xb9\x5e\xdc\xd4\x96\xf7\xbf\x7c\x39\x2f\x28\x75\x1f\xdf\xbc\x9b\x68\xb0\x1d\xf9\xfd\x31\x9e\x87\xa5\x54\xd2\x8e\xa0\xbd\xc0\x7d\x70\xbb\xf2\xa7\x25\x71\xcb\x4b\x3a\x70\xb3\x16\xb8\x07\x6e\x41\x7c\x15\xb1\x28\xc4\x45\x88\xf1\x62\x76\xac\x2c\x5f\xcb\xbb\x9b\x3a\x10\x9b\x4d\x4b\xa0\x45\x0b\xd9\x91\x32\xbe\xdd\x1b\xa5\x04\x67\x49\x88\x2f\xe7\x45\x80\xe0\xc5\xec\x68\x59\xbe\xde\x87\xb4\x32\xb2\xdb\xcd\x21\x2a\x52\xc6\x41\x4e\xda\xa7\x7b\x0f\xd1\x05\x2e\xe1\xce\x6c\xc7\x45\xfd\x70\x8f\x31\xa1\xd9\x1b\xe6\xc4\x48\xb5\xe3\xa0\x7e\xb8\xf7\x68\xb0\x84\x2d\xc5\xc8\xd0\x42\x76\x7c\x8c\x6f\x1c\xa5\x56\x29\x94\x0a\x6e\x75\x0d\x15\xa7\xce\x96\xa5\xdb\xbf\x9c\x1f\x4a\x2f\x73\x46\x94\xbf\xe4\x7c\x40\xba\x71\x9c\xaa\xcf\x9c\xfa\x25\x40\x84\x04\xf3\xc7\x0b\x2c\x5d\x4c\x4e\x67\xd2\x83\x24\x8b\x3f\xea\x35\xe3\x28\xbc\x74\xfa\xc6\x90\x39\x81\xef\xce\x33\x64\x31\x6c\x8b\x52\x56\x81\x0d\xdf\x1d\xc7\x2b\xcb\xf9\x8a\x08\x4b\xb6\x60\xb7\xd6\x7b\xc9\xe6\xd3\x99\xea\xe9\x4c\xf5\xcf\x3e\x53\xb1\x03\x15\xbf\x20\xfa\xb6\x51\xda\xef\x62\x58\xcd\xbd\xa3\xfc\x69\xc8\x85\x71\x9a\xe2\x2f\x1b\x15\x59\xa0\xd1\xeb\xb2\xc2\xa8\x94\xbc\x74\x76\x33\x25\xf2\x01\x8b\x40\xf9\xfa\xb9\xc4\xc0\xc3\x6c\x30\xaa\x90\xef\x7a\x6e\x91\x81\x9f\x62\xf4\x82\x50\x7c\x9a\xbd\xe8\x2a\x9f\x60\xb2\x92\x8b\x74\x25\x1d\x85\xc3\xac\xa2\x25\x14\x41\x46\x72\xc0\x9a\x59\x80\xb1\x64\x70\x5f\x8b\xf0\x15\x8d\x40\x45\x2f\x64\x5f\x5b\xd0\x98\xe2\x28\x08\xa3\x8b\x47\xc7\xe3\x90\xb6\x23\xdb\x10\xd9\x90\x62\xa1\x03\x4d\x6c\x34\x70\x46\x65\x9a\x60\xe5\x56\x92\x0e\x44\xa9\xf9\x96\x84\x0c\x9a\x2e\x23\x28\xa4\x60\x91\x9d\x2c\x52\x75\x14\x46\x69\xe6\x8f\xc7\xa5\x5a\xd6\x4a\xdb\x7d\xdd\xdd\x85\x0a\xf0\xb8\xc0\xd9\x87\xf8\xa2\x44\x40\x31\x52\xca\xe9\x63\x4f\x5b\xd4\x8a\x14\xb4\x3a\x8d\xe7\xc6\xe1\x20\x45\xe6\xb4\xd7\x1b\xf9\xd1\x05\x2e\xd1\xa4\x4d\xf8\xa0\x20\x64\x93\x2c\x65\xf4\x14\x41\x88\x74\x4c\x6a\x24\x1e\x8f\x65\x79\x60\x61\x7e\x93\x8e\x46\x2b\xc0\x1a\x0d\x76\x93\x8e\x4c\x76\xe3\x16\x9f\xe6\xdc\xd2\x18\x64\x80\x8c\x5b\x1a\xc5\x92\xe0\x41\xd5\xf4\x6e\x62\x44\x36\x4d\xfd\xe3\x21\x62\x92\x2e\x32\xae\x29\x68\xb3\x0c\x07\xbd\xe8\xfd\x9a\xd7\xc8\xf8\x01\xda\x96\x49\xcf\x90\x44\x29\x0e\x38\x1b\x75\xc9\x3f\x14\x58\x3a\x1a\x75\xc9\x3f\x54\x78\xb5\x25\x64\x68\xb5\x9e\x44\xd2\x27\x91\xf4\x1f\x2e\x92\xe6\x7a\x7e\xee\x63\xfd\x40\xd9\xa2\xa9\x7f\xf8\x11\xbe\x20\xf3\xec\x27\x9b\xfd\xd0\x91\x97\x20\x5d\x7d\xa7\x16\x85\x44\xff\x5c\x3d\x1f\x0e\xfc\xa9\x0c\xc4\x05\x63\xaf\xb7\x79\x68\x42\x90\x30\x61\x8e\xe8\xcc\x7a\x19\x6d\xa0\x17\xb5\xeb\x41\x27\x78\x15\x34\x06\x41\xab\xf5\xca\x5f\x6b\xb7\x06\xad\x57\xad\x46\xa7\x85\xeb\xeb\xb5\x57\x83\x76\x0d\x37\x5b\x41\xa7\xd5\xee\x34\xfa\x2f\x72\x5c\x6c\x60\xfc\xba\x5f\xaf\xd7\xfb\x83\xda\x5a\x6b\xf0\x6a\x30\xf4\xd7\xd6\xeb\xc3\xda\xa0\xb9\x8e\x3b\xcd\x7e\xd0\xae\x0f\x5e\xd5\xfb\xeb\xfe\xb0\x56\x7b\xe1\xe6\x4d\x14\xc7\xae\x24\xe9\xfa\xfd\xb0\x6b\x19\xc4\x9c\x13\x32\x37\xf8\xae\xb5\x7f\x74\xa7\xa7\x85\x09\xda\x06\x64\x7d\x5c\x2d\x70\xcd\xee\x52\xa8\x0a\xc7\x2c\x9e\xc5\x1f\xbb\x75\xef\xc7\x39\xf3\xf4\x63\xb7\x41\x98\x6d\xfb\x89\xd9\x3e\x31\xdb\x7f\x36\xb3\xcd\x79\x2d\x57\x7e\x69\xcc\xb6\xc8\x30\x79\x98\xc4\x5f\xf0\xc4\x8f\x56\x02\xfc\xf3\xb7\x4a\xe7\xaf\x5f\x90\xde\x27\x5d\x3f\x55\x24\x4a\xdf\xe9\x0b\x25\x23\x81\x56\x22\xd5\x4b\xdc\x25\xf7\xfe\xe2\x19\xfe\x0b\xb2\xf5\xf3\xb1\x78\xfc\x7c\xfd\x65\x73\x7c\xdf\x3b\xc5\xb7\xa5\x4b\x05\x49\xbe\x6d\xa1\x5b\xb4\x11\xfe\x0f\xdb\x5b\x5a\x17\xd2\x6d\x7f\x27\xe9\xb5\x9d\xfd\x7e\xa0\x04\xdb\x3f\x6c\x50\xc2\xd1\x5e\x91\x0d\x65\x18\x46\x38\xb8\x4f\x06\x6e\x9e\x39\x36\x8b\x11\x4b\x5b\x9d\xa7\xb3\x86\x74\xdc\xe2\xb0\x2d\x12\xb2\xae\xa0\x7d\xb2\xb1\x85\x38\x65\x94\x04\xc3\xa4\x8d\xa5\x96\x03\x7b\x6e\x36\x7d\x3e\xae\x3b\x6c\xa4\xbe\x7e\x9c\x8d\xc7\xb7\x92\xb1\x7b\x38\x44\xf8\x3a\x4c\xa1\xb8\x75\xc8\xb5\x16\x0b\x73\xca\xf3\x0c\x36\xbc\x35\x9a\xc3\x46\xce\xbb\xbf\x8c\xea\x67\x55\x47\x9a\xf9\x95\x69\x3c\xad\x54\x21\x6f\x35\xbb\xf7\x22\xfc\x1f\xd6\x13\x8c\xd6\x0f\xb2\x70\xa3\x0e\x37\xb5\x6f\xc8\x31\xcb\x62\x3b\x29\xaa\x76\x10\x2e\x62\x64\xaf\x78\x2f\x9c\xd4\x58\x3e\x7d\x37\xd4\x11\xa2\x24\xe2\x09\x4a\xf2\x74\xde\xef\x70\x56\x91\x4e\xe7\x38\x9a\x4d\x70\xe2\xf7\xc7\xb8\x8b\xb2\x64\x86\x4d\xd5\x9f\x3f\xc1\x69\x61\xaa\x6e\x29\x9f\x37\x14\x06\xe5\x2d\x92\x72\x78\xa7\x73\x92\x78\xa7\x5a\x16\xef\xd4\x91\xc6\x5b\x2f\xf2\x5a\xd1\x88\x89\xe6\xeb\x3c\x7b\x3f\xed\x84\x3d\xbb\x4b\xdc\xff\xc3\x83\xf2\x1e\x1d\x32\xd6\x17\x02\xdf\x4f\x6f\xa2\xc1\x3b\xd8\x6f\x88\xc8\x0b\x5d\xa8\x9e\x29\x39\xd1\x37\x59\x91\x8a\xe4\xa6\xa1\x55\x53\x26\x09\x40\xa8\x2c\x03\x6e\x97\xd1\x12\xe0\xb0\x32\x18\xf9\xc9\x66\x56\xa9\x55\x57\xb2\xf8\xd3\x74\x8a\x93\x9e\x9f\xe2\x4a\x95\x7f\x86\xac\xca\x95\x7a\xd5\xb9\xf1\xf0\x99\x75\x67\x1e\xcd\x37\xee\x3c\x8d\x2a\x8f\x88\xc6\x6b\x5c\x90\x0e\x99\x2b\x46\x08\x28\x4a\x82\x6d\xf1\xd6\x96\x62\x5b\x55\xf4\xf0\xcc\xf6\xa2\x0a\xdd\xee\x25\x8d\x4d\x9e\x8a\xbb\xa8\x83\x7c\xd4\x17\xeb\x65\x7e\xd7\xef\x0e\x02\x86\x72\x33\x27\x6b\x87\x68\xda\xf3\x05\x7b\x55\x32\x3d\xba\x9a\x12\xdd\x3e\xd8\x66\x52\xf4\x5b\x35\x7b\xf9\x05\xce\x16\x4c\x5e\x7e\x81\x5d\xdb\xc9\xf7\x9d\xbb\xdc\x42\x1c\xe5\xb3\x97\xeb\x66\x73\x5d\x59\x1e\x35\x95\xe4\xa7\x67\xaa\x7a\x9d\x4c\x13\xab\xa2\x6d\x56\x25\x13\xa1\xcb\x53\xf6\x58\xe9\xd0\xf9\x00\x49\x07\x73\x2d\x66\x0f\x39\x62\x77\x9e\x8e\xd8\x4f\x47\xec\x7f\xf6\x11\x5b\xd2\x67\x32\x0e\x31\x61\x2c\x5d\x3d\x69\xff\x17\x1e\x0e\x13\x7c\x83\x7e\x0d\xc7\x83\xcf\x18\xbd\xf9\x03\x0f\x87\xae\x68\x3d\x0b\x85\xf6\xd9\xf7\x13\x72\x84\x3f\xf0\xa3\x01\xf6\xa1\xac\x2d\xa8\xcf\x1d\xe2\x00\xb1\x2a\xef\xfc\x4b\xf4\x6b\x1c\x07\xe8\xcd\x85\xf3\x90\xdf\xca\x0f\xf9\xff\xc5\xb8\xa9\xe2\x3c\xcc\x58\x6c\x51\x4a\x5b\x4b\xa0\x3a\x3d\x0b\xad\x2d\x05\x2d\x4e\x92\x58\x0b\x1e\xb4\x4a\xdf\x51\x1b\x04\xba\xed\xec\x65\x2f\x52\xb2\x31\x4e\xe3\x28\x0d\xfb\x63\x4a\x60\x53\x1f\x9c\x48\xd0\x84\xdd\xf9\x90\xbd\x68\x9a\xc4\x97\x61\x80\x93\x54\xd4\xf2\xc7\x69\x6c\x56\x8d\xc7\x63\x52\x95\x50\x1b\xb7\x1e\x47\x51\x1c\xd0\xaf\x61\x34\x88\x27\x32\x64\x02\x8c\xe5\x14\xa0\x57\xae\x59\x38\xc1\x64\xb1\x85\x29\xaa\xa3\x14\x0f\xe2\x28\x80\xdd\x31\x8c\x2e\xc6\x38\x8b\x23\x18\x4e\xd2\xbd\x82\x83\x3e\x47\x55\x39\xee\xf3\x97\x68\x43\x74\x45\xd2\x33\x90\xb6\x41\x03\x7c\x2b\xbd\xe4\xb8\xc8\x5a\x07\xe7\xe1\x8f\x48\x28\xa3\x24\x8e\xe2\x59\x3a\xbe\x81\x30\x18\x8e\x7d\x98\x7c\xb2\x9c\x47\x50\xe0\x67\xbe\xf3\x84\xac\xf6\x56\x51\x79\x44\x81\xd2\x79\x02\x46\x3e\xa9\xfd\xa0\xf4\x5e\x49\x6e\x18\x47\x69\x4c\xb6\x2e\x42\x14\x15\x4a\x1a\x2b\x7b\xd1\xa5\x3f\x0e\x83\x43\x56\xbe\x22\xcb\x3c\xdc\x0b\x1b\x06\x43\x92\xf0\xd5\x3d\x9e\x91\xf9\x4a\x16\x1f\xd2\x77\x80\xd2\x0a\xed\xbd\x07\xdd\x64\xc6\x16\xd2\xf9\x85\x9d\xca\x37\xd4\xb9\xa2\xc2\x2c\x03\xcd\xaf\xca\xa1\x53\xbc\x91\x30\xfd\x85\xa0\x7b\x44\xa9\x10\x0b\x41\x4d\xea\x66\x36\x4a\xe2\x2b\xa4\x76\x4f\x2f\xaf\x74\x87\x75\x93\x7e\x5a\x29\x75\xf2\xf7\x17\x9a\x7d\x90\x66\x0b\x49\x40\x3f\x97\x0a\xe9\x67\x3e\x31\x00\x70\x83\x22\xa4\xe0\xb9\xa5\x68\x83\xa7\xce\x94\x64\xe3\x22\xea\x78\x18\x42\x30\xe7\x9e\xca\xfd\x0c\x64\x09\x79\x9e\x74\x0a\x27\x89\x2e\xe2\x5b\x7a\x53\xd5\xcd\x6d\xc8\x9f\x02\x67\x11\x1a\x9b\x3f\x64\x46\x6d\xb9\x7d\x43\xc8\x65\xd9\x5e\x15\x12\xd4\x83\x73\xba\x8f\x0d\x36\x6a\x2c\x3a\x19\x90\x02\x6f\xc9\x77\x8b\x92\x89\xd6\x7b\x08\xc2\x84\x16\xbe\x33\xc2\x04\x9c\x64\xea\xe4\x4c\xe6\x6e\xa4\x98\x3e\x00\x2d\xaa\x34\xc8\xf5\x6c\x30\x1b\x15\xde\xca\xbd\x48\x2f\x9d\x47\x7b\x4a\x87\x04\xd1\xa1\x39\xdb\x1f\xce\xc4\xbe\x4a\xa4\x4d\x7e\x26\x64\x22\x9f\x41\x71\x19\x9f\x2a\xbb\x6a\xae\x90\x96\x44\x5d\x75\xd7\x77\x6e\xf7\xf3\x76\xee\x8c\x1c\xa9\x98\xe0\xa2\x23\x4a\xbe\x1d\x8a\x4f\x73\x39\x36\x8d\xfd\x7f\x0b\xd0\xf6\x82\xb9\x4b\xc6\xf2\x55\x98\x25\x71\x4c\xb2\x38\x88\xd1\x60\x8c\xfd\x68\x36\x45\x11\xc0\x27\x03\x2c\x8e\xed\x45\x43\x25\x61\x6f\x59\x79\x14\x49\x39\x20\x8a\x68\x5c\x1d\x4b\x22\x1c\x9d\xd2\xd2\x67\x44\x48\x22\xd5\xbb\x88\x02\x09\x83\xae\x01\xa8\x6b\x03\xd9\xcd\x7f\xde\xf2\x9c\xd8\xab\xab\xfa\xe8\x2b\x0c\x80\x09\x60\xea\x6e\xce\x10\xaa\x88\x15\x3e\x67\x72\xe3\xa9\x10\x4a\x89\x08\xca\xcc\x68\xe1\x74\x73\x11\x92\x23\x5d\xa8\xeb\x8e\x49\x1d\xcb\x9c\x1b\x73\x5b\x38\xf2\x02\x84\x4a\xa4\x50\x97\x77\x88\x5a\x96\x59\x06\xf9\xb5\x34\x3c\x39\xfe\x6c\x74\x2a\x4c\xa3\xfa\x19\xdf\xa4\x95\xbc\x6e\x95\x6b\x79\x21\x59\x3c\xfa\xe9\x27\xe4\x1a\x43\x42\x4c\xc9\x09\x7d\x5f\x51\x0a\xbd\x56\xc7\x59\x17\x80\x0b\xc6\x3b\xdf\x7d\x12\x4c\x78\x01\x91\xff\xf9\xb0\x4f\xf0\x60\xe4\x47\x61\x3a\xe1\xc7\xd0\x62\xe6\x00\x00\x8a\x87\x97\xb6\x21\x0f\xec\x67\x8c\xa7\x22\x7f\x00\xef\xec\xea\xcb\x3f\xd2\x51\x18\x91\x86\xae\x07\xf1\x64\x3a\xc6\xd7\x61\x76\xd3\x6d\xc3\x91\x8c\x14\x20\x04\x51\x21\x9b\xc3\x67\x7c\x43\x35\x05\x62\x34\xa5\xf1\x5a\x5d\x45\x09\x9e\xc4\x97\x18\xf9\xe3\x31\xf4\x2a\xf5\x10\xbe\x1e\xe0\x69\x06\x62\x3f\x7b\x25\x97\xcf\x46\xf8\x06\x45\x98\x8e\x48\x1f\xb3\xfa\x01\xe9\xf1\xcc\x1f\x8f\x6f\x50\xff\x06\x86\x8c\x0c\x0f\x4b\x05\x00\x34\xf3\x2b\xd9\x90\xc2\xe8\xa2\x52\x95\xf6\x81\xca\x0f\x4a\xef\xd0\xd7\xaf\x04\xdf\x95\x30\x0a\xf0\xf5\xc1\xb0\x02\x6e\x8a\x84\xd8\xce\x5f\x54\x61\xf2\x97\xeb\xfa\x06\x21\x51\xd8\x67\x7c\x73\xb6\x22\x56\xa2\x6e\x0e\x6d\x52\x24\x29\x6f\x98\x26\xff\x8d\xc9\x13\x4e\x99\x64\xde\x07\xd4\x36\x17\xc5\x51\x19\x9e\x40\x4d\x6a\x8b\x68\x92\x59\x0c\x9b\x2a\x50\x07\x15\xa2\x0e\x01\x67\xe9\x4c\x8a\x33\xa5\xf7\x04\xb0\xa4\x8a\xf4\xd0\x60\x65\xfb\x64\xf7\xfc\xf0\xe0\xc3\x87\xbd\x8f\xef\xce\x4f\xf6\xf6\xb7\x0f\x3e\x9d\xc8\xc7\xa3\x32\x33\x60\x0a\x55\x8a\xc4\xf4\x28\x47\x47\x53\x26\x23\x78\x6d\xf9\x99\x8f\x36\xd0\xe9\xd9\x6b\xf5\xfd\x1e\xb8\x1b\xf3\xd7\xe5\x96\xaa\x00\xb8\x32\x9d\xa5\xa3\x8a\x4e\xf7\x4c\xc4\x53\x4a\xef\x05\x29\x2d\xfc\x19\xdf\x54\x8d\x31\xc8\x01\x2e\x30\x78\xa5\xc4\x4d\x01\x99\x35\xca\x97\xd4\xc4\x9f\x2a\x4c\x32\x04\xb2\x05\x86\x02\x24\x46\x48\x53\x1d\xa6\x7d\x7f\x2a\xa9\x2e\x24\xbd\xb6\xea\x29\x4e\x05\x57\xe0\x1a\xd5\x3f\xf5\x31\xd8\xf7\xa7\xa7\x50\x2d\x84\x2d\x9e\x8f\xcc\x29\x14\x3f\x93\x3c\xd2\x45\xe3\x8a\xdf\x3c\x5a\x58\x66\x8e\x55\xa9\x59\x09\x6f\x72\x72\xb0\x75\xd0\xe5\x44\x86\xc6\xf1\xc5\x7f\xe8\x52\x75\xec\x90\xab\xef\x2b\x49\x97\x50\x16\xa4\xd6\xa3\x23\xfb\xb6\x32\xf1\xa7\x15\x97\xb1\x02\xff\x03\xfb\xc5\x20\x1f\x65\x32\xf6\xec\xa8\x17\x06\xb2\xe3\x8d\xa0\x88\xcf\x18\xa5\xb3\x04\xf4\xc4\x9c\x59\x85\x29\x4a\xb3\x90\xd0\x03\xe5\xe4\x38\x40\xfe\x10\x1c\x84\x92\x24\xbc\xf4\xc7\xda\x5e\xab\xc0\x24\x03\x02\x6e\xff\x74\x69\x84\xc1\x99\x8e\x62\xde\xa5\x95\x41\x6e\x0f\xa0\xd6\x11\x5f\x9c\x0e\x33\x5c\x77\x22\x7f\xba\x45\x78\xcc\xf4\xcc\x96\x1a\x43\x7f\x9c\x62\xf9\x96\x8d\xb9\x3d\xcd\x1d\x53\x91\xce\x9f\xb5\x89\xee\x00\x83\xcc\x0b\xcc\xb8\xb4\x68\x1d\x87\xff\xd7\xc6\x78\xfe\x00\x35\x4b\x8c\x63\x79\xc5\x00\x52\x28\x4c\xea\x25\x54\x54\x47\x49\x5b\xec\xee\x61\x52\x71\x71\xeb\x19\x90\x7c\xc9\xe9\xca\xb8\x74\xa4\x07\xd5\x50\x6f\xbc\xb4\xd4\x4b\x66\xea\x0a\xa6\x90\xfe\xb1\xdb\x80\xd0\x3e\x4c\x19\xfe\x63\xb7\x09\x6e\xa8\x6b\x65\xee\xc8\x58\xcc\x4d\x9c\x65\x61\x74\x61\xf7\xec\x05\xc6\x14\x48\x99\x6b\xd1\x86\xf0\x59\x7b\x6d\x94\xc8\x23\x3d\x0b\xfb\x20\x57\xd0\x22\xd6\x28\xeb\x37\x41\x79\xfd\xe9\x5a\xef\xe9\x5a\xef\x1f\x7e\xad\xc7\x22\xfa\xb2\x53\xcb\x5d\xa2\xfa\xce\x33\x87\x75\xe4\xbe\xd0\x52\x5f\x2c\x62\x38\xcb\x97\x74\x9d\x1d\x0e\x36\x83\x20\x85\xa1\x13\xbb\x9b\x1f\x81\x5a\x2a\x45\x33\x2a\x7e\x31\xa7\x37\x8f\x08\x5f\x61\x06\x91\xf2\x10\x24\x05\xa0\x9b\x2a\xdd\xed\x9f\x3f\x97\xcf\x07\xec\x7c\xf6\x5c\x57\x12\x91\x6d\xf3\x39\xbb\xb6\x92\xca\x49\xbc\x8a\xc6\xe9\xe1\xae\x74\xa4\x5c\x1c\x31\x87\x2b\x85\xa3\x31\xb9\x89\x8c\xbd\x45\xd5\xe8\x12\x8a\xe8\xbe\xcd\x7b\x9a\x5a\x36\x0b\x9b\x3d\x0e\xff\x53\xf7\x2d\x7d\x7b\x72\xe9\x2e\x85\x85\x20\x0f\x44\x04\x28\xff\xf4\x13\xe0\x4e\x15\x53\x61\x74\x01\xdc\xb8\xaa\x40\xe4\xd7\x17\xf3\x52\x9a\x52\x88\xb2\x97\xf2\x5d\x3b\x29\xa4\xa1\xb1\x9f\x42\x33\xc7\x19\x99\xec\x1f\x36\x36\x8c\x81\xe6\x7f\xc6\x8b\xd5\x55\x9a\xb9\x5d\x21\x29\x58\x6a\x59\x32\x23\x32\x5b\x92\x66\x28\x8d\xa9\x9d\xe3\x74\x0a\xac\x1b\xce\xce\x7e\x74\x93\x91\x03\xbf\x87\xfa\x78\x48\x18\x00\x5d\xe2\xfc\x0a\x15\x46\x83\x2a\x19\xb5\xbf\x70\x58\xf9\xc1\x82\xf5\x4f\x3f\x21\xdb\xc8\x57\x8d\xfa\xc8\xbc\x6e\x20\xa8\x5a\xdc\xa3\x9d\x9d\x8d\x29\xdf\x8c\xf0\x75\x86\x7a\x87\x9f\xd0\xe0\x66\x30\xc6\x9e\xe8\x26\x0c\xbb\xd8\x6c\xa0\x27\xd0\x65\x66\xb3\x34\x4d\xe2\x01\xe1\x59\x29\x1d\x1d\xa3\x15\xe9\x18\x2c\x96\x89\x6d\x2e\x2c\x1d\x61\xa4\xa1\x97\xba\xf5\x50\xad\x4c\xff\x2c\xc3\x4a\x49\xc1\x25\x9a\x49\xc6\x60\xcf\x05\x00\xdd\x8c\x4d\xd2\xc5\x56\x4c\x3b\x28\x47\xba\x5f\xdd\x12\xea\xd6\xcb\x85\xf0\xbd\xc0\xcb\xd9\x04\x7b\x2f\xeb\x90\xa8\xce\x00\x38\x0b\x59\x27\xdc\x4e\x72\xcf\x9a\x96\xd3\x99\x6b\xb3\xd8\x64\x5e\x93\xff\x90\xac\x6b\xda\x23\x72\xb4\xa4\x9c\x5a\xa2\x5c\x78\x69\x49\x2a\x27\xd6\xab\x74\xd2\x87\x0f\x7e\x10\x08\xdb\x2e\x29\xef\xa7\xf8\xae\x4f\x8f\x74\x70\x90\x58\x2c\x37\xde\x82\xf7\x92\xad\x38\x15\xe8\xc4\x48\xc8\x96\xbe\x79\xbb\x85\x16\x8b\xe1\x30\x7f\xa5\x6a\xa5\x72\x16\x04\x5a\x05\x0d\xf9\x52\x48\xc8\xb3\xe8\x96\x68\x0d\x02\x13\x2a\xe7\x8a\x34\x07\xd5\x82\xd1\xb6\x4a\xb5\x02\x21\xb7\x01\x1b\x91\xd5\xd5\x6c\x17\x44\xf6\x7d\xca\x51\xfa\x24\xfb\xfe\xd3\x65\xdf\xdc\xa4\x8d\x27\xec\x7d\x28\x1f\xdd\xbd\xbe\x1f\xa9\xd2\x6e\xd8\xf7\x85\xeb\x2d\xbe\xa6\xea\xea\x22\xd7\xdd\xe3\x89\x9f\x64\xdb\xac\x60\xee\x76\xeb\xbc\x1a\x03\xb5\x12\x34\xcb\xfb\xa2\xe9\xbc\xa5\xd7\xe2\x12\xec\x38\x4b\xc2\xe8\xe2\x16\x5c\x5b\x6c\xef\x89\xb4\xdc\xf7\x23\xf9\xd3\x2f\xfe\x78\x86\x6f\xd1\x25\xf9\x0f\xbb\x0e\x21\x90\x87\x38\xc1\x73\x6e\x48\x3d\xd5\xbc\x00\x82\xd4\x30\x9c\x54\xb1\x38\x1b\x79\x80\x11\x91\xd6\x3d\xda\x92\xb9\x85\x81\xda\x8d\x8e\x32\x64\x9b\xee\xfb\x51\x25\x8b\xab\x4c\x55\x04\x3a\x1c\xf2\x99\xab\x7c\x2a\x16\x2b\x22\x52\x0f\xd2\x44\x54\x5e\x84\x54\x7d\x43\x21\x32\x3f\xdd\x17\xa6\xfe\x98\x41\xdc\x0a\x13\x22\x8b\xd9\x1c\x62\x78\x8f\x4e\x62\xe6\xd9\x2b\x77\x07\xaa\x33\xe8\x95\xaa\xd9\x35\xde\x9e\x90\x63\xa0\x1b\x36\x49\x17\x5c\x24\x84\xa7\x34\xce\x46\x72\x4a\xf0\x4a\x15\x1a\x61\xd8\x46\x69\x16\x66\x33\x2a\x70\x99\xe6\x5f\x01\x9e\xc6\x69\x98\xc9\x58\x32\xb8\x02\x3d\x00\x33\x18\x87\x38\xca\x74\x4b\x8c\xd2\x0d\x1b\x26\x16\x3c\xd5\xb8\x39\x82\x8b\x62\x64\x8e\x1f\x57\xc1\x17\x5e\x25\x0b\xd2\x1b\xce\xa2\x00\x6c\x22\x07\x38\xc9\xfc\x50\x4c\xbf\x63\xf9\x88\x89\x5d\x6c\x1d\x3d\xfa\x12\x12\x78\xdd\x61\x2d\xb1\x91\x27\xb3\xa9\x65\xfc\x92\x64\x5b\xe1\xbd\x9e\xc5\xb9\x44\x4b\x40\x77\x69\x03\x12\x6d\x8e\x67\xb8\x4b\xff\xc3\xc5\x5c\x2d\xd9\xbb\x73\x56\xd8\xe4\xe7\x93\x02\x71\xed\xc3\x01\xe2\x9c\x10\x71\x0e\x89\x2a\x93\x59\x9a\xc1\x56\x87\x27\x38\xca\x04\xdd\xf4\x6f\x32\x9c\x36\x1b\x55\x26\x8c\xff\x50\xd5\x26\x92\x95\x7b\xf0\xe9\x23\x93\xa0\x4d\x20\xaf\x4f\x49\x15\xcd\xa2\xf0\xbf\x67\x18\x85\x01\x8e\xb2\x70\x18\xaa\xac\xb8\xd4\x64\xf3\xe1\x29\x31\xc5\xd0\xa4\x9d\x6d\xfa\xb0\xed\x48\x9b\xd0\x6b\x9d\x0a\xf8\x20\x57\xfc\x7e\x58\x5d\xf1\x33\xc2\x59\x57\xf8\x00\x73\xd0\x7f\xde\x97\x0a\x0c\x61\x95\x0f\xa3\x35\x0a\x82\xb9\x21\xfe\xd8\x6d\x12\xd9\x95\x67\xee\xbf\x3d\xf3\xda\xa5\x72\x25\x33\xf5\x6e\xbb\x54\xc2\xb6\xd7\xb2\x16\x3e\x26\x02\xc6\xd0\x1f\x64\x71\x72\xe3\x51\x8d\x32\x19\xd8\x67\x84\x4f\x13\x59\x3f\x1e\x22\xd1\x9b\x8d\x0d\xf4\x23\x8d\xc8\xf4\x23\x94\x79\xb6\xba\x8a\x7a\xf1\x64\x12\x47\xff\x75\xfc\xfc\xd9\x33\xa3\xf3\xf9\x2f\xd6\x00\xc7\xa9\xf2\x23\x19\x86\x04\xff\x58\xf5\x90\xf4\x0a\x47\x83\xe5\xbe\x9f\xe2\x4e\x4b\xfb\x30\x09\xda\x7a\xd1\xcb\xe9\xe7\x60\xa8\xbd\x1c\x84\xd3\x11\x4e\x96\x29\xe4\xea\xeb\xe7\xcf\x6e\x9f\x3f\xc3\xe3\x14\x23\xa9\x33\x54\x63\x4e\xfb\xc2\x87\xe1\x47\xf4\xd3\x4f\xec\xc3\x8a\x3f\x09\x44\xdf\x36\xf7\xb7\x9e\x3f\x7b\x46\x3f\x54\x4e\x39\xce\x1e\x52\x51\x85\x67\x82\x21\xfd\x40\x11\x83\xdf\x32\x3e\x67\x62\x94\x65\xc4\x58\x43\x34\x1c\x06\xaa\xf4\x93\xf8\x2a\xc5\x49\xf5\xf9\xb3\x67\x62\xc4\xe2\x38\x5b\xe9\x25\x37\xd3\x2c\xfe\xaf\x63\x5a\xf5\x16\x8e\x4f\xf2\xfe\x23\xbe\xa3\x3f\x9f\x3f\x7f\x56\x51\xcf\x63\xcf\x10\x55\x89\x1c\x8f\xe2\x24\x1b\xcc\xb2\x94\xbe\x21\xcb\xa6\x87\x36\x10\xaf\xfb\x5a\x7a\x7d\x3e\x0e\xfb\xe4\xd3\xca\x38\xec\x4b\xef\x41\x1b\xd6\x83\x4e\x91\xaf\xa4\xd4\x8a\xf4\x4e\x81\xe0\x8f\x2f\x62\x00\x41\x7e\xbc\x7e\x2e\xb0\xf8\x10\xc7\x9f\x67\x53\x94\xf9\xfd\x31\x96\x30\x39\x7e\x7b\xf0\x1b\x3b\xf4\x89\x77\x7b\x1f\x7f\x39\xb7\xbd\x3f\xfe\xf4\xf6\x7c\x7f\xef\xb7\xf3\x9a\xeb\x43\xdd\xf5\xa1\xe1\xfa\xd0\xb4\xb6\xed\x6a\x47\xfe\x68\xb4\x25\x7f\x34\xda\x93\x3f\xf2\x36\xc5\xd0\xf4\xe2\xc9\x94\x9c\x14\xc7\xe6\x10\xd9\xa6\x54\xab\x15\xc4\xb3\x3e\x11\xfb\x49\xad\xbc\x00\xb0\x58\x19\x0b\x24\x9b\x2a\x84\x10\x4e\x10\x85\xe8\x0d\x6a\xb4\x3b\xaf\x51\xb8\xb4\xa4\x80\x17\x42\x22\x7a\x83\xea\x8d\x75\xe3\x1b\xf9\x0b\x4e\xc3\x33\xb4\x41\x60\xbc\x41\xf5\xd7\xea\x77\x7a\x97\x5a\x50\xab\x42\xab\x55\xd1\xef\xa8\x76\x5d\xaf\xf7\xf5\xfa\xf9\xe3\xed\x73\xa5\xd7\xbf\xfa\xe3\xcf\xe8\xdd\x4e\xa5\xf1\xfb\x7a\x55\xed\xed\x35\x0d\x91\xa8\xbe\x0b\xb5\x97\x0b\x8d\x80\x34\xc8\x69\x3f\xbe\x56\x3f\x82\xa5\x01\x69\xf3\x3a\x44\xbf\xa3\xca\x75\xde\x21\xf6\xbb\x21\xfd\x6e\x4a\xbf\x5b\x55\xad\xb3\x00\xa5\x92\x5e\xa3\x9f\x7f\xfe\x19\xad\x43\xc9\xf4\x1a\xfd\x84\x6a\xd7\xc3\x21\x1d\xa0\x4e\x53\xab\x42\x56\xc7\xe9\x35\x19\xc8\xf4\x5a\xfb\xc4\x17\xcf\x69\x0a\xdf\xaf\x5f\x3f\x77\x76\x6a\x32\x1b\x67\xe1\x74\x1c\x0e\x40\x4d\x60\x76\xef\x9a\x90\x71\x70\x7a\x7d\xf6\xda\xf2\xad\x45\xbf\x35\xac\x1f\xd7\xe9\xc7\xd6\x59\x41\xeb\xe9\xac\x8f\x40\xc0\xf1\xd0\x24\xbc\x46\x83\x78\x3c\x9b\x44\xa9\x42\xfd\x32\x4c\x22\x29\x54\x02\xe8\xd5\x4b\x42\x33\xb5\x3a\x1f\x29\xf6\x58\xab\xd7\x6a\xfa\xd0\x8a\x95\x4c\x07\xab\x92\xc1\xc4\xb4\xaa\xe8\x2b\xf9\x4d\xc7\xdb\x51\xa5\x2e\x57\xa9\x77\xa4\x2a\xf5\x8e\xab\x4e\x43\xae\xb3\x5e\x45\x79\x9d\x86\x31\xeb\x82\x1b\xd0\x3a\x59\xc1\x48\x85\xd1\xa5\x3c\x5a\xe4\xb1\xf4\x88\x5d\xaf\x4b\xe3\xc3\xc8\xb3\xc5\x5e\xd5\xf8\x8b\x86\x32\xa4\x85\x23\xaa\xf0\x47\x46\x63\x65\x86\x55\x61\x9d\x4a\xbd\x39\x63\xab\xb0\x55\xa5\xe2\x9c\x01\x56\x58\x2e\xab\x58\x34\xca\x70\x5b\x00\x8a\x60\x9c\x98\x9c\xf0\x87\x6b\x2b\x13\x64\x0c\x60\x63\x01\x0e\x08\x55\x1a\xe8\x77\x14\x9c\x92\xff\x5d\xaf\xa3\xdf\xd1\x75\xe3\xec\x4c\x5f\x48\x50\x36\x44\xbf\x6f\x40\xc1\xeb\xd0\x28\xa0\x30\x49\xf8\x79\x0b\x87\x5a\xb1\xaf\x1c\x26\x78\x40\x3b\x17\xa0\xa3\x41\x1c\xb1\x0d\x26\xdf\x95\x8e\x7a\x07\x1f\xc9\x1e\x51\xbb\xae\xd5\x3c\x54\xbb\xae\xd5\xe1\xdf\x06\xfc\xdb\x82\x7f\xd7\x3d\xa0\x05\xf2\x6f\x03\xfe\x6d\xc1\xbf\xeb\xf0\x6f\xbd\x4f\xfe\x6d\x76\xf2\xcd\xec\xe5\x4b\x86\xd4\x4b\xb4\xb9\x7d\x4c\x03\xb2\x23\x2a\x0e\x21\x22\x10\x24\x61\x36\x9a\xac\xf0\x32\xab\x39\x2a\xa4\xf4\x06\x13\x1f\x56\xe8\x83\x24\x61\xac\xe0\xeb\x8c\x86\x0f\x10\x5d\x3e\x0f\xe2\x23\x9c\xe2\xac\x8b\x1c\x5b\x24\x1b\x84\xe3\xcf\xe1\x94\x99\xfe\xc6\x43\x14\x1d\xc5\x70\x1c\x1b\xf9\x29\xea\x63\x1c\x81\x7b\x00\xbb\xe0\xf2\xa3\x00\x6c\xf8\x82\x30\x40\x51\x9c\x31\x3b\x4c\x93\x14\x68\x36\x17\x0e\x89\xdb\x8b\x9e\x7f\xc6\x37\x87\x49\x18\x27\x47\xd4\x04\x78\x63\x23\x7f\x6f\x25\x1d\x6e\x17\xa6\xcd\xa9\xd9\x01\x55\x7c\xe3\x7f\xdc\xe2\x70\xc3\xde\x7c\xfe\xd6\xc2\x9f\x3f\xe3\x9b\x5f\xe3\x04\xac\x18\x3f\xe3\x9b\x95\x2b\xf2\xdb\x5e\xec\x38\xfc\x82\x59\xa9\x34\xbc\x78\x4b\x18\x10\x5a\x45\xad\xa2\x65\x24\x1c\x01\x12\x18\x20\x13\x2c\x1f\x39\x8e\x63\xfe\xcc\x1b\x5c\x42\x9d\x52\x2d\x90\xfe\xa7\x83\x11\x26\xc7\x0f\x44\x44\x68\x4b\x1f\xd2\xa3\xf8\x8a\xc0\xae\xf0\x66\x96\xc8\x2e\xfd\xb2\xb0\x0f\x32\x5c\xfb\xb0\xf0\x46\xa5\x71\x96\xde\x9d\xea\x4b\x35\xb7\x11\x25\xe8\x50\xd1\x83\xfe\x7c\xc3\x30\x64\xcf\x16\x29\x04\x31\xb2\x13\xe5\xe9\x20\x59\xcb\x91\x3f\x09\x95\x53\xa8\x73\x46\x47\x16\x66\x9c\xbd\xb1\xb0\x1a\x37\xc3\x42\xd2\x7e\x62\x00\x87\x70\x3a\xfa\x50\xca\x68\xff\xc0\x10\xff\x97\x40\xdc\x89\x39\x9b\x85\xa3\x38\x43\x84\x24\xdd\x85\x32\x79\x0f\x50\xb7\x80\x42\xc8\xc7\xb3\x7e\x19\xc8\x20\x3e\x71\x98\x67\xd2\xde\x06\x1f\xf2\x9d\x8a\xc9\x68\x67\xd2\x2e\x26\x97\x58\x57\x0a\x00\xa6\x0c\x32\x7b\x3d\x07\xdb\xfd\xf0\x1a\xd8\x76\x11\xb6\xbf\x6f\x00\x13\x3f\x65\x83\xbc\x9a\x53\xc7\x57\x54\x63\xa8\x5b\x26\x1b\xe5\x13\x0e\xa4\xc5\xd6\xdd\xcf\xa8\x43\xf8\x99\x36\x61\x68\x63\x03\xb5\xe6\x4d\xda\x77\x37\xb4\xf6\x3e\x3b\x46\xdc\xb5\x66\x0c\x5a\x67\x43\x72\x86\x7e\x27\xb2\x84\xb9\x88\xe6\x72\x73\x59\xa6\x2b\x66\x33\x61\x74\xf9\xde\xc2\x69\x8c\xd7\x6e\x66\x43\x8a\xe6\xfc\x46\x3c\xe5\x2c\x87\xbf\x72\x70\x1d\x99\x61\x31\x3e\xba\x2c\xea\xd8\x88\x17\x8e\x8c\xbc\x99\x7f\x15\x10\x8d\x93\x9d\x3c\x2c\x67\x6a\x59\xc1\xcd\x43\xfc\x0d\x6a\x81\x27\x0b\x7d\x28\xa2\x7d\x75\x2e\x4e\x39\x04\x26\x69\x2e\xd8\x91\x02\x60\xaa\xd0\xad\xae\x21\x42\x8a\xaa\x70\xed\x58\x4a\x67\xe8\x77\xf7\xe2\x74\xfc\xa9\xc2\xb7\x7d\x05\xea\x08\x34\x4f\xd5\xa5\x68\x9f\x03\xa7\x24\xeb\x49\xd3\x83\xa3\x41\x72\x33\xa5\xa6\xb1\xb2\x9c\xb7\xef\xa1\x78\x38\x4c\x71\x66\xcc\x0c\x5d\x23\x41\xdc\x13\xf5\xf2\xc2\x9e\xb9\x57\x7b\xf9\x09\x31\xff\x59\xcf\x7f\x36\xf2\x9f\x4d\x0f\x58\x8c\x7c\xca\x50\x70\x0d\xf0\xa2\xb8\x12\xae\x79\xe5\x4f\x51\x23\x0a\x40\xf6\x6c\x65\x23\x87\x10\x43\xe8\x7b\xff\x94\x82\x21\xf2\x8b\x3e\xa4\xca\x37\xb5\x6c\xb3\xa0\x6c\xd3\x7a\x24\x2a\x33\x84\x2a\xad\x7a\x2a\x81\xaa\x8f\x75\xf5\xb1\xa1\x3e\x36\x3d\xa1\xb0\x30\x36\xef\xd5\x55\xb4\x47\x4e\xbe\xdf\xc5\x18\xd9\x27\x5d\x19\x26\xeb\xac\x7b\xe8\x7e\xe4\x66\x23\x1a\x76\x20\x28\x2d\x59\x5b\x06\xf6\x1d\x66\xc1\x42\xe1\x46\x92\x8a\xea\x04\x53\x8b\x8e\xab\x26\x0d\xd6\x19\xbc\xfe\x5d\x61\xb6\x35\x9b\x06\x28\xad\xeb\xd3\xa1\xd5\x32\xe6\x07\x6a\x35\xd4\x5a\x0d\xbd\x96\x55\xdb\x94\x36\xf5\xe9\xd4\x6a\x35\x6d\x6a\xa8\xf7\xda\xd9\xc1\x7e\xf4\x97\xb7\x40\xdb\x89\xe1\xc8\x72\xc6\x11\xfb\x2f\x1d\xd5\x0d\x54\x7f\xcd\x7e\xbe\xe1\x33\xc4\x5e\x38\xf6\x5d\x98\xe3\x70\x98\x01\xa5\x7b\x0e\x45\x59\xe1\xc4\x71\xd4\x33\x32\x79\x92\xba\xa6\x26\x24\xaf\xdf\x25\x45\x57\x25\xad\x1b\x72\xd7\xef\x92\x52\xab\x92\x36\x74\xa9\xeb\x77\x49\x7f\x95\x36\xa5\xd7\xc6\x36\xbc\xb4\x64\xdb\x00\x00\xb9\xba\x8a\x5c\xdd\x81\x5c\x63\x0e\x72\xcd\x42\xe4\x6a\x77\x44\xae\xa1\x22\xd7\x70\x20\xd7\x9c\x83\x5c\xad\x10\xb9\xfa\x1d\x91\x6b\xaa\xc8\x35\x1d\xc8\xd5\xe6\x20\x57\x2f\x44\xae\x31\x17\x39\x2b\xe9\x7e\x9a\x82\x11\x51\x9a\xf9\x19\x36\x0b\x00\x3b\xc9\x6a\x96\x8e\x01\xcb\xc8\x74\x3d\x1a\x7c\x21\x73\x91\x35\x6c\x5f\xc8\x40\x64\xba\x76\xdc\xaa\x44\xb1\xae\xa7\x39\xbc\x0f\x96\x4f\x85\x9e\x3c\xa4\xb5\xa3\x9f\x5a\x2c\xcb\x47\x3f\xb6\x98\x2b\x48\x39\xb7\xe4\x4b\xa8\x5a\x8e\x12\xc4\xfa\xe1\xd8\xd5\xdd\xd8\x99\xeb\xc7\xc0\xce\x58\x42\x2a\x76\xb5\xbb\x60\xd7\x90\xb0\x6b\xb8\xb1\x33\x17\x90\x81\x9d\xb1\x86\x54\xec\xea\x77\xc1\xae\x29\x61\xd7\x74\x63\x67\xae\x20\x03\x3b\x63\x11\xa9\xd8\x35\xe6\x63\x67\x52\x2b\xe6\x91\xad\xed\x72\x09\xdd\x86\x2d\xeb\x48\x17\x72\x8c\xe5\xa4\x6e\xae\x96\x55\x65\x88\x3e\x4d\x97\xec\xc3\x8e\xc2\x5d\xd4\x68\x77\x56\x9b\x0d\xa6\x81\xae\xda\x54\xc1\x5c\x62\x11\x02\x52\xca\x3c\x87\x99\x6a\xf8\x45\xca\x12\x3e\x21\xc8\xe1\x3d\xf4\x07\x58\xe8\x88\x05\x90\xff\xc4\xd7\xfe\x64\x2a\x4e\xca\xf9\x07\x3e\xa7\x14\x56\x86\xaf\x33\xe9\x76\x7b\x65\x73\xfb\x78\x85\x9d\x23\x2a\x13\x6e\x92\xfe\x19\xdf\x78\x68\x30\xbc\x10\xd2\x7c\x0e\x65\x3a\xf6\x09\x12\xd7\x19\xd2\xa1\x30\x09\xbf\x92\xb7\x63\x03\xc4\x74\xda\x3d\x8b\x12\xfb\x9c\x86\x4d\xdd\xc5\xe3\x29\x4e\x2a\x9b\xdb\xf4\x5a\x9f\xea\xec\x9f\x3f\x63\x36\x2b\x72\x93\xaf\x9f\x3f\x87\x10\xb8\x60\x40\xa2\x58\x15\x74\xdb\x0d\x8f\xdb\x25\x74\xdb\x60\x3b\x22\x59\x26\x74\xdb\x2d\x2f\x37\x49\xe8\xb6\xc1\x87\x71\x12\xb4\x7f\xec\x76\xea\xb7\x67\x5e\xbb\x71\x2f\x6b\x91\x6f\x69\x26\xf2\x68\xc6\x1c\xdf\xd0\x2c\x83\xae\x84\x97\x88\x19\x50\x90\xe6\xd1\x20\x9e\x4c\xe3\x08\x62\xae\x93\x6f\xab\xcf\x9f\x89\x79\x1f\x87\xfd\x15\x56\xf4\xeb\x57\xd9\x00\x40\x78\x7d\x3e\xb0\x71\x87\x9f\xe2\xdc\xaa\xc3\x4f\xb1\xf4\xed\xd7\x38\x09\xc0\x2f\x5d\x14\x10\x6f\x64\x08\xb3\x21\x18\xfc\x01\xad\x6f\xf2\x5b\x9e\x1c\xa6\xf5\xb3\x82\x19\x06\xd7\xaa\x1e\x59\xa8\xd2\xfb\x4f\xd9\x70\x1d\xa0\xe0\x68\xb0\x42\x1e\x34\xac\x3b\x2d\xf1\x95\x3e\x16\x19\xa2\x88\x2f\xdb\x97\xd3\xf7\x5b\x3b\xf9\x65\x13\x7d\xb6\xde\x60\xf5\x53\x6a\x9f\x47\x96\x15\xbf\xc5\xca\xf0\x64\x3a\xf6\x33\x1b\x83\x12\x51\xa6\xff\x8c\x58\x44\x1e\xae\x41\x05\xaf\x02\xc1\xeb\x40\xef\x17\x7e\xc1\x2b\x3c\xc2\x64\x17\xb5\x50\xa5\xde\x58\x47\xfd\x30\x4b\xab\x45\x00\xc3\x4b\x0b\xbc\xbd\x5f\xee\x0a\xee\x7c\xfb\x63\xef\xfc\xb7\x9d\x83\xa3\xfd\xf3\xfd\x83\xad\x6d\xb4\x09\xb1\x0d\x32\x3f\xca\x50\x82\xa7\x09\x4e\x71\x94\x85\xd1\x05\x57\xc4\x10\x32\x9c\xc4\x41\xde\x77\x2b\xcc\xad\xed\x52\x30\x19\x3b\x35\x60\x4a\x97\x82\x9a\xc9\x91\x78\xb4\x53\x94\xe5\x92\x30\x9f\x4d\x8a\x6e\x0f\xfc\xbe\x67\x09\x18\x3c\x88\x24\x1f\x72\x11\xa5\xb8\xd4\x3b\x41\xf7\x64\x0e\xd0\xc9\x08\x93\x51\xcf\x62\x34\x63\x7e\x02\x84\x05\x20\x52\x18\x40\x2b\x20\x57\xf3\x87\xc1\xf0\xa2\x0b\xa4\xcb\x71\xad\xca\x3b\xaa\x81\x2d\x6c\x17\x29\x85\xcd\xc8\x2f\x8c\x5c\x93\x61\x43\x9f\xda\x63\x4a\xb8\x13\xd2\x23\xc8\x7f\xc6\x37\x2b\xd6\xb2\xdc\x35\x74\x30\xbc\x40\x95\x03\x68\xc5\x1f\x57\xa1\xce\xc0\x36\x78\x25\xc7\x40\x6d\x8b\x07\x12\xa5\x13\x7a\x4b\x48\x84\xf7\x8e\x10\xca\xa0\xa8\x4f\xe4\x5c\x11\x0e\xdc\xdf\x55\x29\xc1\x2c\x80\x14\x69\x41\xde\xe3\xf9\xd5\xf3\x0a\xdd\xa6\xb7\xe9\x30\xc7\x49\x85\x5d\x9e\xc1\x10\x7a\xe8\x4f\x14\x5e\x76\x51\x78\x99\xf3\xc6\x5b\xc5\xf4\x40\x99\x6f\x15\x52\x57\x89\x0b\xc5\x24\x07\x5d\x03\x20\x67\x0e\xa1\xf5\xd9\x8d\xb3\xba\x56\x2d\xb2\x87\x2e\xa1\x95\xa4\x27\xc7\x42\x7c\xa2\xa7\x87\xa5\xa7\x2d\xfc\x50\xf4\x24\x20\xdd\x8f\x9e\x54\x3e\x7d\x07\x7a\xda\x8b\xc2\x2c\xf4\xc7\xe1\x17\x9c\x22\x1f\x45\xf8\x6a\x7c\xc3\x30\x0c\xd8\x70\xcc\xa7\x25\xbe\x6b\x5c\x0f\xe3\x64\xb2\x1f\x07\x18\x6d\x53\x67\x35\x88\xd3\x9c\x73\xba\x38\x91\xe9\x14\xac\xab\xc1\xcf\x8f\x53\xad\xd8\x64\xec\x64\xf8\xdd\x91\xec\x83\x91\x55\xc5\xfc\x60\xe3\x14\x77\x24\xb8\x30\x0a\x15\x0b\x1b\x31\x4d\x12\xb9\x58\x54\xd4\x9b\xd3\x29\xa1\x05\x18\x2d\x9e\x6e\x3a\xb5\x5c\x33\x90\x21\xde\x10\x3f\xf9\xa6\x48\x69\xd0\x3c\x15\x67\x44\x72\xa6\x86\xf5\x71\x32\xa1\xd3\xee\xdb\x74\x37\x94\xbe\x73\x92\xda\xc8\xc9\xeb\xb5\xad\x24\xb5\xa3\x01\x5b\x19\xeb\x59\x3c\xa4\x84\x4e\x3d\x00\x6c\xfd\x00\xfb\xa2\x4a\xe9\x85\x03\x36\x3a\x2a\x1f\x86\x60\x0e\xa9\x68\x09\xb4\x67\xf7\x24\x1f\xb6\x04\x4d\xdc\x94\x19\x4e\xca\x18\x51\x51\xa3\xa2\xc0\xcf\x7c\xd4\x07\xd9\x4b\x2d\xe1\x90\xc7\x00\x34\x4d\x75\xc1\xdd\x9d\x75\xc0\x87\x38\x81\xb9\x1c\xc4\xd1\x20\xc1\x19\x5e\x66\xc3\x31\x8e\x2f\x14\xa6\x2c\xdd\x4b\x1d\x2d\x36\xd6\x10\x50\x03\x30\xa7\xfe\x2d\x8c\xa7\xe0\x40\x62\x29\x38\x58\x60\xd3\xfb\x9a\x32\x57\x18\x02\x94\x29\x3b\x09\x6f\xe0\x6d\xb0\x06\x24\xf0\x25\x76\x2e\x89\x3f\x09\x58\x34\x6a\x16\x8b\x46\x10\x46\x17\x0f\xc0\x4d\xf2\xce\x6f\x70\xf2\x60\xf0\x2b\x2f\x48\x9b\x2f\x54\x32\x29\x53\xef\x8a\x63\xee\xa4\x30\x56\xb2\xab\x85\x79\xa5\x43\xe7\xe0\x1e\x38\x0a\x6c\xb3\xef\xc3\x17\xb9\xba\x8d\xa6\x68\x7b\xc8\xbf\xf4\xc3\xb1\xdf\x1f\x63\x6a\x86\x98\xba\xb7\xc5\x73\xde\x99\xd2\x54\xb5\x13\x46\x6c\xe3\x2b\xdc\xa7\x18\x5c\x75\x9f\xf9\x18\x67\xcc\x3d\x9a\x46\x4d\xa3\x90\xf2\x5d\x03\x85\x29\xc2\xc3\x21\x1e\x64\xe1\x25\x1e\xdf\x20\x1f\x05\x38\xcd\x92\x19\x3c\x7b\x28\xc1\x7e\xb0\x1c\x47\x03\x5c\x6a\x9f\x29\x4b\xbd\x80\xc6\x63\xd1\x30\x05\xfe\xd8\x94\xcc\x47\xb2\x52\x9e\x88\x45\x95\x45\xa9\x5f\x54\x9c\x4f\xfe\xbc\x68\x79\xfa\xdf\xc9\xe7\x62\x06\x85\xd4\x12\xe1\xb0\x10\x00\x2a\x5c\x2d\x4a\x51\xcb\x45\xc9\x02\x0c\x19\x02\x22\x11\x54\xd9\x82\xc3\x01\x0b\x98\xc9\x39\xf5\x8e\x34\x21\xd6\xc5\x67\xd6\x9e\xab\x6c\xae\x37\xd6\x57\x9b\x0d\xf9\x13\x55\x89\xd8\xbe\x68\x72\x50\x17\xd5\x95\xaf\xaa\xfc\xdb\x45\x8d\x32\x67\xa7\xd4\xaa\xca\xf6\xe7\x2b\xb2\x91\x73\x6d\xf2\x53\x0b\x1b\xe9\x93\x11\x96\x84\x02\x96\x69\xcb\x47\x23\xd0\x1a\x13\x21\xb3\xc4\x52\xe4\x22\xec\x66\xc4\xf1\x81\x08\x03\x7c\x59\x13\xa1\x89\xad\x6b\x4b\x87\xbe\xc1\x61\x89\x59\x7b\x9b\x2a\x4f\x4d\x47\x6e\xc8\xb6\xce\x55\xa6\xd4\xeb\x3a\xfd\xa6\xc8\x9f\xf8\x94\xe2\x31\x1e\x64\xb4\xe1\xe3\x2c\xf1\x33\x7c\x71\x53\x71\x99\x6b\x4b\xda\x67\x10\x17\x37\xd0\x0b\xca\x4a\x5f\x38\xcd\xc3\xd8\x6c\x1c\xfa\x69\x4a\xd8\xc4\x5b\x3f\xc5\x81\xe2\x31\x27\xff\x15\x1b\x87\x31\x50\xc7\x38\x81\x03\x17\xd9\xd5\xdc\x90\x8a\x17\xb9\x9e\xdc\x8f\xdd\x67\x14\xd8\xa8\xbb\x90\x62\xe4\x24\x33\x36\xf3\x86\xa5\xc8\x6e\x34\x8f\x02\x66\x9f\x07\x71\x71\x43\x51\xf4\x90\xfb\x02\x47\x1f\x03\xcf\x61\xe9\xc9\xc8\xbe\x6b\xf4\x5f\xbb\xcf\xb9\x17\xda\xea\x4d\x91\x87\x0a\x6f\x8c\x74\xcc\x2d\x13\xaa\xb3\x6d\x99\x4b\x56\xaa\x4c\xc3\x6b\xbf\x7a\x53\x75\xd8\x69\x96\x60\x7f\x72\x27\x55\x36\xc8\x50\x4c\xf9\x2c\xdb\xe0\x37\x1b\xcb\xfd\x90\x1a\x6c\xab\x27\x1a\x2a\x9d\x40\x1c\x6b\x49\x33\x5d\x47\x95\x66\x43\x55\x4c\x4b\x0a\xdf\x63\xc0\x4f\x53\xfb\xea\x2f\x0b\x3c\x42\x76\x2c\x7b\xad\x6d\x87\xe5\x22\xe2\xd4\x4f\xe0\xb8\x65\x13\x10\xcd\xed\x0d\x8e\x37\xb9\x75\x15\x17\x1a\x7f\xf8\xe1\xc5\x70\x3c\x4b\x47\x2f\xca\x6d\x73\x14\x8a\x6b\xa3\x13\xc3\xdc\x45\xf5\xa2\x79\x85\x73\x2d\xa4\x35\x9d\xca\xb7\xa5\xb2\xf2\xfc\x7c\x42\xcf\xbe\xbd\x15\xf6\xe3\xcf\xdb\xf9\x14\xa2\x78\xec\x40\x3d\x83\x4a\xa4\x36\xa4\xdb\x4d\x76\xd0\x36\x9c\x83\xd9\x7b\x59\xe9\x5d\xa4\xa0\x97\x55\x94\x13\x9e\x9d\x2b\x97\xaf\x17\xde\x4d\x37\xd5\x1e\x59\x15\x82\x7a\x6a\x99\x5c\xc1\x0f\x54\xfd\x0d\xf6\x43\x3e\x53\x7c\xbb\x03\x3d\x6c\xef\x6d\xcf\x50\x45\x73\x8e\x12\x5e\x52\xaf\x9d\xbb\x68\x9e\x73\x18\x85\xba\x42\x51\x97\x2b\x9a\xa4\x7a\x77\xd2\x38\x8b\xe9\xcc\x0f\x48\xff\x33\xa7\x33\xd7\x04\x2f\x38\x9d\x56\xc5\x6f\xc9\xe9\x14\x75\xef\x31\x9d\x45\x0a\xdf\x72\x57\x07\xdf\x74\x3a\xef\x3d\x5d\x05\x4b\x60\xce\x7c\xe9\x7a\xd3\x82\x49\xa2\x9b\x89\xd0\xf3\x0e\x6c\x62\x1d\xb3\xba\xbe\x44\x1b\x28\xbc\x94\x67\xab\x68\x8b\x60\x3b\x26\x0d\x2c\xdd\x1b\xf9\x61\x04\x39\x4f\x5c\x77\xad\x6f\xc1\x6e\xe0\x9c\x77\x1e\x6d\xb8\x83\x0f\xe8\x2a\x36\x65\x07\x21\x75\x0d\x62\x90\x86\x26\x6f\x4c\xdb\x25\xc4\x9d\xe8\xeb\x22\x8e\xf2\xb6\xc7\xb7\x03\xed\x24\x24\x35\xa1\xcc\x1d\xe9\xd5\xdb\x9e\x65\xef\x31\xc1\xd3\x26\x0e\x45\xfc\xcf\x8c\xab\x31\x28\x95\xfa\x19\x33\xea\x5e\xd1\xeb\x18\x30\x34\x9a\xa5\xd2\x91\xd0\x8a\x30\x61\x29\xe6\x32\x12\x52\x39\x21\xb2\xde\x90\x30\xbb\x2c\x02\x84\xfd\xbc\x1a\x61\x16\x7a\x9f\xe2\x07\x91\x3c\xd3\x12\xc8\x99\x0b\xc3\x5e\x90\xfc\xc1\x54\x32\x51\x87\x7a\x03\x40\x7e\x3c\xe8\x82\x70\x6d\xd0\x65\x59\x79\x32\x50\xae\x02\x34\xcc\xe4\x55\x28\x4e\x5b\x68\xab\x03\x2c\xd2\x6f\x48\xe4\x85\xe4\x30\x9c\xcd\x85\x58\xa1\xc9\x11\xaf\x1c\xe6\xac\xbf\x1d\x1c\xc1\x79\x99\x11\x9d\x59\xe6\x3a\x4e\xa0\x5f\xb9\xa2\xdb\x43\x4a\xbf\xbc\xbc\x59\x9b\xd0\xcf\xf0\x90\x7d\x5d\x2a\xfa\xe8\x5a\x31\x3b\xc2\x13\x0c\x52\x38\xec\xae\x94\x04\xd8\x55\x14\x9c\xf6\xc1\xa1\x1d\x5e\x9b\xd5\xb9\x04\x8b\x2f\x79\xdc\x79\xca\x4c\x69\x42\x79\x8e\xb7\x30\x05\x74\x76\x40\xf6\xdc\x99\xbb\x6e\x03\x5c\x62\xdd\x8a\x7d\xea\x69\xdd\x3e\xad\x5b\x74\xf7\x75\x7b\x9f\xd5\x01\x16\xc2\xa3\x30\x5d\x78\x6d\x58\x31\x61\x14\x0d\x5c\xe4\xb7\x83\x23\x27\x07\x90\x3d\xc8\x0c\x0e\x70\x5f\xb6\x63\xc5\xec\x24\x1f\x9a\x3e\x1e\xc4\x13\xb6\x74\x08\x5b\x08\xe3\x59\x5a\x9e\x79\x88\xc1\x2a\xcb\x1e\x04\x29\xf1\x6e\x54\x9c\xb8\x2f\xe4\x01\x05\x22\x12\x97\x96\x6c\x1e\xfe\xa3\x38\x4e\x31\x9a\x84\xd7\x44\x16\xb2\xf4\x0f\x3c\x41\x4d\x21\x0d\xc9\x84\xc8\xa4\x30\x17\xd9\xc5\x97\x20\x9d\x92\x93\x4e\x3a\xeb\xa7\xf8\xbf\x67\x38\xca\xac\x2a\x06\xa4\x8a\x76\x52\x5a\x0f\x75\x14\x9d\xaa\x41\x19\x25\x6d\x56\xe6\xab\xfa\xc9\xce\x66\xc3\xca\x16\x23\x29\x5f\x6d\xd6\x48\x49\xe4\x0f\x26\x30\xb7\x1e\x0f\xcf\xd0\xef\x1b\xb4\xde\x69\x58\x18\xba\x24\xff\xcd\x4d\xa0\xdf\xf6\x58\x79\x25\xa0\x89\x24\xda\x1e\xfa\x41\x40\x26\x70\x8e\x02\x64\x0a\x69\xae\x7a\x2b\xf4\xbf\x76\xf5\xc7\xe1\xfb\xde\x31\xfa\x5f\xed\xd5\x35\x34\x65\x40\x53\xa6\xcb\xb3\xc1\x3c\xfc\x3c\x48\xd7\x40\x4e\x9e\xfa\xc1\x0a\x7f\x2a\x90\x8d\x0f\x7d\x7e\xfd\x3c\x4b\x79\xec\x7c\x11\x08\x85\x99\x2b\x43\xe0\x64\x81\xc7\x42\xf6\x57\x00\x59\xbe\x7d\x26\x68\x59\x2b\xd9\xf5\x78\x2c\x04\x94\x74\x1f\x09\x80\x52\x11\xcd\x92\x0c\x0a\xc4\xb3\x7c\xe4\x63\xb3\x38\x7c\x89\x71\x25\xbf\xf2\xeb\x35\x4f\x8b\x9b\xa5\x5c\x30\xfb\x81\x7e\xb9\x76\x67\x06\x22\xaa\xd1\x58\x27\x1b\xd2\x78\xb9\x62\x86\xcc\xa2\x4c\xd0\x0e\xf8\x15\x99\x50\x23\x46\xb0\x06\x50\xfa\x62\x99\xe6\x9c\x16\x11\x56\xfe\xa5\x15\xb0\x35\x4b\xef\x85\x78\xbb\x66\xe8\x05\x9a\xea\x0d\xbe\x12\x7a\x81\x08\x28\x0a\x16\xb9\xaf\x8b\xf1\x9e\x39\xb8\x18\xef\xc1\xad\x45\x79\x3b\x17\xb3\x42\xa4\xd2\xe2\xf0\x05\x39\xfb\x51\xdb\x44\x21\x5a\x72\xb9\xe5\xcb\xd0\x69\x9c\x7b\xe9\x4d\x81\xf4\xaa\x61\x87\x36\x72\xdb\x77\x7e\xf8\x97\x41\x7b\x2a\x4a\x36\x33\x84\xcd\x20\xb0\x0f\x02\xcc\xf5\x20\x8e\x06\x7e\xc6\x61\x96\xd6\xc0\x7c\x8a\xa6\x82\xa1\xc0\x92\x1d\xf9\x01\x0d\x64\xc4\x16\xea\xb7\xe1\x32\xb3\x48\xe7\x33\xdf\x84\x23\x40\xb3\x25\xae\xdc\xa1\x9c\xce\x12\x6c\x7c\xe0\x1d\xce\x94\xcc\xc5\xd2\x22\x86\x18\xb0\x68\xec\xa7\x19\x3c\xcf\x5f\xd3\xb9\x78\x7d\x5a\x51\x97\xf3\x32\xaa\x57\xa9\x8b\xd9\x19\x73\x06\xb3\x79\x12\x53\xc1\xc1\x4d\x31\x39\xb8\x0d\x7d\x0d\x4a\x9b\x29\xdd\x36\x17\xd4\xf3\xff\x15\x17\x41\x36\x17\x05\xfb\xcd\x82\xed\x56\xa1\xe8\x1e\xe8\xe1\x8c\xfe\xf7\xe3\x00\xdf\x52\xf5\xe0\x89\x38\xad\xd1\x4b\x11\x38\x49\x48\xdd\xe9\xbd\xed\xb9\xa0\xb0\xb9\xba\x15\xf4\x45\x60\xe9\xc2\x86\x09\x11\x48\xde\x41\xe0\xe0\x47\xc0\x06\x40\x32\x9c\xd4\x08\x9c\x60\x0a\x98\x79\xda\xa9\x8e\xb6\x6d\x34\x71\xab\x78\x23\x2c\x60\x18\x48\x27\x5a\xfd\xd8\x93\xac\x0f\x8b\x6d\x00\x0b\x02\x9c\xa9\xf6\xa1\x16\x3f\x4e\x90\x9b\xc9\x08\x28\x6a\x51\xa4\x2a\x76\xc9\xf7\x09\xd8\x7e\x3a\xf0\xcf\x27\xd6\x3c\x0c\x18\xb6\xa4\x5c\xd2\x56\x8d\x4b\x9c\x27\x06\x02\x15\xb6\x44\xd0\x68\xc0\xa9\x5c\xbb\x9b\xb1\x4b\xfb\xab\x2f\x8b\x9b\x57\xad\x57\xaa\xe8\xe5\xea\xc2\x18\x08\x55\x8b\xe3\x2c\xf3\x1e\xe3\x29\xf2\x33\x34\xc6\x84\x0b\xc6\x11\x5f\x01\x2c\xcd\x07\xb5\x04\x85\xfd\x1a\x18\xae\xc9\xb7\x90\x38\xdf\x4c\xc2\x88\x1a\x89\xb2\x43\xbc\x11\x2e\x51\x7d\x64\x95\xe8\xf4\x49\xf8\x53\x42\x9a\x80\xfd\x31\x3d\xf2\x86\x97\xe8\xa7\x9f\xac\xfa\x78\x3d\x50\xc7\xe1\x9d\x74\x19\x39\x26\xaa\x32\xc5\x79\x3e\xd7\x9b\x2d\x7b\x25\xed\x16\x49\x73\x91\x44\x18\x4a\xb3\x57\x16\x82\xe6\xcd\x3d\x2c\x21\xaf\xae\x92\x83\x0c\xcd\xf7\xe5\x12\xb9\x40\x5e\x67\xa6\x5f\x20\x81\xc3\xef\xb9\x3a\x08\x7e\x15\x4f\x6d\x04\x5d\xa7\xe4\x3b\x5d\xc6\x3f\xde\xb2\x7a\x5c\xbc\xad\xed\x81\xe4\x37\x67\x06\xa8\x7c\x64\x6b\x6f\x9e\xe5\xdf\x3d\x2d\x15\xc0\xf4\x8e\xc9\x1e\x76\x33\x14\x34\x88\xc7\x63\x4c\xe9\x3f\x1e\x72\xd1\x00\x44\x4d\x0c\xc9\xf4\x8a\x44\x0f\x49\x14\x95\x9c\xbc\xc9\x36\x9a\xf8\x57\xd2\x2b\xab\x5f\xa2\xdd\xf5\x83\x3a\xa0\x0b\x21\xa5\x4c\xed\xfc\xe2\x11\x52\x3c\x30\x2e\x48\xeb\x93\xf5\x69\x98\xe3\xba\x00\xa5\xfe\x98\x62\x0f\x3f\x00\x18\xa8\x24\x7d\x1a\x7e\x14\x27\xe1\x25\x95\x55\x38\xc7\xb0\x02\xe4\x57\xa9\xb9\x9c\x2f\x59\x0e\x9a\xb1\x56\xcb\xc9\x35\x77\xe9\x59\xb1\x7c\x33\x18\xe1\xc9\xdd\xe0\xda\x05\x4e\xa6\x32\x07\x8b\xe9\xa1\x04\xcf\x0a\x82\x26\x65\xbc\xcd\x93\x36\xd2\x53\x0c\x15\xb1\xf8\x5b\x5d\x0c\x1b\xc4\xd1\x25\x4e\x32\x45\x86\xa5\xe9\xee\xb8\x31\x25\x58\x7c\x52\xeb\x3f\xb7\xdb\xea\x21\xad\xa2\x3a\xaf\x8a\x97\x25\xed\x61\xe6\xbb\x58\xa9\xa8\xcd\x3f\xd6\x09\xef\x26\x19\x1f\xcd\x4e\xd4\x8f\x44\x16\xab\x69\x9c\xa6\x61\x7f\x8c\xdd\x2b\xd6\xd2\xd4\x62\xce\x4d\xf9\x40\x99\xf6\xa0\xf4\x1b\x3f\x81\xff\x69\x40\x41\x42\x7d\x4e\x56\x70\x57\xfa\x9d\x3b\x3c\x59\x2b\x7d\xc6\x37\x5d\xd5\x2f\xca\x5a\x4c\xf3\x94\xb2\x17\x22\xcb\xb8\x0b\xff\xce\x29\x28\x56\x65\xd7\x74\xe7\xb2\xd7\x60\x22\xbc\x6e\x99\x60\x2f\x2c\xe4\x7a\xf5\xe8\xfc\xbe\x77\xbc\x66\xaf\x20\xb1\xf0\x96\xbd\x84\x58\x38\x12\x50\xfa\x6e\xe5\x60\x8a\xa3\xe3\xe3\x0f\x46\xb5\xf2\xce\x64\xf2\xf4\xdb\x05\xaf\x49\x78\xbd\x17\xa9\xe5\x4a\x9b\x1e\xd1\x55\x9c\x2e\xb6\x8c\x91\x73\xdd\x98\xac\x44\xf3\x0d\x74\x70\x13\x72\xa8\x73\x03\xe7\x06\xb6\xdc\x2b\x03\x76\x05\xf8\x1d\x0e\x43\x7d\x8d\x17\xc0\x81\x2c\x60\x29\x4d\x01\x06\xe9\xe3\x70\xee\x45\x99\x63\x1c\xc5\xf4\x8d\xc6\x00\x59\xd2\x7e\x5c\xc4\x3d\xca\x2e\x69\x8a\xbc\xb8\xa6\x63\x6b\x7b\x09\xbd\x78\x61\xf7\xad\xb0\x96\x5f\xc9\x62\x9a\x6f\xc8\xe5\xca\x31\xa7\x96\x83\x54\x9d\x84\xc9\x2b\xca\xc4\x29\xc6\xc6\x65\x55\x95\x97\x40\x5f\xbf\x52\x72\xcd\xeb\xac\xf0\x49\xbc\xe1\xc7\x5e\x43\x47\x63\x95\x93\x28\x95\xcd\xbb\xd7\xa0\xed\xc0\xd5\x86\xf8\x69\xbf\xdd\x60\x3d\xb7\x11\xa7\x0d\x34\x2b\x2e\x72\x19\xc3\xee\xa5\x0e\x62\xf1\x75\x87\x58\x75\xbe\x7b\xc9\x45\xbc\x99\xe5\x41\x3c\x99\xfa\x19\x6c\x2f\x65\x97\xa1\xbc\x2d\x68\x9b\x98\x24\xfe\x94\xdd\x13\x6d\xcb\xef\x2e\xc8\x3d\x94\xe1\x60\x4c\xdb\x3e\xe6\xe4\xed\x20\x64\x89\xba\x5c\xbc\x51\xa1\x6f\x51\xbc\x34\xf7\x9d\xa3\x96\x91\x23\x2d\x29\x4b\x30\xff\x62\x0b\xd4\x48\xc4\x5d\xad\x02\x79\x67\x3b\xc6\x42\x7f\xcd\x43\x2c\x29\xee\x54\xb5\x5c\x49\xd1\x6a\x0c\xed\xfd\x69\xed\xba\xdd\xec\xd4\x3b\x83\x35\x48\x6c\xd0\x69\x77\x5a\xed\x61\x7b\x78\x56\xe5\xaa\x78\x00\xcd\x1f\xf2\x7e\x38\xce\x91\x25\x50\x70\x8e\x85\xe3\xf0\x25\xea\xe6\x8c\x8c\x86\xb5\x59\x7c\xcf\x2b\x5a\x63\xb2\xbf\xd2\xa2\xc2\x23\x5f\x27\x39\x9d\xde\x79\xc9\xa8\x31\x1b\xf8\x82\xbe\xc3\x1a\x7e\xd8\x00\x0e\xa6\x30\xaa\x2d\xbd\xa9\x9f\xa4\xb8\xa2\x2c\xd4\x82\x8b\xc9\x24\x55\x14\x3f\x79\x35\xab\x57\x02\x29\x8e\x68\x0c\xaf\x39\x8b\x8e\x12\x86\x81\x4c\x91\x7a\xb5\x08\x22\xbf\x8c\x93\x0e\xc3\x2c\x29\x84\x01\xee\x04\xa7\x19\xb5\x6d\xf0\xc7\x96\x05\xaa\xc1\x3c\xad\x9d\xa1\x8d\x0d\x94\xaf\x3d\xf4\xd3\x4f\x7a\xbb\xa7\x75\x56\x86\xaf\x49\x97\x0a\x6a\xfb\x9a\x5e\x60\x98\x2d\x23\x95\xc3\x18\x8b\x5f\x6b\x91\x99\xf2\x34\x3c\xd4\xaa\x16\x58\xd7\xc5\x97\xec\x88\x0e\x57\x41\x39\x0c\xb3\xbc\x01\x7f\x0a\x0d\xd4\xf4\x5b\x6b\xa3\xb8\x72\xab\x53\xef\x94\x63\x14\xd6\xa3\x91\xe3\x18\xe4\x49\xa7\x13\x55\x34\x2f\xbc\x2b\xe2\x8b\xf0\x2a\xf1\xa7\x53\x90\x23\xfd\x8c\x35\x2f\xab\x4c\x90\x4f\x76\xfa\x54\xf2\x4a\x2b\x5c\xbd\x8a\xab\x8f\xe1\xca\x96\x3b\xfc\xd8\x3e\x95\x75\x20\xb9\xf3\x65\x8f\x10\x7a\xb8\x8c\x5f\x24\xd5\x73\x1d\x81\xdc\x5b\xd6\x59\xea\x10\x1a\x05\x94\x6a\xc4\x01\x23\xbf\xd8\xb1\x1c\x9c\x8a\x42\x44\xe9\xde\x8b\x80\x50\xd7\x10\xd5\xa4\x89\x2d\x0c\x2a\xc5\xae\x1d\xc8\xbc\x31\x6f\xba\xfb\x78\xa8\xe6\xca\x27\xcb\x51\xa7\xc0\xfb\x9c\x35\x4d\x6d\x50\xd8\xef\xdc\xef\xfc\x6f\x12\xc3\xc5\xbe\x85\x6d\xfe\xb5\x1b\x18\x59\x96\x76\x8d\x8a\xb9\xac\x84\x7f\xa5\xa9\x8d\x50\x5c\x2d\x1d\xa7\xb0\xc7\x6b\x30\x0f\x52\xa3\xab\x13\xbe\x69\xe3\x9e\x58\x6d\x0e\x69\xa0\x40\xd9\x61\x71\x8e\x75\x7b\xb1\xde\x2d\x84\xce\x42\xd1\x73\xb6\x6d\xf6\xeb\x52\x74\x83\x38\x77\x3e\xb1\x05\x40\xb3\xfa\xac\x1a\x62\x49\xee\x99\x21\x02\x24\xb0\xce\xde\x45\x32\xe9\x41\xff\x72\x98\x70\x05\x6c\x40\x61\xf6\x46\x84\xe3\x0a\xc7\x5c\xd7\x7e\x54\x7e\x3b\x2d\xda\xb4\x95\xfd\xd5\x2c\xc8\x55\x8b\x96\x4f\x84\xac\x44\xdf\x56\xc2\x4b\x4b\x11\x49\x47\xc8\xe8\xc5\x2c\x43\xb5\x82\x39\x20\xb8\x10\x35\x8b\x09\x7d\x60\x5e\x92\xbd\xb2\x14\x96\x74\x81\xba\x85\xb5\xa5\xb4\xa4\x17\x24\xa4\x37\xb4\x1c\xd7\x6e\x4b\x1f\x5b\xd8\x3d\x74\x2a\x26\x4e\x28\xbe\xe4\x6b\x19\xf4\x68\xdb\x93\x4c\x00\x62\x87\xd2\x2e\x9a\xa4\x47\xc8\xed\xfd\x77\xdc\xa7\xb4\x00\x2d\x22\xd2\xf1\x37\xd8\x9b\xf2\xa8\xca\xf3\xd9\x34\xf7\x9e\xb7\xb0\x69\x4e\x76\x2c\x8c\x82\xe4\x51\x7f\x67\x96\xfd\xd0\x28\xea\xfb\xd2\x03\x6e\x29\xce\xd8\x05\x8e\x08\x03\xdf\x60\x57\x61\x1a\x07\x49\xb5\x20\x2f\x26\x0d\xb0\xbc\x53\xb0\xdb\x6f\x38\xbf\xca\xc8\xe7\xdc\xc4\xd6\x1c\xe3\x14\xe6\x86\x21\x4f\x9e\xb2\x89\x29\x51\x17\xe9\xb0\xe4\x7b\x93\xc4\x64\x14\x85\x8f\x75\x9b\x10\x4d\x2c\xac\x8d\xb1\xb2\x35\x7d\xac\xd4\xfb\x17\xd0\x31\xf9\x69\x3a\x9b\xe0\x40\xbd\x4f\xf4\xc7\x09\xf6\x83\x1b\x69\xbf\x53\x0e\x64\xb3\x88\xa6\xad\x2c\x11\xd1\x6c\x31\xb6\x67\xe7\x5f\x0b\x1d\x9a\x08\xe3\x02\x13\xf5\x24\xc5\x0b\xf3\x7a\xb7\xbe\x68\x16\x2d\x0a\xeb\x2f\x94\xb8\x0d\x92\xa7\x2a\xa4\x03\x4e\x05\x48\x10\xbf\x9d\x07\x9c\x1b\x3a\x25\x79\xf5\xb0\xca\xb6\x54\xde\x2c\x76\x8d\xbc\x08\xe7\x84\xb0\xe1\x36\x21\x94\x3d\x99\x4b\x55\xbf\xd8\x40\x85\xda\x51\x06\xad\x40\x29\x6a\x68\x26\xac\x37\x24\xef\xed\x26\x12\xf3\xae\x4c\x3e\x07\x43\xb8\x2f\xa1\xff\x2d\xbe\x2c\x99\x67\x85\x61\x5e\x98\xbc\xa7\xd0\x49\x2b\xe5\xee\x49\xb6\x08\x78\xb8\xd3\x27\x8d\x91\xb5\xbc\xf7\x0b\x57\x18\x4c\x59\xbc\xa0\xf2\xea\x58\x5e\x83\x59\x5e\xb0\x07\x90\x53\x48\x33\x00\xb8\xd8\x2b\x24\x0f\x54\x8e\xa9\x6d\x45\x18\x31\x4b\x5e\x66\x07\xc0\x4c\x66\x2e\x70\x04\xc6\xbc\xc5\xd0\x44\x94\x72\x07\x30\x1a\x3a\xbb\x18\x96\xa9\x33\x00\x15\x96\x24\x24\x6d\xa2\x4e\x0b\x4c\x8e\xe1\x03\xb7\x9f\xdd\x1b\xa2\x78\x12\x12\x19\xc1\x43\x3e\xfd\x74\x15\x8e\xc7\xa8\x8f\x45\x83\x01\x4a\xfc\x28\x88\x27\xe3\x9b\x07\x3a\xdc\x53\xab\x09\x36\x4c\x1e\xda\xfb\xc5\x83\x29\x25\x8d\x7f\x03\x2e\x44\x27\x39\x30\x59\x90\x44\x8d\x2b\xf8\x1a\x0f\x66\x19\xae\xbc\xe0\xd1\xa8\x5e\x78\x2c\x71\x87\xc7\xcc\xb7\x1c\x62\xd1\x03\x41\xf7\xd0\x0b\x32\x1c\xe4\xff\x5f\xb8\xcf\xcc\x14\x8c\xcc\xdd\x38\x35\x7b\x9c\x44\x3d\x46\x5d\x54\xb1\x69\x37\xea\xa7\xd3\xcc\x66\xd9\xa1\xa8\xfe\xc1\x79\x95\x64\x28\x91\x29\x9c\x4a\xa7\xb5\x6a\xa4\x35\xb7\xb8\xd5\xd1\xa5\x2d\xad\x6b\x53\x5a\xa1\xf1\x66\x69\xe2\x81\x5c\x81\x2b\x62\xdc\xe5\x69\x90\xd9\x42\xba\xad\xae\xb0\x44\xde\xd2\x78\x00\xfe\xd6\x80\xb5\x84\x36\xb3\x62\x0c\xc0\x6e\xda\x50\x93\x8b\x64\xd0\x4c\x41\xce\x93\xc9\xf2\x31\x47\x2f\x4d\x7d\xb6\x92\x1a\x3a\x4f\xe1\x6c\x77\x96\x3a\x62\xa2\xd4\x82\x87\xf1\xfc\x48\x2d\xa4\xe8\xbb\x69\xb5\x6d\x9a\x01\x45\xc5\x1d\x30\xbe\xcc\x59\x9e\xc6\x92\x3d\x01\xcb\x21\x7e\xdd\x5d\x1f\x6e\x89\x12\x27\x14\xe2\xf6\x6f\x36\x0d\xd7\x23\xea\xc7\xdf\x6f\xed\xdc\x22\xb2\x7d\x72\x0b\x4a\xdb\x2e\x9c\x4b\x79\x9c\xd9\x16\x6f\x71\x0b\x69\xc5\x2d\x1d\x76\x3b\x3f\x7c\x0e\x86\x5d\x69\x7b\x96\x28\x64\x41\xf5\x38\x73\xa9\x5a\x64\x5f\xfe\x3e\xf4\xe5\x85\xd2\xc1\x77\xa0\x8e\xf8\x9b\xa8\xcd\x2d\x8b\xaf\x94\x26\xf9\x05\x1f\x6a\x57\x58\xd9\xc7\x6f\xd8\x43\x7f\x3e\xb2\x06\x3b\xdf\x8e\xbe\x91\xc2\x41\xdb\x5d\xe3\xcc\xa5\xdc\xb5\xc9\x2e\x04\x3c\x11\x5b\xb8\xb8\x22\x61\x4f\x87\x57\xc8\x18\xec\x99\x6e\x7b\x2e\xef\x4e\x2a\xc6\xd2\xbe\x19\x5d\x5a\x81\x2d\x56\xc1\x60\xc5\x1a\x92\xc0\xa9\x98\x57\xf4\x25\xee\xeb\x0c\x39\x00\x84\x31\x3f\x6a\xfb\x92\x1e\xdf\x40\x63\x3f\xbc\xa6\xc9\x40\xa0\x82\x75\x48\xa5\xb3\x35\x35\xcc\x54\xa0\xbb\xf4\x26\xd6\x13\xdf\x3d\xf4\xc1\x7f\x01\x3f\x7e\x60\x05\xf1\xf7\xce\x98\xbf\x47\x3d\xb1\x8d\x19\x2e\xaa\x28\xbe\x17\x63\x7c\x70\x14\x4d\x45\xf1\x43\x31\xee\x92\x7a\xe2\x6f\xce\xbb\xbf\xb9\xb2\xf8\xdb\x6f\x15\x9e\x62\xdb\xe3\x38\xa1\x3d\xdc\xde\x51\x4a\x1f\xee\xbe\xbf\xb0\x6d\x1d\xf2\xf8\x96\xdc\x3d\x8a\x14\xe4\xb9\x2a\x4f\x64\xba\x94\x53\x5a\xb2\xfc\x95\xb7\x67\x5e\xbb\xf9\xbd\x26\xa5\x7c\xf0\x1c\x94\x8b\xe6\x9e\x54\x72\x4e\x1a\x88\x99\xe9\x27\xb5\xb4\x93\xbc\xa2\x23\xf1\x24\xe8\x47\x73\xe0\xe2\xa7\x9a\x7c\x72\xdf\xcf\x46\x1e\xb2\xa4\xa0\xcc\x8f\xd7\x1f\xe2\x81\x3f\x46\xd3\x78\x7c\x33\x0c\xc7\x28\x1e\x22\xba\x69\xb1\x53\xbc\xe5\xc8\xcb\x62\xdb\x6f\xa8\x05\xb5\x86\x15\xc6\x24\x5e\xef\x90\xf7\xb7\xaf\xcd\xd8\x41\x92\xad\x65\xff\x0f\x83\xa9\x81\x8d\xe0\xac\x4f\x66\x50\x27\xe2\x9d\x95\x69\x12\x67\x31\xf9\x84\x36\xc8\xe9\x43\x2f\xc0\xea\xa1\x0d\x14\xe1\x2b\x82\x40\x31\x84\x68\x36\x1e\x3b\x16\x8a\xc0\x20\x5f\x26\x52\xbc\x23\x5b\x24\x4f\x3e\x27\xc5\x4a\x6e\xa7\x62\xfb\x43\xd8\x4f\xfc\xe4\x66\x9e\x8e\x5c\xca\x0f\xea\x04\x05\xd9\x42\x99\xd6\x93\x08\x17\xbc\xcb\xfe\x18\x85\xd1\x08\x27\xa1\x12\xc0\x55\x89\xe8\xa0\xe7\x19\x35\x23\x8c\x9a\xd3\x59\x22\xec\x1f\x8f\x31\x0c\xee\x71\xc2\xcf\x60\xe4\x67\x1c\x21\x16\xca\x83\x8a\x41\xc6\xa9\x12\xa1\xa2\x38\x80\x5c\xee\x8a\x2f\x71\x92\x84\x01\x4e\xd1\x21\x55\x88\x84\x38\xa5\x0c\x7c\x7a\x83\xc2\x88\x65\x33\xce\x11\x28\xd1\x82\x9e\xab\xe1\x64\x51\x00\x86\xcc\xe5\x28\xb7\x48\xd4\x40\x32\x51\xfb\x37\x27\x94\x84\x15\xe9\xa6\xc0\x24\x51\xf6\x17\x0b\xf1\x38\xe8\xa2\x17\x90\x29\xeb\x85\x6e\x38\x62\x6f\x93\xfc\x4d\x70\x36\x8a\x83\x42\x1f\x79\xa9\xb4\x1e\x23\xdf\xe6\x78\x86\x90\x19\xce\x90\xa2\xaf\x18\x64\xf3\x79\x75\x06\x31\x9c\xfa\x57\x91\xf9\x45\x62\x24\x44\x58\xc8\xd3\xea\xb9\xcc\x89\x37\x67\x17\x13\x1c\x59\x4c\x87\xc9\x8e\x52\x8c\x05\xca\x99\x0f\x3b\x77\xe5\xe5\xad\xe9\x1f\xac\x08\x30\x33\x29\xee\xfa\x15\x0a\xc7\xd2\xc4\x8e\xd3\x0f\xbc\xc9\x91\x9f\x1e\x5c\x45\x8c\xec\x6f\x2a\x2f\x48\xcd\x17\x55\xe1\xf3\x44\x1e\x61\x13\xe4\xe5\xc9\x8b\xb9\xfd\xa0\xb5\x0a\xa7\xdb\x52\xeb\xff\x49\x67\x53\x22\x6a\x45\x61\xb6\xe2\x13\xe1\x94\x6d\x7d\x7e\x72\x31\x23\xa3\x6b\x1d\x0f\x64\xc9\xa0\x50\x30\x4e\xb9\xc7\x6d\xf2\x22\x45\x39\x47\x0f\xa9\x52\x98\x4f\x3a\x5d\xa5\x26\x04\xb9\x83\xca\x7e\xe0\xd8\x76\x10\x57\x8c\x0f\x71\x82\xa3\x01\x69\x00\xc6\x79\xaa\xaf\x57\x63\x18\x98\x5c\x6c\x03\xe8\xdc\x67\x90\x2d\x35\x86\x8d\xa9\x6e\xc3\x4a\x49\x65\xa6\x49\x55\xde\xb3\x88\x8e\x03\x4c\x20\x5d\xb5\x66\x08\xd4\x4d\x3e\x1f\x79\x06\x9b\x4a\x55\x5c\xc3\x11\x51\x1a\x42\xca\x01\x90\x4a\xf5\xef\xcc\x2b\x79\xc4\x72\xb4\xc1\xd8\x26\xbf\xb3\x98\xcb\x8b\x68\xb9\x62\x8e\x67\x36\x02\x4b\x2e\x8f\x93\x6d\xae\x5c\x1e\x41\x5d\x5a\x23\xfc\x9d\xba\x4e\x9c\x54\xc3\x8b\xdf\x85\x6c\x8a\xdc\xd5\x1d\x73\x85\x0e\x18\x33\x63\x49\x02\x80\xa4\xc0\x84\x3e\x08\x50\x1a\x4f\x30\x4d\x3d\x85\xae\x46\x38\x42\x37\xf1\x2c\x11\x66\xf6\x3e\x11\x67\x29\xf0\x07\x8e\x9d\x7b\xdf\x5d\x50\x77\x74\x2e\xda\xcb\x10\x65\x00\x2b\x2b\xe6\xc8\x88\xa1\xbf\xe3\x76\x37\x17\x8d\x52\x73\xda\x8b\xa7\x44\xd8\x99\xe6\x72\x0f\x93\x77\xee\x21\x4e\x49\xc0\x40\xc3\xa4\xc8\x54\x13\xd0\x44\x3e\xf0\x94\xb2\xd5\x49\xf7\xcf\xb2\xf2\xcb\x1d\xc7\x1d\x1a\x51\x2e\xb1\x45\xff\xac\x6b\x5c\x44\x3c\xe4\x97\x6d\x1f\xfd\x09\x18\x4d\xcc\xa9\x87\xd8\x56\x9d\x17\xd3\x37\x6b\x19\x60\xb5\x70\x8b\x25\xd3\x79\x2a\x17\x3f\x43\x1b\x52\xfb\xea\xa7\x05\x52\x17\x39\x36\xd9\x6d\x74\x15\x47\x2f\x32\x2a\x3f\x73\x77\x47\x29\x78\xe1\x38\x8e\xa7\xc8\xef\xc7\x97\x96\x6d\xb0\xb8\xcb\x2f\x38\xb4\x17\xee\x0e\x03\x17\x15\xad\xca\xfd\x14\x6f\x4b\xe4\xd5\x2a\xb5\x78\xc4\xe1\x04\x7a\x0a\xf6\x2f\x8b\xac\x1b\xdb\xc6\x37\x18\xc7\x11\x7e\x04\x8e\x07\x70\xd1\x46\xbe\x87\xc0\x8b\x12\x3b\x19\x29\x36\x77\x23\x93\x73\x91\xa8\xc2\x11\xe7\xa7\x56\x7b\x32\xfb\x19\xd9\x7a\xbb\x1f\x21\x1f\x3c\x6f\xb5\x58\x84\x85\x91\x85\x8c\x38\xef\xc5\x20\x6c\xe1\x69\x84\xf1\x83\x1a\x0e\x31\x0d\x2f\xa2\x70\x18\x0e\xfc\x28\x63\x01\x25\x43\xda\x7b\x00\x49\xdb\xb1\x1d\x93\x7f\x95\x3c\x88\xe9\x59\x59\x7e\xf3\x00\x61\x63\xcc\xe6\x75\xb2\x70\x84\xc1\x97\x4d\xaf\xe6\x8c\x35\xb2\x9a\x85\x89\x91\xd2\x6e\x30\xe6\x0e\x1a\x7e\xb0\x54\x2f\xb2\x7f\xb6\xb2\xb1\x1b\xb6\x30\x0e\xed\x7f\x79\x00\xa7\xb5\xeb\x5a\xad\x56\xaf\x35\x6a\x4d\x0f\xd5\xae\x6b\xad\x5a\xbb\xd6\xa9\xad\x9d\x3d\x1a\x60\x0f\x75\x4a\x87\x5e\x61\xe1\xeb\xf8\x8c\x18\x2b\xf6\x8a\x39\x04\xc3\x72\xe5\x0f\xf4\xbf\x5f\xbf\x42\xcc\x5e\x4d\xd4\x18\xa2\x8a\x98\xde\x1f\x36\x2c\x8a\x42\xf9\x0f\xa0\x4a\x46\x43\xfc\x67\x69\x63\x52\x1d\x00\x25\x8f\x31\x8e\x2e\xb2\x11\x35\x3d\x72\x72\x91\xf2\x31\x63\xf2\x85\xb2\x58\xa4\x98\xed\x68\x10\x07\x84\xde\x31\xfd\xa1\x93\x3b\xbc\x2e\x8e\xfd\x29\x08\x00\x47\x83\x95\x5d\x7c\xed\x6e\x73\x5e\x00\x99\x52\xab\x7d\xe1\xe0\x2e\x39\xb1\x96\x88\xec\x62\x89\x6b\x30\x2f\xac\x8b\xa5\x8a\x32\x24\x9f\xb2\xe1\xfa\x42\xd1\x5c\xd8\x54\x38\x63\xb9\xf0\xa9\xfa\xfa\x15\xed\xe2\xeb\xc2\xf0\x2d\x73\x08\x68\xe0\x67\x38\x62\x7b\xbe\x4a\x41\x0e\xe6\xef\x26\x24\xe9\x1e\x36\x1f\xf0\x13\xc6\x0d\x25\xca\x84\x34\xbf\x8b\xde\xeb\x96\xc5\xa5\x0c\x6d\x08\xec\xea\x3c\x7e\x86\x78\xd3\x70\xa7\x34\x83\x92\x3a\x53\xa2\x81\x9d\x17\x0b\x47\x42\x06\xf6\x57\x83\x61\x59\x7c\x15\xb3\x91\x2f\x42\x1d\xe4\x24\xe6\x2e\x1d\xa6\xc7\x39\x8f\x51\x78\x8e\x03\xf8\xb1\xca\x92\x28\xfc\xbc\x8e\xd1\xa9\xde\xd8\x9f\x4c\x11\xbe\x86\x48\x92\xfd\x50\xef\x1c\xbd\x57\x25\x65\xcc\xdb\x06\x7a\x9f\x3a\xb0\x05\x49\x51\x10\xff\x97\x23\x50\x3a\xd4\x27\x22\x69\x84\x61\xab\x45\x7e\x86\x7c\x94\x85\x13\x8b\xc4\x6d\x0b\xc9\x2e\x77\xd7\x9d\x14\x42\x1e\x1c\x52\x14\x6d\x10\xf4\xd8\x2c\x9c\x86\x3c\x2a\x36\xf9\x4f\xa5\xd1\x42\xcb\xa8\x12\x52\x8c\x5f\xa2\xf5\x6a\x55\x44\xcb\x76\x4a\xf1\x14\x8e\xda\xe3\x25\x14\x8a\x70\xdb\x5f\x37\xf2\xa6\xdf\xbc\xe1\x6d\x58\xca\x8b\x46\x4b\x08\xfe\xce\x6d\x49\x1e\x53\xba\xb8\xee\x35\xa6\xee\x28\xf7\x65\xbb\xbf\x81\xcc\xc1\x2e\x93\x31\xd8\xa4\x42\xb1\xd9\x2e\x6d\xa8\x68\xda\x72\xac\xf8\x61\xe4\xf7\xf5\x93\x87\x74\x00\x28\xcb\x4e\x69\x0c\x0e\x22\x04\x2a\x82\x61\x98\xdd\x57\x14\xcc\x17\xa7\x58\x5d\x0e\x26\x45\x3e\x97\x0d\xdd\x6b\x61\x4d\xa6\x1c\x65\x8b\x8b\xe4\x64\x32\x76\x86\x61\x11\xd5\x4e\x05\x0c\x1e\x67\x7e\x03\x96\x0e\xfd\x03\xd2\x6f\x36\x08\xe9\xa7\x0a\x5f\xb0\x10\xbc\x22\x4a\x6d\xa0\x7d\x3f\x1b\xad\x0c\x70\x38\xce\x6b\xae\xa2\x05\x22\x12\xd9\xcf\xbf\xa5\x76\x1e\x87\x39\x92\x71\xfc\xbd\xab\xdd\x27\x3b\xee\xca\xb4\x60\x9c\x77\x55\x5a\x98\x77\xce\x95\xc1\xc2\x49\x8d\xe2\x2a\x47\x3f\x37\x4f\xce\x2b\x26\x8d\x30\xf3\xfb\x9a\xd3\xa4\x8e\xd4\x5b\x7c\x0a\x24\xb1\x61\x18\x8e\xc7\x3c\xec\x2c\x73\x93\x80\xf3\xd6\x7c\xa1\x84\x1f\xe6\x22\xdb\xa1\x57\x06\xe5\x74\xf1\x29\x35\xcb\x0c\x52\x29\x42\x79\x28\xe3\xb3\x12\x47\x30\xe6\x0a\x52\x77\x9f\xb4\x68\x09\x99\x4c\x22\xfb\x11\x4b\x66\x0f\xe6\x81\x8a\x7c\x4d\xd4\x1b\xf2\xc9\xf9\x95\x3b\xca\xfc\xf9\x15\xda\x20\xff\x3a\x12\xa8\x4d\xce\xbf\x90\x6d\xe6\xba\xe9\x07\xb8\xb3\xde\xd7\xc3\xaf\x8b\x62\x7e\xfa\x19\xc9\x9c\xa3\xe0\x9e\xa0\xc4\xdd\x1d\x6d\xb5\x52\xbb\x7e\x55\xeb\xbc\x42\x2f\x49\x17\xbe\xc0\x9e\xbe\xb3\xb3\xb3\x53\x45\x4b\xf4\xc5\xcf\x3f\xa3\xda\x75\xbd\x06\xdb\x3d\x41\xc0\xb1\xdd\xd3\x2e\x56\x6a\xd7\xad\x4e\xbb\x46\x81\x5d\xe9\xc0\xae\xca\x02\x83\xe1\xc5\xe9\x0c\x3c\x7d\x2a\x80\xc6\x9b\x37\xb4\x26\x5a\x42\x30\xd2\x85\xf5\x59\xdd\xd5\x0d\xa8\xc3\xfe\x8a\xcb\x2e\x6d\xa0\xda\x4a\xdb\x59\x06\xc6\x94\x15\x7d\x49\xed\x6d\x38\xb5\x55\xd1\xcf\x68\xa5\x8d\xfe\x03\xd5\x51\x17\x2d\xd7\xcb\x88\x28\x06\xe7\x50\xc5\x0d\x0f\x25\x03\x7f\x30\xc2\x2c\xbb\xce\x7c\x81\x83\xd4\x3c\x27\xf4\x98\x54\x2a\xb4\x2a\x39\x2a\x29\x48\x92\xdd\x44\x1a\x0c\xfb\x15\x13\xad\xba\x81\xce\x93\x0a\x2d\x0f\x04\xb9\xd6\x5f\xb3\xf4\xe9\x2a\xcf\xe1\x53\x11\xe5\x73\xf8\xe8\x2b\xaa\x95\x0c\x6b\x1e\xe1\x2b\xc9\xd9\x09\x6e\x1d\x99\x02\x24\xe2\xe9\x7b\x9e\x69\x23\x69\x77\x3e\x65\x47\xfb\x79\x86\x34\x38\x1a\x80\x21\x0d\xfd\xaf\xdd\x90\x66\x17\x5f\x9b\x9a\x00\x1b\x38\x52\x70\x83\x02\x5d\xa1\xbf\xcb\xc5\xdf\xd4\xd5\x17\x23\x7c\x5d\x5a\x85\x51\xe2\xe4\xb9\x60\x54\xcd\x52\xad\x3f\x14\x23\x1f\xe1\x6b\x33\x84\x26\x1b\x3f\xe9\x68\x3f\x3f\x91\x90\x35\x70\xe6\x5d\x8f\xa9\x57\xa5\x4f\x9e\xe9\xa2\xc7\x48\x3a\xeb\x26\xa0\x11\xbe\xee\x8d\xfc\xa4\x74\x9e\xad\x74\xee\x81\x0e\x72\xa4\x85\xf4\x20\x77\x75\xcf\x43\x1c\xc7\x8e\xad\x71\x00\x4b\x80\xb4\xaa\xb9\xda\xa7\xde\xa9\xda\xf8\x9d\xad\x2a\x69\xa7\x36\x2c\xae\xeb\x60\x10\x02\xdc\x1f\x71\x18\x55\x5e\xbc\xb8\x43\xc4\x4d\x89\xc2\xe9\x7a\x5b\x44\xd3\xc3\x57\x0a\x25\xdc\xf2\x0b\xc6\x21\x3c\xfd\xf5\x52\x13\x5f\x6c\xd4\x66\x5b\xac\xc7\xf2\x91\x32\x69\x95\xc5\x12\xa5\xd0\x3a\x1f\xf8\xd1\x85\x3e\xb2\xa3\xcc\x22\xab\xe6\x6a\x91\xd4\x74\x72\xa3\x6c\x0b\x6d\x14\xe4\xc7\xa4\xab\xa5\x09\x9a\x09\xe8\xf4\x5e\x94\xb1\xce\xae\xa4\xb3\x7e\x9a\x25\x95\xd0\x43\x8d\xaa\x07\x49\xf8\x72\x95\x05\x59\x51\xeb\x55\x9b\x03\xee\xc2\x7b\x9e\x32\x4c\xab\xa8\x51\xd6\x7d\xf6\x83\x9f\x85\x51\xbd\xdc\xa6\xc5\xca\xf2\x7d\x4b\x3c\xde\x6d\xeb\x62\xd5\xff\xba\xdd\xab\x2c\x02\x0f\xb5\xa6\xc6\xd0\x9e\x7d\x0f\xa3\xb8\xfc\x8f\xda\xc6\xe8\x70\x7c\xc7\x3b\x99\x84\x20\xdd\x91\xe8\xd4\xad\x0c\x93\x78\x42\xde\xf6\xe2\x00\xc3\x26\x55\x76\x43\x92\x01\xde\x63\x4f\x52\xe8\xf6\xee\xdb\x92\x20\xc7\x85\x16\xc3\x77\xbd\x39\xb1\x55\x44\xf7\x27\x79\xb9\x95\xdf\xa2\x44\xad\xc5\x76\x29\x51\x4d\x6c\x54\xe2\xcd\x63\xef\x55\x5a\xd3\xf3\x72\x39\x87\x92\x16\x3d\xef\xed\xca\x80\x11\xf4\x66\x56\x09\xf9\x9a\xd0\xb7\x2a\xbb\x6e\x71\xe1\xad\x4a\x43\xb8\xec\x4e\xf5\xe9\x64\x67\x79\xbd\xdc\x46\xf5\x29\x1b\xae\x8b\x6d\x8a\x3d\xdc\x6d\x93\xa2\x8d\xfe\x75\x7b\x54\xc9\xf6\x1f\x6a\x65\xcd\xb2\xe1\xba\x7d\x83\x22\xa3\xf8\x98\xdb\x53\x96\xdc\x14\x18\x18\x05\x98\x1c\xd1\x3f\x1d\xed\xf5\xb8\xa7\x53\x05\xa7\x03\x7f\x8a\x2b\x05\x1b\xa7\xc9\x96\xd1\xc0\xcf\x06\x23\x54\x31\xd3\x47\x03\x0a\xa3\x24\xbe\x02\xba\x85\x8c\x2b\x95\x17\xfb\xfe\x78\x18\x27\x13\x1c\xb0\x69\x08\xfc\xcc\x37\x53\xd0\x2d\xce\xc0\xe5\x49\xbd\x3b\xff\x66\x73\xb5\x08\x99\x7c\xd7\xcc\x1b\x28\x8c\xb2\xee\x9c\x0c\xcb\x33\x6e\x56\xc7\x65\x0c\xa0\x6c\x0d\xb3\x88\x51\x0f\xb5\x10\x50\xe8\x8a\xc3\xa9\x96\x0e\x40\x23\x52\xf0\x42\x2e\x4c\x1c\xb0\x6c\x66\x92\x17\xba\x33\x13\xaf\x64\x27\x7b\x23\xa5\x44\x9b\xcc\xd2\x0c\xf5\x31\x0a\xc9\x88\x4e\x70\x94\xd1\x3c\x6b\x3e\x5c\xaf\x27\x38\x13\x1e\x0b\xa5\x72\xfb\x6a\x79\x3a\x55\xe5\x3e\xcd\x71\x48\x5d\xab\xf2\x04\xf1\x9f\xf1\x34\x43\xb3\x68\xca\x93\x06\xaa\xd9\x41\x25\x9b\x96\x9a\x85\xfb\xbe\x65\xe3\x00\x99\x06\x37\xc5\x28\x08\x2f\x31\xd7\xe7\x92\x66\x70\x90\xdd\x95\x59\xf3\x68\x23\xfd\x82\x25\xd1\x66\x49\x4c\xb3\x18\x85\x59\xca\xbd\x62\x10\xa1\xe0\xfb\xde\x31\xf5\xad\xc8\xd3\x84\xb8\xee\x4b\xa6\x52\x59\x77\x99\x79\x1f\x02\x2b\x65\x9b\xcd\x00\x64\xe0\x64\x9e\x8a\xda\xce\xaa\x33\x25\x5a\x3e\xda\xf2\x33\x9f\x0b\xeb\xb5\xb2\x92\xe6\x66\x10\xa4\xd0\x06\xcf\x0b\xee\x18\x69\x46\x0b\xe5\x37\x45\x11\x64\xc1\xc8\x3c\xce\x8c\x5d\x10\x5d\xf3\xcc\x09\x80\xf2\x4b\xea\x53\xe2\x4b\x16\x94\xd4\x9e\x18\x38\xde\xe3\x4c\xe6\x39\x45\xa7\xf2\xc2\xe4\xf7\xa5\xea\xcd\xdf\x1b\x59\xc9\x32\xc9\xcc\x4d\xf7\xfa\x3c\x1d\x9d\x1c\x50\x54\x1a\x20\x16\x4c\x54\x05\x25\xfb\x38\x03\x19\xcd\x89\x13\xc9\x68\x4d\x62\xca\x80\xe1\xfc\x48\x69\x9b\xd0\x35\x17\xf9\x72\x53\x22\x1b\x30\x83\x68\x97\x36\xd4\x24\xe9\x65\x29\x98\xe7\x3a\x4d\x91\x7f\xe9\x87\x63\x88\xd8\x45\xf9\x02\x30\x3b\x37\xd5\x9c\x48\xce\x2a\x61\x74\x19\x7f\xc6\xa9\x9e\x64\xb8\xc2\x92\x03\x7b\xe8\x6a\x14\x0e\x46\x56\x56\xdd\xbf\x29\x60\xd5\x66\xab\x7c\xa1\xf4\xe3\x78\x8c\xfd\xe8\x16\x05\xf1\xce\x78\x96\x8e\xd0\xaf\x23\x9c\xd1\x78\x26\x3c\x17\x2d\xb8\x6b\x4d\xfd\x04\x18\x05\x7b\x95\x73\x6d\xc1\xae\xef\x10\x0e\x44\x70\x7a\x18\xf1\xfb\x6f\xf3\x02\xe0\x16\x25\x24\xd7\x9a\xe1\xa9\x72\x5d\x71\x39\x16\x04\x63\xcf\x14\xac\xc6\x5a\xa5\x45\x95\xc5\x47\x07\x7c\x41\x9d\x09\x5b\x22\x39\x71\x5b\xb4\x25\xe4\x35\x37\x4e\x83\x91\x75\xa9\x55\xc8\x47\xc9\xd0\xcc\x45\xf7\xbc\x78\x2e\x2b\x6c\x68\x29\x99\x8b\x0a\x73\xe8\x79\x6d\x7b\x44\xbf\x5e\x3c\x8b\x32\x4e\x5f\x16\x66\x42\x80\x46\x34\x91\xf0\x11\xc4\x2d\xde\x50\xf1\x5f\xd5\x9a\x7c\x6d\xf2\x22\xd7\x90\x33\x0c\x8e\xe2\x59\x14\xa0\xd9\x94\x3a\x14\x0e\xc6\xb3\x00\x6b\x74\x6f\x56\xd3\x30\xca\x8d\x5c\xe4\x0f\xe5\x63\xdb\x0a\x2c\x82\xf8\x2a\x92\xf1\x88\xa3\xf1\x0d\x1a\xce\xc4\xa2\xb4\x44\xd2\x5f\x5d\x45\x63\x9c\x52\xa7\x4a\xbb\xac\x05\x7c\x23\xc1\x13\x3f\x8c\x54\xe1\xaa\x5c\xbf\x26\xfe\x75\x45\xe9\x17\x5c\x9c\xa2\x65\x5b\x66\x76\x6f\xfe\x95\xaa\x98\x73\xaa\x79\x70\x4d\x39\x50\x32\xc7\x43\x69\xfd\x25\x92\x08\xd0\x45\x4f\x40\x1b\x4e\x72\x22\x5f\xd5\x3e\x86\x51\x45\x6e\xf2\x25\x6a\x79\x0a\x9d\xd9\xcc\x27\x79\x06\x6f\x1b\x91\x10\xba\x93\x00\x16\xbb\x6d\x51\x3e\x4f\xd5\x2c\xec\xf7\x1b\x79\x04\xc4\xdb\x25\x69\x3d\x39\x8d\x26\x08\x66\x38\x21\xa7\x49\xb1\x31\x2c\xe7\x07\x04\x70\x86\xb4\x57\x64\xdc\x45\xdd\x83\x04\x57\xb1\xe5\xaa\x77\xcd\x31\x52\x52\x60\xe5\x0c\x1f\xa6\xdc\x2c\xaa\x70\x5f\x99\x85\xe9\xc9\xb0\xe4\x11\xb5\xa0\xa1\x70\x32\xb4\xbc\x21\xcf\xf4\x7c\xaa\xe4\xb1\x45\x8b\xb0\x75\x2b\x9c\x54\xfc\x3d\xb9\xe9\xfb\x1a\xbb\x95\xce\x42\x59\xe8\xe4\x75\x4f\x2b\x37\xc7\x6e\xf8\x17\x99\xbc\x9d\x1b\x1b\x62\x8e\x89\x75\xc6\x0a\x2d\xde\x54\x1e\x26\x4e\x9a\x8e\x4c\xf4\xfc\x0c\x3e\xf2\x53\xc8\x90\xeb\x3c\x71\xcf\x4d\x45\x9e\xb3\x6b\xd9\x07\x8a\x4e\x3a\x83\x4e\xc3\xae\xe1\x14\xc5\x91\x74\x14\xae\x77\x50\xa5\x5d\x6f\x80\x25\x6b\xd5\x72\x2c\xde\xa5\x95\xf9\x31\x58\x3c\xda\xcf\xc3\x0f\x12\xf5\xb5\x28\x03\x59\x61\xc0\xd4\x22\x57\x33\x3a\x08\x0b\xe4\x24\xbf\x6b\x74\x3b\xd2\x10\xa2\x21\x92\xe7\x05\xb9\x2b\x6d\x43\x22\xe6\x40\x09\xdd\x76\xbc\xbb\xd9\x68\x77\xec\x4e\x62\x45\xa9\xae\xef\x1c\x61\x8d\xc7\x56\x2b\x1f\x66\xed\x18\x8b\xf0\x1e\x6e\x0d\x81\xa9\x86\x98\x63\x89\x9d\x6b\x52\xf8\xc2\x79\x78\x95\x09\xa3\x97\x87\x50\x91\x00\xc2\xb2\x8a\x47\x2d\xe1\x58\x49\x00\x5a\x61\x5e\xa6\xd4\xa0\xef\xcd\x6c\x38\x2c\x1b\x33\xdf\x90\x8f\x16\x1b\xeb\x4f\xd3\x00\x58\x86\x3c\xd8\x34\x2d\x7f\xf9\x8c\x7d\xce\x08\xc2\x14\xb8\x1e\x47\xb8\xb4\x0b\x11\x65\x45\xcc\x7f\x68\xee\xf2\x5e\x60\xce\x67\x80\x57\xe5\x05\x43\xca\xa6\x4b\x51\x4b\xce\x57\x9d\xd0\x82\x32\xa1\x28\x63\xe0\x58\x8f\x0e\x8d\x04\x53\xd8\xa8\x10\x2c\xe4\xc1\xc6\x97\x08\xe9\x04\x5f\x1b\x28\xe9\x1c\x6b\x8a\xbf\x0f\xe6\x3b\xb1\xc3\x92\xdc\xa4\x02\x17\x27\x83\x44\x1f\x63\x40\xd9\xcf\x68\xbe\x78\x56\x33\x8f\x19\x8a\xc2\x14\xe1\xe1\x10\x0f\xb2\xf0\x12\x8f\x6f\x90\x8f\x02\x9c\x66\xc9\x0c\x9e\x3d\x90\xd3\x97\xe3\x68\x80\x4b\x45\x19\x2d\x49\xa1\x4a\xa2\x07\x40\x29\x0f\xc8\x0d\x25\x16\xd7\x5c\x90\x41\x78\xa0\x9d\x01\x6d\x70\x72\x14\xc9\x84\x1c\x6a\x09\x47\xe9\x22\x42\x2f\xa8\x36\x9f\xea\x79\xd1\x85\xe8\x7e\xc7\x32\xbe\xe6\x81\xa8\x18\x0c\x9a\xb7\x56\xe6\x09\xf0\x0b\x70\x56\x69\x84\x38\x93\xdd\x91\xe6\xc1\xba\x78\x48\x79\xd7\xe2\x91\x92\xdf\xb5\xeb\x8d\xd5\x66\xa3\x9c\x98\x9f\x32\x8d\x8f\x12\xff\xde\x67\x93\xf6\x42\x04\x4e\x0a\xa3\x0c\x27\x43\xc9\x5a\x18\x39\x57\x05\xe7\xaf\xac\xeb\x9c\x6a\xe9\x76\xcb\xe2\x23\xfa\x68\x84\xc7\x53\x9c\x10\xf1\xa7\xc4\x22\xd8\x61\xb8\x31\xdf\x60\x1d\xe5\x6f\x70\x8f\x47\x65\x26\xdd\xa9\x82\x76\x75\xe5\x9c\xf6\x6a\x17\xba\x54\xb1\x09\x5b\x6e\xfd\x9c\x5c\x55\x31\x1e\x04\xd0\xae\xfb\x3d\x63\x5d\xd8\x03\xe0\x22\xf5\xbc\xc8\x56\x22\x1c\x16\xd5\x2c\x62\x79\x86\x4b\x95\xc2\x17\x3f\x36\x5a\xe9\x89\xb0\xe4\xdd\xfd\xcd\xde\xc3\xd3\x13\x11\xa1\x79\x50\x0a\xd2\x02\xa3\xab\xbf\x05\x4d\xed\x4e\xfc\x41\x29\xba\x9a\xf8\x83\xfb\xd0\x96\xa8\x7e\x2f\xfa\xfa\x8c\xed\x2a\x24\x89\xbe\x7a\xe7\x80\x16\x99\x07\x4a\x64\xb4\x11\x5a\x77\x31\x62\x2b\x3c\xfe\x0a\x4d\xd2\x1c\x1f\x06\x82\x0d\x38\x31\xb0\x1f\xb9\x17\x03\xcf\xd4\x02\x21\x7d\xf7\xfd\x6c\x44\xc3\xfa\x3e\xe3\xef\xd9\x30\xbf\xce\x23\xfd\xde\x9e\x79\xed\xd6\xf7\x1a\xde\x97\x21\x53\xe1\xe1\x88\xab\x0f\x1e\xef\x97\x43\x5e\x34\xee\xaf\xc0\x50\x8e\xff\xeb\x0a\xfa\x2b\xbe\x43\xf0\x5f\x5b\x00\x5d\xf3\x8a\x82\x47\x8d\xcd\xa7\x4c\x22\x00\x29\x1a\xac\xf4\xbe\x20\x3c\x8d\x52\x5b\x72\x81\x71\x85\x91\xed\xb4\xca\x99\x68\xb1\xb2\xdc\x48\x4b\x3c\xde\xcd\x4c\x8b\x55\xff\xeb\xec\xb4\xca\x22\xf0\x50\x9c\xb2\x0f\xed\xd9\x4d\xb5\x28\x2e\xff\x00\x5b\x62\xa3\xfc\xc4\x9f\x0a\xe1\x70\xe2\x4f\x17\x8f\xbd\x60\x71\x11\x37\x41\xb8\xac\x32\xe9\x98\xdf\xd5\x60\x19\x2d\x6d\xa0\xa6\xdb\x66\xf9\x26\xc3\x75\x8b\xd1\x32\xfd\x73\x99\x2e\xd3\x3f\xa7\x01\x33\x07\xdc\xc8\x01\x57\x42\xb4\x84\xea\x55\x8b\x4d\x34\xff\x52\xc6\x32\x9a\x03\x6e\x6a\x80\x1b\x4e\xc0\x0d\x2b\x60\x3b\xe4\x2c\x09\xa7\x63\xb8\x7a\xa9\xd0\x61\x79\xf3\x06\xfc\x26\xbe\xd2\xe7\x06\x79\x5e\x27\x8f\x80\x82\x0d\x8a\x98\x8a\x3f\xe8\x54\x54\xfe\x40\x6f\x48\xeb\x3f\xfd\x84\x00\x9b\x3f\xd0\x4b\x54\x5b\x59\x6b\x4b\x33\x54\x7d\x8d\xfe\x28\x08\x77\x21\xcd\x3d\xb5\x05\x9f\xf8\x53\xb0\x99\xdd\xcc\x2a\x15\x8e\x30\x74\xba\x83\x5e\xa2\x4a\x13\x2d\xa3\x3f\xaa\xac\xa7\xcd\xa1\xd5\xdb\xc9\x88\xcf\x60\x2a\x2e\x82\x80\xa7\xfb\x36\xa9\x91\x7d\x20\x28\xa1\x0d\x24\xa1\xd3\x31\x9c\x49\x20\xb6\x5e\x5e\xdc\x6e\x1c\x3c\x0a\xc7\x18\x55\xe4\x7e\xb2\x70\x01\xae\x58\x23\xd6\x61\x91\x9b\x59\xbc\xcf\x8c\xb3\xca\x50\xef\x61\x27\xaf\xf0\xe4\xbb\xdb\x59\x0a\x56\xbb\x10\xa3\xff\xae\x4d\x2d\xd9\x0e\x41\xed\x7a\xe4\xad\xa4\xbc\xb9\xa5\xa8\xb5\xe0\xe6\x20\xea\x09\x43\x79\xf1\x46\x18\xca\xcf\xe7\xfb\x46\x89\x04\x5f\xe2\x24\xc5\xfb\x52\xc1\xfc\x95\x2d\xae\xd9\x0f\xf9\x67\x27\x75\x17\x02\xb5\x6d\x01\xfc\x4f\xe7\x3f\x84\xfd\x90\x15\xca\x3a\x58\xc8\x69\xd4\x86\x4f\xf9\xc2\x66\xb6\xf9\x7f\x54\xcf\xd0\x06\xfa\xa3\x5c\xac\x4e\x0b\x4b\xd9\xbb\x88\xe2\x04\x7f\x33\xae\x22\x81\xdc\x8b\x02\xf0\x73\xce\xa7\x3b\x24\x6f\x0e\x86\xf3\x78\x86\xd4\x0e\x85\xf1\xc3\xc6\x06\x5a\xae\xcf\xe1\x49\x32\x85\xc9\xb5\xef\xc4\x88\xad\x22\x41\x22\xd2\x5e\xa6\xf8\x43\x1c\x4f\xf3\x25\xe1\xe9\x38\x78\xd2\x8c\x2a\x22\x87\x76\xe3\xe9\x4f\xbb\xe8\xc5\xe6\xdb\xde\xd6\xf6\xce\xbb\xdd\xbd\xff\x7a\xff\x61\xff\xe3\xc1\xe1\xff\x3e\x3a\x3e\xf9\xf4\xcb\xaf\xbf\xfd\xfb\xff\xf8\xfd\x41\x80\x87\x17\xa3\xf0\x8f\xcf\xe3\x49\x14\x4f\xff\x3b\x49\xb3\xd9\xe5\xd5\xf5\xcd\x97\x5a\xbd\xd1\x6c\xb5\x3b\x6b\xeb\xaf\x96\x56\x37\x58\x84\x5b\x71\xb4\x13\x8b\x76\x61\x54\xf3\x21\x76\x78\xa5\xe4\x96\x1b\x8a\x85\xa9\x4d\x14\xd2\xda\xb1\xb9\xa9\x90\x99\x0e\x1d\xfb\x0d\x73\xec\x4a\x89\x90\x24\x2d\x8f\x9c\x9a\x64\x07\x16\xb4\x8c\xea\xd5\x33\xf0\x5e\xc9\x05\xa6\x86\x49\x5c\x1c\x68\xa3\x0c\xd0\xea\x19\xdf\xe0\x65\x31\xcc\x02\x95\x0a\x44\x91\x12\xb9\xe7\x2b\x11\x66\x00\xfd\xaf\xb4\x45\xd9\xb7\x26\x2a\x0e\xde\x83\xd8\x10\x2f\x2d\x29\x1f\x04\xd9\x8a\x1f\x8c\x22\x8d\xd8\x92\xd6\xb0\x08\xb7\x79\xee\x1e\xfd\x90\x2f\xed\x11\xaf\x9d\x99\x7d\xda\x4f\x47\xff\xa7\xa3\xbf\x38\xfa\x7f\x3a\xd9\x59\xae\x77\xd0\xdb\xed\xd2\x0e\x5a\xf5\xce\xdb\x6d\xd9\x47\xab\xde\x51\x9f\xe0\xeb\xdd\x9d\xb6\x28\x32\x7f\xad\xe3\x56\x49\x1c\x1e\xd0\x79\xab\xde\x71\x7a\x6f\xd5\x3b\xff\x00\x8d\x40\xf9\xc3\x3a\x0c\xc6\x7d\xce\xea\x76\x7f\x7f\xb0\x8c\x8a\x03\x7c\x18\x87\x51\xe6\x72\x32\xae\x77\x1c\x4e\xc6\xd6\xc3\x74\x8e\xa9\xdb\xcb\x58\x34\x59\xd6\xd5\x58\x02\x7a\x8f\x13\x94\x4e\xc4\xf7\x72\x56\x03\xda\x5c\x74\x6d\x7c\xd7\xc7\x28\xba\xaa\x84\xcb\x1a\x5f\x7c\x0b\xf9\xac\x41\xa5\xc5\x7c\x8d\x79\x2d\x21\xdf\xf2\x17\x8f\xed\x69\xac\x36\x5c\xce\xd1\xb8\x0e\xb2\x8f\xc0\x50\x75\x33\x26\x22\x50\xbe\x58\x1a\x64\xb1\x68\x41\xd8\xdc\x14\xee\x92\x72\xb4\xd1\x79\x59\x3e\x14\x06\x23\xcb\x0f\x25\xf6\x30\x69\x9f\xfa\x70\xef\x7d\xea\xc3\x77\xb0\x4f\x95\xc1\xe1\xa1\xf7\x29\xeb\x72\xfa\xb0\xfd\xb4\x4d\x89\xbf\x07\xdb\xa6\xd2\x2b\x7f\xba\x1d\x05\xa1\x1f\x55\x16\xdd\xb1\x6c\x47\xf2\xef\x7f\xcb\xfa\xf0\x38\x5b\x56\x99\x65\xf2\xfd\x6f\x59\x1f\xb6\xb5\x4d\xeb\x69\xc7\x32\x76\x2c\x69\xc5\x2c\xb4\x79\x7d\xd3\xdd\x4b\xcc\x8b\x84\x2d\x01\xa4\xf4\x91\x47\xc3\x87\x2f\xec\xee\x84\x2e\xee\x5a\x8d\xfc\x3f\x5c\xac\xd0\x8f\xa4\xfb\xec\x2b\xfd\x96\x2f\xff\x79\xea\x02\x20\x2c\xb7\xb6\xa0\x73\x2f\x6d\x01\xcb\x51\xfb\x2d\x95\x06\x1e\x92\x5e\xa5\x23\xbf\xae\xbd\x1a\x4d\xfc\xc1\x23\xaa\x16\x3c\xc4\x9b\x85\x5f\xd0\xda\x3f\x41\xdd\x60\xe4\x8b\xbd\x83\x2a\x42\x31\x62\x91\xbe\xec\x6f\xb5\xa1\x26\x98\xdc\xec\x6f\xb5\x6d\x32\x1e\x98\x38\x7f\xc6\x37\x34\x0b\x36\xb5\x83\x15\x7d\x05\xe7\x5f\x3f\xca\x78\x12\xef\x38\x99\x50\x1b\xed\xed\x5f\x0e\xcf\x61\xd3\x3d\x89\xdf\xe3\x5c\x18\x44\x57\x57\x57\x2b\xf1\x14\x47\x69\x3a\x5e\x89\x93\x8b\xd5\x20\x1e\xa4\xab\x90\x84\x3b\x5e\xd5\xea\x8c\xb2\xc9\xd8\xa2\x08\xd9\xbe\x9c\xbe\xdf\xda\xc9\xd1\x16\xcf\x25\x83\x21\xcc\xf7\x01\xd1\xf6\x38\xc3\xfb\x85\xa5\x3c\x87\x3d\x8a\x0c\x4c\x4a\x1e\xc2\x88\xbb\xbd\x48\xe1\x9e\x73\x57\x97\x16\xaa\xd4\x1b\xeb\x8a\xa7\x8b\x01\xdf\x61\xa4\x26\x87\xc5\xd0\x13\xa4\xec\x6f\xb5\xe7\x61\x1b\x66\xcc\x16\x59\x0f\x52\x2d\x7d\xc8\x62\x34\xa5\x56\xa7\xb2\x77\x8e\x63\x87\x33\xfc\x62\xb4\xdd\x81\x0d\x4f\x17\xd5\x1b\xeb\x60\x42\xaa\x7c\xa5\x9d\x03\xcc\xb5\x2f\x39\x3e\x4a\xdb\xb7\x77\x76\xbb\x71\x10\xed\x63\xfb\xe1\x60\xa9\xd1\x07\x30\xb3\xfe\x1c\x0c\x0d\xef\x1b\x4a\xf3\x73\x52\x34\xcd\xaf\xf8\x67\x3e\x57\xeb\x5a\x3e\xbf\xbb\x82\xf1\xd4\x69\xac\xd5\x6a\x3a\xe0\x05\xbd\x83\xe6\xfa\xfd\x94\x93\x77\xb7\x20\x85\x3f\xa1\x11\x42\x15\x90\x08\xdb\x87\x0c\xac\x64\xd1\xde\xc5\x4a\x9f\xd7\xa5\xb1\x00\x6c\x80\x0a\x2a\xa7\xfe\x38\x43\x9b\xf0\x9f\xc5\xc5\x62\xa0\x2e\x4a\xde\x0f\x41\x5e\x98\x6c\x1e\x9f\x83\xe1\x0a\x75\x8b\xc0\x15\xde\x19\x0f\xf0\x2b\xc8\x5b\x03\xc5\x95\xfc\x8e\x6a\xcd\x85\x04\x5e\x75\x8a\x2d\xe2\x2d\x59\xe9\x8c\x7b\x98\xb5\x85\x97\x1a\x21\x0f\x66\xa2\x9c\xaf\x0e\x2b\x2c\x97\x5b\x18\x84\x16\xa0\x43\xfc\x1e\xc6\xc6\x96\x12\x6d\x91\x33\x72\x0e\x4c\xf8\x04\x8b\x37\xce\xe3\x32\xdf\x63\x68\x8f\xd8\x93\xa5\x9c\xc4\xc4\x69\xd1\xfc\x85\x05\xcb\x77\x6c\x63\x22\xe0\xd5\x8f\xcc\x98\x45\xc3\x95\x1b\xb4\xbc\xe1\xf8\x58\x8f\x02\x44\x8c\x03\xcf\x01\xe7\x05\xb3\xea\xb2\x44\xcb\xce\xbf\x56\x46\x72\x30\x86\xdc\x09\x84\x41\xe1\xc4\x26\x19\x05\x1b\xf4\xaa\x36\x2f\xfc\xe9\xcc\x12\x84\x26\xc4\xc0\x99\x9f\x95\x83\x52\x9d\x1e\x94\xa4\x81\x2e\x4c\xfb\xa3\x61\x2f\x90\x75\x8e\x82\x0d\x63\xcb\x50\x99\xef\x24\xb2\x62\x31\x63\xac\x6d\x68\xa3\x2c\xd5\x92\x74\x34\x9c\xfe\x2c\xd1\x2e\x44\x80\x39\x5e\xaf\xac\xcd\x75\x29\x1e\x2c\xfb\x1d\xdf\x89\xf7\x2e\xc8\x77\x1f\xd0\xfb\xd6\xe2\x57\x26\xf5\xa6\x3c\x37\x97\x2a\x29\xda\x0d\xe9\xbd\xca\xdd\xf3\x0f\x48\xe1\xea\x62\xd3\xa6\xfb\xb5\x8b\xb3\x2f\x56\xcd\x43\x0e\xb1\xe1\x3e\x60\x0a\xc5\x06\xa1\x42\xce\x65\x7d\xd7\x9e\x63\xba\xb0\xb0\x61\x57\x25\x16\x70\x5c\x29\xde\xef\x6e\x5f\x17\x1c\xdf\x29\x34\xfb\xd9\xdd\xe3\x87\xcf\x6e\x7b\xdd\xe3\x47\xd2\xee\xda\x1a\x39\xd3\xaf\xfd\xad\xcf\xf4\x83\x70\x3a\xc2\xc9\xf2\x23\x9b\x08\xc0\xe9\x5d\x6e\xea\xaf\x39\xc4\x9b\x99\x3b\x1f\xe4\x34\xdf\x83\x8e\x1d\x12\x8e\x93\x8a\x43\xbb\xfc\xd2\x6d\x42\x20\xde\x6b\x99\x30\x94\x1a\xe4\x0c\xe7\x67\x50\x89\xfe\xe4\x8c\x98\x55\xdc\x81\x97\x19\x8b\xaa\x40\x8b\x2c\x90\x4e\x83\x9c\x6e\xe8\xdc\x64\xf8\x3a\x23\xa7\x48\x9f\x3d\xa3\x29\xed\x13\xf3\xcd\xe2\xa9\x36\xfc\x00\x0f\xc2\x89\x3f\x1e\xdf\xb0\x34\xa0\x41\xe9\x9b\x1b\x79\x54\x6e\x59\x2b\x6c\xe0\x4e\x04\x1a\x6a\xb3\x8b\x27\xe3\xb8\x0b\x7e\x8f\x9a\x9e\x23\x9f\x12\xe9\x56\x47\xee\xfc\x62\x17\x3b\x4a\x4d\x87\xa3\x96\x5c\x66\x25\x9f\xdd\x3c\x81\xc4\x2e\xbe\xbe\x63\x26\x08\xcb\xf0\x4a\xe4\x23\xdf\x37\x2c\x38\x9d\xda\xcd\x43\x18\x4d\x67\xd9\x7d\xe6\x94\x93\x87\x4a\x74\x77\xa0\xb3\x87\x22\x8e\x81\xc6\x28\x2c\xf4\x71\xe7\xa4\x12\x30\x5a\xf6\x10\x36\xf9\xe4\x6c\xa0\xbc\x0d\x5a\xe1\xb5\x95\x7a\x7a\x0a\xf5\x70\x8d\x40\x0e\xa8\x2b\x03\xbd\xb5\xeb\xe6\xdd\x3b\x6d\xde\x5d\x6d\xb7\x95\x36\x88\x6e\xbb\xe1\x69\xca\xf3\xf5\x27\x53\xbb\x7f\xba\xee\xdb\xb5\x3b\x1a\x91\xcc\x8b\x34\xe1\xe6\x21\x05\x1c\x80\x85\xc6\xd5\x9a\x88\x8a\x94\xd8\x90\x1d\x55\x1f\x26\x21\x3d\xb8\xbc\xce\xe5\x78\xa5\x95\xc4\x25\x55\x51\x44\x56\x07\xe7\x65\x3c\x48\x70\xf6\x40\x4a\x25\x22\xff\xee\xda\x03\x07\x41\x2f\x19\x9b\xb0\x79\x22\x53\x47\xdf\xb2\x1a\x43\xd9\x39\xd8\x11\x20\xd8\xaa\x33\x12\xfa\x22\xea\xa3\x20\x1e\x75\x0f\xf7\x02\x6f\xb7\x87\x8c\x2f\x0b\x07\xa6\x39\xe1\x65\xe9\xa1\x4a\x8a\x2e\xab\x8f\x93\xdd\x10\xbf\x40\x31\x45\x3b\xfa\x56\x8a\x8b\xc9\xba\x5e\x14\x19\x53\xab\xc4\xf5\x05\x3a\x2c\x7b\x94\xcc\xcd\xf1\x38\xbe\x42\x7e\xd2\x0f\xb3\xc4\x4f\x6e\x10\x53\x2f\x7d\xc6\x37\x96\xb8\x83\x9f\x65\x8d\xc4\xcf\xd6\x86\x0b\x06\x4a\x57\xb7\x94\x1b\xad\x39\xce\x90\x04\xa5\x02\x37\x48\x88\xff\x06\xba\x8d\x38\x41\x61\x14\xe1\x04\xa2\xcf\xc6\xb3\x0c\x04\x08\x3d\x0a\x1f\xc4\x4c\xa4\x3a\x46\x4a\x86\xec\x81\xb6\x62\x04\xa4\xe3\x1a\x3f\xb9\x46\x68\xa9\xb1\x08\x09\xc4\x92\x56\x32\x2e\xd2\x47\x86\x52\xc1\x50\x2a\x68\x34\xf6\xdb\xc1\x11\xcc\x27\xbd\x06\x9c\xfa\x01\x1a\xc4\x51\x9a\xf9\x91\xde\xbc\x35\x89\x94\x3a\xc7\x6e\xc5\x9a\xc0\xfb\x34\x3c\x43\xbf\x6f\xa0\xda\x75\x7b\x40\xff\x67\x73\x87\x31\x0a\x37\x3b\xf4\x7f\xc5\x9a\xb1\x58\xd3\x89\x85\xda\xb3\x8d\x22\xff\x82\x38\x64\xb0\x03\x3d\x46\x14\x32\xc1\xc4\x1f\x24\x12\x59\x41\xbe\x32\x1b\x33\xb6\x0c\x24\x74\xda\xc6\xc7\x1d\x7a\x52\x55\x5f\x9c\x2f\x98\xbb\x45\x20\x83\x61\xfe\x6e\xe2\x8f\xed\x6f\xf6\x58\xf4\x31\xc0\x2b\x84\x25\x56\x18\x09\x65\xc1\x29\x2f\x13\x88\xcc\x28\xfd\xf0\xc1\xc8\x64\x92\xe0\xad\xcc\x0d\x3e\xf6\x58\xd1\xc3\x60\xa8\xff\xa7\x47\x0f\x9b\x23\xa6\x2e\x22\x22\x12\x1e\x9a\xd3\xd0\xdc\x08\x62\xee\x1a\x73\xa3\x88\xb9\xab\x3e\x52\x24\xb1\xfb\x73\xbb\x1e\x55\x4f\xc3\x78\x5b\xf6\x63\x22\x5d\xec\xda\x83\xa3\x15\x06\x1c\x2b\xe4\x98\xf2\x58\x69\x40\x73\x09\x85\x4b\x1a\xfc\x92\x49\xa0\x52\x75\x86\x1c\x9b\xf8\x03\xfb\x25\x91\x38\xf8\x3b\x8c\xe0\x5e\xfd\xad\x15\xe6\xd7\x9d\xd6\xb2\xe5\xf5\x38\xec\x2f\x13\x54\x02\xb0\x6d\x4d\xb5\xaf\x38\x1a\x2c\x83\x4d\xa3\xe5\x3d\x75\xb3\xd4\x3e\x4c\x82\xf6\x7c\xe3\xbb\x74\xe4\x37\xda\x3a\x48\xf2\xb2\xa1\x83\x4b\x47\x7e\xbb\xde\x30\x5f\x36\xd7\x2d\x25\x9b\xda\xab\x24\x9c\xe2\x49\x50\xef\xd4\xac\xb6\x7f\xca\xab\x69\xff\x73\x30\xd4\xdb\xc1\x97\xd3\xcf\xc1\xb0\xe8\xde\x41\xed\x7a\x1c\xe0\xe5\xc1\xb0\x6f\x7d\x9d\x25\x8e\xd7\xcb\x17\x63\x3f\x98\xf8\x91\xed\x73\x6c\x07\x86\x07\xfa\xeb\xa9\x1f\x2c\xfb\x51\x1a\x5e\xbf\x6a\xe8\x83\x40\x3e\x85\x69\x5c\xaf\xd5\x1b\xfa\x88\xb3\x4f\xaf\xd6\x5e\xad\xe9\x33\x44\x3e\x7d\xc1\x49\xcc\x5c\xaf\x2d\x5f\x23\xc7\x37\xaa\x23\x5b\x1e\xe1\x6b\xed\x83\x8f\x75\xe2\xa2\x71\x37\x02\xe3\x7d\x32\xd0\x27\x37\xf1\xfb\xfd\x30\xb3\xbe\x5c\x1e\xe3\x0b\x7f\x70\xf3\xd8\x77\x40\x62\xf5\xc0\x93\xbe\x68\xe0\x65\xbe\x56\xc4\x23\x5b\x22\xf0\x4c\x56\x86\x66\x16\xca\xd6\x81\xf8\xdd\x68\x89\xdf\x84\xea\xf9\x6f\x42\xec\xe2\x37\xfd\x95\x93\x76\x6e\x5f\x0a\xbf\x18\x21\x53\x0c\x28\xfd\x1a\x77\x58\x14\x1d\x4e\xad\xd2\x53\x96\xa8\x4f\x82\x36\xf3\xb7\xb1\x52\x83\x50\x22\x6d\x56\x26\x40\xf1\x46\xd0\x9d\xfc\x86\x92\x9b\x78\x23\x53\x99\x78\x19\xa9\xaf\x24\x9a\x82\x67\x42\x4a\xf0\x23\xa7\x20\x3a\x2a\x03\x36\x50\x8c\x5e\xa4\xdf\x9c\x4c\x16\x55\x44\x2a\x0a\x48\x99\xd7\x2e\xae\x98\x74\x87\x62\x63\x5d\xea\xb6\xeb\x5e\xb1\x36\xd9\x53\xe9\xaa\xdb\x6e\x79\x0a\xe1\x75\xdb\x6d\x2f\x9f\xf8\x6e\xbb\xe3\xa9\xa3\xd7\x6d\xaf\xe9\x37\xc2\x3a\x29\x77\x3b\x35\x8f\x51\x6b\xb7\x03\xf8\x08\x4a\xe9\x76\x1a\x9e\x4c\x2b\xdd\x4e\xcb\xb3\x51\x4b\xb7\xd3\xf4\x64\x0a\xe9\x76\xda\x9e\x4c\x3f\xdd\x0e\xe0\xa5\xd0\x4c\xb7\xb3\xe6\xe9\x54\xd3\xed\xac\x7b\x3a\xdd\x74\x3b\xaf\x3c\x83\x48\xba\x6b\x35\xcf\x42\x4e\xdd\x35\xc0\x9f\x2d\x89\xee\x1a\x60\xcf\x48\xa3\xbb\xd6\xf2\x0c\xe2\xe8\xae\x01\xe2\x84\x8c\xba\x6b\x80\x73\xbe\xce\xba\x6b\x1d\xf9\x02\xdd\xcb\x97\x6c\x77\x8d\x5f\xad\x93\xc5\xdc\x5d\x7b\xe5\xf1\xa5\xda\x5d\xaf\x79\xf9\x12\xee\xae\xd7\xbd\x7c\x71\x77\xd7\x01\x9d\x9c\x82\xbb\xeb\xd0\xb8\x60\x34\xdd\xf5\xd6\xed\x99\xd7\xa9\x3d\x5d\x1e\xfc\xf5\x97\x07\xbd\x11\x1e\x7c\x26\x9d\x82\x95\x42\xdd\x80\x68\x9a\xb3\x74\x36\x25\x03\x83\x59\x7c\x6a\xa9\xdf\x20\xc7\xd3\x90\xe6\xe8\x87\x0d\xf4\x82\x43\x7e\x61\xb1\x08\x11\x4e\x1a\x0f\x78\x5d\x51\x68\x8e\x2f\xda\x39\xc2\x43\x9c\x60\x38\xe8\x25\xe1\x05\x9c\xc9\xc2\x28\xcc\x72\x30\xe9\x6c\x8a\x13\x50\x5d\x6f\x68\xe9\x39\x24\x28\x9b\xb3\x8b\x09\x8e\x32\xad\x00\xca\x62\x34\xf2\xa3\x60\x8c\x95\x71\x93\x61\xf7\xad\x90\x15\x9b\x1a\xa8\x6a\xba\x03\x4a\xba\x6f\x1a\x4b\x9e\x9a\x40\x85\x51\xb6\x2e\x69\xe8\x87\x72\x7d\xa1\x98\x50\x67\xc7\x3c\xe6\xe7\x35\xa8\x12\xfe\x13\x81\x0a\x2f\x64\x6c\x94\x43\x84\x15\xb1\x98\xa6\xff\x02\x48\x97\x21\xbe\x72\xa1\xe8\x6c\x5e\x42\x78\x8f\xa3\x80\xbe\x7e\x55\xcb\x73\x82\x03\x2c\x41\x67\xcc\xab\xff\x40\xd6\x9c\xb0\x1d\x81\x45\x67\x07\x6e\x54\xad\x1a\xad\x38\xb1\xaa\x77\xec\x68\xb9\x5b\x5a\xac\xc6\x5e\x94\x35\x1b\x8b\x36\xb1\x58\x8d\x9d\x71\xec\xdf\xa5\x4a\xa7\x05\xef\xf3\xf2\x77\x24\xa5\x15\x4a\xc1\x1e\x92\x5f\xdd\x64\xf8\x00\x92\x03\x19\xaf\x6d\x79\x97\x15\xfa\xdb\xa5\x8b\x2e\x6f\xab\xcc\x8a\xc8\x4b\x2f\xa6\x42\xc8\xa1\xbd\x15\xb8\xa1\x0d\x3b\xce\x16\xcd\xc2\xf6\x35\xcb\xbe\x7a\x93\xd9\x8c\x9f\x17\x72\x17\xb4\xa1\xb2\x48\x3e\xed\xbc\xfe\x69\x78\x76\xa7\xe4\xd9\xb9\x39\x77\xf8\x05\x53\x55\x6d\xee\x38\xaa\x16\x15\x8c\x35\x4f\x6d\xe1\x21\xe6\x46\x68\xeb\x88\x32\xdf\xd6\xac\x67\x64\x34\xc9\x6b\x02\x0f\x45\x44\xea\x93\x99\xb9\xd9\xae\x3f\x9d\x8e\x6f\x58\xc3\x7e\x72\x31\x23\x2c\x3c\x2d\xf2\x57\x64\xfc\x7a\x65\x9a\xc4\x59\x4c\x70\x94\x39\x77\x91\xe1\x84\xbe\xfb\xd8\x15\x2c\x9d\xfa\x93\xac\xf3\xd7\xc8\x3a\x10\x30\xfa\x2f\x88\x4b\x64\xcd\xa9\x54\xc2\x44\x02\xb6\x58\x7a\x8f\x87\xb2\x5c\xb7\x4e\xaa\x9c\x30\x66\x21\x95\xa4\xaa\x4b\xed\xe6\xcf\x26\xe9\xb9\xf8\x4a\xa7\x65\xe7\x22\x27\x84\x4d\x6c\xd0\xe1\x5b\xf1\xfb\x29\xfd\x91\x86\x11\x0b\xc6\x4a\x58\x46\xed\xba\x5e\x63\x7f\x55\xf4\x55\x4d\xe3\xcb\x96\x57\xa5\x6a\xb5\x50\xdf\xdf\x6a\x6b\xd6\x14\x36\x03\x10\xdd\x6b\x12\x6d\xb0\x51\xb5\x18\x80\xf0\xb4\x37\x85\xb7\x63\xb9\x26\xd8\x9e\xab\xf8\xd4\xe4\xa4\xb5\xeb\xce\x5a\xab\xdd\x68\xd6\xea\x1e\xaa\x5d\xe3\xe1\x20\xf0\xfb\xeb\xaf\x2c\x79\x15\x6b\xd7\xaf\xd6\xfb\x7e\x30\x18\x62\x0f\x06\xa6\xd9\x68\xb7\xd6\x3a\x6a\xb9\x33\xe7\x8d\x98\x96\x46\x4f\xee\xc5\xbe\xc8\xa4\x67\xdb\xbb\xae\xfc\x29\xc2\xe0\x5e\x3d\x7f\x0f\xa9\x77\xdc\x3b\x86\xfb\xfa\x9a\xcf\x06\x45\xe2\x9c\xc0\xe3\xe9\x05\x51\xe8\x88\xc0\xbb\x7f\x2e\x95\xde\x3f\xe5\x0f\x67\x36\x97\x10\xe9\x33\x21\x38\xb3\x00\xf9\xab\x54\x2a\x12\x4c\xea\x29\x8e\xbe\x22\xf9\x25\xec\x75\xad\xaa\xe6\x23\x8e\xbe\x96\x04\xd8\x68\x55\x2d\x00\x21\x94\xb1\xe2\x92\x6e\x82\xbb\x9f\x71\xc8\xae\x72\x43\x61\xbf\xee\x57\x86\xb4\x86\xa4\x31\x45\x4b\xa8\xa6\x8b\x0f\x4a\xe9\xba\x56\xba\x5e\x58\xba\xa1\x95\x6e\x14\x96\x6e\x6a\xa5\x9b\x85\xa5\x5b\x5a\xe9\x56\x61\xe9\xb6\x56\xba\x5d\x58\xba\xa3\x95\xee\x14\x96\x5e\xd3\x4a\xaf\x15\x96\x5e\xd7\x4a\xaf\x17\x96\x7e\xa5\x95\x7e\x55\x3c\x3b\x35\x6d\x76\xe6\x4c\x66\x5d\x2b\x5e\x3c\x9b\xf5\x86\x56\xbc\x78\x3a\xeb\x4d\xad\x78\xf1\x7c\xd6\x5b\x5a\xf1\xe2\x09\xad\xb7\xb5\xe2\x6d\x83\x1b\xac\xae\x12\x86\xfc\x39\x8c\x2e\x48\xd5\xd0\x1f\xf7\x6d\x62\xb3\x4f\xb6\x81\x53\xeb\x40\xf5\xe1\x93\x75\x50\x06\xf0\xc9\x3a\x00\x01\x7c\x6a\xda\xd0\xe9\xe5\x77\xd0\xea\x37\x82\xc4\xce\x4e\xc5\xf7\x50\xdf\x43\x03\x0f\x05\x9e\xb4\x40\x3d\x84\xd6\x3c\xb2\x85\xd6\xce\x74\xde\x10\xd0\x7a\x81\x87\x44\xd5\x7c\x84\x3c\x84\xea\x0d\x0f\x9d\x9c\xd6\x8d\x7a\x03\x5a\x8f\xb6\x44\xab\xe6\x8b\x96\xd4\x5b\x23\xf5\x1a\x46\xbd\x3e\xad\x27\x90\xf4\xa5\x7a\x4d\x0f\xa1\x06\xb4\xd7\x34\xea\x15\xf5\xaf\x25\xfa\xd7\x5a\xa8\x7f\x6d\xd1\xbf\xf6\x42\xfd\xeb\x88\xfe\x75\x16\xea\xdf\x9a\xe8\xdf\xda\x42\xfd\x5b\x17\xfd\x5b\x5f\xa8\x7f\xaf\x44\xff\x5e\x2d\xd4\xbf\x7a\xcd\x63\xfd\xab\x9b\x04\x53\xd4\xc1\x7a\xdd\x63\x1d\xac\x9b\x14\x53\xd4\x43\x82\x25\xed\x61\xdd\x24\x99\x42\x12\x6d\x7a\x9c\x44\x4d\x9a\x29\xec\x63\x4b\xf4\xd1\x24\x9a\xc2\x3e\xb6\x45\x1f\x81\x6a\xcc\x4e\xbe\x7b\xe7\xe8\xa4\x87\x50\x9b\x76\xd2\xa4\x9b\x80\x56\xb4\x76\x92\xd0\xdb\x2b\x5a\xd1\x24\x9c\x01\xad\x68\xef\x64\xdd\x43\xa4\xa3\x27\xa7\x75\x93\x72\xfa\xb4\xa2\xb5\x93\x84\x63\x34\x6a\x50\xd1\x24\x9d\xa2\x3e\xb6\x45\x1f\x1b\x76\x5e\xe3\xea\x23\xa1\x39\xda\xc7\x86\x9d\xd9\x38\xfb\xd8\xe6\x7d\x6c\xd8\xb9\x8d\xab\x8f\x2d\xd1\xc7\x86\x9d\xdd\xb8\xfa\xf8\x2a\xef\xa3\x9d\xdf\x38\xfb\xd8\x12\x7d\xb4\x33\x1c\x57\x1f\x09\x63\x64\x7d\xb4\x73\x1c\x57\x1f\xd7\xf3\x3e\xda\x59\x8e\x93\x56\x9b\x1e\xef\xa3\x9d\xe7\xb8\xfa\xd8\x10\xb4\xda\xb0\x33\x1d\x57\x1f\xd7\x44\x1f\x9b\x76\xa6\xe3\xea\x23\x59\xfe\xb4\x8f\xcd\xba\x7d\x41\xee\xee\xba\x89\xb5\x05\xb8\x36\xed\x5c\x67\x77\xd7\xde\x49\x32\xac\x64\x6d\x9d\x9c\x36\xed\x5c\x67\x77\xb7\x60\x41\x76\xa0\xa2\x9d\xeb\xec\xee\x3a\x3a\xd9\xf2\x50\xa3\x09\x15\x4d\xd2\x29\xea\x63\x3d\xef\xa3\x9d\xe9\xb8\xfa\xd8\xca\xfb\x68\x67\x3a\xae\x3e\xc2\x44\xd2\x3e\xda\x99\x8e\xb3\x8f\x35\xd1\x47\x3b\xd3\x71\xf6\xb1\xe9\xb1\x3e\xb6\xec\x4c\xc7\xd5\xc7\x9a\xe8\x63\xcb\xce\x74\x5c\x7d\x6c\x8a\x3e\xb6\xec\x4c\xc7\xd5\x47\xc2\xca\x69\x1f\x5b\x76\xa6\xe3\xea\xe3\x2b\x31\x8f\x2d\x3b\xd3\x71\xf5\x91\x2c\x0f\xd6\x47\x3b\xd3\x71\xd2\x6a\x9b\xd3\x6a\xcb\xce\x74\x5c\x7d\x6c\xe4\x7d\x5c\xb3\x2f\xc8\xbd\x3d\xb7\xa0\xda\xa1\x9d\xb4\x73\x9d\xbd\x3d\x7b\x27\x81\xe6\x80\x07\xb4\xec\x5c\x67\x6f\xaf\x40\x0c\x68\x83\x08\x68\xe7\x3a\x7b\x7b\xf6\x4e\x12\xde\xd1\x80\x61\x6d\xdb\x45\x1d\x57\x1f\xc9\x7c\xd0\x3e\xb6\xed\x4c\xc7\xd5\xc7\xa6\xe8\x63\xdb\xce\x74\x9c\x7d\xac\x89\x3e\xda\x99\x8e\xab\x8f\xf5\xbc\x8f\x76\xa6\xe3\xea\xe3\xba\x98\xc7\xb6\x9d\xe9\xb8\xfa\x08\x34\x47\xfb\x68\x67\x3a\xae\x3e\x82\x48\x4e\xfb\x68\x67\x3a\xce\x3e\x36\x3d\xde\x47\x3b\xd3\x71\xf5\xb1\x25\xfa\xd8\xb1\x33\x1d\x67\x1f\xeb\xbc\x8f\x1d\x3b\xd3\x71\xf5\xb1\x21\xfa\xd8\xb1\x33\x1d\x57\x1f\x5f\x89\x79\xec\x34\xcd\x05\x09\xd7\x28\x19\x4e\x26\x38\x08\xfd\x8c\x39\x95\x81\xbb\x82\x5a\x8e\x1c\x71\xd1\x06\xaa\xc0\x7f\x97\x90\xaf\x6b\x58\x69\x99\x3a\x2b\x53\x27\x65\xfa\xf6\x32\x0d\x56\xa6\x41\xca\x0c\xec\x65\x9a\xac\x4c\x93\x94\x09\x0c\x6d\xae\xa6\xaa\xdc\xb1\x58\xea\x2e\x18\xd0\x16\x32\xa5\x8b\x6c\xba\x7e\xe6\xdb\x0e\xe6\x7e\xe6\x8b\x50\x3e\x7e\xe6\xbb\x95\x63\xd1\xdb\x30\x4b\x4f\xe2\xcc\x1f\x0b\x98\xd1\x96\x9f\xf9\xd4\x83\xe4\x25\x5a\xb7\x40\x87\x3a\x1f\xf0\x30\xe3\xd0\x85\xc7\x09\x94\x37\x3a\xe3\x4c\x79\x25\xd0\x3c\xcd\x41\xfe\xfc\xf3\xcf\xa8\x0d\x17\x6f\xb5\xeb\xf5\x5a\x7e\xdf\x96\x97\xf8\x17\x6a\x36\x0c\xe2\x50\xfb\xb2\x8b\x36\x10\xa8\xdd\x87\xe3\x38\x4e\x2a\x52\x27\x57\x15\xdd\xbb\xab\x73\x50\xf6\x03\xda\x90\x9e\xf4\x85\x23\x50\xaf\x54\x2a\x39\x6e\x4b\xa8\xd3\xa2\xf9\xd2\x5e\x41\x30\xd1\x56\x95\x2a\x6c\xec\xfa\x59\x5e\x95\xe1\x9c\x2b\x67\xe5\xb7\xe5\xb5\xb3\x26\x38\xa6\x9a\xd5\xc1\xcd\xd3\xcd\x1a\x5c\x62\x91\xce\xb6\xca\x74\xf6\x83\xb5\xb3\x1f\xee\xda\xd9\x0f\xd6\xce\x7e\x28\xdb\x59\xb3\xb7\xb2\x13\x55\x45\x74\x9f\x07\x9b\x82\x9c\x7a\x76\xff\x41\x30\x78\xa7\x6e\x0c\xe0\xa3\x68\xf3\xa4\x2a\xcc\x2b\x3f\xc7\x1b\x52\xd1\x79\x5b\xc8\x77\x97\x19\xc6\x3b\xbd\xdf\x16\xba\xf7\x70\x5c\x71\xa1\xa2\xeb\x7f\x81\x09\x5c\x61\xec\x9e\xda\xef\x2e\x76\xd9\x2d\x59\xa5\xb2\xab\x5c\x4b\xec\x2e\x7c\x1f\x41\x69\x61\x57\xb9\x8b\xd8\x75\x5e\x42\xcc\xbf\x71\x38\x62\xb9\x81\x61\x0e\x59\x04\x9e\x00\xc6\x54\x2d\x5a\x22\x59\x39\xb8\x21\x14\xb2\x7a\x50\xb0\x82\x53\xa6\xb8\xa1\x83\xc7\xfc\xfa\xdf\xd8\x78\xe1\xf3\xb9\x41\x0b\x2e\xef\x4a\x1e\x41\x83\x7c\xb5\x7b\x38\xd0\x5f\x02\x49\x4d\xf5\x75\xed\xa1\xd4\x43\xea\x15\x1a\xf0\x49\xb4\x81\x7c\xb4\x84\x2a\x95\x3e\xfa\x89\x6e\x8e\x95\xff\x4b\x7e\x06\x55\xc2\x06\xae\xd1\x12\xca\xa4\xf6\x44\xc0\xe2\x88\x4c\x53\x4a\x57\x2a\x8d\x53\xde\x6c\xa0\x65\x94\x56\xa1\x5a\x5f\x33\x7a\x13\x58\x69\xe7\xff\x72\x58\xc1\x76\x5c\x19\xa0\x9f\xd0\xff\x7d\x1c\xac\xb4\x43\xd0\x5c\xac\xfa\xe8\x77\x34\x40\xbf\x13\xc4\x1e\x1e\x19\x4d\x00\x9c\x8b\x0c\x41\xa4\xd2\x47\x5f\x1f\x78\x70\xe4\xdb\xea\x63\x57\x9a\xf4\xb9\x89\xf7\xcb\x04\x59\xe3\x7e\x62\x9a\x8b\x22\xac\x06\x13\x8c\xc3\x59\xcc\x51\xfa\xae\x61\xcd\xd8\xba\x14\x46\x2e\xfb\x5b\x6d\x8b\xef\x57\x71\x79\xd3\xe1\x2b\x8f\x2f\xa6\x5c\xe6\xab\x19\xf9\xf7\xb7\xda\x56\x93\x01\xe7\x24\xcc\xc9\x55\xff\x50\x53\x70\xa7\xd0\x0e\xf3\x27\x4e\xf6\xf2\x7b\x88\x89\xa3\x4e\x65\x62\x22\x76\x27\xfe\x80\x4c\x86\x92\x19\xde\x9c\x0f\x56\xcc\x9c\x93\x3c\x9b\x3d\x9d\x97\xc2\x0c\xec\x2c\xb2\xb5\xc3\x02\xaa\xf1\xb7\x76\x31\xfb\xe7\xc7\x64\xa3\x8b\xed\x25\x8b\x33\x84\x76\x30\x0e\xfa\xfe\xe0\x33\x8b\xab\x39\x89\x03\x58\x52\x84\x66\xc4\x7c\xc3\xcb\xde\xce\x5b\x22\x02\x59\xc4\x03\x30\x73\x82\xaf\x8a\xb5\x1c\x58\xb8\xd0\x56\xf6\x09\x00\x66\xcc\x23\x56\x7d\x6f\xe7\xed\xca\x76\x44\x63\x95\x83\x01\xd5\xce\x5b\x8b\xc1\xcf\xd4\x61\x2e\xc3\xcc\x0c\x0b\x4c\x66\xdc\xa2\x29\x0b\x41\xc5\x05\x12\xfa\x68\xbb\x67\x96\x42\x79\xd0\x42\x72\x28\x0f\xb5\x3c\x8f\x51\xfe\x1e\xdf\xa4\x59\x82\xfd\xc9\x66\x14\xb0\xde\x59\xac\x23\x63\x66\x16\x2b\xc0\x79\xac\x01\x9b\x90\x7d\x84\x27\x18\x82\x8c\x83\x31\x26\x9d\x27\x16\x2b\x13\xfc\xe7\x23\x7c\x9d\xd1\xd7\x76\xf1\x1d\x5f\xbe\x65\x31\x53\xa1\xf5\x95\x74\x1c\x0e\x70\x85\xa3\x20\x6e\xea\x05\x2e\x36\xfb\x49\x65\xd6\xb6\xf0\x3f\x65\xd6\xee\x31\xba\x60\x38\x3c\x0a\xd3\x85\xc7\xf6\x9b\xd1\xcd\x49\xde\xa1\x3e\x1e\xc4\x13\xe6\x75\x4f\x08\x22\x8c\x67\x69\x39\x92\x11\x5d\x2c\x25\x8e\x17\xf4\xa6\x32\xb7\x0b\x9a\x6f\x84\x79\x60\x83\xf3\xde\x65\x1e\xac\xe5\xf2\xb5\x6a\x34\x2e\x87\x63\xa6\xcd\xe7\x9f\x21\xb3\xeb\xa5\xf5\x48\x23\x4a\xa3\x0d\x14\x5e\xb2\x29\xac\x39\x56\x62\x7c\x89\xd1\xde\x2f\x70\xfe\x4c\x67\xfd\x14\xff\xf7\x0c\x47\x59\xc1\xe9\x19\xf0\x15\x0e\x0c\x73\x0d\xa0\x75\x7c\xb4\x09\x31\x27\x81\xfc\x31\x2a\xc7\x74\xa0\xa1\x60\x45\x00\xf1\x90\xda\x95\xd5\x55\xc4\x66\x24\x7f\x67\xcd\x96\x5b\x1c\x35\x86\x9a\x9e\xe7\x16\x82\x10\x09\x46\x34\x0a\xe7\x68\x83\x5e\x18\x16\x5c\x9c\xd8\x79\x5b\x64\x70\xcd\x37\x9d\x45\xe2\xd4\x75\x9a\x4f\xc2\xc7\xf7\x2e\x7c\xa0\xff\x9c\x26\x38\xc5\xc9\x25\xa6\x62\x48\x3c\x23\xa2\xbc\x24\x7e\x80\x1a\xc3\xcf\xc2\xfe\x98\x71\x60\xb4\x95\xa0\xb7\x49\xe8\x47\xe8\x1d\x75\xcf\x44\xc3\x70\x8c\x71\x34\x58\x19\x00\x08\x1e\xf2\x19\x22\x60\x6b\xf4\x73\x72\x04\x45\xfe\xcb\x8f\xd0\x6e\x32\xeb\xdf\xa0\x3f\x46\xe4\x3f\x2b\x57\xb8\xff\x9f\x17\x13\x3f\x1c\xaf\x0c\xe2\x89\x5d\xde\x39\x39\xe2\xcd\x15\x88\x3d\x72\xa1\xd2\xd2\xcf\xb3\x3c\xdf\x4b\x34\x20\x07\x05\x9a\x32\xe9\xf9\xb3\x67\x64\xd0\x81\xf4\x44\x3a\x24\x50\x12\x51\xa5\x50\x15\x66\x9d\xfe\xfa\x13\xad\xae\xc6\x97\x38\x19\x8e\xe3\x2b\x52\x07\x36\xbe\x3a\x4f\x07\x4a\xea\xd5\x3b\xd5\x9f\x48\xd9\xd7\xe2\x73\x43\xfe\xbc\xae\x7f\x6d\xb2\x3d\x8c\x35\x06\x78\x02\x2a\x04\xac\x68\x77\x75\x15\xf1\x66\x51\xbf\x4e\x8a\x00\xca\xd0\x74\xed\xb5\xa8\xd2\xc8\xab\x88\x32\xcf\x00\x01\x5a\x88\x96\x6a\xaa\xa5\x58\xb1\x67\x80\x0a\x2b\x77\x0b\xff\x12\x82\x94\x4b\x2c\x2d\xf5\x9b\xd2\x77\xf8\x87\x97\xa1\x45\x96\x96\xfa\x8d\xd7\xcf\xdd\x05\x96\x96\xfa\x75\xf6\x9d\xfc\x0b\x1d\xe7\x8d\xc2\xc3\xd2\x06\xf4\xfc\xcd\x1b\x96\x0f\x52\x7e\xdd\xa0\x2a\x40\xe5\x2d\x43\xc8\x6c\x49\x54\xab\x5d\xd7\xea\x4c\xeb\x97\x17\x65\x5c\x8f\x14\x22\x2f\x6f\x75\xea\x60\xcb\xa3\x32\xa0\xff\x55\x69\x84\xbd\xa4\x37\x48\x9c\x94\xf2\x97\x55\x46\x30\xd2\x14\xac\xae\x22\xb2\x4b\xc0\x4d\x0c\x0a\xa5\x85\x44\x17\x8f\xb1\xd2\x5e\xa4\x08\xe0\xa5\x28\x8e\xc6\x37\x74\x39\x6e\xfd\x7a\x70\xb4\x85\xfe\x40\x6f\xd0\x3a\xc0\xe4\x0d\xd6\x6d\x58\xd0\xbb\x38\xb5\xb3\xec\x1b\xef\x2f\x5f\x4b\xca\x59\x40\xac\xab\x15\xc7\xeb\xbf\x50\xe6\x5c\x54\xe4\x34\x8a\x6b\x32\x8c\xd9\x2a\xe3\x89\xa2\x59\x3e\x60\x06\xea\x45\x12\x0f\x72\x4b\x3d\x20\x34\xd8\x1b\x29\x96\x81\xd0\x1d\xe4\x20\x34\x5f\x16\xe2\xd2\x01\x21\x6c\x93\xe6\x29\x2b\x7a\xa6\x8b\x46\xec\xb3\x84\xab\xaa\x7a\x5e\x44\x28\x42\x0e\xc1\x08\xdd\x4d\x38\x42\x0b\x0a\x48\x48\x95\xe7\xcc\x43\x57\x4e\xf7\xf2\xd9\x4b\x2c\x8d\xd7\x9a\x64\x25\x8a\x4b\x02\x96\x53\xc4\x92\x0a\x2f\x20\x69\xb5\x9e\x24\xad\xef\x5d\xd2\x72\xc8\x57\x0e\xf5\xce\xc9\x51\xb1\x9c\xb3\xa8\x7a\xc7\xc2\xd2\x75\x5e\xfe\xc4\xc4\xff\x79\x4c\xbc\xf0\x34\xfb\x08\x2c\x7b\x2f\x1a\x24\x18\x22\x37\x30\xe0\x1a\x48\x26\x87\xe4\x93\xbb\x8c\xa8\x31\x8d\xe3\x0b\xdc\x96\x7f\x45\xb5\xbf\xd5\xe6\x50\x76\x57\x98\x7f\xde\x26\x65\x16\xd8\x05\xda\x4f\xbb\xc0\xdf\x62\x17\xd8\x1e\xe3\x41\x96\xc4\x51\x38\x40\xbd\x38\xc0\xfd\x38\x9e\xaf\xf0\xdf\xee\x15\x29\xfc\xe9\xd7\x85\x76\x84\xed\x9e\xaa\xf0\x27\xcf\x0f\xb5\x03\xc8\xac\x5d\x65\x20\x6a\xbd\x22\x2d\x26\xc1\x47\x59\x48\x8f\x85\x5f\x80\xef\x84\x1f\x4f\xbd\xd4\x9b\xaf\x37\x83\x32\x0b\xac\xe3\xbf\x77\x72\xe4\xff\x39\xeb\xf8\x60\x96\x4d\x67\x59\xf9\x4b\xbb\x83\xc2\x4b\xbb\x83\xc5\x2f\xed\x74\xa9\xee\x40\xbb\xc4\x3b\xf8\x6b\xaf\x83\x1e\x5d\xaa\x33\x75\xf3\xe2\xcd\xc3\x4a\x76\x05\x0d\x7d\x2f\xd2\xdd\x3f\xe9\x84\x7d\xa0\x5d\x6b\xba\x84\xa8\x83\x12\x97\x16\x07\x0b\x5e\x5a\x3c\x65\xb1\xfb\x7b\x30\xdf\xcd\x8f\xc7\x7b\xe8\xb7\x95\x57\x8d\x26\x37\x10\x47\x69\x46\x96\xf7\xc5\x8d\xc1\x7d\xa7\x7e\xb0\xb2\x19\xa5\xe1\x6f\xa4\xb4\xc8\x05\x37\xf5\x03\x99\xfd\x05\x7e\xe6\x4b\x17\xa1\xae\x0b\xd0\x54\xbd\x01\x25\xb5\x8e\x73\x83\x5f\xc5\x00\xf8\xb5\x5a\xb4\xaf\xa7\x15\xe9\xbb\x12\x8a\x00\x51\xcc\xa2\x4c\xf4\x4c\x0b\x66\x05\xb6\x78\x87\xf4\x9b\x01\x8c\xbe\x58\x56\x31\xfb\x97\xf6\xdd\x68\x8d\xc6\xb4\x19\xfb\x29\x8d\x9c\x85\xa6\x71\x1a\xaa\x1e\xf8\xa4\x51\xf2\x9d\xd4\x3f\x8c\x79\x67\x45\x0b\x4b\x1a\x46\xcb\xa8\xae\x35\x72\xe8\x07\xf9\x33\x0c\x94\xc8\x36\xa2\xbe\xa6\xac\x44\x6e\x2b\x0f\xa9\xa5\x36\x92\x87\xd4\x92\x4b\xdb\x82\x6b\xa9\x96\xd9\x4b\x1a\x20\x6e\x87\xc8\x2d\x70\x67\x91\x85\x38\x74\x8a\x78\x87\x33\x29\xe1\xbc\x32\x55\x54\x81\x2f\x46\xb3\x78\xe6\xa4\x3e\x57\x54\x34\x97\xc9\xf1\x97\xf5\x3d\xbf\x08\x92\x50\x60\xfb\x8a\xe1\x21\xa1\x81\x71\xf4\xf6\xf9\xb3\x5b\x2b\xdf\xe4\xcb\xe5\xfa\x55\xa3\xb9\x10\xef\xbc\x5f\x62\xb2\x27\xde\xf9\xad\x78\xe7\xde\xf1\x01\x82\x90\xb8\xe5\x58\xe7\x1e\x0b\xa0\x7b\x5f\xd6\xf9\x97\xb3\xc3\x7c\x49\xcc\xe1\x87\x16\x56\x45\xd3\x01\xd8\x23\xd0\xad\x24\x7e\x14\xc4\x93\x8a\xc1\x01\xab\xd5\x15\x4d\x52\x2a\x86\xc3\x52\x87\x9d\x1a\x5c\xae\xd1\x3a\xf3\x08\xb8\x27\x46\xa5\x33\x2a\x4e\x9c\x0b\x31\xaa\xbf\x77\xe6\x85\xff\x51\x8c\x6a\x75\x6f\xbb\x87\x5e\xad\xbd\x5a\x5b\xae\x23\x46\x1b\x68\x1f\x67\xa3\x38\x40\x0d\x17\xb7\x82\xd0\xde\x77\xe5\x56\x9b\x41\x40\xfd\x07\xd5\x05\x51\x82\x0b\xf0\xd5\x4b\x6a\xd3\x3f\xbe\x68\x95\x06\xfe\x0f\x4e\x62\xc8\x1d\x96\x8d\x30\x4a\x70\x2a\xf1\x45\xa5\x23\xa4\x1c\xeb\x31\x79\x36\xf0\xbe\x13\x2f\x60\x0b\xf1\x0b\xc3\x41\x5d\x8d\xce\xe6\x01\x34\x85\x67\x5f\xd8\x71\x84\xd1\x24\x4e\x30\x15\x1e\x97\x97\xa1\x6f\xae\x51\xe4\xeb\x7d\x79\xb9\xe4\x02\x87\xf9\x5c\x64\x81\xaf\xdd\x2f\xca\xf9\xd3\x02\xff\x66\xa7\x38\x14\xc5\xf1\xb4\x9c\x18\xf2\x91\x93\xa3\x73\x65\x0b\x62\x77\xaf\x89\xbc\x48\x11\xcd\x89\xa6\x16\x22\xba\xfb\x85\x9b\x7d\x22\xba\x6f\x45\x74\xff\x47\x62\x7e\xc5\x24\x27\xf1\xc0\xbf\x50\xf8\x2d\x7d\x70\x96\xcf\xb7\x86\x00\x5c\xa9\x14\x8b\xc0\x55\xf4\xf5\xab\xfe\xea\x4e\x5b\x8c\xbd\xc7\xf3\xe3\x0a\xac\xae\xa2\x4f\x04\xbe\x5a\x2f\x34\x22\x05\x80\x66\x41\x94\xb9\x1a\x85\x63\x8c\x2a\x3f\x54\x72\x5f\xeb\x3c\x06\x37\x78\x1c\x1a\x31\xb7\x85\x09\xa7\xa1\xc8\x0c\xc5\x96\x84\x54\x15\xa5\xee\xd8\x0d\xf1\x78\xcb\xec\x5e\x12\x05\x2d\xc4\x4b\xfe\xde\x8e\x5b\x96\x1c\x5d\x34\x49\xd6\xe3\xf2\x95\x3c\x13\x12\xb4\xf6\xd7\xe7\xf9\x78\xdc\x24\xe1\xe5\x62\x62\x1b\x31\xaf\xc5\x97\xe3\xdd\xcd\x7a\x1e\xeb\x99\x3c\x49\x1f\xcd\x44\xe0\x36\x07\xd1\x43\x3f\x4d\xc9\x42\x5e\x26\xa8\x05\xe8\x3d\xbe\x41\x5b\x38\x09\x2f\x69\x4e\xc8\x1d\x3e\x28\x8d\xe2\x98\xd3\x87\x6f\xdf\x6f\xed\x34\xf2\xd6\xc4\x73\xc9\xc4\xe3\xbd\x38\x1a\x86\x17\x33\x96\x89\x32\x86\xac\x90\x69\x51\x7e\xc9\x24\x9e\xe2\x24\xbb\x41\x7f\xd2\x63\x31\x78\x93\x02\xf3\x3d\x19\xd1\x1c\xc7\x29\x79\x08\x23\x96\x2e\x20\x8b\x85\x2f\xcd\x0a\xda\xc2\x43\x7f\x36\xce\xba\xa8\x85\x2a\xf5\xc6\x3a\x24\x52\xae\xba\xe0\x3b\x12\x9a\xe3\x84\x27\x32\xcf\xc1\x91\xf1\x9f\x87\x66\x98\xb1\xe4\x99\x29\x80\xca\x0f\xf5\xd2\x87\x2c\x46\x53\x9c\x0c\xe3\x64\x22\x01\x57\x20\x4b\xe9\x1f\x07\xc3\x8b\xae\x6b\x94\x11\xbd\xf8\x3a\x86\x98\x33\xf5\xc6\xfa\x6a\xb3\xa1\x85\xe0\xa6\x5d\xa1\xa8\x6b\x9f\x72\x84\x94\xc6\x6f\xab\x45\x09\x49\x8b\x12\xc8\x93\x59\x09\x72\xd2\xe2\xeb\x6d\x7e\x16\xd1\x03\xe0\x73\xb7\xa4\xab\x72\xc6\x50\x32\x7e\x03\x1b\xdd\x70\x7f\xb3\x61\x9c\xc0\x29\x26\x6f\xf4\x01\x12\x83\x7e\x0e\x86\x46\xd2\x78\x4a\xed\xfc\xf4\xa8\x98\x61\x2d\x52\xf1\xcf\x7c\xb2\xd6\x69\xfa\xc9\x7b\x83\xf1\xd4\x69\xac\xd5\x6a\x3a\xe0\x82\xec\xf5\x83\xe1\x85\xdd\xf0\x82\x4c\xc4\x86\xf8\xc9\x09\x8f\x14\x77\x05\xc3\x30\xd7\x3b\x5c\x57\x50\x0f\xba\xb2\x2c\xe8\x2e\xf9\x66\xa7\x0c\x36\x50\x0b\x7f\x58\x29\x59\x39\xf5\xc7\x19\xda\x84\xff\x2c\x9e\x88\x96\xbb\xd1\x48\x7e\xed\xf7\x21\x3b\x9a\x48\x3d\x18\xae\xb0\xa8\x24\x15\xde\x19\x0f\xf0\x73\x4e\x2a\x2b\x2e\xcf\xab\x56\x73\xa1\xdc\x2e\xea\xd4\x5b\x0d\x08\xc3\xcc\x91\x14\x96\x79\xd9\x83\xef\x3e\xa3\x55\x42\x3e\x94\x07\x79\x62\x76\xec\x66\x89\xee\x04\xe5\x20\x9b\xd2\xc1\xa6\xe9\xe6\x0d\x7d\x8e\x2d\xd4\x13\xc8\xc9\x7b\x51\x80\xaf\x6d\x35\x4e\x6b\xd7\x4c\x01\x64\x89\xd6\x39\x27\x44\x97\x40\x45\x08\xcb\xe2\x8d\x33\x7f\x7d\x8e\x0d\xaf\x94\xbf\x71\x56\xe2\x5b\xde\x06\x99\x95\x15\xf6\x64\x33\xc2\xc8\xb7\x16\x5a\x34\x7f\x31\xc7\xc8\x42\xfd\xc8\x04\x75\xad\x83\x3c\x2e\xd2\x1b\x8e\x8f\xd5\xb8\x40\x74\x92\xe5\x39\xe6\xc9\xb2\x81\x02\xf3\x34\xbe\x79\xaf\xf5\x39\x43\x2c\xa3\x77\x9e\x1a\xd8\xfc\x3e\x3f\x1b\x03\xc0\x57\x86\xd8\x3a\xba\x66\x71\x91\xc5\x28\x7f\xc5\x3a\xee\x40\x64\x4f\x8c\xb1\x1d\x74\x28\x47\xb3\x63\x60\x2d\x58\x28\xb6\x1c\x75\x6a\xcb\x21\x4d\x9f\xd3\x98\x03\x01\x3f\x57\x9a\x80\xd1\x13\x23\x2d\x7f\xb4\x8d\x75\x99\xf1\x46\xf3\x42\x41\xd9\x3a\xcb\x47\x5f\x7e\x67\x0f\x58\x25\x35\xf1\xdb\xc1\x91\xda\x1d\x70\x9d\xb2\x78\x5c\x1b\xe3\xf6\x07\xb5\x81\xf9\x83\xdb\xc0\x48\xb3\xf9\x1a\xfd\x51\x30\x7a\xe4\x2f\xaf\x71\xfa\x07\x98\xc3\x18\x1d\x39\xfd\x43\x37\x8b\xe1\x7f\xb7\xe6\x6b\x3d\xe0\x14\xf9\x93\x98\x03\xd3\x4d\x43\xa3\xb6\x29\xd1\x98\xc4\x69\xed\x6c\x69\xa9\xd8\xa4\x48\x02\x2e\x1d\x7d\x39\xdf\xb0\x04\x31\x63\x7b\x59\x5e\xaf\xc8\x80\x52\x3e\x46\xdc\x6b\x43\x2f\x13\x6c\xa6\x70\x23\x5f\x70\x13\x7f\x28\xd1\x32\x4c\x6d\xe9\xf6\xe7\x47\xaf\xb1\x88\x06\x0f\x10\xc4\x86\x8a\x08\x42\x32\xa4\x42\xa1\x4b\x4c\x58\xac\x9a\x87\x1c\xb2\xe9\x7d\xc0\x14\xca\xa6\x79\x90\x1d\x71\x94\x74\x09\x30\x1e\xd2\x05\x55\x36\xec\xaa\x58\x4c\x0a\xcd\x11\x9e\x6e\x8b\x6c\xd1\x28\x34\x7b\xa0\x1e\x3d\x85\x2e\xcf\x09\x7b\x7b\xe6\xad\xfd\xbd\x7d\xe8\x17\x48\xeb\x3e\x3f\x39\xfa\xe3\xea\x8e\x9c\xe9\xb5\x5d\x59\xaf\xff\x09\xda\xa5\x63\x30\xce\xec\x71\xe3\x5d\xaa\x44\x92\x5f\x16\xe9\x91\x04\x1e\x47\x78\x96\xfa\xfd\x31\x66\xe1\xc0\x24\x74\x8e\x91\x9c\x6a\x91\x42\xd1\xdf\xbc\x43\x6a\x86\x35\x69\x5b\x38\x82\x6c\xca\x88\x19\xda\x32\x1b\x63\x53\x93\x24\xca\x43\x8c\x95\x30\x45\x3e\xa2\x09\x98\xd1\x25\x4e\x52\x88\x5a\x36\xf2\x33\x14\xe1\x8b\x31\x1e\x64\x38\x20\x6c\x78\xc0\x52\xaa\x66\x4c\xe1\x93\xc5\x68\x1c\x66\xd9\x18\x2f\xd3\x00\x97\x2b\x2a\x50\x9c\x24\x71\x82\x82\x18\xa7\xd1\x8b\x0c\xf9\xc3\x21\x1e\xd0\xba\x14\xa9\x17\x29\x4a\xf1\x60\x96\x84\xd9\x8d\x27\x2a\xf6\x67\x19\x0a\x33\xa8\xc4\x6b\x84\x59\x2a\x02\x2a\x84\xe3\x30\x63\x4e\xdc\x34\xaf\x6b\x48\xf8\xf3\x04\x47\x74\x3f\x48\x6d\x8a\x32\x3a\x20\x1f\x68\xe7\x84\xba\x4c\x7b\x2b\xcf\xdf\x5d\x93\xb6\x15\x1f\x52\xde\xcb\x66\xd0\xce\x03\x46\x6e\xbd\x0d\xa7\x86\xcb\xa2\xd3\x42\xc8\x4e\x68\x64\xf7\xc2\xce\x73\xda\x6f\xa2\x5d\xf2\xcb\x92\x38\xee\xfd\x69\xed\xcc\x43\x95\xf7\xa7\xcd\x33\x16\x2c\x00\x7d\x25\x8f\xec\x2a\xa0\xde\xa9\x5a\x92\xc8\xbd\x3f\xad\xd3\x4a\x35\xb5\x52\xb3\xb8\x52\x83\x56\xaa\xab\x95\x6a\xc5\x95\x9a\xb4\x52\x43\xad\x54\x17\x95\xd4\x3a\xb6\xec\x48\xc6\x90\x71\x2f\x43\xd7\xa0\xf5\xc4\xa0\xf5\xec\x83\x66\xe2\x23\x0d\x17\xeb\x13\xbd\x30\x19\x0e\x79\xda\x41\x8a\x34\x0d\xb2\x5a\xab\x91\x2f\xb6\xfe\x9a\x13\xd1\x54\x21\xd7\xad\x90\x1b\xa5\x20\xd7\x9c\x03\x2f\xc1\xd0\x20\x37\x4b\x41\xae\xbb\x66\xc7\x93\x60\x68\x90\x6b\x1a\xe4\xf9\x13\xd9\xf3\x93\xe4\x06\xf5\xf5\x74\xaa\x74\xaa\xfa\x34\xfe\x85\xa9\xc9\xc8\xe8\xe4\x13\xd6\x93\xde\xa4\x19\x9e\xa0\x61\x3c\x4b\x50\x16\x4e\xf4\xb9\x5f\x30\x28\x6f\x84\xaf\xb3\x63\xb2\xfa\xdc\xf1\x63\x2d\x11\x6f\xf7\xe3\x20\x1c\xde\x50\x4e\x48\xe9\xb0\x04\x16\xeb\x6e\x2c\x7a\xa7\xd4\x71\xe0\xb7\x53\x48\x79\x09\xd1\x56\x8c\x4c\x71\xb6\x24\xb9\xbf\xa0\x14\x67\xb3\xa9\xfa\xa1\xc0\xa3\x63\xfe\x61\x7f\xef\x17\xea\xda\x51\x74\xc2\xdf\xfb\xe5\xbc\x86\x36\xd0\xde\x2f\x66\x6a\x34\xa9\x48\x9d\x16\xa9\x5b\xa3\x19\xcb\x4b\x1a\xa6\x32\x9d\xf5\x2f\x31\x11\x15\x5c\x47\xff\x1a\x0d\x7e\x0c\x6d\xd3\xe8\xc7\x5f\x11\x7d\x72\x45\x3f\x96\x8b\xb3\x30\xc7\xa2\x7c\x7e\x1d\x6a\x0f\x73\x2c\x9a\x6d\x88\x66\xeb\x4a\xb3\xf5\x79\xcd\xd6\xd5\x66\xeb\x8b\x35\x0b\x61\x74\xc2\x1a\x5f\x82\x04\x48\xd8\x50\x57\xa0\xab\x6a\x13\xaa\x36\xf8\x62\x86\xaa\x35\x75\x99\x3a\x66\x84\x91\x75\x11\x6b\x45\x40\xad\x35\x7a\xae\xd7\x63\xfb\xd3\x8f\x75\xfa\xb1\x6e\xfd\xd8\xa0\x1f\x1b\xd6\x8f\x4d\xfa\xb1\x69\xfd\xd8\x2a\x6a\xb3\x5d\xd4\x66\xa7\xa8\xcd\x35\xd1\x66\x81\x46\xaa\x14\xe7\x41\x8b\x73\x1f\x54\x8e\x03\x21\x53\x49\x21\xfb\x11\x3d\x48\x72\x57\xa7\xf2\x5a\x92\x3e\x4a\x71\x66\xb5\x88\xbd\x77\xee\xed\x1d\x06\x37\xf7\x32\x03\x2e\xa4\x96\x3e\xa6\xa1\x86\x7e\x03\x22\x44\x95\xdf\xc8\xdc\xf3\x55\x02\xcf\x62\xef\x7d\xad\x57\xac\xd3\x8a\x0d\x56\x71\x4d\xab\xd8\x76\x56\x6c\xd0\x8a\x2d\x56\xb1\xae\x55\x5c\x73\x56\x6c\xd2\x8a\x9d\x33\x81\x9a\x52\xb1\x9e\x57\xbc\xd7\x2e\x56\x14\xa5\x9e\x22\xc2\x63\xc7\x1f\xb3\x94\xec\x2c\x78\x3c\x3c\xde\x25\x7a\x3c\x87\xc3\x18\x9c\x80\x63\x8b\x1f\x6f\xc5\xd7\xea\x84\x87\xa4\x1c\xbd\xc2\x9b\xee\xb8\xd8\x8b\x4e\xa6\x7e\x61\xc7\x93\xdf\xdc\xe6\x1f\xc3\x4b\xfa\xa5\xd3\x5a\x6d\x36\x74\xb5\x9c\x58\x26\x82\x60\x2b\x25\x5d\xa1\x94\xf5\xa1\x7c\x91\x44\x50\xcd\xe0\xe7\xd8\xbf\xc4\x28\x1e\x07\x4e\x56\xbb\x80\xfc\xd0\x3b\xa7\x93\xdb\xd3\xe3\x1d\x2a\x2d\xf6\xfc\xf1\x60\x36\x26\x2b\x2c\xc2\x57\xce\x66\x7b\x2c\x11\x4c\x8f\x26\x82\xa9\x5d\xb7\x82\x26\xfc\x1f\x5a\xe2\x12\x9a\x9e\xaf\xa5\xc7\xf2\xc2\xf4\x68\x5e\x98\xda\x35\xab\xd1\x84\x98\xf2\x3d\x2e\xa0\xd6\xaa\xe8\x0d\xaa\xf4\xce\xa5\xe7\xff\x40\x75\xd4\x45\xb5\xaa\x09\xb1\xc1\x20\x36\x28\x44\x06\xb0\xc5\x20\xd6\x35\x88\xf5\x12\x10\x9b\x0c\x62\xd3\xe8\x56\x85\xb6\xa3\x40\x6c\x94\x80\xd8\x62\x10\x5b\xd6\x5e\x37\x35\x88\xcd\x12\x10\xdb\x0c\x62\xdb\xda\xeb\x96\x06\xb1\x55\x02\x62\x87\x41\xec\x58\x7b\xdd\xd6\x20\xb6\x4b\x40\x5c\x63\x10\xd7\xac\xbd\xee\x68\x10\x3b\x73\x21\xe6\x62\x3f\x05\xaa\x54\x5f\xd3\xab\xeb\xde\x31\x82\xa6\xc9\xee\x73\xb1\x7c\x8f\x45\x44\x4a\x5d\x5c\x03\xaf\x0e\x49\xd7\x7a\x96\x24\x1c\x3c\x5d\x7e\x32\x1b\x64\x68\x14\x5e\x8c\x90\x1f\x05\x68\x1c\x5f\x21\x3f\xb9\x98\x41\xf8\x17\x70\x73\xfe\xef\x99\x9f\x18\x89\x7b\xa0\x01\x1f\x6d\x90\x56\xb8\x14\x67\x51\x1e\x5c\xf4\x69\x11\xba\x4b\x58\x8f\x4f\xbc\xcf\x0a\x06\x09\x4e\x67\xe3\x0c\xc5\xc3\xa2\xe6\x47\x74\x0b\xa8\x5c\xf8\xe8\x25\xba\xf0\xa9\xeb\x4a\x7d\xad\x8a\x96\x10\x7d\xd5\x67\xaf\xda\xf0\xaa\x0f\xaf\x6c\x48\x8e\x29\x20\xa9\x2b\xf4\x48\xf8\x12\x5d\x5c\xc3\x0c\x57\x81\x20\x78\x01\x21\x76\x4a\x05\x6c\x89\x60\x48\x87\x7e\x3b\x38\x42\x10\x4e\x52\xfe\xf8\x8e\x72\xb8\x8b\x11\xfa\x1d\x5d\x8c\xcb\x32\x39\xbb\x52\xe5\x37\xc6\xe2\xde\x51\x16\x57\xa9\xbc\xcb\xb7\x6f\xb2\x93\xbd\x93\xc4\x82\x2a\x2b\xd0\x51\x0b\x74\xf2\x02\x3a\x3d\xff\xc6\xb8\xe1\x3b\xca\x0d\x2b\xb4\x99\x7c\xbf\x7d\xc7\xf9\x1f\xec\xb7\x4b\x88\xb4\x66\xc2\x68\x30\x18\x0d\x0e\xa3\xae\x22\x50\x37\x30\xac\xa9\x05\x6a\x45\x18\x36\x19\xf4\x26\x87\xde\x50\x31\x6c\x68\x18\xd6\x2d\x18\xb6\x18\x8c\x16\x87\xd1\x54\x11\x68\x1a\x18\x36\xd4\x02\x8d\x22\x0c\xdb\x0c\x7a\x9b\x43\x6f\xa9\x18\xb6\x34\x0c\x9b\x16\x0c\x3b\x0c\x46\x87\xc3\x68\xab\x08\xb4\x0d\x0c\x5b\x6a\x81\x56\x11\x86\x6b\x0c\xfa\xda\x99\x42\x22\x02\xc3\x8e\x86\x61\x5b\xc1\xb0\x54\xe2\x8f\x94\x27\x9d\x10\xba\xd6\x12\x69\x27\xe6\x5d\x77\x51\x58\x19\xbe\xce\xe4\x7b\x27\x59\x93\xca\x43\x29\x28\x69\x1c\xe8\x6d\x91\x79\x7f\x35\x1d\xfb\x04\x9b\xeb\x0c\x39\xc1\xb1\x38\x33\x95\xbc\x65\x1b\x44\x71\x71\x55\xa4\xd4\x55\x93\x77\xc8\x25\xab\x45\x77\x50\x72\xc1\xd2\xc6\xc8\x9e\x7a\x37\xd2\x6d\xb7\xbc\xfc\x52\xa4\xdb\xee\x78\xec\xae\xa4\xdb\xa9\xdf\x9e\x79\x6b\x7f\xef\x48\x84\x4f\xf7\x55\x4f\xf7\x55\x8f\x76\x5f\xa5\x2d\xf1\xfc\x3e\x47\xbf\xc9\xf9\x7b\xdd\xe1\x3c\x54\x56\xb8\xf7\xe2\x68\xfe\x5e\x3d\x9a\xbf\xbf\xeb\xd1\xfc\xbd\x7a\x34\x7f\x5f\x74\x34\x9f\xa7\x60\x7e\xba\xa9\x7a\xba\xa9\x7a\xba\xa9\x52\xbe\x3c\xdd\x54\x3d\xdd\x54\x3d\xdd\x54\xe5\xcd\x3e\xdd\x54\xe9\x1f\x9f\x6e\xaa\x1c\x8f\x4f\x37\x55\x4f\x37\x55\x4f\x37\x55\xf0\xf7\x74\x53\x55\x4e\x89\xfb\x74\x53\xf5\x74\x53\xf5\x74\x53\x25\xfd\x3d\xdd\x54\x3d\xdd\x54\x3d\xdd\x54\x3d\xdd\x54\xfd\x4f\xbe\xa9\x7a\xb0\x3b\xaa\xbb\xdd\x4e\x95\xb9\x97\x2a\x71\x23\xf5\x58\x77\x51\x7f\xef\x7c\x28\x4f\x77\x51\xff\xfc\xbb\x28\xf9\xee\xa8\xd7\x9a\xeb\xe8\x24\xdf\x1c\xf5\x5a\xd2\xb5\x11\x3c\x3c\xfe\x9d\x11\xf5\xd2\x14\xb7\x46\xf6\xa0\x02\xdc\x43\xbb\xe8\x5a\x09\xdc\x38\x65\x8f\x62\x29\x66\xba\xa9\xaf\x88\xc2\x0c\xa5\xfd\xf8\xda\x84\x73\x2c\xd0\x39\x96\xaf\xe9\xf8\x9f\x4d\x9a\x6c\xb4\x3b\xee\x43\x39\x3b\x74\x87\xf3\xd5\xb8\xef\xf1\x8d\x4d\x8f\xab\xb6\xe8\x71\xff\xf1\xb9\x0d\xb3\x41\x21\x43\xc0\xa3\x4a\x84\xe8\x5f\xf2\x38\x39\x54\x87\xac\x12\xd9\xda\xf8\xd8\x9f\x2a\x80\xcc\x48\x68\xca\x67\x23\x28\x9a\xed\xec\x4f\x7a\x51\xf9\x03\x2d\xd1\xf1\x59\xe2\x8d\x56\xd1\xbf\xa0\x57\x8e\x58\x0a\x57\xfe\xd4\x8e\x33\xec\x1b\xa6\x86\x40\x9a\x80\x63\xbb\x63\x3c\x79\x4d\x66\x7c\xfe\xf4\xf4\xac\x2a\x7e\x96\x55\x43\x10\xcd\x1f\x2c\xcb\xac\x00\x74\x6f\xb5\x1c\xd7\x84\x80\x16\xc4\xc8\xbf\x4e\xa6\xc7\xae\x32\x54\x5a\x16\x4e\xce\x8d\x76\xc7\xa1\x10\xa9\x39\x95\x21\xd6\x46\xcb\x2a\x46\xa4\xf5\xa4\x29\x46\xf2\x41\x0b\xb5\x2f\x7f\xe4\xc3\x39\x37\x03\x3c\x28\x07\xd5\xea\x9f\x65\x3c\xb5\xf9\x10\xab\x29\xa2\xcb\x28\xa2\x2a\xb5\xc8\xb2\x88\x42\xd0\xa0\xd3\x84\x71\x8c\x2a\x95\xef\x0a\x09\x3b\x08\xd7\x4a\xb4\x05\x04\xeb\x26\xd6\x9c\x50\xd5\xf7\x6a\x67\xbf\x92\xba\x15\xb6\xa6\x48\x15\x86\xd7\x59\x9e\xd7\x20\xd2\xf3\x18\x68\xc7\xa7\x4f\x10\x07\xc5\x72\xa3\x95\x93\x7a\x68\x9c\xdd\xc9\x58\x28\x73\xc5\xc4\x32\x05\xbb\xef\x55\xee\xed\xb5\x1e\x42\xe8\xed\xb5\x16\x96\x78\xcd\x3d\x56\x13\x77\x7b\x2d\x6b\x6c\x0b\xb8\xa1\x09\x71\x70\x87\x1d\x7e\x2b\x89\xa7\xca\x2e\xcf\x5e\xc0\x20\x7c\x83\xa8\x78\x01\x69\x4e\x0d\x34\xa7\xe9\xf9\xc9\xc4\x93\x52\x22\xd4\x1c\xaa\xbf\x6a\xc8\x60\xf5\x58\x73\x04\x75\x29\xea\x97\xb6\x8a\x09\xa8\xae\x0a\x42\x8d\x18\x57\x4a\x88\x21\x6d\xf0\x82\xc5\x77\x18\x64\x3c\x0b\x36\x70\x61\xf8\x42\xf0\x22\xbb\xf8\xcf\xb0\x99\x2f\x2f\x5b\xf7\xf0\x05\xd8\x3d\x9a\x93\x00\xe9\x3b\x5a\x6d\x64\x88\x1e\x66\xc5\x01\xa4\xc5\x57\x1d\xa3\xf9\xe2\x95\x47\x0a\x15\x9f\x34\x7b\xad\xc7\x3a\x66\xde\x2f\x5d\xdf\xb7\x3c\x5f\x3e\xda\x29\xf0\xdb\x06\x71\x26\xac\x0a\xa7\x38\xb9\xc4\xcf\x9f\x55\x06\x55\xd4\xa8\xd5\x1b\xa8\x7f\x83\x7a\xff\xdf\xff\x1b\x24\xe1\x00\xed\xe3\x34\x0a\xc7\x2b\x68\x73\x3c\x46\x49\x78\x31\xca\x52\xc4\xca\x07\x2b\xcf\x9f\x3f\x3b\xc2\x41\x98\x66\x49\xd8\x9f\x01\x7c\x3f\x0a\x20\x28\x4f\x18\xa1\x34\x9e\x25\x03\x0c\x6f\xfa\x61\xe4\x27\x37\x84\x1d\x4c\x52\x8f\x45\x69\x48\xe0\xbf\xf1\x2c\x43\x13\xe0\xe9\x03\xe0\xac\x1e\xf2\x13\x8c\xa6\x38\x99\x84\x59\x86\x03\x34\x4d\xe2\xcb\x30\xc0\x01\x0d\x3a\x41\xd6\xe9\x30\x1e\x8f\xe3\xab\x30\xba\x40\x83\x38\x0a\x42\xba\x86\x49\xa5\x09\xce\xba\x6c\xc5\x2f\x23\x15\xad\x14\x14\xc3\x14\x9f\x41\x1c\x60\x34\x99\xa5\x19\xd9\xa8\xfd\x30\x02\xa0\x7e\x3f\xbe\x24\x9f\xa6\x37\xd0\x45\x14\xc5\x59\x38\xc0\x1e\x8d\x2b\x34\x0e\x53\xd0\x2c\xcb\xed\x45\x81\x86\x4c\x10\xa6\x83\xb1\x1f\x4e\x70\xb2\xe2\xc2\x21\x8c\xe4\x81\xe0\x38\x4c\x93\x38\x98\x0d\xf0\x83\xa3\x81\x58\xd7\x82\x78\x30\x13\x71\x30\x48\x8d\xd5\x38\x61\x31\x32\x26\x7e\x86\x93\xd0\x1f\xa7\xf9\x30\xc3\xdc\x40\x35\x09\x75\x32\xcf\x27\xbb\x7b\xc7\xe8\xf8\x60\xe7\xe4\xd7\xcd\xa3\x6d\xb4\x77\x8c\x0e\x8f\x0e\x7e\xd9\xdb\xda\xde\x42\x6f\xff\x8d\x4e\x76\xb7\x51\xef\xe0\xf0\xdf\x47\x7b\xef\x76\x4f\xd0\xee\xc1\x87\xad\xed\xa3\x63\xb4\xf9\x71\x0b\xf5\x0e\x3e\x9e\x1c\xed\xbd\xfd\x74\x72\x70\x74\x8c\x7e\xdc\x3c\x46\x7b\xc7\x3f\xc2\x87\xcd\x8f\xff\x46\xdb\xbf\x1d\x1e\x6d\x1f\x1f\xa3\x83\x23\xb4\xb7\x7f\xf8\x61\x6f\x7b\x0b\xfd\xba\x79\x74\xb4\xf9\xf1\x64\x6f\xfb\xd8\x43\x7b\x1f\x7b\x1f\x3e\x6d\xed\x7d\x7c\xe7\xa1\xb7\x9f\x4e\xd0\xc7\x83\x13\xf4\x61\x6f\x7f\xef\x64\x7b\x0b\x9d\x1c\x78\xd0\xa8\x59\x0d\x1d\xec\xa0\xfd\xed\xa3\xde\xee\xe6\xc7\x93\xcd\xb7\x7b\x1f\xf6\x4e\xfe\x0d\xed\xed\xec\x9d\x7c\x24\x6d\xed\x1c\x1c\xa1\x4d\x74\xb8\x79\x74\xb2\xd7\xfb\xf4\x61\xf3\x08\x1d\x7e\x3a\x3a\x3c\x38\xde\x46\xa4\x5b\x5b\x7b\xc7\xbd\x0f\x9b\x7b\xfb\xdb\x5b\x2b\x68\xef\x23\xfa\x78\x80\xb6\x7f\xd9\xfe\x78\x82\x8e\x77\x37\x3f\x7c\xb0\xf6\x92\xe0\xae\xf4\xf1\xed\x36\xfa\xb0\xb7\xf9\xf6\xc3\x36\x6d\xe9\xe3\xbf\xd1\xd6\xde\xd1\x76\xef\x84\x74\x27\xff\xd5\xdb\xdb\xda\xfe\x78\xb2\xf9\xc1\x43\xc7\x87\xdb\xbd\x3d\xf2\x63\xfb\xb7\xed\xfd\xc3\x0f\x9b\x47\xff\xf6\x18\xcc\xe3\xed\xff\xfd\x69\xfb\xe3\xc9\xde\xe6\x07\xb4\xb5\xb9\xbf\xf9\x6e\xfb\x18\x55\xe6\x0c\xc9\xe1\xd1\x41\xef\xd3\xd1\xf6\x3e\xc1\xf9\x60\x07\x1d\x7f\x7a\x7b\x7c\xb2\x77\xf2\xe9\x64\x1b\xbd\x3b\x38\xd8\x82\x81\x3e\xde\x3e\xfa\x65\xaf\xb7\x7d\xfc\x1a\x7d\x38\x38\x86\xd1\xfa\x74\xbc\xed\xa1\xad\xcd\x93\x4d\x68\xf8\xf0\xe8\x60\x67\xef\xe4\xf8\x35\xf9\xfd\xf6\xd3\xf1\x1e\x0c\xda\xde\xc7\x93\xed\xa3\xa3\x4f\x87\x27\x7b\x07\x1f\xab\x68\xf7\xe0\xd7\xed\x5f\xb6\x8f\x50\x6f\xf3\xd3\xf1\xf6\x16\x8c\xee\xc1\x47\xe8\xea\xc9\xee\xf6\xc1\xd1\xbf\x09\x50\x32\x06\x30\xf8\x1e\xfa\x75\x77\xfb\x64\x77\xfb\x88\x0c\x28\x8c\xd4\x26\x19\x82\xe3\x93\xa3\xbd\xde\x89\x5c\xec\xe0\x08\x9d\x1c\x1c\x9d\x48\x7d\x44\x1f\xb7\xdf\x7d\xd8\x7b\xb7\xfd\xb1\xb7\x4d\xbe\x1e\x10\x28\xbf\xee\x1d\x6f\x57\xd1\xe6\xd1\xde\x31\x29\xb0\x47\x9b\xfd\x75\xf3\xdf\xe8\xe0\x13\x74\x99\xcc\xd1\xa7\xe3\x6d\xfa\x53\xa2\x58\x0f\x66\x12\xed\xed\xa0\xcd\xad\x5f\xf6\x08\xda\xac\xf0\xe1\xc1\xf1\xf1\x1e\xa3\x13\x18\xb2\xde\x2e\x1b\xee\x95\xe7\xcf\x5e\xae\xaa\x3a\xaf\x7d\x3f\x1b\x3d\xac\xde\xab\x5c\xd4\x69\x1a\xf8\x58\x14\xa1\x8f\xa5\xac\xb3\xe1\xc2\xce\x8f\xb2\x14\x65\x7e\x9f\x4b\x2c\xa4\xca\xf9\x97\xb1\x35\xd8\x66\x2e\x47\xd5\x3c\x84\xea\x1e\x42\x0d\x0f\xa1\xa6\x87\x50\xcb\x43\xa8\xed\x21\xd4\xf1\x10\x5a\xf3\x10\x5a\xf7\x10\x7a\xe5\xa1\x7a\xcd\x43\xf5\xba\x87\xea\x0d\x0f\xd5\x9b\x1e\xaa\xb7\x3c\x54\x6f\x4b\x16\x96\x6b\xb4\x2e\xf9\x46\xe0\x91\xf2\x04\x46\xbd\x4d\xe1\x92\x7a\xd0\xd6\x2b\x06\xbf\xc1\x60\xd4\xa1\x8d\x1c\x4e\x93\xb5\xd5\x62\xb8\xbc\x62\x30\xd6\x25\x3c\xd7\x18\xac\x0e\xc3\xa5\x4e\x61\xd6\xe5\x58\xcb\x75\x56\x97\xe3\x52\xa3\x30\x00\x0f\x8e\x67\x93\xc2\x22\xf0\xeb\x72\xbf\x65\x38\x2d\x56\xb7\xcd\x70\x5f\x63\x30\x1a\x12\x9e\x75\x06\x6b\x9d\xe1\xc2\xfa\x5d\x6f\x9e\x55\x5f\xcb\x73\x91\xcc\x99\x0b\x8e\xc7\x9a\x34\x56\x0d\x06\x93\xe3\xdc\x51\xc7\x03\xfa\xd6\xd4\xfa\xde\x61\x75\x9a\x39\x2c\xa8\xdb\xce\x71\xe6\x30\xf8\x78\x40\x5b\x75\xad\xef\x50\xa8\x2d\x75\x70\x8d\x21\xd8\xc9\x07\x57\x00\x69\x48\x03\x4d\x91\xcd\x01\xad\xb3\x3a\xd2\x60\xc1\xc4\xb4\xf3\xc1\x15\x30\x9a\xd2\x40\x53\x64\x25\x84\x1a\x6c\x64\x6b\x12\x30\x3e\x1a\x6b\x62\xf6\x04\x85\x22\x36\x3a\x14\x59\x75\x36\xd2\x79\x2b\x83\xa2\xc8\xc6\x0a\xd0\x93\x5b\xe2\xb4\xd5\x94\xc6\xb3\x93\x7f\x53\x68\x7a\xcd\x83\x4f\x30\x54\x9c\x5e\x5f\xe5\xb4\xc7\x69\xaa\xde\x96\x86\x75\x8d\x95\x55\xe6\xa3\x9e\x13\x81\x98\x8b\x57\xac\x20\x27\x9e\x75\xa9\x0c\x47\x7c\x0d\x7e\xcb\x67\x29\xb1\x96\x5b\x79\x55\xde\xbe\x58\xf3\xf2\x9a\x58\x57\x40\xe6\xa0\xf8\xfa\x6c\xe7\xb4\x2f\xfa\xd9\xc8\x51\x10\xe3\xc4\x48\x86\xc2\x45\xda\x94\xcc\x5b\x20\x0c\x31\x65\xf0\xdb\x39\x02\xd0\xcf\xb5\x7c\x21\x42\x83\x2d\x86\x48\x47\x43\xba\xa9\x0e\xbe\xe8\x74\x3d\x87\x23\xc6\x4e\x2c\x68\xf8\xae\xc0\x11\x0c\xa4\x2e\x0d\x52\x27\x6f\x57\x2c\x3c\xb6\x80\xeb\x4d\xcb\x7c\x88\x0e\x68\x88\x73\x40\x62\xc1\x35\xa4\xff\xb6\xc5\x2a\x56\x07\xa8\x6d\x29\xd7\x52\x67\x46\xcc\x64\xde\x29\x54\xaf\xa3\x33\x25\x4b\xf6\xf9\x88\xac\x10\xcb\x7c\x20\x11\xaa\xb9\xe6\xa1\xda\x75\x7b\x73\xbd\xb1\xf6\xea\xd5\x2b\xf2\xbb\xb3\xbd\xf5\x6a\xfb\xed\x66\x9d\xfc\x5e\xdf\xa9\xbf\x7d\xdb\xdb\xea\x91\xdf\x9b\xaf\xda\xcd\x9d\xad\xd6\xb6\x3a\xdf\xa3\xc4\xd9\x40\xbb\xb6\xd9\x58\x7f\xbb\xdd\x81\x06\x7a\xad\xad\xad\x7a\xa3\x05\x0d\x6c\xad\xd5\x9a\xdb\x3b\x4d\xf2\x7b\x6d\xb3\xb3\xb5\xd6\xd9\x86\x86\x39\x42\x67\x56\x7d\xc0\xd1\xde\xe1\xf6\xfe\x56\xbd\x53\x83\xf0\xfb\x73\x74\x48\xa2\x6c\xae\x45\x92\x5e\xd1\x5d\xf9\xae\x77\x45\x54\x99\x08\x48\x38\x82\x60\x77\xd6\x5a\xed\x46\xb3\x06\x23\xb8\xbd\xd3\xdb\xda\x7c\xbb\x0e\x1d\x7c\xb5\xfe\x76\x73\xab\xb7\xb3\x4d\x7e\xd7\x6b\xcd\x46\xbb\xb5\x06\x83\xd3\x6b\x6e\x35\xb6\xeb\x3b\xb5\x33\xa7\x6a\xbc\xac\x52\xde\xaa\xd8\x2d\xed\xa5\x54\x2f\xb8\xa9\x99\x6f\x8e\x4f\xb1\x00\xdd\x6b\x6e\x16\xe9\xb8\xbe\xd9\x3f\x97\x4a\xf3\xcb\x83\x73\xd3\x90\x09\x15\xdd\xa9\x48\xf5\xd0\x06\xaa\x98\x05\x10\x35\x00\x95\x1a\xcb\x0d\x1f\xa4\x97\x8b\x19\x95\x1a\x00\x99\x5d\xa9\x06\xd0\xb4\x2e\x35\xc1\x15\xa8\xc6\xd0\x3c\x5b\xe7\x5d\x24\xee\x1f\x08\x29\x3a\xaf\x1c\x81\x01\x9c\x8f\xc6\xee\x02\x09\x14\x48\x9c\x05\x40\xfc\x3c\xff\xe2\x86\x00\x32\xd1\xf9\x17\x37\x04\xd8\xa6\xcf\x53\x37\x04\xd8\x34\xce\xd3\xc4\x1e\xd1\x7a\x75\x95\xac\xb2\xcf\xe4\xd0\x7c\xe9\x27\x21\x91\x8e\x2d\x97\xb4\xfe\xd8\x43\xfd\xb1\x87\x06\x63\x0f\x05\x63\x0f\xe1\xb1\xa5\x21\x3f\xf1\x50\x3f\xf1\xd0\x20\xf1\x50\x90\x78\x08\x27\x7a\x63\x3e\x41\xc5\x27\x08\xef\x9a\x2e\x23\xfd\x04\x82\x8e\xc3\xc7\xba\xfe\x71\x40\x3e\x0e\xe8\xc7\x86\xfe\x31\x20\x1f\x03\xfa\xb1\xa9\x7f\x84\x03\x03\xa6\x1f\x5b\xfa\x47\x91\xa6\xda\x57\xf3\x52\xf3\x2e\xe9\xb7\x82\x56\x53\x42\xf8\xef\xd2\x06\xaa\x5b\xd7\x76\x46\x96\x8f\x3f\x46\x4b\xf9\x9a\x5a\xfa\x32\x3e\x0d\xcf\xce\xaa\x5f\x6d\x4e\x0c\xe0\xb5\xf3\xa6\xde\xa9\xfe\xf9\xfc\x99\xca\x1a\x49\x1b\x68\x58\xaf\xf4\xc7\xde\x60\xec\x05\xe3\x2a\x5a\x42\xa3\xb1\xdd\xf7\xe6\x16\x09\x85\x5c\xf8\xa6\xd9\xa0\xaa\x36\x0b\xb4\x86\x0e\xcd\x18\x79\x03\x5a\x6b\xdd\x09\xad\xa9\x43\x33\xa6\xca\x80\xd6\x69\x39\xa1\xb5\x74\x68\xc6\xdc\x4a\xd0\xfe\x5c\x5d\x65\x10\xd7\x6b\x4e\x88\x6d\x1d\xa2\x41\x10\xc8\x1e\x26\x9d\x4c\x62\x66\x9d\x2e\xf2\x05\x25\x71\x36\xae\x64\x5e\x4a\xa6\xd5\xe6\xb4\x01\x34\x90\x2d\xe1\xb1\x7d\xca\x61\x45\x18\x4b\x8a\xfc\x01\xdd\x06\xb6\x2f\x40\xee\xd0\x2e\x59\x93\x75\xab\x1b\x10\xac\x97\xbe\xad\x36\x2c\x33\xe3\x26\x51\xa0\xea\x27\x68\x49\xa2\xd6\xe4\xee\xd4\xda\xae\xf4\x13\x6f\x90\x78\x41\x02\x23\x9e\xdc\x8f\x5a\x5b\x3a\xb4\xfb\x52\xab\x0a\xed\x5e\xd4\xda\xd0\xa1\xdd\x9b\x5a\xeb\x3a\xc4\x07\xa6\xd6\x04\x6e\xad\x0b\xc8\x35\x71\x90\x2b\x70\xd4\xc4\x46\xae\xc0\x88\x6d\x5f\x80\x45\x53\x72\x4d\x9c\xe4\x0a\x1b\x80\xad\x36\x6c\x0d\xa6\x85\x86\xce\xca\xf7\xe4\x74\x0c\x20\x43\x82\xd5\xaf\x26\x61\x92\x7f\x36\x50\x65\x97\x9a\xe6\x0e\x08\x67\x0e\x2c\x3d\xdd\x65\x26\xbc\xbb\xd4\xfc\x36\x20\xe5\x6c\x23\xb2\xcb\xcc\x74\x77\xa9\x21\x2d\x26\xe5\x7c\x6b\xb9\x26\x2b\x07\xc6\xb2\xb0\x23\xf4\xad\xe5\x5a\xac\x1c\x18\x26\xf7\x49\xb9\x81\xb5\x1c\x18\x30\x2b\xc3\xa2\x8b\xb5\x3b\x2c\xb5\xc6\x3d\xcc\xb3\x02\x3f\xf3\x85\x30\x44\x1e\x2c\x1b\xff\xfc\x34\x8c\xbc\x64\xf4\x36\xcc\xd2\x93\x38\x03\x8e\x47\x61\x46\x5b\x7e\xe6\x53\xab\xad\x97\x68\xdd\x02\x1d\xea\x7c\xc0\xc3\xcc\x48\xda\x08\xe5\x8d\xce\x6c\x06\x81\x99\x85\x18\xb1\x7c\x8b\xd4\x98\x29\x07\x49\xa4\xc9\xf6\x19\xfa\xba\x41\x13\x0b\xe7\x36\x12\xa2\xc4\xbf\x50\xb3\xa1\x53\x6b\x0e\xa9\x52\xa9\xe4\x45\x97\x10\xe1\x0f\x04\xe4\xab\x2a\x01\xd5\x22\xeb\xb6\xde\x72\x08\xd0\xbc\x2a\x1d\x8e\x5c\x78\x96\x5e\x96\x17\x9e\x0d\x60\x4c\x70\xd6\x80\xcd\x13\x9c\x6d\x1d\x95\xf3\x74\xe4\xf9\x30\x79\x8e\x1d\x30\x8e\xb1\xa4\xed\x58\x5d\x85\x93\x20\x82\xec\x2e\xd4\x21\xcb\x6a\x38\x35\xa5\x27\x2f\x33\x9b\x4b\x31\x59\xc2\xea\x96\x65\x74\x0b\xe1\xec\xa2\x0d\x24\x8b\xef\xf7\x3b\xbf\xb5\x4b\x1d\xdf\xec\x27\xb2\x5d\x38\x8a\xed\x5a\x9c\x49\x50\xd1\x19\x6c\x57\xb8\xeb\xed\x2a\xc7\xab\xdd\x85\xcf\x55\x94\x42\x76\x95\x33\xd5\xae\xf3\x30\x35\xdf\x14\xee\x88\xde\x84\xd3\xc9\x65\x19\x2c\x02\x18\x6c\xb5\x28\xbb\x31\xd7\x26\x48\x61\x53\x83\x71\x1c\x15\x33\x28\x30\x25\x20\xa5\x72\xed\x02\x3c\xba\xcd\x20\xe8\xe7\x73\x83\x48\x68\x3d\x93\xd6\x18\x9a\xf0\x55\xb1\x8b\x82\x9f\xb7\xf4\xf6\x1f\xc9\x16\x71\xc3\x7a\xe5\xda\x43\x37\x1e\xfa\x62\x4b\xf3\x51\xa9\x5c\x83\x67\xe7\x0d\xfc\xfb\x25\xcf\xd6\x7e\x6b\xc0\x69\x14\xc3\xa9\x5c\x57\x7f\xaa\xdc\x54\xa9\x3b\xf9\xff\x25\x0f\x5f\xaa\xd5\xea\xff\xcf\xde\xdb\x6f\xc7\x6d\x23\x0b\xe2\x7f\xc7\x4f\x81\x99\xdf\x19\xbb\x15\xb5\x24\x02\xfc\x02\x6d\x2b\xbf\x4d\x14\xfb\x3a\x1b\x3b\xf6\xb1\x9d\xb5\xef\xf1\xb1\x33\x20\x09\xaa\x19\xb7\xba\x75\xbb\x29\xab\x35\x13\xcf\xd9\xd7\xd8\xd7\xdb\x27\xd9\x83\x02\x48\x82\x24\x00\x76\xcb\x72\xee\x64\xc6\x9a\x33\x4e\x77\xb3\x50\x55\xa8\x2f\x14\xf1\x51\xb8\x67\xc3\xe6\x8f\x62\x13\x88\xfe\x21\x30\xb6\xac\x59\x70\x05\xe3\xb8\x6e\x03\x06\xe0\xed\x6a\xef\xf6\xe4\x1f\xc0\x9c\x1d\x63\xb8\x8d\xcc\x84\xd0\x7e\x6b\x51\x59\x70\x41\x2a\xb1\x99\x2e\x8c\x98\x36\xf7\xef\x2f\x80\xab\xcd\x37\xdf\x7c\x33\xf1\xc9\xc1\x42\x67\x4a\x7e\x70\xee\x86\xa9\x37\xc3\xc8\x7b\xe0\xb6\xdb\x0c\x63\xbd\xed\x47\xed\x6f\x81\x3d\x4f\xf5\xe7\x6a\x29\x23\xd3\x10\x8d\xe5\x7e\x1e\x0b\xf4\x75\x2f\xe6\x51\x9e\xd1\xee\x64\xa9\x27\xf0\x26\x77\x14\x8b\x77\x0c\xbb\x70\xec\xad\x2e\x6b\x6e\x4d\xdb\x6d\x86\x93\x83\xbd\xad\x36\x35\xc0\x76\x5b\x95\x6a\xe5\x3c\x7a\xf2\xed\xc9\xef\xa0\x1a\x47\xf3\xf7\xfc\x0a\x9a\xae\x79\xb6\xe2\x95\xe5\xee\x24\x8b\x42\xe1\xca\xc1\x1b\x54\xa8\xbc\xc8\xb0\x51\xcd\xa3\x33\x96\xb5\xea\xd1\xb7\x58\x19\x34\xd4\x01\x1e\x6a\xe9\x8c\x65\x06\x4d\x7d\xf5\x51\xae\x03\x5b\xb6\x46\xd5\x90\xe6\xdb\x89\x3e\xbe\x9d\xc6\xf1\x97\x2d\x4e\xff\x0a\x47\x56\x3e\xf7\xd2\x7d\xaf\xb0\x9a\x46\xd8\x5a\x32\xed\xc5\xa3\x6f\x0f\xf0\x16\x2b\x19\xc3\xbb\xaa\x6f\x72\xfd\xe2\x18\x4e\x9f\xb6\x4b\x18\xe5\xa2\xac\x26\x86\x02\x54\xdd\x25\x0d\x5e\x64\x39\x4b\x69\x62\xa8\xcd\xe4\x6d\x12\x9a\xb2\x3c\x2b\x78\x67\x8d\xc3\x04\x98\xf9\x39\xe1\xb8\xf0\xba\xcf\x3e\x7d\x09\xc4\x96\xa1\x9b\x93\xef\xe1\x0c\xfa\x00\xc1\x36\x73\xcf\xe6\xe9\x62\xf1\x28\x35\x4f\x16\x43\xc2\x68\x9e\x2a\x86\xd7\x55\xf3\x44\xb1\x78\xc4\x9b\x69\xe2\x01\xa7\xd6\x79\x62\xeb\x9c\xb0\xe5\x6d\x01\xe6\x7d\x90\x3c\x61\x6a\xa9\x05\xf3\x4a\x26\xfe\xdd\x12\x18\xdd\xb3\xa7\xf5\x5f\x3d\xa1\x64\x46\x54\x9f\x73\x78\xf5\xa6\x44\x07\xc8\x7f\x8b\xde\xa9\x8f\xb4\xfd\x88\x03\xed\x73\x64\xbb\x3b\x52\xb1\x34\x59\xc0\xe1\x58\xf9\x6e\x09\xaf\x0f\x3e\x36\x97\xa9\x31\xbf\x09\xc1\xd4\xd2\x84\x09\x24\x21\x20\x61\xf2\x4d\x26\x86\x03\xb2\x1c\xed\x03\x21\xdb\x44\x23\xba\x8f\x88\x67\x95\x1a\x4c\x9b\x4d\x26\x29\xba\x8d\x32\x99\xe7\x8a\x8f\x39\x60\xf6\x36\x21\x93\xab\xb0\x23\x53\x7c\xe8\x3e\x0a\xc6\x48\xa4\xe8\x1d\xca\xd0\x3b\x94\x4b\xcc\x11\xcf\x13\x9e\x32\x53\xd1\xa1\x1e\xe6\x68\x07\xe6\x25\xef\xe2\x53\xa6\x7a\x71\x80\xbc\x4d\xec\xf1\x20\xf0\x49\x60\xa7\x75\xf4\x75\x43\x8e\x7a\x7b\xe8\xeb\xa3\xad\xfb\x22\xf0\xfb\x61\x92\xfb\x9c\xf4\x67\x79\x90\x45\xa5\xc2\x5f\x72\xd3\x74\x1f\x3a\x46\x99\x69\x8a\x0f\x01\xc9\xfb\xf7\x91\xef\xa9\x5e\x82\xfa\x8d\x77\x8b\xa2\x63\x64\xe2\x83\x6d\x77\x5a\x6b\xab\xc9\x40\x35\x89\x56\x4f\xb6\xb1\xfe\x09\x6f\xd4\x99\x08\x84\x09\xc3\x41\xe5\x13\xd4\x99\x04\x84\xc9\xc2\xcc\x0c\xe3\xeb\x13\x85\xb9\x19\x26\xd0\x27\x09\x79\x1f\xe6\xcb\x04\xdf\x3f\xeb\x04\x9f\xc8\x85\x0f\x8b\xf9\x72\xb9\xd2\xe7\xdc\x8e\x60\xa0\x56\x7f\x9f\x44\x04\x6a\x21\xb4\x98\x47\xe6\xe9\x06\xd3\x74\x9f\x69\x86\x6e\xc7\x79\x20\xe3\x74\xdd\x1f\x71\x36\xe8\xcb\x14\xc2\x60\x32\x40\xa4\xcf\x3b\xcd\x1e\x40\x03\xd7\xc4\x41\x37\x21\xef\xce\x19\x88\x67\x5f\xa6\x0b\x6e\x74\xba\x00\xf4\xb1\xc5\x4c\x81\x59\x2d\xed\x24\x81\x52\x8d\xfd\xd8\x94\x00\xb0\x4f\x0b\xd0\x3f\x74\x81\x8d\xf5\x8c\x91\x30\xfa\xdc\xb5\x31\x14\x95\x7f\x9f\xe9\x83\xc1\xf4\x80\xfe\x0e\x4f\xc2\xa8\xf3\x16\xaf\x9d\xc2\xee\xcf\x0a\x10\x12\x6c\x37\x2f\x20\x00\x3b\x38\xe1\xbb\x44\xfe\xbb\xce\x0d\x64\xd8\x0b\x13\x9e\x53\xf1\xca\xef\x47\x71\x96\x87\x5e\x0c\x9f\xbd\xd8\xcb\x73\x0c\x9f\x8b\xd8\xe3\x61\xe2\x9b\xe7\x0c\x8a\x22\xf3\xbc\xd4\x87\xc9\x85\x88\x86\x14\x87\x58\x7e\x0e\x8a\x84\x16\x0c\x10\xa4\xbc\x60\x41\xc1\x82\x1d\xa6\x0b\xb6\xca\x3c\xb5\xb0\xaf\x44\xa7\xb5\x74\x9c\xa2\x85\x88\xda\xa4\x33\x07\xc7\xc3\xe4\xc5\xb2\xb0\xf4\x65\x88\x1e\x19\x71\x09\x09\x76\x1d\xa4\x45\x93\x91\x61\xba\xe3\x1d\x83\x81\x9a\x10\xf3\x21\xf6\x2f\x43\xf5\x27\x0c\xd5\x42\x2b\xdb\x0d\xd6\x46\xe5\x74\x86\x6b\xa9\x20\xe7\x80\x4d\x48\xff\xa8\xb3\x76\xae\x59\x0d\x47\x77\xe3\x44\x0c\xe0\xc9\x97\x79\xfd\xff\x9e\x81\xf9\x8f\x77\x2c\xef\x07\x79\x89\x43\xf9\xb7\xe6\x54\x2e\x5a\x2d\x2f\x16\x39\xca\xba\xe7\xf5\xb4\x1e\x3c\xea\x5f\x9d\xf2\x63\x77\x19\xa0\x9e\xa8\xe5\x2d\x0e\xf9\xc4\x94\xc1\x20\x7d\x49\xb9\x5c\x3f\x5b\x95\x67\x7c\xb2\x30\x0e\x63\xeb\xff\x5a\x55\x3f\xd5\xef\xf9\xe2\xcb\x64\xd1\x7f\xcf\x6c\x26\x82\xa5\x3a\xd1\x31\x22\xf7\xea\xcf\xf7\x8f\x25\x86\xfa\x07\xc7\xdc\xf0\x9f\x26\x0b\xf4\x17\x05\xb6\x67\x9d\x2f\x54\x3e\x5a\xb0\xf9\x9a\x8f\xef\x0a\xec\xcf\x8f\xd5\xef\xe3\xab\x8b\xee\x1b\xae\x41\x2c\xa7\xbc\x7a\xb8\x62\xf0\x99\xcd\xbf\x2b\xab\xb5\x41\x40\xcd\x12\xfe\x02\x1d\xa0\xc9\x02\x2a\x7b\xee\xa1\xaf\x3b\x93\x1f\xfd\x99\x2c\x8d\x56\x3d\x4b\xad\x57\x66\x87\xdf\x40\x21\xbd\xfa\x3d\x97\xb3\x72\xce\xd1\x44\x3d\xbb\x8f\xd4\x96\xcc\xbe\x14\x5b\x6d\x5a\x05\xdd\xa0\xa0\x56\x29\x3f\x7a\x23\x81\xa0\xec\xe8\x40\x10\x60\x0b\xe7\xcb\xcb\xc9\x62\x8a\x30\x3a\x42\x64\x6f\x8b\x8a\xed\x08\x6e\x42\xd9\x05\xad\xbf\x67\x2c\x9e\x2d\x51\xec\xef\x8f\x4c\x85\x2e\x3a\x10\x75\x86\x34\x69\x71\x5e\x7f\x8d\x4d\x24\xde\xdb\x65\xd3\xc3\x0c\xfd\xb3\xaf\xb4\x3d\x3a\x5c\xcf\xcb\x8c\x4f\xbc\xbd\x2f\xab\x5e\x5b\xaf\x7a\x0d\x1e\x15\xf0\x28\x34\x3d\x3a\x85\x47\x83\x05\x23\xc8\x59\xe0\x51\xfc\xc9\xcb\x68\x91\xa3\xd6\xfd\xef\xbd\x8c\x76\xca\xce\xce\x98\xb7\x69\x16\xd3\xf0\x40\x28\x43\x68\xd8\x68\x3c\xa9\x5b\xde\xbf\x8f\x88\x5c\xf4\xaa\x7f\xf9\xe6\x9b\x6f\x50\xbc\xb7\x87\xd0\x3b\x33\xa6\xee\x5f\x07\x13\x0e\x06\x98\x30\xdd\xdb\xdb\x0e\x53\xb7\x9d\x6f\x0c\x2f\x9d\x9e\xe0\xb6\xdf\xc6\x4d\xf2\x5d\x60\xad\xdb\x58\x32\xab\x75\x1b\x6f\xea\x7a\xd3\x5b\x32\xdb\xc5\xe4\x0f\x31\x25\x3b\x76\xbb\x6e\x67\xbe\x93\x00\xb5\x86\xa3\x94\xb8\xaf\x7a\x0e\x45\x7e\x55\x0f\xf7\x9d\x0b\xa6\xb6\xd5\xcf\x0c\x4e\x35\x4e\x38\xba\x8d\x0a\xd8\xec\xf6\x0f\xf1\xf1\xd4\x76\x85\xcb\x19\x83\x0a\x73\x0c\xdd\x46\x29\x80\x33\xb9\x3a\xf8\x0e\xa9\x75\x42\x13\xff\x90\xac\x94\xa7\x82\xf1\x66\xa9\x55\x2d\xb6\xa9\xb5\x56\xb9\xf5\x4f\x3e\xc1\x89\xf6\x04\xfb\x9d\x47\x9d\x46\xe6\xb1\xad\x21\x06\xf7\xd4\x4c\x38\xd8\xb8\xac\x9c\xcc\xa1\x5d\xa4\x30\xca\x27\x58\x7b\x82\xb1\xfe\x28\x96\x3b\x5b\xe5\x23\x12\x9a\x47\x3c\x58\x40\x16\x94\x66\x68\xbf\x26\xbb\x2f\x84\xba\x2f\x2f\x7a\xb3\x2e\x1e\x43\x43\x82\x8e\x6b\xc1\xec\x0b\xd1\x9a\x28\x88\xc0\x75\x6a\x40\x20\x62\x5d\xbf\x4e\xbb\xf8\x13\xe1\xd1\x94\x7e\x41\xed\x4c\xb8\x2d\x01\x9b\x96\xf9\xd0\xc8\x12\x69\xbf\xda\x3a\x1a\x59\x0e\x9d\x54\x42\x10\x15\x31\xd1\xfa\x77\x59\x1a\x95\x30\xa1\x82\x81\x92\xe1\x85\x19\x26\x52\x30\x50\x12\xfc\xd4\x0c\x13\x2b\x18\xf0\xf9\xd9\x97\x65\xd8\x2f\xcb\xb0\x5f\x96\x61\x87\xd9\xe6\x97\x65\xd8\x7f\xca\x39\xde\x30\xda\x79\x8e\x37\x8c\x46\xe7\x78\xf5\x77\xb6\xe1\x1c\x6f\x18\x7d\x99\xe3\xbd\xf1\x39\xde\x30\xda\x76\x8e\xd7\xa4\x9c\xee\x1c\x2f\x28\xc8\xbd\x69\xbb\x59\x3b\x33\x2f\xcd\x52\xef\x0f\xbd\x34\xbb\x89\x82\xdf\xe5\xe2\x82\x86\xce\x97\x59\xe0\xee\x2c\xf0\x26\x82\x35\xd5\xc3\x4d\x14\x68\xbf\xbf\x8e\x02\x55\xa5\x1b\x20\x0e\xb5\x3a\xd1\x3b\xd5\x74\xd3\xfa\xf7\xfc\xd1\xd3\x5f\x9e\x3e\x7c\xf8\xe2\xc1\xcb\x17\xfd\xd9\xe2\x67\x3f\xfc\xf2\xc3\x4f\xdf\x3f\x78\xfd\x60\x78\x2b\xf7\xf3\xa7\x3f\xff\xf4\xfd\x2f\x27\x4f\x7f\x7a\xf1\xf2\xdb\x9f\x9a\x96\x1a\x39\x39\xad\x7c\xb2\xdd\xb4\xb2\xd6\x62\x35\x5b\xd6\x45\x5b\x7a\x73\xd2\x35\x69\xf1\x76\x8d\xa7\xe8\xca\x56\xaa\xbc\x92\x53\x22\x15\xba\x8f\x48\x70\x0f\x55\x86\x29\x11\xad\xcf\x6f\x36\x68\x1f\x85\xe8\x6b\x74\x25\x4f\x0f\x56\xf5\x21\x4d\xf8\x44\xf6\x60\xa6\x12\xfd\x05\x45\x83\x5c\x04\xd2\x40\x7e\xf9\x1a\x1d\xa3\x2b\xf4\x17\x14\x9a\xb2\x44\x7e\xf9\x9f\x02\x2b\x41\x5f\x23\x41\xc7\x17\x74\xf6\x0c\xc0\x1b\x39\x2d\xf7\xba\xf7\xf3\x95\xfc\xf9\x3f\x2d\x53\xc1\x9a\xd8\xce\x4b\x54\xc2\x75\x02\x06\xa1\x35\x92\xd9\x48\xc9\x6c\xe4\x01\xcd\x8d\x41\x30\x0d\xa8\x94\x2e\xba\x92\xa0\x57\x96\x69\xa5\xd6\x40\xba\x62\xbc\x82\x0b\x7e\x86\xbd\x16\x72\xed\x77\xfd\xe3\x68\xdf\x7a\xab\x1c\x5d\x6b\x78\xfc\xf0\xc5\x73\xc1\xeb\xc6\xc3\x26\x63\xd0\xef\x9d\xb0\xcc\x8f\x09\x30\x20\x51\x1b\xeb\x93\xf5\x65\xcf\xb6\x8c\x60\x8f\x6b\x30\x8b\x08\xd5\xcd\x13\xbf\xa2\xfb\x28\xbe\x87\x7e\x75\xcc\xcc\x41\x1f\xe0\x68\xaa\xb9\x2a\x4a\x4d\x3e\x2d\xab\x67\xcb\x35\xd4\x71\x15\x56\x05\x97\xe5\xfe\xba\x87\x0e\x90\x69\x37\x75\x8d\x5c\x6f\x74\x1f\xa9\x7a\x11\x26\x60\xf1\x37\xe8\xe0\xbb\x63\x04\x64\x34\x2c\x16\x5a\xdd\x1d\xd5\x3a\xd5\x6f\x8e\x81\xac\x7d\x73\xf5\x80\xf2\x13\x8d\x72\x07\xd5\x81\xe1\xbd\xa7\x61\x60\xbb\xa9\x25\xcd\xb0\x16\x7c\x53\x81\x01\x8d\xa8\x85\xda\x77\xa2\x1f\x1d\xa1\x67\xab\xf2\xac\xac\xca\x0f\x1c\x9d\x2f\xe7\x57\x8b\xe5\x59\xc9\xe6\x68\xf9\x81\xaf\xd0\x7f\x3c\x9c\x90\xbd\xbb\x68\xf3\x8e\xa2\x7d\xb4\x79\x17\xc1\xbf\x21\xfc\x1b\x88\x30\x63\x46\xa9\x2c\x5a\x92\x97\xe7\x07\xde\x21\x6f\x13\x3b\xb6\xcc\x5b\x98\x53\x18\x8e\x8d\xf6\x31\xb2\xe8\xd5\x0b\xf0\x72\x8e\x4f\x0d\x3f\x75\x81\xb1\xbe\xce\xa6\x03\xfb\xd9\xdb\x75\x35\x65\x0d\xfe\x53\xf1\xb3\xf3\xe5\x8a\xad\xae\x3a\x37\xd1\x09\x17\x78\xa9\x0f\x44\xd6\x55\x4a\xe3\xad\x33\x66\xef\x7f\x69\xec\xd9\x18\xdf\xbd\xb5\x1d\x7f\xbb\x95\x1d\xbf\xb3\xae\xe3\xbb\x56\x75\x6e\xfe\x2a\x81\xe5\x45\x75\x7e\x51\x3d\x86\x57\xeb\x0e\x2c\x82\x24\x3d\xe7\xeb\x72\xc5\x73\xed\xa2\x81\xb4\xac\xd6\x75\x41\x68\xd9\xb8\xf3\xb6\x50\x37\x7e\xba\x98\xd7\x6a\xd2\x6a\x70\xb3\x15\xbf\x8b\x08\x09\xa6\x88\x84\xd1\x14\xf9\x34\x98\xa2\x10\x93\x7e\x63\x75\x67\xc1\x5d\xf1\x4c\x7f\xd4\xbf\xb4\xa0\x7e\x69\xb6\xde\x5b\xa0\xf7\xae\x87\xed\x1a\xf7\x17\xc0\x4c\x2d\xdc\x84\x58\xbf\x7b\xd7\xdf\xde\xbc\xb5\x44\xfb\x2d\x4c\x4d\xfc\x01\x1e\x69\x72\x0b\x7e\xd9\x98\x1d\x2c\xc2\x8d\x95\x12\x00\x4e\x9a\xdb\x7a\x61\x04\x88\x3c\x0f\x1d\x20\x31\xd0\x36\x37\x25\xe8\x92\x10\xd9\x8b\x4f\x3e\xd7\x8a\x9e\x61\x62\xce\x20\x34\xe3\xe4\x59\xdd\x89\xc7\x6c\x01\x73\x3f\xbd\xae\x1d\x21\x62\x9a\x43\x4b\xd7\xcb\x55\x3a\x2e\xff\x1e\xfa\x4f\xa9\x24\xf8\x84\x94\xa8\xbb\x28\x26\x64\x6d\x9d\x36\x7f\x42\xe0\x0e\xfa\x3e\xb8\x88\xf5\xae\x62\x16\xd6\x2b\xa8\x05\x79\x67\x3d\x41\xd2\x29\x24\x48\xae\x53\x41\x90\x74\x4a\x07\x92\xeb\xd7\x0c\x54\x0c\xe3\x31\x8e\x71\x97\x65\x7c\x2d\x9e\x71\x97\x69\xbc\x0b\xd7\x46\x3d\x48\xe3\x6a\xa6\x46\xca\x45\xb5\x94\xd6\x6c\xd6\xf4\x9c\xc1\x64\x5e\xed\xce\x06\x51\x08\x88\x43\xb8\x6f\xf6\xdd\x31\xc8\xc5\x06\x33\x5f\x5e\x22\x05\x33\xbe\x1a\xf1\x5c\x0c\xb0\x6b\x8b\x0f\xc8\x44\x19\xfc\x40\x7e\x94\x49\x2f\x7c\xb6\xbb\xc0\xcb\x19\xaf\xd8\xf0\xc9\x0e\x6f\x0d\x1a\xb2\x27\xa5\x78\x05\x99\x5f\x9c\x2d\xa0\x73\x06\xb7\xaa\x25\x58\xa7\xd9\x53\xd4\x66\xd2\x46\xe0\x1d\xdf\x49\x74\x1a\x1d\x2d\xb5\x6f\x28\x16\x42\xe2\xaf\x4e\x3d\x1b\xed\xb9\x60\x1f\x6b\xb0\xf3\xe5\xa5\x35\x2f\xb5\x4a\xeb\xa5\x31\xcf\x31\xf5\xe4\xa5\xd0\xc2\xcb\x37\x1b\x1b\xef\x2f\x37\xd2\xd6\x8e\xa1\x07\x76\x20\x30\xb6\x63\x60\x7d\xbb\xdd\x37\xd7\x33\x03\x47\x58\x6d\x7b\x14\x40\x97\x26\x42\x2f\x01\xbc\x1e\xba\x16\xcb\x5f\x6e\x70\x0b\x8e\xb7\x01\x97\xf6\xf5\x72\x83\x5d\x7a\x54\xb0\x8f\x1b\x58\xd0\xa3\xd3\xbc\xd7\x17\x2b\xf0\x28\x79\x9d\x88\x30\xf5\x71\x2b\x7f\xb9\x09\x54\x2c\x40\x93\x89\xe2\xad\x39\x1a\xac\xe8\xab\xf3\xc1\xb6\xd7\x1b\xc0\xf6\xb8\xc1\x26\xa3\x86\xc4\xf6\xb8\x87\xed\xc9\x38\xb6\xdf\xd5\xa9\x3a\xa1\xd0\x61\x9f\xa8\x1f\x12\x2d\x66\x8a\x76\x7a\xdb\x7b\x3e\x5b\xa2\x67\xa5\xc3\xb2\x05\xc9\xfa\xce\x47\x7c\x4f\xfb\x2a\x53\xb9\xe6\xfb\x27\x9b\x7c\x47\x72\x0d\x5a\x97\x19\x0b\x20\x69\x41\x63\x01\xa9\x86\x7e\xdc\x42\xdb\x43\x12\x0c\x16\xb3\xe5\x53\x99\xa5\x1c\x77\xe6\xc3\x74\xbe\xac\x9d\x7d\xbe\x84\x44\xcf\x11\xe2\xc5\x0b\x74\x4b\x62\x74\xe2\x41\xf3\x95\x49\xdd\xe9\xfb\xf7\x5b\x26\xc1\xb4\xeb\xfe\xc1\x55\x9a\x3e\x41\x07\xda\x73\x9b\xa1\xa3\xae\xeb\x34\x38\x8c\xc8\x9f\xec\x88\xbc\x3b\xe7\xd1\x76\x77\xab\x19\x8f\x7e\x97\x15\x57\x1a\x1a\x98\xed\x18\x32\x17\x05\xd7\xee\xf9\x93\x11\x1a\x8f\x77\xa4\xe1\x1a\xdb\x56\x6c\xb1\x3e\x5f\xae\x9d\x56\x02\xe1\xf7\x59\xf9\x58\x3a\xc6\xcb\x37\xda\x84\x62\x6b\x87\xd6\x31\x4f\x36\xdc\x66\xe0\x53\x90\x63\xa3\x9f\x35\x7e\x9c\x97\x88\x55\x30\x04\x42\xbc\x34\xe7\x84\x2f\x3d\xe8\x83\xb1\x68\x6b\xf3\x72\xe4\x35\x01\xc0\x08\xf7\xd2\xab\xbb\x23\xa1\x6d\x2e\xff\xd2\xab\x3b\xa3\xe0\x2c\xe3\xd6\xd1\x11\x3a\x99\xb9\x82\xdf\xf6\xc3\xfa\x35\x87\x8c\xf1\xd0\x88\xb4\xf0\x55\xc7\xe1\x66\x5c\x19\x31\xee\xdd\x42\x6a\xdd\xea\x65\x63\x70\xdb\x37\xd9\xe0\xa6\xd1\x44\x4b\x42\xf6\xb6\x19\x00\x25\x02\xd2\x43\x40\x06\x08\x9c\x52\x14\xb9\xc7\x6a\x79\xe9\x10\xe2\x5c\xf3\x86\x97\xad\x6b\xbc\x43\x93\x7f\x28\xf6\xe5\x0f\xb7\x6b\x66\xe0\xab\x2b\x7e\xcc\x35\xaf\x79\xd9\xba\x90\x8e\x11\x7e\x68\x31\xce\x97\x97\x9f\x3e\x41\xfb\xc3\xd2\xf4\x46\x32\xd0\xb7\xd5\xd3\x3a\xd3\x90\x62\x7c\xeb\x4d\x66\xc2\xf3\xd1\x97\xb6\x0e\x16\x9b\x23\x76\xf2\x95\x6e\x0b\xe1\x92\x8e\xc5\x8e\x7f\xae\x6d\x51\x86\x49\x9a\x1b\xdf\x15\x35\x80\x6f\x66\x7c\x44\xbb\xe1\x34\xd0\xd7\x30\x79\x35\x9c\x07\xba\xee\x5e\x2a\x7c\x9d\xad\x54\xb0\x49\x2a\xe3\xe5\xbc\xbb\xdf\x09\xef\xa1\xa3\x2e\xff\x7b\xe8\xeb\xfe\x0f\x40\x1c\x16\x68\x9a\xdd\x5c\xff\x24\x9b\xa0\x3e\x79\x0e\x4f\x9f\x66\xac\x99\x37\xce\x41\xa2\x23\xa3\xea\x75\x90\x7a\x16\x70\x88\xf3\xc8\xb8\x99\xee\xc5\x7f\x5d\x70\xfe\x37\x3e\x44\x3a\x63\xeb\x59\x6d\xdc\x5b\xdd\x45\x3f\xe0\xe2\x53\x26\x0b\xc7\xe7\x84\xb6\x4f\xe9\x6d\xe9\xfc\xee\x73\x88\x2d\x3d\xfb\xac\x9c\x96\x1a\xaa\x89\x39\x3d\xe1\xdc\x69\x6e\x4e\x43\xa5\xa6\xe7\x74\x54\xd7\x9d\x57\x6c\x45\xe1\xee\xc4\xe3\x41\x27\x1e\x5f\xb7\x13\x8f\x07\x9d\x78\xbc\x5b\x27\xcc\xaa\x92\xa6\xab\x9c\xac\x5a\xa2\x15\xaf\x56\x25\xff\xc0\x0d\x1b\x10\x91\x3a\xdc\x2d\xe3\xc1\xf9\xc5\x7a\x56\xb3\x61\x12\x91\x01\xf2\xc9\x10\xf2\xd3\xcb\x13\x1b\x4e\x0f\x35\xa4\xa7\x43\x17\xb6\x9e\x27\xba\xa1\x5d\x93\xf6\xf8\xa5\xb6\x50\x1a\xc2\x59\x73\xd8\x69\x8b\x08\xb1\xe5\x62\x4e\xfd\xb1\xdd\x9f\xe9\x14\xfb\x97\xed\x9a\xd7\xdc\xae\xe9\xef\xba\x59\xd3\x1f\xdb\xaa\xe9\x3b\x36\x6a\xfa\x5f\xb6\x69\xde\xf4\x36\x4d\x7f\xcb\x4d\x9a\x06\xb5\x74\xb6\x68\xfa\xdb\x6c\xd0\xf4\xed\xc7\xf0\x9b\x8d\x87\x77\x69\xf0\xf1\xed\x94\xe2\x7f\x91\xed\x9a\xfd\x02\x3b\x21\x26\xbf\xdb\x1e\xce\xba\xdc\x8e\xa0\xf9\xc7\x2a\xb7\x73\xad\xdd\x96\xea\x71\xbb\xdb\xb3\x86\xd9\xa9\x20\x4f\x88\x49\x67\x5b\x48\x88\x89\x75\x9b\x09\xdd\xb2\x20\x8f\x00\xec\x6c\x35\xa1\xaa\xaa\x45\x88\xc9\x8d\x1d\x21\xd6\xbb\x6f\xad\xc9\x33\xd8\xe4\xe0\x6d\xb2\x34\x4d\x93\x3c\xcc\xa7\x5a\xc1\x9e\xbd\xa9\x09\x32\x22\x09\x23\x09\x61\x7a\x39\x9f\x3d\x43\xdd\x1e\x43\xd3\x04\x87\x89\x87\x43\xa6\x57\xff\x31\x13\xc1\x21\x29\x78\x26\x6b\x06\xd5\xb5\x81\xb6\x24\x12\xc5\xbe\x4f\xa2\x48\x96\x15\x52\x95\x83\xcc\x44\x28\x4f\x83\x80\xd1\x58\xaf\x2b\xb4\x25\x91\x3c\xf5\x32\xc2\xbd\x5c\x2f\x43\x64\x26\x12\xc4\x69\x18\x50\x9c\xeb\x45\x8a\x7a\xa9\xe9\x4d\x57\x29\x12\xf6\x74\xcd\x2a\x45\x38\xfa\x52\xa6\xe8\x86\x72\x22\xba\x73\x99\x22\xd1\x64\x2c\x2f\xd2\x63\xc6\x30\x33\xa2\x5f\xca\x14\xdd\x7c\x6e\x44\xb7\x2d\x53\x64\x54\x4e\x37\x3f\xa2\xa3\x65\x8a\x7c\xea\x2e\x53\x24\x86\xf1\xbb\x94\x98\xb2\x25\xf2\x2f\x92\x2d\xfd\x4b\x1f\x6e\xb9\xd9\x83\x2d\x9f\xe9\xc8\xca\xf5\x93\x28\xf9\xa8\xe9\xae\x42\xf4\x4b\xbd\x83\xd7\x70\xd7\x4d\x77\x93\xef\x21\x3b\x3f\x9f\x5f\x4d\xd4\x8f\x53\xc4\x56\xa7\x17\x67\x7c\x51\xad\xfb\x77\xf2\xe8\xc7\x67\x5a\x7e\xa0\x94\x52\x4b\xa2\x47\xde\xdb\x04\x84\x32\x52\x24\x90\x57\xe4\x31\xa1\x8c\x13\xb2\x37\x1d\xc2\xc5\xd8\x8f\x83\x20\x81\x32\x83\xc4\xe7\x45\x14\x66\xb9\x9e\x1a\x0c\x1a\xa4\x61\xe6\x15\x69\x56\xc0\x05\x08\x59\x90\xfb\x29\x29\x4c\x88\x79\x92\x86\x79\xca\x42\xb8\x3d\x1b\xd3\x24\x4f\xd3\xcc\x89\xd8\x4f\xc2\x28\x23\x61\x0a\xe9\x8c\x1f\xd0\x34\xf4\xa9\x09\x71\x98\x14\x18\xe3\x02\x38\x4e\x23\x2f\xcc\x3d\x9c\x38\x11\x27\xc4\x2f\x28\x61\x70\xe5\x36\x2b\x70\x12\x14\x49\x6a\x42\xcc\x52\x9c\x85\x3c\x07\x8e\x73\x16\xe5\x14\x63\xea\x44\x9c\x53\x2f\x66\x4c\xca\x98\xf9\x9e\xef\x91\xc0\x28\x63\x4c\xa8\x1f\xa6\xf2\xce\x88\x20\x8c\xbd\xa8\x48\xb9\x13\x31\x09\x7c\x4c\xc3\x14\xee\x8e\x08\x38\x0f\x52\x42\x33\xa3\x28\x42\x2f\x8b\xf3\x0c\x2e\x10\xcf\xc3\xa2\x48\x03\x4e\x9c\x88\x63\x92\xf2\x30\x8f\x41\x14\x05\x89\x53\x9a\x44\x46\xe5\x51\x2f\xe7\x29\x96\x97\x57\xf8\x29\x8e\x92\x28\xc5\x6e\x19\xa7\x79\xe6\x45\xb2\x42\x25\x09\xb3\x18\x13\x3f\x34\x21\xce\x70\x92\x16\x58\x32\x90\x15\x51\x42\xa2\x24\x70\x22\xe6\x41\x92\x46\x49\x06\xb2\x4b\x78\x81\x03\x96\x1b\x65\xcc\x8b\x94\x07\x31\x85\x6b\xc4\x7d\x1a\x14\x24\xe4\xbe\x13\xb1\x57\x64\x38\xc9\x33\x68\x40\x53\x9a\xe5\x61\x6a\xe4\x98\x04\x5e\xc6\x70\x96\xc1\x25\xed\x31\xcb\x92\x2c\x0a\xdd\xca\xcb\x79\x42\xb2\x08\x1c\x24\x4c\x48\xea\x91\xd8\x88\x38\x60\x71\x40\x03\x06\xef\x08\x11\x67\x11\x0f\xa8\x9b\xe3\x30\x4b\x3d\x96\xe4\xc0\x49\x9a\x07\xb8\x48\xf3\xc0\xe8\xd2\x51\x91\x50\x9a\x03\x62\xea\x63\x1c\xfa\xa9\x9b\xe3\x84\xfa\x3c\xc4\x21\x01\x97\xe6\x51\x94\x17\xcc\xec\x20\xd4\xc7\x59\x14\x41\x86\x4f\xf2\x34\xf0\x09\xf6\xdc\xb1\xc2\xf3\x7c\x12\x67\x54\xde\xf9\x5e\xa4\x04\xfb\x46\x73\x4b\x8b\x30\x89\x8b\x4c\xd5\x37\xe5\x85\xc7\xb9\xdb\x2a\xb2\x88\x7b\x5e\x5a\x80\xe1\xfb\x39\xa3\xb4\xc8\x8c\x56\x91\x87\x2c\x4e\x70\x00\x88\x13\xdf\x63\x2c\x26\x6e\x51\x78\x51\xc6\x22\x3f\x94\xd7\xbb\x78\x9e\x4f\x89\xd9\x41\x70\x40\x12\x92\xc8\x77\x2f\x8f\x79\x3c\xe2\xb1\x5b\x14\x24\x4e\x63\x8f\x51\x08\x2e\x41\x94\x13\x52\x14\x46\x97\x26\x1c\x0b\x31\x81\xc8\xc2\x8c\x44\x59\x42\x22\x27\xe2\x20\x27\x59\x94\x17\x60\x15\x21\xcb\x02\xc2\x78\x6e\x8c\x15\xbe\x4f\xbd\x1c\x83\xc8\x92\x3c\x09\x53\x3f\x2f\x9c\x88\xa3\xd0\x63\xb1\x1f\x06\xd2\x41\x58\x11\xf9\x39\x37\x9b\x5b\xc4\x3c\x96\x42\xdc\xf6\xb3\x38\x4e\x09\x73\x87\x4d\x8a\x33\x92\x25\x44\x46\xb7\x98\xe7\x8c\xf3\xc8\x84\x38\x21\x31\x21\x99\x14\x19\x0e\x28\xf1\x43\x3f\x75\x22\x66\x24\x2d\x38\x65\x32\xce\x66\x05\xf6\xfc\xc8\xe8\x20\x8c\x62\x16\x45\x01\x70\x9c\x66\x01\xf1\x3d\xcf\x1d\xdd\x32\x12\xa4\x34\x8d\x3d\x88\xb3\x5e\x41\x93\x38\xc1\xc6\xe8\x16\x47\x59\x88\x19\xc8\xd8\x8b\xc2\x20\xe5\xbe\xdb\x2a\x72\x9c\x10\x4e\x71\x02\x88\x23\x5e\x84\x04\x1b\xc7\xbc\x3c\x4a\x12\x2f\x22\xa0\x8b\x30\x8c\x42\x96\x8c\x78\x5e\x11\x78\xdc\x0f\xa5\xec\xc2\x38\xc6\xc4\x23\xcc\x68\xc7\x5e\xc4\x98\x27\x7b\xe6\x93\x34\xcd\x71\xea\x56\x1e\x4e\x58\x90\x61\x0c\x61\x33\xa5\x39\xc9\xbd\xcc\xc8\x31\xe6\x7e\x1c\x65\x9e\xb4\x63\x1c\x60\x96\x86\xee\xe8\x46\xe2\x80\xc6\x71\x00\x76\x9c\x17\x94\xf3\x34\x49\x4c\x88\xfd\x20\xf5\xd2\x2c\x85\x9e\x71\x9c\xa4\x01\x1d\x31\x37\x3f\xc1\x99\x97\xa5\xa0\x94\x2c\xcc\x92\x90\x45\xbe\x31\x1e\xf3\x9c\x32\x16\x40\xd8\xe4\x7e\x80\x29\xcb\xdc\xe6\x16\xa6\x49\x96\xb1\xa0\x90\x23\x43\xe4\x73\x3f\x36\x22\x8e\x28\xe1\x51\x21\x83\x55\x1e\xa5\x24\xa5\xcc\x2d\x8a\x38\xa0\x05\x25\x1c\x1c\x24\xcc\x79\x91\x12\x73\xac\x88\x29\x0b\x23\x5f\x8e\x34\x81\x8f\x63\x52\x44\x6e\xab\xa0\x41\x46\x63\x8a\x65\x26\x84\x0b\x8f\xa5\xb1\x31\x6c\xd2\x2c\x8b\x3d\x22\x95\x87\x59\x14\xf8\x09\x77\xe7\x6e\x89\x97\xf2\xa2\x28\x98\xcc\x22\x23\x1f\x73\x62\xb4\x0a\x16\x84\x5e\x94\x71\xf0\xbc\x9c\x53\x92\xe6\xdc\x9d\xbb\xa5\xbc\x48\x98\x5f\xc8\x91\x81\x64\x51\x9c\x60\x73\x5e\x11\xc5\x38\xa6\x85\x1c\xc2\xfc\x98\x84\x3e\x71\x2b\x2f\x63\x24\xf6\x79\x06\x32\xe6\x8c\x44\x11\x4e\x8c\x32\xce\x31\x8d\x52\x2a\x87\x26\x22\x0c\x89\x74\x27\x01\x87\x89\x08\xcb\x59\x9c\xe7\xe0\x20\x59\xce\x3d\x9e\x62\x63\xd8\x2c\xc2\x38\x0f\x8a\xb8\x50\x83\x2e\xcf\x71\xec\xb6\x63\x2f\x2a\xbc\x28\x96\xf9\x42\x4c\x70\x1c\x15\xa9\xd1\xa5\x3d\x16\xf9\x71\x9e\x81\x83\x30\x92\xd1\x84\x32\xf7\x08\x82\xb1\x5f\x24\xd4\x0b\xd4\xc4\x5d\xe2\xe5\xcc\xc8\x31\x4e\x63\xec\xa5\xbe\x8c\xc7\x3e\xce\x82\x18\xbb\x65\x4c\x68\x9e\xc6\x71\x11\x4a\xab\xf0\x82\x38\xa7\xc6\x78\xec\x93\x8c\xb1\x34\x06\xab\x08\xbc\x2c\x26\x41\xe2\x76\x10\x3f\x4b\x78\xca\x3d\x10\x05\x0e\xb3\x24\xe5\xa9\x51\x79\x81\x8f\xf3\x28\xce\xa0\x67\x49\x86\x3d\x2f\x0f\xdc\x76\x1c\x64\x59\x98\x07\x32\xf1\xce\x52\x9f\x07\x24\x35\x0e\x4d\x22\x5d\x21\x49\x02\xc1\xaa\xc8\xa2\x30\xe6\x22\xbc\xba\x62\x45\x91\xa5\x51\xc1\xe4\x20\xc9\xf2\xa8\x60\xdc\xc8\x71\x94\x05\x01\x4e\x28\x20\x0e\x58\x10\x87\x14\xc7\x6a\x12\xf5\xad\xe3\xd8\x6a\xfb\x5e\xf8\xea\xba\x27\x54\x6d\xd7\xa0\xbd\xea\x9c\x50\xfd\xe5\x7a\x27\x54\x43\x4c\xb6\x5b\x3a\x30\x2c\x47\xdc\x7c\xf5\xd1\xeb\x2e\x1d\x44\xcc\x4b\x78\x3d\xe1\xee\xa7\x59\x96\x78\x96\xa5\x83\x34\x8d\x62\xc6\xe5\xf0\x4b\x83\x8c\xb1\xb8\x9b\xba\x38\x88\xf8\x59\xc4\x0b\x3f\x86\x48\x56\xf0\x24\x28\xa8\x88\x64\x26\x48\x16\x06\x45\x11\xfa\xe0\x05\x61\x81\x73\x3f\x2a\xb6\x9d\xd5\x0f\xb1\xc7\x43\x22\x83\x0f\xcb\x79\x44\x49\x6e\x59\x3a\x48\x52\x2f\x8c\xa8\x34\x48\x92\xfa\x3c\xca\x70\xb1\x25\x11\x5c\x50\x3f\x4f\xa4\xcd\x17\x69\x80\xd3\x3c\xb2\xf4\x24\x4c\xb9\x97\xe5\x32\x0d\xc2\x7e\xcc\x09\x8e\x93\x5d\x96\x0e\x6e\xfa\x1c\xe9\x36\xa5\x61\x01\xce\xb3\x57\x7e\x7d\x84\xed\xa5\x5f\x1f\x11\x7b\xed\xd7\x47\xbe\xbd\xf8\xeb\xa3\xc0\x5e\xfd\xf5\x51\x68\x2f\xff\xfa\x28\xb2\xd7\x7f\x7d\x14\x5b\x0a\xc0\xca\x0e\x42\x79\x58\xe3\x3e\x70\xf9\x7c\x2e\x9f\x0f\x0f\x7b\x48\x19\x40\x73\xe3\x11\x28\xf9\x7c\x2e\x9f\x5b\x9a\x13\x68\x4e\xac\xcd\xc9\x5c\x3e\xb7\x34\xf7\xa1\xb9\x6f\x6d\xee\xcf\xe5\x73\x4b\xf3\x00\x9a\x07\xd6\xe6\xc1\x5c\x3e\xb7\x34\x0f\xa1\x79\x68\x6d\x1e\xce\xe5\x73\x4b\xf3\x08\x9a\x47\xd6\xe6\xd1\x5c\x3e\xb7\x34\x8f\xa1\x79\x6c\x6d\x1e\xcf\xe5\x73\xc3\xb6\xbe\x2d\x8b\x1e\x4b\xcb\x30\x21\x67\xd2\x28\xfa\x15\xf7\x60\xcb\xad\x34\x08\x53\xab\x54\xda\x82\xa9\x55\x26\xed\xc0\xd4\x2a\x93\x26\x60\x6a\x95\x4b\xf5\x9b\x5a\xe5\x52\xf3\xa6\x56\x5c\x6a\xdd\xd4\x8a\x4b\x85\x9b\x5a\x15\x52\xd9\xa6\x56\x85\xd4\xb3\xa9\xd5\xa9\xd4\xb1\xa9\xd5\xa9\x54\xaf\xa9\xd5\x4c\xaa\xd6\xd4\x6a\x26\xb5\x3a\x37\xd5\x1d\x74\x1d\xdd\xdd\xf2\x3a\x54\x6b\x3d\xed\x9a\xfe\xab\x52\xd6\x1e\xb6\x1d\x37\x7f\x00\x23\x78\xbd\x7c\x36\x04\xd9\xa2\x50\xb4\x24\x23\x44\xf0\xaa\xac\x4f\x1b\xe8\x55\xa3\xd1\xd7\x88\xbc\x05\x48\x73\x2d\xd7\x16\xc7\x5c\xe2\x50\xe7\x0b\xfa\x38\xe0\xd4\xfc\xb5\x2a\x50\x1f\x1d\xa1\xff\x80\x6a\xc4\x76\xe2\x75\x49\xe7\x9d\x2a\x54\x6f\x66\x4d\x9d\xe3\xcd\xd8\x59\x3c\x05\x36\xd7\x5a\xb8\xcf\xe3\x49\xa8\x59\xa7\x0a\xf6\x4c\x16\xff\xd5\x8b\x57\xcf\xa1\x44\x71\x5d\x0e\xb8\x03\x47\x07\x70\xb0\xe9\xf5\x1d\xea\x82\xc5\xae\x13\xa6\x12\x72\xde\xe1\x62\x3e\xe4\x62\x66\xe2\x62\x3e\xe4\x62\xa6\x73\xd1\x85\x8b\x87\x70\x96\x4a\xc6\xba\x4a\x2d\x35\x73\x3e\x68\xb5\xb7\x77\x29\xbe\xdd\x6a\x14\x6f\xa7\x51\xdc\x6a\x14\x6f\xa5\x51\x3c\xeb\x14\xf8\x9e\xd5\x55\xb8\xb5\xc2\xdc\x73\x55\xab\x5b\x13\x12\x56\x12\xee\x82\xc1\x3e\xe6\x44\x53\x69\x8d\x2f\x1a\x55\x29\x9e\x77\xd8\x98\x1b\xd8\x98\x99\xd8\x98\x0f\xd8\x98\x75\xd8\xe8\x22\x8c\x06\xf8\x48\xe4\xd4\xe9\x4e\xb5\xc3\x5d\xa1\x24\x6e\xd5\x1e\xbb\xd4\xfe\xaa\x8c\x65\xe4\x32\x0e\xcc\x3d\xc8\xb9\x82\x74\x9c\x09\x97\x90\x38\xd2\x02\x89\xf5\x56\xe8\x1a\x56\x32\x80\x8d\x99\x45\x1f\x76\x5e\xc3\x8e\xf2\xd0\x46\x9a\xb9\x10\x5a\x19\xf7\x47\xae\x2e\x78\x1b\xca\x66\x12\x7c\x06\x35\xdb\x04\x1e\xa1\x49\x6f\x0f\xdd\xaf\xbd\xb3\xf9\xe5\xff\x47\x18\xdd\x45\x83\x6d\xd3\x43\x3e\xc4\xbf\xb5\x06\xc7\xd9\x10\xff\xee\x37\xde\x62\xe1\x02\x5f\x97\x0b\x90\xe2\x96\x3c\x48\xed\x0c\x39\x90\x9a\x18\xd0\x37\x23\x6d\x47\xc5\x57\xa5\x4d\xbd\xed\xa8\xf7\xaa\x34\x31\x67\xaf\x89\xaf\x8a\xe2\xcf\xd0\x6d\x54\xcc\x54\x59\x7c\xf1\xc5\x7c\x8e\x4f\xb6\x91\xbe\xcf\xe7\xa2\xcd\x5c\xb5\x11\x5f\x4e\xe7\x8e\x62\xfa\x33\xa8\xa6\x2f\x50\xa7\x92\x0e\x7c\xce\xe4\xe7\x54\x7d\xb6\x37\x9f\x43\x73\x41\x25\x95\x24\xe1\x73\x26\x3f\xa7\xea\xb3\xbb\x24\xff\x4c\xd6\xe4\x57\x01\x47\x8e\x2b\x6c\x2e\xcb\x4b\xef\xc9\xe2\x07\x6c\x56\x57\xec\x57\x0f\x3b\x35\xfb\x67\xda\x2d\x12\xac\x1e\x75\x9c\x95\xf9\xe1\x6d\x6a\xd2\x20\x52\x34\x67\x5d\x9a\xf3\x0e\xcd\x59\x97\xe6\x5c\xa7\x39\xdb\x86\x26\x96\xfd\xe4\x6a\x68\x90\xe7\x4d\xb8\x1c\x14\x68\x5d\xf6\x7f\x56\x5f\x5a\xa1\x3d\x0c\xda\x87\x82\xa6\x5f\x3f\x93\x65\xb8\xdd\x34\x65\x3f\x15\x70\x4d\x73\xd6\xa5\x39\xef\xd0\x9c\x75\x69\xce\x75\x9a\xb3\x96\xa6\x31\xeb\x1c\xbf\x87\xc0\xcc\xeb\x8f\x50\x7d\xe9\x47\xfb\x61\xaa\x1f\xc1\x79\x7f\x2c\x5d\xc7\xa8\x7e\x84\x60\xf0\x63\x69\x0b\xa1\x1f\xe0\xa2\x04\x01\x33\x9b\x37\x2c\x9a\x9c\x52\x02\x0a\x82\xb3\xb6\x2f\x32\x5c\x54\x58\x0f\x17\xb3\x6d\x62\x55\x4b\x56\xfc\x2b\x24\xe2\xa6\x59\x01\xa9\x6c\x66\x22\x98\x5d\x8b\xe2\x8f\xc6\xd0\xd3\xa7\xf8\x63\x69\xa2\xf8\x63\x79\x1d\x8a\xe6\x60\xd7\xa7\xf8\xca\x48\xf1\x95\x89\xa2\xd9\xda\xfa\x97\x57\x58\x48\xc2\xe4\x45\xed\xf6\x00\x68\xe5\x0e\xe6\x41\xea\xa8\xb4\x2f\xc3\x23\xb0\x48\x74\x16\x6b\x5c\xdb\xb1\xf9\xf3\x79\xce\x2a\x8e\x2e\xdd\x6f\xfa\xe2\x0f\xde\x37\x8d\xf6\x0d\xaf\x9b\xa7\x26\xb6\x61\x00\x2a\x4c\x6d\xe0\xc5\xb6\x30\xb5\x81\x77\x68\x6e\x6a\x03\xaf\xd0\xdc\xd4\x06\x5e\xc9\x27\xf9\x1c\xae\xef\x98\xdb\xee\xef\x80\x77\xfa\x49\x3e\x03\x28\x29\x3a\xae\x4b\x2e\x1f\x08\xcd\x7a\x13\x88\xc0\x94\x99\x78\x84\x29\x85\xcc\xc4\x23\xcc\x5e\xa4\xa6\x36\x30\x79\x91\x9a\xda\xc0\x3c\x09\x33\xb5\x81\x69\x92\xc1\x6d\x06\xe2\x0f\xa6\x5d\x26\xd2\xd4\x2b\x62\x15\x06\x4c\xdc\x4c\xa4\x1c\x84\x65\xed\xb7\x23\x8e\x94\x46\x35\x4c\x76\x6e\xf4\xb2\x12\x6d\xce\x10\x32\x83\x47\x60\xff\x6c\x90\x0d\x3c\x6a\x8a\x51\x4c\x1e\x81\xdd\x33\xc9\xec\x23\x4f\xe7\x96\x0d\x99\xed\xe3\xd1\x66\x19\x25\x41\x10\x51\x3a\x24\x88\x5b\x82\x20\x9e\x54\x11\xec\x44\x82\x74\x9c\xa0\x36\x2f\x29\x09\x12\x08\xb1\x43\x82\xa4\x25\x48\x66\xf5\xb8\x34\x01\x78\x2d\xbc\x8e\x13\xd4\x66\x32\x25\x41\x5f\x10\xcc\x87\x04\xfd\x96\xa0\x2f\x68\xe5\x8a\xa0\x3f\xe2\x0e\x7d\x3c\xda\xdc\xa7\x24\x18\x08\x82\x7c\x48\x30\x68\x09\x06\x82\x16\x57\x04\x03\x9d\x20\x1f\x27\xa8\xcd\x96\x4a\x82\xa1\x20\x58\x0c\x09\x86\x2d\xc1\x50\xd0\x2a\x14\xc1\x50\x27\x58\x8c\x13\xd4\xe6\x57\x25\xc1\x08\x5e\x2a\x86\x04\xa3\x96\x20\x64\xef\xa7\x8a\x60\xd4\x79\x89\x18\x27\xa8\xcd\xc8\x4a\x82\xb1\x20\x38\x1b\x12\x8c\x5b\x82\xf0\xda\xa4\xc6\x64\x01\xef\x4a\x02\x3e\xf9\xec\xc5\x97\x4b\x71\x6e\xee\x52\x1c\x2c\x92\x7b\x75\xb3\x99\x40\x06\x75\x58\x7c\xef\xa6\xaf\xc5\x31\x93\xc1\xff\x94\x17\xe3\x9c\x2c\x17\x1f\xf8\x4a\x56\xf9\x45\xd5\x12\xf9\xe4\x20\x2d\x2b\x91\xa0\xe4\x88\xc1\xfe\xec\x94\x17\xcb\x15\x57\xdb\xa9\x07\x5a\xd3\xce\x9a\x68\x6b\x77\xd5\xf2\xb5\x4f\x6e\xe2\x22\x9e\x3f\xea\x15\x3c\x3a\x9f\x4d\x7d\x90\xbb\x08\x7b\x24\x38\xf2\x55\x9d\xe2\x2f\xa7\x9b\xac\x47\x95\x42\x4c\x76\x3d\xdd\x24\x9a\x8c\x9c\x6e\xea\x6c\x6b\x18\x9c\x6e\x0a\x31\xf9\x72\xba\xe9\xa6\x4f\x37\x09\xad\x6c\x77\xba\xc9\xa8\x9c\xce\xe9\x26\xa9\x20\xe7\xe9\x26\x79\x8e\x76\xcb\xd3\xdf\xfe\x1f\xfa\x3c\x13\x5f\x64\x07\x29\x5b\xf3\x28\xe8\x3d\x38\xcb\xc3\x3e\xe8\x87\xf3\xf7\x79\xd1\xfb\x31\x2b\xcf\x67\x7c\xf5\xbb\x1c\x89\xd2\x58\x85\xef\x82\x43\xf9\x40\x32\x06\x9f\x75\x7e\xfe\x15\x8e\x4e\xbd\xda\xea\x4e\x20\xd8\x3c\x73\x02\x5d\x6f\xe0\xb4\xdf\xc6\x8f\x42\x1d\x1d\xa1\x67\x7c\x75\x06\xa3\xe8\xc9\x6c\x59\x66\x1c\xe1\xfe\xb5\x29\xa2\xf9\xb3\x13\xdc\x3d\xbb\x14\xc6\x53\x14\x24\x53\x14\xe0\x29\xf2\xfd\x29\x22\xe1\x14\xe1\x78\x8a\x92\x29\x42\x58\xdb\x6a\x14\xd2\x29\x0a\xbd\x29\x0a\xc8\x14\xf9\xc1\x14\x91\x68\x8a\x30\x9d\x22\xec\x4d\x11\xd1\xe1\x92\x29\x0a\xf1\x14\x05\xfe\x14\xf9\xe1\x14\x91\x78\x8a\x70\x32\x45\x58\xe0\xd7\xe0\x22\x6f\x8a\x42\x32\x45\x41\x30\x45\x7e\x34\x45\x91\x3f\x45\x61\x38\x45\x41\x3c\x45\x7e\xa2\x01\xfa\x78\x8a\x88\x3f\x45\x38\x9c\xa2\x78\x8a\x50\x44\xa6\x28\x0c\xa6\x28\x80\xab\x05\x74\x40\xc1\x09\x99\x22\x1c\x4c\x51\x24\x00\xf1\x14\x85\xfe\x14\x05\xe1\x14\xf9\xb1\x06\x48\x92\x29\x22\x78\x8a\xb0\x20\x39\x45\x88\xd0\x29\x22\xde\x14\x61\xc1\x8e\x04\x7b\xeb\x90\x2b\x31\xcb\x95\x74\xe5\x2a\xb8\x10\x72\x14\xfd\x26\xe2\xf3\x14\xa1\x50\xe7\x56\x11\x16\xdd\x12\xdc\x02\x43\x9e\xce\xa5\xaf\x04\x27\xb8\x12\x00\xd1\x14\xe9\xdd\xc5\x91\x94\x87\x10\x30\x70\xef\x77\x15\x21\x14\x2a\x04\x2c\xe4\xe7\xc7\x52\xb0\x61\xd8\x93\x57\xe0\x29\x6d\x85\x52\xfb\x81\x4e\x41\xa8\x46\x98\x86\x2f\x54\x1a\x49\xb5\x87\xba\x0e\x85\x0a\x84\x3d\x08\xbb\x10\x3a\x14\x82\xad\xb3\x9a\xce\x8d\x50\x17\x67\x17\x73\x06\xd7\xa4\x88\xa4\x72\x3d\x2b\x8b\xc1\x0d\x4f\xe0\x05\x3f\xbc\xfc\xe5\xc5\xa3\x1f\x1e\xca\x3b\xa5\x84\xc4\xc8\x14\x41\xe7\x85\x84\xa8\xb0\x48\xa5\x26\x90\xae\xb2\x54\xac\xd4\x49\x94\xf5\x82\x40\xa8\x4e\xff\xc5\x77\x4f\x5f\xf3\x35\x62\x8b\x5c\xd5\x46\x3f\x07\x95\xca\xfb\x34\x0c\x7c\x08\xf8\x5f\x9e\x75\xf5\xd9\x4b\x29\xbd\x8d\x77\x17\x5e\x46\x28\xf1\xbc\x69\xff\x59\xfd\xae\x20\x41\x0c\x00\xa4\x03\x40\x3d\x8f\x0c\x40\x7c\x0d\x64\xf8\x34\xd0\x9f\x1a\x08\x84\x5d\x02\xc4\x40\x20\xea\x32\x69\x02\x89\x7b\xfd\x30\x10\xa2\x1d\x46\x86\x28\x92\x3e\x95\x21\x0a\xa6\x83\x98\x00\xd2\xbe\xb4\x86\x20\x59\x8f\xcc\x00\x20\xef\x77\x65\x08\xc2\x35\x90\x21\x85\xa2\xcb\xe5\xb0\x39\x75\xb5\xc6\x74\x54\x1f\x84\x8e\x10\xf0\xe9\x88\x55\x05\x7d\x22\x06\xbb\xa0\x6e\xbb\x89\xe8\xa8\x61\xc6\xd4\x65\x98\x94\x8e\xea\x3b\xa1\x23\xfa\x66\x7d\x26\x0c\x26\xd1\x27\x33\xe4\x24\xa3\xa3\x1a\xcf\xe9\x88\xd5\x70\xea\xb6\xee\xa2\x4f\xc3\xa0\x79\xab\xba\x54\x94\xc0\x66\x41\x12\xed\xa9\x45\x99\x7e\x07\xc4\x48\x3d\xe8\x62\x31\xf5\x31\xd4\x41\x8c\x36\xa1\xf3\x69\x78\x1e\x77\xd9\x70\xf8\x06\x76\x98\x7f\xd2\xe7\xd4\x1a\x28\xb0\x43\xa3\x69\xb7\x33\x06\xab\xe8\x74\xc6\x1a\x27\xb0\xc3\x7e\x79\x0f\xc4\x16\x2a\xb0\x39\x14\xd0\x51\x51\x60\x3a\x2a\x0a\x42\x47\x55\xef\x53\xb7\xda\x82\x1e\x0a\x5b\xac\x70\x89\x3b\xa2\x2e\x13\x8e\xe9\x88\x32\x28\x1d\x91\x64\x42\x47\x4d\x8b\x51\xb7\x42\xd3\xbe\xbc\x0d\x83\x47\x9f\xca\x10\x24\xa7\x2e\x95\x72\x3a\xe2\x42\x45\x5f\xa3\xfa\x1d\x55\xd3\xb1\x2c\x23\xf0\x3c\x1a\x78\xd8\x1a\x41\x14\x8c\x35\xcd\x68\x14\x68\x8b\x20\x35\x11\xcf\x44\x24\xe8\x12\x31\xc2\x84\x5d\x3c\x46\x66\xa2\x2e\x1e\x23\x4c\xdc\xc2\x18\xa8\xe8\xc1\xd6\xd8\x3c\xe9\x93\x30\x20\x61\xfd\xee\xd8\x13\x0e\x45\xc8\x80\x24\xeb\x08\xd6\x00\x90\xb7\x00\xd6\x00\x22\x59\x30\x34\x2e\xfa\x5a\xb1\xe6\x5d\x4e\x61\x62\x3a\xd2\x0b\x42\x5d\xd2\xf6\xfb\x24\x4c\xb6\x41\x7b\x7a\x37\xd9\x06\x1d\x17\x78\x44\x47\x0c\x35\xa6\xe3\x86\x4a\xe9\x88\x52\x12\xea\x50\x0a\xa3\x6e\x5f\x4a\xfb\x1c\xd8\x03\x89\xd3\x55\x72\x3a\x62\xc4\xbc\x2f\x53\x7b\x3c\xb1\x5a\x90\xfe\x02\x62\x78\x8a\xb7\x70\x7b\x4c\xb6\x70\x26\xec\x6f\xe1\xf8\x38\xd8\xc2\x9e\x71\xe8\x74\x7d\x1c\x8d\xb9\x24\x8e\x47\x82\xa1\x9e\x82\x9b\x31\x24\x63\xe1\x12\xb3\x31\xbf\xc7\xe9\x16\xd1\x12\x67\x63\x81\x0c\xe7\x5b\x04\x4b\xcc\xb7\x08\x65\xb8\xe8\x6b\xc8\x68\x2e\x63\xa1\x02\xe3\x31\x0f\xc5\x64\x0b\x07\xc1\xfe\x88\x97\xe1\x60\x9b\xc0\x16\x6e\x11\x76\x70\xe4\x8c\x6e\x38\xde\x22\x2c\x61\xba\x85\x2f\xe2\x64\x0b\xaf\xc7\x6c\x8b\x68\x8a\xd3\xb1\x08\x86\x33\x57\x08\xc3\xf9\x58\x58\xe0\x5b\x84\x51\x5c\xf4\x22\xd4\x2e\xa9\x0a\xf6\x02\x4b\x30\x32\xb3\x4c\x3a\x52\xc1\xd6\x14\x45\xe2\x36\x61\x0f\xb4\xe7\x9e\xe1\x79\xd8\x53\xce\x10\x22\xea\x08\xcd\x44\x23\xee\x40\x8c\x0f\xc7\xf6\xdc\xa4\xa5\x62\xcb\x4c\xea\x9e\xda\xb2\x92\x96\x8b\x21\x9f\x59\x4f\x9a\x43\x88\xbc\x23\x2d\x5b\x6a\x02\x18\x2c\x69\x89\x6a\x6b\x96\x80\xab\x7b\x98\x8e\xb1\x4f\xa8\xdd\x50\x7c\x3a\x66\x28\x01\x1d\x53\x74\x48\xdd\x9d\x8f\xa8\xdb\x94\x62\xed\xf9\xf0\x29\xa5\x76\xd1\x25\xd4\x25\x3a\x46\xc7\xcc\x2b\xa5\x6e\x27\xc8\xa8\xdb\x74\x72\x3a\x66\x18\x9c\x8e\x39\x41\x41\xc7\x4c\xbc\x93\x56\x58\x8c\x00\x8f\xb8\x2b\x26\x23\x16\x8a\xfd\xd1\x90\x81\x03\xa7\xa5\xe2\x70\xd4\xe1\x71\x34\x1a\x35\x70\xec\x8a\xc4\x74\xd4\x13\x71\x32\x1a\x32\x30\x73\x78\x23\x4e\x47\xc2\x05\xce\x46\xa3\x16\xd6\xc3\x81\x81\x04\x1f\x89\xbd\xb8\x18\x0d\x49\x2a\xb5\x70\x76\x13\x3b\xfd\x0a\x93\xf1\xd0\xe2\x3b\x22\x07\x0e\x46\xdc\x1a\x87\xa3\xb1\x05\x47\x4e\x07\xc6\xf1\x68\x6c\xc3\x74\x24\xf8\xe0\x64\xd4\x03\x31\x1b\x09\x03\x38\x1d\x8d\x81\x38\x1b\x0d\x05\x38\x1f\x8d\x47\x98\x3b\x82\x1d\x2e\xba\xd1\x68\x97\xfc\x81\x7a\x92\xa4\x39\xb6\xd4\xd9\x27\xf6\x02\x4b\x2a\x51\x33\x6d\x78\xee\xb7\x18\x02\xb3\x21\x06\x76\x23\x0a\xbb\x12\x31\xe7\x10\x4d\x72\x6c\x22\x1f\x7b\x9d\xf4\xcf\x3e\x7e\xd6\x2b\x2a\xe6\x0c\xa2\xd5\xad\x39\x7f\x90\xcf\xcd\xb9\x43\x2b\x3e\xdb\x0a\x4a\x2b\x1e\x03\x8e\x5c\xf3\x52\x4b\xe6\x50\x9b\xb7\x39\x77\x68\x15\x6c\xe9\xbf\x53\xbf\x98\xda\xbb\x47\xe8\x18\xf3\x3e\x1d\x13\x40\x40\xdd\x2a\x0e\xe9\x58\x17\x22\x6a\xb5\x9f\x98\x8e\x19\x1f\xa5\x2e\xf9\x25\x5d\xe2\xb6\x24\xc2\x61\x1d\x29\x75\x69\x2f\xa3\x63\xd6\x97\x53\xb7\xfd\x72\xea\x76\xbf\x82\x8e\x79\x08\xf6\x46\x5c\x04\xe3\x11\x2f\xc4\x64\xd4\x0d\xb1\xef\x1a\x29\x9c\x16\x8e\xc3\x51\x17\xc1\x91\x37\xa6\x27\x1c\x8f\x46\x32\x4c\x47\xbd\x05\x27\xa3\xe1\x02\xb3\xd1\x80\x87\xd3\x91\x98\x89\xb3\xd1\xb8\x81\xf3\x91\xb0\x84\xb9\x23\x2e\xe1\xc2\x19\x36\x64\xf6\xe0\xee\x03\x1e\xf5\x4b\x4c\xec\x8e\x89\xfd\x11\xb7\xc7\xc1\x88\xe1\xe3\x70\xd4\x77\x70\x34\x1e\xdd\x62\x47\x78\xc3\x74\xdc\x79\x12\x67\xfc\xc0\x6c\x34\xfe\xe1\x74\x34\x88\xe2\xcc\x19\x44\x70\x3e\x1a\xa5\x30\x1f\x09\x53\xb8\xe8\xc6\x91\xdd\x92\x07\x63\x4c\xa9\xf9\xb5\xad\x90\x34\xdc\x18\x53\x86\xbb\xda\x76\x0d\x63\xc6\xa0\x00\x60\x3e\xc5\x98\x37\x34\x39\x9f\xe1\x79\x54\x23\xb0\x01\xc4\x2d\x83\x86\xa7\xba\xce\x6d\x29\x43\xcb\x9f\x25\x67\x68\x7b\x68\xa0\x90\xb6\x0c\x9a\x59\xc8\x3a\x00\xa6\x81\xc3\xea\x7b\x5c\x57\x8e\x01\x75\xd1\x11\x8e\x79\xce\xc1\xd5\x1e\xd3\x11\xe1\x12\xea\xd9\x0c\xc7\xa7\x6e\xc3\x09\xa8\xcb\x70\x42\x3a\x62\x17\x11\x1d\x91\x5a\x4c\x47\x4c\x8f\xd2\x11\xd5\x26\xd4\x26\x77\x46\x47\x74\x9a\x52\xb7\xd5\x66\x74\xc4\x6a\x72\x3a\xa2\x39\x4e\xdd\x86\x5b\x50\x97\xd9\x63\xcf\xe9\xb6\x18\x7b\x56\xbd\x62\x32\xe6\xd3\xd8\x1f\xf3\x49\x1c\x8c\x78\x35\x0e\xc7\x9c\x02\x47\x63\x91\x03\xc7\x23\xbe\xdd\x8c\x7b\x56\x35\xe2\x64\xcc\x81\x30\x1b\x89\x8f\x38\x1d\x8b\x20\x38\x73\x46\x28\x9c\x8f\x45\x18\xcc\xed\x83\x73\x31\x12\x21\x20\x3f\x70\xeb\x0a\x8f\x58\x1a\x26\x23\x9e\x8e\xfd\x31\x67\xc6\xc1\x98\xb3\xe2\x70\x2c\x54\x45\xf6\x50\x84\xe3\xb1\x60\x81\xa9\xdb\x5d\x92\x31\x87\xc7\xcc\x1a\x2c\x70\x3a\xe6\xcb\x38\x1b\x09\x17\x38\x77\x06\x4b\xcc\xc7\x42\x19\x2e\x7a\x01\x67\x97\xac\x40\xb1\x4d\x4d\x51\xa4\xc6\x69\xca\x0b\x64\x5b\x62\xee\xb3\xdf\x3e\x27\x26\xdc\x41\x2b\x11\x23\xfe\x50\xef\x8f\x29\x2b\x68\x9e\x0e\x71\xc7\x1d\x83\xb6\x8e\x8a\xc6\x6c\x40\x63\x6a\x88\x98\xd5\x64\x8d\x2c\xa7\xca\x40\x4d\x19\x80\x26\xab\xe1\xf3\x5c\x43\x3b\x7c\xca\x9b\xbe\x0e\x9f\x15\x1d\x29\x9b\x7a\xea\x54\x12\xa6\x6e\x25\x11\x6a\xe9\x91\x4f\x5d\xda\x09\xa8\xab\x3f\x21\x75\x5b\x5d\x44\xdd\x96\x11\x53\xbb\x3c\x28\x75\xd9\x45\x42\xed\xf6\xcc\xa8\x5b\xf5\x29\x75\xeb\x30\xa3\x16\x9b\xca\xa9\x5b\x45\x9c\xba\x6c\xaa\xa0\x6e\x53\xc6\xde\x88\x1f\x61\x3c\x62\x7c\x98\x8c\x78\x2a\xf6\x1d\x06\x88\x03\xa7\x9f\xe2\x70\xc4\x15\x71\xe4\x8d\xc4\xa0\xd8\xe9\x73\x4d\x06\x6b\xe1\x3d\xb1\x46\x6d\x66\xf3\x56\x9c\x8e\x84\x36\x9c\x39\xe2\x22\xce\x47\x62\x08\xe6\x23\x3e\x8b\x0b\x67\x70\x13\x23\xba\x85\x71\xec\x34\x25\x4c\x9c\x4e\x8b\xfd\x11\xbf\xc4\xc1\x88\x63\xe2\xd0\xe1\x99\x38\x1a\x89\x35\x38\x1e\x0d\x56\x23\x9e\x84\x93\x11\x1f\xc5\xcc\x11\x00\x70\xea\x8c\x5a\x38\x73\x86\x16\x9c\xdb\xfc\x1f\xf3\x31\x17\x2e\xba\xa1\x67\xf7\xa1\xdb\x60\x23\x35\xab\x81\x87\x0d\x43\xb7\x4a\x35\x0c\x83\xb6\x42\x6a\x6a\x16\x34\x49\x8e\xe9\x69\x68\xe9\x7e\x24\x51\x1a\xc6\xe8\x36\x65\x1a\x3e\xa5\x5a\x07\x4c\xc3\x74\xd3\xf7\x61\x53\xa6\x19\xf9\xf0\x69\xaa\x75\xc2\xf4\xaa\xae\xe5\x71\x86\x61\x5a\xca\x6d\x88\x95\xb7\x72\x33\xbd\xa4\x6b\x99\xef\xb0\xa7\x2e\x31\x60\x6a\x16\x2a\xa1\x2e\xfd\xfa\xd4\xd5\xc7\x80\x3a\x0c\x27\xa4\x2e\xe1\x45\xd4\xd5\x93\x98\xda\xc4\x43\xa9\xc3\xac\x12\xea\x52\x35\xa3\x2e\x8d\xa4\xd4\x61\x08\x19\xb5\x99\x79\x4e\x5d\x96\xcc\xa9\xd9\x62\x0b\xea\x50\x32\xf6\x9c\x5a\xc6\xd8\xe9\xae\xc4\xe9\xaf\xd8\x77\xfa\x0a\x0e\x5c\xee\x80\x43\xa7\x2b\xe1\xc8\xe9\x10\x38\x76\x45\x04\x35\xde\x18\x1f\x25\xce\x68\x81\x99\xcb\x63\x70\x6a\x09\x1a\x38\xb3\x05\xd9\xdc\xe9\xb9\x98\x3b\x83\x02\x2e\xac\x11\x11\x7b\x4e\xad\x63\xa7\x23\x62\xe2\xf6\x6e\xdf\x62\x69\x38\x70\x3a\x1a\x0e\x5d\x2e\x8c\x23\xab\x1f\xe2\xd8\x19\x19\x30\x75\x7a\x3f\x4e\x9c\xbe\x88\x99\x25\x58\xe1\xd4\xe9\x6e\x38\x73\x45\x07\x9c\x5b\xbd\x18\x73\x67\xe4\xc0\x85\x16\x1c\x76\x19\x53\xa9\x18\xe0\x89\x01\x61\x23\x9c\x61\x3c\xbe\xdb\x2e\x6e\x0c\xc3\xb1\x6c\x37\x0c\xc4\x0a\x9f\xe1\x51\x28\xf1\x11\x23\x1f\x51\xf3\xd0\x14\x84\x15\x27\xe6\x71\x86\x7a\x66\xfe\x93\xa6\xdf\xa6\x10\x2c\xf9\x34\x3d\x4a\x1b\xa4\x06\x3e\xb3\xbb\xf2\xb0\xc7\x30\xfc\x9a\xed\x84\x37\x42\x34\xb4\x29\x14\x13\x86\x47\xf5\xa2\x92\xb5\xe7\xf2\x31\x76\xc9\x54\xc1\x10\x97\xfe\x15\x8c\xef\xd2\xb5\xfa\x3d\x70\x09\x5b\xc1\x84\x76\xb1\x2a\x88\x68\xb4\xcf\xb1\xc5\xb4\xd4\x63\xea\x92\xa8\x82\x49\x6c\x5a\x52\xcf\x99\xdd\x4a\x15\x44\xea\xb2\x47\x05\x93\x99\x55\xae\x9e\xe6\x2e\x33\x52\x30\xdc\x65\xa2\x0a\xa6\xb0\x7b\x68\x9d\x11\x1b\x1d\x1b\xbb\x7a\x80\x89\x45\xc8\xd8\xb7\x59\x1c\x0e\x5c\xcc\xe2\xd0\xa5\x16\x1c\xb9\x84\x81\x63\x47\x17\x6d\xf1\x37\xb1\xab\x10\x33\x97\xa5\xe2\xd4\x19\x0f\x33\x97\x47\xe1\xdc\x6e\xdf\x98\xdb\x8c\x0e\x17\xe3\xde\xd5\xbe\xdc\x58\x21\xb0\x3b\x16\x60\x32\x6e\x70\xd8\x1f\xf3\x3e\x1c\x38\xbd\x0f\x87\xe3\x41\xa0\x56\xb6\xb3\xbb\xf1\x78\x50\xc2\x74\x3c\xb8\xe1\x64\x3c\x1a\xd4\xe6\xe0\xf2\x32\x69\x14\xd6\xa7\xd9\x58\x58\x93\x86\xe1\xe0\x93\x8f\x45\x9c\xda\x48\x80\x8a\x36\xb2\xcb\x8f\x7a\x5d\x83\x27\x6c\xfd\x7e\x8d\xaa\x19\xab\xd0\x9a\xcf\x79\x56\x41\x3d\xa2\x17\xdf\x3d\x7d\x8d\xca\xc5\x79\x7d\x4d\x44\x53\xd1\xe0\xc9\xb7\x2f\x7a\x17\x17\xb7\x07\x13\xa7\xa8\xdd\xf8\x0f\x17\x28\xaa\x2f\xf0\x59\x7d\x99\xea\x0d\x3d\xf5\xab\x04\x90\x5f\xea\xcf\xe2\xcb\x54\xeb\x4f\x9f\x73\xad\xaa\xd2\xf7\x0f\x5e\xc8\xc2\x58\x48\x16\x7e\x71\xdf\x51\x25\xa0\x9b\x0b\xaa\xe4\x17\xad\x4a\xca\x75\xaf\xa8\x72\x97\xd6\x7b\xcf\xaf\x9a\x12\x60\xef\xf9\x95\xa1\xf4\xdd\x7b\x7e\x55\xd7\xd5\x7b\xcf\xaf\xcc\x65\xf5\x04\x0d\xa9\xa2\x30\x42\x69\x59\xad\x11\xcb\xb2\xe5\x2a\x2f\x17\xa7\xa8\x5a\xa2\x67\x27\xd8\x88\xf7\xbb\x12\x4a\x01\xbd\xe9\xd7\x40\x36\xdd\x1d\x12\x46\xf6\xbb\x43\x5a\x74\xcf\x96\x02\xe1\xb3\x13\xfc\xa6\x7c\x8b\x0e\x10\x36\xd4\x28\x55\x74\x65\x79\xfe\x49\xdd\xbb\x37\x6d\x7b\x55\x8e\x4f\xfc\x67\xe2\x63\x74\xa0\xa1\x86\x3a\x7c\x7b\xe8\xf6\x00\xb1\xa1\x60\xe9\xb7\xeb\x35\x3f\x4b\xe7\x1c\xe1\x08\xad\x2f\xd2\xf7\xfc\xca\x20\xfe\xf5\x45\xfa\x23\xbf\x5a\x37\x2a\x68\xbf\xdb\x85\xb2\x78\x01\x40\x52\x34\xf5\x97\xfb\x08\x47\xcd\x37\xfb\x15\x2b\x27\x50\x71\x4a\xf1\x63\x16\xe4\xba\xc6\xae\x78\x79\xa3\x90\xbe\x55\x4c\x19\xf1\xba\xaf\x6e\x49\xcb\xea\x05\x54\x45\x39\xd6\x8a\xa0\x34\x78\x6d\x28\xa5\x41\x05\xd4\x68\x50\x64\xd8\xc6\x64\x35\x24\xb0\x5b\x4d\x97\x4e\xb1\x5a\x9e\x41\x80\x99\xf3\xa2\x42\x84\x82\x67\x08\xca\xe6\x86\x52\x38\x6f\x26\x25\x3a\x92\x77\x43\x78\x50\xc0\xb1\x36\xae\xc9\xe4\xd9\x09\x51\x36\xb8\x87\xf6\x1b\x09\xec\xa1\xbf\x20\x42\xdf\x42\x8d\x47\xb0\xad\x12\xfd\x05\xee\xb8\xd8\x9a\xbd\x55\x79\x3a\xdb\x9e\xbf\x00\xca\x77\xb6\x4c\xee\x75\xb8\x24\x14\x1e\x4b\x5e\xd1\x3e\x22\x81\x85\xe1\x3d\x03\xc7\x03\xb2\xa6\xca\xfe\xa2\x03\xe5\x22\xe3\x88\xb3\x6c\xa6\xcc\x0e\x95\x6b\xc4\xce\xcf\xe7\x25\xcf\x85\x2e\xd9\x02\xf1\xcd\x39\x5b\xe4\x3c\xaf\xeb\x32\x42\x78\x9f\x1a\xb1\x09\x11\x28\x34\x19\x5b\xa0\x94\xa3\x74\xb5\x7c\xcf\x17\xa8\x5c\x54\x4b\x44\x65\x51\xe0\x35\x5a\x67\x6c\x2e\xd1\x4b\x94\x6b\x33\xb6\xcb\x59\x99\xcd\x10\x9b\xcf\x97\x97\x6b\x40\x2d\xf0\x56\x4b\x81\xf6\x62\xcd\x73\x74\x59\x56\xb3\xe5\x45\x25\x19\x5c\x97\xcb\xc5\x10\x8b\x12\x34\x94\xd7\x9c\xb4\x5f\xee\xdf\x57\xd7\xca\xb4\x3f\x89\x80\xe2\x63\x93\xe4\x3a\x96\x8b\xa5\xe5\xc6\x6e\xc3\x55\x68\x21\x88\xb5\x9f\x21\x66\x4d\x4a\xa9\xc4\xaf\x91\xd0\xbe\x6f\x56\x95\xad\x1f\xb1\xde\x8f\xf8\xad\x2a\xec\xf9\x9b\xfe\x13\x5c\x0a\x30\xb8\x6a\xc7\x10\x01\x4f\x64\xe1\x4b\x54\x2e\x3e\xf0\xd5\x9a\xdb\xa3\x60\xb9\xf8\xf0\xa2\x17\x08\x3b\x3f\x6d\x35\x40\x60\xc7\x00\xd1\x62\xd3\x25\xb6\x7e\x83\x43\x61\xd0\x7d\xec\x1f\x3b\x13\x0e\xed\x17\xbe\xc8\x56\x57\xe7\xd5\x0e\x57\x01\xaa\x8a\xb5\xcb\x93\xa6\x5d\x0b\x3c\xed\x86\x7c\x6b\x09\xdd\x9c\x7f\x0e\xaa\xad\x44\x5c\xb5\x7b\x4f\xdc\x94\xa7\xb5\x20\x4d\x49\xc7\x7f\xf0\x4a\xcf\xd3\xba\xcc\xcd\x01\xa9\x76\x35\x56\x5f\x07\x12\x6c\xd5\x07\x83\x9b\xb3\x0c\xd9\xc7\x0f\x8b\xb2\x2a\xd9\x5c\x2f\x7d\xd5\x85\xe1\x9b\x6c\xc6\x16\xa7\xfc\xf1\xf3\xb6\x2c\xaa\xac\x3c\xe6\x6d\xbc\x42\xfe\xaf\x6f\xd2\xe6\x36\xf2\x7e\x6a\x78\x63\x2d\x0a\x6b\x9b\xe7\x8f\xf5\x36\x04\xe8\xf8\xea\x6f\xbb\x36\x54\xf2\xe6\x15\x85\xf8\xff\x96\xbc\x41\x9b\x50\xfd\x19\x2b\xd3\xba\xae\x6a\x93\xe5\xc3\xc0\xa3\xe4\x47\xe9\x55\xf0\x79\xfc\xda\x36\xc3\x48\x64\xcc\x27\x00\x9d\xed\xda\x8b\xc6\x30\x74\x3b\xb1\xc0\xae\xba\xb0\x2b\x05\x6b\x64\xf2\x21\x2f\xd7\x15\x9f\x37\x56\x6c\xc6\x58\x40\xe7\xb7\x4b\x2d\xa8\x3b\x40\x17\x62\xa0\x95\xa5\xd6\xde\x94\x6f\xdf\x4c\x26\x8a\xdb\x77\x6d\xb8\x16\x89\x64\xf3\xea\x02\xdf\xa1\xac\xb6\x49\x34\x86\x80\xdd\x73\xa4\x95\x4d\x52\x3d\x4f\x9a\xd7\x6c\x14\xe3\x01\xfc\xe7\x45\xbe\x44\xeb\x4b\x76\x2e\xd3\x8f\x39\x5b\x57\xd2\x18\x86\x21\xbc\x72\xab\xac\xc7\x6c\x57\x61\x2e\xc7\xaf\x0c\x36\x0c\x15\xc5\x77\x75\xf5\x81\x6b\xdc\x98\x0b\x5e\xc7\xd5\xaf\x13\x52\x46\x42\x97\xe1\x8d\xac\x42\xcb\x8b\x6a\x10\x81\x9b\x90\xeb\x56\x59\x27\xe4\xda\x75\xd6\x19\x32\xde\xf3\x2b\x59\x02\x3a\x0a\x8e\x7c\xa2\x3f\x29\x3f\x58\x1e\x68\x75\xa3\x23\x63\xd5\xe8\x23\xf4\x42\x58\xa0\x7a\x09\x58\x2d\xd7\xeb\x36\x4d\x87\x9a\x87\x90\x10\xc3\x6b\xa9\x6c\xd1\x0c\x54\xad\xe0\x26\xf5\x78\x75\xc6\xd6\xef\x3b\x2e\x5b\xdb\xee\x64\xd2\x31\x51\xe1\x88\xf5\xe8\xfa\xae\xd3\x75\xe1\xb4\x02\x8b\x26\x82\x8e\xc9\xbe\x03\x9b\xfd\xca\x68\xf8\xe2\x99\xc8\xa8\x24\x66\x05\x55\xfb\xdd\x80\xed\xe7\x8f\xb7\x67\x7b\x65\x67\x7b\xee\x66\x7b\xee\x60\x7b\xb5\x05\xdb\xce\x22\xd2\xeb\xba\x8a\xb4\x9c\xfe\xd8\xae\x8e\xf4\x58\x11\x66\x89\xab\xe2\x9b\x4a\x2f\xc5\xfc\xfd\x83\x17\x87\x2a\x41\xeb\xd4\x62\x9e\xa2\xac\x38\x35\x14\xd7\x3e\x9f\x33\xc1\xc4\xa6\x42\x7d\x2c\x2a\xe1\x9a\xb4\x74\x4c\x88\x9a\xca\xce\xc3\x89\x9a\x6e\xd1\xed\xef\x1f\xbc\x30\x56\xdc\x7e\xb9\x2a\xcf\xe7\xfc\x60\xb7\x29\x22\xd9\xa8\x33\x51\xa4\xff\xf4\xc7\x99\x2e\x52\x13\x11\x82\xed\x12\x2a\x94\x66\xfd\xeb\x81\x54\x16\xcb\xd7\x18\x1d\x0b\xb8\x43\x29\xd5\x07\x52\xc7\xcb\xd5\xa4\xbd\x67\x5d\x5d\x1c\x5f\x93\x3e\x5c\xcf\xcb\x8c\x4f\xbc\x29\x22\x7b\x83\xbb\x30\x1a\xb4\xe4\x9a\x68\xc9\x14\x05\x0e\xb4\xfe\x35\xd1\x06\x53\x14\xed\xd9\x2f\xd2\xb8\xf6\xbb\x07\x5f\xe3\x43\xbd\xb1\xd6\xc2\x2a\x99\x43\xfd\x9d\x63\x8b\x06\xfe\x16\x14\x6e\xe6\x9d\x46\xd0\xda\x91\x39\xb2\x6b\xf7\xf1\x16\x14\xcc\xa3\x1e\x4e\xc8\x8d\x0d\x7b\xff\x24\x61\xb5\x89\x2e\x37\x10\x5c\x5b\x5c\x3b\x86\x58\x5b\x88\xeb\x06\xda\x06\xca\x59\x3f\xbf\x81\xea\x95\xd0\xd7\x0a\xb3\xdf\x0d\xc9\xb4\x57\x55\x5f\x2b\xee\x7e\x37\x0c\xa6\x6d\x55\xf7\xbb\x61\x34\x55\xc5\xde\xef\x46\xf8\xe3\xdb\x29\x0d\x3e\xa9\xe0\xfe\xef\x59\x69\xff\xb3\xd5\xc3\xff\xef\xa9\x6c\x0f\x37\x15\x94\x0b\x9e\xdf\x6c\x89\xfb\xef\xd8\x9a\xb7\x55\xeb\xd9\x9a\x6b\xcf\x5e\xfb\xc4\x59\x01\x7f\xe8\xcb\x9b\x28\x40\x0b\x76\xc6\xd7\xe7\xba\x97\x1e\xe9\x6c\x08\x10\xc1\x86\xfc\xef\xdf\x3f\x9a\xd0\x7c\x8b\xa2\xa0\xb9\xc2\xc6\x84\xe6\x75\x14\x08\x3e\x80\xa9\x4d\x14\x1c\xaa\x2f\x82\x7f\x43\x66\xd0\xa2\x96\xe8\xd5\x74\x4a\xf9\x37\xbe\x46\x0c\x2d\xf8\xe5\xfc\x0a\x49\x5f\xcb\x4d\x84\xf5\x80\x82\x3a\xb7\x79\x2c\x2e\xce\x52\xbe\xfa\x88\xe0\x56\x29\xb8\x55\x45\x7c\xf0\x09\xa4\xf3\x87\xce\x26\xf3\xe5\x25\xb4\x10\xff\x35\x35\xe8\x36\xee\x46\xb7\x21\x40\x2d\x97\x4d\x2b\x97\x3a\x22\xd4\xe2\xa9\x07\x66\xb9\xfa\xe7\x11\xcf\x87\xb7\xb2\xc0\x0b\xbd\xc8\xeb\xce\x77\xd6\x92\x86\x10\xbf\x28\x3b\x19\x95\xe8\xe1\x54\x70\x6d\x1e\xc3\xd4\xfd\x5a\x86\x5b\x3d\xe1\xb1\xe8\xed\x31\xea\xde\xbe\xad\xbf\x99\xf7\x35\xf5\x5d\x59\x5d\x96\x6b\x8e\x7e\x7a\xfa\x72\x0d\x18\xc6\x14\x53\x5f\x94\xa2\x0c\xe4\x23\xfa\x56\xe8\x57\xc8\xe5\x00\x04\xa3\x46\x12\x56\x54\x7c\x85\x16\xfc\x94\x55\xe5\xe2\xf4\x06\x04\x0f\xa8\xb8\x10\xbc\x52\xc1\xe1\x62\x59\x4d\xac\x52\x3d\x3a\x42\x8b\xe5\x68\xa6\x0a\x77\xb2\x48\x81\xfe\xa3\x91\xee\x3d\x23\x98\x14\xec\x3f\x6a\x21\x1b\x52\x52\x25\x19\x25\x98\xda\x1a\x5a\x75\xde\xeb\x70\xd7\xc9\x00\x6c\x5a\xf9\xf6\xa7\xef\x35\xad\xc0\x72\x02\x8c\xdb\xe7\x6c\x0d\xcb\x0b\x5b\xf9\x50\xa3\x29\xc0\x21\x5c\xa2\x51\x56\xb5\x14\x24\x6a\xbc\x37\xac\xfc\x6f\x7f\xfa\xfe\x66\x54\x2f\xd7\x76\x5a\xc5\xb3\x45\x3e\x61\x8b\x65\x35\xe3\x2b\xc5\x88\xcb\x0c\xd8\x22\xd7\xcd\x40\xf4\x70\xc4\x14\x5a\x3f\xbb\x2d\x05\x32\x66\x15\x8d\xe7\x29\xf8\xdf\xcd\x3e\x9e\x3e\xff\xdc\xe6\xf1\xf4\xf9\x67\xb2\x8e\xa7\xcf\x6f\xc6\x38\x96\xab\x8e\x6d\x2c\x57\x3b\x98\xc6\x72\x75\x6d\xcb\xf8\x6d\x47\xcb\xf8\xed\x77\xb6\x8c\xd7\x9f\xdf\x34\x5e\x7f\x36\xdb\x78\x7d\x53\xc6\xb1\xe9\x59\xc7\x66\x27\xf3\xd8\x7c\x82\x7d\xbc\xdb\xd1\x3e\xde\xfd\x4e\xf6\x01\x8b\xf2\xba\x65\x2c\xe4\xcc\xa8\x7a\x21\x9c\xf3\xa2\xda\x3e\x2b\x5b\x80\x4d\xc8\x6f\x68\x59\x34\x98\xe0\x0a\x9b\x9b\x32\x06\x40\x76\x33\xe6\x00\xa8\x3a\x06\x01\xbf\x3c\x9e\x90\xd0\x65\x07\x12\x48\x37\x85\x85\xc9\x0e\xc4\x2b\xd0\x02\xdd\x47\x3e\xb1\xad\x74\x69\x96\x32\x69\x4d\xe5\xfe\x7d\xb4\x80\x25\xf2\xc6\x18\xe4\xd6\x21\x82\x0e\xd0\xc2\x78\x59\xbd\xd9\x84\x04\x9e\xa1\xad\x7d\x44\xf5\xcb\x93\x9b\x21\x1d\xcd\x64\x81\x0e\x0c\x37\x86\x0e\x48\xf7\x97\xba\x04\xb9\xff\x4e\xeb\x85\xa9\xfc\x7f\x3b\xf3\x7d\x3e\xb1\xbf\x5c\xd4\xd6\xfb\xfc\x86\xac\x57\xea\xbd\x6b\xa9\x9a\xf1\xd6\xf6\xbc\x85\xf1\x0e\x22\x26\xa0\xba\x86\xfd\x6a\x5e\xd0\xe0\x19\x37\x60\x45\xfe\x77\xb7\xe0\xe7\xcb\x8a\x55\xfc\x73\x07\xe0\x15\x50\xb9\x29\x13\x06\x6c\x37\x63\xc2\x92\x31\xdd\x84\x57\xcb\xd1\xf8\x2b\x40\x46\xed\x57\xf5\x08\xec\x40\x45\xf5\xc5\x9e\x48\x07\xdb\x5f\x9e\x4f\xa2\x60\x60\x96\x9f\xaa\xb0\x1b\x8a\x39\x7f\x2c\x8d\x8d\x84\x1c\x01\xb1\xbb\xc2\x9e\x0f\x14\xf6\xf8\x3a\x0a\xfb\x36\xcf\x3f\x77\xe6\xcb\xf2\xfc\x33\x65\xbe\xf2\xca\xef\x9b\x78\x67\xce\x7b\xef\xcc\xf9\x4e\xef\xcc\xf9\xd6\xef\xcc\xfd\x11\x61\xbf\x49\x64\x61\xc3\xa8\x39\xf9\xcd\xd8\x6a\x75\x25\x9a\xd5\x63\x88\xbc\x18\xbe\x33\xac\xb4\xd7\xc3\x9b\x71\x0c\x13\xa9\xfd\x36\xe7\x46\xfb\x92\x86\xe2\xe1\x53\x23\xba\xfc\x66\x5e\x5d\xf9\x76\xa1\xae\x00\x5f\x16\xfa\xdc\xe6\xda\x74\xc3\xf1\x6a\x79\xce\x57\xd5\x15\xfa\xbb\xba\x62\x18\x00\xc1\xbc\x1a\x14\x83\x69\x45\x65\x20\xeb\x43\x13\x9e\x3a\xac\x34\x77\xa2\x77\xa3\xcb\xba\x3c\x5d\x94\x45\x99\xb1\x45\x85\x52\x78\x5e\x2e\x34\xdf\x00\xa2\x8e\xd9\xdf\x76\x5e\xba\x66\xa6\xfe\xe5\x06\xe6\x81\x87\x1c\xd8\xdd\xb1\x23\xae\xc9\xd3\x73\x61\x96\x6c\xbe\xd7\x91\xfd\xa8\xe0\x90\x31\x20\x37\x92\xd3\xd0\x6e\x25\x44\xde\x55\xf3\x27\xf8\xea\xa5\x2e\xea\x7e\x2f\x3a\x6b\xbe\x5d\x9f\xfd\x44\x64\x6f\x06\xed\xc5\xdf\xae\xd3\xda\xd3\x5d\xb1\x60\x8a\x13\xcc\x70\x0a\x67\x6a\x32\x9c\x63\x8e\x8b\xbd\x01\x92\xb7\xff\x46\x5d\x9d\x22\xec\x6d\xbd\x3c\x00\x46\x37\x6d\xcc\x76\x10\x96\x2f\xd5\xe6\x09\x08\x8b\xf5\x17\xf9\xdf\xdf\x7e\x33\x1c\xc0\x10\x79\x7f\xe3\x03\x7f\x3a\x46\xc3\x55\x30\xfd\x4f\x8e\xcd\x35\xf8\x71\xc3\x46\x7f\x2f\xa0\x35\x69\xef\x23\x90\x3e\x34\xe7\x8b\xd3\x6a\x86\xbe\x46\x74\xcb\xad\xd4\xfd\x40\x73\xb2\x5c\x7c\xe0\xab\xfa\xd5\x50\x0b\xc3\x2a\x3e\x88\x41\xbb\x3e\x1d\xb0\x55\xe0\xa9\x47\xed\x46\xbb\x9d\x95\xb9\x8f\xe8\x65\x37\x88\xde\x59\xa3\x9c\x55\x0c\xb1\xf5\x8e\x74\xb6\x9e\xc9\xea\xae\x14\x6e\xb4\x00\x7d\x58\x2d\x5f\xfb\xc4\xbe\x14\x02\x8f\x3f\x61\xcf\x8e\xa2\xd5\x35\x2a\xc3\xce\x9d\x1a\xee\xb1\x54\x66\xc3\x64\xad\x5e\xd3\x2e\x1e\xa9\x36\x03\x2e\xd9\xdd\xad\x37\xef\x77\x69\xbb\x4f\x7a\xb5\x4b\x78\x75\xab\x37\x83\x2d\xfc\xe2\xaf\xe6\xe1\xf0\xfc\x62\x3d\x9b\xd4\x89\x94\xc8\x11\x4c\xef\x95\x66\xe8\x5e\x2e\x81\x0c\xfb\x64\xeb\x54\x44\x53\x70\x1d\x41\x6a\x9c\xd3\xae\xdb\x58\x37\x92\x0c\xbc\x02\xd0\x08\x93\xcc\x96\xe7\x30\x48\x5a\xc6\x7e\x34\x9a\xb6\x36\x66\xcf\x51\x36\x5f\x2e\x5c\x6f\x2a\xdb\x9a\x34\xe0\xe9\xdb\x32\xfc\x68\xb7\x65\x78\xec\xb4\x65\x1d\x33\x64\x29\x92\xdd\x66\xe7\xab\x69\xa7\xeb\x09\xc0\xff\x19\x0c\xfb\xcf\x52\x32\x43\xa4\x75\x2c\x95\xf8\x86\x61\xb6\xde\x35\x66\x27\x00\x67\x98\xea\x85\x75\x99\x9c\x58\xc8\x34\x2e\x74\xd9\xf1\x9f\x51\x37\xb8\xdc\xc6\x07\x2e\x95\xc9\xd7\xe8\xdf\x94\x6f\x4d\x62\xb7\x9b\x2a\x00\x77\xd6\x97\x9b\xf4\xd8\xba\x6f\xa6\xb7\x5b\x46\x6d\x8d\xf9\xf8\x76\x4a\xc3\x6d\xf6\xbb\x1c\x7d\xfd\x27\x34\xab\xaa\xf3\xf5\xdd\xa3\xa3\xb3\x6a\xb6\x3e\x4c\xf9\xd1\x45\x55\xd0\x5f\xd7\xe8\x03\x39\xc4\x87\x04\xa5\x57\xe8\x7f\x9c\xb1\x6a\x56\xb2\xb5\xb0\x98\x76\x83\x0c\xec\x0a\x91\x9b\x3d\x8e\x8e\xd0\xf7\xbc\x92\xc7\xe1\x38\x17\xe2\x2e\x59\x3a\xe7\x6b\xf4\x57\x45\xe9\xaf\xb7\xbe\x82\x6d\xfc\x2b\xce\x1f\x34\xfb\x5f\x06\x3b\x69\xd0\x1d\xa9\xbc\x3b\xe8\xf6\xed\xfa\xe7\x7b\x76\xf4\xe8\xaf\xb2\x3b\x1a\xf2\x27\xf0\x43\x8b\xfb\x4c\x7d\xef\xa2\x56\xbf\xde\xbe\x6d\xd8\x9f\x73\xdc\x61\xb2\x01\x76\xb2\x71\x0a\x3b\x67\xfe\x3a\x95\xbb\xf1\x7f\x5a\xe6\xfc\xf0\xd7\x35\x5a\xae\xd0\x77\x72\x2b\x4d\x59\x94\x3c\x47\xd9\x32\xe7\x53\xc0\xc2\x16\x39\xba\x58\x73\x54\x56\x62\x5c\xfb\xab\x90\xa3\xd6\x07\xb5\x0f\xa7\xe9\xc3\xa9\xfa\xde\xed\x83\xfc\xf5\x9e\xdc\x93\xd4\x36\x3b\x6c\xa0\x8f\x75\x64\xbf\xfd\xa6\x7d\x3b\xbc\x2c\x17\xb9\x78\xbb\xec\xc0\xc8\xad\x43\x82\x17\xa4\xff\x0c\x9b\x7d\x6e\x7d\x75\xf4\xf5\xc1\x8d\xfd\x7d\x7d\x74\x4b\xf6\x76\x5d\xad\xca\xc5\xe9\xc3\xd5\xf2\xec\x64\xc6\x56\x27\xcb\x5c\x68\xee\x05\xfc\x78\x58\x68\xbf\x2a\xe1\xbf\x64\xef\xf9\x42\xca\xb8\x6f\xb2\xe7\x17\x8b\x2b\x21\xdf\x5b\x5f\x35\x11\xec\x22\x5b\x93\x9c\x8b\x1f\x27\x92\x8e\xec\x20\x2c\x6d\xc2\xe6\xfb\x7a\x08\x84\x9f\xb2\xe5\xc5\xa2\xe2\x2b\x35\x73\x09\x3f\xcd\xeb\x58\x21\x9b\xb7\xc1\x02\x9e\xc2\x79\xc6\xfa\x0b\xdf\x54\x2b\x26\xbe\x5c\xce\xca\x39\x47\x93\x1a\xdb\x7d\x85\x44\x92\xfe\x0a\xda\xb4\x08\x33\xd5\xbd\x6f\xab\xba\xc1\xfe\xbe\x70\xf5\xaf\x40\xa7\x12\xf8\x9b\x63\xe4\x6d\xbe\xa7\x9e\x27\x74\x2e\x7f\xba\x0f\x3f\x7d\xf7\xf0\xa1\xf8\xc9\x42\x49\x88\x0b\x5e\xd7\xd7\x17\xab\xd5\xf2\x94\x55\x7c\x0a\x56\x57\xcd\xf8\x8a\xc3\x39\x4f\xb4\xe0\x9b\x0a\x09\x16\x58\x56\xf1\x15\x34\x82\x6e\x6c\xc3\x1f\x30\x38\x91\xe0\xb7\x91\xb7\x79\x78\xe2\x79\x7b\xc2\x42\xbd\xcd\xf7\xf0\xf1\xef\x22\x38\xcf\x97\x97\x2d\x7d\x68\xf6\x95\x94\xbc\x1c\xca\x27\xaa\x8b\x02\x81\xff\xf0\xe1\x1e\x1c\xcd\xf4\xf6\xd0\x3e\xd2\x30\xc3\x83\xfd\xba\xe2\x90\xa2\xde\x66\xc1\xaa\xab\x17\x8b\x33\x56\x65\x33\x9e\xb7\xf4\xee\xa1\xe5\x62\x7e\x85\xd8\xf9\x39\x87\x7e\x97\x6b\x70\x40\x74\xb1\x28\xab\xa9\x78\xd1\xcc\xd8\x9a\xc3\xdb\xa6\x10\x44\x83\xa9\x81\x11\x42\xaa\xea\x7d\x51\x0d\x56\x31\xd4\x33\xed\xeb\x39\x2b\x57\xc3\x9e\x41\xbf\x14\xaf\x5f\x29\xd1\x1d\x1c\x28\xde\x6f\xf5\x3b\x60\x69\x29\x00\xc5\xff\x55\xbc\x97\x50\xb5\x37\x5e\xc7\x19\xf8\x02\x9c\x01\x46\xe1\xd6\x17\x1a\x2b\x97\x79\x4b\xd7\xc8\xcb\x45\xce\x37\xe8\x18\x1d\x60\xa3\xd9\x37\x7e\x74\xe7\x8e\x66\xfc\xfb\xfb\xb2\x99\xc5\xf8\x81\xce\x1b\x00\x79\xdb\x37\x76\x61\x4a\x0f\x85\xc6\xa5\x64\xe4\xaf\x07\xc7\xb5\xfa\xef\x69\xf2\x42\xfb\xc7\x86\xf8\x51\x23\xfa\xe6\x1b\x84\xbd\xda\x80\xd0\x6f\xca\x87\x94\x4a\x6a\x4e\xa4\xb1\xa2\xdf\x50\xc7\x0e\x1b\xe1\x6f\x41\x08\x10\xda\x94\xd4\x08\x3f\x9b\xf1\xec\xfd\x8b\x8c\xcd\xd9\xea\x7f\x89\x56\x13\xa1\x87\x67\xcb\x72\x21\x77\x53\x83\x00\x9a\x9f\xba\x1e\xdf\xfe\x2c\xbd\xbe\x15\x4e\x35\x5b\x2d\x2f\xd1\x83\xd5\x6a\xb9\x9a\x40\xaf\xee\x3c\x16\xa9\x50\x6b\x9a\x3f\xef\xdf\x41\xfb\x2d\x82\xc3\x6a\x29\x23\xeb\x04\x47\x7b\x87\xd5\xf2\xe7\xf3\x73\xbe\x3a\x61\x6b\x3e\xd9\x43\xfb\x12\x81\x30\xf9\xc5\xb2\x12\x06\x0e\xcc\x4a\xb9\xdc\x11\x0f\xeb\x8e\x7e\xfc\x0c\x23\x41\x2b\x27\xc8\xaa\x45\x26\xde\x8a\x63\x2a\x97\xd9\xd4\xe0\x24\xa5\x6c\xd0\xc6\x44\x17\xe0\x37\x75\x1b\xa9\x51\x98\xaa\xdc\x50\x6f\xaf\xaf\x17\xe9\x10\x27\x75\x43\x93\x5a\x34\xb4\xb7\x95\x71\x3e\x7c\x48\x55\xac\x53\x61\x0e\x1f\xa4\x57\x15\x47\x6b\xfe\x5f\x17\x7c\x91\x41\xa0\xb3\x33\xda\xd2\xa8\x4d\x07\x06\xc2\xab\xb3\x74\x39\x6f\x1c\xc9\x46\x99\x7a\x5d\xca\x64\x48\xb9\xc1\x34\x2e\xa4\x48\x0a\x08\x2b\x01\x9d\x78\x0d\x4b\xcd\xc6\x63\x03\x13\x10\x86\x75\x26\xfc\x21\x13\x0e\x83\xbf\xb7\x23\x93\x98\x48\x2e\x3d\xc5\xe5\x03\xaf\x83\x62\xff\xd8\x62\x35\xd1\x16\x9d\x79\xe0\x0d\x3a\x13\x7c\x92\x44\x31\x55\xcc\xc6\x92\xd9\x87\x5b\x32\x8b\xc9\xae\x9d\x6a\x21\x4d\x5c\x75\x3b\xda\xf5\x80\xc6\x36\x01\x43\xdf\x25\x44\xea\xaf\xc6\x89\x7e\xd2\xd4\x20\x15\xa9\xfb\x30\xb9\x1a\x64\x4d\x2d\xfc\xe8\xa0\xd2\x80\xd6\x3f\x08\x25\xc8\x68\xb5\xe5\xe0\xd2\xf6\x58\x27\xac\x8f\x32\x1a\xca\xfd\x63\x87\xeb\xf7\x22\x7a\xdb\xec\x73\x25\xc2\x8d\xec\x57\x9c\xe5\x27\xcb\x45\x55\x2e\x2e\xe0\xf0\x2c\x68\xbf\x0d\x45\x82\x93\x1f\xa0\xef\xdf\x1c\x03\x5b\x27\x22\xb1\x30\x8c\x06\x77\x7e\x58\x7c\x60\xf3\x32\x07\x20\x29\xed\x3b\xaa\x5b\x8d\xbc\xbb\x54\x90\x44\x08\x13\x05\x6f\x1a\x3a\x6f\x95\x9b\x88\xa6\xcd\x8f\xfb\xfb\x22\x19\xaf\x23\x54\x0f\xcd\x6d\x19\x46\x64\x22\x28\xa2\xe4\xdf\xb5\x60\x68\x84\xf6\x1f\x36\x8c\x1d\x1d\xa1\x1f\x0a\x74\xc9\x91\xc8\xd7\x2e\xce\x91\xc8\x54\xa7\xa8\xac\xfe\xef\xff\xfe\x3f\xf5\xb0\xa4\xa3\x00\x8e\x6f\x59\x7a\x3e\x00\xbc\x33\x08\xfe\xd2\x7a\x5f\x80\x17\x4c\x5a\x2b\x17\xc0\x58\x37\x43\xa2\x7f\xf1\xf5\x2f\x81\xc1\x7c\x87\xba\xfa\x04\x55\x75\x31\x1d\x0f\xb5\xae\x24\x5b\xb0\x39\x1c\x7e\x68\xe4\xf8\x9c\xb3\x1c\x15\xe5\x6a\x5d\xd5\x52\x82\x6e\xed\xae\xe6\xe1\xe8\x86\x26\x8b\xe5\x50\xbc\xeb\xbd\xda\x26\x24\xa1\xdb\x4a\xff\x2a\xb2\x6a\xbc\x36\xf2\xad\x79\x1d\x8e\x61\x3d\x3c\x0f\x6a\x83\x3a\xa9\x51\x81\x5a\xd0\xb1\xc5\x61\xee\xf5\xe3\x81\x8e\x0c\xcb\xd7\x0c\xa8\xb9\xd3\x68\xd7\x94\x80\x35\xd6\xdb\x9a\xaf\x16\xa3\xba\x09\xfc\x0e\x26\x58\xa7\xf5\xb2\xef\x7e\x5f\xb6\x67\xec\x0a\x95\x8b\x6c\x7e\x01\x2f\x21\xe2\xe5\x42\x7f\xa5\x31\x49\xf9\x61\x2d\x9d\x07\x3b\x48\x07\x4c\xf9\x7a\x02\xf4\xd4\x7b\x1a\x81\xbd\x49\x92\x96\x2e\x50\xdf\x26\x50\x0f\x92\x17\x29\xb0\xb1\xfc\xe0\x73\xca\x7c\x38\xc2\xf7\x25\x4a\x95\x44\x1f\xde\xac\x44\x21\x64\x5c\x53\xe8\x31\x08\xdd\xdb\xf4\xc5\xee\x6d\xbc\x93\x3d\xf4\x1b\x48\x64\x22\x79\x90\xbf\x36\xfa\x08\xac\xfa\x80\x37\x2a\xc3\x3b\x06\xf6\xf4\x57\x30\xb3\x26\x6a\x79\x1a\xb5\xf0\xf3\xcb\x87\x07\x14\xe5\x30\x53\xc6\xf3\x26\xf2\xd6\x61\x53\x9d\xc0\x6a\xbe\x43\x40\xd3\xbe\x43\xfc\xb9\xd7\xcb\x49\x54\xae\xd1\x8e\xc6\x92\xbf\x06\x5f\x37\x25\xd1\xc0\xea\xa8\x06\x54\xf4\x00\xa8\x25\x25\x5a\x8c\x6d\x67\x7f\x3a\xe9\x4e\x3b\x4f\x54\x9d\x9d\x6b\xd9\xc8\xa4\x3a\x3b\x47\xc7\xbd\xb1\x64\x0f\xfd\xe9\xf8\x58\x06\xe5\x7e\x76\xa2\x16\x31\xaa\xb3\xf3\x7e\x9e\xa1\xbd\xa0\xb7\xd0\x7b\x9f\x73\xf2\x4d\x88\x15\x1d\x03\x83\x77\x3e\xf0\xd5\xba\x5c\x2e\xee\xdc\x45\x77\x60\xd2\xf7\xce\x54\xfc\x2a\xf9\xb9\x73\x57\xcb\x0a\xe1\x77\xd9\x5d\xf5\xbb\xfc\x72\xeb\xab\x8f\x6a\x92\xee\xc5\xf2\x8c\xa3\x6f\x9f\x7c\x8f\xd2\x8b\x72\x9e\xa3\xe5\x79\x55\x9e\x95\x7f\xe3\xab\xf5\x14\xcd\xcb\xf7\x1c\xad\x0e\x7f\x5d\x4f\xe5\x2b\x31\xcc\xb4\xaf\xcf\x79\x56\x16\x65\x26\x9c\x37\x2f\x41\xe1\xe7\xac\xaa\xf8\x6a\xb1\x06\x7c\xd0\xa8\x9a\x71\x54\x2c\xe7\xf3\xe5\x65\xb9\x38\xbd\x2b\xe7\x3c\x85\xf9\xf5\xce\x45\xa2\x3b\xb5\xd1\xdc\x91\x93\xbb\x1d\x80\x43\x76\x96\xf7\x66\x51\x9b\x23\x92\xe2\xd9\xad\xaf\xa4\xba\xd4\xa1\xc9\x66\x9a\xbb\x3b\x80\x89\x3e\x83\xee\x40\x39\xed\xdb\x45\x6f\xd6\xf8\x4f\xda\xf7\xc3\xc5\x32\xe7\x2f\xaf\xce\x79\x9b\xcc\xb5\x73\xd5\xea\xc5\xa3\x5c\xe8\xf3\xc6\xcf\xcb\xc5\xe9\xf2\x7f\xbe\x40\x1f\xbc\x43\x7a\xe8\xc1\xeb\x79\xdb\x42\x3b\x4b\xda\x30\xa3\x42\x63\x8d\x89\xad\x2e\x67\x6c\xde\xc3\x14\x1f\x7a\x07\x72\x22\x66\x55\xef\x8d\x92\xa7\x18\xd5\x6f\x33\xb6\x7e\x7a\xb9\x78\x56\x6f\x81\x39\x56\x40\x87\xdd\xdf\x01\xbc\x59\x22\x81\xaa\x71\x52\x28\x75\xc4\xe8\x82\xcb\xf5\x21\xf1\x1c\x0e\x12\xef\x09\xd9\xe8\xb2\x7a\xf3\x5e\x16\x30\x14\x10\xf0\xb9\x33\xf9\xd5\xeb\xd7\xf3\x59\xb9\x58\x8a\x5e\x31\x74\xc9\x53\xa4\x0e\xaa\xaa\x59\xeb\x43\x65\xd0\x4a\x26\x1f\x6f\xa9\x23\xaa\xb0\x6c\xf2\x71\xfa\xf7\x8f\x6f\xa7\x34\xda\x66\x49\x64\x70\x62\xf7\xf5\x93\xc7\x8f\xaa\xea\xfc\xb9\x18\x32\xd6\x55\x83\xed\xcf\x69\x79\x2a\x37\xb3\x1c\xfe\xba\xfe\xf3\x36\x98\xef\x5c\xac\x39\xbc\xb0\x65\xd5\x9d\x7b\xb7\x86\x84\xbe\x2b\x4f\x7f\x02\x84\xf7\x44\x87\x7f\x5d\xcf\x44\x50\x2e\x4f\x17\xcb\x15\xbf\x3b\x2f\x17\xfc\x56\x43\xfa\x92\xa7\xfe\x56\x24\x85\x92\x5e\xf1\x54\x8e\x4d\xf2\x98\xf1\x9d\xc3\xa3\x79\x99\x1e\x09\x14\x22\x38\xdf\x3a\x3a\x42\xf9\x72\x71\xa7\x42\xcb\x0f\x7c\xb5\x2a\x73\x5e\xaf\x38\xd4\x0b\x1c\xb7\xb4\x33\xc8\x6a\xe9\x40\x44\xb8\x3b\xcd\x8e\x06\x58\x90\xe8\x00\x1c\x4a\x9a\x5d\x28\x61\x21\xb0\x4e\xa6\x83\x00\x77\xf7\x6e\x7d\x34\x88\x43\x3e\x51\x2b\x5b\x35\xcb\x7f\xbe\x4b\xc8\xc7\xb7\x42\x0c\xd3\x37\x52\x0c\x6f\xf7\x6e\x1d\x1d\xfd\x7f\x68\xbd\xbc\x58\x65\xfc\x09\x3b\x3f\x2f\x17\xa7\x3f\x3f\x7f\x7c\x2c\x1e\x1e\xcc\x61\x17\xe9\xaf\xeb\xc3\x33\x76\x7e\xeb\xff\x05\x00\x00\xff\xff\x73\x19\x9e\x3a\x8a\x21\x06\x00")
 
 func web3JsBytes() ([]byte, error) {
 	return bindataRead(
@@ -114,7 +106,7 @@ func web3Js() (*asset, error) {
 	}
 
 	info := bindataFileInfo{name: "web3.js", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
-	a := &asset{bytes: bytes, info: info}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0x32, 0x6b, 0xa6, 0x48, 0xcf, 0x60, 0x55, 0x11, 0x99, 0x68, 0x24, 0xdb, 0x89, 0x36, 0xbe, 0xaa, 0xc, 0x77, 0xc9, 0x80, 0xa8, 0xd2, 0x72, 0x9d, 0x71, 0xa8, 0xc3, 0x9a, 0x61, 0x8f, 0xaa}}
 	return a, nil
 }
 
@@ -133,6 +125,12 @@ func Asset(name string) ([]byte, error) {
 	return nil, fmt.Errorf("Asset %s not found", name)
 }
 
+// AssetString returns the asset contents as a string (instead of a []byte).
+func AssetString(name string) (string, error) {
+	data, err := Asset(name)
+	return string(data), err
+}
+
 // MustAsset is like Asset but panics when Asset would return an error.
 // It simplifies safe initialization of global variables.
 func MustAsset(name string) []byte {
@@ -144,6 +142,12 @@ func MustAsset(name string) []byte {
 	return a
 }
 
+// MustAssetString is like AssetString but panics when Asset would return an
+// error. It simplifies safe initialization of global variables.
+func MustAssetString(name string) string {
+	return string(MustAsset(name))
+}
+
 // AssetInfo loads and returns the asset info for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
@@ -159,6 +163,33 @@ func AssetInfo(name string) (os.FileInfo, error) {
 	return nil, fmt.Errorf("AssetInfo %s not found", name)
 }
 
+// AssetDigest returns the digest of the file with the given name. It returns an
+// error if the asset could not be found or the digest could not be loaded.
+func AssetDigest(name string) ([sha256.Size]byte, error) {
+	canonicalName := strings.Replace(name, "\\", "/", -1)
+	if f, ok := _bindata[canonicalName]; ok {
+		a, err := f()
+		if err != nil {
+			return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err)
+		}
+		return a.digest, nil
+	}
+	return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name)
+}
+
+// Digests returns a map of all known files and their checksums.
+func Digests() (map[string][sha256.Size]byte, error) {
+	mp := make(map[string][sha256.Size]byte, len(_bindata))
+	for name := range _bindata {
+		a, err := _bindata[name]()
+		if err != nil {
+			return nil, err
+		}
+		mp[name] = a.digest
+	}
+	return mp, nil
+}
+
 // AssetNames returns the names of the assets.
 func AssetNames() []string {
 	names := make([]string, 0, len(_bindata))
@@ -171,7 +202,8 @@ func AssetNames() []string {
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
 	"bignumber.js": bignumberJs,
-	"web3.js":      web3Js,
+
+	"web3.js": web3Js,
 }
 
 // AssetDir returns the file names below a certain
@@ -183,9 +215,9 @@ var _bindata = map[string]func() (*asset, error){
 //       img/
 //         a.png
 //         b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"}
-// AssetDir("data/img") would return []string{"a.png", "b.png"}
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// then AssetDir("data") would return []string{"foo.txt", "img"},
+// AssetDir("data/img") would return []string{"a.png", "b.png"},
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and
 // AssetDir("") will return []string{"data"}.
 func AssetDir(name string) ([]string, error) {
 	node := _bintree
@@ -219,7 +251,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
 	"web3.js":      {web3Js, map[string]*bintree{}},
 }}
 
-// RestoreAsset restores an asset under the given directory
+// RestoreAsset restores an asset under the given directory.
 func RestoreAsset(dir, name string) error {
 	data, err := Asset(name)
 	if err != nil {
@@ -237,14 +269,10 @@ func RestoreAsset(dir, name string) error {
 	if err != nil {
 		return err
 	}
-	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-	if err != nil {
-		return err
-	}
-	return nil
+	return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
 }
 
-// RestoreAssets restores an asset under the given directory recursively
+// RestoreAssets restores an asset under the given directory recursively.
 func RestoreAssets(dir, name string) error {
 	children, err := AssetDir(name)
 	// File
diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js
index 9b52740a59bbd12dd164edc89f0119e5f7c67523..c016a320bf2416cef301d547d2020aa1b00d608e 100644
--- a/internal/jsre/deps/web3.js
+++ b/internal/jsre/deps/web3.js
@@ -3734,7 +3734,7 @@ var inputCallFormatter = function (options){
         options.to = inputAddressFormatter(options.to);
     }
 
-    ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
+    ['maxFeePerGas', 'maxPriorityFeePerGas', 'gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
         return options[key] !== undefined;
     }).forEach(function(key){
         options[key] = utils.fromDecimal(options[key]);
@@ -3759,7 +3759,7 @@ var inputTransactionFormatter = function (options){
         options.to = inputAddressFormatter(options.to);
     }
 
-    ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
+    ['maxFeePerGas', 'maxPriorityFeePerGas', 'gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
         return options[key] !== undefined;
     }).forEach(function(key){
         options[key] = utils.fromDecimal(options[key]);
@@ -3783,6 +3783,12 @@ var outputTransactionFormatter = function (tx){
     tx.nonce = utils.toDecimal(tx.nonce);
     tx.gas = utils.toDecimal(tx.gas);
     tx.gasPrice = utils.toBigNumber(tx.gasPrice);
+    if(tx.maxFeePerGas !== undefined) {
+      tx.maxFeePerGas = utils.toBigNumber(tx.maxFeePerGas);
+    }
+    if(tx.maxPriorityFeePerGas !== undefined) {
+      tx.maxPriorityFeePerGas = utils.toBigNumber(tx.maxPriorityFeePerGas);
+    }
     tx.value = utils.toBigNumber(tx.value);
     return tx;
 };
@@ -3801,7 +3807,9 @@ var outputTransactionReceiptFormatter = function (receipt){
         receipt.transactionIndex = utils.toDecimal(receipt.transactionIndex);
     receipt.cumulativeGasUsed = utils.toDecimal(receipt.cumulativeGasUsed);
     receipt.gasUsed = utils.toDecimal(receipt.gasUsed);
-
+    if(receipt.effectiveGasPrice !== undefined) {
+      receipt.effectiveGasPrice = utils.toBigNumber(receipt.effectiveGasPrice);
+    }
     if(utils.isArray(receipt.logs)) {
         receipt.logs = receipt.logs.map(function(log){
             return outputLogFormatter(log);
@@ -3819,8 +3827,10 @@ var outputTransactionReceiptFormatter = function (receipt){
  * @returns {Object}
 */
 var outputBlockFormatter = function(block) {
-
     // transform to number
+    if (block.baseFeePerGas !== undefined) {
+      block.baseFeePerGas = utils.toBigNumber(block.baseFeePerGas);
+    }
     block.gasLimit = utils.toDecimal(block.gasLimit);
     block.gasUsed = utils.toDecimal(block.gasUsed);
     block.size = utils.toDecimal(block.size);
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index f610aa31929fc65d0bb9c196f05aca35164711d0..88159923a4a4038c49af5a2e1617582bfe6f7891 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -18,58 +18,23 @@
 package web3ext
 
 var Modules = map[string]string{
-	"accounting": AccountingJs,
-	"admin":      AdminJs,
-	"chequebook": ChequebookJs,
-	"clique":     CliqueJs,
-	"ethash":     EthashJs,
-	"debug":      DebugJs,
-	"eth":        EthJs,
-	"miner":      MinerJs,
-	"net":        NetJs,
-	"personal":   PersonalJs,
-	"rpc":        RpcJs,
-	"shh":        ShhJs,
-	"swarmfs":    SwarmfsJs,
-	"txpool":     TxpoolJs,
-	"les":        LESJs,
-	"vflux":      VfluxJs,
+	"admin":    AdminJs,
+	"clique":   CliqueJs,
+	"ethash":   EthashJs,
+	"debug":    DebugJs,
+	"eth":      EthJs,
+	"miner":    MinerJs,
+	"net":      NetJs,
+	"personal": PersonalJs,
+	"rpc":      RpcJs,
+	"txpool":   TxpoolJs,
+	"les":      LESJs,
+	"vflux":    VfluxJs,
 
 	// Bor related apis
 	"bor": BorJs,
 }
 
-const ChequebookJs = `
-web3._extend({
-	property: 'chequebook',
-	methods: [
-		new web3._extend.Method({
-			name: 'deposit',
-			call: 'chequebook_deposit',
-			params: 1,
-			inputFormatter: [null]
-		}),
-		new web3._extend.Property({
-			name: 'balance',
-			getter: 'chequebook_balance',
-			outputFormatter: web3._extend.utils.toDecimal
-		}),
-		new web3._extend.Method({
-			name: 'cash',
-			call: 'chequebook_cash',
-			params: 1,
-			inputFormatter: [null]
-		}),
-		new web3._extend.Method({
-			name: 'issue',
-			call: 'chequebook_issue',
-			params: 2,
-			inputFormatter: [null, null]
-		}),
-	]
-});
-`
-
 const CliqueJs = `
 web3._extend({
 	property: 'clique',
@@ -111,6 +76,12 @@ web3._extend({
 			call: 'clique_status',
 			params: 0
 		}),
+		new web3._extend.Method({
+			name: 'getSigner',
+			call: 'clique_getSigner',
+			params: 1,
+			inputFormatter: [null]
+		}),
 	],
 	properties: [
 		new web3._extend.Property({
@@ -589,6 +560,12 @@ web3._extend({
 			params: 2,
 			inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter],
 		}),
+		new web3._extend.Method({
+			name: 'feeHistory',
+			call: 'eth_feeHistory',
+			params: 3,
+			inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter, null]
+		}),
 	],
 	properties: [
 		new web3._extend.Property({
@@ -603,6 +580,11 @@ web3._extend({
 				return formatted;
 			}
 		}),
+		new web3._extend.Property({
+			name: 'maxPriorityFeePerGas',
+			getter: 'eth_maxPriorityFeePerGas',
+			outputFormatter: web3._extend.utils.toBigNumber
+		}),
 	]
 });
 `
@@ -638,6 +620,12 @@ web3._extend({
 			params: 1,
 			inputFormatter: [web3._extend.utils.fromDecimal]
 		}),
+		new web3._extend.Method({
+			name: 'setGasLimit',
+			call: 'miner_setGasLimit',
+			params: 1,
+			inputFormatter: [web3._extend.utils.fromDecimal]
+		}),
 		new web3._extend.Method({
 			name: 'setRecommitInterval',
 			call: 'miner_setRecommitInterval',
@@ -734,50 +722,6 @@ web3._extend({
 });
 `
 
-const ShhJs = `
-web3._extend({
-	property: 'shh',
-	methods: [
-	],
-	properties:
-	[
-		new web3._extend.Property({
-			name: 'version',
-			getter: 'shh_version',
-			outputFormatter: web3._extend.utils.toDecimal
-		}),
-		new web3._extend.Property({
-			name: 'info',
-			getter: 'shh_info'
-		}),
-	]
-});
-`
-
-const SwarmfsJs = `
-web3._extend({
-	property: 'swarmfs',
-	methods:
-	[
-		new web3._extend.Method({
-			name: 'mount',
-			call: 'swarmfs_mount',
-			params: 2
-		}),
-		new web3._extend.Method({
-			name: 'unmount',
-			call: 'swarmfs_unmount',
-			params: 1
-		}),
-		new web3._extend.Method({
-			name: 'listmounts',
-			call: 'swarmfs_listmounts',
-			params: 0
-		}),
-	]
-});
-`
-
 const TxpoolJs = `
 web3._extend({
 	property: 'txpool',
@@ -801,49 +745,10 @@ web3._extend({
 				return status;
 			}
 		}),
-	]
-});
-`
-
-const AccountingJs = `
-web3._extend({
-	property: 'accounting',
-	methods: [
-		new web3._extend.Property({
-			name: 'balance',
-			getter: 'account_balance'
-		}),
-		new web3._extend.Property({
-			name: 'balanceCredit',
-			getter: 'account_balanceCredit'
-		}),
-		new web3._extend.Property({
-			name: 'balanceDebit',
-			getter: 'account_balanceDebit'
-		}),
-		new web3._extend.Property({
-			name: 'bytesCredit',
-			getter: 'account_bytesCredit'
-		}),
-		new web3._extend.Property({
-			name: 'bytesDebit',
-			getter: 'account_bytesDebit'
-		}),
-		new web3._extend.Property({
-			name: 'msgCredit',
-			getter: 'account_msgCredit'
-		}),
-		new web3._extend.Property({
-			name: 'msgDebit',
-			getter: 'account_msgDebit'
-		}),
-		new web3._extend.Property({
-			name: 'peerDrops',
-			getter: 'account_peerDrops'
-		}),
-		new web3._extend.Property({
-			name: 'selfDrops',
-			getter: 'account_selfDrops'
+		new web3._extend.Method({
+			name: 'contentFrom',
+			call: 'txpool_contentFrom',
+			params: 1,
 		}),
 	]
 });
diff --git a/les/api_backend.go b/les/api_backend.go
index 53d925b65237182c3f9c245891bd35d3c95abc62..10724c34f6113be90c292ee8f153bff2f763d0cc 100644
--- a/les/api_backend.go
+++ b/les/api_backend.go
@@ -60,7 +60,13 @@ func (b *LesApiBackend) SetHead(number uint64) {
 }
 
 func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
-	if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber {
+	// Return the latest current as the pending one since there
+	// is no pending notion in the light client. TODO(rjl493456442)
+	// unify the behavior of `HeaderByNumber` and `PendingBlockAndReceipts`.
+	if number == rpc.PendingBlockNumber {
+		return b.eth.blockchain.CurrentHeader(), nil
+	}
+	if number == rpc.LatestBlockNumber {
 		return b.eth.blockchain.CurrentHeader(), nil
 	}
 	return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(number))
@@ -122,6 +128,10 @@ func (b *LesApiBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r
 	return nil, errors.New("invalid arguments; neither block nor hash specified")
 }
 
+func (b *LesApiBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
+	return nil, nil
+}
+
 func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
 	header, err := b.HeaderByNumber(ctx, number)
 	if err != nil {
@@ -212,6 +222,10 @@ func (b *LesApiBackend) TxPoolContent() (map[common.Address]types.Transactions,
 	return b.eth.txPool.Content()
 }
 
+func (b *LesApiBackend) TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
+	return b.eth.txPool.ContentFrom(addr)
+}
+
 func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
 	return b.eth.txPool.SubscribeNewTxsEvent(ch)
 }
@@ -251,8 +265,12 @@ func (b *LesApiBackend) ProtocolVersion() int {
 	return b.eth.LesVersion() + 10000
 }
 
-func (b *LesApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
-	return b.gpo.SuggestPrice(ctx)
+func (b *LesApiBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
+	return b.gpo.SuggestTipCap(ctx)
+}
+
+func (b *LesApiBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
+	return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
 }
 
 func (b *LesApiBackend) ChainDb() ethdb.Database {
diff --git a/les/client.go b/les/client.go
index 6fa8e3597e38206cc2b0d4096007378fe4933b52..7a56a5c5dab4764c1d392d62820715d13be9b632 100644
--- a/les/client.go
+++ b/les/client.go
@@ -88,7 +88,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
 	if err != nil {
 		return nil, err
 	}
-	chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideBerlin)
+	chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon)
 	if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat {
 		return nil, genesisErr
 	}
diff --git a/les/client_handler.go b/les/client_handler.go
index 73149975c3a537cefb1bc6f3428bb672303ef90d..e95996c51f6f65ccd8fd693c6c8c91e536ede468 100644
--- a/les/client_handler.go
+++ b/les/client_handler.go
@@ -19,6 +19,7 @@ package les
 import (
 	"context"
 	"math/big"
+	"math/rand"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -388,7 +389,7 @@ func (pc *peerConnection) RequestHeadersByHash(origin common.Hash, amount int, s
 			return dp.(*serverPeer) == pc.peer
 		},
 		request: func(dp distPeer) func() {
-			reqID := genReqID()
+			reqID := rand.Uint64()
 			peer := dp.(*serverPeer)
 			cost := peer.getRequestCost(GetBlockHeadersMsg, amount)
 			peer.fcServer.QueuedRequest(reqID, cost)
@@ -412,7 +413,7 @@ func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip
 			return dp.(*serverPeer) == pc.peer
 		},
 		request: func(dp distPeer) func() {
-			reqID := genReqID()
+			reqID := rand.Uint64()
 			peer := dp.(*serverPeer)
 			cost := peer.getRequestCost(GetBlockHeadersMsg, amount)
 			peer.fcServer.QueuedRequest(reqID, cost)
@@ -429,7 +430,7 @@ func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip
 // RetrieveSingleHeaderByNumber requests a single header by the specified block
 // number. This function will wait the response until it's timeout or delivered.
 func (pc *peerConnection) RetrieveSingleHeaderByNumber(context context.Context, number uint64) (*types.Header, error) {
-	reqID := genReqID()
+	reqID := rand.Uint64()
 	rq := &distReq{
 		getCost: func(dp distPeer) uint64 {
 			peer := dp.(*serverPeer)
diff --git a/les/fetcher.go b/les/fetcher.go
index fc4c5e386a566b9e65b18051ba8ce73ccf9d60c3..a6d1c93c4b712a0b1f81a7300e5d95f59d359368 100644
--- a/les/fetcher.go
+++ b/les/fetcher.go
@@ -507,7 +507,7 @@ func (f *lightFetcher) requestHeaderByHash(peerid enode.ID) func(common.Hash) er
 			getCost: func(dp distPeer) uint64 { return dp.(*serverPeer).getRequestCost(GetBlockHeadersMsg, 1) },
 			canSend: func(dp distPeer) bool { return dp.(*serverPeer).ID() == peerid },
 			request: func(dp distPeer) func() {
-				peer, id := dp.(*serverPeer), genReqID()
+				peer, id := dp.(*serverPeer), rand.Uint64()
 				cost := peer.getRequestCost(GetBlockHeadersMsg, 1)
 				peer.fcServer.QueuedRequest(id, cost)
 
diff --git a/les/handler_test.go b/les/handler_test.go
index d1dbee6bdf93cd6ac296a2ad72c777dfc0041eaa..bb8ad33829f11d22961c9fb5e30710e683df5d67 100644
--- a/les/handler_test.go
+++ b/les/handler_test.go
@@ -370,7 +370,7 @@ func testGetReceipt(t *testing.T, protocol int) {
 		block := bc.GetBlockByNumber(i)
 
 		hashes = append(hashes, block.Hash())
-		receipts = append(receipts, rawdb.ReadRawReceipts(server.db, block.Hash(), block.NumberU64()))
+		receipts = append(receipts, rawdb.ReadReceipts(server.db, block.Hash(), block.NumberU64(), bc.Config()))
 	}
 	// Send the hash request and verify the response
 	sendRequest(rawPeer.app, GetReceiptsMsg, 42, hashes)
diff --git a/les/odr.go b/les/odr.go
index d45c6a1a5d0501a125f55831873f3a21f7a6f90d..10ff0854d38500e9ccf37e258da36ca0889e6e8e 100644
--- a/les/odr.go
+++ b/les/odr.go
@@ -18,6 +18,7 @@ package les
 
 import (
 	"context"
+	"math/rand"
 	"sort"
 	"time"
 
@@ -156,7 +157,7 @@ func (odr *LesOdr) RetrieveTxStatus(ctx context.Context, req *light.TxStatusRequ
 		var (
 			// Deep copy the request, so that the partial result won't be mixed.
 			req     = &TxStatusRequest{Hashes: req.Hashes}
-			id      = genReqID()
+			id      = rand.Uint64()
 			distreq = &distReq{
 				getCost: func(dp distPeer) uint64 { return req.GetCost(dp.(*serverPeer)) },
 				canSend: func(dp distPeer) bool { return canSend[dp.(*serverPeer).id] },
@@ -200,7 +201,7 @@ func (odr *LesOdr) RetrieveTxStatus(ctx context.Context, req *light.TxStatusRequ
 func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error) {
 	lreq := LesRequest(req)
 
-	reqID := genReqID()
+	reqID := rand.Uint64()
 	rq := &distReq{
 		getCost: func(dp distPeer) uint64 {
 			return lreq.GetCost(dp.(*serverPeer))
diff --git a/les/odr_test.go b/les/odr_test.go
index 0c75014d4975158370995b2b291f07cf8dcfe1e8..ea88495d198d258eb0ff582533589159859386ab 100644
--- a/les/odr_test.go
+++ b/les/odr_test.go
@@ -135,11 +135,11 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
 				from := statedb.GetOrNewStateObject(bankAddr)
 				from.SetBalance(math.MaxBig256)
 
-				msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, nil, false)}
+				msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
 
 				context := core.NewEVMBlockContext(header, bc, nil)
 				txContext := core.NewEVMTxContext(msg)
-				vmenv := vm.NewEVM(context, txContext, statedb, config, vm.Config{})
+				vmenv := vm.NewEVM(context, txContext, statedb, config, vm.Config{NoBaseFee: true})
 
 				//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
 				gp := new(core.GasPool).AddGas(math.MaxUint64)
@@ -150,10 +150,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
 			header := lc.GetHeaderByHash(bhash)
 			state := light.NewState(ctx, header, lc.Odr())
 			state.SetBalance(bankAddr, math.MaxBig256)
-			msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, nil, false)}
+			msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
 			context := core.NewEVMBlockContext(header, lc, nil)
 			txContext := core.NewEVMTxContext(msg)
-			vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{})
+			vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true})
 			gp := new(core.GasPool).AddGas(math.MaxUint64)
 			result, _ := core.ApplyMessage(vmenv, msg, gp)
 			if state.Error() == nil {
diff --git a/les/protocol.go b/les/protocol.go
index 07a4452f40c979328ca571e7059dcc7e16cd47c6..06db9024eb8b16eb509ed82332825d41330393a5 100644
--- a/les/protocol.go
+++ b/les/protocol.go
@@ -307,19 +307,19 @@ func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
 // into either a block hash or a block number.
 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
-	_, size, _ := s.Kind()
-	origin, err := s.Raw()
-	if err == nil {
-		switch {
-		case size == 32:
-			err = rlp.DecodeBytes(origin, &hn.Hash)
-		case size <= 8:
-			err = rlp.DecodeBytes(origin, &hn.Number)
-		default:
-			err = fmt.Errorf("invalid input size %d for origin", size)
-		}
+	_, size, err := s.Kind()
+	switch {
+	case err != nil:
+		return err
+	case size == 32:
+		hn.Number = 0
+		return s.Decode(&hn.Hash)
+	case size <= 8:
+		hn.Hash = common.Hash{}
+		return s.Decode(&hn.Number)
+	default:
+		return fmt.Errorf("invalid input size %d for origin", size)
 	}
-	return err
 }
 
 // CodeData is the network response packet for a node data retrieval.
diff --git a/les/retrieve.go b/les/retrieve.go
index 3174d498789bcaaf1e7e48bd89de18e627eabab6..307af04212559f6056c3822452f4a6b2b08e001e 100644
--- a/les/retrieve.go
+++ b/les/retrieve.go
@@ -18,8 +18,6 @@ package les
 
 import (
 	"context"
-	"crypto/rand"
-	"encoding/binary"
 	"fmt"
 	"sync"
 	"time"
@@ -430,10 +428,3 @@ func (r *sentReq) stop(err error) {
 func (r *sentReq) getError() error {
 	return r.err
 }
-
-// genReqID generates a new random request ID
-func genReqID() uint64 {
-	var rnd [8]byte
-	rand.Read(rnd[:])
-	return binary.BigEndian.Uint64(rnd[:])
-}
diff --git a/les/servingqueue.go b/les/servingqueue.go
index 16e064cb3f8a5124e6c0066cd28c17eabc673944..10c7e6f48cba21c40897ff1e5b0c7ebe1926b649 100644
--- a/les/servingqueue.go
+++ b/les/servingqueue.go
@@ -159,27 +159,23 @@ func (sq *servingQueue) newTask(peer *clientPeer, maxTime uint64, priority int64
 // run tokens from the token channel and allow the corresponding tasks to run
 // without entering the priority queue.
 func (sq *servingQueue) threadController() {
+	defer sq.wg.Done()
 	for {
 		token := make(runToken)
 		select {
 		case best := <-sq.queueBestCh:
 			best.tokenCh <- token
 		case <-sq.stopThreadCh:
-			sq.wg.Done()
 			return
 		case <-sq.quit:
-			sq.wg.Done()
 			return
 		}
-		<-token
 		select {
 		case <-sq.stopThreadCh:
-			sq.wg.Done()
 			return
 		case <-sq.quit:
-			sq.wg.Done()
 			return
-		default:
+		case <-token:
 		}
 	}
 }
@@ -298,6 +294,7 @@ func (sq *servingQueue) addTask(task *servingTask) {
 // and always tries to send the highest priority task to queueBestCh. Successfully sent
 // tasks are removed from the queue.
 func (sq *servingQueue) queueLoop() {
+	defer sq.wg.Done()
 	for {
 		if sq.best != nil {
 			expTime := sq.best.expTime
@@ -316,7 +313,6 @@ func (sq *servingQueue) queueLoop() {
 					sq.best, _ = sq.queue.PopItem().(*servingTask)
 				}
 			case <-sq.quit:
-				sq.wg.Done()
 				return
 			}
 		} else {
@@ -324,7 +320,6 @@ func (sq *servingQueue) queueLoop() {
 			case task := <-sq.queueAddCh:
 				sq.addTask(task)
 			case <-sq.quit:
-				sq.wg.Done()
 				return
 			}
 		}
@@ -335,6 +330,7 @@ func (sq *servingQueue) queueLoop() {
 // of active thread controller goroutines.
 func (sq *servingQueue) threadCountLoop() {
 	var threadCountTarget int
+	defer sq.wg.Done()
 	for {
 		for threadCountTarget > sq.threadCount {
 			sq.wg.Add(1)
@@ -347,14 +343,12 @@ func (sq *servingQueue) threadCountLoop() {
 			case sq.stopThreadCh <- struct{}{}:
 				sq.threadCount--
 			case <-sq.quit:
-				sq.wg.Done()
 				return
 			}
 		} else {
 			select {
 			case threadCountTarget = <-sq.setThreadsCh:
 			case <-sq.quit:
-				sq.wg.Done()
 				return
 			}
 		}
diff --git a/les/state_accessor.go b/les/state_accessor.go
index af5df36508ec0078221f3baee113e3a9c19b3912..112e6fd44d12a8657ece4cfe4125e63a25f627fe 100644
--- a/les/state_accessor.go
+++ b/les/state_accessor.go
@@ -55,10 +55,10 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.
 	signer := types.MakeSigner(leth.blockchain.Config(), block.Number())
 	for idx, tx := range block.Transactions() {
 		// Assemble the transaction call message and return if the requested offset
-		msg, _ := tx.AsMessage(signer)
+		msg, _ := tx.AsMessage(signer, block.BaseFee())
 		txContext := core.NewEVMTxContext(msg)
 		context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil)
-		statedb.Prepare(tx.Hash(), block.Hash(), idx)
+		statedb.Prepare(tx.Hash(), idx)
 		if idx == txIndex {
 			return msg, context, statedb, nil
 		}
diff --git a/les/test_helper.go b/les/test_helper.go
index fc85ed957fda1e5bae318fe45d966abc0f7e79ed..9ff2583b9765ff501275335463f18ed64d7dbe98 100644
--- a/les/test_helper.go
+++ b/les/test_helper.go
@@ -55,7 +55,7 @@ import (
 var (
 	bankKey, _ = crypto.GenerateKey()
 	bankAddr   = crypto.PubkeyToAddress(bankKey.PublicKey)
-	bankFunds  = big.NewInt(1000000000000000000)
+	bankFunds  = big.NewInt(1_000_000_000_000_000_000)
 
 	userKey1, _ = crypto.GenerateKey()
 	userKey2, _ = crypto.GenerateKey()
@@ -123,7 +123,7 @@ func prepare(n int, backend *backends.SimulatedBackend) {
 
 			// bankUser transfers some ether to user1
 			nonce, _ := backend.PendingNonceAt(ctx, bankAddr)
-			tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil), signer, bankKey)
+			tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10_000_000_000_000_000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, bankKey)
 			backend.SendTransaction(ctx, tx)
 		case 1:
 			// Builtin-block
@@ -134,20 +134,20 @@ func prepare(n int, backend *backends.SimulatedBackend) {
 			userNonce1, _ := backend.PendingNonceAt(ctx, userAddr1)
 
 			// bankUser transfers more ether to user1
-			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, userAddr1, big.NewInt(1000), params.TxGas, nil, nil), signer, bankKey)
+			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, userAddr1, big.NewInt(1_000_000_000_000_000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, bankKey)
 			backend.SendTransaction(ctx, tx1)
 
 			// user1 relays ether to user2
-			tx2, _ := types.SignTx(types.NewTransaction(userNonce1, userAddr2, big.NewInt(1000), params.TxGas, nil, nil), signer, userKey1)
+			tx2, _ := types.SignTx(types.NewTransaction(userNonce1, userAddr2, big.NewInt(1_000_000_000_000_000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, userKey1)
 			backend.SendTransaction(ctx, tx2)
 
 			// user1 deploys a test contract
-			tx3, _ := types.SignTx(types.NewContractCreation(userNonce1+1, big.NewInt(0), 200000, big.NewInt(0), testContractCode), signer, userKey1)
+			tx3, _ := types.SignTx(types.NewContractCreation(userNonce1+1, big.NewInt(0), 200000, big.NewInt(params.InitialBaseFee), testContractCode), signer, userKey1)
 			backend.SendTransaction(ctx, tx3)
 			testContractAddr = crypto.CreateAddress(userAddr1, userNonce1+1)
 
 			// user1 deploys a event contract
-			tx4, _ := types.SignTx(types.NewContractCreation(userNonce1+2, big.NewInt(0), 200000, big.NewInt(0), testEventEmitterCode), signer, userKey1)
+			tx4, _ := types.SignTx(types.NewContractCreation(userNonce1+2, big.NewInt(0), 200000, big.NewInt(params.InitialBaseFee), testEventEmitterCode), signer, userKey1)
 			backend.SendTransaction(ctx, tx4)
 		case 2:
 			// Builtin-block
@@ -156,12 +156,12 @@ func prepare(n int, backend *backends.SimulatedBackend) {
 
 			// bankUser transfer some ether to signer
 			bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
-			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, signerAddr, big.NewInt(1000000000), params.TxGas, nil, nil), signer, bankKey)
+			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, signerAddr, big.NewInt(1000000000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, bankKey)
 			backend.SendTransaction(ctx, tx1)
 
 			// invoke test contract
 			data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
-			tx2, _ := types.SignTx(types.NewTransaction(bankNonce+1, testContractAddr, big.NewInt(0), 100000, nil, data), signer, bankKey)
+			tx2, _ := types.SignTx(types.NewTransaction(bankNonce+1, testContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data), signer, bankKey)
 			backend.SendTransaction(ctx, tx2)
 		case 3:
 			// Builtin-block
@@ -171,7 +171,7 @@ func prepare(n int, backend *backends.SimulatedBackend) {
 			// invoke test contract
 			bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
 			data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
-			tx, _ := types.SignTx(types.NewTransaction(bankNonce, testContractAddr, big.NewInt(0), 100000, nil, data), signer, bankKey)
+			tx, _ := types.SignTx(types.NewTransaction(bankNonce, testContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data), signer, bankKey)
 			backend.SendTransaction(ctx, tx)
 		}
 		backend.Commit()
@@ -197,6 +197,7 @@ func newTestClientHandler(backend *backends.SimulatedBackend, odr *LesOdr, index
 			Config:   params.AllEthashProtocolChanges,
 			Alloc:    core.GenesisAlloc{bankAddr: {Balance: bankFunds}},
 			GasLimit: 100000000,
+			BaseFee:  big.NewInt(params.InitialBaseFee),
 		}
 		oracle *checkpointoracle.CheckpointOracle
 	)
@@ -256,6 +257,7 @@ func newTestServerHandler(blocks int, indexers []*core.ChainIndexer, db ethdb.Da
 			Config:   params.AllEthashProtocolChanges,
 			Alloc:    core.GenesisAlloc{bankAddr: {Balance: bankFunds}},
 			GasLimit: 100000000,
+			BaseFee:  big.NewInt(params.InitialBaseFee),
 		}
 		oracle *checkpointoracle.CheckpointOracle
 	)
diff --git a/les/txrelay.go b/les/txrelay.go
index 9d29b2f23480446fc90db737539c5ee1bb88d781..40a51fb76f8edaae65b052e961c702dda6bb34ea 100644
--- a/les/txrelay.go
+++ b/les/txrelay.go
@@ -18,6 +18,7 @@ package les
 
 import (
 	"context"
+	"math/rand"
 	"sync"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -117,7 +118,7 @@ func (ltrx *lesTxRelay) send(txs types.Transactions, count int) {
 		ll := list
 		enc, _ := rlp.EncodeToBytes(ll)
 
-		reqID := genReqID()
+		reqID := rand.Uint64()
 		rq := &distReq{
 			getCost: func(dp distPeer) uint64 {
 				peer := dp.(*serverPeer)
diff --git a/light/lightchain_test.go b/light/lightchain_test.go
index 2aed08d74edf538b9e2230d21feb2ecd3a452ec0..af36ebd96a23fae0de3fbb4e51b6b61817a9489c 100644
--- a/light/lightchain_test.go
+++ b/light/lightchain_test.go
@@ -322,8 +322,8 @@ func TestBadHeaderHashes(t *testing.T) {
 	var err error
 	headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10)
 	core.BadHashes[headers[2].Hash()] = true
-	if _, err = bc.InsertHeaderChain(headers, 1); !errors.Is(err, core.ErrBlacklistedHash) {
-		t.Errorf("error mismatch: have: %v, want %v", err, core.ErrBlacklistedHash)
+	if _, err = bc.InsertHeaderChain(headers, 1); !errors.Is(err, core.ErrBannedHash) {
+		t.Errorf("error mismatch: have: %v, want %v", err, core.ErrBannedHash)
 	}
 }
 
diff --git a/light/odr_test.go b/light/odr_test.go
index 0fc45b873418f18d3a90fc25fe63253d8a405721..fdf657a82ec5d54dfdbf0dbcae2a7abf725158e9 100644
--- a/light/odr_test.go
+++ b/light/odr_test.go
@@ -42,7 +42,7 @@ import (
 var (
 	testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
-	testBankFunds   = big.NewInt(100000000)
+	testBankFunds   = big.NewInt(1_000_000_000_000_000_000)
 
 	acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
 	acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
@@ -194,10 +194,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
 
 		// Perform read-only call.
 		st.SetBalance(testBankAddress, math.MaxBig256)
-		msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, nil, false)}
+		msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
 		txContext := core.NewEVMTxContext(msg)
 		context := core.NewEVMBlockContext(header, chain, nil)
-		vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{})
+		vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true})
 		gp := new(core.GasPool).AddGas(math.MaxUint64)
 		result, _ := core.ApplyMessage(vmenv, msg, gp)
 		res = append(res, result.Return()...)
@@ -213,17 +213,17 @@ func testChainGen(i int, block *core.BlockGen) {
 	switch i {
 	case 0:
 		// In block 1, the test bank sends account #1 some ether.
-		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
+		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testBankKey)
 		block.AddTx(tx)
 	case 1:
 		// In block 2, the test bank sends some more ether to account #1.
 		// acc1Addr passes it on to account #2.
 		// acc1Addr creates a test contract.
-		tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
+		tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testBankKey)
 		nonce := block.TxNonce(acc1Addr)
-		tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
+		tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, acc1Key)
 		nonce++
-		tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), testContractCode), signer, acc1Key)
+		tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, block.BaseFee(), testContractCode), signer, acc1Key)
 		testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
 		block.AddTx(tx1)
 		block.AddTx(tx2)
@@ -233,7 +233,7 @@ func testChainGen(i int, block *core.BlockGen) {
 		block.SetCoinbase(acc2Addr)
 		block.SetExtra([]byte("yeehaw"))
 		data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
-		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
+		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, block.BaseFee(), data), signer, testBankKey)
 		block.AddTx(tx)
 	case 3:
 		// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
@@ -244,16 +244,19 @@ func testChainGen(i int, block *core.BlockGen) {
 		b3.Extra = []byte("foo")
 		block.AddUncle(b3)
 		data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
-		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
+		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, block.BaseFee(), data), signer, testBankKey)
 		block.AddTx(tx)
 	}
 }
 
 func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
 	var (
-		sdb     = rawdb.NewMemoryDatabase()
-		ldb     = rawdb.NewMemoryDatabase()
-		gspec   = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
+		sdb   = rawdb.NewMemoryDatabase()
+		ldb   = rawdb.NewMemoryDatabase()
+		gspec = core.Genesis{
+			Alloc:   core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
+		}
 		genesis = gspec.MustCommit(sdb)
 	)
 	gspec.MustCommit(ldb)
diff --git a/light/trie_test.go b/light/trie_test.go
index 052194b4d86706eae4c8b4eb66ad0d9d6d0d8b35..e8294cc2a235477aa20161cf563d21cc169b2668 100644
--- a/light/trie_test.go
+++ b/light/trie_test.go
@@ -20,6 +20,7 @@ import (
 	"bytes"
 	"context"
 	"fmt"
+	"math/big"
 	"testing"
 
 	"github.com/davecgh/go-spew/spew"
@@ -36,7 +37,10 @@ func TestNodeIterator(t *testing.T) {
 	var (
 		fulldb  = rawdb.NewMemoryDatabase()
 		lightdb = rawdb.NewMemoryDatabase()
-		gspec   = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
+		gspec   = core.Genesis{
+			Alloc:   core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
+		}
 		genesis = gspec.MustCommit(fulldb)
 	)
 	gspec.MustCommit(lightdb)
diff --git a/light/txpool.go b/light/txpool.go
index 1296389e3b11066a8cf40e42a992df6e413c649a..a7df4aeec38845d78222038fbf8e3ea457df6451 100644
--- a/light/txpool.go
+++ b/light/txpool.go
@@ -505,6 +505,25 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
 	return pending, queued
 }
 
+// ContentFrom retrieves the data content of the transaction pool, returning the
+// pending as well as queued transactions of this address, grouped by nonce.
+func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
+	pool.mu.RLock()
+	defer pool.mu.RUnlock()
+
+	// Retrieve the pending transactions and sort by nonce
+	var pending types.Transactions
+	for _, tx := range pool.pending {
+		account, _ := types.Sender(pool.signer, tx)
+		if account != addr {
+			continue
+		}
+		pending = append(pending, tx)
+	}
+	// There are no queued transactions in a light pool, just return an empty map
+	return pending, types.Transactions{}
+}
+
 // RemoveTransactions removes all given transactions from the pool.
 func (pool *TxPool) RemoveTransactions(txs types.Transactions) {
 	pool.mu.Lock()
diff --git a/light/txpool_test.go b/light/txpool_test.go
index 39d5afe52f4513ec8511db8bd3000e550e70bd34..cc2651d29ae5d2b940a69cc5fa05d5d0d706df41 100644
--- a/light/txpool_test.go
+++ b/light/txpool_test.go
@@ -77,13 +77,16 @@ func txPoolTestChainGen(i int, block *core.BlockGen) {
 
 func TestTxPool(t *testing.T) {
 	for i := range testTx {
-		testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
+		testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey)
 	}
 
 	var (
-		sdb     = rawdb.NewMemoryDatabase()
-		ldb     = rawdb.NewMemoryDatabase()
-		gspec   = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
+		sdb   = rawdb.NewMemoryDatabase()
+		ldb   = rawdb.NewMemoryDatabase()
+		gspec = core.Genesis{
+			Alloc:   core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
+			BaseFee: big.NewInt(params.InitialBaseFee),
+		}
 		genesis = gspec.MustCommit(sdb)
 	)
 	gspec.MustCommit(ldb)
diff --git a/metrics/config.go b/metrics/config.go
index d05d6642653c9d5a043f34935f94361b9cc00e41..2eb09fb48a3344a6d1831a53f1f4d1dbe0ac57d2 100644
--- a/metrics/config.go
+++ b/metrics/config.go
@@ -28,6 +28,11 @@ type Config struct {
 	InfluxDBUsername string `toml:",omitempty"`
 	InfluxDBPassword string `toml:",omitempty"`
 	InfluxDBTags     string `toml:",omitempty"`
+
+	EnableInfluxDBV2     bool   `toml:",omitempty"`
+	InfluxDBToken        string `toml:",omitempty"`
+	InfluxDBBucket       string `toml:",omitempty"`
+	InfluxDBOrganization string `toml:",omitempty"`
 }
 
 // DefaultConfig is the default config for metrics used in go-ethereum.
@@ -42,4 +47,10 @@ var DefaultConfig = Config{
 	InfluxDBUsername: "test",
 	InfluxDBPassword: "test",
 	InfluxDBTags:     "host=localhost",
+
+	// influxdbv2-specific flags
+	EnableInfluxDBV2:     false,
+	InfluxDBToken:        "test",
+	InfluxDBBucket:       "geth",
+	InfluxDBOrganization: "geth",
 }
diff --git a/metrics/cpu_syscall.go b/metrics/cpu_syscall.go
index e245453e824f6f9ef60febfb8bc5cc6232866903..50e04ef1d34b834513148ae1319317591c4da639 100644
--- a/metrics/cpu_syscall.go
+++ b/metrics/cpu_syscall.go
@@ -19,7 +19,7 @@
 package metrics
 
 import (
-	"syscall"
+	syscall "golang.org/x/sys/unix"
 
 	"github.com/ethereum/go-ethereum/log"
 )
diff --git a/metrics/influxdb/influxdbv2.go b/metrics/influxdb/influxdbv2.go
new file mode 100644
index 0000000000000000000000000000000000000000..00901f52c9f4f4830a0768fa46c6cadeca5d00a0
--- /dev/null
+++ b/metrics/influxdb/influxdbv2.go
@@ -0,0 +1,223 @@
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+package influxdb
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/metrics"
+	influxdb2 "github.com/influxdata/influxdb-client-go/v2"
+	"github.com/influxdata/influxdb-client-go/v2/api"
+)
+
+type v2Reporter struct {
+	reg      metrics.Registry
+	interval time.Duration
+
+	endpoint     string
+	token        string
+	bucket       string
+	organization string
+	namespace    string
+	tags         map[string]string
+
+	client influxdb2.Client
+	write  api.WriteAPI
+
+	cache map[string]int64
+}
+
+// InfluxDBWithTags starts a InfluxDB reporter which will post the from the given metrics.Registry at each d interval with the specified tags
+func InfluxDBV2WithTags(r metrics.Registry, d time.Duration, endpoint string, token string, bucket string, organization string, namespace string, tags map[string]string) {
+	rep := &v2Reporter{
+		reg:          r,
+		interval:     d,
+		endpoint:     endpoint,
+		token:        token,
+		bucket:       bucket,
+		organization: organization,
+		namespace:    namespace,
+		tags:         tags,
+		cache:        make(map[string]int64),
+	}
+
+	rep.client = influxdb2.NewClient(rep.endpoint, rep.token)
+	defer rep.client.Close()
+
+	// async write client
+	rep.write = rep.client.WriteAPI(rep.organization, rep.bucket)
+	errorsCh := rep.write.Errors()
+
+	// have to handle write errors in a separate goroutine like this b/c the channel is unbuffered and will block writes if not read
+	go func() {
+		for err := range errorsCh {
+			log.Warn("write error", "err", err.Error())
+		}
+	}()
+	rep.run()
+}
+
+func (r *v2Reporter) run() {
+	intervalTicker := time.Tick(r.interval)
+	pingTicker := time.Tick(time.Second * 5)
+
+	for {
+		select {
+		case <-intervalTicker:
+			r.send()
+		case <-pingTicker:
+			_, err := r.client.Health(context.Background())
+			if err != nil {
+				log.Warn("Got error from influxdb client health check", "err", err.Error())
+			}
+		}
+	}
+
+}
+
+func (r *v2Reporter) send() {
+	r.reg.Each(func(name string, i interface{}) {
+		now := time.Now()
+		namespace := r.namespace
+
+		switch metric := i.(type) {
+
+		case metrics.Counter:
+			v := metric.Count()
+			l := r.cache[name]
+
+			measurement := fmt.Sprintf("%s%s.count", namespace, name)
+			fields := map[string]interface{}{
+				"value": v - l,
+			}
+
+			pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+			r.write.WritePoint(pt)
+
+			r.cache[name] = v
+
+		case metrics.Gauge:
+			ms := metric.Snapshot()
+
+			measurement := fmt.Sprintf("%s%s.gauge", namespace, name)
+			fields := map[string]interface{}{
+				"value": ms.Value(),
+			}
+
+			pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+			r.write.WritePoint(pt)
+
+		case metrics.GaugeFloat64:
+			ms := metric.Snapshot()
+
+			measurement := fmt.Sprintf("%s%s.gauge", namespace, name)
+			fields := map[string]interface{}{
+				"value": ms.Value(),
+			}
+
+			pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+			r.write.WritePoint(pt)
+
+		case metrics.Histogram:
+			ms := metric.Snapshot()
+
+			if ms.Count() > 0 {
+				ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999})
+				measurement := fmt.Sprintf("%s%s.histogram", namespace, name)
+				fields := map[string]interface{}{
+					"count":    ms.Count(),
+					"max":      ms.Max(),
+					"mean":     ms.Mean(),
+					"min":      ms.Min(),
+					"stddev":   ms.StdDev(),
+					"variance": ms.Variance(),
+					"p50":      ps[0],
+					"p75":      ps[1],
+					"p95":      ps[2],
+					"p99":      ps[3],
+					"p999":     ps[4],
+					"p9999":    ps[5],
+				}
+
+				pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+				r.write.WritePoint(pt)
+			}
+
+		case metrics.Meter:
+			ms := metric.Snapshot()
+
+			measurement := fmt.Sprintf("%s%s.meter", namespace, name)
+			fields := map[string]interface{}{
+				"count": ms.Count(),
+				"m1":    ms.Rate1(),
+				"m5":    ms.Rate5(),
+				"m15":   ms.Rate15(),
+				"mean":  ms.RateMean(),
+			}
+
+			pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+			r.write.WritePoint(pt)
+
+		case metrics.Timer:
+			ms := metric.Snapshot()
+			ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999})
+
+			measurement := fmt.Sprintf("%s%s.timer", namespace, name)
+			fields := map[string]interface{}{
+				"count":    ms.Count(),
+				"max":      ms.Max(),
+				"mean":     ms.Mean(),
+				"min":      ms.Min(),
+				"stddev":   ms.StdDev(),
+				"variance": ms.Variance(),
+				"p50":      ps[0],
+				"p75":      ps[1],
+				"p95":      ps[2],
+				"p99":      ps[3],
+				"p999":     ps[4],
+				"p9999":    ps[5],
+				"m1":       ms.Rate1(),
+				"m5":       ms.Rate5(),
+				"m15":      ms.Rate15(),
+				"meanrate": ms.RateMean(),
+			}
+
+			pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+			r.write.WritePoint(pt)
+
+		case metrics.ResettingTimer:
+			t := metric.Snapshot()
+
+			if len(t.Values()) > 0 {
+				ps := t.Percentiles([]float64{50, 95, 99})
+				val := t.Values()
+
+				measurement := fmt.Sprintf("%s%s.span", namespace, name)
+				fields := map[string]interface{}{
+					"count": len(val),
+					"max":   val[len(val)-1],
+					"mean":  t.Mean(),
+					"min":   val[0],
+					"p50":   ps[0],
+					"p95":   ps[1],
+					"p99":   ps[2],
+				}
+
+				pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+				r.write.WritePoint(pt)
+			}
+		}
+	})
+
+	// Force all unwritten data to be sent
+	r.write.Flush()
+}
diff --git a/miner/miner.go b/miner/miner.go
index 00c3d0cb5cfc9f0e51962f84265f4a09397a7718..a4a01b9f4ff708aa339997c75bcb69e3278e920b 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -194,11 +194,22 @@ func (miner *Miner) PendingBlock() *types.Block {
 	return miner.worker.pendingBlock()
 }
 
+// PendingBlockAndReceipts returns the currently pending block and corresponding receipts.
+func (miner *Miner) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
+	return miner.worker.pendingBlockAndReceipts()
+}
+
 func (miner *Miner) SetEtherbase(addr common.Address) {
 	miner.coinbase = addr
 	miner.worker.setEtherbase(addr)
 }
 
+// SetGasCeil sets the gaslimit to strive for when mining blocks post 1559.
+// For pre-1559 blocks, it sets the ceiling.
+func (miner *Miner) SetGasCeil(ceil uint64) {
+	miner.worker.setGasCeil(ceil)
+}
+
 // EnablePreseal turns on the preseal mining feature. It's enabled by default.
 // Note this function shouldn't be exposed to API, it's unnecessary for users
 // (miners) to actually know the underlying detail. It's only for outside project
diff --git a/miner/stress/1559/main.go b/miner/stress/1559/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..90f210b2726d0c2240a2e4b2b1625d26cb019e5d
--- /dev/null
+++ b/miner/stress/1559/main.go
@@ -0,0 +1,255 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// This file contains a miner stress test for eip 1559.
+package main
+
+import (
+	"crypto/ecdsa"
+	"io/ioutil"
+	"math/big"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"time"
+
+	"github.com/ethereum/go-ethereum/accounts/keystore"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/fdlimit"
+	"github.com/ethereum/go-ethereum/consensus/ethash"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/eth"
+	"github.com/ethereum/go-ethereum/eth/downloader"
+	"github.com/ethereum/go-ethereum/eth/ethconfig"
+	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/miner"
+	"github.com/ethereum/go-ethereum/node"
+	"github.com/ethereum/go-ethereum/p2p"
+	"github.com/ethereum/go-ethereum/p2p/enode"
+	"github.com/ethereum/go-ethereum/params"
+)
+
+var (
+	londonBlock = big.NewInt(30) // Predefined london fork block for activating eip 1559.
+)
+
+func main() {
+	log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+	fdlimit.Raise(2048)
+
+	// Generate a batch of accounts to seal and fund with
+	faucets := make([]*ecdsa.PrivateKey, 128)
+	for i := 0; i < len(faucets); i++ {
+		faucets[i], _ = crypto.GenerateKey()
+	}
+	// Pre-generate the ethash mining DAG so we don't race
+	ethash.MakeDataset(1, filepath.Join(os.Getenv("HOME"), ".ethash"))
+
+	// Create an Ethash network based off of the Ropsten config
+	genesis := makeGenesis(faucets)
+
+	var (
+		nodes  []*eth.Ethereum
+		enodes []*enode.Node
+	)
+	for i := 0; i < 4; i++ {
+		// Start the node and wait until it's up
+		stack, ethBackend, err := makeMiner(genesis)
+		if err != nil {
+			panic(err)
+		}
+		defer stack.Close()
+
+		for stack.Server().NodeInfo().Ports.Listener == 0 {
+			time.Sleep(250 * time.Millisecond)
+		}
+		// Connect the node to all the previous ones
+		for _, n := range enodes {
+			stack.Server().AddPeer(n)
+		}
+		// Start tracking the node and its enode
+		nodes = append(nodes, ethBackend)
+		enodes = append(enodes, stack.Server().Self())
+
+		// Inject the signer key and start sealing with it
+		store := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+		if _, err := store.NewAccount(""); err != nil {
+			panic(err)
+		}
+	}
+
+	// Iterate over all the nodes and start mining
+	time.Sleep(3 * time.Second)
+	for _, node := range nodes {
+		if err := node.StartMining(1); err != nil {
+			panic(err)
+		}
+	}
+	time.Sleep(3 * time.Second)
+
+	// Start injecting transactions from the faucets like crazy
+	var (
+		nonces = make([]uint64, len(faucets))
+
+		// The signer activates the 1559 features even before the fork,
+		// so the new 1559 txs can be created with this signer.
+		signer = types.LatestSignerForChainID(genesis.Config.ChainID)
+	)
+	for {
+		// Pick a random mining node
+		index := rand.Intn(len(faucets))
+		backend := nodes[index%len(nodes)]
+
+		headHeader := backend.BlockChain().CurrentHeader()
+		baseFee := headHeader.BaseFee
+
+		// Create a self transaction and inject into the pool. The legacy
+		// and 1559 transactions can all be created by random even if the
+		// fork is not happened.
+		tx := makeTransaction(nonces[index], faucets[index], signer, baseFee)
+		if err := backend.TxPool().AddLocal(tx); err != nil {
+			continue
+		}
+		nonces[index]++
+
+		// Wait if we're too saturated
+		if pend, _ := backend.TxPool().Stats(); pend > 4192 {
+			time.Sleep(100 * time.Millisecond)
+		}
+
+		// Wait if the basefee is raised too fast
+		if baseFee != nil && baseFee.Cmp(new(big.Int).Mul(big.NewInt(100), big.NewInt(params.GWei))) > 0 {
+			time.Sleep(500 * time.Millisecond)
+		}
+	}
+}
+
+func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signer, baseFee *big.Int) *types.Transaction {
+	// Generate legacy transaction
+	if rand.Intn(2) == 0 {
+		tx, err := types.SignTx(types.NewTransaction(nonce, crypto.PubkeyToAddress(privKey.PublicKey), new(big.Int), 21000, big.NewInt(100000000000+rand.Int63n(65536)), nil), signer, privKey)
+		if err != nil {
+			panic(err)
+		}
+		return tx
+	}
+	// Generate eip 1559 transaction
+	recipient := crypto.PubkeyToAddress(privKey.PublicKey)
+
+	// Feecap and feetip are limited to 32 bytes. Offer a sightly
+	// larger buffer for creating both valid and invalid transactions.
+	var buf = make([]byte, 32+5)
+	rand.Read(buf)
+	gasTipCap := new(big.Int).SetBytes(buf)
+
+	// If the given base fee is nil(the 1559 is still not available),
+	// generate a fake base fee in order to create 1559 tx forcibly.
+	if baseFee == nil {
+		baseFee = new(big.Int).SetInt64(int64(rand.Int31()))
+	}
+	// Generate the feecap, 75% valid feecap and 25% unguaranted.
+	var gasFeeCap *big.Int
+	if rand.Intn(4) == 0 {
+		rand.Read(buf)
+		gasFeeCap = new(big.Int).SetBytes(buf)
+	} else {
+		gasFeeCap = new(big.Int).Add(baseFee, gasTipCap)
+	}
+	return types.MustSignNewTx(privKey, signer, &types.DynamicFeeTx{
+		ChainID:    signer.ChainID(),
+		Nonce:      nonce,
+		GasTipCap:  gasTipCap,
+		GasFeeCap:  gasFeeCap,
+		Gas:        21000,
+		To:         &recipient,
+		Value:      big.NewInt(100),
+		Data:       nil,
+		AccessList: nil,
+	})
+}
+
+// makeGenesis creates a custom Ethash genesis block based on some pre-defined
+// faucet accounts.
+func makeGenesis(faucets []*ecdsa.PrivateKey) *core.Genesis {
+	genesis := core.DefaultRopstenGenesisBlock()
+
+	genesis.Config = params.AllEthashProtocolChanges
+	genesis.Config.LondonBlock = londonBlock
+	genesis.Difficulty = params.MinimumDifficulty
+
+	// Small gaslimit for easier basefee moving testing.
+	genesis.GasLimit = 8_000_000
+
+	genesis.Config.ChainID = big.NewInt(18)
+	genesis.Config.EIP150Hash = common.Hash{}
+
+	genesis.Alloc = core.GenesisAlloc{}
+	for _, faucet := range faucets {
+		genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = core.GenesisAccount{
+			Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil),
+		}
+	}
+	if londonBlock.Sign() == 0 {
+		log.Info("Enabled the eip 1559 by default")
+	} else {
+		log.Info("Registered the london fork", "number", londonBlock)
+	}
+	return genesis
+}
+
+func makeMiner(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
+	// Define the basic configurations for the Ethereum node
+	datadir, _ := ioutil.TempDir("", "")
+
+	config := &node.Config{
+		Name:    "geth",
+		Version: params.Version,
+		DataDir: datadir,
+		P2P: p2p.Config{
+			ListenAddr:  "0.0.0.0:0",
+			NoDiscovery: true,
+			MaxPeers:    25,
+		},
+		UseLightweightKDF: true,
+	}
+	// Create the node and configure a full Ethereum node on it
+	stack, err := node.New(config)
+	if err != nil {
+		return nil, nil, err
+	}
+	ethBackend, err := eth.New(stack, &ethconfig.Config{
+		Genesis:         genesis,
+		NetworkId:       genesis.Config.ChainID.Uint64(),
+		SyncMode:        downloader.FullSync,
+		DatabaseCache:   256,
+		DatabaseHandles: 256,
+		TxPool:          core.DefaultTxPoolConfig,
+		GPO:             ethconfig.Defaults.GPO,
+		Ethash:          ethconfig.Defaults.Ethash,
+		Miner: miner.Config{
+			GasCeil:  genesis.GasLimit * 11 / 10,
+			GasPrice: big.NewInt(1),
+			Recommit: time.Second,
+		},
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+	err = stack.Start()
+	return stack, ethBackend, err
+}
diff --git a/miner/stress_clique.go b/miner/stress/clique/main.go
similarity index 98%
rename from miner/stress_clique.go
rename to miner/stress/clique/main.go
index c585e0b1f6eec89959d835e559f9ec5158275c46..2aad40bb51ce157866474ff31ae3d8c9cde3baed 100644
--- a/miner/stress_clique.go
+++ b/miner/stress/clique/main.go
@@ -14,8 +14,6 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-// +build none
-
 // This file contains a miner stress test based on the Clique consensus engine.
 package main
 
@@ -36,6 +34,7 @@ import (
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/eth/downloader"
+	"github.com/ethereum/go-ethereum/eth/ethconfig"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/miner"
 	"github.com/ethereum/go-ethereum/node"
@@ -192,9 +191,8 @@ func makeSealer(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
 		DatabaseCache:   256,
 		DatabaseHandles: 256,
 		TxPool:          core.DefaultTxPoolConfig,
-		GPO:             eth.DefaultConfig.GPO,
+		GPO:             ethconfig.Defaults.GPO,
 		Miner: miner.Config{
-			GasFloor: genesis.GasLimit * 9 / 10,
 			GasCeil:  genesis.GasLimit * 11 / 10,
 			GasPrice: big.NewInt(1),
 			Recommit: time.Second,
diff --git a/miner/stress_ethash.go b/miner/stress/ethash/main.go
similarity index 97%
rename from miner/stress_ethash.go
rename to miner/stress/ethash/main.go
index 0b838d48b9f2c76b1d2d9972f542ca5b5d251ab7..7958e9ab8ef7b664c5721f8100df40a68abc9197 100644
--- a/miner/stress_ethash.go
+++ b/miner/stress/ethash/main.go
@@ -14,8 +14,6 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-// +build none
-
 // This file contains a miner stress test based on the Ethash consensus engine.
 package main
 
@@ -37,6 +35,7 @@ import (
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/eth/downloader"
+	"github.com/ethereum/go-ethereum/eth/ethconfig"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/miner"
 	"github.com/ethereum/go-ethereum/node"
@@ -169,10 +168,9 @@ func makeMiner(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
 		DatabaseCache:   256,
 		DatabaseHandles: 256,
 		TxPool:          core.DefaultTxPoolConfig,
-		GPO:             eth.DefaultConfig.GPO,
-		Ethash:          eth.DefaultConfig.Ethash,
+		GPO:             ethconfig.Defaults.GPO,
+		Ethash:          ethconfig.Defaults.Ethash,
 		Miner: miner.Config{
-			GasFloor: genesis.GasLimit * 9 / 10,
 			GasCeil:  genesis.GasLimit * 11 / 10,
 			GasPrice: big.NewInt(1),
 			Recommit: time.Second,
diff --git a/miner/worker.go b/miner/worker.go
index 2cee6af0c3267691319b0da57db5ecfd4cda82f4..8bdb1eff7ca02a214033f1ca8eb8a1023c936f04 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -162,9 +162,10 @@ type worker struct {
 	pendingMu    sync.RWMutex
 	pendingTasks map[common.Hash]*task
 
-	snapshotMu    sync.RWMutex // The lock used to protect the block snapshot and state snapshot
-	snapshotBlock *types.Block
-	snapshotState *state.StateDB
+	snapshotMu       sync.RWMutex // The lock used to protect the snapshots below
+	snapshotBlock    *types.Block
+	snapshotReceipts types.Receipts
+	snapshotState    *state.StateDB
 
 	// atomic status counters
 	running int32 // The indicator whether the consensus engine is running or not.
@@ -243,6 +244,12 @@ func (w *worker) setEtherbase(addr common.Address) {
 	w.coinbase = addr
 }
 
+func (w *worker) setGasCeil(ceil uint64) {
+	w.mu.Lock()
+	defer w.mu.Unlock()
+	w.config.GasCeil = ceil
+}
+
 // setExtra sets the content used to initialize the block extra field.
 func (w *worker) setExtra(extra []byte) {
 	w.mu.Lock()
@@ -284,6 +291,14 @@ func (w *worker) pendingBlock() *types.Block {
 	return w.snapshotBlock
 }
 
+// pendingBlockAndReceipts returns pending block and corresponding receipts.
+func (w *worker) pendingBlockAndReceipts() (*types.Block, types.Receipts) {
+	// return a snapshot to avoid contention on currentMu mutex
+	w.snapshotMu.RLock()
+	defer w.snapshotMu.RUnlock()
+	return w.snapshotBlock, w.snapshotReceipts
+}
+
 // start sets the running status as 1 and triggers new work submitting.
 func (w *worker) start() {
 	atomic.StoreInt32(&w.running, 1)
@@ -499,7 +514,7 @@ func (w *worker) mainLoop() {
 					acc, _ := types.Sender(w.current.signer, tx)
 					txs[acc] = append(txs[acc], tx)
 				}
-				txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs)
+				txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
 				tcount := w.current.tcount
 				w.commitTransactions(txset, coinbase, nil)
 				// Only update the snapshot if any new transactons were added
@@ -730,6 +745,7 @@ func (w *worker) updateSnapshot() {
 		w.current.receipts,
 		trie.NewStackTrie(nil),
 	)
+	w.snapshotReceipts = copyReceipts(w.current.receipts)
 	w.snapshotState = w.current.state.Copy()
 }
 
@@ -753,8 +769,9 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
 		return true
 	}
 
+	gasLimit := w.current.header.GasLimit
 	if w.current.gasPool == nil {
-		w.current.gasPool = new(core.GasPool).AddGas(w.current.header.GasLimit)
+		w.current.gasPool = new(core.GasPool).AddGas(gasLimit)
 	}
 
 	var coalescedLogs []*types.Log
@@ -769,7 +786,7 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
 		if interrupt != nil && atomic.LoadInt32(interrupt) != commitInterruptNone {
 			// Notify resubmit loop to increase resubmitting interval due to too frequent commits.
 			if atomic.LoadInt32(interrupt) == commitInterruptResubmit {
-				ratio := float64(w.current.header.GasLimit-w.current.gasPool.Gas()) / float64(w.current.header.GasLimit)
+				ratio := float64(gasLimit-w.current.gasPool.Gas()) / float64(gasLimit)
 				if ratio < 0.1 {
 					ratio = 0.1
 				}
@@ -804,7 +821,7 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
 			continue
 		}
 		// Start executing the transaction
-		w.current.state.Prepare(tx.Hash(), common.Hash{}, w.current.tcount)
+		w.current.state.Prepare(tx.Hash(), w.current.tcount)
 
 		logs, err := w.commitTransaction(tx, coinbase)
 		switch {
@@ -880,10 +897,18 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
 	header := &types.Header{
 		ParentHash: parent.Hash(),
 		Number:     num.Add(num, common.Big1),
-		GasLimit:   core.CalcGasLimit(parent, w.config.GasFloor, w.config.GasCeil),
+		GasLimit:   core.CalcGasLimit(parent.GasLimit(), w.config.GasCeil),
 		Extra:      w.extra,
 		Time:       uint64(timestamp),
 	}
+	// Set baseFee and GasLimit if we are on an EIP-1559 chain
+	if w.chainConfig.IsLondon(header.Number) {
+		header.BaseFee = misc.CalcBaseFee(w.chainConfig, parent.Header())
+		if !w.chainConfig.IsLondon(parent.Number()) {
+			parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
+			header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
+		}
+	}
 	// Only set the coinbase if our consensus engine is running (avoid spurious block rewards)
 	if w.isRunning() {
 		if w.coinbase == (common.Address{}) {
@@ -952,7 +977,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
 	}
 
 	// Fill the block with all available pending transactions.
-	pending, err := w.eth.TxPool().Pending()
+	pending, err := w.eth.TxPool().Pending(true)
 	if err != nil {
 		log.Error("Failed to fetch pending transactions", "err", err)
 		return
@@ -973,13 +998,13 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
 		}
 	}
 	if len(localTxs) > 0 {
-		txs := types.NewTransactionsByPriceAndNonce(w.current.signer, localTxs)
+		txs := types.NewTransactionsByPriceAndNonce(w.current.signer, localTxs, header.BaseFee)
 		if w.commitTransactions(txs, w.coinbase, interrupt) {
 			return
 		}
 	}
 	if len(remoteTxs) > 0 {
-		txs := types.NewTransactionsByPriceAndNonce(w.current.signer, remoteTxs)
+		txs := types.NewTransactionsByPriceAndNonce(w.current.signer, remoteTxs, header.BaseFee)
 		if w.commitTransactions(txs, w.coinbase, interrupt) {
 			return
 		}
@@ -1037,11 +1062,12 @@ func (w *worker) postSideBlock(event core.ChainSideEvent) {
 	}
 }
 
-// totalFees computes total consumed fees in ETH. Block transactions and receipts have to have the same order.
+// totalFees computes total consumed miner fees in ETH. Block transactions and receipts have to have the same order.
 func totalFees(block *types.Block, receipts []*types.Receipt) *big.Float {
 	feesWei := new(big.Int)
 	for i, tx := range block.Transactions() {
-		feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), tx.GasPrice()))
+		minerFee, _ := tx.EffectiveGasTip(block.BaseFee())
+		feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), minerFee))
 	}
 	return new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether)))
 }
diff --git a/miner/worker_test.go b/miner/worker_test.go
index 0fe62316e1f129c4100062240c565b504dbd2ecf..9c4dc0f3788e13ad7a8403922662c71d82218f41 100644
--- a/miner/worker_test.go
+++ b/miner/worker_test.go
@@ -67,7 +67,6 @@ var (
 
 	testConfig = &Config{
 		Recommit: time.Second,
-		GasFloor: params.GenesisGasLimit,
 		GasCeil:  params.GenesisGasLimit,
 	}
 )
@@ -84,19 +83,21 @@ func init() {
 
 	signer := types.LatestSigner(params.TestChainConfig)
 	tx1 := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{
-		ChainID: params.TestChainConfig.ChainID,
-		Nonce:   0,
-		To:      &testUserAddress,
-		Value:   big.NewInt(1000),
-		Gas:     params.TxGas,
+		ChainID:  params.TestChainConfig.ChainID,
+		Nonce:    0,
+		To:       &testUserAddress,
+		Value:    big.NewInt(1000),
+		Gas:      params.TxGas,
+		GasPrice: big.NewInt(params.InitialBaseFee),
 	})
 	pendingTxs = append(pendingTxs, tx1)
 
 	tx2 := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{
-		Nonce: 1,
-		To:    &testUserAddress,
-		Value: big.NewInt(1000),
-		Gas:   params.TxGas,
+		Nonce:    1,
+		To:       &testUserAddress,
+		Value:    big.NewInt(1000),
+		Gas:      params.TxGas,
+		GasPrice: big.NewInt(params.InitialBaseFee),
 	})
 	newTxs = append(newTxs, tx2)
 
@@ -182,10 +183,11 @@ func (b *testWorkerBackend) newRandomUncle() *types.Block {
 
 func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
 	var tx *types.Transaction
+	gasPrice := big.NewInt(10 * params.InitialBaseFee)
 	if creation {
-		tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, nil, common.FromHex(testCode)), types.HomesteadSigner{}, testBankKey)
+		tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, gasPrice, common.FromHex(testCode)), types.HomesteadSigner{}, testBankKey)
 	} else {
-		tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
+		tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, gasPrice, nil), types.HomesteadSigner{}, testBankKey)
 	}
 	return tx
 }
@@ -221,6 +223,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) {
 		engine = ethash.NewFaker()
 	}
 
+	chainConfig.LondonBlock = big.NewInt(0)
 	w, b := newTestWorker(t, chainConfig, engine, db, 0)
 	defer w.close()
 
diff --git a/mobile/types.go b/mobile/types.go
index de6457e7e17c48c52c3fdd177daf5e27c55d383c..d1427ac11d3835fde7a8a30b4364fce6f998913b 100644
--- a/mobile/types.go
+++ b/mobile/types.go
@@ -292,19 +292,6 @@ func (tx *Transaction) GetNonce() int64      { return int64(tx.tx.Nonce()) }
 func (tx *Transaction) GetHash() *Hash   { return &Hash{tx.tx.Hash()} }
 func (tx *Transaction) GetCost() *BigInt { return &BigInt{tx.tx.Cost()} }
 
-// Deprecated: GetSigHash cannot know which signer to use.
-func (tx *Transaction) GetSigHash() *Hash { return &Hash{types.HomesteadSigner{}.Hash(tx.tx)} }
-
-// Deprecated: use EthereumClient.TransactionSender
-func (tx *Transaction) GetFrom(chainID *BigInt) (address *Address, _ error) {
-	var signer types.Signer = types.HomesteadSigner{}
-	if chainID != nil {
-		signer = types.NewEIP155Signer(chainID.bigint)
-	}
-	from, err := types.Sender(signer, tx.tx)
-	return &Address{from}, err
-}
-
 func (tx *Transaction) GetTo() *Address {
 	if to := tx.tx.To(); to != nil {
 		return &Address{*to}
diff --git a/node/rpcstack.go b/node/rpcstack.go
index 56e23cc5c78dd36bea4df0354a5359579740f960..2c55a070b22913f4efa427133a3ac7b41abb91cc 100644
--- a/node/rpcstack.go
+++ b/node/rpcstack.go
@@ -251,7 +251,7 @@ func (h *httpServer) doStop() {
 
 	// Shut down the server.
 	httpHandler := h.httpHandler.Load().(*rpcHandler)
-	wsHandler := h.httpHandler.Load().(*rpcHandler)
+	wsHandler := h.wsHandler.Load().(*rpcHandler)
 	if httpHandler != nil {
 		h.httpHandler.Store((*rpcHandler)(nil))
 		httpHandler.server.Stop()
@@ -280,7 +280,7 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error {
 
 	// Create RPC server and handler.
 	srv := rpc.NewServer()
-	if err := RegisterApisFromWhitelist(apis, config.Modules, srv, false); err != nil {
+	if err := RegisterApis(apis, config.Modules, srv, false); err != nil {
 		return err
 	}
 	h.httpConfig = config
@@ -312,7 +312,7 @@ func (h *httpServer) enableWS(apis []rpc.API, config wsConfig) error {
 
 	// Create RPC server and handler.
 	srv := rpc.NewServer()
-	if err := RegisterApisFromWhitelist(apis, config.Modules, srv, false); err != nil {
+	if err := RegisterApis(apis, config.Modules, srv, false); err != nil {
 		return err
 	}
 	h.wsConfig = config
@@ -515,20 +515,20 @@ func (is *ipcServer) stop() error {
 	return err
 }
 
-// RegisterApisFromWhitelist checks the given modules' availability, generates a whitelist based on the allowed modules,
+// RegisterApis checks the given modules' availability, generates an allowlist based on the allowed modules,
 // and then registers all of the APIs exposed by the services.
-func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server, exposeAll bool) error {
+func RegisterApis(apis []rpc.API, modules []string, srv *rpc.Server, exposeAll bool) error {
 	if bad, available := checkModuleAvailability(modules, apis); len(bad) > 0 {
 		log.Error("Unavailable modules in HTTP API list", "unavailable", bad, "available", available)
 	}
-	// Generate the whitelist based on the allowed modules
-	whitelist := make(map[string]bool)
+	// Generate the allow list based on the allowed modules
+	allowList := make(map[string]bool)
 	for _, module := range modules {
-		whitelist[module] = true
+		allowList[module] = true
 	}
 	// Register all the APIs exposed by the services
 	for _, api := range apis {
-		if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
+		if exposeAll || allowList[api.Namespace] || (len(allowList) == 0 && api.Public) {
 			if err := srv.RegisterName(api.Namespace, api.Service); err != nil {
 				return err
 			}
diff --git a/oss-fuzz.sh b/oss-fuzz.sh
index a9bac0325765fe5a1d1dc35c7b286cd912d38952..9a24f6b1751d2d9d263d93eca6f26f14407557eb 100644
--- a/oss-fuzz.sh
+++ b/oss-fuzz.sh
@@ -102,6 +102,7 @@ compile_fuzzer tests/fuzzers/stacktrie  Fuzz fuzzStackTrie
 compile_fuzzer tests/fuzzers/difficulty Fuzz fuzzDifficulty
 compile_fuzzer tests/fuzzers/abi        Fuzz fuzzAbi
 compile_fuzzer tests/fuzzers/les        Fuzz fuzzLes
+compile_fuzzer tests/fuzzers/secp256k1  Fuzz fuzzSecp256k1
 compile_fuzzer tests/fuzzers/vflux      FuzzClientPool fuzzClientPool
 
 compile_fuzzer tests/fuzzers/bls12381  FuzzG1Add fuzz_g1_add
diff --git a/p2p/dial.go b/p2p/dial.go
index d36d6655019aedcfa997511677a2c51479df9e59..83ced3cb328082b3c489c679b78a82b67f6d9eb8 100644
--- a/p2p/dial.go
+++ b/p2p/dial.go
@@ -77,7 +77,7 @@ var (
 	errAlreadyDialing   = errors.New("already dialing")
 	errAlreadyConnected = errors.New("already connected")
 	errRecentlyDialed   = errors.New("recently dialed")
-	errNotWhitelisted   = errors.New("not contained in netrestrict whitelist")
+	errNetRestrict      = errors.New("not contained in netrestrict list")
 	errNoPort           = errors.New("node does not provide TCP port")
 )
 
@@ -133,7 +133,7 @@ type dialConfig struct {
 	self           enode.ID         // our own ID
 	maxDialPeers   int              // maximum number of dialed peers
 	maxActiveDials int              // maximum number of active dials
-	netRestrict    *netutil.Netlist // IP whitelist, disabled if nil
+	netRestrict    *netutil.Netlist // IP netrestrict list, disabled if nil
 	resolver       nodeResolver
 	dialer         NodeDialer
 	log            log.Logger
@@ -402,7 +402,7 @@ func (d *dialScheduler) checkDial(n *enode.Node) error {
 		return errAlreadyConnected
 	}
 	if d.netRestrict != nil && !d.netRestrict.Contains(n.IP()) {
-		return errNotWhitelisted
+		return errNetRestrict
 	}
 	if d.history.contains(string(n.ID().Bytes())) {
 		return errRecentlyDialed
diff --git a/p2p/discover/common.go b/p2p/discover/common.go
index 3708bfb72c4b18cba36dfeca82a5ef86a32617da..e389821fda8b8f4c6d47d14bbca8c2f1c84d2425 100644
--- a/p2p/discover/common.go
+++ b/p2p/discover/common.go
@@ -41,7 +41,7 @@ type Config struct {
 	PrivateKey *ecdsa.PrivateKey
 
 	// These settings are optional:
-	NetRestrict  *netutil.Netlist   // network whitelist
+	NetRestrict  *netutil.Netlist   // list of allowed IP networks
 	Bootnodes    []*enode.Node      // list of bootstrap nodes
 	Unhandled    chan<- ReadPacket  // unhandled packets are sent on this channel
 	Log          log.Logger         // if set, log messages go here
diff --git a/p2p/discover/v4_udp.go b/p2p/discover/v4_udp.go
index ad23eee6b471b36aa8ff223ba551a5a84cb1b7af..334716aebed01e247e6aac7396861210bd65f9d3 100644
--- a/p2p/discover/v4_udp.go
+++ b/p2p/discover/v4_udp.go
@@ -34,7 +34,6 @@ import (
 	"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
 	"github.com/ethereum/go-ethereum/p2p/enode"
 	"github.com/ethereum/go-ethereum/p2p/netutil"
-	"github.com/ethereum/go-ethereum/rlp"
 )
 
 // Errors
@@ -217,7 +216,7 @@ func (t *UDPv4) Ping(n *enode.Node) error {
 func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
 	rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil)
 	if err = <-rm.errc; err == nil {
-		seq = rm.reply.(*v4wire.Pong).ENRSeq()
+		seq = rm.reply.(*v4wire.Pong).ENRSeq
 	}
 	return seq, err
 }
@@ -248,13 +247,12 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r
 }
 
 func (t *UDPv4) makePing(toaddr *net.UDPAddr) *v4wire.Ping {
-	seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq())
 	return &v4wire.Ping{
 		Version:    4,
 		From:       t.ourEndpoint(),
 		To:         v4wire.NewEndpoint(toaddr, 0),
 		Expiration: uint64(time.Now().Add(expiration).Unix()),
-		Rest:       []rlp.RawValue{seq},
+		ENRSeq:     t.localNode.Node().Seq(),
 	}
 }
 
@@ -585,7 +583,7 @@ func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*node, error)
 		return nil, err
 	}
 	if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
-		return nil, errors.New("not contained in netrestrict whitelist")
+		return nil, errors.New("not contained in netrestrict list")
 	}
 	key, err := v4wire.DecodePubkey(crypto.S256(), rn.ID)
 	if err != nil {
@@ -660,12 +658,11 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
 	req := h.Packet.(*v4wire.Ping)
 
 	// Reply.
-	seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq())
 	t.send(from, fromID, &v4wire.Pong{
 		To:         v4wire.NewEndpoint(from, req.From.TCP),
 		ReplyTok:   mac,
 		Expiration: uint64(time.Now().Add(expiration).Unix()),
-		Rest:       []rlp.RawValue{seq},
+		ENRSeq:     t.localNode.Node().Seq(),
 	})
 
 	// Ping back if our last pong on file is too far in the past.
diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go
index 262e3f0ba3009ec8890a34f70af510abfe0e7589..e36912f010aebc3f2dc639ec46124571c0a50351 100644
--- a/p2p/discover/v4_udp_test.go
+++ b/p2p/discover/v4_udp_test.go
@@ -470,13 +470,13 @@ func TestUDPv4_EIP868(t *testing.T) {
 	// Perform endpoint proof and check for sequence number in packet tail.
 	test.packetIn(nil, &v4wire.Ping{Expiration: futureExp})
 	test.waitPacketOut(func(p *v4wire.Pong, addr *net.UDPAddr, hash []byte) {
-		if p.ENRSeq() != wantNode.Seq() {
-			t.Errorf("wrong sequence number in pong: %d, want %d", p.ENRSeq(), wantNode.Seq())
+		if p.ENRSeq != wantNode.Seq() {
+			t.Errorf("wrong sequence number in pong: %d, want %d", p.ENRSeq, wantNode.Seq())
 		}
 	})
 	test.waitPacketOut(func(p *v4wire.Ping, addr *net.UDPAddr, hash []byte) {
-		if p.ENRSeq() != wantNode.Seq() {
-			t.Errorf("wrong sequence number in ping: %d, want %d", p.ENRSeq(), wantNode.Seq())
+		if p.ENRSeq != wantNode.Seq() {
+			t.Errorf("wrong sequence number in ping: %d, want %d", p.ENRSeq, wantNode.Seq())
 		}
 		test.packetIn(nil, &v4wire.Pong{Expiration: futureExp, ReplyTok: hash})
 	})
diff --git a/p2p/discover/v4wire/v4wire.go b/p2p/discover/v4wire/v4wire.go
index b5dcb6e51731abb85fe8ff82624be6b9e85166e5..23e7134414c9ba0193b1698a2f4a789302d775db 100644
--- a/p2p/discover/v4wire/v4wire.go
+++ b/p2p/discover/v4wire/v4wire.go
@@ -50,6 +50,8 @@ type (
 		Version    uint
 		From, To   Endpoint
 		Expiration uint64
+		ENRSeq     uint64 `rlp:"optional"` // Sequence number of local record, added by EIP-868.
+
 		// Ignore additional fields (for forward compatibility).
 		Rest []rlp.RawValue `rlp:"tail"`
 	}
@@ -62,6 +64,8 @@ type (
 		To         Endpoint
 		ReplyTok   []byte // This contains the hash of the ping packet.
 		Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
+		ENRSeq     uint64 `rlp:"optional"` // Sequence number of local record, added by EIP-868.
+
 		// Ignore additional fields (for forward compatibility).
 		Rest []rlp.RawValue `rlp:"tail"`
 	}
@@ -162,13 +166,11 @@ type Packet interface {
 	Kind() byte
 }
 
-func (req *Ping) Name() string   { return "PING/v4" }
-func (req *Ping) Kind() byte     { return PingPacket }
-func (req *Ping) ENRSeq() uint64 { return seqFromTail(req.Rest) }
+func (req *Ping) Name() string { return "PING/v4" }
+func (req *Ping) Kind() byte   { return PingPacket }
 
-func (req *Pong) Name() string   { return "PONG/v4" }
-func (req *Pong) Kind() byte     { return PongPacket }
-func (req *Pong) ENRSeq() uint64 { return seqFromTail(req.Rest) }
+func (req *Pong) Name() string { return "PONG/v4" }
+func (req *Pong) Kind() byte   { return PongPacket }
 
 func (req *Findnode) Name() string { return "FINDNODE/v4" }
 func (req *Findnode) Kind() byte   { return FindnodePacket }
@@ -187,15 +189,6 @@ func Expired(ts uint64) bool {
 	return time.Unix(int64(ts), 0).Before(time.Now())
 }
 
-func seqFromTail(tail []rlp.RawValue) uint64 {
-	if len(tail) == 0 {
-		return 0
-	}
-	var seq uint64
-	rlp.DecodeBytes(tail[0], &seq)
-	return seq
-}
-
 // Encoder/decoder.
 
 const (
diff --git a/p2p/discover/v4wire/v4wire_test.go b/p2p/discover/v4wire/v4wire_test.go
index 4dddeadd20841d68be97e3151256a9bd2f6e60c3..3b4161998dc629ed46ac70917574fde852208c5e 100644
--- a/p2p/discover/v4wire/v4wire_test.go
+++ b/p2p/discover/v4wire/v4wire_test.go
@@ -23,7 +23,6 @@ import (
 	"testing"
 
 	"github.com/davecgh/go-spew/spew"
-	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/rlp"
 )
@@ -40,7 +39,6 @@ var testPackets = []struct {
 			From:       Endpoint{net.ParseIP("127.0.0.1").To4(), 3322, 5544},
 			To:         Endpoint{net.ParseIP("::1"), 2222, 3333},
 			Expiration: 1136239445,
-			Rest:       []rlp.RawValue{},
 		},
 	},
 	{
@@ -50,26 +48,8 @@ var testPackets = []struct {
 			From:       Endpoint{net.ParseIP("127.0.0.1").To4(), 3322, 5544},
 			To:         Endpoint{net.ParseIP("::1"), 2222, 3333},
 			Expiration: 1136239445,
-			Rest:       []rlp.RawValue{{0x01}, {0x02}},
-		},
-	},
-	{
-		input: "577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3",
-		wantPacket: &Ping{
-			Version:    555,
-			From:       Endpoint{net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 3322, 5544},
-			To:         Endpoint{net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348"), 2222, 33338},
-			Expiration: 1136239445,
-			Rest:       []rlp.RawValue{{0xC5, 0x01, 0x02, 0x03, 0x04, 0x05}},
-		},
-	},
-	{
-		input: "09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b2069869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f055542124e",
-		wantPacket: &Pong{
-			To:         Endpoint{net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348"), 2222, 33338},
-			ReplyTok:   common.Hex2Bytes("fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c954"),
-			Expiration: 1136239445,
-			Rest:       []rlp.RawValue{{0xC6, 0x01, 0x02, 0x03, 0xC2, 0x04, 0x05}, {0x06}},
+			ENRSeq:     1,
+			Rest:       []rlp.RawValue{{0x02}},
 		},
 	},
 	{
diff --git a/p2p/dnsdisc/client.go b/p2p/dnsdisc/client.go
index f2a4bed4c6e44da1cf89a2cce270df42e6236ae3..096df06a54f9539ccb7efb6f23079d2d12e6476c 100644
--- a/p2p/dnsdisc/client.go
+++ b/p2p/dnsdisc/client.go
@@ -298,6 +298,12 @@ func (it *randomIterator) pickTree() *clientTree {
 	it.mu.Lock()
 	defer it.mu.Unlock()
 
+	// First check if iterator was closed.
+	// Need to do this here to avoid nil map access in rebuildTrees.
+	if it.trees == nil {
+		return nil
+	}
+
 	// Rebuild the trees map if any links have changed.
 	if it.lc.changed {
 		it.rebuildTrees()
diff --git a/p2p/dnsdisc/client_test.go b/p2p/dnsdisc/client_test.go
index 741bee4230bedc355942c04b960205e54e30cc8c..9320dd667a9410115f88acedef6be967677b0d53 100644
--- a/p2p/dnsdisc/client_test.go
+++ b/p2p/dnsdisc/client_test.go
@@ -115,6 +115,21 @@ func TestIterator(t *testing.T) {
 	checkIterator(t, it, nodes)
 }
 
+func TestIteratorCloseWithoutNext(t *testing.T) {
+	tree1, url1 := makeTestTree("t1", nil, nil)
+	c := NewClient(Config{Resolver: newMapResolver(tree1.ToTXT("t1"))})
+	it, err := c.NewIterator(url1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	it.Close()
+	ok := it.Next()
+	if ok {
+		t.Fatal("Next returned true after Close")
+	}
+}
+
 // This test checks if closing randomIterator races.
 func TestIteratorClose(t *testing.T) {
 	nodes := testNodes(nodesSeed1, 500)
diff --git a/p2p/enode/node.go b/p2p/enode/node.go
index c2429e0e8eb463991d0aa52a14d6d5a33d03946a..d747ca3313778712b30fcb6662efb3c2c2b95633 100644
--- a/p2p/enode/node.go
+++ b/p2p/enode/node.go
@@ -121,7 +121,7 @@ func (n *Node) UDP() int {
 	return int(port)
 }
 
-// UDP returns the TCP port of the node.
+// TCP returns the TCP port of the node.
 func (n *Node) TCP() int {
 	var port enr.TCP
 	n.Load(&port)
diff --git a/p2p/msgrate/msgrate.go b/p2p/msgrate/msgrate.go
new file mode 100644
index 0000000000000000000000000000000000000000..5bfa27b43378ab124faad74c17dcf93163ff6734
--- /dev/null
+++ b/p2p/msgrate/msgrate.go
@@ -0,0 +1,466 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// Package msgrate allows estimating the throughput of peers for more balanced syncs.
+package msgrate
+
+import (
+	"errors"
+	"math"
+	"sort"
+	"sync"
+	"time"
+
+	"github.com/ethereum/go-ethereum/log"
+)
+
+// measurementImpact is the impact a single measurement has on a peer's final
+// capacity value. A value closer to 0 reacts slower to sudden network changes,
+// but it is also more stable against temporary hiccups. 0.1 worked well for
+// most of Ethereum's existence, so might as well go with it.
+const measurementImpact = 0.1
+
+// capacityOverestimation is the ratio of items to over-estimate when retrieving
+// a peer's capacity to avoid locking into a lower value due to never attempting
+// to fetch more than some local stable value.
+const capacityOverestimation = 1.01
+
+// qosTuningPeers is the number of best peers to tune round trip times based on.
+// An Ethereum node doesn't need hundreds of connections to operate correctly,
+// so instead of lowering our download speed to the median of potentially many
+// bad nodes, we can target a smaller set of vey good nodes. At worse this will
+// result in less nodes to sync from, but that's still better than some hogging
+// the pipeline.
+const qosTuningPeers = 5
+
+// rttMinEstimate is the minimal round trip time to target requests for. Since
+// every request entails a 2 way latency + bandwidth + serving database lookups,
+// it should be generous enough to permit meaningful work to be done on top of
+// the transmission costs.
+const rttMinEstimate = 2 * time.Second
+
+// rttMaxEstimate is the maximal round trip time to target requests for. Although
+// the expectation is that a well connected node will never reach this, certain
+// special connectivity ones might experience significant delays (e.g. satellite
+// uplink with 3s RTT). This value should be low enough to forbid stalling the
+// pipeline too long, but large enough to cover the worst of the worst links.
+const rttMaxEstimate = 20 * time.Second
+
+// rttPushdownFactor is a multiplier to attempt forcing quicker requests than
+// what the message rate tracker estimates. The reason is that message rate
+// tracking adapts queries to the RTT, but multiple RTT values can be perfectly
+// valid, they just result in higher packet sizes. Since smaller packets almost
+// always result in stabler download streams, this factor hones in on the lowest
+// RTT from all the functional ones.
+const rttPushdownFactor = 0.9
+
+// rttMinConfidence is the minimum value the roundtrip confidence factor may drop
+// to. Since the target timeouts are based on how confident the tracker is in the
+// true roundtrip, it's important to not allow too huge fluctuations.
+const rttMinConfidence = 0.1
+
+// ttlScaling is the multiplier that converts the estimated roundtrip time to a
+// timeout cap for network requests. The expectation is that peers' response time
+// will fluctuate around the estimated roundtrip, but depending in their load at
+// request time, it might be higher than anticipated. This scaling factor ensures
+// that we allow remote connections some slack but at the same time do enforce a
+// behavior similar to our median peers.
+const ttlScaling = 3
+
+// ttlLimit is the maximum timeout allowance to prevent reaching crazy numbers
+// if some unforeseen network events shappen. As much as we try to hone in on
+// the most optimal values, it doesn't make any sense to go above a threshold,
+// even if everything is slow and screwy.
+const ttlLimit = time.Minute
+
+// tuningConfidenceCap is the number of active peers above which to stop detuning
+// the confidence number. The idea here is that once we hone in on the capacity
+// of a meaningful number of peers, adding one more should ot have a significant
+// impact on things, so just ron with the originals.
+const tuningConfidenceCap = 10
+
+// tuningImpact is the influence that a new tuning target has on the previously
+// cached value. This number is mostly just an out-of-the-blue heuristic that
+// prevents the estimates from jumping around. There's no particular reason for
+// the current value.
+const tuningImpact = 0.25
+
+// Tracker estimates the throughput capacity of a peer with regard to each data
+// type it can deliver. The goal is to dynamically adjust request sizes to max
+// out network throughput without overloading either the peer or th elocal node.
+//
+// By tracking in real time the latencies and bandiwdths peers exhibit for each
+// packet type, it's possible to prevent overloading by detecting a slowdown on
+// one type when another type is pushed too hard.
+//
+// Similarly, real time measurements also help avoid overloading the local net
+// connection if our peers would otherwise be capable to deliver more, but the
+// local link is saturated. In that case, the live measurements will force us
+// to reduce request sizes until the throughput gets stable.
+//
+// Lastly, message rate measurements allows us to detect if a peer is unsuaully
+// slow compared to other peers, in which case we can decide to keep it around
+// or free up the slot so someone closer.
+//
+// Since throughput tracking and estimation adapts dynamically to live network
+// conditions, it's fine to have multiple trackers locally track the same peer
+// in different subsystem. The throughput will simply be distributed across the
+// two trackers if both are highly active.
+type Tracker struct {
+	// capacity is the number of items retrievable per second of a given type.
+	// It is analogous to bandwidth, but we deliberately avoided using bytes
+	// as the unit, since serving nodes also spend a lot of time loading data
+	// from disk, which is linear in the number of items, but mostly constant
+	// in their sizes.
+	//
+	// Callers of course are free to use the item counter as a byte counter if
+	// or when their protocol of choise if capped by bytes instead of items.
+	// (eg. eth.getHeaders vs snap.getAccountRange).
+	capacity map[uint64]float64
+
+	// roundtrip is the latency a peer in general responds to data requests.
+	// This number is not used inside the tracker, but is exposed to compare
+	// peers to each other and filter out slow ones. Note however, it only
+	// makes sense to compare RTTs if the caller caters request sizes for
+	// each peer to target the same RTT. There's no need to make this number
+	// the real networking RTT, we just need a number to compare peers with.
+	roundtrip time.Duration
+
+	lock sync.RWMutex
+}
+
+// NewTracker creates a new message rate tracker for a specific peer. An initial
+// RTT is needed to avoid a peer getting marked as an outlier compared to others
+// right after joining. It's suggested to use the median rtt across all peers to
+// init a new peer tracker.
+func NewTracker(caps map[uint64]float64, rtt time.Duration) *Tracker {
+	if caps == nil {
+		caps = make(map[uint64]float64)
+	}
+	return &Tracker{
+		capacity:  caps,
+		roundtrip: rtt,
+	}
+}
+
+// Capacity calculates the number of items the peer is estimated to be able to
+// retrieve within the alloted time slot. The method will round up any division
+// errors and will add an additional overestimation ratio on top. The reason for
+// overshooting the capacity is because certain message types might not increase
+// the load proportionally to the requested items, so fetching a bit more might
+// still take the same RTT. By forcefully overshooting by a small amount, we can
+// avoid locking into a lower-that-real capacity.
+func (t *Tracker) Capacity(kind uint64, targetRTT time.Duration) int {
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	// Calculate the actual measured throughput
+	throughput := t.capacity[kind] * float64(targetRTT) / float64(time.Second)
+
+	// Return an overestimation to force the peer out of a stuck minima, adding
+	// +1 in case the item count is too low for the overestimator to dent
+	return roundCapacity(1 + capacityOverestimation*throughput)
+}
+
+// roundCapacity gives the integer value of a capacity.
+// The result fits int32, and is guaranteed to be positive.
+func roundCapacity(cap float64) int {
+	const maxInt32 = float64(1<<31 - 1)
+	return int(math.Min(maxInt32, math.Max(1, math.Ceil(cap))))
+}
+
+// Update modifies the peer's capacity values for a specific data type with a new
+// measurement. If the delivery is zero, the peer is assumed to have either timed
+// out or to not have the requested data, resulting in a slash to 0 capacity. This
+// avoids assigning the peer retrievals that it won't be able to honour.
+func (t *Tracker) Update(kind uint64, elapsed time.Duration, items int) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	// If nothing was delivered (timeout / unavailable data), reduce throughput
+	// to minimum
+	if items == 0 {
+		t.capacity[kind] = 0
+		return
+	}
+	// Otherwise update the throughput with a new measurement
+	if elapsed <= 0 {
+		elapsed = 1 // +1 (ns) to ensure non-zero divisor
+	}
+	measured := float64(items) / (float64(elapsed) / float64(time.Second))
+
+	t.capacity[kind] = (1-measurementImpact)*(t.capacity[kind]) + measurementImpact*measured
+	t.roundtrip = time.Duration((1-measurementImpact)*float64(t.roundtrip) + measurementImpact*float64(elapsed))
+}
+
+// Trackers is a set of message rate trackers across a number of peers with the
+// goal of aggregating certain measurements across the entire set for outlier
+// filtering and newly joining initialization.
+type Trackers struct {
+	trackers map[string]*Tracker
+
+	// roundtrip is the current best guess as to what is a stable round trip time
+	// across the entire collection of connected peers. This is derived from the
+	// various trackers added, but is used as a cache to avoid recomputing on each
+	// network request. The value is updated once every RTT to avoid fluctuations
+	// caused by hiccups or peer events.
+	roundtrip time.Duration
+
+	// confidence represents the probability that the estimated roundtrip value
+	// is the real one across all our peers. The confidence value is used as an
+	// impact factor of new measurements on old estimates. As our connectivity
+	// stabilizes, this value gravitates towards 1, new measurements havinng
+	// almost no impact. If there's a large peer churn and few peers, then new
+	// measurements will impact it more. The confidence is increased with every
+	// packet and dropped with every new connection.
+	confidence float64
+
+	// tuned is the time instance the tracker recalculated its cached roundtrip
+	// value and confidence values. A cleaner way would be to have a heartbeat
+	// goroutine do it regularly, but that requires a lot of maintenance to just
+	// run every now and again.
+	tuned time.Time
+
+	// The fields below can be used to override certain default values. Their
+	// purpose is to allow quicker tests. Don't use them in production.
+	OverrideTTLLimit time.Duration
+
+	log  log.Logger
+	lock sync.RWMutex
+}
+
+// NewTrackers creates an empty set of trackers to be filled with peers.
+func NewTrackers(log log.Logger) *Trackers {
+	return &Trackers{
+		trackers:         make(map[string]*Tracker),
+		roundtrip:        rttMaxEstimate,
+		confidence:       1,
+		tuned:            time.Now(),
+		OverrideTTLLimit: ttlLimit,
+		log:              log,
+	}
+}
+
+// Track inserts a new tracker into the set.
+func (t *Trackers) Track(id string, tracker *Tracker) error {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if _, ok := t.trackers[id]; ok {
+		return errors.New("already tracking")
+	}
+	t.trackers[id] = tracker
+	t.detune()
+
+	return nil
+}
+
+// Untrack stops tracking a previously added peer.
+func (t *Trackers) Untrack(id string) error {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if _, ok := t.trackers[id]; !ok {
+		return errors.New("not tracking")
+	}
+	delete(t.trackers, id)
+	return nil
+}
+
+// MedianRoundTrip returns the median RTT across all known trackers. The purpose
+// of the median RTT is to initialize a new peer with sane statistics that it will
+// hopefully outperform. If it seriously underperforms, there's a risk of dropping
+// the peer, but that is ok as we're aiming for a strong median.
+func (t *Trackers) MedianRoundTrip() time.Duration {
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	return t.medianRoundTrip()
+}
+
+// medianRoundTrip is the internal lockless version of MedianRoundTrip to be used
+// by the QoS tuner.
+func (t *Trackers) medianRoundTrip() time.Duration {
+	// Gather all the currently measured round trip times
+	rtts := make([]float64, 0, len(t.trackers))
+	for _, tt := range t.trackers {
+		tt.lock.RLock()
+		rtts = append(rtts, float64(tt.roundtrip))
+		tt.lock.RUnlock()
+	}
+	sort.Float64s(rtts)
+
+	median := rttMaxEstimate
+	if qosTuningPeers <= len(rtts) {
+		median = time.Duration(rtts[qosTuningPeers/2]) // Median of our best few peers
+	} else if len(rtts) > 0 {
+		median = time.Duration(rtts[len(rtts)/2]) // Median of all out connected peers
+	}
+	// Restrict the RTT into some QoS defaults, irrelevant of true RTT
+	if median < rttMinEstimate {
+		median = rttMinEstimate
+	}
+	if median > rttMaxEstimate {
+		median = rttMaxEstimate
+	}
+	return median
+}
+
+// MeanCapacities returns the capacities averaged across all the added trackers.
+// The purpos of the mean capacities are to initialize a new peer with some sane
+// starting values that it will hopefully outperform. If the mean overshoots, the
+// peer will be cut back to minimal capacity and given another chance.
+func (t *Trackers) MeanCapacities() map[uint64]float64 {
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	return t.meanCapacities()
+}
+
+// meanCapacities is the internal lockless version of MeanCapacities used for
+// debug logging.
+func (t *Trackers) meanCapacities() map[uint64]float64 {
+	capacities := make(map[uint64]float64)
+	for _, tt := range t.trackers {
+		tt.lock.RLock()
+		for key, val := range tt.capacity {
+			capacities[key] += val
+		}
+		tt.lock.RUnlock()
+	}
+	for key, val := range capacities {
+		capacities[key] = val / float64(len(t.trackers))
+	}
+	return capacities
+}
+
+// TargetRoundTrip returns the current target round trip time for a request to
+// complete in.The returned RTT is slightly under the estimated RTT. The reason
+// is that message rate estimation is a 2 dimensional problem which is solvable
+// for any RTT. The goal is to gravitate towards smaller RTTs instead of large
+// messages, to result in a stabler download stream.
+func (t *Trackers) TargetRoundTrip() time.Duration {
+	// Recalculate the internal caches if it's been a while
+	t.tune()
+
+	// Caches surely recent, return target roundtrip
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	return time.Duration(float64(t.roundtrip) * rttPushdownFactor)
+}
+
+// TargetTimeout returns the timeout allowance for a single request to finish
+// under. The timeout is proportional to the roundtrip, but also takes into
+// consideration the tracker's confidence in said roundtrip and scales it
+// accordingly. The final value is capped to avoid runaway requests.
+func (t *Trackers) TargetTimeout() time.Duration {
+	// Recalculate the internal caches if it's been a while
+	t.tune()
+
+	// Caches surely recent, return target timeout
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	return t.targetTimeout()
+}
+
+// targetTimeout is the internal lockless version of TargetTimeout to be used
+// during QoS tuning.
+func (t *Trackers) targetTimeout() time.Duration {
+	timeout := time.Duration(ttlScaling * float64(t.roundtrip) / t.confidence)
+	if timeout > t.OverrideTTLLimit {
+		timeout = t.OverrideTTLLimit
+	}
+	return timeout
+}
+
+// tune gathers the individual tracker statistics and updates the estimated
+// request round trip time.
+func (t *Trackers) tune() {
+	// Tune may be called concurrently all over the place, but we only want to
+	// periodically update and even then only once. First check if it was updated
+	// recently and abort if so.
+	t.lock.RLock()
+	dirty := time.Since(t.tuned) > t.roundtrip
+	t.lock.RUnlock()
+	if !dirty {
+		return
+	}
+	// If an update is needed, obtain a write lock but make sure we don't update
+	// it on all concurrent threads one by one.
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if dirty := time.Since(t.tuned) > t.roundtrip; !dirty {
+		return // A concurrent request beat us to the tuning
+	}
+	// First thread reaching the tuning point, update the estimates and return
+	t.roundtrip = time.Duration((1-tuningImpact)*float64(t.roundtrip) + tuningImpact*float64(t.medianRoundTrip()))
+	t.confidence = t.confidence + (1-t.confidence)/2
+
+	t.tuned = time.Now()
+	t.log.Debug("Recalculated msgrate QoS values", "rtt", t.roundtrip, "confidence", t.confidence, "ttl", t.targetTimeout(), "next", t.tuned.Add(t.roundtrip))
+	t.log.Trace("Debug dump of mean capacities", "caps", log.Lazy{Fn: t.meanCapacities})
+}
+
+// detune reduces the tracker's confidence in order to make fresh measurements
+// have a larger impact on the estimates. It is meant to be used during new peer
+// connections so they can have a proper impact on the estimates.
+func (t *Trackers) detune() {
+	// If we have a single peer, confidence is always 1
+	if len(t.trackers) == 1 {
+		t.confidence = 1
+		return
+	}
+	// If we have a ton of peers, don't drop the confidence since there's enough
+	// remaining to retain the same throughput
+	if len(t.trackers) >= tuningConfidenceCap {
+		return
+	}
+	// Otherwise drop the confidence factor
+	peers := float64(len(t.trackers))
+
+	t.confidence = t.confidence * (peers - 1) / peers
+	if t.confidence < rttMinConfidence {
+		t.confidence = rttMinConfidence
+	}
+	t.log.Debug("Relaxed msgrate QoS values", "rtt", t.roundtrip, "confidence", t.confidence, "ttl", t.targetTimeout())
+}
+
+// Capacity is a helper function to access a specific tracker without having to
+// track it explicitly outside.
+func (t *Trackers) Capacity(id string, kind uint64, targetRTT time.Duration) int {
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	tracker := t.trackers[id]
+	if tracker == nil {
+		return 1 // Unregister race, don't return 0, it's a dangerous number
+	}
+	return tracker.Capacity(kind, targetRTT)
+}
+
+// Update is a helper function to access a specific tracker without having to
+// track it explicitly outside.
+func (t *Trackers) Update(id string, kind uint64, elapsed time.Duration, items int) {
+	t.lock.RLock()
+	defer t.lock.RUnlock()
+
+	if tracker := t.trackers[id]; tracker != nil {
+		tracker.Update(kind, elapsed, items)
+	}
+}
diff --git a/p2p/msgrate/msgrate_test.go b/p2p/msgrate/msgrate_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a5c8dd0518ca261e094093cf6c7bafdb27cbb233
--- /dev/null
+++ b/p2p/msgrate/msgrate_test.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package msgrate
+
+import "testing"
+
+func TestCapacityOverflow(t *testing.T) {
+	tracker := NewTracker(nil, 1)
+	tracker.Update(1, 1, 100000)
+	cap := tracker.Capacity(1, 10000000)
+	if int32(cap) < 0 {
+		t.Fatalf("Negative: %v", int32(cap))
+	}
+}
diff --git a/p2p/nat/natupnp_test.go b/p2p/nat/natupnp_test.go
index 79f6d25ae87f457d27ae32468b8da5a7a73c2a13..17483a70367ca6e60a27055d46545384161ecb39 100644
--- a/p2p/nat/natupnp_test.go
+++ b/p2p/nat/natupnp_test.go
@@ -21,6 +21,7 @@ import (
 	"io"
 	"net"
 	"net/http"
+	"os"
 	"runtime"
 	"strings"
 	"testing"
@@ -162,7 +163,11 @@ func TestUPNP_DDWRT(t *testing.T) {
 	// Attempt to discover the fake device.
 	discovered := discoverUPnP()
 	if discovered == nil {
-		t.Fatalf("not discovered")
+		if os.Getenv("CI") != "" {
+			t.Fatalf("not discovered")
+		} else {
+			t.Skipf("UPnP not discovered (known issue, see https://github.com/ethereum/go-ethereum/issues/21476)")
+		}
 	}
 	upnp, _ := discovered.(*upnp)
 	if upnp.service != "IGDv1-IP1" {
diff --git a/p2p/peer.go b/p2p/peer.go
index 8ebc858392b50263f3a4003ba7d1062f5992a50a..b6d0dbd1aebd3def807c2e403cdd54259ddd041d 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -115,7 +115,8 @@ type Peer struct {
 	disc     chan DiscReason
 
 	// events receives message send / receive events if set
-	events *event.Feed
+	events   *event.Feed
+	testPipe *MsgPipeRW // for testing
 }
 
 // NewPeer returns a peer for testing purposes.
@@ -128,6 +129,15 @@ func NewPeer(id enode.ID, name string, caps []Cap) *Peer {
 	return peer
 }
 
+// NewPeerPipe creates a peer for testing purposes.
+// The message pipe given as the last parameter is closed when
+// Disconnect is called on the peer.
+func NewPeerPipe(id enode.ID, name string, caps []Cap, pipe *MsgPipeRW) *Peer {
+	p := NewPeer(id, name, caps)
+	p.testPipe = pipe
+	return p
+}
+
 // ID returns the node's public key.
 func (p *Peer) ID() enode.ID {
 	return p.rw.node.ID()
@@ -185,6 +195,10 @@ func (p *Peer) LocalAddr() net.Addr {
 // Disconnect terminates the peer connection with the given reason.
 // It returns immediately and does not wait until the connection is closed.
 func (p *Peer) Disconnect(reason DiscReason) {
+	if p.testPipe != nil {
+		p.testPipe.Close()
+	}
+
 	select {
 	case p.disc <- reason:
 	case <-p.closed:
diff --git a/p2p/peer_error.go b/p2p/peer_error.go
index ab61bfef062d5be26fd48f90285a207ecbbef558..393cc86b0970909fd8312eb229bc1b6b318f66da 100644
--- a/p2p/peer_error.go
+++ b/p2p/peer_error.go
@@ -89,7 +89,7 @@ var discReasonToString = [...]string{
 }
 
 func (d DiscReason) String() string {
-	if len(discReasonToString) < int(d) {
+	if len(discReasonToString) <= int(d) {
 		return fmt.Sprintf("unknown disconnect reason %d", d)
 	}
 	return discReasonToString[d]
diff --git a/p2p/rlpx/buffer.go b/p2p/rlpx/buffer.go
new file mode 100644
index 0000000000000000000000000000000000000000..bb38e10577ef71a542466e3e10231b8dd1f2232a
--- /dev/null
+++ b/p2p/rlpx/buffer.go
@@ -0,0 +1,127 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package rlpx
+
+import (
+	"io"
+)
+
+// readBuffer implements buffering for network reads. This type is similar to bufio.Reader,
+// with two crucial differences: the buffer slice is exposed, and the buffer keeps all
+// read data available until reset.
+//
+// How to use this type:
+//
+// Keep a readBuffer b alongside the underlying network connection. When reading a packet
+// from the connection, first call b.reset(). This empties b.data. Now perform reads
+// through b.read() until the end of the packet is reached. The complete packet data is
+// now available in b.data.
+type readBuffer struct {
+	data []byte
+	end  int
+}
+
+// reset removes all processed data which was read since the last call to reset.
+// After reset, len(b.data) is zero.
+func (b *readBuffer) reset() {
+	unprocessed := b.end - len(b.data)
+	copy(b.data[:unprocessed], b.data[len(b.data):b.end])
+	b.end = unprocessed
+	b.data = b.data[:0]
+}
+
+// read reads at least n bytes from r, returning the bytes.
+// The returned slice is valid until the next call to reset.
+func (b *readBuffer) read(r io.Reader, n int) ([]byte, error) {
+	offset := len(b.data)
+	have := b.end - len(b.data)
+
+	// If n bytes are available in the buffer, there is no need to read from r at all.
+	if have >= n {
+		b.data = b.data[:offset+n]
+		return b.data[offset : offset+n], nil
+	}
+
+	// Make buffer space available.
+	need := n - have
+	b.grow(need)
+
+	// Read.
+	rn, err := io.ReadAtLeast(r, b.data[b.end:cap(b.data)], need)
+	if err != nil {
+		return nil, err
+	}
+	b.end += rn
+	b.data = b.data[:offset+n]
+	return b.data[offset : offset+n], nil
+}
+
+// grow ensures the buffer has at least n bytes of unused space.
+func (b *readBuffer) grow(n int) {
+	if cap(b.data)-b.end >= n {
+		return
+	}
+	need := n - (cap(b.data) - b.end)
+	offset := len(b.data)
+	b.data = append(b.data[:cap(b.data)], make([]byte, need)...)
+	b.data = b.data[:offset]
+}
+
+// writeBuffer implements buffering for network writes. This is essentially
+// a convenience wrapper around a byte slice.
+type writeBuffer struct {
+	data []byte
+}
+
+func (b *writeBuffer) reset() {
+	b.data = b.data[:0]
+}
+
+func (b *writeBuffer) appendZero(n int) []byte {
+	offset := len(b.data)
+	b.data = append(b.data, make([]byte, n)...)
+	return b.data[offset : offset+n]
+}
+
+func (b *writeBuffer) Write(data []byte) (int, error) {
+	b.data = append(b.data, data...)
+	return len(data), nil
+}
+
+const maxUint24 = int(^uint32(0) >> 8)
+
+func readUint24(b []byte) uint32 {
+	return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16
+}
+
+func putUint24(v uint32, b []byte) {
+	b[0] = byte(v >> 16)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v)
+}
+
+// growslice ensures b has the wanted length by either expanding it to its capacity
+// or allocating a new slice if b has insufficient capacity.
+func growslice(b []byte, wantLength int) []byte {
+	if len(b) >= wantLength {
+		return b
+	}
+	if cap(b) >= wantLength {
+		return b[:cap(b)]
+	}
+	return make([]byte, wantLength)
+}
diff --git a/p2p/rlpx/buffer_test.go b/p2p/rlpx/buffer_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9fee4172bd09b5e309be549ee00926541821920b
--- /dev/null
+++ b/p2p/rlpx/buffer_test.go
@@ -0,0 +1,51 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package rlpx
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common/hexutil"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestReadBufferReset(t *testing.T) {
+	reader := bytes.NewReader(hexutil.MustDecode("0x010202030303040505"))
+	var b readBuffer
+
+	s1, _ := b.read(reader, 1)
+	s2, _ := b.read(reader, 2)
+	s3, _ := b.read(reader, 3)
+
+	assert.Equal(t, []byte{1}, s1)
+	assert.Equal(t, []byte{2, 2}, s2)
+	assert.Equal(t, []byte{3, 3, 3}, s3)
+
+	b.reset()
+
+	s4, _ := b.read(reader, 1)
+	s5, _ := b.read(reader, 2)
+
+	assert.Equal(t, []byte{4}, s4)
+	assert.Equal(t, []byte{5, 5}, s5)
+
+	s6, err := b.read(reader, 2)
+
+	assert.EqualError(t, err, "EOF")
+	assert.Nil(t, s6)
+}
diff --git a/p2p/rlpx/rlpx.go b/p2p/rlpx/rlpx.go
index 2021bf08be11cc62692cca07327b865b03df4a82..326c7c494138e4142bf790445a9b8937e0c90df0 100644
--- a/p2p/rlpx/rlpx.go
+++ b/p2p/rlpx/rlpx.go
@@ -48,19 +48,45 @@ import (
 // This type is not generally safe for concurrent use, but reading and writing of messages
 // may happen concurrently after the handshake.
 type Conn struct {
-	dialDest  *ecdsa.PublicKey
-	conn      net.Conn
-	handshake *handshakeState
-	snappy    bool
+	dialDest *ecdsa.PublicKey
+	conn     net.Conn
+	session  *sessionState
+
+	// These are the buffers for snappy compression.
+	// Compression is enabled if they are non-nil.
+	snappyReadBuffer  []byte
+	snappyWriteBuffer []byte
 }
 
-type handshakeState struct {
+// sessionState contains the session keys.
+type sessionState struct {
 	enc cipher.Stream
 	dec cipher.Stream
 
-	macCipher  cipher.Block
-	egressMAC  hash.Hash
-	ingressMAC hash.Hash
+	egressMAC  hashMAC
+	ingressMAC hashMAC
+	rbuf       readBuffer
+	wbuf       writeBuffer
+}
+
+// hashMAC holds the state of the RLPx v4 MAC contraption.
+type hashMAC struct {
+	cipher     cipher.Block
+	hash       hash.Hash
+	aesBuffer  [16]byte
+	hashBuffer [32]byte
+	seedBuffer [32]byte
+}
+
+func newHashMAC(cipher cipher.Block, h hash.Hash) hashMAC {
+	m := hashMAC{cipher: cipher, hash: h}
+	if cipher.BlockSize() != len(m.aesBuffer) {
+		panic(fmt.Errorf("invalid MAC cipher block size %d", cipher.BlockSize()))
+	}
+	if h.Size() != len(m.hashBuffer) {
+		panic(fmt.Errorf("invalid MAC digest size %d", h.Size()))
+	}
+	return m
 }
 
 // NewConn wraps the given network connection. If dialDest is non-nil, the connection
@@ -76,7 +102,13 @@ func NewConn(conn net.Conn, dialDest *ecdsa.PublicKey) *Conn {
 // after the devp2p Hello message exchange when the negotiated version indicates that
 // compression is available on both ends of the connection.
 func (c *Conn) SetSnappy(snappy bool) {
-	c.snappy = snappy
+	if snappy {
+		c.snappyReadBuffer = []byte{}
+		c.snappyWriteBuffer = []byte{}
+	} else {
+		c.snappyReadBuffer = nil
+		c.snappyWriteBuffer = nil
+	}
 }
 
 // SetReadDeadline sets the deadline for all future read operations.
@@ -95,12 +127,13 @@ func (c *Conn) SetDeadline(time time.Time) error {
 }
 
 // Read reads a message from the connection.
+// The returned data buffer is valid until the next call to Read.
 func (c *Conn) Read() (code uint64, data []byte, wireSize int, err error) {
-	if c.handshake == nil {
+	if c.session == nil {
 		panic("can't ReadMsg before handshake")
 	}
 
-	frame, err := c.handshake.readFrame(c.conn)
+	frame, err := c.session.readFrame(c.conn)
 	if err != nil {
 		return 0, nil, 0, err
 	}
@@ -111,7 +144,7 @@ func (c *Conn) Read() (code uint64, data []byte, wireSize int, err error) {
 	wireSize = len(data)
 
 	// If snappy is enabled, verify and decompress message.
-	if c.snappy {
+	if c.snappyReadBuffer != nil {
 		var actualSize int
 		actualSize, err = snappy.DecodedLen(data)
 		if err != nil {
@@ -120,51 +153,55 @@ func (c *Conn) Read() (code uint64, data []byte, wireSize int, err error) {
 		if actualSize > maxUint24 {
 			return code, nil, 0, errPlainMessageTooLarge
 		}
-		data, err = snappy.Decode(nil, data)
+		c.snappyReadBuffer = growslice(c.snappyReadBuffer, actualSize)
+		data, err = snappy.Decode(c.snappyReadBuffer, data)
 	}
 	return code, data, wireSize, err
 }
 
-func (h *handshakeState) readFrame(conn io.Reader) ([]byte, error) {
-	// read the header
-	headbuf := make([]byte, 32)
-	if _, err := io.ReadFull(conn, headbuf); err != nil {
+func (h *sessionState) readFrame(conn io.Reader) ([]byte, error) {
+	h.rbuf.reset()
+
+	// Read the frame header.
+	header, err := h.rbuf.read(conn, 32)
+	if err != nil {
 		return nil, err
 	}
 
-	// verify header mac
-	shouldMAC := updateMAC(h.ingressMAC, h.macCipher, headbuf[:16])
-	if !hmac.Equal(shouldMAC, headbuf[16:]) {
+	// Verify header MAC.
+	wantHeaderMAC := h.ingressMAC.computeHeader(header[:16])
+	if !hmac.Equal(wantHeaderMAC, header[16:]) {
 		return nil, errors.New("bad header MAC")
 	}
-	h.dec.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now decrypted
-	fsize := readInt24(headbuf)
-	// ignore protocol type for now
 
-	// read the frame content
-	var rsize = fsize // frame size rounded up to 16 byte boundary
+	// Decrypt the frame header to get the frame size.
+	h.dec.XORKeyStream(header[:16], header[:16])
+	fsize := readUint24(header[:16])
+	// Frame size rounded up to 16 byte boundary for padding.
+	rsize := fsize
 	if padding := fsize % 16; padding > 0 {
 		rsize += 16 - padding
 	}
-	framebuf := make([]byte, rsize)
-	if _, err := io.ReadFull(conn, framebuf); err != nil {
+
+	// Read the frame content.
+	frame, err := h.rbuf.read(conn, int(rsize))
+	if err != nil {
 		return nil, err
 	}
 
-	// read and validate frame MAC. we can re-use headbuf for that.
-	h.ingressMAC.Write(framebuf)
-	fmacseed := h.ingressMAC.Sum(nil)
-	if _, err := io.ReadFull(conn, headbuf[:16]); err != nil {
+	// Validate frame MAC.
+	frameMAC, err := h.rbuf.read(conn, 16)
+	if err != nil {
 		return nil, err
 	}
-	shouldMAC = updateMAC(h.ingressMAC, h.macCipher, fmacseed)
-	if !hmac.Equal(shouldMAC, headbuf[:16]) {
+	wantFrameMAC := h.ingressMAC.computeFrame(frame)
+	if !hmac.Equal(wantFrameMAC, frameMAC) {
 		return nil, errors.New("bad frame MAC")
 	}
 
-	// decrypt frame content
-	h.dec.XORKeyStream(framebuf, framebuf)
-	return framebuf[:fsize], nil
+	// Decrypt the frame data.
+	h.dec.XORKeyStream(frame, frame)
+	return frame[:fsize], nil
 }
 
 // Write writes a message to the connection.
@@ -172,83 +209,90 @@ func (h *handshakeState) readFrame(conn io.Reader) ([]byte, error) {
 // Write returns the written size of the message data. This may be less than or equal to
 // len(data) depending on whether snappy compression is enabled.
 func (c *Conn) Write(code uint64, data []byte) (uint32, error) {
-	if c.handshake == nil {
+	if c.session == nil {
 		panic("can't WriteMsg before handshake")
 	}
 	if len(data) > maxUint24 {
 		return 0, errPlainMessageTooLarge
 	}
-	if c.snappy {
-		data = snappy.Encode(nil, data)
+	if c.snappyWriteBuffer != nil {
+		// Ensure the buffer has sufficient size.
+		// Package snappy will allocate its own buffer if the provided
+		// one is smaller than MaxEncodedLen.
+		c.snappyWriteBuffer = growslice(c.snappyWriteBuffer, snappy.MaxEncodedLen(len(data)))
+		data = snappy.Encode(c.snappyWriteBuffer, data)
 	}
 
 	wireSize := uint32(len(data))
-	err := c.handshake.writeFrame(c.conn, code, data)
+	err := c.session.writeFrame(c.conn, code, data)
 	return wireSize, err
 }
 
-func (h *handshakeState) writeFrame(conn io.Writer, code uint64, data []byte) error {
-	ptype, _ := rlp.EncodeToBytes(code)
+func (h *sessionState) writeFrame(conn io.Writer, code uint64, data []byte) error {
+	h.wbuf.reset()
 
-	// write header
-	headbuf := make([]byte, 32)
-	fsize := len(ptype) + len(data)
+	// Write header.
+	fsize := rlp.IntSize(code) + len(data)
 	if fsize > maxUint24 {
 		return errPlainMessageTooLarge
 	}
-	putInt24(uint32(fsize), headbuf)
-	copy(headbuf[3:], zeroHeader)
-	h.enc.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now encrypted
+	header := h.wbuf.appendZero(16)
+	putUint24(uint32(fsize), header)
+	copy(header[3:], zeroHeader)
+	h.enc.XORKeyStream(header, header)
 
-	// write header MAC
-	copy(headbuf[16:], updateMAC(h.egressMAC, h.macCipher, headbuf[:16]))
-	if _, err := conn.Write(headbuf); err != nil {
-		return err
-	}
+	// Write header MAC.
+	h.wbuf.Write(h.egressMAC.computeHeader(header))
 
-	// write encrypted frame, updating the egress MAC hash with
-	// the data written to conn.
-	tee := cipher.StreamWriter{S: h.enc, W: io.MultiWriter(conn, h.egressMAC)}
-	if _, err := tee.Write(ptype); err != nil {
-		return err
-	}
-	if _, err := tee.Write(data); err != nil {
-		return err
-	}
+	// Encode and encrypt the frame data.
+	offset := len(h.wbuf.data)
+	h.wbuf.data = rlp.AppendUint64(h.wbuf.data, code)
+	h.wbuf.Write(data)
 	if padding := fsize % 16; padding > 0 {
-		if _, err := tee.Write(zero16[:16-padding]); err != nil {
-			return err
-		}
+		h.wbuf.appendZero(16 - padding)
 	}
+	framedata := h.wbuf.data[offset:]
+	h.enc.XORKeyStream(framedata, framedata)
 
-	// write frame MAC. egress MAC hash is up to date because
-	// frame content was written to it as well.
-	fmacseed := h.egressMAC.Sum(nil)
-	mac := updateMAC(h.egressMAC, h.macCipher, fmacseed)
-	_, err := conn.Write(mac)
+	// Write frame MAC.
+	h.wbuf.Write(h.egressMAC.computeFrame(framedata))
+
+	_, err := conn.Write(h.wbuf.data)
 	return err
 }
 
-func readInt24(b []byte) uint32 {
-	return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16
+// computeHeader computes the MAC of a frame header.
+func (m *hashMAC) computeHeader(header []byte) []byte {
+	sum1 := m.hash.Sum(m.hashBuffer[:0])
+	return m.compute(sum1, header)
 }
 
-func putInt24(v uint32, b []byte) {
-	b[0] = byte(v >> 16)
-	b[1] = byte(v >> 8)
-	b[2] = byte(v)
+// computeFrame computes the MAC of framedata.
+func (m *hashMAC) computeFrame(framedata []byte) []byte {
+	m.hash.Write(framedata)
+	seed := m.hash.Sum(m.seedBuffer[:0])
+	return m.compute(seed, seed[:16])
 }
 
-// updateMAC reseeds the given hash with encrypted seed.
-// it returns the first 16 bytes of the hash sum after seeding.
-func updateMAC(mac hash.Hash, block cipher.Block, seed []byte) []byte {
-	aesbuf := make([]byte, aes.BlockSize)
-	block.Encrypt(aesbuf, mac.Sum(nil))
-	for i := range aesbuf {
-		aesbuf[i] ^= seed[i]
+// compute computes the MAC of a 16-byte 'seed'.
+//
+// To do this, it encrypts the current value of the hash state, then XORs the ciphertext
+// with seed. The obtained value is written back into the hash state and hash output is
+// taken again. The first 16 bytes of the resulting sum are the MAC value.
+//
+// This MAC construction is a horrible, legacy thing.
+func (m *hashMAC) compute(sum1, seed []byte) []byte {
+	if len(seed) != len(m.aesBuffer) {
+		panic("invalid MAC seed")
+	}
+
+	m.cipher.Encrypt(m.aesBuffer[:], sum1)
+	for i := range m.aesBuffer {
+		m.aesBuffer[i] ^= seed[i]
 	}
-	mac.Write(aesbuf)
-	return mac.Sum(nil)[:16]
+	m.hash.Write(m.aesBuffer[:])
+	sum2 := m.hash.Sum(m.hashBuffer[:0])
+	return sum2[:16]
 }
 
 // Handshake performs the handshake. This must be called before any data is written
@@ -257,23 +301,26 @@ func (c *Conn) Handshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey, error) {
 	var (
 		sec Secrets
 		err error
+		h   handshakeState
 	)
 	if c.dialDest != nil {
-		sec, err = initiatorEncHandshake(c.conn, prv, c.dialDest)
+		sec, err = h.runInitiator(c.conn, prv, c.dialDest)
 	} else {
-		sec, err = receiverEncHandshake(c.conn, prv)
+		sec, err = h.runRecipient(c.conn, prv)
 	}
 	if err != nil {
 		return nil, err
 	}
 	c.InitWithSecrets(sec)
+	c.session.rbuf = h.rbuf
+	c.session.wbuf = h.wbuf
 	return sec.remote, err
 }
 
 // InitWithSecrets injects connection secrets as if a handshake had
 // been performed. This cannot be called after the handshake.
 func (c *Conn) InitWithSecrets(sec Secrets) {
-	if c.handshake != nil {
+	if c.session != nil {
 		panic("can't handshake twice")
 	}
 	macc, err := aes.NewCipher(sec.MAC)
@@ -287,12 +334,11 @@ func (c *Conn) InitWithSecrets(sec Secrets) {
 	// we use an all-zeroes IV for AES because the key used
 	// for encryption is ephemeral.
 	iv := make([]byte, encc.BlockSize())
-	c.handshake = &handshakeState{
+	c.session = &sessionState{
 		enc:        cipher.NewCTR(encc, iv),
 		dec:        cipher.NewCTR(encc, iv),
-		macCipher:  macc,
-		egressMAC:  sec.EgressMAC,
-		ingressMAC: sec.IngressMAC,
+		egressMAC:  newHashMAC(macc, sec.EgressMAC),
+		ingressMAC: newHashMAC(macc, sec.IngressMAC),
 	}
 }
 
@@ -303,28 +349,18 @@ func (c *Conn) Close() error {
 
 // Constants for the handshake.
 const (
-	maxUint24 = int(^uint32(0) >> 8)
-
 	sskLen = 16                     // ecies.MaxSharedKeyLength(pubKey) / 2
 	sigLen = crypto.SignatureLength // elliptic S256
 	pubLen = 64                     // 512 bit pubkey in uncompressed representation without format byte
 	shaLen = 32                     // hash length (for nonce etc)
 
-	authMsgLen  = sigLen + shaLen + pubLen + shaLen + 1
-	authRespLen = pubLen + shaLen + 1
-
 	eciesOverhead = 65 /* pubkey */ + 16 /* IV */ + 32 /* MAC */
-
-	encAuthMsgLen  = authMsgLen + eciesOverhead  // size of encrypted pre-EIP-8 initiator handshake
-	encAuthRespLen = authRespLen + eciesOverhead // size of encrypted pre-EIP-8 handshake reply
 )
 
 var (
 	// this is used in place of actual frame header data.
 	// TODO: replace this when Msg contains the protocol type code.
 	zeroHeader = []byte{0xC2, 0x80, 0x80}
-	// sixteen zero bytes
-	zero16 = make([]byte, 16)
 
 	// errPlainMessageTooLarge is returned if a decompressed message length exceeds
 	// the allowed 24 bits (i.e. length >= 16MB).
@@ -338,19 +374,20 @@ type Secrets struct {
 	remote                *ecdsa.PublicKey
 }
 
-// encHandshake contains the state of the encryption handshake.
-type encHandshake struct {
+// handshakeState contains the state of the encryption handshake.
+type handshakeState struct {
 	initiator            bool
 	remote               *ecies.PublicKey  // remote-pubk
 	initNonce, respNonce []byte            // nonce
 	randomPrivKey        *ecies.PrivateKey // ecdhe-random
 	remoteRandomPub      *ecies.PublicKey  // ecdhe-random-pubk
+
+	rbuf readBuffer
+	wbuf writeBuffer
 }
 
 // RLPx v4 handshake auth (defined in EIP-8).
 type authMsgV4 struct {
-	gotPlain bool // whether read packet had plain format.
-
 	Signature       [sigLen]byte
 	InitiatorPubkey [pubLen]byte
 	Nonce           [shaLen]byte
@@ -370,17 +407,16 @@ type authRespV4 struct {
 	Rest []rlp.RawValue `rlp:"tail"`
 }
 
-// receiverEncHandshake negotiates a session token on conn.
+// runRecipient negotiates a session token on conn.
 // it should be called on the listening side of the connection.
 //
 // prv is the local client's private key.
-func receiverEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s Secrets, err error) {
+func (h *handshakeState) runRecipient(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s Secrets, err error) {
 	authMsg := new(authMsgV4)
-	authPacket, err := readHandshakeMsg(authMsg, encAuthMsgLen, prv, conn)
+	authPacket, err := h.readMsg(authMsg, prv, conn)
 	if err != nil {
 		return s, err
 	}
-	h := new(encHandshake)
 	if err := h.handleAuthMsg(authMsg, prv); err != nil {
 		return s, err
 	}
@@ -389,22 +425,18 @@ func receiverEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s Secrets,
 	if err != nil {
 		return s, err
 	}
-	var authRespPacket []byte
-	if authMsg.gotPlain {
-		authRespPacket, err = authRespMsg.sealPlain(h)
-	} else {
-		authRespPacket, err = sealEIP8(authRespMsg, h)
-	}
+	authRespPacket, err := h.sealEIP8(authRespMsg)
 	if err != nil {
 		return s, err
 	}
 	if _, err = conn.Write(authRespPacket); err != nil {
 		return s, err
 	}
+
 	return h.secrets(authPacket, authRespPacket)
 }
 
-func (h *encHandshake) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) error {
+func (h *handshakeState) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) error {
 	// Import the remote identity.
 	rpub, err := importPublicKey(msg.InitiatorPubkey[:])
 	if err != nil {
@@ -438,7 +470,7 @@ func (h *encHandshake) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) erro
 
 // secrets is called after the handshake is completed.
 // It extracts the connection secrets from the handshake values.
-func (h *encHandshake) secrets(auth, authResp []byte) (Secrets, error) {
+func (h *handshakeState) secrets(auth, authResp []byte) (Secrets, error) {
 	ecdheSecret, err := h.randomPrivKey.GenerateShared(h.remoteRandomPub, sskLen, sskLen)
 	if err != nil {
 		return Secrets{}, err
@@ -471,21 +503,23 @@ func (h *encHandshake) secrets(auth, authResp []byte) (Secrets, error) {
 
 // staticSharedSecret returns the static shared secret, the result
 // of key agreement between the local and remote static node key.
-func (h *encHandshake) staticSharedSecret(prv *ecdsa.PrivateKey) ([]byte, error) {
+func (h *handshakeState) staticSharedSecret(prv *ecdsa.PrivateKey) ([]byte, error) {
 	return ecies.ImportECDSA(prv).GenerateShared(h.remote, sskLen, sskLen)
 }
 
-// initiatorEncHandshake negotiates a session token on conn.
+// runInitiator negotiates a session token on conn.
 // it should be called on the dialing side of the connection.
 //
 // prv is the local client's private key.
-func initiatorEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s Secrets, err error) {
-	h := &encHandshake{initiator: true, remote: ecies.ImportECDSAPublic(remote)}
+func (h *handshakeState) runInitiator(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s Secrets, err error) {
+	h.initiator = true
+	h.remote = ecies.ImportECDSAPublic(remote)
+
 	authMsg, err := h.makeAuthMsg(prv)
 	if err != nil {
 		return s, err
 	}
-	authPacket, err := sealEIP8(authMsg, h)
+	authPacket, err := h.sealEIP8(authMsg)
 	if err != nil {
 		return s, err
 	}
@@ -495,18 +529,19 @@ func initiatorEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ec
 	}
 
 	authRespMsg := new(authRespV4)
-	authRespPacket, err := readHandshakeMsg(authRespMsg, encAuthRespLen, prv, conn)
+	authRespPacket, err := h.readMsg(authRespMsg, prv, conn)
 	if err != nil {
 		return s, err
 	}
 	if err := h.handleAuthResp(authRespMsg); err != nil {
 		return s, err
 	}
+
 	return h.secrets(authPacket, authRespPacket)
 }
 
 // makeAuthMsg creates the initiator handshake message.
-func (h *encHandshake) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) {
+func (h *handshakeState) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) {
 	// Generate random initiator nonce.
 	h.initNonce = make([]byte, shaLen)
 	_, err := rand.Read(h.initNonce)
@@ -538,13 +573,13 @@ func (h *encHandshake) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) {
 	return msg, nil
 }
 
-func (h *encHandshake) handleAuthResp(msg *authRespV4) (err error) {
+func (h *handshakeState) handleAuthResp(msg *authRespV4) (err error) {
 	h.respNonce = msg.Nonce[:]
 	h.remoteRandomPub, err = importPublicKey(msg.RandomPubkey[:])
 	return err
 }
 
-func (h *encHandshake) makeAuthResp() (msg *authRespV4, err error) {
+func (h *handshakeState) makeAuthResp() (msg *authRespV4, err error) {
 	// Generate random nonce.
 	h.respNonce = make([]byte, shaLen)
 	if _, err = rand.Read(h.respNonce); err != nil {
@@ -558,81 +593,53 @@ func (h *encHandshake) makeAuthResp() (msg *authRespV4, err error) {
 	return msg, nil
 }
 
-func (msg *authMsgV4) decodePlain(input []byte) {
-	n := copy(msg.Signature[:], input)
-	n += shaLen // skip sha3(initiator-ephemeral-pubk)
-	n += copy(msg.InitiatorPubkey[:], input[n:])
-	copy(msg.Nonce[:], input[n:])
-	msg.Version = 4
-	msg.gotPlain = true
-}
+// readMsg reads an encrypted handshake message, decoding it into msg.
+func (h *handshakeState) readMsg(msg interface{}, prv *ecdsa.PrivateKey, r io.Reader) ([]byte, error) {
+	h.rbuf.reset()
+	h.rbuf.grow(512)
 
-func (msg *authRespV4) sealPlain(hs *encHandshake) ([]byte, error) {
-	buf := make([]byte, authRespLen)
-	n := copy(buf, msg.RandomPubkey[:])
-	copy(buf[n:], msg.Nonce[:])
-	return ecies.Encrypt(rand.Reader, hs.remote, buf, nil, nil)
-}
+	// Read the size prefix.
+	prefix, err := h.rbuf.read(r, 2)
+	if err != nil {
+		return nil, err
+	}
+	size := binary.BigEndian.Uint16(prefix)
 
-func (msg *authRespV4) decodePlain(input []byte) {
-	n := copy(msg.RandomPubkey[:], input)
-	copy(msg.Nonce[:], input[n:])
-	msg.Version = 4
+	// Read the handshake packet.
+	packet, err := h.rbuf.read(r, int(size))
+	if err != nil {
+		return nil, err
+	}
+	dec, err := ecies.ImportECDSA(prv).Decrypt(packet, nil, prefix)
+	if err != nil {
+		return nil, err
+	}
+	// Can't use rlp.DecodeBytes here because it rejects
+	// trailing data (forward-compatibility).
+	s := rlp.NewStream(bytes.NewReader(dec), 0)
+	err = s.Decode(msg)
+	return h.rbuf.data[:len(prefix)+len(packet)], err
 }
 
-var padSpace = make([]byte, 300)
+// sealEIP8 encrypts a handshake message.
+func (h *handshakeState) sealEIP8(msg interface{}) ([]byte, error) {
+	h.wbuf.reset()
 
-func sealEIP8(msg interface{}, h *encHandshake) ([]byte, error) {
-	buf := new(bytes.Buffer)
-	if err := rlp.Encode(buf, msg); err != nil {
+	// Write the message plaintext.
+	if err := rlp.Encode(&h.wbuf, msg); err != nil {
 		return nil, err
 	}
-	// pad with random amount of data. the amount needs to be at least 100 bytes to make
+	// Pad with random amount of data. the amount needs to be at least 100 bytes to make
 	// the message distinguishable from pre-EIP-8 handshakes.
-	pad := padSpace[:mrand.Intn(len(padSpace)-100)+100]
-	buf.Write(pad)
+	h.wbuf.appendZero(mrand.Intn(100) + 100)
+
 	prefix := make([]byte, 2)
-	binary.BigEndian.PutUint16(prefix, uint16(buf.Len()+eciesOverhead))
+	binary.BigEndian.PutUint16(prefix, uint16(len(h.wbuf.data)+eciesOverhead))
 
-	enc, err := ecies.Encrypt(rand.Reader, h.remote, buf.Bytes(), nil, prefix)
+	enc, err := ecies.Encrypt(rand.Reader, h.remote, h.wbuf.data, nil, prefix)
 	return append(prefix, enc...), err
 }
 
-type plainDecoder interface {
-	decodePlain([]byte)
-}
-
-func readHandshakeMsg(msg plainDecoder, plainSize int, prv *ecdsa.PrivateKey, r io.Reader) ([]byte, error) {
-	buf := make([]byte, plainSize)
-	if _, err := io.ReadFull(r, buf); err != nil {
-		return buf, err
-	}
-	// Attempt decoding pre-EIP-8 "plain" format.
-	key := ecies.ImportECDSA(prv)
-	if dec, err := key.Decrypt(buf, nil, nil); err == nil {
-		msg.decodePlain(dec)
-		return buf, nil
-	}
-	// Could be EIP-8 format, try that.
-	prefix := buf[:2]
-	size := binary.BigEndian.Uint16(prefix)
-	if size < uint16(plainSize) {
-		return buf, fmt.Errorf("size underflow, need at least %d bytes", plainSize)
-	}
-	buf = append(buf, make([]byte, size-uint16(plainSize)+2)...)
-	if _, err := io.ReadFull(r, buf[plainSize:]); err != nil {
-		return buf, err
-	}
-	dec, err := key.Decrypt(buf[2:], nil, prefix)
-	if err != nil {
-		return buf, err
-	}
-	// Can't use rlp.DecodeBytes here because it rejects
-	// trailing data (forward-compatibility).
-	s := rlp.NewStream(bytes.NewReader(dec), 0)
-	return buf, s.Decode(msg)
-}
-
 // importPublicKey unmarshals 512 bit public keys.
 func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
 	var pubKey65 []byte
diff --git a/p2p/rlpx/rlpx_test.go b/p2p/rlpx/rlpx_test.go
index 127a0181645494b1ecffcaf181a73cc6629a8756..28759f2b4948d8adcce503ffaeeffcae41f4aa72 100644
--- a/p2p/rlpx/rlpx_test.go
+++ b/p2p/rlpx/rlpx_test.go
@@ -22,6 +22,7 @@ import (
 	"encoding/hex"
 	"fmt"
 	"io"
+	"math/rand"
 	"net"
 	"reflect"
 	"strings"
@@ -30,6 +31,7 @@ import (
 	"github.com/davecgh/go-spew/spew"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/crypto/ecies"
+	"github.com/ethereum/go-ethereum/p2p/simulations/pipes"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/stretchr/testify/assert"
 )
@@ -124,7 +126,7 @@ func TestFrameReadWrite(t *testing.T) {
 		IngressMAC: hash,
 		EgressMAC:  hash,
 	})
-	h := conn.handshake
+	h := conn.session
 
 	golden := unhex(`
 		00828ddae471818bb0bfa6b551d1cb42
@@ -166,27 +168,11 @@ func (h fakeHash) Sum(b []byte) []byte       { return append(b, h...) }
 
 type handshakeAuthTest struct {
 	input       string
-	isPlain     bool
 	wantVersion uint
 	wantRest    []rlp.RawValue
 }
 
 var eip8HandshakeAuthTests = []handshakeAuthTest{
-	// (Auth₁) RLPx v4 plain encoding
-	{
-		input: `
-			048ca79ad18e4b0659fab4853fe5bc58eb83992980f4c9cc147d2aa31532efd29a3d3dc6a3d89eaf
-			913150cfc777ce0ce4af2758bf4810235f6e6ceccfee1acc6b22c005e9e3a49d6448610a58e98744
-			ba3ac0399e82692d67c1f58849050b3024e21a52c9d3b01d871ff5f210817912773e610443a9ef14
-			2e91cdba0bd77b5fdf0769b05671fc35f83d83e4d3b0b000c6b2a1b1bba89e0fc51bf4e460df3105
-			c444f14be226458940d6061c296350937ffd5e3acaceeaaefd3c6f74be8e23e0f45163cc7ebd7622
-			0f0128410fd05250273156d548a414444ae2f7dea4dfca2d43c057adb701a715bf59f6fb66b2d1d2
-			0f2c703f851cbf5ac47396d9ca65b6260bd141ac4d53e2de585a73d1750780db4c9ee4cd4d225173
-			a4592ee77e2bd94d0be3691f3b406f9bba9b591fc63facc016bfa8
-		`,
-		isPlain:     true,
-		wantVersion: 4,
-	},
 	// (Auth₂) EIP-8 encoding
 	{
 		input: `
@@ -233,18 +219,6 @@ type handshakeAckTest struct {
 }
 
 var eip8HandshakeRespTests = []handshakeAckTest{
-	// (Ack₁) RLPx v4 plain encoding
-	{
-		input: `
-			049f8abcfa9c0dc65b982e98af921bc0ba6e4243169348a236abe9df5f93aa69d99cadddaa387662
-			b0ff2c08e9006d5a11a278b1b3331e5aaabf0a32f01281b6f4ede0e09a2d5f585b26513cb794d963
-			5a57563921c04a9090b4f14ee42be1a5461049af4ea7a7f49bf4c97a352d39c8d02ee4acc416388c
-			1c66cec761d2bc1c72da6ba143477f049c9d2dde846c252c111b904f630ac98e51609b3b1f58168d
-			dca6505b7196532e5f85b259a20c45e1979491683fee108e9660edbf38f3add489ae73e3dda2c71b
-			d1497113d5c755e942d1
-		`,
-		wantVersion: 4,
-	},
 	// (Ack₂) EIP-8 encoding
 	{
 		input: `
@@ -287,10 +261,13 @@ var eip8HandshakeRespTests = []handshakeAckTest{
 	},
 }
 
+var (
+	keyA, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
+	keyB, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+)
+
 func TestHandshakeForwardCompatibility(t *testing.T) {
 	var (
-		keyA, _       = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
-		keyB, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		pubA          = crypto.FromECDSAPub(&keyA.PublicKey)[1:]
 		pubB          = crypto.FromECDSAPub(&keyB.PublicKey)[1:]
 		ephA, _       = crypto.HexToECDSA("869d6ecf5211f1cc60418a13b9d870b22959d0c16f02bec714c960dd2298a32d")
@@ -304,7 +281,7 @@ func TestHandshakeForwardCompatibility(t *testing.T) {
 		_             = authSignature
 	)
 	makeAuth := func(test handshakeAuthTest) *authMsgV4 {
-		msg := &authMsgV4{Version: test.wantVersion, Rest: test.wantRest, gotPlain: test.isPlain}
+		msg := &authMsgV4{Version: test.wantVersion, Rest: test.wantRest}
 		copy(msg.Signature[:], authSignature)
 		copy(msg.InitiatorPubkey[:], pubA)
 		copy(msg.Nonce[:], nonceA)
@@ -319,9 +296,10 @@ func TestHandshakeForwardCompatibility(t *testing.T) {
 
 	// check auth msg parsing
 	for _, test := range eip8HandshakeAuthTests {
+		var h handshakeState
 		r := bytes.NewReader(unhex(test.input))
 		msg := new(authMsgV4)
-		ciphertext, err := readHandshakeMsg(msg, encAuthMsgLen, keyB, r)
+		ciphertext, err := h.readMsg(msg, keyB, r)
 		if err != nil {
 			t.Errorf("error for input %x:\n  %v", unhex(test.input), err)
 			continue
@@ -337,10 +315,11 @@ func TestHandshakeForwardCompatibility(t *testing.T) {
 
 	// check auth resp parsing
 	for _, test := range eip8HandshakeRespTests {
+		var h handshakeState
 		input := unhex(test.input)
 		r := bytes.NewReader(input)
 		msg := new(authRespV4)
-		ciphertext, err := readHandshakeMsg(msg, encAuthRespLen, keyA, r)
+		ciphertext, err := h.readMsg(msg, keyA, r)
 		if err != nil {
 			t.Errorf("error for input %x:\n  %v", input, err)
 			continue
@@ -356,14 +335,14 @@ func TestHandshakeForwardCompatibility(t *testing.T) {
 
 	// check derivation for (Auth₂, Ack₂) on recipient side
 	var (
-		hs = &encHandshake{
+		hs = &handshakeState{
 			initiator:     false,
 			respNonce:     nonceB,
 			randomPrivKey: ecies.ImportECDSA(ephB),
 		}
-		authCiphertext     = unhex(eip8HandshakeAuthTests[1].input)
-		authRespCiphertext = unhex(eip8HandshakeRespTests[1].input)
-		authMsg            = makeAuth(eip8HandshakeAuthTests[1])
+		authCiphertext     = unhex(eip8HandshakeAuthTests[0].input)
+		authRespCiphertext = unhex(eip8HandshakeRespTests[0].input)
+		authMsg            = makeAuth(eip8HandshakeAuthTests[0])
 		wantAES            = unhex("80e8632c05fed6fc2a13b0f8d31a3cf645366239170ea067065aba8e28bac487")
 		wantMAC            = unhex("2ea74ec5dae199227dff1af715362700e989d889d7a493cb0639691efb8e5f98")
 		wantFooIngressHash = unhex("0c7ec6340062cc46f5e9f1e3cf86f8c8c403c5a0964f5df0ebd34a75ddc86db5")
@@ -388,6 +367,74 @@ func TestHandshakeForwardCompatibility(t *testing.T) {
 	}
 }
 
+func BenchmarkHandshakeRead(b *testing.B) {
+	var input = unhex(eip8HandshakeAuthTests[0].input)
+
+	for i := 0; i < b.N; i++ {
+		var (
+			h   handshakeState
+			r   = bytes.NewReader(input)
+			msg = new(authMsgV4)
+		)
+		if _, err := h.readMsg(msg, keyB, r); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkThroughput(b *testing.B) {
+	pipe1, pipe2, err := pipes.TCPPipe()
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	var (
+		conn1, conn2  = NewConn(pipe1, nil), NewConn(pipe2, &keyA.PublicKey)
+		handshakeDone = make(chan error, 1)
+		msgdata       = make([]byte, 1024)
+		rand          = rand.New(rand.NewSource(1337))
+	)
+	rand.Read(msgdata)
+
+	// Server side.
+	go func() {
+		defer conn1.Close()
+		// Perform handshake.
+		_, err := conn1.Handshake(keyA)
+		handshakeDone <- err
+		if err != nil {
+			return
+		}
+		conn1.SetSnappy(true)
+		// Keep sending messages until connection closed.
+		for {
+			if _, err := conn1.Write(0, msgdata); err != nil {
+				return
+			}
+		}
+	}()
+
+	// Set up client side.
+	defer conn2.Close()
+	if _, err := conn2.Handshake(keyB); err != nil {
+		b.Fatal("client handshake error:", err)
+	}
+	conn2.SetSnappy(true)
+	if err := <-handshakeDone; err != nil {
+		b.Fatal("server hanshake error:", err)
+	}
+
+	// Read N messages.
+	b.SetBytes(int64(len(msgdata)))
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		_, _, _, err := conn2.Read()
+		if err != nil {
+			b.Fatal("read error:", err)
+		}
+	}
+}
+
 func unhex(str string) []byte {
 	r := strings.NewReplacer("\t", "", " ", "", "\n", "")
 	b, err := hex.DecodeString(r.Replace(str))
diff --git a/p2p/server.go b/p2p/server.go
index f70ebf721645bec34bed1c9a424271fc66de65db..bcfc1bd10bd7c6194d1f6b10df2a8e57769b0c77 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -353,7 +353,7 @@ func (srv *Server) RemovePeer(node *enode.Node) {
 	}
 }
 
-// AddTrustedPeer adds the given node to a reserved whitelist which allows the
+// AddTrustedPeer adds the given node to a reserved trusted list which allows the
 // node to always connect, even if the slot are full.
 func (srv *Server) AddTrustedPeer(node *enode.Node) {
 	select {
@@ -370,7 +370,7 @@ func (srv *Server) RemoveTrustedPeer(node *enode.Node) {
 	}
 }
 
-// SubscribePeers subscribes the given channel to peer events
+// SubscribeEvents subscribes the given channel to peer events
 func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription {
 	return srv.peerFeed.Subscribe(ch)
 }
@@ -903,7 +903,7 @@ func (srv *Server) checkInboundConn(remoteIP net.IP) error {
 	}
 	// Reject connections that do not match NetRestrict.
 	if srv.NetRestrict != nil && !srv.NetRestrict.Contains(remoteIP) {
-		return fmt.Errorf("not whitelisted in NetRestrict")
+		return fmt.Errorf("not in netrestrict list")
 	}
 	// Reject Internet peers that try too often.
 	now := srv.clock.Now()
diff --git a/p2p/simulations/mocker.go b/p2p/simulations/mocker.go
index 8ce777a0103f78ab11e3bf35de9125dcd612b101..fd25e2c918ddbf428799e71d1662ce596455f14c 100644
--- a/p2p/simulations/mocker.go
+++ b/p2p/simulations/mocker.go
@@ -123,20 +123,12 @@ func probabilistic(net *Network, quit chan struct{}, nodeCount int) {
 		randWait := time.Duration(rand.Intn(5000)+1000) * time.Millisecond
 		rand1 := rand.Intn(nodeCount - 1)
 		rand2 := rand.Intn(nodeCount - 1)
-		if rand1 < rand2 {
+		if rand1 <= rand2 {
 			lowid = rand1
 			highid = rand2
 		} else if rand1 > rand2 {
 			highid = rand1
 			lowid = rand2
-		} else {
-			if rand1 == 0 {
-				rand2 = 9
-			} else if rand1 == 9 {
-				rand1 = 0
-			}
-			lowid = rand1
-			highid = rand2
 		}
 		var steps = highid - lowid
 		wg.Add(steps)
diff --git a/p2p/transport.go b/p2p/transport.go
index 3f1cd7d64f20211f4bfb73f29fb0b069002ca74e..d594259866288194c2ad3e04f30468f5c0cfa131 100644
--- a/p2p/transport.go
+++ b/p2p/transport.go
@@ -25,6 +25,7 @@ import (
 	"sync"
 	"time"
 
+	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/bitutil"
 	"github.com/ethereum/go-ethereum/metrics"
 	"github.com/ethereum/go-ethereum/p2p/rlpx"
@@ -62,6 +63,10 @@ func (t *rlpxTransport) ReadMsg() (Msg, error) {
 	t.conn.SetReadDeadline(time.Now().Add(frameReadTimeout))
 	code, data, wireSize, err := t.conn.Read()
 	if err == nil {
+		// Protocol messages are dispatched to subprotocol handlers asynchronously,
+		// but package rlpx may reuse the returned 'data' buffer on the next call
+		// to Read. Copy the message data to avoid this being an issue.
+		data = common.CopyBytes(data)
 		msg = Msg{
 			ReceivedAt: time.Now(),
 			Code:       code,
diff --git a/params/bootnodes.go b/params/bootnodes.go
index f36ad61729c2094282aed3211e3c36ad07a4be48..bc291449e285845a02714063ce42fbfe67f86731 100644
--- a/params/bootnodes.go
+++ b/params/bootnodes.go
@@ -67,13 +67,6 @@ var GoerliBootnodes = []string{
 	"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.15.119.157:40303",
 }
 
-// YoloV3Bootnodes are the enode URLs of the P2P bootstrap nodes running on the
-// YOLOv3 ephemeral test network.
-// TODO: Set Yolov3 bootnodes
-var YoloV3Bootnodes = []string{
-	"enode://9e1096aa59862a6f164994cb5cb16f5124d6c992cdbf4535ff7dea43ea1512afe5448dca9df1b7ab0726129603f1a3336b631e4d7a1a44c94daddd03241587f9@3.9.20.133:30303",
-}
-
 var V5Bootnodes = []string{
 	// Teku team's bootnode
 	"enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA",
diff --git a/params/config.go b/params/config.go
index 3b31d4e8019f05d9c42d2f3fb828ae48bcce68e2..1cacea5d5517053a5d5330123a04b02da4567bfd 100644
--- a/params/config.go
+++ b/params/config.go
@@ -31,7 +31,6 @@ var (
 	RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
 	RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
 	GoerliGenesisHash  = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
-	YoloV3GenesisHash  = common.HexToHash("0xf1f2876e8500c77afcc03228757b39477eceffccf645b734967fe3c7e16967b7")
 )
 
 // TrustedCheckpoints associates each known checkpoint with the genesis hash of
@@ -69,15 +68,16 @@ var (
 		IstanbulBlock:       big.NewInt(9_069_000),
 		MuirGlacierBlock:    big.NewInt(9_200_000),
 		BerlinBlock:         big.NewInt(12_244_000),
+		LondonBlock:         big.NewInt(12_965_000),
 		Ethash:              new(EthashConfig),
 	}
 
 	// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
 	MainnetTrustedCheckpoint = &TrustedCheckpoint{
-		SectionIndex: 371,
-		SectionHead:  common.HexToHash("0x50fd3cec5376ede90ef9129772022690cd1467f22c18abb7faa11e793c51e9c9"),
-		CHTRoot:      common.HexToHash("0xb57b4b22a77b5930847b1ca9f62daa11eae6578948cb7b18997f2c0fe5757025"),
-		BloomRoot:    common.HexToHash("0xa338f8a868a194fa90327d0f5877f656a9f3640c618d2a01a01f2e76ef9ef954"),
+		SectionIndex: 395,
+		SectionHead:  common.HexToHash("0xbfca95b8c1de014e252288e9c32029825fadbff58285f5b54556525e480dbb5b"),
+		CHTRoot:      common.HexToHash("0x2ccf3dbb58eb6375e037fdd981ca5778359e4b8fa0270c2878b14361e64161e7"),
+		BloomRoot:    common.HexToHash("0x2d46ec65a6941a2dc1e682f8f81f3d24192021f492fdf6ef0fdd51acb0f4ba0f"),
 	}
 
 	// MainnetCheckpointOracle contains a set of configs for the main network oracle.
@@ -109,15 +109,16 @@ var (
 		IstanbulBlock:       big.NewInt(6_485_846),
 		MuirGlacierBlock:    big.NewInt(7_117_117),
 		BerlinBlock:         big.NewInt(9_812_189),
+		LondonBlock:         big.NewInt(10_499_401),
 		Ethash:              new(EthashConfig),
 	}
 
 	// RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
 	RopstenTrustedCheckpoint = &TrustedCheckpoint{
-		SectionIndex: 279,
-		SectionHead:  common.HexToHash("0x4a4912848d4c06090097073357c10015d11c6f4544a0f93cbdd584701c3b7d58"),
-		CHTRoot:      common.HexToHash("0x9053b7867ae921e80a4e2f5a4b15212e4af3d691ca712fb33dc150e9c6ea221c"),
-		BloomRoot:    common.HexToHash("0x3dc04cb1be7ddc271f3f83469b47b76184a79d7209ef51d85b1539ea6d25a645"),
+		SectionIndex: 329,
+		SectionHead:  common.HexToHash("0xe66f7038333a01fb95dc9ea03e5a2bdaf4b833cdcb9e393b9127e013bd64d39b"),
+		CHTRoot:      common.HexToHash("0x1b0c883338ac0d032122800c155a2e73105fbfebfaa50436893282bc2d9feec5"),
+		BloomRoot:    common.HexToHash("0x3cc98c88d283bf002378246f22c653007655cbcea6ed89f98d739f73bd341a01"),
 	}
 
 	// RopstenCheckpointOracle contains a set of configs for the Ropsten test network oracle.
@@ -149,6 +150,7 @@ var (
 		IstanbulBlock:       big.NewInt(5_435_345),
 		MuirGlacierBlock:    nil,
 		BerlinBlock:         big.NewInt(8_290_928),
+		LondonBlock:         big.NewInt(8_897_988),
 		Clique: &CliqueConfig{
 			Period: 15,
 			Epoch:  30000,
@@ -157,10 +159,10 @@ var (
 
 	// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
 	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
-		SectionIndex: 254,
-		SectionHead:  common.HexToHash("0x0cba01dd71baa22ac8fa0b105bc908e94f9ecfbc79b4eb97427fe07b5851dd10"),
-		CHTRoot:      common.HexToHash("0x5673d8fc49c9c7d8729068640e4b392d46952a5a38798973bac1cf1d0d27ad7d"),
-		BloomRoot:    common.HexToHash("0x70e01232b66df9a7778ae3291c9217afb9a2d9f799f32d7b912bd37e7bce83a8"),
+		SectionIndex: 276,
+		SectionHead:  common.HexToHash("0xea89a4b04e3da9bd688e316f8de669396b6d4a38a19d2cd96a00b70d58b836aa"),
+		CHTRoot:      common.HexToHash("0xd6889d0bf6673c0d2c1cf6e9098a6fe5b30888a115b6112796aa8ee8efc4a723"),
+		BloomRoot:    common.HexToHash("0x6009a9256b34b8bde3a3f094afb647ba5d73237546017b9025d64ac1ff54c47c"),
 	}
 
 	// RinkebyCheckpointOracle contains a set of configs for the Rinkeby test network oracle.
@@ -190,6 +192,7 @@ var (
 		IstanbulBlock:       big.NewInt(1_561_651),
 		MuirGlacierBlock:    nil,
 		BerlinBlock:         big.NewInt(4_460_644),
+		LondonBlock:         big.NewInt(5_062_605),
 		Clique: &CliqueConfig{
 			Period: 15,
 			Epoch:  30000,
@@ -198,10 +201,10 @@ var (
 
 	// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
 	GoerliTrustedCheckpoint = &TrustedCheckpoint{
-		SectionIndex: 138,
-		SectionHead:  common.HexToHash("0xb7ea0566abd7d0def5b3c9afa3431debb7bb30b65af35f106ca93a59e6c859a7"),
-		CHTRoot:      common.HexToHash("0x378c7ea9081242beb982e2e39567ba12f2ed3e59e5aba3f9db1d595646d7c9f4"),
-		BloomRoot:    common.HexToHash("0x523c169286cfca52e8a6579d8c35dc8bf093412d8a7478163bfa81ae91c2492d"),
+		SectionIndex: 160,
+		SectionHead:  common.HexToHash("0xb5a666c790dc35a5613d04ebba8ba47a850b45a15d9b95ad7745c35ae034b5a5"),
+		CHTRoot:      common.HexToHash("0x6b4e00df52bdc38fa6c26c8ef595c2ad6184963ea36ab08ee744af460aa735e1"),
+		BloomRoot:    common.HexToHash("0x8fa88f5e50190cb25243aeee262a1a9e4434a06f8d455885dcc1b5fc48c33836"),
 	}
 
 	// GoerliCheckpointOracle contains a set of configs for the Goerli test network oracle.
@@ -217,43 +220,21 @@ var (
 		Threshold: 2,
 	}
 
-	// YoloV3ChainConfig contains the chain parameters to run a node on the YOLOv3 test network.
-	YoloV3ChainConfig = &ChainConfig{
-		ChainID:             new(big.Int).SetBytes([]byte("yolov3x")),
-		HomesteadBlock:      big.NewInt(0),
-		DAOForkBlock:        nil,
-		DAOForkSupport:      true,
-		EIP150Block:         big.NewInt(0),
-		EIP155Block:         big.NewInt(0),
-		EIP158Block:         big.NewInt(0),
-		ByzantiumBlock:      big.NewInt(0),
-		ConstantinopleBlock: big.NewInt(0),
-		PetersburgBlock:     big.NewInt(0),
-		IstanbulBlock:       big.NewInt(0),
-		MuirGlacierBlock:    nil,
-		BerlinBlock:         nil, // Don't enable Berlin directly, we're YOLOing it
-		YoloV3Block:         big.NewInt(0),
-		Clique: &CliqueConfig{
-			Period: 15,
-			Epoch:  30000,
-		},
-	}
-
 	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
 	// and accepted by the Ethereum core developers into the Ethash consensus.
 	//
 	// This configuration is intentionally not using keyed fields to force anyone
 	// adding flags to the config to also have to set these fields.
-	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}
+	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
 
 	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
 	// and accepted by the Ethereum core developers into the Clique consensus.
 	//
 	// This configuration is intentionally not using keyed fields to force anyone
 	// adding flags to the config to also have to set these fields.
-	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
+	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
 
-	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}
+	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
 	TestRules       = TestChainConfig.Rules(new(big.Int))
 )
 
@@ -331,9 +312,8 @@ type ChainConfig struct {
 	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
 	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
 	BerlinBlock         *big.Int `json:"berlinBlock,omitempty"`         // Berlin switch block (nil = no fork, 0 = already on berlin)
+	LondonBlock         *big.Int `json:"londonBlock,omitempty"`         // London switch block (nil = no fork, 0 = already on london)
 
-	YoloV3Block   *big.Int `json:"yoloV3Block,omitempty"`   // YOLO v3: Gas repricings TODO @holiman add EIP references
-	EWASMBlock    *big.Int `json:"ewasmBlock,omitempty"`    // EWASM switch block (nil = no fork, 0 = already activated)
 	CatalystBlock *big.Int `json:"catalystBlock,omitempty"` // Catalyst switch block (nil = no fork, 0 = already on catalyst)
 
 	// Various consensus engines
@@ -391,7 +371,7 @@ func (c *ChainConfig) String() string {
 	default:
 		engine = "unknown"
 	}
-	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, YOLO v3: %v, Engine: %v}",
+	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Engine: %v}",
 		c.ChainID,
 		c.HomesteadBlock,
 		c.DAOForkBlock,
@@ -405,7 +385,7 @@ func (c *ChainConfig) String() string {
 		c.IstanbulBlock,
 		c.MuirGlacierBlock,
 		c.BerlinBlock,
-		c.YoloV3Block,
+		c.LondonBlock,
 		engine,
 	)
 }
@@ -464,7 +444,12 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
 
 // IsBerlin returns whether num is either equal to the Berlin fork block or greater.
 func (c *ChainConfig) IsBerlin(num *big.Int) bool {
-	return isForked(c.BerlinBlock, num) || isForked(c.YoloV3Block, num)
+	return isForked(c.BerlinBlock, num)
+}
+
+// IsLondon returns whether num is either equal to the London fork block or greater.
+func (c *ChainConfig) IsLondon(num *big.Int) bool {
+	return isForked(c.LondonBlock, num)
 }
 
 // IsCatalyst returns whether num is either equal to the Merge fork block or greater.
@@ -472,11 +457,6 @@ func (c *ChainConfig) IsCatalyst(num *big.Int) bool {
 	return isForked(c.CatalystBlock, num)
 }
 
-// IsEWASM returns whether num represents a block number after the EWASM fork
-func (c *ChainConfig) IsEWASM(num *big.Int) bool {
-	return isForked(c.EWASMBlock, num)
-}
-
 // CheckCompatible checks whether scheduled fork transitions have been imported
 // with a mismatching chain configuration.
 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
@@ -516,6 +496,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
 		{name: "istanbulBlock", block: c.IstanbulBlock},
 		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
 		{name: "berlinBlock", block: c.BerlinBlock},
+		{name: "londonBlock", block: c.LondonBlock},
 	} {
 		if lastFork.name != "" {
 			// Next one must be higher number
@@ -582,11 +563,8 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
 	if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) {
 		return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
 	}
-	if isForkIncompatible(c.YoloV3Block, newcfg.YoloV3Block, head) {
-		return newCompatError("YOLOv3 fork block", c.YoloV3Block, newcfg.YoloV3Block)
-	}
-	if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
-		return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
+	if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) {
+		return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
 	}
 	return nil
 }
@@ -655,7 +633,7 @@ type Rules struct {
 	ChainID                                                 *big.Int
 	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
 	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
-	IsBerlin, IsCatalyst                                    bool
+	IsBerlin, IsLondon, IsCatalyst                          bool
 }
 
 // Rules ensures c's ChainID is not nil.
@@ -675,6 +653,7 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
 		IsPetersburg:     c.IsPetersburg(num),
 		IsIstanbul:       c.IsIstanbul(num),
 		IsBerlin:         c.IsBerlin(num),
+		IsLondon:         c.IsLondon(num),
 		IsCatalyst:       c.IsCatalyst(num),
 	}
 }
diff --git a/params/protocol_params.go b/params/protocol_params.go
index 88f1a06e12d30c2249e73e2380f43ee4c06fca5c..7abb2441bf30fcc1a9a4f936923bfe430ebad5b3 100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -38,7 +38,7 @@ const (
 	Sha3Gas     uint64 = 30 // Once per SHA3 operation.
 	Sha3WordGas uint64 = 6  // Once per word of the SHA3 operation's data.
 
-	SstoreSetGas    uint64 = 20000 // Once per SLOAD operation.
+	SstoreSetGas    uint64 = 20000 // Once per SSTORE operation.
 	SstoreResetGas  uint64 = 5000  // Once per SSTORE operation if the zeroness changes from zero.
 	SstoreClearGas  uint64 = 5000  // Once per SSTORE operation if the zeroness doesn't change.
 	SstoreRefundGas uint64 = 15000 // Once per SSTORE operation if the zeroness changes to zero.
@@ -57,6 +57,16 @@ const (
 	SstoreResetGasEIP2200             uint64 = 5000  // Once per SSTORE operation from clean non-zero to something else
 	SstoreClearsScheduleRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
 
+	ColdAccountAccessCostEIP2929 = uint64(2600) // COLD_ACCOUNT_ACCESS_COST
+	ColdSloadCostEIP2929         = uint64(2100) // COLD_SLOAD_COST
+	WarmStorageReadCostEIP2929   = uint64(100)  // WARM_STORAGE_READ_COST
+
+	// In EIP-2200: SstoreResetGas was 5000.
+	// In EIP-2929: SstoreResetGas was changed to '5000 - COLD_SLOAD_COST'.
+	// In EIP-3529: SSTORE_CLEARS_SCHEDULE is defined as SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST
+	// Which becomes: 5000 - 2100 + 1900 = 4800
+	SstoreClearsScheduleRefundEIP3529 uint64 = SstoreResetGasEIP2200 - ColdSloadCostEIP2929 + TxAccessListStorageKeyGas
+
 	JumpdestGas   uint64 = 1     // Once per JUMPDEST operation.
 	EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
 
@@ -108,6 +118,10 @@ const (
 	// Introduced in Tangerine Whistle (Eip 150)
 	CreateBySelfdestructGas uint64 = 25000
 
+	BaseFeeChangeDenominator = 8          // Bounds the amount the base fee can change between blocks.
+	ElasticityMultiplier     = 2          // Bounds the maximum gas limit an EIP-1559 block may have.
+	InitialBaseFee           = 1000000000 // Initial base fee for EIP-1559 blocks.
+
 	MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
 
 	// Precompiled contract gas prices
@@ -137,6 +151,11 @@ const (
 	Bls12381PairingPerPairGas uint64 = 23000  // Per-point pair gas price for BLS12-381 elliptic curve pairing check
 	Bls12381MapG1Gas          uint64 = 5500   // Gas price for BLS12-381 mapping field element to G1 operation
 	Bls12381MapG2Gas          uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation
+
+	// The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529,
+	// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
+	RefundQuotient        uint64 = 2
+	RefundQuotientEIP3529 uint64 = 5
 )
 
 // Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations
diff --git a/params/version.go b/params/version.go
index 1c7bf8d88eaa805454cee9c19bbb0c2d5a47e637..8d222ac0470881244ea081e5ee0d93569f442412 100644
--- a/params/version.go
+++ b/params/version.go
@@ -23,7 +23,7 @@ import (
 const (
 	VersionMajor = 1        // Major version component of the current release
 	VersionMinor = 10       // Minor version component of the current release
-	VersionPatch = 3        // Patch version component of the current release
+	VersionPatch = 8        // Patch version component of the current release
 	VersionMeta  = "stable" // Version metadata to append to the version string
 )
 
diff --git a/rlp/decode.go b/rlp/decode.go
index 79b7ef062664eeccda203d0f68710f10c8d559ed..ac04d5d56949f85d622517244487d21a6f4f73ce 100644
--- a/rlp/decode.go
+++ b/rlp/decode.go
@@ -220,20 +220,51 @@ func decodeBigIntNoPtr(s *Stream, val reflect.Value) error {
 }
 
 func decodeBigInt(s *Stream, val reflect.Value) error {
-	b, err := s.Bytes()
-	if err != nil {
+	var buffer []byte
+	kind, size, err := s.Kind()
+	switch {
+	case err != nil:
 		return wrapStreamError(err, val.Type())
+	case kind == List:
+		return wrapStreamError(ErrExpectedString, val.Type())
+	case kind == Byte:
+		buffer = s.uintbuf[:1]
+		buffer[0] = s.byteval
+		s.kind = -1 // re-arm Kind
+	case size == 0:
+		// Avoid zero-length read.
+		s.kind = -1
+	case size <= uint64(len(s.uintbuf)):
+		// For integers smaller than s.uintbuf, allocating a buffer
+		// can be avoided.
+		buffer = s.uintbuf[:size]
+		if err := s.readFull(buffer); err != nil {
+			return wrapStreamError(err, val.Type())
+		}
+		// Reject inputs where single byte encoding should have been used.
+		if size == 1 && buffer[0] < 128 {
+			return wrapStreamError(ErrCanonSize, val.Type())
+		}
+	default:
+		// For large integers, a temporary buffer is needed.
+		buffer = make([]byte, size)
+		if err := s.readFull(buffer); err != nil {
+			return wrapStreamError(err, val.Type())
+		}
+	}
+
+	// Reject leading zero bytes.
+	if len(buffer) > 0 && buffer[0] == 0 {
+		return wrapStreamError(ErrCanonInt, val.Type())
 	}
+
+	// Set the integer bytes.
 	i := val.Interface().(*big.Int)
 	if i == nil {
 		i = new(big.Int)
 		val.Set(reflect.ValueOf(i))
 	}
-	// Reject leading zero bytes
-	if len(b) > 0 && b[0] == 0 {
-		return wrapStreamError(ErrCanonInt, val.Type())
-	}
-	i.SetBytes(b)
+	i.SetBytes(buffer)
 	return nil
 }
 
@@ -245,7 +276,7 @@ func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) {
 		}
 		return decodeByteSlice, nil
 	}
-	etypeinfo := cachedTypeInfo1(etype, tags{})
+	etypeinfo := theTC.infoWhileGenerating(etype, tags{})
 	if etypeinfo.decoderErr != nil {
 		return nil, etypeinfo.decoderErr
 	}
@@ -348,25 +379,23 @@ func decodeByteArray(s *Stream, val reflect.Value) error {
 	if err != nil {
 		return err
 	}
-	vlen := val.Len()
+	slice := byteArrayBytes(val)
 	switch kind {
 	case Byte:
-		if vlen == 0 {
+		if len(slice) == 0 {
 			return &decodeError{msg: "input string too long", typ: val.Type()}
-		}
-		if vlen > 1 {
+		} else if len(slice) > 1 {
 			return &decodeError{msg: "input string too short", typ: val.Type()}
 		}
-		bv, _ := s.Uint()
-		val.Index(0).SetUint(bv)
+		slice[0] = s.byteval
+		s.kind = -1
 	case String:
-		if uint64(vlen) < size {
+		if uint64(len(slice)) < size {
 			return &decodeError{msg: "input string too long", typ: val.Type()}
 		}
-		if uint64(vlen) > size {
+		if uint64(len(slice)) > size {
 			return &decodeError{msg: "input string too short", typ: val.Type()}
 		}
-		slice := val.Slice(0, vlen).Interface().([]byte)
 		if err := s.readFull(slice); err != nil {
 			return err
 		}
@@ -394,9 +423,16 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
 		if _, err := s.List(); err != nil {
 			return wrapStreamError(err, typ)
 		}
-		for _, f := range fields {
+		for i, f := range fields {
 			err := f.info.decoder(s, val.Field(f.index))
 			if err == EOL {
+				if f.optional {
+					// The field is optional, so reaching the end of the list before
+					// reaching the last field is acceptable. All remaining undecoded
+					// fields are zeroed.
+					zeroFields(val, fields[i:])
+					break
+				}
 				return &decodeError{msg: "too few elements", typ: typ}
 			} else if err != nil {
 				return addErrorContext(err, "."+typ.Field(f.index).Name)
@@ -407,10 +443,17 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
 	return dec, nil
 }
 
+func zeroFields(structval reflect.Value, fields []field) {
+	for _, f := range fields {
+		fv := structval.Field(f.index)
+		fv.Set(reflect.Zero(fv.Type()))
+	}
+}
+
 // makePtrDecoder creates a decoder that decodes into the pointer's element type.
 func makePtrDecoder(typ reflect.Type, tag tags) (decoder, error) {
 	etype := typ.Elem()
-	etypeinfo := cachedTypeInfo1(etype, tags{})
+	etypeinfo := theTC.infoWhileGenerating(etype, tags{})
 	switch {
 	case etypeinfo.decoderErr != nil:
 		return nil, etypeinfo.decoderErr
@@ -504,7 +547,7 @@ func decodeDecoder(s *Stream, val reflect.Value) error {
 }
 
 // Kind represents the kind of value contained in an RLP stream.
-type Kind int
+type Kind int8
 
 const (
 	Byte Kind = iota
@@ -547,22 +590,16 @@ type ByteReader interface {
 type Stream struct {
 	r ByteReader
 
-	// number of bytes remaining to be read from r.
-	remaining uint64
-	limited   bool
-
-	// auxiliary buffer for integer decoding
-	uintbuf []byte
-
-	kind    Kind   // kind of value ahead
-	size    uint64 // size of value ahead
-	byteval byte   // value of single byte in type tag
-	kinderr error  // error from last readKind
-	stack   []listpos
+	remaining uint64   // number of bytes remaining to be read from r
+	size      uint64   // size of value ahead
+	kinderr   error    // error from last readKind
+	stack     []uint64 // list sizes
+	uintbuf   [32]byte // auxiliary buffer for integer decoding
+	kind      Kind     // kind of value ahead
+	byteval   byte     // value of single byte in type tag
+	limited   bool     // true if input limit is in effect
 }
 
-type listpos struct{ pos, size uint64 }
-
 // NewStream creates a new decoding stream reading from r.
 //
 // If r implements the ByteReader interface, Stream will
@@ -632,8 +669,8 @@ func (s *Stream) Raw() ([]byte, error) {
 		s.kind = -1 // rearm Kind
 		return []byte{s.byteval}, nil
 	}
-	// the original header has already been read and is no longer
-	// available. read content and put a new header in front of it.
+	// The original header has already been read and is no longer
+	// available. Read content and put a new header in front of it.
 	start := headsize(size)
 	buf := make([]byte, uint64(start)+size)
 	if err := s.readFull(buf[start:]); err != nil {
@@ -716,7 +753,14 @@ func (s *Stream) List() (size uint64, err error) {
 	if kind != List {
 		return 0, ErrExpectedList
 	}
-	s.stack = append(s.stack, listpos{0, size})
+
+	// Remove size of inner list from outer list before pushing the new size
+	// onto the stack. This ensures that the remaining outer list size will
+	// be correct after the matching call to ListEnd.
+	if inList, limit := s.listLimit(); inList {
+		s.stack[len(s.stack)-1] = limit - size
+	}
+	s.stack = append(s.stack, size)
 	s.kind = -1
 	s.size = 0
 	return size, nil
@@ -725,17 +769,13 @@ func (s *Stream) List() (size uint64, err error) {
 // ListEnd returns to the enclosing list.
 // The input reader must be positioned at the end of a list.
 func (s *Stream) ListEnd() error {
-	if len(s.stack) == 0 {
+	// Ensure that no more data is remaining in the current list.
+	if inList, listLimit := s.listLimit(); !inList {
 		return errNotInList
-	}
-	tos := s.stack[len(s.stack)-1]
-	if tos.pos != tos.size {
+	} else if listLimit > 0 {
 		return errNotAtEOL
 	}
 	s.stack = s.stack[:len(s.stack)-1] // pop
-	if len(s.stack) > 0 {
-		s.stack[len(s.stack)-1].pos += tos.size
-	}
 	s.kind = -1
 	s.size = 0
 	return nil
@@ -763,7 +803,7 @@ func (s *Stream) Decode(val interface{}) error {
 
 	err = decoder(s, rval.Elem())
 	if decErr, ok := err.(*decodeError); ok && len(decErr.ctx) > 0 {
-		// add decode target type to error so context has more meaning
+		// Add decode target type to error so context has more meaning.
 		decErr.ctx = append(decErr.ctx, fmt.Sprint("(", rtyp.Elem(), ")"))
 	}
 	return err
@@ -786,6 +826,9 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
 		case *bytes.Reader:
 			s.remaining = uint64(br.Len())
 			s.limited = true
+		case *bytes.Buffer:
+			s.remaining = uint64(br.Len())
+			s.limited = true
 		case *strings.Reader:
 			s.remaining = uint64(br.Len())
 			s.limited = true
@@ -804,10 +847,8 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
 	s.size = 0
 	s.kind = -1
 	s.kinderr = nil
-	if s.uintbuf == nil {
-		s.uintbuf = make([]byte, 8)
-	}
 	s.byteval = 0
+	s.uintbuf = [32]byte{}
 }
 
 // Kind returns the kind and size of the next value in the
@@ -822,35 +863,29 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
 // the value. Subsequent calls to Kind (until the value is decoded)
 // will not advance the input reader and return cached information.
 func (s *Stream) Kind() (kind Kind, size uint64, err error) {
-	var tos *listpos
-	if len(s.stack) > 0 {
-		tos = &s.stack[len(s.stack)-1]
-	}
-	if s.kind < 0 {
-		s.kinderr = nil
-		// Don't read further if we're at the end of the
-		// innermost list.
-		if tos != nil && tos.pos == tos.size {
-			return 0, 0, EOL
-		}
-		s.kind, s.size, s.kinderr = s.readKind()
-		if s.kinderr == nil {
-			if tos == nil {
-				// At toplevel, check that the value is smaller
-				// than the remaining input length.
-				if s.limited && s.size > s.remaining {
-					s.kinderr = ErrValueTooLarge
-				}
-			} else {
-				// Inside a list, check that the value doesn't overflow the list.
-				if s.size > tos.size-tos.pos {
-					s.kinderr = ErrElemTooLarge
-				}
-			}
+	if s.kind >= 0 {
+		return s.kind, s.size, s.kinderr
+	}
+
+	// Check for end of list. This needs to be done here because readKind
+	// checks against the list size, and would return the wrong error.
+	inList, listLimit := s.listLimit()
+	if inList && listLimit == 0 {
+		return 0, 0, EOL
+	}
+	// Read the actual size tag.
+	s.kind, s.size, s.kinderr = s.readKind()
+	if s.kinderr == nil {
+		// Check the data size of the value ahead against input limits. This
+		// is done here because many decoders require allocating an input
+		// buffer matching the value size. Checking it here protects those
+		// decoders from inputs declaring very large value size.
+		if inList && s.size > listLimit {
+			s.kinderr = ErrElemTooLarge
+		} else if s.limited && s.size > s.remaining {
+			s.kinderr = ErrValueTooLarge
 		}
 	}
-	// Note: this might return a sticky error generated
-	// by an earlier call to readKind.
 	return s.kind, s.size, s.kinderr
 }
 
@@ -877,37 +912,35 @@ func (s *Stream) readKind() (kind Kind, size uint64, err error) {
 		s.byteval = b
 		return Byte, 0, nil
 	case b < 0xB8:
-		// Otherwise, if a string is 0-55 bytes long,
-		// the RLP encoding consists of a single byte with value 0x80 plus the
-		// length of the string followed by the string. The range of the first
-		// byte is thus [0x80, 0xB7].
+		// Otherwise, if a string is 0-55 bytes long, the RLP encoding consists
+		// of a single byte with value 0x80 plus the length of the string
+		// followed by the string. The range of the first byte is thus [0x80, 0xB7].
 		return String, uint64(b - 0x80), nil
 	case b < 0xC0:
-		// If a string is more than 55 bytes long, the
-		// RLP encoding consists of a single byte with value 0xB7 plus the length
-		// of the length of the string in binary form, followed by the length of
-		// the string, followed by the string. For example, a length-1024 string
-		// would be encoded as 0xB90400 followed by the string. The range of
-		// the first byte is thus [0xB8, 0xBF].
+		// If a string is more than 55 bytes long, the RLP encoding consists of a
+		// single byte with value 0xB7 plus the length of the length of the
+		// string in binary form, followed by the length of the string, followed
+		// by the string. For example, a length-1024 string would be encoded as
+		// 0xB90400 followed by the string. The range of the first byte is thus
+		// [0xB8, 0xBF].
 		size, err = s.readUint(b - 0xB7)
 		if err == nil && size < 56 {
 			err = ErrCanonSize
 		}
 		return String, size, err
 	case b < 0xF8:
-		// If the total payload of a list
-		// (i.e. the combined length of all its items) is 0-55 bytes long, the
-		// RLP encoding consists of a single byte with value 0xC0 plus the length
-		// of the list followed by the concatenation of the RLP encodings of the
-		// items. The range of the first byte is thus [0xC0, 0xF7].
+		// If the total payload of a list (i.e. the combined length of all its
+		// items) is 0-55 bytes long, the RLP encoding consists of a single byte
+		// with value 0xC0 plus the length of the list followed by the
+		// concatenation of the RLP encodings of the items. The range of the
+		// first byte is thus [0xC0, 0xF7].
 		return List, uint64(b - 0xC0), nil
 	default:
-		// If the total payload of a list is more than 55 bytes long,
-		// the RLP encoding consists of a single byte with value 0xF7
-		// plus the length of the length of the payload in binary
-		// form, followed by the length of the payload, followed by
-		// the concatenation of the RLP encodings of the items. The
-		// range of the first byte is thus [0xF8, 0xFF].
+		// If the total payload of a list is more than 55 bytes long, the RLP
+		// encoding consists of a single byte with value 0xF7 plus the length of
+		// the length of the payload in binary form, followed by the length of
+		// the payload, followed by the concatenation of the RLP encodings of
+		// the items. The range of the first byte is thus [0xF8, 0xFF].
 		size, err = s.readUint(b - 0xF7)
 		if err == nil && size < 56 {
 			err = ErrCanonSize
@@ -925,23 +958,24 @@ func (s *Stream) readUint(size byte) (uint64, error) {
 		b, err := s.readByte()
 		return uint64(b), err
 	default:
-		start := int(8 - size)
-		for i := 0; i < start; i++ {
-			s.uintbuf[i] = 0
+		buffer := s.uintbuf[:8]
+		for i := range buffer {
+			buffer[i] = 0
 		}
-		if err := s.readFull(s.uintbuf[start:]); err != nil {
+		start := int(8 - size)
+		if err := s.readFull(buffer[start:]); err != nil {
 			return 0, err
 		}
-		if s.uintbuf[start] == 0 {
-			// Note: readUint is also used to decode integer
-			// values. The error needs to be adjusted to become
-			// ErrCanonInt in this case.
+		if buffer[start] == 0 {
+			// Note: readUint is also used to decode integer values.
+			// The error needs to be adjusted to become ErrCanonInt in this case.
 			return 0, ErrCanonSize
 		}
-		return binary.BigEndian.Uint64(s.uintbuf), nil
+		return binary.BigEndian.Uint64(buffer[:]), nil
 	}
 }
 
+// readFull reads into buf from the underlying stream.
 func (s *Stream) readFull(buf []byte) (err error) {
 	if err := s.willRead(uint64(len(buf))); err != nil {
 		return err
@@ -963,6 +997,7 @@ func (s *Stream) readFull(buf []byte) (err error) {
 	return err
 }
 
+// readByte reads a single byte from the underlying stream.
 func (s *Stream) readByte() (byte, error) {
 	if err := s.willRead(1); err != nil {
 		return 0, err
@@ -974,16 +1009,16 @@ func (s *Stream) readByte() (byte, error) {
 	return b, err
 }
 
+// willRead is called before any read from the underlying stream. It checks
+// n against size limits, and updates the limits if n doesn't overflow them.
 func (s *Stream) willRead(n uint64) error {
 	s.kind = -1 // rearm Kind
 
-	if len(s.stack) > 0 {
-		// check list overflow
-		tos := s.stack[len(s.stack)-1]
-		if n > tos.size-tos.pos {
+	if inList, limit := s.listLimit(); inList {
+		if n > limit {
 			return ErrElemTooLarge
 		}
-		s.stack[len(s.stack)-1].pos += n
+		s.stack[len(s.stack)-1] = limit - n
 	}
 	if s.limited {
 		if n > s.remaining {
@@ -993,3 +1028,11 @@ func (s *Stream) willRead(n uint64) error {
 	}
 	return nil
 }
+
+// listLimit returns the amount of data remaining in the innermost list.
+func (s *Stream) listLimit() (inList bool, limit uint64) {
+	if len(s.stack) == 0 {
+		return false, 0
+	}
+	return true, s.stack[len(s.stack)-1]
+}
diff --git a/rlp/decode_test.go b/rlp/decode_test.go
index d94c3969b221d85b70fe183acf9490737888a8d2..7c3dafeac44d399c3111d6497e031196cfe0b997 100644
--- a/rlp/decode_test.go
+++ b/rlp/decode_test.go
@@ -26,6 +26,8 @@ import (
 	"reflect"
 	"strings"
 	"testing"
+
+	"github.com/ethereum/go-ethereum/common/math"
 )
 
 func TestStreamKind(t *testing.T) {
@@ -327,6 +329,11 @@ type recstruct struct {
 	Child *recstruct `rlp:"nil"`
 }
 
+type bigIntStruct struct {
+	I *big.Int
+	B string
+}
+
 type invalidNilTag struct {
 	X []byte `rlp:"nil"`
 }
@@ -369,19 +376,47 @@ type intField struct {
 	X int
 }
 
-var (
-	veryBigInt = big.NewInt(0).Add(
-		big.NewInt(0).Lsh(big.NewInt(0xFFFFFFFFFFFFFF), 16),
-		big.NewInt(0xFFFF),
-	)
-)
+type optionalFields struct {
+	A uint
+	B uint `rlp:"optional"`
+	C uint `rlp:"optional"`
+}
+
+type optionalAndTailField struct {
+	A    uint
+	B    uint   `rlp:"optional"`
+	Tail []uint `rlp:"tail"`
+}
+
+type optionalBigIntField struct {
+	A uint
+	B *big.Int `rlp:"optional"`
+}
+
+type optionalPtrField struct {
+	A uint
+	B *[3]byte `rlp:"optional"`
+}
+
+type optionalPtrFieldNil struct {
+	A uint
+	B *[3]byte `rlp:"optional,nil"`
+}
 
-type hasIgnoredField struct {
+type ignoredField struct {
 	A uint
 	B uint `rlp:"-"`
 	C uint
 }
 
+var (
+	veryBigInt = new(big.Int).Add(
+		big.NewInt(0).Lsh(big.NewInt(0xFFFFFFFFFFFFFF), 16),
+		big.NewInt(0xFFFF),
+	)
+	veryVeryBigInt = new(big.Int).Exp(veryBigInt, big.NewInt(8), nil)
+)
+
 var decodeTests = []decodeTest{
 	// booleans
 	{input: "01", ptr: new(bool), value: true},
@@ -450,12 +485,15 @@ var decodeTests = []decodeTest{
 	{input: "C0", ptr: new(string), error: "rlp: expected input string or byte for string"},
 
 	// big ints
+	{input: "80", ptr: new(*big.Int), value: big.NewInt(0)},
 	{input: "01", ptr: new(*big.Int), value: big.NewInt(1)},
 	{input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt},
+	{input: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001", ptr: new(*big.Int), value: veryVeryBigInt},
 	{input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works
 	{input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"},
-	{input: "820001", ptr: new(big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
-	{input: "8105", ptr: new(big.Int), error: "rlp: non-canonical size information for *big.Int"},
+	{input: "00", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
+	{input: "820001", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
+	{input: "8105", ptr: new(*big.Int), error: "rlp: non-canonical size information for *big.Int"},
 
 	// structs
 	{
@@ -468,6 +506,13 @@ var decodeTests = []decodeTest{
 		ptr:   new(recstruct),
 		value: recstruct{1, &recstruct{2, &recstruct{3, nil}}},
 	},
+	{
+		// This checks that empty big.Int works correctly in struct context. It's easy to
+		// miss the update of s.kind for this case, so it needs its own test.
+		input: "C58083343434",
+		ptr:   new(bigIntStruct),
+		value: bigIntStruct{new(big.Int), "444"},
+	},
 
 	// struct errors
 	{
@@ -551,8 +596,8 @@ var decodeTests = []decodeTest{
 	// struct tag "-"
 	{
 		input: "C20102",
-		ptr:   new(hasIgnoredField),
-		value: hasIgnoredField{A: 1, C: 2},
+		ptr:   new(ignoredField),
+		value: ignoredField{A: 1, C: 2},
 	},
 
 	// struct tag "nilList"
@@ -592,6 +637,110 @@ var decodeTests = []decodeTest{
 		value: nilStringSlice{X: &[]uint{3}},
 	},
 
+	// struct tag "optional"
+	{
+		input: "C101",
+		ptr:   new(optionalFields),
+		value: optionalFields{1, 0, 0},
+	},
+	{
+		input: "C20102",
+		ptr:   new(optionalFields),
+		value: optionalFields{1, 2, 0},
+	},
+	{
+		input: "C3010203",
+		ptr:   new(optionalFields),
+		value: optionalFields{1, 2, 3},
+	},
+	{
+		input: "C401020304",
+		ptr:   new(optionalFields),
+		error: "rlp: input list has too many elements for rlp.optionalFields",
+	},
+	{
+		input: "C101",
+		ptr:   new(optionalAndTailField),
+		value: optionalAndTailField{A: 1},
+	},
+	{
+		input: "C20102",
+		ptr:   new(optionalAndTailField),
+		value: optionalAndTailField{A: 1, B: 2, Tail: []uint{}},
+	},
+	{
+		input: "C401020304",
+		ptr:   new(optionalAndTailField),
+		value: optionalAndTailField{A: 1, B: 2, Tail: []uint{3, 4}},
+	},
+	{
+		input: "C101",
+		ptr:   new(optionalBigIntField),
+		value: optionalBigIntField{A: 1, B: nil},
+	},
+	{
+		input: "C20102",
+		ptr:   new(optionalBigIntField),
+		value: optionalBigIntField{A: 1, B: big.NewInt(2)},
+	},
+	{
+		input: "C101",
+		ptr:   new(optionalPtrField),
+		value: optionalPtrField{A: 1},
+	},
+	{
+		input: "C20180", // not accepted because "optional" doesn't enable "nil"
+		ptr:   new(optionalPtrField),
+		error: "rlp: input string too short for [3]uint8, decoding into (rlp.optionalPtrField).B",
+	},
+	{
+		input: "C20102",
+		ptr:   new(optionalPtrField),
+		error: "rlp: input string too short for [3]uint8, decoding into (rlp.optionalPtrField).B",
+	},
+	{
+		input: "C50183010203",
+		ptr:   new(optionalPtrField),
+		value: optionalPtrField{A: 1, B: &[3]byte{1, 2, 3}},
+	},
+	{
+		input: "C101",
+		ptr:   new(optionalPtrFieldNil),
+		value: optionalPtrFieldNil{A: 1},
+	},
+	{
+		input: "C20180", // accepted because "nil" tag allows empty input
+		ptr:   new(optionalPtrFieldNil),
+		value: optionalPtrFieldNil{A: 1},
+	},
+	{
+		input: "C20102",
+		ptr:   new(optionalPtrFieldNil),
+		error: "rlp: input string too short for [3]uint8, decoding into (rlp.optionalPtrFieldNil).B",
+	},
+
+	// struct tag "optional" field clearing
+	{
+		input: "C101",
+		ptr:   &optionalFields{A: 9, B: 8, C: 7},
+		value: optionalFields{A: 1, B: 0, C: 0},
+	},
+	{
+		input: "C20102",
+		ptr:   &optionalFields{A: 9, B: 8, C: 7},
+		value: optionalFields{A: 1, B: 2, C: 0},
+	},
+	{
+		input: "C20102",
+		ptr:   &optionalAndTailField{A: 9, B: 8, Tail: []uint{7, 6, 5}},
+		value: optionalAndTailField{A: 1, B: 2, Tail: []uint{}},
+	},
+	{
+		input: "C101",
+		ptr:   &optionalPtrField{A: 9, B: &[3]byte{8, 7, 6}},
+		value: optionalPtrField{A: 1},
+	},
+
 	// RawValue
 	{input: "01", ptr: new(RawValue), value: RawValue(unhex("01"))},
 	{input: "82FFFF", ptr: new(RawValue), value: RawValue(unhex("82FFFF"))},
@@ -822,6 +971,40 @@ func TestDecoderFunc(t *testing.T) {
 	x()
 }
 
+// This tests the validity checks for fields with struct tag "optional".
+func TestInvalidOptionalField(t *testing.T) {
+	type (
+		invalid1 struct {
+			A uint `rlp:"optional"`
+			B uint
+		}
+		invalid2 struct {
+			T []uint `rlp:"tail,optional"`
+		}
+		invalid3 struct {
+			T []uint `rlp:"optional,tail"`
+		}
+	)
+
+	tests := []struct {
+		v   interface{}
+		err string
+	}{
+		{v: new(invalid1), err: `rlp: struct field rlp.invalid1.B needs "optional" tag`},
+		{v: new(invalid2), err: `rlp: invalid struct tag "optional" for rlp.invalid2.T (also has "tail" tag)`},
+		{v: new(invalid3), err: `rlp: invalid struct tag "tail" for rlp.invalid3.T (also has "optional" tag)`},
+	}
+	for _, test := range tests {
+		err := DecodeBytes(unhex("C20102"), test.v)
+		if err == nil {
+			t.Errorf("no error for %T", test.v)
+		} else if err.Error() != test.err {
+			t.Errorf("wrong error for %T: %v", test.v, err.Error())
+		}
+	}
+
+}
+
 func ExampleDecode() {
 	input, _ := hex.DecodeString("C90A1486666F6F626172")
 
@@ -898,7 +1081,7 @@ func ExampleStream() {
 	// [102 111 111 98 97 114] <nil>
 }
 
-func BenchmarkDecode(b *testing.B) {
+func BenchmarkDecodeUints(b *testing.B) {
 	enc := encodeTestSlice(90000)
 	b.SetBytes(int64(len(enc)))
 	b.ReportAllocs()
@@ -913,7 +1096,7 @@ func BenchmarkDecode(b *testing.B) {
 	}
 }
 
-func BenchmarkDecodeIntSliceReuse(b *testing.B) {
+func BenchmarkDecodeUintsReused(b *testing.B) {
 	enc := encodeTestSlice(100000)
 	b.SetBytes(int64(len(enc)))
 	b.ReportAllocs()
@@ -928,6 +1111,44 @@ func BenchmarkDecodeIntSliceReuse(b *testing.B) {
 	}
 }
 
+func BenchmarkDecodeByteArrayStruct(b *testing.B) {
+	enc, err := EncodeToBytes(&byteArrayStruct{})
+	if err != nil {
+		b.Fatal(err)
+	}
+	b.SetBytes(int64(len(enc)))
+	b.ReportAllocs()
+	b.ResetTimer()
+
+	var out byteArrayStruct
+	for i := 0; i < b.N; i++ {
+		if err := DecodeBytes(enc, &out); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkDecodeBigInts(b *testing.B) {
+	ints := make([]*big.Int, 200)
+	for i := range ints {
+		ints[i] = math.BigPow(2, int64(i))
+	}
+	enc, err := EncodeToBytes(ints)
+	if err != nil {
+		b.Fatal(err)
+	}
+	b.SetBytes(int64(len(enc)))
+	b.ReportAllocs()
+	b.ResetTimer()
+
+	var out []*big.Int
+	for i := 0; i < b.N; i++ {
+		if err := DecodeBytes(enc, &out); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
 func encodeTestSlice(n uint) []byte {
 	s := make([]uint, n)
 	for i := uint(0); i < n; i++ {
diff --git a/rlp/doc.go b/rlp/doc.go
index 7e6ee8520019a91e0c666787275fa0f1995052ec..113828e39b90665a4f78ffd6c18d92adde008fd2 100644
--- a/rlp/doc.go
+++ b/rlp/doc.go
@@ -102,29 +102,60 @@ Signed integers, floating point numbers, maps, channels and functions cannot be
 
 Struct Tags
 
-Package rlp honours certain struct tags: "-", "tail", "nil", "nilList" and "nilString".
+As with other encoding packages, the "-" tag ignores fields.
 
-The "-" tag ignores fields.
+    type StructWithIgnoredField struct{
+        Ignored uint `rlp:"-"`
+        Field   uint
+    }
+
+Go struct values encode/decode as RLP lists. There are two ways of influencing the mapping
+of fields to list elements. The "tail" tag, which may only be used on the last exported
+struct field, allows slurping up any excess list elements into a slice.
+
+    type StructWithTail struct{
+        Field   uint
+        Tail    []string `rlp:"tail"`
+    }
 
-The "tail" tag, which may only be used on the last exported struct field, allows slurping
-up any excess list elements into a slice. See examples for more details.
+The "optional" tag says that the field may be omitted if it is zero-valued. If this tag is
+used on a struct field, all subsequent public fields must also be declared optional.
 
-The "nil" tag applies to pointer-typed fields and changes the decoding rules for the field
-such that input values of size zero decode as a nil pointer. This tag can be useful when
-decoding recursive types.
+When encoding a struct with optional fields, the output RLP list contains all values up to
+the last non-zero optional field.
 
-    type StructWithOptionalFoo struct {
-        Foo *[20]byte `rlp:"nil"`
+When decoding into a struct, optional fields may be omitted from the end of the input
+list. For the example below, this means input lists of one, two, or three elements are
+accepted.
+
+   type StructWithOptionalFields struct{
+        Required  uint
+        Optional1 uint `rlp:"optional"`
+        Optional2 uint `rlp:"optional"`
+   }
+
+The "nil", "nilList" and "nilString" tags apply to pointer-typed fields only, and change
+the decoding rules for the field type. For regular pointer fields without the "nil" tag,
+input values must always match the required input length exactly and the decoder does not
+produce nil values. When the "nil" tag is set, input values of size zero decode as a nil
+pointer. This is especially useful for recursive types.
+
+    type StructWithNilField struct {
+        Field *[3]byte `rlp:"nil"`
     }
 
+In the example above, Field allows two possible input sizes. For input 0xC180 (a list
+containing an empty string) Field is set to nil after decoding. For input 0xC483000000 (a
+list containing a 3-byte string), Field is set to a non-nil array pointer.
+
 RLP supports two kinds of empty values: empty lists and empty strings. When using the
-"nil" tag, the kind of empty value allowed for a type is chosen automatically. A struct
-field whose Go type is a pointer to an unsigned integer, string, boolean or byte
-array/slice expects an empty RLP string. Any other pointer field type encodes/decodes as
-an empty RLP list.
+"nil" tag, the kind of empty value allowed for a type is chosen automatically. A field
+whose Go type is a pointer to an unsigned integer, string, boolean or byte array/slice
+expects an empty RLP string. Any other pointer field type encodes/decodes as an empty RLP
+list.
 
 The choice of null value can be made explicit with the "nilList" and "nilString" struct
-tags. Using these tags encodes/decodes a Go nil pointer value as the kind of empty
-RLP value defined by the tag.
+tags. Using these tags encodes/decodes a Go nil pointer value as the empty RLP value kind
+defined by the tag.
 */
 package rlp
diff --git a/rlp/encode.go b/rlp/encode.go
index 77b591045d2fb6cd811252a56311bfcd31b93493..3348644342965ec2de14766b1cfed0ebe7d02edc 100644
--- a/rlp/encode.go
+++ b/rlp/encode.go
@@ -124,19 +124,15 @@ func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
 }
 
 type encbuf struct {
-	str      []byte        // string data, contains everything except list headers
-	lheads   []listhead    // all list headers
-	lhsize   int           // sum of sizes of all encoded list headers
-	sizebuf  [9]byte       // auxiliary buffer for uint encoding
-	bufvalue reflect.Value // used in writeByteArrayCopy
+	str     []byte     // string data, contains everything except list headers
+	lheads  []listhead // all list headers
+	lhsize  int        // sum of sizes of all encoded list headers
+	sizebuf [9]byte    // auxiliary buffer for uint encoding
 }
 
 // encbufs are pooled.
 var encbufPool = sync.Pool{
-	New: func() interface{} {
-		var bytes []byte
-		return &encbuf{bufvalue: reflect.ValueOf(&bytes).Elem()}
-	},
+	New: func() interface{} { return new(encbuf) },
 }
 
 func (w *encbuf) reset() {
@@ -429,21 +425,14 @@ func writeBytes(val reflect.Value, w *encbuf) error {
 	return nil
 }
 
-var byteType = reflect.TypeOf(byte(0))
-
 func makeByteArrayWriter(typ reflect.Type) writer {
-	length := typ.Len()
-	if length == 0 {
+	switch typ.Len() {
+	case 0:
 		return writeLengthZeroByteArray
-	} else if length == 1 {
+	case 1:
 		return writeLengthOneByteArray
-	}
-	if typ.Elem() != byteType {
-		return writeNamedByteArray
-	}
-	return func(val reflect.Value, w *encbuf) error {
-		writeByteArrayCopy(length, val, w)
-		return nil
+	default:
+		return writeByteArray
 	}
 }
 
@@ -462,29 +451,18 @@ func writeLengthOneByteArray(val reflect.Value, w *encbuf) error {
 	return nil
 }
 
-// writeByteArrayCopy encodes byte arrays using reflect.Copy. This is
-// the fast path for [N]byte where N > 1.
-func writeByteArrayCopy(length int, val reflect.Value, w *encbuf) {
-	w.encodeStringHeader(length)
-	offset := len(w.str)
-	w.str = append(w.str, make([]byte, length)...)
-	w.bufvalue.SetBytes(w.str[offset:])
-	reflect.Copy(w.bufvalue, val)
-}
-
-// writeNamedByteArray encodes byte arrays with named element type.
-// This exists because reflect.Copy can't be used with such types.
-func writeNamedByteArray(val reflect.Value, w *encbuf) error {
+func writeByteArray(val reflect.Value, w *encbuf) error {
 	if !val.CanAddr() {
-		// Slice requires the value to be addressable.
-		// Make it addressable by copying.
+		// Getting the byte slice of val requires it to be addressable. Make it
+		// addressable by copying.
 		copy := reflect.New(val.Type()).Elem()
 		copy.Set(val)
 		val = copy
 	}
-	size := val.Len()
-	slice := val.Slice(0, size).Bytes()
-	w.encodeString(slice)
+
+	slice := byteArrayBytes(val)
+	w.encodeStringHeader(len(slice))
+	w.str = append(w.str, slice...)
 	return nil
 }
 
@@ -517,7 +495,7 @@ func writeInterface(val reflect.Value, w *encbuf) error {
 }
 
 func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) {
-	etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
+	etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{})
 	if etypeinfo.writerErr != nil {
 		return nil, etypeinfo.writerErr
 	}
@@ -546,21 +524,46 @@ func makeStructWriter(typ reflect.Type) (writer, error) {
 			return nil, structFieldError{typ, f.index, f.info.writerErr}
 		}
 	}
-	writer := func(val reflect.Value, w *encbuf) error {
-		lh := w.list()
-		for _, f := range fields {
-			if err := f.info.writer(val.Field(f.index), w); err != nil {
-				return err
+
+	var writer writer
+	firstOptionalField := firstOptionalField(fields)
+	if firstOptionalField == len(fields) {
+		// This is the writer function for structs without any optional fields.
+		writer = func(val reflect.Value, w *encbuf) error {
+			lh := w.list()
+			for _, f := range fields {
+				if err := f.info.writer(val.Field(f.index), w); err != nil {
+					return err
+				}
 			}
+			w.listEnd(lh)
+			return nil
+		}
+	} else {
+		// If there are any "optional" fields, the writer needs to perform additional
+		// checks to determine the output list length.
+		writer = func(val reflect.Value, w *encbuf) error {
+			lastField := len(fields) - 1
+			for ; lastField >= firstOptionalField; lastField-- {
+				if !val.Field(fields[lastField].index).IsZero() {
+					break
+				}
+			}
+			lh := w.list()
+			for i := 0; i <= lastField; i++ {
+				if err := fields[i].info.writer(val.Field(fields[i].index), w); err != nil {
+					return err
+				}
+			}
+			w.listEnd(lh)
+			return nil
 		}
-		w.listEnd(lh)
-		return nil
 	}
 	return writer, nil
 }
 
 func makePtrWriter(typ reflect.Type, ts tags) (writer, error) {
-	etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
+	etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{})
 	if etypeinfo.writerErr != nil {
 		return nil, etypeinfo.writerErr
 	}
diff --git a/rlp/encode_test.go b/rlp/encode_test.go
index 418ee10a350eb90bef910f0a74744fb64b9f6d81..25d4aac267264bf32834f58b9b431d8ab5ccd22f 100644
--- a/rlp/encode_test.go
+++ b/rlp/encode_test.go
@@ -23,6 +23,7 @@ import (
 	"io"
 	"io/ioutil"
 	"math/big"
+	"runtime"
 	"sync"
 	"testing"
 
@@ -130,6 +131,14 @@ var encTests = []encTest{
 		val:    big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
 		output: "A1010000000000000000000000000000000000000000000000000000000000000000",
 	},
+	{
+		val:    veryBigInt,
+		output: "89FFFFFFFFFFFFFFFFFF",
+	},
+	{
+		val:    veryVeryBigInt,
+		output: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001",
+	},
 
 	// non-pointer big.Int
 	{val: *big.NewInt(0), output: "80"},
@@ -257,12 +266,30 @@ var encTests = []encTest{
 	{val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"},
 	{val: &recstruct{5, nil}, output: "C205C0"},
 	{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
+	{val: &intField{X: 3}, error: "rlp: type int is not RLP-serializable (struct field rlp.intField.X)"},
+
+	// struct tag "-"
+	{val: &ignoredField{A: 1, B: 2, C: 3}, output: "C20103"},
+
+	// struct tag "tail"
 	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02"), unhex("03")}}, output: "C3010203"},
 	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"},
 	{val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"},
 	{val: &tailRaw{A: 1, Tail: nil}, output: "C101"},
-	{val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"},
-	{val: &intField{X: 3}, error: "rlp: type int is not RLP-serializable (struct field rlp.intField.X)"},
+
+	// struct tag "optional"
+	{val: &optionalFields{}, output: "C180"},
+	{val: &optionalFields{A: 1}, output: "C101"},
+	{val: &optionalFields{A: 1, B: 2}, output: "C20102"},
+	{val: &optionalFields{A: 1, B: 2, C: 3}, output: "C3010203"},
+	{val: &optionalFields{A: 1, B: 0, C: 3}, output: "C3018003"},
+	{val: &optionalAndTailField{A: 1}, output: "C101"},
+	{val: &optionalAndTailField{A: 1, B: 2}, output: "C20102"},
+	{val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"},
+	{val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"},
+	{val: &optionalBigIntField{A: 1}, output: "C101"},
+	{val: &optionalPtrField{A: 1}, output: "C101"},
+	{val: &optionalPtrFieldNil{A: 1}, output: "C101"},
 
 	// nil
 	{val: (*uint)(nil), output: "80"},
@@ -462,3 +489,54 @@ func BenchmarkEncodeBigInts(b *testing.B) {
 		}
 	}
 }
+
+func BenchmarkEncodeConcurrentInterface(b *testing.B) {
+	type struct1 struct {
+		A string
+		B *big.Int
+		C [20]byte
+	}
+	value := []interface{}{
+		uint(999),
+		&struct1{A: "hello", B: big.NewInt(0xFFFFFFFF)},
+		[10]byte{1, 2, 3, 4, 5, 6},
+		[]string{"yeah", "yeah", "yeah"},
+	}
+
+	var wg sync.WaitGroup
+	for cpu := 0; cpu < runtime.NumCPU(); cpu++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			var buffer bytes.Buffer
+			for i := 0; i < b.N; i++ {
+				buffer.Reset()
+				err := Encode(&buffer, value)
+				if err != nil {
+					panic(err)
+				}
+			}
+		}()
+	}
+	wg.Wait()
+}
+
+type byteArrayStruct struct {
+	A [20]byte
+	B [32]byte
+	C [32]byte
+}
+
+func BenchmarkEncodeByteArrayStruct(b *testing.B) {
+	var out bytes.Buffer
+	var value byteArrayStruct
+
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		out.Reset()
+		if err := Encode(&out, &value); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/rlp/raw.go b/rlp/raw.go
index 3071e99cab1bf27a2c77fa4bfc0faaca622379ce..f355efc144df990b62c8d5ef09e8e4dd6247d2d7 100644
--- a/rlp/raw.go
+++ b/rlp/raw.go
@@ -34,6 +34,14 @@ func ListSize(contentSize uint64) uint64 {
 	return uint64(headsize(contentSize)) + contentSize
 }
 
+// IntSize returns the encoded size of the integer x.
+func IntSize(x uint64) int {
+	if x < 0x80 {
+		return 1
+	}
+	return 1 + intsize(x)
+}
+
 // Split returns the content of first RLP value and any
 // bytes after the value as subslices of b.
 func Split(b []byte) (k Kind, content, rest []byte, err error) {
diff --git a/rlp/raw_test.go b/rlp/raw_test.go
index c976c4f73429522cde5d85da6f4b7b2149864760..185e269d075a46291a7b2848985684e3d9dd26e2 100644
--- a/rlp/raw_test.go
+++ b/rlp/raw_test.go
@@ -263,6 +263,12 @@ func TestAppendUint64(t *testing.T) {
 		if !bytes.Equal(x, unhex(test.output)) {
 			t.Errorf("AppendUint64(%v, %d): got %x, want %s", test.slice, test.input, x, test.output)
 		}
+
+		// Check that IntSize returns the appended size.
+		length := len(x) - len(test.slice)
+		if s := IntSize(test.input); s != length {
+			t.Errorf("IntSize(%d): got %d, want %d", test.input, s, length)
+		}
 	}
 }
 
diff --git a/rlp/safe.go b/rlp/safe.go
new file mode 100644
index 0000000000000000000000000000000000000000..a80380aef473feaec3b3c6a51d63d125a7431ca8
--- /dev/null
+++ b/rlp/safe.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// +build nacl js !cgo
+
+package rlp
+
+import "reflect"
+
+// byteArrayBytes returns a slice of the byte array v.
+func byteArrayBytes(v reflect.Value) []byte {
+	return v.Slice(0, v.Len()).Bytes()
+}
diff --git a/rlp/typecache.go b/rlp/typecache.go
index 6026e1a6495146b78c3b156049f5c8bb265d93aa..62553d3b55c1c1efce8230e6bfc9a102dce95c1a 100644
--- a/rlp/typecache.go
+++ b/rlp/typecache.go
@@ -21,13 +21,10 @@ import (
 	"reflect"
 	"strings"
 	"sync"
+	"sync/atomic"
 )
 
-var (
-	typeCacheMutex sync.RWMutex
-	typeCache      = make(map[typekey]*typeinfo)
-)
-
+// typeinfo is an entry in the type cache.
 type typeinfo struct {
 	decoder    decoder
 	decoderErr error // error from makeDecoder
@@ -38,15 +35,16 @@ type typeinfo struct {
 // tags represents struct tags.
 type tags struct {
 	// rlp:"nil" controls whether empty input results in a nil pointer.
-	nilOK bool
-
-	// This controls whether nil pointers are encoded/decoded as empty strings
-	// or empty lists.
+	// nilKind is the kind of empty value allowed for the field.
 	nilKind Kind
+	nilOK   bool
+
+	// rlp:"optional" allows for a field to be missing in the input list.
+	// If this is set, all subsequent fields must also be optional.
+	optional bool
 
-	// rlp:"tail" controls whether this field swallows additional list
-	// elements. It can only be set for the last field, which must be
-	// of slice type.
+	// rlp:"tail" controls whether this field swallows additional list elements. It can
+	// only be set for the last field, which must be of slice type.
 	tail bool
 
 	// rlp:"-" ignores fields.
@@ -64,68 +62,126 @@ type decoder func(*Stream, reflect.Value) error
 
 type writer func(reflect.Value, *encbuf) error
 
+var theTC = newTypeCache()
+
+type typeCache struct {
+	cur atomic.Value
+
+	// This lock synchronizes writers.
+	mu   sync.Mutex
+	next map[typekey]*typeinfo
+}
+
+func newTypeCache() *typeCache {
+	c := new(typeCache)
+	c.cur.Store(make(map[typekey]*typeinfo))
+	return c
+}
+
 func cachedDecoder(typ reflect.Type) (decoder, error) {
-	info := cachedTypeInfo(typ, tags{})
+	info := theTC.info(typ)
 	return info.decoder, info.decoderErr
 }
 
 func cachedWriter(typ reflect.Type) (writer, error) {
-	info := cachedTypeInfo(typ, tags{})
+	info := theTC.info(typ)
 	return info.writer, info.writerErr
 }
 
-func cachedTypeInfo(typ reflect.Type, tags tags) *typeinfo {
-	typeCacheMutex.RLock()
-	info := typeCache[typekey{typ, tags}]
-	typeCacheMutex.RUnlock()
-	if info != nil {
+func (c *typeCache) info(typ reflect.Type) *typeinfo {
+	key := typekey{Type: typ}
+	if info := c.cur.Load().(map[typekey]*typeinfo)[key]; info != nil {
 		return info
 	}
-	// not in the cache, need to generate info for this type.
-	typeCacheMutex.Lock()
-	defer typeCacheMutex.Unlock()
-	return cachedTypeInfo1(typ, tags)
+
+	// Not in the cache, need to generate info for this type.
+	return c.generate(typ, tags{})
 }
 
-func cachedTypeInfo1(typ reflect.Type, tags tags) *typeinfo {
+func (c *typeCache) generate(typ reflect.Type, tags tags) *typeinfo {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
+	cur := c.cur.Load().(map[typekey]*typeinfo)
+	if info := cur[typekey{typ, tags}]; info != nil {
+		return info
+	}
+
+	// Copy cur to next.
+	c.next = make(map[typekey]*typeinfo, len(cur)+1)
+	for k, v := range cur {
+		c.next[k] = v
+	}
+
+	// Generate.
+	info := c.infoWhileGenerating(typ, tags)
+
+	// next -> cur
+	c.cur.Store(c.next)
+	c.next = nil
+	return info
+}
+
+func (c *typeCache) infoWhileGenerating(typ reflect.Type, tags tags) *typeinfo {
 	key := typekey{typ, tags}
-	info := typeCache[key]
-	if info != nil {
-		// another goroutine got the write lock first
+	if info := c.next[key]; info != nil {
 		return info
 	}
-	// put a dummy value into the cache before generating.
-	// if the generator tries to lookup itself, it will get
+	// Put a dummy value into the cache before generating.
+	// If the generator tries to lookup itself, it will get
 	// the dummy value and won't call itself recursively.
-	info = new(typeinfo)
-	typeCache[key] = info
+	info := new(typeinfo)
+	c.next[key] = info
 	info.generate(typ, tags)
 	return info
 }
 
 type field struct {
-	index int
-	info  *typeinfo
+	index    int
+	info     *typeinfo
+	optional bool
 }
 
+// structFields resolves the typeinfo of all public fields in a struct type.
 func structFields(typ reflect.Type) (fields []field, err error) {
-	lastPublic := lastPublicField(typ)
+	var (
+		lastPublic  = lastPublicField(typ)
+		anyOptional = false
+	)
 	for i := 0; i < typ.NumField(); i++ {
 		if f := typ.Field(i); f.PkgPath == "" { // exported
 			tags, err := parseStructTag(typ, i, lastPublic)
 			if err != nil {
 				return nil, err
 			}
+
+			// Skip rlp:"-" fields.
 			if tags.ignored {
 				continue
 			}
-			info := cachedTypeInfo1(f.Type, tags)
-			fields = append(fields, field{i, info})
+			// If any field has the "optional" tag, subsequent fields must also have it.
+			if tags.optional || tags.tail {
+				anyOptional = true
+			} else if anyOptional {
+				return nil, fmt.Errorf(`rlp: struct field %v.%s needs "optional" tag`, typ, f.Name)
+			}
+			info := theTC.infoWhileGenerating(f.Type, tags)
+			fields = append(fields, field{i, info, tags.optional})
 		}
 	}
 	return fields, nil
 }
 
+// anyOptionalFields returns the index of the first field with "optional" tag.
+func firstOptionalField(fields []field) int {
+	for i, f := range fields {
+		if f.optional {
+			return i
+		}
+	}
+	return len(fields)
+}
+
 type structFieldError struct {
 	typ   reflect.Type
 	field int
@@ -166,11 +222,19 @@ func parseStructTag(typ reflect.Type, fi, lastPublic int) (tags, error) {
 			case "nilList":
 				ts.nilKind = List
 			}
+		case "optional":
+			ts.optional = true
+			if ts.tail {
+				return ts, structTagError{typ, f.Name, t, `also has "tail" tag`}
+			}
 		case "tail":
 			ts.tail = true
 			if fi != lastPublic {
 				return ts, structTagError{typ, f.Name, t, "must be on last field"}
 			}
+			if ts.optional {
+				return ts, structTagError{typ, f.Name, t, `also has "optional" tag`}
+			}
 			if f.Type.Kind() != reflect.Slice {
 				return ts, structTagError{typ, f.Name, t, "field type is not slice"}
 			}
diff --git a/tests/vm_test.go b/rlp/unsafe.go
similarity index 52%
rename from tests/vm_test.go
rename to rlp/unsafe.go
index fb839827acc943cadaf1e19181476d11ea1830af..94ed5405a8e4e21fc7ffa81bf41cd14f155540f3 100644
--- a/tests/vm_test.go
+++ b/rlp/unsafe.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The go-ethereum Authors
+// Copyright 2021 The go-ethereum Authors
 // This file is part of the go-ethereum library.
 //
 // The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,26 +14,22 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-package tests
+// +build !nacl,!js,cgo
 
-import (
-	"testing"
+package rlp
 
-	"github.com/ethereum/go-ethereum/core/vm"
+import (
+	"reflect"
+	"unsafe"
 )
 
-func TestVM(t *testing.T) {
-	t.Parallel()
-	vmt := new(testMatcher)
-	vmt.slow("^vmPerformance")
-	vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
-
-	vmt.walk(t, vmTestDir, func(t *testing.T, name string, test *VMTest) {
-		withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
-			return vmt.checkFailure(t, name+"/trie", test.Run(vmconfig, false))
-		})
-		withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
-			return vmt.checkFailure(t, name+"/snap", test.Run(vmconfig, true))
-		})
-	})
+// byteArrayBytes returns a slice of the byte array v.
+func byteArrayBytes(v reflect.Value) []byte {
+	len := v.Len()
+	var s []byte
+	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
+	hdr.Data = v.UnsafeAddr()
+	hdr.Cap = len
+	hdr.Len = len
+	return s
 }
diff --git a/rpc/types.go b/rpc/types.go
index d1b878c7858ff0bff76458e2d9b9f993d91a512e..ad068defa8865f378ff8afddb2fb01e989748e11 100644
--- a/rpc/types.go
+++ b/rpc/types.go
@@ -21,6 +21,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"math"
+	"strconv"
 	"strings"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -191,3 +192,24 @@ func BlockNumberOrHashWithHash(hash common.Hash, canonical bool) BlockNumberOrHa
 		RequireCanonical: canonical,
 	}
 }
+
+// DecimalOrHex unmarshals a non-negative decimal or hex parameter into a uint64.
+type DecimalOrHex uint64
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (dh *DecimalOrHex) UnmarshalJSON(data []byte) error {
+	input := strings.TrimSpace(string(data))
+	if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
+		input = input[1 : len(input)-1]
+	}
+
+	value, err := strconv.ParseUint(input, 10, 64)
+	if err != nil {
+		value, err = hexutil.DecodeUint64(input)
+	}
+	if err != nil {
+		return err
+	}
+	*dh = DecimalOrHex(value)
+	return nil
+}
diff --git a/rpc/websocket.go b/rpc/websocket.go
index ab55ae69c100abb7f9ba3fc68513bfe22110d269..afeb4c2081b84202bf013f38ae60effd9d7ae09a 100644
--- a/rpc/websocket.go
+++ b/rpc/websocket.go
@@ -96,7 +96,7 @@ func wsHandshakeValidator(allowedOrigins []string) func(*http.Request) bool {
 		if _, ok := req.Header["Origin"]; !ok {
 			return true
 		}
-		// Verify origin against whitelist.
+		// Verify origin against allow list.
 		origin := strings.ToLower(req.Header.Get("Origin"))
 		if allowAllOrigins || originIsAllowed(origins, origin) {
 			return true
diff --git a/signer/core/api.go b/signer/core/api.go
index 3811162f8f8ca16c473fa79f7181f9fe0088595a..fb68018a6bcba74628cad1d6dd2aabd9a5bf1f0b 100644
--- a/signer/core/api.go
+++ b/signer/core/api.go
@@ -33,6 +33,7 @@ import (
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 	"github.com/ethereum/go-ethereum/signer/storage"
 )
 
@@ -52,7 +53,7 @@ type ExternalAPI interface {
 	// New request to create a new account
 	New(ctx context.Context) (common.Address, error)
 	// SignTransaction request to sign the specified transaction
-	SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error)
+	SignTransaction(ctx context.Context, args apitypes.SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error)
 	// SignData - request to sign the given data (plus prefix)
 	SignData(ctx context.Context, contentType string, addr common.MixedcaseAddress, data interface{}) (hexutil.Bytes, error)
 	// SignTypedData - request to sign the given structured data (plus prefix)
@@ -104,7 +105,7 @@ type Validator interface {
 	// ValidateTransaction does a number of checks on the supplied transaction, and
 	// returns either a list of warnings, or an error (indicating that the transaction
 	// should be immediately rejected).
-	ValidateTransaction(selector *string, tx *SendTxArgs) (*ValidationMessages, error)
+	ValidateTransaction(selector *string, tx *apitypes.SendTxArgs) (*apitypes.ValidationMessages, error)
 }
 
 // SignerAPI defines the actual implementation of ExternalAPI
@@ -220,24 +221,24 @@ func (m Metadata) String() string {
 type (
 	// SignTxRequest contains info about a Transaction to sign
 	SignTxRequest struct {
-		Transaction SendTxArgs       `json:"transaction"`
-		Callinfo    []ValidationInfo `json:"call_info"`
-		Meta        Metadata         `json:"meta"`
+		Transaction apitypes.SendTxArgs       `json:"transaction"`
+		Callinfo    []apitypes.ValidationInfo `json:"call_info"`
+		Meta        Metadata                  `json:"meta"`
 	}
 	// SignTxResponse result from SignTxRequest
 	SignTxResponse struct {
 		//The UI may make changes to the TX
-		Transaction SendTxArgs `json:"transaction"`
-		Approved    bool       `json:"approved"`
+		Transaction apitypes.SendTxArgs `json:"transaction"`
+		Approved    bool                `json:"approved"`
 	}
 	SignDataRequest struct {
-		ContentType string                  `json:"content_type"`
-		Address     common.MixedcaseAddress `json:"address"`
-		Rawdata     []byte                  `json:"raw_data"`
-		Messages    []*NameValueType        `json:"messages"`
-		Callinfo    []ValidationInfo        `json:"call_info"`
-		Hash        hexutil.Bytes           `json:"hash"`
-		Meta        Metadata                `json:"meta"`
+		ContentType string                    `json:"content_type"`
+		Address     common.MixedcaseAddress   `json:"address"`
+		Rawdata     []byte                    `json:"raw_data"`
+		Messages    []*NameValueType          `json:"messages"`
+		Callinfo    []apitypes.ValidationInfo `json:"call_info"`
+		Hash        hexutil.Bytes             `json:"hash"`
+		Meta        Metadata                  `json:"meta"`
 	}
 	SignDataResponse struct {
 		Approved bool `json:"approved"`
@@ -456,6 +457,16 @@ func (api *SignerAPI) newAccount() (common.Address, error) {
 // it also returns 'true' if the transaction was modified, to make it possible to configure the signer not to allow
 // UI-modifications to requests
 func logDiff(original *SignTxRequest, new *SignTxResponse) bool {
+	var intPtrModified = func(a, b *hexutil.Big) bool {
+		aBig := (*big.Int)(a)
+		bBig := (*big.Int)(b)
+		if aBig != nil && bBig != nil {
+			return aBig.Cmp(bBig) != 0
+		}
+		// One or both of them are nil
+		return a != b
+	}
+
 	modified := false
 	if f0, f1 := original.Transaction.From, new.Transaction.From; !reflect.DeepEqual(f0, f1) {
 		log.Info("Sender-account changed by UI", "was", f0, "is", f1)
@@ -469,9 +480,17 @@ func logDiff(original *SignTxRequest, new *SignTxResponse) bool {
 		modified = true
 		log.Info("Gas changed by UI", "was", g0, "is", g1)
 	}
-	if g0, g1 := big.Int(original.Transaction.GasPrice), big.Int(new.Transaction.GasPrice); g0.Cmp(&g1) != 0 {
+	if a, b := original.Transaction.GasPrice, new.Transaction.GasPrice; intPtrModified(a, b) {
+		log.Info("GasPrice changed by UI", "was", a, "is", b)
+		modified = true
+	}
+	if a, b := original.Transaction.MaxPriorityFeePerGas, new.Transaction.MaxPriorityFeePerGas; intPtrModified(a, b) {
+		log.Info("maxPriorityFeePerGas changed by UI", "was", a, "is", b)
+		modified = true
+	}
+	if a, b := original.Transaction.MaxFeePerGas, new.Transaction.MaxFeePerGas; intPtrModified(a, b) {
+		log.Info("maxFeePerGas changed by UI", "was", a, "is", b)
 		modified = true
-		log.Info("GasPrice changed by UI", "was", g0, "is", g1)
 	}
 	if v0, v1 := big.Int(original.Transaction.Value), big.Int(new.Transaction.Value); v0.Cmp(&v1) != 0 {
 		modified = true
@@ -519,7 +538,7 @@ func (api *SignerAPI) lookupOrQueryPassword(address common.Address, title, promp
 }
 
 // SignTransaction signs the given Transaction and returns it both as json and rlp-encoded form
-func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) {
+func (api *SignerAPI) SignTransaction(ctx context.Context, args apitypes.SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) {
 	var (
 		err    error
 		result SignTxResponse
@@ -530,7 +549,7 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
 	}
 	// If we are in 'rejectMode', then reject rather than show the user warnings
 	if api.rejectMode {
-		if err := msgs.getWarnings(); err != nil {
+		if err := msgs.GetWarnings(); err != nil {
 			return nil, err
 		}
 	}
@@ -567,7 +586,7 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
 		return nil, err
 	}
 	// Convert fields into a real transaction
-	var unsignedTx = result.Transaction.toTransaction()
+	var unsignedTx = result.Transaction.ToTransaction()
 	// Get the password for the transaction
 	pw, err := api.lookupOrQueryPassword(acc.Address, "Account password",
 		fmt.Sprintf("Please enter the password for account %s", acc.Address.String()))
@@ -603,7 +622,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common
 	}
 	// If we are in 'rejectMode', then reject rather than show the user warnings
 	if api.rejectMode {
-		if err := msgs.getWarnings(); err != nil {
+		if err := msgs.GetWarnings(); err != nil {
 			return nil, err
 		}
 	}
diff --git a/signer/core/api_test.go b/signer/core/api_test.go
index 800020b0cf00da0c6dc4899a8a3950eea493e84d..36f12f71a52d1e09a2f7879aa0c6abc75bcbe258 100644
--- a/signer/core/api_test.go
+++ b/signer/core/api_test.go
@@ -35,6 +35,7 @@ import (
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 	"github.com/ethereum/go-ethereum/signer/fourbyte"
 	"github.com/ethereum/go-ethereum/signer/storage"
 )
@@ -223,18 +224,18 @@ func TestNewAcc(t *testing.T) {
 	}
 }
 
-func mkTestTx(from common.MixedcaseAddress) core.SendTxArgs {
+func mkTestTx(from common.MixedcaseAddress) apitypes.SendTxArgs {
 	to := common.NewMixedcaseAddress(common.HexToAddress("0x1337"))
 	gas := hexutil.Uint64(21000)
 	gasPrice := (hexutil.Big)(*big.NewInt(2000000000))
 	value := (hexutil.Big)(*big.NewInt(1e18))
 	nonce := (hexutil.Uint64)(0)
 	data := hexutil.Bytes(common.Hex2Bytes("01020304050607080a"))
-	tx := core.SendTxArgs{
+	tx := apitypes.SendTxArgs{
 		From:     from,
 		To:       &to,
 		Gas:      gas,
-		GasPrice: gasPrice,
+		GasPrice: &gasPrice,
 		Value:    value,
 		Data:     &data,
 		Nonce:    nonce}
diff --git a/signer/core/types.go b/signer/core/apitypes/types.go
similarity index 64%
rename from signer/core/types.go
rename to signer/core/apitypes/types.go
index e952a21209c1e5f31181668d1023900a000793e1..625959219f66a30b485821a613f1c4e1cdff5e8f 100644
--- a/signer/core/types.go
+++ b/signer/core/apitypes/types.go
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-package core
+package apitypes
 
 import (
 	"encoding/json"
@@ -52,7 +52,7 @@ func (vs *ValidationMessages) Info(msg string) {
 }
 
 /// getWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present
-func (v *ValidationMessages) getWarnings() error {
+func (v *ValidationMessages) GetWarnings() error {
 	var messages []string
 	for _, msg := range v.Messages {
 		if msg.Typ == WARN || msg.Typ == CRIT {
@@ -66,14 +66,21 @@ func (v *ValidationMessages) getWarnings() error {
 }
 
 // SendTxArgs represents the arguments to submit a transaction
+// This struct is identical to ethapi.TransactionArgs, except for the usage of
+// common.MixedcaseAddress in From and To
 type SendTxArgs struct {
-	From     common.MixedcaseAddress  `json:"from"`
-	To       *common.MixedcaseAddress `json:"to"`
-	Gas      hexutil.Uint64           `json:"gas"`
-	GasPrice hexutil.Big              `json:"gasPrice"`
-	Value    hexutil.Big              `json:"value"`
-	Nonce    hexutil.Uint64           `json:"nonce"`
+	From                 common.MixedcaseAddress  `json:"from"`
+	To                   *common.MixedcaseAddress `json:"to"`
+	Gas                  hexutil.Uint64           `json:"gas"`
+	GasPrice             *hexutil.Big             `json:"gasPrice"`
+	MaxFeePerGas         *hexutil.Big             `json:"maxFeePerGas"`
+	MaxPriorityFeePerGas *hexutil.Big             `json:"maxPriorityFeePerGas"`
+	Value                hexutil.Big              `json:"value"`
+	Nonce                hexutil.Uint64           `json:"nonce"`
+
 	// We accept "data" and "input" for backwards-compatibility reasons.
+	// "input" is the newer name and should be preferred by clients.
+	// Issue detail: https://github.com/ethereum/go-ethereum/issues/15628
 	Data  *hexutil.Bytes `json:"data"`
 	Input *hexutil.Bytes `json:"input,omitempty"`
 
@@ -90,39 +97,60 @@ func (args SendTxArgs) String() string {
 	return err.Error()
 }
 
-func (args *SendTxArgs) toTransaction() *types.Transaction {
-	var input []byte
-	if args.Data != nil {
-		input = *args.Data
-	} else if args.Input != nil {
-		input = *args.Input
-	}
+// ToTransaction converts the arguments to a transaction.
+func (args *SendTxArgs) ToTransaction() *types.Transaction {
+	// Add the To-field, if specified
 	var to *common.Address
 	if args.To != nil {
-		_to := args.To.Address()
-		to = &_to
+		dstAddr := args.To.Address()
+		to = &dstAddr
+	}
+
+	var input []byte
+	if args.Input != nil {
+		input = *args.Input
+	} else if args.Data != nil {
+		input = *args.Data
 	}
+
 	var data types.TxData
-	if args.AccessList == nil {
-		data = &types.LegacyTx{
-			To:       to,
-			Nonce:    uint64(args.Nonce),
-			Gas:      uint64(args.Gas),
-			GasPrice: (*big.Int)(&args.GasPrice),
-			Value:    (*big.Int)(&args.Value),
-			Data:     input,
+	switch {
+	case args.MaxFeePerGas != nil:
+		al := types.AccessList{}
+		if args.AccessList != nil {
+			al = *args.AccessList
+		}
+		data = &types.DynamicFeeTx{
+			To:         to,
+			ChainID:    (*big.Int)(args.ChainID),
+			Nonce:      uint64(args.Nonce),
+			Gas:        uint64(args.Gas),
+			GasFeeCap:  (*big.Int)(args.MaxFeePerGas),
+			GasTipCap:  (*big.Int)(args.MaxPriorityFeePerGas),
+			Value:      (*big.Int)(&args.Value),
+			Data:       input,
+			AccessList: al,
 		}
-	} else {
+	case args.AccessList != nil:
 		data = &types.AccessListTx{
 			To:         to,
 			ChainID:    (*big.Int)(args.ChainID),
 			Nonce:      uint64(args.Nonce),
 			Gas:        uint64(args.Gas),
-			GasPrice:   (*big.Int)(&args.GasPrice),
+			GasPrice:   (*big.Int)(args.GasPrice),
 			Value:      (*big.Int)(&args.Value),
 			Data:       input,
 			AccessList: *args.AccessList,
 		}
+	default:
+		data = &types.LegacyTx{
+			To:       to,
+			Nonce:    uint64(args.Nonce),
+			Gas:      uint64(args.Gas),
+			GasPrice: (*big.Int)(args.GasPrice),
+			Value:    (*big.Int)(&args.Value),
+			Data:     input,
+		}
 	}
 	return types.NewTx(data)
 }
diff --git a/signer/core/auditlog.go b/signer/core/auditlog.go
index bda88a8b2e55a169d0fd18a2fb14ce04f5d06fe5..84877ee712cf43b71fbe91651939b48e0368af0c 100644
--- a/signer/core/auditlog.go
+++ b/signer/core/auditlog.go
@@ -24,6 +24,7 @@ import (
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/log"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 type AuditLogger struct {
@@ -43,7 +44,7 @@ func (l *AuditLogger) New(ctx context.Context) (common.Address, error) {
 	return l.api.New(ctx)
 }
 
-func (l *AuditLogger) SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) {
+func (l *AuditLogger) SignTransaction(ctx context.Context, args apitypes.SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) {
 	sel := "<nil>"
 	if methodSelector != nil {
 		sel = *methodSelector
diff --git a/signer/core/cliui.go b/signer/core/cliui.go
index e0375483c362c25e59c31741a25e35dabd5ba69c..05c60906cc0cd2fda2c7f1a5dfd017d1dee06c7e 100644
--- a/signer/core/cliui.go
+++ b/signer/core/cliui.go
@@ -113,10 +113,15 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro
 	} else {
 		fmt.Printf("to:    <contact creation>\n")
 	}
-	fmt.Printf("from:     %v\n", request.Transaction.From.String())
-	fmt.Printf("value:    %v wei\n", weival)
-	fmt.Printf("gas:      %v (%v)\n", request.Transaction.Gas, uint64(request.Transaction.Gas))
-	fmt.Printf("gasprice: %v wei\n", request.Transaction.GasPrice.ToInt())
+	fmt.Printf("from:               %v\n", request.Transaction.From.String())
+	fmt.Printf("value:              %v wei\n", weival)
+	fmt.Printf("gas:                %v (%v)\n", request.Transaction.Gas, uint64(request.Transaction.Gas))
+	if request.Transaction.MaxFeePerGas != nil {
+		fmt.Printf("maxFeePerGas:          %v wei\n", request.Transaction.MaxFeePerGas.ToInt())
+		fmt.Printf("maxPriorityFeePerGas:  %v wei\n", request.Transaction.MaxPriorityFeePerGas.ToInt())
+	} else {
+		fmt.Printf("gasprice: %v wei\n", request.Transaction.GasPrice.ToInt())
+	}
 	fmt.Printf("nonce:    %v (%v)\n", request.Transaction.Nonce, uint64(request.Transaction.Nonce))
 	if chainId := request.Transaction.ChainID; chainId != nil {
 		fmt.Printf("chainid:  %v\n", chainId)
diff --git a/signer/core/gnosis_safe.go b/signer/core/gnosis_safe.go
index e4385f9dc37acb5e1d15b5c34e1df08c41fc399f..bdf7f837a0f8e4ac064bb86733722561f3430932 100644
--- a/signer/core/gnosis_safe.go
+++ b/signer/core/gnosis_safe.go
@@ -7,6 +7,7 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/common/math"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 // GnosisSafeTx is a type to parse the safe-tx returned by the relayer,
@@ -76,12 +77,13 @@ func (tx *GnosisSafeTx) ToTypedData() TypedData {
 
 // ArgsForValidation returns a SendTxArgs struct, which can be used for the
 // common validations, e.g. look up 4byte destinations
-func (tx *GnosisSafeTx) ArgsForValidation() *SendTxArgs {
-	args := &SendTxArgs{
+func (tx *GnosisSafeTx) ArgsForValidation() *apitypes.SendTxArgs {
+	gp := hexutil.Big(tx.GasPrice)
+	args := &apitypes.SendTxArgs{
 		From:     tx.Safe,
 		To:       &tx.To,
 		Gas:      hexutil.Uint64(tx.SafeTxGas.Uint64()),
-		GasPrice: hexutil.Big(tx.GasPrice),
+		GasPrice: &gp,
 		Value:    hexutil.Big(tx.Value),
 		Nonce:    hexutil.Uint64(tx.Nonce.Uint64()),
 		Data:     tx.Data,
diff --git a/signer/core/signed_data.go b/signer/core/signed_data.go
index 42d9c18b75f2bdac5a4b8221aa7f0c6e336d773b..bd447ad01b024da0e54765c8f14bc25a7b593904 100644
--- a/signer/core/signed_data.go
+++ b/signer/core/signed_data.go
@@ -38,6 +38,7 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/rlp"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 type SigFormat struct {
@@ -327,7 +328,7 @@ func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAd
 // signTypedData is identical to the capitalized version, except that it also returns the hash (preimage)
 // - the signature preimage (hash)
 func (api *SignerAPI) signTypedData(ctx context.Context, addr common.MixedcaseAddress,
-	typedData TypedData, validationMessages *ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
+	typedData TypedData, validationMessages *apitypes.ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
 	domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
 	if err != nil {
 		return nil, nil, err
diff --git a/signer/fourbyte/validation.go b/signer/fourbyte/validation.go
index baec32f72c338c987d2f125bd5925f50f38c1852..58111e8e00c82adbf19667805cda1c27ac5482f1 100644
--- a/signer/fourbyte/validation.go
+++ b/signer/fourbyte/validation.go
@@ -23,14 +23,14 @@ import (
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 // ValidateTransaction does a number of checks on the supplied transaction, and
 // returns either a list of warnings, or an error (indicating that the transaction
 // should be immediately rejected).
-func (db *Database) ValidateTransaction(selector *string, tx *core.SendTxArgs) (*core.ValidationMessages, error) {
-	messages := new(core.ValidationMessages)
+func (db *Database) ValidateTransaction(selector *string, tx *apitypes.SendTxArgs) (*apitypes.ValidationMessages, error) {
+	messages := new(apitypes.ValidationMessages)
 
 	// Prevent accidental erroneous usage of both 'input' and 'data' (show stopper)
 	if tx.Data != nil && tx.Input != nil && !bytes.Equal(*tx.Data, *tx.Input) {
@@ -73,6 +73,16 @@ func (db *Database) ValidateTransaction(selector *string, tx *core.SendTxArgs) (
 	if bytes.Equal(tx.To.Address().Bytes(), common.Address{}.Bytes()) {
 		messages.Crit("Transaction recipient is the zero address")
 	}
+	switch {
+	case tx.GasPrice == nil && tx.MaxFeePerGas == nil:
+		messages.Crit("Neither 'gasPrice' nor 'maxFeePerGas' specified.")
+	case tx.GasPrice == nil && tx.MaxPriorityFeePerGas == nil:
+		messages.Crit("Neither 'gasPrice' nor 'maxPriorityFeePerGas' specified.")
+	case tx.GasPrice != nil && tx.MaxFeePerGas != nil:
+		messages.Crit("Both 'gasPrice' and 'maxFeePerGas' specified.")
+	case tx.GasPrice != nil && tx.MaxPriorityFeePerGas != nil:
+		messages.Crit("Both 'gasPrice' and 'maxPriorityFeePerGas' specified.")
+	}
 	// Semantic fields validated, try to make heads or tails of the call data
 	db.ValidateCallData(selector, data, messages)
 	return messages, nil
@@ -80,7 +90,7 @@ func (db *Database) ValidateTransaction(selector *string, tx *core.SendTxArgs) (
 
 // ValidateCallData checks if the ABI call-data + method selector (if given) can
 // be parsed and seems to match.
-func (db *Database) ValidateCallData(selector *string, data []byte, messages *core.ValidationMessages) {
+func (db *Database) ValidateCallData(selector *string, data []byte, messages *apitypes.ValidationMessages) {
 	// If the data is empty, we have a plain value transfer, nothing more to do
 	if len(data) == 0 {
 		return
diff --git a/signer/fourbyte/validation_test.go b/signer/fourbyte/validation_test.go
index 0e98cd88e4b466993335e9bf418807a35ebb8985..c3085696f432685aea3ed9656bd95af760c9f418 100644
--- a/signer/fourbyte/validation_test.go
+++ b/signer/fourbyte/validation_test.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
-	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 )
 
 func mixAddr(a string) (*common.MixedcaseAddress, error) {
@@ -36,7 +36,7 @@ func toHexUint(h string) hexutil.Uint64 {
 	b := big.NewInt(0).SetBytes(common.FromHex(h))
 	return hexutil.Uint64(b.Uint64())
 }
-func dummyTxArgs(t txtestcase) *core.SendTxArgs {
+func dummyTxArgs(t txtestcase) *apitypes.SendTxArgs {
 	to, _ := mixAddr(t.to)
 	from, _ := mixAddr(t.from)
 	n := toHexUint(t.n)
@@ -55,12 +55,12 @@ func dummyTxArgs(t txtestcase) *core.SendTxArgs {
 		input = &a
 
 	}
-	return &core.SendTxArgs{
+	return &apitypes.SendTxArgs{
 		From:     *from,
 		To:       to,
 		Value:    value,
 		Nonce:    n,
-		GasPrice: gasPrice,
+		GasPrice: &gasPrice,
 		Gas:      gas,
 		Data:     data,
 		Input:    input,
diff --git a/signer/rules/rules_test.go b/signer/rules/rules_test.go
index 510c57e67fe1a1a26cfd6d8f313a9f3618034375..d506ef2db09f2b6e1d7455c8c7c08d896db6a419 100644
--- a/signer/rules/rules_test.go
+++ b/signer/rules/rules_test.go
@@ -28,6 +28,7 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/signer/core"
+	"github.com/ethereum/go-ethereum/signer/core/apitypes"
 	"github.com/ethereum/go-ethereum/signer/storage"
 )
 
@@ -180,7 +181,7 @@ func TestSignTxRequest(t *testing.T) {
 	}
 	t.Logf("to %v", to.Address().String())
 	resp, err := r.ApproveTx(&core.SignTxRequest{
-		Transaction: core.SendTxArgs{
+		Transaction: apitypes.SendTxArgs{
 			From: *from,
 			To:   to},
 		Callinfo: nil,
@@ -432,15 +433,15 @@ func dummyTx(value hexutil.Big) *core.SignTxRequest {
 	gasPrice := hexutil.Big(*big.NewInt(2000000))
 
 	return &core.SignTxRequest{
-		Transaction: core.SendTxArgs{
+		Transaction: apitypes.SendTxArgs{
 			From:     *from,
 			To:       to,
 			Value:    value,
 			Nonce:    n,
-			GasPrice: gasPrice,
+			GasPrice: &gasPrice,
 			Gas:      gas,
 		},
-		Callinfo: []core.ValidationInfo{
+		Callinfo: []apitypes.ValidationInfo{
 			{Typ: "Warning", Message: "All your base are bellong to us"},
 		},
 		Meta: core.Metadata{Remote: "remoteip", Local: "localip", Scheme: "inproc"},
diff --git a/tests/block_test.go b/tests/block_test.go
index 4820ba733fe080fdaf84573bf9a2eea37482a07d..74c7ed819763f9fb78baf719efc8efe790af988d 100644
--- a/tests/block_test.go
+++ b/tests/block_test.go
@@ -43,15 +43,14 @@ func TestBlockchain(t *testing.T) {
 
 	// Very slow test
 	bt.skipLoad(`.*/stTimeConsuming/.*`)
-
 	// test takes a lot for time and goes easily OOM because of sha3 calculation on a huge range,
 	// using 4.6 TGas
 	bt.skipLoad(`.*randomStatetest94.json.*`)
 	bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
-		if err := bt.checkFailure(t, name+"/trie", test.Run(false)); err != nil {
+		if err := bt.checkFailure(t, test.Run(false)); err != nil {
 			t.Errorf("test without snapshotter failed: %v", err)
 		}
-		if err := bt.checkFailure(t, name+"/snap", test.Run(true)); err != nil {
+		if err := bt.checkFailure(t, test.Run(true)); err != nil {
 			t.Errorf("test with snapshotter failed: %v", err)
 		}
 	})
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 745208b5b865eb0215af4eaa7e2c4af75a9646ab..bcf861e09b9c951ee15841b31adc1e4ee95f2a50 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -23,6 +23,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"math/big"
+	"os"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
@@ -59,9 +60,10 @@ type btJSON struct {
 }
 
 type btBlock struct {
-	BlockHeader  *btHeader
-	Rlp          string
-	UncleHeaders []*btHeader
+	BlockHeader     *btHeader
+	ExpectException string
+	Rlp             string
+	UncleHeaders    []*btHeader
 }
 
 //go:generate gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go
@@ -83,15 +85,17 @@ type btHeader struct {
 	GasLimit         uint64
 	GasUsed          uint64
 	Timestamp        uint64
+	BaseFeePerGas    *big.Int
 }
 
 type btHeaderMarshaling struct {
-	ExtraData  hexutil.Bytes
-	Number     *math.HexOrDecimal256
-	Difficulty *math.HexOrDecimal256
-	GasLimit   math.HexOrDecimal64
-	GasUsed    math.HexOrDecimal64
-	Timestamp  math.HexOrDecimal64
+	ExtraData     hexutil.Bytes
+	Number        *math.HexOrDecimal256
+	Difficulty    *math.HexOrDecimal256
+	GasLimit      math.HexOrDecimal64
+	GasUsed       math.HexOrDecimal64
+	Timestamp     math.HexOrDecimal64
+	BaseFeePerGas *math.HexOrDecimal256
 }
 
 func (t *BlockTest) Run(snapshotter bool) error {
@@ -166,6 +170,7 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
 		Mixhash:    t.json.Genesis.MixHash,
 		Coinbase:   t.json.Genesis.Coinbase,
 		Alloc:      t.json.Pre,
+		BaseFee:    t.json.Genesis.BaseFeePerGas,
 	}
 }
 
@@ -184,7 +189,7 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
 func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) {
 	validBlocks := make([]btBlock, 0)
 	// insert the test blocks, which will execute all transactions
-	for _, b := range t.json.Blocks {
+	for bi, b := range t.json.Blocks {
 		cb, err := b.decode()
 		if err != nil {
 			if b.BlockHeader == nil {
@@ -204,7 +209,12 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
 			}
 		}
 		if b.BlockHeader == nil {
-			return nil, fmt.Errorf("block insertion should have failed")
+			if data, err := json.MarshalIndent(cb.Header(), "", "  "); err == nil {
+				fmt.Fprintf(os.Stderr, "block (index %d) insertion should have failed due to: %v:\n%v\n",
+					bi, b.ExpectException, string(data))
+			}
+			return nil, fmt.Errorf("block (index %d) insertion should have failed due to: %v",
+				bi, b.ExpectException)
 		}
 
 		// validate RLP decoding by checking all values against test file JSON
diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go
index e80cd248bc7d918249cefaeefac46e1e26c3f736..acbf96e71247b19eb9fe7ece4cff6743dc55dd4c 100644
--- a/tests/difficulty_test.go
+++ b/tests/difficulty_test.go
@@ -79,12 +79,12 @@ func TestDifficulty(t *testing.T) {
 	dt.config("difficulty.json", mainnetChainConfig)
 
 	dt.walk(t, difficultyTestDir, func(t *testing.T, name string, test *DifficultyTest) {
-		cfg := dt.findConfig(name)
+		cfg := dt.findConfig(t)
 		if test.ParentDifficulty.Cmp(params.MinimumDifficulty) < 0 {
 			t.Skip("difficulty below minimum")
 			return
 		}
-		if err := dt.checkFailure(t, name, test.Run(cfg)); err != nil {
+		if err := dt.checkFailure(t, test.Run(cfg)); err != nil {
 			t.Error(err)
 		}
 	})
diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go
index 298050ad3650ebfa3524e058929cfca97650b71f..c0f452f3edd514c89c67967e326e07e73324604c 100644
--- a/tests/fuzzers/bls12381/bls12381_fuzz.go
+++ b/tests/fuzzers/bls12381/bls12381_fuzz.go
@@ -159,7 +159,7 @@ func FuzzCrossG1MultiExp(data []byte) int {
 		gethPoints = append(gethPoints, new(bls12381.PointG1).Set(kp1))
 		gnarkPoints = append(gnarkPoints, *cp1)
 	}
-	if len(gethScalars) == 0{
+	if len(gethScalars) == 0 {
 		return 0
 	}
 	// compute multi exponentiation
diff --git a/tests/fuzzers/secp256k1/secp_fuzzer.go b/tests/fuzzers/secp256k1/secp_fuzzer.go
new file mode 100644
index 0000000000000000000000000000000000000000..53845b64334504520b8c3814e06f0157ca13039e
--- /dev/null
+++ b/tests/fuzzers/secp256k1/secp_fuzzer.go
@@ -0,0 +1,50 @@
+// Copyright 2021 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// build +gofuzz
+
+package secp256k1
+
+import (
+	"fmt"
+
+	"github.com/btcsuite/btcd/btcec"
+	"github.com/ethereum/go-ethereum/crypto/secp256k1"
+	fuzz "github.com/google/gofuzz"
+)
+
+func Fuzz(input []byte) int {
+	var (
+		fuzzer = fuzz.NewFromGoFuzz(input)
+		curveA = secp256k1.S256()
+		curveB = btcec.S256()
+		dataP1 []byte
+		dataP2 []byte
+	)
+	// first point
+	fuzzer.Fuzz(&dataP1)
+	x1, y1 := curveB.ScalarBaseMult(dataP1)
+	// second point
+	fuzzer.Fuzz(&dataP2)
+	x2, y2 := curveB.ScalarBaseMult(dataP2)
+	resAX, resAY := curveA.Add(x1, y1, x2, y2)
+	resBX, resBY := curveB.Add(x1, y1, x2, y2)
+	if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 {
+		fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2)
+		panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY))
+	}
+	return 0
+}
diff --git a/tests/fuzzers/secp256k1/secp_test.go b/tests/fuzzers/secp256k1/secp_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..76bae87086f5de66b0b226f0dc8bc1ed49fa233e
--- /dev/null
+++ b/tests/fuzzers/secp256k1/secp_test.go
@@ -0,0 +1,8 @@
+package secp256k1
+
+import "testing"
+
+func TestFuzzer(t *testing.T) {
+	test := "00000000N0000000/R00000000000000000U0000S0000000mkhP000000000000000U"
+	Fuzz([]byte(test))
+}
diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go
index f2e086a7b3be9c1063edd3f58ff54dbd72d2ba4b..4387f8db41c8b60bbfed380d06dfd4afb37944fe 100644
--- a/tests/gen_btheader.go
+++ b/tests/gen_btheader.go
@@ -33,6 +33,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
 		GasLimit         math.HexOrDecimal64
 		GasUsed          math.HexOrDecimal64
 		Timestamp        math.HexOrDecimal64
+		BaseFeePerGas    *math.HexOrDecimal256
 	}
 	var enc btHeader
 	enc.Bloom = b.Bloom
@@ -51,6 +52,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
 	enc.GasLimit = math.HexOrDecimal64(b.GasLimit)
 	enc.GasUsed = math.HexOrDecimal64(b.GasUsed)
 	enc.Timestamp = math.HexOrDecimal64(b.Timestamp)
+	enc.BaseFeePerGas = (*math.HexOrDecimal256)(b.BaseFeePerGas)
 	return json.Marshal(&enc)
 }
 
@@ -73,6 +75,7 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
 		GasLimit         *math.HexOrDecimal64
 		GasUsed          *math.HexOrDecimal64
 		Timestamp        *math.HexOrDecimal64
+		BaseFeePerGas    *math.HexOrDecimal256
 	}
 	var dec btHeader
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -126,5 +129,8 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
 	if dec.Timestamp != nil {
 		b.Timestamp = uint64(*dec.Timestamp)
 	}
+	if dec.BaseFeePerGas != nil {
+		b.BaseFeePerGas = (*big.Int)(dec.BaseFeePerGas)
+	}
 	return nil
 }
diff --git a/tests/gen_stenv.go b/tests/gen_stenv.go
index bfecc145b46b296039aa41c48f1a087b21bf3205..ecf7af8503825f62c05436f271f2c6208f148339 100644
--- a/tests/gen_stenv.go
+++ b/tests/gen_stenv.go
@@ -21,6 +21,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
 		GasLimit   math.HexOrDecimal64      `json:"currentGasLimit"   gencodec:"required"`
 		Number     math.HexOrDecimal64      `json:"currentNumber"     gencodec:"required"`
 		Timestamp  math.HexOrDecimal64      `json:"currentTimestamp"  gencodec:"required"`
+		BaseFee    *math.HexOrDecimal256    `json:"currentBaseFee"  gencodec:"optional"`
 	}
 	var enc stEnv
 	enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
@@ -28,6 +29,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
 	enc.GasLimit = math.HexOrDecimal64(s.GasLimit)
 	enc.Number = math.HexOrDecimal64(s.Number)
 	enc.Timestamp = math.HexOrDecimal64(s.Timestamp)
+	enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee)
 	return json.Marshal(&enc)
 }
 
@@ -39,6 +41,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
 		GasLimit   *math.HexOrDecimal64      `json:"currentGasLimit"   gencodec:"required"`
 		Number     *math.HexOrDecimal64      `json:"currentNumber"     gencodec:"required"`
 		Timestamp  *math.HexOrDecimal64      `json:"currentTimestamp"  gencodec:"required"`
+		BaseFee    *math.HexOrDecimal256     `json:"currentBaseFee"  gencodec:"optional"`
 	}
 	var dec stEnv
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -64,5 +67,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
 		return errors.New("missing required field 'currentTimestamp' for stEnv")
 	}
 	s.Timestamp = uint64(*dec.Timestamp)
+	if dec.BaseFee != nil {
+		s.BaseFee = (*big.Int)(dec.BaseFee)
+	}
 	return nil
 }
diff --git a/tests/gen_sttransaction.go b/tests/gen_sttransaction.go
index 2670f4f9c8e7eaea6e79cceb3d5a75e4a0a25e6e..7693a207a56cb84df59bd4d2584ef31bfdce29a8 100644
--- a/tests/gen_sttransaction.go
+++ b/tests/gen_sttransaction.go
@@ -16,17 +16,21 @@ var _ = (*stTransactionMarshaling)(nil)
 // MarshalJSON marshals as JSON.
 func (s stTransaction) MarshalJSON() ([]byte, error) {
 	type stTransaction struct {
-		GasPrice    *math.HexOrDecimal256 `json:"gasPrice"`
-		Nonce       math.HexOrDecimal64   `json:"nonce"`
-		To          string                `json:"to"`
-		Data        []string              `json:"data"`
-		AccessLists []*types.AccessList   `json:"accessLists,omitempty"`
-		GasLimit    []math.HexOrDecimal64 `json:"gasLimit"`
-		Value       []string              `json:"value"`
-		PrivateKey  hexutil.Bytes         `json:"secretKey"`
+		GasPrice             *math.HexOrDecimal256 `json:"gasPrice"`
+		MaxFeePerGas         *math.HexOrDecimal256 `json:"maxFeePerGas"`
+		MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"`
+		Nonce                math.HexOrDecimal64   `json:"nonce"`
+		To                   string                `json:"to"`
+		Data                 []string              `json:"data"`
+		AccessLists          []*types.AccessList   `json:"accessLists,omitempty"`
+		GasLimit             []math.HexOrDecimal64 `json:"gasLimit"`
+		Value                []string              `json:"value"`
+		PrivateKey           hexutil.Bytes         `json:"secretKey"`
 	}
 	var enc stTransaction
 	enc.GasPrice = (*math.HexOrDecimal256)(s.GasPrice)
+	enc.MaxFeePerGas = (*math.HexOrDecimal256)(s.MaxFeePerGas)
+	enc.MaxPriorityFeePerGas = (*math.HexOrDecimal256)(s.MaxPriorityFeePerGas)
 	enc.Nonce = math.HexOrDecimal64(s.Nonce)
 	enc.To = s.To
 	enc.Data = s.Data
@@ -45,14 +49,16 @@ func (s stTransaction) MarshalJSON() ([]byte, error) {
 // UnmarshalJSON unmarshals from JSON.
 func (s *stTransaction) UnmarshalJSON(input []byte) error {
 	type stTransaction struct {
-		GasPrice    *math.HexOrDecimal256 `json:"gasPrice"`
-		Nonce       *math.HexOrDecimal64  `json:"nonce"`
-		To          *string               `json:"to"`
-		Data        []string              `json:"data"`
-		AccessLists []*types.AccessList   `json:"accessLists,omitempty"`
-		GasLimit    []math.HexOrDecimal64 `json:"gasLimit"`
-		Value       []string              `json:"value"`
-		PrivateKey  *hexutil.Bytes        `json:"secretKey"`
+		GasPrice             *math.HexOrDecimal256 `json:"gasPrice"`
+		MaxFeePerGas         *math.HexOrDecimal256 `json:"maxFeePerGas"`
+		MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"`
+		Nonce                *math.HexOrDecimal64  `json:"nonce"`
+		To                   *string               `json:"to"`
+		Data                 []string              `json:"data"`
+		AccessLists          []*types.AccessList   `json:"accessLists,omitempty"`
+		GasLimit             []math.HexOrDecimal64 `json:"gasLimit"`
+		Value                []string              `json:"value"`
+		PrivateKey           *hexutil.Bytes        `json:"secretKey"`
 	}
 	var dec stTransaction
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -61,6 +67,12 @@ func (s *stTransaction) UnmarshalJSON(input []byte) error {
 	if dec.GasPrice != nil {
 		s.GasPrice = (*big.Int)(dec.GasPrice)
 	}
+	if dec.MaxFeePerGas != nil {
+		s.MaxFeePerGas = (*big.Int)(dec.MaxFeePerGas)
+	}
+	if dec.MaxPriorityFeePerGas != nil {
+		s.MaxPriorityFeePerGas = (*big.Int)(dec.MaxPriorityFeePerGas)
+	}
 	if dec.Nonce != nil {
 		s.Nonce = uint64(*dec.Nonce)
 	}
diff --git a/tests/gen_vmexec.go b/tests/gen_vmexec.go
deleted file mode 100644
index 2fe155152d0cdf9169d7aed98f325822605b1848..0000000000000000000000000000000000000000
--- a/tests/gen_vmexec.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package tests
-
-import (
-	"encoding/json"
-	"errors"
-	"math/big"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/common/hexutil"
-	"github.com/ethereum/go-ethereum/common/math"
-)
-
-var _ = (*vmExecMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (v vmExec) MarshalJSON() ([]byte, error) {
-	type vmExec struct {
-		Address  common.UnprefixedAddress `json:"address"  gencodec:"required"`
-		Caller   common.UnprefixedAddress `json:"caller"   gencodec:"required"`
-		Origin   common.UnprefixedAddress `json:"origin"   gencodec:"required"`
-		Code     hexutil.Bytes            `json:"code"     gencodec:"required"`
-		Data     hexutil.Bytes            `json:"data"     gencodec:"required"`
-		Value    *math.HexOrDecimal256    `json:"value"    gencodec:"required"`
-		GasLimit math.HexOrDecimal64      `json:"gas"      gencodec:"required"`
-		GasPrice *math.HexOrDecimal256    `json:"gasPrice" gencodec:"required"`
-	}
-	var enc vmExec
-	enc.Address = common.UnprefixedAddress(v.Address)
-	enc.Caller = common.UnprefixedAddress(v.Caller)
-	enc.Origin = common.UnprefixedAddress(v.Origin)
-	enc.Code = v.Code
-	enc.Data = v.Data
-	enc.Value = (*math.HexOrDecimal256)(v.Value)
-	enc.GasLimit = math.HexOrDecimal64(v.GasLimit)
-	enc.GasPrice = (*math.HexOrDecimal256)(v.GasPrice)
-	return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (v *vmExec) UnmarshalJSON(input []byte) error {
-	type vmExec struct {
-		Address  *common.UnprefixedAddress `json:"address"  gencodec:"required"`
-		Caller   *common.UnprefixedAddress `json:"caller"   gencodec:"required"`
-		Origin   *common.UnprefixedAddress `json:"origin"   gencodec:"required"`
-		Code     *hexutil.Bytes            `json:"code"     gencodec:"required"`
-		Data     *hexutil.Bytes            `json:"data"     gencodec:"required"`
-		Value    *math.HexOrDecimal256     `json:"value"    gencodec:"required"`
-		GasLimit *math.HexOrDecimal64      `json:"gas"      gencodec:"required"`
-		GasPrice *math.HexOrDecimal256     `json:"gasPrice" gencodec:"required"`
-	}
-	var dec vmExec
-	if err := json.Unmarshal(input, &dec); err != nil {
-		return err
-	}
-	if dec.Address == nil {
-		return errors.New("missing required field 'address' for vmExec")
-	}
-	v.Address = common.Address(*dec.Address)
-	if dec.Caller == nil {
-		return errors.New("missing required field 'caller' for vmExec")
-	}
-	v.Caller = common.Address(*dec.Caller)
-	if dec.Origin == nil {
-		return errors.New("missing required field 'origin' for vmExec")
-	}
-	v.Origin = common.Address(*dec.Origin)
-	if dec.Code == nil {
-		return errors.New("missing required field 'code' for vmExec")
-	}
-	v.Code = *dec.Code
-	if dec.Data == nil {
-		return errors.New("missing required field 'data' for vmExec")
-	}
-	v.Data = *dec.Data
-	if dec.Value == nil {
-		return errors.New("missing required field 'value' for vmExec")
-	}
-	v.Value = (*big.Int)(dec.Value)
-	if dec.GasLimit == nil {
-		return errors.New("missing required field 'gas' for vmExec")
-	}
-	v.GasLimit = uint64(*dec.GasLimit)
-	if dec.GasPrice == nil {
-		return errors.New("missing required field 'gasPrice' for vmExec")
-	}
-	v.GasPrice = (*big.Int)(dec.GasPrice)
-	return nil
-}
diff --git a/tests/init.go b/tests/init.go
index 67f706eb50bc0a70e6ff6c40769707a3fff8d403..b0a38e68b0740c332f302c56691c6f816ff669fe 100644
--- a/tests/init.go
+++ b/tests/init.go
@@ -141,7 +141,7 @@ var Forks = map[string]*params.ChainConfig{
 		PetersburgBlock:     big.NewInt(0),
 		IstanbulBlock:       big.NewInt(5),
 	},
-	"YOLOv3": {
+	"Berlin": {
 		ChainID:             big.NewInt(1),
 		HomesteadBlock:      big.NewInt(0),
 		EIP150Block:         big.NewInt(0),
@@ -151,11 +151,35 @@ var Forks = map[string]*params.ChainConfig{
 		ConstantinopleBlock: big.NewInt(0),
 		PetersburgBlock:     big.NewInt(0),
 		IstanbulBlock:       big.NewInt(0),
-		YoloV3Block:         big.NewInt(0),
+		BerlinBlock:         big.NewInt(0),
 	},
-	// This specification is subject to change, but is for now identical to YOLOv3
-	// for cross-client testing purposes
-	"Berlin": {
+	"BerlinToLondonAt5": {
+		ChainID:             big.NewInt(1),
+		HomesteadBlock:      big.NewInt(0),
+		EIP150Block:         big.NewInt(0),
+		EIP155Block:         big.NewInt(0),
+		EIP158Block:         big.NewInt(0),
+		ByzantiumBlock:      big.NewInt(0),
+		ConstantinopleBlock: big.NewInt(0),
+		PetersburgBlock:     big.NewInt(0),
+		IstanbulBlock:       big.NewInt(0),
+		BerlinBlock:         big.NewInt(0),
+		LondonBlock:         big.NewInt(5),
+	},
+	"London": {
+		ChainID:             big.NewInt(1),
+		HomesteadBlock:      big.NewInt(0),
+		EIP150Block:         big.NewInt(0),
+		EIP155Block:         big.NewInt(0),
+		EIP158Block:         big.NewInt(0),
+		ByzantiumBlock:      big.NewInt(0),
+		ConstantinopleBlock: big.NewInt(0),
+		PetersburgBlock:     big.NewInt(0),
+		IstanbulBlock:       big.NewInt(0),
+		BerlinBlock:         big.NewInt(0),
+		LondonBlock:         big.NewInt(0),
+	},
+	"Aleut": {
 		ChainID:             big.NewInt(1),
 		HomesteadBlock:      big.NewInt(0),
 		EIP150Block:         big.NewInt(0),
@@ -166,6 +190,7 @@ var Forks = map[string]*params.ChainConfig{
 		PetersburgBlock:     big.NewInt(0),
 		IstanbulBlock:       big.NewInt(0),
 		BerlinBlock:         big.NewInt(0),
+		LondonBlock:         big.NewInt(0),
 	},
 }
 
diff --git a/tests/init_test.go b/tests/init_test.go
index 5af3e44bff961ce032762a0efa726f8d402f647a..312ad8869a3754ab6899c8820845d4b8e12d4374 100644
--- a/tests/init_test.go
+++ b/tests/init_test.go
@@ -18,7 +18,6 @@ package tests
 
 import (
 	"encoding/json"
-	"flag"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -34,24 +33,12 @@ import (
 	"github.com/ethereum/go-ethereum/params"
 )
 
-// Command line flags to configure the interpreters.
-var (
-	testEVM   = flag.String("vm.evm", "", "EVM configuration")
-	testEWASM = flag.String("vm.ewasm", "", "EWASM configuration")
-)
-
-func TestMain(m *testing.M) {
-	flag.Parse()
-	os.Exit(m.Run())
-}
-
 var (
 	baseDir            = filepath.Join(".", "testdata")
 	blockTestDir       = filepath.Join(baseDir, "BlockchainTests")
 	stateTestDir       = filepath.Join(baseDir, "GeneralStateTests")
 	legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
 	transactionTestDir = filepath.Join(baseDir, "TransactionTests")
-	vmTestDir          = filepath.Join(baseDir, "VMTests")
 	rlpTestDir         = filepath.Join(baseDir, "RLPTests")
 	difficultyTestDir  = filepath.Join(baseDir, "BasicTests")
 )
@@ -101,11 +88,11 @@ func findLine(data []byte, offset int64) (line int) {
 
 // testMatcher controls skipping and chain config assignment to tests.
 type testMatcher struct {
-	configpat    []testConfig
-	failpat      []testFailure
-	skiploadpat  []*regexp.Regexp
-	slowpat      []*regexp.Regexp
-	whitelistpat *regexp.Regexp
+	configpat      []testConfig
+	failpat        []testFailure
+	skiploadpat    []*regexp.Regexp
+	slowpat        []*regexp.Regexp
+	runonlylistpat *regexp.Regexp
 }
 
 type testConfig struct {
@@ -136,8 +123,8 @@ func (tm *testMatcher) fails(pattern string, reason string) {
 	tm.failpat = append(tm.failpat, testFailure{regexp.MustCompile(pattern), reason})
 }
 
-func (tm *testMatcher) whitelist(pattern string) {
-	tm.whitelistpat = regexp.MustCompile(pattern)
+func (tm *testMatcher) runonly(pattern string) {
+	tm.runonlylistpat = regexp.MustCompile(pattern)
 }
 
 // config defines chain config for tests matching the pattern.
@@ -167,10 +154,9 @@ func (tm *testMatcher) findSkip(name string) (reason string, skipload bool) {
 }
 
 // findConfig returns the chain config matching defined patterns.
-func (tm *testMatcher) findConfig(name string) *params.ChainConfig {
-	// TODO(fjl): name can be derived from testing.T when min Go version is 1.8
+func (tm *testMatcher) findConfig(t *testing.T) *params.ChainConfig {
 	for _, m := range tm.configpat {
-		if m.p.MatchString(name) {
+		if m.p.MatchString(t.Name()) {
 			return &m.config
 		}
 	}
@@ -178,11 +164,10 @@ func (tm *testMatcher) findConfig(name string) *params.ChainConfig {
 }
 
 // checkFailure checks whether a failure is expected.
-func (tm *testMatcher) checkFailure(t *testing.T, name string, err error) error {
-	// TODO(fjl): name can be derived from t when min Go version is 1.8
+func (tm *testMatcher) checkFailure(t *testing.T, err error) error {
 	failReason := ""
 	for _, m := range tm.failpat {
-		if m.p.MatchString(name) {
+		if m.p.MatchString(t.Name()) {
 			failReason = m.reason
 			break
 		}
@@ -231,9 +216,9 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
 	if r, _ := tm.findSkip(name); r != "" {
 		t.Skip(r)
 	}
-	if tm.whitelistpat != nil {
-		if !tm.whitelistpat.MatchString(name) {
-			t.Skip("Skipped by whitelist")
+	if tm.runonlylistpat != nil {
+		if !tm.runonlylistpat.MatchString(name) {
+			t.Skip("Skipped by runonly")
 		}
 	}
 	t.Parallel()
@@ -290,10 +275,10 @@ func runTestFunc(runTest interface{}, t *testing.T, name string, m reflect.Value
 	})
 }
 
-func TestMatcherWhitelist(t *testing.T) {
+func TestMatcherRunonlylist(t *testing.T) {
 	t.Parallel()
 	tm := new(testMatcher)
-	tm.whitelist("invalid*")
+	tm.runonly("invalid*")
 	tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) {
 		if name[:len("invalidRLPTest.json")] != "invalidRLPTest.json" {
 			t.Fatalf("invalid test found: %s != invalidRLPTest.json", name)
diff --git a/tests/rlp_test.go b/tests/rlp_test.go
index 1601625df569b8b0965d65699bddbc364ffc303e..79a1683eb23a75308bf451443132d053228495e8 100644
--- a/tests/rlp_test.go
+++ b/tests/rlp_test.go
@@ -24,7 +24,7 @@ func TestRLP(t *testing.T) {
 	t.Parallel()
 	tm := new(testMatcher)
 	tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) {
-		if err := tm.checkFailure(t, name, test.Run()); err != nil {
+		if err := tm.checkFailure(t, test.Run()); err != nil {
 			t.Error(err)
 		}
 	})
diff --git a/tests/state_test.go b/tests/state_test.go
index b77a898c21f6268bb48465a3c068e5662a94569e..c2ca0e8d694861a4dff6fb61c30d2aae9c2bd18f 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -64,21 +64,30 @@ func TestState(t *testing.T) {
 			for _, subtest := range test.Subtests() {
 				subtest := subtest
 				key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)
-				name := name + "/" + key
 
 				t.Run(key+"/trie", func(t *testing.T) {
 					withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
 						_, _, err := test.Run(subtest, vmconfig, false)
-						return st.checkFailure(t, name+"/trie", err)
+						if err != nil && len(test.json.Post[subtest.Fork][subtest.Index].ExpectException) > 0 {
+							// Ignore expected errors (TODO MariusVanDerWijden check error string)
+							return nil
+						}
+						return st.checkFailure(t, err)
 					})
 				})
 				t.Run(key+"/snap", func(t *testing.T) {
 					withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
 						snaps, statedb, err := test.Run(subtest, vmconfig, true)
-						if _, err := snaps.Journal(statedb.IntermediateRoot(false)); err != nil {
-							return err
+						if snaps != nil && statedb != nil {
+							if _, err := snaps.Journal(statedb.IntermediateRoot(false)); err != nil {
+								return err
+							}
+						}
+						if err != nil && len(test.json.Post[subtest.Fork][subtest.Index].ExpectException) > 0 {
+							// Ignore expected errors (TODO MariusVanDerWijden check error string)
+							return nil
 						}
-						return st.checkFailure(t, name+"/snap", err)
+						return st.checkFailure(t, err)
 					})
 				})
 			}
@@ -91,7 +100,7 @@ const traceErrorLimit = 400000
 
 func withTrace(t *testing.T, gasLimit uint64, test func(vm.Config) error) {
 	// Use config from command line arguments.
-	config := vm.Config{EVMInterpreter: *testEVM, EWASMInterpreter: *testEWASM}
+	config := vm.Config{}
 	err := test(config)
 	if err == nil {
 		return
@@ -117,6 +126,6 @@ func withTrace(t *testing.T, gasLimit uint64, test func(vm.Config) error) {
 	} else {
 		t.Log("EVM operation log:\n" + buf.String())
 	}
-	//t.Logf("EVM output: 0x%x", tracer.Output())
-	//t.Logf("EVM error: %v", tracer.Error())
+	// t.Logf("EVM output: 0x%x", tracer.Output())
+	// t.Logf("EVM error: %v", tracer.Error())
 }
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index 46834de6daeb8e0b755c83bfdff8d55e71ff2eee..f7fb08bfbc8d7cde92aa1c0126801616a8eec275 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -65,9 +65,11 @@ type stJSON struct {
 }
 
 type stPostState struct {
-	Root    common.UnprefixedHash `json:"hash"`
-	Logs    common.UnprefixedHash `json:"logs"`
-	Indexes struct {
+	Root            common.UnprefixedHash `json:"hash"`
+	Logs            common.UnprefixedHash `json:"logs"`
+	TxBytes         hexutil.Bytes         `json:"txbytes"`
+	ExpectException string                `json:"expectException"`
+	Indexes         struct {
 		Data  int `json:"data"`
 		Gas   int `json:"gas"`
 		Value int `json:"value"`
@@ -82,6 +84,7 @@ type stEnv struct {
 	GasLimit   uint64         `json:"currentGasLimit"   gencodec:"required"`
 	Number     uint64         `json:"currentNumber"     gencodec:"required"`
 	Timestamp  uint64         `json:"currentTimestamp"  gencodec:"required"`
+	BaseFee    *big.Int       `json:"currentBaseFee"  gencodec:"optional"`
 }
 
 type stEnvMarshaling struct {
@@ -90,26 +93,31 @@ type stEnvMarshaling struct {
 	GasLimit   math.HexOrDecimal64
 	Number     math.HexOrDecimal64
 	Timestamp  math.HexOrDecimal64
+	BaseFee    *math.HexOrDecimal256
 }
 
 //go:generate gencodec -type stTransaction -field-override stTransactionMarshaling -out gen_sttransaction.go
 
 type stTransaction struct {
-	GasPrice    *big.Int            `json:"gasPrice"`
-	Nonce       uint64              `json:"nonce"`
-	To          string              `json:"to"`
-	Data        []string            `json:"data"`
-	AccessLists []*types.AccessList `json:"accessLists,omitempty"`
-	GasLimit    []uint64            `json:"gasLimit"`
-	Value       []string            `json:"value"`
-	PrivateKey  []byte              `json:"secretKey"`
+	GasPrice             *big.Int            `json:"gasPrice"`
+	MaxFeePerGas         *big.Int            `json:"maxFeePerGas"`
+	MaxPriorityFeePerGas *big.Int            `json:"maxPriorityFeePerGas"`
+	Nonce                uint64              `json:"nonce"`
+	To                   string              `json:"to"`
+	Data                 []string            `json:"data"`
+	AccessLists          []*types.AccessList `json:"accessLists,omitempty"`
+	GasLimit             []uint64            `json:"gasLimit"`
+	Value                []string            `json:"value"`
+	PrivateKey           []byte              `json:"secretKey"`
 }
 
 type stTransactionMarshaling struct {
-	GasPrice   *math.HexOrDecimal256
-	Nonce      math.HexOrDecimal64
-	GasLimit   []math.HexOrDecimal64
-	PrivateKey hexutil.Bytes
+	GasPrice             *math.HexOrDecimal256
+	MaxFeePerGas         *math.HexOrDecimal256
+	MaxPriorityFeePerGas *math.HexOrDecimal256
+	Nonce                math.HexOrDecimal64
+	GasLimit             []math.HexOrDecimal64
+	PrivateKey           hexutil.Bytes
 }
 
 // GetChainConfig takes a fork definition and returns a chain config.
@@ -177,16 +185,39 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
 	block := t.genesis(config).ToBlock(nil)
 	snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter)
 
+	var baseFee *big.Int
+	if config.IsLondon(new(big.Int)) {
+		baseFee = t.json.Env.BaseFee
+		if baseFee == nil {
+			// Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to
+			// parent - 2 : 0xa as the basefee for 'this' context.
+			baseFee = big.NewInt(0x0a)
+		}
+	}
 	post := t.json.Post[subtest.Fork][subtest.Index]
-	msg, err := t.json.Tx.toMessage(post)
+	msg, err := t.json.Tx.toMessage(post, baseFee)
 	if err != nil {
 		return nil, nil, common.Hash{}, err
 	}
 
+	// Try to recover tx with current signer
+	if len(post.TxBytes) != 0 {
+		var ttx types.Transaction
+		err := ttx.UnmarshalBinary(post.TxBytes)
+		if err != nil {
+			return nil, nil, common.Hash{}, err
+		}
+
+		if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil {
+			return nil, nil, common.Hash{}, err
+		}
+	}
+
 	// Prepare the EVM.
 	txContext := core.NewEVMTxContext(msg)
 	context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
 	context.GetHash = vmTestBlockHash
+	context.BaseFee = baseFee
 	evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)
 
 	// Execute the message.
@@ -248,7 +279,7 @@ func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis {
 	}
 }
 
-func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
+func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Message, error) {
 	// Derive sender from private key if present.
 	var from common.Address
 	if len(tx.PrivateKey) > 0 {
@@ -297,7 +328,27 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
 	if tx.AccessLists != nil && tx.AccessLists[ps.Indexes.Data] != nil {
 		accessList = *tx.AccessLists[ps.Indexes.Data]
 	}
-	msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, accessList, true)
+	// If baseFee provided, set gasPrice to effectiveGasPrice.
+	gasPrice := tx.GasPrice
+	if baseFee != nil {
+		if tx.MaxFeePerGas == nil {
+			tx.MaxFeePerGas = gasPrice
+		}
+		if tx.MaxFeePerGas == nil {
+			tx.MaxFeePerGas = new(big.Int)
+		}
+		if tx.MaxPriorityFeePerGas == nil {
+			tx.MaxPriorityFeePerGas = tx.MaxFeePerGas
+		}
+		gasPrice = math.BigMin(new(big.Int).Add(tx.MaxPriorityFeePerGas, baseFee),
+			tx.MaxFeePerGas)
+	}
+	if gasPrice == nil {
+		return nil, fmt.Errorf("no gas price provided")
+	}
+
+	msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, gasPrice,
+		tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false)
 	return msg, nil
 }
 
@@ -307,3 +358,7 @@ func rlpHash(x interface{}) (h common.Hash) {
 	hw.Sum(h[:0])
 	return h
 }
+
+func vmTestBlockHash(n uint64) common.Hash {
+	return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
+}
diff --git a/tests/testdata b/tests/testdata
index c600d7795aa2ea57a9c856fc79f72fc05b542124..092a8834dc445e683103689d6f0e75a5d380a190 160000
--- a/tests/testdata
+++ b/tests/testdata
@@ -1 +1 @@
-Subproject commit c600d7795aa2ea57a9c856fc79f72fc05b542124
+Subproject commit 092a8834dc445e683103689d6f0e75a5d380a190
diff --git a/tests/transaction_test.go b/tests/transaction_test.go
index 0e3670d04bf7ae7ad95ba5824e26e522fe735ed5..cb0f2623189c34a2dcba5871ac8c6a3d7b6ec3fb 100644
--- a/tests/transaction_test.go
+++ b/tests/transaction_test.go
@@ -47,7 +47,7 @@ func TestTransaction(t *testing.T) {
 	txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json")
 	txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) {
 		cfg := params.MainnetChainConfig
-		if err := txt.checkFailure(t, name, test.Run(cfg)); err != nil {
+		if err := txt.checkFailure(t, test.Run(cfg)); err != nil {
 			t.Error(err)
 		}
 	})
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
deleted file mode 100644
index 418cc6716864e8240436665adc2513e8366f8fb0..0000000000000000000000000000000000000000
--- a/tests/vm_test_util.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package tests
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"math/big"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/common/hexutil"
-	"github.com/ethereum/go-ethereum/common/math"
-	"github.com/ethereum/go-ethereum/core"
-	"github.com/ethereum/go-ethereum/core/rawdb"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/vm"
-	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/params"
-)
-
-// VMTest checks EVM execution without block or transaction context.
-// See https://github.com/ethereum/tests/wiki/VM-Tests for the test format specification.
-type VMTest struct {
-	json vmJSON
-}
-
-func (t *VMTest) UnmarshalJSON(data []byte) error {
-	return json.Unmarshal(data, &t.json)
-}
-
-type vmJSON struct {
-	Env           stEnv                 `json:"env"`
-	Exec          vmExec                `json:"exec"`
-	Logs          common.UnprefixedHash `json:"logs"`
-	GasRemaining  *math.HexOrDecimal64  `json:"gas"`
-	Out           hexutil.Bytes         `json:"out"`
-	Pre           core.GenesisAlloc     `json:"pre"`
-	Post          core.GenesisAlloc     `json:"post"`
-	PostStateRoot common.Hash           `json:"postStateRoot"`
-}
-
-//go:generate gencodec -type vmExec -field-override vmExecMarshaling -out gen_vmexec.go
-
-type vmExec struct {
-	Address  common.Address `json:"address"  gencodec:"required"`
-	Caller   common.Address `json:"caller"   gencodec:"required"`
-	Origin   common.Address `json:"origin"   gencodec:"required"`
-	Code     []byte         `json:"code"     gencodec:"required"`
-	Data     []byte         `json:"data"     gencodec:"required"`
-	Value    *big.Int       `json:"value"    gencodec:"required"`
-	GasLimit uint64         `json:"gas"      gencodec:"required"`
-	GasPrice *big.Int       `json:"gasPrice" gencodec:"required"`
-}
-
-type vmExecMarshaling struct {
-	Address  common.UnprefixedAddress
-	Caller   common.UnprefixedAddress
-	Origin   common.UnprefixedAddress
-	Code     hexutil.Bytes
-	Data     hexutil.Bytes
-	Value    *math.HexOrDecimal256
-	GasLimit math.HexOrDecimal64
-	GasPrice *math.HexOrDecimal256
-}
-
-func (t *VMTest) Run(vmconfig vm.Config, snapshotter bool) error {
-	snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter)
-	if snapshotter {
-		preRoot := statedb.IntermediateRoot(false)
-		defer func() {
-			if _, err := snaps.Journal(preRoot); err != nil {
-				panic(err)
-			}
-		}()
-	}
-	ret, gasRemaining, err := t.exec(statedb, vmconfig)
-
-	if t.json.GasRemaining == nil {
-		if err == nil {
-			return fmt.Errorf("gas unspecified (indicating an error), but VM returned no error")
-		}
-		if gasRemaining > 0 {
-			return fmt.Errorf("gas unspecified (indicating an error), but VM returned gas remaining > 0")
-		}
-		return nil
-	}
-	// Test declares gas, expecting outputs to match.
-	if !bytes.Equal(ret, t.json.Out) {
-		return fmt.Errorf("return data mismatch: got %x, want %x", ret, t.json.Out)
-	}
-	if gasRemaining != uint64(*t.json.GasRemaining) {
-		return fmt.Errorf("remaining gas %v, want %v", gasRemaining, *t.json.GasRemaining)
-	}
-	for addr, account := range t.json.Post {
-		for k, wantV := range account.Storage {
-			if haveV := statedb.GetState(addr, k); haveV != wantV {
-				return fmt.Errorf("wrong storage value at %x:\n  got  %x\n  want %x", k, haveV, wantV)
-			}
-		}
-	}
-	// if root := statedb.IntermediateRoot(false); root != t.json.PostStateRoot {
-	// 	return fmt.Errorf("post state root mismatch, got %x, want %x", root, t.json.PostStateRoot)
-	// }
-	if logs := rlpHash(statedb.Logs()); logs != common.Hash(t.json.Logs) {
-		return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, t.json.Logs)
-	}
-	return nil
-}
-
-func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
-	evm := t.newEVM(statedb, vmconfig)
-	e := t.json.Exec
-	return evm.Call(vm.AccountRef(e.Caller), e.Address, e.Data, e.GasLimit, e.Value)
-}
-
-func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
-	initialCall := true
-	canTransfer := func(db vm.StateDB, address common.Address, amount *big.Int) bool {
-		if initialCall {
-			initialCall = false
-			return true
-		}
-		return core.CanTransfer(db, address, amount)
-	}
-	transfer := func(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {}
-	txContext := vm.TxContext{
-		Origin:   t.json.Exec.Origin,
-		GasPrice: t.json.Exec.GasPrice,
-	}
-	context := vm.BlockContext{
-		CanTransfer: canTransfer,
-		Transfer:    transfer,
-		GetHash:     vmTestBlockHash,
-		Coinbase:    t.json.Env.Coinbase,
-		BlockNumber: new(big.Int).SetUint64(t.json.Env.Number),
-		Time:        new(big.Int).SetUint64(t.json.Env.Timestamp),
-		GasLimit:    t.json.Env.GasLimit,
-		Difficulty:  t.json.Env.Difficulty,
-	}
-	vmconfig.NoRecursion = true
-	return vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vmconfig)
-}
-
-func vmTestBlockHash(n uint64) common.Hash {
-	return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
-}
diff --git a/trie/database.go b/trie/database.go
index b18665770e46ce88c1bb8df5836b0116f57f49ce..f140a56642f552d9d61098259957d844099d4672 100644
--- a/trie/database.go
+++ b/trie/database.go
@@ -703,12 +703,6 @@ func (db *Database) Commit(node common.Hash, report bool, callback func(common.H
 	// Move all of the accumulated preimages into a write batch
 	if db.preimages != nil {
 		rawdb.WritePreimages(batch, db.preimages)
-		if batch.ValueSize() > ethdb.IdealBatchSize {
-			if err := batch.Write(); err != nil {
-				return err
-			}
-			batch.Reset()
-		}
 		// Since we're going to replay trie node writes into the clean cache, flush out
 		// any batched pre-images before continuing.
 		if err := batch.Write(); err != nil {
diff --git a/trie/sync_bloom.go b/trie/sync_bloom.go
index 1afcce21dab9ef994d9b4a4fd80af3b0635b4612..49986fcf0a91f56f137389bf1cd4b8e64bf0d902 100644
--- a/trie/sync_bloom.go
+++ b/trie/sync_bloom.go
@@ -45,11 +45,12 @@ var (
 // provided disk database on creation in a background thread and will only start
 // returning live results once that's finished.
 type SyncBloom struct {
-	bloom  *bloomfilter.Filter
-	inited uint32
-	closer sync.Once
-	closed uint32
-	pend   sync.WaitGroup
+	bloom   *bloomfilter.Filter
+	inited  uint32
+	closer  sync.Once
+	closed  uint32
+	pend    sync.WaitGroup
+	closeCh chan struct{}
 }
 
 // NewSyncBloom creates a new bloom filter of the given size (in megabytes) and
@@ -64,7 +65,8 @@ func NewSyncBloom(memory uint64, database ethdb.Iteratee) *SyncBloom {
 
 	// Assemble the fast sync bloom and init it from previous sessions
 	b := &SyncBloom{
-		bloom: bloom,
+		bloom:   bloom,
+		closeCh: make(chan struct{}),
 	}
 	b.pend.Add(2)
 	go func() {
@@ -125,16 +127,15 @@ func (b *SyncBloom) init(database ethdb.Iteratee) {
 // meter periodically recalculates the false positive error rate of the bloom
 // filter and reports it in a metric.
 func (b *SyncBloom) meter() {
+	// check every second
+	tick := time.NewTicker(1 * time.Second)
 	for {
-		// Report the current error ration. No floats, lame, scale it up.
-		bloomErrorGauge.Update(int64(b.bloom.FalsePosititveProbability() * 100000))
-
-		// Wait one second, but check termination more frequently
-		for i := 0; i < 10; i++ {
-			if atomic.LoadUint32(&b.closed) == 1 {
-				return
-			}
-			time.Sleep(100 * time.Millisecond)
+		select {
+		case <-tick.C:
+			// Report the current error ration. No floats, lame, scale it up.
+			bloomErrorGauge.Update(int64(b.bloom.FalsePosititveProbability() * 100000))
+		case <-b.closeCh:
+			return
 		}
 	}
 }
@@ -145,6 +146,7 @@ func (b *SyncBloom) Close() error {
 	b.closer.Do(func() {
 		// Ensure the initializer is stopped
 		atomic.StoreUint32(&b.closed, 1)
+		close(b.closeCh)
 		b.pend.Wait()
 
 		// Wipe the bloom, but mark it "uninited" just in case someone attempts an access
diff --git a/trie/trie.go b/trie/trie.go
index 7ed235fa8ac6a6df71ae226bbd55678357f552f5..e492a532cb280e3140259cdb0829d66dbabf8785 100644
--- a/trie/trie.go
+++ b/trie/trie.go
@@ -405,6 +405,14 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
 		n.flags = t.newFlag()
 		n.Children[key[0]] = nn
 
+		// Because n is a full node, it must've contained at least two children
+		// before the delete operation. If the new child value is non-nil, n still
+		// has at least two children after the deletion, and cannot be reduced to
+		// a short node.
+		if nn != nil {
+			return true, n, nil
+		}
+		// Reduction:
 		// Check how many non-nil entries are left after deleting and
 		// reduce the full node to a short node if only one entry is
 		// left. Since n must've contained at least two children