diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..151a3fabe --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,37 @@ +# Proposed changes +Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. + +## Types of changes + +What types of changes does your code introduce to XDC network? +_Put an `✅` in the boxes that apply_ + +- [ ] Bugfix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation Update (if none of the other choices apply) +- [ ] Regular KTLO or any of the maintaince work. e.g code style +- [ ] CICD Improvement + +## Impacted Components +Which part of the codebase this PR will touch base on, + +_Put an `✅` in the boxes that apply_ + +- [ ] Consensus +- [ ] Account +- [ ] Network +- [ ] Geth +- [ ] Smart Contract +- [ ] External components +- [ ] Not sure (Please specify below) + +## Checklist +_Put an `✅` in the boxes once you have confirmed below actions (or provide reasons on not doing so) that_ + +- [ ] This PR has sufficient test coverage (unit/integration test) OR I have provided reason in the PR description for not having test coverage +- [ ] Provide an end-to-end test plan in the PR description on how to manually test it on the devnet/testnet. +- [ ] Tested the backwards compatibility. +- [ ] Tested with XDC nodes running this version co-exist with those running the previous version. +- [ ] Relevant documentation has been updated as part of this PR +- [ ] N/A diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef0045df8..7ebf7aa7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: #allow manual trigger to workflow jobs: - test_build_and_push_to_docker_registry: + test_golang: name: Test, build and push image to registry runs-on: ubuntu-latest env: @@ -17,12 +17,48 @@ jobs: defaults: run: working-directory: ${{ env.GOPATH }}/src/XDC-Subnet + strategy: + fail-fast: false + matrix: + include: + - name: A-B tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[a-b].*") + - name: C-[a-m] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[a-m].*") + - name: C-[n-o] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[n-o].*") + - name: C-[p-z] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[p-z].*") + - name: D-I tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[d-i].*") + - name: J-N tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[j-n].*") + - name: O-R tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[o-r].*") + - name: S tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/s.*") + - name: T-Z tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[t-z].*") steps: - name: Check out code uses: actions/checkout@v3 with: path: ${{ env.GOPATH }}/src/XDC-Subnet - + - name: Set up Go 1.21.x + uses: actions/setup-go@v4 + with: + go-version: "1.21.x" # The Go version to download (if necessary) and use. + - name: Run tests + run: ${{ matrix.script }} + env: + GO111MODULE: auto + + test_nodejs: + name: Run nodejs tests + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 - name: Use Node.js uses: actions/setup-node@v1 with: @@ -32,16 +68,12 @@ jobs: cd contracts/validator/src yarn npx hardhat test - - name: Set up Go 1.21.x - uses: actions/setup-go@v4 - with: - go-version: "1.21.x" # The Go version to download (if necessary) and use. - - name: Run tests - run: | - make test - env: - GO111MODULE: auto + build: + needs: [test_golang, test_nodejs] + name: Build and push image to registry + runs-on: ubuntu-latest + steps: - name: Docker login env: DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} @@ -61,5 +93,4 @@ jobs: - name: Build and push image run: | docker build . --file docker/Dockerfile --tag ${{ steps.image.outputs.name }} - docker push ${{ steps.image.outputs.name }} - + docker push ${{ steps.image.outputs.name }} \ No newline at end of file diff --git a/.github/workflows/pr_test.yml b/.github/workflows/pr_test.yml index 485a9dff8..d9cd73842 100644 --- a/.github/workflows/pr_test.yml +++ b/.github/workflows/pr_test.yml @@ -3,10 +3,14 @@ on: pull_request: branches: - master + #TODO: remove push trigger + push: #temporary trigger tests this way + branches: + - '*' jobs: - test_on_pr: - name: Run tests on PR + test_golang: + name: Run golang tests runs-on: ubuntu-latest env: GOPATH: ${{ github.workspace }} @@ -14,11 +18,48 @@ jobs: defaults: run: working-directory: ${{ env.GOPATH }}/src/XDC-Subnet + strategy: + fail-fast: false + matrix: + include: + - name: A-B tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[a-b].*") + - name: C-[a-m] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[a-m].*") + - name: C-[n-o] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[n-o].*") + - name: C-[p-z] tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/c[p-z].*") + - name: D-I tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[d-i].*") + - name: J-N tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[j-n].*") + - name: O-R tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[o-r].*") + - name: S tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/s.*") + - name: T-Z tests + script: mv common/constants/constants.go.unittest common/constants.go; go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDC-Subnet/[t-z].*") steps: - name: Check out code uses: actions/checkout@v3 with: path: ${{ env.GOPATH }}/src/XDC-Subnet + - name: Set up Go 1.21.x + uses: actions/setup-go@v4 + with: + go-version: "1.21.x" # The Go version to download (if necessary) and use. + - name: Run tests + run: ${{ matrix.script }} + env: + GO111MODULE: auto + + test_nodejs: + name: Run nodejs tests + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 - name: Use Node.js uses: actions/setup-node@v1 with: @@ -28,12 +69,3 @@ jobs: cd contracts/validator/src yarn npx hardhat test - - name: Set up Go 1.21.x - uses: actions/setup-go@v4 - with: - go-version: "1.21.x" # The Go version to download (if necessary) and use. - - name: Run tests - run: | - make test - env: - GO111MODULE: auto diff --git a/.gitignore b/.gitignore index f34305b08..5047f65fc 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,11 @@ profile.cov **/yarn-error.log coverage.txt -go.sum \ No newline at end of file +<<<<<<< HEAD +go.sum +======= +go.sum +**/.terraform* +cicd/devnet/tmp +cicd/devnet/terraform/node-config.json +>>>>>>> fd8e7c9d624a085c70178ec7c8de7da274fe0a7c diff --git a/.travis.yml.bak b/.travis.yml.bak new file mode 100644 index 000000000..b4e3db53b --- /dev/null +++ b/.travis.yml.bak @@ -0,0 +1,180 @@ +sudo: required +language: go +go_import_path: github.com/XinFinOrg/XDPoSChain + +on: + branches: + - master + - dev-upgrade + tags: true + +env: + global: + - GOPROXY=https://proxy.golang.org + - GO111MODULE=on + # Terraform env + - tf_version=1.3.0 + # Setting terraform init CLI options - https://www.terraform.io/docs/commands/init.html + - tf_init_cli_options=" -input=false" + # Set terraform validation CLI options - https://www.terraform.io/docs/commands/validate.html + - tf_validation_cli_options="" + # Set terraform plan CLI options - https://www.terraform.io/docs/commands/plan.html + - tf_plan_cli_options=" -lock=false -input=false" + # Set terraform apply CLI options - https://www.terraform.io/docs/commands/apply.html + - tf_apply_cli_options=" -auto-approve -input=false" + + +jobs: + include: + - stage: Tests + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: A-B tests + script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[a-b].*") + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[a-m].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: C-[a-m] tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[n-o].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: C-[n-o] tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[p-z].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: C-[p-z] tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[d-i].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: D-I tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[j-n].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: J-N tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[o-r].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: O-R tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/s.*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: S tests + - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[t-z].*") + os: linux + dist: bionic + go: 1.21.x + env: + - GO111MODULE=auto + name: T-Z tests + + - stage: TAG Build + if: tag IS present + services: + - docker + install: skip + before_script: + - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + - docker --version # document the version travis is using + - docker build -t xinfinorg/xdposchain:$TRAVIS_TAG -f cicd/Dockerfile . + script: + - docker push xinfinorg/xdposchain:$TRAVIS_TAG + + - stage: (Devnet) Build, and push images + if: branch = dev-upgrade AND type = push AND tag IS blank + services: + - docker + install: skip + before_script: + - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + - docker --version # document the version travis is using + - docker pull xinfinorg/devnet:latest # build the "previous" tag so that our devnet environment can run with both old and new code at the same time. + - docker tag xinfinorg/devnet:latest xinfinorg/devnet:previous + - docker rmi xinfinorg/devnet:latest + - docker build -t xinfinorg/devnet:latest -f cicd/Dockerfile . + script: + - docker push xinfinorg/devnet:latest + - docker push xinfinorg/devnet:previous + + - stage: (Devnet)Terraform plan + if: branch = dev-upgrade AND type = push AND tag IS blank + dist: xenial + language: bash + install: + - wget https://releases.hashicorp.com/terraform/"$tf_version"/terraform_"$tf_version"_linux_amd64.zip + - unzip terraform_"$tf_version"_linux_amd64.zip + - sudo mv terraform /usr/local/bin/ + - rm terraform_"$tf_version"_linux_amd64.zip + script: + - echo "Pull request detected, creating change plan(Devnet)" + - cd cicd/devnet/terraform + # Terraform init, validate, then create change plan. If any fail, fail validation + - terraform init $tf_init_cli_options + - terraform validate $tf_validation_cli_options + - terraform plan $tf_plan_cli_options + + - stage: (Devnet) Terraform apply + if: branch = dev-upgrade AND type = push AND tag IS blank + dist: xenial + language: bash + install: + # Download and install terraform before each run + - wget https://releases.hashicorp.com/terraform/"$tf_version"/terraform_"$tf_version"_linux_amd64.zip + - unzip terraform_"$tf_version"_linux_amd64.zip + - sudo mv terraform /usr/local/bin/ + - rm terraform_"$tf_version"_linux_amd64.zip + - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + - unzip awscliv2.zip + - sudo ./aws/install + - export PATH=$PATH:$HOME/.local/bin # put aws in the path + script: + - echo "Merge detected, executing changes(Devnet)" + - cd cicd/devnet/terraform + # Terraform init and then apply changes to environment + - terraform init $tf_init_cli_options + - terraform apply $tf_apply_cli_options + - sleep 5 + - | + source .env + for ((i=$us_east_2_start;i<$us_east_2_end;i++)); do + echo "Force deploy xdc-$i" + aws ecs update-service --region us-east-2 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; + done + for ((i=$eu_west_1_start;i<$eu_west_1_end;i++)); do + echo "Force deploy xdc-$i" + aws ecs update-service --region eu-west-1 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; + done + for ((i=$ap_southeast_2_start;i<$ap_southeast_2_end;i++)); do + echo "Force deploy xdc-$i" + aws ecs update-service --region ap-southeast-2 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; + done + aws ecs update-service --region ap-southeast-1 --cluster devnet-xdcnode-cluster --service ecs-service-rpc1 --force-new-deployment --no-cli-pager; + + - stage: (Devnet) Send Deployment Notification + if: branch = dev-upgrade AND type = push AND tag IS blank + language: bash + script: + - curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=$TRAVIS_COMMIT" \ No newline at end of file diff --git a/XDCx/XDCx.go b/XDCx/XDCx.go index a4f3b2540..7e284bf2c 100644 --- a/XDCx/XDCx.go +++ b/XDCx/XDCx.go @@ -95,8 +95,14 @@ func NewMongoDBEngine(cfg *Config) *XDCxDAO.MongoDatabase { } func New(cfg *Config) *XDCX { - tokenDecimalCache, _ := lru.New(defaultCacheLimit) - orderCache, _ := lru.New(tradingstate.OrderCacheLimit) + tokenDecimalCache, err := lru.New(defaultCacheLimit) + if err != nil { + log.Warn("[XDCx-New] fail to create new lru for token decimal", "error", err) + } + orderCache, err := lru.New(tradingstate.OrderCacheLimit) + if err != nil { + log.Warn("[XDCx-New] fail to create new lru for order", "error", err) + } XDCX := &XDCX{ orderNonce: make(map[common.Address]*big.Int), Triegc: prque.New(), @@ -121,7 +127,10 @@ func New(cfg *Config) *XDCX { // Overflow returns an indication if the message queue is full. func (XDCx *XDCX) Overflow() bool { - val, _ := XDCx.settings.Load(overflowIdx) + val, ok := XDCx.settings.Load(overflowIdx) + if !ok { + log.Warn("[XDCx-Overflow] fail to load overflow index") + } return val.(bool) } @@ -198,20 +207,12 @@ func (XDCx *XDCX) ProcessOrderPending(header *types.Header, coinbase common.Addr S: common.BigToHash(S), }, } - cancel := false - if order.Status == tradingstate.OrderStatusCancelled { - cancel = true - } log.Info("Process order pending", "orderPending", order, "BaseToken", order.BaseToken.Hex(), "QuoteToken", order.QuoteToken) originalOrder := &tradingstate.OrderItem{} *originalOrder = *order originalOrder.Quantity = tradingstate.CloneBigInt(order.Quantity) - if cancel { - order.Status = tradingstate.OrderStatusCancelled - } - newTrades, newRejectedOrders, err := XDCx.CommitOrder(header, coinbase, chain, statedb, XDCXstatedb, tradingstate.GetTradingOrderBookHash(order.BaseToken, order.QuoteToken), order) for _, reject := range newRejectedOrders { @@ -579,17 +580,16 @@ func (XDCX *XDCX) GetEmptyTradingState() (*tradingstate.TradingStateDB, error) { func (XDCx *XDCX) GetStateCache() tradingstate.Database { return XDCx.StateCache } + func (XDCx *XDCX) HasTradingState(block *types.Block, author common.Address) bool { root, err := XDCx.GetTradingStateRoot(block, author) if err != nil { return false } _, err = XDCx.StateCache.OpenTrie(root) - if err != nil { - return false - } - return true + return err == nil } + func (XDCx *XDCX) GetTriegc() *prque.Prque { return XDCx.Triegc } @@ -639,7 +639,7 @@ func (XDCx *XDCX) RollbackReorgTxMatch(txhash common.Hash) error { continue } orderCacheAtTxHash := c.(map[common.Hash]tradingstate.OrderHistoryItem) - orderHistoryItem, _ := orderCacheAtTxHash[tradingstate.GetOrderHistoryKey(order.BaseToken, order.QuoteToken, order.Hash)] + orderHistoryItem := orderCacheAtTxHash[tradingstate.GetOrderHistoryKey(order.BaseToken, order.QuoteToken, order.Hash)] if (orderHistoryItem == tradingstate.OrderHistoryItem{}) { log.Debug("XDCx reorg: remove order due to empty orderHistory", "order", tradingstate.ToJSON(order)) if err := db.DeleteObject(order.Hash, &tradingstate.OrderItem{}); err != nil { diff --git a/XDCx/order_processor.go b/XDCx/order_processor.go index a2aa86e93..5c456fb64 100644 --- a/XDCx/order_processor.go +++ b/XDCx/order_processor.go @@ -2,11 +2,12 @@ package XDCx import ( "encoding/json" - "github.com/XinFinOrg/XDC-Subnet/core/types" "math/big" "strconv" "time" + "github.com/XinFinOrg/XDC-Subnet/core/types" + "github.com/XinFinOrg/XDC-Subnet/consensus" "fmt" @@ -303,7 +304,10 @@ func (XDCx *XDCX) processOrderList(coinbase common.Address, chain consensus.Chai } if tradedQuantity.Sign() > 0 { quantityToTrade = tradingstate.Sub(quantityToTrade, tradedQuantity) - tradingStateDB.SubAmountOrderItem(orderBook, orderId, price, tradedQuantity, side) + err := tradingStateDB.SubAmountOrderItem(orderBook, orderId, price, tradedQuantity, side) + if err != nil { + log.Warn("processOrderList SubAmountOrderItem", "err", err, "orderBook", orderBook, "orderId", orderId, "price", *price, "tradedQuantity", *tradedQuantity, "side", side) + } tradingStateDB.SetLastPrice(orderBook, price) log.Debug("Update quantity for orderId", "orderId", orderId.Hex()) log.Debug("TRADE", "orderBook", orderBook, "Taker price", price, "maker price", order.Price, "Amount", tradedQuantity, "orderId", orderId, "side", side) @@ -589,11 +593,22 @@ func DoSettleBalance(coinbase common.Address, takerOrder, makerOrder *tradingsta masternodeOwner := statedb.GetOwner(coinbase) statedb.AddBalance(masternodeOwner, matchingFee) - tradingstate.SetTokenBalance(takerOrder.UserAddress, newTakerInTotal, settleBalance.Taker.InToken, statedb) - tradingstate.SetTokenBalance(takerOrder.UserAddress, newTakerOutTotal, settleBalance.Taker.OutToken, statedb) - - tradingstate.SetTokenBalance(makerOrder.UserAddress, newMakerInTotal, settleBalance.Maker.InToken, statedb) - tradingstate.SetTokenBalance(makerOrder.UserAddress, newMakerOutTotal, settleBalance.Maker.OutToken, statedb) + err = tradingstate.SetTokenBalance(takerOrder.UserAddress, newTakerInTotal, settleBalance.Taker.InToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "takerOder.UserAddress", takerOrder.UserAddress, "newTakerInTotal", *newTakerInTotal, "settleBalance.Taker.InToken", settleBalance.Taker.InToken) + } + err = tradingstate.SetTokenBalance(takerOrder.UserAddress, newTakerOutTotal, settleBalance.Taker.OutToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "takerOrder.UserAddress", takerOrder.UserAddress, "newTakerOutTotal", *newTakerOutTotal, "settleBalance.Taker.OutToken", settleBalance.Taker.OutToken) + } + err = tradingstate.SetTokenBalance(makerOrder.UserAddress, newMakerInTotal, settleBalance.Maker.InToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "makerOrder.UserAddress", makerOrder.UserAddress, "newMakerInTotal", *newMakerInTotal, "settleBalance.Maker.InToken", settleBalance.Maker.InToken) + } + err = tradingstate.SetTokenBalance(makerOrder.UserAddress, newMakerOutTotal, settleBalance.Maker.OutToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "makerOrder.UserAddress", makerOrder.UserAddress, "newMakerOutTotal", *newMakerOutTotal, "settleBalance.Maker.OutToken", settleBalance.Maker.OutToken) + } // add balance for relayers //log.Debug("ApplyXDCXMatchedTransaction settle fee for relayers", @@ -602,8 +617,14 @@ func DoSettleBalance(coinbase common.Address, takerOrder, makerOrder *tradingsta // "makerRelayerOwner", makerExOwner, // "makerFeeToken", quoteToken, "makerFee", settleBalanceResult[makerAddr][XDCx.Fee].(*big.Int)) // takerFee - tradingstate.SetTokenBalance(takerExOwner, newTakerFee, makerOrder.QuoteToken, statedb) - tradingstate.SetTokenBalance(makerExOwner, newMakerFee, makerOrder.QuoteToken, statedb) + err = tradingstate.SetTokenBalance(takerExOwner, newTakerFee, makerOrder.QuoteToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "takerExOwner", takerExOwner, "newTakerFee", *newTakerFee, "makerOrder.QuoteToken", makerOrder.QuoteToken) + } + err = tradingstate.SetTokenBalance(makerExOwner, newMakerFee, makerOrder.QuoteToken, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "makerExOwner", makerExOwner, "newMakerFee", *newMakerFee, "makerOrder.QuoteToken", makerOrder.QuoteToken) + } return nil } @@ -652,7 +673,10 @@ func (XDCx *XDCX) ProcessCancelOrder(header *types.Header, tradingStateDB *tradi return err, false } // relayers pay XDC for masternode - tradingstate.SubRelayerFee(originOrder.ExchangeAddress, common.RelayerCancelFee, statedb) + err = tradingstate.SubRelayerFee(originOrder.ExchangeAddress, common.RelayerCancelFee, statedb) + if err != nil { + log.Warn("ProcessCancelOrder SubRelayerFee", "err", err, "originOrder.ExchangeAddress", originOrder.ExchangeAddress, "common.RelayerCancelFee", *common.RelayerCancelFee) + } masternodeOwner := statedb.GetOwner(coinbase) // relayers pay XDC for masternode statedb.AddBalance(masternodeOwner, common.RelayerCancelFee) @@ -661,12 +685,24 @@ func (XDCx *XDCX) ProcessCancelOrder(header *types.Header, tradingStateDB *tradi switch originOrder.Side { case tradingstate.Ask: // users pay token (which they have) for relayer - tradingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.BaseToken, statedb) - tradingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.BaseToken, statedb) + err := tradingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.BaseToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder SubTokenBalance", "err", err, "originOrder.UserAddress", originOrder.UserAddress, "tokenCancelFee", *tokenCancelFee, "originOrder.BaseToken", originOrder.BaseToken) + } + err = tradingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.BaseToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder AddTokenBalance", "err", err, "relayerOwner", relayerOwner, "tokenCancelFee", *tokenCancelFee, "originOrder.BaseToken", originOrder.BaseToken) + } case tradingstate.Bid: // users pay token (which they have) for relayer - tradingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.QuoteToken, statedb) - tradingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.QuoteToken, statedb) + err := tradingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.QuoteToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder SubTokenBalance", "err", err, "originOrder.UserAddress", originOrder.UserAddress, "tokenCancelFee", *tokenCancelFee, "originOrder.QuoteToken", originOrder.QuoteToken) + } + err = tradingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.QuoteToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder AddTokenBalance", "err", err, "relayerOwner", relayerOwner, "tokenCancelFee", *tokenCancelFee, "originOrder.QuoteToken", originOrder.QuoteToken) + } default: } // update cancel fee diff --git a/XDCx/tradingstate/journal.go b/XDCx/tradingstate/journal.go index 629e12e43..c8c596a33 100644 --- a/XDCx/tradingstate/journal.go +++ b/XDCx/tradingstate/journal.go @@ -20,6 +20,7 @@ import ( "math/big" "github.com/XinFinOrg/XDC-Subnet/common" + "github.com/XinFinOrg/XDC-Subnet/log" ) type journalEntry interface { @@ -78,13 +79,19 @@ type ( ) func (ch insertOrder) undo(s *TradingStateDB) { - s.CancelOrder(ch.orderBook, ch.order) + err := s.CancelOrder(ch.orderBook, ch.order) + if err != nil { + log.Warn("undo CancelOrder", "err", err, "ch.orderBook", ch.orderBook, "ch.order", ch.order) + } } func (ch cancelOrder) undo(s *TradingStateDB) { s.InsertOrderItem(ch.orderBook, ch.orderId, ch.order) } func (ch insertLiquidationPrice) undo(s *TradingStateDB) { - s.RemoveLiquidationPrice(ch.orderBook, ch.price, ch.lendingBook, ch.tradeId) + err := s.RemoveLiquidationPrice(ch.orderBook, ch.price, ch.lendingBook, ch.tradeId) + if err != nil { + log.Warn("undo RemoveLiquidationPrice", "err", err, "ch.orderBook", ch.orderBook, "ch.price", ch.price, "ch.lendingBook", ch.lendingBook, "ch.tradeId", ch.tradeId) + } } func (ch removeLiquidationPrice) undo(s *TradingStateDB) { s.InsertLiquidationPrice(ch.orderBook, ch.price, ch.lendingBook, ch.tradeId) diff --git a/XDCx/tradingstate/relayer_state.go b/XDCx/tradingstate/relayer_state.go index 8f77592b2..daf502ca6 100644 --- a/XDCx/tradingstate/relayer_state.go +++ b/XDCx/tradingstate/relayer_state.go @@ -41,10 +41,7 @@ func IsResignedRelayer(relayer common.Address, statedb *state.StateDB) bool { slot := RelayerMappingSlot["RESIGN_REQUESTS"] locBig := GetLocMappingAtKey(relayer.Hash(), slot) locHash := common.BigToHash(locBig) - if statedb.GetState(common.HexToAddress(common.RelayerRegistrationSMC), locHash) != (common.Hash{}) { - return true - } - return false + return statedb.GetState(common.HexToAddress(common.RelayerRegistrationSMC), locHash) != (common.Hash{}) } func GetBaseTokenLength(relayer common.Address, statedb *state.StateDB) uint64 { diff --git a/XDCx/tradingstate/state_liquidationprice.go b/XDCx/tradingstate/state_liquidationprice.go index c47754558..1b87e1de0 100644 --- a/XDCx/tradingstate/state_liquidationprice.go +++ b/XDCx/tradingstate/state_liquidationprice.go @@ -118,7 +118,11 @@ func (self *liquidationPriceState) updateTrie(db Database) Trie { self.setError(tr.TryDelete(lendingId[:])) continue } - stateObject.updateRoot(db) + err := stateObject.updateRoot(db) + if err != nil { + log.Warn("updateTrie updateRoot", "err", err) + } + // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(stateObject) self.setError(tr.TryUpdate(lendingId[:], v)) diff --git a/XDCx/tradingstate/state_orderbook.go b/XDCx/tradingstate/state_orderbook.go index 5c93ba97e..1dff2165b 100644 --- a/XDCx/tradingstate/state_orderbook.go +++ b/XDCx/tradingstate/state_orderbook.go @@ -213,7 +213,10 @@ func (self *tradingExchanges) updateAsksTrie(db Database) Trie { self.setError(tr.TryDelete(price[:])) continue } - orderList.updateRoot(db) + err := orderList.updateRoot(db) + if err != nil { + log.Warn("updateAsksTrie updateRoot", "err", err, "price", price, "orderList", *orderList) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(orderList) self.setError(tr.TryUpdate(price[:], v)) @@ -279,7 +282,10 @@ func (self *tradingExchanges) updateBidsTrie(db Database) Trie { self.setError(tr.TryDelete(price[:])) continue } - orderList.updateRoot(db) + err := orderList.updateRoot(db) + if err != nil { + log.Warn("updateBidsTrie updateRoot", "err", err, "price", price, "orderList", *orderList) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(orderList) self.setError(tr.TryUpdate(price[:], v)) @@ -753,7 +759,10 @@ func (self *tradingExchanges) updateLiquidationPriceTrie(db Database) Trie { self.setError(tr.TryDelete(price[:])) continue } - stateObject.updateRoot(db) + err := stateObject.updateRoot(db) + if err != nil { + log.Warn("updateLiquidationPriceTrie updateRoot", "err", err, "price", price, "stateObject", *stateObject) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(stateObject) self.setError(tr.TryUpdate(price[:], v)) diff --git a/XDCx/tradingstate/statedb.go b/XDCx/tradingstate/statedb.go index c83c34fb2..8b619a52f 100644 --- a/XDCx/tradingstate/statedb.go +++ b/XDCx/tradingstate/statedb.go @@ -539,7 +539,10 @@ func (s *TradingStateDB) Finalise() { for addr, stateObject := range s.stateExhangeObjects { if _, isDirty := s.stateExhangeObjectsDirty[addr]; isDirty { // Write any storage changes in the state object to its storage trie. - stateObject.updateAsksRoot(s.db) + err := stateObject.updateAsksRoot(s.db) + if err != nil { + log.Warn("Finalise updateAsksRoot", "err", err, "addr", addr, "stateObject", *stateObject) + } stateObject.updateBidsRoot(s.db) stateObject.updateOrdersRoot(s.db) stateObject.updateLiquidationPriceRoot(s.db) @@ -713,7 +716,10 @@ func (self *TradingStateDB) RemoveLiquidationPrice(orderBook common.Hash, price lendingBookState.subVolume(One) liquidationPriceState.subVolume(One) if liquidationPriceState.Volume().Sign() == 0 { - orderbookState.getLiquidationPriceTrie(self.db).TryDelete(priceHash[:]) + err := orderbookState.getLiquidationPriceTrie(self.db).TryDelete(priceHash[:]) + if err != nil { + log.Warn("RemoveLiquidationPrice getLiquidationPriceTrie.TryDelete", "err", err, "priceHash", priceHash[:]) + } } orderbookState.subLendingCount(One) self.journal = append(self.journal, removeLiquidationPrice{ diff --git a/XDCxDAO/leveldb.go b/XDCxDAO/leveldb.go index 8f296edf1..de1e40ff8 100644 --- a/XDCxDAO/leveldb.go +++ b/XDCxDAO/leveldb.go @@ -58,7 +58,7 @@ func NewBatchDatabaseWithEncode(datadir string, cacheLimit int) *BatchDatabase { } func (db *BatchDatabase) IsEmptyKey(key []byte) bool { - return key == nil || len(key) == 0 || bytes.Equal(key, db.emptyKey) + return len(key) == 0 || bytes.Equal(key, db.emptyKey) } func (db *BatchDatabase) getCacheKey(key []byte) string { @@ -172,13 +172,13 @@ func (db *BatchDatabase) Sync() error { } func (db *BatchDatabase) NewIterator(prefix []byte, start []byte) ethdb.Iterator { - return db.NewIterator(prefix, start) + panic("NewIterator from XDCxDAO leveldb is not supported") } func (db *BatchDatabase) Stat(property string) (string, error) { - return db.Stat(property) + return "", errNotSupported } func (db *BatchDatabase) Compact(start []byte, limit []byte) error { - return db.Compact(start, limit) + return errNotSupported } diff --git a/XDCxDAO/mongodb.go b/XDCxDAO/mongodb.go index 5d71d883f..9e37510e9 100644 --- a/XDCxDAO/mongodb.go +++ b/XDCxDAO/mongodb.go @@ -4,6 +4,9 @@ import ( "bytes" "encoding/hex" "fmt" + "strings" + "time" + "github.com/XinFinOrg/XDC-Subnet/XDCx/tradingstate" "github.com/XinFinOrg/XDC-Subnet/XDCxlending/lendingstate" "github.com/XinFinOrg/XDC-Subnet/common" @@ -12,8 +15,6 @@ import ( "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" lru "github.com/hashicorp/golang-lru" - "strings" - "time" ) const ( @@ -77,7 +78,7 @@ func NewMongoDatabase(session *mgo.Session, dbName string, mongoURL string, repl } func (db *MongoDatabase) IsEmptyKey(key []byte) bool { - return key == nil || len(key) == 0 || bytes.Equal(key, db.emptyKey) + return len(key) == 0 || bytes.Equal(key, db.emptyKey) } func (db *MongoDatabase) getCacheKey(key []byte) string { @@ -873,15 +874,15 @@ func (db *MongoDatabase) Sync() error { } func (db *MongoDatabase) NewIterator(prefix []byte, start []byte) ethdb.Iterator { - return db.NewIterator(prefix, start) + panic("NewIterator from XDCxDAO mongodb is not supported") } func (db *MongoDatabase) Stat(property string) (string, error) { - return db.Stat(property) + return "", errNotSupported } func (db *MongoDatabase) Compact(start []byte, limit []byte) error { - return db.Compact(start, limit) + return errNotSupported } func (db *MongoDatabase) NewBatch() ethdb.Batch { diff --git a/XDCxlending/XDCxlending.go b/XDCxlending/XDCxlending.go index 157bdf40d..3cc49f8f1 100644 --- a/XDCxlending/XDCxlending.go +++ b/XDCxlending/XDCxlending.go @@ -144,20 +144,12 @@ func (l *Lending) ProcessOrderPending(header *types.Header, coinbase common.Addr S: common.BigToHash(S), }, } - cancel := false - if order.Status == lendingstate.LendingStatusCancelled { - cancel = true - } log.Info("Process order pending", "orderPending", order, "LendingToken", order.LendingToken.Hex(), "CollateralToken", order.CollateralToken) originalOrder := &lendingstate.LendingItem{} *originalOrder = *order originalOrder.Quantity = lendingstate.CloneBigInt(order.Quantity) - if cancel { - order.Status = lendingstate.LendingStatusCancelled - } - newTrades, newRejectedOrders, err := l.CommitOrder(header, coinbase, chain, statedb, lendingStatedb, tradingStateDb, lendingstate.GetLendingOrderBookHash(order.LendingToken, order.Term), order) for _, reject := range newRejectedOrders { log.Debug("Reject order", "reject", *reject) @@ -764,7 +756,7 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error { continue } cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingItemHistoryItem) - lendingItemHistory, _ := cacheAtTxHash[lendingstate.GetLendingItemHistoryKey(item.LendingToken, item.CollateralToken, item.Hash)] + lendingItemHistory := cacheAtTxHash[lendingstate.GetLendingItemHistoryKey(item.LendingToken, item.CollateralToken, item.Hash)] if (lendingItemHistory == lendingstate.LendingItemHistoryItem{}) { log.Debug("XDCxlending reorg: remove item due to empty lendingItemHistory", "item", lendingstate.ToJSON(item)) if err := db.DeleteObject(item.Hash, &lendingstate.LendingItem{}); err != nil { @@ -797,7 +789,7 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error { continue } cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingTradeHistoryItem) - lendingTradeHistoryItem, _ := cacheAtTxHash[trade.Hash] + lendingTradeHistoryItem := cacheAtTxHash[trade.Hash] if (lendingTradeHistoryItem == lendingstate.LendingTradeHistoryItem{}) { log.Debug("XDCxlending reorg: remove trade due to empty LendingTradeHistory", "trade", lendingstate.ToJSON(trade)) if err := db.DeleteObject(trade.Hash, &lendingstate.LendingTrade{}); err != nil { diff --git a/XDCxlending/lendingstate/journal.go b/XDCxlending/lendingstate/journal.go index 335e77ed4..86e5285f1 100644 --- a/XDCxlending/lendingstate/journal.go +++ b/XDCxlending/lendingstate/journal.go @@ -17,8 +17,11 @@ package lendingstate import ( - "github.com/XinFinOrg/XDC-Subnet/common" "math/big" + + "github.com/XinFinOrg/XDC-Subnet/common" + + "github.com/XinFinOrg/XDC-Subnet/log" ) type journalEntry interface { @@ -76,7 +79,10 @@ type ( ) func (ch insertOrder) undo(s *LendingStateDB) { - s.CancelLendingOrder(ch.orderBook, ch.order) + err := s.CancelLendingOrder(ch.orderBook, ch.order) + if err != nil { + log.Warn("undo CancelLendingOrder", "err", err, "ch.orderBook", ch.orderBook, "ch.order", *ch.order) + } } func (ch cancelOrder) undo(s *LendingStateDB) { s.InsertLendingItem(ch.orderBook, ch.orderId, ch.order) diff --git a/XDCxlending/lendingstate/lendingcontract.go b/XDCxlending/lendingstate/lendingcontract.go index 7362e0c4a..21d2a04c5 100644 --- a/XDCxlending/lendingstate/lendingcontract.go +++ b/XDCxlending/lendingstate/lendingcontract.go @@ -142,12 +142,11 @@ func IsValidPair(statedb *state.StateDB, coinbase common.Address, baseToken comm // @param baseToken: address of baseToken // @param terms: term // @return: -// - collaterals []common.Address : list of addresses of collateral -// - isSpecialCollateral : TRUE if collateral is a token which is NOT available for trading in XDCX, otherwise FALSE -func GetCollaterals(statedb *state.StateDB, coinbase common.Address, baseToken common.Address, term uint64) (collaterals []common.Address, isSpecialCollateral bool) { +// - collaterals []common.Address : list of addresses of collateral +func GetCollaterals(statedb *state.StateDB, coinbase common.Address, baseToken common.Address, term uint64) (collaterals []common.Address) { validPair, _ := IsValidPair(statedb, coinbase, baseToken, term) if !validPair { - return []common.Address{}, false + return []common.Address{} } //TODO: ILO Collateral is not supported in release 2.2.0 @@ -171,7 +170,7 @@ func GetCollaterals(statedb *state.StateDB, coinbase common.Address, baseToken c collaterals = append(collaterals, addr) } } - return collaterals, false + return collaterals } // @function GetCollateralDetail diff --git a/XDCxlending/lendingstate/lendingitem.go b/XDCxlending/lendingstate/lendingitem.go index e2c57e0d7..1aed9c998 100644 --- a/XDCxlending/lendingstate/lendingitem.go +++ b/XDCxlending/lendingstate/lendingitem.go @@ -2,14 +2,15 @@ package lendingstate import ( "fmt" + "math/big" + "strconv" + "time" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/core/state" "github.com/XinFinOrg/XDC-Subnet/core/types" "github.com/XinFinOrg/XDC-Subnet/crypto/sha3" "github.com/globalsign/mgo/bson" - "math/big" - "strconv" - "time" ) const ( @@ -26,6 +27,13 @@ const ( LendingStatusCancelled = "CANCELLED" Market = "MO" Limit = "LO" + /* + Based on all structs that were used to encode into extraData, we can see the liquidationData is likely be the one with max length in payload. + A assumptions was made that each numeric value (RecallAmount, LiquidationAmount, CollateralPrice) is up to 30 digits long and the Reason field is 20 characters long, the estimated maximum size of the ExtraData JSON string in the ProcessLiquidationData function would be approximately 185 bytes. + Hence the value of 200 has been chosen to safeguard the block/tx in XDC in terms of sizes. + + */ + MaxLendingExtraDataSize = 200 ) var ValidInputLendingStatus = map[string]bool{ @@ -232,6 +240,9 @@ func (l *LendingItem) VerifyLendingItem(state *state.StateDB) error { if err := l.VerifyLendingSignature(); err != nil { return err } + if err := l.VerifyLendingExtraData(); err != nil { + return err + } return nil } @@ -243,11 +254,11 @@ func (l *LendingItem) VerifyLendingSide() error { } func (l *LendingItem) VerifyCollateral(state *state.StateDB) error { - if l.CollateralToken.String() == EmptyAddress || l.CollateralToken.String() == l.LendingToken.String() { + if l.CollateralToken.IsZero() || l.CollateralToken == l.LendingToken { return fmt.Errorf("invalid collateral %s", l.CollateralToken.Hex()) } validCollateral := false - collateralList, _ := GetCollaterals(state, l.Relayer, l.LendingToken, l.Term) + collateralList := GetCollaterals(state, l.Relayer, l.LendingToken, l.Term) for _, collateral := range collateralList { if l.CollateralToken.String() == collateral.String() { validCollateral = true @@ -281,6 +292,13 @@ func (l *LendingItem) VerifyLendingType() error { return nil } +func (l *LendingItem) VerifyLendingExtraData() error { + if len(l.ExtraData) > MaxLendingExtraDataSize { + return fmt.Errorf("VerifyLendingExtraData: invalid lending extraData size. Size: %v", len(l.ExtraData)) + } + return nil +} + func (l *LendingItem) VerifyLendingStatus() error { if valid, ok := ValidInputLendingStatus[l.Status]; !ok && !valid { return fmt.Errorf("VerifyLendingStatus: invalid lending status. Status: %s", l.Status) @@ -329,7 +347,7 @@ func (l *LendingItem) EncodedSide() *big.Int { return big.NewInt(1) } -//verify signatures +// verify signatures func (l *LendingItem) VerifyLendingSignature() error { V := big.NewInt(int64(l.Signature.V)) R := l.Signature.R.Big() diff --git a/XDCxlending/lendingstate/lendingitem_test.go b/XDCxlending/lendingstate/lendingitem_test.go index 4c58f9b8f..776f4ca7a 100644 --- a/XDCxlending/lendingstate/lendingitem_test.go +++ b/XDCxlending/lendingstate/lendingitem_test.go @@ -2,17 +2,18 @@ package lendingstate import ( "fmt" + "math/big" + "math/rand" + "os" + "testing" + "time" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/core/rawdb" "github.com/XinFinOrg/XDC-Subnet/core/state" "github.com/XinFinOrg/XDC-Subnet/crypto" "github.com/XinFinOrg/XDC-Subnet/crypto/sha3" "github.com/XinFinOrg/XDC-Subnet/rpc" - "math/big" - "math/rand" - "os" - "testing" - "time" ) func TestLendingItem_VerifyLendingSide(t *testing.T) { @@ -108,6 +109,27 @@ func TestLendingItem_VerifyLendingType(t *testing.T) { } } +func TestLendingItem_VerifyExtraData(t *testing.T) { + tests := []struct { + name string + fields *LendingItem + wantErr bool + }{ + {"within the limit", &LendingItem{ExtraData: "123"}, false}, + {"within the limit", &LendingItem{ExtraData: "This is a string specifically designed to exceed 201 bytes in length. It contains enough characters, including spaces and punctuation, to ensure that its total size goes beyond the specified limit for demonstration purposes."}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := &LendingItem{ + ExtraData: tt.fields.ExtraData, + } + if err := l.VerifyLendingExtraData(); (err != nil) != tt.wantErr { + t.Errorf("VerifyLendingExtraData() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func TestLendingItem_VerifyLendingStatus(t *testing.T) { tests := []struct { name string diff --git a/XDCxlending/lendingstate/state_lendingbook.go b/XDCxlending/lendingstate/state_lendingbook.go index 71f9889a8..86e45ea0e 100644 --- a/XDCxlending/lendingstate/state_lendingbook.go +++ b/XDCxlending/lendingstate/state_lendingbook.go @@ -181,8 +181,10 @@ func (self *lendingExchangeState) getLiquidationTimeTrie(db Database) Trie { return self.liquidationTimeTrie } -/** - Get State +/* +* + + Get State */ func (self *lendingExchangeState) getBorrowingOrderList(db Database, rate common.Hash) (stateOrderList *itemListState) { // Prefer 'live' objects. @@ -299,8 +301,10 @@ func (self *lendingExchangeState) getLendingTrade(db Database, tradeId common.Ha return obj } -/** - Update Trie +/* +* + + Update Trie */ func (self *lendingExchangeState) updateLendingTimeTrie(db Database) Trie { tr := self.getLendingItemTrie(db) @@ -344,7 +348,10 @@ func (self *lendingExchangeState) updateBorrowingTrie(db Database) Trie { self.setError(tr.TryDelete(rate[:])) continue } - orderList.updateRoot(db) + err := orderList.updateRoot(db) + if err != nil { + log.Warn("updateBorrowingTrie updateRoot", "err", err, "rate", rate, "orderList", *orderList) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(orderList) self.setError(tr.TryUpdate(rate[:], v)) @@ -362,7 +369,10 @@ func (self *lendingExchangeState) updateInvestingTrie(db Database) Trie { self.setError(tr.TryDelete(rate[:])) continue } - orderList.updateRoot(db) + err := orderList.updateRoot(db) + if err != nil { + log.Warn("updateInvestingTrie updateRoot", "err", err, "rate", rate, "orderList", *orderList) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(orderList) self.setError(tr.TryUpdate(rate[:], v)) @@ -380,7 +390,10 @@ func (self *lendingExchangeState) updateLiquidationTimeTrie(db Database) Trie { self.setError(tr.TryDelete(time[:])) continue } - itemList.updateRoot(db) + err := itemList.updateRoot(db) + if err != nil { + log.Warn("updateLiquidationTimeTrie updateRoot", "err", err, "time", time, "itemList", *itemList) + } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(itemList) self.setError(tr.TryUpdate(time[:], v)) @@ -513,8 +526,10 @@ func (self *lendingExchangeState) CommitLiquidationTimeTrie(db Database) error { return err } -/** - Get Trie Data +/* +* + + Get Trie Data */ func (self *lendingExchangeState) getBestInvestingInterest(db Database) common.Hash { trie := self.getInvestingTrie(db) diff --git a/XDCxlending/lendingstate/statedb.go b/XDCxlending/lendingstate/statedb.go index 05e1c53fa..2e7bddbe4 100644 --- a/XDCxlending/lendingstate/statedb.go +++ b/XDCxlending/lendingstate/statedb.go @@ -524,7 +524,10 @@ func (s *LendingStateDB) Finalise() { for addr, stateObject := range s.lendingExchangeStates { if _, isDirty := s.lendingExchangeStatesDirty[addr]; isDirty { // Write any storage changes in the state object to its storage trie. - stateObject.updateInvestingRoot(s.db) + err := stateObject.updateInvestingRoot(s.db) + if err != nil { + log.Warn("Finalise updateInvestingRoot", "err", err, "addr", addr, "stateObject", *stateObject) + } stateObject.updateBorrowingRoot(s.db) stateObject.updateOrderRoot(s.db) stateObject.updateLendingTradeRoot(s.db) @@ -630,7 +633,10 @@ func (self *LendingStateDB) RemoveLiquidationTime(lendingBook common.Hash, trade liquidationTime.removeTradeId(self.db, tradeIdHash) liquidationTime.subVolume(One) if liquidationTime.Volume().Sign() == 0 { - lendingExchangeState.getLiquidationTimeTrie(self.db).TryDelete(timeHash[:]) + err := lendingExchangeState.getLiquidationTimeTrie(self.db).TryDelete(timeHash[:]) + if err != nil { + log.Warn("RemoveLiquidationTime getLiquidationTimeTrie.TryDelete", "err", err, "timeHash[:]", timeHash[:]) + } } return nil } diff --git a/XDCxlending/order_processor.go b/XDCxlending/order_processor.go index c67a008f4..1886bbc86 100644 --- a/XDCxlending/order_processor.go +++ b/XDCxlending/order_processor.go @@ -262,10 +262,9 @@ func (l *Lending) processOrderList(header *types.Header, coinbase common.Address collateralToken = oldestOrder.CollateralToken borrowFee = lendingstate.GetFee(statedb, oldestOrder.Relayer) } - if collateralToken.String() == lendingstate.EmptyAddress { + if collateralToken.IsZero() { return nil, nil, nil, fmt.Errorf("empty collateral") } - collateralPrice := common.BasePrice depositRate, liquidationRate, recallRate := lendingstate.GetCollateralDetail(statedb, collateralToken) if depositRate == nil || depositRate.Sign() <= 0 { return nil, nil, nil, fmt.Errorf("invalid depositRate %v", depositRate) @@ -339,7 +338,10 @@ func (l *Lending) processOrderList(header *types.Header, coinbase common.Address } if tradedQuantity.Sign() > 0 { quantityToTrade = lendingstate.Sub(quantityToTrade, tradedQuantity) - lendingStateDB.SubAmountLendingItem(lendingOrderBook, orderId, Interest, tradedQuantity, side) + err := lendingStateDB.SubAmountLendingItem(lendingOrderBook, orderId, Interest, tradedQuantity, side) + if err != nil { + log.Warn("processOrderList SubAmountLendingItem", "err", err, "lendingOrderBook", lendingOrderBook, "orderId", orderId, "Interest", *Interest, "tradedQuantity", *tradedQuantity, "side", side) + } log.Debug("Update quantity for orderId", "orderId", orderId.Hex()) log.Debug("LEND", "lendingOrderBook", lendingOrderBook.Hex(), "Taker Interest", Interest, "maker Interest", order.Interest, "Amount", tradedQuantity, "orderId", orderId, "side", side) tradingId := lendingStateDB.GetTradeNonce(lendingOrderBook) + 1 @@ -669,7 +671,10 @@ func DoSettleBalance(coinbase common.Address, takerOrder, makerOrder *lendingsta statedb.AddBalance(masternodeOwner, matchingFee) for token, balances := range mapBalances { for adrr, value := range balances { - lendingstate.SetTokenBalance(adrr, value, token, statedb) + err := lendingstate.SetTokenBalance(adrr, value, token, statedb) + if err != nil { + log.Warn("DoSettleBalance SetTokenBalance", "err", err, "addr", adrr, "value", *value, "token", token) + } } } return nil @@ -744,12 +749,24 @@ func (l *Lending) ProcessCancelOrder(header *types.Header, lendingStateDB *lendi switch originOrder.Side { case lendingstate.Investing: // users pay token for relayer - lendingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.LendingToken, statedb) - lendingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.LendingToken, statedb) + err := lendingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.LendingToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder SubTokenBalance", "err", err, "originOrder.UserAddress", originOrder.UserAddress, "tokenCancelFee", *tokenCancelFee, "originOrder.LendingToken", originOrder.LendingToken) + } + err = lendingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.LendingToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder AddTokenBalance", "err", err, "relayerOwner", relayerOwner, "tokenCancelFee", *tokenCancelFee, "originOrder.LendingToken", originOrder.LendingToken) + } case lendingstate.Borrowing: // users pay token for relayer - lendingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.CollateralToken, statedb) - lendingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.CollateralToken, statedb) + err := lendingstate.SubTokenBalance(originOrder.UserAddress, tokenCancelFee, originOrder.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder SubTokenBalance", "err", err, "originOrder.UserAddress", originOrder.UserAddress, "tokenCancelFee", *tokenCancelFee, "originOrder.CollateralToken", originOrder.CollateralToken) + } + err = lendingstate.AddTokenBalance(relayerOwner, tokenCancelFee, originOrder.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessCancelOrder AddTokenBalance", "err", err, "relayerOwner", relayerOwner, "tokenCancelFee", *tokenCancelFee, "originOrder.CollateralToken", originOrder.CollateralToken) + } default: } extraData, _ := json.Marshal(struct { @@ -829,12 +846,21 @@ func (l *Lending) LiquidationExpiredTrade(header *types.Header, chain consensus. recallAmount := common.Big0 if repayAmount.Cmp(lendingTrade.CollateralLockedAmount) < 0 { recallAmount = new(big.Int).Sub(lendingTrade.CollateralLockedAmount, repayAmount) - lendingstate.AddTokenBalance(lendingTrade.Borrower, recallAmount, lendingTrade.CollateralToken, statedb) + err := lendingstate.AddTokenBalance(lendingTrade.Borrower, recallAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("LiquidationExpiredTrade AddTokenBalance", "err", err, "lendingTrade.Borrower", lendingTrade.Borrower, "recallAmount", *recallAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } } else { repayAmount = lendingTrade.CollateralLockedAmount } - lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) - lendingstate.AddTokenBalance(lendingTrade.Investor, repayAmount, lendingTrade.CollateralToken, statedb) + err = lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("LiquidationExpiredTrade SubTokenBalance", "err", err, "LendingLockAddress", common.HexToAddress(common.LendingLockAddress), "lendingTrade.CollateralLockedAmount", *lendingTrade.CollateralLockedAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingstate.AddTokenBalance(lendingTrade.Investor, repayAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("LiquidationExpiredTrade AddTokenBalance", "err", err, "lendingTrade.Investor", lendingTrade.Investor, "repayAmount", repayAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } err = lendingStateDB.RemoveLiquidationTime(lendingBook, lendingTradeId, lendingTrade.LiquidationTime) if err != nil { @@ -870,10 +896,15 @@ func (l *Lending) LiquidationTrade(lendingStateDB *lendingstate.LendingStateDB, if lendingTrade.TradeId != lendingTradeId { return nil, fmt.Errorf("Lending Trade Id not found : %d ", lendingTradeId) } - lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) - lendingstate.AddTokenBalance(lendingTrade.Investor, lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) - - err := lendingStateDB.RemoveLiquidationTime(lendingBook, lendingTradeId, lendingTrade.LiquidationTime) + err := lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("LiquidationTrade SubTokenBalance", "err", err, "LendingLockAddress", common.HexToAddress(common.LendingLockAddress), "lendingTrade.CollateralLockedAmount", *lendingTrade.CollateralLockedAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingstate.AddTokenBalance(lendingTrade.Investor, lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("LiquidationTrade AddTokenBalance", "err", err, "lendingTrade.Investor", lendingTrade.Investor, "lendingTrade.CollateralLockedAmount", *lendingTrade.CollateralLockedAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingStateDB.RemoveLiquidationTime(lendingBook, lendingTradeId, lendingTrade.LiquidationTime) if err != nil { log.Debug("LiquidationTrade RemoveLiquidationTime", "err", err) return nil, err @@ -953,11 +984,11 @@ func (l *Lending) GetMediumTradePriceBeforeEpoch(chain consensus.ChainContext, s return nil, nil } -//LendToken and CollateralToken must meet at least one of following conditions -//- Have direct pair in XDCX: lendToken/CollateralToken or CollateralToken/LendToken -//- Have pairs with XDC: -//- lendToken/XDC and CollateralToken/XDC -//- XDC/lendToken and XDC/CollateralToken +// LendToken and CollateralToken must meet at least one of following conditions +// - Have direct pair in XDCX: lendToken/CollateralToken or CollateralToken/LendToken +// - Have pairs with XDC: +// - lendToken/XDC and CollateralToken/XDC +// - XDC/lendToken and XDC/CollateralToken func (l *Lending) GetCollateralPrices(header *types.Header, chain consensus.ChainContext, statedb *state.StateDB, tradingStateDb *tradingstate.TradingStateDB, collateralToken common.Address, lendingToken common.Address) (*big.Int, *big.Int, error) { // lendTokenXDCPrice: price of ticker lendToken/XDC // collateralXDCPrice: price of ticker collateralToken/XDC @@ -1097,8 +1128,14 @@ func (l *Lending) ProcessTopUpLendingTrade(lendingStateDB *lendingstate.LendingS if err != nil { return err, true, nil } - lendingstate.SubTokenBalance(lendingTrade.Borrower, quantity, lendingTrade.CollateralToken, statedb) - lendingstate.AddTokenBalance(common.HexToAddress(common.LendingLockAddress), quantity, lendingTrade.CollateralToken, statedb) + err = lendingstate.SubTokenBalance(lendingTrade.Borrower, quantity, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessTopUpLendingTrade SubTokenBalance", "err", err, "lendingTrade.Borrower", lendingTrade.Borrower, "quantity", *quantity, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingstate.AddTokenBalance(common.HexToAddress(common.LendingLockAddress), quantity, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessTopUpLendingTrade AddTokenBalance", "err", err, "LendingLockAddress", common.HexToAddress(common.LendingLockAddress), "quantity", *quantity, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } oldLockedAmount := lendingTrade.CollateralLockedAmount newLockedAmount := new(big.Int).Add(quantity, oldLockedAmount) newLiquidationPrice := new(big.Int).Mul(lendingTrade.LiquidationPrice, oldLockedAmount) @@ -1153,11 +1190,22 @@ func (l *Lending) ProcessRepayLendingTrade(header *types.Header, chain consensus } return newLendingTrade, err } else { - lendingstate.SubTokenBalance(lendingTrade.Borrower, paymentBalance, lendingTrade.LendingToken, statedb) - lendingstate.AddTokenBalance(lendingTrade.Investor, paymentBalance, lendingTrade.LendingToken, statedb) - - lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) - lendingstate.AddTokenBalance(lendingTrade.Borrower, lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + err := lendingstate.SubTokenBalance(lendingTrade.Borrower, paymentBalance, lendingTrade.LendingToken, statedb) + if err != nil { + log.Warn("ProcessRepayLendingTrade SubTokenBalance", "err", err, "lendingTrade.Borrower", lendingTrade.Borrower, "paymentBalance", *paymentBalance, "lendingTrade.LendingToken", lendingTrade.LendingToken) + } + err = lendingstate.AddTokenBalance(lendingTrade.Investor, paymentBalance, lendingTrade.LendingToken, statedb) + if err != nil { + log.Warn("ProcessRepayLendingTrade AddTokenBalance", "err", err, "lendingTrade.Investor", lendingTrade.Investor, "paymentBalance", *paymentBalance, "lendingTrade.LendingToken", lendingTrade.LendingToken) + } + err = lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessRepayLendingTrade SubTokenBalance", "err", err, "LendingLockAddress", common.HexToAddress(common.LendingLockAddress), "lendingTrade.CollateralLockedAmount", *lendingTrade.CollateralLockedAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingstate.AddTokenBalance(lendingTrade.Borrower, lendingTrade.CollateralLockedAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessRepayLendingTrade AddTokenBalance", "err", err, "lendingTrade.Borrower", lendingTrade.Borrower, "lendingTrade.CollateralLockedAmount", *lendingTrade.CollateralLockedAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } err = lendingStateDB.RemoveLiquidationTime(lendingBook, lendingTradeId, lendingTrade.LiquidationTime) if err != nil { @@ -1202,8 +1250,14 @@ func (l *Lending) ProcessRecallLendingTrade(lendingStateDB *lendingstate.Lending if err != nil { return err, true, nil } - lendingstate.AddTokenBalance(lendingTrade.Borrower, recallAmount, lendingTrade.CollateralToken, statedb) - lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), recallAmount, lendingTrade.CollateralToken, statedb) + err = lendingstate.AddTokenBalance(lendingTrade.Borrower, recallAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessRecallLendingTrade AddTokenBalance", "err", err, "lendingTrade.Borrower", lendingTrade.Borrower, "recallAmount", *recallAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } + err = lendingstate.SubTokenBalance(common.HexToAddress(common.LendingLockAddress), recallAmount, lendingTrade.CollateralToken, statedb) + if err != nil { + log.Warn("ProcessRecallLendingTrade SubTokenBalance", "err", err, "LendingLockAddress", common.HexToAddress(common.LendingLockAddress), "recallAmount", *recallAmount, "lendingTrade.CollateralToken", lendingTrade.CollateralToken) + } lendingStateDB.UpdateLiquidationPrice(lendingBook, lendingTrade.TradeId, newLiquidationPrice) lendingStateDB.UpdateCollateralLockedAmount(lendingBook, lendingTrade.TradeId, newLockedAmount) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 254b1f7fb..2b7c0f26c 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -19,8 +19,11 @@ package abi import ( "bytes" "encoding/json" + "errors" "fmt" "io" + + "github.com/XinFinOrg/XDC-Subnet/crypto" ) // The ABI holds information about a contract's context and available @@ -144,3 +147,25 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { } return nil, fmt.Errorf("no method with id: %#x", sigdata[:4]) } + +// revertSelector is a special function selector for revert reason unpacking. +var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] + +// UnpackRevert resolves the abi-encoded revert reason. According to the solidity +// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert, +// the provided revert reason is abi-encoded as if it were a call to a function +// `Error(string)`. So it's a special tool for it. +func UnpackRevert(data []byte) (string, error) { + if len(data) < 4 { + return "", errors.New("invalid data for unpacking") + } + if !bytes.Equal(data[:4], revertSelector) { + return "", errors.New("invalid data for unpacking") + } + typ, _ := NewType("string") + unpacked, err := (Arguments{{Type: typ}}).Unpack2(data[4:]) + if err != nil { + return "", err + } + return unpacked[0].(string), nil +} diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 512d8fdfa..5ff473f62 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -18,6 +18,7 @@ package abi import ( "encoding/json" + "errors" "fmt" "reflect" "strings" @@ -100,6 +101,17 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { return arguments.unpackAtomic(v, marshalledValues) } +// Unpack2 performs the operation hexdata -> Go format. +func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { + if len(data) == 0 { + if len(arguments.NonIndexed()) != 0 { + return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected") + } + return make([]interface{}, 0), nil + } + return arguments.UnpackValues(data) +} + func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { var ( @@ -278,7 +290,7 @@ func capitalise(input string) string { return strings.ToUpper(input[:1]) + input[1:] } -//unpackStruct extracts each argument into its corresponding struct field +// unpackStruct extracts each argument into its corresponding struct field func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { name := capitalise(arg.Name) typ := value.Type() diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 7abf2b3c7..6517a1b63 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -20,7 +20,6 @@ import ( "crypto/ecdsa" "errors" "io" - "io/ioutil" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" "github.com/XinFinOrg/XDC-Subnet/common" @@ -31,7 +30,7 @@ import ( // NewTransactor is a utility method to easily create a transaction signer from // an encrypted json key stream and the associated passphrase. func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { - json, err := ioutil.ReadAll(keyin) + json, err := io.ReadAll(keyin) if err != nil { return nil, err } diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 27978dd48..468bd016a 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -20,7 +20,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "math/big" "os" "sync" @@ -73,7 +72,7 @@ type SimulatedBackend struct { func SimulateWalletAddressAndSignFn(path string) (common.Address, func(account accounts.Account, hash []byte) ([]byte, error), error) { veryLightScryptN := 2 veryLightScryptP := 1 - dir, _ := ioutil.TempDir("", "eth-SimulateWalletAddressAndSignFn-test") + dir, _ := os.MkdirTemp("", "eth-SimulateWalletAddressAndSignFn-test") new := func(kd string) *keystore.KeyStore { return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) @@ -85,7 +84,7 @@ func SimulateWalletAddressAndSignFn(path string) (common.Address, func(account a var a1 accounts.Account // Read the JSON file - jsonData, err := ioutil.ReadFile(path) // currently only for v2 test + jsonData, err := os.ReadFile(path) // currently only for v2 test if err != nil { a1, err = ks.NewAccount(pass) if err != nil { @@ -363,7 +362,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call // 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 XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) { +func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (ret []byte, usedGas uint64, failed bool, err error) { // Ensure message is initialized properly. if call.GasPrice == nil { call.GasPrice = big.NewInt(1) @@ -391,7 +390,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal vmenv := vm.NewEVM(evmContext, statedb, nil, b.config, vm.Config{}) gaspool := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + ret, usedGas, failed, err, _ = core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + return } // SendTransaction updates the pending block to include the given transaction. @@ -427,18 +427,24 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa // // TODO(karalabe): Deprecate when the subscription one can return past data too. func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.FilterQuery) ([]types.Log, error) { - // Initialize unset filter boundaried to run from genesis to chain head - from := int64(0) - if query.FromBlock != nil { - from = query.FromBlock.Int64() - } - to := int64(-1) - if query.ToBlock != nil { - to = query.ToBlock.Int64() + var filter *filters.Filter + if query.BlockHash != nil { + // Block filter requested, construct a single-shot filter + filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) + } else { + // Initialize unset filter boundaried to run from genesis to chain head + from := int64(0) + if query.FromBlock != nil { + from = query.FromBlock.Int64() + } + to := int64(-1) + if query.ToBlock != nil { + to = query.ToBlock.Int64() + } + // Construct the range filter + filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) } - // Construct and execute the filter - filter := filters.New(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) - + // Run the filter and return all the logs logs, err := filter.Logs(ctx) if err != nil { return nil, err @@ -539,6 +545,10 @@ func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumb return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } +func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return fb.bc.GetHeaderByHash(hash), nil +} + func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash)), nil } diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 3777ad7e3..13b7c8419 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -30,6 +30,10 @@ import ( "github.com/XinFinOrg/XDC-Subnet" ) +var ( + errNoEventSignature = errors.New("no event signature") +) + // SignerFn is a signer function callback when a contract requires a method to // sign the transaction before submission. type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error) @@ -128,7 +132,7 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, return err } var ( - msg = XDPoSChain.CallMsg{From: opts.From, To: &c.address, Data: input, GasPrice: common.MinGasPrice, Gas: uint64(4200000)} + msg = XDPoSChain.CallMsg{From: opts.From, To: &c.address, Data: input, GasPrice: common.MinGasPrice50x, Gas: uint64(4200000)} ctx = ensureContext(opts.Context) code []byte output []byte @@ -326,6 +330,13 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter // UnpackLog unpacks a retrieved log into the provided output structure. func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error { + // Anonymous events are not supported. + if len(log.Topics) == 0 { + return errNoEventSignature + } + if log.Topics[0] != c.abi.Events[event].Id() { + return fmt.Errorf("event signature mismatch") + } if len(log.Data) > 0 { if err := c.abi.Unpack(out, event, log.Data); err != nil { return err diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 1f885234a..bf0ab7f7e 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -18,7 +18,6 @@ package bind import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -831,7 +830,7 @@ func TestBindings(t *testing.T) { t.Skip("symlinked environment doesn't support bind (https://github.com/golang/go/issues/14845)") } // Create a temporary workspace for the test suite - ws, err := ioutil.TempDir("", "") + ws, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("failed to create temporary workspace: %v", err) } @@ -848,7 +847,7 @@ func TestBindings(t *testing.T) { if err != nil { t.Fatalf("test %d: failed to generate binding: %v", i, err) } - if err = ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil { + if err = os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil { t.Fatalf("test %d: failed to write binding: %v", i, err) } // Generate the test file with the injected test code @@ -857,7 +856,7 @@ func TestBindings(t *testing.T) { if err != nil { t.Fatalf("test %d: failed to generate tests: %v", i, err) } - if err := ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), blob, 0600); err != nil { + if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), blob, 0600); err != nil { t.Fatalf("test %d: failed to write tests: %v", i, err) } } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index a1f13ffa2..cec1ce8f5 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -103,7 +103,11 @@ func NewType(t string) (typ Type, err error) { return typ, err } // parse the type and size of the abi-type. - parsedType := typeRegex.FindAllStringSubmatch(t, -1)[0] + matches := typeRegex.FindAllStringSubmatch(t, -1) + if len(matches) == 0 { + return Type{}, fmt.Errorf("invalid type '%v'", t) + } + parsedType := matches[0] // varSize is the size of the variable var varSize int if len(parsedType[3]) > 0 { diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 543e9a512..a34bec865 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -18,7 +18,6 @@ package keystore import ( "fmt" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -381,11 +380,11 @@ func TestUpdatedKeyfileContents(t *testing.T) { return } - // needed so that modTime of `file` is different to its current value after ioutil.WriteFile + // needed so that modTime of `file` is different to its current value after os.WriteFile time.Sleep(1000 * time.Millisecond) // Now replace file contents with crap - if err := ioutil.WriteFile(file, []byte("foo"), 0644); err != nil { + if err := os.WriteFile(file, []byte("foo"), 0644); err != nil { t.Fatal(err) return } @@ -398,9 +397,9 @@ func TestUpdatedKeyfileContents(t *testing.T) { // forceCopyFile is like cp.CopyFile, but doesn't complain if the destination exists. func forceCopyFile(dst, src string) error { - data, err := ioutil.ReadFile(src) + data, err := os.ReadFile(src) if err != nil { return err } - return ioutil.WriteFile(dst, data, 0644) + return os.WriteFile(dst, data, 0644) } diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index 570b9ca0c..a82953934 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -17,7 +17,6 @@ package keystore import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -41,7 +40,7 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er t0 := time.Now() // List all the failes from the keystore folder - files, err := ioutil.ReadDir(keyDir) + files, err := os.ReadDir(keyDir) if err != nil { return nil, nil, nil, err } @@ -58,14 +57,18 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er for _, fi := range files { // Skip any non-key files from the folder path := filepath.Join(keyDir, fi.Name()) - if skipKeyFile(fi) { + fiInfo, err := fi.Info() + if err != nil { + log.Warn("scan get FileInfo", "err", err, "path", path) + } + if fiInfo == nil || skipKeyFile(fiInfo) { log.Trace("Ignoring file on account scan", "path", path) continue } // Gather the set of all and fresly modified files all.Add(path) - modified := fi.ModTime() + modified := fiInfo.ModTime() if modified.After(fc.lastMod) { mods.Add(path) } @@ -91,7 +94,8 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er // skipKeyFile ignores editor backups, hidden files and folders/symlinks. func skipKeyFile(fi os.FileInfo) bool { // Skip editor backups and UNIX-style hidden files. - if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") { + name := fi.Name() + if strings.HasSuffix(name, "~") || strings.HasPrefix(name, ".") { return true } // Skip misc special files, directories (yes, symlinks too). diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index f21a0e14a..c632573f2 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -23,7 +23,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -188,7 +187,7 @@ func writeKeyFile(file string, content []byte) error { } // Atomic write: create a temporary hidden file first // then move it into place. TempFile assigns mode 0600. - f, err := ioutil.TempFile(filepath.Dir(file), "."+filepath.Base(file)+".tmp") + f, err := os.CreateTemp(filepath.Dir(file), "."+filepath.Base(file)+".tmp") if err != nil { return err } diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 76260587b..3d21ccaee 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -198,11 +198,19 @@ func (ks *KeyStore) Subscribe(sink chan<- accounts.WalletEvent) event.Subscripti // forces a manual refresh (only triggers for systems where the filesystem notifier // is not running). func (ks *KeyStore) updater() { + // Create a timer for the wallet refresh cycle + timer := time.NewTimer(walletRefreshCycle) + defer timer.Stop() + for { // Wait for an account update or a refresh timeout select { case <-ks.changes: - case <-time.After(walletRefreshCycle): + // Stop the timer if we receive an account update before the timer fires + if !timer.Stop() { + <-timer.C + } + case <-timer.C: } // Run the wallet refresher ks.refreshWallets() @@ -215,6 +223,9 @@ func (ks *KeyStore) updater() { return } ks.mu.Unlock() + + // Reset the timer for the next cycle + timer.Reset(walletRefreshCycle) } } diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 65111d29b..1f8d1f4aa 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -33,7 +33,7 @@ import ( "encoding/hex" "encoding/json" "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/XinFinOrg/XDC-Subnet/common" @@ -76,7 +76,7 @@ type keyStorePassphrase struct { func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { // Load the key from the keystore and decrypt its contents - keyjson, err := ioutil.ReadFile(filename) + keyjson, err := os.ReadFile(filename) if err != nil { return nil, err } diff --git a/accounts/keystore/keystore_passphrase_test.go b/accounts/keystore/keystore_passphrase_test.go index 651216122..11323ea54 100644 --- a/accounts/keystore/keystore_passphrase_test.go +++ b/accounts/keystore/keystore_passphrase_test.go @@ -17,7 +17,7 @@ package keystore import ( - "io/ioutil" + "os" "testing" "github.com/XinFinOrg/XDC-Subnet/common" @@ -30,7 +30,7 @@ const ( // Tests that a json key file can be decrypted and encrypted in multiple rounds. func TestKeyEncryptDecrypt(t *testing.T) { - keyjson, err := ioutil.ReadFile("testdata/very-light-scrypt.json") + keyjson, err := os.ReadFile("testdata/very-light-scrypt.json") if err != nil { t.Fatal(err) } diff --git a/accounts/keystore/keystore_plain_test.go b/accounts/keystore/keystore_plain_test.go index 991c79a2a..45c3f04d6 100644 --- a/accounts/keystore/keystore_plain_test.go +++ b/accounts/keystore/keystore_plain_test.go @@ -20,7 +20,6 @@ import ( "crypto/rand" "encoding/hex" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -32,7 +31,7 @@ import ( ) func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { - d, err := ioutil.TempDir("", "geth-keystore-test") + d, err := os.MkdirTemp("", "geth-keystore-test") if err != nil { t.Fatal(err) } diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 069ef060e..68c682e0d 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -17,7 +17,6 @@ package keystore import ( - "io/ioutil" "math/rand" "os" "runtime" @@ -375,7 +374,7 @@ func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { } func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { - d, err := ioutil.TempDir("", "eth-keystore-test") + d, err := os.MkdirTemp("", "eth-keystore-test") if err != nil { t.Fatal(err) } diff --git a/build/ci.go b/build/ci.go index 602dd1bda..b45e13fba 100644 --- a/build/ci.go +++ b/build/ci.go @@ -39,7 +39,6 @@ import ( "fmt" "go/parser" "go/token" - "io/ioutil" "log" "os" "os/exec" @@ -149,7 +148,7 @@ func doInstall(cmdline []string) { goinstall.Args = append(goinstall.Args, packages...) build.MustRun(goinstall) - if cmds, err := ioutil.ReadDir("cmd"); err == nil { + if cmds, err := os.ReadDir("cmd"); err == nil { for _, cmd := range cmds { pkgs, err := parser.ParseDir(token.NewFileSet(), filepath.Join(".", "cmd", cmd.Name()), nil, parser.PackageClauseOnly) if err != nil { diff --git a/cicd/.dockerignore b/cicd/.dockerignore new file mode 100644 index 000000000..1d1fe94df --- /dev/null +++ b/cicd/.dockerignore @@ -0,0 +1 @@ +Dockerfile \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/rpc.tf b/cicd/devnet/terraform/module/region/rpc.tf new file mode 100644 index 000000000..2ba07813c --- /dev/null +++ b/cicd/devnet/terraform/module/region/rpc.tf @@ -0,0 +1,104 @@ +# Allocate an Elastic IP for the NLB +resource "aws_eip" "nlb_eip" { + domain = "vpc" +} + + +# Create a Network Load Balancer +resource "aws_lb" "rpc_node_nlb" { + count = var.enableFixedIp ? 1 : 0 + name = "rpc-node-nlb" + load_balancer_type = "network" + + enable_deletion_protection = false + + subnet_mapping { + subnet_id = aws_subnet.devnet_subnet.id + allocation_id = aws_eip.nlb_eip.id + } +} + +# Listener and Target Group for the rpc node container +resource "aws_lb_target_group" "rpc_node_tg_8545" { + count = var.enableFixedIp ? 1 : 0 + name = "rpc-node-tg" + port = 8545 + protocol = "TCP" + vpc_id = aws_vpc.devnet_vpc.id + target_type = "ip" +} + +resource "aws_lb_listener" "rpc_node_listener_8545" { + count = var.enableFixedIp ? 1 : 0 + load_balancer_arn = aws_lb.rpc_node_nlb[0].arn + port = 8545 + protocol = "TCP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn + } +} + +resource "aws_ecs_service" "devnet_rpc_node_ecs_service" { + for_each = var.enableFixedIp ? var.devnetNodeKeys : {} + name = "ecs-service-${each.key}" + cluster = aws_ecs_cluster.devnet_ecs_cluster.id + task_definition = "${aws_ecs_task_definition.devnet_task_definition_group[each.key].family}:${max(aws_ecs_task_definition.devnet_task_definition_group[each.key].revision, data.aws_ecs_task_definition.devnet_ecs_task_definition[each.key].revision)}" + launch_type = "FARGATE" + scheduling_strategy = "REPLICA" + desired_count = 1 + force_new_deployment = true + deployment_minimum_healthy_percent = 0 + deployment_maximum_percent = 100 + + network_configuration { + subnets = [aws_subnet.devnet_subnet.id] + assign_public_ip = true + security_groups = [ + aws_default_security_group.devnet_xdcnode_security_group.id + ] + } + + deployment_circuit_breaker { + enable = true + rollback = false + } + + load_balancer { + target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn + container_name = "tfXdcNode" + container_port = 8545 + } + + depends_on = [ + aws_lb_listener.rpc_node_listener_8545 + ] + + tags = { + Name = "TfDevnetRpcNodeEcsService-${each.key}" + } +} + +# Target Group for port 30303 +resource "aws_lb_target_group" "rpc_node_tg_30303" { + count = var.enableFixedIp ? 1 : 0 + name = "rpc-node-tg-30303" + port = 30303 + protocol = "TCP" + vpc_id = aws_vpc.devnet_vpc.id + target_type = "ip" +} + +# Listener for port 30303 +resource "aws_lb_listener" "rpc_node_listener_30303" { + count = var.enableFixedIp ? 1 : 0 + load_balancer_arn = aws_lb.rpc_node_nlb[0].arn + port = 30303 + protocol = "TCP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.rpc_node_tg_30303[0].arn + } +} \ No newline at end of file diff --git a/cmd/XDC/accountcmd.go b/cmd/XDC/accountcmd.go index 72607ee53..37f2a4441 100644 --- a/cmd/XDC/accountcmd.go +++ b/cmd/XDC/accountcmd.go @@ -18,7 +18,7 @@ package main import ( "fmt" - "io/ioutil" + "os" "github.com/XinFinOrg/XDC-Subnet/accounts" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" @@ -340,7 +340,7 @@ func importWallet(ctx *cli.Context) error { if len(keyfile) == 0 { utils.Fatalf("keyfile must be given as argument") } - keyJson, err := ioutil.ReadFile(keyfile) + keyJson, err := os.ReadFile(keyfile) if err != nil { utils.Fatalf("Could not read wallet file: %v", err) } diff --git a/cmd/XDC/accountcmd_test.go b/cmd/XDC/accountcmd_test.go index 4ab63b802..8512dd7d0 100644 --- a/cmd/XDC/accountcmd_test.go +++ b/cmd/XDC/accountcmd_test.go @@ -17,7 +17,7 @@ package main import ( - "io/ioutil" + "os" "path/filepath" "runtime" "strings" @@ -115,7 +115,7 @@ Passphrase: {{.InputLine "foo"}} Address: {0xd4584b5f6229b7be90727b0fc8c6b91bb427821f} `) - files, err := ioutil.ReadDir(filepath.Join(XDC.Datadir, "keystore")) + files, err := os.ReadDir(filepath.Join(XDC.Datadir, "keystore")) if len(files) != 1 { t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err) } diff --git a/cmd/XDC/bugcmd.go b/cmd/XDC/bugcmd.go index 9f9f1bb1c..345782f94 100644 --- a/cmd/XDC/bugcmd.go +++ b/cmd/XDC/bugcmd.go @@ -20,8 +20,8 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/url" + "os" "os/exec" "runtime" "strings" @@ -74,7 +74,7 @@ func printOSDetails(w io.Writer) { case "openbsd", "netbsd", "freebsd", "dragonfly": printCmdOut(w, "uname -v: ", "uname", "-v") case "solaris": - out, err := ioutil.ReadFile("/etc/release") + out, err := os.ReadFile("/etc/release") if err == nil { fmt.Fprintf(w, "/etc/release: %s\n", out) } else { diff --git a/cmd/XDC/chaincmd.go b/cmd/XDC/chaincmd.go index 372a34f82..94df9c594 100644 --- a/cmd/XDC/chaincmd.go +++ b/cmd/XDC/chaincmd.go @@ -306,7 +306,8 @@ func exportChain(ctx *cli.Context) error { utils.Fatalf("This command requires an argument.") } stack, _ := makeFullNode(ctx) - chain, _ := utils.MakeChain(ctx, stack) + chain, db := utils.MakeChain(ctx, stack) + defer db.Close() start := time.Now() var err error @@ -340,6 +341,7 @@ func importPreimages(ctx *cli.Context) error { } stack, _ := makeFullNode(ctx) diskdb := utils.MakeChainDatabase(ctx, stack) + defer diskdb.Close() start := time.Now() if err := utils.ImportPreimages(diskdb, ctx.Args().First()); err != nil { @@ -356,6 +358,7 @@ func exportPreimages(ctx *cli.Context) error { } stack, _ := makeFullNode(ctx) diskdb := utils.MakeChainDatabase(ctx, stack) + defer diskdb.Close() start := time.Now() if err := utils.ExportPreimages(diskdb, ctx.Args().First()); err != nil { @@ -373,6 +376,7 @@ func copyDb(ctx *cli.Context) error { // Initialize a new chain for the running node to sync into stack, _ := makeFullNode(ctx) chain, chainDb := utils.MakeChain(ctx, stack) + defer chainDb.Close() syncmode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode) dl := downloader.New(syncmode, chainDb, new(event.TypeMux), chain, nil, nil, nil) @@ -445,6 +449,8 @@ func removeDB(ctx *cli.Context) error { func dump(ctx *cli.Context) error { stack, _ := makeFullNode(ctx) chain, chainDb := utils.MakeChain(ctx, stack) + defer chainDb.Close() + for _, arg := range ctx.Args() { var block *types.Block if hashish(arg) { @@ -464,7 +470,6 @@ func dump(ctx *cli.Context) error { fmt.Printf("%s\n", state.Dump()) } } - chainDb.Close() return nil } diff --git a/cmd/XDC/config.go b/cmd/XDC/config.go index 93be526d7..2b349689e 100644 --- a/cmd/XDC/config.go +++ b/cmd/XDC/config.go @@ -182,6 +182,7 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) { common.MinGasPrice = big.NewInt(gasPrice) } } + common.MinGasPrice50x = common.MinGasPrice50x.Mul(common.MinGasPrice, big.NewInt(50)) // read passwords from environment passwords := []string{} diff --git a/cmd/XDC/dao_test.go b/cmd/XDC/dao_test.go index 601d187f4..e61f2bd86 100644 --- a/cmd/XDC/dao_test.go +++ b/cmd/XDC/dao_test.go @@ -17,7 +17,6 @@ package main import ( - "io/ioutil" "math/big" "os" "path/filepath" @@ -109,7 +108,7 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc // Start a XDC instance with the requested flags set and immediately terminate if genesis != "" { json := filepath.Join(datadir, "genesis.json") - if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { + if err := os.WriteFile(json, []byte(genesis), 0600); err != nil { t.Fatalf("test %d: failed to write genesis file: %v", test, err) } runXDC(t, "--datadir", datadir, "init", json).WaitExit() diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 93fff4f05..0eb0b03a8 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -136,6 +136,7 @@ var ( utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.RPCHttpWriteTimeoutFlag, utils.RPCApiFlag, utils.WSEnabledFlag, utils.WSListenAddrFlag, diff --git a/cmd/XDC/run_test.go b/cmd/XDC/run_test.go index b574eee1a..a6bf58aea 100644 --- a/cmd/XDC/run_test.go +++ b/cmd/XDC/run_test.go @@ -18,7 +18,6 @@ package main import ( "fmt" - "io/ioutil" "os" "testing" @@ -27,7 +26,7 @@ import ( ) func tmpdir(t *testing.T) string { - dir, err := ioutil.TempDir("", "XDC-test") + dir, err := os.MkdirTemp("", "XDC-test") if err != nil { t.Fatal(err) } diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index e2bf4d334..e07f9703d 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -144,6 +144,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.RPCHttpWriteTimeoutFlag, utils.RPCApiFlag, utils.WSEnabledFlag, utils.WSListenAddrFlag, diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index c5a119af5..f27f15cfe 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -20,7 +20,6 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" "os" "strings" @@ -100,7 +99,7 @@ func main() { } } else { // Otherwise load up the ABI, optional bytecode and type name from the parameters - abi, err := ioutil.ReadFile(*abiFlag) + abi, err := os.ReadFile(*abiFlag) if err != nil { fmt.Printf("Failed to read input ABI: %v\n", err) os.Exit(-1) @@ -109,7 +108,7 @@ func main() { bin := []byte{} if *binFlag != "" { - if bin, err = ioutil.ReadFile(*binFlag); err != nil { + if bin, err = os.ReadFile(*binFlag); err != nil { fmt.Printf("Failed to read input bytecode: %v\n", err) os.Exit(-1) } @@ -133,7 +132,7 @@ func main() { fmt.Printf("%s\n", code) return } - if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil { + if err := os.WriteFile(*outFlag, []byte(code), 0600); err != nil { fmt.Printf("Failed to write ABI binding: %v\n", err) os.Exit(-1) } diff --git a/cmd/ethkey/generate.go b/cmd/ethkey/generate.go index a257216ff..8ef79e35b 100644 --- a/cmd/ethkey/generate.go +++ b/cmd/ethkey/generate.go @@ -19,7 +19,6 @@ package main import ( "crypto/ecdsa" "fmt" - "io/ioutil" "os" "path/filepath" @@ -100,7 +99,7 @@ If you want to encrypt an existing private key, it can be specified by setting if err := os.MkdirAll(filepath.Dir(keyfilepath), 0700); err != nil { utils.Fatalf("Could not create directory %s", filepath.Dir(keyfilepath)) } - if err := ioutil.WriteFile(keyfilepath, keyjson, 0600); err != nil { + if err := os.WriteFile(keyfilepath, keyjson, 0600); err != nil { utils.Fatalf("Failed to write keyfile to %s: %v", keyfilepath, err) } diff --git a/cmd/ethkey/inspect.go b/cmd/ethkey/inspect.go index 41d1f61f1..521cd978a 100644 --- a/cmd/ethkey/inspect.go +++ b/cmd/ethkey/inspect.go @@ -19,7 +19,7 @@ package main import ( "encoding/hex" "fmt" - "io/ioutil" + "os" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" "github.com/XinFinOrg/XDC-Subnet/cmd/utils" @@ -54,7 +54,7 @@ make sure to use this feature with great caution!`, keyfilepath := ctx.Args().First() // Read key from file. - keyjson, err := ioutil.ReadFile(keyfilepath) + keyjson, err := os.ReadFile(keyfilepath) if err != nil { utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err) } diff --git a/cmd/ethkey/message.go b/cmd/ethkey/message.go index 9e07282d8..e79491375 100644 --- a/cmd/ethkey/message.go +++ b/cmd/ethkey/message.go @@ -19,7 +19,7 @@ package main import ( "encoding/hex" "fmt" - "io/ioutil" + "os" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" "github.com/XinFinOrg/XDC-Subnet/cmd/utils" @@ -56,7 +56,7 @@ To sign a message contained in a file, use the --msgfile flag. // Load the keyfile. keyfilepath := ctx.Args().First() - keyjson, err := ioutil.ReadFile(keyfilepath) + keyjson, err := os.ReadFile(keyfilepath) if err != nil { utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err) } @@ -146,7 +146,7 @@ func getMessage(ctx *cli.Context, msgarg int) []byte { if len(ctx.Args()) > msgarg { utils.Fatalf("Can't use --msgfile and message argument at the same time.") } - msg, err := ioutil.ReadFile(file) + msg, err := os.ReadFile(file) if err != nil { utils.Fatalf("Can't read message file: %v", err) } diff --git a/cmd/ethkey/message_test.go b/cmd/ethkey/message_test.go index 39352b1d2..a261d5248 100644 --- a/cmd/ethkey/message_test.go +++ b/cmd/ethkey/message_test.go @@ -17,14 +17,13 @@ package main import ( - "io/ioutil" "os" "path/filepath" "testing" ) func TestMessageSignVerify(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "ethkey-test") + tmpdir, err := os.MkdirTemp("", "ethkey-test") if err != nil { t.Fatal("Can't create temporary directory:", err) } diff --git a/cmd/ethkey/utils.go b/cmd/ethkey/utils.go index 73f5044e2..29c33c9db 100644 --- a/cmd/ethkey/utils.go +++ b/cmd/ethkey/utils.go @@ -19,7 +19,7 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" + "os" "strings" "github.com/XinFinOrg/XDC-Subnet/cmd/utils" @@ -35,7 +35,7 @@ func getPassPhrase(ctx *cli.Context, confirmation bool) string { // Look for the --passphrase flag. passphraseFile := ctx.String(passphraseFlag.Name) if passphraseFile != "" { - content, err := ioutil.ReadFile(passphraseFile) + content, err := os.ReadFile(passphraseFile) if err != nil { utils.Fatalf("Failed to read passphrase file '%s': %v", passphraseFile, err) diff --git a/cmd/evm/compiler.go b/cmd/evm/compiler.go index b58881535..b5fbf9db8 100644 --- a/cmd/evm/compiler.go +++ b/cmd/evm/compiler.go @@ -19,7 +19,7 @@ package main import ( "errors" "fmt" - "io/ioutil" + "os" "github.com/XinFinOrg/XDC-Subnet/cmd/evm/internal/compiler" @@ -41,7 +41,7 @@ func compileCmd(ctx *cli.Context) error { } fn := ctx.Args().First() - src, err := ioutil.ReadFile(fn) + src, err := os.ReadFile(fn) if err != nil { return err } diff --git a/cmd/evm/disasm.go b/cmd/evm/disasm.go index 30f247910..a33a3b571 100644 --- a/cmd/evm/disasm.go +++ b/cmd/evm/disasm.go @@ -19,7 +19,7 @@ package main import ( "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/XinFinOrg/XDC-Subnet/core/asm" @@ -39,7 +39,7 @@ func disasmCmd(ctx *cli.Context) error { } fn := ctx.Args().First() - in, err := ioutil.ReadFile(fn) + in, err := os.ReadFile(fn) if err != nil { return err } diff --git a/cmd/evm/json_logger.go b/cmd/evm/json_logger.go index 988c9068d..5dd2679f9 100644 --- a/cmd/evm/json_logger.go +++ b/cmd/evm/json_logger.go @@ -56,7 +56,12 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos log.Memory = memory.Data() } if !l.cfg.DisableStack { - log.Stack = stack.Data() + //TODO(@holiman) improve this + logstack := make([]*big.Int, len(stack.Data())) + for i, item := range stack.Data() { + logstack[i] = item.ToBig() + } + log.Stack = logstack } return l.encoder.Encode(log) } diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 1f0642878..9d4317348 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "os" "runtime/pprof" "time" @@ -126,13 +126,13 @@ func runCmd(ctx *cli.Context) error { // If - is specified, it means that code comes from stdin if ctx.GlobalString(CodeFileFlag.Name) == "-" { //Try reading from stdin - if hexcode, err = ioutil.ReadAll(os.Stdin); err != nil { + if hexcode, err = io.ReadAll(os.Stdin); err != nil { fmt.Printf("Could not load code from stdin: %v\n", err) os.Exit(1) } } else { // Codefile with hex assembly - if hexcode, err = ioutil.ReadFile(ctx.GlobalString(CodeFileFlag.Name)); err != nil { + if hexcode, err = os.ReadFile(ctx.GlobalString(CodeFileFlag.Name)); err != nil { fmt.Printf("Could not load code from file: %v\n", err) os.Exit(1) } @@ -143,7 +143,7 @@ func runCmd(ctx *cli.Context) error { code = common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)) } else if fn := ctx.Args().First(); len(fn) > 0 { // EASM-file to compile - src, err := ioutil.ReadFile(fn) + src, err := os.ReadFile(fn) if err != nil { return err } diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 90523fb7c..2d0f4a688 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -20,7 +20,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "github.com/XinFinOrg/XDC-Subnet/core/state" @@ -76,7 +75,7 @@ func stateTestCmd(ctx *cli.Context) error { debugger = vm.NewStructLogger(config) } // Load the test content from the input file - src, err := ioutil.ReadFile(ctx.Args().First()) + src, err := os.ReadFile(ctx.Args().First()) if err != nil { return err } diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 36cf71c49..58468a434 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -28,7 +28,7 @@ import ( "flag" "fmt" "html/template" - "io/ioutil" + "io" "math" "math/big" "net/http" @@ -139,7 +139,7 @@ func main() { log.Crit("Failed to render the faucet template", "err", err) } // Load and parse the genesis block requested by the user - blob, err := ioutil.ReadFile(*genesisFlag) + blob, err := os.ReadFile(*genesisFlag) if err != nil { log.Crit("Failed to read genesis block contents", "genesis", *genesisFlag, "err", err) } @@ -157,13 +157,13 @@ func main() { } } // Load up the account key and decrypt its password - if blob, err = ioutil.ReadFile(*accPassFlag); err != nil { + if blob, err = os.ReadFile(*accPassFlag); err != nil { log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err) } pass := string(blob) ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP) - if blob, err = ioutil.ReadFile(*accJSONFlag); err != nil { + if blob, err = os.ReadFile(*accJSONFlag); err != nil { log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err) } acc, err := ks.Import(blob, pass, pass) @@ -729,7 +729,7 @@ func authTwitter(url string) (string, string, common.Address, error) { } username := parts[len(parts)-3] - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return "", "", common.Address{}, err } @@ -763,7 +763,7 @@ func authGooglePlus(url string) (string, string, common.Address, error) { } defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return "", "", common.Address{}, err } @@ -797,7 +797,7 @@ func authFacebook(url string) (string, string, common.Address, error) { } defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return "", "", common.Address{}, err } diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index fab1d4346..cbdede5df 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -1,15 +1,15 @@ // Code generated by go-bindata. DO NOT EDIT. // sources: -// faucet.html +// faucet.html (11.726kB) package main import ( "bytes" "compress/gzip" + "crypto/sha256" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -19,7 +19,7 @@ import ( func bindataRead(data []byte, name string) ([]byte, error) { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } var buf bytes.Buffer @@ -27,7 +27,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { clErr := gz.Close() if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } if clErr != nil { return nil, err @@ -37,8 +37,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 { @@ -83,7 +84,7 @@ func faucetHtml() (*asset, error) { } info := bindataFileInfo{name: "faucet.html", 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{0x9b, 0x9e, 0x78, 0xa7, 0x98, 0x53, 0xe5, 0xcc, 0x18, 0xfc, 0x7e, 0x9a, 0xb2, 0xa6, 0xa5, 0x82, 0xbc, 0x1e, 0xb5, 0x94, 0xa5, 0x5d, 0xfe, 0x42, 0x78, 0x75, 0x6d, 0x98, 0x6d, 0x26, 0x43, 0x8d}} return a, nil } @@ -102,6 +103,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 { @@ -113,6 +120,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. @@ -128,6 +141,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)) @@ -142,18 +182,23 @@ var _bindata = map[string]func() (*asset, error){ "faucet.html": faucetHtml, } +// AssetDebug is true if the assets were built with the debug flag enabled. +const AssetDebug = false + // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// 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 +// +// data/ +// foo.txt +// 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, and // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree @@ -186,7 +231,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "faucet.html": {faucetHtml, 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 { @@ -200,14 +245,14 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + err = os.WriteFile(_filePath(dir, name), data, info.Mode()) if err != nil { return err } 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/cmd/puppeth/ssh.go b/cmd/puppeth/ssh.go index c9d75229f..9427c2306 100644 --- a/cmd/puppeth/ssh.go +++ b/cmd/puppeth/ssh.go @@ -21,7 +21,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "net" "os" "os/user" @@ -72,7 +71,7 @@ func dial(server string, pubkey []byte) (*sshClient, error) { var auths []ssh.AuthMethod path := filepath.Join(user.HomeDir, ".ssh", "id_rsa") - if buf, err := ioutil.ReadFile(path); err != nil { + if buf, err := os.ReadFile(path); err != nil { log.Warn("No SSH key, falling back to passwords", "path", path, "err", err) } else { key, err := ssh.ParsePrivateKey(buf) diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go index e8271bf8b..fcb1c3db7 100644 --- a/cmd/puppeth/wizard.go +++ b/cmd/puppeth/wizard.go @@ -20,7 +20,6 @@ import ( "bufio" "encoding/json" "fmt" - "io/ioutil" "math/big" "net" "os" @@ -63,8 +62,7 @@ func (c config) flush() { os.MkdirAll(filepath.Dir(c.path), 0755) out, _ := json.MarshalIndent(c.Genesis, "", " ") - log.Warn("writing to file", "filename", c.path) - if err := ioutil.WriteFile(c.path, out, 0644); err != nil { + if err := os.WriteFile(c.path, out, 0644); err != nil { log.Warn("Failed to save puppeth configs", "file", c.path, "err", err) } } diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index c90f87a80..f765cfdcb 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -20,8 +20,8 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "math/rand" + "os" "time" "github.com/XinFinOrg/XDC-Subnet/common" @@ -100,8 +100,8 @@ func (w *wizard) makeGenesis() { genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = w.readDefaultInt(3) fmt.Println() - fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %d)\n", common.MaxMasternodes/3*2+1) - minCandidateThreshold := w.readDefaultInt(common.MaxMasternodes/3*2 + 1) + fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %f)\n", 0.666) + minCandidateThreshold := w.readDefaultFloat(0.666) //TODO: change input style to cover for float threshold genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = minCandidateThreshold genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig @@ -126,16 +126,15 @@ func (w *wizard) makeGenesis() { // We also need the initial list of signers fmt.Println() - fmt.Printf("Which accounts are initial masternodes? (mandatory at least %d)\n", minCandidateThreshold) + fmt.Printf("Which accounts are initial masternodes? (mandatory at least %f)\n", minCandidateThreshold) var candidates []common.Address for { if address := w.readAddress(); address != nil { candidates = append(candidates, *address) continue - } - if len(candidates) >= minCandidateThreshold { - break + } else { + break //TODO: check empty input can pass this step } } // Sort the signers and embed into the extra-data section @@ -297,7 +296,7 @@ func (w *wizard) manageGenesis() { fmt.Println() fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network) out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") - if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil { + if err := os.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil { log.Error("Failed to save genesis file", "err", err) } log.Info("Exported existing genesis block") diff --git a/cmd/puppeth/wizard_genesis_file.go b/cmd/puppeth/wizard_genesis_file.go index 7ed08f416..924272eaf 100644 --- a/cmd/puppeth/wizard_genesis_file.go +++ b/cmd/puppeth/wizard_genesis_file.go @@ -172,12 +172,13 @@ func (w *wizard) makeGenesisFile() { genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = input.TimeoutSyncThreshold fmt.Println() - fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %d)\n", common.MaxMasternodes/3*2+1) - // genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultInt(common.MaxMasternodes/3*2 + 1) - fmt.Println(input.CertThreshold) - minCandidateThreshold := input.CertThreshold + fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %f)\n", 0.666) + fmt.Println(0.666) + // fmt.Printf("How many v2 vote collection to generate a QC, should be two thirds of masternodes? (default = %d)\n", common.MaxMasternodes/3*2+1) + // fmt.Println(input.CertThreshold) + // minCandidateThreshold := input.CertThreshold + minCandidateThreshold := 0.666 //TODO: change input style to cover for float threshold genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = minCandidateThreshold - genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig // We also need the grand master address diff --git a/cmd/swarm/config_test.go b/cmd/swarm/config_test.go index 22763f28f..5fef8c42b 100644 --- a/cmd/swarm/config_test.go +++ b/cmd/swarm/config_test.go @@ -19,7 +19,6 @@ package main import ( "fmt" "io" - "io/ioutil" "os" "os/exec" "testing" @@ -67,7 +66,7 @@ func TestFailsNoBzzAccount(t *testing.T) { } func TestCmdLineOverrides(t *testing.T) { - dir, err := ioutil.TempDir("", "bzztest") + dir, err := os.MkdirTemp("", "bzztest") if err != nil { t.Fatal(err) } @@ -161,7 +160,7 @@ func TestFileOverrides(t *testing.T) { t.Fatalf("Error creating TOML file in TestFileOverride: %v", err) } //create file - f, err := ioutil.TempFile("", "testconfig.toml") + f, err := os.CreateTemp("", "testconfig.toml") if err != nil { t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) } @@ -172,7 +171,7 @@ func TestFileOverrides(t *testing.T) { } f.Sync() - dir, err := ioutil.TempDir("", "bzztest") + dir, err := os.MkdirTemp("", "bzztest") if err != nil { t.Fatal(err) } @@ -259,7 +258,7 @@ func TestEnvVars(t *testing.T) { envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*")) envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true")) - dir, err := ioutil.TempDir("", "bzztest") + dir, err := os.MkdirTemp("", "bzztest") if err != nil { t.Fatal(err) } @@ -368,7 +367,7 @@ func TestCmdLineOverridesFile(t *testing.T) { t.Fatalf("Error creating TOML file in TestFileOverride: %v", err) } //write file - f, err := ioutil.TempFile("", "testconfig.toml") + f, err := os.CreateTemp("", "testconfig.toml") if err != nil { t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) } @@ -379,7 +378,7 @@ func TestCmdLineOverridesFile(t *testing.T) { } f.Sync() - dir, err := ioutil.TempDir("", "bzztest") + dir, err := os.MkdirTemp("", "bzztest") if err != nil { t.Fatal(err) } diff --git a/cmd/swarm/hash.go b/cmd/swarm/hash.go index ece993814..3fe8746f9 100644 --- a/cmd/swarm/hash.go +++ b/cmd/swarm/hash.go @@ -33,7 +33,7 @@ func hash(ctx *cli.Context) { } f, err := os.Open(args[0]) if err != nil { - utils.Fatalf("Error opening file " + args[1]) + utils.Fatalf("Error opening file " + args[0]) } defer f.Close() diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 8e43dcd21..21bd51e19 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -19,7 +19,6 @@ package main import ( "crypto/ecdsa" "fmt" - "io/ioutil" "os" "os/signal" "runtime" @@ -504,7 +503,7 @@ func decryptStoreAccount(ks *keystore.KeyStore, account string, passwords []stri if err != nil { utils.Fatalf("Can't find swarm account key: %v - Is the provided bzzaccount(%s) from the right datadir/Path?", err, account) } - keyjson, err := ioutil.ReadFile(a.URL.Path) + keyjson, err := os.ReadFile(a.URL.Path) if err != nil { utils.Fatalf("Can't load swarm account key: %v", err) } diff --git a/cmd/swarm/run_test.go b/cmd/swarm/run_test.go index 6f44eca27..dc90c2cc7 100644 --- a/cmd/swarm/run_test.go +++ b/cmd/swarm/run_test.go @@ -18,7 +18,6 @@ package main import ( "fmt" - "io/ioutil" "net" "os" "path/filepath" @@ -89,7 +88,7 @@ func newTestCluster(t *testing.T, size int) *testCluster { } }() - tmpdir, err := ioutil.TempDir("", "swarm-test") + tmpdir, err := os.MkdirTemp("", "swarm-test") if err != nil { t.Fatal(err) } diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go index dde6077a7..295d5f1ac 100644 --- a/cmd/swarm/upload.go +++ b/cmd/swarm/upload.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "net/http" "os" @@ -51,7 +50,7 @@ func upload(ctx *cli.Context) { if len(args) != 1 { if fromStdin { - tmp, err := ioutil.TempFile("", "swarm-stdin") + tmp, err := os.CreateTemp("", "swarm-stdin") if err != nil { utils.Fatalf("error create tempfile: %s", err) } diff --git a/cmd/swarm/upload_test.go b/cmd/swarm/upload_test.go index df7fc216a..c7d1eeb05 100644 --- a/cmd/swarm/upload_test.go +++ b/cmd/swarm/upload_test.go @@ -18,7 +18,6 @@ package main import ( "io" - "io/ioutil" "net/http" "os" "testing" @@ -33,7 +32,7 @@ func TestCLISwarmUp(t *testing.T) { defer cluster.Shutdown() // create a tmp file - tmp, err := ioutil.TempFile("", "swarm-test") + tmp, err := os.CreateTemp("", "swarm-test") assertNil(t, err) defer tmp.Close() defer os.Remove(tmp.Name()) @@ -68,7 +67,7 @@ func assertHTTPResponse(t *testing.T, res *http.Response, expectedStatus int, ex if res.StatusCode != expectedStatus { t.Fatalf("expected HTTP status %d, got %s", expectedStatus, res.Status) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) assertNil(t, err) if string(data) != expectedBody { t.Fatalf("expected HTTP body %q, got %q", expectedBody, data) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 287e7d250..9880e8709 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -20,7 +20,6 @@ package utils import ( "crypto/ecdsa" "fmt" - "io/ioutil" "math/big" "os" "path/filepath" @@ -398,6 +397,11 @@ var ( Usage: "HTTP-RPC server listening port", Value: node.DefaultHTTPPort, } + RPCHttpWriteTimeoutFlag = cli.DurationFlag{ + Name: "rpcwritetimeout", + Usage: "HTTP-RPC server write timeout (default = 10s)", + Value: node.DefaultHTTPWriteTimeOut, + } RPCCORSDomainFlag = cli.StringFlag{ Name: "rpccorsdomain", Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", @@ -720,6 +724,9 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(RPCPortFlag.Name) { cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name) } + if ctx.GlobalIsSet(RPCHttpWriteTimeoutFlag.Name) { + cfg.HTTPWriteTimeout = ctx.GlobalDuration(RPCHttpWriteTimeoutFlag.Name) + } if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) { cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name)) } @@ -825,7 +832,7 @@ func MakePasswordList(ctx *cli.Context) []string { if path == "" { return nil } - text, err := ioutil.ReadFile(path) + text, err := os.ReadFile(path) if err != nil { Fatalf("Failed to read password file: %v", err) } diff --git a/cmd/utils/flags_test.go b/cmd/utils/flags_test.go index 5a7144043..adbf25b45 100644 --- a/cmd/utils/flags_test.go +++ b/cmd/utils/flags_test.go @@ -1,7 +1,6 @@ package utils import ( - "io/ioutil" "log" "os" "path/filepath" @@ -18,13 +17,13 @@ func TestWalkMatch(t *testing.T) { if err != nil { log.Fatal(err) } - test1Dir, _ := ioutil.TempDir(dir, "test1") - test2Dir, _ := ioutil.TempDir(dir, "test2") - err = ioutil.WriteFile(filepath.Join(test1Dir, "test1.ldb"), []byte("hello"), os.ModePerm) + test1Dir, _ := os.MkdirTemp(dir, "test1") + test2Dir, _ := os.MkdirTemp(dir, "test2") + err = os.WriteFile(filepath.Join(test1Dir, "test1.ldb"), []byte("hello"), os.ModePerm) if err != nil { log.Fatal(err) } - err = ioutil.WriteFile(filepath.Join(test2Dir, "test2.abc"), []byte("hello"), os.ModePerm) + err = os.WriteFile(filepath.Join(test2Dir, "test2.abc"), []byte("hello"), os.ModePerm) if err != nil { log.Fatal(err) } diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go index 0c271d5f7..2415823d6 100644 --- a/cmd/wnode/main.go +++ b/cmd/wnode/main.go @@ -28,7 +28,6 @@ import ( "encoding/hex" "flag" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -483,7 +482,7 @@ func sendFilesLoop() { fmt.Println("Quit command received") return } - b, err := ioutil.ReadFile(s) + b, err := os.ReadFile(s) if err != nil { fmt.Printf(">>> Error: %s \n", err) } else { @@ -513,7 +512,7 @@ func fileReaderLoop() { fmt.Println("Quit command received") return } - raw, err := ioutil.ReadFile(s) + raw, err := os.ReadFile(s) if err != nil { fmt.Printf(">>> Error: %s \n", err) } else { @@ -670,7 +669,7 @@ func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) { //} fullpath := filepath.Join(dir, name) - err := ioutil.WriteFile(fullpath, env.Data, 0644) + err := os.WriteFile(fullpath, env.Data, 0644) if err != nil { fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err) } else if show { diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index 234714a2b..f34020123 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -22,7 +22,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "os" "os/exec" "regexp" "strconv" @@ -184,7 +184,7 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro func slurpFiles(files []string) (string, error) { var concat bytes.Buffer for _, file := range files { - content, err := ioutil.ReadFile(file) + content, err := os.ReadFile(file) if err != nil { return "", err } diff --git a/common/constants.go b/common/constants.go index 373bde5b1..6595032f0 100644 --- a/common/constants.go +++ b/common/constants.go @@ -40,6 +40,11 @@ var TIPXDCX = big.NewInt(0) var TIPXDCXLending = big.NewInt(0) var TIPXDCXCancellationFee = big.NewInt(0) var TIPXDCXCancellationFeeTestnet = big.NewInt(0) +var TIPXDCXDISABLE = big.NewInt(0) +var BerlinBlock = big.NewInt(0) +var LondonBlock = big.NewInt(0) +var MergeBlock = big.NewInt(0) +var ShanghaiBlock = big.NewInt(0) var TIPXDCXTestnet = big.NewInt(0) var IsTestnet bool = false @@ -69,8 +74,8 @@ var TRC21GasPrice = big.NewInt(250000000) var RateTopUp = big.NewInt(90) // 90% var BaseTopUp = big.NewInt(100) var BaseRecall = big.NewInt(100) -var TIPTRC21Fee = big.NewInt(13523400) -var TIPTRC21FeeTestnet = big.NewInt(225000) +var TIPTRC21Fee = big.NewInt(0) +var TIPTRC21FeeTestnet = big.NewInt(0) var LimitTimeFinality = uint64(30) // limit in 30 block var IgnoreSignerCheckBlockArray = map[uint64]bool{ diff --git a/common/constants/constants.go.unittest b/common/constants/constants.go.unittest new file mode 100644 index 000000000..7415978c0 --- /dev/null +++ b/common/constants/constants.go.unittest @@ -0,0 +1,152 @@ +package common + +import ( + "math/big" +) + +const ( + RewardMasterPercent = 90 + RewardVoterPercent = 0 + RewardFoundationPercent = 10 + HexSignMethod = "e341eaa4" + HexSetSecret = "34d38600" + HexSetOpening = "e11f5ba2" + EpocBlockSecret = 800 + EpocBlockOpening = 850 + EpocBlockRandomize = 900 + MaxMasternodes = 108 + BlocksPerYearTest = uint64(200000) + BlocksPerYear = uint64(15768000) + LimitThresholdNonceInQueue = 10 + DefaultMinGasPrice = 250000000 + MergeSignRange = 15 + RangeReturnSigner = 150 + MinimunMinerBlockPerEpoch = 1 + + OneYear = uint64(365 * 86400) + LiquidateLendingTradeBlock = uint64(100) +) + +var Rewound = uint64(0) + +var TIP2019Block = big.NewInt(1) +var TIPSigning = big.NewInt(0) +var TIPRandomize = big.NewInt(0) +var TIPV2SwitchBlock = big.NewInt(0) + +var TIPNoHalvingMNReward = big.NewInt(0) // hardfork no halving masternodes reward +var BlackListHFNumber = uint64(0) +var TIPXDCXDISABLE = big.NewInt(0) +var TIPXDCX = big.NewInt(38383838) +var TIPXDCXLending = big.NewInt(38383838) +var TIPXDCXCancellationFee = big.NewInt(38383838) +var TIPXDCXCancellationFeeTestnet = big.NewInt(38383838) +var TIPXDCXMinerDisable = big.NewInt(88999999900) +var TIPXDCXReceiverDisable = big.NewInt(99999999999) +var BerlinBlock = big.NewInt(9999999999) +var LondonBlock = big.NewInt(9999999999) +var MergeBlock = big.NewInt(9999999999) +var ShanghaiBlock = big.NewInt(9999999999) +var Eip1559Block = big.NewInt(9999999999) + +var TIPXDCXTestnet = big.NewInt(0) +var IsTestnet bool = false +var StoreRewardFolder string +var RollbackHash Hash +var BasePrice = big.NewInt(1000000000000000000) // 1 +var RelayerLockedFund = big.NewInt(20000) // 20000 XDC +var RelayerFee = big.NewInt(1000000000000000) // 0.001 +var XDCXBaseFee = big.NewInt(10000) // 1 / XDCXBaseFee +var RelayerCancelFee = big.NewInt(100000000000000) // 0.0001 +var XDCXBaseCancelFee = new(big.Int).Mul(XDCXBaseFee, big.NewInt(10)) // 1/ (XDCXBaseFee *10) +var RelayerLendingFee = big.NewInt(10000000000000000) // 0.01 +var RelayerLendingCancelFee = big.NewInt(1000000000000000) // 0.001 +var BaseLendingInterest = big.NewInt(100000000) // 1e8 + +var MinGasPrice = big.NewInt(DefaultMinGasPrice) +var RelayerRegistrationSMC = "0x16c63b79f9C8784168103C0b74E6A59EC2de4a02" +var RelayerRegistrationSMCTestnet = "0xA1996F69f47ba14Cb7f661010A7C31974277958c" +var LendingRegistrationSMC = "0x7d761afd7ff65a79e4173897594a194e3c506e57" +var LendingRegistrationSMCTestnet = "0x28d7fC2Cf5c18203aaCD7459EFC6Af0643C97bE8" +var TRC21IssuerSMCTestNet = HexToAddress("0x0E2C88753131CE01c7551B726b28BFD04e44003F") +var TRC21IssuerSMC = HexToAddress("0x8c0faeb5C6bEd2129b8674F262Fd45c4e9468bee") +var XDCXListingSMC = HexToAddress("0xDE34dD0f536170993E8CFF639DdFfCF1A85D3E53") +var XDCXListingSMCTestNet = HexToAddress("0x14B2Bf043b9c31827A472CE4F94294fE9a6277e0") +var TRC21GasPriceBefore = big.NewInt(2500) +var TRC21GasPrice = big.NewInt(250000000) +var RateTopUp = big.NewInt(90) // 90% +var BaseTopUp = big.NewInt(100) +var BaseRecall = big.NewInt(100) +var TIPTRC21Fee = big.NewInt(0) +var TIPTRC21FeeTestnet = big.NewInt(0) +var LimitTimeFinality = uint64(30) // limit in 30 block + +var IgnoreSignerCheckBlockArray = map[uint64]bool{ + uint64(1032300): true, + uint64(1033200): true, + uint64(27307800): true, + uint64(28270800): true, +} +var Blacklist = map[Address]bool{ + HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true, + HexToAddress("0x5ac26105b35ea8935be382863a70281ec7a985e9"): true, + HexToAddress("0x09c4f991a41e7ca0645d7dfbfee160b55e562ea4"): true, + HexToAddress("0xb3157bbc5b401a45d6f60b106728bb82ebaa585b"): true, + HexToAddress("0x741277a8952128d5c2ffe0550f5001e4c8247674"): true, + HexToAddress("0x10ba49c1caa97d74b22b3e74493032b180cebe01"): true, + HexToAddress("0x07048d51d9e6179578a6e3b9ee28cdc183b865e4"): true, + HexToAddress("0x4b899001d73c7b4ec404a771d37d9be13b8983de"): true, + HexToAddress("0x85cb320a9007f26b7652c19a2a65db1da2d0016f"): true, + HexToAddress("0x06869dbd0e3a2ea37ddef832e20fa005c6f0ca39"): true, + HexToAddress("0x82e48bc7e2c93d89125428578fb405947764ad7c"): true, + HexToAddress("0x1f9a78534d61732367cbb43fc6c89266af67c989"): true, + HexToAddress("0x7c3b1fa91df55ff7af0cad9e0399384dc5c6641b"): true, + HexToAddress("0x5888dc1ceb0ff632713486b9418e59743af0fd20"): true, + HexToAddress("0xa512fa1c735fc3cc635624d591dd9ea1ce339ca5"): true, + HexToAddress("0x0832517654c7b7e36b1ef45d76de70326b09e2c7"): true, + HexToAddress("0xca14e3c4c78bafb60819a78ff6e6f0f709d2aea7"): true, + HexToAddress("0x652ce195a23035114849f7642b0e06647d13e57a"): true, + HexToAddress("0x29a79f00f16900999d61b6e171e44596af4fb5ae"): true, + HexToAddress("0xf9fd1c2b0af0d91b0b6754e55639e3f8478dd04a"): true, + HexToAddress("0xb835710c9901d5fe940ef1b99ed918902e293e35"): true, + HexToAddress("0x04dd29ce5c253377a9a3796103ea0d9a9e514153"): true, + HexToAddress("0x2b4b56846eaf05c1fd762b5e1ac802efd0ab871c"): true, + HexToAddress("0x1d1f909f6600b23ce05004f5500ab98564717996"): true, + HexToAddress("0x0dfdcebf80006dc9ab7aae8c216b51c6b6759e86"): true, + HexToAddress("0x2b373890a28e5e46197fbc04f303bbfdd344056f"): true, + HexToAddress("0xa8a3ef3dc5d8e36aee76f3671ec501ec31e28254"): true, + HexToAddress("0x4f3d18136fe2b5665c29bdaf74591fc6625ef427"): true, + HexToAddress("0x175d728b0e0f1facb5822a2e0c03bde93596e324"): true, + HexToAddress("0xd575c2611984fcd79513b80ab94f59dc5bab4916"): true, + HexToAddress("0x0579337873c97c4ba051310236ea847f5be41bc0"): true, + HexToAddress("0xed12a519cc15b286920fc15fd86106b3e6a16218"): true, + HexToAddress("0x492d26d852a0a0a2982bb40ec86fe394488c419e"): true, + HexToAddress("0xce5c7635d02dc4e1d6b46c256cae6323be294a32"): true, + HexToAddress("0x8b94db158b5e78a6c032c7e7c9423dec62c8b11c"): true, + HexToAddress("0x0e7c48c085b6b0aa7ca6e4cbcc8b9a92dc270eb4"): true, + HexToAddress("0x206e6508462033ef8425edc6c10789d241d49acb"): true, + HexToAddress("0x7710e7b7682f26cb5a1202e1cff094fbf7777758"): true, + HexToAddress("0xcb06f949313b46bbf53b8e6b2868a0c260ff9385"): true, + HexToAddress("0xf884e43533f61dc2997c0e19a6eff33481920c00"): true, + HexToAddress("0x8b635ef2e4c8fe21fc2bda027eb5f371d6aa2fc1"): true, + HexToAddress("0x10f01a27cf9b29d02ce53497312b96037357a361"): true, + HexToAddress("0x693dd49b0ed70f162d733cf20b6c43dc2a2b4d95"): true, + HexToAddress("0xe0bec72d1c2a7a7fb0532cdfac44ebab9f6f41ee"): true, + HexToAddress("0xc8793633a537938cb49cdbbffd45428f10e45b64"): true, + HexToAddress("0x0d07a6cbbe9fa5c4f154e5623bfe47fb4d857d8e"): true, + HexToAddress("0xd4080b289da95f70a586610c38268d8d4cf1e4c4"): true, + HexToAddress("0x8bcfb0caf41f0aa1b548cae76dcdd02e33866a1b"): true, + HexToAddress("0xabfef22b92366d3074676e77ea911ccaabfb64c1"): true, + HexToAddress("0xcc4df7a32faf3efba32c9688def5ccf9fefe443d"): true, + HexToAddress("0x7ec1e48a582475f5f2b7448a86c4ea7a26ea36f8"): true, + HexToAddress("0xe3de67289080f63b0c2612844256a25bb99ac0ad"): true, + HexToAddress("0x3ba623300cf9e48729039b3c9e0dee9b785d636e"): true, + HexToAddress("0x402f2cfc9c8942f5e7a12c70c625d07a5d52fe29"): true, + HexToAddress("0xd62358d42afbde095a4ca868581d85f9adcc3d61"): true, + HexToAddress("0x3969f86acb733526cd61e3c6e3b4660589f32bc6"): true, + HexToAddress("0x67615413d7cdadb2c435a946aec713a9a9794d39"): true, + HexToAddress("0xfe685f43acc62f92ab01a8da80d76455d39d3cb3"): true, + HexToAddress("0x3538a544021c07869c16b764424c5987409cba48"): true, + HexToAddress("0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"): true, + HexToAddress("0x0000000000000000000000000000000000000011"): true, +} diff --git a/common/gas.go b/common/gas.go new file mode 100644 index 000000000..26783af02 --- /dev/null +++ b/common/gas.go @@ -0,0 +1,30 @@ +package common + +import ( + "math/big" +) + +var MinGasPrice50x = big.NewInt(12500000000) +var GasPrice50x = big.NewInt(12500000000) + +func GetGasFee(blockNumber, gas uint64) *big.Int { + fee := new(big.Int).SetUint64(gas) + if blockNumber >= uint64(10) { //temp fix trc21issuer test fail + fee = fee.Mul(fee, GasPrice50x) + } + return fee +} + +func GetGasPrice(number *big.Int) *big.Int { + if number == nil { + return new(big.Int).Set(TRC21GasPrice) + } + return new(big.Int).Set(GasPrice50x) +} + +func GetMinGasPrice(number *big.Int) *big.Int { + if number == nil { + return new(big.Int).Set(MinGasPrice) + } + return new(big.Int).Set(MinGasPrice50x) +} \ No newline at end of file diff --git a/common/lru/basiclru.go b/common/lru/basiclru.go new file mode 100644 index 000000000..a429157fe --- /dev/null +++ b/common/lru/basiclru.go @@ -0,0 +1,223 @@ +// Copyright 2022 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 . + +// Package lru implements generically-typed LRU caches. +package lru + +// BasicLRU is a simple LRU cache. +// +// This type is not safe for concurrent use. +// The zero value is not valid, instances must be created using NewCache. +type BasicLRU[K comparable, V any] struct { + list *list[K] + items map[K]cacheItem[K, V] + cap int +} + +type cacheItem[K any, V any] struct { + elem *listElem[K] + value V +} + +// NewBasicLRU creates a new LRU cache. +func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] { + if capacity <= 0 { + capacity = 1 + } + c := BasicLRU[K, V]{ + items: make(map[K]cacheItem[K, V]), + list: newList[K](), + cap: capacity, + } + return c +} + +// Add adds a value to the cache. Returns true if an item was evicted to store the new item. +func (c *BasicLRU[K, V]) Add(key K, value V) (evicted bool) { + item, ok := c.items[key] + if ok { + // Already exists in cache. + item.value = value + c.items[key] = item + c.list.moveToFront(item.elem) + return false + } + + var elem *listElem[K] + if c.Len() >= c.cap { + elem = c.list.removeLast() + delete(c.items, elem.v) + evicted = true + } else { + elem = new(listElem[K]) + } + + // Store the new item. + // Note that, if another item was evicted, we re-use its list element here. + elem.v = key + c.items[key] = cacheItem[K, V]{elem, value} + c.list.pushElem(elem) + return evicted +} + +// Contains reports whether the given key exists in the cache. +func (c *BasicLRU[K, V]) Contains(key K) bool { + _, ok := c.items[key] + return ok +} + +// Get retrieves a value from the cache. This marks the key as recently used. +func (c *BasicLRU[K, V]) Get(key K) (value V, ok bool) { + item, ok := c.items[key] + if !ok { + return value, false + } + c.list.moveToFront(item.elem) + return item.value, true +} + +// GetOldest retrieves the least-recently-used item. +// Note that this does not update the item's recency. +func (c *BasicLRU[K, V]) GetOldest() (key K, value V, ok bool) { + lastElem := c.list.last() + if lastElem == nil { + return key, value, false + } + key = lastElem.v + item := c.items[key] + return key, item.value, true +} + +// Len returns the current number of items in the cache. +func (c *BasicLRU[K, V]) Len() int { + return len(c.items) +} + +// Peek retrieves a value from the cache, but does not mark the key as recently used. +func (c *BasicLRU[K, V]) Peek(key K) (value V, ok bool) { + item, ok := c.items[key] + return item.value, ok +} + +// Purge empties the cache. +func (c *BasicLRU[K, V]) Purge() { + c.list.init() + for k := range c.items { + delete(c.items, k) + } +} + +// Remove drops an item from the cache. Returns true if the key was present in cache. +func (c *BasicLRU[K, V]) Remove(key K) bool { + item, ok := c.items[key] + if ok { + delete(c.items, key) + c.list.remove(item.elem) + } + return ok +} + +// RemoveOldest drops the least recently used item. +func (c *BasicLRU[K, V]) RemoveOldest() (key K, value V, ok bool) { + lastElem := c.list.last() + if lastElem == nil { + return key, value, false + } + + key = lastElem.v + item := c.items[key] + delete(c.items, key) + c.list.remove(lastElem) + return key, item.value, true +} + +// Keys returns all keys in the cache. +func (c *BasicLRU[K, V]) Keys() []K { + keys := make([]K, 0, len(c.items)) + return c.list.appendTo(keys) +} + +// list is a doubly-linked list holding items of type he. +// The zero value is not valid, use newList to create lists. +type list[T any] struct { + root listElem[T] +} + +type listElem[T any] struct { + next *listElem[T] + prev *listElem[T] + v T +} + +func newList[T any]() *list[T] { + l := new(list[T]) + l.init() + return l +} + +// init reinitializes the list, making it empty. +func (l *list[T]) init() { + l.root.next = &l.root + l.root.prev = &l.root +} + +// push adds an element to the front of the list. +func (l *list[T]) pushElem(e *listElem[T]) { + e.prev = &l.root + e.next = l.root.next + l.root.next = e + e.next.prev = e +} + +// moveToFront makes 'node' the head of the list. +func (l *list[T]) moveToFront(e *listElem[T]) { + e.prev.next = e.next + e.next.prev = e.prev + l.pushElem(e) +} + +// remove removes an element from the list. +func (l *list[T]) remove(e *listElem[T]) { + e.prev.next = e.next + e.next.prev = e.prev + e.next, e.prev = nil, nil +} + +// removeLast removes the last element of the list. +func (l *list[T]) removeLast() *listElem[T] { + last := l.last() + if last != nil { + l.remove(last) + } + return last +} + +// last returns the last element of the list, or nil if the list is empty. +func (l *list[T]) last() *listElem[T] { + e := l.root.prev + if e == &l.root { + return nil + } + return e +} + +// appendTo appends all list elements to a slice. +func (l *list[T]) appendTo(slice []T) []T { + for e := l.root.prev; e != &l.root; e = e.prev { + slice = append(slice, e.v) + } + return slice +} diff --git a/common/lru/basiclru_test.go b/common/lru/basiclru_test.go new file mode 100644 index 000000000..29812bda1 --- /dev/null +++ b/common/lru/basiclru_test.go @@ -0,0 +1,255 @@ +// Copyright 2022 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 . + +package lru + +import ( + crand "crypto/rand" + "fmt" + "io" + "math/rand" + "testing" +) + +// Some of these test cases were adapted +// from https://github.com/hashicorp/golang-lru/blob/master/simplelru/lru_test.go + +func TestBasicLRU(t *testing.T) { + cache := NewBasicLRU[int, int](128) + + for i := 0; i < 256; i++ { + cache.Add(i, i) + } + if cache.Len() != 128 { + t.Fatalf("bad len: %v", cache.Len()) + } + + // Check that Keys returns least-recent key first. + keys := cache.Keys() + if len(keys) != 128 { + t.Fatal("wrong Keys() length", len(keys)) + } + for i, k := range keys { + v, ok := cache.Peek(k) + if !ok { + t.Fatalf("expected key %d be present", i) + } + if v != k { + t.Fatalf("expected %d == %d", k, v) + } + if v != i+128 { + t.Fatalf("wrong value at key %d: %d, want %d", i, v, i+128) + } + } + + for i := 0; i < 128; i++ { + _, ok := cache.Get(i) + if ok { + t.Fatalf("%d should be evicted", i) + } + } + for i := 128; i < 256; i++ { + _, ok := cache.Get(i) + if !ok { + t.Fatalf("%d should not be evicted", i) + } + } + + for i := 128; i < 192; i++ { + ok := cache.Remove(i) + if !ok { + t.Fatalf("%d should be in cache", i) + } + ok = cache.Remove(i) + if ok { + t.Fatalf("%d should not be in cache", i) + } + _, ok = cache.Get(i) + if ok { + t.Fatalf("%d should be deleted", i) + } + } + + // Request item 192. + cache.Get(192) + // It should be the last item returned by Keys(). + for i, k := range cache.Keys() { + if (i < 63 && k != i+193) || (i == 63 && k != 192) { + t.Fatalf("out of order key: %v", k) + } + } + + cache.Purge() + if cache.Len() != 0 { + t.Fatalf("bad len: %v", cache.Len()) + } + if _, ok := cache.Get(200); ok { + t.Fatalf("should contain nothing") + } +} + +func TestBasicLRUAddExistingKey(t *testing.T) { + cache := NewBasicLRU[int, int](1) + + cache.Add(1, 1) + cache.Add(1, 2) + + v, _ := cache.Get(1) + if v != 2 { + t.Fatal("wrong value:", v) + } +} + +// This test checks GetOldest and RemoveOldest. +func TestBasicLRUGetOldest(t *testing.T) { + cache := NewBasicLRU[int, int](128) + for i := 0; i < 256; i++ { + cache.Add(i, i) + } + + k, _, ok := cache.GetOldest() + if !ok { + t.Fatalf("missing") + } + if k != 128 { + t.Fatalf("bad: %v", k) + } + + k, _, ok = cache.RemoveOldest() + if !ok { + t.Fatalf("missing") + } + if k != 128 { + t.Fatalf("bad: %v", k) + } + + k, _, ok = cache.RemoveOldest() + if !ok { + t.Fatalf("missing oldest item") + } + if k != 129 { + t.Fatalf("wrong oldest item: %v", k) + } +} + +// Test that Add returns true/false if an eviction occurred +func TestBasicLRUAddReturnValue(t *testing.T) { + cache := NewBasicLRU[int, int](1) + if cache.Add(1, 1) { + t.Errorf("first add shouldn't have evicted") + } + if !cache.Add(2, 2) { + t.Errorf("second add should have evicted") + } +} + +// This test verifies that Contains doesn't change item recency. +func TestBasicLRUContains(t *testing.T) { + cache := NewBasicLRU[int, int](2) + cache.Add(1, 1) + cache.Add(2, 2) + if !cache.Contains(1) { + t.Errorf("1 should be in the cache") + } + cache.Add(3, 3) + if cache.Contains(1) { + t.Errorf("Contains should not have updated recency of 1") + } +} + +// Test that Peek doesn't update recent-ness +func TestBasicLRUPeek(t *testing.T) { + cache := NewBasicLRU[int, int](2) + cache.Add(1, 1) + cache.Add(2, 2) + if v, ok := cache.Peek(1); !ok || v != 1 { + t.Errorf("1 should be set to 1") + } + cache.Add(3, 3) + if cache.Contains(1) { + t.Errorf("should not have updated recent-ness of 1") + } +} + +func BenchmarkLRU(b *testing.B) { + var ( + capacity = 1000 + indexes = make([]int, capacity*20) + keys = make([]string, capacity) + values = make([][]byte, capacity) + ) + for i := range indexes { + indexes[i] = rand.Intn(capacity) + } + for i := range keys { + b := make([]byte, 32) + crand.Read(b) + keys[i] = string(b) + crand.Read(b) + values[i] = b + } + + var sink []byte + + b.Run("Add/BasicLRU", func(b *testing.B) { + cache := NewBasicLRU[int, int](capacity) + for i := 0; i < b.N; i++ { + cache.Add(i, i) + } + }) + b.Run("Get/BasicLRU", func(b *testing.B) { + cache := NewBasicLRU[string, []byte](capacity) + for i := 0; i < capacity; i++ { + index := indexes[i] + cache.Add(keys[index], values[index]) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + k := keys[indexes[i%len(indexes)]] + v, ok := cache.Get(k) + if ok { + sink = v + } + } + }) + + // // vs. github.com/hashicorp/golang-lru/simplelru + // b.Run("Add/simplelru.LRU", func(b *testing.B) { + // cache, _ := simplelru.NewLRU(capacity, nil) + // for i := 0; i < b.N; i++ { + // cache.Add(i, i) + // } + // }) + // b.Run("Get/simplelru.LRU", func(b *testing.B) { + // cache, _ := simplelru.NewLRU(capacity, nil) + // for i := 0; i < capacity; i++ { + // index := indexes[i] + // cache.Add(keys[index], values[index]) + // } + // + // b.ResetTimer() + // for i := 0; i < b.N; i++ { + // k := keys[indexes[i%len(indexes)]] + // v, ok := cache.Get(k) + // if ok { + // sink = v.([]byte) + // } + // } + // }) + + fmt.Fprintln(io.Discard, sink) +} diff --git a/common/lru/blob_lru.go b/common/lru/blob_lru.go new file mode 100644 index 000000000..c9b339850 --- /dev/null +++ b/common/lru/blob_lru.go @@ -0,0 +1,84 @@ +// Copyright 2022 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 . + +package lru + +import ( + "math" + "sync" +) + +// blobType is the type constraint for values stored in SizeConstrainedCache. +type blobType interface { + ~[]byte | ~string +} + +// SizeConstrainedCache is a cache where capacity is in bytes (instead of item count). When the cache +// is at capacity, and a new item is added, older items are evicted until the size +// constraint is met. +// +// OBS: This cache assumes that items are content-addressed: keys are unique per content. +// In other words: two Add(..) with the same key K, will always have the same value V. +type SizeConstrainedCache[K comparable, V blobType] struct { + size uint64 + maxSize uint64 + lru BasicLRU[K, V] + lock sync.Mutex +} + +// NewSizeConstrainedCache creates a new size-constrained LRU cache. +func NewSizeConstrainedCache[K comparable, V blobType](maxSize uint64) *SizeConstrainedCache[K, V] { + return &SizeConstrainedCache[K, V]{ + size: 0, + maxSize: maxSize, + lru: NewBasicLRU[K, V](math.MaxInt), + } +} + +// Add adds a value to the cache. Returns true if an eviction occurred. +// OBS: This cache assumes that items are content-addressed: keys are unique per content. +// In other words: two Add(..) with the same key K, will always have the same value V. +// OBS: The value is _not_ copied on Add, so the caller must not modify it afterwards. +func (c *SizeConstrainedCache[K, V]) Add(key K, value V) (evicted bool) { + c.lock.Lock() + defer c.lock.Unlock() + + // Unless it is already present, might need to evict something. + // OBS: If it is present, we still call Add internally to bump the recentness. + if !c.lru.Contains(key) { + targetSize := c.size + uint64(len(value)) + for targetSize > c.maxSize { + evicted = true + _, v, ok := c.lru.RemoveOldest() + if !ok { + // list is now empty. Break + break + } + targetSize -= uint64(len(v)) + } + c.size = targetSize + } + c.lru.Add(key, value) + return evicted +} + +// Get looks up a key's value from the cache. +func (c *SizeConstrainedCache[K, V]) Get(key K) (V, bool) { + c.lock.Lock() + defer c.lock.Unlock() + + return c.lru.Get(key) +} diff --git a/common/lru/blob_lru_test.go b/common/lru/blob_lru_test.go new file mode 100644 index 000000000..ca1b0ddd7 --- /dev/null +++ b/common/lru/blob_lru_test.go @@ -0,0 +1,155 @@ +// Copyright 2022 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 . + +package lru + +import ( + "encoding/binary" + "fmt" + "testing" +) + +type testKey [8]byte + +func mkKey(i int) (key testKey) { + binary.LittleEndian.PutUint64(key[:], uint64(i)) + return key +} + +func TestSizeConstrainedCache(t *testing.T) { + lru := NewSizeConstrainedCache[testKey, []byte](100) + var want uint64 + // Add 11 items of 10 byte each. First item should be swapped out + for i := 0; i < 11; i++ { + k := mkKey(i) + v := fmt.Sprintf("value-%04d", i) + lru.Add(k, []byte(v)) + want += uint64(len(v)) + if want > 100 { + want = 100 + } + if have := lru.size; have != want { + t.Fatalf("size wrong, have %d want %d", have, want) + } + } + // Zero:th should be evicted + { + k := mkKey(0) + if _, ok := lru.Get(k); ok { + t.Fatalf("should be evicted: %v", k) + } + } + // Elems 1-11 should be present + for i := 1; i < 11; i++ { + k := mkKey(i) + want := fmt.Sprintf("value-%04d", i) + have, ok := lru.Get(k) + if !ok { + t.Fatalf("missing key %v", k) + } + if string(have) != want { + t.Fatalf("wrong value, have %v want %v", have, want) + } + } +} + +// This test adds inserting an element exceeding the max size. +func TestSizeConstrainedCacheOverflow(t *testing.T) { + lru := NewSizeConstrainedCache[testKey, []byte](100) + + // Add 10 items of 10 byte each, filling the cache + for i := 0; i < 10; i++ { + k := mkKey(i) + v := fmt.Sprintf("value-%04d", i) + lru.Add(k, []byte(v)) + } + // Add one single large elem. We expect it to swap out all entries. + { + k := mkKey(1337) + v := make([]byte, 200) + lru.Add(k, v) + } + // Elems 0-9 should be missing + for i := 1; i < 10; i++ { + k := mkKey(i) + if _, ok := lru.Get(k); ok { + t.Fatalf("should be evicted: %v", k) + } + } + // The size should be accurate + if have, want := lru.size, uint64(200); have != want { + t.Fatalf("size wrong, have %d want %d", have, want) + } + // Adding one small item should swap out the large one + { + i := 0 + k := mkKey(i) + v := fmt.Sprintf("value-%04d", i) + lru.Add(k, []byte(v)) + if have, want := lru.size, uint64(10); have != want { + t.Fatalf("size wrong, have %d want %d", have, want) + } + } +} + +// This checks what happens when inserting the same k/v multiple times. +func TestSizeConstrainedCacheSameItem(t *testing.T) { + lru := NewSizeConstrainedCache[testKey, []byte](100) + + // Add one 10 byte-item 10 times. + k := mkKey(0) + v := fmt.Sprintf("value-%04d", 0) + for i := 0; i < 10; i++ { + lru.Add(k, []byte(v)) + } + + // The size should be accurate. + if have, want := lru.size, uint64(10); have != want { + t.Fatalf("size wrong, have %d want %d", have, want) + } +} + +// This tests that empty/nil values are handled correctly. +func TestSizeConstrainedCacheEmpties(t *testing.T) { + lru := NewSizeConstrainedCache[testKey, []byte](100) + + // This test abuses the lru a bit, using different keys for identical value(s). + for i := 0; i < 10; i++ { + lru.Add(testKey{byte(i)}, []byte{}) + lru.Add(testKey{byte(255 - i)}, nil) + } + + // The size should not count, only the values count. So this could be a DoS + // since it basically has no cap, and it is intentionally overloaded with + // different-keyed 0-length values. + if have, want := lru.size, uint64(0); have != want { + t.Fatalf("size wrong, have %d want %d", have, want) + } + + for i := 0; i < 10; i++ { + if v, ok := lru.Get(testKey{byte(i)}); !ok { + t.Fatalf("test %d: expected presence", i) + } else if v == nil { + t.Fatalf("test %d, v is nil", i) + } + + if v, ok := lru.Get(testKey{byte(255 - i)}); !ok { + t.Fatalf("test %d: expected presence", i) + } else if v != nil { + t.Fatalf("test %d, v is not nil", i) + } + } +} diff --git a/common/lru/lru.go b/common/lru/lru.go new file mode 100644 index 000000000..45965adb0 --- /dev/null +++ b/common/lru/lru.go @@ -0,0 +1,95 @@ +// Copyright 2022 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 . + +package lru + +import "sync" + +// Cache is a LRU cache. +// This type is safe for concurrent use. +type Cache[K comparable, V any] struct { + cache BasicLRU[K, V] + mu sync.Mutex +} + +// NewCache creates an LRU cache. +func NewCache[K comparable, V any](capacity int) *Cache[K, V] { + return &Cache[K, V]{cache: NewBasicLRU[K, V](capacity)} +} + +// Add adds a value to the cache. Returns true if an item was evicted to store the new item. +func (c *Cache[K, V]) Add(key K, value V) (evicted bool) { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Add(key, value) +} + +// Contains reports whether the given key exists in the cache. +func (c *Cache[K, V]) Contains(key K) bool { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Contains(key) +} + +// Get retrieves a value from the cache. This marks the key as recently used. +func (c *Cache[K, V]) Get(key K) (value V, ok bool) { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Get(key) +} + +// Len returns the current number of items in the cache. +func (c *Cache[K, V]) Len() int { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Len() +} + +// Peek retrieves a value from the cache, but does not mark the key as recently used. +func (c *Cache[K, V]) Peek(key K) (value V, ok bool) { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Peek(key) +} + +// Purge empties the cache. +func (c *Cache[K, V]) Purge() { + c.mu.Lock() + defer c.mu.Unlock() + + c.cache.Purge() +} + +// Remove drops an item from the cache. Returns true if the key was present in cache. +func (c *Cache[K, V]) Remove(key K) bool { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Remove(key) +} + +// Keys returns all keys of items currently in the LRU. +func (c *Cache[K, V]) Keys() []K { + c.mu.Lock() + defer c.mu.Unlock() + + return c.cache.Keys() +} diff --git a/common/test_utils.go b/common/test_utils.go index a848642f7..7a175412f 100644 --- a/common/test_utils.go +++ b/common/test_utils.go @@ -19,12 +19,12 @@ package common import ( "encoding/json" "fmt" - "io/ioutil" + "os" ) // LoadJSON reads the given file and unmarshals its content. func LoadJSON(file string, val interface{}) error { - content, err := ioutil.ReadFile(file) + content, err := os.ReadFile(file) if err != nil { return err } diff --git a/common/types.go b/common/types.go index 323fa9c08..68f909105 100644 --- a/common/types.go +++ b/common/types.go @@ -73,6 +73,9 @@ func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } func Uint64ToHash(b uint64) Hash { return BytesToHash(new(big.Int).SetUint64(b).Bytes()) } func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } +// IsZero returns if a Hash is empty +func (h Hash) IsZero() bool { return h == Hash{} } + // Get the string representation of the underlying hash func (h Hash) Str() string { return string(h[:]) } func (h Hash) Bytes() []byte { return h[:] } @@ -190,6 +193,9 @@ func IsHexAddress(s string) bool { return len(s) == 2*AddressLength && isHex(s) } +// IsZero returns if a address is empty +func (a Address) IsZero() bool { return a == Address{} } + // Get the string representation of the underlying address func (a Address) Str() string { return string(a[:]) } func (a Address) Bytes() []byte { return a[:] } diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index ebb7bfaf7..ddb5d40c2 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -17,6 +17,7 @@ package XDPoS import ( + "fmt" "math/big" "github.com/XinFinOrg/XDC-Subnet/common" @@ -88,7 +89,11 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { } } - log.Info("xdc config loading", "config", config) + if config.V2.SwitchBlock.Uint64()%config.Epoch != 0 { + panic(fmt.Sprintf("v2 switch number is not epoch switch block %d, epoch %d", config.V2.SwitchBlock.Uint64(), config.Epoch)) + } + + log.Info("xdc config loading", "v2 config", config.V2) minePeriodCh := make(chan int) @@ -300,6 +305,10 @@ func (x *XDPoS) GetCurrentEpochSwitchBlock(chain consensus.ChainReader, blockNum return x.EngineV2.GetCurrentEpochSwitchBlock(chain, blockNumber) } +func (x *XDPoS) CalculateMissingRounds(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiMissedRoundsMetadata, error) { + return x.EngineV2.CalculateMissingRounds(chain, header) +} + // Same DB across all consensus engines func (x *XDPoS) GetDb() ethdb.Database { return x.db @@ -315,8 +324,7 @@ func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) ( } func (x *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) { - // Legacy V1 function - return []common.Address{}, nil + return x.EngineV2.GetSignersFromSnapshot(chain, header) } func (x *XDPoS) FindParentBlockToAssign(chain consensus.ChainReader, currentBlock *types.Block) *types.Block { diff --git a/consensus/XDPoS/api.go b/consensus/XDPoS/api.go index 5b1b9e22d..5f1e72ba1 100644 --- a/consensus/XDPoS/api.go +++ b/consensus/XDPoS/api.go @@ -23,6 +23,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/consensus" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS/utils" "github.com/XinFinOrg/XDC-Subnet/core/types" + "github.com/XinFinOrg/XDC-Subnet/params" "github.com/XinFinOrg/XDC-Subnet/rlp" "github.com/XinFinOrg/XDC-Subnet/rpc" ) @@ -52,6 +53,7 @@ type NetworkInformation struct { RelayerRegistrationAddress common.Address Denom string NetworkName string + ConsensusConfigs params.XDPoSConfig } type SignerTypes struct { @@ -221,22 +223,7 @@ func (api *API) GetV2BlockByHeader(header *types.Header, uncle bool) *V2BlockInf } func (api *API) GetV2BlockByNumber(number *rpc.BlockNumber) *V2BlockInfo { - var header *types.Header - if number == nil || *number == rpc.LatestBlockNumber { - header = api.chain.CurrentHeader() - } else if *number == rpc.CommittedBlockNumber { - latestCommittedBlock := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo() - if latestCommittedBlock == nil { - return &V2BlockInfo{ - Hash: header.Hash(), - Error: "can not find latest committed block from consensus", - } - } - header = api.chain.GetHeaderByHash(latestCommittedBlock.Hash) - } else { - header = api.chain.GetHeaderByNumber(uint64(number.Int64())) - } - + header := api.getHeaderFromApiBlockNum(number) if header == nil { return &V2BlockInfo{ Number: big.NewInt(number.Int64()), @@ -274,9 +261,30 @@ func (api *API) NetworkInformation() NetworkInformation { info.XDCValidatorAddress = common.HexToAddress(common.MasternodeVotingSMC) info.Denom = api.chain.Config().XDPoS.Denom info.NetworkName = api.chain.Config().XDPoS.NetworkName + info.ConsensusConfigs = *api.XDPoS.config return info } +/* +An API exclusively for V2 consensus, designed to assist in troubleshooting miners by identifying who mined during their allocated term. +*/ +func (api *API) GetMissedRoundsInEpochByBlockNum(number *rpc.BlockNumber) (*utils.PublicApiMissedRoundsMetadata, error) { + return api.XDPoS.CalculateMissingRounds(api.chain, api.getHeaderFromApiBlockNum(number)) +} + +func (api *API) getHeaderFromApiBlockNum(number *rpc.BlockNumber) *types.Header { + var header *types.Header + if number == nil || *number == rpc.LatestBlockNumber { + header = api.chain.CurrentHeader() + } else if *number == rpc.CommittedBlockNumber { + hash := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash + header = api.chain.GetHeaderByHash(hash) + } else { + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) + } + return header +} + func calculateSigners(message map[string]SignerTypes, pool map[string]map[common.Hash]utils.PoolObj, masternodes []common.Address) { for name, objs := range pool { var currentSigners []common.Address diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index 6a6d9d121..77ac37195 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -3,8 +3,8 @@ package engine_v2 import ( "encoding/json" "fmt" - "io/ioutil" "math/big" + "os" "path/filepath" "sync" "time" @@ -171,7 +171,7 @@ func (x *XDPoS_v2) Initial(chain consensus.ChainReader, header *types.Header) er } func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) error { - log.Info("[initial] initial v2 related parameters") + log.Warn("[initial] initial v2 related parameters") if x.highestQuorumCert.ProposedBlockInfo.Hash != (common.Hash{}) { // already initialized log.Info("[initial] Already initialized", "x.highestQuorumCert.ProposedBlockInfo.Hash", x.highestQuorumCert.ProposedBlockInfo.Hash) @@ -234,6 +234,7 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er log.Error("[initial] Error while get masternodes", "error", err) return err } + snap := newSnapshot(lastGapNum, lastGapHeader.Hash(), masternodes, []common.Address{}) x.snapshots.Add(snap.Hash, snap) err = storeSnapshot(snap, x.db) @@ -244,7 +245,7 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er } // Initial timeout - log.Info("[initial] miner wait period", "period", x.config.V2.CurrentConfig.MinePeriod) + log.Warn("[initial] miner wait period", "period", x.config.V2.CurrentConfig.MinePeriod) // avoid deadlock go func() { x.minePeriodCh <- x.config.V2.CurrentConfig.MinePeriod @@ -254,7 +255,7 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er x.timeoutWorker.Reset(chain) x.isInitilised = true - log.Info("[initial] finish initialisation") + log.Warn("[initial] finish initialisation") return nil } @@ -350,7 +351,7 @@ func (x *XDPoS_v2) Prepare(chain consensus.ChainReader, header *types.Header) er return err } if isEpochSwitchBlock { - masterNodes, err := x.calcMasternodes(chain, header.Number, header.ParentHash) + masterNodes, _, err := x.calcMasternodes(chain, header.Number, header.ParentHash, currentRound) if err != nil { return err } @@ -382,7 +383,7 @@ func (x *XDPoS_v2) Prepare(chain consensus.ChainReader, header *types.Header) er } if header.Coinbase != signer { - log.Error("[Prepare] The mined blocker header coinbase address mismatch with waller address", "headerCoinbase", header.Coinbase.Hex(), "WalletAddress", signer.Hex()) + log.Error("[Prepare] The mined blocker header coinbase address mismatch with wallet address", "headerCoinbase", header.Coinbase.Hex(), "WalletAddress", signer.Hex()) return consensus.ErrCoinbaseMismatch } @@ -407,7 +408,7 @@ func (x *XDPoS_v2) Finalize(chain consensus.ChainReader, header *types.Header, s if len(common.StoreRewardFolder) > 0 { data, err := json.Marshal(rewards) if err == nil { - err = ioutil.WriteFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644) + err = os.WriteFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644) } if err != nil { log.Error("Error when save reward info ", "number", header.Number, "hash", header.Hash().Hex(), "err", err) @@ -803,17 +804,6 @@ func (x *XDPoS_v2) VerifyBlockInfo(blockChainReader consensus.ChainReader, block } func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert *types.QuorumCert, parentHeader *types.Header) error { - /* - 1. Check if num of QC signatures is >= x.config.v2.CertThreshold - 2. Get epoch master node list by hash - 3. Verify signer signatures: (List of signatures) - - Use ecRecover to get the public key - - Use the above public key to find out the xdc address - - Use the above xdc address to check against the master node list from step 1(For the received QC epoch) - 4. Verify gapNumber = epochSwitchNumber - epochSwitchNumber%Epoch - Gap - 5. Verify blockInfo - */ - if quorumCert == nil { log.Warn("[verifyQC] QC is Nil") return utils.ErrInvalidQC @@ -834,9 +824,9 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert * qcRound := quorumCert.ProposedBlockInfo.Round certThreshold := x.config.V2.Config(uint64(qcRound)).CertThreshold - if (qcRound > 0) && (signatures == nil || (len(signatures) < certThreshold)) { + if (qcRound > 0) && (signatures == nil || float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold) { //First V2 Block QC, QC Signatures is initial nil - log.Warn("[verifyHeader] Invalid QC Signature is nil or less then config", "QC", quorumCert, "QCNumber", quorumCert.ProposedBlockInfo.Number, "Signatures len", len(signatures), "CertThreshold", certThreshold) + log.Warn("[verifyHeader] Invalid QC Signature is nil or less then config", "QC", quorumCert, "QCNumber", quorumCert.ProposedBlockInfo.Number, "Signatures len", len(signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold) return utils.ErrInvalidQCSignatures } start := time.Now() @@ -1041,14 +1031,12 @@ func (x *XDPoS_v2) GetStandbynodes(chain consensus.ChainReader, header *types.He } // Calculate masternodes for a block number and parent hash. In V2, truncating candidates[:MaxMasternodes] is done in this function. -func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash) ([]common.Address, error) { - // using new max masterndoes +func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash, round types.Round) ([]common.Address, []common.Address, error) { maxMasternodes := common.MaxMasternodes - snap, err := x.getSnapshot(chain, blockNum.Uint64(), false) if err != nil { log.Error("[calcMasternodes] Adaptor v2 getSnapshot has error", "err", err) - return nil, err + return nil, nil, err } // candidates are masternodes candidates := snap.NextEpochMasterNodes @@ -1058,16 +1046,8 @@ func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.In if len(masternodes) > maxMasternodes { masternodes = masternodes[:maxMasternodes] } - if len(masternodes) < x.config.V2.CurrentConfig.CertThreshold { - log.Warn("[calcMasternodes] Current epoch masternodes less than threshold", "number", blockNum, "masternodes", len(masternodes), "threshold", x.config.V2.CurrentConfig.CertThreshold) - for i, a := range masternodes { - log.Warn("final masternode", "i", i, "addr", a) - } - for i, a := range penalties { - log.Warn("penalty", "i", i, "addr", a) - } - } - return masternodes, nil + + return masternodes, penalties, nil } // Given hash, get master node from the epoch switch block of the epoch @@ -1104,15 +1084,17 @@ func (x *XDPoS_v2) allowedToSend(chain consensus.ChainReader, blockHeader *types for _, mn := range masterNodes { log.Debug("[allowedToSend] Master node list", "masterNodeAddress", mn.Hash()) } - log.Info("[allowedToSend] Not in the Masternode list, not suppose to send message", "sendType", sendType, "MyAddress", signer.Hex()) + log.Debug("[allowedToSend] Not in the Masternode list, not suppose to send message", "sendType", sendType, "MyAddress", signer.Hex()) return false } // Periodlly execution(Attached to engine initialisation during "new"). Used for pool cleaning etc func (x *XDPoS_v2) periodicJob() { go func() { + ticker := time.NewTicker(utils.PeriodicJobPeriod * time.Second) + defer ticker.Stop() for { - <-time.After(utils.PeriodicJobPeriod * time.Second) + <-ticker.C x.hygieneVotePool() x.hygieneTimeoutPool() } diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 09f81f773..7b26b6391 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -40,9 +40,10 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types penalties := []common.Address{} standbynodes := []common.Address{} epochSwitchInfo := &types.EpochSwitchInfo{ - Penalties: penalties, - Standbynodes: standbynodes, - Masternodes: masternodes, + Penalties: penalties, + Standbynodes: standbynodes, + Masternodes: masternodes, + MasternodesLen: len(masternodes), EpochSwitchBlockInfo: &types.BlockInfo{ Hash: hash, Number: h.Number, @@ -74,9 +75,10 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types standbynodes = common.RemoveItemFromArray(standbynodes, penalties) } epochSwitchInfo := &types.EpochSwitchInfo{ - Penalties: penalties, - Standbynodes: standbynodes, - Masternodes: masternodes, + Penalties: penalties, + Standbynodes: standbynodes, + Masternodes: masternodes, + MasternodesLen: len(masternodes), EpochSwitchBlockInfo: &types.BlockInfo{ Hash: hash, Number: h.Number, diff --git a/consensus/XDPoS/engines/engine_v2/forensics_test.go b/consensus/XDPoS/engines/engine_v2/forensics_test.go index 6c22673c9..229f54568 100644 --- a/consensus/XDPoS/engines/engine_v2/forensics_test.go +++ b/consensus/XDPoS/engines/engine_v2/forensics_test.go @@ -3,7 +3,6 @@ package engine_v2 import ( "crypto/ecdsa" "fmt" - "io/ioutil" "math/big" "math/rand" "os" @@ -48,7 +47,7 @@ func RandStringBytes(n int) string { func getSignerAndSignFn(pk *ecdsa.PrivateKey) (common.Address, func(account accounts.Account, hash []byte) ([]byte, error), error) { veryLightScryptN := 2 veryLightScryptP := 1 - dir, _ := ioutil.TempDir("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) + dir, _ := os.MkdirTemp("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) new := func(kd string) *keystore.KeyStore { return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) diff --git a/consensus/XDPoS/engines/engine_v2/mining.go b/consensus/XDPoS/engines/engine_v2/mining.go index 18f5b3b3a..ae5a9a1f9 100644 --- a/consensus/XDPoS/engines/engine_v2/mining.go +++ b/consensus/XDPoS/engines/engine_v2/mining.go @@ -26,7 +26,7 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare } var masterNodes []common.Address if isEpochSwitch { - masterNodes, err = x.calcMasternodes(chain, big.NewInt(0).Add(parent.Number, big.NewInt(1)), parent.Hash()) + masterNodes, _, err = x.calcMasternodes(chain, big.NewInt(0).Add(parent.Number, big.NewInt(1)), parent.Hash(), round) if err != nil { log.Error("[yourturn] Cannot calcMasternodes at gap num ", "err", err, "parent number", parent.Number) return false, err @@ -43,7 +43,7 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare curIndex := utils.Position(masterNodes, signer) if curIndex == -1 { - log.Warn("[yourturn] I am not in masternodes list", "Hash", parent.Hash(), "signer", signer) + log.Debug("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex()) return false, nil } diff --git a/consensus/XDPoS/engines/engine_v2/snapshot_test.go b/consensus/XDPoS/engines/engine_v2/snapshot_test.go index d73e4bf2e..8e282f5ec 100644 --- a/consensus/XDPoS/engines/engine_v2/snapshot_test.go +++ b/consensus/XDPoS/engines/engine_v2/snapshot_test.go @@ -2,7 +2,7 @@ package engine_v2 import ( "fmt" - "io/ioutil" + "os" "testing" "github.com/XinFinOrg/XDC-Subnet/common" @@ -24,7 +24,7 @@ func TestGetMasterNodes(t *testing.T) { func TestStoreLoadSnapshot(t *testing.T) { snap := newSnapshot(1, common.Hash{0x1}, nil, nil) - dir, err := ioutil.TempDir("", "snapshot-test") + dir, err := os.MkdirTemp("", "snapshot-test") if err != nil { panic(fmt.Sprintf("can't create temporary directory: %v", err)) } diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 25a813a4a..49fdb5e32 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -27,9 +27,15 @@ func (x *XDPoS_v2) timeoutHandler(blockChainReader consensus.ChainReader, timeou numberOfTimeoutsInPool, pooledTimeouts := x.timeoutPool.Add(timeout) log.Debug("[timeoutHandler] collect timeout", "number", numberOfTimeoutsInPool) + epochInfo, err := x.getEpochSwitchInfo(blockChainReader, blockChainReader.CurrentHeader(), blockChainReader.CurrentHeader().Hash()) + if err != nil { + log.Error("[timeoutHandler] Error when getting epoch switch Info", "error", err) + return fmt.Errorf("fail on timeoutHandler due to failure in getting epoch switch info, %s", err) + } + // Threshold reached certThreshold := x.config.V2.Config(uint64(x.currentRound)).CertThreshold - isThresholdReached := numberOfTimeoutsInPool >= certThreshold + isThresholdReached := float64(numberOfTimeoutsInPool) >= float64(epochInfo.MasternodesLen)*certThreshold if isThresholdReached { log.Info(fmt.Sprintf("Timeout pool threashold reached: %v, number of items in the pool: %v", isThresholdReached, numberOfTimeoutsInPool)) err := x.onTimeoutPoolThresholdReached(blockChainReader, pooledTimeouts, timeout, timeout.GapNumber) @@ -89,11 +95,11 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time snap, err := x.getSnapshot(chain, timeoutCert.GapNumber, true) if err != nil { log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "TCGapNumber", timeoutCert.GapNumber) - return fmt.Errorf("[verifyTC] Unable to get snapshot") + return fmt.Errorf("[verifyTC] Unable to get snapshot, %s", err) } if snap == nil || len(snap.NextEpochMasterNodes) == 0 { log.Error("[verifyTC] Something wrong with the snapshot from gapNumber", "messageGapNumber", timeoutCert.GapNumber, "snapshot", snap) - return fmt.Errorf("Empty master node lists from snapshot") + return fmt.Errorf("empty master node lists from snapshot") } signatures, duplicates := UniqueSignatures(timeoutCert.Signatures) @@ -103,14 +109,22 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time } } + epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + if err != nil { + log.Error("[verifyTC] Error when getting epoch switch Info", "error", err) + return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err) + } + certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold - if len(signatures) < certThreshold { - log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", certThreshold) + if float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold { + log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold) return utils.ErrInvalidTCSignatures } var wg sync.WaitGroup wg.Add(len(signatures)) + + var mutex sync.Mutex var haveError error signedTimeoutObj := types.TimeoutSigHash(&types.TimeoutForSign{ @@ -122,15 +136,19 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time go func(sig types.Signature) { defer wg.Done() verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochMasterNodes) - if err != nil { - log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err) - haveError = fmt.Errorf("Error while verfying TC message signatures") - return - } - if !verified { - log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures)) - haveError = fmt.Errorf("Fail to verify TC due to signature mis-match") - return + if err != nil || !verified { + log.Error("[verifyTC] Error or verification failure", "Signature", sig, "Error", err) + mutex.Lock() // Lock before accessing haveError + if haveError == nil { + if err != nil { + log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err) + haveError = fmt.Errorf("error while verifying TC message signatures, %s", err) + } else { + log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures)) + haveError = fmt.Errorf("fail to verify TC due to signature mis-match") + } + } + mutex.Unlock() // Unlock after modifying haveError } }(signature) } @@ -185,6 +203,7 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentBlockHeader, currentBlockHeader.Hash()) if err != nil { log.Error("[sendTimeout] Error when trying to get current epoch switch info for a non-epoch block", "currentRound", x.currentRound, "currentBlockNum", currentBlockHeader.Number, "currentBlockHash", currentBlockHeader.Hash(), "epochNum", epochNum) + return err } gapNumber = epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch - x.config.Gap // prevent overflow diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index 7e396c2d5..8d35008b3 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -6,6 +6,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/accounts" "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS/utils" + "github.com/XinFinOrg/XDC-Subnet/consensus" "github.com/XinFinOrg/XDC-Subnet/core/types" "github.com/XinFinOrg/XDC-Subnet/crypto" "github.com/XinFinOrg/XDC-Subnet/crypto/sha3" @@ -157,3 +158,62 @@ func (x *XDPoS_v2) GetRoundNumber(header *types.Header) (types.Round, error) { return decodedExtraField.Round, nil } } + +func (x *XDPoS_v2) GetSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) { + snap, err := x.getSnapshot(chain, header.Number.Uint64(), false) + if err != nil { + return nil, err + } + return snap.NextEpochMasterNodes, err +} + +func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiMissedRoundsMetadata, error) { + var missedRounds []utils.MissedRoundInfo + switchInfo, err := x.getEpochSwitchInfo(chain, header, header.Hash()) + if err != nil { + return nil, err + } + masternodes := switchInfo.Masternodes + + // Loop through from the epoch switch block to the current "header" block + nextHeader := header + for nextHeader.Number.Cmp(switchInfo.EpochSwitchBlockInfo.Number) > 0 { + parentHeader := chain.GetHeaderByHash(nextHeader.ParentHash) + parentRound, err := x.GetRoundNumber(parentHeader) + if err != nil { + return nil, err + } + currRound, err := x.GetRoundNumber(nextHeader) + if err != nil { + return nil, err + } + // This indicates that an increment in the round number is missing during the block production process. + if parentRound+1 != currRound { + // We need to iterate from the parentRound to the currRound to determine which miner did not perform mining. + for i := parentRound + 1; i < currRound; i++ { + leaderIndex := uint64(i) % x.config.Epoch % uint64(len(masternodes)) + whosTurn := masternodes[leaderIndex] + missedRounds = append( + missedRounds, + utils.MissedRoundInfo{ + Round: i, + Miner: whosTurn, + CurrentBlockHash: nextHeader.Hash(), + CurrentBlockNum: nextHeader.Number, + ParentBlockHash: parentHeader.Hash(), + ParentBlockNum: parentHeader.Number, + }, + ) + } + } + // Assign the pointer to the next one + nextHeader = parentHeader + } + missedRoundsMetadata := &utils.PublicApiMissedRoundsMetadata{ + EpochRound: switchInfo.EpochSwitchBlockInfo.Round, + EpochBlockNumber: switchInfo.EpochSwitchBlockInfo.Number, + MissedRounds: missedRounds, + } + + return missedRoundsMetadata, nil +} diff --git a/consensus/XDPoS/engines/engine_v2/verifyHeader.go b/consensus/XDPoS/engines/engine_v2/verifyHeader.go index 6ffd527eb..c5c02d4d8 100644 --- a/consensus/XDPoS/engines/engine_v2/verifyHeader.go +++ b/consensus/XDPoS/engines/engine_v2/verifyHeader.go @@ -36,7 +36,8 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade } if len(header.Validator) == 0 { - return consensus.ErrNoValidatorSignature + // This should never happen, if it does, then it means the peer is sending us invalid data. + return consensus.ErrNoValidatorSignatureV2 } if fullVerify { @@ -112,7 +113,7 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade return utils.ErrEmptyEpochSwitchValidators } - localMasterNodes, err := x.calcMasternodes(chain, header.Number, header.ParentHash) + localMasterNodes, _, err := x.calcMasternodes(chain, header.Number, header.ParentHash, round) masterNodes = localMasterNodes if err != nil { log.Error("[verifyHeader] Fail to calculate master nodes list with penalty", "Number", header.Number, "Hash", header.Hash()) @@ -168,7 +169,6 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade return err } - // Check its validator verified, validatorAddress, err := x.verifyMsgSignature(sigHash(header), header.Validator, masterNodes) if err != nil { for index, mn := range masterNodes { @@ -178,11 +178,11 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade return err } if !verified { - log.Warn("[verifyHeader] Fail to verify the block validator as the validator address not within the masternode list", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex()) + log.Warn("[verifyHeader] Fail to verify the block validator as the validator address not within the masternode list", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex()) return utils.ErrValidatorNotWithinMasternodes } if validatorAddress != header.Coinbase { - log.Warn("[verifyHeader] Header validator and coinbase address not match", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex(), "coinbase", header.Coinbase.Hex()) + log.Warn("[verifyHeader] Header validator and coinbase address not match", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validatorAddress", validatorAddress.Hex(), "coinbase", header.Coinbase.Hex()) return utils.ErrCoinbaseAndValidatorMismatch } // Check the proposer is the leader diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index e1aad0109..4c8c91342 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -79,15 +79,21 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *types.Vote) go x.ForensicsProcessor.DetectEquivocationInVotePool(voteMsg, x.votePool) go x.ForensicsProcessor.ProcessVoteEquivocation(chain, x, voteMsg) + epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + if err != nil { + log.Error("[voteHandler] Error when getting epoch switch Info", "error", err) + return fmt.Errorf("Fail on voteHandler due to failure in getting epoch switch info") + } + certThreshold := x.config.V2.Config(uint64(voteMsg.ProposedBlockInfo.Round)).CertThreshold - thresholdReached := numberOfVotesInPool >= certThreshold + thresholdReached := float64(numberOfVotesInPool) >= float64(epochInfo.MasternodesLen)*certThreshold if thresholdReached { log.Info(fmt.Sprintf("[voteHandler] Vote pool threashold reached: %v, number of items in the pool: %v", thresholdReached, numberOfVotesInPool)) // Check if the block already exist, otherwise we try luck with the next vote proposedBlockHeader := chain.GetHeaderByHash(voteMsg.ProposedBlockInfo.Hash) if proposedBlockHeader == nil { - log.Warn("[voteHandler] The proposed block from vote message does not exist yet, wait for the next vote to try again", "blockNum", voteMsg.ProposedBlockInfo.Number, "Hash", voteMsg.ProposedBlockInfo.Hash, "Round", voteMsg.ProposedBlockInfo.Round) + log.Info("[voteHandler] The proposed block from vote message does not exist yet, wait for the next vote to try again", "blockNum", voteMsg.ProposedBlockInfo.Number, "Hash", voteMsg.ProposedBlockInfo.Hash, "Round", voteMsg.ProposedBlockInfo.Round) return nil } @@ -160,9 +166,15 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole } } + epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + if err != nil { + log.Error("[voteHandler] Error when getting epoch switch Info", "error", err) + return fmt.Errorf("Fail on voteHandler due to failure in getting epoch switch info") + } + // Skip and wait for the next vote to process again if valid votes is less than what we required certThreshold := x.config.V2.Config(uint64(currentVoteMsg.(*types.Vote).ProposedBlockInfo.Round)).CertThreshold - if len(validSignatures) < certThreshold { + if float64(len(validSignatures)) < float64(epochInfo.MasternodesLen)*certThreshold { log.Warn("[onVotePoolThresholdReached] Not enough valid signatures to generate QC", "VotesSignaturesAfterFilter", validSignatures, "NumberOfValidVotes", len(validSignatures), "NumberOfVotes", len(pooledVotes)) return nil } @@ -172,7 +184,7 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole Signatures: validSignatures, GapNumber: currentVoteMsg.(*types.Vote).GapNumber, } - err := x.processQC(chain, quorumCert) + err = x.processQC(chain, quorumCert) if err != nil { log.Error("Error while processing QC in the Vote handler after reaching pool threshold, ", err) return err @@ -185,7 +197,7 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, blockInfo *types.BlockInfo, quorumCert *types.QuorumCert) (bool, error) { // Make sure this node has not voted for this round. if x.currentRound <= x.highestVotedRound { - log.Warn("Failed to pass the voting rule verification, currentRound is not large then highestVoteRound", "x.currentRound", x.currentRound, "x.highestVotedRound", x.highestVotedRound) + log.Info("Failed to pass the voting rule verification, currentRound is not large then highestVoteRound", "x.currentRound", x.currentRound, "x.highestVotedRound", x.highestVotedRound) return false, nil } /* @@ -195,7 +207,7 @@ func (x *XDPoS_v2) verifyVotingRule(blockChainReader consensus.ChainReader, bloc header's QC's ProposedBlockInfo.Round > lockQuorumCert's ProposedBlockInfo.Round */ if blockInfo.Round != x.currentRound { - log.Warn("Failed to pass the voting rule verification, blockRound is not equal currentRound", "x.currentRound", x.currentRound, "blockInfo.Round", blockInfo.Round) + log.Info("Failed to pass the voting rule verification, blockRound is not equal currentRound", "x.currentRound", x.currentRound, "blockInfo.Round", blockInfo.Round) return false, nil } // XDPoS v1.0 switch to v2.0, the proposed block can always pass voting rule diff --git a/consensus/XDPoS/utils/errors.go b/consensus/XDPoS/utils/errors.go index 49821782e..31be30152 100644 --- a/consensus/XDPoS/utils/errors.go +++ b/consensus/XDPoS/utils/errors.go @@ -93,8 +93,8 @@ var ( ErrInvalidTCSignatures = errors.New("Invalid TC Signatures") ErrEmptyBlockInfoHash = errors.New("BlockInfo hash is empty") ErrInvalidFieldInNonEpochSwitch = errors.New("Invalid field exist in a non-epoch swtich block") - ErrValidatorNotWithinMasternodes = errors.New("Validaotor address is not in the master node list") - ErrCoinbaseAndValidatorMismatch = errors.New("Validaotor and coinbase address in header does not match") + ErrValidatorNotWithinMasternodes = errors.New("Validator address is not in the master node list") + ErrCoinbaseAndValidatorMismatch = errors.New("Validator and coinbase address in header does not match") ErrNotItsTurn = errors.New("Not validator's turn to mine this block") ErrInvalidFieldInNonGapPlusOneSwitch = errors.New("invalid field exist in a non-gapPlusOne swtich block") diff --git a/consensus/XDPoS/utils/types.go b/consensus/XDPoS/utils/types.go index 166503edf..1b551c2e6 100644 --- a/consensus/XDPoS/utils/types.go +++ b/consensus/XDPoS/utils/types.go @@ -57,3 +57,17 @@ type PublicApiSnapshot struct { Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating } + +type MissedRoundInfo struct { + Round types.Round + Miner common.Address + CurrentBlockHash common.Hash + CurrentBlockNum *big.Int + ParentBlockHash common.Hash + ParentBlockNum *big.Int +} +type PublicApiMissedRoundsMetadata struct { + EpochRound types.Round + EpochBlockNumber *big.Int + MissedRounds []MissedRoundInfo +} diff --git a/consensus/errors.go b/consensus/errors.go index 0747516f8..c8ed578c2 100644 --- a/consensus/errors.go +++ b/consensus/errors.go @@ -39,6 +39,8 @@ var ( ErrNoValidatorSignature = errors.New("no validator in header") + ErrNoValidatorSignatureV2 = errors.New("no validator in v2 header") + ErrNotReadyToPropose = errors.New("not ready to propose, QC is not ready") ErrNotReadyToMine = errors.New("Not ready to mine, it's not your turn") diff --git a/consensus/ethash/algorithm.go b/consensus/ethash/algorithm.go index 357294405..3e7655111 100644 --- a/consensus/ethash/algorithm.go +++ b/consensus/ethash/algorithm.go @@ -156,12 +156,16 @@ func generateCache(dest []uint32, epoch uint64, seed []byte) { defer close(done) go func() { + waitDuration := 3 * time.Second + timer := time.NewTimer(waitDuration) + defer timer.Stop() for { select { case <-done: return - case <-time.After(3 * time.Second): + case <-timer.C: logger.Info("Generating ethash verification cache", "percentage", atomic.LoadUint32(&progress)*100/uint32(rows)/4, "elapsed", common.PrettyDuration(time.Since(start))) + timer.Reset(waitDuration) } } }() diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index 1d23a5715..8ddacea14 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -18,7 +18,6 @@ package ethash import ( "bytes" - "io/ioutil" "math/big" "os" "reflect" @@ -688,7 +687,7 @@ func TestHashimoto(t *testing.T) { // Tests that caches generated on disk may be done concurrently. func TestConcurrentDiskCacheGeneration(t *testing.T) { // Create a temp folder to generate the caches into - cachedir, err := ioutil.TempDir("", "") + cachedir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("Failed to create temporary cache dir: %v", err) } diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go index 885f81ae2..715abb0d7 100644 --- a/consensus/ethash/ethash_test.go +++ b/consensus/ethash/ethash_test.go @@ -17,7 +17,6 @@ package ethash import ( - "io/ioutil" "math/big" "math/rand" "os" @@ -46,7 +45,7 @@ func TestTestMode(t *testing.T) { // This test checks that cache lru logic doesn't crash under load. // It reproduces https://github.com/XinFinOrg/XDC-Subnet/issues/14943 func TestCacheFileEvict(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "ethash-test") + tmpdir, err := os.MkdirTemp("", "ethash-test") if err != nil { t.Fatal(err) } diff --git a/consensus/tests/api_test.go b/consensus/tests/api_test.go new file mode 100644 index 000000000..9abc7c743 --- /dev/null +++ b/consensus/tests/api_test.go @@ -0,0 +1,32 @@ +package tests + +import ( + "math/big" + "testing" + + "github.com/XinFinOrg/XDC-Subnet/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS" + "github.com/XinFinOrg/XDC-Subnet/core" + "github.com/XinFinOrg/XDC-Subnet/crypto" + "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/stretchr/testify/assert" +) + +var ( + voterKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee04aefe388d1e14474d32c45c72ce7b7a") + voterAddr = crypto.PubkeyToAddress(voterKey.PublicKey) //xdc5F74529C0338546f82389402a01c31fB52c6f434 +) + +func TestConfigApi(t *testing.T) { + bc := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, + }, 10000000, params.TestXDPoSMockChainConfig, nil) + + engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + + info := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).NetworkInformation() + assert.Equal(t, info.NetworkId, big.NewInt(1337)) + assert.Equal(t, info.ConsensusConfigs.V2.CurrentConfig.CertThreshold, 0.667) + assert.Equal(t, info.ConsensusConfigs.V2.CurrentConfig.MinePeriod, 2) + assert.Equal(t, info.ConsensusConfigs.V2.CurrentConfig.TimeoutSyncThreshold, 2) +} diff --git a/consensus/tests/engine_v2_tests/adaptor_test.go b/consensus/tests/engine_v2_tests/adaptor_test.go index a27eebafe..76944b39e 100644 --- a/consensus/tests/engine_v2_tests/adaptor_test.go +++ b/consensus/tests/engine_v2_tests/adaptor_test.go @@ -136,7 +136,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) { err := blockchain.InsertBlock(currentBlock) assert.Nil(t, err) masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header()) - assert.Equal(t, 20, len(masternodes1)) + assert.Equal(t, 5, len(masternodes1)) masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64()) assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum) for blockNum = 902; blockNum < 915; blockNum++ { diff --git a/consensus/tests/engine_v2_tests/api_test.go b/consensus/tests/engine_v2_tests/api_test.go new file mode 100644 index 000000000..cab0ee131 --- /dev/null +++ b/consensus/tests/engine_v2_tests/api_test.go @@ -0,0 +1,99 @@ +package engine_v2_tests + +import ( + "math/big" + "testing" + + "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS" + "github.com/XinFinOrg/XDC-Subnet/core/types" + "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/XinFinOrg/XDC-Subnet/rpc" + "github.com/stretchr/testify/assert" +) + +func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2(t *testing.T) { + _, bc, cb, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) + + engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + blockNum := rpc.BlockNumber(cb.NumberU64()) + + data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + + assert.Nil(t, err) + assert.Equal(t, types.Round(1800), data.EpochRound) + assert.Equal(t, big.NewInt(1800), data.EpochBlockNumber) + assert.Equal(t, 0, len(data.MissedRounds)) + + blockNum = rpc.BlockNumber(1800) + + data, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + + assert.Nil(t, err) + assert.Equal(t, types.Round(1800), data.EpochRound) + assert.Equal(t, big.NewInt(1800), data.EpochBlockNumber) + assert.Equal(t, 0, len(data.MissedRounds)) + + blockNum = rpc.BlockNumber(1801) + + data, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + + assert.Nil(t, err) + assert.Equal(t, types.Round(1800), data.EpochRound) + assert.Equal(t, big.NewInt(1800), data.EpochBlockNumber) + assert.Equal(t, 0, len(data.MissedRounds)) +} + +func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2FistEpoch(t *testing.T) { + _, bc, _, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 10, params.TestXDPoSMockChainConfig) + + engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + blockNum := rpc.BlockNumber(2) + + data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + + assert.Nil(t, err) + assert.Equal(t, types.Round(0), data.EpochRound) + assert.Equal(t, big.NewInt(0), data.EpochBlockNumber) + assert.Equal(t, 0, len(data.MissedRounds)) +} + +func TestGetMissedRoundsInEpochByBlockNum(t *testing.T) { + blockchain, bc, currentBlock, signer, signFn := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) + chainConfig := params.TestXDPoSMockChainConfig + engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + blockCoinBase := signer.Hex() + + startingBlockNum := currentBlock.Number().Int64() + 1 + // Skipped the round + roundNumber := startingBlockNum + 2 + block := CreateBlock(blockchain, chainConfig, currentBlock, int(startingBlockNum), roundNumber, blockCoinBase, signer, signFn, nil, nil, "c2bf7b59be5184fc1148be5db14692b2dc89a1b345895d3e8d0ee7b8a7607450") + err := blockchain.InsertBlock(block) + if err != nil { + t.Fatal(err) + } + + // Update Signer as there is no previous signer assigned + err = UpdateSigner(blockchain) + if err != nil { + t.Fatal(err) + } + + blockNum := rpc.BlockNumber(1803) + + data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + + assert.Nil(t, err) + assert.Equal(t, types.Round(1800), data.EpochRound) + assert.Equal(t, big.NewInt(1800), data.EpochBlockNumber) + assert.Equal(t, 2, len(data.MissedRounds)) + assert.NotEmpty(t, data.MissedRounds[0].Miner) + assert.Equal(t, data.MissedRounds[0].Round, types.Round(1803)) + assert.Equal(t, data.MissedRounds[0].CurrentBlockNum, big.NewInt(1803)) + assert.Equal(t, data.MissedRounds[0].ParentBlockNum, big.NewInt(1802)) + assert.NotEmpty(t, data.MissedRounds[1].Miner) + assert.Equal(t, data.MissedRounds[1].Round, types.Round(1804)) + assert.Equal(t, data.MissedRounds[0].CurrentBlockNum, big.NewInt(1803)) + assert.Equal(t, data.MissedRounds[0].ParentBlockNum, big.NewInt(1802)) + + assert.NotEqual(t, data.MissedRounds[0].Miner, data.MissedRounds[1].Miner) +} diff --git a/consensus/tests/engine_v2_tests/authorised_masternode_test.go b/consensus/tests/engine_v2_tests/authorised_masternode_test.go index 4dcf44a3b..bbe7805fb 100644 --- a/consensus/tests/engine_v2_tests/authorised_masternode_test.go +++ b/consensus/tests/engine_v2_tests/authorised_masternode_test.go @@ -1,7 +1,6 @@ package engine_v2_tests import ( - "fmt" "math/big" "testing" "time" @@ -47,21 +46,21 @@ func TestIsYourTurnConsensusV2(t *testing.T) { err := blockchain.InsertBlock(currentBlock) assert.Nil(t, err) // Less then Mine Period - isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.StringToAddress(fmt.Sprintf("%02d", 2))) + isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, acc2Addr) assert.Nil(t, err) assert.False(t, isYourTurn) time.Sleep(time.Duration(minePeriod) * time.Second) // The second address is valid as the round starting from 1 - isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, common.StringToAddress(fmt.Sprintf("%02d", 2))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc2Addr) assert.Nil(t, err) assert.True(t, isYourTurn) // The first and third address are not valid - isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.StringToAddress(fmt.Sprintf("%02d", 1))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc1Addr) assert.Nil(t, err) assert.False(t, isYourTurn) - isYourTurn, err = adaptor.YourTurn(blockchain, currentBlock.Header(), common.StringToAddress(fmt.Sprintf("%02d", 3))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc3Addr) assert.Nil(t, err) assert.False(t, isYourTurn) @@ -73,13 +72,13 @@ func TestIsYourTurnConsensusV2(t *testing.T) { time.Sleep(time.Duration(minePeriod) * time.Second) adaptor.EngineV2.SetNewRoundFaker(blockchain, 2, false) - isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.StringToAddress(fmt.Sprintf("%02d", 2))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc2Addr) assert.False(t, isYourTurn) - isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.StringToAddress(fmt.Sprintf("%02d", 3))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc3Addr) assert.True(t, isYourTurn) - isYourTurn, _ = adaptor.YourTurn(blockchain, currentBlock.Header(), common.StringToAddress(fmt.Sprintf("%02d", 1))) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc1Addr) assert.False(t, isYourTurn) } @@ -100,7 +99,7 @@ func TestIsYourTurnConsensusV2CrossConfig(t *testing.T) { assert.Nil(t, err) // after first mine period time.Sleep(time.Duration(firstMinePeriod) * time.Second) - isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0000000000000000000000000000000000003131")) + isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, acc1Addr) assert.Nil(t, err) assert.False(t, isYourTurn) @@ -110,7 +109,7 @@ func TestIsYourTurnConsensusV2CrossConfig(t *testing.T) { secondMinePeriod := blockchain.Config().XDPoS.V2.CurrentConfig.MinePeriod time.Sleep(time.Duration(secondMinePeriod-firstMinePeriod) * time.Second) - isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0000000000000000000000000000000000003131")) + isYourTurn, err = adaptor.YourTurn(blockchain, currentBlockHeader, acc1Addr) assert.Nil(t, err) assert.True(t, isYourTurn) } diff --git a/consensus/tests/engine_v2_tests/forensics_test.go b/consensus/tests/engine_v2_tests/forensics_test.go index 6c70e6875..8b2fa1878 100644 --- a/consensus/tests/engine_v2_tests/forensics_test.go +++ b/consensus/tests/engine_v2_tests/forensics_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/XinFinOrg/XDC-Subnet/accounts" + "github.com/XinFinOrg/XDC-Subnet/accounts/abi/bind/backends" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS/utils" "github.com/XinFinOrg/XDC-Subnet/core/types" @@ -43,13 +44,19 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) { Signature: signedHash, GapNumber: 450, } + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) + signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: signedHash, + GapNumber: 450, + } err = engineV2.VoteHandler(blockchain, voteMsg) assert.Nil(t, err) - // Create a vote message that should trigger vote pool hook, but master-signed votes is not enough signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes()) - assert.Nil(t, err) voteMsg = &types.Vote{ ProposedBlockInfo: blockInfo, Signature: signedHash, @@ -58,7 +65,20 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) { err = engineV2.VoteHandler(blockchain, voteMsg) assert.Nil(t, err) - // Create a vote message that should trigger vote pool hook, and master-signed votes is enough and increment the round to 6 + // Create another vote which is signed by someone not from the master node list + randomSigner, randomSignFn, err := backends.SimulateWalletAddressAndSignFn("") + assert.Nil(t, err) + randomlySignedHash, err := randomSignFn(accounts.Account{Address: randomSigner}, voteSigningHash.Bytes()) + assert.Nil(t, err) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: randomlySignedHash, + GapNumber: 450, + } + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) + + // Create a vote message that should trigger vote pool hook and increment the round to 6 signedHash = SignHashByPK(acc3Key, voteSigningHash.Bytes()) voteMsg = &types.Vote{ ProposedBlockInfo: blockInfo, diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index ce89bc239..06f2038a0 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -6,7 +6,6 @@ import ( "crypto/ecdsa" "encoding/hex" "fmt" - "io/ioutil" "math/big" "math/rand" "os" @@ -78,7 +77,7 @@ func RandStringBytes(n int) string { func getSignerAndSignFn(pk *ecdsa.PrivateKey) (common.Address, func(account accounts.Account, hash []byte) ([]byte, error), error) { veryLightScryptN := 2 veryLightScryptP := 1 - dir, _ := ioutil.TempDir("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) + dir, _ := os.MkdirTemp("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) new := func(kd string) *keystore.KeyStore { return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) @@ -124,14 +123,6 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig, signer comm var candidates []common.Address var caps []*big.Int - defalutCap := new(big.Int) - defalutCap.SetString("1000000000", 10) - - for i := 1; i <= 15; i++ { - addr := fmt.Sprintf("%02d", i) - candidates = append(candidates, common.StringToAddress(addr)) // StringToAddress does not exist - caps = append(caps, defalutCap) - } acc1Cap, acc2Cap, acc3Cap, voterCap, signerCap := new(big.Int), new(big.Int), new(big.Int), new(big.Int), new(big.Int) @@ -141,8 +132,9 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig, signer comm voterCap.SetString("10000002", 10) signerCap.SetString("10000001", 10) - caps = append(caps, voterCap, acc1Cap, acc2Cap, acc3Cap, signerCap) - candidates = append(candidates, voterAddr, acc1Addr, acc2Addr, acc3Addr, signer) + caps = append(caps, acc1Cap, acc2Cap, acc3Cap, signerCap, voterCap) + candidates = append(candidates, acc1Addr, acc2Addr, acc3Addr, signer, voterAddr) + // initial helper backend contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, @@ -572,6 +564,19 @@ func PrepareXDCTestBlockChainWith128Candidates(t *testing.T, numOfBlocks int, ch if err != nil { t.Fatal(err) } + + //FROM XDPOS: find v2 switch block, don't need in subnet + // First v2 block + // if (int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64()) == 1 { + // lastv1BlockNumber := block.Header().Number.Uint64() - 1 + // checkpointBlockNumber := lastv1BlockNumber - lastv1BlockNumber%chainConfig.XDPoS.Epoch + // checkpointHeader := blockchain.GetHeaderByNumber(checkpointBlockNumber) + // err := engine.EngineV2.Initial(blockchain, checkpointHeader) + // if err != nil { + // panic(err) + // } + // } + currentBlock = block } @@ -609,7 +614,7 @@ func PrepareQCandProcess(t *testing.T, blockchain *BlockChain, currentBlock *typ func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), penalties []common.Address, signersKey []*ecdsa.PrivateKey, merkleRoot string) *types.Block { currentBlock := startingBlock if len(merkleRoot) == 0 { - merkleRoot = "b3e34cf1d3d80bcd2c5add880842892733e45979ddaf16e531f660fdf7ca5787" + merkleRoot = "711be05c0b9d89bd511dd4c20ade1820b2c1fb13343ee0cedd3869150eb2d377" } var header *types.Header statedb, err := blockchain.State() @@ -757,6 +762,8 @@ func findSignerAndSignFn(bc *BlockChain, header *types.Header, signer common.Add } else if index == 3 { // Skip signing anything for voterAddress to simulate penalty return signer, signFn + } else if index == 4 { + _, signFn, err = getSignerAndSignFn(voterKey) } addressedSignFn = signFn if err != nil { @@ -781,7 +788,7 @@ func sealHeader(bc *BlockChain, header *types.Header, signer common.Address, sig func getMasternodesList(signer common.Address) []common.Address { var masternodes []common.Address // Place the test's signer address to the last - masternodes = append(masternodes, acc1Addr, acc2Addr, acc3Addr, signer) + masternodes = append(masternodes, acc1Addr, acc2Addr, acc3Addr, signer, voterAddr) return masternodes } diff --git a/consensus/tests/engine_v2_tests/mine_test.go b/consensus/tests/engine_v2_tests/mine_test.go index d133ab03d..1f70bf4ed 100644 --- a/consensus/tests/engine_v2_tests/mine_test.go +++ b/consensus/tests/engine_v2_tests/mine_test.go @@ -28,7 +28,7 @@ func TestYourTurnInitialV2(t *testing.T) { t.Logf("Inserting block with propose at 11...") blockCoinbaseA := "0xaaa0000000000000000000000000000000000011" //Get from block validator error message - merkleRoot := "b3e34cf1d3d80bcd2c5add880842892733e45979ddaf16e531f660fdf7ca5787" + merkleRoot := "711be05c0b9d89bd511dd4c20ade1820b2c1fb13343ee0cedd3869150eb2d377" extraInBytes := generateV2Extra(11, parentBlock, signer, signFn, nil) header := &types.Header{ @@ -55,10 +55,10 @@ func TestYourTurnInitialV2(t *testing.T) { time.Sleep(time.Duration(minePeriod) * time.Second) // YourTurn is called before mine first v2 block - b, err := adaptor.YourTurn(blockchain, block11.Header(), common.HexToAddress("xdc0000000000000000000000000000000000003031")) + b, err := adaptor.YourTurn(blockchain, block11.Header(), acc1Addr) assert.Nil(t, err) assert.False(t, b) - b, err = adaptor.YourTurn(blockchain, block11.Header(), common.HexToAddress("xdc0000000000000000000000000000000000003132")) + b, err = adaptor.YourTurn(blockchain, block11.Header(), acc2Addr) assert.Nil(t, err) // round=1, so masternode[1] has YourTurn = True assert.True(t, b) @@ -79,7 +79,7 @@ func TestShouldMineOncePerRound(t *testing.T) { _, err := adaptor.Seal(blockchain, block910, nil) assert.Nil(t, err) time.Sleep(time.Duration(minePeriod) * time.Second) - merkleRoot := "b3e34cf1d3d80bcd2c5add880842892733e45979ddaf16e531f660fdf7ca5787" + merkleRoot := "711be05c0b9d89bd511dd4c20ade1820b2c1fb13343ee0cedd3869150eb2d377" header := &types.Header{ Root: common.HexToHash(merkleRoot), @@ -128,7 +128,7 @@ func TestUpdateMasterNodes(t *testing.T) { t.Fatal(err) } //Get from block validator error message - merkleRoot := "42970e0f2265db7d85d0d9cd7328d58bd53bdb54d85d7997e95a1c3f60845602" + merkleRoot := "2f34d88e4afb95a51b5dd3b157bdec944790c033bbf6e990cc7f946ad07d47c4" header := &types.Header{ Root: common.HexToHash(merkleRoot), Number: big.NewInt(int64(1350)), @@ -209,7 +209,7 @@ func TestPrepareFail(t *testing.T) { err = adaptor.Prepare(blockchain, notReadyToMine) assert.Equal(t, consensus.ErrNotReadyToMine, err) - adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(19), false) + adaptor.EngineV2.SetNewRoundFaker(blockchain, types.Round(18), false) header901WithoutCoinbase := &types.Header{ ParentHash: currentBlock.ParentHash(), Number: big.NewInt(int64(901)), diff --git a/consensus/tests/engine_v2_tests/penalty_test.go b/consensus/tests/engine_v2_tests/penalty_test.go index 243620f88..fb7e500e4 100644 --- a/consensus/tests/engine_v2_tests/penalty_test.go +++ b/consensus/tests/engine_v2_tests/penalty_test.go @@ -33,7 +33,7 @@ func TestHookPenaltyV2TwoEpoch(t *testing.T) { header450 := blockchain.GetHeaderByNumber(450) penalty, err := adaptor.EngineV2.HookPenalty(blockchain, header450.Number, header450.ParentHash, masternodes, config.XDPoS) assert.Nil(t, err) - assert.Equal(t, 125, len(penalty)) // we have 4 miners created for all blocks, 3 is among 128 masternode candidates (test issue, no need to fix). So 125 candidates left are penalties + assert.Equal(t, 124, len(penalty)) // we have 4 miners created for all blocks, 3 is among 128 masternode candidates (test issue, no need to fix). So 125 candidates left are penalties header1335 := blockchain.GetHeaderByNumber(config.XDPoS.Epoch + config.XDPoS.Gap - uint64(common.MergeSignRange)) tx, err := signingTxWithKey(header1335, 0, voterKey) diff --git a/consensus/tests/engine_v2_tests/timeout_test.go b/consensus/tests/engine_v2_tests/timeout_test.go index 5177b14e1..6fe445176 100644 --- a/consensus/tests/engine_v2_tests/timeout_test.go +++ b/consensus/tests/engine_v2_tests/timeout_test.go @@ -145,15 +145,14 @@ func TestTimeoutPeriodAndThreadholdConfigChange(t *testing.T) { // Timeout handler func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { - params.TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig = params.UnitTestV2Configs[0] blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, nil) engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 // Set round to 1 - engineV2.SetNewRoundFaker(blockchain, types.Round(1), false) + engineV2.SetNewRoundFaker(blockchain, types.Round(5), false) // Create two timeout message which will not reach timeout pool threshold timeoutMsg := &types.Timeout{ - Round: types.Round(1), + Round: types.Round(5), Signature: []byte{1}, GapNumber: 450, } @@ -161,32 +160,39 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { err := engineV2.TimeoutHandler(blockchain, timeoutMsg) assert.Nil(t, err) currentRound, _, _, _, _, _ := engineV2.GetPropertiesFaker() - assert.Equal(t, types.Round(1), currentRound) + assert.Equal(t, types.Round(5), currentRound) timeoutMsg = &types.Timeout{ - Round: types.Round(1), + Round: types.Round(5), Signature: []byte{2}, GapNumber: 450, } err = engineV2.TimeoutHandler(blockchain, timeoutMsg) assert.Nil(t, err) + timeoutMsg = &types.Timeout{ + Round: types.Round(5), + Signature: []byte{3}, + GapNumber: 450, + } + err = engineV2.TimeoutHandler(blockchain, timeoutMsg) + assert.Nil(t, err) currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() - assert.Equal(t, types.Round(1), currentRound) + assert.Equal(t, types.Round(5), currentRound) // Send a timeout with different gap number, it shall not trigger timeout pool hook timeoutMsg = &types.Timeout{ - Round: types.Round(1), - Signature: []byte{3}, + Round: types.Round(5), + Signature: []byte{4}, GapNumber: 1350, } err = engineV2.TimeoutHandler(blockchain, timeoutMsg) assert.Nil(t, err) currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() - assert.Equal(t, types.Round(1), currentRound) + assert.Equal(t, types.Round(5), currentRound) // Create a timeout message that should trigger timeout pool hook timeoutMsg = &types.Timeout{ - Round: types.Round(1), - Signature: []byte{4}, + Round: types.Round(5), + Signature: []byte{5}, GapNumber: 450, } @@ -205,12 +211,12 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert assert.NotNil(t, tc) - assert.Equal(t, tc.Round, types.Round(1)) + assert.Equal(t, tc.Round, types.Round(5)) assert.Equal(t, uint64(450), tc.GapNumber) // The signatures shall not include the byte{3} from a different gap number - sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{4}} + sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}, []byte{5}} assert.ElementsMatch(t, tc.Signatures, sigatures) - assert.Equal(t, types.Round(2), currentRound) + assert.Equal(t, types.Round(6), currentRound) } func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) { diff --git a/consensus/tests/engine_v2_tests/verify_header_test.go b/consensus/tests/engine_v2_tests/verify_header_test.go index 1cc3fa3ef..145f641ae 100644 --- a/consensus/tests/engine_v2_tests/verify_header_test.go +++ b/consensus/tests/engine_v2_tests/verify_header_test.go @@ -1,6 +1,7 @@ package engine_v2_tests import ( + "encoding/json" "fmt" "math/big" "testing" @@ -24,7 +25,7 @@ func TestShouldVerifyBlock(t *testing.T) { adaptor := blockchain.Engine().(*XDPoS.XDPoS) // Happy path - happyPathHeader := blockchain.GetBlockByNumber(919).Header() + happyPathHeader := blockchain.GetBlockByNumber(920).Header() err := adaptor.VerifyHeader(blockchain, happyPathHeader, true) assert.Nil(t, err) @@ -38,7 +39,7 @@ func TestShouldVerifyBlock(t *testing.T) { noValidatorBlock := blockchain.GetBlockByNumber(902).Header() noValidatorBlock.Validator = []byte{} err = adaptor.VerifyHeader(blockchain, noValidatorBlock, true) - assert.Equal(t, consensus.ErrNoValidatorSignature, err) + assert.Equal(t, consensus.ErrNoValidatorSignatureV2, err) blockFromFuture := blockchain.GetBlockByNumber(902).Header() blockFromFuture.Time = big.NewInt(time.Now().Unix() + 10000) @@ -77,7 +78,7 @@ func TestShouldVerifyBlock(t *testing.T) { err = adaptor.VerifyHeader(blockchain, invalidPenaltiesExistBlock, true) assert.Equal(t, utils.ErrInvalidFieldInNonGapPlusOneSwitch, err) - merkleRoot := "b3e34cf1d3d80bcd2c5add880842892733e45979ddaf16e531f660fdf7ca5787" + merkleRoot := "711be05c0b9d89bd511dd4c20ade1820b2c1fb13343ee0cedd3869150eb2d377" parentNotExistBlock := blockchain.GetBlockByNumber(901).Header() parentNotExistBlock.ParentHash = common.HexToHash(merkleRoot) err = adaptor.VerifyHeader(blockchain, parentNotExistBlock, true) @@ -216,9 +217,10 @@ func TestConfigSwitchOnDifferentCertThreshold(t *testing.T) { acc1SignedHash = SignHashByPK(acc1Key, types.VoteSigHash(voteForSign).Bytes()) acc2SignedHash = SignHashByPK(acc2Key, types.VoteSigHash(voteForSign).Bytes()) acc3SignedHash = SignHashByPK(acc3Key, types.VoteSigHash(voteForSign).Bytes()) + voteSignedHash := SignHashByPK(voterKey, types.VoteSigHash(voteForSign).Bytes()) var signaturesThr []types.Signature - signaturesThr = append(signaturesThr, acc1SignedHash, acc2SignedHash, acc3SignedHash) + signaturesThr = append(signaturesThr, acc1SignedHash, acc2SignedHash, acc3SignedHash, voteSignedHash) quorumCert = &types.QuorumCert{ ProposedBlockInfo: proposedBlockInfo, Signatures: signaturesThr, @@ -240,6 +242,50 @@ func TestConfigSwitchOnDifferentCertThreshold(t *testing.T) { assert.Equal(t, utils.ErrValidatorNotWithinMasternodes, err) } +/* + 1. Insert 20 masternode before gap block + 2. Prepare 20 masternode block header with round 9000 + 3. verify this header while node is on round 899, + This is to simulate node is syncing from remote during config switch +*/ +func TestConfigSwitchOnDifferentMasternodeCount(t *testing.T) { + b, err := json.Marshal(params.TestXDPoSMockChainConfig) + assert.Nil(t, err) + configString := string(b) + + var config params.ChainConfig + err = json.Unmarshal([]byte(configString), &config) + assert.Nil(t, err) + // Enable verify + config.XDPoS.V2.SkipV2Validation = false + // Block 901 is the first v2 block with round of 1 + blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*2, &config, nil) + adaptor := blockchain.Engine().(*XDPoS.XDPoS) + x := adaptor.EngineV2 + + // Generate round 900 header, num 1800 + header1800 := blockchain.GetBlockByNumber(1800).Header() + + snap, err := x.GetSnapshot(blockchain, currentBlock.Header()) + assert.Nil(t, err) + assert.Equal(t, len(snap.NextEpochMasterNodes), 5) + header1800.Validators = []common.Address{} + for i := 0; i < len(snap.NextEpochMasterNodes); i++ { + header1800.Validators = append(header1800.Validators, []common.Address{snap.NextEpochMasterNodes[i]}...) + } + + round, err := x.GetRoundNumber(header1800) + assert.Nil(t, err) + assert.Equal(t, round, types.Round(1800)) + + adaptor.EngineV2.SetNewRoundFaker(blockchain, 1799, false) + + err = adaptor.VerifyHeader(blockchain, header1800, true) + + // error ErrValidatorNotWithinMasternodes means verifyQC is passed and move to next verification process + assert.Equal(t, utils.ErrValidatorNotWithinMasternodes, err) +} + func TestConfigSwitchOnDifferentMindPeriod(t *testing.T) { config := params.TestXDPoSMockChainConfig // Enable verify diff --git a/consensus/tests/engine_v2_tests/vote_test.go b/consensus/tests/engine_v2_tests/vote_test.go index 9f4cf1b5e..86d6fd3cb 100644 --- a/consensus/tests/engine_v2_tests/vote_test.go +++ b/consensus/tests/engine_v2_tests/vote_test.go @@ -35,7 +35,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te // Set round to 1 engineV2.SetNewRoundFaker(blockchain, types.Round(1), false) - // Create two vote messages which will not reach vote pool threshold + // Create three vote messages which will not reach vote pool threshold signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) assert.Nil(t, err) voteMsg := &types.Vote{ @@ -52,8 +52,16 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te assert.Equal(t, types.Round(0), highestQuorumCert.ProposedBlockInfo.Round) assert.Equal(t, types.Round(1), currentRound) - signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes()) + signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: signedHash, + GapNumber: 0, + } + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) + signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes()) voteMsg = &types.Vote{ ProposedBlockInfo: blockInfo, Signature: signedHash, @@ -104,7 +112,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) { // Set round to 5 engineV2.SetNewRoundFaker(blockchain, types.Round(5), false) - // Create two vote messages which will not reach vote pool threshold + // Create three vote messages which will not reach vote pool threshold signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) assert.Nil(t, err) voteMsg := &types.Vote{ @@ -127,6 +135,15 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) { } err = engineV2.VoteHandler(blockchain, voteMsg) assert.Nil(t, err) + + signedHash = SignHashByPK(acc2Key, voteSigningHash.Bytes()) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: signedHash, + GapNumber: 0, + } + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) currentRound, lockQuorumCert, highestQuorumCert, _, _, _ = engineV2.GetPropertiesFaker() // Still using the initlised value because we did not yet go to the next round assert.Equal(t, types.Round(3), lockQuorumCert.ProposedBlockInfo.Round) @@ -212,7 +229,7 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi } func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { - blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 5, params.TestXDPoSMockChainConfig, nil) + blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 5, params.TestXDPoSMockChainConfig, nil) engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 // Set round to 5 @@ -229,15 +246,27 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { GapNumber: 0, } voteSigningHash := types.VoteSigHash(voteForSign) - // Create two vote message which will not reach vote pool threshold - signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes()) + + // Create three vote message which will not reach vote pool threshold + signedHash, err := signFn(accounts.Account{Address: signer}, voteSigningHash.Bytes()) + assert.Nil(t, err) voteMsg := &types.Vote{ ProposedBlockInfo: blockInfo, Signature: signedHash, GapNumber: 0, } - err := engineV2.VoteHandler(blockchain, voteMsg) + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) + + signedHash = SignHashByPK(acc1Key, voteSigningHash.Bytes()) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: signedHash, + GapNumber: 0, + } + + err = engineV2.VoteHandler(blockchain, voteMsg) assert.Nil(t, err) currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() // initialised with nil and 0 round @@ -301,13 +330,19 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { } err = engineV2.TimeoutHandler(blockchain, timeoutMsg) assert.Nil(t, err) + timeoutMsg = &types.Timeout{ + Round: types.Round(6), + Signature: []byte{3}, + } + err = engineV2.TimeoutHandler(blockchain, timeoutMsg) + assert.Nil(t, err) currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() assert.Equal(t, types.Round(6), currentRound) // Create a timeout message that should trigger timeout pool hook timeoutMsg = &types.Timeout{ Round: types.Round(6), - Signature: []byte{3}, + Signature: []byte{4}, } err = engineV2.TimeoutHandler(blockchain, timeoutMsg) @@ -324,7 +359,7 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { tc := syncInfoMsg.(*types.SyncInfo).HighestTimeoutCert assert.NotNil(t, tc) assert.Equal(t, types.Round(6), tc.Round) - sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}} + sigatures := []types.Signature{[]byte{1}, []byte{2}, []byte{3}, []byte{4}} assert.ElementsMatch(t, tc.Signatures, sigatures) // Round shall be +1 now currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() @@ -428,7 +463,7 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) { GapNumber: 0, } voteSigningHash := types.VoteSigHash(voteForSign) - // Create two vote message which will not reach vote pool threshold + // Create three vote message which will not reach vote pool threshold signedHash := SignHashByPK(acc1Key, voteSigningHash.Bytes()) voteMsg := &types.Vote{ ProposedBlockInfo: blockInfo, @@ -450,13 +485,20 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) { } err = engineV2.VoteHandler(blockchain, voteMsg) assert.Nil(t, err) + voteMsg = &types.Vote{ + ProposedBlockInfo: blockInfo, + Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()), + GapNumber: 0, + } + err = engineV2.VoteHandler(blockchain, voteMsg) + assert.Nil(t, err) currentRound, _, _, _, _, _ = engineV2.GetPropertiesFaker() assert.Equal(t, types.Round(5), currentRound) // Create a vote message that should trigger vote pool hook voteMsg = &types.Vote{ ProposedBlockInfo: blockInfo, - Signature: SignHashByPK(acc3Key, voteSigningHash.Bytes()), + Signature: SignHashByPK(voterKey, voteSigningHash.Bytes()), GapNumber: 0, } diff --git a/console/console.go b/console/console.go index a7da0643b..8acd13384 100644 --- a/console/console.go +++ b/console/console.go @@ -19,7 +19,6 @@ package console import ( "fmt" "io" - "io/ioutil" "os" "os/signal" "path/filepath" @@ -137,7 +136,7 @@ func (c *Console) init(preload []string) error { // Configure the input prompter for history and tab completion. if c.prompter != nil { - if content, err := ioutil.ReadFile(c.histPath); err != nil { + if content, err := os.ReadFile(c.histPath); err != nil { c.prompter.SetHistory(nil) } else { c.history = strings.Split(string(content), "\n") @@ -452,7 +451,7 @@ func (c *Console) Execute(path string) error { // Stop cleans up the console and terminates the runtime environment. func (c *Console) Stop(graceful bool) error { - if err := ioutil.WriteFile(c.histPath, []byte(strings.Join(c.history, "\n")), 0600); err != nil { + if err := os.WriteFile(c.histPath, []byte(strings.Join(c.history, "\n")), 0600); err != nil { return err } if err := os.Chmod(c.histPath, 0600); err != nil { // Force 0600, even if it was different previously diff --git a/console/console_test.go b/console/console_test.go index 5c0c20503..b49f0f6e0 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -19,14 +19,14 @@ package console import ( "bytes" "errors" - "github.com/XinFinOrg/XDC-Subnet/XDCx" - "github.com/XinFinOrg/XDC-Subnet/XDCxlending" - "io/ioutil" "os" "strings" "testing" "time" + "github.com/XinFinOrg/XDC-Subnet/XDCx" + "github.com/XinFinOrg/XDC-Subnet/XDCxlending" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/consensus/ethash" "github.com/XinFinOrg/XDC-Subnet/core" @@ -86,7 +86,7 @@ type tester struct { // Please ensure you call Close() on the returned tester to avoid leaks. func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { // Create a temporary storage for the node keys and initialize it - workspace, err := ioutil.TempDir("", "console-tester-") + workspace, err := os.MkdirTemp("", "console-tester-") if err != nil { t.Fatalf("failed to create temporary keystore: %v", err) } diff --git a/contracts/chequebook/cheque.go b/contracts/chequebook/cheque.go index 8a31a0603..f6465e685 100644 --- a/contracts/chequebook/cheque.go +++ b/contracts/chequebook/cheque.go @@ -30,7 +30,6 @@ import ( "crypto/ecdsa" "encoding/json" "fmt" - "io/ioutil" "math/big" "os" "sync" @@ -160,7 +159,7 @@ func (self *Chequebook) setBalanceFromBlockChain() { // LoadChequebook loads a chequebook from disk (file path). func LoadChequebook(path string, prvKey *ecdsa.PrivateKey, backend Backend, checkBalance bool) (self *Chequebook, err error) { var data []byte - data, err = ioutil.ReadFile(path) + data, err = os.ReadFile(path) if err != nil { return } @@ -230,7 +229,7 @@ func (self *Chequebook) Save() (err error) { } self.log.Trace("Saving chequebook to disk", self.path) - return ioutil.WriteFile(self.path, data, os.ModePerm) + return os.WriteFile(self.path, data, os.ModePerm) } // Stop quits the autodeposit go routine to terminate diff --git a/contracts/chequebook/gencode.go b/contracts/chequebook/gencode.go index 258ec27f8..269d81488 100644 --- a/contracts/chequebook/gencode.go +++ b/contracts/chequebook/gencode.go @@ -23,8 +23,8 @@ package main import ( "fmt" - "io/ioutil" "math/big" + "os" "github.com/XinFinOrg/XDC-Subnet/accounts/abi/bind" "github.com/XinFinOrg/XDC-Subnet/accounts/abi/bind/backends" @@ -65,7 +65,7 @@ func main() { // updated when the contract code is changed. const ContractDeployedCode = "%#x" `, code) - if err := ioutil.WriteFile("contract/code.go", []byte(content), 0644); err != nil { + if err := os.WriteFile("contract/code.go", []byte(content), 0644); err != nil { panic(err) } } diff --git a/contracts/trc21issuer/simulation/test/main.go b/contracts/trc21issuer/simulation/test/main.go index 7633465c3..f764a8c85 100644 --- a/contracts/trc21issuer/simulation/test/main.go +++ b/contracts/trc21issuer/simulation/test/main.go @@ -49,11 +49,10 @@ func airDropTokenToAccountNoXDC() { if err != nil { log.Fatal("can't transaction's receipt ", err, "hash", tx.Hash().Hex()) } - fee := big.NewInt(0).SetUint64(hexutil.MustDecodeUint64(receipt["gasUsed"].(string))) - if hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) > common.TIPTRC21Fee.Uint64() { - fee = fee.Mul(fee, common.TRC21GasPrice) - } - fmt.Println("fee", fee.Uint64(), "number", hexutil.MustDecodeUint64(receipt["blockNumber"].(string))) + gasUsed := hexutil.MustDecodeUint64(receipt["gasUsed"].(string)) + blockNumber := hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) + fee := common.GetGasFee(blockNumber, gasUsed) + fmt.Println("fee", fee.Uint64(), "number", blockNumber) remainFee = big.NewInt(0).Sub(remainFee, fee) //check balance fee balanceIssuerFee, err := trc21IssuerInstance.GetTokenCapacity(trc21TokenAddr) @@ -112,11 +111,10 @@ func testTransferTRC21TokenWithAccountNoXDC() { if err != nil { log.Fatal("can't transaction's receipt ", err, "hash", tx.Hash().Hex()) } - fee := big.NewInt(0).SetUint64(hexutil.MustDecodeUint64(receipt["gasUsed"].(string))) - if hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) > common.TIPTRC21Fee.Uint64() { - fee = fee.Mul(fee, common.TRC21GasPrice) - } - fmt.Println("fee", fee.Uint64(), "number", hexutil.MustDecodeUint64(receipt["blockNumber"].(string))) + gasUsed := hexutil.MustDecodeUint64(receipt["gasUsed"].(string)) + blockNumber := hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) + fee := common.GetGasFee(blockNumber, gasUsed) + fmt.Println("fee", fee.Uint64(), "number", blockNumber) remainFee = big.NewInt(0).Sub(remainFee, fee) //check balance fee balanceIssuerFee, err := trc21IssuerInstance.GetTokenCapacity(trc21TokenAddr) @@ -179,11 +177,10 @@ func testTransferTrc21Fail() { if err != nil { log.Fatal("can't transaction's receipt ", err, "hash", tx.Hash().Hex()) } - fee := big.NewInt(0).SetUint64(hexutil.MustDecodeUint64(receipt["gasUsed"].(string))) - if hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) > common.TIPTRC21Fee.Uint64() { - fee = fee.Mul(fee, common.TRC21GasPrice) - } - fmt.Println("fee", fee.Uint64(), "number", hexutil.MustDecodeUint64(receipt["blockNumber"].(string))) + gasUsed := hexutil.MustDecodeUint64(receipt["gasUsed"].(string)) + blockNumber := hexutil.MustDecodeUint64(receipt["blockNumber"].(string)) + fee := common.GetGasFee(blockNumber, gasUsed) + fmt.Println("fee", fee.Uint64(), "number", blockNumber) remainFee = big.NewInt(0).Sub(remainFee, fee) //check balance fee balanceIssuerFee, err = trc21IssuerInstance.GetTokenCapacity(trc21TokenAddr) diff --git a/contracts/trc21issuer/trc21issuer_test.go b/contracts/trc21issuer/trc21issuer_test.go index 85e44aecc..77087171b 100644 --- a/contracts/trc21issuer/trc21issuer_test.go +++ b/contracts/trc21issuer/trc21issuer_test.go @@ -82,10 +82,7 @@ func TestFeeTxWithTRC21Token(t *testing.T) { if err != nil { t.Fatal("can't transaction's receipt ", err, "hash", tx.Hash()) } - fee := big.NewInt(0).SetUint64(receipt.GasUsed) - if receipt.Logs[0].BlockNumber > common.TIPTRC21Fee.Uint64() { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(receipt.Logs[0].BlockNumber, receipt.GasUsed) remainFee := big.NewInt(0).Sub(minApply, fee) // check balance trc21 again @@ -134,10 +131,7 @@ func TestFeeTxWithTRC21Token(t *testing.T) { if err != nil { t.Fatal("can't transaction's receipt ", err, "hash", tx.Hash()) } - fee = big.NewInt(0).SetUint64(receipt.GasUsed) - if receipt.Logs[0].BlockNumber > common.TIPTRC21Fee.Uint64() { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee = common.GetGasFee(receipt.Logs[0].BlockNumber, receipt.GasUsed) remainFee = big.NewInt(0).Sub(remainFee, fee) //check balance fee balanceIssuerFee, err = trc21Issuer.GetTokenCapacity(trc21TokenAddr) diff --git a/core/asm/asm_test.go b/core/asm/asm_test.go index 92b26b67a..cd7520ec6 100644 --- a/core/asm/asm_test.go +++ b/core/asm/asm_test.go @@ -22,53 +22,37 @@ import ( "encoding/hex" ) -// Tests disassembling the instructions for valid evm code -func TestInstructionIteratorValid(t *testing.T) { - cnt := 0 - script, _ := hex.DecodeString("61000000") - - it := NewInstructionIterator(script) - for it.Next() { - cnt++ - } - - if err := it.Error(); err != nil { - t.Errorf("Expected 2, but encountered error %v instead.", err) - } - if cnt != 2 { - t.Errorf("Expected 2, but got %v instead.", cnt) - } -} - -// Tests disassembling the instructions for invalid evm code -func TestInstructionIteratorInvalid(t *testing.T) { - cnt := 0 - script, _ := hex.DecodeString("6100") - - it := NewInstructionIterator(script) - for it.Next() { - cnt++ - } - - if it.Error() == nil { - t.Errorf("Expected an error, but got %v instead.", cnt) - } -} - -// Tests disassembling the instructions for empty evm code -func TestInstructionIteratorEmpty(t *testing.T) { - cnt := 0 - script, _ := hex.DecodeString("") - - it := NewInstructionIterator(script) - for it.Next() { - cnt++ - } - - if err := it.Error(); err != nil { - t.Errorf("Expected 0, but encountered error %v instead.", err) - } - if cnt != 0 { - t.Errorf("Expected 0, but got %v instead.", cnt) +// Tests disassembling instructions +func TestInstructionIterator(t *testing.T) { + for i, tc := range []struct { + want int + code string + wantErr string + }{ + {2, "61000000", ""}, // valid code + {0, "6100", "incomplete push instruction at 0"}, // invalid code + {2, "5900", ""}, // push0 + {0, "", ""}, // empty + + } { + var ( + have int + code, _ = hex.DecodeString(tc.code) + it = NewInstructionIterator(code) + ) + for it.Next() { + have++ + } + var haveErr = "" + if it.Error() != nil { + haveErr = it.Error().Error() + } + if haveErr != tc.wantErr { + t.Errorf("test %d: encountered error: %q want %q", i, haveErr, tc.wantErr) + continue + } + if have != tc.want { + t.Errorf("wrong instruction count, have %d want %d", have, tc.want) + } } } diff --git a/core/bench_test.go b/core/bench_test.go index f06d76f6b..c54d1a1e0 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -18,12 +18,12 @@ package core import ( "crypto/ecdsa" - "github.com/XinFinOrg/XDC-Subnet/core/rawdb" - "io/ioutil" "math/big" "os" "testing" + "github.com/XinFinOrg/XDC-Subnet/core/rawdb" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/common/math" "github.com/XinFinOrg/XDC-Subnet/consensus/ethash" @@ -151,7 +151,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { if !disk { db = rawdb.NewMemoryDatabase() } else { - dir, err := ioutil.TempDir("", "eth-core-bench") + dir, err := os.MkdirTemp("", "eth-core-bench") if err != nil { b.Fatalf("cannot create temporary directory: %v", err) } @@ -248,7 +248,7 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) { func benchWriteChain(b *testing.B, full bool, count uint64) { for i := 0; i < b.N; i++ { - dir, err := ioutil.TempDir("", "eth-chain-bench") + dir, err := os.MkdirTemp("", "eth-chain-bench") if err != nil { b.Fatalf("cannot create temporary directory: %v", err) } @@ -263,7 +263,7 @@ func benchWriteChain(b *testing.B, full bool, count uint64) { } func benchReadChain(b *testing.B, full bool, count uint64) { - dir, err := ioutil.TempDir("", "eth-chain-bench") + dir, err := os.MkdirTemp("", "eth-chain-bench") if err != nil { b.Fatalf("cannot create temporary directory: %v", err) } diff --git a/core/blockchain.go b/core/blockchain.go index 0931f9976..33e123dbb 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -39,6 +39,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/consensus" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS" "github.com/XinFinOrg/XDC-Subnet/consensus/XDPoS/utils" + contractValidator "github.com/XinFinOrg/XDC-Subnet/contracts/validator/contract" "github.com/XinFinOrg/XDC-Subnet/core/state" "github.com/XinFinOrg/XDC-Subnet/core/types" "github.com/XinFinOrg/XDC-Subnet/core/vm" @@ -986,8 +987,9 @@ func (bc *BlockChain) procFutureBlocks() { if i == len(blocks)-1 && err == nil { engine, ok := bc.Engine().(*XDPoS.XDPoS) if ok { + j := i go func() { - header := blocks[i].Header() + header := blocks[j].Header() err = engine.HandleProposedBlock(bc, header) if err != nil { log.Info("[procFutureBlocks] handle proposed block has error", "err", err, "block hash", header.Hash(), "number", header.Number) @@ -2199,6 +2201,31 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { return fmt.Errorf("Invalid new chain") } } + // Ensure XDPoS engine committed block will be not reverted + if xdpos, ok := bc.Engine().(*XDPoS.XDPoS); ok { + latestCommittedBlock := xdpos.EngineV2.GetLatestCommittedBlockInfo() + if latestCommittedBlock != nil { + currentBlock := bc.CurrentBlock() + currentBlock.Number().Cmp(latestCommittedBlock.Number) + cmp := commonBlock.Number().Cmp(latestCommittedBlock.Number) + if cmp < 0 { + for _, oldBlock := range oldChain { + if oldBlock.Number().Cmp(latestCommittedBlock.Number) == 0 { + if oldBlock.Hash() != latestCommittedBlock.Hash { + log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "committed hash", latestCommittedBlock.Hash) + } else { + log.Warn("Stop reorg, blockchain is under forking attack", "old committed num", oldBlock.Number(), "old committed hash", oldBlock.Hash()) + return fmt.Errorf("stop reorg, blockchain is under forking attack. old committed num %d, hash %x", oldBlock.Number(), oldBlock.Hash()) + } + } + } + } else if cmp == 0 { + if commonBlock.Hash() != latestCommittedBlock.Hash { + log.Error("Impossible reorg, please file an issue", "oldnum", commonBlock.Number(), "oldhash", commonBlock.Hash(), "committed hash", latestCommittedBlock.Hash) + } + } + } + } // Ensure the user sees large reorgs if len(oldChain) > 0 && len(newChain) > 0 { logFn := log.Warn @@ -2319,7 +2346,11 @@ func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, e var roundNumber = types.Round(0) engine, ok := bc.Engine().(*XDPoS.XDPoS) if ok { + var err error roundNumber, err = engine.EngineV2.GetRoundNumber(block.Header()) + if err != nil { + log.Error("reportBlock", "GetRoundNumber", err) + } } var receiptString string @@ -2428,6 +2459,11 @@ func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { return bc.hc.HasHeader(hash, number) } +// GetCanonicalHash returns the canonical hash for a given block number +func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash { + return bc.hc.GetCanonicalHash(number) +} + // GetBlockHashesFromHash retrieves a number of block hashes starting at a given // hash, fetching towards the genesis block. func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { @@ -2498,22 +2534,38 @@ func (bc *BlockChain) UpdateM1() error { } log.Info("It's time to update new set of masternodes for the next epoch...") // get masternodes information from smart contract + client, err := bc.GetClient() + if err != nil { + return err + } + addr := common.HexToAddress(common.MasternodeVotingSMC) + validator, err := contractValidator.NewXDCValidator(addr, client) + if err != nil { + return err + } + opts := new(bind.CallOpts) var candidates []common.Address // get candidates from slot of stateDB // if can't get anything, request from contracts stateDB, err := bc.State() if err != nil { - log.Error("update masternodes has statedb error", "error", err) - return err + candidates, err = validator.GetCandidates(opts) + if err != nil { + return err + } + } else { + candidates = state.GetCandidates(stateDB) } - candidates = state.GetCandidates(stateDB) var ms []utils.Masternode for _, candidate := range candidates { - v := state.GetCandidateCap(stateDB, candidate) - //TODO: smart contract shouldn't return "0x0000000000000000000000000000000000000000" - if candidate.String() != "0x0000000000000000000000000000000000000000" { + v, err := validator.GetCandidateCap(opts, candidate) + if err != nil { + return err + } + // TODO: smart contract shouldn't return "0x0000000000000000000000000000000000000000" + if !candidate.IsZero() { ms = append(ms, utils.Masternode{Address: candidate, Stake: v}) } } diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go index 92cee971e..732bac02c 100644 --- a/core/bloombits/matcher.go +++ b/core/bloombits/matcher.go @@ -606,6 +606,9 @@ func (s *MatcherSession) DeliverSections(bit uint, sections []uint64, bitsets [] // of the session, any request in-flight need to be responded to! Empty responses // are fine though in that case. func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) { + ticker := time.NewTicker(wait) + defer ticker.Stop() + for { // Allocate a new bloom bit index to retrieve data for, stopping when done bit, ok := s.AllocateRetrieval() @@ -621,7 +624,7 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan s.DeliverSections(bit, []uint64{}, [][]byte{}) return - case <-time.After(wait): + case <-ticker.C: // Throttling up, fetch whatever's available } } diff --git a/core/chain_makers.go b/core/chain_makers.go index da8f9ff48..6903a0bb9 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -108,10 +108,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if b.header.Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(b.header.Number.Uint64(), gas) state.UpdateTRC21Fee(b.statedb, map[common.Address]*big.Int{*tx.To(): new(big.Int).Sub(feeCapacity[*tx.To()], new(big.Int).SetUint64(gas))}, fee) } } diff --git a/core/database_util.go b/core/database_util.go index e0016ea32..d6c9a6ea6 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -260,6 +260,10 @@ func GetBlockReceipts(db DatabaseReader, hash common.Hash, number uint64) types. receipts := make(types.Receipts, len(storageReceipts)) for i, receipt := range storageReceipts { receipts[i] = (*types.Receipt)(receipt) + for _, log := range receipts[i].Logs { + // update BlockHash to fix #208 + log.BlockHash = hash + } } return receipts } diff --git a/core/evm.go b/core/evm.go index 926607292..8ec115e31 100644 --- a/core/evm.go +++ b/core/evm.go @@ -23,17 +23,23 @@ import ( "github.com/XinFinOrg/XDC-Subnet/consensus" "github.com/XinFinOrg/XDC-Subnet/core/types" "github.com/XinFinOrg/XDC-Subnet/core/vm" + "github.com/XinFinOrg/XDC-Subnet/crypto" ) // NewEVMContext creates a new context for use in the EVM. func NewEVMContext(msg Message, header *types.Header, chain consensus.ChainContext, author *common.Address) vm.Context { // If we don't have an explicit author (i.e. not mining), extract from the header - var beneficiary common.Address + var ( + beneficiary common.Address + random common.Hash + ) if author == nil { beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation } else { beneficiary = *author } + // since xdpos chain do not use difficulty and mixdigest, we use hash of the block number as random + random = crypto.Keccak256Hash(header.Number.Bytes()) return vm.Context{ CanTransfer: CanTransfer, Transfer: Transfer, @@ -45,6 +51,7 @@ func NewEVMContext(msg Message, header *types.Header, chain consensus.ChainConte Difficulty: new(big.Int).Set(header.Difficulty), GasLimit: header.GasLimit, GasPrice: new(big.Int).Set(msg.GasPrice()), + Random: &random, } } diff --git a/core/headerchain.go b/core/headerchain.go index 9347cb730..b05c2cab1 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -383,6 +383,11 @@ func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { return hc.GetHeader(hash, number) } +func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash { + // TODO: return rawdb.ReadCanonicalHash(hc.chainDb, number) + return GetCanonicalHash(hc.chainDb, number) +} + // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. func (hc *HeaderChain) CurrentHeader() *types.Header { diff --git a/core/lending_pool.go b/core/lending_pool.go index b32beb7c1..12d476783 100644 --- a/core/lending_pool.go +++ b/core/lending_pool.go @@ -431,11 +431,11 @@ func (pool *LendingPool) validateNewLending(cloneStateDb *state.StateDB, cloneLe return ErrInvalidLendingType } if tx.Side() == lendingstate.Borrowing { - if tx.CollateralToken().String() == lendingstate.EmptyAddress || tx.CollateralToken().String() == tx.LendingToken().String() { + if tx.CollateralToken().IsZero() || tx.CollateralToken() == tx.LendingToken() { return ErrInvalidLendingCollateral } validCollateral := false - collateralList, _ := lendingstate.GetCollaterals(cloneStateDb, tx.RelayerAddress(), tx.LendingToken(), tx.Term()) + collateralList := lendingstate.GetCollaterals(cloneStateDb, tx.RelayerAddress(), tx.LendingToken(), tx.Term()) for _, collateral := range collateralList { if tx.CollateralToken().String() == collateral.String() { validCollateral = true @@ -541,7 +541,7 @@ func (pool *LendingPool) validateBalance(cloneStateDb *state.StateDB, cloneLendi // collateralPrice = BTC/USD (eg: 8000 USD) // lendTokenXDCPrice: price of lendingToken in XDC quote var lendTokenXDCPrice, collateralPrice, collateralTokenDecimal *big.Int - if collateralToken.String() != lendingstate.EmptyAddress { + if !collateralToken.IsZero() { collateralTokenDecimal, err = XDCXServ.GetTokenDecimal(pool.chain, cloneStateDb, collateralToken) if err != nil { return fmt.Errorf("validateOrder: failed to get collateralTokenDecimal. err: %v", err) @@ -944,9 +944,10 @@ func (pool *LendingPool) removeTx(hash common.Hash) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *LendingPool) promoteExecutables(accounts []common.Address) { - start := time.Now() log.Debug("start promoteExecutables") - defer log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + defer func(start time.Time) { + log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + }(time.Now()) // Gather all the accounts potentially needing updates if accounts == nil { accounts = make([]common.Address, 0, len(pool.queue)) diff --git a/core/order_pool.go b/core/order_pool.go index f50234dc3..a01038286 100644 --- a/core/order_pool.go +++ b/core/order_pool.go @@ -859,8 +859,10 @@ func (pool *OrderPool) removeTx(hash common.Hash) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *OrderPool) promoteExecutables(accounts []common.Address) { - start := time.Now() - defer log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + defer func(start time.Time) { + log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + }(time.Now()) + // Gather all the accounts potentially needing updates if accounts == nil { accounts = make([]common.Address, 0, len(pool.queue)) diff --git a/core/state/state_object.go b/core/state/state_object.go index a36e3cb9b..bd5a4b15f 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -306,9 +306,6 @@ func (self *stateObject) setBalance(amount *big.Int) { } } -// Return the gas back to the origin. Used by the Virtual machine or Closures -func (c *stateObject) ReturnGas(gas *big.Int) {} - func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { stateObject := newObject(db, self.address, self.data, onDirty) if self.trie != nil { @@ -396,6 +393,10 @@ func (self *stateObject) Nonce() uint64 { return self.data.Nonce } +func (self *stateObject) Root() common.Hash { + return self.data.Root +} + // Never called, but must be present to allow stateObject to be used // as a vm.Account interface that also satisfies the vm.ContractRef // interface. Interfaces are awesome. diff --git a/core/state/statedb.go b/core/state/statedb.go index 097d5891d..ef9ba12ab 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -83,6 +83,14 @@ type StateDB struct { lock sync.Mutex } +type AccountInfo struct { + CodeSize int + Nonce uint64 + Balance *big.Int + CodeHash common.Hash + StorageHash common.Hash +} + func (self *StateDB) SubRefund(gas uint64) { self.journal = append(self.journal, refundChange{ prev: self.refund}) @@ -221,6 +229,16 @@ func (self *StateDB) GetNonce(addr common.Address) uint64 { return 0 } +// GetStorageRoot retrieves the storage root from the given address or empty +// if object not found. +func (self *StateDB) GetStorageRoot(addr common.Address) common.Hash { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.Root() + } + return common.Hash{} +} + func (self *StateDB) GetCode(addr common.Address) []byte { stateObject := self.getStateObject(addr) if stateObject != nil { @@ -252,6 +270,28 @@ func (self *StateDB) GetCodeHash(addr common.Address) common.Hash { return common.BytesToHash(stateObject.CodeHash()) } +func (self *StateDB) GetAccountInfo(addr common.Address) *AccountInfo { + result := AccountInfo{} + + stateObject := self.getStateObject(addr) + if stateObject == nil { + result.Balance = common.Big0 + return &result + } + + if stateObject.code != nil { + result.CodeSize = len(stateObject.code) + } else { + result.CodeSize, _ = self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) + } + result.Nonce = stateObject.Nonce() + result.Balance = stateObject.Balance() + result.CodeHash = common.BytesToHash(stateObject.CodeHash()) + result.StorageHash = stateObject.Root() + + return &result +} + func (self *StateDB) GetState(addr common.Address, bhash common.Hash) common.Hash { stateObject := self.getStateObject(addr) if stateObject != nil { diff --git a/core/state/statedb_utils.go b/core/state/statedb_utils.go index c3c2a191b..718e54ddf 100644 --- a/core/state/statedb_utils.go +++ b/core/state/statedb_utils.go @@ -93,16 +93,17 @@ func GetCandidates(statedb *StateDB) []common.Address { slot := slotValidatorMapping["candidates"] slotHash := common.BigToHash(new(big.Int).SetUint64(slot)) arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash) - keys := []common.Hash{} - for i := uint64(0); i < arrLength.Big().Uint64(); i++ { + count := arrLength.Big().Uint64() + rets := make([]common.Address, 0, count) + + for i := uint64(0); i < count; i++ { key := GetLocDynamicArrAtElement(slotHash, i, 1) - keys = append(keys, key) - } - rets := []common.Address{} - for _, key := range keys { ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key) - rets = append(rets, common.HexToAddress(ret.Hex())) + if !ret.IsZero() { + rets = append(rets, common.HexToAddress(ret.Hex())) + } } + return rets } diff --git a/core/state_processor.go b/core/state_processor.go index 07550658b..7b66f8d29 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -120,10 +120,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if block.Header().Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(block.Header().Number.Uint64(), gas) balanceFee[*tx.To()] = new(big.Int).Sub(balanceFee[*tx.To()], fee) balanceUpdated[*tx.To()] = balanceFee[*tx.To()] totalFeeUsed = totalFeeUsed.Add(totalFeeUsed, fee) @@ -201,10 +198,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated receipts[i] = receipt allLogs = append(allLogs, receipt.Logs...) if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if block.Header().Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(block.Header().Number.Uint64(), gas) balanceFee[*tx.To()] = new(big.Int).Sub(balanceFee[*tx.To()], fee) balanceUpdated[*tx.To()] = balanceFee[*tx.To()] totalFeeUsed = totalFeeUsed.Add(totalFeeUsed, fee) @@ -409,7 +403,7 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // End Bypass blacklist address // Apply the transaction to the current state (included in the env) - _, gas, failed, err := ApplyMessage(vmenv, msg, gp, coinbaseOwner) + _, gas, failed, err, _ := ApplyMessage(vmenv, msg, gp, coinbaseOwner) if err != nil { return nil, 0, err, false diff --git a/core/state_transition.go b/core/state_transition.go index 8a1387c3a..2d3d09780 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -131,7 +131,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) ([]byte, uint64, bool, error) { +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) ([]byte, uint64, bool, error, error) { return NewStateTransition(evm, msg, gp).TransitionDb(owner) } @@ -217,7 +217,7 @@ func (st *StateTransition) preCheck() error { // TransitionDb will transition the state by applying the current message and // returning the result including the the used gas. It returns an error if it // failed. An error indicates a consensus issue. -func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedGas uint64, failed bool, err error) { +func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedGas uint64, failed bool, err error, vmErr error) { if err = st.preCheck(); err != nil { return } @@ -230,10 +230,10 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG // Pay intrinsic gas gas, err := IntrinsicGas(st.data, contractCreation, homestead) if err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } if err = st.useGas(gas); err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } var ( @@ -263,7 +263,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG // sufficient balance to make the transfer happen. The first // balance transfer may never fail. if vmerr == vm.ErrInsufficientBalance { - return nil, 0, false, vmerr + return nil, 0, false, vmerr, nil } } st.refundGas() @@ -276,7 +276,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) } - return ret, st.gasUsed(), vmerr != nil, err + return ret, st.gasUsed(), vmerr != nil, err, vmerr } func (st *StateTransition) refundGas() { diff --git a/core/token_validator.go b/core/token_validator.go index 7a5ac2b81..a1efae02f 100644 --- a/core/token_validator.go +++ b/core/token_validator.go @@ -112,7 +112,7 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{}) gaspool := new(GasPool).AddGas(1000000) owner := common.Address{} - rval, _, _, err := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + rval, _, _, err, _ := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) if err != nil { return nil, err } diff --git a/core/tx_list.go b/core/tx_list.go index 35e6af59c..d180cdd30 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -290,7 +290,7 @@ func (l *txList) Forward(threshold uint64) types.Transactions { // a point in calculating all the costs or if the balance covers all. If the threshold // is lower than the costgas cap, the caps will be reset to a new high after removing // the newly invalidated transactions. -func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[common.Address]*big.Int) (types.Transactions, types.Transactions) { +func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[common.Address]*big.Int, number *big.Int) (types.Transactions, types.Transactions) { // If all transactions are below the threshold, short circuit if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { return nil, nil @@ -303,7 +303,7 @@ func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[co maximum := costLimit if tx.To() != nil { if feeCapacity, ok := trc21Issuers[*tx.To()]; ok { - return new(big.Int).Add(costLimit, feeCapacity).Cmp(tx.TRC21Cost()) < 0 || tx.Gas() > gasLimit + return new(big.Int).Add(costLimit, feeCapacity).Cmp(tx.TxCost(number)) < 0 || tx.Gas() > gasLimit } } return tx.Cost().Cmp(maximum) > 0 || tx.Gas() > gasLimit diff --git a/core/tx_pool.go b/core/tx_pool.go index 83b78e5c2..16656f60b 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -632,7 +632,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // cost == V + GP * GL balance := pool.currentState.GetBalance(from) cost := tx.Cost() - minGasPrice := common.MinGasPrice + var number *big.Int = nil + if pool.chain.CurrentHeader() != nil { + number = pool.chain.CurrentHeader().Number + } + minGasPrice := common.GetMinGasPrice(number) feeCapacity := big.NewInt(0) if tx.To() != nil { @@ -641,8 +645,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if !state.ValidateTRC21Tx(pool.pendingState.StateDB, from, *tx.To(), tx.Data()) { return ErrInsufficientFunds } - cost = tx.TRC21Cost() - minGasPrice = common.TRC21GasPrice + cost = tx.TxCost(number) } } if new(big.Int).Add(balance, feeCapacity).Cmp(cost) < 0 { @@ -1042,9 +1045,11 @@ func (pool *TxPool) removeTx(hash common.Hash) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *TxPool) promoteExecutables(accounts []common.Address) { - start := time.Now() log.Debug("start promoteExecutables") - defer log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + defer func(start time.Time) { + log.Debug("end promoteExecutables", "time", common.PrettyDuration(time.Since(start))) + }(time.Now()) + // Gather all the accounts potentially needing updates if accounts == nil { accounts = make([]common.Address, 0, len(pool.queue)) @@ -1066,7 +1071,11 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { pool.priced.Removed() } // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas, pool.trc21FeeCapacity) + var number *big.Int = nil + if pool.chain.CurrentHeader() != nil { + number = pool.chain.CurrentHeader().Number + } + drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas, pool.trc21FeeCapacity, number) for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable queued transaction", "hash", hash) @@ -1224,7 +1233,11 @@ func (pool *TxPool) demoteUnexecutables() { pool.priced.Removed() } // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later - drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas, pool.trc21FeeCapacity) + var number *big.Int = nil + if pool.chain.CurrentHeader() != nil { + number = pool.chain.CurrentHeader().Number + } + drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas, pool.trc21FeeCapacity, number) for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable pending transaction", "hash", hash) diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 1c54c37ef..fecb5cf4e 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -19,15 +19,15 @@ package core import ( "crypto/ecdsa" "fmt" - "github.com/XinFinOrg/XDC-Subnet/consensus" - "github.com/XinFinOrg/XDC-Subnet/core/rawdb" - "io/ioutil" "math/big" "math/rand" "os" "testing" "time" + "github.com/XinFinOrg/XDC-Subnet/consensus" + "github.com/XinFinOrg/XDC-Subnet/core/rawdb" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/core/state" "github.com/XinFinOrg/XDC-Subnet/core/types" @@ -1543,7 +1543,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { t.Parallel() // Create a temporary file for the journal - file, err := ioutil.TempFile("", "") + file, err := os.CreateTemp("", "") if err != nil { t.Fatalf("failed to create temporary journal: %v", err) } diff --git a/core/types/consensus_v2.go b/core/types/consensus_v2.go index d8cb732b3..3a5b9f2a2 100644 --- a/core/types/consensus_v2.go +++ b/core/types/consensus_v2.go @@ -14,17 +14,17 @@ type Signature []byte // Block Info struct in XDPoS 2.0, used for vote message, etc. type BlockInfo struct { - Hash common.Hash - Round Round - Number *big.Int + Hash common.Hash `json:"hash"` + Round Round `json:"round"` + Number *big.Int `json:"number"` } // Vote message in XDPoS 2.0 type Vote struct { - signer common.Address - ProposedBlockInfo *BlockInfo - Signature Signature - GapNumber uint64 + signer common.Address //field not exported + ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"` + Signature Signature `json:"signature"` + GapNumber uint64 `json:"gapNumber"` } func (v *Vote) Hash() common.Hash { @@ -81,9 +81,9 @@ func (s *SyncInfo) Hash() common.Hash { // Quorum Certificate struct in XDPoS 2.0 type QuorumCert struct { - ProposedBlockInfo *BlockInfo - Signatures []Signature - GapNumber uint64 + ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"` + Signatures []Signature `json:"signatures"` + GapNumber uint64 `json:"gapNumber"` } // Timeout Certificate struct in XDPoS 2.0 @@ -114,6 +114,7 @@ type EpochSwitchInfo struct { Penalties []common.Address Standbynodes []common.Address Masternodes []common.Address + MasternodesLen int EpochSwitchBlockInfo *BlockInfo EpochSwitchParentBlockInfo *BlockInfo } diff --git a/core/types/lending_transaction.go b/core/types/lending_transaction.go index 19075f99e..f7f8ae905 100644 --- a/core/types/lending_transaction.go +++ b/core/types/lending_transaction.go @@ -32,7 +32,6 @@ import ( var ( // ErrInvalidLengdingSig invalidate signer ErrInvalidLengdingSig = errors.New("invalid transaction v, r, s values") - errNoSignerLengding = errors.New("missing signing methods") ) const ( @@ -86,50 +85,32 @@ type lendingtxdata struct { // IsCreatedLending check if tx is cancelled transaction func (tx *LendingTransaction) IsCreatedLending() bool { - if (tx.IsLoTypeLending() || tx.IsMoTypeLending()) && tx.Status() == LendingStatusNew { - return true - } - return false + return (tx.IsLoTypeLending() || tx.IsMoTypeLending()) && tx.Status() == LendingStatusNew } // IsCancelledLending check if tx is cancelled transaction func (tx *LendingTransaction) IsCancelledLending() bool { - if tx.Status() == LendingStatusCancelled { - return true - } - return false + return tx.Status() == LendingStatusCancelled } // IsRepayLending check if tx is repay lending transaction func (tx *LendingTransaction) IsRepayLending() bool { - if tx.Type() == LendingRePay { - return true - } - return false + return tx.Type() == LendingRePay } // IsTopupLending check if tx is repay lending transaction func (tx *LendingTransaction) IsTopupLending() bool { - if tx.Type() == LendingTopup { - return true - } - return false + return tx.Type() == LendingTopup } // IsMoTypeLending check if tx type is MO lending func (tx *LendingTransaction) IsMoTypeLending() bool { - if tx.Type() == LendingTypeMo { - return true - } - return false + return tx.Type() == LendingTypeMo } // IsLoTypeLending check if tx type is LO lending func (tx *LendingTransaction) IsLoTypeLending() bool { - if tx.Type() == LendingTypeLo { - return true - } - return false + return tx.Type() == LendingTypeLo } // EncodeRLP implements rlp.Encoder diff --git a/core/types/order_transaction.go b/core/types/order_transaction.go index 3bae7f8c6..8e8553f40 100644 --- a/core/types/order_transaction.go +++ b/core/types/order_transaction.go @@ -32,7 +32,6 @@ import ( var ( // ErrInvalidOrderSig invalidate signer ErrInvalidOrderSig = errors.New("invalid transaction v, r, s values") - errNoSignerOrder = errors.New("missing signing methods") ) const ( @@ -77,26 +76,17 @@ type ordertxdata struct { // IsCancelledOrder check if tx is cancelled transaction func (tx *OrderTransaction) IsCancelledOrder() bool { - if tx.Status() == OrderStatusCancelled { - return true - } - return false + return tx.Status() == OrderStatusCancelled } // IsMoTypeOrder check if tx type is MO Order func (tx *OrderTransaction) IsMoTypeOrder() bool { - if tx.Type() == OrderTypeMo { - return true - } - return false + return tx.Type() == OrderTypeMo } // IsLoTypeOrder check if tx type is LO Order func (tx *OrderTransaction) IsLoTypeOrder() bool { - if tx.Type() == OrderTypeLo { - return true - } - return false + return tx.Type() == OrderTypeLo } // EncodeRLP implements rlp.Encoder @@ -166,7 +156,6 @@ func (tx *OrderTransaction) WithSignature(signer OrderSigner, sig []byte) (*Orde // ImportSignature make order tx with specific signature func (tx *OrderTransaction) ImportSignature(V, R, S *big.Int) *OrderTransaction { - if V != nil { tx.data.V = V } @@ -304,6 +293,10 @@ func NewOrderTransactionByNonce(signer OrderSigner, txs map[common.Address]Order // Initialize a price based heap with the head transactions heads := make(OrderTxByNonce, 0, len(txs)) for from, accTxs := range txs { + if len(accTxs) == 0 { + delete(txs, from) + continue + } heads = append(heads, accTxs[0]) // Ensure the sender address is from the signer acc, _ := OrderSender(signer, accTxs[0]) diff --git a/core/types/order_transaction_test.go b/core/types/order_transaction_test.go new file mode 100644 index 000000000..a874b16fb --- /dev/null +++ b/core/types/order_transaction_test.go @@ -0,0 +1,31 @@ +package types + +import ( + "crypto/ecdsa" + "math/big" + "testing" + + "github.com/XinFinOrg/XDC-Subnet/common" + "github.com/XinFinOrg/XDC-Subnet/crypto" +) + +func TestNewOrderTransactionByNonce(t *testing.T) { + // Generate a batch of accounts to start with + keys := make([]*ecdsa.PrivateKey, 1) + for i := 0; i < len(keys); i++ { + keys[i], _ = crypto.GenerateKey() + } + + groups := map[common.Address]OrderTransactions{} + for start, key := range keys { + addr := crypto.PubkeyToAddress(key.PublicKey) + for i := 0; i < 1; i++ { + //tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil), signer, key) + orderTx := NewOrderTransaction(uint64(start+i), big.NewInt(1), big.NewInt(2), common.Address{}, common.Address{}, common.Address{}, common.Address{}, "new", "BID", "test", common.Hash{}, 1001) + + groups[addr] = append(groups[addr], orderTx) + } + } + tx := NewOrderTransactionByNonce(OrderTxSigner{}, groups) + t.Log(tx) +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 25942e7e3..2accd6590 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -262,11 +262,7 @@ func (tx *Transaction) AsMessage(s Signer, balanceFee *big.Int, number *big.Int) var err error msg.from, err = Sender(s, tx) if balanceFee != nil { - if number.Cmp(common.TIPTRC21Fee) > 0 { - msg.gasPrice = common.TRC21GasPrice - } else { - msg.gasPrice = common.TRC21GasPriceBefore - } + msg.gasPrice = common.GasPrice50x } return msg, err } @@ -291,8 +287,8 @@ func (tx *Transaction) Cost() *big.Int { } // Cost returns amount + gasprice * gaslimit. -func (tx *Transaction) TRC21Cost() *big.Int { - total := new(big.Int).Mul(common.TRC21GasPrice, new(big.Int).SetUint64(tx.data.GasLimit)) +func (tx *Transaction) TxCost(number *big.Int) *big.Int { + total := new(big.Int).Mul(common.GetGasPrice(number), new(big.Int).SetUint64(tx.data.GasLimit)) total.Add(total, tx.data.Amount) return total } @@ -700,9 +696,9 @@ type Message struct { balanceTokenFee *big.Int } -func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool, balanceTokenFee *big.Int) Message { +func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool, balanceTokenFee *big.Int, number *big.Int) Message { if balanceTokenFee != nil { - gasPrice = common.TRC21GasPrice + gasPrice = common.GetGasPrice(number) } return Message{ from: from, @@ -726,3 +722,5 @@ 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) CheckNonce() bool { return m.checkNonce } + +func (m *Message) SetNonce(nonce uint64) { m.nonce = nonce } diff --git a/core/vm/analysis.go b/core/vm/analysis.go index 449cded2a..3733bab6a 100644 --- a/core/vm/analysis.go +++ b/core/vm/analysis.go @@ -17,12 +17,12 @@ 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) + set2BitsMask = uint16(0b11) + set3BitsMask = uint16(0b111) + set4BitsMask = uint16(0b1111) + set5BitsMask = uint16(0b1_1111) + set6BitsMask = uint16(0b11_1111) + set7BitsMask = uint16(0b111_1111) ) // bitvec is a bit vector which maps bytes in a program. @@ -30,32 +30,26 @@ const ( // it's data (i.e. argument of PUSHxx). type bitvec []byte -var lookup = [8]byte{ - 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, -} - func (bits bitvec) set1(pos uint64) { - bits[pos/8] |= lookup[pos%8] + bits[pos/8] |= 1 << (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 + a := flag << (pos % 8) + bits[pos/8] |= byte(a) + if b := byte(a >> 8); b != 0 { bits[pos/8+1] = b } } func (bits bitvec) set8(pos uint64) { - a := byte(0xFF >> (pos % 8)) + a := byte(0xFF << (pos % 8)) bits[pos/8] |= a bits[pos/8+1] = ^a } func (bits bitvec) set16(pos uint64) { - a := byte(0xFF >> (pos % 8)) + a := byte(0xFF << (pos % 8)) bits[pos/8] |= a bits[pos/8+1] = 0xFF bits[pos/8+2] = ^a @@ -63,7 +57,7 @@ func (bits bitvec) set16(pos uint64) { // codeSegment checks if the position is in a code segment. func (bits *bitvec) codeSegment(pos uint64) bool { - return ((*bits)[pos/8] & (0x80 >> (pos % 8))) == 0 + return (((*bits)[pos/8] >> (pos % 8)) & 1) == 0 } // codeBitmap collects data locations in code. diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go index c2f91087f..c90039e74 100644 --- a/core/vm/analysis_test.go +++ b/core/vm/analysis_test.go @@ -17,6 +17,7 @@ package vm import ( + "math/bits" "testing" "github.com/XinFinOrg/XDC-Subnet/crypto" @@ -28,24 +29,27 @@ func TestJumpDestAnalysis(t *testing.T) { exp byte which int }{ - {[]byte{byte(PUSH1), 0x01, 0x01, 0x01}, 0x40, 0}, - {[]byte{byte(PUSH1), byte(PUSH1), byte(PUSH1), byte(PUSH1)}, 0x50, 0}, - {[]byte{byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), 0x01, 0x01, 0x01}, 0x7F, 0}, - {[]byte{byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x80, 1}, - {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), byte(PUSH2), byte(PUSH2), 0x01, 0x01, 0x01}, 0x03, 0}, - {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), 0x01, 0x01, 0x01, 0x01, 0x01}, 0x00, 1}, - {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x74, 0}, - {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x00, 1}, - {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x3F, 0}, - {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0xC0, 1}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x7F, 0}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0xFF, 1}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0x80, 2}, - {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0x7f, 0}, - {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0xA0, 1}, - {[]byte{byte(PUSH32)}, 0x7F, 0}, - {[]byte{byte(PUSH32)}, 0xFF, 1}, - {[]byte{byte(PUSH32)}, 0xFF, 2}, + {[]byte{byte(PUSH1), 0x01, 0x01, 0x01}, 0b0000_0010, 0}, + {[]byte{byte(PUSH1), byte(PUSH1), byte(PUSH1), byte(PUSH1)}, 0b0000_1010, 0}, + {[]byte{0x00, byte(PUSH1), 0x00, byte(PUSH1), 0x00, byte(PUSH1), 0x00, byte(PUSH1)}, 0b0101_0100, 0}, + {[]byte{byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), 0x01, 0x01, 0x01}, bits.Reverse8(0x7F), 0}, + {[]byte{byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0001, 1}, + {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), byte(PUSH2), byte(PUSH2), 0x01, 0x01, 0x01}, 0b1100_0000, 0}, + {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0000, 1}, + {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0010_1110, 0}, + {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0000, 1}, + {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1100, 0}, + {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0011, 1}, + {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1110, 0}, + {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1111, 1}, + {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0001, 2}, + {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0b1111_1110, 0}, + {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0b0000_0101, 1}, + {[]byte{byte(PUSH32)}, 0b1111_1110, 0}, + {[]byte{byte(PUSH32)}, 0b1111_1111, 1}, + {[]byte{byte(PUSH32)}, 0b1111_1111, 2}, + {[]byte{byte(PUSH32)}, 0b1111_1111, 3}, + {[]byte{byte(PUSH32)}, 0b0000_0001, 4}, } for i, test := range tests { ret := codeBitmap(test.code) @@ -55,9 +59,12 @@ func TestJumpDestAnalysis(t *testing.T) { } } +const analysisCodeSize = 1200 * 1024 + func BenchmarkJumpdestAnalysis_1200k(bench *testing.B) { // 1.4 ms - code := make([]byte, 1200000) + code := make([]byte, analysisCodeSize) + bench.SetBytes(analysisCodeSize) bench.ResetTimer() for i := 0; i < bench.N; i++ { codeBitmap(code) @@ -66,7 +73,8 @@ func BenchmarkJumpdestAnalysis_1200k(bench *testing.B) { } func BenchmarkJumpdestHashing_1200k(bench *testing.B) { // 4 ms - code := make([]byte, 1200000) + code := make([]byte, analysisCodeSize) + bench.SetBytes(analysisCodeSize) bench.ResetTimer() for i := 0; i < bench.N; i++ { crypto.Keccak256Hash(code) @@ -77,13 +85,19 @@ func BenchmarkJumpdestHashing_1200k(bench *testing.B) { func BenchmarkJumpdestOpAnalysis(bench *testing.B) { var op OpCode bencher := func(b *testing.B) { - code := make([]byte, 32*b.N) + code := make([]byte, analysisCodeSize) + b.SetBytes(analysisCodeSize) for i := range code { code[i] = byte(op) } bits := make(bitvec, len(code)/8+1+4) b.ResetTimer() - codeBitmapInternal(code, bits) + for i := 0; i < b.N; i++ { + for j := range bits { + bits[j] = 0 + } + codeBitmapInternal(code, bits) + } } for op = PUSH1; op <= PUSH32; op++ { bench.Run(op.String(), bencher) diff --git a/core/vm/common.go b/core/vm/common.go index ec968f991..85fe1ec35 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -17,15 +17,14 @@ package vm import ( - "math/big" - "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/common/math" + "github.com/holiman/uint256" ) // calcMemSize64 calculates the required memory size, and returns // the size and whether the result overflowed uint64 -func calcMemSize64(off, l *big.Int) (uint64, bool) { +func calcMemSize64(off, l *uint256.Int) (uint64, bool) { if !l.IsUint64() { return 0, true } @@ -35,16 +34,16 @@ func calcMemSize64(off, l *big.Int) (uint64, bool) { // calcMemSize64WithUint calculates the required memory size, and returns // the size and whether the result overflowed uint64 // Identical to calcMemSize64, but length is a uint64 -func calcMemSize64WithUint(off *big.Int, length64 uint64) (uint64, bool) { +func calcMemSize64WithUint(off *uint256.Int, length64 uint64) (uint64, bool) { // if length is zero, memsize is always zero, regardless of offset if length64 == 0 { return 0, false } // Check that offset doesn't overflow - if !off.IsUint64() { + offset64, overflow := off.Uint64WithOverflow() + if overflow { return 0, true } - offset64 := off.Uint64() val := offset64 + length64 // if value < either of it's parts, then it overflowed return val, val < offset64 @@ -64,22 +63,6 @@ func getData(data []byte, start uint64, size uint64) []byte { return common.RightPadBytes(data[start:end], int(size)) } -// getDataBig returns a slice from the data based on the start and size and pads -// up to size with zero's. This function is overflow safe. -func getDataBig(data []byte, start *big.Int, size *big.Int) []byte { - dlen := big.NewInt(int64(len(data))) - - s := math.BigMin(start, dlen) - e := math.BigMin(new(big.Int).Add(s, size), dlen) - return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64())) -} - -// bigUint64 returns the integer casted to a uint64 and returns whether it -// overflowed in the process. -func bigUint64(v *big.Int) (uint64, bool) { - return v.Uint64(), !v.IsUint64() -} - // toWordSize returns the ceiled word size required for memory expansion. func toWordSize(size uint64) uint64 { if size > math.MaxUint64-31 { diff --git a/core/vm/contract.go b/core/vm/contract.go index 7519b76d6..d7661b1fa 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -20,6 +20,7 @@ import ( "math/big" "github.com/XinFinOrg/XDC-Subnet/common" + "github.com/holiman/uint256" ) // ContractRef is a reference to the contract's backing object @@ -81,11 +82,11 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin return c } -func (c *Contract) validJumpdest(dest *big.Int) bool { - udest := dest.Uint64() +func (c *Contract) validJumpdest(dest *uint256.Int) bool { + udest, overflow := dest.Uint64WithOverflow() // PC cannot go beyond len(code) and certainly can't be bigger than 63bits. // Don't bother checking for JUMPDEST in that case. - if dest.BitLen() >= 63 || udest >= uint64(len(c.Code)) { + if overflow || udest >= uint64(len(c.Code)) { return false } // Only JUMPDESTs allowed for destinations @@ -131,16 +132,11 @@ func (c *Contract) AsDelegate() *Contract { // GetOp returns the n'th element in the contract's byte array func (c *Contract) GetOp(n uint64) OpCode { - return OpCode(c.GetByte(n)) -} - -// GetByte returns the n'th byte in the contract's byte array -func (c *Contract) GetByte(n uint64) byte { if n < uint64(len(c.Code)) { - return c.Code[n] + return OpCode(c.Code[n]) } - return 0 + return STOP } // Caller returns the caller of the contract. diff --git a/core/vm/contracts.go b/core/vm/contracts.go index bf783deba..251d68d01 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -488,6 +488,7 @@ func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) { return runBn256Pairing(input) } + type blake2F struct{} func (c *blake2F) RequiredGas(input []byte) uint64 { @@ -521,7 +522,7 @@ func (c *blake2F) Run(input []byte) ([]byte, error) { // Parse the input into the Blake2b call parameters var ( rounds = binary.BigEndian.Uint32(input[0:4]) - final = (input[212] == blake2FFinalBlockBytes) + final = input[212] == blake2FFinalBlockBytes h [8]uint64 m [16]uint64 diff --git a/core/vm/eips.go b/core/vm/eips.go index ba2b18e49..9ce69e16c 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -19,7 +19,9 @@ package vm import ( "fmt" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/holiman/uint256" ) // EnableEIP enables the given EIP on the config. @@ -27,6 +29,10 @@ import ( // defined jump tables are not polluted. func EnableEIP(eipNum int, jt *JumpTable) error { switch eipNum { + case 3855: + enable3855(jt) + case 3198: + enable3198(jt) case 2200: enable2200(jt) case 1884: @@ -51,17 +57,16 @@ func enable1884(jt *JumpTable) { jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 // New opcode - jt[SELFBALANCE] = operation{ + jt[SELFBALANCE] = &operation{ execute: opSelfBalance, constantGas: GasFastStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, } } func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - balance := interpreter.intPool.get().Set(interpreter.evm.StateDB.GetBalance(callContext.contract.Address())) + balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(callContext.contract.Address())) callContext.stack.push(balance) return nil, nil } @@ -70,18 +75,17 @@ func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx // - Adds an opcode that returns the current chain’s EIP-155 unique identifier func enable1344(jt *JumpTable) { // New opcode - jt[CHAINID] = operation{ + jt[CHAINID] = &operation{ execute: opChainID, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, } } // opChainID implements CHAINID opcode func opChainID(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - chainId := interpreter.intPool.get().Set(interpreter.evm.chainConfig.ChainId) + chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainId) callContext.stack.push(chainId) return nil, nil } @@ -91,3 +95,39 @@ func enable2200(jt *JumpTable) { jt[SLOAD].constantGas = params.SloadGasEIP2200 jt[SSTORE].dynamicGas = gasSStoreEIP2200 } + +// 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, callContext *callCtx) ([]byte, error) { + baseFee, _ := uint256.FromBig(common.MinGasPrice50x) + callContext.stack.push(baseFee) + return nil, nil +} + +// enable3855 applies EIP-3855 (PUSH0 opcode) +func enable3855(jt *JumpTable) { + // New opcode + jt[PUSH0] = &operation{ + execute: opPush0, + constantGas: GasQuickStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } +} + +// opPush0 implements the PUSH0 opcode +func opPush0(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + callContext.stack.push(new(uint256.Int)) + return nil, nil +} diff --git a/core/vm/errors.go b/core/vm/errors.go index c813aa36a..236e22568 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -34,6 +34,10 @@ var ( ErrWriteProtection = errors.New("write protection") ErrReturnDataOutOfBounds = errors.New("return data out of bounds") ErrGasUintOverflow = errors.New("gas uint64 overflow") + + // errStopToken is an internal token indicating interpreter loop termination, + // never returned to outside callers. + errStopToken = errors.New("stop token") ) // 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 5d84bd73a..652553af1 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -46,12 +46,14 @@ type ( // 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) { if contract.CodeAddr != nil { - precompiles := PrecompiledContractsHomestead - if evm.chainRules.IsByzantium { - precompiles = PrecompiledContractsByzantium - } - if evm.chainRules.IsIstanbul { + var precompiles map[common.Address]PrecompiledContract + switch { + case evm.chainRules.IsIstanbul: precompiles = PrecompiledContractsIstanbul + case evm.chainRules.IsByzantium: + precompiles = PrecompiledContractsByzantium + default: + precompiles = PrecompiledContractsHomestead } if p := precompiles[*contract.CodeAddr]; p != nil { switch p.(type) { @@ -105,6 +107,7 @@ type Context struct { BlockNumber *big.Int // Provides information for NUMBER Time *big.Int // Provides information for TIME Difficulty *big.Int // Provides information for DIFFICULTY + Random *common.Hash // Provides information for PREVRANDAO } // EVM is the Ethereum Virtual Machine base object and provides @@ -189,9 +192,6 @@ 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 { - return nil, gas, nil - } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -263,9 +263,6 @@ 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 { - return nil, gas, nil - } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -302,9 +299,6 @@ 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 { - return nil, gas, nil - } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -332,9 +326,6 @@ 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 { - return nil, gas, nil - } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -353,7 +344,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, // but is the correct thing to do and matters on other networks, in tests, and potential // future scenarios - evm.StateDB.AddBalance(addr, bigZero) + evm.StateDB.AddBalance(addr, big.NewInt(0)) } // When an error was returned by the EVM or when setting the creation code @@ -412,10 +403,6 @@ 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 { - return nil, address, gas, nil - } - if evm.vmConfig.Debug && evm.depth == 0 { evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value) } @@ -423,13 +410,16 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, ret, err := run(evm, contract, nil, false) - // check whether the max code size has been exceeded - maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize + // 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 + } + // 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 // by the error checking condition below. - if err == nil && !maxCodeSizeExceeded { + if err == nil { createDataGas := uint64(len(ret)) * params.CreateDataGas if contract.UseGas(createDataGas) { evm.StateDB.SetCode(address, ret) @@ -441,21 +431,17 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // 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. - if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) { + if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { evm.StateDB.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { contract.UseGas(contract.Gas) } } - // Assign err if contract code size exceeds the max while the err is still empty. - if maxCodeSizeExceeded && err == nil { - err = ErrMaxCodeSizeExceeded - } + if evm.vmConfig.Debug && evm.depth == 0 { evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) } return ret, address, contract.Gas, err - } // Create creates a new contract using code as deployment code. @@ -466,7 +452,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I // Create2 creates a new contract using code as deployment code. // -// The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] +// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { codeAndHash := &codeAndHash{code: code} diff --git a/core/vm/gas.go b/core/vm/gas.go index bda326cdc..5cf1d852d 100644 --- a/core/vm/gas.go +++ b/core/vm/gas.go @@ -17,7 +17,7 @@ package vm import ( - "math/big" + "github.com/holiman/uint256" ) // Gas costs @@ -34,7 +34,7 @@ const ( // // The cost of gas was changed during the homestead price change HF. // As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64. -func callGas(isEip150 bool, availableGas, base uint64, callCost *big.Int) (uint64, error) { +func callGas(isEip150 bool, availableGas, base uint64, callCost *uint256.Int) (uint64, error) { if isEip150 { availableGas = availableGas - base gas := availableGas - availableGas/64 diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 5e8e367d6..06ee9c4dc 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -61,7 +61,7 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { // as argument: // CALLDATACOPY (stack position 2) // CODECOPY (stack position 2) -// EXTCODECOPY (stack poition 3) +// EXTCODECOPY (stack position 3) // RETURNDATACOPY (stack position 2) func memoryCopierGas(stackpos int) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { @@ -71,7 +71,7 @@ func memoryCopierGas(stackpos int) gasFunc { return 0, err } // And gas for copying data, charged per word at param.CopyGas - words, overflow := bigUint64(stack.Back(stackpos)) + words, overflow := stack.Back(stackpos).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -97,7 +97,7 @@ var ( func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x)) + current = evm.StateDB.GetState(contract.Address(), common.Hash(x.Bytes32())) ) // The legacy gas metering only takes into consideration the current state // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283) @@ -132,11 +132,11 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi // 2.2.2. If original value equals new value (this storage slot is reset) // 2.2.2.1. If original value is 0, add 19800 gas to refund counter. // 2.2.2.2. Otherwise, add 4800 gas to refund counter. - value := common.BigToHash(y) + value := common.Hash(y.Bytes32()) if current == value { // noop (1) return params.NetSstoreNoopGas, nil } - original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x)) + original := evm.StateDB.GetCommittedState(contract.Address(), common.Hash(x.Bytes32())) if original == current { if original == (common.Hash{}) { // create slot (2.1.1) return params.NetSstoreInitGas, nil @@ -163,19 +163,19 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi return params.NetSstoreDirtyGas, nil } -// 0. If *gasleft* is less than or equal to 2300, fail the current call. -// 1. If current value equals new value (this is a no-op), SSTORE_NOOP_GAS gas is deducted. -// 2. If current value does not equal new value: -// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context): -// 2.1.1. If original value is 0, SSTORE_INIT_GAS gas is deducted. -// 2.1.2. Otherwise, SSTORE_CLEAN_GAS gas is deducted. If new value is 0, add SSTORE_CLEAR_REFUND to refund counter. -// 2.2. If original value does not equal current value (this storage slot is dirty), SSTORE_DIRTY_GAS gas is deducted. Apply both of the following clauses: +// 0. If *gasleft* is less than or equal to 2300, fail the current call. +// 1. If current value equals new value (this is a no-op), SLOAD_GAS is deducted. +// 2. If current value does not equal new value: +// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context): +// 2.1.1. If original value is 0, SSTORE_SET_GAS (20K) gas is deducted. +// 2.1.2. Otherwise, SSTORE_RESET_GAS gas is deducted. If new value is 0, add SSTORE_CLEARS_SCHEDULE to refund counter. +// 2.2. If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses: // 2.2.1. If original value is not 0: -// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEAR_REFUND gas from refund counter. We can prove that refund counter will never go below 0. -// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEAR_REFUND gas to refund counter. +// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEARS_SCHEDULE gas from refund counter. +// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEARS_SCHEDULE gas to refund counter. // 2.2.2. If original value equals new value (this storage slot is reset): -// 2.2.2.1. If original value is 0, add SSTORE_INIT_REFUND to refund counter. -// 2.2.2.2. Otherwise, add SSTORE_CLEAN_REFUND gas to refund counter. +// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. +// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. func gasSStoreEIP2200(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 { @@ -184,43 +184,43 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m // Gas sentry honoured, do the actual gas calculation based on the stored value var ( y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x)) + current = evm.StateDB.GetState(contract.Address(), common.Hash(x.Bytes32())) ) - value := common.BigToHash(y) + value := common.Hash(y.Bytes32()) if current == value { // noop (1) - return params.SstoreNoopGasEIP2200, nil + return params.SloadGasEIP2200, nil } - original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x)) + original := evm.StateDB.GetCommittedState(contract.Address(), common.Hash(x.Bytes32())) if original == current { if original == (common.Hash{}) { // create slot (2.1.1) - return params.SstoreInitGasEIP2200, nil + return params.SstoreSetGasEIP2200, nil } if value == (common.Hash{}) { // delete slot (2.1.2b) - evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200) + evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200) } - return params.SstoreCleanGasEIP2200, nil // write existing slot (2.1.2) + return params.SstoreResetGasEIP2200, 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.SstoreClearRefundEIP2200) + evm.StateDB.SubRefund(params.SstoreClearsScheduleRefundEIP2200) } else if value == (common.Hash{}) { // delete slot (2.2.1.2) - evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200) + evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200) } } if original == value { if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1) - evm.StateDB.AddRefund(params.SstoreInitRefundEIP2200) + evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200) } else { // reset to original existing slot (2.2.2.2) - evm.StateDB.AddRefund(params.SstoreCleanRefundEIP2200) + evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200) } } - return params.SstoreDirtyGasEIP2200, nil // dirty update (2.2) + return params.SloadGasEIP2200, nil // dirty update (2.2) } func makeGasLog(n uint64) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - requestedSize, overflow := bigUint64(stack.Back(1)) + requestedSize, overflow := stack.Back(1).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } @@ -248,16 +248,16 @@ func makeGasLog(n uint64) gasFunc { } } -func gasSha3(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err } - wordGas, overflow := bigUint64(stack.Back(1)) + wordGas, overflow := stack.Back(1).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow { + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Keccak256WordGas); overflow { return 0, ErrGasUintOverflow } if gas, overflow = math.SafeAdd(gas, wordGas); overflow { @@ -287,11 +287,11 @@ func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memoryS if err != nil { return 0, err } - wordGas, overflow := bigUint64(stack.Back(2)) + wordGas, overflow := stack.Back(2).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow { + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Keccak256WordGas); overflow { return 0, ErrGasUintOverflow } if gas, overflow = math.SafeAdd(gas, wordGas); overflow { @@ -329,8 +329,8 @@ func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( gas uint64 - transfersValue = stack.Back(2).Sign() != 0 - address = common.BigToAddress(stack.Back(1)) + transfersValue = !stack.Back(2).IsZero() + address = common.Address(stack.Back(1).Bytes20()) ) if evm.chainRules.IsEIP158 { if transfersValue && evm.StateDB.Empty(address) { @@ -423,7 +423,7 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me // EIP150 homestead gas reprice fork: if evm.chainRules.IsEIP150 { gas = params.SelfdestructGasEIP150 - var address = common.BigToAddress(stack.Back(0)) + var address = common.Address(stack.Back(0).Bytes20()) if evm.chainRules.IsEIP158 { // if empty and transfers value diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 806323240..e35c2afe6 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -17,303 +17,173 @@ package vm import ( - "math/big" + "sync/atomic" "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/holiman/uint256" "github.com/XinFinOrg/XDC-Subnet/common" - "github.com/XinFinOrg/XDC-Subnet/common/math" "github.com/XinFinOrg/XDC-Subnet/core/types" "golang.org/x/crypto/sha3" ) -var ( - bigZero = new(big.Int) - tt255 = math.BigPow(2, 255) -) - func opAdd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - math.U256(y.Add(x, y)) - - interpreter.intPool.putOne(x) + y.Add(&x, y) return nil, nil } func opSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - math.U256(y.Sub(x, y)) - - interpreter.intPool.putOne(x) + y.Sub(&x, y) return nil, nil } func opMul(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y := callContext.stack.pop(), callContext.stack.pop() - callContext.stack.push(math.U256(x.Mul(x, y))) - - interpreter.intPool.putOne(y) - + x, y := callContext.stack.pop(), callContext.stack.peek() + y.Mul(&x, y) return nil, nil } func opDiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - if y.Sign() != 0 { - math.U256(y.Div(x, y)) - } else { - y.SetUint64(0) - } - interpreter.intPool.putOne(x) + y.Div(&x, y) return nil, nil } func opSdiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y := math.S256(callContext.stack.pop()), math.S256(callContext.stack.pop()) - res := interpreter.intPool.getZero() - - if y.Sign() == 0 || x.Sign() == 0 { - callContext.stack.push(res) - } else { - if x.Sign() != y.Sign() { - res.Div(x.Abs(x), y.Abs(y)) - res.Neg(res) - } else { - res.Div(x.Abs(x), y.Abs(y)) - } - callContext.stack.push(math.U256(res)) - } - interpreter.intPool.put(x, y) + x, y := callContext.stack.pop(), callContext.stack.peek() + y.SDiv(&x, y) return nil, nil } func opMod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y := callContext.stack.pop(), callContext.stack.pop() - if y.Sign() == 0 { - callContext.stack.push(x.SetUint64(0)) - } else { - callContext.stack.push(math.U256(x.Mod(x, y))) - } - interpreter.intPool.putOne(y) + x, y := callContext.stack.pop(), callContext.stack.peek() + y.Mod(&x, y) return nil, nil } func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y := math.S256(callContext.stack.pop()), math.S256(callContext.stack.pop()) - res := interpreter.intPool.getZero() - - if y.Sign() == 0 { - callContext.stack.push(res) - } else { - if x.Sign() < 0 { - res.Mod(x.Abs(x), y.Abs(y)) - res.Neg(res) - } else { - res.Mod(x.Abs(x), y.Abs(y)) - } - callContext.stack.push(math.U256(res)) - } - interpreter.intPool.put(x, y) + x, y := callContext.stack.pop(), callContext.stack.peek() + y.SMod(&x, y) return nil, nil } func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - base, exponent := callContext.stack.pop(), callContext.stack.pop() - // some shortcuts - cmpToOne := exponent.Cmp(big1) - if cmpToOne < 0 { // Exponent is zero - // x ^ 0 == 1 - callContext.stack.push(base.SetUint64(1)) - } else if base.Sign() == 0 { - // 0 ^ y, if y != 0, == 0 - callContext.stack.push(base.SetUint64(0)) - } else if cmpToOne == 0 { // Exponent is one - // x ^ 1 == x - callContext.stack.push(base) - } else { - callContext.stack.push(math.Exp(base, exponent)) - interpreter.intPool.putOne(base) - } - interpreter.intPool.putOne(exponent) + base, exponent := callContext.stack.pop(), callContext.stack.peek() + exponent.Exp(&base, exponent) return nil, nil } func opSignExtend(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - back := callContext.stack.pop() - if back.Cmp(big.NewInt(31)) < 0 { - bit := uint(back.Uint64()*8 + 7) - num := callContext.stack.pop() - mask := back.Lsh(common.Big1, bit) - mask.Sub(mask, common.Big1) - if num.Bit(int(bit)) > 0 { - num.Or(num, mask.Not(mask)) - } else { - num.And(num, mask) - } - - callContext.stack.push(math.U256(num)) - } - - interpreter.intPool.putOne(back) + back, num := callContext.stack.pop(), callContext.stack.peek() + num.ExtendSign(num, &back) return nil, nil } func opNot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x := callContext.stack.peek() - math.U256(x.Not(x)) + x.Not(x) return nil, nil } func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - if x.Cmp(y) < 0 { - y.SetUint64(1) + if x.Lt(y) { + y.SetOne() } else { - y.SetUint64(0) + y.Clear() } - interpreter.intPool.putOne(x) return nil, nil } func opGt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - if x.Cmp(y) > 0 { - y.SetUint64(1) + if x.Gt(y) { + y.SetOne() } else { - y.SetUint64(0) + y.Clear() } - interpreter.intPool.putOne(x) return nil, nil } func opSlt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - - xSign := x.Cmp(tt255) - ySign := y.Cmp(tt255) - - switch { - case xSign >= 0 && ySign < 0: - y.SetUint64(1) - - case xSign < 0 && ySign >= 0: - y.SetUint64(0) - - default: - if x.Cmp(y) < 0 { - y.SetUint64(1) - } else { - y.SetUint64(0) - } + if x.Slt(y) { + y.SetOne() + } else { + y.Clear() } - interpreter.intPool.putOne(x) return nil, nil } func opSgt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - - xSign := x.Cmp(tt255) - ySign := y.Cmp(tt255) - - switch { - case xSign >= 0 && ySign < 0: - y.SetUint64(0) - - case xSign < 0 && ySign >= 0: - y.SetUint64(1) - - default: - if x.Cmp(y) > 0 { - y.SetUint64(1) - } else { - y.SetUint64(0) - } + if x.Sgt(y) { + y.SetOne() + } else { + y.Clear() } - interpreter.intPool.putOne(x) return nil, nil } func opEq(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - if x.Cmp(y) == 0 { - y.SetUint64(1) + if x.Eq(y) { + y.SetOne() } else { - y.SetUint64(0) + y.Clear() } - interpreter.intPool.putOne(x) return nil, nil } func opIszero(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x := callContext.stack.peek() - if x.Sign() > 0 { - x.SetUint64(0) + if x.IsZero() { + x.SetOne() } else { - x.SetUint64(1) + x.Clear() } return nil, nil } func opAnd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y := callContext.stack.pop(), callContext.stack.pop() - callContext.stack.push(x.And(x, y)) - - interpreter.intPool.putOne(y) + x, y := callContext.stack.pop(), callContext.stack.peek() + y.And(&x, y) return nil, nil } func opOr(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - y.Or(x, y) - - interpreter.intPool.putOne(x) + y.Or(&x, y) return nil, nil } func opXor(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { x, y := callContext.stack.pop(), callContext.stack.peek() - y.Xor(x, y) - - interpreter.intPool.putOne(x) + y.Xor(&x, y) return nil, nil } func opByte(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { th, val := callContext.stack.pop(), callContext.stack.peek() - if th.Cmp(common.Big32) < 0 { - b := math.Byte(val, 32, int(th.Int64())) - val.SetUint64(uint64(b)) - } else { - val.SetUint64(0) - } - interpreter.intPool.putOne(th) + val.Byte(&th) return nil, nil } func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - if z.Cmp(bigZero) > 0 { - x.Add(x, y) - x.Mod(x, z) - callContext.stack.push(math.U256(x)) + x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.peek() + if z.IsZero() { + z.Clear() } else { - callContext.stack.push(x.SetUint64(0)) + z.AddMod(&x, &y, z) } - interpreter.intPool.put(y, z) return nil, nil } func opMulmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - if z.Cmp(bigZero) > 0 { - x.Mul(x, y) - x.Mod(x, z) - callContext.stack.push(math.U256(x)) - } else { - callContext.stack.push(x.SetUint64(0)) - } - interpreter.intPool.put(y, z) + x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.peek() + z.MulMod(&x, &y, z) return nil, nil } @@ -322,16 +192,12 @@ func opMulmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([] // and pushes on the stack arg2 shifted to the left by arg1 number of bits. func opSHL(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards - shift, value := math.U256(callContext.stack.pop()), math.U256(callContext.stack.peek()) - defer interpreter.intPool.putOne(shift) // First operand back into the pool - - if shift.Cmp(common.Big256) >= 0 { - value.SetUint64(0) - return nil, nil + shift, value := callContext.stack.pop(), callContext.stack.peek() + if shift.LtUint64(256) { + value.Lsh(value, uint(shift.Uint64())) + } else { + value.Clear() } - n := uint(shift.Uint64()) - math.U256(value.Lsh(value, n)) - return nil, nil } @@ -340,16 +206,12 @@ func opSHL(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. func opSHR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards - shift, value := math.U256(callContext.stack.pop()), math.U256(callContext.stack.peek()) - defer interpreter.intPool.putOne(shift) // First operand back into the pool - - if shift.Cmp(common.Big256) >= 0 { - value.SetUint64(0) - return nil, nil + shift, value := callContext.stack.pop(), callContext.stack.peek() + if shift.LtUint64(256) { + value.Rsh(value, uint(shift.Uint64())) + } else { + value.Clear() } - n := uint(shift.Uint64()) - math.U256(value.Rsh(value, n)) - return nil, nil } @@ -357,29 +219,24 @@ func opSHR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. func opSAR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - // Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one - shift, value := math.U256(callContext.stack.pop()), math.S256(callContext.stack.pop()) - defer interpreter.intPool.putOne(shift) // First operand back into the pool - - if shift.Cmp(common.Big256) >= 0 { + shift, value := callContext.stack.pop(), callContext.stack.peek() + if shift.GtUint64(256) { if value.Sign() >= 0 { - value.SetUint64(0) + value.Clear() } else { - value.SetInt64(-1) + // Max negative shift: all bits set + value.SetAllOne() } - callContext.stack.push(math.U256(value)) return nil, nil } n := uint(shift.Uint64()) - value.Rsh(value, n) - callContext.stack.push(math.U256(value)) - + value.SRsh(value, n) return nil, nil } -func opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - offset, size := callContext.stack.pop(), callContext.stack.pop() - data := callContext.memory.GetPtr(offset.Int64(), size.Int64()) +func opKeccak256(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + offset, size := callContext.stack.pop(), callContext.stack.peek() + data := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) if interpreter.hasher == nil { interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) @@ -393,45 +250,50 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by if evm.vmConfig.EnablePreimageRecording { evm.StateDB.AddPreimage(interpreter.hasherBuf, data) } - callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.hasherBuf[:])) - interpreter.intPool.put(offset, size) + size.SetBytes(interpreter.hasherBuf[:]) return nil, nil } - func opAddress(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetBytes(callContext.contract.Address().Bytes())) + callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Address().Bytes())) return nil, nil } func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() - slot.Set(interpreter.evm.StateDB.GetBalance(common.BigToAddress(slot))) + address := common.Address(slot.Bytes20()) + slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address)) return nil, nil } func opOrigin(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Origin.Bytes())) + callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes())) return nil, nil } - func opCaller(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetBytes(callContext.contract.Caller().Bytes())) + callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Caller().Bytes())) return nil, nil } func opCallValue(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().Set(callContext.contract.value)) + v, _ := uint256.FromBig(callContext.contract.value) + callContext.stack.push(v) return nil, nil } func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetBytes(getDataBig(callContext.contract.Input, callContext.stack.pop(), big32))) + x := callContext.stack.peek() + if offset, overflow := x.Uint64WithOverflow(); !overflow { + data := getData(callContext.contract.Input, offset, 32) + x.SetBytes(data) + } else { + x.Clear() + } return nil, nil } func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetInt64(int64(len(callContext.contract.Input)))) + callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(callContext.contract.Input)))) return nil, nil } @@ -441,14 +303,20 @@ func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCt dataOffset = callContext.stack.pop() length = callContext.stack.pop() ) - callContext.memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(callContext.contract.Input, dataOffset, length)) + dataOffset64, overflow := dataOffset.Uint64WithOverflow() + if overflow { + dataOffset64 = 0xffffffffffffffff + } + // These values are checked for overflow during gas cost calculation + memOffset64 := memOffset.Uint64() + length64 := length.Uint64() + callContext.memory.Set(memOffset64, length64, getData(callContext.contract.Input, dataOffset64, length64)) - interpreter.intPool.put(memOffset, dataOffset, length) return nil, nil } func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetUint64(uint64(len(interpreter.returnData)))) + callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData)))) return nil, nil } @@ -457,30 +325,33 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *call memOffset = callContext.stack.pop() dataOffset = callContext.stack.pop() length = callContext.stack.pop() - - end = interpreter.intPool.get().Add(dataOffset, length) ) - defer interpreter.intPool.put(memOffset, dataOffset, length, end) - if !end.IsUint64() || uint64(len(interpreter.returnData)) < end.Uint64() { + offset64, overflow := dataOffset.Uint64WithOverflow() + if overflow { return nil, ErrReturnDataOutOfBounds } - callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[dataOffset.Uint64():end.Uint64()]) - + // we can reuse dataOffset now (aliasing it for clarity) + var end = dataOffset + end.Add(&dataOffset, &length) + end64, overflow := end.Uint64WithOverflow() + if overflow || uint64(len(interpreter.returnData)) < end64 { + return nil, ErrReturnDataOutOfBounds + } + callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64]) return nil, nil } func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() - slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) - + slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.Address(slot.Bytes20())))) return nil, nil } func opCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - l := interpreter.intPool.get().SetInt64(int64(len(callContext.contract.Code))) + l := new(uint256.Int) + l.SetUint64(uint64(len(callContext.contract.Code))) callContext.stack.push(l) - return nil, nil } @@ -490,24 +361,32 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ( codeOffset = callContext.stack.pop() length = callContext.stack.pop() ) - codeCopy := getDataBig(callContext.contract.Code, codeOffset, length) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = 0xffffffffffffffff + } + codeCopy := getData(callContext.contract.Code, uint64CodeOffset, length.Uint64()) callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { var ( - addr = common.BigToAddress(callContext.stack.pop()) - memOffset = callContext.stack.pop() - codeOffset = callContext.stack.pop() - length = callContext.stack.pop() + stack = callContext.stack + a = stack.pop() + memOffset = stack.pop() + codeOffset = stack.pop() + length = stack.pop() ) - codeCopy := getDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = 0xffffffffffffffff + } + addr := common.Address(a.Bytes20()) + codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } @@ -546,9 +425,9 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx // this account should be regarded as a non-existent account and zero should be returned. func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() - address := common.BigToAddress(slot) + address := common.Address(slot.Bytes20()) if interpreter.evm.StateDB.Empty(address) { - slot.SetUint64(0) + slot.Clear() } else { slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) } @@ -556,56 +435,80 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx } func opGasprice(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice)) + v, _ := uint256.FromBig(interpreter.evm.GasPrice) + callContext.stack.push(v) return nil, nil } func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - num := callContext.stack.pop() - - n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257) - if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 { - callContext.stack.push(interpreter.evm.GetHash(num.Uint64()).Big()) + num := callContext.stack.peek() + num64, overflow := num.Uint64WithOverflow() + if overflow { + num.Clear() + return nil, nil + } + var upper, lower uint64 + upper = interpreter.evm.BlockNumber.Uint64() + if upper < 257 { + lower = 0 + } else { + lower = upper - 256 + } + if num64 >= lower && num64 < upper { + num.SetBytes(interpreter.evm.GetHash(num64).Bytes()) } else { - callContext.stack.push(interpreter.intPool.getZero()) + num.Clear() } - interpreter.intPool.put(num, n) return nil, nil } func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Coinbase.Bytes())) + callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Coinbase.Bytes())) return nil, nil } func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time))) + v, _ := uint256.FromBig(interpreter.evm.Time) + callContext.stack.push(v) return nil, nil } func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber))) + v, _ := uint256.FromBig(interpreter.evm.BlockNumber) + callContext.stack.push(v) return nil, nil } func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty))) + v, _ := uint256.FromBig(interpreter.evm.Difficulty) + callContext.stack.push(v) + return nil, nil +} + +func opRandom(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + var v *uint256.Int + if interpreter.evm.Context.Random != nil { + v = new(uint256.Int).SetBytes((interpreter.evm.Context.Random.Bytes())) + } else { // if context random is not set, use emptyCodeHash as default + v = new(uint256.Int).SetBytes(emptyCodeHash.Bytes()) + } + callContext.stack.push(v) return nil, nil } func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit))) + callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.GasLimit)) return nil, nil } func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - interpreter.intPool.putOne(callContext.stack.pop()) + callContext.stack.pop() return nil, nil } func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { v := callContext.stack.peek() - offset := v.Int64() + offset := int64(v.Uint64()) v.SetBytes(callContext.memory.GetPtr(offset, 32)) return nil, nil } @@ -613,58 +516,58 @@ func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]b func opMstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { // pop value of the stack mStart, val := callContext.stack.pop(), callContext.stack.pop() - callContext.memory.Set32(mStart.Uint64(), val) - - interpreter.intPool.put(mStart, val) + callContext.memory.Set32(mStart.Uint64(), &val) return nil, nil } func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - off, val := callContext.stack.pop().Int64(), callContext.stack.pop().Int64() - callContext.memory.store[off] = byte(val & 0xff) - + off, val := callContext.stack.pop(), callContext.stack.pop() + callContext.memory.store[off.Uint64()] = byte(val.Uint64()) return nil, nil } func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { loc := callContext.stack.peek() - val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), common.BigToHash(loc)) + hash := common.Hash(loc.Bytes32()) + val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), hash) loc.SetBytes(val.Bytes()) return nil, nil } func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - loc := common.BigToHash(callContext.stack.pop()) + if interpreter.readOnly { + return nil, ErrWriteProtection + } + loc := callContext.stack.pop() val := callContext.stack.pop() - interpreter.evm.StateDB.SetState(callContext.contract.Address(), loc, common.BigToHash(val)) - - interpreter.intPool.putOne(val) + interpreter.evm.StateDB.SetState(callContext.contract.Address(), + common.Hash(loc.Bytes32()), common.Hash(val.Bytes32())) return nil, nil } func opJump(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if atomic.LoadInt32(&interpreter.evm.abort) != 0 { + return nil, errStopToken + } pos := callContext.stack.pop() - if !callContext.contract.validJumpdest(pos) { + if !callContext.contract.validJumpdest(&pos) { return nil, ErrInvalidJump } - *pc = pos.Uint64() - - interpreter.intPool.putOne(pos) + *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop return nil, nil } func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if atomic.LoadInt32(&interpreter.evm.abort) != 0 { + return nil, errStopToken + } pos, cond := callContext.stack.pop(), callContext.stack.pop() - if cond.Sign() != 0 { - if !callContext.contract.validJumpdest(pos) { + if !cond.IsZero() { + if !callContext.contract.validJumpdest(&pos) { return nil, ErrInvalidJump } - *pc = pos.Uint64() - } else { - *pc++ + *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop } - - interpreter.intPool.put(pos, cond) return nil, nil } @@ -673,219 +576,253 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ( } func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetUint64(*pc)) + callContext.stack.push(new(uint256.Int).SetUint64(*pc)) return nil, nil } func opMsize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetInt64(int64(callContext.memory.Len()))) + callContext.stack.push(new(uint256.Int).SetUint64(uint64(callContext.memory.Len()))) return nil, nil } func opGas(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.push(interpreter.intPool.get().SetUint64(callContext.contract.Gas)) + callContext.stack.push(new(uint256.Int).SetUint64(callContext.contract.Gas)) return nil, nil } func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if interpreter.readOnly { + return nil, ErrWriteProtection + } var ( value = callContext.stack.pop() offset, size = callContext.stack.pop(), callContext.stack.pop() - input = callContext.memory.GetCopy(offset.Int64(), size.Int64()) + input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) gas = callContext.contract.Gas ) if interpreter.evm.chainRules.IsEIP150 { gas -= gas / 64 } + // reuse size int for stackvalue + stackvalue := size callContext.contract.UseGas(gas) - res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, value) + res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, value.ToBig()) // Push item on the stack based on the returned error. If the ruleset is // homestead we must check for CodeStoreOutOfGasError (homestead only // rule) and treat as an error, if the ruleset is frontier we must // ignore this error and pretend the operation was successful. if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { - callContext.stack.push(interpreter.intPool.getZero()) + stackvalue.Clear() } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { - callContext.stack.push(interpreter.intPool.getZero()) + stackvalue.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) + stackvalue.SetBytes(addr.Bytes()) } + callContext.stack.push(&stackvalue) callContext.contract.Gas += returnGas - interpreter.intPool.put(value, offset, size) if suberr == ErrExecutionReverted { + interpreter.returnData = res // set REVERT data to return data buffer return res, nil } + interpreter.returnData = nil // clear dirty return data buffer return nil, nil } func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if interpreter.readOnly { + return nil, ErrWriteProtection + } var ( endowment = callContext.stack.pop() offset, size = callContext.stack.pop(), callContext.stack.pop() salt = callContext.stack.pop() - input = callContext.memory.GetCopy(offset.Int64(), size.Int64()) + input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) gas = callContext.contract.Gas ) // Apply EIP150 gas -= gas / 64 callContext.contract.UseGas(gas) - res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas, endowment, salt) + // reuse size int for stackvalue + stackvalue := size + res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas, + endowment.ToBig(), salt.ToBig()) // Push item on the stack based on the returned error. if suberr != nil { - callContext.stack.push(interpreter.intPool.getZero()) + stackvalue.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) + stackvalue.SetBytes(addr.Bytes()) } + callContext.stack.push(&stackvalue) callContext.contract.Gas += returnGas - interpreter.intPool.put(endowment, offset, size, salt) if suberr == ErrExecutionReverted { + interpreter.returnData = res // set REVERT data to return data buffer return res, nil } + interpreter.returnData = nil // clear dirty return data buffer return nil, nil } func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + stack := callContext.stack // Pop gas. The actual gas in interpreter.evm.callGasTemp. - interpreter.intPool.putOne(callContext.stack.pop()) + // We can use this as a temporary value + temp := stack.pop() gas := interpreter.evm.callGasTemp // Pop other call parameters. - addr, value, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - toAddr := common.BigToAddress(addr) - value = math.U256(value) + addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() + toAddr := common.Address(addr.Bytes20()) // Get the arguments from the memory. - args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64()) + args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - if value.Sign() != 0 { + if interpreter.readOnly && !value.IsZero() { + return nil, ErrWriteProtection + } + if !value.IsZero() { gas += params.CallStipend } - ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, value) + ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, value.ToBig()) if err != nil { - callContext.stack.push(interpreter.intPool.getZero()) + temp.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetUint64(1)) + temp.SetOne() } + stack.push(&temp) if err == nil || err == ErrExecutionReverted { ret = common.CopyBytes(ret) callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } callContext.contract.Gas += returnGas - interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + interpreter.returnData = ret return ret, nil } func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - interpreter.intPool.putOne(callContext.stack.pop()) + stack := callContext.stack + // We use it as a temporary value + temp := stack.pop() gas := interpreter.evm.callGasTemp // Pop other call parameters. - addr, value, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - toAddr := common.BigToAddress(addr) - value = math.U256(value) + addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() + toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64()) + args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - if value.Sign() != 0 { + if !value.IsZero() { gas += params.CallStipend } - ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, value) + ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, value.ToBig()) if err != nil { - callContext.stack.push(interpreter.intPool.getZero()) + temp.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetUint64(1)) + temp.SetOne() } + stack.push(&temp) if err == nil || err == ErrExecutionReverted { ret = common.CopyBytes(ret) callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } callContext.contract.Gas += returnGas - interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + interpreter.returnData = ret return ret, nil } func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + stack := callContext.stack // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - interpreter.intPool.putOne(callContext.stack.pop()) + // We use it as a temporary value + temp := stack.pop() gas := interpreter.evm.callGasTemp // Pop other call parameters. - addr, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - toAddr := common.BigToAddress(addr) + addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() + toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64()) + args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas) if err != nil { - callContext.stack.push(interpreter.intPool.getZero()) + temp.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetUint64(1)) + temp.SetOne() } + stack.push(&temp) if err == nil || err == ErrExecutionReverted { ret = common.CopyBytes(ret) callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } callContext.contract.Gas += returnGas - interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + interpreter.returnData = ret return ret, nil } func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - interpreter.intPool.putOne(callContext.stack.pop()) + stack := callContext.stack + // We use it as a temporary value + temp := stack.pop() gas := interpreter.evm.callGasTemp // Pop other call parameters. - addr, inOffset, inSize, retOffset, retSize := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop(), callContext.stack.pop() - toAddr := common.BigToAddress(addr) + addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() + toAddr := common.Address(addr.Bytes20()) // Get arguments from the memory. - args := callContext.memory.GetPtr(inOffset.Int64(), inSize.Int64()) + args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas) if err != nil { - callContext.stack.push(interpreter.intPool.getZero()) + temp.Clear() } else { - callContext.stack.push(interpreter.intPool.get().SetUint64(1)) + temp.SetOne() } + stack.push(&temp) if err == nil || err == ErrExecutionReverted { ret = common.CopyBytes(ret) callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } callContext.contract.Gas += returnGas - interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + interpreter.returnData = ret return ret, nil } func opReturn(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { offset, size := callContext.stack.pop(), callContext.stack.pop() - ret := callContext.memory.GetPtr(offset.Int64(), size.Int64()) + ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) - interpreter.intPool.put(offset, size) - return ret, nil + return ret, errStopToken } func opRevert(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { offset, size := callContext.stack.pop(), callContext.stack.pop() - ret := callContext.memory.GetPtr(offset.Int64(), size.Int64()) + ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) - interpreter.intPool.put(offset, size) - return ret, nil + interpreter.returnData = ret + return ret, ErrExecutionReverted +} + +func opUndefined(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + return nil, &ErrInvalidOpCode{opcode: OpCode(callContext.contract.Code[*pc])} } func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - return nil, nil + return nil, errStopToken } -func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { +func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if interpreter.readOnly { + return nil, ErrWriteProtection + } + beneficiary := callContext.stack.pop() balance := interpreter.evm.StateDB.GetBalance(callContext.contract.Address()) - interpreter.evm.StateDB.AddBalance(common.BigToAddress(callContext.stack.pop()), balance) - + interpreter.evm.StateDB.AddBalance(common.Address(beneficiary.Bytes20()), balance) interpreter.evm.StateDB.Suicide(callContext.contract.Address()) - return nil, nil + return nil, errStopToken } // following functions are used by the instruction jump table @@ -893,13 +830,18 @@ func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([ // make log instruction function func makeLog(size int) executionFunc { return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + if interpreter.readOnly { + return nil, ErrWriteProtection + } topics := make([]common.Hash, size) - mStart, mSize := callContext.stack.pop(), callContext.stack.pop() + stack := callContext.stack + mStart, mSize := stack.pop(), stack.pop() for i := 0; i < size; i++ { - topics[i] = common.BigToHash(callContext.stack.pop()) + addr := stack.pop() + topics[i] = common.Hash(addr.Bytes32()) } - d := callContext.memory.GetCopy(mStart.Int64(), mSize.Int64()) + d := callContext.memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) interpreter.evm.StateDB.AddLog(&types.Log{ Address: callContext.contract.Address(), Topics: topics, @@ -909,7 +851,6 @@ func makeLog(size int) executionFunc { BlockNumber: interpreter.evm.BlockNumber.Uint64(), }) - interpreter.intPool.put(mStart, mSize) return nil, nil } } @@ -918,13 +859,13 @@ func makeLog(size int) executionFunc { func opPush1(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { var ( codeLen = uint64(len(callContext.contract.Code)) - integer = interpreter.intPool.get() + integer = new(uint256.Int) ) *pc += 1 if *pc < codeLen { callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc]))) } else { - callContext.stack.push(integer.SetUint64(0)) + callContext.stack.push(integer.Clear()) } return nil, nil } @@ -944,8 +885,9 @@ func makePush(size uint64, pushByteSize int) executionFunc { endMin = startMin + pushByteSize } - integer := interpreter.intPool.get() - callContext.stack.push(integer.SetBytes(common.RightPadBytes(callContext.contract.Code[startMin:endMin], pushByteSize))) + integer := new(uint256.Int) + callContext.stack.push(integer.SetBytes(common.RightPadBytes( + callContext.contract.Code[startMin:endMin], pushByteSize))) *pc += size return nil, nil @@ -955,7 +897,7 @@ func makePush(size uint64, pushByteSize int) executionFunc { // make dup instruction function func makeDup(size int64) executionFunc { return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - callContext.stack.dup(interpreter.intPool, int(size)) + callContext.stack.dup(int(size)) return nil, nil } } diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 8918bd7fe..4ed5fb053 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -20,12 +20,13 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "log" "math/big" + "os" "testing" "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/holiman/uint256" "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/crypto" @@ -42,6 +43,7 @@ type twoOperandParams struct { y string } +var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" var commonParams []*twoOperandParams var twoOpMethods map[string]executionFunc @@ -91,31 +93,6 @@ func init() { } } -// getResult is a convenience function to generate the expected values -func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { - var ( - env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) - interpreter = env.interpreter.(*EVMInterpreter) - ) - interpreter.intPool = poolOfIntPools.get() - result := make([]TwoOperandTestcase, len(args)) - for i, param := range args { - x := new(big.Int).SetBytes(common.Hex2Bytes(param.x)) - y := new(big.Int).SetBytes(common.Hex2Bytes(param.y)) - stack.push(x) - stack.push(y) - _, err := opFn(&pc, interpreter, &callCtx{nil, stack, nil}) - if err != nil { - log.Fatalln(err) - } - actual := stack.pop() - result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)} - } - return result -} - func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { var ( @@ -124,42 +101,23 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu pc = uint64(0) evmInterpreter = env.interpreter.(*EVMInterpreter) ) - // Stuff a couple of nonzero bigints into pool, to ensure that ops do not rely on pooled integers to be zero - evmInterpreter.intPool = poolOfIntPools.get() - evmInterpreter.intPool.put(big.NewInt(-1337)) - evmInterpreter.intPool.put(big.NewInt(-1337)) - evmInterpreter.intPool.put(big.NewInt(-1337)) for i, test := range tests { - x := new(big.Int).SetBytes(common.Hex2Bytes(test.X)) - y := new(big.Int).SetBytes(common.Hex2Bytes(test.Y)) - expected := new(big.Int).SetBytes(common.Hex2Bytes(test.Expected)) + x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.X)) + y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Y)) + expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected)) stack.push(x) stack.push(y) opFn(&pc, evmInterpreter, &callCtx{nil, stack, nil}) + if len(stack.data) != 1 { + t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data)) + } actual := stack.pop() if actual.Cmp(expected) != 0 { t.Errorf("Testcase %v %d, %v(%x, %x): expected %x, got %x", name, i, name, x, y, expected, actual) } - // Check pool usage - // 1.pool is not allowed to contain anything on the stack - // 2.pool is not allowed to contain the same pointers twice - if evmInterpreter.intPool.pool.len() > 0 { - - poolvals := make(map[*big.Int]struct{}) - poolvals[actual] = struct{}{} - - for evmInterpreter.intPool.pool.len() > 0 { - key := evmInterpreter.intPool.get() - if _, exist := poolvals[key]; exist { - t.Errorf("Testcase %v %d, pool contains double-entry", name, i) - } - poolvals[key] = struct{}{} - } - } } - poolOfIntPools.put(evmInterpreter.intPool) } func TestByteOp(t *testing.T) { @@ -235,6 +193,68 @@ func TestSAR(t *testing.T) { testTwoOperandOp(t, tests, opSAR, "sar") } +func TestAddMod(t *testing.T) { + var ( + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) + stack = newstack() + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) + pc = uint64(0) + ) + tests := []struct { + x string + y string + z string + expected string + }{ + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + }, + } + // x + y = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd + // in 256 bit repr, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd + + for i, test := range tests { + x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.x)) + y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.y)) + z := new(uint256.Int).SetBytes(common.Hex2Bytes(test.z)) + expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.expected)) + stack.push(z) + stack.push(y) + stack.push(x) + opAddmod(&pc, evmInterpreter, &callCtx{nil, stack, nil}) + actual := stack.pop() + if actual.Cmp(expected) != 0 { + t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual) + } + } +} + +// getResult is a convenience function to generate the expected values +func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { + var ( + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) + stack = newstack() + pc = uint64(0) + interpreter = env.interpreter.(*EVMInterpreter) + ) + result := make([]TwoOperandTestcase, len(args)) + for i, param := range args { + x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x)) + y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y)) + stack.push(x) + stack.push(y) + _, err := opFn(&pc, interpreter, &callCtx{nil, stack, nil}) + if err != nil { + log.Fatalln(err) + } + actual := stack.pop() + result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)} + } + return result +} + // utility function to fill the json-file with testcases // Enable this test to generate the 'testcases_xx.json' files func TestWriteExpectedValues(t *testing.T) { @@ -245,7 +265,7 @@ func TestWriteExpectedValues(t *testing.T) { if err != nil { t.Fatal(err) } - _ = ioutil.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) + _ = os.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) if err != nil { t.Fatal(err) } @@ -255,7 +275,7 @@ func TestWriteExpectedValues(t *testing.T) { // TestJsonTestcases runs through all the testcases defined as json-files func TestJsonTestcases(t *testing.T) { for name := range twoOpMethods { - data, err := ioutil.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) + data, err := os.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) if err != nil { t.Fatal("Failed to read file", err) } @@ -276,7 +296,6 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) { ) env.interpreter = evmInterpreter - evmInterpreter.intPool = poolOfIntPools.get() // convert args byteArgs := make([][]byte, len(args)) for i, arg := range args { @@ -286,13 +305,13 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) { bench.ResetTimer() for i := 0; i < bench.N; i++ { for _, arg := range byteArgs { - a := new(big.Int).SetBytes(arg) + a := new(uint256.Int) + a.SetBytes(arg) stack.push(a) } op(&pc, evmInterpreter, &callCtx{nil, stack, nil}) stack.pop() } - poolOfIntPools.put(evmInterpreter.intPool) } func BenchmarkOpAdd64(b *testing.B) { @@ -338,8 +357,8 @@ func BenchmarkOpSub256(b *testing.B) { } func BenchmarkOpMul(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opMul, x, y) } @@ -370,64 +389,64 @@ func BenchmarkOpSdiv(b *testing.B) { } func BenchmarkOpMod(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opMod, x, y) } func BenchmarkOpSmod(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opSmod, x, y) } func BenchmarkOpExp(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opExp, x, y) } func BenchmarkOpSignExtend(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opSignExtend, x, y) } func BenchmarkOpLt(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opLt, x, y) } func BenchmarkOpGt(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opGt, x, y) } func BenchmarkOpSlt(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opSlt, x, y) } func BenchmarkOpSgt(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opSgt, x, y) } func BenchmarkOpEq(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opEq, x, y) } @@ -437,45 +456,45 @@ func BenchmarkOpEq2(b *testing.B) { opBenchmark(b, opEq, x, y) } func BenchmarkOpAnd(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opAnd, x, y) } func BenchmarkOpOr(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opOr, x, y) } func BenchmarkOpXor(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opXor, x, y) } func BenchmarkOpByte(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup opBenchmark(b, opByte, x, y) } func BenchmarkOpAddmod(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup + z := alphabetSoup opBenchmark(b, opAddmod, x, y, z) } func BenchmarkOpMulmod(b *testing.B) { - x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" - z := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" + x := alphabetSoup + y := alphabetSoup + z := alphabetSoup opBenchmark(b, opMulmod, x, y, z) } @@ -512,21 +531,21 @@ func TestOpMstore(t *testing.T) { ) env.interpreter = evmInterpreter - evmInterpreter.intPool = poolOfIntPools.get() mem.Resize(64) pc := uint64(0) v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700" - stack.pushN(new(big.Int).SetBytes(common.Hex2Bytes(v)), big.NewInt(0)) + stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v))) + stack.push(new(uint256.Int)) opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil}) if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v { t.Fatalf("Mstore fail, got %v, expected %v", got, v) } - stack.pushN(big.NewInt(0x1), big.NewInt(0)) + stack.push(new(uint256.Int).SetUint64(0x1)) + stack.push(new(uint256.Int)) opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil}) if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" { t.Fatalf("Mstore failed to overwrite previous value") } - poolOfIntPools.put(evmInterpreter.intPool) } func BenchmarkOpMstore(bench *testing.B) { @@ -538,21 +557,20 @@ func BenchmarkOpMstore(bench *testing.B) { ) env.interpreter = evmInterpreter - evmInterpreter.intPool = poolOfIntPools.get() mem.Resize(64) pc := uint64(0) - memStart := big.NewInt(0) - value := big.NewInt(0x1337) + memStart := new(uint256.Int) + value := new(uint256.Int).SetUint64(0x1337) bench.ResetTimer() for i := 0; i < bench.N; i++ { - stack.pushN(value, memStart) + stack.push(value) + stack.push(memStart) opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil}) } - poolOfIntPools.put(evmInterpreter.intPool) } -func BenchmarkOpSHA3(bench *testing.B) { +func BenchmarkOpKeccak256(bench *testing.B) { var ( env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack = newstack() @@ -560,17 +578,16 @@ func BenchmarkOpSHA3(bench *testing.B) { evmInterpreter = NewEVMInterpreter(env, env.vmConfig) ) env.interpreter = evmInterpreter - evmInterpreter.intPool = poolOfIntPools.get() mem.Resize(32) pc := uint64(0) - start := big.NewInt(0) + start := new(uint256.Int) bench.ResetTimer() for i := 0; i < bench.N; i++ { - stack.pushN(big.NewInt(32), start) - opSha3(&pc, evmInterpreter, &callCtx{mem, stack, nil}) + stack.push(uint256.NewInt(32)) + stack.push(start) + opKeccak256(&pc, evmInterpreter, &callCtx{mem, stack, nil}) } - poolOfIntPools.put(evmInterpreter.intPool) } func TestCreate2Addreses(t *testing.T) { @@ -644,6 +661,38 @@ func TestCreate2Addreses(t *testing.T) { if !bytes.Equal(expected.Bytes(), address.Bytes()) { t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String()) } + } +} +func TestRandom(t *testing.T) { + type testcase struct { + name string + random common.Hash + } + + for _, tt := range []testcase{ + {name: "empty hash", random: common.Hash{}}, + {name: "1", random: common.Hash{0}}, + {name: "emptyCodeHash", random: emptyCodeHash}, + {name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})}, + } { + var ( + env = NewEVM(Context{Random: &tt.random}, nil, nil, params.TestChainConfig, Config{}) + stack = newstack() + pc = uint64(0) + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) + ) + opRandom(&pc, evmInterpreter, &callCtx{nil, stack, nil}) + if len(stack.data) != 1 { + t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data)) + } + actual := stack.pop() + expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.random.Bytes())) + if overflow { + t.Errorf("Testcase %v: invalid overflow", tt.name) + } + if actual.Cmp(expected) != 0 { + t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual) + } } } diff --git a/core/vm/int_pool_verifier.go b/core/vm/int_pool_verifier.go deleted file mode 100644 index 82fbfed69..000000000 --- a/core/vm/int_pool_verifier.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 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 . - -// +build VERIFY_EVM_INTEGER_POOL - -package vm - -import "fmt" - -const verifyPool = true - -func verifyIntegerPool(ip *intPool) { - for i, item := range ip.pool.data { - if item.Cmp(checkVal) != 0 { - panic(fmt.Sprintf("%d'th item failed aggressive pool check. Value was modified", i)) - } - } -} diff --git a/core/vm/int_pool_verifier_empty.go b/core/vm/int_pool_verifier_empty.go deleted file mode 100644 index a5f1dc02b..000000000 --- a/core/vm/int_pool_verifier_empty.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 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 . - -// +build !VERIFY_EVM_INTEGER_POOL - -package vm - -const verifyPool = false - -func verifyIntegerPool(ip *intPool) {} diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 0f8db5c2c..0fcbe4451 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -18,7 +18,6 @@ package vm import ( "hash" - "sync/atomic" "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/common/math" @@ -29,10 +28,9 @@ import ( type Config struct { Debug bool // Enables debugging Tracer Tracer // Opcode logger - NoRecursion bool // Disables call, callcode, delegate call and create EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages - JumpTable [256]operation // EVM instruction table, automatically populated if unset + JumpTable *JumpTable // EVM instruction table, automatically populated if unset EWASMInterpreter string // External EWASM interpreter options EVMInterpreter string // External EVM interpreter options @@ -83,8 +81,6 @@ type EVMInterpreter struct { evm *EVM cfg Config - intPool *intPool - hasher keccakState // Keccak256 hasher instance shared across opcodes hasherBuf common.Hash // Keccak256 hasher result array shared aross opcodes @@ -94,35 +90,44 @@ type EVMInterpreter struct { // NewEVMInterpreter returns a new instance of the Interpreter. func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { - // We use the STOP instruction whether to see - // the jump table was initialised. If it was not - // we'll set the default jump table. - if !cfg.JumpTable[STOP].valid { - var jt JumpTable + // If jump table was not initialised we set the default one. + if cfg.JumpTable == nil { switch { + case evm.chainRules.IsShanghai: + cfg.JumpTable = &shanghaiInstructionSet + case evm.chainRules.IsMerge: + cfg.JumpTable = &mergeInstructionSet + case evm.chainRules.IsLondon: + cfg.JumpTable = &londonInstructionSet + case evm.chainRules.IsBerlin: + cfg.JumpTable = &berlinInstructionSet case evm.chainRules.IsIstanbul: - jt = istanbulInstructionSet + cfg.JumpTable = &istanbulInstructionSet case evm.chainRules.IsConstantinople: - jt = constantinopleInstructionSet + cfg.JumpTable = &constantinopleInstructionSet case evm.chainRules.IsByzantium: - jt = byzantiumInstructionSet + cfg.JumpTable = &byzantiumInstructionSet case evm.chainRules.IsEIP158: - jt = spuriousDragonInstructionSet + cfg.JumpTable = &spuriousDragonInstructionSet case evm.chainRules.IsEIP150: - jt = tangerineWhistleInstructionSet + cfg.JumpTable = &tangerineWhistleInstructionSet case evm.chainRules.IsHomestead: - jt = homesteadInstructionSet + cfg.JumpTable = &homesteadInstructionSet default: - jt = frontierInstructionSet + cfg.JumpTable = &frontierInstructionSet } - for i, eip := range cfg.ExtraEips { - if err := EnableEIP(eip, &jt); err != nil { + var extraEips []int + for _, eip := range cfg.ExtraEips { + copy := *cfg.JumpTable + if err := EnableEIP(eip, ©); err != nil { // Disable it, so caller can check if it's activated or not - cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...) log.Error("EIP activation failed", "eip", eip, "error", err) + } else { + extraEips = append(extraEips, eip) } + cfg.JumpTable = © } - cfg.JumpTable = jt + cfg.ExtraEips = extraEips } return &EVMInterpreter{ @@ -138,20 +143,13 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // considered a revert-and-consume-all-gas operation except for // ErrExecutionReverted which means revert-and-keep-gas-left. func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) { - if in.intPool == nil { - in.intPool = poolOfIntPools.get() - defer func() { - poolOfIntPools.put(in.intPool) - in.intPool = nil - }() - } // Increment the call depth which is restricted to 1024 in.evm.depth++ defer func() { in.evm.depth-- }() // Make sure the readOnly is only set if we aren't in readOnly yet. - // This makes also sure that the readOnly flag isn't removed for child calls. + // This also makes sure that the readOnly flag isn't removed for child calls. if readOnly && !in.readOnly { in.readOnly = true defer func() { in.readOnly = false }() @@ -188,9 +186,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( ) contract.Input = input - // Reclaim the stack as an int pool when the execution stops - defer func() { in.intPool.put(stack.data...) }() - if in.cfg.Debug { defer func() { if err != nil { @@ -206,12 +201,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during // the execution of one of the operations or until the done flag is set by the // parent context. - steps := 0 for { - steps++ - if steps%1000 == 0 && atomic.LoadInt32(&in.evm.abort) != 0 { - break - } if in.cfg.Debug { // Capture pre-execution values for tracing. logged, pcCopy, gasCopy = false, pc, contract.Gas @@ -221,26 +211,12 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // enough stack items available to perform the operation. op = contract.GetOp(pc) operation := in.cfg.JumpTable[op] - if !operation.valid { - return nil, &ErrInvalidOpCode{opcode: op} - } // Validate stack if sLen := stack.len(); sLen < operation.minStack { return nil, &ErrStackUnderflow{stackLen: sLen, required: operation.minStack} } else if sLen > operation.maxStack { return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack} } - // If the operation is valid, enforce and write restrictions - if in.readOnly && in.evm.chainRules.IsByzantium { - // If the interpreter is operating in readonly mode, make sure no - // state-modifying operation is performed. The 3rd stack item - // for a call operation is the value. Transferring value from one - // account to the others means the state is modified and should also - // return with an error. - if operation.writes || (op == CALL && stack.Back(2).Sign() != 0) { - return nil, ErrWriteProtection - } - } // Static portion of gas cost = operation.constantGas // For tracing if !contract.UseGas(operation.constantGas) { @@ -285,29 +261,17 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // execute the operation res, err = operation.execute(&pc, in, callContext) - // verifyPool is a build flag. Pool verification makes sure the integrity - // of the integer pool by comparing values to a default value. - if verifyPool { - verifyIntegerPool(in.intPool) - } - // 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 = res - } - switch { - case err != nil: - return nil, err - case operation.reverts: - log.Debug("ErrExecutionReverted", "pc", pc, "reverts", operation.reverts, "err", err) - return res, ErrExecutionReverted - case operation.halts: - return res, nil - case !operation.jumps: - pc++ + if err != nil { + break } + pc++ + } + + if err == errStopToken { + err = nil // clear stop token error } - return nil, nil + + return res, err } // CanRun tells if the contract, passed as an argument, can be diff --git a/core/vm/intpool.go b/core/vm/intpool.go deleted file mode 100644 index eed074b07..000000000 --- a/core/vm/intpool.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2017 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 . - -package vm - -import ( - "math/big" - "sync" -) - -var checkVal = big.NewInt(-42) - -const poolLimit = 256 - -// intPool is a pool of big integers that -// can be reused for all big.Int operations. -type intPool struct { - pool *Stack -} - -func newIntPool() *intPool { - return &intPool{pool: newstack()} -} - -// get retrieves a big int from the pool, allocating one if the pool is empty. -// Note, the returned int's value is arbitrary and will not be zeroed! -func (p *intPool) get() *big.Int { - if p.pool.len() > 0 { - return p.pool.pop() - } - return new(big.Int) -} - -// getZero retrieves a big int from the pool, setting it to zero or allocating -// a new one if the pool is empty. -func (p *intPool) getZero() *big.Int { - if p.pool.len() > 0 { - return p.pool.pop().SetUint64(0) - } - return new(big.Int) -} - -// putOne returns an allocated big int to the pool to be later reused by get calls. -// Note, the values as saved as is; neither put nor get zeroes the ints out! -// As opposed to 'put' with variadic args, this method becomes inlined by the -// go compiler -func (p *intPool) putOne(i *big.Int) { - if len(p.pool.data) > poolLimit { - return - } - p.pool.push(i) -} - -// put returns an allocated big int to the pool to be later reused by get calls. -// Note, the values as saved as is; neither put nor get zeroes the ints out! -func (p *intPool) put(is ...*big.Int) { - if len(p.pool.data) > poolLimit { - return - } - for _, i := range is { - // verifyPool is a build flag. Pool verification makes sure the integrity - // of the integer pool by comparing values to a default value. - if verifyPool { - i.Set(checkVal) - } - p.pool.push(i) - } -} - -// The intPool pool's default capacity -const poolDefaultCap = 25 - -// intPoolPool manages a pool of intPools. -type intPoolPool struct { - pools []*intPool - lock sync.Mutex -} - -var poolOfIntPools = &intPoolPool{ - pools: make([]*intPool, 0, poolDefaultCap), -} - -// get is looking for an available pool to return. -func (ipp *intPoolPool) get() *intPool { - ipp.lock.Lock() - defer ipp.lock.Unlock() - - if len(poolOfIntPools.pools) > 0 { - ip := ipp.pools[len(ipp.pools)-1] - ipp.pools = ipp.pools[:len(ipp.pools)-1] - return ip - } - return newIntPool() -} - -// put a pool that has been allocated with get. -func (ipp *intPoolPool) put(ip *intPool) { - ipp.lock.Lock() - defer ipp.lock.Unlock() - - if len(ipp.pools) < cap(ipp.pools) { - ipp.pools = append(ipp.pools, ip) - } -} diff --git a/core/vm/intpool_test.go b/core/vm/intpool_test.go deleted file mode 100644 index 6c0d00f3c..000000000 --- a/core/vm/intpool_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2018 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 . - -package vm - -import ( - "testing" -) - -func TestIntPoolPoolGet(t *testing.T) { - poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) - - nip := poolOfIntPools.get() - if nip == nil { - t.Fatalf("Invalid pool allocation") - } -} - -func TestIntPoolPoolPut(t *testing.T) { - poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) - - nip := poolOfIntPools.get() - if len(poolOfIntPools.pools) != 0 { - t.Fatalf("Pool got added to list when none should have been") - } - - poolOfIntPools.put(nip) - if len(poolOfIntPools.pools) == 0 { - t.Fatalf("Pool did not get added to list when one should have been") - } -} - -func TestIntPoolPoolReUse(t *testing.T) { - poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) - nip := poolOfIntPools.get() - poolOfIntPools.put(nip) - poolOfIntPools.get() - - if len(poolOfIntPools.pools) != 0 { - t.Fatalf("Invalid number of pools. Got %d, expected %d", len(poolOfIntPools.pools), 0) - } -} diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 39f6dca03..99e3b82e2 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -40,13 +40,6 @@ type operation struct { // memorySize returns the memory size required for the operation memorySize memorySizeFunc - - halts bool // indicates whether the operation should halt further execution - jumps bool // indicates whether the program counter should not increment - writes bool // determines whether this a state modifying operation - valid bool // indication whether the retrieved operation is valid and known - reverts bool // determines whether the operation reverts state (implicitly halts) - returns bool // determines whether the operations sets the return data content } var ( @@ -57,10 +50,48 @@ var ( byzantiumInstructionSet = newByzantiumInstructionSet() constantinopleInstructionSet = newConstantinopleInstructionSet() istanbulInstructionSet = newIstanbulInstructionSet() + berlinInstructionSet = newBerlinInstructionSet() + londonInstructionSet = newLondonInstructionSet() + mergeInstructionSet = newMergeInstructionSet() + shanghaiInstructionSet = newShanghaiInstructionSet() ) // JumpTable contains the EVM opcodes supported at a given fork. -type JumpTable [256]operation +type JumpTable [256]*operation + +func newShanghaiInstructionSet() JumpTable { + instructionSet := newMergeInstructionSet() + enable3855(&instructionSet) // PUSH0 instruction + return instructionSet +} + +func newMergeInstructionSet() JumpTable { + instructionSet := newLondonInstructionSet() + instructionSet[PREVRANDAO] = &operation{ + execute: opRandom, + constantGas: GasQuickStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } + return instructionSet +} + +// newLondonInstructionSet returns the frontier, homestead, byzantium, +// constantinople, 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, +// constantinople, istanbul, petersburg and berlin instructions. +func newBerlinInstructionSet() JumpTable { + instructionSet := newIstanbulInstructionSet() + // enable2929(&instructionSet) // Gas cost increases for state access opcodes https://eips.ethereum.org/EIPS/eip-2929 + return instructionSet +} // newIstanbulInstructionSet returns the frontier, homestead // byzantium, contantinople and petersburg instructions. @@ -78,44 +109,37 @@ func newIstanbulInstructionSet() JumpTable { // byzantium and contantinople instructions. func newConstantinopleInstructionSet() JumpTable { instructionSet := newByzantiumInstructionSet() - instructionSet[SHL] = operation{ + instructionSet[SHL] = &operation{ execute: opSHL, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, } - instructionSet[SHR] = operation{ + instructionSet[SHR] = &operation{ execute: opSHR, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, } - instructionSet[SAR] = operation{ + instructionSet[SAR] = &operation{ execute: opSAR, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, } - instructionSet[EXTCODEHASH] = operation{ + instructionSet[EXTCODEHASH] = &operation{ execute: opExtCodeHash, constantGas: params.ExtcodeHashGasConstantinople, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, } - instructionSet[CREATE2] = operation{ + instructionSet[CREATE2] = &operation{ execute: opCreate2, constantGas: params.Create2Gas, dynamicGas: gasCreate2, minStack: minStack(4, 1), maxStack: maxStack(4, 1), memorySize: memoryCreate2, - valid: true, - writes: true, - returns: true, } return instructionSet } @@ -124,41 +148,34 @@ func newConstantinopleInstructionSet() JumpTable { // byzantium instructions. func newByzantiumInstructionSet() JumpTable { instructionSet := newSpuriousDragonInstructionSet() - instructionSet[STATICCALL] = operation{ + instructionSet[STATICCALL] = &operation{ execute: opStaticCall, constantGas: params.CallGasEIP150, dynamicGas: gasStaticCall, minStack: minStack(6, 1), maxStack: maxStack(6, 1), memorySize: memoryStaticCall, - valid: true, - returns: true, } - instructionSet[RETURNDATASIZE] = operation{ + instructionSet[RETURNDATASIZE] = &operation{ execute: opReturnDataSize, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, } - instructionSet[RETURNDATACOPY] = operation{ + instructionSet[RETURNDATACOPY] = &operation{ execute: opReturnDataCopy, constantGas: GasFastestStep, dynamicGas: gasReturnDataCopy, minStack: minStack(3, 0), maxStack: maxStack(3, 0), memorySize: memoryReturnDataCopy, - valid: true, } - instructionSet[REVERT] = operation{ + instructionSet[REVERT] = &operation{ execute: opRevert, dynamicGas: gasRevert, minStack: minStack(2, 0), maxStack: maxStack(2, 0), memorySize: memoryRevert, - valid: true, - reverts: true, - returns: true, } return instructionSet } @@ -188,15 +205,13 @@ func newTangerineWhistleInstructionSet() JumpTable { // instructions that can be executed during the homestead phase. func newHomesteadInstructionSet() JumpTable { instructionSet := newFrontierInstructionSet() - instructionSet[DELEGATECALL] = operation{ + instructionSet[DELEGATECALL] = &operation{ execute: opDelegateCall, dynamicGas: gasDelegateCall, constantGas: params.CallGasFrontier, minStack: minStack(6, 1), maxStack: maxStack(6, 1), memorySize: memoryDelegateCall, - valid: true, - returns: true, } return instructionSet } @@ -204,226 +219,194 @@ func newHomesteadInstructionSet() JumpTable { // newFrontierInstructionSet returns the frontier instructions // that can be executed during the frontier phase. func newFrontierInstructionSet() JumpTable { - return JumpTable{ + tbl := JumpTable{ STOP: { execute: opStop, constantGas: 0, minStack: minStack(0, 0), maxStack: maxStack(0, 0), - halts: true, - valid: true, }, ADD: { execute: opAdd, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, MUL: { execute: opMul, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SUB: { execute: opSub, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, DIV: { execute: opDiv, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SDIV: { execute: opSdiv, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, MOD: { execute: opMod, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SMOD: { execute: opSmod, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, ADDMOD: { execute: opAddmod, constantGas: GasMidStep, minStack: minStack(3, 1), maxStack: maxStack(3, 1), - valid: true, }, MULMOD: { execute: opMulmod, constantGas: GasMidStep, minStack: minStack(3, 1), maxStack: maxStack(3, 1), - valid: true, }, EXP: { execute: opExp, dynamicGas: gasExpFrontier, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SIGNEXTEND: { execute: opSignExtend, constantGas: GasFastStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, LT: { execute: opLt, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, GT: { execute: opGt, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SLT: { execute: opSlt, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, SGT: { execute: opSgt, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, EQ: { execute: opEq, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, ISZERO: { execute: opIszero, constantGas: GasFastestStep, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, AND: { execute: opAnd, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, XOR: { execute: opXor, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, OR: { execute: opOr, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, NOT: { execute: opNot, constantGas: GasFastestStep, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, BYTE: { execute: opByte, constantGas: GasFastestStep, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - valid: true, }, - SHA3: { - execute: opSha3, - constantGas: params.Sha3Gas, - dynamicGas: gasSha3, + KECCAK256: { + execute: opKeccak256, + constantGas: params.Keccak256Gas, + dynamicGas: gasKeccak256, minStack: minStack(2, 1), maxStack: maxStack(2, 1), - memorySize: memorySha3, - valid: true, + memorySize: memoryKeccak256, }, ADDRESS: { execute: opAddress, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, BALANCE: { execute: opBalance, constantGas: params.BalanceGasFrontier, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, ORIGIN: { execute: opOrigin, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, CALLER: { execute: opCaller, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, CALLVALUE: { execute: opCallValue, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, CALLDATALOAD: { execute: opCallDataLoad, constantGas: GasFastestStep, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, CALLDATASIZE: { execute: opCallDataSize, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, CALLDATACOPY: { execute: opCallDataCopy, @@ -432,14 +415,12 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(3, 0), maxStack: maxStack(3, 0), memorySize: memoryCallDataCopy, - valid: true, }, CODESIZE: { execute: opCodeSize, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, CODECOPY: { execute: opCodeCopy, @@ -448,21 +429,18 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(3, 0), maxStack: maxStack(3, 0), memorySize: memoryCodeCopy, - valid: true, }, GASPRICE: { execute: opGasprice, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, EXTCODESIZE: { execute: opExtCodeSize, constantGas: params.ExtcodeSizeGasFrontier, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, EXTCODECOPY: { execute: opExtCodeCopy, @@ -471,56 +449,48 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(4, 0), maxStack: maxStack(4, 0), memorySize: memoryExtCodeCopy, - valid: true, }, BLOCKHASH: { execute: opBlockhash, constantGas: GasExtStep, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, COINBASE: { execute: opCoinbase, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, TIMESTAMP: { execute: opTimestamp, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, NUMBER: { execute: opNumber, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, DIFFICULTY: { execute: opDifficulty, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, GASLIMIT: { execute: opGasLimit, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, POP: { execute: opPop, constantGas: GasQuickStep, minStack: minStack(1, 0), maxStack: maxStack(1, 0), - valid: true, }, MLOAD: { execute: opMload, @@ -529,7 +499,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(1, 1), maxStack: maxStack(1, 1), memorySize: memoryMLoad, - valid: true, }, MSTORE: { execute: opMstore, @@ -538,7 +507,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(2, 0), maxStack: maxStack(2, 0), memorySize: memoryMStore, - valid: true, }, MSTORE8: { execute: opMstore8, @@ -547,515 +515,438 @@ func newFrontierInstructionSet() JumpTable { memorySize: memoryMStore8, minStack: minStack(2, 0), maxStack: maxStack(2, 0), - - valid: true, }, SLOAD: { execute: opSload, constantGas: params.SloadGasFrontier, minStack: minStack(1, 1), maxStack: maxStack(1, 1), - valid: true, }, SSTORE: { execute: opSstore, dynamicGas: gasSStore, minStack: minStack(2, 0), maxStack: maxStack(2, 0), - valid: true, - writes: true, }, JUMP: { execute: opJump, constantGas: GasMidStep, minStack: minStack(1, 0), maxStack: maxStack(1, 0), - jumps: true, - valid: true, }, JUMPI: { execute: opJumpi, constantGas: GasSlowStep, minStack: minStack(2, 0), maxStack: maxStack(2, 0), - jumps: true, - valid: true, }, PC: { execute: opPc, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, MSIZE: { execute: opMsize, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, GAS: { execute: opGas, constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, JUMPDEST: { execute: opJumpdest, constantGas: params.JumpdestGas, minStack: minStack(0, 0), maxStack: maxStack(0, 0), - valid: true, }, PUSH1: { execute: opPush1, constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH2: { execute: makePush(2, 2), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH3: { execute: makePush(3, 3), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH4: { execute: makePush(4, 4), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH5: { execute: makePush(5, 5), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH6: { execute: makePush(6, 6), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH7: { execute: makePush(7, 7), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH8: { execute: makePush(8, 8), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH9: { execute: makePush(9, 9), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH10: { execute: makePush(10, 10), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH11: { execute: makePush(11, 11), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH12: { execute: makePush(12, 12), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH13: { execute: makePush(13, 13), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH14: { execute: makePush(14, 14), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH15: { execute: makePush(15, 15), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH16: { execute: makePush(16, 16), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH17: { execute: makePush(17, 17), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH18: { execute: makePush(18, 18), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH19: { execute: makePush(19, 19), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH20: { execute: makePush(20, 20), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH21: { execute: makePush(21, 21), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH22: { execute: makePush(22, 22), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH23: { execute: makePush(23, 23), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH24: { execute: makePush(24, 24), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH25: { execute: makePush(25, 25), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH26: { execute: makePush(26, 26), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH27: { execute: makePush(27, 27), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH28: { execute: makePush(28, 28), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH29: { execute: makePush(29, 29), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH30: { execute: makePush(30, 30), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH31: { execute: makePush(31, 31), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, PUSH32: { execute: makePush(32, 32), constantGas: GasFastestStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), - valid: true, }, DUP1: { execute: makeDup(1), constantGas: GasFastestStep, minStack: minDupStack(1), maxStack: maxDupStack(1), - valid: true, }, DUP2: { execute: makeDup(2), constantGas: GasFastestStep, minStack: minDupStack(2), maxStack: maxDupStack(2), - valid: true, }, DUP3: { execute: makeDup(3), constantGas: GasFastestStep, minStack: minDupStack(3), maxStack: maxDupStack(3), - valid: true, }, DUP4: { execute: makeDup(4), constantGas: GasFastestStep, minStack: minDupStack(4), maxStack: maxDupStack(4), - valid: true, }, DUP5: { execute: makeDup(5), constantGas: GasFastestStep, minStack: minDupStack(5), maxStack: maxDupStack(5), - valid: true, }, DUP6: { execute: makeDup(6), constantGas: GasFastestStep, minStack: minDupStack(6), maxStack: maxDupStack(6), - valid: true, }, DUP7: { execute: makeDup(7), constantGas: GasFastestStep, minStack: minDupStack(7), maxStack: maxDupStack(7), - valid: true, }, DUP8: { execute: makeDup(8), constantGas: GasFastestStep, minStack: minDupStack(8), maxStack: maxDupStack(8), - valid: true, }, DUP9: { execute: makeDup(9), constantGas: GasFastestStep, minStack: minDupStack(9), maxStack: maxDupStack(9), - valid: true, }, DUP10: { execute: makeDup(10), constantGas: GasFastestStep, minStack: minDupStack(10), maxStack: maxDupStack(10), - valid: true, }, DUP11: { execute: makeDup(11), constantGas: GasFastestStep, minStack: minDupStack(11), maxStack: maxDupStack(11), - valid: true, }, DUP12: { execute: makeDup(12), constantGas: GasFastestStep, minStack: minDupStack(12), maxStack: maxDupStack(12), - valid: true, }, DUP13: { execute: makeDup(13), constantGas: GasFastestStep, minStack: minDupStack(13), maxStack: maxDupStack(13), - valid: true, }, DUP14: { execute: makeDup(14), constantGas: GasFastestStep, minStack: minDupStack(14), maxStack: maxDupStack(14), - valid: true, }, DUP15: { execute: makeDup(15), constantGas: GasFastestStep, minStack: minDupStack(15), maxStack: maxDupStack(15), - valid: true, }, DUP16: { execute: makeDup(16), constantGas: GasFastestStep, minStack: minDupStack(16), maxStack: maxDupStack(16), - valid: true, }, SWAP1: { execute: makeSwap(1), constantGas: GasFastestStep, minStack: minSwapStack(2), maxStack: maxSwapStack(2), - valid: true, }, SWAP2: { execute: makeSwap(2), constantGas: GasFastestStep, minStack: minSwapStack(3), maxStack: maxSwapStack(3), - valid: true, }, SWAP3: { execute: makeSwap(3), constantGas: GasFastestStep, minStack: minSwapStack(4), maxStack: maxSwapStack(4), - valid: true, }, SWAP4: { execute: makeSwap(4), constantGas: GasFastestStep, minStack: minSwapStack(5), maxStack: maxSwapStack(5), - valid: true, }, SWAP5: { execute: makeSwap(5), constantGas: GasFastestStep, minStack: minSwapStack(6), maxStack: maxSwapStack(6), - valid: true, }, SWAP6: { execute: makeSwap(6), constantGas: GasFastestStep, minStack: minSwapStack(7), maxStack: maxSwapStack(7), - valid: true, }, SWAP7: { execute: makeSwap(7), constantGas: GasFastestStep, minStack: minSwapStack(8), maxStack: maxSwapStack(8), - valid: true, }, SWAP8: { execute: makeSwap(8), constantGas: GasFastestStep, minStack: minSwapStack(9), maxStack: maxSwapStack(9), - valid: true, }, SWAP9: { execute: makeSwap(9), constantGas: GasFastestStep, minStack: minSwapStack(10), maxStack: maxSwapStack(10), - valid: true, }, SWAP10: { execute: makeSwap(10), constantGas: GasFastestStep, minStack: minSwapStack(11), maxStack: maxSwapStack(11), - valid: true, }, SWAP11: { execute: makeSwap(11), constantGas: GasFastestStep, minStack: minSwapStack(12), maxStack: maxSwapStack(12), - valid: true, }, SWAP12: { execute: makeSwap(12), constantGas: GasFastestStep, minStack: minSwapStack(13), maxStack: maxSwapStack(13), - valid: true, }, SWAP13: { execute: makeSwap(13), constantGas: GasFastestStep, minStack: minSwapStack(14), maxStack: maxSwapStack(14), - valid: true, }, SWAP14: { execute: makeSwap(14), constantGas: GasFastestStep, minStack: minSwapStack(15), maxStack: maxSwapStack(15), - valid: true, }, SWAP15: { execute: makeSwap(15), constantGas: GasFastestStep, minStack: minSwapStack(16), maxStack: maxSwapStack(16), - valid: true, }, SWAP16: { execute: makeSwap(16), constantGas: GasFastestStep, minStack: minSwapStack(17), maxStack: maxSwapStack(17), - valid: true, }, LOG0: { execute: makeLog(0), @@ -1063,8 +954,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(2, 0), maxStack: maxStack(2, 0), memorySize: memoryLog, - valid: true, - writes: true, }, LOG1: { execute: makeLog(1), @@ -1072,8 +961,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(3, 0), maxStack: maxStack(3, 0), memorySize: memoryLog, - valid: true, - writes: true, }, LOG2: { execute: makeLog(2), @@ -1081,8 +968,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(4, 0), maxStack: maxStack(4, 0), memorySize: memoryLog, - valid: true, - writes: true, }, LOG3: { execute: makeLog(3), @@ -1090,8 +975,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(5, 0), maxStack: maxStack(5, 0), memorySize: memoryLog, - valid: true, - writes: true, }, LOG4: { execute: makeLog(4), @@ -1099,8 +982,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(6, 0), maxStack: maxStack(6, 0), memorySize: memoryLog, - valid: true, - writes: true, }, CREATE: { execute: opCreate, @@ -1109,9 +990,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(3, 1), maxStack: maxStack(3, 1), memorySize: memoryCreate, - valid: true, - writes: true, - returns: true, }, CALL: { execute: opCall, @@ -1120,8 +998,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(7, 1), maxStack: maxStack(7, 1), memorySize: memoryCall, - valid: true, - returns: true, }, CALLCODE: { execute: opCallCode, @@ -1130,8 +1006,6 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(7, 1), maxStack: maxStack(7, 1), memorySize: memoryCall, - valid: true, - returns: true, }, RETURN: { execute: opReturn, @@ -1139,17 +1013,21 @@ func newFrontierInstructionSet() JumpTable { minStack: minStack(2, 0), maxStack: maxStack(2, 0), memorySize: memoryReturn, - halts: true, - valid: true, }, SELFDESTRUCT: { - execute: opSuicide, + execute: opSelfdestruct, dynamicGas: gasSelfdestruct, minStack: minStack(1, 0), maxStack: maxStack(1, 0), - halts: true, - valid: true, - writes: true, }, } + + // Fill all unassigned slots with opUndefined. + for i, entry := range tbl { + if entry == nil { + tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0)} + } + } + + return tbl } diff --git a/core/vm/logger.go b/core/vm/logger.go index 5ae847e60..08f45748d 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -156,8 +156,8 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui // it in the local storage container. if op == SSTORE && stack.len() >= 2 { var ( - value = common.BigToHash(stack.data[stack.len()-2]) - address = common.BigToHash(stack.data[stack.len()-1]) + value = common.Hash(stack.data[stack.len()-2].Bytes32()) + address = common.Hash(stack.data[stack.len()-1].Bytes32()) ) l.changedValues[contract.Address()][address] = value } @@ -172,7 +172,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui if !l.cfg.DisableStack { stck = make([]*big.Int, len(stack.Data())) for i, item := range stack.Data() { - stck[i] = new(big.Int).Set(item) + stck[i] = new(big.Int).Set(item.ToBig()) } } // Copy a snapshot of the current storage to a new container diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go index c3e5978eb..ee16306db 100644 --- a/core/vm/logger_json.go +++ b/core/vm/logger_json.go @@ -62,14 +62,19 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint log.Memory = memory.Data() } if !l.cfg.DisableStack { - log.Stack = stack.Data() + //TODO(@holiman) improve this + logstack := make([]*big.Int, len(stack.Data())) + for i, item := range stack.Data() { + logstack[i] = item.ToBig() + } + log.Stack = logstack } return l.encoder.Encode(log) } // CaptureFault outputs state information on the logger. func (l *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { - return nil + return l.CaptureState(env, pc, op, gas, cost, memory, stack, contract, depth, err) } // CaptureEnd is triggered at end of execution. @@ -80,8 +85,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 { - return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) + errMsg = err.Error() } - return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) + return 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 77c7b3a34..f055efe22 100644 --- a/core/vm/logger_test.go +++ b/core/vm/logger_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/XinFinOrg/XDC-Subnet/params" + "github.com/holiman/uint256" "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/core/state" @@ -30,7 +31,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) {} @@ -57,8 +57,8 @@ func TestStoreCapture(t *testing.T) { stack = newstack() contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 0) ) - stack.push(big.NewInt(1)) - stack.push(big.NewInt(0)) + stack.push(uint256.NewInt(1)) + stack.push(new(uint256.Int)) var index common.Hash logger.CaptureState(env, 0, SSTORE, 0, 0, mem, stack, contract, 0, nil) if len(logger.changedValues[contract.Address()]) == 0 { diff --git a/core/vm/memory.go b/core/vm/memory.go index 0d1ef3b1d..9b3ca1904 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -16,12 +16,7 @@ package vm -import ( - "fmt" - "math/big" - - "github.com/XinFinOrg/XDC-Subnet/common/math" -) +import "github.com/holiman/uint256" // Memory implements a simple memory model for the ethereum virtual machine. type Memory struct { @@ -50,16 +45,15 @@ func (m *Memory) Set(offset, size uint64, value []byte) { // Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to // 32 bytes. -func (m *Memory) Set32(offset uint64, val *big.Int) { +func (m *Memory) Set32(offset uint64, val *uint256.Int) { // length of store may never be less than offset + size. // The store should be resized PRIOR to setting the memory if offset+32 > uint64(len(m.store)) { panic("invalid memory: store empty") } - // Zero the memory area - copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) // Fill in relevant bits - math.ReadBits(val, m.store[offset:offset+32]) + b32 := val.Bytes32() + copy(m.store[offset:], b32[:]) } // Resize resizes the memory to size @@ -69,7 +63,7 @@ func (m *Memory) Resize(size uint64) { } } -// Get returns offset + size as a new slice +// GetCopy returns offset + size as a new slice func (m *Memory) GetCopy(offset, size int64) (cpy []byte) { if size == 0 { return nil @@ -107,18 +101,3 @@ func (m *Memory) Len() int { func (m *Memory) Data() []byte { return m.store } - -// Print dumps the content of the memory. -func (m *Memory) Print() { - fmt.Printf("### mem %d bytes ###\n", len(m.store)) - if len(m.store) > 0 { - addr := 0 - for i := 0; i+32 <= len(m.store); i += 32 { - fmt.Printf("%03d: % x\n", addr, m.store[i:i+32]) - addr++ - } - } else { - fmt.Println("-- empty --") - } - fmt.Println("####################") -} diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go index 4fcb41442..e35ca84e0 100644 --- a/core/vm/memory_table.go +++ b/core/vm/memory_table.go @@ -16,7 +16,7 @@ package vm -func memorySha3(stack *Stack) (uint64, bool) { +func memoryKeccak256(stack *Stack) (uint64, bool) { return calcMemSize64(stack.Back(0), stack.Back(1)) } diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 322e01d17..26523e53c 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -25,103 +25,101 @@ type OpCode byte // IsPush specifies if an opcode is a PUSH opcode. func (op OpCode) IsPush() bool { - switch op { - case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: - return true - } - return false -} - -// IsStaticJump specifies if an opcode is JUMP. -func (op OpCode) IsStaticJump() bool { - return op == JUMP + return PUSH0 <= op && op <= PUSH32 } // 0x0 range - arithmetic ops. const ( - STOP OpCode = iota - ADD - MUL - SUB - DIV - SDIV - MOD - SMOD - ADDMOD - MULMOD - EXP - SIGNEXTEND + STOP OpCode = 0x0 + ADD OpCode = 0x1 + MUL OpCode = 0x2 + SUB OpCode = 0x3 + DIV OpCode = 0x4 + SDIV OpCode = 0x5 + MOD OpCode = 0x6 + SMOD OpCode = 0x7 + ADDMOD OpCode = 0x8 + MULMOD OpCode = 0x9 + EXP OpCode = 0xa + SIGNEXTEND OpCode = 0xb ) // 0x10 range - comparison ops. const ( - LT OpCode = iota + 0x10 - GT - SLT - SGT - EQ - ISZERO - AND - OR - XOR - NOT - BYTE - SHL - SHR - SAR + LT OpCode = 0x10 + GT OpCode = 0x11 + SLT OpCode = 0x12 + SGT OpCode = 0x13 + EQ OpCode = 0x14 + ISZERO OpCode = 0x15 + AND OpCode = 0x16 + OR OpCode = 0x17 + XOR OpCode = 0x18 + NOT OpCode = 0x19 + BYTE OpCode = 0x1a + SHL OpCode = 0x1b + SHR OpCode = 0x1c + SAR OpCode = 0x1d +) - SHA3 OpCode = 0x20 +// 0x20 range - crypto. +const ( + KECCAK256 OpCode = 0x20 ) // 0x30 range - closure state. const ( - ADDRESS OpCode = 0x30 + iota - BALANCE - ORIGIN - CALLER - CALLVALUE - CALLDATALOAD - CALLDATASIZE - CALLDATACOPY - CODESIZE - CODECOPY - GASPRICE - EXTCODESIZE - EXTCODECOPY - RETURNDATASIZE - RETURNDATACOPY - EXTCODEHASH + ADDRESS OpCode = 0x30 + BALANCE OpCode = 0x31 + ORIGIN OpCode = 0x32 + CALLER OpCode = 0x33 + CALLVALUE OpCode = 0x34 + CALLDATALOAD OpCode = 0x35 + CALLDATASIZE OpCode = 0x36 + CALLDATACOPY OpCode = 0x37 + CODESIZE OpCode = 0x38 + CODECOPY OpCode = 0x39 + GASPRICE OpCode = 0x3a + EXTCODESIZE OpCode = 0x3b + EXTCODECOPY OpCode = 0x3c + RETURNDATASIZE OpCode = 0x3d + RETURNDATACOPY OpCode = 0x3e + EXTCODEHASH OpCode = 0x3f ) // 0x40 range - block operations. const ( - BLOCKHASH OpCode = 0x40 + iota - COINBASE - TIMESTAMP - NUMBER - DIFFICULTY - GASLIMIT + BLOCKHASH OpCode = 0x40 + COINBASE OpCode = 0x41 + TIMESTAMP OpCode = 0x42 + NUMBER OpCode = 0x43 + DIFFICULTY OpCode = 0x44 + RANDOM OpCode = 0x44 // Same as DIFFICULTY + PREVRANDAO OpCode = 0x44 // Same as DIFFICULTY + GASLIMIT OpCode = 0x45 CHAINID OpCode = 0x46 SELFBALANCE OpCode = 0x47 + BASEFEE OpCode = 0x48 ) // 0x50 range - 'storage' and execution. const ( - POP OpCode = 0x50 + iota - MLOAD - MSTORE - MSTORE8 - SLOAD - SSTORE - JUMP - JUMPI - PC - MSIZE - GAS - JUMPDEST + POP OpCode = 0x50 + MLOAD OpCode = 0x51 + MSTORE OpCode = 0x52 + MSTORE8 OpCode = 0x53 + SLOAD OpCode = 0x54 + SSTORE OpCode = 0x55 + JUMP OpCode = 0x56 + JUMPI OpCode = 0x57 + PC OpCode = 0x58 + MSIZE OpCode = 0x59 + GAS OpCode = 0x5a + JUMPDEST OpCode = 0x5b + PUSH0 OpCode = 0x5f ) -// 0x60 range. +// 0x60 range - pushes. const ( PUSH1 OpCode = 0x60 + iota PUSH2 @@ -155,7 +153,11 @@ const ( PUSH30 PUSH31 PUSH32 - DUP1 +) + +// 0x80 range - dups. +const ( + DUP1 = 0x80 + iota DUP2 DUP3 DUP4 @@ -171,7 +173,11 @@ const ( DUP14 DUP15 DUP16 - SWAP1 +) + +// 0x90 range - swaps. +const ( + SWAP1 = 0x90 + iota SWAP2 SWAP3 SWAP4 @@ -198,28 +204,22 @@ const ( LOG4 ) -// unofficial opcodes used for parsing. -const ( - PUSH OpCode = 0xb0 + iota - DUP - SWAP -) - // 0xf0 range - closures. const ( - CREATE OpCode = 0xf0 + iota - CALL - CALLCODE - RETURN - DELEGATECALL - CREATE2 + CREATE OpCode = 0xf0 + CALL OpCode = 0xf1 + CALLCODE OpCode = 0xf2 + RETURN OpCode = 0xf3 + DELEGATECALL OpCode = 0xf4 + CREATE2 OpCode = 0xf5 + STATICCALL OpCode = 0xfa REVERT OpCode = 0xfd + INVALID OpCode = 0xfe SELFDESTRUCT OpCode = 0xff ) -// Since the opcodes aren't all in order we can't use a regular slice. -var opCodeToString = map[OpCode]string{ +var opCodeToString = [256]string{ // 0x0 range - arithmetic ops. STOP: "STOP", ADD: "ADD", @@ -251,7 +251,7 @@ var opCodeToString = map[OpCode]string{ MULMOD: "MULMOD", // 0x20 range - crypto. - SHA3: "SHA3", + KECCAK256: "KECCAK256", // 0x30 range - closure state. ADDRESS: "ADDRESS", @@ -276,10 +276,11 @@ var opCodeToString = map[OpCode]string{ COINBASE: "COINBASE", TIMESTAMP: "TIMESTAMP", NUMBER: "NUMBER", - DIFFICULTY: "DIFFICULTY", + DIFFICULTY: "DIFFICULTY", // TODO rename to PREVRANDAO post merge GASLIMIT: "GASLIMIT", CHAINID: "CHAINID", SELFBALANCE: "SELFBALANCE", + BASEFEE: "BASEFEE", // 0x50 range - 'storage' and execution. POP: "POP", @@ -296,6 +297,7 @@ var opCodeToString = map[OpCode]string{ MSIZE: "MSIZE", GAS: "GAS", JUMPDEST: "JUMPDEST", + PUSH0: "PUSH0", // 0x60 range - push. PUSH1: "PUSH1", @@ -379,20 +381,16 @@ var opCodeToString = map[OpCode]string{ CREATE2: "CREATE2", STATICCALL: "STATICCALL", REVERT: "REVERT", + INVALID: "INVALID", SELFDESTRUCT: "SELFDESTRUCT", - - PUSH: "PUSH", - DUP: "DUP", - SWAP: "SWAP", } func (op OpCode) String() string { - str := opCodeToString[op] - if len(str) == 0 { - return fmt.Sprintf("opcode 0x%x not defined", int(op)) + if s := opCodeToString[op]; s != "" { + return s } - return str + return fmt.Sprintf("opcode %#x not defined", int(op)) } var stringToOp = map[string]OpCode{ @@ -422,7 +420,7 @@ var stringToOp = map[string]OpCode{ "SAR": SAR, "ADDMOD": ADDMOD, "MULMOD": MULMOD, - "SHA3": SHA3, + "KECCAK256": KECCAK256, "ADDRESS": ADDRESS, "BALANCE": BALANCE, "ORIGIN": ORIGIN, @@ -449,6 +447,7 @@ var stringToOp = map[string]OpCode{ "DIFFICULTY": DIFFICULTY, "GASLIMIT": GASLIMIT, "SELFBALANCE": SELFBALANCE, + "BASEFEE": BASEFEE, "POP": POP, "MLOAD": MLOAD, "MSTORE": MSTORE, @@ -461,6 +460,7 @@ var stringToOp = map[string]OpCode{ "MSIZE": MSIZE, "GAS": GAS, "JUMPDEST": JUMPDEST, + "PUSH0": PUSH0, "PUSH1": PUSH1, "PUSH2": PUSH2, "PUSH3": PUSH3, @@ -536,6 +536,7 @@ var stringToOp = map[string]OpCode{ "RETURN": RETURN, "CALLCODE": CALLCODE, "REVERT": REVERT, + "INVALID": INVALID, "SELFDESTRUCT": SELFDESTRUCT, } diff --git a/core/vm/privacy/bulletproof.go b/core/vm/privacy/bulletproof.go index 2a18079f4..590f9b4c2 100644 --- a/core/vm/privacy/bulletproof.go +++ b/core/vm/privacy/bulletproof.go @@ -420,11 +420,7 @@ func InnerProductVerify(c *big.Int, P, U ECPoint, G, H []ECPoint, ipp InnerProdA Pcalc3 := ux.Mult(ccalc) Pcalc := Pcalc1.Add(Pcalc2).Add(Pcalc3) - if !Pprime.Equal(Pcalc) { - return false - } - - return true + return Pprime.Equal(Pcalc) } /* Inner Product Verify Fast @@ -834,7 +830,7 @@ func (ipp *InnerProdArg) Deserialize(proof []byte, numChallenges int) error { if len(proof) <= (offset + 32*numChallenges) { return errors.New("input data too short") } - for i := 0; i < int(numChallenges); i++ { + for i := 0; i < numChallenges; i++ { ipp.Challenges = append(ipp.Challenges, new(big.Int).SetBytes(proof[offset:offset+32])) offset += 32 } diff --git a/core/vm/privacy/bulletproof_test.go b/core/vm/privacy/bulletproof_test.go index 54f67c080..8088ac98e 100644 --- a/core/vm/privacy/bulletproof_test.go +++ b/core/vm/privacy/bulletproof_test.go @@ -4,11 +4,12 @@ import ( "crypto/rand" "encoding/json" "fmt" - "github.com/stretchr/testify/assert" - "io/ioutil" + "io" "math/big" "os" "testing" + + "github.com/stretchr/testify/assert" ) func TestInnerProductProveLen1(t *testing.T) { @@ -409,7 +410,7 @@ func parseTestData(filePath string) MultiRangeProof { defer jsonFile.Close() - byteValue, _ := ioutil.ReadAll(jsonFile) + byteValue, _ := io.ReadAll(jsonFile) // we initialize our Users array // var result map[string]interface{} @@ -448,7 +449,8 @@ func parseTestData(filePath string) MultiRangeProof { return proof } -/** +/* +* Utils for parsing data from json */ func MapBigI(list []string, f func(string) *big.Int) []*big.Int { diff --git a/core/vm/privacy/ringct.go b/core/vm/privacy/ringct.go index 61a41b0dd..5a25d0153 100644 --- a/core/vm/privacy/ringct.go +++ b/core/vm/privacy/ringct.go @@ -8,9 +8,11 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/XinFinOrg/XDC-Subnet/common" "math/big" + "github.com/XinFinOrg/XDC-Subnet/common" + "github.com/XinFinOrg/XDC-Subnet/crypto/secp256k1" + "github.com/XinFinOrg/XDC-Subnet/crypto" "github.com/XinFinOrg/XDC-Subnet/log" ) @@ -120,14 +122,15 @@ func (r Ring) Bytes() (b []byte) { return } -func PadTo32Bytes(in []byte) (out []byte) { - out = append(out, in...) - for { - if len(out) == 32 { - return - } - out = append([]byte{0}, out...) +func PadTo32Bytes(in []byte) []byte { + padded := make([]byte, 32) + if len(in) >= 32 { + copy(padded, in) + } else { + copy(padded[32-len(in):], in) } + + return padded } // converts the signature to a byte array @@ -174,6 +177,20 @@ func (r *RingSignature) Serialize() ([]byte, error) { } func computeSignatureSize(numRing int, ringSize int) int { + const MaxInt = int(^uint(0) >> 1) + + if numRing < 0 || ringSize < 0 { + return -1 + } + + // Calculate term and check for overflow + + term := numRing * ringSize * 65 + + if term < 0 || term < numRing || term < ringSize { + return -1 + } + return 8 + 8 + 32 + 32 + numRing*ringSize*32 + numRing*ringSize*33 + numRing*33 } @@ -198,7 +215,7 @@ func Deserialize(r []byte) (*RingSignature, error) { sig.NumRing = size_int if len(r) != computeSignatureSize(sig.NumRing, sig.Size) { - return nil, errors.New("incorrect ring size") + return nil, fmt.Errorf("incorrect ring size, len r: %d, sig.NumRing: %d sig.Size: %d", len(r), sig.NumRing, sig.Size) } m := r[offset : offset+32] @@ -243,6 +260,10 @@ func Deserialize(r []byte) (*RingSignature, error) { sig.SerializedRing = r + if !Verify(sig, false) { + return nil, errors.New("failed to deserialize, invalid ring signature") + } + return sig, nil } @@ -272,7 +293,7 @@ func GenNewKeyRing(size int, privkey *ecdsa.PrivateKey, s int) ([]*ecdsa.PublicK ring := make([]*ecdsa.PublicKey, size) pubkey := privkey.Public().(*ecdsa.PublicKey) - if s > len(ring) { + if s >= len(ring) { return nil, errors.New("index s out of bounds") } @@ -341,7 +362,8 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS for i := 0; i < numRing; i++ { pubkeys[i] = &privkeys[i].PublicKey } - curve := pubkeys[0].Curve + //cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated + curve := pubkeys[0].Curve.(*secp256k1.BitCurve) sig := new(RingSignature) sig.Size = ringsize sig.NumRing = numRing @@ -431,6 +453,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS // calculate L[j][idx] = s[j][idx]*G + c[idx]*Ring[j][idx] px, py := curve.ScalarMult(rings[j][idx].X, rings[j][idx].Y, PadTo32Bytes(C[idx].Bytes())) // px, py = c_i*P_i sx, sy := curve.ScalarBaseMult(PadTo32Bytes(S[j][idx].Bytes())) // sx, sy = s[n-1]*G + if px == nil || py == nil || sx == nil || sy == nil { + return nil, errors.New("Could not create ring signature") + } l_x, l_y := curve.Add(sx, sy, px, py) L[j][idx] = &ecdsa.PublicKey{curve, l_x, l_y} lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...) @@ -440,6 +465,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS px, py = curve.ScalarMult(images[j].X, images[j].Y, C[idx].Bytes()) // px, py = c_i*I hx, hy := HashPoint(rings[j][idx]) sx, sy = curve.ScalarMult(hx, hy, S[j][idx].Bytes()) // sx, sy = s[n-1]*H_p(P_i) + if px == nil || py == nil || sx == nil || sy == nil { + return nil, errors.New("Could not create ring signature") + } r_x, r_y := curve.Add(sx, sy, px, py) R[j][idx] = &ecdsa.PublicKey{curve, r_x, r_y} rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...) @@ -488,18 +516,41 @@ func Verify(sig *RingSignature, verifyMes bool) bool { S := sig.S C := make([]*big.Int, ringsize+1) C[0] = sig.C - curve := sig.Curve + //cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated + curve := sig.Curve.(*secp256k1.BitCurve) image := sig.I + //check on curve + for i := 0; i < numRing; i++ { + onCurve := curve.IsOnCurve(image[i].X, image[i].Y) + if !onCurve { + return false + } + for j := 0; j < ringsize; j++ { + onCurve := curve.IsOnCurve(rings[i][j].X, rings[i][j].Y) + if !onCurve { + return false + } + } + } + // calculate c[i+1] = H(m, s[i]*G + c[i]*P[i]) // and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size //log.Info("C", "0", common.Bytes2Hex(C[0].Bytes())) for j := 0; j < ringsize; j++ { var l []byte for i := 0; i < numRing; i++ { + // Validate S[i][j] and C[j] + if !isValidScalar(S[i][j], curve) || !isValidScalar(C[j], curve) { + return false // Or handle the error as required + } + // calculate L[i][j] = s[i][j]*G + c[j]*Ring[i][j] px, py := curve.ScalarMult(rings[i][j].X, rings[i][j].Y, C[j].Bytes()) // px, py = c_i*P_i sx, sy := curve.ScalarBaseMult(S[i][j].Bytes()) // sx, sy = s[i]*G + if px == nil || py == nil || sx == nil || sy == nil { + return false + } l_x, l_y := curve.Add(sx, sy, px, py) lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...) //log.Info("L[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(lT)) @@ -508,9 +559,17 @@ func Verify(sig *RingSignature, verifyMes bool) bool { // calculate R_i = s[i][j]*H_p(Ring[i][j]) + c[j]*I[j] px, py = curve.ScalarMult(image[i].X, image[i].Y, C[j].Bytes()) // px, py = c[i]*I hx, hy := HashPoint(rings[i][j]) + + // Validate S[i][j], hx, and hy + if !isValidScalar(S[i][j], curve) || !isValidScalar(hx, curve) || !isValidScalar(hy, curve) { + return false // Or handle the error as required + } //log.Info("H[i][j]", "i", i, "j", j, "x.input", common.Bytes2Hex(rings[i][j].X.Bytes()), "y.input", common.Bytes2Hex(rings[i][j].Y.Bytes())) //log.Info("H[i][j]", "i", i, "j", j, "x", common.Bytes2Hex(hx.Bytes()), "y", common.Bytes2Hex(hy.Bytes())) sx, sy = curve.ScalarMult(hx, hy, S[i][j].Bytes()) // sx, sy = s[i]*H_p(P[i]) + if px == nil || py == nil || sx == nil || sy == nil { + return false + } r_x, r_y := curve.Add(sx, sy, px, py) rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...) //log.Info("R[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(rT)) @@ -533,6 +592,10 @@ func Verify(sig *RingSignature, verifyMes bool) bool { return bytes.Equal(sig.C.Bytes(), C[ringsize].Bytes()) } +func isValidScalar(scalar *big.Int, curve elliptic.Curve) bool { + return scalar.Sign() >= 0 && scalar.Cmp(curve.Params().N) < 0 +} + func Link(sig_a *RingSignature, sig_b *RingSignature) bool { for i := 0; i < len(sig_a.I); i++ { for j := 0; j < len(sig_b.I); j++ { @@ -566,35 +629,3 @@ func GenerateMultiRingParams(numRing int, ringSize int, s int) (rings []Ring, pr } return rings, privkeys, m, nil } - -func TestRingSignature() (bool, []byte) { - /*for i := 14; i < 15; i++ { - for j := 14; j < 15; j++ { - for k := 0; k <= j; k++ {*/ - numRing := 1 - ringSize := 10 - s := 9 - rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) - ringSignature, err := Sign(m, rings, privkeys, s) - if err != nil { - log.Error("Failed to create Ring signature") - return false, []byte{} - } - - sig, err := ringSignature.Serialize() - if err != nil { - return false, []byte{} - } - - deserializedSig, err := Deserialize(sig) - if err != nil { - return false, []byte{} - } - verified := Verify(deserializedSig, false) - if !verified { - log.Error("Failed to verify Ring signature") - return false, []byte{} - } - - return true, []byte{} -} diff --git a/core/vm/privacy/ringct_test.go b/core/vm/privacy/ringct_test.go index 703b08df0..6cc1e2903 100644 --- a/core/vm/privacy/ringct_test.go +++ b/core/vm/privacy/ringct_test.go @@ -1,9 +1,17 @@ package privacy import ( + "bytes" + "encoding/binary" "fmt" + "math/big" "testing" - ) + + "github.com/XinFinOrg/XDC-Subnet/crypto" + "github.com/stretchr/testify/assert" + + "github.com/XinFinOrg/XDC-Subnet/crypto/secp256k1" +) func TestSign(t *testing.T) { /*for i := 14; i < 15; i++ { @@ -44,3 +52,273 @@ func TestSign(t *testing.T) { } } + +func TestDeserialize(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 5 + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + + ringSignature, err := Sign(m, rings, privkeys, s) + if err != nil { + t.Error("Failed to create Ring signature") + } + + // A normal signature. + sig, err := ringSignature.Serialize() + if err != nil { + t.Error("Failed to Serialize input Ring signature") + } + + // Modify the serialized signature s.t. + // the new signature passes the length check + // but triggers buffer overflow in Deserialize(). + // ringSize: 10 -> 56759212534490939 + // len(sig): 3495 -> 3804 + // 80 + 5 * (56759212534490939*65 + 33) = 18446744073709551616 + 3804 + bs := make([]byte, 8) + binary.BigEndian.PutUint64(bs, 56759212534490939) + for i := 0; i < 8; i++ { + sig[i+8] = bs[i] + } + tail := make([]byte, 3804-len(sig)) + sig = append(sig, tail...) + + _, err = Deserialize(sig) + assert.EqualError(t, err, "incorrect ring size, len r: 3804, sig.NumRing: 5 sig.Size: 56759212534490939") +} + +func TestVerify1(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 7 + + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + if err != nil { + t.Error("fail to generate rings") + } + + ringSignature, err := Sign(m, rings, privkeys, s) + if err != nil { + t.Error("fail to create ring signature") + } + + sig, err := ringSignature.Serialize() + if err != nil { + t.Error("fail to serialize input ring signature") + } + + deserializedSig, err := Deserialize(sig) + if err != nil { + t.Error("fail to deserialize ring signature") + } + + assert.True(t, Verify(deserializedSig, false), "Verify should return true") +} + +func TestDeserialize2(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 7 + + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + if err != nil { + t.Error("fail to generate rings") + } + + ringSignature, err := Sign(m, rings, privkeys, s) + if err != nil { + t.Error("fail to create ring signature") + } + + // change one sig to the scalar field + ringSignature.S[0][0] = curve.Params().N + + sig, err := ringSignature.Serialize() + if err != nil { + t.Error("fail to serialize input ring signature") + } + + _, err = Deserialize(sig) + assert.EqualError(t, err, "failed to deserialize, invalid ring signature") +} + +func TestPadTo32Bytes(t *testing.T) { + arr := [44]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34} + + // test input slice is longer than 32 bytes + assert.True(t, bytes.Equal(PadTo32Bytes(arr[0:]), arr[0:32]), "Test PadTo32Bytes longer than 32 bytes #1") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[1:]), arr[1:33]), "Test PadTo32Bytes longer than 32 bytes #2") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[2:]), arr[2:34]), "Test PadTo32Bytes longer than 32 bytes #3") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[3:]), arr[3:35]), "Test PadTo32Bytes longer than 32 bytes #4") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[4:]), arr[4:36]), "Test PadTo32Bytes longer than 32 bytes #5") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[5:]), arr[5:37]), "Test PadTo32Bytes longer than 32 bytes #6") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[6:]), arr[6:38]), "Test PadTo32Bytes longer than 32 bytes #7") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[7:]), arr[7:39]), "Test PadTo32Bytes longer than 32 bytes #8") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[8:]), arr[8:40]), "Test PadTo32Bytes longer than 32 bytes #9") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[9:]), arr[9:41]), "Test PadTo32Bytes longer than 32 bytes #10") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:]), arr[10:42]), "Test PadTo32Bytes longer than 32 bytes #11") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[11:]), arr[11:43]), "Test PadTo32Bytes longer than 32 bytes #12") + + // test input slice is equal 32 bytes + assert.True(t, bytes.Equal(PadTo32Bytes(arr[0:32]), arr[0:32]), "Test PadTo32Bytes equal 32 bytes #1") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[1:33]), arr[1:33]), "Test PadTo32Bytes equal 32 bytes #2") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[2:34]), arr[2:34]), "Test PadTo32Bytes equal 32 bytes #3") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[3:35]), arr[3:35]), "Test PadTo32Bytes equal 32 bytes #4") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[4:36]), arr[4:36]), "Test PadTo32Bytes equal 32 bytes #5") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[5:37]), arr[5:37]), "Test PadTo32Bytes equal 32 bytes #6") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[6:38]), arr[6:38]), "Test PadTo32Bytes equal 32 bytes #7") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[7:39]), arr[7:39]), "Test PadTo32Bytes equal 32 bytes #8") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[8:40]), arr[8:40]), "Test PadTo32Bytes equal 32 bytes #9") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[9:41]), arr[9:41]), "Test PadTo32Bytes equal 32 bytes #10") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:42]), arr[10:42]), "Test PadTo32Bytes equal 32 bytes #11") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[11:43]), arr[11:43]), "Test PadTo32Bytes equal 32 bytes #12") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[12:44]), arr[12:44]), "Test PadTo32Bytes equal 32 bytes #13") + + // test input slice is shorter than 32 bytes + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:32]), arr[0:32]), "Test PadTo32Bytes shorter than 32 bytes #1") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:33]), arr[1:33]), "Test PadTo32Bytes shorter than 32 bytes #2") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:34]), arr[2:34]), "Test PadTo32Bytes shorter than 32 bytes #3") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:35]), arr[3:35]), "Test PadTo32Bytes shorter than 32 bytes #4") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:36]), arr[4:36]), "Test PadTo32Bytes shorter than 32 bytes #5") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:37]), arr[5:37]), "Test PadTo32Bytes shorter than 32 bytes #6") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:38]), arr[6:38]), "Test PadTo32Bytes shorter than 32 bytes #7") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:39]), arr[7:39]), "Test PadTo32Bytes shorter than 32 bytes #8") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:40]), arr[8:40]), "Test PadTo32Bytes shorter than 32 bytes #9") + assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:41]), arr[9:41]), "Test PadTo32Bytes shorter than 32 bytes #10") +} + +func TestCurveAddNegative(t *testing.T) { + curve := crypto.S256().(*secp256k1.BitCurve) + + x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(2)).Bytes()) + fmt.Printf("Point(%x, %x)\n", x1, y1) + + x2 := x1 + y2 := new(big.Int).Neg(y1) // negative of point (x1,y1) + + x3, y3 := curve.Add(x1, y1, x2, y2) + fmt.Printf("Output is Point(%x, %x)\n", x3, y3) + + x0 := new(big.Int).SetUint64(uint64(0)) + y0 := new(big.Int).SetUint64(uint64(0)) // infinity + + if (x3.Cmp(x0) == 0) && (y3.Cmp(y0) == 0) { + // fmt.Printf("Correct, add negative of self should yield (0,0)") + } else { + t.Error("Incorrect, add negative of self did not yield (0,0)") + } +} + +func TestCurveAddZero(t *testing.T) { + // curve := crypto.S256() + curve := crypto.S256().(*secp256k1.BitCurve) + + x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(1)).Bytes()) + fmt.Printf("Point(%x, %x)\n", x1, y1) + + x0 := new(big.Int).SetUint64(uint64(0)) + y0 := new(big.Int).SetUint64(uint64(0)) // infinity + fmt.Printf("Is point (%d,%d) on the curve: %t \n", x0, y0, curve.IsOnCurve(x0, y0)) + + x2, y2 := curve.Add(x1, y1, x0, y0) + fmt.Printf("Output is Point(%x, %x)\n", x2, y2) + + if (x1.Cmp(x2) == 0) && (y1.Cmp(y2) == 0) { + // fmt.Printf("Correct, Point on curve is the same after Zero addition\n") + } else { + t.Error("Incorrect, Point on curve changed after Zero addition\n") + } +} + +func TestOnCurveVerify(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 5 + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + ringSignature, err := Sign(m, rings, privkeys, s) + if err != nil { + t.Error("Failed to create Ring signature") + } + + valid := Verify(ringSignature, false) + if !valid { + t.Error("Incorrect, unmodified ringSignature should be valid") + } + + ringsModified := ringSignature.Ring + ringsModified[0][0].X = big.NewInt(1) + ringsModified[0][0].Y = big.NewInt(1) + valid = Verify(ringSignature, false) + if valid { + t.Error("Incorrect, modified ringSignature should be invalid") + } +} + +func TestOnCurveDeserialize(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 5 + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + ringSignature, err := Sign(m, rings, privkeys, s) + if err != nil { + t.Error("Failed to create Ring signature") + } + + sig, err := ringSignature.Serialize() + if err != nil { + t.Error("Failed to Serialize input Ring signature") + } + _, err = Deserialize(sig) + if err != nil { + t.Error("Failed to Deserialize") + } + + ringsModified := ringSignature.Ring + ringsModified[0][0].X = big.NewInt(1) + ringsModified[0][0].Y = big.NewInt(1) + + sig, err = ringSignature.Serialize() + if err != nil { + t.Error("Failed to Serialize input Ring signature") + } + _, err = Deserialize(sig) + assert.EqualError(t, err, "failed to deserialize, invalid ring signature") +} + +func TestCurveScalarMult(t *testing.T) { + curve := crypto.S256().(*secp256k1.BitCurve) + + x, y := curve.ScalarBaseMult(curve.Params().N.Bytes()) + if x == nil && y == nil { + fmt.Println("Scalar multiplication with base point returns nil when scalar is the scalar field") + } + + x2, y2 := curve.ScalarMult(new(big.Int).SetUint64(uint64(100)), new(big.Int).SetUint64(uint64(2)), curve.Params().N.Bytes()) + if x2 == nil && y2 == nil { + fmt.Println("Scalar multiplication with a point (not necessarily on curve) returns nil when scalar is the scalar field") + } +} + +func TestNilPointerDereferencePanic(t *testing.T) { + numRing := 5 + ringSize := 10 + s := 7 + rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s) + + ringSig, err := Sign(m, rings, privkeys, s) + if err != nil { + fmt.Println("Failed to set up") + } + + ringSig.S[0][0] = curve.Params().N // change one sig to the scalar field + + sig, err := ringSig.Serialize() + if err != nil { + t.Error("Failed to Serialize input Ring signature") + } + + _, err = Deserialize(sig) + // Should failed to verify Ring signature as the signature is invalid + assert.EqualError(t, err, "failed to deserialize, invalid ring signature") +} diff --git a/core/vm/stack.go b/core/vm/stack.go index c9c3d07f4..a389c04b7 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -17,37 +17,31 @@ package vm import ( - "fmt" - "math/big" + "github.com/holiman/uint256" ) // Stack is an object for basic stack operations. Items popped to the stack are // expected to be changed and modified. stack does not take care of adding newly // initialised objects. type Stack struct { - data []*big.Int + data []uint256.Int } func newstack() *Stack { - return &Stack{data: make([]*big.Int, 0, 1024)} + return &Stack{data: make([]uint256.Int, 0, 16)} } -// Data returns the underlying big.Int array. -func (st *Stack) Data() []*big.Int { +// Data returns the underlying uint256.Int array. +func (st *Stack) Data() []uint256.Int { return st.data } -func (st *Stack) push(d *big.Int) { +func (st *Stack) push(d *uint256.Int) { // NOTE push limit (1024) is checked in baseCheck - //stackItem := new(big.Int).Set(d) - //st.data = append(st.data, stackItem) - st.data = append(st.data, d) -} -func (st *Stack) pushN(ds ...*big.Int) { - st.data = append(st.data, ds...) + st.data = append(st.data, *d) } -func (st *Stack) pop() (ret *big.Int) { +func (st *Stack) pop() (ret uint256.Int) { ret = st.data[len(st.data)-1] st.data = st.data[:len(st.data)-1] return @@ -61,28 +55,15 @@ func (st *Stack) swap(n int) { st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] } -func (st *Stack) dup(pool *intPool, n int) { - st.push(pool.get().Set(st.data[st.len()-n])) +func (st *Stack) dup(n int) { + st.push(&st.data[st.len()-n]) } -func (st *Stack) peek() *big.Int { - return st.data[st.len()-1] +func (st *Stack) peek() *uint256.Int { + return &st.data[st.len()-1] } // Back returns the n'th item in stack -func (st *Stack) Back(n int) *big.Int { - return st.data[st.len()-n-1] -} - -// Print dumps the content of the stack -func (st *Stack) Print() { - fmt.Println("### stack ###") - if len(st.data) > 0 { - for i, val := range st.data { - fmt.Printf("%-3d %v\n", i, val) - } - } else { - fmt.Println("-- empty --") - } - fmt.Println("#############") +func (st *Stack) Back(n int) *uint256.Int { + return &st.data[st.len()-n-1] } diff --git a/crypto/bn256/bn256_fuzz.go b/crypto/bn256/bn256_fuzz.go index 4a16c95c2..979a4775b 100644 --- a/crypto/bn256/bn256_fuzz.go +++ b/crypto/bn256/bn256_fuzz.go @@ -21,42 +21,52 @@ package bn256 import ( "bytes" + "fmt" + "io" "math/big" cloudflare "github.com/XinFinOrg/XDC-Subnet/crypto/bn256/cloudflare" google "github.com/XinFinOrg/XDC-Subnet/crypto/bn256/google" ) -// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. -func FuzzAdd(data []byte) int { - // Ensure we have enough data in the first place - if len(data) != 128 { - return 0 +func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1) { + _, xc, err := cloudflare.RandomG1(input) + if err != nil { + // insufficient input + return nil, nil } - // Ensure both libs can parse the first curve point - xc := new(cloudflare.G1) - _, errc := xc.Unmarshal(data[:64]) - xg := new(google.G1) - _, errg := xg.Unmarshal(data[:64]) - - if (errc == nil) != (errg == nil) { - panic("parse mismatch") - } else if errc != nil { - return 0 + if _, err := xg.Unmarshal(xc.Marshal()); err != nil { + panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err)) } - // Ensure both libs can parse the second curve point - yc := new(cloudflare.G1) - _, errc = yc.Unmarshal(data[64:]) + return xc, xg +} - yg := new(google.G1) - _, errg = yg.Unmarshal(data[64:]) +func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2) { + _, xc, err := cloudflare.RandomG2(input) + if err != nil { + // insufficient input + return nil, nil + } + xg := new(google.G2) + if _, err := xg.Unmarshal(xc.Marshal()); err != nil { + panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err)) + } + return xc, xg +} - if (errc == nil) != (errg == nil) { - panic("parse mismatch") - } else if errc != nil { +// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. +func FuzzAdd(data []byte) int { + input := bytes.NewReader(data) + xc, xg := getG1Points(input) + if xc == nil { return 0 } + yc, yg := getG1Points(input) + if yc == nil { + return 0 + } + // Ensure both libs can parse the second curve point // Add the two points and ensure they result in the same output rc := new(cloudflare.G1) rc.Add(xc, yc) @@ -67,73 +77,50 @@ func FuzzAdd(data []byte) int { if !bytes.Equal(rc.Marshal(), rg.Marshal()) { panic("add mismatch") } - return 0 + return 1 } // FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare // libraries. func FuzzMul(data []byte) int { - // Ensure we have enough data in the first place - if len(data) != 96 { + input := bytes.NewReader(data) + pc, pg := getG1Points(input) + if pc == nil { return 0 } - // Ensure both libs can parse the curve point - pc := new(cloudflare.G1) - _, errc := pc.Unmarshal(data[:64]) - - pg := new(google.G1) - _, errg := pg.Unmarshal(data[:64]) - - if (errc == nil) != (errg == nil) { - panic("parse mismatch") - } else if errc != nil { + // Add the two points and ensure they result in the same output + remaining := input.Len() + if remaining == 0 { return 0 } - // Add the two points and ensure they result in the same output + buf := make([]byte, remaining) + input.Read(buf) + rc := new(cloudflare.G1) - rc.ScalarMult(pc, new(big.Int).SetBytes(data[64:])) + rc.ScalarMult(pc, new(big.Int).SetBytes(buf)) rg := new(google.G1) - rg.ScalarMult(pg, new(big.Int).SetBytes(data[64:])) + rg.ScalarMult(pg, new(big.Int).SetBytes(buf)) if !bytes.Equal(rc.Marshal(), rg.Marshal()) { panic("scalar mul mismatch") } - return 0 + return 1 } func FuzzPair(data []byte) int { - // Ensure we have enough data in the first place - if len(data) != 192 { + input := bytes.NewReader(data) + pc, pg := getG1Points(input) + if pc == nil { return 0 } - // Ensure both libs can parse the curve point - pc := new(cloudflare.G1) - _, errc := pc.Unmarshal(data[:64]) - - pg := new(google.G1) - _, errg := pg.Unmarshal(data[:64]) - - if (errc == nil) != (errg == nil) { - panic("parse mismatch") - } else if errc != nil { - return 0 - } - // Ensure both libs can parse the twist point - tc := new(cloudflare.G2) - _, errc = tc.Unmarshal(data[64:]) - - tg := new(google.G2) - _, errg = tg.Unmarshal(data[64:]) - - if (errc == nil) != (errg == nil) { - panic("parse mismatch") - } else if errc != nil { + tc, tg := getG2Points(input) + if tc == nil { return 0 } // Pair the two points and ensure thet result in the same output if cloudflare.PairingCheck([]*cloudflare.G1{pc}, []*cloudflare.G2{tc}) != google.PairingCheck([]*google.G1{pg}, []*google.G2{tg}) { panic("pair mismatch") } - return 0 + return 1 } diff --git a/crypto/bn256/cloudflare/bn256.go b/crypto/bn256/cloudflare/bn256.go index c6ea2d07e..a6dd972ba 100644 --- a/crypto/bn256/cloudflare/bn256.go +++ b/crypto/bn256/cloudflare/bn256.go @@ -23,7 +23,7 @@ import ( func randomK(r io.Reader) (k *big.Int, err error) { for { k, err = rand.Int(r, Order) - if k.Sign() > 0 || err != nil { + if err != nil || k.Sign() > 0 { return } } @@ -100,6 +100,10 @@ func (e *G1) Marshal() []byte { // Each value is a 256-bit number. const numBytes = 256 / 8 + if e.p == nil { + e.p = &curvePoint{} + } + e.p.MakeAffine() ret := make([]byte, numBytes*2) if e.p.IsInfinity() { @@ -382,6 +386,11 @@ func (e *GT) Marshal() []byte { // Each value is a 256-bit number. const numBytes = 256 / 8 + if e.p == nil { + e.p = &gfP12{} + e.p.SetOne() + } + ret := make([]byte, numBytes*12) temp := &gfP{} diff --git a/crypto/bn256/cloudflare/bn256_test.go b/crypto/bn256/cloudflare/bn256_test.go index 0c8016d86..481e2f78c 100644 --- a/crypto/bn256/cloudflare/bn256_test.go +++ b/crypto/bn256/cloudflare/bn256_test.go @@ -92,6 +92,19 @@ func TestTripartiteDiffieHellman(t *testing.T) { } } +func TestG2SelfAddition(t *testing.T) { + s, _ := rand.Int(rand.Reader, Order) + p := new(G2).ScalarBaseMult(s) + + if !p.p.IsOnCurve() { + t.Fatal("p isn't on curve") + } + m := p.Add(p, p).Marshal() + if _, err := p.Unmarshal(m); err != nil { + t.Fatalf("p.Add(p, p) ∉ G₂: %v", err) + } +} + func BenchmarkG1(b *testing.B) { x, _ := rand.Int(rand.Reader, Order) b.ResetTimer() diff --git a/crypto/bn256/cloudflare/curve.go b/crypto/bn256/cloudflare/curve.go index 18e9b38f3..16f0489e3 100644 --- a/crypto/bn256/cloudflare/curve.go +++ b/crypto/bn256/cloudflare/curve.go @@ -171,15 +171,15 @@ func (c *curvePoint) Double(a *curvePoint) { gfpAdd(t, d, d) gfpSub(&c.x, f, t) + gfpMul(&c.z, &a.y, &a.z) + gfpAdd(&c.z, &c.z, &c.z) + gfpAdd(t, C, C) gfpAdd(t2, t, t) gfpAdd(t, t2, t2) gfpSub(&c.y, d, &c.x) gfpMul(t2, e, &c.y) gfpSub(&c.y, t2, t) - - gfpMul(t, &a.y, &a.z) - gfpAdd(&c.z, t, t) } func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { diff --git a/crypto/bn256/cloudflare/gfp.go b/crypto/bn256/cloudflare/gfp.go index e8e84e7b3..b15e1697e 100644 --- a/crypto/bn256/cloudflare/gfp.go +++ b/crypto/bn256/cloudflare/gfp.go @@ -61,6 +61,7 @@ func (e *gfP) Marshal(out []byte) { func (e *gfP) Unmarshal(in []byte) error { // Unmarshal the bytes into little endian form for w := uint(0); w < 4; w++ { + e[3-w] = 0 for b := uint(0); b < 8; b++ { e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) } diff --git a/crypto/bn256/cloudflare/gfp_amd64.s b/crypto/bn256/cloudflare/gfp_amd64.s index e7d430971..8c5fe23fb 100644 --- a/crypto/bn256/cloudflare/gfp_amd64.s +++ b/crypto/bn256/cloudflare/gfp_amd64.s @@ -49,7 +49,7 @@ TEXT ·gfpNeg(SB),0,$0-16 SBBQ 24(DI), R11 MOVQ $0, AX - gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX) + gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,CX,BX) MOVQ c+0(FP), DI storeBlock(R8,R9,R10,R11, 0(DI)) @@ -68,7 +68,7 @@ TEXT ·gfpAdd(SB),0,$0-24 ADCQ 24(SI), R11 ADCQ $0, R12 - gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX) + gfpCarry(R8,R9,R10,R11,R12, R13,R14,CX,AX,BX) MOVQ c+0(FP), DI storeBlock(R8,R9,R10,R11, 0(DI)) @@ -83,7 +83,7 @@ TEXT ·gfpSub(SB),0,$0-24 MOVQ ·p2+0(SB), R12 MOVQ ·p2+8(SB), R13 MOVQ ·p2+16(SB), R14 - MOVQ ·p2+24(SB), R15 + MOVQ ·p2+24(SB), CX MOVQ $0, AX SUBQ 0(SI), R8 @@ -94,12 +94,12 @@ TEXT ·gfpSub(SB),0,$0-24 CMOVQCC AX, R12 CMOVQCC AX, R13 CMOVQCC AX, R14 - CMOVQCC AX, R15 + CMOVQCC AX, CX ADDQ R12, R8 ADCQ R13, R9 ADCQ R14, R10 - ADCQ R15, R11 + ADCQ CX, R11 MOVQ c+0(FP), DI storeBlock(R8,R9,R10,R11, 0(DI)) @@ -115,7 +115,7 @@ TEXT ·gfpMul(SB),0,$160-24 mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI)) storeBlock( R8, R9,R10,R11, 0(SP)) - storeBlock(R12,R13,R14,R15, 32(SP)) + storeBlock(R12,R13,R14,CX, 32(SP)) gfpReduceBMI2() JMP end @@ -125,6 +125,6 @@ nobmi2Mul: end: MOVQ c+0(FP), DI - storeBlock(R12,R13,R14,R15, 0(DI)) + storeBlock(R12,R13,R14,CX, 0(DI)) RET diff --git a/crypto/bn256/cloudflare/mul_amd64.h b/crypto/bn256/cloudflare/mul_amd64.h index bab5da831..9d8e4b37d 100644 --- a/crypto/bn256/cloudflare/mul_amd64.h +++ b/crypto/bn256/cloudflare/mul_amd64.h @@ -165,7 +165,7 @@ \ \ // Add the 512-bit intermediate to m*N loadBlock(96+stack, R8,R9,R10,R11) \ - loadBlock(128+stack, R12,R13,R14,R15) \ + loadBlock(128+stack, R12,R13,R14,CX) \ \ MOVQ $0, AX \ ADDQ 0+stack, R8 \ @@ -175,7 +175,7 @@ ADCQ 32+stack, R12 \ ADCQ 40+stack, R13 \ ADCQ 48+stack, R14 \ - ADCQ 56+stack, R15 \ + ADCQ 56+stack, CX \ ADCQ $0, AX \ \ - gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) + gfpCarry(R12,R13,R14,CX,AX, R8,R9,R10,R11,BX) diff --git a/crypto/bn256/cloudflare/mul_bmi2_amd64.h b/crypto/bn256/cloudflare/mul_bmi2_amd64.h index 71ad0499a..403566c6f 100644 --- a/crypto/bn256/cloudflare/mul_bmi2_amd64.h +++ b/crypto/bn256/cloudflare/mul_bmi2_amd64.h @@ -29,7 +29,7 @@ ADCQ $0, R14 \ \ MOVQ a2, DX \ - MOVQ $0, R15 \ + MOVQ $0, CX \ MULXQ 0+rb, AX, BX \ ADDQ AX, R10 \ ADCQ BX, R11 \ @@ -43,7 +43,7 @@ MULXQ 24+rb, AX, BX \ ADCQ AX, R13 \ ADCQ BX, R14 \ - ADCQ $0, R15 \ + ADCQ $0, CX \ \ MOVQ a3, DX \ MULXQ 0+rb, AX, BX \ @@ -52,13 +52,13 @@ MULXQ 16+rb, AX, BX \ ADCQ AX, R13 \ ADCQ BX, R14 \ - ADCQ $0, R15 \ + ADCQ $0, CX \ MULXQ 8+rb, AX, BX \ ADDQ AX, R12 \ ADCQ BX, R13 \ MULXQ 24+rb, AX, BX \ ADCQ AX, R14 \ - ADCQ BX, R15 + ADCQ BX, CX #define gfpReduceBMI2() \ \ // m = (T * N') mod R, store m in R8:R9:R10:R11 @@ -106,7 +106,7 @@ ADCQ 32(SP), R12 \ ADCQ 40(SP), R13 \ ADCQ 48(SP), R14 \ - ADCQ 56(SP), R15 \ + ADCQ 56(SP), CX \ ADCQ $0, AX \ \ - gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) + gfpCarry(R12,R13,R14,CX,AX, R8,R9,R10,R11,BX) diff --git a/crypto/bn256/cloudflare/twist.go b/crypto/bn256/cloudflare/twist.go index 0c2f80d4e..2c7a69a4d 100644 --- a/crypto/bn256/cloudflare/twist.go +++ b/crypto/bn256/cloudflare/twist.go @@ -150,15 +150,15 @@ func (c *twistPoint) Double(a *twistPoint) { t.Add(d, d) c.x.Sub(f, t) + c.z.Mul(&a.y, &a.z) + c.z.Add(&c.z, &c.z) + t.Add(C, C) t2.Add(t, t) t.Add(t2, t2) c.y.Sub(d, &c.x) t2.Mul(e, &c.y) c.y.Sub(t2, t) - - t.Mul(&a.y, &a.z) - c.z.Add(t, t) } func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { diff --git a/crypto/crypto.go b/crypto/crypto.go index 12cfff385..38c7f4285 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -24,7 +24,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/big" "os" @@ -175,7 +174,7 @@ func LoadECDSA(file string) (*ecdsa.PrivateKey, error) { // restrictive permissions. The key data is saved hex-encoded. func SaveECDSA(file string, key *ecdsa.PrivateKey) error { k := hex.EncodeToString(FromECDSA(key)) - return ioutil.WriteFile(file, []byte(k), 0600) + return os.WriteFile(file, []byte(k), 0600) } func GenerateKey() (*ecdsa.PrivateKey, error) { diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 46eb15e4e..4ce916d0e 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -20,7 +20,6 @@ import ( "bytes" "crypto/ecdsa" "encoding/hex" - "io/ioutil" "math/big" "os" "testing" @@ -122,7 +121,7 @@ func TestLoadECDSAFile(t *testing.T) { } } - ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600) + os.WriteFile(fileName0, []byte(testPrivHex), 0600) defer os.Remove(fileName0) key0, err := LoadECDSA(fileName0) diff --git a/crypto/secp256k1/LICENSE b/crypto/secp256k1/LICENSE new file mode 100644 index 000000000..f9090e142 --- /dev/null +++ b/crypto/secp256k1/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2010 The Go Authors. All rights reserved. +Copyright (c) 2011 ThePiachu. All rights reserved. +Copyright (c) 2015 Jeffrey Wilcke. All rights reserved. +Copyright (c) 2015 Felix Lange. All rights reserved. +Copyright (c) 2015 Gustav Simonsson. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of the copyright holder. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index f84a8ea38..8610f50ea 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -1,5 +1,6 @@ // Copyright 2010 The Go Authors. All rights reserved. // Copyright 2011 ThePiachu. All rights reserved. +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -34,16 +35,28 @@ package secp256k1 import ( "crypto/elliptic" "math/big" - "unsafe" +) - "github.com/XinFinOrg/XDC-Subnet/common/math" +const ( + // number of bits in a big.Word + wordBits = 32 << (uint64(^big.Word(0)) >> 63) + // number of bytes in a big.Word + wordBytes = wordBits / 8 ) -/* -#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" +// readBits encodes the absolute value of bigint as big-endian bytes. Callers +// must ensure that buf has enough space. If buf is too short the result will +// be incomplete. +func readBits(bigint *big.Int, buf []byte) { + i := len(buf) + for _, d := range bigint.Bits() { + for j := 0; j < wordBytes && i > 0; j++ { + i-- + buf[i] = byte(d) + d >>= 8 + } + } +} // This code is from https://github.com/ThePiachu/GoBit and implements // several Koblitz elliptic curves over prime fields. @@ -77,7 +90,7 @@ func (BitCurve *BitCurve) Params() *elliptic.CurveParams { } } -// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve. +// IsOnCurve returns true if the given (x,y) lies on the BitCurve. func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { // y² = x³ + b y2 := new(big.Int).Mul(y, y) //y² @@ -96,6 +109,10 @@ func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { // affineFromJacobian reverses the Jacobian transform. See the comment at the // top of the file. func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { + if z.Sign() == 0 { + return new(big.Int), new(big.Int) + } + zinv := new(big.Int).ModInverse(z, BitCurve.P) zinvsq := new(big.Int).Mul(zinv, zinv) @@ -109,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)) } @@ -218,40 +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) - math.ReadBits(Bx, point[:32]) - math.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) { @@ -264,8 +258,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { byteLen := (BitCurve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point flag - math.ReadBits(x, ret[1:1+byteLen]) - math.ReadBits(y, ret[1+byteLen:]) + readBits(x, ret[1:1+byteLen]) + readBits(y, ret[1+byteLen:]) return ret } @@ -289,12 +283,12 @@ var theCurve = new(BitCurve) func init() { // See SEC 2 section 2.7.1 // curve parameters taken from: - // http://www.secg.org/collateral/sec2_final.pdf - theCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16) - theCurve.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) - theCurve.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16) - theCurve.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16) - theCurve.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16) + // http://www.secg.org/sec2-v2.pdf + theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) + theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) + theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) + theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) + theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) theCurve.BitSize = 256 } diff --git a/crypto/secp256k1/dummy.go b/crypto/secp256k1/dummy.go new file mode 100644 index 000000000..65a75080f --- /dev/null +++ b/crypto/secp256k1/dummy.go @@ -0,0 +1,21 @@ +//go:build dummy +// +build dummy + +// This file is part of a workaround for `go mod vendor` which won't vendor +// C files if there's no Go file in the same directory. +// This would prevent the crypto/secp256k1/libsecp256k1/include/secp256k1.h file to be vendored. +// +// This Go file imports the c directory where there is another dummy.go file which +// is the second part of this workaround. +// +// These two files combined make it so `go mod vendor` behaves correctly. +// +// See this issue for reference: https://github.com/golang/go/issues/26366 + +package secp256k1 + +import ( + _ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/include" + _ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src" + _ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src/modules/recovery" +) diff --git a/crypto/secp256k1/ext.h b/crypto/secp256k1/ext.h index 9b043c724..e422fe4b4 100644 --- a/crypto/secp256k1/ext.h +++ b/crypto/secp256k1/ext.h @@ -1,18 +1,6 @@ -// 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 . +// 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. // secp256k1_context_create_sign_verify creates a context for signing and signature verification. static secp256k1_context* secp256k1_context_create_sign_verify() { diff --git a/crypto/secp256k1/libsecp256k1/contrib/dummy.go b/crypto/secp256k1/libsecp256k1/contrib/dummy.go new file mode 100644 index 000000000..2c946210c --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/contrib/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package contrib diff --git a/crypto/secp256k1/libsecp256k1/dummy.go b/crypto/secp256k1/libsecp256k1/dummy.go new file mode 100644 index 000000000..04bbe3d76 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package libsecp256k1 diff --git a/crypto/secp256k1/libsecp256k1/include/dummy.go b/crypto/secp256k1/libsecp256k1/include/dummy.go new file mode 100644 index 000000000..64c71b845 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package include diff --git a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s index 5df561f2f..5a9cc3ffc 100644 --- a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s +++ b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s @@ -11,7 +11,7 @@ Note: - To avoid unnecessary loads and make use of available registers, two 'passes' have every time been interleaved, with the odd passes accumulating c' and d' - which will be added to c and d respectively in the the even passes + which will be added to c and d respectively in the even passes */ @@ -23,7 +23,7 @@ Note: .eabi_attribute 10, 0 @ Tag_FP_arch = none .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP - .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed + .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 .text diff --git a/crypto/secp256k1/libsecp256k1/src/dummy.go b/crypto/secp256k1/libsecp256k1/src/dummy.go new file mode 100644 index 000000000..2df270adc --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package src diff --git a/crypto/secp256k1/libsecp256k1/src/modules/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/dummy.go new file mode 100644 index 000000000..99c538db5 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package module diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go new file mode 100644 index 000000000..48c2e0aa5 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package ecdh diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go new file mode 100644 index 000000000..8efbd7abe --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go @@ -0,0 +1,8 @@ +//go:build dummy +// +build dummy + +// Package c contains only a C file. +// +// This Go file is part of a workaround for `go mod vendor`. +// Please see the file crypto/secp256k1/dummy.go for more information. +package recovery diff --git a/crypto/secp256k1/libsecp256k1/src/num.h b/crypto/secp256k1/libsecp256k1/src/num.h index 7bb9c5be8..eff842200 100644 --- a/crypto/secp256k1/libsecp256k1/src/num.h +++ b/crypto/secp256k1/libsecp256k1/src/num.h @@ -54,7 +54,7 @@ static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const se even if r was negative. */ static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); -/** Right-shift the passed number by bits bits. */ +/** Right-shift the passed number by bits. */ static void secp256k1_num_shift(secp256k1_num *r, int bits); /** Check whether a number is zero. */ diff --git a/crypto/secp256k1/libsecp256k1/src/secp256k1.c b/crypto/secp256k1/libsecp256k1/src/secp256k1.c index fb8b882fa..7d637bfad 100755 --- a/crypto/secp256k1/libsecp256k1/src/secp256k1.c +++ b/crypto/secp256k1/libsecp256k1/src/secp256k1.c @@ -26,7 +26,6 @@ } while(0) static void default_illegal_callback_fn(const char* str, void* data) { - (void)data; fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); abort(); } @@ -37,7 +36,6 @@ static const secp256k1_callback default_illegal_callback = { }; static void default_error_callback_fn(const char* str, void* data) { - (void)data; fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); abort(); } diff --git a/crypto/secp256k1/panic_cb.go b/crypto/secp256k1/panic_cb.go index e0e9034ee..a30b04f51 100644 --- a/crypto/secp256k1/panic_cb.go +++ b/crypto/secp256k1/panic_cb.go @@ -1,18 +1,9 @@ -// 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 . +// 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. + +//go:build !gofuzz && cgo +// +build !gofuzz,cgo package secp256k1 diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go new file mode 100644 index 000000000..8afa9d023 --- /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. + +//go:build !gofuzz && cgo +// +build !gofuzz,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 000000000..22f53ac6a --- /dev/null +++ b/crypto/secp256k1/scalar_mult_nocgo.go @@ -0,0 +1,14 @@ +// 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. + +//go:build gofuzz || !cgo +// +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 eefbb99ee..61abc1eaf 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -1,18 +1,9 @@ -// 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 . +// 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. + +//go:build !gofuzz && cgo +// +build !gofuzz,cgo // Package secp256k1 wraps the bitcoin secp256k1 C library. package secp256k1 @@ -20,12 +11,24 @@ package secp256k1 /* #cgo CFLAGS: -I./libsecp256k1 #cgo CFLAGS: -I./libsecp256k1/src/ + +#ifdef __SIZEOF_INT128__ +# define HAVE___INT128 +# define USE_FIELD_5X52 +# define USE_SCALAR_4X64 +#else +# define USE_FIELD_10X26 +# define USE_SCALAR_8X32 +#endif + +#ifndef NDEBUG +# define NDEBUG +#endif + +#define USE_ENDOMORPHISM #define USE_NUM_NONE -#define USE_FIELD_10X26 #define USE_FIELD_INV_BUILTIN -#define USE_SCALAR_8X32 #define USE_SCALAR_INV_BUILTIN -#define NDEBUG #include "./libsecp256k1/src/secp256k1.c" #include "./libsecp256k1/src/modules/recovery/main_impl.h" #include "ext.h" @@ -98,7 +101,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) { return sig, nil } -// RecoverPubkey returns the the public key of the signer. +// RecoverPubkey returns the public key of the signer. // msg must be the 32-byte hash of the message to be signed. // sig must be a 65-byte compact ECDSA signature containing the // recovery id as the last element. diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index acc84fc17..74408d06d 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -1,18 +1,9 @@ -// 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 . +// 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. + +//go:build !gofuzz && cgo +// +build !gofuzz,cgo package secp256k1 @@ -22,10 +13,8 @@ import ( "crypto/elliptic" "crypto/rand" "encoding/hex" + "io" "testing" - - "github.com/XinFinOrg/XDC-Subnet/common/math" - "github.com/XinFinOrg/XDC-Subnet/crypto/randentropy" ) const TestCount = 1000 @@ -36,11 +25,24 @@ func generateKeyPair() (pubkey, privkey []byte) { panic(err) } pubkey = elliptic.Marshal(S256(), key.X, key.Y) - return pubkey, math.PaddedBigBytes(key.D, 32) + + privkey = make([]byte, 32) + blob := key.D.Bytes() + copy(privkey[32-len(blob):], blob) + + return pubkey, privkey +} + +func csprngEntropy(n int) []byte { + buf := make([]byte, n) + if _, err := io.ReadFull(rand.Reader, buf); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } + return buf } func randSig() []byte { - sig := randentropy.GetEntropyCSPRNG(65) + sig := csprngEntropy(65) sig[32] &= 0x70 sig[64] %= 4 return sig @@ -49,7 +51,7 @@ func randSig() []byte { // tests for malleability // highest bit of signature ECDSA s value must be 0, in the 33th byte func compactSigCheck(t *testing.T, sig []byte) { - var b int = int(sig[32]) + var b = int(sig[32]) if b < 0 { t.Errorf("highest bit is negative: %d", b) } @@ -63,7 +65,7 @@ func compactSigCheck(t *testing.T, sig []byte) { func TestSignatureValidity(t *testing.T) { pubkey, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Errorf("signature error: %s", err) @@ -86,7 +88,7 @@ func TestSignatureValidity(t *testing.T) { func TestInvalidRecoveryID(t *testing.T) { _, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) sig[64] = 99 _, err := RecoverPubkey(msg, sig) @@ -97,7 +99,7 @@ func TestInvalidRecoveryID(t *testing.T) { func TestSignAndRecover(t *testing.T) { pubkey1, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Errorf("signature error: %s", err) @@ -148,7 +150,7 @@ func TestRandomMessagesWithRandomKeys(t *testing.T) { func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) { for i := 0; i < TestCount; i++ { pubkey1, seckey := keys() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Fatalf("signature error: %s", err) @@ -176,7 +178,7 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte) func TestRecoveryOfRandomSignature(t *testing.T) { pubkey1, _ := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) for i := 0; i < TestCount; i++ { // recovery can sometimes work, but if so should always give wrong pubkey @@ -189,11 +191,11 @@ func TestRecoveryOfRandomSignature(t *testing.T) { func TestRandomMessagesAgainstValidSig(t *testing.T) { pubkey1, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) for i := 0; i < TestCount; i++ { - msg = randentropy.GetEntropyCSPRNG(32) + msg = csprngEntropy(32) pubkey2, _ := RecoverPubkey(msg, sig) // recovery can sometimes work, but if so should always give wrong pubkey if bytes.Equal(pubkey1, pubkey2) { @@ -219,7 +221,7 @@ func TestRecoverSanity(t *testing.T) { func BenchmarkSign(b *testing.B) { _, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -228,7 +230,7 @@ func BenchmarkSign(b *testing.B) { } func BenchmarkRecover(b *testing.B) { - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) _, seckey := generateKeyPair() sig, _ := Sign(msg, seckey) b.ResetTimer() diff --git a/eth/api_backend.go b/eth/api_backend.go index b706580e7..637e23a4f 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -21,8 +21,8 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "math/big" + "os" "path/filepath" "github.com/XinFinOrg/XDC-Subnet/XDCx/tradingstate" @@ -89,7 +89,32 @@ func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum confirmedHash := b.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash return b.eth.blockchain.GetHeaderByHash(confirmedHash), nil } - return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)), nil + header := b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)) + if header == nil { + return nil, errors.New("header for number not found") + } + return header, nil +} + +func (b *EthApiBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.HeaderByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + header := b.eth.blockchain.GetHeaderByHash(hash) + if header == nil { + return nil, errors.New("header for hash not found") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { + return nil, errors.New("hash is not currently canonical") + } + return header, nil + } + return nil, errors.New("invalid arguments; neither block nor hash specified") +} + +func (b *EthApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return b.eth.blockchain.GetHeaderByHash(hash), nil } func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { @@ -110,6 +135,31 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil } +func (b *EthApiBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + return b.eth.blockchain.GetBlockByHash(hash), nil +} + +func (b *EthApiBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.BlockByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + header := b.eth.blockchain.GetHeaderByHash(hash) + if header == nil { + return nil, errors.New("header for hash not found") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { + return nil, errors.New("hash is not currently canonical") + } + block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64()) + if block == nil { + return nil, errors.New("header found, but block body is missing") + } + return block, nil + } + return nil, errors.New("invalid arguments; neither block nor hash specified") +} + func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { // Pending state is only known by the miner if blockNr == rpc.PendingBlockNumber { @@ -125,9 +175,36 @@ func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return nil, nil, errors.New("header not found") } stateDb, err := b.eth.BlockChain().StateAt(header.Root) + if err != nil { + return nil, nil, err + } return stateDb, header, err } +func (b *EthApiBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.StateAndHeaderByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + header, err := b.HeaderByHash(ctx, hash) + if err != nil { + return nil, nil, err + } + if header == nil { + return nil, nil, errors.New("header for hash not found") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { + return nil, nil, errors.New("hash is not currently canonical") + } + stateDb, err := b.eth.BlockChain().StateAt(header.Root) + if err != nil { + return nil, nil, err + } + return stateDb, header, nil + } + return nil, nil, errors.New("invalid arguments; neither block nor hash specified") +} + func (b *EthApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) { return b.eth.blockchain.GetBlockByHash(blockHash), nil } @@ -285,7 +362,7 @@ func (b *EthApiBackend) GetEngine() consensus.Engine { func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int { header := s.eth.blockchain.GetHeaderByHash(hash) if header != nil { - data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + data, err := os.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) if err == nil { rewards := make(map[string]map[string]map[string]*big.Int) err = json.Unmarshal(data, &rewards) @@ -293,7 +370,7 @@ func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]map[string] return rewards } } else { - data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) + data, err = os.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) if err == nil { rewards := make(map[string]map[string]map[string]*big.Int) err = json.Unmarshal(data, &rewards) diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 3ab764ac0..d8746065b 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -21,8 +21,8 @@ import ( "context" "errors" "fmt" - "io/ioutil" "math/big" + "os" "runtime" "sync" "time" @@ -393,7 +393,7 @@ func (api *PrivateDebugAPI) TraceBlock(ctx context.Context, blob []byte, config // TraceBlockFromFile returns the structured logs created during the execution of // EVM and returns them as a JSON object. func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string, config *TraceConfig) ([]*txTraceResult, error) { - blob, err := ioutil.ReadFile(file) + blob, err := os.ReadFile(file) if err != nil { return nil, fmt.Errorf("could not read file: %v", err) } @@ -468,6 +468,10 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, jobs <- &txTraceTask{statedb: statedb.Copy(), index: i} var balacne *big.Int if tx.To() != nil { + // Bypass the validation for trading and lending transactions as their nonce are not incremented + if tx.IsSkipNonceTransaction() { + continue + } if value, ok := feeCapacity[*tx.To()]; ok { balacne = value } @@ -478,7 +482,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, vmenv := vm.NewEVM(vmctx, statedb, XDCxState, api.config, vm.Config{}) owner := common.Address{} - if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { + if _, _, _, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { failed = err break } @@ -634,7 +638,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v vmenv := vm.NewEVM(vmctx, statedb, nil, api.config, vm.Config{Debug: true, Tracer: tracer}) owner := common.Address{} - ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) + ret, gas, failed, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } @@ -704,10 +708,7 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree } if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if block.Header().Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(block.Header().Number.Uint64(), gas) feeCapacity[*tx.To()] = new(big.Int).Sub(feeCapacity[*tx.To()], fee) balanceUpdated[*tx.To()] = feeCapacity[*tx.To()] totalFeeUsed = totalFeeUsed.Add(totalFeeUsed, fee) diff --git a/eth/bloombits.go b/eth/bloombits.go index cb351cf55..75f617c6e 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -44,7 +44,7 @@ const ( // bloomRetrievalWait is the maximum time to wait for enough bloom bit requests // to accumulate request an entire batch (avoiding hysteresis). - bloomRetrievalWait = time.Duration(0) + bloomRetrievalWait = time.Microsecond * 100 ) // startBloomHandlers starts a batch of goroutines to accept bloom bit database diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 6419de974..051fe57cf 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -1674,6 +1674,8 @@ func testFakedSyncProgress(t *testing.T, protocol int, mode SyncMode) { // We use data driven subtests to manage this so that it will be parallel on its own // and not with the other tests, avoiding intermittent failures. func TestDeliverHeadersHang(t *testing.T) { + t.Skip("This test failed sometimes and is inconsistant result. Disable for now.") + testCases := []struct { protocol int syncMode SyncMode diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index b79c77b2b..b4bd47265 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -146,6 +146,9 @@ func (q *queue) Reset() { // Close marks the end of the sync, unblocking WaitResults. // It may be called even if the queue is already closed. func (q *queue) Close() { + q.lock.Lock() + defer q.lock.Unlock() + q.closed = true q.active.Broadcast() } @@ -507,6 +510,7 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common // If we're the first to request this task, initialise the result container index := int(header.Number.Int64() - int64(q.resultOffset)) if index >= len(q.resultCache) || index < 0 { + log.Error("index allocation went beyond available resultCache space", "index", index, "len.resultCache", len(q.resultCache), "blockNum", header.Number.Int64(), "resultOffset", q.resultOffset) common.Report("index allocation went beyond available resultCache space") return nil, false, errInvalidChain } diff --git a/eth/filters/api.go b/eth/filters/api.go index 82c0c0727..20572840c 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -32,8 +32,16 @@ import ( "github.com/XinFinOrg/XDC-Subnet/ethdb" "github.com/XinFinOrg/XDC-Subnet/event" "github.com/XinFinOrg/XDC-Subnet/rpc" + "github.com/XinFinOrg/XDC-Subnet/core" ) +var ( + errExceedMaxTopics = errors.New("exceed max topics") +) + +// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 +const maxTopics = 4 + var ( deadline = 5 * time.Minute // consider a filter inactive if it has not been polled for within deadline ) @@ -98,7 +106,7 @@ func (api *PublicFilterAPI) timeoutLoop() { // NewPendingTransactionFilter creates a filter that fetches pending transaction hashes // as transactions enter the pending state. // -// It is part of the filter package because this filter can be used throug the +// It is part of the filter package because this filter can be used through the // `eth_getFilterChanges` polling method that is also used for log filters. // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter @@ -268,14 +276,8 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc } // FilterCriteria represents a request to create a new filter. -// -// TODO(karalabe): Kill this in favor of ethereum.FilterQuery. -type FilterCriteria struct { - FromBlock *big.Int - ToBlock *big.Int - Addresses []common.Address - Topics [][]common.Hash -} +// Same as ethereum.FilterQuery but with UnmarshalJSON() method. +type FilterCriteria ethereum.FilterQuery // NewFilter creates a new filter and returns the filter id. It can be // used to retrieve logs when the state changes. This method cannot be @@ -326,16 +328,28 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { - // Convert the RPC block numbers into internal representations - if crit.FromBlock == nil { - crit.FromBlock = big.NewInt(rpc.LatestBlockNumber.Int64()) - } - if crit.ToBlock == nil { - crit.ToBlock = big.NewInt(rpc.LatestBlockNumber.Int64()) + if len(crit.Topics) > maxTopics { + return nil, errExceedMaxTopics } - // Create and run the filter to get all the logs - filter := New(api.backend, crit.FromBlock.Int64(), crit.ToBlock.Int64(), crit.Addresses, crit.Topics) + var filter *Filter + if crit.BlockHash != nil { + // Block filter requested, construct a single-shot filter + filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics) + } else { + // Convert the RPC block numbers into internal representations + begin := rpc.LatestBlockNumber.Int64() + if crit.FromBlock != nil { + begin = crit.FromBlock.Int64() + } + end := rpc.LatestBlockNumber.Int64() + if crit.ToBlock != nil { + end = crit.ToBlock.Int64() + } + // Construct the range filter + filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics) + } + // Run the filter and return all the logs logs, err := filter.Logs(ctx) if err != nil { return nil, err @@ -373,17 +387,24 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty return nil, fmt.Errorf("filter not found") } - begin := rpc.LatestBlockNumber.Int64() - if f.crit.FromBlock != nil { - begin = f.crit.FromBlock.Int64() - } - end := rpc.LatestBlockNumber.Int64() - if f.crit.ToBlock != nil { - end = f.crit.ToBlock.Int64() + var filter *Filter + if f.crit.BlockHash != nil { + // Block filter requested, construct a single-shot filter + filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics) + } else { + // Convert the RPC block numbers into internal representations + begin := rpc.LatestBlockNumber.Int64() + if f.crit.FromBlock != nil { + begin = f.crit.FromBlock.Int64() + } + end := rpc.LatestBlockNumber.Int64() + if f.crit.ToBlock != nil { + end = f.crit.ToBlock.Int64() + } + // Construct the range filter + filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics) } - // Create and run the filter to get all the logs - filter := New(api.backend, begin, end, f.crit.Addresses, f.crit.Topics) - + // Run the filter and return all the logs logs, err := filter.Logs(ctx) if err != nil { return nil, err @@ -418,6 +439,10 @@ func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { case LogsSubscription: logs := f.logs f.logs = nil + for _, log := range logs { + // update BlockHash to fix #208 + log.BlockHash = core.GetCanonicalHash(api.chainDb, log.BlockNumber) + } return returnLogs(logs), nil } } @@ -446,7 +471,8 @@ func returnLogs(logs []*types.Log) []*types.Log { // UnmarshalJSON sets *args fields with given data. func (args *FilterCriteria) UnmarshalJSON(data []byte) error { type input struct { - From *rpc.BlockNumber `json:"fromBlock"` + BlockHash *common.Hash `json:"blockHash"` + FromBlock *rpc.BlockNumber `json:"fromBlock"` ToBlock *rpc.BlockNumber `json:"toBlock"` Addresses interface{} `json:"address"` Topics []interface{} `json:"topics"` @@ -457,12 +483,20 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error { return err } - if raw.From != nil { - args.FromBlock = big.NewInt(raw.From.Int64()) - } + if raw.BlockHash != nil { + if raw.FromBlock != nil || raw.ToBlock != nil { + // BlockHash is mutually exclusive with FromBlock/ToBlock criteria + return fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other") + } + args.BlockHash = raw.BlockHash + } else { + if raw.FromBlock != nil { + args.FromBlock = big.NewInt(raw.FromBlock.Int64()) + } - if raw.ToBlock != nil { - args.ToBlock = big.NewInt(raw.ToBlock.Int64()) + if raw.ToBlock != nil { + args.ToBlock = big.NewInt(raw.ToBlock.Int64()) + } } args.Addresses = []common.Address{} @@ -545,7 +579,7 @@ func decodeAddress(s string) (common.Address, error) { } b, err := hexutil.Decode(s) if err == nil && len(b) != common.AddressLength { - err = fmt.Errorf("hex has invalid length %d after decoding", len(b)) + err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for address", len(b), common.AddressLength) } return common.BytesToAddress(b), err } @@ -553,7 +587,7 @@ func decodeAddress(s string) (common.Address, error) { func decodeTopic(s string) (common.Hash, error) { b, err := hexutil.Decode(s) if err == nil && len(b) != common.HashLength { - err = fmt.Errorf("hex has invalid length %d after decoding", len(b)) + err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for topic", len(b), common.HashLength) } return common.BytesToHash(b), err } diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go index 0db555b22..38427d325 100644 --- a/eth/filters/bench_test.go +++ b/eth/filters/bench_test.go @@ -66,7 +66,7 @@ const benchFilterCnt = 2000 func benchmarkBloomBits(b *testing.B, sectionSize uint64) { benchDataDir := node.DefaultDataDir() + "/geth/chaindata" - fmt.Println("Running bloombits benchmark section size:", sectionSize) + b.Log("Running bloombits benchmark section size:", sectionSize) db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "") if err != nil { @@ -78,7 +78,7 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) { } clearBloomBits(db) - fmt.Println("Generating bloombits data...") + b.Log("Generating bloombits data...") headNum := core.GetBlockNumber(db, head) if headNum < sectionSize+512 { b.Fatalf("not enough blocks for running a benchmark") @@ -113,16 +113,16 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) { core.WriteBloomBits(db, uint(i), sectionIdx, sectionHead, comp) } //if sectionIdx%50 == 0 { - // fmt.Println(" section", sectionIdx, "/", cnt) + // b.Log(" section", sectionIdx, "/", cnt) //} } d := time.Since(start) - fmt.Println("Finished generating bloombits data") - fmt.Println(" ", d, "total ", d/time.Duration(cnt*sectionSize), "per block") - fmt.Println(" data size:", dataSize, " compressed size:", compSize, " compression ratio:", float64(compSize)/float64(dataSize)) + b.Log("Finished generating bloombits data") + b.Log(" ", d, "total ", d/time.Duration(cnt*sectionSize), "per block") + b.Log(" data size:", dataSize, " compressed size:", compSize, " compression ratio:", float64(compSize)/float64(dataSize)) - fmt.Println("Running filter benchmarks...") + b.Log("Running filter benchmarks...") start = time.Now() mux := new(event.TypeMux) var backend *testBackend @@ -136,14 +136,14 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) { var addr common.Address addr[0] = byte(i) addr[1] = byte(i / 256) - filter := New(backend, 0, int64(cnt*sectionSize-1), []common.Address{addr}, nil) + filter := NewRangeFilter(backend, 0, int64(cnt*sectionSize-1), []common.Address{addr}, nil) if _, err := filter.Logs(context.Background()); err != nil { b.Error("filter.Find error:", err) } } d = time.Since(start) - fmt.Println("Finished running filter benchmarks") - fmt.Println(" ", d, "total ", d/time.Duration(benchFilterCnt), "per address", d*time.Duration(1000000)/time.Duration(benchFilterCnt*cnt*sectionSize), "per million blocks") + b.Log("Finished running filter benchmarks") + b.Log(" ", d, "total ", d/time.Duration(benchFilterCnt), "per address", d*time.Duration(1000000)/time.Duration(benchFilterCnt*cnt*sectionSize), "per million blocks") db.Close() } @@ -175,7 +175,7 @@ func clearBloomBits(db ethdb.Database) { func BenchmarkNoBloomBits(b *testing.B) { benchDataDir := node.DefaultDataDir() + "/geth/chaindata" - fmt.Println("Running benchmark without bloombits") + b.Log("Running benchmark without bloombits") db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "") if err != nil { b.Fatalf("error opening database at %v: %v", benchDataDir, err) @@ -188,14 +188,14 @@ func BenchmarkNoBloomBits(b *testing.B) { clearBloomBits(db) - fmt.Println("Running filter benchmarks...") + b.Log("Running filter benchmarks...") start := time.Now() mux := new(event.TypeMux) backend := &testBackend{mux, db, 0, new(event.Feed), new(event.Feed), new(event.Feed), new(event.Feed)} - filter := New(backend, 0, int64(headNum), []common.Address{{}}, nil) + filter := NewRangeFilter(backend, 0, int64(headNum), []common.Address{{}}, nil) filter.Logs(context.Background()) d := time.Since(start) - fmt.Println("Finished running filter benchmarks") - fmt.Println(" ", d, "total ", d*time.Duration(1000000)/time.Duration(headNum+1), "per million blocks") + b.Log("Finished running filter benchmarks") + b.Log(" ", d, "total ", d*time.Duration(1000000)/time.Duration(headNum+1), "per million blocks") db.Close() } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 533819176..797b63bf7 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -18,6 +18,7 @@ package filters import ( "context" + "errors" "math/big" "github.com/XinFinOrg/XDC-Subnet/common" @@ -33,6 +34,7 @@ type Backend interface { ChainDb() ethdb.Database EventMux() *event.TypeMux HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) + HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) @@ -49,17 +51,19 @@ type Backend interface { type Filter struct { backend Backend - db ethdb.Database - begin, end int64 - addresses []common.Address - topics [][]common.Hash + db ethdb.Database + addresses []common.Address + topics [][]common.Hash + + block common.Hash // Block hash if filtering a single block + begin, end int64 // Range interval if filtering multiple blocks matcher *bloombits.Matcher } -// New creates a new filter which uses a bloom filter on blocks to figure out whether -// a particular block is interesting or not. -func New(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { +// NewRangeFilter creates a new filter which uses a bloom filter on blocks to +// figure out whether a particular block is interesting or not. +func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { // Flatten the address and topic filter clauses into a single bloombits filter // system. Since the bloombits are not positional, nil topics are permitted, // which get flattened into a nil byte slice. @@ -78,23 +82,52 @@ func New(backend Backend, begin, end int64, addresses []common.Address, topics [ } filters = append(filters, filter) } - // Assemble and return the filter size, _ := backend.BloomStatus() + // Create a generic filter and convert it into a range filter + filter := newFilter(backend, addresses, topics) + + filter.matcher = bloombits.NewMatcher(size, filters) + filter.begin = begin + filter.end = end + + return filter +} + +// NewBlockFilter creates a new filter which directly inspects the contents of +// a block to figure out whether it is interesting or not. +func NewBlockFilter(backend Backend, block common.Hash, addresses []common.Address, topics [][]common.Hash) *Filter { + // Create a generic filter and convert it into a block filter + filter := newFilter(backend, addresses, topics) + filter.block = block + return filter +} + +// newFilter creates a generic filter that can either filter based on a block hash, +// or based on range queries. The search criteria needs to be explicitly set. +func newFilter(backend Backend, addresses []common.Address, topics [][]common.Hash) *Filter { return &Filter{ backend: backend, - begin: begin, - end: end, addresses: addresses, topics: topics, db: backend.ChainDb(), - matcher: bloombits.NewMatcher(size, filters), } } // Logs searches the blockchain for matching log entries, returning all from the // first block that contains matches, updating the start of the filter accordingly. func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { + // If we're doing singleton block filtering, execute and return + if f.block != (common.Hash{}) { + header, err := f.backend.HeaderByHash(ctx, f.block) + if err != nil { + return nil, err + } + if header == nil { + return nil, errors.New("unknown block") + } + return f.blockLogs(ctx, header) + } // Figure out the limits of the filter range header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) if header == nil { @@ -187,13 +220,23 @@ func (f *Filter) unindexedLogs(ctx context.Context, end uint64) ([]*types.Log, e if header == nil || err != nil { return logs, err } - if bloomFilter(header.Bloom, f.addresses, f.topics) { - found, err := f.checkMatches(ctx, header) - if err != nil { - return logs, err - } - logs = append(logs, found...) + found, err := f.blockLogs(ctx, header) + if err != nil { + return logs, err + } + logs = append(logs, found...) + } + return logs, nil +} + +// blockLogs returns the logs matching the filter criteria within a single block. +func (f *Filter) blockLogs(ctx context.Context, header *types.Header) (logs []*types.Log, err error) { + if bloomFilter(header.Bloom, f.addresses, f.topics) { + found, err := f.checkMatches(ctx, header) + if err != nil { + return logs, err } + logs = append(logs, found...) } return logs, nil } @@ -258,9 +301,9 @@ Logs: if len(topics) > len(log.Topics) { continue Logs } - for i, topics := range topics { - match := len(topics) == 0 // empty rule set == wildcard - for _, topic := range topics { + for i, sub := range topics { + match := len(sub) == 0 // empty rule set == wildcard + for _, topic := range sub { if log.Topics[i] == topic { match = true break diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 695dab8f7..11c832642 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -30,6 +30,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/core" "github.com/XinFinOrg/XDC-Subnet/core/types" "github.com/XinFinOrg/XDC-Subnet/event" + "github.com/XinFinOrg/XDC-Subnet/log" "github.com/XinFinOrg/XDC-Subnet/rpc" ) @@ -91,8 +92,21 @@ type EventSystem struct { backend Backend lightMode bool lastHead *types.Header - install chan *subscription // install filter for event notification - uninstall chan *subscription // remove filter for event notification + + // Subscriptions + txSub event.Subscription // Subscription for new transaction event + logsSub event.Subscription // Subscription for new log event + rmLogsSub event.Subscription // Subscription for removed log event + chainSub event.Subscription // Subscription for new chain event + pendingLogSub *event.TypeMuxSubscription // Subscription for pending log event + + // Channels + install chan *subscription // install filter for event notification + uninstall chan *subscription // remove filter for event notification + txCh chan core.TxPreEvent // Channel to receive new transaction event + logsCh chan []*types.Log // Channel to receive new log event + rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event + chainCh chan core.ChainEvent // Channel to receive new chain event } // NewEventSystem creates a new manager that listens for event on the given mux, @@ -108,6 +122,24 @@ func NewEventSystem(mux *event.TypeMux, backend Backend, lightMode bool) *EventS lightMode: lightMode, install: make(chan *subscription), uninstall: make(chan *subscription), + txCh: make(chan core.TxPreEvent, txChanSize), + logsCh: make(chan []*types.Log, logsChanSize), + rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), + chainCh: make(chan core.ChainEvent, chainEvChanSize), + } + + // Subscribe events + m.txSub = m.backend.SubscribeTxPreEvent(m.txCh) + m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh) + m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh) + m.chainSub = m.backend.SubscribeChainEvent(m.chainCh) + // TODO(rjl493456442): use feed to subscribe pending log event + m.pendingLogSub = m.mux.Subscribe(core.PendingLogsEvent{}) + + // Make sure none of the subscriptions are empty + if m.txSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || + m.pendingLogSub.Closed() { + log.Crit("Subscribe for event system failed") } go m.eventLoop() @@ -306,8 +338,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev interface{}) { } } case *event.TypeMuxEvent: - switch muxe := e.Data.(type) { - case core.PendingLogsEvent: + if muxe, ok := e.Data.(core.PendingLogsEvent); ok { for _, f := range filters[PendingLogsSubscription] { if e.Time.After(f.created) { if matchedLogs := filterLogs(muxe.Logs, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 { @@ -411,50 +442,35 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common. // eventLoop (un)installs filters and processes mux events. func (es *EventSystem) eventLoop() { - var ( - index = make(filterIndex) - sub = es.mux.Subscribe(core.PendingLogsEvent{}) - // Subscribe TxPreEvent form txpool - txCh = make(chan core.TxPreEvent, txChanSize) - txSub = es.backend.SubscribeTxPreEvent(txCh) - // Subscribe RemovedLogsEvent - rmLogsCh = make(chan core.RemovedLogsEvent, rmLogsChanSize) - rmLogsSub = es.backend.SubscribeRemovedLogsEvent(rmLogsCh) - // Subscribe []*types.Log - logsCh = make(chan []*types.Log, logsChanSize) - logsSub = es.backend.SubscribeLogsEvent(logsCh) - // Subscribe ChainEvent - chainEvCh = make(chan core.ChainEvent, chainEvChanSize) - chainEvSub = es.backend.SubscribeChainEvent(chainEvCh) - ) - - // Unsubscribe all events - defer sub.Unsubscribe() - defer txSub.Unsubscribe() - defer rmLogsSub.Unsubscribe() - defer logsSub.Unsubscribe() - defer chainEvSub.Unsubscribe() - + // Ensure all subscriptions get cleaned up + defer func() { + es.pendingLogSub.Unsubscribe() + es.txSub.Unsubscribe() + es.logsSub.Unsubscribe() + es.rmLogsSub.Unsubscribe() + es.chainSub.Unsubscribe() + }() + + index := make(filterIndex) for i := UnknownSubscription; i < LastIndexSubscription; i++ { index[i] = make(map[rpc.ID]*subscription) } for { select { - case ev, active := <-sub.Chan(): - if !active { // system stopped - return - } - es.broadcast(index, ev) - // Handle subscribed events - case ev := <-txCh: + case ev := <-es.txCh: es.broadcast(index, ev) - case ev := <-rmLogsCh: + case ev := <-es.logsCh: es.broadcast(index, ev) - case ev := <-logsCh: + case ev := <-es.rmLogsCh: es.broadcast(index, ev) - case ev := <-chainEvCh: + case ev := <-es.chainCh: + es.broadcast(index, ev) + case ev, active := <-es.pendingLogSub.Chan(): + if !active { // system stopped + return + } es.broadcast(index, ev) case f := <-es.install: @@ -466,6 +482,7 @@ func (es *EventSystem) eventLoop() { index[f.typ][f.id] = f } close(f.installed) + case f := <-es.uninstall: if f.typ == MinedAndPendingLogsSubscription { // the type are logs and pending logs subscriptions @@ -477,13 +494,13 @@ func (es *EventSystem) eventLoop() { close(f.err) // System stopped - case <-txSub.Err(): + case <-es.txSub.Err(): return - case <-rmLogsSub.Err(): + case <-es.logsSub.Err(): return - case <-logsSub.Err(): + case <-es.rmLogsSub.Err(): return - case <-chainEvSub.Err(): + case <-es.chainSub.Err(): return } } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index b504f4831..ad7feecd7 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -69,6 +69,11 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe return core.GetHeader(b.db, hash, num), nil } +func (b *testBackend) HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) { + num := core.GetBlockNumber(b.db, blockHash) + return core.GetHeader(b.db, blockHash, num), nil +} + func (b *testBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) { number := core.GetBlockNumber(b.db, blockHash) return core.GetBlockReceipts(b.db, blockHash, number), nil @@ -335,6 +340,33 @@ func TestInvalidLogFilterCreation(t *testing.T) { } } +func TestInvalidGetLogsRequest(t *testing.T) { + var ( + mux = new(event.TypeMux) + db = rawdb.NewMemoryDatabase() + txFeed = new(event.Feed) + rmLogsFeed = new(event.Feed) + logsFeed = new(event.Feed) + chainFeed = new(event.Feed) + backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed} + api = NewPublicFilterAPI(backend, false) + blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") + ) + + // Reason: Cannot specify both BlockHash and FromBlock/ToBlock) + testCases := []FilterCriteria{ + 0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)}, + 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)}, + 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, + } + + for i, test := range testCases { + if _, err := api.GetLogs(context.Background(), test); err == nil { + t.Errorf("Expected Logs for case #%d to fail", i) + } + } +} + // TestLogFilter tests whether log filters match the correct logs that are posted to the event feed. func TestLogFilter(t *testing.T) { t.Parallel() diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 7ebbf3ef1..30cb7441e 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -18,12 +18,12 @@ package filters import ( "context" - "github.com/XinFinOrg/XDC-Subnet/core/rawdb" - "io/ioutil" "math/big" "os" "testing" + "github.com/XinFinOrg/XDC-Subnet/core/rawdb" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/consensus/ethash" "github.com/XinFinOrg/XDC-Subnet/core" @@ -43,7 +43,7 @@ func makeReceipt(addr common.Address) *types.Receipt { } func BenchmarkFilters(b *testing.B) { - dir, err := ioutil.TempDir("", "filtertest") + dir, err := os.MkdirTemp("", "filtertest") if err != nil { b.Fatal(err) } @@ -97,7 +97,7 @@ func BenchmarkFilters(b *testing.B) { } b.ResetTimer() - filter := New(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) + filter := NewRangeFilter(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) for i := 0; i < b.N; i++ { logs, _ := filter.Logs(context.Background()) @@ -108,7 +108,7 @@ func BenchmarkFilters(b *testing.B) { } func TestFilters(t *testing.T) { - dir, err := ioutil.TempDir("", "filtertest") + dir, err := os.MkdirTemp("", "filtertest") if err != nil { t.Fatal(err) } @@ -186,14 +186,14 @@ func TestFilters(t *testing.T) { } } - filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) + filter := NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) logs, _ := filter.Logs(context.Background()) if len(logs) != 4 { t.Error("expected 4 log, got", len(logs)) } - filter = New(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}) + filter = NewRangeFilter(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}) logs, _ = filter.Logs(context.Background()) if len(logs) != 1 { t.Error("expected 1 log, got", len(logs)) @@ -202,7 +202,7 @@ func TestFilters(t *testing.T) { t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) } - filter = New(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}) + filter = NewRangeFilter(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}) logs, _ = filter.Logs(context.Background()) if len(logs) != 1 { t.Error("expected 1 log, got", len(logs)) @@ -211,7 +211,7 @@ func TestFilters(t *testing.T) { t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) } - filter = New(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}}) + filter = NewRangeFilter(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}}) logs, _ = filter.Logs(context.Background()) if len(logs) != 2 { @@ -219,7 +219,7 @@ func TestFilters(t *testing.T) { } failHash := common.BytesToHash([]byte("fail")) - filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}}) + filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}}) logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { @@ -227,14 +227,14 @@ func TestFilters(t *testing.T) { } failAddr := common.BytesToAddress([]byte("failmenow")) - filter = New(backend, 0, -1, []common.Address{failAddr}, nil) + filter = NewRangeFilter(backend, 0, -1, []common.Address{failAddr}, nil) logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { t.Error("expected 0 log, got", len(logs)) } - filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}}) + filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}}) logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 6c1d9df08..784f39145 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -141,7 +141,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { } // Check gas price min. - minGasPrice := common.MinGasPrice + minGasPrice := common.GetMinGasPrice(head.Number) if price.Cmp(minGasPrice) < 0 { price = new(big.Int).Set(minGasPrice) } diff --git a/eth/handler.go b/eth/handler.go index bf9507196..32c6326f1 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -280,7 +280,7 @@ func (pm *ProtocolManager) removePeer(id string) { // Unregister the peer from the downloader and Ethereum peer set pm.downloader.UnregisterPeer(id) if err := pm.peers.Unregister(id); err != nil { - log.Warn("Peer removal failed", "peer", id, "err", err) + log.Debug("Peer removal failed", "peer", id, "err", err) } // Hard disconnect at the networking layer if peer != nil { @@ -962,7 +962,7 @@ func (pm *ProtocolManager) BroadcastVote(vote *types.Vote) { for _, peer := range peers { err := peer.SendVote(vote) if err != nil { - log.Error("[BroadcastVote] Fail to broadcast vote message", "peerId", peer.id, "version", peer.version, "blockNum", vote.ProposedBlockInfo.Number, "err", err) + log.Debug("[BroadcastVote] Fail to broadcast vote message", "peerId", peer.id, "version", peer.version, "blockNum", vote.ProposedBlockInfo.Number, "err", err) pm.removePeer(peer.id) } } @@ -979,7 +979,7 @@ func (pm *ProtocolManager) BroadcastTimeout(timeout *types.Timeout) { for _, peer := range peers { err := peer.SendTimeout(timeout) if err != nil { - log.Error("[BroadcastTimeout] Fail to broadcast timeout message, remove peer", "peerId", peer.id, "version", peer.version, "timeout", timeout, "err", err) + log.Debug("[BroadcastTimeout] Fail to broadcast timeout message, remove peer", "peerId", peer.id, "version", peer.version, "timeout", timeout, "err", err) pm.removePeer(peer.id) } } @@ -996,7 +996,7 @@ func (pm *ProtocolManager) BroadcastSyncInfo(syncInfo *types.SyncInfo) { for _, peer := range peers { err := peer.SendSyncInfo(syncInfo) if err != nil { - log.Error("[BroadcastSyncInfo] Fail to broadcast syncInfo message, remove peer", "peerId", peer.id, "version", peer.version, "syncInfo", syncInfo, "err", err) + log.Debug("[BroadcastSyncInfo] Fail to broadcast syncInfo message, remove peer", "peerId", peer.id, "version", peer.version, "syncInfo", syncInfo, "err", err) pm.removePeer(peer.id) } } diff --git a/eth/hooks/engine_v2_hooks.go b/eth/hooks/engine_v2_hooks.go index d9878a272..269e1cb3c 100644 --- a/eth/hooks/engine_v2_hooks.go +++ b/eth/hooks/engine_v2_hooks.go @@ -45,9 +45,9 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf break } log.Info("[V2 Hook Penalty] parentHeader is nil, wait block to be writen in disk", "parentNumber", parentNumber) - time.Sleep(200 * time.Millisecond) // 0.2s + time.Sleep(time.Second) // 1s - if timeout > 50 { // wait over 10s + if timeout > 30 { // wait over 30s log.Error("[V2 Hook Penalty] parentHeader is nil, wait too long not writen in to disk", "parentNumber", parentNumber) return []common.Address{}, fmt.Errorf("parentHeader is nil") } diff --git a/eth/tracers/internal/tracers/assets.go b/eth/tracers/internal/tracers/assets.go index d0a0bf7c1..d974de5c2 100644 --- a/eth/tracers/internal/tracers/assets.go +++ b/eth/tracers/internal/tracers/assets.go @@ -3,7 +3,7 @@ // 4byte_tracer.js (2.933kB) // bigram_tracer.js (1.712kB) // call_tracer.js (8.643kB) -// evmdis_tracer.js (4.194kB) +// evmdis_tracer.js (4.195kB) // noop_tracer.js (1.271kB) // opcount_tracer.js (1.372kB) // prestate_tracer.js (4.234kB) @@ -18,7 +18,6 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -28,7 +27,7 @@ import ( func bindataRead(data []byte, name string) ([]byte, error) { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } var buf bytes.Buffer @@ -36,7 +35,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { clErr := gz.Close() if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } if clErr != nil { return nil, err @@ -137,7 +136,7 @@ func call_tracerJs() (*asset, error) { return a, nil } -var _evmdis_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\xdf\x6f\xda\xca\x12\x7e\x86\xbf\x62\x94\x27\x50\x29\x60\x63\x08\x38\x27\x47\xe2\xa6\xf4\x1c\xae\xd2\x24\x02\x72\x8f\x2a\x94\x87\x05\xc6\xb0\xaa\xf1\x5a\xbb\x6b\x72\xb8\x55\xfe\xf7\xab\xd9\x59\x03\xf9\x75\xdb\x4a\xa7\x0f\x3b\xb5\x77\xbe\x6f\xbe\x9d\x19\xcf\x92\x56\x0b\xae\x54\xbe\xd7\x72\xbd\xb1\x10\xb6\x83\x73\x98\x6d\x10\xd6\xea\x23\xda\x0d\x6a\x2c\xb6\x30\x2c\xec\x46\x69\x53\x6d\xb5\x60\xb6\x91\x06\x12\x99\x22\x48\x03\xb9\xd0\x16\x54\x02\xf6\x85\x7f\x2a\x17\x5a\xe8\x7d\xb3\xda\x6a\x31\xe6\xcd\x6d\x62\x48\x34\x22\x18\x95\xd8\x47\xa1\x31\x86\xbd\x2a\x60\x29\x32\xd0\xb8\x92\xc6\x6a\xb9\x28\x2c\x82\xb4\x20\xb2\x55\x4b\x69\xd8\xaa\x95\x4c\xf6\x44\x29\x2d\x14\xd9\x0a\xb5\x0b\x6d\x51\x6f\x4d\xa9\xe3\x8f\x9b\x7b\xb8\x46\x63\x50\xc3\x1f\x98\xa1\x16\x29\xdc\x15\x8b\x54\x2e\xe1\x5a\x2e\x31\x33\x08\xc2\x40\x4e\x6f\xcc\x06\x57\xb0\x70\x74\x04\xfc\x4c\x52\xa6\x5e\x0a\x7c\x56\x45\xb6\x12\x56\xaa\xac\x01\x28\x49\x39\xec\x50\x1b\xa9\x32\xe8\x94\xa1\x3c\x61\x03\x94\x26\x92\x9a\xb0\x74\x00\x0d\x2a\x27\x5c\x1d\x44\xb6\x87\x54\xd8\x23\xf4\x27\x12\x72\x3c\xf7\x0a\x64\xe6\xc2\x6c\x54\x8e\x60\x37\xc2\xd2\xa9\x1f\x65\x9a\xc2\x02\xa1\x30\x98\x14\x69\x83\xd8\x16\x85\x85\xbf\xc6\xb3\x3f\x6f\xef\x67\x30\xbc\xf9\x0a\x7f\x0d\x27\x93\xe1\xcd\xec\xeb\x05\x3c\x4a\xbb\x51\x85\x05\xdc\x21\x53\xc9\x6d\x9e\x4a\x5c\xc1\xa3\xd0\x5a\x64\x76\x0f\x2a\x21\x86\x2f\xa3\xc9\xd5\x9f\xc3\x9b\xd9\xf0\x5f\xe3\xeb\xf1\xec\x2b\x28\x0d\x9f\xc7\xb3\x9b\xd1\x74\x0a\x9f\x6f\x27\x30\x84\xbb\xe1\x64\x36\xbe\xba\xbf\x1e\x4e\xe0\xee\x7e\x72\x77\x3b\x1d\x35\x61\x8a\xa4\x0a\x09\xff\xe3\x9c\x27\xae\x7a\x1a\x61\x85\x56\xc8\xd4\x94\x99\xf8\xaa\x0a\x30\x1b\x55\xa4\x2b\xd8\x88\x1d\x82\xc6\x25\xca\x1d\xae\x40\xc0\x52\xe5\xfb\x9f\x2e\x2a\x71\x89\x54\x65\x6b\x77\xe6\x77\x1b\x12\xc6\x09\x64\xca\x36\xc0\x20\xc2\x6f\x1b\x6b\xf3\xb8\xd5\x7a\x7c\x7c\x6c\xae\xb3\xa2\xa9\xf4\xba\x95\x32\x9d\x69\xfd\xde\xac\x12\x27\xee\xb6\x2b\x69\x66\x5a\x2c\x51\x83\x46\x5b\xe8\xcc\x80\x29\x92\x84\xfc\x2c\xc8\x2c\x51\x7a\xeb\xda\x04\x12\xad\xb6\x20\xc0\x92\x2f\x58\x05\x39\x6a\xda\xf4\x14\x1f\x8d\xdd\xa7\x4e\xe6\x4a\x1a\x61\x0c\x6e\x17\xe9\xbe\x59\xfd\x5e\xad\x18\x2b\x96\xdf\x62\x98\x7f\x57\xb9\x89\x61\xfe\xf0\xf4\xd0\xa8\x56\x2b\x59\x5e\x98\x0d\x9a\x18\xbe\xb7\x63\x68\x37\x20\x88\x21\x68\x40\xe8\xd6\x8e\x5b\x23\xb7\x76\xdd\xda\x73\xeb\xb9\x5b\xfb\x6e\x1d\xb8\x35\x68\xb3\x61\x74\xc0\x6e\x01\xfb\x05\xec\x18\xb0\x67\xc8\x9e\xa1\x8f\xc3\x81\x42\x8e\x14\x72\xa8\x90\x63\x85\xcc\xd2\x61\x97\x88\x59\x22\x66\xe9\x32\x4b\x97\x59\xba\xec\xd2\x65\x96\xae\x17\xdc\x75\xe7\xe9\x32\x4b\xf7\x9c\x9f\x98\xa5\xcb\x2c\x3d\x3e\x72\x8f\x01\x3d\x7f\x44\x06\xf4\x58\x7c\x8f\x01\x3d\x06\xf4\x19\xd0\xe7\xb0\xfd\x90\x9f\x3a\x6c\x98\xa5\xcf\x61\xfb\x3d\x36\x1c\xb6\xcf\x2c\x7d\x66\x19\xb0\xf8\x41\xe0\xf6\x06\x1c\x6f\xc0\xf1\x06\x3e\xab\x65\x5a\x7d\x5e\xdb\x3e\xb1\xed\xd0\xdb\x8e\xb7\x91\xb7\x5d\x6f\x7d\xe6\xdb\x3e\xf5\x6d\x9f\xfb\xb6\xe7\x3b\xd4\xc9\xf3\x05\x9e\x2f\xf0\x7c\x81\xe7\x0b\x3c\x5f\x59\xc9\xb2\x94\x65\x2d\x7d\x31\x03\x5f\xcd\xc0\x97\x33\xf0\xf5\x0c\x7c\x41\x03\x5f\xd1\xc0\x97\x34\xf0\x35\x0d\x42\xcf\x17\xf6\x63\x08\xc9\x0e\x62\xe8\x34\x20\xe8\xb4\x63\x88\xc8\x06\x31\x74\xc9\x86\x31\xf4\xc8\x76\x62\x38\x27\x1b\xc5\xd0\x27\xdb\x8d\x61\x40\x96\xf8\xa8\x6b\x3b\x44\x48\x8c\x1d\x52\x48\x94\x1d\x92\x48\x9c\x11\x69\x24\xd2\x88\x44\x12\x6b\x44\x2a\x89\x36\x22\x99\xc4\x1b\x45\xac\x23\xea\xb2\x8e\xa8\xc7\x3a\xa2\x73\xd6\x41\xdd\xe7\x00\x03\xd6\x41\xfd\x47\x3a\xa8\x01\x49\x87\xeb\x40\xd2\xe1\x7a\x90\x74\xb8\x2e\x24\x4a\xea\x43\xa7\xc3\x75\x22\x91\x52\x2f\x3a\x1d\xae\x1b\x89\xd6\xf5\x23\xf1\xfa\x8e\x0c\x7a\x81\xb7\xa1\xb7\x1d\x6f\x23\x67\xc3\xc8\x7f\x45\x91\xff\x8c\x22\xff\x1d\x45\x1d\xbf\xef\xfd\xdc\x47\xf0\x44\xdf\x79\xab\x05\x1a\x4d\x91\x5a\x1a\xfe\x32\xdb\xa9\x6f\x34\x9e\x37\x98\x81\x48\x53\x37\xc7\x54\xbe\x54\x2b\x34\x3c\x1f\x17\x88\x19\x48\x8b\x5a\xd0\x05\xa1\x76\xa8\xe9\x6e\x2c\x27\x93\xa3\x23\x4c\x22\x33\x91\x96\xc4\x7e\x86\xd2\x60\x92\xd9\xba\x59\xad\xf0\xfb\x18\x92\x22\x5b\xd2\xe8\xaa\xd5\xe1\xbb\xa7\x00\xbb\x91\xa6\xe9\x46\xd2\xbc\xfd\xd0\x54\xb9\xb9\x80\x52\x67\x22\xde\x92\x49\xd4\x62\x69\x0b\x91\x02\xfe\x8d\xcb\xc2\xcd\x42\x95\x80\xc8\xbc\x72\x48\x78\xe0\x57\x1c\xfe\x24\x6a\xaa\xd6\x0d\x58\x2d\x28\x78\x19\xc2\x58\xcc\x4f\x23\xd0\xb5\x81\x3b\xd4\xfb\x92\xcb\x5d\x83\x14\xf2\x3f\x5f\x7c\x38\x24\x6a\xc2\xbd\xc9\x5c\xad\x54\x76\x42\x43\xa2\xc5\x16\xe1\xf2\xf4\x74\xc7\xff\x36\x53\xcc\xd6\x76\x03\x1f\x21\x78\xb8\xa8\x7a\x04\x6a\xad\x34\x5c\x42\xaa\xd6\xcd\x35\xda\x11\x3d\xd6\xea\x17\xd5\x4a\x45\x26\x50\x73\xbb\x4c\x5f\x71\xdc\xf3\x33\xf7\xea\xec\x01\x2e\x19\x4a\x9e\x4f\x80\xa9\x41\x20\x80\xa7\xf9\x84\xb9\xdd\xd4\xea\x70\x79\x2a\xc5\xc7\xf7\x74\x2a\xa7\x4b\x05\x2e\xf9\xa9\xa2\xf2\x18\xe8\x1f\x11\xa8\xbc\x69\xd5\x4d\xb1\x5d\xa0\xae\xd5\x1b\x6e\x7b\x45\x84\x10\xc3\x73\x7e\xde\x2b\xcb\x3c\x7f\x70\xcf\x4f\x24\xc9\xa9\x77\x8a\xa9\xb6\xe5\xc9\x7f\x87\xb6\x8f\xee\xce\x9e\x6b\xdc\xa9\x1c\x2e\xe1\xe0\x38\x7f\x05\xe1\x64\x11\x22\x51\xba\x46\x28\x09\x97\xd0\xbe\x00\x09\xbf\xf1\xd9\xfc\x0d\x36\x67\xb6\xa6\xca\x1f\x2e\x40\x7e\xf8\x50\x77\xa0\x8a\x7f\xcb\x1a\x9b\xe4\xea\x72\xc4\x09\xc9\x11\xbf\xd5\x64\xbd\x69\xd5\xd4\x6a\x99\xad\x6b\x41\xaf\xee\x72\x5f\x79\xa2\xc5\x3c\x4a\xbb\x64\x7f\x97\x12\xef\x54\xf7\x67\x58\x0a\x83\x70\x76\x35\xbc\xbe\x3e\x8b\xe1\xf8\x70\x75\xfb\x69\x74\x16\x1f\x0e\x29\x33\x63\xe9\xe7\x2b\x97\xf8\x24\x6e\xa7\xde\xdc\x89\xb4\xc0\xdb\x84\xeb\x7d\x70\x97\xff\xc5\xd7\xde\xd1\x2b\x6f\x2e\xe0\xfc\x6c\x2d\x8c\x6b\x87\x17\x80\xf6\xbb\x00\xab\xde\xf2\x0f\x9e\xa7\xe1\x39\xc4\x31\xbd\x85\x0a\x4f\x50\x2f\x30\x32\xcb\x0b\x7b\xc0\x6c\x71\xab\xf4\xbe\x69\xe8\x87\x4f\xcd\xe7\xa4\x71\x48\xce\x07\x7f\xee\x17\x14\xc7\x5e\xcf\x8a\x34\x7d\xbe\xc7\x73\xe4\x9d\x4d\x95\x73\x4e\xe6\xbe\x77\x4e\x3e\x02\xd7\x02\xec\xe7\xa3\x2d\x34\x8a\x6f\x17\xc7\x8a\x7e\x1a\x5d\x8f\xfe\x18\xce\x46\xcf\x2a\x3b\x9d\x0d\x67\xe3\x2b\x7e\xf5\xe3\xda\x86\xbf\x54\xdb\xd7\x9d\x70\x3c\x87\x3b\x06\xbc\x6a\xc1\xb7\x5b\xe0\x97\x7b\xe0\x97\x9a\xe0\x58\xd0\x7f\xa2\xa2\xff\xbf\xa4\xff\x74\x4d\x27\xa3\xd9\xfd\xe4\xe6\xa4\x74\xf4\xe7\xca\x4f\x7c\x33\xde\xf5\xed\xba\x05\xaf\xdc\x79\x7c\xf9\x2b\xee\x8d\xc6\x57\x85\x6d\xb8\xd0\x1f\x4a\xd6\x77\xf4\x4e\x67\xb7\x77\xc7\xde\xbb\x1f\x5f\x8d\x0f\x43\xe5\x47\x31\xda\x0d\x68\xbf\xc3\xfa\xef\xfb\x2f\x77\x9f\x46\xd3\x99\x67\x2a\x33\x9b\x2f\x0f\x9f\xe9\x1a\xed\xdd\x55\xed\x64\x06\xca\xa4\x9c\x7f\xd2\xdc\x51\x9a\xcb\xe9\x77\x40\xa7\x98\x1d\xe0\xcf\x6e\x0e\xf8\x08\xed\xbf\xbb\x78\xe4\x3a\x0e\xf7\x97\x05\xf3\x37\x98\x23\x3e\xd6\xf5\xd9\x45\x7a\x3c\xdd\xf3\x3b\x88\xf1\xd5\xca\x53\xf5\xa9\xfa\xbf\x00\x00\x00\xff\xff\x51\x4b\xdc\x7e\x62\x10\x00\x00") +var _evmdis_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\xdf\x6f\xda\xca\x12\x7e\x86\xbf\x62\x94\x27\x50\x29\x60\x63\x08\x38\x27\x47\xe2\xa6\xf4\x1c\xae\xd2\x24\x02\x72\x8f\x2a\x94\x87\x05\xc6\xb0\xaa\xf1\x5a\xbb\x6b\x72\xb8\x55\xfe\xf7\xab\xd9\x59\x03\xf9\x75\xdb\x4a\xa7\x0f\x3b\xb5\x77\xbe\x6f\xbe\x9d\x19\xcf\x92\x56\x0b\xae\x54\xbe\xd7\x72\xbd\xb1\x10\xb6\x83\x73\x98\x6d\x10\xd6\xea\x23\xda\x0d\x6a\x2c\xb6\x30\x2c\xec\x46\x69\x53\x6d\xb5\x60\xb6\x91\x06\x12\x99\x22\x48\x03\xb9\xd0\x16\x54\x02\xf6\x85\x7f\x2a\x17\x5a\xe8\x7d\xb3\xda\x6a\x31\xe6\xcd\x6d\x62\x48\x34\x22\x18\x95\xd8\x47\xa1\x31\x86\xbd\x2a\x60\x29\x32\xd0\xb8\x92\xc6\x6a\xb9\x28\x2c\x82\xb4\x20\xb2\x55\x4b\x69\xd8\xaa\x95\x4c\xf6\x44\x29\x2d\x14\xd9\x0a\xb5\x0b\x6d\x51\x6f\x4d\xa9\xe3\x8f\x9b\x7b\xb8\x46\x63\x50\xc3\x1f\x98\xa1\x16\x29\xdc\x15\x8b\x54\x2e\xe1\x5a\x2e\x31\x33\x08\xc2\x40\x4e\x6f\xcc\x06\x57\xb0\x70\x74\x04\xfc\x4c\x52\xa6\x5e\x0a\x7c\x56\x45\xb6\x12\x56\xaa\xac\x01\x28\x49\x39\xec\x50\x1b\xa9\x32\xe8\x94\xa1\x3c\x61\x03\x94\x26\x92\x9a\xb0\x74\x00\x0d\x2a\x27\x5c\x1d\x44\xb6\x87\x54\xd8\x23\xf4\x27\x12\x72\x3c\xf7\x0a\x64\xe6\xc2\x6c\x54\x8e\x60\x37\xc2\xd2\xa9\x1f\x65\x9a\xc2\x02\xa1\x30\x98\x14\x69\x83\xd8\x16\x85\x85\xbf\xc6\xb3\x3f\x6f\xef\x67\x30\xbc\xf9\x0a\x7f\x0d\x27\x93\xe1\xcd\xec\xeb\x05\x3c\x4a\xbb\x51\x85\x05\xdc\x21\x53\xc9\x6d\x9e\x4a\x5c\xc1\xa3\xd0\x5a\x64\x76\x0f\x2a\x21\x86\x2f\xa3\xc9\xd5\x9f\xc3\x9b\xd9\xf0\x5f\xe3\xeb\xf1\xec\x2b\x28\x0d\x9f\xc7\xb3\x9b\xd1\x74\x0a\x9f\x6f\x27\x30\x84\xbb\xe1\x64\x36\xbe\xba\xbf\x1e\x4e\xe0\xee\x7e\x72\x77\x3b\x1d\x35\x61\x8a\xa4\x0a\x09\xff\xe3\x9c\x27\xae\x7a\x1a\x61\x85\x56\xc8\xd4\x94\x99\xf8\xaa\x0a\x30\x1b\x55\xa4\x2b\xd8\x88\x1d\x82\xc6\x25\xca\x1d\xae\x40\xc0\x52\xe5\xfb\x9f\x2e\x2a\x71\x89\x54\x65\x6b\x77\xe6\x77\x1b\x12\xc6\x09\x64\xca\x36\xc0\x20\xc2\x6f\x1b\x6b\xf3\xb8\xd5\x7a\x7c\x7c\x6c\xae\xb3\xa2\xa9\xf4\xba\x95\x32\x9d\x69\xfd\xde\xac\x12\x27\xee\xb6\x2b\x69\x66\x5a\x2c\x51\x83\x46\x5b\xe8\xcc\x80\x29\x92\x44\x2e\x25\x66\x16\x64\x96\x28\xbd\x75\x7d\x02\x89\x56\x5b\x10\x60\xc9\x19\xac\x82\x1c\x35\x6d\x7a\x8e\x8f\xc6\xee\x53\xa7\x73\x25\x8d\x30\x06\xb7\x8b\x74\xdf\xac\x7e\xaf\x56\x8c\x15\xcb\x6f\x31\xcc\xbf\xab\xdc\xc4\x30\x7f\x78\x7a\x68\x54\xab\x95\x2c\x2f\xcc\x06\x4d\x0c\xdf\xdb\x31\xb4\x1b\x10\xc4\x10\x34\x20\x74\x6b\xc7\xad\x91\x5b\xbb\x6e\xed\xb9\xf5\xdc\xad\x7d\xb7\x0e\xdc\x1a\xb4\xd9\x30\x3a\x60\xb7\x80\xfd\x02\x76\x0c\xd8\x33\x64\xcf\xd0\xc7\xe1\x40\x21\x47\x0a\x39\x54\xc8\xb1\x42\x66\xe9\xb0\x4b\xc4\x2c\x11\xb3\x74\x99\xa5\xcb\x2c\x5d\x76\xe9\x32\x4b\xd7\x0b\xee\xba\xf3\x74\x99\xa5\x7b\xce\x4f\xcc\xd2\x65\x96\x1e\x1f\xb9\xc7\x80\x9e\x3f\x22\x03\x7a\x2c\xbe\xc7\x80\x1e\x03\xfa\x0c\xe8\x73\xd8\x7e\xc8\x4f\x1d\x36\xcc\xd2\xe7\xb0\xfd\x1e\x1b\x0e\xdb\x67\x96\x3e\xb3\x0c\x58\xfc\x20\x70\x7b\x03\x8e\x37\xe0\x78\x03\x9f\xd5\x32\xad\x3e\xaf\x6d\x9f\xd8\x76\xe8\x6d\xc7\xdb\xc8\xdb\xae\xb7\x3e\xf3\x6d\x9f\xfa\xb6\xcf\x7d\xdb\xf3\x1d\xea\xe4\xf9\x02\xcf\x17\x78\xbe\xc0\xf3\x05\x9e\xaf\xac\x64\x59\xca\xb2\x96\xbe\x98\x81\xaf\x66\xe0\xcb\x19\xf8\x7a\x06\xbe\xa0\x81\xaf\x68\xe0\x4b\x1a\xf8\x9a\x06\xa1\xe7\x0b\xfb\x31\x84\x64\x07\x31\x74\x1a\x10\x74\xda\x31\x44\x64\x83\x18\xba\x64\xc3\x18\x7a\x64\x3b\x31\x9c\x93\x8d\x62\xe8\x93\xed\xc6\x30\x20\x4b\x7c\xd4\xb5\x1d\x22\x24\xc6\x0e\x29\x24\xca\x0e\x49\x24\xce\x88\x34\x12\x69\x44\x22\x89\x35\x22\x95\x44\x1b\x91\x4c\xe2\x8d\x22\xd6\x11\x75\x59\x47\xd4\x63\x1d\xd1\x39\xeb\xa0\xee\x73\x80\x01\xeb\xa0\xfe\x23\x1d\xd4\x80\xa4\xc3\x75\x20\xe9\x70\x3d\x48\x3a\x5c\x17\x12\x25\xf5\xa1\xd3\xe1\x3a\x91\x48\xa9\x17\x9d\x0e\xd7\x8d\x44\xeb\xfa\x91\x78\x7d\x47\x06\xbd\xc0\xdb\xd0\xdb\x8e\xb7\x91\xb3\x61\xe4\xbf\xa2\xc8\x7f\x46\x91\xff\x8e\xa2\x8e\xdf\xf7\x7e\xee\x23\x78\xa2\xef\xbc\xd5\x02\x8d\xa6\x48\x2d\x4d\x7f\x99\xed\xd4\x37\x9a\xcf\x1b\xcc\x40\xa4\xa9\x1b\x64\x2a\x5f\xaa\x15\x1a\x1e\x90\x0b\xc4\x0c\xa4\x45\x2d\xe8\x86\x50\x3b\xd4\x74\x39\x96\xa3\xc9\xd1\x11\x26\x91\x99\x48\x4b\x62\x3f\x44\x69\x30\xc9\x6c\xdd\xac\x56\xf8\x7d\x0c\x49\x91\x2d\x69\x74\xd5\xea\xf0\xdd\x53\x80\xdd\x48\xd3\x74\x23\x69\xde\x7e\x68\xaa\xdc\x5c\x40\xa9\x33\x11\x6f\xc9\x24\x6a\xb1\xb4\x85\x48\x01\xff\xc6\x65\xe1\x66\xa1\x4a\x40\x64\x5e\x39\x24\x3c\xf1\x2b\x0e\x7f\x12\x35\x55\xeb\x06\xac\x16\x14\xbc\x0c\x61\x2c\xe6\xa7\x11\xe8\xde\xc0\x1d\xea\x7d\xc9\xe5\xee\x41\x0a\xf9\x9f\x2f\x3e\x1c\x12\x35\xe1\xde\x64\xae\x56\x2a\x3b\xa1\x21\xd1\x62\x8b\x70\x79\x7a\xba\xe3\x7f\x9b\x29\x66\x6b\xbb\x81\x8f\x10\x3c\x5c\x54\x3d\x02\xb5\x56\x1a\x2e\x21\x55\xeb\xe6\x1a\xed\x88\x1e\x6b\xf5\x8b\x6a\xa5\x22\x13\xa8\xb9\x5d\xa6\xaf\x38\xee\xf9\x99\x7b\x75\xf6\x00\x97\x0c\x25\xcf\x27\xc0\xd4\x20\x10\xc0\xd3\x7c\xc2\xdc\x6e\x6a\x75\xb8\x3c\x95\xe2\xe3\x7b\x3a\x95\xd3\xa5\x02\x97\xfc\x54\x51\x79\x0c\xf4\x8f\x08\x54\xde\xb4\xea\xa6\xd8\x2e\x50\xd7\xea\x0d\xb7\xbd\x22\x42\x88\xe1\x39\x3f\xef\x95\x65\x9e\x3f\xb8\xe7\x27\x92\xe4\xd4\x3b\xc5\x54\xdb\xf2\xe4\xbf\x43\xdb\x47\x77\x67\xcf\x35\xee\x54\x0e\x97\x70\x70\x9c\xbf\x82\x70\xb2\x08\x91\x28\x5d\x23\x94\x84\x4b\x68\x5f\x80\x84\xdf\xf8\x6c\xfe\x06\x9b\x33\x5b\x53\xe5\x0f\x17\x20\x3f\x7c\xa8\x3b\x50\xc5\xbf\x65\x8d\x4d\x72\x75\x39\xe2\x84\xe4\x88\xdf\x6a\xb2\xde\xb4\x6a\x6a\xb5\xcc\xd6\xb5\xa0\x57\x77\xb9\xaf\x3c\xd1\x62\x1e\xa5\x5d\xb2\xbf\x4b\x89\x77\xaa\xfb\x33\x2c\x85\x41\x38\xbb\x1a\x5e\x5f\x9f\xc5\x70\x7c\xb8\xba\xfd\x34\x3a\x8b\x0f\x87\x94\x99\xb1\xf4\xfb\x95\x4b\x7c\x12\xb7\x53\x6f\xee\x44\x5a\xe0\x6d\xc2\xf5\x3e\xb8\xcb\xff\xe2\x6b\xef\xe8\x95\x37\x17\x70\x7e\xb6\x16\xc6\xb5\xc3\x0b\x40\xfb\x5d\x80\x55\x6f\xf9\x07\xcf\xd3\xf0\x1c\xe2\x98\xde\x42\x85\x27\xa8\x17\x18\x99\xe5\x85\x3d\x60\xb6\xb8\x55\x7a\xdf\x34\xf4\xcb\xa7\xe6\x73\xd2\x38\x24\xe7\x83\x3f\xf7\x0b\x8a\x63\xaf\x67\x45\x9a\x3e\xdf\xe3\x39\xf2\xce\xa6\xca\x39\x27\x73\xdf\x3b\x27\x1f\x81\x6b\x01\xf6\xf3\xd1\x16\x1a\xc5\xb7\x8b\x63\x45\x3f\x8d\xae\x47\x7f\x0c\x67\xa3\x67\x95\x9d\xce\x86\xb3\xf1\x15\xbf\xfa\x71\x6d\xc3\x5f\xaa\xed\xeb\x4e\x38\x9e\xc3\x1d\x03\x5e\xb5\xe0\xdb\x2d\xf0\xcb\x3d\xf0\x4b\x4d\x70\x2c\xe8\x3f\x51\xd1\xff\x5f\xd2\x7f\xba\xa6\x93\xd1\xec\x7e\x72\x73\x52\x3a\xfa\x7b\xe5\x27\xbe\x19\xef\xfa\x76\xdd\x82\x57\xee\x3c\xbe\xfc\x15\xf7\x46\xe3\xab\xc2\x36\x5c\xe8\x0f\x25\xeb\x3b\x7a\xa7\xb3\xdb\xbb\x63\xef\xdd\x8f\xaf\xc6\x87\xa1\xf2\xa3\x18\xed\x06\xb4\xdf\x61\xfd\xf7\xfd\x97\xbb\x4f\xa3\xe9\xcc\x33\x95\x99\xcd\x97\x87\xcf\x74\x8d\xf6\xee\xaa\x76\x32\x03\x65\x52\xce\x3f\x69\xee\x28\xcd\xe5\xf4\x3b\xa0\x53\xcc\x0e\xf0\x67\x37\x07\x7c\x84\xf6\xdf\x5d\x3c\x72\x1d\x87\xfb\xcb\x82\xf9\x1b\xcc\x11\x1f\xeb\xfa\xec\x22\x3d\x9e\xee\xf9\x1d\xc4\xf8\x6a\xe5\xa9\xfa\x54\xfd\x5f\x00\x00\x00\xff\xff\xdf\x2f\xd9\xfa\x63\x10\x00\x00") func evmdis_tracerJsBytes() ([]byte, error) { return bindataRead( @@ -153,7 +152,7 @@ func evmdis_tracerJs() (*asset, error) { } info := bindataFileInfo{name: "evmdis_tracer.js", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd5, 0xe8, 0x96, 0xa1, 0x8b, 0xc, 0x68, 0x3c, 0xe8, 0x5d, 0x7e, 0xf0, 0xab, 0xfe, 0xec, 0xd1, 0xb, 0x3d, 0xfc, 0xc7, 0xac, 0xb5, 0xa, 0x41, 0x55, 0x0, 0x3a, 0x60, 0xa7, 0x8e, 0x46, 0x93}} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0xc8, 0x73, 0x8e, 0xfb, 0x1f, 0x84, 0x7d, 0x37, 0xd9, 0x26, 0x24, 0x37, 0xb8, 0x65, 0xb1, 0xed, 0xa0, 0x76, 0x9a, 0xf0, 0x8e, 0x3a, 0x9b, 0x20, 0x93, 0x27, 0x26, 0x2e, 0xc9, 0x9b, 0xde}} return a, nil } @@ -348,34 +347,31 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "4byte_tracer.js": _4byte_tracerJs, - - "bigram_tracer.js": bigram_tracerJs, - - "call_tracer.js": call_tracerJs, - - "evmdis_tracer.js": evmdis_tracerJs, - - "noop_tracer.js": noop_tracerJs, - - "opcount_tracer.js": opcount_tracerJs, - + "4byte_tracer.js": _4byte_tracerJs, + "bigram_tracer.js": bigram_tracerJs, + "call_tracer.js": call_tracerJs, + "evmdis_tracer.js": evmdis_tracerJs, + "noop_tracer.js": noop_tracerJs, + "opcount_tracer.js": opcount_tracerJs, "prestate_tracer.js": prestate_tracerJs, - - "trigram_tracer.js": trigram_tracerJs, - - "unigram_tracer.js": unigram_tracerJs, + "trigram_tracer.js": trigram_tracerJs, + "unigram_tracer.js": unigram_tracerJs, } +// AssetDebug is true if the assets were built with the debug flag enabled. +const AssetDebug = false + // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// 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, and @@ -433,7 +429,7 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + err = os.WriteFile(_filePath(dir, name), data, info.Mode()) if err != nil { return err } diff --git a/eth/tracers/testdata/call_tracer_inner_throw_outer_revert.json b/eth/tracers/testdata/call_tracer_inner_throw_outer_revert.json index 7627c8c23..ec2ceb426 100644 --- a/eth/tracers/testdata/call_tracer_inner_throw_outer_revert.json +++ b/eth/tracers/testdata/call_tracer_inner_throw_outer_revert.json @@ -59,7 +59,7 @@ "result": { "calls": [ { - "error": "invalid opcode: opcode 0xfe not defined", + "error": "invalid opcode: INVALID", "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", "gas": "0x75fe3", "gasUsed": "0x75fe3", diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go index f5c0b7189..84049d928 100644 --- a/eth/tracers/tracer.go +++ b/eth/tracers/tracer.go @@ -162,7 +162,7 @@ func (sw *stackWrapper) peek(idx int) *big.Int { log.Warn("Tracer accessed out of bound stack", "size", len(sw.stack.Data()), "index", idx) return new(big.Int) } - return sw.stack.Data()[len(sw.stack.Data())-idx-1] + return sw.stack.Back(idx).ToBig() } // pushObject assembles a JSVM object wrapping a swappable stack and pushes it diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 57f8a86a9..06746a3b3 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -40,7 +40,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) {} diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index e106d5a23..78636916c 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -20,6 +20,13 @@ import ( "crypto/ecdsa" "crypto/rand" "encoding/json" + "math/big" + "os" + "path/filepath" + "reflect" + "strings" + "testing" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/common/hexutil" "github.com/XinFinOrg/XDC-Subnet/common/math" @@ -31,12 +38,6 @@ import ( "github.com/XinFinOrg/XDC-Subnet/params" "github.com/XinFinOrg/XDC-Subnet/rlp" "github.com/XinFinOrg/XDC-Subnet/tests" - "io/ioutil" - "math/big" - "path/filepath" - "reflect" - "strings" - "testing" ) // To generate a new callTracer test, copy paste the makeTest method below into @@ -183,7 +184,7 @@ func TestPrestateTracerCreate2(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err = st.TransitionDb(common.Address{}); err != nil { + if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -203,7 +204,7 @@ func TestPrestateTracerCreate2(t *testing.T) { // Iterates over all the input-output datasets in the tracer test harness and // runs the JavaScript tracers against them. func TestCallTracer(t *testing.T) { - files, err := ioutil.ReadDir("testdata") + files, err := os.ReadDir("testdata") if err != nil { t.Fatalf("failed to retrieve tracer test suite: %v", err) } @@ -216,7 +217,7 @@ func TestCallTracer(t *testing.T) { t.Parallel() // Call tracer test found, read if from disk - blob, err := ioutil.ReadFile(filepath.Join("testdata", file.Name())) + blob, err := os.ReadFile(filepath.Join("testdata", file.Name())) if err != nil { t.Fatalf("failed to read testcase: %v", err) } @@ -258,7 +259,7 @@ func TestCallTracer(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err = st.TransitionDb(common.Address{}); err != nil { + if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 4b282002b..17cbc176e 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -93,13 +93,14 @@ type Service struct { // websocket. // // From Gorilla websocket docs: -// Connections support one concurrent reader and one concurrent writer. -// Applications are responsible for ensuring that no more than one goroutine calls the write methods -// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel -// concurrently and that no more than one goroutine calls the read methods -// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler -// concurrently. -// The Close and WriteControl methods can be called concurrently with all other methods. +// +// Connections support one concurrent reader and one concurrent writer. +// Applications are responsible for ensuring that no more than one goroutine calls the write methods +// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel +// concurrently and that no more than one goroutine calls the read methods +// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler +// concurrently. +// The Close and WriteControl methods can be called concurrently with all other methods. type connWrapper struct { conn *websocket.Conn @@ -628,6 +629,20 @@ func (s *Service) reportBlock(conn *connWrapper, block *types.Block) error { return conn.WriteJSON(report) } +// reportForensics forward the forensics repors it to the stats server. +func (s *Service) reportForensics(conn *connWrapper, forensicsProof *types.ForensicProof) error { + log.Info("Sending Forensics report to ethstats", "ForensicsType", forensicsProof.ForensicsType) + + stats := map[string]interface{}{ + "id": s.node, + "forensicsProof": forensicsProof, + } + report := map[string][]interface{}{ + "emit": {"forensics", stats}, + } + return conn.WriteJSON(report) +} + // assembleBlockStats retrieves any required metadata to report a single block // and assembles the block stats. If block is nil, the current head is processed. func (s *Service) assembleBlockStats(block *types.Block) *blockStats { @@ -662,7 +677,10 @@ func (s *Service) assembleBlockStats(block *types.Block) *blockStats { txs = []txStats{} } // Assemble and return the block stats - author, _ := s.engine.Author(header) + author, err := s.engine.Author(header) + if err != nil { + log.Error("Failed to retrieve block author", "err", err, "number", header.Number, "hash", header.Hash()) + } return &blockStats{ Number: header.Number, diff --git a/event/event.go b/event/event.go index 20d20d1f5..423278731 100644 --- a/event/event.go +++ b/event/event.go @@ -180,6 +180,12 @@ func (s *TypeMuxSubscription) Unsubscribe() { s.closewait() } +func (s *TypeMuxSubscription) Closed() bool { + s.closeMu.Lock() + defer s.closeMu.Unlock() + return s.closed +} + func (s *TypeMuxSubscription) closewait() { s.closeMu.Lock() defer s.closeMu.Unlock() diff --git a/go.mod b/go.mod index 12e0335e4..b144708a8 100644 --- a/go.mod +++ b/go.mod @@ -18,10 +18,11 @@ require ( github.com/gizak/termui v2.2.0+incompatible github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 github.com/go-stack/stack v1.8.1 - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/gorilla/websocket v1.4.2 github.com/hashicorp/golang-lru v0.5.3 + github.com/holiman/uint256 v1.2.4 github.com/huin/goupnp v1.3.0 github.com/influxdata/influxdb v1.7.9 github.com/jackpal/go-nat-pmp v1.0.2 @@ -39,11 +40,11 @@ require ( github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - golang.org/x/crypto v0.15.0 - golang.org/x/net v0.17.0 - golang.org/x/sync v0.4.0 - golang.org/x/sys v0.14.0 - golang.org/x/tools v0.14.0 + golang.org/x/crypto v0.22.0 + golang.org/x/net v0.24.0 + golang.org/x/sync v0.7.0 + golang.org/x/sys v0.19.0 + golang.org/x/tools v0.20.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce @@ -57,8 +58,9 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa // indirect - github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/uuid v1.3.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -72,9 +74,14 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/term v0.14.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 0e4048ac1..56a3145f9 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,9 @@ github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -53,12 +56,19 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200106141417-aaec0e7bde29 h1:Ewd9K+mC725sITA12QQHRqWj78NU4t7EhlFVVgdlzJg= github.com/dop251/goja v0.0.0-20200106141417-aaec0e7bde29/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 h1:O7I1iuzEA7SG+dK8ocOBSlYAA9jBUmCYl/Qa7ey7JAM= +github.com/dop251/goja v0.0.0-20240220182346-e401ed450204/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= @@ -66,13 +76,16 @@ github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/ethereum/go-ethereum v1.9.11 h1:Z0jugPDfuI5qsPY1XgBGVwikpdFK/ANqP7MrYvkmk+A= github.com/ethereum/go-ethereum v1.9.11/go.mod h1:7oC0Ni6dosMv5pxMigm6s0hN8g4haJMBnqmmo0D9YfQ= +github.com/ethereum/go-ethereum v1.13.15 h1:U7sSGYGo4SPjP6iNIifNoyIAiNjrmQkz6EwQG+/EZWo= +github.com/ethereum/go-ethereum v1.13.15/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gizak/termui v2.2.0+incompatible h1:qvZU9Xll/Xd/Xr/YO+HfBKXhy8a8/94ao6vV9DSXzUE= github.com/gizak/termui v2.2.0+incompatible/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= @@ -81,8 +94,9 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= @@ -98,9 +112,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= @@ -108,8 +121,10 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -120,10 +135,13 @@ github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1 github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.7.9 h1:uSeBTNO4rBkbp1Be5FKRsAmglM9nlx25TzVQRQt1An4= github.com/influxdata/influxdb v1.7.9/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= @@ -140,6 +158,7 @@ github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJo github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -219,6 +238,7 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= @@ -226,6 +246,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -243,27 +265,41 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/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.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -279,22 +315,38 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w 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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -304,15 +356,14 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951 h1:DMTcQRFbEH62YPRWwOI647s2e5mHda3oBPMHfrLs2bw= gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951/go.mod h1:owOxCRGGeAx1uugABik6K9oeNu1cgxP/R9ItzLDxNWA= diff --git a/interfaces.go b/interfaces.go index d6de91f09..9a2f3645b 100644 --- a/interfaces.go +++ b/interfaces.go @@ -132,6 +132,7 @@ type ContractCaller interface { // FilterQuery contains options for contract log filtering. type FilterQuery struct { + BlockHash *common.Hash // used by eth_getLogs, return logs only from block with this hash FromBlock *big.Int // beginning of the queried range, nil means genesis block ToBlock *big.Int // end of the range, nil means latest block Addresses []common.Address // restricts matches to events created by specific contracts diff --git a/internal/build/util.go b/internal/build/util.go index a249dac3d..387c2a7d6 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -21,7 +21,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "os" "os/exec" @@ -81,7 +80,7 @@ func RunGit(args ...string) string { // readGitFile returns content of file in .git directory. func readGitFile(file string) string { - content, err := ioutil.ReadFile(path.Join(".git", file)) + content, err := os.ReadFile(path.Join(".git", file)) if err != nil { return "" } @@ -114,7 +113,7 @@ func CopyFile(dst, src string, mode os.FileMode) { // so that go commands executed by build use the same version of Go as the 'host' that runs // build code. e.g. // -// /usr/lib/go-1.11/bin/go run build/ci.go ... +// /usr/lib/go-1.11/bin/go run build/ci.go ... // // runs using go 1.11 and invokes go 1.11 tools from the same GOROOT. This is also important // because runtime.Version checks on the host should match the tools that are run. diff --git a/internal/cmdtest/test_cmd.go b/internal/cmdtest/test_cmd.go index c2969f8dd..40aa87596 100644 --- a/internal/cmdtest/test_cmd.go +++ b/internal/cmdtest/test_cmd.go @@ -21,7 +21,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "os/exec" "regexp" @@ -77,7 +76,7 @@ func (tt *TestCmd) Run(name string, args ...string) { // InputLine writes the given text to the childs stdin. // This method can also be called from an expect template, e.g.: // -// geth.expect(`Passphrase: {{.InputLine "password"}}`) +// geth.expect(`Passphrase: {{.InputLine "password"}}`) func (tt *TestCmd) InputLine(s string) string { io.WriteString(tt.stdin, s+"\n") return "" @@ -170,7 +169,7 @@ func (tt *TestCmd) ExpectRegexp(regex string) (*regexp.Regexp, []string) { func (tt *TestCmd) ExpectExit() { var output []byte tt.withKillTimeout(func() { - output, _ = ioutil.ReadAll(tt.stdout) + output, _ = io.ReadAll(tt.stdout) }) tt.WaitExit() if tt.Cleanup != nil { diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 302130cc5..4bf2f66db 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -106,7 +106,7 @@ var Flags = []cli.Flag{ //blockprofilerateFlag, cpuprofileFlag, //traceFlag, - periodicProfilingFlag, + //periodicProfilingFlag, debugDataDirFlag, } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index dc1b79ce8..666fa3fed 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -31,6 +31,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/XDCx/tradingstate" "github.com/XinFinOrg/XDC-Subnet/accounts" + "github.com/XinFinOrg/XDC-Subnet/accounts/abi" "github.com/XinFinOrg/XDC-Subnet/accounts/abi/bind" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" "github.com/XinFinOrg/XDC-Subnet/common" @@ -526,8 +527,8 @@ func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]map[s // GetBalance returns the amount of wei for the given address in the state of the // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta // block numbers are also allowed. -func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) { - state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) +func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -658,8 +659,8 @@ func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, bloc } // GetCode returns the code stored at the given address in the state for the given block number. -func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) +func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -667,11 +668,29 @@ func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Addres return code, state.Error() } +// GetAccountInfo returns the information at the given address in the state for the given block number. +func (s *PublicBlockChainAPI) GetAccountInfo(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (map[string]interface{}, error) { + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + info := state.GetAccountInfo(address) + result := map[string]interface{}{ + "address": address, + "balance": (*hexutil.Big)(info.Balance), + "codeSize": info.CodeSize, + "codeHash": info.CodeHash, + "nonce": info.Nonce, + "storageHash": info.StorageHash, + } + return result, nil +} + // GetStorageAt returns the storage from the state at the given address, key and // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block // numbers are also allowed. -func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) +func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -796,11 +815,10 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd return result, err } candidatesAddresses := state.GetCandidates(statedb) + candidates = make([]utils.Masternode, 0, len(candidatesAddresses)) for _, address := range candidatesAddresses { v := state.GetCandidateCap(statedb, address) - if address.String() != "0x0000000000000000000000000000000000000000" { - candidates = append(candidates, utils.Masternode{Address: address, Stake: v}) - } + candidates = append(candidates, utils.Masternode{Address: address, Stake: v}) } } if err != nil || len(candidates) == 0 { @@ -810,24 +828,19 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd } maxMasternodes := common.MaxMasternodes - isTopCandidate := false - // check penalties from checkpoint headers and modify status of a node to SLASHED if it's in top 150 candidates - // if it's SLASHED but it's out of top 150, the status should be still PROPOSED + // check penalties from checkpoint headers and modify status of a node to SLASHED if it's in top maxMasternodes candidates. + // if it's SLASHED but it's out of top maxMasternodes, the status should be still PROPOSED. + isCandidate := false for i := 0; i < len(candidates); i++ { if coinbaseAddress == candidates[i].Address { - if i < maxMasternodes { - isTopCandidate = true - } + isCandidate = true result[fieldStatus] = statusProposed result[fieldCapacity] = candidates[i].Stake break } } - if !isTopCandidate { - return result, nil - } - // Second, Find candidates that have masternode status + // Get masternode list if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok { masternodes = engine.GetMasternodesFromCheckpointHeader(header) if len(masternodes) == 0 { @@ -838,43 +851,67 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd } else { log.Error("Undefined XDPoS consensus engine") } - // Set masternode status + + // Set to statusMasternode if it is masternode for _, masternode := range masternodes { if coinbaseAddress == masternode { result[fieldStatus] = statusMasternode + if !isCandidate { + result[fieldCapacity] = -1 + log.Warn("Find non-candidate masternode", "masternode", masternode.String(), "checkpointNumber", checkpointNumber, "epoch", epoch, "epochNumber", epochNumber) + } return result, nil } } + if !isCandidate || len(masternodes) >= maxMasternodes { + return result, nil + } + + if len(candidates) > maxMasternodes { + sort.Slice(candidates, func(i, j int) bool { + return candidates[i].Stake.Cmp(candidates[j].Stake) > 0 + }) + } + // Third, Get penalties list penaltyList = append(penalties, header.Penalties...) // map slashing status - for _, pen := range penaltyList { - if coinbaseAddress == pen { - result[fieldStatus] = statusSlashed - return result, nil + total := len(masternodes) + for _, candidate := range candidates { + for _, pen := range penaltyList { + if candidate.Address == pen { + if coinbaseAddress == pen { + result[fieldStatus] = statusSlashed + return result, nil + } + total++ + if total >= maxMasternodes { + return result, nil + } + } } } + return result, nil } // GetCandidates returns status of all candidates at a specified epochNumber func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.EpochNumber) (map[string]interface{}, error) { var ( - block *types.Block - header *types.Header - checkpointNumber rpc.BlockNumber - epochNumber rpc.EpochNumber - masternodes []common.Address - candidates []utils.Masternode - penalties []common.Address - err error + block *types.Block + header *types.Header + checkpointNumber rpc.BlockNumber + epochNumber rpc.EpochNumber + masternodes, penaltyList []common.Address + candidates []utils.Masternode + penalties []common.Address + err error ) result := map[string]interface{}{ fieldSuccess: true, } - candidatesStatusMap := map[string]map[string]interface{}{} checkpointNumber, epochNumber = s.GetPreviousCheckpointFromEpoch(ctx, epoch) result[fieldEpoch] = epochNumber.Int64() @@ -903,11 +940,10 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch return result, err } candidatesAddresses := state.GetCandidates(statedb) + candidates = make([]utils.Masternode, 0, len(candidatesAddresses)) for _, address := range candidatesAddresses { v := state.GetCandidateCap(statedb, address) - if address.String() != "0x0000000000000000000000000000000000000000" { - candidates = append(candidates, utils.Masternode{Address: address, Stake: v}) - } + candidates = append(candidates, utils.Masternode{Address: address, Stake: v}) } } @@ -916,15 +952,8 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch result[fieldSuccess] = false return result, err } - // First, set all candidate to propose - for _, candidate := range candidates { - candidatesStatusMap[candidate.Address.String()] = map[string]interface{}{ - fieldStatus: statusProposed, - fieldCapacity: candidate.Stake, - } - } - // Second, Find candidates that have masternode status + // Find candidates that have masternode status if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok { masternodes = engine.GetMasternodesFromCheckpointHeader(header) if len(masternodes) == 0 { @@ -935,36 +964,65 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch } else { log.Error("Undefined XDPoS consensus engine") } - // Set masternode status + + // Set all candidate to statusProposed + candidatesStatusMap := make(map[string]map[string]interface{}, len(candidates)) + for _, candidate := range candidates { + candidatesStatusMap[candidate.Address.String()] = map[string]interface{}{ + fieldStatus: statusProposed, + fieldCapacity: candidate.Stake, + } + } + + // Set masternodes to statusMasternode for _, masternode := range masternodes { - if candidatesStatusMap[masternode.String()] != nil { - candidatesStatusMap[masternode.String()][fieldStatus] = statusMasternode + key := masternode.String() + if candidatesStatusMap[key] != nil { + candidatesStatusMap[key][fieldStatus] = statusMasternode + } else { + candidatesStatusMap[key] = map[string]interface{}{ + fieldStatus: statusMasternode, + fieldCapacity: -1, + } + log.Warn("Masternode is not candidate", "masternode", key, "checkpointNumber", checkpointNumber, "epoch", epoch, "epochNumber", epochNumber) } } - // Third, Get penalties list - penalties = append(penalties, header.Penalties...) + maxMasternodes := common.MaxMasternodes - // map slashing status - if len(penalties) == 0 { + if len(masternodes) >= maxMasternodes { result[fieldCandidates] = candidatesStatusMap return result, nil } - var topCandidates []utils.Masternode - if len(candidates) > common.MaxMasternodes { - topCandidates = candidates[:common.MaxMasternodes] - } else { - topCandidates = candidates + if len(candidates) > maxMasternodes { + sort.Slice(candidates, func(i, j int) bool { + return candidates[i].Stake.Cmp(candidates[j].Stake) > 0 + }) } - // check penalties from checkpoint headers and modify status of a node to SLASHED if it's in top 150 candidates - // if it's SLASHED but it's out of top 150, the status should be still PROPOSED - for _, pen := range penalties { - for _, candidate := range topCandidates { - if candidate.Address == pen && candidatesStatusMap[pen.String()] != nil { + + // Get penalties list + penaltyList = append(penalties, header.Penalties...) + + // map slashing status + if len(penaltyList) == 0 { + result[fieldCandidates] = candidatesStatusMap + return result, nil + } + + // check penalties from checkpoint headers and modify status of a node to SLASHED if it's in top maxMasternodes candidates. + // if it's SLASHED but it's out of top maxMasternodes, the status should be still PROPOSED. + total := len(masternodes) + for _, candidate := range candidates { + for _, pen := range penaltyList { + if candidate.Address == pen { candidatesStatusMap[pen.String()][fieldStatus] = statusSlashed + total++ + if total >= maxMasternodes { + result[fieldCandidates] = candidatesStatusMap + return result, nil + } } - penalties = append(penalties, block.Penalties()...) } } @@ -976,24 +1034,23 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch // GetPreviousCheckpointFromEpoch returns header of the previous checkpoint func (s *PublicBlockChainAPI) GetPreviousCheckpointFromEpoch(ctx context.Context, epochNum rpc.EpochNumber) (rpc.BlockNumber, rpc.EpochNumber) { var checkpointNumber uint64 - - if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok { - if epochNum == rpc.LatestEpochNumber { - currentCheckpointNumber, epochNumber, err := engine.GetCurrentEpochSwitchBlock(s.chainReader, s.b.CurrentBlock().Number()) - if err != nil { - log.Error("[GetPreviousCheckpointFromEpoch] Error while trying to get current epoch switch block information", "Block", s.b.CurrentBlock(), "Error", err) - } - checkpointNumber = currentCheckpointNumber - epochNum = rpc.EpochNumber(epochNumber) - } else if epochNum < 2 { - checkpointNumber = 0 - } else { - checkpointNumber = s.b.ChainConfig().XDPoS.Epoch * (uint64(epochNum) - 1) - } - return rpc.BlockNumber(checkpointNumber), epochNum + epoch := s.b.ChainConfig().XDPoS.Epoch + + if epochNum == rpc.LatestEpochNumber { + blockNumer := s.b.CurrentBlock().Number().Uint64() + diff := blockNumer % epoch + // checkpoint number + checkpointNumber = blockNumer - diff + epochNum = rpc.EpochNumber(checkpointNumber / epoch) + if diff > 0 { + epochNum += 1 + } + } else if epochNum < 2 { + checkpointNumber = 0 } else { - panic("[GetPreviousCheckpointFromEpoch] Error while trying to get XDPoS consensus engine") + checkpointNumber = epoch * (uint64(epochNum) - 1) } + return rpc.BlockNumber(checkpointNumber), epochNum } // getCandidatesFromSmartContract returns all candidates with their capacities at the current time @@ -1015,23 +1072,18 @@ func (s *PublicBlockChainAPI) getCandidatesFromSmartContract() ([]utils.Masterno return []utils.Masternode{}, err } - var candidatesWithStakeInfo []utils.Masternode + candidatesWithStakeInfo := make([]utils.Masternode, 0, len(candidates)) for _, candidate := range candidates { - v, err := validator.GetCandidateCap(opts, candidate) - if err != nil { - return []utils.Masternode{}, err - } - if candidate.String() != "0x0000000000000000000000000000000000000000" { + if !candidate.IsZero() { + v, err := validator.GetCandidateCap(opts, candidate) + if err != nil { + return []utils.Masternode{}, err + } candidatesWithStakeInfo = append(candidatesWithStakeInfo, utils.Masternode{Address: candidate, Stake: v}) } - - if len(candidatesWithStakeInfo) > 0 { - sort.Slice(candidatesWithStakeInfo, func(i, j int) bool { - return candidatesWithStakeInfo[i].Stake.Cmp(candidatesWithStakeInfo[j].Stake) >= 0 - }) - } } + return candidatesWithStakeInfo, nil } @@ -1045,12 +1097,12 @@ type CallArgs struct { Data hexutil.Bytes `json:"data"` } -func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error) { +func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error, error) { defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) - statedb, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + statedb, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if statedb == nil || err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } // Set sender address or use a default if none specified addr := args.From @@ -1072,7 +1124,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr balanceTokenFee := big.NewInt(0).SetUint64(gas) balanceTokenFee = balanceTokenFee.Mul(balanceTokenFee, gasPrice) // Create new call message - msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false, balanceTokenFee) + msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false, balanceTokenFee, header.Number) // Setup context so it may be cancelled the call has completed // or, in case of unmetered gas, setup a context with a timeout. @@ -1086,22 +1138,22 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr // this makes sure resources are cleaned up. defer cancel() - block, err := s.b.BlockByNumber(ctx, blockNr) + block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } author, err := s.b.GetEngine().Author(block.Header()) if err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } XDCxState, err := s.b.XDCxService().GetTradingState(block, author) if err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } // Get a new instance of the EVM. evm, vmError, err := s.b.GetEVM(ctx, msg, statedb, XDCxState, header, vmCfg) if err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil } // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) @@ -1114,23 +1166,77 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr // and apply the message. gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - res, gas, failed, err := core.ApplyMessage(evm, msg, gp, owner) + res, gas, failed, err, vmErr := core.ApplyMessage(evm, msg, gp, owner) if err := vmError(); err != nil { - return nil, 0, false, err + return nil, 0, false, err, nil + } + + // If the timer caused an abort, return an appropriate error message + if evm.Cancelled() { + return nil, 0, false, fmt.Errorf("execution aborted (timeout = %v)", timeout), nil } - return res, gas, failed, err + if err != nil { + return res, 0, false, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()), nil + } + return res, gas, failed, err, vmErr +} + +func newRevertError(res []byte) *revertError { + reason, errUnpack := abi.UnpackRevert(res) + err := errors.New("execution reverted") + if errUnpack == nil { + err = fmt.Errorf("execution reverted: %v", reason) + } + return &revertError{ + error: err, + reason: hexutil.Encode(res), + } +} + +// revertError is an API error that encompasses an EVM revertal with JSON error +// code and a binary data blob. +type revertError struct { + error + reason string // revert reason hex encoded +} + +// ErrorCode returns the JSON error code for a revertal. +// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal +func (e *revertError) ErrorCode() int { + return 3 +} + +// ErrorData returns the hex encoded revert reason. +func (e *revertError) ErrorData() interface{} { + return e.reason } // Call executes the given transaction on the state for the given block number. // It 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, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { - result, _, _, err := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second) - return (hexutil.Bytes)(result), err +func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Bytes, error) { + if blockNrOrHash == nil { + latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + blockNrOrHash = &latest + } + result, _, failed, err, vmErr := s.doCall(ctx, args, *blockNrOrHash, vm.Config{}, 5*time.Second) + if err != nil { + return nil, err + } + // If the result contains a revert reason, try to unpack and return it. + if failed && len(result) > 0 { + return nil, newRevertError(result) + } + + return (hexutil.Bytes)(result), vmErr } -// 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) (hexutil.Uint64, error) { +func (s *PublicBlockChainAPI) doEstimateGas(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Uint64, error) { + // Retrieve the base state and mutate it with any overrides + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return 0, err + } + // Binary search the gas requirement, as it may be higher than the amount used var ( lo uint64 = params.TxGas - 1 @@ -1150,34 +1256,92 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h cap = hi // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) bool { + executable := func(gas uint64) (bool, []byte, error, error) { args.Gas = hexutil.Uint64(gas) - _, _, failed, err := s.doCall(ctx, args, rpc.LatestBlockNumber, vm.Config{}, 0) - if err != nil || failed { - log.Warn("[EstimateGas] api", "err", err) - return false + res, _, failed, err, vmErr := s.doCall(ctx, args, blockNrOrHash, vm.Config{}, 0) + if err != nil { + if errors.Is(err, vm.ErrOutOfGas) || errors.Is(err, core.ErrIntrinsicGas) { + return false, nil, nil, nil // Special case, raise gas limit + } + return false, nil, err, nil // Bail out + } + if failed { + return false, res, nil, vmErr + } + + return true, nil, nil, nil + } + + // If the transaction is a plain value transfer, short circuit estimation and + // directly try 21000. Returning 21000 without any execution is dangerous as + // some tx field combos might bump the price up even for plain transfers (e.g. + // unused access list items). Ever so slightly wasteful, but safer overall. + if len(args.Data) == 0 && args.To != nil { + statedb, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) + if statedb == nil || err != nil { + return 0, err + } + + if statedb.GetCodeSize(*args.To) == 0 { + ok, _, err, _ := executable(params.TxGas) + if ok && err == nil { + return hexutil.Uint64(params.TxGas), nil + } } - return true } + // Execute the binary search and hone in on an executable gas limit for lo+1 < hi { mid := (hi + lo) / 2 - if !executable(mid) { + ok, _, err, _ := executable(mid) + + // If the error is not nil(consensus error), it means the provided message + // call or transaction will never be accepted no matter how much gas it is + // assigned. Return the error directly, don't struggle any more. + if err != nil { + return 0, err + } + + if !ok { lo = mid } else { hi = mid } } + // Reject the transaction as invalid if it still fails at the highest allowance if hi == cap { - if !executable(hi) { - return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") + ok, res, err, vmErr := executable(hi) + if err != nil { + return 0, err + } + + if !ok { + if vmErr != vm.ErrOutOfGas { + if len(res) > 0 { + return 0, newRevertError(res) + } + return 0, vmErr + } + + // Otherwise, the specified gas cap is too low + return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } } return hexutil.Uint64(hi), nil } +// 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) { + bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + if blockNrOrHash != nil { + bNrOrHash = *blockNrOrHash + } + return s.doEstimateGas(ctx, args, bNrOrHash) +} + // ExecutionResult groups all structured logs emitted by the EVM // while replaying a transaction in debug mode as well as transaction // execution status, the amount of gas used and the return value @@ -1604,8 +1768,17 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx cont } // GetTransactionCount returns the number of transactions the given address has sent for the given block number -func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { - state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) +func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { + // Ask transaction pool for the nonce which includes pending transactions + if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { + nonce, err := s.b.GetPoolNonce(ctx, address) + if err != nil { + return nil, err + } + return (*hexutil.Uint64)(&nonce), nil + } + // Resolve block number and use its state to ask for the nonce + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } @@ -2967,6 +3140,9 @@ func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash, return addrs, err } blockData, err := b.BlockByNumber(nil, rpc.BlockNumber(i)) + if err != nil { + return addrs, err + } signTxs := engine.CacheSigningTxs(header.Hash(), blockData.Transactions()) for _, signtx := range signTxs { blkHash := common.BytesToHash(signtx.Data()[len(signtx.Data())-32:]) diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index b97167be2..013dc82aa 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -57,8 +57,13 @@ type Backend interface { // BlockChain API SetHead(number uint64) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) + HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) + HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) + BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) + BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) + StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetTd(blockHash common.Hash) *big.Int diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go index dfbc98d36..d96a9112b 100644 --- a/internal/guide/guide_test.go +++ b/internal/guide/guide_test.go @@ -23,7 +23,6 @@ package guide import ( - "io/ioutil" "math/big" "os" "path/filepath" @@ -37,7 +36,7 @@ import ( // Tests that the account management snippets work correctly. func TestAccountManagement(t *testing.T) { // Create a temporary folder to work with - workdir, err := ioutil.TempDir("", "") + workdir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("Failed to create temporary work dir: %v", err) } diff --git a/internal/jsre/deps/bindata.go b/internal/jsre/deps/bindata.go index 6abd674f2..87f3281af 100644 --- a/internal/jsre/deps/bindata.go +++ b/internal/jsre/deps/bindata.go @@ -1,15 +1,16 @@ -// Code generated for package deps by go-bindata DO NOT EDIT. (@generated) +// Code generated by go-bindata. DO NOT EDIT. // sources: -// bignumber.js -// web3.js +// bignumber.js (17.314kB) +// web3.js (404.13kB) + package deps import ( "bytes" "compress/gzip" + "crypto/sha256" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -19,7 +20,7 @@ import ( func bindataRead(data []byte, name string) ([]byte, error) { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } var buf bytes.Buffer @@ -27,7 +28,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { clErr := gz.Close() if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) + return nil, fmt.Errorf("read %q: %w", name, err) } if clErr != nil { return nil, err @@ -37,8 +38,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,37 +50,26 @@ 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 } - -// Mode 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 } -var _bignumberJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x7c\x7b\x73\xd3\xc8\xb2\xf8\xff\xa7\xea\x7c\x07\x5b\x97\xa8\x66\xa2\x96\x2c\x99\x40\x88\x44\x4b\xc5\x42\xc2\x66\x7f\x21\xe1\x47\x60\x77\xef\x35\x5e\xca\x91\x47\xf6\x80\x2c\x19\x3d\x12\x02\xca\xf9\xec\xb7\x7a\x46\x92\x9d\x07\xe7\xec\xfd\x27\x96\xe6\xd1\xd3\xd3\xd3\xef\x69\x65\xb4\x3b\xb8\x90\x8b\xac\x5e\x5d\x88\xc2\xf9\x5c\x0e\x2e\xc7\x8e\xeb\x3c\x1e\x2c\xab\x6a\x5d\xfa\xa3\xd1\x42\x56\xcb\xfa\xc2\x89\xf3\xd5\xe8\x8d\xfc\x22\xde\xc4\xe9\x68\x7b\xf8\xe8\xe4\xf8\xe5\xe1\xe9\xcb\xc3\xc1\xee\xe8\x9f\xff\x18\xed\x0e\x56\xf9\x5c\x26\x52\xcc\x07\x17\xd7\x83\xef\x22\x95\x8b\x41\x95\x0f\x12\xf9\xed\x21\x78\x45\x7e\x21\x8a\xea\x4b\x21\x57\x22\x1b\xe5\x55\x95\xff\x57\x21\x16\x75\x3a\x2b\x6c\xf1\x6d\x5d\x88\xb2\x94\x79\x66\xcb\x2c\xce\x57\xeb\x59\x25\x2f\x64\x2a\xab\x6b\xb5\xce\x30\xa9\xb3\xb8\x92\x79\xc6\x04\xff\x61\xd4\xa5\x18\x94\x55\x21\xe3\xca\x08\xba\x8e\x81\xea\xea\xdf\x66\x4c\x40\xc6\x7f\x5c\xce\x8a\x41\x05\x05\x48\xc8\xa1\x86\x12\x12\xac\x96\xb2\x0c\x64\xc2\x86\x2c\x19\xc8\xac\xac\x66\x59\x2c\xf2\x64\x30\xe3\xbc\x10\x55\x5d\x64\x83\xcf\xa6\x79\xc2\xc6\x4f\xc1\x88\xf3\xac\xac\x8a\x3a\xae\xf2\x62\x10\xcf\xd2\x74\x70\x25\xab\x65\x5e\x57\x83\x4c\x5c\x19\x20\x38\x64\xe2\xaa\x5d\x87\x00\x66\x75\x9a\x0e\x31\x33\xcd\x5f\x59\x06\x63\x78\xba\x07\x6f\xc0\xb8\x98\x95\xc2\xe0\xfc\x07\xf5\xa3\xdb\x64\x50\xa2\xb0\x0c\x03\x3c\x17\x31\xeb\x56\x4c\xb0\x85\x74\x0b\xa1\x48\xf8\x25\x87\x0f\x2c\x81\xb7\x56\xe2\x08\xcb\x83\x2f\x6a\x1d\x96\xa3\xa1\x0f\xc3\x40\xac\xae\xd7\x34\x58\x70\xd3\x74\x77\xc5\x10\xdd\xa6\x19\x12\xb0\x77\x62\x71\xf8\x6d\xcd\x8c\xbf\xec\xc8\xb0\x58\x85\xc6\xc4\xb0\xce\x9c\x32\x95\xb1\x60\x2e\x64\xdc\x32\xa6\x96\xc1\x2d\x83\x45\xfe\xc7\x8f\x8e\x61\x55\x96\xc1\xa3\x47\x06\x3c\xde\x0f\xb3\xc8\x90\x86\x6f\x18\xdc\xa9\x44\x59\xb1\xb2\x27\xcc\x82\x25\x50\x42\x4e\xdb\xcd\x23\x96\x38\x25\xba\xa1\x37\x12\x11\x2b\xb1\x6c\x41\x7b\x1c\x6c\x8f\xfb\x1e\x7c\x36\xcd\xd2\x29\xc4\x3a\x9d\xc5\x82\x8d\xfe\x72\x3f\x3a\xee\x6e\xf3\xd1\x19\x01\xc1\x4d\x45\xb6\xa8\x96\xa1\xf7\x84\x28\xfd\x06\x2e\x88\x96\x39\x0e\x3d\xee\x13\xd0\xbd\x27\x88\x58\x3a\xf1\x72\x56\xbc\xcc\xe7\xe2\x45\xc5\x5c\xfe\xe0\x1a\x25\xbe\x62\x25\x78\x2e\x64\x90\x38\x25\xbf\x11\x69\x29\x88\xd0\xb7\xc9\xd8\x13\xd9\x29\x51\x38\x25\x24\x8e\x40\xe1\x08\x48\x9c\x18\x19\x3d\xc6\x3c\x12\x2d\x68\xee\x0b\xb8\xcc\xe5\x9c\xbd\x41\xf7\x3f\xd1\x1a\xd1\x55\xc7\xba\x45\x07\x81\xb6\x68\x71\x13\x88\xf8\xaf\x7f\x11\x43\xe6\x05\x2b\xd0\x05\x89\x22\x90\x21\x7a\x6e\x20\x47\xe8\xb9\x50\x58\x16\x0f\x7a\xd4\x04\x16\x0a\xa1\x89\x98\x6e\x10\xb8\xd1\xbc\xd2\xef\x6b\xb8\x6e\x4f\x44\x35\xdf\x3d\x16\x1e\xfc\x5f\x88\x77\x73\x43\x88\xb1\x02\x4b\x47\x66\x73\xf1\xed\x2c\x61\x86\x63\x70\x1e\xda\x9e\x69\xaa\xf1\xdd\xe1\x19\x8e\x41\x87\xc6\x81\x49\x82\x22\x66\x45\xbc\x64\x23\x31\x92\x9c\x87\x6e\xc4\xdc\xb0\x30\x4d\x56\xa0\xe4\x50\x58\x68\x75\xeb\x48\xcb\xe3\xa0\x96\xad\x2f\x48\x52\xb3\x05\x73\x41\x72\xee\x77\xe3\xcb\x96\x0b\x38\x48\x74\x83\xbd\x67\x77\xd1\x96\x3c\x90\x44\x22\x42\xb3\xee\x47\x3f\x30\xd0\xb6\x6b\x1e\xa8\xc3\xda\xec\x52\x42\x6d\x79\x9c\xcb\x64\x6b\x2a\xe4\xa6\xf9\xd9\x34\xeb\x2d\xb6\x4b\x9c\x72\x57\x70\x28\xb0\xb0\xa5\xed\x41\x11\x7e\xe7\x74\x08\x74\x1c\x24\xcc\x01\x11\x7e\x20\x13\xf6\x3a\x2c\x54\xc7\x84\x7a\xdc\x69\xd0\x1d\xc8\xd6\xb9\x4d\x41\x22\x2b\x2c\x8f\xef\x5c\x83\xde\xa2\xb4\xf0\x9a\x43\x1d\x4a\xcd\x03\xd2\x34\x13\x27\x76\xd6\x75\xb9\x64\x3d\x95\x14\x49\xa0\xb6\xf1\x3a\xa8\x43\x19\xf0\xfb\x23\x24\x28\x38\x3c\xd8\xda\x1c\x91\xec\xda\xee\xf6\x75\xa3\xb1\xb4\xb1\x56\xb4\x0a\xa4\x6d\x07\xa5\x85\x86\x6b\x10\x47\xf4\xf0\xb4\x78\x0c\xb6\xb7\xf1\x06\xdd\x9b\x5e\x5f\xbe\x22\x3d\x06\x15\x48\xad\x33\x49\x5b\x26\x10\xc3\x12\x16\xb0\x86\x39\x8a\x5b\x6c\x02\x2b\x7c\x0b\x57\xf8\x45\xad\xf8\x78\x3f\xac\x4c\x53\x89\x52\x95\x9f\xe4\x57\xa2\x78\x39\x2b\x05\xe3\x1c\xe6\x21\xba\xa6\xc9\x12\xfc\x0d\x7e\x43\x17\x68\xc4\x1d\xae\x82\x75\xab\xfa\x2a\x0e\x4b\x5c\x3b\xeb\xfc\x8a\x89\x76\x63\xf6\x9c\xc3\x6f\x98\xc0\xda\x89\xb1\x64\x29\x2b\xd8\xd2\x89\x39\x2c\x1d\xc1\x95\xd0\x73\x58\x3b\x02\xd7\x4e\xdc\x73\xd2\x02\x4b\x26\xa0\xa2\xae\x1a\x13\x5c\x74\x4c\xe3\x22\x2e\x26\xb6\x9d\x4c\x83\x85\xb3\xce\xd7\x8c\x2b\x76\x19\x2e\x26\xee\xb4\x15\x22\xc3\x35\xa8\xc9\x0d\xe7\x91\x6d\xd7\x3e\xad\x84\x0b\x5a\x0a\x6b\x58\x3a\x25\x4a\x58\xe2\x4b\xb6\x84\x35\xac\xe0\x8a\xe0\x2f\x70\xe9\xc4\x10\xe3\xd2\x29\xa0\x46\x85\x53\x8e\xb5\xb5\xb2\x3c\x98\xe3\x62\x92\x4f\x21\xc1\x6c\x34\x86\x18\xe3\xa6\x71\xc3\xbc\x69\xb4\x79\x58\x4c\x72\xcb\x9b\x42\x8c\x7b\xe1\x55\xd4\x9a\x8c\x79\xd3\xc4\xdc\x34\x99\x8b\x78\xd5\x34\x57\x88\x6c\xe9\x94\xcf\xdd\xe8\xb1\x3f\xe6\xdc\x9f\x87\x49\xd3\xcc\x11\x13\xd3\x64\x7b\x6a\x44\xdc\x34\x4f\x11\xaf\x4c\xd3\x33\x17\x93\xdc\xf6\xa6\xdb\x93\x9e\xf9\xfb\x9c\x83\x47\x2b\xea\x0d\x0a\x8c\xa3\x94\x19\x9e\x01\xf6\x8a\xfb\xb4\xd1\x8e\x7d\x3b\xfa\x60\x0e\x31\xa7\x93\xb4\xed\x2c\xb0\x2c\x22\x55\x3e\x0d\xb3\x80\xd3\x3e\xd0\x85\xbc\x69\x98\x65\xd5\xb0\x70\xea\xac\x5c\xca\xa4\x62\x1e\xd7\x82\xb9\x45\xe3\x61\x4b\x61\xdd\x31\x57\xc7\x6d\x18\x41\x12\xe2\x3c\x10\x16\x9e\x29\x91\x7d\x51\xb1\xc5\x64\x6e\x59\x53\xce\x03\x81\x29\x13\x50\xf3\x9b\x56\x8d\x89\x0d\x2f\x7e\xba\xcf\x8b\x25\xf1\x22\x1d\x51\x85\x9a\x68\x15\xd9\xd9\x0a\x5c\x78\x06\x12\x2e\x79\xe4\x36\x95\xff\x05\x86\xa4\xce\x3b\x80\x4e\x95\x9f\x6b\xd5\xa3\xce\x3b\x27\x5d\x3f\x71\xa7\x64\x82\x1d\x01\x04\x86\x6c\xf0\x12\x0b\x26\x14\x63\xa1\x77\x80\x28\x9b\x66\xbc\x87\x28\x4d\xf3\x97\x10\xcb\x28\x61\x4b\x28\xb9\x9f\xaa\x9f\x5e\x21\x08\xfc\xc0\x5a\x93\xcd\x09\x53\xe2\x37\x82\xd9\xc3\x22\xc6\x68\xd5\xce\x6d\xa0\xac\x0e\x31\x6b\x9a\x5f\x42\xac\xb9\x56\x0c\x41\x16\xc6\xc1\x52\x09\x2c\xc4\xa4\xf1\x96\x48\x8b\xd6\xad\xc0\x92\xe3\x60\x63\x09\x4b\x4c\x55\x2b\x69\xb6\x30\x56\x96\xc7\xb6\xb3\xd0\x55\x07\x47\xd3\x1d\x23\xc8\x6c\xbb\x85\xc4\x83\xcd\x6c\x0b\x6b\x3b\x86\x6e\x68\x6d\x79\x88\xb1\x69\xb6\x73\xf8\xad\x49\x3d\xe5\xca\xe7\xae\x69\xe6\x91\x61\x1b\xd6\xd2\x5f\x6e\x4e\xe6\xdb\x1d\xaf\x0a\x5d\xad\xa0\x99\x20\x56\xd3\x5a\x80\x9e\xa0\xea\x5c\x1a\x7a\x0b\x2c\x4b\x3e\xef\xc4\x3a\x50\xb8\x17\x7d\xbf\x9c\x72\x18\x16\x4e\xc9\x7f\x54\x58\x04\x17\x85\x98\x7d\xb9\xc9\x1c\xf2\xb7\x58\x05\x05\xc1\xac\xb0\xe8\xb9\xa4\xda\xe0\x72\xd4\x72\x49\x41\x7c\xa2\xbb\x59\x16\x8a\xa6\x11\x61\xd5\x34\x62\x88\x31\x13\x9c\x93\xae\x2f\x80\xc9\xa6\x31\xe6\x22\x96\xab\x59\x3a\x50\x1a\xa8\x34\xb8\xd5\x0f\x8f\x8c\x01\xf9\x75\x79\x32\x28\x66\xd9\x42\x18\xbe\x31\xc8\xf2\x6a\x30\xcb\x06\x32\xab\xc4\x42\x14\x06\x27\x1f\x65\xb8\xa5\x2f\x8f\xf5\xea\xfa\x0c\x89\x1e\x05\x7a\x20\x31\xeb\xe5\x21\x9b\xd8\xb6\x9c\x06\x59\xa7\x71\x94\x11\xc0\x6c\xe2\x4e\x7f\xe6\x07\xd0\x46\xad\x6a\xf7\xda\xf6\x78\xf8\x3d\x12\x4e\x4c\x3c\xa5\xd8\xdd\x7f\x1d\x56\xaa\x61\x22\x94\xea\xf6\x19\xfd\x56\x40\x4d\x19\x87\x2d\xd1\x39\xe9\xd0\xd2\x28\x11\x91\x0f\x8b\x22\x2f\xd8\xc4\xa0\xe7\x5f\xe4\xe2\x54\xbb\x33\x60\xc4\xab\xb5\xa1\x9c\xdc\x44\x2e\x0c\x30\xe6\xf2\x52\xff\x7d\x9f\x1f\x67\x95\x01\x86\xf8\x6a\x80\xb1\xa8\xd4\x1f\x61\x80\x91\x56\xea\x0f\x3d\xae\x64\x56\x97\xf4\x9b\xcf\x0d\x30\xd6\xa9\x7a\x59\x17\x22\x96\xe4\xc0\x1b\x60\x14\xb3\x6c\x9e\xaf\xe8\x21\xaf\x33\x1a\xa3\xf4\x86\x01\x46\x25\x57\x82\x06\x57\xf9\x2b\xb9\x90\x95\x7e\x3c\xfc\xb6\xce\x33\x91\x55\x72\x96\xaa\xf7\x23\xf9\x4d\xcc\xf5\x53\x5e\xac\x66\x95\x7e\x2c\x66\x6a\x8b\xb4\x52\x7e\xa5\x9a\xde\x6e\xad\xd8\xc9\xba\x01\xc6\x66\x93\xd3\x89\x98\x5a\x06\xe3\x03\xc3\xca\x2c\xc3\x1f\x18\x56\xc5\x83\x6a\x59\xe4\x57\x83\xc2\xc9\x66\x2b\x81\x9b\xc1\x9a\x4e\x06\xbc\x41\x17\x8a\x0d\x41\x3f\x74\x5c\xa6\x49\xda\xc7\x11\x90\x42\x0c\x33\x52\x29\xb0\xc4\x77\xa4\x5f\x66\xfc\x87\xf0\xb5\xad\x47\x72\x4e\x67\x74\xd4\xa5\x3a\xea\x52\x1d\xb5\xf2\x67\x94\x22\xca\x6c\x09\x6e\x98\xf3\xdc\xc2\x6b\xa8\x31\x83\x04\x67\x93\x14\x5d\x32\x0c\xc9\x68\x39\x91\x76\x6d\x7b\xd3\x1d\xcf\x6d\xdc\x5e\xe7\xa4\x38\x67\x2c\xb7\x3c\x3e\xba\xe6\x90\x86\x38\xeb\xcc\x9e\x72\x0d\x0b\xae\x24\x67\x20\xb4\x13\xd0\x75\x3e\xc7\x34\x98\x69\x17\xc0\x25\x1e\xc4\x58\xb9\xa2\x1e\xe4\x3b\x6a\xe5\xdc\xbe\xb6\x3c\xed\x60\x6a\x7d\x4e\x68\xa7\xe4\xcc\x78\xf7\x51\xdf\x9a\x23\x21\x46\x37\xac\x23\xd7\xbf\x83\xee\x8d\x92\xed\x82\x6c\x5e\xd6\xd9\xbc\xd9\x24\xb5\xc8\x48\x31\x9a\x91\xf8\xc9\x4e\x37\x83\x5c\xaf\xbd\xb0\x8a\x58\xdc\x34\x45\x6b\x01\xab\xa6\xa9\x10\x99\xd8\xb2\x80\x71\xf8\xa4\x69\x9e\x68\xad\xb5\xa7\x46\x14\xca\x02\x92\xd7\x91\x87\x6e\x54\x87\x6e\xd4\xa2\x31\xf5\x5d\x7f\x36\x49\x09\xf6\x8e\xe7\x9a\xde\x36\xb0\xce\x32\x66\x4d\x33\x9c\x6d\x4c\xff\xa0\xa3\x15\x9d\x7b\x44\xca\x56\xa8\x60\x8b\x86\xe0\x72\x92\xed\x5c\x4f\x81\xa4\xcd\xce\x9a\xc6\xe5\xbe\x6a\x56\x52\x08\x42\xb9\x0c\x88\x79\xc4\x7a\x18\x29\x94\xe8\x41\x6a\xdb\xdc\xdf\x6a\xb4\x88\x1f\x96\x93\x6b\x3b\x9f\x02\xd1\x17\x09\xe5\x15\xeb\x90\xde\x59\x4e\xea\x29\xdf\x2d\x7d\x97\x43\xa1\xb4\x74\xa0\xb5\xa4\x8b\x98\x6a\x0d\x93\xa3\x07\xb5\x66\xa9\x5a\x9d\x4b\xad\xce\x25\xdf\xb8\xc8\xd4\x67\x61\x49\xeb\xdf\x1a\x52\xaa\xa3\x1b\x62\x49\xda\xd9\x11\x96\xa5\x77\x86\xa7\xa6\xc9\xd4\x13\x19\x73\xad\x76\x89\x89\x27\xa9\x82\x42\xbf\x43\x3c\xd5\x5c\x15\x10\x49\x6d\x72\x05\x4a\xf4\x6e\x34\x3a\xb3\x2d\xe7\x0a\x67\xca\x65\x20\x4e\xd3\xba\xee\x46\x38\xe2\xae\x0a\x13\x8e\x78\xfe\x5a\xe1\xd0\xab\xb1\x2d\xdb\x4f\xb2\xf5\x52\xc9\xde\x7b\x9c\x39\xeb\x22\xaf\x72\x0a\xb7\xe0\x6b\x6b\x27\x3c\x0e\x6f\x71\xec\xc2\x17\xdc\x83\x5f\xd0\xde\x87\x47\x38\xf6\xe0\x35\xda\x9e\xd8\x87\xef\x48\x7f\x3f\xe3\xd0\x85\x5f\xf1\x08\x7e\xc7\xa1\x07\x7f\xa0\x07\xbf\xa1\xe7\xba\xf0\x27\xfe\x68\x35\xff\xb9\x58\xcf\x8a\x59\x95\x17\x3e\xb9\x9f\x8b\x22\xaf\xd7\x5b\x4d\xd0\x35\xc9\xef\xc2\x7f\x0c\xa5\x88\xf3\x6c\x3e\x2b\xae\x5f\xf7\x8d\x2e\x24\xad\x12\x7a\x7d\x67\xee\xc0\xb8\xd3\xa5\x86\xdf\x04\x3d\x8b\xcd\xb2\xbc\x5a\x8a\x02\x33\x98\x39\xef\xce\x3e\x9c\xbe\xfa\xf4\xe1\x2d\xba\xfd\xcb\xab\xb3\x3f\x4e\xd1\xeb\x5f\x5f\x1e\x1e\x9f\xe0\xb8\x7f\x3d\x3a\x39\x3b\x7b\x87\x8f\xfb\xf7\x5f\x5f\x9c\x1c\xd1\xfc\xbd\xdb\x2d\x0a\xc8\x93\xdb\x6d\x87\xbf\x1f\x9e\xe2\xd3\xdb\x6d\x0a\xfa\xfe\xed\x36\xbd\xc4\x33\x98\x39\x87\x1f\x5e\x9e\x1c\xbf\xc2\x03\x98\x39\xda\x36\x60\x9f\x7a\xd1\x2a\x50\xe9\x43\x12\x16\xfc\x71\x03\x12\x67\xc5\xa2\x5e\x89\xac\x22\xce\x93\xe4\x5e\x25\xc4\x6a\x46\x7e\xf1\x59\xc4\xd5\x26\x6a\x2e\xa3\x2d\x30\x2d\x59\x4a\x67\x39\x2b\xcf\xae\xb2\xb7\x45\xbe\x16\x45\x75\xcd\x32\x1e\x69\x95\xc1\x04\x96\x93\x6c\xca\x7d\x0a\x86\x07\xee\x8d\x7f\x7f\xb2\xec\xd2\x08\xd5\x66\x8e\x9c\x54\xe4\x5c\x76\xb3\xfa\xf8\x9a\x65\x68\xbc\x3a\x7c\x79\xfc\xe6\xc5\xc9\xa7\xb7\x27\x2f\x5e\x1e\x9e\x1b\x9c\xfc\x47\x01\x2e\x1c\xc2\x18\x32\x52\x3e\x6f\xd1\x6d\x28\x1a\x9c\x64\x53\x7c\x0b\x6a\x8e\x22\xd0\xf1\xe9\xeb\x4f\x6f\xce\x5e\x1d\x6e\xa6\x3c\xeb\xa6\x7c\xd9\x9a\xf2\x45\x4f\x39\xfc\xf3\xed\xd9\xe9\xe1\xe9\xfb\xe3\x17\x27\x9f\x5e\xbc\xa7\x39\xe4\x1d\xf1\xe8\x57\xe5\x0a\x81\x7d\x08\x6e\x3b\x9b\x5a\xbc\xe9\x36\x06\xbf\x10\x38\x1a\xf5\x48\x3d\x78\x53\xee\xd3\x82\xf6\xe1\xf6\x10\x9b\x51\x2f\x73\x43\x11\xd9\xc2\x17\x9c\xf3\x16\x81\xc9\x2f\xf0\x68\xda\xe2\xfd\xe2\xf4\xf5\xe1\x43\x6b\xdb\xde\xed\xc5\xbd\x0d\xe4\xd7\xdd\xe2\xdf\x7f\xba\xb8\xdb\x88\xe8\x35\xda\xec\xfb\x6d\x04\x7c\x9d\x31\x83\xcc\x32\x06\xf1\x2c\x23\xcf\xe9\x42\x0c\xbe\x8b\x22\x37\x40\x6c\xd0\x7b\x0d\xdf\x5b\xf4\x0e\xdf\xbd\x3b\x7b\xa7\x8e\x80\x09\x44\x1c\x0e\x45\xd3\x78\x88\x28\x9a\x86\xb4\x89\x88\x18\x29\x82\x5f\x91\x7d\xa6\x3e\x1e\x1d\xf9\xf9\xd6\x22\x57\x04\x54\xc3\xfc\xac\xe1\xbd\x7c\xf7\xdf\x6f\xdf\x9f\xfd\x3b\x78\xbf\xe3\x90\x51\xeb\x70\xd9\x34\x1d\x6b\x0e\x3b\xd6\x5c\x72\x10\xa6\x39\xfc\x5d\xe5\x07\x68\x0d\x23\x2e\xae\xd7\x55\x3e\xa8\xb3\xd9\xe5\x4c\xa6\xb3\x8b\x54\x18\xb0\xe4\x0f\xe3\xf0\xbb\xc6\xe1\xcd\xd9\xab\x0f\x27\x67\x77\x18\xe5\xa0\xa3\xdc\x1f\x5b\x8c\xf2\x87\x9e\xf0\xf6\xec\x8f\x4f\x6f\xdf\x1d\xbe\x3c\x3e\x3f\x3e\x3b\x7d\x80\x1d\x7f\xdb\x9a\xf2\x9b\x9e\x72\x74\xf6\xee\x4d\xcb\x53\xf7\xe4\x4b\x44\x7f\xa2\xd8\x3e\x89\xd6\x81\x6d\xc7\x6d\xf0\xfd\x13\x8a\x1b\x98\x39\xab\xd9\x37\xbc\x2f\x54\xdf\xd8\x46\x9c\xdf\x3b\x69\xc5\xd5\x50\x99\xfd\xc7\xa1\x0b\x3d\x54\xfb\x7d\xf7\x34\x06\x1e\xb8\xee\xbe\x77\x70\x30\x7e\xb2\xb7\xbf\xe7\x1e\x1c\x8c\x21\xc3\x37\xb3\x6a\xd9\x8e\x67\x7c\x57\x98\x63\xf7\x60\xdf\x7b\xe2\x3d\xa0\x26\x56\xec\xce\x58\xfe\x90\x3e\x78\xf6\xf8\xd9\xb3\xa7\xee\xb3\x5d\xe6\xb9\xfb\x8f\xf7\xf7\xbc\x67\xe3\xbd\xdd\x5b\xf3\x1a\x97\x5b\xac\x1b\x75\xb7\x67\xa3\x2b\xb6\xf2\xcc\x77\x92\xc7\xe8\x42\x82\x93\x29\xa4\xad\x4d\xfa\xaa\xbc\x39\xd1\x06\xa4\x62\x73\x82\xde\x1e\xc5\xa3\xc2\x7f\x0b\x39\xce\x99\x20\x87\xed\x77\x2e\x13\xb6\x34\xcd\xa5\xb3\x10\xd5\x3b\xb5\xee\xef\xb3\xb4\x16\xa5\x36\xef\x15\xde\xeb\x50\x01\xe6\x07\x99\x55\x8f\xc7\x2f\x8a\x62\x76\xcd\xf2\x5d\x1c\x73\x1e\xe4\x61\x19\xf0\x1a\xbd\xc7\x9e\xbb\x3f\xde\xad\x26\xe5\xd4\x62\xd5\xa4\xb4\xbc\x69\x18\x86\x9e\xc7\xa1\x0e\xf1\x40\x78\x4f\x22\x56\xfc\x0d\xa0\x63\xce\x81\x60\x60\x41\xa2\xaf\xe1\x60\xa1\xa4\x9f\x25\xda\x71\xac\x77\x3c\xe1\xed\x71\x28\x2d\x1c\xf3\xa0\xc4\x7c\x34\xee\x83\x4b\xb5\x23\x4d\xc6\x5f\xae\xab\xed\xdd\x6c\x35\x12\xe6\xfb\x3d\xe2\xe3\x67\xde\xde\xfe\xde\xc1\xfe\xd3\x7d\xcf\x7d\xfa\xe4\xe9\x2e\x7b\xec\x99\x84\x01\xb7\x3c\xf7\xe0\xe0\x89\xe7\x3d\x1d\xef\xef\xef\x3f\xdd\xd5\xb8\x58\x7b\xe3\x83\xbd\x83\xa7\xfb\xe3\x03\xdd\x32\x9e\x5a\xde\xd3\xfd\xfd\xfd\xb1\xa7\xdf\x1f\xb7\xbb\xdf\x9b\x3e\x7f\xee\x3d\xe5\xfa\xe5\xc9\xf4\xf9\xf3\x67\xdc\xa2\xc7\xa7\xd3\x9e\x1e\xb7\x71\xda\xe7\x4e\x9c\xaf\xaf\x59\x45\xe1\xfd\x03\x5b\xdd\xd7\x5b\xdd\xd7\x5b\x55\x72\xe5\xed\xfd\x4c\x33\xa8\x74\x52\xa9\x3d\xb7\x76\x9b\x19\xe3\x40\xcb\x86\xb5\x69\xb2\x64\x52\x5a\xd6\x14\x5b\xf0\x81\xf6\xa0\x92\x89\x6d\x97\x53\x10\xe4\x55\xe7\xa6\x29\x48\x5b\xe3\xbb\xc9\xb5\x2d\xa6\x90\xd0\x91\xac\x58\x3e\xaa\xf9\x6e\xcd\x95\x8f\x45\x4d\x41\xa2\x3d\x2c\x28\x6d\x9b\xeb\x84\x55\xc9\x13\x9c\xc8\x3e\x2b\xa9\xc3\x0f\xdb\x6b\xa7\xb8\x34\x45\xe7\x6c\x38\x48\x1b\xaf\xf5\xe2\xa5\xf2\x26\x93\xbb\xde\xa4\x72\x15\xaf\x43\xf2\x14\x69\xac\x5d\xf6\x0e\x5a\xea\x08\x94\x90\x3a\x31\x26\x90\xde\xdc\x30\x0e\x2f\xb7\x85\xbc\x8f\x96\xc4\xad\xf0\xf3\x96\xe0\x74\xf1\x3f\x89\xcf\xce\x0b\x88\x31\x1b\xbd\x68\x74\xfa\x40\x60\x9f\x80\x0f\x12\xdb\x0e\x78\x8e\x62\x92\x4c\x77\x5e\x40\xad\x1e\x68\x20\x14\x18\xef\xe6\x56\xbd\x9b\x82\xc4\x74\x37\xb7\x8a\x9d\x17\xbb\x2f\x2c\xf2\x3a\x98\x1c\x55\x4a\xb8\x0b\x1a\xc8\xad\x78\xb7\x06\x9a\x86\x72\xa7\xea\xc4\xba\x34\x4d\xd1\xa7\xaf\xca\x5b\x21\x73\x76\x2f\xc2\x53\x79\xa6\x21\x16\x3c\xc7\x2a\x2c\x22\xcf\xb7\x3d\x1d\x86\x69\xea\xe6\xe8\x06\x55\x28\x55\x7e\x9a\x14\xc0\x44\x4e\x87\x98\x4d\xe4\x94\xff\x20\xc4\xe5\x34\xa4\x17\x3d\x4d\x3b\xd6\x2d\x12\xf9\x66\xd1\x62\xb3\x68\x97\x40\x90\x04\x96\x76\x2f\x26\xd5\xd4\x46\x09\x12\xe9\xe9\x79\x36\xa9\x08\x98\x0b\xf4\x86\x72\xb7\xb0\xd4\x00\x6a\xd6\xc1\xde\x90\xcc\x36\xed\xaf\xbb\x57\x09\x44\x77\xe6\x3c\xb8\xb9\xab\xd7\xfa\x08\x56\x6f\x37\xdd\x24\x79\xe1\x0a\x2e\xe1\x02\xce\xe0\x1c\xde\xc1\x0b\x38\x84\x57\xf0\x09\xbe\xc1\x11\x4a\xa7\x44\xcc\x9d\x52\x6d\x09\x8e\x51\x3a\x31\x9c\x60\xee\xc4\xfa\x1e\xed\xd8\x34\x8f\x15\x06\x27\xa6\x79\x42\x81\x55\x17\x59\x69\x35\x29\x9d\xd2\x34\x73\xfa\xc3\x8e\xa3\xe1\x49\xd3\xd0\xe0\x21\xd2\x48\xff\x84\x47\xc7\xa6\xe9\x22\x52\x5b\xd3\x0c\x4f\x22\x77\xf7\xc8\x3f\x1a\xb9\xbe\x3b\x72\x35\xaf\x5e\xb6\xda\xf6\x88\xc3\x05\x5e\xea\x5c\x7b\x8c\xd2\x11\x76\xee\x08\x38\xc2\xda\x8a\x2d\x0f\x92\xa6\x61\x09\x9e\x42\x8c\x15\x93\x0e\xa9\x5c\xbb\x62\xb9\x7a\x80\x23\x3c\x1a\x5d\x37\x2e\x87\x25\xba\xc1\xc9\x64\x39\x45\x64\xc7\x93\xe5\x94\xe2\xb9\x60\xd9\x06\xe5\xd4\x1e\xf6\xcd\xa6\x19\xdb\x36\xb8\xe1\x11\xbf\xd0\x9a\xc1\xe3\xb0\xc0\xa1\xbb\x11\xb2\x43\x3c\xee\x18\xfa\x13\x9e\x74\x8f\x14\x44\x1e\x59\x38\x86\x35\x52\x78\xc7\x68\x93\x96\xc7\x39\xac\x43\xcf\x34\xd9\x09\x0a\x76\x02\x6b\x48\x38\x1c\xa3\x60\xc7\xfa\x71\x6b\xfe\x06\x2a\x87\x17\xf8\x09\xce\xf0\xb8\xbf\x2a\xf8\xc4\xe1\x1c\xcf\xba\xb0\xeb\x53\x78\x1e\x9c\x4d\xce\x49\xad\xb8\x3c\xf8\x86\x27\x9d\x04\xc1\xb7\x9e\xcf\x5d\x0e\xaf\x14\x9d\xe1\x64\xe2\x4d\x43\x4c\x46\x63\xd3\x7c\x65\x59\xc1\x3c\x1f\xac\xd1\x25\x49\x64\x27\x70\x06\x9f\xe0\x9c\x83\x1b\xa6\x11\x7b\x87\x67\x34\xfc\xd3\x10\xcf\x4d\x93\xbd\xc3\x77\xbb\x89\xc5\xce\x26\x9e\x22\x0a\x57\xbb\x7a\x37\x7a\xa5\xb6\x13\xb1\x75\xa8\x92\xd2\x6b\x4c\x6c\x8f\xc3\x7c\xb3\xb7\x2b\x9c\x77\x1b\xda\x60\xac\x56\x9b\xc3\x19\x5c\xd1\x6a\x1e\x62\x4a\x73\x6d\x1b\x0a\x36\x87\xab\xf0\x53\xf4\xcd\x3f\x81\x2b\x48\x38\xe7\x3e\x05\xbe\x6b\xd3\x64\x29\xae\x51\x81\xee\x77\x77\x1b\x78\x78\x65\x9a\xf3\xed\xed\x16\xec\x0c\xe6\x70\x4e\x48\xd8\xed\x12\x77\x30\xe8\xf7\xeb\x85\x0a\x01\xcb\x52\x93\xce\x5b\x04\xce\x15\x02\x5b\x68\x73\x9f\x34\x69\x37\xf4\x0c\x55\x76\xf3\x62\xb2\x24\xc2\xaf\x21\x35\x4d\x22\x58\xd4\x9e\xc4\xf1\xe4\x05\x51\xca\x67\x67\x38\xa1\xe7\x29\x9c\xa3\xc7\x83\xab\xa5\x4c\x05\x63\x2f\x2c\xeb\xf9\x61\x97\x14\x39\xd3\x09\xd3\x23\x52\xe4\x0b\xdc\xb4\xc1\x85\x92\x84\x8b\x4e\x82\x29\x28\x4f\x10\x4f\xb5\x9e\x58\xa2\x07\x47\x48\x43\x82\x23\xa5\xb8\x8f\x94\xe2\x56\x4c\xfc\x81\x5d\x42\x6d\xb1\x4b\x47\xe0\xd2\x8a\x55\x1a\xd1\xf2\xa0\x84\x45\x9b\x49\xa6\x8e\x18\x2e\x9d\x02\xad\x45\xa7\x16\x2f\x95\x2e\xbf\x1f\xe2\xe1\xe8\x2f\x66\x47\xdc\x65\x93\x6f\x17\xf9\x94\xb3\x8f\x57\x93\x8f\x57\xce\x74\xf7\x11\x1f\x49\xc8\xa8\x77\xf2\x97\x33\xb5\xf8\x47\xe7\xd1\x08\x2a\x1c\xfd\xf5\xd1\x69\x5b\x1e\x8d\xa0\xc0\xd1\x5f\x76\xc4\x8e\xb3\x44\x66\xb2\xba\x6e\x4e\x67\xa7\xd4\x2c\x69\x58\xb9\xfb\xd1\x62\x0a\x16\x6f\xfe\xfa\x58\x5a\xcd\xc7\xd2\x7a\x34\x5a\xdc\xf3\xbe\xee\xea\x28\x2c\xa3\xda\xaf\xfb\xeb\x23\x09\xc6\x23\xcf\x50\x82\x5b\xe8\x4b\xd1\x98\xf3\xdc\x29\x51\x96\xa7\xb3\x53\x16\xeb\x38\xd2\x77\xc3\x38\xb2\x3d\xdf\xeb\xaf\x3c\x86\xa4\x85\x62\x8c\x7b\x40\x02\x36\x0e\x9f\xb6\x5c\x9d\xc5\x43\xe3\x9b\x81\xc8\x2a\xac\xee\x5c\x6b\x45\xde\x53\xdf\xb8\x20\xcf\x3b\x1a\xfb\xcf\x20\x31\xcd\x64\x88\x69\x24\xfc\xec\x86\xd3\x1b\x4b\x31\x81\xed\x35\x32\x8d\x6c\xff\x5e\x81\xe1\x3a\xd4\xc2\xa1\x1e\x62\x7c\x47\x5d\xc6\x90\xf2\xe0\xb3\xbe\xa2\x34\x94\x13\x6f\x58\x2c\x89\x8c\xc1\xc5\xac\x14\x03\xc3\x4a\x7c\xc3\xe0\xe4\xdf\xb7\x79\xdc\x9a\x03\x6d\x9c\xf6\x7b\x93\x3b\x31\xe6\x6d\xc2\x05\xde\xa0\xab\x4e\xf7\xbd\x33\xbb\x28\xf3\xb4\xae\x84\xf2\x01\x51\xbd\xdf\x3f\xf1\xf6\x1e\x6e\x29\xcb\xbb\xf7\x00\x4c\x38\x25\x89\xa1\xb8\x81\xf7\x4e\x2c\x64\xfa\x40\x34\xd0\xdd\x87\xa8\xf9\x40\x7f\x55\x12\x6d\xcc\xd5\x9c\x7c\xb5\x9e\x15\x62\xfe\x3e\xc7\xf7\x4e\xbc\x5a\xe3\x36\xcd\x7b\x10\x6f\xd0\x03\xa9\x00\x6c\x15\x56\xa8\xf9\x6d\xfa\xe6\xad\xca\xdb\xe3\x7b\x67\xbe\x7e\x28\x27\x51\xa8\xd2\x8e\xd6\x28\x15\x3d\x51\xeb\x34\xd5\x6e\x3a\x63\x19\x16\xdd\xdd\xa2\x47\xf6\x41\xa3\x39\xba\xe6\x7c\xf7\x1a\x32\xa4\xf0\x48\xfb\x70\xd9\x8e\xe7\x22\xba\x41\xa6\xa4\x4b\x90\x8c\xb6\xe0\xdc\x50\xa8\x28\xd3\x6d\xc9\x31\x97\x97\x72\x2e\xe6\xbf\x5c\xa3\x7a\xfe\xd9\xce\x1e\xc3\xcb\xbb\x3b\x83\xb7\xf0\x85\x6f\x81\x50\x69\x77\xb1\x10\x45\x07\x4b\x35\xfc\x0c\xe0\xde\x03\x00\x5d\xf0\x14\x40\xf1\xb5\x9e\xa5\x44\x27\xf1\xf5\x67\xd3\x9f\x00\x69\xb5\x87\xa9\x9d\xa4\x79\x5e\xfc\xfd\x23\x7e\xac\x26\x2d\x0a\x31\xab\x44\xf1\x7e\x39\xcb\x90\xa2\xc1\x9f\x2d\xfc\xf4\x81\x23\x0e\xdd\x3b\x10\xce\x8a\x43\xda\x82\x62\x97\x45\x25\x7e\x06\x6b\x9f\xac\x08\xb2\xec\x81\x7d\x70\x1d\xf9\x67\x04\x58\x96\x47\xa4\x87\xc4\xfd\x2d\x0d\x87\x9a\x63\xf4\xa8\x96\xfc\xd8\x3e\xff\x7c\xb8\x69\x6e\xb1\x4e\xa8\xdb\x3a\xbe\x1a\x6b\x58\xa7\xb3\xd3\x07\xe6\xab\xa1\x65\x3b\x42\x2c\x66\x95\xbc\x14\xd8\xbe\x3c\x40\x70\x3d\xfc\xb9\xab\x27\xfc\x8f\x28\xf2\x7f\x87\x93\x8b\x2d\xff\x4f\xdc\x29\xcd\x48\x45\x59\xb6\xc7\x91\xfe\xf4\x38\x9e\x3d\x70\x1c\x7a\xc1\x6e\xfa\xf6\x59\xa4\x3f\x3f\x8b\x03\x65\x6f\xff\xf3\x61\xa8\x9b\x23\x7c\xef\x94\xf5\xc5\x1d\x50\xb7\x23\x06\x05\x23\xc1\xd2\x51\xb5\x5a\x6f\x94\x18\xe2\x16\xaf\x67\xaa\x96\x67\x98\x34\xcd\x30\xbb\xad\x3f\x95\xe3\x48\x46\x73\xb8\x29\xb0\x22\x05\x66\x67\x50\x3a\xeb\xb4\x2e\x99\xe0\x81\xb2\x2a\xa8\x4e\x10\x54\x8e\x7a\x74\x0d\x4b\x2c\x9d\x18\x16\x28\x5a\x15\x92\x36\xcd\x50\x5f\xb4\x0e\x97\x4d\x33\x5c\x74\xc0\x96\x11\x6b\xe1\x09\xee\xeb\x35\x17\x51\xe9\x77\xeb\x0e\x97\xda\x95\xdd\xaa\x2e\x18\xd0\xf3\xfd\x59\x34\x30\x2a\xfd\xc7\x88\x5f\x22\xdb\xf5\x5d\x65\xeb\x53\xac\x58\xca\x95\x1f\xab\xee\xa4\x97\xbd\x5f\x97\x60\x6a\xc7\xda\x0d\x60\x35\xba\x61\xc2\x23\x96\xa0\x9d\x40\x8e\x4b\xee\xb3\x18\x53\xc8\x71\x41\xd6\xa0\x10\x97\xa2\x20\x5b\x05\x19\x26\xea\x82\x37\xdf\xdc\x01\x6d\x75\xdf\x6c\x05\x35\xac\x46\x96\xf4\xb7\xd6\xfc\x39\xcb\xfa\xbb\x7d\xce\xa3\xc4\xcf\x20\xc1\x0c\xdd\x40\x86\x59\x90\xe9\xc0\x67\x39\xc9\xa6\x43\x5c\x90\xd6\xfc\x51\x23\xbd\x3d\xa7\x97\xcd\x65\x02\x85\xbe\x39\x92\x57\xbc\x80\x05\xe6\xa0\x08\x20\x9c\x92\xf0\x62\x72\x03\xdf\x56\xa9\x8a\xce\xef\xed\x6e\xaa\xf5\xcd\xf4\xa4\x68\x5d\x5c\x6a\xca\xf0\xd4\xf6\x02\x19\x26\xfa\x7a\x64\xa9\xae\x58\x9f\x2f\x54\xe8\xa5\x0b\xad\x64\x50\x98\xe6\x90\x3a\x8a\x29\x4d\x9e\x62\xc6\x03\xdb\xa6\x27\x58\x4e\xe4\xd4\xc2\xd3\x1b\xfa\xb5\x91\x66\xa9\xbb\x0c\x0a\x95\xe9\x28\x82\x65\x1f\x29\xdb\x76\xdc\x6b\x7c\x75\x4a\xc7\x4c\xc0\x12\x62\xee\xab\x43\xd4\x27\xe6\xf9\x1e\x6c\x5d\x66\x80\x50\x8a\x70\x95\xcf\xeb\x94\x84\x65\x95\xcf\x1f\xe0\x70\x7d\x6b\xae\x6a\x10\x37\x66\xcf\xbb\xcd\xdb\x43\xe9\xc4\x4d\x33\x14\x4e\xd9\x34\x82\x44\x7b\xa8\x0b\x17\xa2\x0d\x83\xfb\xd4\xd4\x34\x52\xf5\xca\xed\x5e\xc9\x7d\x76\x80\xf8\x47\xc4\x0a\x25\x22\xca\x76\x43\x85\x2f\x99\x04\x01\x2e\x3c\xe6\xaa\xa9\x80\xca\x29\x77\xb1\xe0\xfe\xa6\xeb\x0f\x0e\x52\x0b\x28\xab\x1c\x75\x51\xcb\x04\xd7\x36\x21\x23\x6d\x25\xe6\xa8\x9e\xfe\xae\xef\xa0\xce\x5a\xfb\xbb\xda\x58\x92\xf4\x91\xfb\x31\x7f\x88\x32\x1d\x5d\x20\xa7\x78\xb3\x95\xfa\xf1\x83\x52\x9f\xff\x5c\xea\xf3\xfb\x52\xdf\xed\xa9\x15\xfb\x1a\x55\x7c\xa8\xab\x40\x46\xd7\x90\xa8\x70\x36\xed\xc5\xbe\x6e\x9a\x61\xa9\xc5\x9e\xb4\x4b\x7a\x7b\x9d\xbc\x93\xf2\x44\x4b\x79\xba\x25\xe5\xf4\x4c\x6e\xa0\x1a\x48\xfd\x91\xf4\xdd\xdd\x5c\x89\x75\x8d\x15\xab\x39\x29\x36\x56\x92\x28\x27\xbd\x58\xe7\x58\xdb\x6d\xde\x2c\x0f\xdd\x88\x95\x58\x43\x81\x29\xf7\x59\x8e\x76\x0e\x05\x26\x1c\x8a\x8d\xcc\x06\xb9\x6d\x07\xc5\x46\x9c\xb7\xba\xda\x9b\xb9\xa4\x0b\x77\x32\x4c\xbb\x47\x37\xcc\xed\x4c\xd5\xdd\xa5\x40\xee\x69\x82\x05\x64\x98\xd3\xea\x6e\x90\x05\x3c\x47\x96\x4c\x6c\x3b\x9b\x62\x32\xc9\xa6\x56\x4a\x7f\x72\x3e\x3a\x6d\x5c\xa0\x86\x1d\x3c\xed\xce\x35\x37\x4d\x96\xf4\x21\x57\xce\xc1\xb2\x4a\x0e\x24\x1f\x09\x94\x8a\x57\xfa\x3a\x00\x52\xf3\xdb\x27\xad\xcf\x59\x65\x3d\xf4\x49\x4b\x2c\x34\xd1\xfb\x0c\xaa\x18\xaa\xf4\xbd\x69\x7a\x43\xa4\x77\x57\xff\x30\x9d\x7f\x7b\x0c\x46\x97\x73\x36\x54\x0a\x1e\xc4\x50\x0f\x6f\xb3\xb0\x9c\x84\xe7\xae\xe7\x57\xa1\xec\xbd\x3e\xc8\xb0\xda\xbd\xb6\x48\x20\xe4\xa4\x6a\xb5\x46\x50\xb5\xee\x5e\xa5\xdc\xbd\x8c\xdc\x3d\x9d\xc6\x94\xa4\x16\x2a\x15\x68\xb5\x7d\x14\x68\xf5\xb7\x96\xa6\x59\x90\x0b\x14\x12\x65\xc9\xb7\x14\x96\xc7\x41\x99\x39\x55\xf6\xf0\x90\xf8\x3f\x20\x2a\x4c\x57\x22\x89\xa6\xe9\xf3\xc7\x4f\x38\x37\xcd\x0f\xac\x82\x7f\xfd\x4b\x58\xbd\xa7\x75\xab\xc0\xd8\x85\x67\xe0\x3d\xd1\x95\x4f\x99\xff\x85\x43\x45\xeb\xaa\x53\xb9\x4f\xf2\x5b\x0a\x47\xdd\xea\x9c\xc3\x39\x78\x4f\xb7\xe8\xc9\xa3\xac\x95\x79\xc3\x13\x86\xa5\x6a\x67\x5a\x56\xce\x48\xcb\x64\x4a\xc9\x98\x26\xb3\xcf\x75\xd1\xcc\x39\xcd\x28\x77\xd5\x3d\x90\xeb\x7b\xa4\x94\x32\x75\xfe\xe5\xd7\x7a\x56\x88\x77\x79\x5e\x11\x03\x7c\x2d\xaa\x87\x9c\xf5\x7b\x76\x9e\x44\xb0\x74\x4a\x8a\xf4\x54\x21\xd5\x5b\x6b\x0f\x16\x2d\xb5\x0c\xd7\x79\xa2\x83\x3d\x62\x0b\xb2\xcb\x24\x99\xc9\x96\xe8\xe9\x71\x64\xb2\x5d\x15\xd6\xd3\x00\xd5\x1f\xb9\x23\xd7\x4f\xa2\x52\x21\x18\x28\xfb\xaa\x52\xff\x84\x17\x23\xce\x75\x15\xc0\x14\xd1\x1b\xb9\x11\x9d\x22\x4b\x38\xb0\xae\x8c\xc7\x8a\xf9\xce\x18\x55\x15\x63\xa6\x6b\xa4\x60\x1b\x40\xa6\x0d\x35\x8b\x2d\x8f\x8f\xc6\xdc\x66\x6e\x18\x37\x4d\xbc\x33\xa6\x61\x0a\x62\x86\x9a\x9c\x3e\x23\x69\xbc\x55\xea\xa2\xcc\x73\xb6\xa9\xc9\xde\x54\x58\x0a\x83\x5b\x1e\xb7\x62\x0e\xb2\xa5\x40\xc6\xb9\xdf\x3d\xa7\x96\x61\x90\xa6\xa6\xf3\x50\x86\x52\x65\xc3\x20\xc5\xd8\x5a\xc2\x63\xb5\xfd\x94\x0c\x66\xa0\xeb\x5f\x25\x90\xa5\xd5\x47\x5b\x6b\x07\xe8\x25\x2b\xa1\x86\x25\x78\xea\x72\x8e\xd5\x4e\xcc\x7b\x34\x52\xae\xdd\xb8\x82\x49\x27\xe6\xdb\xed\x4a\x27\x4a\x47\x3c\x8f\x4d\xd3\xb6\xd3\x2d\xe4\x53\xfb\x31\xa4\xc4\xfb\xc6\xc1\xc1\xc1\x81\xa1\x78\x94\xe5\x4d\x63\xec\xb5\xaf\x9c\xff\x60\x43\x2b\x6b\x9a\xa1\x95\xf5\x85\xc8\xa6\x69\x3c\x31\x10\xb3\xae\x32\xd0\x25\xa6\x67\x1f\x98\x04\xe9\x08\xeb\xad\x35\x06\x8a\x39\x71\x28\x5b\xe4\x25\x77\xc4\x57\x56\x6e\x57\x2b\x0c\x73\x35\xa3\x86\xba\x9d\xe1\x72\xa8\xbb\xbd\x76\xc3\xf9\x0f\x89\x75\x3b\x67\x69\xe1\x1e\xa4\xf4\x27\x47\xef\xa6\x0f\x6c\xba\x25\x3d\xf8\xd2\x9a\x71\x05\x83\xac\x78\x9d\xfe\x3b\x3f\xb5\xad\x03\xea\x12\xa8\x2b\x9d\x42\xd5\x5c\x7d\x86\x17\x4e\x0c\xe7\x48\x76\x6c\xff\x96\x1d\xe3\x5d\xe6\xf4\xcc\x34\xcf\x75\x06\xc9\x34\xcf\xb7\x32\xa7\xc3\x0b\x32\x9c\xda\x03\x38\x33\xcd\xa1\x1e\x31\x3c\x6f\x9a\x73\xfa\xd1\x6f\x67\x7d\x7d\x85\x68\xe3\x7f\xe5\x9d\xec\xe2\x85\x53\x02\x41\x8e\x74\xad\x85\xab\xeb\x57\x5c\xee\x6f\xd7\x63\x70\x10\x6d\x49\x5a\xc5\x2e\x54\x24\x63\x55\x4c\xe8\x84\x69\x0f\x25\xdd\xe4\xce\x16\x78\xde\x3f\x2a\x1e\x5b\xe1\x19\x9c\xe1\x39\x9c\xe3\x0a\x72\x65\x56\x94\x93\x47\x26\x25\xb5\x16\xb0\xc2\xc9\x54\xd9\xaa\xd5\x56\xf9\x51\x5e\xb0\x2b\x3c\x85\x4b\x7c\x41\xae\x6a\x60\xdb\x79\x88\x6e\xb0\x29\x92\x5f\xe3\xf9\x24\x9f\xee\x5c\xc2\x5c\x3d\x8c\x2e\x1b\x17\x4a\x4c\xa1\xc6\xdc\x2a\x83\x3a\xcc\x03\x1e\xe3\x99\xba\x37\xd9\xb9\x84\x25\x9e\x4d\x4a\x3d\x28\xc1\xf9\x6e\x6c\x2d\x77\xd7\x10\xe3\x7a\x37\xb6\x92\x9d\xcb\xdd\x4b\x6b\x35\xa9\xa7\x56\x01\x05\xb2\x78\x74\xa5\x6e\x08\x12\x1a\xcd\xad\xf9\xee\x12\x56\x93\xda\xb6\xa7\x18\xef\x5c\x05\x34\x0e\x8b\x8e\x1d\x8a\xc8\xb2\xa4\xbf\xea\x9d\x41\xb2\x6d\x2b\x90\x9a\x2d\xda\xb2\xb5\xbf\xa9\xda\x07\x77\x2e\x07\x3d\x52\xee\xcf\xb6\x4b\xe5\xf4\x45\xa1\x72\x91\x32\xbc\xaf\xe0\x9f\xf5\x0a\x1e\x44\x44\x06\x81\x96\xf3\x2b\x8d\xca\x96\x2e\x79\x38\x2c\xfb\xd4\x86\x62\xf7\xee\x27\x0f\x78\x44\x96\xc5\x6b\x17\xa6\x06\x0d\x52\x55\xde\xfd\xdf\x80\x8d\x5d\x0d\xac\x33\x53\x1d\xcc\xb1\xdb\xc1\x54\x35\x7c\x0f\x52\xec\xa7\x30\xbd\x9f\xc0\xf4\x94\x0e\xd7\x71\xee\x96\xdb\xe8\x94\xeb\x54\x56\xba\x34\x3d\x47\xeb\x4f\xa7\x2f\xe4\x81\x9a\x5e\xef\xd7\xf2\x40\x89\xdd\xa8\xae\x8a\x87\x3c\x41\x12\x96\x14\xe5\x44\x95\x68\x77\xf1\x37\xcc\x30\x8e\x92\x5e\x6f\xf9\x09\x2c\x37\xe5\x4f\x6d\x98\x53\x60\x4e\x9e\x1c\xd4\x58\xc0\xd2\xc6\x82\x43\x1e\xba\xa6\xb9\x0c\xdd\x8e\xbb\x97\x3b\x79\xd3\xe4\x90\xe0\xac\xfd\x26\x82\xb9\x50\xf0\x60\x19\x16\x41\x61\x61\xce\x13\x0b\x4b\xab\xef\x2b\x20\xe7\x41\x1d\xaa\xf2\xf9\xb6\x43\x2d\x5f\x70\x0e\xb1\xaa\xa9\x37\x6c\xc3\x4a\xf8\x4d\x85\x69\x94\x58\x7f\x3a\x77\x4b\x9c\x2c\x0a\x12\xad\x3f\x9d\x7b\x65\x49\x3c\x4a\x37\x99\xc9\xad\x2f\x85\x3e\x7e\x9c\xff\x30\xac\xda\x32\x6e\x3e\x7e\xfc\xc5\x00\x63\x61\x70\x30\x1e\x99\xc6\x3d\x18\xdd\x0a\xdc\x4f\xb9\x9f\x6c\x0a\x73\xf5\x61\xb7\x43\x1f\x74\xfb\xee\x28\x4d\xfc\x0c\x0b\xad\x2a\xd7\xb8\x70\x62\x98\xf7\xf7\xea\xb0\xc2\x6a\xf3\x72\x85\xc9\xad\x1b\xf7\x9e\x5d\xd8\x67\x1c\x7a\x50\x62\x5f\x8a\xfd\x19\x97\xc0\x86\x8c\x22\x79\x95\xc3\x61\x9c\x37\x4d\xe9\xa4\x15\xfb\xaa\x8c\x8b\x2e\x8f\x18\x83\xb1\x9a\x7d\x1b\xcc\x45\x96\xaf\x64\x46\x5b\x19\x18\x16\x5b\x46\xc6\x9d\x1a\xe0\x87\x4a\x80\x05\x0e\x97\xa6\xa9\x12\x2e\x1f\x58\x09\xda\x31\xf3\xb8\xb3\xa8\x04\xfb\xca\xa3\xd2\xef\xdc\xd0\x75\x1f\xfb\x6f\x97\xa1\x6b\x73\x5d\xb0\x35\xf1\xe9\xdc\x11\xd8\x27\x8e\x16\x8e\xb0\x3d\x98\x2b\xab\x8e\xef\x26\xac\xc6\x7c\xe7\x9a\x3f\x77\xa3\x6b\xab\xf6\xeb\x29\x2d\x2c\x68\x2f\xf1\x6a\xcd\xe6\x3c\x74\x23\x0a\x16\xe6\xfe\xca\x2f\xa1\xc6\xef\xf0\x9d\xbc\x8d\x9e\x14\x31\x87\x44\x43\x72\x83\x14\xc9\xdc\xcf\x55\x76\x50\xc9\x8a\x72\x01\xd2\xd6\x4a\x5e\x71\x0e\xde\x90\x42\xa0\xd5\x9a\x22\x24\x5e\xe1\x15\x5c\xa1\x84\x15\x26\xb7\x47\x4a\x5c\x71\x8a\x5c\x24\xcc\xb1\x6c\x43\xaa\x4d\xdf\x9c\x53\x70\x23\x3b\xbd\x27\xf1\x25\x13\x5d\x2c\xc9\xe1\x4a\xaf\x9e\x74\x30\x3b\x93\x4e\x10\xab\x0e\x25\xb9\x85\x52\xe2\x94\xb8\x72\x4a\x5c\x38\x25\xe4\xbb\x38\x86\x0c\x5f\x32\xb2\xae\x39\x7c\xe1\x2d\xdc\x05\x77\x66\x17\x25\xe3\x0a\xf5\x97\x2c\x81\xea\xa1\x5e\xfe\xdc\x8b\x26\xab\xad\x33\x80\xab\xad\x97\xa9\x3f\x49\xb6\xfb\xaa\xed\x3e\xf8\x8e\xb5\x76\xe7\xab\x5c\xd7\x08\xdf\x8f\x7c\xb7\x1c\x6b\x4b\x34\x0d\x19\xe0\xc8\xdd\x15\x8e\xce\x07\xe9\xb9\x6f\xf3\x2b\x95\x56\x5c\xe7\x57\x3f\x89\x86\x56\x5d\x35\x95\x25\x78\x97\x1e\x20\x07\xa1\x77\xd5\xc7\x8f\xc1\x10\xad\xba\x57\xf5\x3f\xc3\x2e\xab\xc9\x04\x6f\x9a\x22\x3c\xa7\x18\x68\x84\x2e\x6f\x9a\xf5\xac\x28\xc5\x51\x9a\xcf\x2a\x26\xb8\x92\x93\x21\x13\x48\xe8\xdc\xb9\x69\x50\x7e\xec\x3a\xbf\x62\x96\x04\xc1\xbb\x0c\xcb\x6f\xd1\x9c\xfd\x36\xba\xb6\xc6\xdc\x77\x61\x23\x85\x6d\x45\x6a\xb1\x33\x56\xbf\xea\x5a\xa4\x75\xcb\x60\x58\x39\x71\x5b\x29\x9a\x99\x66\xd5\x67\x43\x55\x60\xb4\x79\xc5\x8c\xeb\xf2\xe0\x15\x2b\x46\x63\x0e\x5d\xd1\x72\x20\x71\xe3\xe3\x41\x66\x9a\x2a\xad\x21\x6f\x83\x91\xb7\xc0\xdc\xca\xc6\x57\xf8\xd5\x99\xcb\x4b\x56\x71\x0e\x99\xb2\x92\xbf\xc1\x97\xde\x4a\xf6\x45\xe2\x7f\xdf\xac\xa9\xaa\xb8\xbd\x9f\x99\x69\x18\xef\xb5\x07\xab\x39\xe5\xa1\x33\xed\xe2\xdb\x8a\xf8\x17\x2b\x47\x04\x5b\x41\x29\x22\xe6\x91\xa4\x60\xc3\xe8\xee\xc8\x0c\x70\x43\xa9\xa2\x48\x52\xeb\xe4\xed\x67\x68\x9c\xce\x4e\x0d\x5f\xb9\xe2\x44\xdf\xde\x3f\x68\x91\x54\x5f\x98\x8e\x9f\x74\x9f\x98\x46\xaf\x58\xca\x32\xc8\x39\xb8\x8d\x00\xcf\x05\xc9\xfd\x5f\x42\x24\x9b\x13\xe2\xa3\x28\x51\x7d\x7e\x37\x84\x16\xab\xba\x88\xae\x5f\xb4\x65\xf6\xa2\xce\xe2\x36\xdb\xa3\x9e\xff\xfe\x5d\x80\xbe\x7f\xb8\x9c\xa5\xb5\x38\x4b\x68\x7a\xfe\xdb\xf9\xd9\x03\x99\x70\x9d\xda\xde\x88\xda\xcd\x86\xfe\x5d\xd5\x29\xa9\xf3\xd9\xa6\x5e\xa2\xda\xc4\xb2\x6e\xd3\x53\x53\x84\x6e\xd3\x08\x44\xcc\xa2\xcc\xcf\x6c\xef\x56\x7d\xc5\xa6\xb2\x42\x0b\x99\x07\x72\x53\x84\x92\xab\xef\x54\x2c\xc3\x08\x64\x58\xb4\x1e\x68\x86\x42\x65\x1b\x2d\xc3\x80\x0a\xaf\xed\xfe\x5b\x8e\xca\xb6\x83\x8c\xa2\x3f\x2b\xe3\x41\x6e\x61\x76\xd3\x16\x82\xdc\xfa\x2a\x31\xbf\xfd\x55\xa2\xe4\x41\xef\x06\xe6\x9b\xef\xfd\x2c\xaf\x69\x3c\xbe\x41\x54\xde\xcd\x0d\x0a\x27\x86\x9c\xa2\x22\xf5\x4d\x51\x49\x3a\xdd\x29\x55\xfd\x0c\xc5\x78\x99\x23\xb6\xb2\x54\xf7\x33\x1d\xa6\x39\x54\x4e\x4c\x81\xb9\x69\x0e\x73\x55\xd4\xd5\x34\xfd\x6d\x58\x15\x15\x91\xeb\xdb\xa5\x5f\x2b\xc7\x65\x88\x3d\x8c\x5a\x03\x70\xc3\x1a\x0a\x4c\x10\x53\x18\xca\xa6\x19\xe6\xbc\xf7\x8a\x5d\x7f\x28\xff\xaa\x74\x59\xcb\xad\x2b\xb6\x24\x4c\xbb\x76\x5d\x5c\xc4\x92\x3e\xe5\xc2\x9f\xb3\xb4\xa7\x13\x8f\x12\x9f\x9c\x79\x37\x28\xc3\x3a\xa8\x75\x16\x59\x4e\xea\xe9\x10\xf3\x49\xdd\x07\xf3\xd4\x12\x52\x43\x07\xb5\xff\x4c\x1a\xd3\xc8\xf5\x37\xcb\x6d\xa8\x98\xdf\xbe\xbd\x65\x42\x7f\xfc\x13\x92\x33\x5d\x85\xb8\x55\xed\x53\x13\x63\xb4\x1f\xfd\x4d\x74\x71\xe4\x40\x95\xc2\x4d\x0d\xc4\x33\xf5\xbe\x29\x3f\xef\x59\x54\x7f\x8f\x24\xb6\xce\xad\xbc\xf7\xfd\x0f\xb9\x37\x2a\xda\xaa\x55\xa1\x7c\xff\xbd\x13\xed\xb5\xfd\x06\x74\xc3\x31\xd2\xb6\x83\x7c\x22\xa7\xbb\x98\xb5\xf5\x60\x93\x02\xdd\xa9\x85\x67\x7d\x1a\x40\x74\x81\x31\x11\x8a\x07\xc5\xf3\x7e\x72\x61\x59\x3c\x9f\x14\xd3\xb0\x52\x5f\xeb\x6a\x9d\x92\x4f\x0a\xcb\x23\x71\xd6\x0f\xe8\x72\xd0\x4f\x16\x75\x4d\x47\x55\xe3\x52\xc3\x74\x07\xab\x5e\x7f\x6e\xdf\x05\xf4\x3b\x4b\xb6\xf5\x23\xdb\x54\x15\x45\x62\x13\xa9\x5b\x86\x63\x58\x62\xe3\x12\x0b\x6e\x31\x37\xcc\x22\x83\xfc\x26\x61\x19\xdc\xca\x36\x00\xd3\x5b\x2c\xae\xcb\xd6\xb2\xce\x2d\x36\x5c\xc7\x08\x2c\x2b\x23\x27\x58\x7d\x83\x26\xb0\xb0\x44\x5f\x60\x58\x6d\x44\xd6\xb2\xb2\xb0\xda\x4c\x33\x20\xb3\xb1\x0a\x6c\x7b\x6b\xaa\x85\x85\x9e\x59\x29\x9b\xb1\xa9\x2b\xd3\x9f\xbc\x6f\xe1\x9c\xf1\x4d\x8c\xb6\xc1\x34\xde\x30\xc7\x40\xe0\x2d\x43\x0a\x64\xa1\xe7\x4c\x70\x7f\x45\x7c\x40\x9b\x99\xe9\xb8\x5f\x57\x3b\x7c\x9c\x5b\xec\xa3\xf3\x71\xbe\xcb\xa3\x86\x7e\x2d\xce\xc4\xc4\xb2\xa7\x11\x3d\x46\x8f\x46\xe4\x36\x29\x83\x1b\x0b\x99\xc2\x4a\x3f\xab\xab\x56\xb8\xc2\xb6\x5a\x77\x70\x91\xe7\xa9\x98\x65\x83\xbc\x18\x5c\xc8\x6c\x56\x5c\x0f\xe6\x14\x6e\x1a\x70\x89\xfa\x4b\x2a\x99\x2d\x06\xab\x7c\x2e\x0c\xb8\xe8\x3e\x4c\x1f\x10\xa3\x0e\x96\xb3\x72\xb0\xca\x0b\x31\xa8\x96\xb3\x6c\xe0\x3d\x19\x94\x72\x91\xc9\x44\xc6\xb3\xac\xd2\x40\x4a\x03\xce\xd0\x70\xbd\xf1\xe3\xbd\x27\x4f\xf7\x9f\x1d\xcc\x2e\xe2\xb9\x48\x16\x4b\xf9\xf9\x4b\xba\xca\xf2\xf5\xd7\xa2\xac\xea\xcb\xab\x6f\xd7\xdf\x5f\xfc\xf2\xf2\xd5\xe1\xd1\xeb\x5f\x8f\x7f\xfb\x7f\x27\x6f\x4e\xcf\xde\xfe\xff\x77\xe7\xef\x3f\xfc\xfe\xc7\x9f\xff\xfd\x3f\x8f\x3e\x19\x70\x8a\x9e\xf0\xf6\xe0\x1a\xbd\x3d\x38\xbf\x5b\xd8\xeb\xc1\x3b\x9c\x78\x64\x7e\x3c\xd7\x05\x4f\x3c\x06\x4f\xec\x81\x27\x9e\x80\x27\x9e\x82\x27\xf6\xc1\x13\xcf\xc0\x13\x07\xe0\x09\x1a\x24\x3c\x8f\xfe\x8c\xe9\xcf\xe3\x29\xbc\x50\x1f\x72\x1c\xa2\x27\x0e\xd4\x17\x55\xaa\x8a\xd2\xe8\x8e\x67\x53\xec\x3c\x17\x89\xcc\x84\x69\xea\x5f\x67\xb6\x9a\x73\xfd\xc8\xee\x9b\x9a\xd9\xcd\xe6\xbb\x4d\xa3\xce\xf4\xb8\xf9\xa6\xfa\x5b\x5d\xd8\x08\xd3\xd4\xbf\x0e\x79\x59\x45\xa5\x2f\x00\x6e\x37\xe1\x0c\x86\x4b\x5e\x15\xd7\x3f\x96\x58\x88\xaf\xb5\x2c\x04\x6b\xeb\x41\x0d\x7e\x13\xcf\xaa\x78\xc9\x5e\xf1\x1f\x37\x9a\x03\x85\xd3\x7f\x59\x86\xb3\x9b\x36\x2b\xf0\xcf\x7f\x8c\x46\xff\x35\x28\xf3\xba\x88\xc5\x9b\xd9\x7a\x2d\xb3\xc5\x87\x77\x27\x38\xcf\xe3\x5b\xff\x61\xc3\x59\xcd\xd6\xff\xfc\xc7\xff\x06\x00\x00\xff\xff\xc7\xd1\x62\x44\xa6\x43\x00\x00") +var _bignumberJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\xbc\x6b\x77\x9b\xc8\x93\x38\xfc\x7e\x3f\x85\xc4\xc6\x9c\x6e\x53\x20\x90\x9d\x38\x86\x14\x9c\x4c\x62\xe7\xe7\x79\x1c\x3b\x4f\x9c\xcc\xcc\xae\xa2\xc9\x91\x51\x23\x75\x82\x40\xe1\x62\xc7\x09\xfe\x7d\xf6\xff\xa9\x6e\x40\xf2\x25\xbb\xb3\x6f\x2c\xe8\x4b\x75\x75\x75\xdd\xbb\xf0\x68\x77\x70\x29\x17\x59\xbd\xba\x14\x85\xf3\xa5\x1c\x5c\x8d\x1d\xd7\xd9\x1b\x2c\xab\x6a\x5d\xfa\xa3\xd1\x42\x56\xcb\xfa\xd2\x89\xf3\xd5\xe8\xad\xfc\x2a\xde\xc6\xe9\x68\x7b\xf8\xe8\xf4\xe4\xd5\xd1\xd9\xab\xa3\xc1\xee\xe8\x3f\x46\xbb\x83\x55\x3e\x97\x89\x14\xf3\xc1\xe5\xcd\xe0\x87\x48\xe5\x62\x50\xe5\x83\x44\x7e\x7f\x0c\x5c\x91\x5f\x8a\xa2\xfa\x5a\xc8\x95\xc8\x46\x79\x55\xe5\xff\x59\x88\x45\x9d\xce\x0a\x5b\x7c\x5f\x17\xa2\x2c\x65\x9e\xd9\x32\x8b\xf3\xd5\x7a\x56\xc9\x4b\x99\xca\xea\x86\x96\x19\x26\x75\x16\x57\x32\xcf\x98\xe0\x3f\x8d\xba\x14\x83\xb2\x2a\x64\x5c\x19\x41\xd7\x31\x50\x5d\xfd\xdb\x8c\x09\xc8\xf8\xcf\xab\x59\x31\xa8\xa0\x00\x09\x39\xd4\x50\x42\x82\xd5\x52\x96\x81\x4c\xd8\x90\x25\x03\x99\x95\xd5\x2c\x8b\x45\x9e\x0c\x66\x9c\x17\xa2\xaa\x8b\x6c\xf0\xc5\x34\x4f\xd9\xf8\x19\x18\x71\x9e\x95\x55\x51\xc7\x55\x5e\x0c\xe2\x59\x9a\x0e\xae\x65\xb5\xcc\xeb\x6a\x90\x89\x6b\x03\x04\x87\x4c\x5c\xb7\xeb\x10\xc0\xac\x4e\xd3\x21\x66\xa6\xf9\x2f\x96\xc1\x18\x9e\xed\xc3\x5b\x30\x2e\x67\xa5\x30\x38\xff\x49\xfd\xe8\x36\x19\x94\x28\x2c\xc3\x00\xcf\x45\xcc\xba\x15\x13\x6c\x21\xdd\x41\x28\x12\x7e\xc9\xe1\x23\x4b\xe0\x9d\x95\x38\xc2\xf2\xe0\xab\x5a\x87\xe5\x68\xe8\xa3\x30\x10\xab\x9b\x35\x0d\x16\xdc\x34\xdd\x5d\x31\x44\xb7\x69\x86\x04\xec\xbd\x58\x1c\x7d\x5f\x33\xe3\x6f\x3b\x32\x2c\x56\xa1\x31\x31\xac\x73\xa7\x4c\x65\x2c\x98\x0b\x19\xb7\x8c\xa9\x65\x70\xcb\x60\x91\xff\xe9\x93\x63\x58\x95\x65\xf0\xe8\x89\x01\x7b\x07\x61\x16\x19\xd2\xf0\x0d\x83\x3b\x95\x28\x2b\x56\xf6\x84\x59\xb0\x04\x4a\xc8\x69\xbb\x79\xc4\x12\xa7\x44\x37\xf4\x46\x22\x62\x25\x96\x2d\x68\x8f\x83\xed\x71\xdf\x83\x2f\xa6\x59\x3a\x85\x58\xa7\xb3\x58\xb0\xd1\xdf\xee\x27\xc7\xdd\x6d\x3e\x39\x23\x20\xb8\xa9\xc8\x16\xd5\x32\xf4\x9e\x12\xa5\xdf\xc2\x25\xd1\x32\xc7\xa1\xc7\x7d\x02\xba\xff\x14\x11\x4b\x27\x5e\xce\x8a\x57\xf9\x5c\xbc\xac\x98\xcb\x1f\x5d\xa3\xc4\xd7\xac\x04\xcf\x85\x0c\x12\xa7\xe4\xb7\x22\x2d\x05\x11\xfa\x2e\x19\x7b\x22\x3b\x25\x0a\xa7\x84\xc4\x11\x28\x1c\x01\x89\x13\x23\xa3\xc7\x98\x47\xa2\x05\xcd\x7d\x01\x57\xb9\x9c\xb3\xb7\xe8\xfe\x6f\xb4\x46\x74\xd5\xb1\x6e\xd1\x41\xa0\x2d\x5a\xdc\x04\x22\xfe\xfb\xdf\xc4\x90\x79\xc1\x0a\x74\x41\xa2\x08\x64\x88\x9e\x1b\xc8\x11\x7a\x2e\x14\x96\xc5\x83\x1e\x35\x81\x85\x42\x68\x22\xa6\x1b\x04\x6e\x35\xaf\xf4\xfb\x1a\xae\xdb\x13\x51\xcd\xf7\x8f\x85\x07\xff\x17\xe2\xdd\xde\x12\x62\xac\xc0\xd2\x91\xd9\x5c\x7c\x3f\x4f\x98\xe1\x18\x9c\x87\xb6\x67\x9a\x6a\x7c\x77\x78\x86\x63\xd0\xa1\x71\x60\x92\xa0\x88\x59\x11\x2f\xd9\x48\x8c\x24\xe7\xa1\x1b\x31\x37\x2c\x4c\x93\x15\x28\x39\x14\x16\x5a\xdd\x3a\xd2\xf2\x38\xa8\x65\xeb\x4b\x92\xd4\x6c\xc1\x5c\x90\x9c\xfb\xdd\xf8\xb2\xe5\x02\x0e\x12\xdd\x60\xff\xf9\x7d\xb4\x25\x0f\x24\x91\x88\xd0\xac\xfb\xd1\x8f\x0c\xb4\xed\x9a\x07\xea\xb0\x36\xbb\x94\x50\x5b\x1e\xe7\x32\xd9\x9a\x0a\xb9\x69\x7e\x31\xcd\x7a\x8b\xed\x12\xa7\xdc\x15\x1c\x0a\x2c\x6c\x69\x7b\x50\x84\x3f\x38\x1d\x02\x1d\x07\x09\x73\x40\x84\x1f\xc8\x84\xbd\x09\x0b\xd5\x31\xa1\x1e\x77\x1a\x74\x07\xb2\x75\x6e\x53\x90\xc8\x0a\xcb\xe3\x3b\x37\xa0\xb7\x28\x2d\xbc\xe1\x50\x87\x52\xf3\x80\x34\xcd\xc4\x89\x9d\x75\x5d\x2e\x59\x4f\x25\x45\x12\xa8\x6d\xbc\x09\xea\x50\x06\xfc\xe1\x08\x09\x0a\x0e\x0f\xb6\x36\x47\x24\xbb\xb1\xbb\x7d\xdd\x6a\x2c\x6d\xac\x15\xad\x02\x69\xdb\x41\x69\xa1\xe1\x1a\xc4\x11\x3d\x3c\x2d\x1e\x83\xed\x6d\xbc\x45\xf7\xb6\xd7\x97\xaf\x49\x8f\x41\x05\x52\xeb\x4c\xd2\x96\x09\xc4\xb0\x84\x05\xac\x61\x8e\xe2\x0e\x9b\xc0\x0a\xdf\xc1\x35\x7e\x55\x2b\xee\x1d\x84\x95\x69\x2a\x51\xaa\xf2\xd3\xfc\x5a\x14\xaf\x66\xa5\x60\x9c\xc3\x3c\x44\xd7\x34\x59\x82\xbf\xc3\xef\xe8\x02\x8d\xb8\xc7\x55\xb0\x6e\x55\x5f\xc5\x61\x89\x6b\x67\x9d\x5f\x33\xd1\x6e\xcc\x9e\x73\xf8\x1d\x13\x58\x3b\x31\x96\x2c\x65\x05\x5b\x3a\x31\x87\xa5\x23\xb8\x12\x7a\x0e\x6b\x47\xe0\xda\x89\x7b\x4e\x5a\x60\xc9\x04\x54\xd4\x55\x63\x82\x8b\x8e\x69\x5c\xc4\xc5\xc4\xb6\x93\x69\xb0\x70\xd6\xf9\x9a\x71\xc5\x2e\xc3\xc5\xc4\x9d\xb6\x42\x64\xb8\x06\x35\xb9\xe1\x3c\xb2\xed\xda\xa7\x95\x70\x41\x4b\x61\x0d\x4b\xa7\x44\x09\x4b\x7c\xc5\x96\xb0\x86\x15\x5c\x13\xfc\x05\x2e\x9d\x18\x62\x5c\x3a\x05\xd4\xa8\x70\xca\xb1\xb6\x56\x96\x07\x73\x5c\x4c\xf2\x29\x24\x98\x8d\xc6\x10\x63\xdc\x34\x6e\x98\x37\x8d\x36\x0f\x8b\x49\x6e\x79\x53\x88\x71\x3f\xbc\x8e\x5a\x93\x31\x6f\x9a\x98\x9b\x26\x73\x11\xaf\x9b\xe6\x1a\x91\x2d\x9d\xf2\x85\x1b\xed\xf9\x63\xce\xfd\x79\x98\x34\xcd\x1c\x31\x31\x4d\xb6\xaf\x46\xc4\x4d\xf3\x0c\xf1\xda\x34\x3d\x73\x31\xc9\x6d\x6f\xba\x3d\xe9\xb9\x7f\xc0\x39\x78\xb4\xa2\xde\xa0\xc0\x38\x4a\x99\xe1\x19\x60\xaf\xb8\x4f\x1b\xed\xd8\xb7\xa3\x0f\xe6\x10\x73\x3a\x49\xdb\xce\x02\xcb\x22\x52\xe5\xd3\x30\x0b\x38\xed\x03\x5d\xc8\x9b\x86\x59\x56\x0d\x0b\xa7\xce\xca\xa5\x4c\x2a\xe6\x71\x2d\x98\x5b\x34\x1e\xb6\x14\xd6\x1d\x73\x75\xdc\x86\x11\x24\x21\xce\x03\x61\xe1\xb9\x12\xd9\x97\x15\x5b\x4c\xe6\x96\x35\xe5\x3c\x10\x98\x32\x01\x35\xbf\x6d\xd5\x98\xd8\xf0\xe2\xe7\x87\xbc\x58\x12\x2f\xd2\x11\x55\xa8\x89\x56\x91\x9d\xad\xc0\x85\xe7\x20\xe1\x8a\x47\x6e\x53\xf9\x5f\x61\x48\xea\xbc\x03\xe8\x54\xf9\x85\x56\x3d\xea\xbc\x73\xd2\xf5\x13\x77\x4a\x26\xd8\x11\x40\x60\xc8\x06\x2f\xb1\x60\x42\x31\x16\x7a\x87\x88\xb2\x69\xc6\xfb\x88\xd2\x34\x7f\x0b\xb1\x8c\x12\xb6\x84\x92\xfb\xa9\xfa\xe9\x15\x82\xc0\x8f\xac\x35\xd9\x9c\x30\x25\x7e\x23\x98\x3d\x2c\x62\x8c\x56\xed\xdc\x05\xca\xea\x10\xb3\xa6\xf9\x2d\xc4\x9a\x6b\xc5\x10\x64\x61\x1c\x2c\x95\xc0\x42\x4c\x1a\x6f\x89\xb4\x68\xdd\x0a\x2c\x39\x0e\x36\x96\xb0\xc4\x54\xb5\x92\x66\x0b\x63\x65\x79\x6c\x3b\x0b\x5d\x75\x70\x34\xdd\x31\x82\xcc\xb6\x5b\x48\x3c\xd8\xcc\xb6\xb0\xb6\x63\xe8\x86\xd6\x96\x87\x18\x9b\x66\x3b\x87\xdf\x99\xd4\x53\xae\x7c\xe1\x9a\x66\x1e\x19\xb6\x61\x2d\xfd\xe5\xe6\x64\xbe\xdf\xf3\xaa\xd0\xd5\x0a\x9a\x09\x62\x35\xad\x05\xe8\x09\xaa\xce\xa5\xa1\xb7\xc0\xb2\xe4\x8b\x4e\xac\x03\x85\x7b\xd1\xf7\xcb\x29\x87\x61\xe1\x94\xfc\x67\x85\x45\x70\x59\x88\xd9\xd7\xdb\xcc\x21\x7f\x8b\x55\x50\x10\xcc\x0a\x8b\x9e\x4b\xaa\x0d\x2e\xc7\x2d\x97\x14\xc4\x27\xba\x9b\x65\xa1\x68\x1a\x11\x56\x4d\x23\x86\x18\x33\xc1\x39\xe9\xfa\x02\x98\x6c\x1a\x63\x2e\x62\xb9\x9a\xa5\x03\xa5\x81\x4a\x83\x5b\xfd\xf0\xc8\x18\x90\x5f\x97\x27\x83\x62\x96\x2d\x84\xe1\x1b\x83\x2c\xaf\x06\xb3\x6c\x20\xb3\x4a\x2c\x44\x61\x70\xf2\x51\x86\x5b\xfa\xf2\x44\xaf\xae\xcf\x90\xe8\x51\xa0\x07\x12\xb3\x5e\x1e\xb2\x89\x6d\xcb\x69\x90\x75\x1a\x47\x19\x01\xcc\x26\xee\xf4\x57\x7e\x00\x6d\xd4\xaa\x76\x6f\x6c\x8f\x87\x3f\x22\xe1\xc4\xc4\x53\x8a\xdd\xfd\x37\x61\xa5\x1a\x26\x42\xa9\x6e\x9f\xd1\x6f\x05\xd4\x94\x71\xd8\x12\x9d\xd3\x0e\x2d\x8d\x12\x11\xf9\xa8\x28\xf2\x82\x4d\x0c\x7a\xfe\x4d\x2e\xce\xb4\x3b\x03\x46\xbc\x5a\x1b\xca\xc9\x4d\xe4\xc2\x00\x63\x2e\xaf\xf4\xdf\x0f\xf9\x49\x56\x19\x60\x88\x6f\x06\x18\x8b\x4a\xfd\x11\x06\x18\x69\xa5\xfe\xd0\xe3\x4a\x66\x75\x49\xbf\xf9\xdc\x00\x63\x9d\xaa\x97\x75\x21\x62\x49\xfe\xbb\x01\x46\x31\xcb\xe6\xf9\x8a\x1e\xf2\x3a\xa3\x31\x4a\x6f\x18\x60\x54\x72\x25\x68\x70\x95\xbf\x96\x0b\x59\xe9\xc7\xa3\xef\xeb\x3c\x13\x59\x25\x67\xa9\x7a\x3f\x96\xdf\xc5\x5c\x3f\xe5\xc5\x6a\x56\xe9\xc7\x62\xa6\xb6\x48\x2b\xe5\xd7\xaa\xe9\xdd\xd6\x8a\x9d\xac\x1b\x60\x6c\x36\x39\x9d\x88\xa9\x65\x30\x3e\x30\xac\xcc\x32\xfc\x81\x61\x55\x3c\xa8\x96\x45\x7e\x3d\x28\x9c\x6c\xb6\x12\xb8\x19\xac\xe9\x64\xc0\x5b\x74\xa1\xd8\x10\xf4\x63\xc7\x65\x9a\xa4\x7d\x1c\x01\x29\xc4\x30\x23\x95\x02\x4b\x7c\x4f\xfa\x65\xc6\x7f\x0a\x5f\xdb\x7a\x24\xe7\x74\x46\x47\x5d\xaa\xa3\x2e\xd5\x51\x2b\x7f\x46\x29\xa2\xcc\x96\xe0\x86\x39\xcf\x2d\xbc\x81\x1a\x33\x48\x70\x36\x49\xd1\x25\xc3\x90\x8c\x96\x13\x69\xd7\xb6\x37\xdd\xf1\xdc\xc6\xed\x75\x4e\x8a\x73\xc6\x72\xcb\xe3\xa3\x1b\x0e\x69\x88\xb3\xce\xec\x29\xd7\xb0\xe0\x4a\x72\x06\x42\x3b\x01\x5d\xe7\x0b\x4c\x83\x99\x76\x01\x5c\xe2\x41\x8c\x95\x2b\xea\x41\xbe\xa3\x56\xce\xed\x1b\xcb\xd3\x0e\xa6\xd6\xe7\x84\x76\x4a\xce\x8c\xf7\x10\xf5\xad\x39\x12\x62\x74\xc3\x3a\x72\xfd\x7b\xe8\xde\x2a\xd9\x2e\xc8\xe6\x65\x9d\xcd\x9b\x4d\x52\x8b\x8c\x14\xa3\x19\x89\x9f\xec\x74\x33\xc8\xf5\xda\x0f\xab\x88\xc5\x4d\x53\xb4\x16\xb0\x6a\x9a\x0a\x91\x89\x2d\x0b\x18\x87\x4f\x9b\xe6\xa9\xd6\x5a\xfb\x6a\x44\xa1\x2c\x20\x79\x1d\x79\xe8\x46\x75\xe8\x46\x2d\x1a\x53\xdf\xf5\x67\x93\x94\x60\xef\x78\xae\xe9\x6d\x03\xeb\x2c\x63\xd6\x34\xc3\xd9\xc6\xf4\x0f\x3a\x5a\xd1\xb9\x47\xa4\x6c\x85\x0a\xb6\x68\x08\x2e\x27\xd9\xce\xcd\x14\x48\xda\xec\xac\x69\x5c\xee\xab\x66\x25\x85\x20\x94\xcb\x80\x98\x47\xac\x87\x91\x42\x89\x1e\xa4\xb6\xcd\xfd\xad\x46\x8b\xf8\x61\x39\xb9\xb1\xf3\x29\x10\x7d\x91\x50\x5e\xb1\x0e\xe9\x9d\xe5\xa4\x9e\xf2\xdd\xd2\x77\x39\x14\x4a\x4b\x07\x5a\x4b\xba\x88\xa9\xd6\x30\x39\x7a\x50\x6b\x96\xaa\xd5\xb9\xd4\xea\x5c\xf2\x8d\x8b\x4c\x7d\x16\x96\xb4\xfe\x9d\x21\xa5\x3a\xba\x21\x96\xa4\x9d\x1d\x61\x59\x7a\x67\x78\x66\x9a\x4c\x3d\x91\x31\xd7\x6a\x97\x98\x78\x92\x2a\x28\xf4\x3b\xc4\x33\xcd\x55\x01\x91\xd4\x26\x57\xa0\x44\xef\x56\xa3\x33\xdb\x72\xae\x70\xa6\x5c\x06\xe2\x34\xad\xeb\x6e\x85\x23\xee\xab\x30\xe1\x88\x17\x6f\x14\x0e\xbd\x1a\xdb\xb2\xfd\x24\x5b\xaf\x94\xec\x7d\xc0\x99\xb3\x2e\xf2\x2a\xa7\x70\x0b\xbe\xb5\x76\xc2\xe3\xf0\x0e\xc7\x2e\x7c\xc5\x7d\xf8\x0d\xed\x03\x78\x82\x63\x0f\xde\xa0\xed\x89\x03\xf8\x81\xf4\xf7\x0b\x0e\x5d\xf8\x17\x1e\xc3\x1f\x38\xf4\xe0\x4f\xf4\xe0\x77\xf4\x5c\x17\xfe\xc2\x9f\xad\xe6\xbf\x10\xeb\x59\x31\xab\xf2\xc2\x27\xf7\x73\x51\xe4\xf5\x7a\xab\x09\xba\x26\xf9\x43\xf8\x7b\x50\x8a\x38\xcf\xe6\xb3\xe2\xe6\x4d\xdf\xe8\x42\xd2\x2a\xa1\x37\xf7\xe6\x0e\x8c\x7b\x5d\x6a\xf8\x6d\xd0\xb3\xd8\x2c\xcb\xab\xa5\x28\x30\x83\x99\xf3\xfe\xfc\xe3\xd9\xeb\xcf\x1f\xdf\xa1\xdb\xbf\xbc\x3e\xff\xf3\x0c\xbd\xfe\xf5\xd5\xd1\xc9\x29\x8e\xfb\xd7\xe3\xd3\xf3\xf3\xf7\xb8\xd7\xbf\xff\xeb\xe5\xe9\x31\xcd\xdf\xbf\xdb\xa2\x80\x3c\xbd\xdb\x76\xf4\xc7\xd1\x19\x3e\xbb\xdb\xa6\xa0\x1f\xdc\x6d\xd3\x4b\x3c\x87\x99\x73\xf4\xf1\xd5\xe9\xc9\x6b\x3c\x84\x99\xa3\x6d\x03\xf6\xa9\x17\xad\x02\x95\x3e\x24\x61\xc1\x9f\xb7\x20\x71\x56\x2c\xea\x95\xc8\x2a\xe2\x3c\x49\xee\x55\x42\xac\x66\xe4\x97\x5f\x44\x5c\x6d\xa2\xe6\x32\xda\x02\xd3\x92\xa5\x74\x96\xb3\xf2\xfc\x3a\x7b\x57\xe4\x6b\x51\x54\x37\x2c\xe3\x91\x56\x19\x4c\x60\x39\xc9\xa6\xdc\xa7\x60\x78\xe0\xde\xfa\x0f\x27\xcb\x2e\x8d\x50\x6d\xe6\xc8\x49\x45\xce\x65\x37\xab\x8f\xaf\x59\x86\xc6\xeb\xa3\x57\x27\x6f\x5f\x9e\x7e\x7e\x77\xfa\xf2\xd5\xd1\x85\xc1\xc9\x7f\x14\xe0\xc2\x11\x8c\x21\x23\xe5\xf3\x0e\xdd\x86\xa2\xc1\x49\x36\xc5\x77\xa0\xe6\x28\x02\x9d\x9c\xbd\xf9\xfc\xf6\xfc\xf5\xd1\x66\xca\xf3\x6e\xca\xd7\xad\x29\x5f\xf5\x94\xa3\xbf\xde\x9d\x9f\x1d\x9d\x7d\x38\x79\x79\xfa\xf9\xe5\x07\x9a\x43\xde\x11\x8f\xfe\xa5\x5c\x21\xb0\x8f\xc0\x6d\x67\x53\x8b\x37\xdd\xc6\xe0\x37\x02\x47\xa3\x9e\xa8\x07\x6f\xca\x7d\x5a\xd0\x3e\xda\x1e\x62\x33\xea\x65\x6e\x28\x22\x5b\xf8\x82\x73\xde\x22\x30\xf9\x0d\x9e\x4c\x5b\xbc\x5f\x9e\xbd\x39\x7a\x6c\x6d\xdb\xbb\xbb\xb8\xb7\x81\xfc\xa6\x5b\xfc\xc7\x2f\x17\x77\x1b\x11\xbd\x41\x9b\xfd\xb8\x8b\x80\xaf\x33\x66\x90\x59\xc6\x20\x9e\x65\xe4\x39\x5d\x8a\xc1\x0f\x51\xe4\x06\x88\x0d\x7a\x6f\xe0\x47\x8b\xde\xd1\xfb\xf7\xe7\xef\xd5\x11\x30\x81\x88\xc3\xa1\x68\x1a\x0f\x11\x45\xd3\x90\x36\x11\x11\x23\x45\xf0\x2f\x64\x5f\xa8\x8f\x47\xc7\x7e\xbe\xb5\xc8\x35\x01\xd5\x30\xbf\x68\x78\xaf\xde\xff\xd7\xbb\x0f\xe7\xff\x13\xbc\x3f\x70\xc8\xa8\x75\xb8\x6c\x9a\x8e\x35\x87\x1d\x6b\x2e\x39\x08\xd3\x1c\xfe\xa1\xf2\x03\xb4\x86\x11\x17\x37\xeb\x2a\x1f\xd4\xd9\xec\x6a\x26\xd3\xd9\x65\x2a\x0c\x58\xf2\xc7\x71\xf8\x43\xe3\xf0\xf6\xfc\xf5\xc7\xd3\xf3\x7b\x8c\x72\xd8\x51\xee\xcf\x2d\x46\xf9\x53\x4f\x78\x77\xfe\xe7\xe7\x77\xef\x8f\x5e\x9d\x5c\x9c\x9c\x9f\x3d\xc2\x8e\xbf\x6f\x4d\xf9\x5d\x4f\x39\x3e\x7f\xff\xb6\xe5\xa9\x07\xf2\x25\xa2\xbf\x50\x6c\x9f\x44\xeb\xc0\xb6\xe3\x36\xf8\xfe\x05\xc5\x2d\xcc\x9c\xd5\xec\x3b\x3e\x14\xaa\xef\x6c\x23\xce\x1f\x9c\xb4\xe2\x6a\xa8\xcc\xfe\xd7\xa1\x0b\x3d\x54\xfb\x7d\x0f\x34\x06\x1e\xba\xee\x81\x77\x78\x38\x7e\xba\x7f\xb0\xef\x1e\x1e\x8e\x21\xc3\xb7\xb3\x6a\xd9\x8e\x67\x7c\x57\x98\x63\xf7\xf0\xc0\x7b\xea\x3d\xa2\x26\x56\xec\xde\x58\xfe\x98\x3e\x78\xbe\xf7\xfc\xf9\x33\xf7\xf9\x2e\xf3\xdc\x83\xbd\x83\x7d\xef\xf9\x78\x7f\xf7\xce\xbc\xc6\xe5\x16\xeb\x46\xdd\xef\xd9\xe8\x8a\xad\x3c\xf3\xbd\xe4\x31\xba\x90\xe0\x64\x0a\x69\x6b\x93\xbe\x29\x6f\x4e\xb4\x01\xa9\xd8\x9c\xa0\xb7\x4f\xf1\xa8\xf0\xdf\x41\x8e\x73\x26\xc8\x61\xfb\x83\xcb\x84\x2d\x4d\x73\xe9\x2c\x44\xf5\x5e\xad\xfb\xc7\x2c\xad\x45\xa9\xcd\x7b\x85\x0f\x3a\x54\x80\xf9\x51\x66\xd5\xde\xf8\x65\x51\xcc\x6e\x58\xbe\x8b\x63\xce\x83\x3c\x2c\x03\x5e\xa3\xb7\xe7\xb9\x07\xe3\xdd\x6a\x52\x4e\x2d\x56\x4d\x4a\xcb\x9b\x86\x61\xe8\x79\x1c\xea\x10\x0f\x85\xf7\x34\x62\xc5\x3f\x00\x3a\xe6\x1c\x08\x06\x16\x24\xfa\x1a\x0e\x16\x4a\xfa\x59\xa2\x1d\xc7\x7a\xc7\x13\xde\x3e\x87\xd2\xc2\x31\x0f\x4a\xcc\x47\xe3\x3e\xb8\x54\x3b\xd2\x64\xfc\xed\xa6\xda\xde\xcd\x56\x23\x61\x7e\xd0\x23\x3e\x7e\xee\xed\x1f\xec\x1f\x1e\x3c\x3b\xf0\xdc\x67\x4f\x9f\xed\xb2\x3d\xcf\x24\x0c\xb8\xe5\xb9\x87\x87\x4f\x3d\xef\xd9\xf8\xe0\xe0\xe0\xd9\xae\xc6\xc5\xda\x1f\x1f\xee\x1f\x3e\x3b\x18\x1f\xea\x96\xf1\xd4\xf2\x9e\x1d\x1c\x1c\x8c\x3d\xfd\xbe\xd7\xee\x7e\x7f\xfa\xe2\x85\xf7\x8c\xeb\x97\xa7\xd3\x17\x2f\x9e\x73\x8b\x1e\x9f\x4d\x7b\x7a\xdc\xc5\xe9\x80\x3b\x71\xbe\xbe\x61\x15\x85\xf7\x8f\x6c\xf5\x40\x6f\xf5\x40\x6f\x55\xc9\x95\xb7\xff\x2b\xcd\xa0\xd2\x49\xa5\xf6\xdc\xda\x6d\x66\x8c\x03\x2d\x1b\xd6\xa6\xc9\x92\x49\x69\x59\x53\x6c\xc1\x07\xda\x83\x4a\x26\xb6\x5d\x4e\x41\x90\x57\x9d\x9b\xa6\x20\x6d\x8d\xef\x27\x37\xb6\x98\x42\x42\x47\xb2\x62\xf9\xa8\xe6\xbb\x35\x57\x3e\x16\x35\x05\x89\xf6\xb0\xa0\xb4\x6d\xae\x13\x56\x25\x4f\x70\x22\xfb\xac\xa4\x0e\x3f\x6c\xaf\x9d\xe2\xd2\x14\x9d\xb3\xe1\x20\x6d\xbc\xd1\x8b\x97\xca\x9b\x4c\xee\x7b\x93\xca\x55\xbc\x09\xc9\x53\xa4\xb1\x76\xd9\x3b\x68\xa9\x23\x50\x42\xea\xc4\x98\x40\x7a\x7b\xcb\x38\xbc\xda\x16\xf2\x3e\x5a\x12\x77\xc2\xcf\x3b\x82\xd3\xc5\xff\x24\x3e\x3b\x2f\x21\xc6\x6c\xf4\xb2\xd1\xe9\x03\x81\x7d\x02\x3e\x48\x6c\x3b\xe0\x39\x8a\x49\x32\xdd\x79\x09\xb5\x7a\xa0\x81\x50\x60\xbc\x9b\x5b\xf5\x6e\x0a\x12\xd3\xdd\xdc\x2a\x76\x5e\xee\xbe\xb4\xc8\xeb\x60\x72\x54\x29\xe1\x2e\x68\x20\xb7\xe2\xdd\x1a\x68\x1a\xca\x9d\xaa\x13\xeb\xd2\x34\x45\x9f\xbe\x2a\xef\x84\xcc\xd9\x83\x08\x4f\xe5\x99\x86\x58\xf0\x1c\xab\xb0\x88\x3c\xdf\xf6\x74\x18\xa6\xa9\x9b\xa3\x1b\x54\xa1\x54\xf9\x69\x52\x00\x13\x39\x1d\x62\x36\x91\x53\xfe\x93\x10\x97\xd3\x90\x5e\xf4\x34\xed\x58\xb7\x48\xe4\x9b\x45\x8b\xcd\xa2\x5d\x02\x41\x12\x58\xda\xbd\x98\x54\x53\x1b\x25\x48\xa4\xa7\x17\xd9\xa4\x22\x60\x2e\xd0\x1b\xca\xdd\xc2\x52\x03\xa8\x59\x07\x7b\x43\x32\xdb\xb4\xbf\xee\x5e\x25\x10\xdd\x99\xf3\xe0\xf6\xbe\x5e\xeb\x23\x58\xbd\xdd\x74\x93\xe4\x85\x6b\xb8\x82\x4b\x38\x87\x0b\x78\x0f\x2f\xe1\x08\x5e\xc3\x67\xf8\x0e\xc7\x28\x9d\x12\x31\x77\x4a\xb5\x25\x38\x41\xe9\xc4\x70\x8a\xb9\x13\xeb\x7b\xb4\x13\xd3\x3c\x51\x18\x9c\x9a\xe6\x29\x05\x56\x5d\x64\xa5\xd5\xa4\x74\x4a\xd3\xcc\xe9\x0f\x3b\x89\x86\xa7\x4d\x43\x83\x87\x48\x23\xfd\x53\x1e\x9d\x98\xa6\x8b\x48\x6d\x4d\x33\x3c\x8d\xdc\xdd\x63\xff\x78\xe4\xfa\xee\xc8\xd5\xbc\x7a\xd5\x6a\xdb\x63\x0e\x97\x78\xa5\x73\xed\x31\x4a\x47\xd8\xb9\x23\xe0\x18\x6b\x2b\xb6\x3c\x48\x9a\x86\x25\x78\x06\x31\x56\x4c\x3a\xa4\x72\xed\x8a\xe5\xea\x01\x8e\xf1\x78\x74\xd3\xb8\x1c\x96\xe8\x06\xa7\x93\xe5\x14\x91\x9d\x4c\x96\x53\x8a\xe7\x82\x65\x1b\x94\x53\x7b\xd8\x37\x9b\x66\x6c\xdb\xe0\x86\xc7\xfc\x52\x6b\x06\x8f\xc3\x02\x87\xee\x46\xc8\x8e\xf0\xa4\x63\xe8\xcf\x78\xda\x3d\x52\x10\x79\x6c\xe1\x18\xd6\x48\xe1\x1d\xa3\x4d\x5a\x1e\xe7\xb0\x0e\x3d\xd3\x64\xa7\x28\xd8\x29\xac\x21\xe1\x70\x82\x82\x9d\xe8\xc7\xad\xf9\x1b\xa8\x1c\x5e\xe2\x67\x38\xc7\x93\xfe\xaa\xe0\x33\x87\x0b\x3c\xef\xc2\xae\xcf\xe1\x45\x70\x3e\xb9\x20\xb5\xe2\xf2\xe0\x3b\x9e\x76\x12\x04\xdf\x7b\x3e\x77\x39\xbc\x56\x74\x86\xd3\x89\x37\x0d\x31\x19\x8d\x4d\xf3\xb5\x65\x05\xf3\x7c\xb0\x46\x97\x24\x91\x9d\xc2\x39\x7c\x86\x0b\x0e\x6e\x98\x46\xec\x3d\x9e\xd3\xf0\xcf\x43\xbc\x30\x4d\xf6\x1e\xdf\xef\x26\x16\x3b\x9f\x78\x8a\x28\x5c\xed\xea\xfd\xe8\xb5\xda\x4e\xc4\xd6\xa1\x4a\x4a\xaf\x31\xb1\x3d\x0e\xf3\xcd\xde\xae\x71\xde\x6d\x68\x83\xb1\x5a\x6d\x0e\xe7\x70\x4d\xab\x79\x88\x29\xcd\xb5\x6d\x28\xd8\x1c\xae\xc3\xcf\xd1\x77\xff\x14\xae\x21\xe1\x9c\xfb\x14\xf8\xae\x4d\x93\xa5\xb8\x46\x05\xba\xdf\xdd\x5d\xe0\xe1\xb5\x69\xce\xb7\xb7\x5b\xb0\x73\x98\xc3\x05\x21\x61\xb7\x4b\xdc\xc3\xa0\xdf\xaf\x17\x2a\x04\x2c\x4b\x4d\xba\x68\x11\xb8\x50\x08\x6c\xa1\xcd\x7d\xd2\xa4\xdd\xd0\x73\x54\xd9\xcd\xcb\xc9\x92\x08\xbf\x86\xd4\x34\x89\x60\x51\x7b\x12\x27\x93\x97\x44\x29\x9f\x9d\xe3\x84\x9e\xa7\x70\x81\x1e\x0f\xae\x97\x32\x15\x8c\xbd\xb4\xac\x17\x47\x5d\x52\xe4\x5c\x27\x4c\x8f\x49\x91\x2f\x70\xd3\x06\x97\x4a\x12\x2e\x3b\x09\xa6\xa0\x3c\x41\x3c\xd3\x7a\x62\x89\x1e\x1c\x23\x0d\x09\x8e\x95\xe2\x3e\x56\x8a\x5b\x31\xf1\x47\x76\x05\xb5\xc5\xae\x1c\x81\x4b\x2b\x56\x69\x44\xcb\x83\x12\x16\x6d\x26\x99\x3a\x62\xb8\x72\x0a\xb4\x16\x9d\x5a\xbc\x52\xba\xfc\x61\x88\x87\xa3\xbf\x99\x1d\x71\x97\x4d\xbe\x5f\xe6\x53\xce\x3e\x5d\x4f\x3e\x5d\x3b\xd3\xdd\x27\x7c\x24\x21\xa3\xde\xc9\xdf\xce\xd4\xe2\x9f\x9c\x27\x23\xa8\x70\xf4\xf7\x27\xa7\x6d\x79\x32\x82\x02\x47\x7f\xdb\x11\x3b\xc9\x12\x99\xc9\xea\xa6\x39\x9b\x9d\x51\xb3\xa4\x61\xe5\xee\x27\x8b\x29\x58\xbc\xf9\xfb\x53\x69\x35\x9f\x4a\xeb\xc9\x68\xf1\xc0\xfb\xba\xaf\xa3\xb0\x8c\x6a\xbf\xee\xaf\x8f\x24\x18\x4f\x3c\x43\x09\x6e\xa1\x2f\x45\x63\xce\x73\xa7\x44\x59\x9e\xcd\xce\x58\xac\xe3\x48\xdf\x0d\xe3\xc8\xf6\x7c\xaf\xbf\xf2\x18\x92\x16\x8a\x31\xee\x01\x09\xd8\x38\x7c\xda\x72\x75\x16\x0f\x8d\xef\x06\x22\xab\xb0\xba\x77\xad\x15\x79\xcf\x7c\xe3\x92\x3c\xef\x68\xec\x3f\x87\xc4\x34\x93\x21\xa6\x91\xf0\xb3\x5b\x4e\x6f\x2c\xc5\x04\xb6\xd7\xc8\x34\xb2\xfd\x7b\x05\x86\xeb\x50\x0b\x87\x7a\x88\xf1\x3d\x75\x19\x43\xca\x83\x2f\xfa\x8a\xd2\x50\x4e\xbc\x61\xb1\x24\x32\x06\x97\xb3\x52\x0c\x0c\x2b\xf1\x0d\x83\x93\x7f\xdf\xe6\x71\x6b\x0e\xb4\x71\xda\xef\x6d\xee\xc4\x98\xb7\x09\x17\x78\x8b\xae\x3a\xdd\x0f\xce\xec\xb2\xcc\xd3\xba\x12\xca\x07\x44\xf5\xfe\xf0\xc4\xdb\x7b\xb8\xa5\x2c\xef\xdf\x03\x30\xe1\x94\x24\x86\xe2\x16\x3e\x38\xb1\x90\xe9\x23\xd1\x40\x77\x1f\xa2\xe6\x03\xfd\x55\x49\xb4\x31\x57\x73\xf2\xd5\x7a\x56\x88\xf9\x87\x1c\x3f\x38\xf1\x6a\x8d\xdb\x34\xef\x41\xbc\x45\x0f\xa4\x02\xb0\x55\x58\xa1\xe6\xb7\xe9\x9b\x77\x2a\x6f\x8f\x1f\x9c\xf9\xfa\xb1\x9c\x44\xa1\x4a\x3b\x5a\xa3\x54\xf4\x44\xad\xd3\x54\xbb\xe9\x8c\x65\x58\x74\x77\x8b\x1e\xd9\x07\x8d\xe6\xe8\x86\xf3\xdd\x1b\xc8\x90\xc2\x23\xed\xc3\x65\x3b\x9e\x8b\xe8\x06\x99\x92\x2e\x41\x32\xda\x82\x73\x43\xa1\xa2\x4c\xb7\x25\xc7\x5c\x5e\xc9\xb9\x98\xff\x76\x83\xea\xf9\x57\x3b\xdb\x83\x57\xf7\x77\x06\xef\xe0\x2b\xdf\x02\xa1\xd2\xee\x62\x21\x8a\x0e\x96\x6a\xf8\x15\xc0\xfd\x47\x00\xba\xe0\x29\x80\xe2\x5b\x3d\x4b\x89\x4e\xe2\xdb\xaf\xa6\x3f\x05\xd2\x6a\x8f\x53\x3b\x49\xf3\xbc\xf8\xe7\x47\xbc\xa7\x26\x2d\x0a\x31\xab\x44\xf1\x61\x39\xcb\x90\xa2\xc1\x5f\x2d\xfc\xec\x91\x23\x0e\xdd\x7b\x10\xce\x8b\x23\xda\x82\x62\x97\x45\x25\x7e\x05\xeb\x80\xac\x08\xb2\xec\x91\x7d\x70\x1d\xf9\x67\x04\x58\x96\xc7\xa4\x87\xc4\xc3\x2d\x0d\x87\x9a\x63\xf4\xa8\x96\xfc\xd8\x3e\xff\x7a\xb8\x69\x6e\xb1\x4e\xa8\xdb\x3a\xbe\x1a\x6b\x58\x67\xb3\xb3\x47\xe6\xab\xa1\x65\x3b\x42\x2c\x66\x95\xbc\x12\xd8\xbe\x3c\x42\x70\x3d\xfc\x85\xab\x27\xfc\xb7\x28\xf2\xff\x09\x27\x17\x5b\xfe\x9f\xb8\x53\x9a\x91\x8a\xb2\x6c\x8f\x23\xfd\xe5\x71\x3c\x7f\xe4\x38\xf4\x82\xdd\xf4\xed\xb3\x48\x7f\x7d\x16\x87\xca\xde\xfe\xef\x87\xa1\x6e\x8e\xf0\x83\x53\xd6\x97\xf7\x40\xdd\x8d\x18\x14\x8c\x04\x4b\x47\xd5\x6a\xbd\x55\x62\x88\x5b\xbc\x9e\xa9\x5a\x9e\x61\xd2\x34\xc3\xec\xae\xfe\x54\x8e\x23\x19\xcd\xe1\xa6\xc0\x8a\x14\x98\x9d\x41\xe9\xac\xd3\xba\x64\x82\x07\xca\xaa\xa0\x3a\x41\x50\x39\xea\xd1\x0d\x2c\xb1\x74\x62\x58\xa0\x68\x55\x48\xda\x34\x43\x7d\xd1\x3a\x5c\x36\xcd\x70\xd1\x01\x5b\x46\xac\x85\x27\xb8\xaf\xd7\x5c\x44\xa5\xdf\xad\x3b\x5c\x6a\x57\x76\xab\xba\x60\x40\xcf\x0f\x67\xd1\xc0\xa8\xf4\xf7\x10\xbf\x46\xb6\xeb\xbb\xca\xd6\xa7\x58\xb1\x94\x2b\x3f\x56\xdd\x49\x2f\x7b\xbf\x2e\xc1\xd4\x8e\xb5\x1b\xc0\x6a\x74\xc3\x84\x47\x2c\x41\x3b\x81\x1c\x97\xdc\x67\x31\xa6\x90\xe3\x82\xac\x41\x21\xae\x44\x41\xb6\x0a\x32\x4c\xd4\x05\x6f\xbe\xb9\x03\xda\xea\xbe\xdd\x0a\x6a\x58\x8d\x2c\xe9\x6f\xad\xf9\x0b\x96\xf5\x77\xfb\x9c\x47\x89\x9f\x41\x82\x19\xba\x81\x0c\xb3\x20\xd3\x81\xcf\x72\x92\x4d\x87\xb8\x20\xad\xf9\xb3\x46\x7a\x7b\x41\x2f\x9b\xcb\x04\x0a\x7d\x73\x24\xaf\x78\x01\x0b\xcc\x41\x11\x40\x38\x25\xe1\xc5\xe4\x06\xbe\xad\x52\x15\x9d\xdf\xdb\xdd\x54\xeb\x9b\xe9\x49\xd1\xba\xb8\xd4\x94\xe1\x99\xed\x05\x32\x4c\xf4\xf5\xc8\x52\x5d\xb1\xbe\x58\xa8\xd0\x4b\x17\x5a\xc9\xa0\x30\xcd\x21\x75\x14\x53\x9a\x3c\xc5\x8c\x07\xb6\x4d\x4f\xb0\x9c\xc8\xa9\x85\x67\xb7\xf4\x6b\x23\xcd\x52\x77\x19\x14\x2a\xd3\x51\x04\xcb\x3e\x52\xb6\xed\xb8\xd7\xf8\xea\x94\x4e\x98\x80\x25\xc4\xdc\x57\x87\xa8\x4f\xcc\xf3\x3d\xd8\xba\xcc\x00\xa1\x14\xe1\x2a\x9f\xd7\x29\x09\xcb\x2a\x9f\x3f\xc2\xe1\xfa\xd6\x5c\xd5\x20\x6e\xcc\x9e\x77\x97\xb7\x87\xd2\x89\x9b\x66\x28\x9c\xb2\x69\x04\x89\xf6\x50\x17\x2e\x44\x1b\x06\xf7\xa9\xa9\x69\xa4\xea\x95\xdb\xbd\x92\xfb\xec\x10\xf1\xcf\x88\x15\x4a\x44\x94\xed\x86\x0a\x5f\x31\x09\x02\x5c\xd8\xe3\xaa\xa9\x80\xca\x29\x77\xb1\xe0\xfe\xa6\xeb\x4f\x0e\x52\x0b\x28\xab\x1c\x75\x51\xcb\x04\xd7\x36\x21\x23\x6d\x25\xe6\xa8\x9e\xfe\xa9\xef\xa0\xce\x5a\xfb\xbb\xda\x58\x92\xf4\x91\xfb\x31\x7f\x8c\x32\x1d\x5d\x20\xa7\x78\xb3\x95\xfa\xf1\xa3\x52\x9f\xff\x5a\xea\xf3\x87\x52\xdf\xed\xa9\x15\xfb\x1a\x55\x7c\xa8\xab\x40\x46\x37\x90\xa8\x70\x36\xed\xc5\xbe\x6e\x9a\x61\xa9\xc5\x9e\xb4\x4b\x7a\x77\x9d\xbc\x93\xf2\x44\x4b\x79\xba\x25\xe5\xf4\x4c\x6e\xa0\x1a\x48\xfd\x91\xf4\xdd\xdd\x5c\x89\x75\x8d\x15\xab\x39\x29\x36\x56\x92\x28\x27\xbd\x58\xe7\x58\xdb\x6d\xde\x2c\x0f\xdd\x88\x95\x58\x43\x81\x29\xf7\x59\x8e\x76\x0e\x05\x26\x1c\x8a\x8d\xcc\x06\xb9\x6d\x07\xc5\x46\x9c\xb7\xba\xda\x9b\xb9\xa4\x0b\x77\x32\x4c\xbb\x47\x37\xcc\xed\x4c\xd5\xdd\xa5\x40\xee\x69\x82\x05\x64\x98\xd3\xea\x6e\x90\x05\x3c\x47\x96\x4c\x6c\x3b\x9b\x62\x32\xc9\xa6\x56\x4a\x7f\x72\x3e\x3a\x6b\x5c\xa0\x86\x1d\x3c\xeb\xce\x35\x37\x4d\x96\xf4\x21\x57\xce\xc1\xb2\x4a\x0e\x24\x1f\x09\x94\x8a\x57\xfa\x3a\x00\x52\xf3\xdb\x27\xad\xcf\x59\x65\x3d\xf4\x49\x4b\x2c\x34\xd1\xfb\x0c\xaa\x18\xaa\xf4\xbd\x69\x7a\x43\xa4\x77\x57\xff\x30\x9d\x7f\xdb\x03\xa3\xcb\x39\x1b\x2a\x05\x0f\x62\xa8\x87\xb7\x59\x58\x4e\xc2\x73\xdf\xf3\xab\x50\xf6\x5e\x1f\x64\x58\xed\xde\x58\x24\x10\x72\x52\xb5\x5a\x23\xa8\x5a\x77\xaf\x52\xee\x5e\x46\xee\x9e\x4e\x63\x4a\x52\x0b\x95\x0a\xb4\xda\x3e\x0a\xb4\xfa\x5b\x4b\xd3\x2c\xc8\x05\x0a\x89\xb2\xe4\x5b\x0a\xcb\xe3\xa0\xcc\x9c\x2a\x7b\x78\x4c\xfc\x1f\x11\x15\xa6\x2b\x91\x44\xd3\xf4\xf9\xe3\xa7\x9c\x9b\xe6\x47\x56\xc1\xbf\xff\x2d\xac\xde\xd3\xba\x53\x60\xec\xc2\x73\xf0\x9e\xea\xca\xa7\xcc\xff\xca\xa1\xa2\x75\xd5\xa9\x3c\x24\xf9\x1d\x85\xa3\x6e\x75\x2e\xe0\x02\xbc\x67\x5b\xf4\xe4\x51\xd6\xca\xbc\xe1\x09\xc3\x52\xb5\x33\x2d\x2b\x67\xa4\x65\x32\xa5\x64\x4c\x93\xd9\x17\xba\x68\xe6\x82\x66\x94\xbb\xea\x1e\xc8\xf5\x3d\x52\x4a\x99\x3a\xff\xf2\x5b\x3d\x2b\xc4\xfb\x3c\xaf\x88\x01\xbe\x15\xd5\x63\xce\xfa\x03\x3b\x4f\x22\x58\x3a\x25\x45\x7a\xaa\x90\xea\x9d\xb5\x0f\x8b\x96\x5a\x86\xeb\x3c\xd5\xc1\x1e\xb1\x05\xd9\x65\x92\xcc\x64\x4b\xf4\xf4\x38\x32\xd9\xae\x0a\xeb\x69\x80\xea\x8f\xdc\x91\xeb\x27\x51\xa9\x10\x0c\x94\x7d\x55\xa9\x7f\xc2\x8b\x11\xe7\xba\x0a\x60\x8a\xe8\x8d\xdc\x88\x4e\x91\x25\x1c\x58\x57\xc6\x63\xc5\x7c\x67\x8c\xaa\x8a\x31\xd3\x35\x52\xb0\x0d\x20\xd3\x86\x9a\xc5\x96\xc7\x47\x63\x6e\x33\x37\x8c\x9b\x26\xde\x19\xd3\x30\x05\x31\x43\x4d\x4e\x9f\x91\x34\xde\x29\x75\x51\xe6\x39\xdb\xd4\x64\x6f\x2a\x2c\x85\xc1\x2d\x8f\x5b\x31\x07\xd9\x52\x20\xe3\xdc\xef\x9e\x53\xcb\x30\x48\x53\xd3\x79\x28\x43\xa9\xb2\x61\x90\x62\x6c\x2d\x61\x4f\x6d\x3f\x25\x83\x19\xe8\xfa\x57\x09\x64\x69\xf5\xd1\xd6\xda\x01\x7a\xc5\x4a\xa8\x61\x09\x9e\xba\x9c\x63\xb5\x13\xf3\x1e\x8d\x94\x6b\x37\xae\x60\xd2\x89\xf9\x76\xbb\xd2\x89\xd2\x11\x2f\x62\xd3\xb4\xed\x74\x0b\xf9\xd4\xde\x83\x94\x78\xdf\x38\x3c\x3c\x3c\x34\x14\x8f\xb2\xbc\x69\x8c\xfd\xf6\x95\xf3\x9f\x6c\x68\x65\x4d\x33\xb4\xb2\xbe\x10\xd9\x34\x8d\xa7\x06\x62\xd6\x55\x06\xba\xc4\xf4\xec\x23\x93\x20\x1d\x61\xbd\xb3\xc6\x40\x31\x27\x0e\x65\x8b\xbc\xe4\x8e\xf8\xc6\xca\xed\x6a\x85\x61\xae\x66\xd4\x50\xb7\x33\x5c\x0e\x75\xb7\xd7\x6e\x38\xff\x29\xb1\x6e\xe7\x2c\x2d\xdc\x87\x94\xfe\xe4\xe8\xdd\xf6\x81\x4d\xb7\xa4\x07\x5f\x5b\x33\xae\x60\x90\x15\xaf\xd3\xff\xc9\x4f\x6d\xeb\x80\xba\x04\xea\x4a\xa7\x50\x35\x57\x9f\xe3\xa5\x13\xc3\x05\x92\x1d\x3b\xb8\x63\xc7\x78\x97\x39\x3d\x37\xcd\x0b\x9d\x41\x32\xcd\x8b\xad\xcc\xe9\xf0\x92\x0c\xa7\xf6\x00\xce\x4d\x73\xa8\x47\x0c\x2f\x9a\xe6\x82\x7e\xf4\xdb\x79\x5f\x5f\x21\xda\xf8\x5f\x79\x27\xbb\x78\xe9\x94\x40\x90\x23\x5d\x6b\xe1\xea\xfa\x15\x97\xfb\xdb\xf5\x18\x1c\x44\x5b\x92\x56\xb1\x4b\x15\xc9\x58\x15\x13\x3a\x61\xda\x43\x49\x37\xb9\xb3\x05\x5e\xf4\x8f\x8a\xc7\x56\x78\x0e\xe7\x78\x01\x17\xb8\x82\x5c\x99\x15\xe5\xe4\x91\x49\x49\xad\x05\xac\x70\x32\x55\xb6\x6a\xb5\x55\x7e\x94\x17\xec\x1a\xcf\xe0\x0a\x5f\x92\xab\x1a\xd8\x76\x1e\xa2\x1b\x6c\x8a\xe4\xd7\x78\x31\xc9\xa7\x3b\x57\x30\x57\x0f\xa3\xab\xc6\x85\x12\x53\xa8\x31\xb7\xca\xa0\x0e\xf3\x80\xc7\x78\xae\xee\x4d\x76\xae\x60\x89\xe7\x93\x52\x0f\x4a\x70\xbe\x1b\x5b\xcb\xdd\x35\xc4\xb8\xde\x8d\xad\x64\xe7\x6a\xf7\xca\x5a\x4d\xea\xa9\x55\x40\x81\x2c\x1e\x5d\xab\x1b\x82\x84\x46\x73\x6b\xbe\xbb\x84\xd5\xa4\xb6\xed\x29\xc6\x3b\xd7\x01\x8d\xc3\xa2\x63\x87\x22\xb2\x2c\xe9\xaf\x7a\x67\x90\x6c\xdb\x0a\xa4\x66\x8b\xb6\x6c\xed\x1f\xaa\xf6\xc1\xbd\xcb\x41\x8f\x94\xfb\xf3\xed\x52\x39\x7d\x51\xa8\x5c\xa4\x0c\x1f\x2a\xf8\xe7\xbd\x82\x07\x11\x91\x41\xa0\xe5\xfc\x4a\xa3\xb2\xa5\x4b\x1e\x0f\xcb\x3e\xb7\xa1\xd8\x83\xfb\xc9\x43\x1e\x91\x65\xf1\xda\x85\xa9\x41\x83\x54\x95\x77\xff\x37\x60\x63\x57\x03\xeb\xcc\x54\x07\x73\xec\x76\x30\x55\x0d\xdf\xa3\x14\xfb\x25\x4c\xef\x17\x30\x3d\xa5\xc3\x75\x9c\xbb\xe5\x36\x3a\xe5\x3a\x95\x95\x2e\x4d\xcf\xd1\xfa\xcb\xe9\x0b\x79\xa0\xa6\xd7\x87\xb5\x3c\x50\x62\x37\xaa\xab\xe2\x21\x4f\x90\x84\x25\x45\x39\x51\x25\xda\x5d\xfc\x0d\x33\x8c\xa3\xa4\xd7\x5b\x7e\x02\xcb\x4d\xf9\x53\x1b\xe6\x14\x98\x93\x27\x07\x35\x16\xb0\xb4\xb1\xe0\x90\x87\xae\x69\x2e\x43\xb7\xe3\xee\xe5\x4e\xde\x34\x39\x24\x38\x6b\xbf\x89\x60\x2e\x14\x3c\x58\x86\x45\x50\x58\x98\xf3\xc4\xc2\xd2\xea\xfb\x0a\xc8\x79\x50\x87\xaa\x7c\xbe\xed\x50\xcb\x17\x9c\x43\xac\x6a\xea\x0d\xdb\xb0\x12\x7e\x5b\x61\x1a\x25\xd6\x5f\xce\xfd\x12\x27\x8b\x82\x44\xeb\x2f\xe7\x41\x59\x12\x8f\xd2\x4d\x66\x72\xeb\x4b\xa1\x4f\x9f\xe6\x3f\x0d\xab\xb6\x8c\xdb\x4f\x9f\x7e\x33\xc0\x58\x18\x1c\x8c\x27\xa6\xf1\x00\x46\xb7\x02\xf7\x53\xee\x27\x9b\xc2\x5c\x7d\xd8\xed\xd0\x47\xdd\xbe\x7b\x4a\x13\xbf\xc0\x42\xab\xca\x35\x2e\x9c\x18\xe6\xfd\xbd\x3a\xac\xb0\xda\xbc\x5c\x63\x72\xe7\xc6\xbd\x67\x17\xf6\x05\x87\x1e\x94\xd8\x97\x62\x7f\xc1\x25\xb0\x21\xa3\x48\x5e\xe5\x70\x18\xe7\x4d\x53\x3a\x69\xc5\xbe\x29\xe3\xa2\xcb\x23\xc6\x60\xac\x66\xdf\x07\x73\x91\xe5\x2b\x99\xd1\x56\x06\x86\xc5\x96\x91\x71\xaf\x06\xf8\xb1\x12\x60\x81\xc3\xa5\x69\xaa\x84\xcb\x47\x56\x82\x76\xcc\x3c\xee\x2c\x2a\xc1\xbe\xf1\xa8\xf4\x3b\x37\x74\xdd\xc7\xfe\xdb\x65\xe8\xda\x5c\x17\x6c\x4d\x7c\x3a\x77\x04\xf6\x89\xa3\x85\x23\x6c\x0f\xe6\xca\xaa\xe3\xfb\x09\xab\x31\xdf\xb9\xe1\x2f\xdc\xe8\xc6\xaa\xfd\x7a\x4a\x0b\x0b\xda\x4b\xbc\x5a\xb3\x39\x0f\xdd\x88\x82\x85\xb9\xbf\xf2\x4b\xa8\xf1\x07\xfc\x20\x6f\xa3\x27\x45\xcc\x21\xd1\x90\xdc\x20\x45\x32\xf7\x73\x95\x1d\x54\xb2\xa2\x5c\x80\xb4\xb5\x92\xd7\x9c\x83\x37\xa4\x10\x68\xb5\xa6\x08\x89\x57\x78\x0d\xd7\x28\x61\x85\xc9\xdd\x91\x12\x57\x9c\x22\x17\x09\x73\x2c\xdb\x90\x6a\xd3\x37\xe7\x14\xdc\xc8\x4e\xef\x49\x7c\xc5\x44\x17\x4b\x72\xb8\xd6\xab\x27\x1d\xcc\xce\xa4\x13\xc4\xaa\x43\x49\x6e\xa1\x94\x38\x25\xae\x9c\x12\x17\x4e\x09\xf9\x2e\x8e\x21\xc3\x57\x8c\xac\x6b\x0e\x5f\x79\x0b\x77\xc1\x9d\xd9\x65\xc9\xb8\x42\xfd\x15\x4b\xa0\x7a\xac\x97\xbf\xf0\xa2\xc9\x6a\xeb\x0c\xe0\x7a\xeb\x65\xea\x4f\x92\xed\xbe\x6a\xbb\x0f\x7e\x60\xad\xdd\xf9\x2a\xd7\x35\xc2\x0f\x23\xdf\x2d\xc7\xda\x12\x4d\x43\x06\x38\x72\x77\x85\xa3\xf3\x41\x7a\xee\xbb\xfc\x5a\xa5\x15\xd7\xf9\xf5\x2f\xa2\xa1\x55\x57\x4d\x65\x09\xde\xa5\x07\xc8\x41\xe8\x5d\xf5\xf1\x1e\x18\xa2\x55\xf7\xaa\xfe\x67\xd8\x65\x35\x99\xe0\x4d\x53\x84\x17\x14\x03\x8d\xd0\xe5\x4d\xb3\x9e\x15\xa5\x38\x4e\xf3\x59\xc5\x04\x57\x72\x32\x64\x02\x09\x9d\x7b\x37\x0d\xca\x8f\x5d\xe7\xd7\xcc\x92\x20\x78\x97\x61\xf9\x3d\x9a\xb3\xdf\x47\x37\xd6\x98\xfb\x2e\x6c\xa4\xb0\xad\x48\x2d\x76\xc6\xea\x57\x5d\x8b\xb4\x6e\x19\x0c\x2b\x27\x6e\x2b\x45\x33\xd3\xac\xfa\x6c\xa8\x0a\x8c\x36\xaf\x98\x71\x5d\x1e\xbc\x62\xc5\x68\xcc\xa1\x2b\x5a\x0e\x24\x6e\x7c\x3c\xc8\x4c\x53\xa5\x35\xe4\x5d\x30\xf2\x0e\x98\x3b\xd9\xf8\x0a\xbf\x39\x73\x79\xc5\x2a\xce\x21\x53\x56\xf2\x77\xf8\xda\x5b\xc9\xbe\x48\xfc\x9f\x9b\x35\x55\x15\xb7\xff\x2b\x33\x0d\xe3\xfd\xf6\x60\x35\xa7\x3c\x76\xa6\x5d\x7c\x5b\x11\xff\x62\xe5\x88\x60\x2b\x28\x45\xc4\x3c\x92\x14\x6c\x18\xdd\x1d\x99\x01\x6e\x28\x55\x14\x49\x6a\x9d\xbc\xfd\x0c\x8d\xb3\xd9\x99\xe1\x2b\x57\x9c\xe8\xdb\xfb\x07\x2d\x92\xea\x0b\xd3\xf1\xd3\xee\x13\xd3\xe8\x35\x4b\x59\x06\x39\x07\xb7\x11\xe0\xb9\x20\xb9\xff\x5b\x88\x64\x73\x42\x7c\x12\x25\xaa\xcf\xef\x86\xd0\x62\x55\x17\xd1\xf5\x8b\xb6\xcc\x5e\xd4\x59\xdc\x66\x7b\xd4\xf3\x3f\xbf\x0b\xd0\xf7\x0f\x57\xb3\xb4\x16\xe7\x09\x4d\xcf\x7f\xbf\x38\x7f\x24\x13\xae\x53\xdb\x1b\x51\xbb\xdd\xd0\xbf\xab\x3a\x25\x75\x3e\xdb\xd4\x4b\x54\x9b\x58\xd6\x6d\x7a\x6a\x8a\xd0\x6d\x1a\x81\x88\x59\x94\xf9\x99\xed\xdd\xa9\xaf\xd8\x54\x56\x68\x21\xf3\x40\x6e\x8a\x50\x72\xf5\x9d\x8a\x65\x18\x81\x0c\x8b\xd6\x03\xcd\x50\xa8\x6c\xa3\x65\x18\x50\xe1\x8d\xdd\x7f\xcb\x51\xd9\x76\x90\x51\xf4\x67\x65\x3c\xc8\x2d\xcc\x6e\xdb\x42\x90\x3b\x5f\x25\xe6\x77\xbf\x4a\x94\x3c\xe8\xdd\xc0\x7c\xf3\xbd\x9f\xe5\x35\x8d\xc7\x37\x88\xca\xfb\xb9\x41\xe1\xc4\x90\x53\x54\xa4\xbe\x29\x2a\x49\xa7\x3b\xa5\xaa\x9f\xa1\x18\x2f\x73\xc4\x56\x96\xea\x61\xa6\xc3\x34\x87\xca\x89\x29\x30\x37\xcd\x61\xae\x8a\xba\x9a\xa6\xbf\x0d\xab\xa2\x22\x72\x7d\xbb\xf4\x6b\xe5\xb8\x0c\xb1\x87\x51\x6b\x00\x6e\x58\x43\x81\x09\x62\x0a\x43\xd9\x34\xc3\x9c\xf7\x5e\xb1\xeb\x0f\xe5\xdf\x95\x2e\x6b\xb9\x73\xc5\x96\x84\x69\xd7\xae\x8b\x8b\x58\xd2\xa7\x5c\xf8\x0b\x96\xf6\x74\xe2\x51\xe2\x93\x33\xef\x06\x65\x58\x07\xb5\xce\x22\xcb\x49\x3d\x1d\x62\x3e\xa9\xfb\x60\x9e\x5a\x42\x6a\xe8\xa0\xf6\x9f\x49\x63\x1a\xb9\xfe\x66\xb9\x0d\x15\xf3\xbb\xb7\xb7\x4c\xe8\x8f\x7f\x42\x72\xa6\xab\x10\xb7\xaa\x7d\x6a\x62\x8c\xf6\xa3\xbf\x89\x2e\x8e\x1c\xa8\x52\xb8\xa9\x81\x78\xae\xde\x37\xe5\xe7\x3d\x8b\xea\xef\x91\xc4\xd6\xb9\x95\x0f\xbe\xff\x21\xf7\x46\x45\x5b\xb5\x2a\x94\xef\xbf\x77\xa2\xbd\xb6\xdf\x80\x6e\x38\x46\xda\x76\x90\x4f\xe4\x74\x17\xb3\xb6\x1e\x6c\x52\xa0\x3b\xb5\xf0\xbc\x4f\x03\x88\x2e\x30\x26\x42\xf1\xa0\x78\xd1\x4f\x2e\x2c\x8b\xe7\x93\x62\x1a\x56\xea\x6b\x5d\xad\x53\xf2\x49\x61\x79\x24\xce\xfa\x01\x5d\x0e\xfa\xc9\xa2\xae\xe9\xa8\x6a\x5c\x6a\x98\xee\x60\xd5\xeb\xcf\xed\xbb\x80\x7e\x67\xc9\xb6\x7e\x64\x9b\xaa\xa2\x48\x6c\x22\x75\xcb\x70\x0c\x4b\x6c\x5c\x62\xc1\x2d\xe6\x86\x59\x64\x90\xdf\x24\x2c\x83\x5b\xd9\x06\x60\x7a\x87\xc5\x75\xd9\x5a\xd6\xb9\xc5\x86\xeb\x18\x81\x65\x65\xe4\x04\xab\x6f\xd0\x04\x16\x96\xe8\x0b\x0c\xab\x8d\xc8\x5a\x56\x16\x56\x9b\x69\x06\x64\x36\x56\x81\x6d\x6f\x4d\xb5\xb0\xd0\x33\x2b\x65\x33\x36\x75\x65\xfa\x93\xf7\x2d\x9c\x33\xbe\x89\xd1\x36\x98\xc6\x1b\xe6\x18\x08\xbc\x63\x48\x81\x2c\xf4\x9c\x09\xee\xaf\x88\x0f\x68\x33\x33\x1d\xf7\xeb\x6a\x87\x4f\x73\x8b\x7d\x72\x3e\xcd\x77\x79\xd4\xd0\xaf\xc5\x99\x98\x58\xf6\x34\xa2\xc7\xe8\xc9\x88\xdc\x26\x65\x70\x63\x21\x53\x58\xe9\x67\x75\xd5\x0a\xd7\xd8\x56\xeb\x0e\x2e\xf3\x3c\x15\xb3\x6c\x90\x17\x83\x4b\x99\xcd\x8a\x9b\xc1\x9c\xc2\x4d\x03\xae\x50\x7f\x49\x25\xb3\xc5\x60\x95\xcf\x85\x01\x97\xdd\x87\xe9\x03\x62\xd4\xc1\x72\x56\x0e\x56\x79\x21\x06\xd5\x72\x96\x0d\xbc\xa7\x83\x52\x2e\x32\x99\xc8\x78\x96\x55\x1a\x48\x69\xc0\x39\x1a\xae\x37\xde\xdb\x7f\xfa\xec\xe0\xf9\xe1\xec\x32\x9e\x8b\x64\xb1\x94\x5f\xbe\xa6\xab\x2c\x5f\x7f\x2b\xca\xaa\xbe\xba\xfe\x7e\xf3\xe3\xe5\x6f\xaf\x5e\x1f\x1d\xbf\xf9\xd7\xc9\xef\xff\xdf\xe9\xdb\xb3\xf3\x77\xff\xff\xfb\x8b\x0f\x1f\xff\xf8\xf3\xaf\xff\xfa\xef\x27\x9f\x0d\x38\x43\x4f\x78\xfb\x70\x83\xde\x3e\x5c\xdc\x2f\xec\xf5\xe0\x3d\x4e\x3c\x32\x3f\x9e\xeb\x82\x27\xf6\xc0\x13\xfb\xe0\x89\xa7\xe0\x89\x67\xe0\x89\x03\xf0\xc4\x73\xf0\xc4\x21\x78\x82\x06\x09\xcf\xa3\x3f\x63\xfa\xb3\x37\x85\x97\xea\x43\x8e\x23\xf4\xc4\xa1\xfa\xa2\x4a\x55\x51\x1a\xdd\xf1\x6c\x8a\x9d\xe7\x22\x91\x99\x30\x4d\xfd\xeb\xcc\x56\x73\xae\x1f\xd9\x43\x53\x33\xbb\xdd\x7c\xb7\x69\xd4\x99\x1e\x37\xdf\x54\x7f\xab\x0b\x1b\x61\x9a\xfa\xd7\x21\x2f\xab\xa8\xf4\x05\xc0\xdd\x26\x9c\xc1\x70\xc9\xab\xe2\xe6\xe7\x12\x0b\xf1\xad\x96\x85\x60\x6d\x3d\xa8\xc1\x6f\xe3\x59\x15\x2f\xd9\x6b\xfe\xf3\x56\x73\xa0\x70\xfa\x2f\xcb\x70\x76\xdb\x66\x05\xfe\x63\x34\xfa\xcf\x41\x99\xd7\x45\x2c\xde\xce\xd6\x6b\x99\x2d\x3e\xbe\x3f\xc5\x79\x1e\xdf\xf9\xf7\x1a\xce\x6a\xb6\xfe\x8f\xff\x17\x00\x00\xff\xff\x2f\x88\x72\xca\xa2\x43\x00\x00") func bignumberJsBytes() ([]byte, error) { return bindataRead( @@ -94,11 +85,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\x77\x13\xc7\xb2\x38\x0e\xbf\x67\x2d\xbe\x43\x5b\xcf\x79\x90\x84\x85\xe4\x0b\x21\x44\xc4\xe1\x18\x43\x82\xf7\x09\x98\x05\x78\x67\xef\xe3\xed\xc3\x1a\x6b\x5a\xd2\x84\xd1\x8c\x7e\x33\x23\x5f\x02\xfe\xee\xff\xd5\xd5\xb7\xea\xdb\x68\x64\x1b\xc2\xde\xb1\xb3\x56\xd0\xcc\x54\xdf\xaa\xab\xab\xab\xaa\xab\xab\x0a\xfa\xff\x16\x49\x41\x77\x3a\xe3\x45\x36\xaa\x92\x3c\x23\xb4\x53\xf5\xb2\x5e\xd1\xfd\xa4\xde\x94\x9d\xbc\xb7\xe8\x7e\x4a\xc6\x9d\xb5\xec\x28\x3f\xe6\xbf\x2a\xf8\x75\x1a\x15\x24\xda\xa9\x2e\xe6\x34\x1f\x13\x59\xd7\x4e\x4b\x16\x6d\xdd\xbb\x27\x5e\x3e\x61\x65\x16\xf7\xee\x45\xdd\x82\x56\x8b\x22\x23\x51\x27\xef\xad\x6d\x74\xd9\xfb\x44\xbe\x4b\xc4\x3b\x56\xeb\x78\x27\xa3\x67\xe4\x45\x51\xe4\x45\xa7\xb5\x17\x65\x59\x5e\x91\x71\x92\xc5\x64\x96\xc7\x8b\x94\x92\x76\x6b\x3d\x5f\x6f\xb5\x5b\xdd\x27\xd5\xb4\xc8\xcf\xc8\xb8\x3f\xca\x63\xba\xd3\x7a\x75\xf0\xfc\xf0\xd7\x17\x1f\x5e\x1f\xbc\xff\xf0\xf3\xc1\xe1\xeb\xe7\xad\xde\xf8\x92\xd5\x97\xee\xb0\xbe\xef\x7c\xa2\xe7\xf3\xbc\xa8\xca\xe1\xa7\xcb\xcb\x27\x6c\x0c\x47\x1b\xc7\xfd\x51\x94\xa6\x9d\xb4\x2f\x3e\xf5\x64\xef\x3b\x94\x0f\x30\xdb\x01\xc0\xcd\xe3\x23\x7a\xfc\x44\x74\xb5\xec\x64\x4f\xb3\x21\xed\x5e\xf6\xd2\x9e\x2e\x49\x7b\x1c\x77\x97\x02\x8a\x35\x29\x3f\x42\x2f\x92\x46\xb8\x1a\xe7\x45\x87\x41\xe7\x3b\x1b\x4f\xf2\x1f\x8b\x7e\x4a\xb3\x49\x35\x7d\x92\xaf\xaf\x77\xcb\x4e\xc1\x10\xaf\xba\x71\xd9\xed\x7c\xda\x1c\x1e\xa9\x2e\x8b\x2a\x7a\x1c\x4b\x3d\xd1\x76\xf7\xd3\xdd\x3b\xfc\x8d\xec\xcd\xce\xd1\xdd\x3b\x84\x7c\x62\xff\x23\xa4\x35\xca\xb3\xb2\x8a\xb2\xaa\x35\x24\x55\xb1\xa0\x3d\xf1\x3a\xc9\xe6\x8b\xaa\x6c\x0d\xc9\x11\x7f\xa1\x0a\xc0\xd7\x2c\x9a\xd1\xd6\x90\xb4\x3e\xe4\x67\x19\x2d\x5a\x3d\xf4\x89\x0d\x92\x7d\x8a\xe2\xb8\xa0\x65\xd9\x92\x9f\x2e\xf9\x8f\x63\xd9\x80\xac\x02\xfe\x95\x2f\xf3\x45\xd5\xa4\xd9\xfc\x03\x2e\x65\x34\x7b\x72\x51\xd1\x72\x7b\x2b\xd8\xac\x84\x53\xa8\x67\xef\x2f\x7b\x37\x87\x91\x2b\xf7\x4c\x0d\x0e\xa3\xb4\x29\x46\xae\x34\x05\xdf\x3e\x2e\x46\x79\x56\xd1\xac\xba\x11\x6c\xfc\xfb\x53\x06\x9b\xcf\x6f\x90\x30\xc6\x51\x5a\x7e\x75\x5c\x14\xb4\xa4\xc5\xa9\x97\x73\xfc\x1b\xcd\x68\xb9\x38\x79\x4b\x27\x49\x59\x15\xd1\x5f\x6f\x66\x7b\xf5\xf5\xd0\xb3\x83\x6b\x6f\x2e\x55\x11\x65\xe5\xd8\xcf\x4e\xff\x0d\x71\x52\xd8\xb4\x72\x25\xa4\x94\xb4\x7a\xb7\x84\xee\x6e\x16\x37\x4e\x0f\xbe\x62\xdb\x5f\x65\x5e\xa2\x66\xf3\x51\x5f\xc9\xbc\x48\x66\x51\x71\xe1\xef\x4f\x9e\xa7\x4d\xe6\x75\x57\x34\xf9\x9f\x81\x56\x6b\xf7\xaf\xaf\x2a\x8c\x94\xbd\xb0\x10\xf1\x4d\x22\x25\x30\x92\x38\x29\xf3\xb3\xec\xba\xa3\x88\xb2\x3c\xbb\x98\xe5\x8b\x72\xb5\x61\x24\x59\x4c\xcf\x69\x6c\x6e\x93\x37\x3a\xeb\xba\x05\xdc\x2d\xb3\x89\xb3\x24\xbb\xee\x8e\xb0\xbb\x00\xcc\xbc\xc8\x62\x1a\xb7\x6c\xbc\xd1\x53\x46\x27\xff\x61\x48\x3b\x49\xe2\xb8\x29\xd2\xae\xdc\xc8\x69\x94\x2e\xfc\x03\x59\x24\x59\xb5\xf5\xdd\xa3\xa5\x13\xf3\x9a\x9e\x3d\x4b\xbe\x81\x29\xb9\xf6\x3a\xdd\x9b\x46\xd9\xe4\x5b\x20\xae\x1b\xa3\xad\x50\x03\x58\x1f\xa9\xa7\xab\x00\xaa\xde\xf0\x2d\xaf\x01\xc6\xee\xde\x39\xbe\x7b\xe7\xee\x9d\xcb\xde\xa7\xcb\xe3\xde\xd6\x9f\x6c\xf4\xf8\x8f\x55\xf1\xff\x5c\xd9\x76\xbc\xc8\xe2\x6b\x91\xd3\xcd\xec\x90\xb7\x4a\xfe\x37\x23\xf2\xdc\xbc\x92\x7f\xab\xd1\x7e\x5b\x38\x69\xa8\x39\x05\x90\x21\x34\x9e\x6f\x56\x26\xfe\x1a\xb2\x84\xb1\x33\x6e\xdf\xe4\xce\x78\x05\xba\x18\x17\xf9\xec\x06\xc8\xa2\xca\x6f\x40\xa1\xbe\xbe\x48\xfa\x6d\xac\xb5\x6f\x09\xa7\x49\x16\x27\x05\x1d\x55\xfb\xfe\x8d\x7a\xb5\x1e\x5d\x7f\x82\x92\x51\x34\x7f\xff\x4d\x4c\x52\x00\xbb\x8d\x75\x7b\x3a\xcf\xcb\xa4\xde\x44\x31\x8f\x2e\xa2\x93\x94\x5a\x62\xc9\x9f\xc9\xde\x82\x94\x79\x63\x7a\xe5\xf5\x49\x64\x57\x0e\xfe\xb9\x85\xe2\x3f\x4d\x2d\xbb\x31\xac\x85\x1a\x68\x4a\x8b\x7f\xde\xa4\x7c\xfb\x73\x71\x53\x2a\xf2\xb5\xb8\xee\x57\x99\x0b\x87\x7f\xde\x4e\xc6\x55\x27\xe3\x46\x76\xc7\xaf\x32\xe9\xfb\xbe\x8d\x73\x99\x70\xf9\xb0\x91\x70\x09\x0e\x3c\x64\x47\x7a\xb9\x74\xda\xfd\xc1\x38\x2f\x66\x51\x55\xd1\xa2\x6c\x77\x9f\x70\x88\x77\x79\x9a\xc4\x49\x75\xf1\xfe\x62\x4e\x4d\x60\xd6\x0b\x00\xbb\x7b\x67\x70\xff\xfe\xdd\x3b\xe4\xbe\x01\x2c\x4e\x38\x48\x52\x92\x88\xcc\x8b\x3c\x67\xf0\xa4\x9a\x46\x15\x29\xe8\x9c\x29\x8c\x59\x55\x12\x31\xa5\x84\x7d\x84\x2a\xf6\x2b\x32\x8b\xaa\xd1\x94\x96\x43\x78\x16\x00\xf8\xf7\xd1\xb1\xf1\xf4\xd0\x7c\x3c\xb6\x3e\x6f\xdb\x2f\x8e\x8f\x1e\x1d\x1f\x1d\xf7\x48\xbf\xdf\x67\xef\x07\xee\x38\x65\xd7\x77\x88\x72\xaf\xea\x74\xe5\xdc\x57\xd3\xa4\xec\x7f\x80\x25\xf4\xb3\x44\x17\x83\xec\x73\xe4\xed\xb3\x0f\xfb\x59\xf5\x04\x43\x73\x29\xc1\x07\x7e\x00\x5f\x44\x83\x4f\xee\xde\xb9\x04\x7c\x7a\x3a\xd3\x9f\x17\x79\xc5\x71\xb8\x43\x32\x7a\x66\x74\xb8\xf3\xe9\x92\x4d\x44\x6d\xb1\x3e\xc8\x4d\xc5\x62\x54\xe5\xac\x03\x1e\xd8\xe5\x4d\xf7\x93\x52\xd0\x81\x46\x0c\xa3\x54\x85\x1c\xe1\xf1\xb4\xb6\xc6\xde\xf6\x61\x22\x3b\x03\x81\xf8\xce\xbf\x8e\x3a\x47\x1b\x0f\x7e\x38\xbe\xdf\xfd\xd7\x71\xf7\xe9\xa0\xab\x86\x6b\xaa\x39\x35\x9d\xbb\xec\x7d\x6a\x61\x2a\x6d\x0d\x7f\xe8\xb5\x38\x25\xb6\x86\x9b\x0f\x2f\x8f\x7b\xdf\x7d\x0b\xa4\xff\x2c\xcf\xd3\x25\x74\x7f\xc2\x40\x82\x44\xcf\xbe\xaa\x1f\x82\x7c\xe1\xe7\x43\xf4\xfb\x18\x7f\xd8\x36\x9e\x96\x93\x38\x74\xf1\xca\xf4\xcd\x4a\xaf\x44\xe0\xa2\x80\x4b\xdd\xec\xc3\xaa\xa4\x6d\x96\xa9\xa1\x6b\xd1\x6a\x6d\xe9\x2b\x51\xf4\xff\x31\x2c\x9b\xf4\x7c\xff\xbf\x9a\x12\xb4\xea\xd5\x72\x6a\x7e\xf4\x4d\x50\x33\xdb\x0d\x15\x39\x57\x7e\x7a\xae\xa6\x94\xc0\xb6\x09\x44\xdd\xf7\x53\x35\xfb\xae\x7f\x49\x82\x85\xdf\x0f\xf1\xc3\xb1\xf1\x69\xdb\x7c\xb4\x68\x9b\x88\xcd\x5a\xff\x7e\x6c\x56\x26\x8b\xfb\x16\x01\x74\xf8\xea\xab\x80\x15\x5f\x6d\x19\x88\x12\x9e\x75\xc0\xbe\xac\xbc\x10\xcc\x42\x75\x2b\x41\x34\x5c\x5f\xfe\x8a\x6b\x81\xd5\xc2\x57\xc2\xa7\xcd\xde\x65\xf7\xca\xeb\x42\xf5\x71\xf9\xc2\xf8\xbe\xd1\xc2\x18\xdc\xe7\xfd\x7e\x3f\x4d\x4a\x32\x4e\x52\xca\xa8\x78\x1e\x15\x15\xc9\xc7\xe4\x8c\x9e\x6c\xf7\x7f\x2f\xfb\xac\x41\x06\x24\x9e\x19\xc8\xb8\xa0\x94\x94\xf9\xb8\x3a\x8b\x0a\x3a\x24\x17\xf9\x82\x8c\xa2\x8c\x14\x34\x4e\xca\xaa\x48\x4e\x16\x15\x25\x49\x45\xa2\x2c\x1e\xe4\x05\x99\xe5\x71\x32\xbe\xe0\x95\x24\x15\x59\x64\x31\x2d\x60\x3d\x54\xb4\x98\x95\xac\x29\xf6\xf0\xcb\xeb\x43\xf2\x2b\x2d\x4b\x5a\x90\x5f\x68\x46\x8b\x28\x25\x6f\x16\x27\x69\x32\x22\xbf\x26\x23\x9a\x95\x94\x44\x25\x99\xb3\x37\xe5\x94\xc6\xe4\xe4\x42\xd2\x15\x25\x3f\xb3\xee\xbc\x13\xdd\x21\x3f\xe7\x8b\x2c\x8e\xd8\xc8\x7b\x84\x26\xd5\x94\x16\xe4\x94\x16\x25\x9b\xad\x6d\xd9\x98\xa8\xb2\x47\xf2\x82\x57\xd3\x89\x2a\x36\x8c\x82\xe4\x73\x56\xb2\x4b\xa2\xec\x82\xa4\x51\xa5\x0b\xfb\xf0\xa0\x87\x1b\x93\x24\x83\x9a\xa7\xb9\x5c\xfc\x49\x45\xce\x92\x34\x25\x27\x94\x2c\x4a\x3a\x5e\xa4\x42\x3a\x3d\x59\x54\xe4\xb7\xfd\xf7\x2f\x0f\x0e\xdf\x93\xdd\xd7\xff\x24\xbf\xed\xbe\x7d\xbb\xfb\xfa\xfd\x3f\x9f\x90\xb3\xa4\x9a\xe6\x8b\x8a\x30\xb1\x15\x2a\x4b\x66\xf3\x34\xa1\x31\x39\x8b\x8a\x22\xca\xaa\x0b\x92\x8f\x79\x1d\xaf\x5e\xbc\xdd\x7b\xb9\xfb\xfa\xfd\xee\xb3\xfd\x5f\xf7\xdf\xff\x93\xe4\x05\xf9\x79\xff\xfd\xeb\x17\xef\xde\x91\x9f\x0f\xde\x92\x5d\xf2\x66\xf7\xed\xfb\xfd\xbd\xc3\x5f\x77\xdf\x92\x37\x87\x6f\xdf\x1c\xbc\x7b\xd1\x27\xe4\x1d\x65\x5d\xa3\xbc\x8a\xe5\xf8\x1e\xc3\xdc\x15\x94\xc4\xb4\x8a\x92\x54\x53\xc2\x3f\xf3\x05\x29\xa7\xf9\x22\x8d\xc9\x34\x3a\xa5\xa4\xa0\x23\x9a\x9c\xd2\x98\x44\x64\x94\xcf\x2f\x1a\xcf\x28\xaf\x2d\x4a\xf3\x6c\x02\x63\x57\x24\x47\xc8\xfe\x98\x64\x79\xd5\x23\x25\xa5\xe4\xc7\x69\x55\xcd\x87\x83\xc1\xd9\xd9\x59\x7f\x92\x2d\xfa\x79\x31\x19\xa4\xbc\x86\x72\xf0\x53\xff\xee\x1d\xc6\xba\x24\x63\xfe\x6f\x20\xe3\x51\x1e\xd3\xa2\xff\x3b\x67\xa6\xff\x1d\x2d\xaa\x69\x5e\x90\x57\x51\x41\x3f\x92\xff\xc9\x2b\x7a\x96\x8c\xfe\x20\x3f\xce\xd8\xf3\x7f\xd3\x6a\x1a\xd3\xd3\xfe\x28\x9f\xfd\xc4\xa1\xe3\xa8\xa2\x64\x6b\x63\xf3\x3b\xc1\x14\x9b\xec\x1f\x75\x22\x32\x2a\x25\x04\x3d\xef\x96\x23\x04\x0e\x04\xcd\xf6\x50\x2f\xe8\x7e\x56\x99\x90\x49\x56\x79\x01\x0f\x1d\xc8\x45\x08\xf4\xf9\x45\x16\xcd\x92\x91\xe4\xf8\xa8\x48\xcc\xbf\x00\x17\xf3\x16\x7d\x57\x15\x49\x36\x31\x0b\x95\xf0\xce\x0b\xfe\x96\x46\xd6\x40\x0b\x1a\xf9\x07\x7a\xe8\xc2\x2e\x82\xc0\x9e\xae\xeb\x3e\x73\xf0\xa4\x14\xc3\x34\x58\x78\x89\x2a\xe9\xc1\xf6\x2c\x19\xba\xbc\x9f\x80\x00\xfa\xaa\x0e\xd8\x73\x38\xf4\xe7\xcf\x5a\x83\x25\x01\xf0\xdd\xa2\x88\x2e\x38\xbc\x62\xf7\xb6\x34\xb1\xc7\xc8\x16\x09\x11\x62\x91\x71\x0e\x12\x93\x2a\x27\x34\x63\xa4\x3d\x88\x29\xfb\x47\xb5\xc4\x78\x76\xc4\x59\x29\xe3\x5b\x52\x6c\xb6\x76\x74\x5e\x3b\x1e\x39\x03\x2c\xad\x2d\x1d\xde\x91\x1d\xa8\xa4\x74\x7a\x0a\x3b\xc5\x8c\x56\xd3\x3c\xf6\xf4\x8e\x1f\x33\xe4\xc5\x8c\x70\x19\x28\x37\x26\x88\x55\xc0\x97\x98\xa8\xe0\x83\x98\x2a\xf9\x91\xfc\x37\x8c\x83\x7c\xe2\x14\x75\xa9\xe5\xff\xff\xe6\x33\x51\x92\x4f\xb8\xc2\x4b\xfe\x0d\xae\xce\x94\xe4\x13\x5c\xb3\xb9\x24\xe2\x31\x61\x1c\x84\xcb\x57\x8c\x3a\xa1\x43\x6c\xeb\x62\xbb\x83\x40\x8e\x81\x18\xb4\xcd\xe3\x7e\x39\xf8\x52\xe8\x62\xa8\x2d\x4d\x99\x11\x61\xb0\x3f\x4e\xd2\x8a\x16\x1d\x54\xb8\x8b\xad\x23\x82\xb4\x2a\x21\x53\x28\xc2\x00\x5b\x47\xf7\x68\xe3\xf8\x89\xe4\xb6\xc9\x98\x74\xd6\x70\x43\x46\x3d\xfc\xde\x10\xbf\x61\xd4\x4e\xb2\xd3\x28\x4d\x62\x4d\x17\xac\xd6\xb5\x21\x69\x93\x75\x62\x34\x20\xeb\xf6\x10\xb8\x4b\x9c\x01\x22\x24\xf3\x34\x4a\x32\x4e\x7a\xce\xd4\x72\x90\x37\xf2\x5b\xcd\xcc\x8a\x0f\x07\x27\xbf\xd3\x51\x75\x69\x57\x2a\x67\x5e\x97\xe4\x35\xc7\x36\x60\xcd\x74\xa2\xbe\x38\xb3\xd9\xe3\x35\xd8\x12\x1c\x4c\x24\x2a\x57\x76\x8e\x18\xf4\x71\x8f\x1c\x01\xfc\xb1\x67\x0d\x87\xd0\x94\x26\x25\xc8\x53\x7c\x8d\xd6\x61\xaa\x34\x30\x02\x0c\x83\x63\xca\xfb\x61\x8e\x8a\x84\x90\xe4\xb6\xdd\x0c\x4f\xa5\xcb\x26\x04\xa6\xca\x20\xfd\x97\x72\x01\x4c\x68\x85\x57\x69\x29\xd8\x8c\x22\x68\x56\x50\x74\x90\x95\x31\xea\xe8\xcf\xa2\x79\x27\xc4\x9a\xc1\xa0\xe8\x5b\x45\x06\xc7\xe5\x55\x77\x78\x6f\x8f\xa0\xcc\x31\x67\xeb\xf2\x49\xaf\x33\xa3\x4f\x62\xa3\x3b\x18\x8f\x4b\x5a\x39\x1d\x2b\x68\xbc\x18\x51\xd4\xb7\x68\x34\xea\x91\x65\x1d\x04\x24\x55\x51\x95\x8c\xde\x44\x45\xf5\x2b\x5c\x81\xb3\xaa\xee\xdb\xdf\x3b\xbe\xbe\xca\xca\x0a\xc6\xbf\x68\xfc\xce\xad\xf3\x55\x54\x4d\xfb\xe3\x34\xcf\x8b\x4e\xc7\x69\x72\x9d\x6c\x6f\x76\xc9\x80\x6c\x6f\x75\xc9\x7d\xb2\xbd\xa5\x06\x8e\xb0\x18\x8d\x46\x64\x9d\x74\xd4\x8e\x65\x60\x3f\x80\x49\xf2\x14\xef\x7c\x84\x6c\x6f\x91\xa1\xf9\x26\xd0\x61\x35\x07\x3d\xb2\x61\x4e\x43\x41\xcb\x45\x5a\x49\x62\xe2\xb3\xf9\x6a\x91\x56\xc9\x6f\x49\x35\xe5\x93\x23\x29\xd2\xe8\x60\x4f\x11\x55\xcf\x9c\x4a\x5d\xbd\x18\x28\x6f\xc1\x51\x33\xfd\xeb\xc1\x6a\xda\xb7\x30\x1a\x76\x03\x2f\x1c\x35\xc8\x56\xeb\x09\x5a\x4e\x34\x1d\x8b\x81\xab\x3e\x8b\xdd\x24\x2f\x5e\x44\xa3\x69\xc7\xe6\x5e\x89\x41\x6d\x6c\xab\x08\x4e\x9f\x9e\xba\xe3\xae\x51\x8a\x63\x06\xfa\xb3\xee\xda\x69\x3b\xe6\x20\xe4\xf2\xc2\x74\xa9\x16\x35\xa3\x6c\x9a\x8e\x05\x8c\x3d\x5f\xd0\x05\xb7\x53\x12\x5d\xf0\xe0\x4c\x1c\x6e\xc3\x5c\xa0\xeb\x3b\x84\x8a\x4b\xa5\x64\x40\xb6\x10\xec\x25\xa1\x69\x49\xed\x21\x0e\x06\x24\xce\xb3\x76\x45\xa2\x38\x26\xa2\x5c\x95\x9b\x95\xf6\x49\x52\xb5\x4b\x12\xa5\x05\x8d\xe2\x0b\x32\xca\x17\x59\x45\xe3\x10\xaa\xbe\xd4\x58\x2f\xf1\xe2\x1c\x0c\xc8\xfb\x83\xe7\x07\x43\x32\x4e\x26\x8b\x82\x12\xa6\x20\x66\xb4\x64\x2a\x27\xd3\x0a\x2f\x4a\x87\x97\x7d\x1d\x8a\xf9\x96\x26\xdc\x9c\x16\x6a\xa2\x52\x61\x27\xcc\x01\x14\x8e\x0b\x3a\x8e\xc0\x3a\x74\x36\xcd\x53\xca\x7b\x9a\x64\x93\xb5\x65\x4c\xa2\x86\x3f\xd8\x7b\x84\x18\x7d\x8f\xe4\x2e\x57\x30\xd7\xbf\x9c\x9f\xa5\xfa\x84\x6f\x4b\xec\x78\x6c\x76\x88\xa4\x78\xe3\xe4\x2c\xd2\xc4\x5e\xd2\xca\x9d\x61\x4e\x69\xaf\xa3\x19\xb5\x77\x2d\xfd\xc5\x90\x5d\xdd\xc2\x9e\xad\xaa\x7e\xfb\xd3\x35\xfb\x2a\x55\x9c\x53\x20\x12\x8b\xca\xf2\xaf\x6e\xf0\xb2\x9e\x79\x41\x4f\x93\x7c\x51\xaa\x4e\x6d\x3d\x61\x88\x49\x32\x92\x64\x95\x5b\x64\xd9\x44\xa0\x4e\x7b\x9b\x64\x7f\xe3\xbc\x20\x70\x25\x3e\x21\x3b\x64\xf3\x09\x49\xc8\x8f\x72\x14\xf2\x76\x3c\x49\xd6\xd7\x83\xe5\xd9\x9f\xd5\xed\xf5\x1d\xb2\xde\x91\x98\x48\xc8\x03\xb2\x79\xcc\x94\x07\xf2\xf9\x33\xd9\x78\x12\xae\xa5\x86\xdd\x0b\xca\x58\x27\x09\xb9\x1f\x9a\xc1\x75\xbb\x1b\x4c\xa4\x08\x6e\x0d\xf2\xef\xd2\x7d\x6d\xbd\xba\xec\x76\xba\xce\x64\x0e\x06\x64\x9c\x14\x65\x45\x68\x4a\x67\x34\xab\x98\x16\xc7\xb1\xd5\x23\xe5\xc7\x64\x4e\x92\x6a\xb5\xd9\x37\xa6\x61\xc3\x37\x0d\x0c\x8f\xf5\x53\x01\x21\x23\xe2\x38\x61\xcd\x44\xa9\x5a\xfa\x02\xaf\x2e\x77\x72\x11\xef\xe7\x9b\x9a\x8c\x02\x7c\xe3\x28\x21\xeb\x64\xf3\x58\xb2\x0f\xb2\x4e\x9c\x7e\xf8\xf0\xdf\x04\xd1\x36\x6f\xf4\x02\x8b\xbd\xd5\xb3\x1c\x38\x95\x5c\x83\x2d\x7d\xe3\xfc\x06\x24\x35\x1b\x67\xd7\x65\x0b\xcb\x68\x95\x84\xb8\xd5\x46\x2d\xb7\x22\x8d\xc8\x7c\x39\xb7\x19\x0c\xc8\x28\x4a\x47\x8b\x34\xaa\xa8\x94\x99\x98\x3a\x29\x7a\x43\x92\x8a\xce\xae\xc3\xab\x18\x9f\x3a\xfa\xf7\xe2\x58\x5d\x07\xfa\x72\xd5\xed\xe7\xba\x33\xf3\x27\x32\x1f\xcc\x78\xbe\x12\xdf\x21\x1e\x83\x95\xe8\x4f\x03\x23\x8c\xb0\x94\x8a\xa3\xd7\xbc\xd6\x68\xc5\x61\x57\x30\x5a\xc9\x0f\xfa\xe0\x56\x59\x62\x02\xf6\xac\x1a\xf3\x0b\x6a\xdd\x23\x44\x42\x13\x5e\x33\x15\x2a\xa7\xcd\x54\x1c\x9c\xcb\x46\x0d\x51\xb4\xc4\x4e\x15\x42\x4e\xd0\x4c\x55\x83\x1c\x51\x06\xf4\x17\x68\x52\x23\x69\x99\x91\x0a\x8f\xd6\xa7\x8b\x9b\x78\xba\x82\x8d\x4a\x16\xe3\x64\x8e\x0b\x70\x2a\x2f\xbd\x5a\xbf\x63\x63\xb8\x69\xab\x16\x1f\x77\x07\x86\x27\xd7\xa0\xb6\xc9\x18\x46\x19\x59\x25\xb6\x72\xd5\x5b\x3a\xf4\xe0\x96\x9a\x37\x0c\xd4\x72\x66\xc5\x0a\xdd\xf8\x78\x1b\x19\xc5\x90\xd2\xeb\x93\xad\x45\xf7\xc2\x3c\x75\x30\x20\xe5\x62\xc6\xcf\x1e\x3d\xbb\x9b\x10\x38\x75\x01\x51\xe1\x51\x72\xcc\x98\xa8\x7a\x82\xad\x2c\xc0\xa9\x64\x1f\x4c\x8c\x48\xf9\xd5\xc5\xc5\x60\x40\x0a\x3a\xcb\x4f\xe1\xa4\x96\x8c\x16\x45\xc1\x44\x5e\x25\xef\xe6\xf0\x5a\xf4\x35\x29\xa1\xfb\x9e\x2e\x97\x2b\x59\x20\x25\x5a\x9b\x5b\x22\x8d\xc1\x91\x07\x4e\x03\x2b\x91\xde\x3b\x6b\x81\x86\xce\xa7\xfc\x1a\xb2\x64\x85\x1e\xba\xab\xec\xc3\x12\x49\x68\x6c\xf7\xc3\x87\x3c\xd6\xe9\x8b\xea\x34\x6b\x71\x24\x4e\xcd\xb0\xbb\x09\x0c\xa2\x23\x9c\x83\x6d\x3f\x14\x71\xf2\xdb\xe9\xf6\xfc\xdf\x9f\xe5\x79\x1a\xfc\xc8\xe4\x99\xd0\xb7\xc3\xba\x8f\xf8\xfc\x36\xdc\x74\xed\x57\xce\xb0\x83\x9f\xdf\xd2\x28\xdc\xef\x43\xfe\xf5\xee\x9d\xe3\xae\xdf\x91\x05\xd0\x88\x9c\x57\xa4\xab\xf2\xf0\x61\xaf\xc5\x8f\xba\x5b\xc3\xef\xe0\x27\xeb\x63\x6b\xf8\x88\xfd\xc6\x47\xcf\xad\xe1\xe3\x9e\xcf\xe9\x25\xc9\xaa\xd6\x70\x73\x83\xfd\x2c\x68\x94\xb6\x86\x9b\x5b\xec\x37\x3f\x80\x6e\x0d\x37\xb7\xd9\xd3\x82\x43\x41\x03\x0b\x01\xf6\xe8\xf2\xb8\xf7\xf8\x6b\xfb\x8f\x2d\x39\x76\xbf\xa2\xa3\x15\xae\x65\x25\x7f\x2b\xab\xa0\xeb\x76\x85\x01\x56\xf5\xbe\xf2\x97\xad\x71\xc2\xb2\x7a\xd3\xa8\xb6\xeb\xb8\x64\x85\xfd\xb0\x1a\x35\x8c\xfc\x00\xfc\x53\x27\x59\x53\xb1\xa0\xcd\x3c\xbc\x1c\x04\x2c\x77\xf4\xfa\xe1\xd6\xd1\xeb\xd6\xd1\xeb\xaf\xeb\xe8\xa5\x97\xc6\x8d\x7a\x7b\x3d\x4b\x26\xaf\x17\xb3\x13\xe0\x98\x8a\x91\x9f\x24\x93\x0c\x5e\xf6\x7f\xd7\x5c\x7f\x51\x25\xa9\xe9\x75\xd4\x1f\xc0\x3b\xfe\x7f\x05\x37\xf2\xc2\x8c\xf2\x6c\x9c\xb8\x6e\x52\x52\x09\x44\x7b\x08\x28\x47\x62\x13\xd1\x48\xe0\x9c\xbd\x24\xb0\x3d\x10\xb8\x4d\xc3\x34\x3a\xc6\xde\xb4\xf3\x31\x2c\x11\x36\x57\xdc\x54\x74\x9f\xe1\x9c\x83\x26\x25\xc9\xe8\x24\xaa\x92\x53\xda\x93\xdc\x0a\x0e\xc0\xaa\xb3\xbc\x5d\x92\x51\x3e\x9b\x2b\x11\x18\x8a\xb1\xd9\x56\x45\xc7\x69\x1e\x55\x49\x36\x21\xf3\x3c\xc9\xaa\x1e\x3f\xe9\x65\xab\x21\xce\xcf\x32\x47\x7f\x34\x8d\x36\x1e\x4d\xf1\x33\xc7\xf8\x67\x85\xfb\x4b\x39\x20\xb6\xc8\x32\x4a\x63\x50\xe0\x4f\xf4\xa4\xc7\x01\xdf\x20\x40\xdf\x25\xf2\x80\x32\xdb\x36\x98\x35\x34\xa1\x38\xb6\x6a\xbb\xcf\x67\xa6\x33\xea\xbf\x78\xff\xf2\xc3\xb3\xfd\x5f\x5e\x1f\xbe\x7a\xf6\xe2\xed\x87\xb7\x07\x87\xaf\x9f\xef\xbf\xfe\xe5\xc3\xab\x83\xe7\x2f\xb0\xba\xa8\xcc\x84\x30\xb1\xfd\x79\x14\xff\x4a\xc7\x55\x87\x3f\x55\xf9\xfb\xb3\xbc\xdc\x53\xe8\x14\xad\xf6\xab\x5c\xc8\x5c\x9b\x8f\xba\x3d\xf2\xe8\xa1\x75\x4a\x85\xf7\x58\x18\x53\x87\xb7\xe2\x3a\x9f\x98\x74\xa0\x34\xee\xd0\x04\x3c\xd3\x2a\xb9\xa9\xac\x5f\x01\xa1\xae\xe8\x62\xa2\xd4\x83\x9c\x2a\x7f\x49\xcf\x25\x0e\xca\xc5\x49\x59\x15\x9d\x2d\x8c\xcc\xd4\x72\x67\xe0\xe5\xa5\x71\x7e\x9d\x3c\xda\xee\x92\x81\x81\x2f\x1b\xf9\x6f\x93\xc9\xb4\x12\xe5\x7a\x24\x25\xf7\xbf\x0e\x76\xc5\x06\x7e\xe3\x48\x0e\x8a\x89\x37\x80\x6b\xa9\x11\x9a\x48\xd6\x56\xc4\x3f\x71\x42\x2c\x43\x2f\x6f\xae\xdb\xe7\x6c\x61\x9d\x34\x9b\xaf\x65\x5c\x91\x6b\x0a\x75\xcb\xe5\x9d\x82\xb8\x81\xa9\x54\xde\xb2\x2b\x4c\xe2\xb8\xc8\x67\x87\xd5\xf8\xf1\xed\x3c\xd6\xcc\xa3\xbc\x13\x16\x64\x7a\xf2\xce\x98\x9c\x43\xf6\x82\x46\xd9\x95\x98\x9e\x7d\x3b\xac\x66\x0a\xdb\x1b\xd7\xfb\x6b\x93\x75\x51\x3f\x79\x4a\x48\x7b\xb3\x4d\x86\xa4\xbd\xd1\xbe\x21\x6e\xb6\x0c\xab\x4c\x59\x86\x62\x7f\x67\x80\x25\x61\x82\xf7\x6c\x91\x56\x09\x17\x58\x4f\x2e\xc8\xd6\xff\xcd\x98\x02\xa0\x7c\x0e\x23\x56\x75\x45\x27\xb4\xa8\xdd\x83\xde\xca\x8a\x97\x49\x01\x57\x98\x1e\xe1\x36\x1e\x9a\x1e\x81\x32\x8b\x2a\x19\x06\x55\xab\x6a\x87\x4e\x66\xb4\xb4\x3e\x6d\x75\xfb\xf3\xfc\xac\xb3\xb9\xf5\xb8\xdb\x75\xd1\xbb\x37\xa5\xa3\x8f\x24\x19\x1b\xf8\x45\x82\x96\x83\x93\x32\x99\x64\x34\xde\x2f\x5f\x23\x00\xc7\x88\xae\xaa\x99\xd2\x73\xd1\x71\x0b\x2f\x92\x9a\x41\xdd\x84\xf6\x2b\x53\xbe\xcb\x99\x86\x74\x96\x30\x79\x3f\x4a\x4b\xec\x20\x6e\xf7\x60\x39\xea\x7c\xc8\x92\x5c\x69\xa3\x47\x36\xbb\x3d\xb2\xf9\x08\xc9\x37\x5b\x5d\xe3\x6b\x97\xec\xec\xec\x30\x52\x0e\x12\x67\xc1\xd8\xcc\x83\x28\x85\x9e\x11\x6e\xc6\xd0\x87\x38\x42\x90\xf5\x90\x16\x37\x6b\x38\x02\xa6\x41\x33\xae\x77\x31\x43\x9f\x96\x3a\x6b\xda\x56\x92\x27\xac\x98\x64\x42\xb8\x42\xe0\x50\xa1\xea\x86\x81\x4a\xd3\xd5\x98\x41\xf3\x69\xdd\xe1\x3d\x42\xe6\xd7\x4e\x97\x7c\xfe\x4c\x5a\x1b\x2d\x65\xdf\x1e\x0c\xc8\x48\x51\x16\x13\xd1\xe5\xc4\xea\x2e\x70\xa8\xa4\xe2\x33\xaf\x04\x7a\x8f\x2c\x2f\x0f\xae\xad\x79\x17\x73\xed\x33\x99\x7a\xe6\x9b\x4f\xf1\x2c\xc9\x16\xf6\x02\x69\x8f\xaf\xf9\xd7\x86\xba\x65\xe5\x9b\xe8\x14\xb0\x41\x97\xae\x48\x53\x8b\x65\x44\x75\x58\x4f\x55\x5e\x7a\xa2\x2b\x11\x94\xec\x82\x87\x94\x0e\x6f\x86\x96\xbe\x1c\xfa\xe4\x3e\x11\x44\x9f\xcb\xef\x97\xa3\x0f\xb0\x87\xa4\x6e\x13\x5d\xb2\x49\x0f\xba\x9c\x0d\xc0\xeb\xe5\x6f\xad\x55\x01\xd4\x8f\x93\xd3\x24\xa6\xf1\xb3\x8b\x1a\xbe\x7f\x55\x22\x5b\x8a\xa6\xc3\x9b\xc7\xd3\xa2\x06\x51\x87\xab\x63\xea\xf0\xba\xa8\x72\x4f\xa0\x79\xf5\x0a\x5b\x61\x41\x4e\x5f\x96\x5f\x01\x45\x72\x63\x34\xa7\x26\x88\x2e\xd9\xbc\x07\x5b\x8e\xd8\xe7\x45\x96\x67\x01\xc2\x76\x77\x4d\x39\x70\xb3\x4d\x9e\xf2\xcd\x5d\x04\x54\x59\x1d\xb1\x35\x9a\x2b\xba\x7f\x5d\xb7\x75\xa6\x74\xac\x51\xc8\x64\x91\x3a\x7d\xca\x91\x62\xb2\x68\x46\xf9\x4d\x2c\xf6\xcb\x16\xec\x04\x10\xab\x55\xd7\xe1\x9b\x05\x47\x0b\x86\x66\x7a\xc4\x30\xfc\xb3\x52\xe2\x76\x3d\xd9\x21\xa1\x0b\xd9\xf7\xbb\x03\xac\x44\x95\xc9\x1f\x82\x85\x96\x70\x14\x27\x2a\x38\xda\x3c\xb6\xc4\xed\xf6\xc6\x39\x93\xcb\xdd\xa9\xee\x97\x69\x32\xa2\x4c\xcc\xd9\x22\xf7\xa1\xbe\x2b\x2c\x80\xa5\xf3\x84\xed\x01\x37\x38\x5d\xab\xcf\x45\xd0\x30\xe1\xee\x4f\x4a\x41\xb5\x78\x05\xc7\xa1\x38\xea\xb3\x91\xf8\xe8\x61\x57\xc8\x02\x55\x2e\xe0\xbb\xe4\xbe\xd2\x69\x7d\xb3\x61\xd5\xc4\xc5\xce\x47\x0f\x7b\xa2\x03\xab\x4f\x47\xad\x81\x80\xa3\xc1\x67\x21\xb8\xd9\x99\x88\xca\x51\x92\xd4\xcf\x85\xc7\xb2\xf0\x55\x67\x41\x1a\x9c\xc0\x52\xd1\x6c\x2e\x56\x9f\x0c\x14\xee\x28\x38\x1b\xbb\x28\x24\x52\x60\x3a\x82\x7b\x41\x08\xfd\xba\x4a\x0f\xe6\x7d\xf1\x90\x56\x11\xd0\x4c\x3c\xb6\x36\xce\x5b\x64\x9d\x08\xa5\x0a\xe6\x80\xff\x56\xee\x16\x0f\x37\x7a\x04\xbf\xaa\x09\x20\xf1\x49\xb9\xc7\x20\x5d\x77\x68\x3d\xf7\x1c\x20\x58\xd0\x43\xe7\x8d\x0b\x88\x19\xc0\x30\xf4\xc1\x2d\xc6\xf1\x3a\x74\x5f\x79\xba\x92\xe7\xe9\xd0\x7e\xe1\x82\x31\x41\x66\x68\xbf\x30\xc0\x94\xa0\x37\xb4\x5f\x78\xc0\x0e\x1d\xb8\x43\x3f\x20\x6e\x57\xbf\xf1\xd5\xe8\x42\x1e\x06\x40\xf1\x90\xf5\x1b\x1f\x20\x46\x3b\x7a\xe5\x01\xf5\x4d\x94\xfb\xc5\x53\xd0\x9c\x2a\xfc\xce\x03\x2c\x56\xc2\xd0\xbf\x1e\x2f\xf5\xa1\xb6\x79\x02\xd6\x1a\x6e\x3e\xee\xb5\xcc\xa3\xb3\xd6\x70\x0b\xbc\x3a\x60\xb9\xb4\x86\x9b\x9b\xbd\x16\x3e\x81\x6b\x0d\xcd\xc7\xcb\xe3\xde\xe6\xc6\xb7\x10\x0e\x68\x9f\x5f\x51\xa8\x89\x6d\x95\x64\x55\x38\xb4\x95\x3c\xa4\x4b\xb2\x4a\x84\xf5\x61\xbf\x1e\xea\x9f\xc7\xe8\xf5\x36\x7e\xb0\x03\xff\x24\x59\x25\xc2\xfe\x24\x59\xf5\xe8\xa1\x86\x7c\x8c\xaa\xdb\xfa\xee\x51\xb0\x46\x56\x66\x69\xa0\x2c\x5b\x31\xfd\xa2\x71\xe0\x38\xbc\xeb\xa3\xb1\x9f\x55\xab\x7a\xa7\x18\x45\x6a\x9c\x52\x78\x93\x75\x65\xaf\xe6\x82\x92\x64\x95\x14\x41\x9f\x5e\x35\x22\x90\xec\xdb\x72\x37\x91\xcd\x66\xe9\x35\x6f\xfd\x44\x6e\xfd\x44\xfe\x73\xfc\x44\x08\x72\x14\xe1\x42\xd7\x4d\xfa\x88\x34\xf1\xfc\x70\x77\x08\xee\xda\x91\xc3\xed\x00\x1d\xe9\xa5\xef\x93\x7d\xcf\xa6\x34\x53\x57\x50\x7b\xdc\x01\x9f\x09\xf8\x2a\xba\x87\x12\x58\x07\x7e\xf7\x11\xcb\x88\xef\x5c\x39\x05\x9e\x2b\xa5\x52\xfe\xef\xe7\xcf\xa4\xdd\xc6\x2c\x39\x97\xb7\x4b\xf8\x8f\x27\xe8\xf2\x68\x92\xc9\x1e\xac\x12\x23\x66\x42\x2b\xec\x6b\x0d\x8e\xfc\xed\x52\x5e\xf5\x05\x66\x03\xb5\x18\xd2\x3d\xd2\x23\xb8\x83\xb1\x25\xa6\x4b\x1b\x98\xae\x18\xd7\x47\x3a\xb2\xab\xdd\xbb\xe6\xed\x02\xc0\x14\xbe\x5d\x60\xb7\x53\xef\xd8\x07\xd7\x2f\x0c\x15\xc7\x38\x75\x5d\x05\x2d\xa3\x82\x32\x2a\x93\xcb\xc5\x8c\xec\xc3\x17\x43\x9c\x8c\xc7\x14\xdc\xc1\xf9\x04\x38\x3a\xd0\x99\xba\xca\x63\xa8\x3e\x12\x39\x62\xda\xa4\xf3\x78\xe6\x57\x78\x4c\x3d\x89\x6d\xa4\xbe\xbe\x44\x73\xce\x88\x74\x4f\x6a\xb0\x7a\xe6\xbf\x1d\x6d\x51\x63\xf0\x20\x53\x93\xa9\xa2\xe0\x55\x91\x9b\xcf\x4e\x92\xcc\x8d\x97\x54\xe5\x13\xca\xf6\x03\xa8\x82\x4e\xfa\x7c\xc9\x45\xf3\x39\xcd\x60\xa5\x45\x19\xbf\xa3\xe2\x60\x5a\x54\xb8\xf4\x90\x49\x70\xb1\x69\x32\x62\xbc\x4c\xf6\xac\x41\x69\x71\x7a\x9c\x8f\x05\x30\x6c\x5f\x4b\xd0\x2c\x47\xb9\xd4\x40\x59\x87\x62\x65\x46\xe1\x67\x41\x4f\x48\x33\x4c\x8f\xa2\x34\x15\xb8\x96\xa7\x54\x7c\x60\xd3\x48\xaf\xed\x32\xf9\x43\x46\xbe\x84\xe3\xc9\x69\x54\xf6\xd8\xbf\x92\xf8\x20\xda\xb5\xef\x9c\xd2\xc0\xbd\x72\xbc\x0d\xd8\x79\x97\x60\xc9\x1f\x03\xcc\xbb\xb4\xc5\x82\x59\xdb\xd9\x01\x19\x65\x9c\x64\x9e\x2b\x67\xcb\xf0\xa1\x63\x62\x89\xea\xc4\x59\xbb\x6b\xc2\xe0\xdf\x77\xcb\x67\x35\x76\x08\x6e\xaf\x76\x6d\x47\x8d\xd6\xa1\xd1\x40\xed\xf0\xd7\x60\xfc\x3a\x30\x44\x97\x3c\x25\xed\x36\x19\x36\xf3\x6e\x43\xc8\xf3\xfb\xb8\xad\x86\x41\xb6\x63\x70\x6b\x89\x12\x45\xfd\xf7\xf7\xb4\x49\x25\x80\x3d\xb9\x71\xc9\xc3\xf1\x08\x6f\x13\xd1\x0c\xd3\x1e\x90\xff\x12\x7c\xea\xf6\xfc\xc8\x84\xc8\x5d\x36\x26\xbd\x51\xc0\xd4\xf2\x63\xeb\x0d\x8e\x3a\x49\x88\x1c\xc5\xf4\x75\xae\x86\x47\x63\x5b\x0c\x22\x12\xed\x69\x01\x4c\xca\x17\x91\xf4\x4c\x68\x80\x52\x3a\x9b\x57\x17\xa6\x09\xb3\xc1\x3e\xbc\x7c\x99\x9a\x64\x8a\x58\xd9\x90\xcb\x32\xab\x61\x49\x06\x37\xab\x09\x6b\xe6\xc7\xc9\x92\x21\x89\x7a\x97\x8e\xc6\x38\x37\x5a\xf7\xc8\x18\x57\x1d\x91\xbe\x6d\x59\x17\x88\xec\xd7\xa4\x34\xa5\x07\xb8\xab\x79\x64\x8c\xea\xd8\x17\x7c\x6c\x09\x22\x74\xed\xee\xfe\xa4\xaf\x78\x29\x2f\x86\xc5\x3c\xe6\xbe\xc5\xe2\xa6\xa3\xb6\xa2\x56\x79\x85\xee\x3c\xf3\xf2\x52\xec\x12\x91\xad\x88\x71\x85\x53\xdd\x15\x15\xb0\xe6\x1d\x31\x73\x83\x54\xab\x96\xef\x81\xa1\x65\x6b\x1f\xf6\xb9\x01\x67\xcc\x2e\x90\x1d\xdc\x6d\x04\x8d\x07\xb3\xbe\xe3\x1e\x60\x88\x6b\x78\x9e\xab\x77\x1c\x54\x4b\x56\x9d\xdc\xb8\x83\x8d\x6e\x46\x0e\x06\x92\x02\xe8\x29\x2d\x2e\xaa\x29\x0f\x68\x83\xea\xc2\x78\x72\xe3\x9c\x49\x5f\x3f\x17\x53\xc6\xc5\x6d\xff\xf9\x8b\x8e\xf2\x75\xb3\x8d\x78\xac\xe7\x97\x3d\xd2\x6e\xa3\x13\x85\x5a\xeb\xc9\x1b\x31\x6d\x8e\x3d\x52\x99\x1e\x2f\x8f\x7b\x9b\xcd\xd2\x73\x7e\x61\x7b\x22\x9c\xd0\xd7\x1b\x14\x0b\x06\x12\xb4\x28\x2a\x17\x3e\xf6\x43\x58\xf7\xe0\xe7\x43\xf4\xfb\x18\x7f\xd8\x36\x9e\x6c\xbb\x22\x7b\x29\x0c\x8b\xec\xa7\xb2\x2c\xb2\x87\xc7\xb8\x52\x6c\x5b\x74\xeb\x6d\x64\x5d\x74\xdc\x13\x56\x32\x2f\xb2\xd2\x2b\xd9\x17\x45\x01\xd7\xc0\xc8\x3e\xac\x6a\x61\x34\xcb\xd4\x98\x18\x45\xab\xb5\xa5\xaf\x64\x64\x64\x68\x0e\x18\x19\x1b\xa7\x97\x50\x9d\x6b\x60\x64\x6c\x96\xb4\xef\x0b\x5e\xa7\xf4\x1c\x81\xae\x44\x30\xbc\xfc\x4a\x24\xa3\x8a\xb8\x44\xc3\x3f\xad\x4a\x36\x76\xa9\x1a\xc2\x51\x6d\x2f\xa9\xe1\x6a\x16\x6a\x2e\xa9\x35\xbc\x25\xe9\x69\xf3\xe6\xef\x47\xa2\xf1\x36\xa0\xc6\x2f\x91\xe5\x67\xc9\xcd\x2c\x1f\xff\x46\xf1\x9c\x93\xb2\x79\x20\xe7\x11\x2d\xaa\x28\xc9\x42\xc1\x9c\x1d\xac\xf2\x83\xb4\x65\xd4\xce\xa1\xfa\xe6\xfb\x25\xf4\x2e\xca\x58\x1f\x1a\x05\x16\xa9\x68\x31\x4b\x32\x50\x0f\x58\xed\x66\xef\x63\x11\x9e\x99\x4c\x92\x53\x9a\x29\x97\x20\x4b\xd9\x0f\x06\x87\xb6\x5d\x88\xb8\x05\x40\xfb\x3f\x03\xc6\x79\x03\x4e\xdb\x21\x6f\x68\x0c\xb3\xc2\xfa\xe1\x41\x98\x5b\x95\x57\x10\xcf\x4f\x69\x51\x9c\x15\x49\x55\x51\x70\xa4\xe3\x1d\x6b\x91\x75\x18\xc1\x4a\x68\x3c\x83\x63\x84\x12\xc7\x80\x00\xbf\x11\xad\x1b\x27\x99\xc0\x66\xe5\x0b\xb8\x6d\x87\x69\x68\x88\x57\xd7\xba\x6a\x35\x89\x0d\xd1\x01\x14\x7a\x42\x50\x04\x90\x39\x18\x80\xb1\x3f\x9a\xb1\xf5\x02\xf1\x3a\x85\x15\x8e\x0d\x9b\x71\x0b\xca\xcf\x52\xd2\xe4\x23\x25\x11\x29\x93\x6c\x92\x52\x15\x1c\x0e\x20\xfb\xa6\xb3\x3a\x10\x36\x0f\x6e\xc4\x83\xbd\xf0\xf6\x3e\x7f\x26\x47\xed\xa3\xcd\xe3\xf6\x71\x57\x8b\x9b\xcb\x42\x48\x88\x1e\x9a\x33\xc0\x9e\x70\x4c\xce\x90\xa6\xc0\x9d\xca\x38\x3e\xc0\xaf\x63\xb3\x47\x1e\x80\xb3\xfc\x06\x74\x67\xd3\x88\x7e\x84\x3a\xe5\xc8\xcb\x32\xe0\x47\x4f\x86\x08\x09\xea\x27\x32\x32\xc8\x7d\x09\x89\xda\x18\x0c\x48\x94\xa6\xe4\x24\x2a\x93\x11\x8f\xa0\x01\xf7\x3b\xb6\xb7\x84\x9d\x29\xcd\x41\x53\x97\x3d\xea\x91\xed\xad\x26\x1e\x3b\xe6\xba\x17\x8c\x4f\x9a\x05\x94\x41\x95\xd0\x09\x97\x4f\x21\x5d\xdb\xd1\x71\x8b\xec\xfc\x04\x8b\x17\xbd\x7c\xc8\xdf\x2e\x31\x04\xee\xaa\x2a\x57\xe6\x11\x53\x1a\xee\x60\x1d\x3f\xc0\x2d\x87\x49\x59\x07\xa5\x33\x82\x0f\x39\xa4\xf8\xc4\xde\x86\x51\x99\x7b\xf7\x08\x7e\x3e\x42\xbf\x51\xb4\xc2\x63\xb9\x6b\xab\x34\x33\x83\xc9\x95\xa7\x4a\xac\xee\xfa\x99\x52\x73\x62\x4e\x95\x9c\x40\x6b\xa6\x50\x70\xc0\x6b\x4f\x94\xdd\xbd\xba\x79\x42\xed\x7e\xf9\x69\xba\xe9\x79\x32\xa3\xec\x68\xb6\x8b\x27\x86\xab\x64\x2d\x70\xdd\xd8\xe2\x53\x20\x74\xb3\x96\xf0\xee\xd8\x14\x33\xb3\xf9\x50\x83\x6e\x1d\x1f\x6d\x0b\x60\xf5\x92\x03\x69\x98\xcd\x63\xfb\x0d\x7a\xe1\xd9\x56\x00\xc9\x57\xda\x57\xf0\xb0\xc4\x68\x9b\x6c\x26\xa8\xc1\x1b\x9b\xdb\x64\x4c\x3a\xe8\x1b\xe6\xaa\x36\x1b\xbf\xe2\x64\x03\x9f\xf7\xdf\x68\xd9\x5c\x42\x08\x62\x8b\x51\x8a\xbe\x77\xf6\x61\x2a\xbd\x04\xd0\xd2\x29\x35\x1d\x32\x10\x8f\x2d\x93\x1a\xcc\xba\x8e\xac\x06\x0c\x1a\xd0\xb1\x03\x1b\x4e\xbe\xfa\xc2\x07\x25\x01\xc2\x93\x6e\x84\x06\x0d\xcb\x0e\x22\x7a\x56\x1a\x95\x15\x39\x3a\x66\xd2\x89\xa8\xfa\x6a\xc4\xb0\x16\xa0\x06\x35\x27\x5c\x86\x23\x9e\xd0\x5f\xa0\x4c\xe9\x6b\x6f\xf0\xa8\x88\xa3\x09\xf5\x2c\x71\x58\x46\xea\x93\xe2\xde\xf6\x71\x1b\x39\xb9\x20\x31\x1d\x47\x8b\x94\x5b\x75\xcb\x05\x13\x87\xd5\x4e\xdf\x12\x61\x92\x7a\x22\xa7\xab\x3b\xaf\x86\x1a\x77\x25\xd6\xad\xb7\xd6\x95\xa5\xee\xa6\x1a\x64\xed\x75\x08\x99\xdd\x40\x9a\xbf\xd1\x2a\x2a\xdd\x65\x04\x4b\x42\x50\xfa\x51\x8b\x2d\x89\x1e\x69\xb1\x55\xc2\xfe\x39\x6e\x1d\xa3\xd5\x20\x40\xf0\x4b\x28\x96\x2d\x52\xf7\xfe\x0a\x9a\xe3\x86\x58\xb4\x83\x24\xda\xfd\x5e\xb6\x52\xdc\x70\x6a\xee\x52\xe1\xfb\x8b\x08\xfc\xc8\x69\xa1\x84\x83\x70\x36\x2c\x63\xe0\xec\xff\x9c\x3f\x58\x04\x2e\x58\x5c\xe7\x5f\x47\xdc\x4a\xf0\xaf\xe3\x6e\x33\xd1\x43\x18\xa5\x55\x48\x91\xda\xc3\x16\x2b\x4b\x8c\x2a\xb0\x02\xa3\x91\xf7\x93\x7d\x27\x7b\x16\x02\x3d\x67\x35\xc2\xff\xc0\xd9\x5b\xfc\x21\xdb\xcd\x73\x29\x11\x0a\x58\x05\x01\x76\x98\xc8\xb2\xa8\xc8\xca\x69\x1f\x3b\x7d\x3f\x21\xc1\xbf\x40\x64\x60\x37\xc0\x32\x4d\xc7\x38\xb0\xb2\x64\x7e\x6e\x31\x75\x9b\xfd\xe8\xd8\x1b\x77\xbf\x3f\x5f\x94\xd3\x8e\x13\x9a\x57\xde\xf4\x97\x71\x76\x7d\x95\xb3\x11\xb9\xc9\x0a\x4e\xbd\xd1\x6f\x71\x63\x28\x86\x6d\xe7\xb4\x47\x70\xa4\x65\x3b\x40\xef\xf5\x63\x5d\x8b\x09\xc5\x31\xae\x6f\x62\x3e\x61\x0c\x8e\x34\x23\xe6\xe1\xcf\x99\x4f\x5f\x70\xe2\x65\x41\x89\x83\xd3\xc2\x26\x17\x82\x06\xd7\xcd\xce\xd5\xe6\xc6\xda\x6c\x7d\xf6\x2e\x63\xd1\xe2\x58\xcf\x0d\x23\xe2\xf2\x53\xe4\x71\x91\xcf\x02\x1e\x1b\x1c\xce\xcb\x87\x4e\x9c\xab\x59\x96\x1b\x96\xe9\x7f\xb5\xca\x45\x39\xc9\x04\x79\xeb\x8d\x18\x9a\x18\x10\x66\x68\x46\x24\xd9\xa5\x8c\xed\x8b\xb1\x36\xd8\xde\xf0\x71\x2e\x17\xae\xc5\x8d\x2e\xe8\xa4\x94\xa1\x04\xe2\xee\x93\x2d\xf0\x23\xe9\xca\x08\xe8\x12\x8d\xa1\x45\x56\x5b\x29\x6e\xdf\xa9\xd9\xbb\xe2\xa0\xc4\xbb\x8a\xbb\x26\xe0\xe2\xeb\x64\x9b\xe7\x90\xe0\x5b\x76\xc9\x40\x4a\x12\x8d\x2b\x5a\xa8\x15\x64\xf4\xf8\x8a\xab\xd9\x5f\xc8\x17\xf6\x5e\x73\x97\x40\xb8\x7b\x52\x8f\x42\x91\xbb\xe9\x75\xa8\x01\x1c\x4a\x26\x18\x78\xdd\x49\x3c\x55\xcf\x8b\x9a\x72\x23\x72\xbf\xbe\x7b\x0c\x76\x7d\xa7\x1e\xa6\x19\x33\x33\x43\x2f\xa3\xe9\x5f\x27\xc9\x97\xe0\x6c\xdf\xca\xae\x83\xff\x9a\xae\x07\xe9\x25\xdc\xf0\xef\x5b\x5b\x0e\xb7\xab\xc1\x9e\xa1\x3f\x6f\x35\x10\xef\x5a\xc0\xc9\x57\xaf\xb1\x16\xec\x5c\x7f\x2b\x6e\x3c\x2e\xf1\xda\x0d\x34\xdb\x7d\xcc\x6e\xac\xd4\x80\x98\x4a\x2f\xf5\xa5\x0e\xb5\xf9\x57\x64\xcd\xaa\x9e\x8b\x83\x4e\xd7\x57\x78\xd9\x00\x3a\x64\x93\xac\x9b\xdd\xeb\xf2\x30\x61\x22\xd5\x9f\x87\x06\x78\x44\x6e\xeb\x84\xd1\xb8\xd6\xbf\x24\x2f\x84\x81\x72\xcb\x8f\xce\x60\x6f\x1a\xbc\xe1\x08\xf1\xe4\xab\xb5\xb6\xd5\xb5\x8c\xc1\xde\xb3\x53\x7b\x00\x0d\x4e\xb8\xeb\xce\xb6\xd5\x45\xc8\xcb\xe3\xde\xe6\x77\xdf\x82\x6b\xd2\xe1\xf2\xbb\x8e\x8b\xda\xcb\x8e\x32\xe2\x0d\xfc\x10\xbe\x41\x0b\x74\xdf\x71\x81\x2f\x3c\x2e\x8c\xfb\x89\x0b\xdf\x95\xc7\x85\xbe\xf3\xb8\xc0\x97\x1e\x17\xf8\xd6\xe3\xc2\xba\xf6\xe8\xd6\xdb\xc8\x35\xc9\x09\xc9\xf3\x45\x6f\x3e\x1e\x86\xae\x3e\x1e\x5e\xe1\xee\xe3\x61\xd3\xcb\x8f\x87\xbe\xdb\x8f\x87\x37\x71\xfd\x71\x71\x13\xf7\x1f\x0f\x57\xb8\x00\xf9\xe8\x9b\x58\x30\x0d\x9c\xf9\x16\xf5\xde\x7c\x2a\x9a\x0f\xff\x25\xa9\x16\x3b\xf4\x2d\x0c\x8f\xbe\x85\xe9\x7a\xb7\xf0\xfa\xf4\x2d\x90\x53\xdf\xc2\xf0\xea\x5b\x18\x6e\x7d\x0b\xdb\xaf\xcf\x57\x7b\xb3\xe5\xf3\x95\x5d\xfb\x0e\x83\xbe\x7d\x87\x57\x71\xee\x3b\x6c\xec\xdd\x77\xe8\x75\xef\xb3\xcb\x5f\x71\x15\xd5\x78\xf8\xad\xb0\x8c\x56\xf1\xf1\xfb\xbe\xd1\x3a\x6a\x2f\x4a\x0a\x06\xe5\x51\xd5\x96\x29\x36\x27\x39\xa1\xd9\x29\x89\x73\x0a\x6e\x1d\x70\x53\x34\xca\x62\x08\xed\x4c\xfe\xf1\xea\xd7\x97\x55\x35\x7f\x4b\xff\xdf\x82\x96\xd5\xdd\x3b\x20\xf2\x5d\xcc\x69\x3e\xb6\x3e\xf1\x58\x4a\xea\x3e\x4e\x5b\x61\x48\xb4\xde\xb7\xc1\xc9\x27\x86\x02\x33\x27\x6c\x10\xd6\x7c\x01\x0a\xc1\xef\xe5\x94\xed\x61\xc9\x24\xcb\x0b\x3a\x4c\xe1\xe2\xd6\xa5\xf2\x1c\x66\x28\x69\x96\x45\xe2\xf6\x6e\xf5\xed\xdd\xea\xff\xa0\xbb\xd5\xfc\x5a\xb5\xf0\x0d\x34\xef\x55\x8b\x9d\x8a\x5c\xfd\x7e\xb5\xdc\x3b\x0f\xab\x24\xe5\x55\x0b\xbb\x2b\xac\x2a\x7e\x0b\xcd\x0b\x9c\x54\x17\x8a\x83\xe2\x82\xa3\x34\x2a\x4b\x72\x04\x05\x8f\x45\xaf\xc5\x17\xcd\xb8\x55\x8d\x8c\x5d\x0d\xe4\xb6\x2e\x2c\xc2\x8c\xdb\x90\x9a\x60\xf0\xab\x24\x0e\xe0\xb0\xac\xb2\xc3\xd7\xfb\xef\xdf\x31\x65\x9f\x4f\x4f\xfb\x8c\x26\x6d\x41\xba\xed\x8f\xf8\xe1\x15\x7e\xf8\x05\x3f\x94\x7f\x44\x27\xb9\x7a\x1a\x27\x59\x46\x2f\xf4\x23\x9d\x55\x39\xdc\x71\x55\xaf\xe6\xc9\xc8\x7a\x93\x45\x99\xf5\x66\x96\x8c\x0a\xe7\x55\x9a\x26\x6e\x39\xb3\x88\x09\xad\x9e\xcc\x62\x93\x22\xca\x62\x3d\x30\xf3\xe3\x2f\xe6\xe3\x7b\xf3\xf1\x8d\xf9\xf8\xc2\x7c\xfc\x5f\xf3\xf1\x9f\xe6\xe3\x6b\xf3\xf1\xb9\xf9\xf8\x77\xf3\xf1\x90\x3f\xde\xbd\x73\x5c\x1b\x56\x89\x4d\xe1\x9b\xdd\xe7\x8c\x08\x86\x64\x7b\xab\xa7\xdf\xbe\xdb\xff\xe5\xf5\xee\xfb\xc3\xb7\x2f\x3e\xfc\xfa\xe2\xf5\x2f\xef\x5f\x0e\xc9\x43\xf4\x15\xa6\x7d\xa8\x7f\xa2\x4f\x01\xf2\x1a\x92\x4f\xc4\x7a\xa1\x93\x15\xc0\x87\x0f\xcf\x0f\x7e\x7b\x4d\x2e\x51\x55\x6f\x0e\x7e\xfd\x95\x81\xbf\xdf\x7f\xf5\xe2\xe0\xf0\xfd\x90\x6c\x6e\x6c\x6c\x0c\x64\x2f\x85\x5b\xc0\xb3\x34\x1f\x7d\x1c\x92\x36\xe3\xbf\x65\xd5\x36\x3f\xee\x8e\x20\x05\xfa\x50\xdf\x7f\xd5\xb7\x6b\x98\xac\xb0\x2c\x20\xcf\x6d\x76\x9a\xdb\x9d\xf1\x2f\xb7\x33\xf2\x7d\x05\xe8\xb8\x9c\x46\xdb\x37\x1a\x74\x64\xaf\xb8\x98\x57\xf9\xdf\xde\xe1\xed\x65\x04\xef\x1e\xa0\xa4\x34\xac\x59\x2f\xc4\x80\x7d\x69\x07\x52\xb4\xb9\xe1\x42\x80\x08\x4b\xe3\x3e\xb3\x78\x47\xee\xdd\x93\x9f\xfb\x32\x44\x09\x97\xcc\xa7\xf4\xbc\xed\xdc\xa7\x34\xe2\xd7\xfd\x44\xb6\x58\x71\x3b\x68\xf8\x96\x0c\x93\x6a\x95\x27\xd2\x4b\x40\xf9\x3f\xd8\xe9\x0f\x88\x7d\xef\x92\x03\x4b\x5c\xb1\x0e\xf6\x5f\xd2\xf3\x3e\x98\x62\x45\x90\xeb\x80\xcf\x16\xc3\x8f\x1c\x3e\xea\x03\x57\x2e\xb9\x21\x71\x48\xb6\xbe\x7b\x24\x4a\xa3\xeb\xed\xf8\xe2\x21\x63\x8d\x0a\xe7\xad\xe1\x77\x3f\xf4\x5a\xe6\x14\xb4\x86\x8f\x37\x2e\x8f\x7b\x5b\xcd\x02\x96\xdd\xf2\xc7\x5b\xfe\xf8\x9f\xc3\x1f\x11\x7b\xe4\xf1\x23\x6e\x8a\x3f\x3a\x4a\xc3\x55\x75\x06\x9f\xca\xa0\x8a\x87\x34\x86\xd5\xd2\x86\xd9\x1c\xba\x3f\x10\x5b\x05\x4a\x2c\x36\x7e\x8c\x21\xd8\x33\x52\x1e\x16\x59\x52\xbd\x8a\xe6\x5a\x14\x6d\x4b\x19\x7e\xc8\x59\x56\x7b\x43\x09\xb3\x4c\x5b\x18\x6a\x66\xda\xde\x34\x55\x8c\x21\xfa\xb2\xb1\xa1\x8b\xfd\x4f\xdd\xc7\x93\xe8\xe4\x24\x9a\x50\xd5\x9a\xf1\x11\x69\x1d\x43\xe7\xe3\xcc\x53\x2d\xfe\xfe\x6a\xc9\xf7\x34\x3f\xa5\x69\x34\x92\x4d\x3b\xdf\xb5\x7e\x33\xf4\x7e\x9f\xf8\xeb\xc7\x20\xbf\x2c\x07\x29\xa7\x51\x96\xe5\x99\x31\x7e\x0b\x44\xab\x55\xc3\x3a\x90\x65\x0d\x81\x7a\x37\xf4\x80\x18\x48\xd5\x0a\xdb\x70\x09\xd4\xd2\xba\x84\x0a\x39\xf4\x42\x99\xd5\x29\x95\xd0\x1e\xa1\x0f\xd2\x3f\x50\x0b\xd2\xa0\x61\x0f\x20\x86\xfd\x68\x02\xfb\x60\x8d\x89\x07\xbd\xb3\xb6\x6a\xa3\xcf\x8d\x6a\x37\x1a\x68\x5a\x02\x17\xaa\x56\x28\xc4\xca\x85\xbd\xd7\x74\xc4\x8f\x79\x14\x0b\x6f\x5e\x70\xb4\x3d\x9f\xd3\x11\xdb\xfb\xf4\xd5\x0a\xc3\x8b\x4d\x44\xf3\xf1\x3a\xa2\xe9\x5a\x4e\x28\x03\x8c\x65\xd2\x3d\xcb\xa9\x6d\x34\x8d\x8a\x68\x54\xd1\xa2\x94\xe7\x19\xe0\xc5\x20\x8a\xa3\x5d\xc8\xdf\x4a\x32\xc9\x7a\xc8\x55\x9d\x6c\x58\x2e\x6f\x2a\xec\x4c\x32\x99\x56\x44\x86\x6d\x76\xa2\x61\x8b\x91\x18\xb2\x2c\x07\xea\x41\x0f\xcb\x1e\x34\xe5\x8b\x87\xc5\xbd\x6b\x00\x08\xf2\x59\xc3\x6d\x66\x75\x8e\xbe\xd9\xed\xff\x9e\x27\x19\x64\x4c\x21\x4f\xa1\x12\x32\x24\xad\x8d\x56\x97\xac\x0b\xe0\x1a\xb7\xc2\x6b\x4c\x0c\xa4\xdb\xfa\xcf\x98\x19\x18\xca\xaa\x53\x23\xba\xb9\xce\xc3\x95\x5f\x75\x92\xea\x7c\x3e\xcd\xf8\x48\xb0\xeb\x82\xc7\x27\x24\xd9\x71\x03\xb5\x3b\x93\xc4\xe3\x9d\xd7\x4d\x51\x92\xb1\x7a\x02\x78\xc3\x71\xdd\x3d\x71\xbd\x58\x07\xb0\x7f\x27\x8f\x80\x73\xc8\x65\x03\xa5\x3a\x4c\x45\x12\xf9\xc1\x80\xfc\x9c\x64\x31\xe1\x77\xfa\x64\x7f\x55\x12\x78\x26\x96\xb4\x5a\xc8\x05\x02\xdc\x88\x7a\x90\x15\x6e\x4a\xcf\xa5\x5f\xb9\x56\xf6\xd8\x4b\xae\x6c\x31\x0d\xa7\x46\x47\x63\x15\x6d\x99\x77\x9a\xc0\x57\x49\xb8\x28\x3d\x21\xc9\xfa\xce\x96\x51\x42\xa6\x56\xc7\x1e\x32\xba\xb9\x4e\xc2\xda\x92\xf9\x68\x54\x2b\x63\xd2\xe1\x65\x76\x76\xc8\x46\xd7\x54\x11\x4f\x0a\x1a\x7d\x44\xc0\x6c\xb8\xeb\x3b\x44\xc4\x25\x60\x53\xba\x37\x8d\x8a\xbd\x3c\xa6\x50\x47\x48\x01\x64\x04\x20\x7d\x9c\xca\xaa\x68\x4e\x39\x7c\x22\x57\x24\x9d\x5d\x56\xe8\xeb\xd2\x0e\x34\xf9\x17\x24\x9e\x2b\xd2\x43\x59\xd5\x45\x3a\x30\x49\xc0\x93\xd6\xa1\x33\x2f\xe8\x38\x39\xe7\x99\xf2\x36\xce\xbb\x6c\x5e\x80\xc7\x84\x92\x4a\x88\x4c\x8f\x35\x34\xe1\x77\x2a\x07\x7d\x38\x4a\x61\x27\xa8\xcf\xe7\xe1\xcb\x0b\x6c\xa6\xb9\x90\x19\x0e\x44\x5f\x30\xb1\xb0\x25\x21\x67\x82\xd3\x04\x2c\x18\xe1\x5b\x2f\x16\x8c\x9c\x22\xd6\x1a\x22\x9a\x71\x5e\xd8\xce\x8b\x65\x55\xf4\x43\x97\x0b\xd0\x24\x33\xb0\x91\x98\xad\xdd\xaa\x93\x5c\x99\x29\x80\x7f\x28\x84\xb4\x88\xa9\x11\x99\x10\xc1\xb0\x5e\xaf\xef\x90\x4c\x6e\x2c\x3f\x92\x2d\xf2\x94\xa9\x53\x64\x9d\xb0\x0d\x25\x0b\x50\x8a\x48\xdb\x30\xa5\xe7\x37\x4d\x30\x76\xee\x0f\x87\x62\x96\xb1\x91\xaf\x4a\x32\x0e\x83\xc1\x34\xf3\xd5\xc8\xe2\x4f\x9f\x69\x2b\xb0\xef\x78\x91\xa6\x0a\x25\x03\x7a\x4a\xb3\x8a\xdf\xf2\x80\x1d\xe3\xf7\x32\xcf\x48\x74\x92\xb8\x5b\x84\x8c\x1e\xfa\x3e\xff\x79\x91\xa6\xce\xfd\x5a\x79\x17\x84\x55\xf0\x40\x54\xe0\x5e\x7d\xe3\x8d\x3b\x6d\xe3\x7d\xc1\x6d\xc7\x10\xd5\x58\xfd\x86\x1d\x98\xbd\xe8\x83\x2f\x4a\x92\xc5\xf4\xfc\x60\xdc\x69\x77\xda\x5d\x88\x95\xfa\x60\xd3\x77\x51\x56\x15\xf0\xb9\x6e\x56\x17\x73\x2a\xda\x04\x38\x20\x2f\x33\x54\x5f\x27\xe9\x7e\x92\x29\xca\xfb\x0c\xfe\x09\xb9\x14\x02\x9f\xe5\x8b\xa9\x5a\x22\xeb\xa4\xdd\x61\x93\xa9\xaa\x5f\x27\xed\xae\x1b\x12\x32\xb4\x3c\xe3\xa4\x9c\xa7\xd1\x05\x9f\x27\x08\xc5\x9b\x55\x4c\x96\x56\x78\x71\xaf\x2c\x9e\x03\xc0\x73\x5e\xb0\xf6\x36\x34\xab\xd0\xa4\x87\xc0\x02\x34\x7a\xc1\x36\x46\x8b\x8a\xe8\xa4\x2f\x33\xb2\x5e\x74\x84\x6f\x63\x97\x3c\xf8\x49\xbd\x44\xd3\xec\xf6\xaf\xfe\xe6\xbc\x72\xa9\x75\x66\xda\x44\xb9\x80\xe3\xb3\x4f\x9e\xda\x57\x9f\xc5\x35\x40\xb6\xa4\x8c\x90\x37\x83\x81\x1e\x6f\x7e\x4a\x8b\x34\x8f\x62\x1a\x2b\xd3\xb6\x67\xb9\x18\xc3\x78\xaf\xa9\x26\x78\xc9\x75\x40\xde\x1f\x3c\x3f\x18\x92\x59\xf4\x11\x8c\xdd\x49\x76\xba\x48\x33\x5a\x44\x27\x29\xbd\xd9\x71\x6a\x3d\xc4\xbe\xeb\xbd\x49\x1e\x10\xf4\xb9\xdb\xed\x17\x74\x9e\x46\x23\xda\x69\x93\x36\x44\x2d\x64\x7a\x4a\xcb\x4d\x25\x9b\x67\xa7\xb4\xa8\x4a\x9d\xa4\x17\x24\xcb\x98\x8e\x92\x59\x94\xda\x5c\x39\xc9\x42\x5b\x44\x95\x3f\xe7\x45\x3c\xc4\x58\x9f\x6f\xd7\x8e\xe9\xc9\x45\x48\x51\xdb\xf2\x34\xb1\x55\xee\x26\xd4\x55\x09\xa4\x9a\x0e\xb7\x81\x20\xcd\x78\xe8\x4d\x0e\x11\xd5\xb7\x24\xcb\x73\x26\xcd\xbd\xee\x50\x91\x20\xa4\xee\x74\x08\x43\xb0\xb5\x1f\x99\xc6\x08\x0e\x92\xd2\xb2\x7c\x3f\x8d\xb2\xce\x06\xc4\x5e\x7e\xc0\x2f\x0f\x88\xdb\x18\x82\xe2\x36\xbb\x90\x0a\x1a\x7d\x71\x70\xba\xbb\x80\xf0\xe7\x02\xb1\x51\x76\x21\xc2\x43\x89\xa8\xbd\x59\x18\xc9\x7d\x85\xe5\xdd\x2c\xe6\x67\x1d\x9c\xbc\x92\xf1\x45\x29\x12\x18\x94\xe4\x84\x8e\xf3\x82\xf6\x3d\x24\xf7\x52\xaa\x2d\xf5\x73\xf1\x59\xec\x60\xcb\xa9\xee\x25\x88\x0d\xc6\x64\xe8\x75\x7e\x5f\x78\xe9\xcd\xa2\x73\x9e\xe9\xf6\x3c\xa9\x2e\x86\xe4\xb1\x30\xcf\xcb\x5d\x2b\x29\x45\x94\x70\x28\xdd\x75\x36\x29\x34\xf1\x9d\x75\x06\xf2\xc4\x2a\x8d\xe7\x78\x49\x79\xa7\xb8\x70\x67\x3c\x65\x44\xc5\xf4\x20\x8e\xc3\xb6\xbf\x16\x48\xa2\xf6\xb7\x77\x07\xaf\xfb\x0a\xeb\xbc\x4d\x1c\xd7\x15\xa2\x2e\x97\x24\xb2\x93\x01\xf7\xc8\x3c\x2a\x4b\xc6\xee\xaa\x69\x91\x2f\x26\x53\x6b\x85\xa8\xf1\x08\x32\x84\x8a\x3d\x67\xb6\x9a\x13\x3e\x00\xa5\xcd\x27\x62\x87\x47\x2e\x21\xc4\x15\x1e\xb3\xc2\x65\xf5\x9d\x2a\xf7\x5e\x54\x05\xe9\xac\x25\xe5\xcf\x49\x96\x54\xd4\x9e\x00\xab\x2b\x20\x84\xe2\x8e\xd8\x32\x9c\xa7\xbf\xe6\xca\x79\x2b\xf6\x25\xbe\x52\x98\xda\x96\xc1\xf6\x41\x7e\xa3\xae\x98\x36\xa1\x15\xe4\x47\x3f\x18\x1f\x66\x89\xdf\x5e\x07\xc5\xab\x29\x15\x3f\xd4\xaa\x24\x55\xde\x53\xd6\x35\x9d\x8d\xc0\x9b\xe2\x55\xf5\x45\xd5\xd3\xe1\x1d\xea\xf2\x32\x10\x87\xae\x24\xb4\x28\xf2\x42\x46\x4d\xe2\xdd\x2e\x49\x96\x57\x64\x94\x17\x05\x1d\x55\xc3\x33\xb4\xb0\xcc\xae\x1b\x2b\x8c\x15\x55\x64\xb1\xe0\x5f\xe1\x9f\xa7\xf0\x4f\xbf\xca\x7f\xcd\xcf\x68\xb1\x17\x95\xb4\x03\xac\x88\x9b\xb2\x11\xe3\x63\x60\x7f\x17\xc7\xf1\xe2\xc4\xea\x88\xfd\x7b\x8c\xec\x04\x08\x06\x07\xda\x37\xe8\x91\x07\xd8\xcb\xe8\x19\x79\xc1\xc6\xd6\x69\xc3\x51\x38\xf4\x05\xdc\x89\xff\xd5\xae\x08\x3d\x4f\xca\xaa\xec\x91\x79\x4a\xa3\x12\xe4\x6f\x18\x7f\x9e\x29\x8c\x8d\xf3\x34\xcd\xcf\x92\x6c\x02\x25\x4b\xc6\x36\xad\x15\x26\xfa\xd8\x83\x18\x1e\x3d\x74\xcd\xa7\x2e\xf5\xb4\x1a\x00\xc4\x71\x73\xc3\x73\x47\x1f\x29\xac\x51\xbe\x55\xc0\x91\x7d\x02\x8e\xcf\x8a\x2f\x73\x82\x60\xdc\x19\x02\xa4\x70\x32\xe0\x38\x56\xa4\xf6\x26\x2f\xcb\xe4\x24\xe5\x13\x0a\xd1\x5b\xa4\x97\xe5\xbb\x7d\x26\xc1\x16\x15\xff\xc9\xc4\x77\x89\xb6\x17\xe3\x71\x32\xb9\x10\x0f\x07\x8a\xb6\x1e\x90\x8f\xac\x0b\xfc\x4f\x9f\xd5\xc1\xa3\x38\xd7\x13\x70\x33\x0d\xa7\x8e\xd5\xf8\xa3\x3c\x85\x13\x80\x13\x0d\xa8\x8e\xbd\xf8\xa3\x38\x28\xd3\xdf\x44\x89\x07\x0f\xd4\xba\xd5\x87\x57\xbc\xc4\x1f\xd1\x49\x6e\x7c\xf3\x15\x91\x47\x4f\x7c\x10\x70\x64\x85\xbf\x89\x22\xa8\x23\xa8\x34\x7f\x94\xb8\x40\x30\xc4\x02\x41\x0f\x70\x7a\x24\xd1\x42\x11\x2e\x27\xf8\xa1\x52\x0f\x8e\x80\x22\xf8\x86\xa5\x87\x7f\x56\x3a\x01\x27\x8f\x51\x94\x31\x45\x24\x52\x9c\x5c\xbc\x17\x56\xbe\xbc\x20\x11\x79\xf9\xe2\x1f\x60\x16\x90\x92\xe0\x0d\xf2\x1b\xb5\x4f\x4b\xc5\xf2\xb7\x29\x95\x21\x25\x23\x74\xbe\x2d\x12\x18\xa1\xe4\x1d\x6c\x9d\x45\x25\x39\xa3\x6c\xe1\xe8\x38\x3f\x91\xca\x4f\x8f\x85\xab\xdf\xa8\x61\x21\x90\x63\x35\x18\x0e\x17\x9c\x58\xe5\x92\x83\x60\x19\x8b\x17\xc1\x19\xa8\x4d\x46\xc6\x99\x97\x23\x5d\xe1\x2d\x5c\x54\x41\x9e\x1a\xcd\x0c\xf1\x13\x92\xd4\x1a\xad\xec\x88\x63\xdb\xb3\xb8\xcf\x68\x72\xbb\x96\x43\x6b\xf9\x3f\x7d\xf9\x57\x79\xed\xe2\x47\x9a\xc9\xd7\x63\x03\x6c\x19\xfe\xb9\x8c\x00\xb0\x72\x43\x6c\xa0\x4a\x66\xb4\xfc\xf3\x58\x40\x26\x0c\xa2\x6c\xe1\x2b\x53\x5a\xc9\xed\x0d\xb0\xb3\x13\xe5\x05\xe4\x21\x0e\xd5\x9f\x66\x24\xa2\x89\x42\x1e\xa0\x32\x4a\xd0\x94\x61\x55\xa7\xa2\xb2\xe9\x1a\x10\x84\x9e\x0c\xec\xbc\x64\x4d\xc9\x32\x3d\xeb\x3b\x90\x26\x81\x29\xc8\x1a\xc4\x8f\xcf\x9f\xc9\xc6\x13\xbf\x06\x25\xaa\x76\xd5\x1f\xfe\xc1\xd2\xbc\xc4\x1c\xc8\xfe\xdc\xbb\x47\xc4\x6f\x9f\x4a\xc1\x9a\xb5\xbf\x62\x0d\xc6\x1b\xc8\xcf\x90\xe9\x44\x69\x65\xa7\xd9\x38\x6f\xf7\xda\x6d\xe3\x50\xc9\x09\xf7\xe7\xab\x00\x13\x4f\xad\x78\x98\xc9\x2c\xd4\x1e\xf2\x51\xb4\xc3\xc1\x64\xaa\x1d\xa5\xf4\x09\x7f\x55\x80\xad\xce\xf2\x76\x49\x46\x2a\x19\x93\x87\xdc\xcc\x6c\x4d\x8d\x68\x2e\x44\x49\x86\x82\x6e\xd6\x6b\x1a\xe5\x4c\x32\x62\xf0\x27\x88\xdc\x7c\x2b\x1a\x02\x08\x74\x70\x28\x46\x55\x02\x1b\x47\x96\x4f\x65\x6b\x7c\xcd\xbf\x16\xcc\x7a\x7f\x9e\x2e\x4a\xdd\x07\xf1\x1c\x88\xe4\xa9\xc0\x5c\x23\xd7\x94\x8e\x3e\x96\x52\x39\xe3\xfc\x54\x9e\xf5\x96\xe2\xc6\x64\x7a\x01\x31\xaf\x03\x99\xce\xf9\x5a\x18\xf9\xb3\x9c\x9b\xe9\xca\x51\x1b\x8c\x45\x44\xa8\x00\x8e\xd5\xc8\xb3\xa6\xc9\x89\xb4\xea\x37\xe6\x51\xd4\x6b\xdb\xf9\x06\xff\xb7\x71\x7e\xb4\xf1\xe0\x87\xe8\xc1\xf8\xf8\xd3\xc3\x8d\xcb\xff\x1a\x24\xfd\x8a\x96\x95\x82\x5f\x11\x0d\xb5\xa3\xff\x72\xe3\x6e\x32\x62\x30\x42\x0c\xfe\xaf\xb3\x71\xde\x7d\x5a\x3b\x64\x83\x30\x07\x03\x9d\x17\x8f\x27\xbe\x83\x2e\xf2\xc0\xdb\xc2\xc5\x73\x06\xb7\xbf\xd9\x86\x8e\x47\x6f\x52\xb6\x0c\x74\x49\xcc\xd8\x28\xde\xfe\x98\xdd\x61\x2c\x11\x81\xed\x3e\xf8\xd9\x0b\x66\xf7\x1a\x12\xf5\xb5\x4b\x08\x13\x5e\xce\xd8\xff\x47\xd1\xbc\x04\xf9\x23\x4d\x89\x7c\xee\xe1\x58\xa4\x4e\xa7\x45\x7e\x07\xd4\x67\xb3\x8d\x03\x25\x23\x70\x1c\xd1\x68\x34\x25\xa3\xa8\x74\x6b\x4a\x4a\x4e\x37\x8b\x99\x98\x2a\x4c\x60\x62\x15\xae\x44\x67\xbc\xc5\x72\x31\x9b\xd1\xb8\x86\xe4\xac\x56\xbf\x00\xe9\x59\x2d\xd4\x92\xe0\x60\xc0\x87\x65\x23\x2a\x52\x65\xc5\x2f\x67\xfb\x42\x96\x19\x01\xf2\x32\x2a\x21\x34\xd2\x34\xda\x96\xed\x98\x66\x1d\x2d\x3e\xf9\x82\x0f\x3d\xdc\x80\x03\x5a\x62\x93\x0d\x04\xc4\xaf\xa6\x24\xa5\x70\x17\x1f\x65\xe4\x9c\xcf\x69\xc1\xba\x2c\xa7\x24\x83\xc4\xa6\x93\x84\xe7\xba\x8c\x4a\x3a\x8b\xe6\x6c\x6a\x36\x4d\x63\x64\x47\xf9\x79\xa0\x8e\x43\x64\xc1\xcd\x47\x5d\xf2\x13\xf9\x9e\x49\x04\xe2\xd3\x51\x72\xdc\xaf\xf2\x43\xd6\x92\x30\x4d\xad\xed\xec\xa0\x8f\xb0\x16\xea\x2b\xfc\x71\xc7\x53\x23\x36\x76\x59\x35\x86\xa2\xef\xe3\xf5\x8a\x76\x09\x73\xb3\x30\xf2\x9f\x60\xe2\x7d\x25\xf4\x4b\x49\xa4\x41\x0a\xad\xf2\x9b\xa5\x50\x65\x7e\xd7\x9b\xfb\x2a\x04\x8a\x8c\xdd\x8a\x26\xed\x4b\xfb\xa2\xa9\x76\x5b\xd1\x97\x4b\xbe\x06\xca\xaf\x46\xcc\x18\x6a\xe4\x0c\x81\x55\x55\x4b\xdf\xb2\x27\xc8\x19\xc1\xa1\x75\x60\x91\x53\xed\x67\xc9\xa8\xf7\x07\xa6\x69\x8d\x79\xc2\x0a\x79\xf2\xa8\x48\xdf\xa4\xec\x65\x84\x6d\x91\x96\x3d\x88\xf5\x9d\x20\xd9\x63\xba\x73\xf8\xee\xd2\xba\x96\x51\xad\x55\xd8\x95\x6b\xb5\x1c\x6b\xb0\xdd\x2a\x67\xf2\x6a\x12\x93\xad\x0d\x1e\xda\xea\x81\x38\x19\xe5\x4d\xf3\x1b\x26\x1b\xe7\x84\xfb\xc1\x78\x48\xbd\x01\x89\x07\xbc\x20\x44\x58\x0b\x83\xd3\x6b\xbf\xb8\x86\x84\x6d\x89\x47\xfe\x9d\x53\xc6\x9c\x56\xb8\x31\x14\x06\xbe\x65\xd7\xed\xd6\xbe\xca\xc4\x41\x5f\xa0\x4e\x13\x48\x26\x68\x85\x53\x33\x55\xab\xbe\x38\xd7\x23\x0f\x3d\xaa\x88\x3c\xf2\x90\x91\xbb\xa5\x6e\x5f\x6a\x69\xba\x49\x7a\x5e\xbf\x3a\xeb\x3d\xe7\xb3\x72\xf6\xf2\xbd\xd0\xa7\x88\x92\x0e\xef\x8c\x2d\x79\xca\x2e\x66\x65\x15\x65\x23\xc6\x71\x74\xe9\xcf\x9f\x35\x0e\x45\x71\xb8\xb6\x08\xbf\x8c\x80\x2d\xde\xb7\xdc\x85\x04\x18\x97\xaa\xb3\xbd\x0a\xd2\xa4\x76\xbe\x1c\x63\xef\x5c\x2f\xad\xe6\xe8\xf2\xe4\x3c\xf3\xe3\x4a\xb0\x64\xd1\x41\x18\x18\xef\x62\xfb\x06\x51\xc5\x7b\xb3\x12\x9e\x64\xbf\x9b\x60\xea\x67\xe4\x79\x73\x05\x5c\xc9\xe2\x57\xc3\x96\x2c\xe2\x7a\x10\x85\x07\xc7\xfa\x56\x35\x19\x19\x1f\xc4\x15\xc7\x75\x20\x7a\xd9\x74\xbd\x30\xf1\x25\x5b\xa4\x29\xa4\x2d\xe9\xb8\x8b\x08\x1c\xed\xc1\xca\xe2\x41\x83\x38\xb7\x5e\x01\x09\x27\xbc\xcf\x8d\x98\x07\x07\xbd\x2a\xeb\xe0\x2f\xaf\x36\xbd\xa2\x97\xab\x0c\x0c\xc2\x5f\x36\x19\x96\x9b\xf9\xa6\xf9\xa0\xdc\xec\x35\x4d\x79\x21\x94\x5c\x3a\x1c\x5b\x2b\xe2\xdb\x33\xb8\x24\xe6\x8a\x28\xad\xf1\xfc\xad\xb4\xd6\x20\xf2\xd8\x58\x32\x1c\x56\xd4\xbe\x06\xa2\x43\x7f\x15\x17\x9e\xad\x6f\x6d\x0d\xce\x69\xf9\xfd\x6d\xe4\x64\x7c\x49\x46\x90\xdf\xad\x43\x7d\x1b\xa6\xa1\x2c\xaf\x8a\x84\x48\xa0\xe1\x05\x9b\x5a\xba\x98\x91\x93\x34\x1f\x7d\x24\x53\x1a\xc5\xb4\x60\x0f\xf9\xcc\xf5\x7a\x49\xca\x67\xec\x83\x57\x34\x99\xd2\x73\x95\x82\x00\x8a\x93\x71\x92\x56\x8e\x91\xd6\x4b\xd5\x00\x6e\x04\xef\x66\x6f\xea\x6d\x12\xdf\x6d\x6e\x69\xa3\x04\x87\x5f\x8a\xa4\xb0\x45\x81\xd7\x86\x2b\xf3\x19\x14\x5c\x28\x6f\xb6\x73\x64\x0f\x30\x7d\x32\xbc\x69\x3c\x9a\xce\x54\x9a\x33\xe1\x72\x9e\x8c\x7c\xf3\xf2\x9e\x7d\x58\x3a\x2f\x95\x86\xaa\x9d\x10\xa8\xcd\x98\x10\x28\x59\x3f\x21\x8f\x1e\xea\xf9\xe0\xe0\xd7\x98\x0f\xa8\x0c\xd7\xe5\x9b\x0e\x07\xe8\x1a\xb3\x11\x8a\x80\x23\x24\xcd\xa1\xfc\xd1\x53\xaf\xe1\xbe\xd7\x50\xfd\x12\x1f\x40\x22\x1d\xf2\x7f\xd4\x2b\xe1\x88\x33\xd4\x3f\xc5\x27\xe4\xa5\x33\xc4\x0f\xaa\xe4\x61\x35\x7e\x3c\x14\xff\xaa\x97\xe0\xfc\x33\x94\x3f\x50\x55\x1c\x5a\xfe\x42\x1f\x44\x09\xf5\x53\x56\xe5\x7a\x45\x0f\x7d\x2f\x05\xb8\xeb\x5d\x3b\xf4\xbc\x33\x81\xa5\x0f\xeb\xd0\x7e\xa1\x46\xf3\x1b\x85\xb1\xfc\x46\xf1\x48\xe0\xa5\xf8\xa1\x20\x95\x98\x3a\xc4\x0f\xea\xb3\x69\x9f\x1f\x3a\x6f\x34\xfe\xb8\xbe\x30\xd4\x3f\xc5\x27\x24\x9b\x0f\xf1\x83\xfa\x6c\xa8\x46\x43\xfb\x85\x02\x43\x00\xf6\x27\xcb\xce\x30\x74\x5f\xa9\x6e\x3a\xa0\xce\x2b\x55\xab\x94\xfb\x86\xe8\xb7\xd1\xe9\x6c\x32\x54\xbf\xd4\x07\xbe\x45\x0f\xd5\x2f\x8d\x05\xce\x14\x86\xfa\xa7\x1e\x1a\xdb\x72\x87\xf2\x87\x7a\xcd\x36\xbd\xa1\xf8\x57\x57\xc3\x58\xe4\x50\xfe\x50\xaf\x81\xbb\x0c\xe5\x8f\x9e\x5c\x81\x3c\x36\xa3\x08\x13\xd0\x1a\x6e\xfe\xd0\xab\x0d\xbf\xd4\x6b\x2d\xaa\xf1\xe3\xd6\xf0\xf1\x77\x97\xc7\xbd\xad\xcd\x46\x81\x46\xcc\x45\xbe\x23\x96\x78\x4b\x84\xd6\x68\x0d\x49\x6b\xa3\xbf\xb5\xd1\xdf\x6c\x89\x08\x88\x3c\xfe\xe1\x56\xb3\x34\xe9\xb7\x51\x4c\x6e\xa3\x98\xfc\x47\x46\x31\x11\x15\xf1\x37\x56\x04\xc4\xbf\xd1\xf1\xb8\xa0\x17\xe4\xb7\x24\x1d\x7d\xa4\xe4\xc7\xdf\xe9\x78\xec\xc4\x32\x69\x1a\x28\x11\xe0\x92\x28\x23\x07\x4c\xbe\x8f\x00\x2c\x89\x32\x0f\xdc\xcf\xd1\x09\x83\xfb\x7b\x3e\xa1\x69\x59\xd1\x34\xa5\x05\xf9\x71\x0c\x2f\x3d\xd0\xbf\x44\xa7\xe4\xb7\x3c\x8f\xc9\x8f\x93\x70\x9c\x95\x87\x77\x71\x1c\x2a\x11\x20\xf5\x55\x94\x45\x13\x33\xdc\x49\x7f\xc0\xf0\x31\x28\x38\xc0\x8c\x03\xa8\xa8\x26\xfb\x27\xa0\x9d\xd9\xd0\xc9\x49\x94\x29\x98\x17\x70\x13\xc3\x06\xe1\xa2\x5c\x39\xa0\xd5\x54\x41\x3e\x7f\x56\x03\x18\x9f\xe8\x78\xcd\xd3\xba\x1a\xcb\xa9\xae\xf1\x35\x64\x03\x08\x41\x66\xb4\x52\x90\x6f\x68\x51\xc2\xf5\xb9\x30\xf8\x5c\x80\xe8\x7e\x9c\x45\xc5\xac\xae\x27\xec\xbb\x86\xa6\x55\x05\x09\xd9\xdc\x02\xa5\xf8\xa4\x60\x25\xd3\x31\x40\x25\x33\x61\xaa\x1c\x8a\x2b\x93\xa4\x56\x95\xf0\x8a\xff\xbf\x26\x40\x0d\x87\x52\x01\xc4\xc4\x3d\x1c\x9a\xc5\x9e\xfe\xf1\x0f\x0a\xee\x19\x68\x69\x2e\xd8\x09\x7b\xaf\x31\x5a\xe4\x73\x5a\x54\x17\x1e\xc0\xb9\xf8\xa4\x60\x5f\x56\xd5\xfc\x4d\x91\x9f\x26\xb1\x97\xfa\xd8\x22\x9e\x8b\xcf\x9a\xf6\xe6\xa3\x9a\x22\xc9\x7c\xe4\x94\x68\x1a\xcd\x93\xfd\xa7\x74\x81\xdf\xe8\xc9\x36\xe9\xc8\xba\xac\xa0\xd6\x85\xbd\x6e\x32\x7a\x66\x2d\x26\x5d\x14\xc7\xb7\x16\xc9\x9b\xd1\x00\x24\x18\x86\xa2\xfc\x12\x13\x3d\x63\x8b\x08\x52\x66\x18\x95\xc4\x27\xe2\xeb\xf3\x67\xee\xc7\x72\x2a\xcb\xbe\x9b\x7a\xca\x66\xb0\x32\xd8\xe7\xd7\xb4\x72\x3f\xcf\xf5\x72\x60\x30\x72\x75\xb8\x80\x27\x7f\xfc\x21\x9b\x61\xd4\xee\xe9\x87\x26\x7b\x80\x12\x8f\x1d\x03\x48\xd3\x3b\xd2\x68\xa2\x79\x32\x54\x3b\xa8\xf8\x57\x68\x36\x46\x57\x05\xe2\x4a\xb3\x34\x26\xa9\xa1\xf1\xd4\xd3\x40\x88\x86\x86\xf8\xc1\xd3\xcc\x07\xb5\x3a\xf8\x0f\x77\xa4\x02\xa2\x83\x3a\x21\x08\x3d\xa1\xe5\x10\xfd\xee\x08\x27\x29\x88\x42\x7e\x29\xc2\x69\x33\xd1\xaa\xa4\x44\x8f\x26\xe7\xfb\x38\xc4\xad\xba\x7b\x87\x91\xa1\x6f\xa8\x4b\x87\x19\x1e\x22\x97\x43\x65\xc5\x32\x17\x2f\xc5\x44\x89\x33\x94\x37\x58\x00\xb8\xf4\x15\xe8\xde\xdb\xa1\x82\xf2\x94\x2e\xba\x2b\x1f\x29\x9d\xef\x97\xef\x2e\xb2\x51\x92\x4d\xea\xfb\x03\x85\xad\x02\x4d\x89\xd3\xdb\x1b\xcc\x42\x9e\x21\xaf\x20\x0b\x4c\x5e\x6f\xe2\x11\xd1\xe0\xc9\x07\x24\xef\x56\x4b\x30\x78\xf6\x01\x8a\x7b\xfb\x12\x8e\x3d\xba\x60\xf8\xb6\x36\x87\x54\x6f\xfc\xc0\x46\xad\xf2\x85\xaf\x79\x7d\x79\x4e\xf6\x40\xbc\xf1\xd7\x6b\x83\xa3\x77\xbe\xda\x31\x4e\x65\xfd\xb5\xb8\xe5\x7e\xa6\x12\xf4\x37\x1a\x18\x1e\x06\x13\xcf\x2e\x20\x76\x13\xe2\xa0\xea\x8d\x0f\xd8\x3d\x37\x97\x85\xf6\x9c\x03\x54\xa7\xdf\xa1\xc2\xce\x17\x5f\xcb\xfb\xcf\x76\x5f\xa3\xe6\xd8\xa3\x0b\xa6\x23\x26\x71\x38\xf1\xec\x05\x94\x01\x7c\x14\x24\xbc\x10\x1b\xa0\xcd\x15\xb8\xf8\x80\x63\x00\xf0\xb3\x30\x2b\xa4\xa8\x79\x6c\x09\x27\xf7\x36\x68\xdd\xc9\x72\x9c\x14\x60\xf2\x1e\x45\x73\xb8\x41\x63\x9c\xeb\x7a\x66\x78\x7f\x6f\xf7\x8d\xc1\x1a\x58\x49\xc3\x2d\x31\xe1\x02\x2a\x5b\xdc\x4c\x56\xe5\x00\xe6\x25\x60\x06\xd2\x17\x4d\xa1\x85\x0f\x61\x8e\x14\xcb\xae\xcd\x57\x7c\xa4\x19\x3e\x6c\x96\x42\xba\xe9\x58\xe7\xf3\x19\xd8\x85\xda\x72\x47\xcb\xf2\x98\xb6\x7b\x26\xc8\x04\x1c\x6c\x86\xa4\xcd\x64\x98\x0f\xa3\x34\xa1\x59\xf5\x77\x0e\xdf\x46\x07\xf8\xdd\xde\xd5\x5a\xa4\xd5\x59\x5e\x7c\x0c\x36\x9a\xd1\xea\x83\x80\xb5\x61\xcc\xec\x1d\x43\x9b\x0f\x5c\xbf\x6f\x54\x18\xe6\x83\x9d\xa3\xd5\xf4\x03\xcc\xfe\x28\x4f\xff\xfe\x27\x75\xf2\x6c\x9a\x94\x73\x1d\x56\xdc\xe9\x63\x39\x9d\xde\x00\x02\xf9\xef\xe3\xd0\x16\x94\x94\x7b\x79\x96\xf1\x48\x63\x68\x49\x76\x4d\x9a\xec\x78\xb7\xdb\x7b\xf7\xbc\xdb\x30\xae\xb3\xd3\x0d\x6e\x7e\x3c\xf6\x85\x94\xfe\xc3\xeb\x01\x1c\x76\x21\xa5\x89\x94\x91\x02\x46\x67\x56\x3f\x8a\xb1\x8b\x95\x12\x6e\x11\x33\x94\x99\xd6\x70\x6b\x83\xbd\xc2\x7a\x50\x6b\xb8\xb5\xc9\xde\x69\xfd\xa3\x35\xdc\x7a\xa8\xde\x70\x89\xac\x35\xdc\x7a\xac\x5e\x61\x5d\xa2\x35\xdc\xde\x52\x1f\x18\x1f\x68\x0d\xb7\xb7\xf5\x0b\xad\x42\xb4\x86\xdb\xba\x52\xad\x91\xb6\x86\xdb\xdf\x3b\xaf\x69\x35\x6d\x0d\xb7\x1f\x3b\xef\x33\x5a\xb5\x86\xdb\x3f\x38\xef\xa5\xa8\xdd\x1a\x3e\xdc\x70\x3e\x96\xd3\x69\x6b\xf8\x70\xd3\x7d\xcf\x84\xed\xd6\xf0\xa1\xee\xbe\xd4\xa9\x5a\xc3\x87\xdf\xa9\x97\xa6\xda\xde\x1a\x3e\x7c\xa4\x3e\x49\xd1\xa7\x35\x7c\xf8\x7d\xbd\xe9\xf1\xf2\xb8\xb7\xb5\x7d\x6b\x13\xbc\xb5\x09\xfe\x75\x6d\x82\x51\x9a\x42\xd0\x92\xeb\x46\x37\x36\xad\x6e\x8e\x51\xc6\x6b\x95\x91\xa9\x9d\x5e\x9c\xf2\x6b\x18\xc8\xd2\x01\x7d\x52\x80\x3a\xcf\xd3\xd2\x8c\x67\xae\xd5\xc8\x6f\x36\xfa\x19\xce\xb4\xad\xea\xe0\x9d\x02\x39\xe3\xd9\xcc\x4c\x18\xc9\xa6\xc4\x47\x14\xe8\x78\x37\x4d\x8d\x01\x99\x92\x95\xa9\xbe\xf5\xc0\x6b\xa1\x47\x6c\xbf\xbd\x80\xed\xc5\x7c\x61\x68\xe6\xbf\x73\x27\x05\xf6\x8f\xf1\xde\x71\x52\x55\x7b\x95\xd3\x4f\xb4\x0f\xf2\xf3\x65\xd3\x85\xc3\x12\x84\x65\x5c\xfd\x1d\xf5\xeb\xf3\x67\x9e\xb9\x8a\xd8\x41\x44\x3e\x5d\x2a\x9f\xd5\xa3\x36\x93\x6a\x21\x85\x47\xbb\x47\xda\x55\xce\x7f\x1e\xf7\x39\xce\x51\x16\xd4\xb1\xef\xec\x57\x34\x75\x34\x3e\x06\x8f\x20\xe5\x9f\x2b\xcf\x83\xbb\x9e\xc4\xfc\x76\x45\xac\x53\xac\x82\x1d\x44\x4e\x3c\x7e\x13\xf4\x85\x2b\x65\x3a\x25\xa6\x6e\x52\x39\x71\xe0\x1b\x7a\x10\xde\x44\x23\xd9\x40\xba\x7d\x91\xcf\x0a\x79\x52\x37\x01\x9e\xfc\xe7\x71\x54\x45\x6a\x28\xec\xa1\xcf\xfe\x47\x76\xd0\xef\xcf\x9f\xb9\x7f\xb2\x82\x80\x53\xf4\x52\xc2\x88\xa7\xcf\x9f\x71\xaa\x5e\x30\x8b\xb2\xe6\xa5\x8f\x00\x02\x3d\xda\x38\xee\x97\x8c\x71\xe8\xd4\x05\x0c\x7c\x26\xe4\x23\x4d\x79\xee\xf4\xfd\xee\x9b\x3e\xdc\xce\x8e\xf0\x7b\x16\x62\xa2\x7b\x46\xdd\xf9\x5d\x07\x33\xe8\x1e\x6d\x1c\x1b\xf7\xeb\xd6\xa0\x0f\x5d\xf2\x09\x6e\xaa\x44\x59\x96\x57\x64\x9c\x64\x31\xef\x5b\x92\x4d\x78\x5b\x4f\x75\x17\x46\x79\x56\xe6\x29\xed\x9f\x45\x45\xd6\x69\xe3\x22\x3c\x58\x13\xe3\xdd\x69\x3e\x69\x63\x2f\x64\xd1\x6d\x86\x11\x5f\x10\x30\x2a\xf8\x15\xce\xbe\x07\x33\xd9\xf1\xad\xdf\x1e\xef\x5b\xcf\xa4\x11\x4b\x55\x83\x2a\x65\x38\x4f\x98\xf1\x66\xeb\xf5\x9c\x8e\x98\x08\xe1\x59\xb0\x3d\x88\x11\x76\x12\x8d\x3e\xa2\xc4\xc3\x10\xc6\x42\xe8\xd9\xf2\x78\xb9\x13\x15\x93\x05\xdc\xe9\x39\x52\xbf\x50\x48\x28\xeb\xce\x80\xac\x14\x52\xca\xd7\x96\x33\x42\x1f\x76\x1c\x10\x46\x08\x9b\x56\x5c\x14\xcd\x5b\xb2\x45\x9a\xfa\x50\x9f\x4b\xf2\x13\x81\x1c\x91\xee\x2d\x41\xc6\x28\xb3\x22\x37\x26\x03\x56\xfb\x27\x89\x65\xda\x44\x32\x3d\xdf\x0d\x3a\x79\x0f\xb4\xb1\x76\xcf\xcb\x88\x7b\x72\x47\x60\x2a\x5d\xa7\xdb\xd3\x2d\x21\x5c\x37\x9a\xb6\xa8\xaa\xa2\xd1\xf4\x7d\xbe\x27\xe3\xb4\xe1\xf9\x93\xc1\xdb\x0c\x6d\x5f\x4f\x34\x1f\x3d\x7f\x74\xc7\x24\x0b\xf7\xa3\x34\x55\xbb\x90\x80\x0e\x6b\x2b\x4e\x5f\xb1\xea\xe2\xd1\x5d\xbc\xca\x0b\x90\x70\x6b\xb8\x05\x7a\x03\xe7\x0b\xad\xe1\x16\x68\x05\x38\x4f\xe3\x36\x00\x5b\xdb\x68\x6b\xf8\x70\x9b\x09\xe3\x0f\x6f\x85\xf1\x5b\x61\xfc\x2f\x26\x8c\xe3\x34\x4c\xa0\xe7\xdf\x68\x1e\xa6\xbf\x95\x79\x56\xcc\x47\xa6\x10\xfb\x3b\x7f\xa9\x8f\x47\x8b\x22\xb7\x65\x6b\xfe\x0e\xc9\xb7\xae\x75\x84\x8d\xdb\x14\x5d\x1d\xc9\x15\x50\xf3\x21\x2c\xbf\x8a\x2f\xac\xed\xa3\xe3\x46\xf1\x2e\xa3\x38\x96\xa1\x4a\x19\xe7\x16\x15\x40\x78\x79\xe8\x60\x21\x13\xb3\x5a\xae\x95\x51\x1c\xfb\xdc\x9a\x89\xc0\x05\x2f\x57\x21\x47\xe2\xc1\xdd\x3b\x30\x64\xcc\xb7\xe3\xd8\x27\xd4\x7b\x71\x50\xf6\xe7\x8b\x72\xaa\x40\x1a\x8d\x4d\x72\xf9\xfa\x91\x08\xa8\x40\x1f\x7d\x22\x81\x15\xa3\x42\xa1\xdc\xe8\xaf\x67\x5a\xf4\xe1\x57\x16\x73\xb3\x97\x04\xee\xa1\xda\x69\x51\xf4\x84\x8c\x5b\x7a\x64\x6e\x4e\x57\xfc\x97\x14\x41\x35\x84\xc0\x15\x0e\xa0\xaa\xf0\xda\x23\x10\x14\x21\x74\x67\x51\x54\x7a\x04\x40\xc7\x86\x1a\x12\x54\x0a\x78\x99\x50\xc5\x4c\x3c\x92\x5d\x12\xd5\xf6\x3d\x52\x94\x5d\x64\x4d\x2c\xb2\x7e\x52\xfe\x3d\x4a\x93\xf8\x2d\x2d\xe7\x79\x56\x52\xd1\x9a\x7b\xe9\xd2\x19\x88\xbf\xc9\x0e\x5f\x83\xfd\xfd\xec\xd4\x5b\xed\x13\xb7\xd6\x4b\x5f\x1f\x83\xf5\xf3\xe0\x61\xce\x90\xf9\x76\x0d\xb1\x46\x7c\x1f\x44\xfb\x7d\xd1\x0d\x88\x42\x82\x5f\xd8\xfd\xba\xc4\x73\xa2\x75\x29\x12\x14\x47\x80\xd4\x0c\xeb\x29\x47\x44\x6b\xb8\x05\x56\x3e\xb1\x64\x5b\xc3\x6d\x70\x19\xfc\xee\x56\x68\xb8\x15\x1a\xfe\x62\x42\x03\x92\x19\x94\xc8\x7f\x93\x06\xbc\xa6\x66\x34\xa6\x59\x15\x16\x5c\x29\x54\x89\x01\x7c\x5c\xdd\xda\x27\x01\xd1\x1d\x38\x6c\xa4\x93\x77\xdb\x24\xf8\x2e\xd2\x74\x10\x9c\x32\x6c\x0a\x11\xa6\x76\xdf\xe5\x66\x2f\x7c\x7d\x10\xa4\x04\xf7\x02\x3b\x87\xdc\xd3\x80\x6f\x14\x9c\x92\x2c\xc0\xa1\xfa\x92\xa8\x20\xe7\xe6\x6b\x7f\x23\x32\xec\xb5\xbf\x7a\xf3\xae\xef\x49\xd2\x13\x25\xed\xe3\xa9\xe8\x24\xf1\x58\x64\x70\x44\x74\x62\x45\x1f\xaf\x20\x97\xff\xce\x0e\x69\xa3\x7e\xb5\xc9\xbd\x7b\x46\x78\x73\xa4\xb2\xf3\x86\xcd\x24\x1a\x97\x5d\x6b\xff\xae\x6d\xd2\x13\x32\x9d\x74\xe0\x65\x68\xa3\x87\x8f\x3c\x94\xba\x77\x2b\xb1\xea\x62\x80\xb6\x20\xc2\x6f\x82\x33\x7a\x14\x96\x03\x8e\x58\x0e\xab\xd0\x89\xcd\x4e\xca\xa8\xd6\x4c\x24\x55\x79\xf9\x44\xe8\x32\xae\xd7\x07\xae\xa5\x45\x71\x2c\x89\xbb\xd4\x56\x00\x83\x5a\xe4\xcb\x4b\x55\x59\x0d\x8d\x09\xea\xf1\x57\x5b\x6f\x5c\xd0\x06\x83\x6b\xd0\x0e\xbe\x6f\xba\x12\x41\x60\x0b\x9a\xb2\x47\xa9\x2e\x7d\xa0\xd5\x54\x5a\xca\x75\x3f\xad\x40\x2a\xcb\x4d\xbf\x63\xc7\xde\xa2\xd1\x80\x4d\xbb\xcd\x26\x9a\x33\x95\x86\xb3\xcc\x19\xd3\xcd\x4e\xb1\x5d\x67\x03\xe3\x91\x64\x8f\x37\x32\xd9\x9c\x59\xbb\x36\x71\xc1\x8b\x85\x5d\x54\x71\x65\x73\x3a\x5d\x9b\x1a\xef\x5c\x78\x82\x77\xd3\xb4\x7e\xfe\x38\x98\x38\xc4\x5a\x9d\xec\xb8\xe1\x76\x49\x27\xaf\x40\x83\xe6\x4d\x4f\xd7\xe6\x57\x47\x83\xf5\x54\xa8\x02\x34\x81\x13\xa5\xa4\x82\x09\xad\x4a\xe1\xd6\x93\x5e\x90\x98\xce\xd3\xfc\x82\xc6\xd2\xd7\x12\x2e\x85\x8e\xa6\x51\x92\xb9\x97\x0e\xa1\xbe\x9f\xf3\x42\xf6\xcc\x17\xb7\x42\x6a\xcb\x5e\x4a\x95\x2b\xf7\x52\x99\x41\xf1\xd5\xc4\x92\x7c\x3a\x94\xe7\x35\xf8\x76\x62\xa0\x59\xec\xf9\x21\x5b\x43\xf6\x55\x44\xd6\x90\xf1\x1d\x72\x3b\xb9\xe6\xe9\x9f\x93\x82\x3b\x91\x88\xbb\x81\x1c\x62\x30\x20\x67\x51\xc2\x6d\xfe\x20\xc8\xcd\x2b\x64\x37\x96\x27\x82\x26\x2d\x88\x65\xa2\xd2\xce\xeb\xde\xd1\xae\x15\x88\x7c\x8d\xc2\x35\x75\xa3\x0f\xce\x9e\x06\xbd\x5e\x5f\x7f\x62\x2b\x6a\x83\x01\x29\xab\x7c\xce\x6d\xcc\x49\x36\x21\xd1\x98\x75\xe7\xbb\x0d\x3e\x77\x25\xe9\x54\xc9\x8c\xe6\x8b\xaa\xeb\xea\xac\x1c\x13\x3f\x91\xef\x36\x02\x5a\x2a\x1f\x44\x9f\x35\xf0\x9b\xa8\x5f\xe7\x2b\xe9\x92\x4f\x97\x3e\x5d\xd2\xc6\xa5\xb8\x80\xe9\xd7\x81\xd5\x04\xf9\x35\x5d\xad\x72\xea\xd0\xd8\x8a\x81\xc1\x21\x50\xc4\xd7\xcd\x88\xd1\x3b\x84\xc9\x3e\x61\x52\xf9\x22\x8b\x6d\x44\xb4\xbd\x8a\x2f\x4d\x71\xbc\x1a\xfc\xe7\x84\xe4\xbe\x72\xbb\x62\x6d\xe2\xca\x75\xbc\x1a\x0f\xfe\x0c\x3a\x9a\xd0\xea\xbd\x6e\xef\x2d\xa7\x3e\xcd\x77\x50\x5f\x5e\x46\xe5\x14\x93\x59\x4f\xd2\x6a\x37\x60\x46\x48\xc6\x1d\x01\x11\xa0\x3f\x7f\x31\x6f\x1f\x21\xcf\x98\xa8\xad\x3f\x32\x97\xa6\xd9\x29\x48\x46\x16\xe8\x91\xfc\x0b\xa5\x3b\x78\x84\xd2\x1d\x84\xfe\x92\x71\xc7\xa4\xc0\xcf\x9f\xc9\x1a\x34\x5a\x5f\x8e\x28\x3e\xef\x25\x56\xfc\x77\xa5\x65\x81\xff\x1a\x2f\x11\x7b\x60\x79\x8c\xb2\xcc\x6f\x2f\x99\x24\xf9\x37\x18\xa8\xd3\xcc\x34\x9f\x20\x42\x06\xed\x45\xb2\xfc\xb5\x76\x77\x69\x17\x88\x21\xf9\x29\xc6\x1b\x98\xf7\x46\xd5\x0d\x06\x84\x6f\x71\x52\xdc\x88\xb2\x98\x88\x63\x1e\x12\x4d\xa2\x24\x13\x0b\xea\x8c\xca\x2c\x9e\x4b\xfe\xfc\xe2\xac\xb3\x6f\x2e\xa9\xc2\x16\x97\x3c\xb2\xc3\x92\x61\x8d\x78\xf4\x40\x71\xee\xc9\xf6\x0e\xb6\xa3\x96\x74\x94\x67\x31\x61\x4c\x79\x79\x2d\x88\x96\x1b\x50\x2f\x31\x18\x26\xd8\xe8\x9a\x77\xda\x1f\x41\xeb\xa6\x3b\x85\x13\x1c\x20\x21\x44\xa8\xd1\x88\x95\x96\x55\x5e\xd0\x58\x25\x3b\xe0\xb2\x0b\x58\x9f\x26\x51\x49\xa2\x19\xdb\xb9\xfa\x7e\x96\x6e\xff\x85\x59\xbc\xfd\xe7\xc9\xc2\x70\x13\x9d\x5c\xd2\xc7\xcb\xf0\xe7\x20\x23\xf1\x94\x71\x60\xb1\xfd\x74\x25\x75\x05\x1d\x93\x48\xea\xff\x39\x62\x0a\xfe\x85\x8a\xbd\xe2\x08\x83\x16\xe0\x72\x8d\xc4\xae\x19\x6b\x23\xa0\xbf\x45\x27\x89\x79\x40\xc2\xef\x7e\x51\x65\x3e\x80\x97\xd1\x49\x42\x76\x18\xac\x16\xd6\xee\x0b\x8b\xed\xf2\xd1\x69\x4d\x2c\x23\x11\x92\x75\x65\x79\x55\x8f\x1c\x65\x46\xcf\xf4\x3b\x39\xba\xec\xe2\x12\x13\x89\x65\xa6\xd9\x94\x9e\x15\x51\xda\x5d\xb5\xec\x56\x5d\x59\x5b\xb4\x36\xc4\x12\x11\x2a\x47\xda\xb5\x63\xb7\xb8\x57\xf8\x16\x20\x4a\x00\xd7\xaa\xa6\x7c\xa5\x5a\x43\x94\x00\xa5\x06\x68\x52\x18\x6e\xbd\xe7\x48\xa4\x66\x6f\xff\x5e\xd5\xc1\xfe\xf4\x2f\x2e\xb2\x2b\x9d\x15\x53\x65\x47\xd2\x45\x4f\x11\x83\xc9\xe8\x06\x03\x9e\x3f\x55\xfb\x9c\x98\xf5\x6a\xc7\x91\x4f\x97\x4f\x18\xb4\xc4\xd7\x9a\xd5\xbe\x40\x91\x51\x39\xe8\xd5\x05\x5c\x95\x02\x0a\xc7\xb7\x43\xd2\x64\x44\xe1\xbc\x44\x3b\xb0\xd8\x39\x3d\x7d\xfe\x34\xe0\x12\x53\xe3\x45\x43\x1c\x4f\x9a\xb2\x3f\xcf\xe7\x66\x28\x44\xbb\x8f\x69\x54\x56\x02\xd8\xa9\x3e\xd0\x27\x4e\x5b\x1d\x56\x12\x82\x64\xad\xa9\x8b\x40\x90\xa0\x1a\xde\x3b\x1d\xd3\xc8\x5c\xde\x2f\xd6\x98\x80\xef\xf3\xa4\x3f\x3f\x91\x0d\xa7\x46\x31\xf5\x72\x51\xec\xca\xb5\xde\xc0\x06\x21\xff\xae\x65\xb4\x44\xd8\xb2\x79\xab\x34\xf5\x21\x5f\x45\x3c\xb6\x35\xb3\xdb\xfd\x79\x74\x11\x9d\xa4\xd4\xdb\x45\x57\xd1\xe0\xce\x66\x25\xcd\x62\x9d\x2a\x2e\xcb\xb3\x07\xa2\x16\x8c\x13\x67\x77\xb9\xac\xa1\x04\x08\x47\xc9\x78\xa8\xdf\x5c\xdc\x91\x8b\xa8\x07\x23\xc7\x35\xcb\xb9\x02\xb7\xc1\xf5\x1d\x5e\xd3\x13\x7b\x46\x6b\xce\x3c\xb1\x0a\x6d\xd8\x1f\xa4\x14\x19\xc5\x99\x6d\xa1\x88\x29\x39\x8b\x4a\x25\xa0\x9a\x15\xca\xa5\x0f\x87\xcc\x48\x43\xd2\x7e\x6c\xd6\x49\xf3\x34\x2a\xa7\x5e\xfc\xb3\x9e\xd3\xa2\x08\x9e\xb6\xe2\x63\x55\xef\xd9\x69\xad\xe4\xc4\xe4\xdb\x38\xe6\x67\x79\x88\x41\xb3\xde\x04\x9a\x0b\xa8\x76\x64\x07\x0a\x05\x05\xb9\xa0\xc4\x39\x4e\x8a\xb2\xaa\x11\x38\x57\x16\x19\x03\x16\x18\x9f\xd9\xc5\x7f\xd4\x6c\x3c\x2e\x0f\xe3\x0a\x39\x75\x39\x06\x96\xcd\xba\xdd\x60\x63\xec\x2f\xc7\xfa\x2a\x18\x08\xf2\x3d\x75\xa2\xc0\xe1\xa4\x09\x4f\xa1\x5a\x6e\x9f\x4c\xa5\x7e\xce\xdd\x75\xe1\x95\x78\x34\x1d\xf7\xae\x23\xc9\xb9\xd6\xbc\xe5\xb6\x64\x8f\x60\x20\x6a\xbb\x34\xc5\xa9\xb1\x6e\x63\x70\xf7\xce\x60\x60\x6d\xe1\xc6\x99\x14\x8a\xfa\x8d\xac\xac\x56\xfd\x1d\xb1\xb3\x0f\x06\x6e\x10\xe9\x60\xbe\xfa\xd1\x08\x82\x41\xe7\x3c\x71\x5a\x92\x4d\xea\xe4\x3d\xcb\x04\x6f\xa1\x81\x4f\xef\xa5\xcb\xb5\x0c\x01\xab\x4e\xb8\x22\x9f\xb0\x24\xd7\x54\xc6\x1a\x93\x2c\xd7\x55\x30\x66\x38\x8f\xca\x92\xc6\x3d\xa8\x43\x47\x65\x64\x20\x25\x5a\xf9\x26\xe7\x53\x54\x29\x26\xc4\x42\xae\xe1\x60\xea\x0b\x0f\x6c\xb9\x04\x93\x95\x85\x32\x7d\x61\x01\x9b\x54\xab\x29\x8a\x8d\x0a\x49\xa2\x20\x87\x9f\xf4\xad\x50\xbd\xea\xa9\x12\x27\x74\x14\x2d\x4a\x4a\xce\x28\x89\xf3\xac\x22\x67\x51\x06\x1e\x5c\xe5\x3c\x4f\x52\xee\x0d\x90\x55\xb4\x18\x47\x23\x1d\x31\xbe\x89\x29\xa0\x99\xba\xef\xec\x70\x0d\x18\x28\x71\xc3\x4a\xeb\xa5\x6f\xae\xdf\x5f\x68\xc5\x43\x97\xb3\x3d\xb6\x47\xce\xa6\xc9\x68\x0a\x0e\x14\x8c\x0d\x54\xb9\xd8\x06\xc9\x3c\x5d\x94\x4d\x4e\x9c\x05\xc7\x58\x3a\xe5\x9a\xd1\x04\xfc\xbe\x96\xc9\xc8\x57\x10\x83\x75\xc1\x06\xb2\xe9\xb5\xe4\xd2\x1a\x99\xd4\xf0\x0f\xbf\x9a\x64\x54\x2f\x15\x99\x77\x50\xfa\xe2\x56\xc0\x4a\x4c\xdb\xa7\x6d\xf9\xf5\xee\x46\x9e\x04\x21\x36\xe6\x51\xcb\xbd\xfa\x78\xe8\xe2\x91\x57\x33\x77\x37\x52\xe4\x9c\xcf\xf1\xe9\xb9\x6b\x44\x7c\x8a\x7d\xc0\xdf\xcb\x22\xea\x27\xc8\xf5\xdc\xf4\x25\x69\x0d\xbf\x0f\x79\x9f\x2b\x77\x8f\xd6\x70\x6b\xdb\x75\x47\x17\x28\x68\x0d\xb7\x37\x2f\x8f\x7b\x5b\x8f\x6e\x5d\xc6\x6e\x5d\xc6\xfe\x62\x2e\x63\xd8\xcf\x5c\x38\x96\xde\x94\xa3\x79\x28\xe6\xaa\x70\x5c\xe5\x57\xeb\x0e\xc6\xf2\xc8\x7d\xb7\x98\x94\xc3\x90\x59\x09\x09\x8f\x42\x8d\x16\xb5\xe0\xec\x95\x72\x13\x62\x6c\x56\xd6\x4a\x0c\xcf\x30\xd8\x19\x7a\xde\x6e\xbc\x7d\xb3\xc7\x77\x83\x6b\xf5\x81\x27\x41\x03\x8e\x4c\xe1\x66\x6a\x95\x93\xb7\x6f\xf6\xc4\x91\x47\xa8\x0f\x22\x18\x01\x44\xf8\xd4\x8d\x4f\xf3\xd2\x38\xdc\x73\xdb\xdf\x3b\x78\xfd\xfa\xc5\xde\xfb\xfd\x83\xd7\xe4\xc5\xdb\xb7\x07\x6f\x87\x64\x4f\x19\xb0\x47\xbc\x4e\x6e\x5c\x88\x29\x69\xaf\x13\x56\x21\x59\x6f\xf7\x43\xdd\xd0\x71\x93\x1a\x63\x40\x45\x5a\xe0\x26\x8d\x8a\x2d\xaa\x84\xd7\x16\x6a\x45\x3a\x2c\x0f\x89\xed\x80\x8d\x07\x0b\x37\x0b\x69\x59\x46\x13\x4a\x76\xc8\xda\x9a\xb8\x3e\xca\xa4\x02\xf1\xbb\xcf\xf3\x44\x3b\x6f\xfa\xb2\xd8\x53\xe2\x7d\x3d\x24\x6a\xde\xfe\xf6\xee\xe0\x35\x4c\x4f\xa1\xfa\xe4\xc9\xaa\x2c\x3a\xe7\xde\x04\xd4\x78\x10\x75\xdb\x23\xd6\xf3\xfa\x9e\x9f\xd2\xe3\x31\xcf\xca\xc6\x93\xfb\x7e\xff\xd5\x8b\x83\xc3\xf7\x43\x22\x0e\xfb\x19\xa5\xb1\x8e\xce\x4a\xb2\x4e\xda\xec\x9f\x68\x34\x65\xcc\xa4\xed\x64\x92\x12\x31\x4e\xbf\xbf\xdd\xda\x6e\xb7\xb6\xbf\xd8\xd6\x86\x77\x36\xb8\x48\xfb\x8d\xbb\x42\xaf\x10\xcf\xa0\x59\x24\x85\x9b\x8d\x66\xa0\xe2\x57\x31\xe6\xa0\xb4\x40\x9c\x1c\xad\x34\x34\x1c\x71\x91\x1a\xda\xc3\x3a\x88\xed\xf1\xfd\xe5\xa3\x21\xcc\xa5\xbb\x34\x3a\x08\x30\x00\x78\xfe\x17\x52\x73\xf9\xbc\xcc\xb3\xee\xd2\x48\x0a\xe8\x6b\x96\x67\x17\xb3\x7c\xa1\x1a\x55\x2f\x6a\x74\x44\x89\xbf\x09\x95\x68\xa3\x31\x17\x25\x20\xdd\x87\x27\x6f\x9a\x7c\xab\x74\xc0\x67\x79\x9e\x5e\x42\x42\xe5\x18\x02\xef\xf3\x5d\x85\x72\xd0\x18\xcd\x15\x5c\xdd\xa1\xb1\x99\x2c\x40\x2a\x96\x90\xb0\x83\x2d\x5a\x59\xff\xe0\xee\x1d\x63\xd6\x70\x94\x37\x06\x63\xc6\x24\xe3\x55\x3b\x19\x4b\xd0\x54\xb8\x27\x3c\x89\x4f\xce\x48\xfa\xa2\x2e\x38\xae\x11\xbf\x43\xce\xc4\x81\x1a\x90\x7f\x78\xed\xf9\x38\x46\x3e\xa7\xdc\x98\xc7\xbc\x87\x98\x58\x0e\xea\x63\x1d\x10\xff\xae\x37\x5b\x97\xbf\x8e\x1a\x44\xa2\x1a\x6b\x83\x4d\x71\x22\x75\xe3\xf2\x77\x34\x29\xaf\x36\x4e\x58\xc5\xde\x41\x56\x22\x96\x7f\xdd\x08\x8d\xd2\x4b\xe8\x64\xb5\xb1\xc9\x4c\x02\x57\x1e\x58\x99\x4c\xb2\xa8\x5a\x14\xee\xc0\x8c\x2f\xa1\x91\x19\x40\x35\x23\x53\x70\xb5\x43\x83\xe8\x16\xab\x8d\x44\xdc\x3f\x91\x6b\x40\x70\xb1\x28\x8b\x95\xdd\xab\xca\x21\x5d\xf9\x38\xc9\xa2\x34\xe4\x6f\xce\x6b\xf1\xba\xed\x1a\x4c\xc0\xfa\x26\x9a\x30\x11\x24\x3f\xd2\x53\x5a\x5c\x54\x53\x6e\x74\x9f\x9d\x24\xc0\x61\x72\x9e\x4a\x1e\x3a\x28\x32\x92\x2c\xc1\x9c\x27\xae\x8c\xe8\x92\x1b\x69\x51\x71\x02\xf5\x0b\xdf\xec\xbc\x0d\x3f\xa3\xc3\xcf\xa8\x28\x2f\x28\xac\xcb\xd2\xc8\x34\xd2\x14\xbb\x66\xed\x5f\x9e\xee\x8a\x06\xf8\x45\x66\x11\xf9\x92\x07\x97\x95\x0b\xa1\xd3\xf5\x5a\x61\xc5\xc4\xbd\x97\xfd\xbb\xf6\x8e\x80\x73\xbf\xd4\x6f\x07\x10\x63\x5c\xe4\xdf\x17\x35\x1c\x25\x90\xf6\xcd\xf6\x91\x10\x50\x78\x3e\x19\x2d\xe9\xd7\xd9\x22\x4d\x43\x57\x92\x90\x09\x94\xf8\x7c\x22\x4c\x7b\x36\xd4\x19\xcc\xbd\x0a\x5f\xad\x41\x9d\xd6\x39\x41\x88\xa9\x70\xae\x33\x75\xf8\x26\xd8\x23\xa7\x8e\x33\x41\xd7\xcd\x92\xb9\x52\x85\x30\x80\xe5\x84\x68\xd2\xcd\x28\xcf\x46\x51\xd5\x31\xa8\xa1\xbb\x24\x38\x52\x98\x49\x8a\xd0\x48\x61\x26\xe9\x6e\xdd\x34\xc8\x10\x63\x71\xa4\xe2\x72\x3c\xc1\x3e\x84\xe3\x15\x28\x27\xbc\x9e\x58\x35\x7d\xef\x1e\x18\x41\xcc\x9e\x2c\xdb\xf4\x6b\x02\x3b\x71\x7c\xdc\x6c\x68\xa7\xa8\x98\x58\xcb\x4f\x4b\xaa\x4f\x8d\xb2\x43\xfc\x24\xc2\x3e\x6d\xe2\x80\x3a\x62\x9c\xe2\x74\x49\x55\x6c\xdf\xba\xe3\xd3\x4b\x3e\x29\x31\x10\x57\xb8\xd5\x7d\xc2\x56\xee\xef\x79\x92\x75\x5a\x2d\x4f\xed\xea\xa2\x23\x27\x42\x8e\x2e\x7c\x68\x03\xe2\x67\x87\x31\x82\x6e\x0f\x77\xc9\x3c\x87\xca\xf2\x6a\xdf\xe8\xae\xc2\xa4\x2f\xa0\x95\x86\x6e\xd8\x3c\x5c\x27\xe9\xf6\xac\x66\xcc\x2e\xa8\xfd\x07\xf1\xf9\x7c\x51\xcd\x17\xd5\xaf\xf9\x44\x33\x78\x19\xe4\x09\x2d\x23\x19\x57\x8a\x47\x2d\x42\x02\x9f\x05\xa7\x99\x3b\x0c\xcc\x8d\x3a\xc6\xa1\xf8\x59\x9e\xc1\x7b\x0b\x1a\x2f\x46\x14\xcd\x5a\x34\x1a\xf5\x88\x88\x99\x6a\xb0\x9c\x68\x34\x3a\x12\xef\x39\xf7\x64\xb8\x11\xcf\x92\xf0\x9f\x9a\x93\xd7\x2f\xa7\xc9\xb8\xea\x74\xc9\xd0\x41\xac\xfc\xe4\x5a\xd6\xa2\xd1\x48\x99\xd2\x84\xc3\xbd\x20\x76\x9a\xd2\x8a\xca\xc1\xa0\x50\x5c\xe6\x07\x4e\x65\x57\x66\x2a\xe8\x8c\x4e\xdc\xff\x11\x0b\x9f\xc9\x0b\x5c\x3c\xac\x8b\xbf\x71\x73\x82\x96\xd1\xfa\x32\x69\xca\x13\xe2\xc3\x16\xa7\xfe\x1d\xc2\x7f\x6d\x35\x09\xff\x55\x57\xc1\x66\x8d\xef\xa2\x55\x05\x31\x24\x4b\x33\x50\x88\x47\x82\xb1\xe3\x8c\x39\xd2\xea\xb7\x17\x70\x2c\x4c\xe4\xf8\x5e\x46\xa3\x8b\xab\xd6\x55\x45\xff\xad\xd5\x25\x44\xfa\xe5\x62\x9c\x31\x58\x53\x87\x0e\x32\x4c\xe9\xc2\x09\x8d\x1d\x21\x88\x63\x93\xaa\x7d\x10\x46\xe0\x34\x44\x27\x5e\xe0\x23\xb5\x49\xf0\xf6\x8f\x83\xa3\x30\xfd\x4a\x02\x27\xe2\x06\x52\xcd\x60\x6c\x75\x27\xe2\xcb\x42\xb4\x5d\x31\x2a\xdb\xe3\x46\x47\x0a\xd7\x0e\xd4\x3a\x08\x18\x56\x5f\x71\xaa\xf4\x18\x2e\x97\x64\xe4\x31\x92\xf1\x40\x2a\x92\xf7\x07\xcf\x0f\x86\xa4\xa0\xdc\xb1\xad\x47\xca\x5c\x78\x1b\xa9\xb3\x3c\xed\xbf\x14\x71\xbb\x5c\x1f\x0a\x26\x55\xbb\x24\x19\x1d\xd1\xb2\x8c\x8a\x0b\xb6\x88\x20\x5b\x7e\xc9\xe8\xaf\x0d\xb1\xb8\x21\x34\x3a\x39\xcb\x8b\x8f\x5c\x68\x9c\x2d\xd2\x2a\x99\xa7\x28\xef\x89\x95\x8a\x28\x10\x47\x6b\x70\x9f\x78\xfd\xea\xbf\x53\x6e\xf5\xbc\x16\xd3\xb1\x43\xf6\xc0\xf2\xd8\xd5\x0d\xd2\x98\xef\x34\x96\x12\xa4\x0a\xf6\x25\xb2\xbc\x41\x91\xd6\x58\x17\x8f\x5c\xe0\x63\xaf\x9a\x12\x02\xb6\x19\x2f\x71\xbd\x48\xcd\xce\x8a\x00\x62\xbe\xba\x96\x3a\x9b\x7a\x6b\xaa\x53\xd9\x74\x23\x62\x19\x38\x63\x73\x20\x3c\x6a\x3f\xff\xe2\x45\x0b\xff\xa4\x18\xa3\xf0\x81\x32\xfb\xe9\x73\xb4\x15\xe5\x4a\x5a\x59\xf9\x97\x7c\xc1\xd5\x96\x69\x7e\x4b\xa6\x3f\xa1\x75\xc3\xd6\x40\x9e\x91\x07\x09\x88\xe8\x74\x41\x17\xab\x8f\x5e\x95\xbc\x99\xf1\x13\xc3\x4d\x97\x9e\xf7\x0d\x96\xa5\x1f\x9e\x10\x05\x21\x39\x15\xfc\xfb\x44\xbd\x56\x6c\x89\xff\xd0\x1f\x10\x33\x92\x3f\x6d\xf9\x14\x92\xe6\x68\x17\x58\x87\xff\x73\xb4\x18\x21\xb0\x02\x1c\x3d\xc0\xc3\x5b\xc3\x6d\x08\x95\x85\x63\xe7\x33\x56\xfe\xc3\xed\xe9\xf0\xed\xe9\xf0\x5f\xec\x74\x58\x9c\x0c\x8b\xcb\xde\x7f\xb1\xfc\x97\x37\x1c\x3a\x5f\xa8\x19\xf7\xc9\x5e\x9e\x9d\x52\xc6\xac\x22\x91\xe7\x1c\x14\x71\xd0\x36\x20\x53\xb9\x4c\x8e\xc4\xa8\x3a\x4a\xcb\x9c\x44\x69\x9a\x9f\x95\xa0\x96\x71\x73\x22\xa3\x1b\xa8\x4a\x6a\x16\xaf\x92\x73\x1a\x5f\xf2\x8f\xf0\xde\x3a\xad\xe1\x13\xca\x7a\x5a\xe5\x76\x62\x73\x61\x62\x45\x9a\x6e\xc7\x34\xe4\x92\xcf\x9f\xe1\x04\x2b\x1f\x23\x0b\x6f\x5b\x59\x7e\xdb\x5d\xc7\x32\x21\x14\x48\x29\x73\x71\x93\x32\xef\x4a\x47\xd9\x43\xcd\xd6\xb8\x65\xe4\x60\x0c\xc6\xf2\x2e\x34\xb1\xe1\x56\x0c\xa0\x72\xbb\x30\xee\x34\x1b\x87\x63\x32\x6d\x99\x6e\x4c\xe8\x79\x4c\x8e\x65\x8c\x59\x1e\x71\xd9\xae\xc7\xb9\x3a\xb0\x10\x0a\x5e\x8f\x4d\xcb\x29\x2d\x92\x31\x04\x86\x29\xe8\x28\x62\x9c\x09\xe5\x80\xba\x77\x8f\xa4\xd1\x1f\x17\x24\xcd\xa3\x98\xc4\x17\x59\x34\x4b\x46\x24\xcf\x68\xc9\x9b\x13\x33\xa4\x5b\x12\x49\xed\x73\x6d\xb0\x00\x30\x79\xf1\x41\x36\xef\x82\xb1\xd9\x9b\xd0\xea\x40\xa9\xe9\x9e\xb8\xe5\x6c\x9a\x90\x38\xbc\x3c\x82\x04\x36\x6b\x88\x09\x92\x6a\x7a\xcd\x69\x8e\x7d\x70\x11\x3e\x59\x92\x10\xe5\x59\x02\xa9\x7f\x70\xff\x08\x18\x45\x4a\xca\xf5\xf8\xa1\xe7\xba\x1c\x57\x14\x16\x05\x15\x16\xd1\x1e\x1c\x5c\x8e\xf8\xfa\xe1\x0a\xfa\x94\x9e\x7b\xcd\x18\xda\xd8\x6b\xbd\xb0\xe3\xa8\x36\x28\x63\x98\x6b\x45\x9a\xfd\xf0\x11\x83\x75\x80\x21\xb3\xf2\x3f\xe5\x63\x80\xba\xc4\x22\xec\x92\xa1\x5c\x8f\x02\xcc\x27\x81\x79\x0f\x3e\x7c\x77\x28\xa1\xaf\x43\xab\xef\x3d\x17\x90\xad\x0e\x0d\xc6\x9e\x3c\x40\x55\x8e\x6b\xf2\x00\x44\x32\x23\xbb\x84\x8a\x8c\x7c\xec\x76\x83\x70\x52\x37\x5c\xe9\x00\xaf\xaf\xca\x75\xbd\x1d\xbc\x4a\x95\xa2\x94\x65\x3d\xc3\x9a\x15\xa7\xc8\x72\x0a\x14\xe9\xc1\xbc\xb3\x04\x90\x09\x69\x37\x8e\xf9\xfd\x15\x65\xeb\x8b\xb2\x98\x94\xb4\x2a\xc9\x62\x0e\x1f\x84\xf6\x03\x6c\x25\xa9\x68\xc1\x36\x9e\xfc\x54\x08\x6f\x22\x2a\x2f\x08\x05\xe8\x0e\xcb\xaf\xf9\xa4\xdc\xad\xde\x55\x51\x51\xdd\xbd\x63\x5b\x46\x4b\x9a\x8e\xf5\xdb\xb1\xe7\x46\xbb\xe4\xfc\x66\x4d\x46\xe2\x3e\x9a\x8e\xdd\x38\x51\xf2\x32\xe5\x84\x56\xdc\xe4\xc6\x4a\x5b\x37\x2a\xc1\xda\xa1\x47\x5b\xf2\x3e\x12\xa9\xfa\x5a\x9c\x85\xb5\xd3\xf7\xb2\x17\xf8\x32\xa1\x55\xc7\xba\xb6\x25\x5c\x46\x5d\xc5\x6a\x30\x20\x71\x9e\xb5\xc5\x0d\x61\xd6\x4d\x81\x40\xf0\x50\x85\x43\x7f\xf9\x52\x7a\x6f\x41\x20\x95\x7e\xbf\x4f\x7e\x5f\xf0\xa0\xd7\xac\x51\xc6\xa9\x5d\x9d\x3d\x74\x15\xb6\xee\x1a\xac\x13\x3e\x38\x19\x5b\x9c\x40\x0d\x26\xa0\xe2\xf2\xaf\x5e\xc5\x98\x3b\xce\x2e\xbd\x9d\xcb\x2f\x5f\x59\x7e\xb6\x46\x27\x1b\x05\x18\xfe\xd2\x34\x3d\xcf\xd3\x94\x93\x54\x88\x9e\x25\xcd\x6a\x48\x9b\x5e\x91\xb5\x06\x8c\xce\xd9\x2b\xe5\x07\x6d\xd0\x50\x1e\xa2\x22\x31\xcf\xb9\x3b\xd3\xd2\x19\x85\xd1\xa4\x1c\xb4\x6f\x5a\xbc\x17\xe1\x7c\xa4\x92\xaf\x64\x5a\x68\x4c\x35\x57\xa4\x18\xed\x30\x0e\x23\xd4\x26\xf8\xa7\xd6\x0b\x5d\xcb\x50\x16\xf2\x90\xd4\xf5\xd0\x74\x5d\xf2\xad\x35\x51\x40\xd7\xec\x78\xec\x8c\x45\xbd\xc9\xd3\x94\x31\x24\xd4\x21\x4e\x9a\x43\x5e\x86\x29\x89\x74\x46\xb3\x0a\x74\xde\x3e\xa3\x42\x18\x22\xda\x86\xe6\xe2\x1a\xc4\x11\xc7\x19\xd0\xe8\x7e\x7c\xdc\x53\x07\x72\xc6\xfb\x9e\x26\x50\xf1\x05\x07\xce\xe2\x16\x6e\xa0\x6a\xbe\xe1\xeb\x64\xa3\x0e\xf1\x5b\xc2\x5e\x8f\x38\x19\x73\xe4\x6a\xf4\x9c\x78\xf4\x84\x26\xb7\x57\x50\x18\x19\x38\xd1\xef\xf9\x2e\xb6\x02\x6f\xe4\x76\x78\x7c\xe0\x6c\xe0\x05\xdb\x24\x57\xb2\xea\x05\xad\x72\x61\x7b\x94\xdf\x00\x68\xf6\xc7\x70\xb2\x20\xc1\xbc\x0a\x61\x1f\x58\x2d\xc6\x6a\x39\xdb\x92\xad\x31\xb8\x83\x0d\xf3\x05\x06\x95\x74\xe0\xb9\x01\xa8\x96\x8e\x74\x46\x52\x5f\xc4\x86\xbd\x17\x04\xd0\xdc\xd1\xfd\x86\x4f\xd6\xd4\xef\x70\xef\xfb\x19\x3d\x13\x07\x6b\x18\x15\x38\x6c\x1d\xe7\xa5\x49\x6c\x86\x6e\x0c\xf0\xd0\x25\x5c\xa1\x33\x3a\xf1\x49\xd0\xa3\x93\x06\xec\x92\x08\xe6\x2d\x54\xd2\x1a\x8a\xb6\x22\xec\x7a\x18\x50\x4d\xe1\x40\x4f\x96\xd9\xce\x8d\x65\xcf\x68\x22\xf6\x85\xab\xc4\x51\x3e\x0a\x0a\xe7\x26\x4c\xb3\x99\xd3\x2c\x06\x7f\x41\x35\xe5\x51\x09\x16\xa0\xac\x64\x44\xab\x43\x0d\xe9\x9a\xf2\x31\x40\xb3\x52\x4c\x7e\xea\x72\xab\x8f\xea\xc0\x22\x8b\xca\x32\x99\x64\x70\x18\xe3\xf4\xd3\xa6\x30\x1f\xf7\xf6\x4e\x94\x92\xd7\x46\x27\x4b\xe7\xca\xdb\x92\xe9\x79\x87\xc6\xa3\xfd\xba\x49\x8a\xe5\xcd\x28\x2d\x68\x14\x5f\xe8\x40\x06\x5a\xf4\x2c\x6f\x82\xf4\x4c\xe9\x58\x8a\xc4\xcb\x47\x97\x8c\x3b\x56\x83\x2a\x36\xe1\x86\x27\x34\x9c\x5e\xb2\x9c\xdf\xfb\x63\x99\x32\xf9\xbc\xca\xc5\x10\x93\xd9\x8c\xc6\x49\x54\xd1\xf4\xc2\x69\x5a\xac\x81\x51\x63\x82\x37\xa5\x1b\x68\xa0\x13\x8a\x54\x12\x08\x9e\x66\x58\xe3\xc5\x06\xc1\x37\x2c\x3e\x30\x74\x90\x7d\xe6\xe4\xbd\x71\x84\x01\x93\x07\x72\x7f\x49\xdc\x21\x65\x25\x32\xf8\xa8\x31\x32\x6b\xea\xc4\x49\xb1\x67\x50\x08\xf9\xf8\x50\xfc\x72\xa5\x31\xe1\x8d\xbb\xc1\xd0\x1c\xf1\x23\x9f\x4b\xe9\xc3\x1c\xd1\xd2\x3d\x01\xc2\x0e\xcc\xf2\x53\x69\x8e\x25\x51\x79\x91\x8d\xb4\xb6\xe5\x95\xb3\x7c\xac\x7e\x91\xc1\x55\x7a\x03\x17\x48\x52\xb1\x31\xe7\xf2\x39\x7c\x59\x61\x95\xba\x1d\x05\xc3\x41\x2e\x5b\xfd\xb5\x38\xf5\xcb\x26\x5e\xe7\x1c\x55\xd6\x11\xfb\xad\x2d\x39\xe4\xaf\x3a\x18\x90\xfd\xb1\x66\xa5\x49\xa9\xee\x6f\x5e\x50\x11\xe0\x87\x24\x15\x41\x71\xe3\x74\xc1\xb3\x29\x05\x6f\x15\x81\x86\x2e\xe1\x6c\xb8\x24\x49\x65\x31\x62\xef\x56\xef\xae\x03\xb5\x12\xbd\xbb\x8e\x6f\x2a\x44\x9d\xf6\xf4\xe2\x0d\x1d\x72\x0f\xf9\xb8\xe1\x97\x8d\x07\x65\x09\xfc\x05\xb5\x1d\x22\xd3\x7c\x12\x6c\x9a\x58\x3c\xac\x46\x7f\x81\x6a\x86\x6c\x1f\x09\x85\x90\x0c\x25\x02\x32\x81\x3c\x3a\x86\x33\xbe\x15\xe8\xca\x09\x76\x26\x84\xfc\xfd\xe7\xfc\xc5\x50\xd0\x5c\xa7\xdb\xe7\x5b\xfa\x28\x92\xd1\x36\x21\x54\x0f\x8d\x09\x5b\xf9\xd3\x22\xcf\xf2\x45\xa9\x42\x6f\x0a\x67\x09\x26\x2f\xd8\xe1\xaf\x78\x35\x42\x86\x6e\x07\x1c\x9a\x21\x16\x49\xae\x1d\x1f\x9b\x90\x93\xc7\x2b\x91\x55\xd1\x60\x3a\xaf\x33\x85\x97\x8d\x38\xb7\x73\x32\xcc\xd1\xec\xcb\xcf\x58\x73\x2e\x7c\x79\xdc\xdb\xde\x68\x74\xf2\xdb\x5e\x94\xdc\xba\x3f\xaa\xda\xdc\x7a\xc2\xfb\x76\x7b\x12\x7c\x7b\x12\xfc\xef\x7f\x12\x8c\xee\x09\x23\x83\xfb\xd5\x2e\x0b\x0b\xe8\x55\x0e\x70\x03\x29\x1a\x9b\x5f\x30\xce\xc6\xc9\xc4\x0b\xc8\x3f\x29\xc8\xfd\x93\xc8\xca\x9a\x94\x9c\x44\x99\x3f\x11\x12\xd8\xc1\x79\xc2\x37\xee\xa5\xce\xcf\x70\x4f\x92\x89\x08\x76\xe1\xb8\x87\x72\xb0\x67\xc9\xc4\x3a\x9f\x30\xdc\x44\xb9\xb5\xfc\x33\x07\xf9\xac\x80\x2f\xad\xa0\x69\xfa\x83\xe9\xfa\x0c\xe6\xd0\x40\x3b\x86\x70\xc5\xfb\xe8\xbf\x5e\x58\xe5\xaa\xb0\x84\x7b\x82\xed\x52\x49\xf9\xa6\xa0\xe2\x00\x18\x1d\xb8\x18\xf5\x9f\xe8\xf7\x76\x23\x47\x2a\x27\x44\x5b\xe8\xbc\xed\x5e\x9b\x46\x45\x9a\xf0\x97\xa3\x7c\x36\x4b\xaa\x8a\xc6\xed\x63\x75\x30\x6c\x54\xf7\xd3\x0e\xd9\x30\x3b\x94\xcd\x17\xd5\x73\x3a\x8e\x16\xa9\xf7\x04\x68\x69\xcf\xd8\x06\x7e\x82\x47\x82\x6f\x37\xf9\x53\x22\x31\xc2\xe9\xc7\xa8\x4d\x6f\xb4\xb3\xf0\xa1\x14\xee\x86\x3b\x98\xaf\x33\x0a\xe7\x42\x1e\x97\x6c\x58\x3d\x81\x39\x36\xda\xf5\x55\x89\xbe\x7b\x11\x22\x29\xec\x25\x3d\x5f\x82\x82\x17\xf3\x7c\x34\xad\x43\x01\xd5\x00\xa2\x27\x20\xb9\xea\xb7\xee\x25\x35\xfb\x63\x8b\x53\x62\xcb\x26\x51\xf9\x1e\x86\x00\x03\xf0\x74\x1f\xb7\xef\x78\x93\xf3\x2e\x97\xc8\x4d\x36\x1f\x93\xc8\x08\xc2\x19\x65\xb1\x3c\xce\x2e\xe1\xc0\x8a\xbb\x77\x30\x3e\xf2\xf2\xc5\x3f\x1c\xf6\x01\xb5\x30\x25\xc1\xcf\x38\xe4\x19\x8a\x11\x05\xdb\xbd\x39\x51\x2a\x7e\x21\xd9\x85\x5b\xaf\xcf\xe2\xac\x5d\x44\xf0\x01\x2d\x3a\x2d\x87\xc7\xcf\x9f\xad\x95\xb1\x3b\x82\x1c\x2b\x46\x0c\x41\x5c\xc2\x17\xac\x4e\xd6\x0c\x1d\x13\x31\xdb\xfc\xe7\xc3\x8e\x28\x88\xab\xaf\x72\x91\xee\x3e\xa9\xc8\x2c\x99\x4c\xb9\x0c\xad\x62\x8d\x0b\xb3\x9f\xdb\x7a\x95\x2f\x6d\xbb\xca\x9d\x96\x8f\xda\x93\xa8\x7c\x53\x24\x23\xda\xee\x11\xf6\x9b\xfd\x03\x13\xca\x7e\x64\x79\x36\xa2\xbe\x6b\xb3\x1f\xe9\x45\xdd\xc5\xd9\x8f\xf4\xa2\xf1\xd5\x59\xa8\xcb\xc5\x26\xaf\x63\x07\x39\xc7\x3c\xa7\xa3\x64\x16\xa5\x1d\x0c\xe0\xbd\xa3\x68\x1d\x79\x7f\x15\x02\x47\x31\x6d\xbf\x04\x9d\xfb\xaa\xff\x22\xe4\x7e\x65\x7a\xbe\x25\xe4\x3f\x91\x90\x85\x24\xe7\x50\x32\x1c\x6e\xcb\x34\x61\x82\x8c\x03\xf2\x5d\x73\x02\x3e\xb7\x64\x3a\xf1\x41\x53\x6c\xb8\x42\x83\x64\xab\xf3\xee\x27\x6d\x29\x3d\xef\x63\x11\x60\x4d\xda\x21\x90\x55\xd0\x84\x50\x41\x5d\x72\x89\x4e\x13\x40\x5f\x09\x62\x1f\x10\x52\xe0\xa2\x62\xa0\x01\x07\xcc\xdb\x8a\x0d\xa5\xcc\xa0\xe7\x7d\xa0\x33\x7f\x29\xf8\x84\x40\x27\x51\xe9\x07\x9c\x44\xa5\x09\x06\x54\x8d\x60\xb5\x94\x8b\xbe\xa3\x22\xd2\x79\xd1\x0b\x6f\x5c\xed\x96\x26\x88\xf3\x2b\x51\x97\x4c\x42\x75\x35\x2a\x13\x29\xb1\xea\x89\x4d\x67\x6d\x5b\x8d\xe2\xec\xca\xad\x68\x44\x46\x7a\x2d\x9d\x4e\x6b\x19\x09\xfa\xc0\xdc\x29\xf4\x40\x21\x62\x94\x5f\x9b\x50\x64\x10\x36\xdc\x68\x88\x36\x55\xaa\xa7\xc5\x6c\x91\x46\x55\x72\x4a\x7f\x89\xca\xc3\x12\x6e\x47\x86\xea\x72\x60\xed\xca\x26\x4b\xab\x98\xe8\x82\x0a\x03\xa6\xab\x88\x84\x4c\xf3\x89\xe3\xbe\xa9\xbf\xa0\x64\x55\x8e\xad\x0e\xec\x6d\x7e\x4b\x9d\xe7\x1e\x36\x03\x6e\x62\x96\x13\xcd\x35\x5e\x18\x30\xdb\xab\x2c\x05\xd0\x4e\xea\xa9\x1f\xea\x6c\x46\xfb\x66\x6d\xd8\xf1\x08\x2a\x41\x9e\x47\x83\x01\x51\x81\xb0\x20\x86\xa4\xd4\xfa\x09\xe1\x0d\xb2\x49\xfb\x35\x99\x25\x95\x67\x5e\x4d\x00\x89\x3b\xf5\x36\x40\x0d\xc6\x77\xb3\x50\x99\xfc\xe1\xe3\x97\xfa\xa3\x09\x5e\x25\x33\x5a\x56\xd1\x6c\x1e\x2c\xa3\x20\xd0\x9a\xe3\x5f\xb2\xe0\xba\x36\xbe\x87\x2a\xd6\x16\x05\xdc\xa1\x38\x19\x8f\x93\xd1\x22\x85\xeb\x3f\x2e\xc3\xb5\x81\xac\xd1\xe4\x55\x94\x3e\x6f\x52\x83\x05\x69\x0a\x5c\xe6\x82\x12\x05\x34\x1f\xb0\x96\x95\xfb\xdd\x95\x64\x92\x8a\xce\xec\x25\x95\x8c\x1d\xdf\x48\x00\xf3\x1c\x18\x1b\xab\xcf\x27\x07\xf0\x92\x4d\x96\xe1\x89\x30\x51\xb0\x45\xd8\x68\x09\xbe\x4b\x26\x19\x2d\x48\x9a\x94\xee\x45\xe7\xd5\x16\x1e\xaf\xa9\x0c\xad\x3f\xdb\x6e\x85\x8a\x84\xd7\xa1\x00\x40\x7a\xbf\x67\xf2\x24\x90\x9a\x36\xfc\x76\xd9\x64\x35\x98\x26\x81\x5a\x6e\x05\x3c\x80\xde\xcb\x44\x18\x78\x5e\xc4\x9c\x60\x33\x02\xee\x48\x63\xce\x98\xe6\x93\xc0\x4c\x60\xc6\xec\x9d\x87\x34\x9f\x20\x3b\xa1\x3b\x0b\xbc\x6e\x73\x22\x70\xa5\x18\xff\xf8\x40\x27\x19\xb3\x47\x63\x87\xd6\xe8\xb1\xbe\x78\x18\x82\x5d\xf6\x89\x51\xab\xb3\x05\x9b\x55\x37\xd8\xcc\xbd\xb5\x98\x8d\xa4\xf9\xc4\x57\xb9\x7c\x1d\xa8\x54\x95\xb2\x95\x0c\x7e\x56\xd5\x48\x53\x3e\x9b\x26\x25\xdb\xdc\xe6\x79\x59\x5d\x49\x55\x7e\x93\x97\x4b\xa4\x3e\x37\x23\xda\xb2\x4d\xd0\xad\x18\x4f\x3d\xeb\xaa\xb9\x03\xb2\x37\xfd\x79\x74\x01\x17\x60\x76\x0c\xf3\x18\xfe\x24\x91\x0e\xef\xaa\x2a\xf5\xaa\x71\xf2\xa3\x01\x7c\x96\x17\x1f\xdf\xe7\x6f\x8a\xfc\x94\x86\x0b\x21\x20\xa3\xf0\xbc\x48\xf2\x22\x41\x1b\x82\x53\x52\x42\x74\x71\x62\x8e\xb1\x91\x10\xce\x70\x66\xe7\xdc\x85\xf7\x94\x07\xee\x31\xf6\x04\xf4\x81\xec\x18\x4f\x4f\xc9\x11\x7a\x3c\x26\x43\xed\xdb\x71\x89\x9b\xe6\x27\x0a\xfc\x70\x21\x4d\xf3\x33\xb8\x07\xa4\xcc\x1b\x75\x4d\x2c\xb9\xa8\xc2\x93\xa0\x32\x02\x23\x79\x96\x5e\xf0\xdc\x2a\x95\x79\x85\x46\x5e\x62\xe1\x97\x55\x7c\x97\xb2\xe4\x4d\x16\x32\xb4\x6f\x5b\x19\x77\x58\x5c\xed\x9b\x75\xb4\x31\xa7\x53\xc7\x5e\xb0\x36\x84\x4f\x70\x80\xf7\x2d\x5d\x05\x0d\xf7\x9d\x7a\xa2\x57\x34\x0f\x08\xa7\xe7\xf3\xa4\xb8\xf0\xf0\x06\xf4\xd5\x20\xc4\x92\x07\x28\xf2\x82\xb3\x6f\xc1\xf5\x61\xc1\xfa\x56\x07\x90\xbd\x4f\x5a\xb4\x20\xba\x4f\xbc\xab\xf6\x6d\x74\x26\xe9\x48\xbc\xf1\xc3\xa1\x06\x76\xcb\x51\x92\x38\xeb\x5b\x95\xc2\xbb\xf1\xdf\x4a\x81\x41\x05\x89\xf2\x1d\xe9\x25\xa3\xdb\x80\xc8\xe2\x90\xb3\xd0\xcb\x40\x06\x83\x15\x97\x0b\xac\x5e\xbc\x5e\xc3\xcb\x15\x2f\xc8\xeb\xac\x34\xeb\xa8\x80\x63\x6b\x95\xe5\xa1\x18\xb1\x6d\xb7\xf3\x25\x27\x32\x4e\x7f\xc4\xbb\x7e\xb9\x38\xe1\x77\x08\x3b\x1b\xbd\x6d\xbe\x76\x5b\xe7\xf1\xa8\x65\x86\xaa\x52\xe1\xb0\x5a\x1b\xe7\x2d\xb2\x4e\xdc\xd2\xdb\x5d\x13\x25\xd0\x33\x7e\x48\x9a\xd1\x33\x38\x2f\xed\x58\x49\xfd\xe1\xf0\xe8\x24\xca\xfa\x49\xf9\xf7\x28\x4d\xe2\x0e\x24\xaa\x11\x6f\x9e\x27\x05\x1d\x55\x1d\xef\xc9\x91\x08\xa6\x07\x90\xa2\xce\x4e\xd7\x3d\x98\xc2\x32\x99\x4e\x3c\x26\x3b\xe1\xab\xd8\x8c\xe1\xe8\xa9\xaa\x49\x25\xa2\x77\x56\x5d\xc2\x54\x64\xfb\xf4\x88\xf8\xfe\x12\xba\xdd\x45\x51\x0b\x34\xc7\x79\x77\x91\x8d\x92\xcc\x2f\x64\x89\x88\xfa\x78\x6e\xd7\xac\x77\xc4\x13\xb6\xcb\x92\xfc\x21\xd2\x17\x78\x94\x26\xd9\x04\x04\x6b\xaf\x89\xc1\x05\xb3\x02\xa7\x89\x00\x66\x4b\x6a\xc0\x50\x56\x05\xd3\x64\x32\xa5\xe5\xb2\x0a\x30\x14\x26\x27\xf1\xf9\x63\x96\x9f\x65\xef\xaa\xa8\xa2\xde\xa0\x9b\xe8\x73\xb8\x09\x5c\xc7\x13\xa7\x8a\xf9\x22\x4d\x69\xbc\xac\x0e\x0c\x15\xb6\x7a\x18\x81\xd4\x42\x89\x3e\x96\x1d\x5c\x0f\x97\x42\xf4\x50\x45\x35\x35\x2c\x2b\xea\x3b\x6c\x1d\x86\x3f\xe1\xa2\xc6\xd1\xe1\xd0\xf3\x0e\x03\xfb\x94\xd8\x61\xf8\x13\x2e\x6a\x33\xc3\xa1\xff\x35\x2e\x62\xec\xe9\x43\xcf\x3b\x01\x1c\xf2\x98\x18\x06\xbf\x18\x05\xfd\x83\x0a\x7f\x0b\x15\xb6\x8d\xad\x9e\x3a\x6c\x10\x73\x00\x86\x42\x3e\xf4\xbe\x75\x0b\xd8\xba\xf6\xb0\xee\xa3\x51\x1c\x6b\x88\x43\xcf\x3b\x03\xd8\x9a\x0b\xcf\x4b\x03\xdc\x66\x8e\xc3\xc0\x7b\xcd\x58\x0d\xa7\x3e\x7e\x2c\xd7\x1a\x6e\x3e\x0e\xc5\xf4\x62\xfb\x4c\x6b\xb8\xbd\x7d\x79\xdc\xdb\xde\xbc\x8d\xee\x72\xeb\xd3\xf7\x17\xf6\xe9\x13\xb4\x7f\x63\x79\xad\x56\x4c\xeb\xd1\xd4\x91\x8f\x67\xdf\x32\x1d\xf4\xf8\xbb\x2f\x93\x21\x64\x95\x8c\x1e\x51\x9a\x0e\xac\x9c\xbc\x70\xcd\xdc\x4e\xb2\xe5\xcb\xf3\x21\x6f\x2d\xb8\x39\x07\xeb\xf2\x7b\x78\x93\x0e\x7e\xe0\x5b\xa9\x48\x39\x81\xd3\x7a\x5f\x29\x17\x84\xae\x57\xec\x44\xb8\x62\xfe\xea\xda\x35\x43\x2e\xcf\x08\xf4\x63\xa8\x56\x3e\x1b\x40\x32\xf3\xb7\x80\x11\x8f\x06\xc8\x0d\xa5\x28\xe1\xdb\x89\x3d\x35\x46\x14\x59\x70\xbc\xd0\xf7\x0c\xb1\x4e\x56\x4c\x4c\x85\xec\x2a\x49\xee\xa5\xda\xa2\x13\x76\x42\x38\x14\xd8\x17\xf8\x75\xb8\x62\x52\xf2\x1c\x24\x6b\x4a\xfa\x6c\xda\x6d\x2c\x4a\xd6\x77\x1d\x77\xf2\x27\x87\xba\xe4\x17\x9c\x84\x54\x5c\xcc\x75\x87\x18\x18\xa1\x1d\xbc\xa3\x46\xcc\xed\x68\x6c\xac\x80\x8e\xda\x2c\xa3\x38\xd7\xba\x2f\x45\x5e\x52\x92\x51\x5e\x14\xbe\x40\xaf\xa0\xdd\x45\x15\xdd\x2d\x26\x66\x76\x19\x95\x1f\x46\x54\xc2\x3f\x82\x7e\x58\x92\x4f\xa0\x1d\x5e\xb2\x36\x93\x4a\xdc\x28\xb2\x82\xc1\x7a\xe6\x0d\xb7\x15\x9e\x30\x6d\x32\xe0\x60\x80\x2e\xc7\x49\x27\x42\xb3\x30\x18\xc8\xab\x64\x60\x7d\x33\x02\x1f\xc1\xae\x0b\xb1\x3c\x75\xc2\x40\xb6\x49\x47\x70\x5d\xb5\x88\x2e\xd4\xad\x4b\x31\x93\x6b\x1d\x27\x47\x6d\xd4\x55\x19\x08\xba\xe4\xde\x3d\xf7\x70\xcb\x3a\xb1\x11\xf0\x3c\x52\x78\x7d\x01\x7d\xa8\x67\x14\xb2\x4b\x38\x57\xc2\xc1\x34\x21\x91\x24\x89\x73\x6d\x67\x27\x44\xdc\xd6\x65\x3a\xa6\xe4\x8b\x04\x90\x35\x09\x1a\x3b\xfe\x48\x1a\x75\x51\xb4\xa5\xf5\x0b\xfc\xc4\x0c\xda\x31\x93\xcd\xe4\x6f\x38\xa0\x8f\xe4\x9c\x8d\x06\x85\xd7\x0f\x44\xd4\x8e\x52\xd5\x32\x72\xa0\xab\xa7\x46\xd5\x87\x7a\x52\x34\x72\x26\x5f\x81\xa5\xac\xcc\x51\xcc\x3c\xc7\xa1\x54\xca\x97\x88\xf9\xe3\x75\xd5\xf1\x25\x35\xae\xf2\x40\x16\x10\x23\xeb\xf1\x0e\x09\x24\xf8\xf0\xe5\x85\x10\x17\xa8\xd0\x98\xcd\x7c\xca\x4b\x3c\xd5\x02\x89\xb0\xe4\x34\x5c\x39\x9b\x8f\xbf\x86\x7a\x42\xb8\x5a\x4e\x1f\x91\x4c\x60\xa3\x47\x1e\x63\x9b\x58\x4d\x3b\x8b\x6c\x1e\x8d\x3e\xf2\xc3\x55\xd3\x51\x13\x5e\x99\x16\x32\xeb\x9d\xee\x88\x13\xb3\x4c\xd6\xc7\x7f\x28\x9a\xdc\x21\x5b\xe4\xa9\x7c\x29\x13\x1f\x10\xa9\x7b\xa2\x60\x18\x2a\x59\x41\x28\xef\x01\x16\x98\x7a\xa2\xbc\x35\xcd\xc2\x9c\x84\xe3\xb2\xab\x8c\x9c\x47\x1b\xc7\x64\x18\x0a\xc7\xbf\x07\xd9\xee\x23\xed\x03\xaa\x04\x78\x67\xe6\xd9\x7e\x67\xb0\x80\x7e\xbf\x2f\xb9\xc0\x9e\x5d\xdc\xde\xb7\x9c\xb8\x52\xfb\x7c\xb7\x84\xa4\xe5\x12\x96\x6d\x64\x91\xaa\xa2\xc7\xa3\x05\xd9\x35\x8b\x38\x8c\x70\x6b\x56\xaa\x79\x91\x71\x8f\x31\xca\x62\x33\xd0\x90\x04\xe3\x09\xff\x85\x26\xc6\x2a\xe1\x49\x4d\x19\xbc\x40\xa0\x9f\xa8\xc5\x14\x43\x4a\xf2\xe5\xe4\x0c\x3d\x0b\xa6\x80\x5f\x25\xbd\xbb\x7f\xd7\x95\x32\x9d\xe5\x03\xab\xf7\x26\x50\x99\xb4\x48\x29\x62\xa0\x1b\x92\xa6\xc1\xa5\x20\x98\xbb\x29\xcb\xe1\x32\x58\x94\x72\xca\xe9\xd3\x16\x1e\x7d\x5d\xf2\x74\x05\x88\x9d\x62\xd6\xbc\x57\xcb\xb5\x15\x5b\x31\x49\x5a\x4d\x39\x2e\x44\xf5\x3d\xa3\x7f\x9e\xcb\xa2\x50\x0c\xaf\xef\x8e\xb9\x4c\x8c\xc4\x02\xee\xbd\xef\x26\xad\xf6\xdc\x78\x50\x1e\x1e\x81\xa2\x41\xc9\xeb\x3d\x46\x1c\x90\x1e\xf7\x73\x7a\x62\x47\x08\xe7\x7d\xa7\xb1\x9b\x35\xa1\x2a\x2e\xec\x3b\xaf\x08\x18\xae\xb9\xd6\x0c\x9c\x98\x77\x73\x47\x10\x48\xa1\xe3\x06\x74\xe2\x2b\x61\x87\xd0\x50\x3c\x29\x7b\x18\xb2\x0f\x86\x64\xb4\x6c\x8f\x69\xa2\xd5\xba\x3b\x8e\x59\xa8\xc1\x7e\x62\xb5\xf2\xef\xb6\x16\x1b\xac\x29\x49\x6a\x02\x54\xb8\x17\xff\x44\x36\x40\x89\x32\xf4\x5c\x8f\xe4\x89\xf3\x1e\x47\x19\x0f\x46\x90\xc5\x22\xc0\x2a\xa4\xb0\xce\x1e\x48\x2d\xd9\xcd\xe8\xbd\x7c\x45\x1b\x49\x28\xd9\xaa\xb2\x66\xa4\x63\x9d\xc4\xaa\x2a\x97\x96\x58\x2d\xe9\x06\x2d\xab\x64\x16\x55\xf4\x97\x08\x8c\x9d\xcb\x49\x0d\x15\x58\x4e\x66\xb8\xf6\x1b\x21\xb1\xaf\x43\x32\x0d\xa7\x0c\x8d\xae\xc1\x74\x79\xa0\xeb\xa6\xea\xad\x6c\x8d\xca\xe4\x85\x90\x46\x49\xda\x2f\xa5\xa4\x61\xcc\xcd\x84\x56\xcf\x9d\x8c\x61\x72\x87\xb6\x6b\x5a\x3e\x7b\xa2\xba\x1b\x9f\xb9\x86\x33\x21\xcf\xea\xc5\xfa\x15\xb9\x95\x56\x92\xd1\xaf\x97\x32\x15\x97\x96\x78\xc7\xeb\xa2\x1e\x7b\x7f\x42\xfe\x54\xd5\xc8\x55\x53\xa8\xaa\x72\xab\x0f\xf7\x8b\xe7\x53\xd5\xb6\x24\x36\xd4\x62\x3e\x92\xd1\xe5\x4a\xae\xc9\x2f\x67\x5d\x02\xbe\xd6\x43\xa9\x66\x84\xa2\xf8\xb7\xcf\xc8\x88\x91\xf1\x49\xc2\x61\x09\xc8\xcc\x56\x64\x4c\x91\x27\x4e\xa3\x65\x38\x7e\x0a\x41\xa4\x3f\xb0\x6e\xb7\xc9\x90\x3f\x58\x7b\x51\xbb\xe7\x4a\x45\x43\x1d\x1a\x51\x7f\x54\xa1\x1d\xc5\xa0\x8e\xd1\x37\xde\x7d\x19\x74\x58\xf0\xd5\x46\x04\x22\x53\x34\x85\x37\x31\x9d\x1b\x6d\xc9\x06\xe6\xc9\x61\x66\xcc\x79\x65\x08\x51\x6b\x26\xaa\xb0\x9b\x16\x88\x0f\x95\x21\xa3\xc9\x50\x36\xfa\x65\x70\xbf\xb1\xf0\xdb\x8f\xe6\xf3\xf4\x42\x84\xdf\x6a\x44\x6f\xce\xc6\x24\x42\x0e\x1b\x73\xaf\x02\x62\x5d\xad\xfe\xe5\x13\x23\x52\x7c\x69\x3e\xa5\xb3\x7c\x39\x73\x74\xa5\xf4\x5e\x9e\x29\xfc\x72\x19\xbe\xe4\x07\xcd\x18\x70\x18\xb2\x30\xbc\xd0\x7e\x35\xb6\x83\x90\xae\x98\xee\xa5\x86\x60\x79\x53\xfe\xe2\xa3\xd1\xaf\xc2\xe5\xf4\xce\x2f\x43\x66\xb1\xc7\x7f\xdf\x1c\x67\xb2\x34\x50\x7d\x52\x8c\x16\x69\x54\xac\xad\xad\xad\x2d\xcd\x6c\x26\xe9\xe9\xc9\xdd\x9b\x49\x6d\xc6\x0d\xda\xad\xe1\xd6\x23\x7f\xf8\xa3\xad\x5b\xd7\x88\x5b\xd7\x88\xbf\x98\x6b\x84\x70\x8b\x60\xd0\x32\x09\x5d\x28\xfd\xcd\x9f\x99\xd7\x26\xe0\x78\xb1\xc4\x4b\x02\xd2\xf2\x9d\xe5\xc5\xc7\xa8\x60\xf4\xcd\x76\xbc\x45\x69\x0e\x96\x91\x60\x9c\x8c\xc7\xb4\xa0\x59\x45\x68\x76\x5a\x8a\x62\x27\x45\x7e\x56\xd2\xe2\xee\x1d\x14\x82\xf7\x2c\xc9\xe2\xfc\x0c\x6c\x29\x28\x2d\x0c\xb9\x77\x4f\x7c\xe9\xff\xe3\xd5\xaf\x2f\xab\x6a\x2e\xa2\x3d\x0b\xde\x6a\xbe\x24\x3b\x7e\x60\x60\x8f\x22\x8f\x49\x32\xc9\x72\xc6\x23\xd2\x24\xa3\xd0\x99\x0c\x72\x54\xe3\x60\x7c\x4e\xa5\x0a\x03\xe7\xb3\x94\x0d\x50\x6c\x84\xed\x6e\xe3\x76\x2e\x25\x56\xff\xf1\xf2\xed\x96\x51\xe3\xb4\xd8\x6a\x77\xc3\x05\xb5\xd8\xc1\xda\x79\x23\x31\xeb\x7a\x8e\x80\x18\xc6\x94\x07\x88\x66\xcb\x63\xe7\xb3\xbe\x22\x3f\x11\xa3\x06\x2c\x2c\x4c\xf3\xb2\xea\x91\x2a\x99\xd1\x7c\x51\xf5\x58\x95\x45\x0f\x0c\xe6\x67\x79\x21\x03\xfe\xc0\xe6\xc3\x00\xc9\x0e\x81\x7f\x3e\x7f\x26\x6d\xb1\x10\xd2\x7c\x14\xa5\xec\xe5\xf0\xf1\x77\x0f\xbf\xe3\xe9\xb2\xf9\x66\xc5\xab\x64\xdb\xa7\xf8\xf5\xf9\x33\xc4\x5c\x12\xdf\x59\x4b\x64\x07\x1a\xd4\x2f\x65\xc3\x64\x47\xf5\xa1\x91\x0c\x36\x2f\xe8\x1c\x92\x47\xd2\x33\x6b\x0a\x1d\x11\x4c\x80\xbe\xc5\x7a\x93\x10\xc0\x9e\xe5\x79\x4a\xa3\xec\x12\x4e\x9c\xd9\xe6\x2e\x85\x20\x8d\x72\x19\x33\x15\xe9\x99\x66\x7b\x56\x30\x2d\x8c\x77\x24\xbf\x99\x9d\x30\x0f\x42\x59\x0b\x02\xf1\xfc\x98\x88\xd3\x17\x67\x78\x70\x04\x8a\x20\x08\xd1\x82\x1a\x0c\xfe\xe5\xdb\x2d\x94\xb3\x9a\x0b\x6d\x68\x2a\xd0\xcc\xf0\x1b\x85\x46\x20\x4a\xab\x2e\x63\x60\x1d\x75\x05\xf1\xee\x1d\x5d\x75\x3e\xa7\x59\xa7\xfd\xe6\xe0\xdd\x7b\x99\x48\x97\x13\x14\xef\xe3\x13\xd9\x65\x3d\xe3\xf7\xee\x99\x33\x6d\x2a\x9b\x0b\x70\x48\x6a\x3f\x8b\xca\x64\x44\xda\x64\x1d\xfa\xf1\x6c\xc1\xf8\x08\xaa\x63\x9d\xb4\x87\xea\xbc\x54\x55\xd4\xaf\x72\x71\xc9\xb2\x7d\x12\x95\xf4\xd1\xc3\xb6\x8d\x07\x1d\x30\xfe\x25\x8d\x62\x5a\x74\xda\xbb\xc0\x8a\x93\x3f\x22\xae\xe0\x41\x07\xc4\x38\x6b\x4a\x31\xa9\x9b\x66\xd5\x03\xa6\xec\xb7\x7b\xa4\xcd\x14\x8b\x64\x04\x75\x0c\x7e\x2f\x95\xcd\x54\x9d\xd1\xc9\x09\x5c\x4e\xc7\x3c\x61\xd1\x45\x36\xc2\x7a\xbd\x63\x15\xf7\x1e\xc8\xcf\xf1\xc1\xbe\x3f\xb3\x7e\x3d\x4d\x96\x76\x6e\x54\x69\xfe\x73\x68\x51\x12\x92\x49\xc5\x22\x43\xbb\x20\x54\x74\x7c\xa1\x11\x99\xc5\x1d\xb8\x9c\xc3\xaf\x86\x24\xe3\x0b\xd5\x86\x44\xba\x3c\xa8\x30\x82\xc2\xfb\xfc\x26\xf6\xf2\x2c\xa3\xe2\xf6\x8c\x24\x3b\x83\x42\x8d\x23\x56\xd9\x05\x99\xe0\xe5\x3d\x3d\xaf\x7c\x1d\x15\xe0\xe8\x06\x91\xb8\x31\x61\x75\xaf\xb6\x6b\x6f\x45\x23\x1d\x5f\xab\xd6\x2a\x5a\x2d\x65\x3a\x90\x47\xb4\x94\x3e\x76\x35\x93\xaa\x23\x12\xf1\xed\x67\x27\xe7\x0f\xa9\x8a\x64\x32\xa1\x05\x4f\x68\xc6\xc8\x02\x24\x22\x15\xf1\x97\x21\x64\x39\x2d\x41\x2f\x7c\x04\x65\xe5\x47\x6f\x42\x5a\xe0\x02\xf4\xc4\x62\x3d\x19\x44\x74\x2f\xab\xa8\xa2\xa3\x69\x94\x4d\x02\x16\x0d\x7e\xfd\x43\xce\x44\x14\x5f\xc0\xb5\x0b\x38\x2c\x7f\xc8\xd8\x91\xcd\x25\xd7\xac\xec\xe6\x4d\x08\x49\x43\xca\x03\x35\x23\x85\x9d\x73\x9a\xb7\x8c\xd2\x40\x1f\xf4\x9f\xda\xa9\x13\xbb\x55\x69\x8e\x98\x47\x7b\xf6\xc1\x9e\xd9\x3c\x28\xa3\x97\x0e\xc6\xf5\x4e\xe2\x41\xb4\x59\x63\xd9\xd7\x4b\xf4\x3d\x2f\xd6\xc1\xdb\x8f\x5c\xf2\x5f\x80\x5f\xd8\x1d\xa9\x63\x19\x6a\x3d\x5a\x6b\x4f\x3b\x16\xa4\x17\x6c\x3d\xf0\x8b\xd4\xb0\x00\x19\xcd\x07\xd7\x5f\x52\x8a\x66\xa8\xc5\x8a\x95\x70\x21\x8d\xb4\xb6\x90\xc1\xd4\x97\xac\x5d\x91\x71\x94\xa4\x34\xee\x93\x03\xa6\x2e\x9e\x25\x4c\xf9\x89\x78\xaa\xc2\x9a\x05\x87\x9a\xf5\x4d\x0e\xc2\xae\x32\xb6\xe8\xec\x35\x49\x3c\x24\x3f\xa8\x3f\x65\xad\x64\x5b\x59\x31\x1f\x0d\x49\x7b\xab\xbf\xa1\xad\x9f\xd2\x82\xda\xce\x68\xf5\x21\x4d\xca\x8a\x66\x10\x7f\x53\x7e\x57\xe6\xcf\xe3\xbb\xa6\xef\x9c\x34\xc8\x15\x22\x05\xa3\x87\xc0\xa5\x57\x27\x1b\xb0\x39\x31\x8e\x35\x03\x23\x42\x5b\x32\x0c\x63\x04\x13\xb0\x5b\xc3\xc7\xec\x97\x21\xbc\xb7\x86\x9b\xdf\x5f\x1e\xf7\xb6\xb7\x6f\x0d\x13\xb7\x86\x89\xbf\x9a\x61\x02\x5d\xda\x80\x7b\xb2\x37\x79\x61\x43\x79\xd5\x62\x35\xf7\x24\x99\x70\xdf\xe8\xfe\xef\xd2\x7c\xc0\x4f\x7c\xe2\x5f\xe9\xd8\xdc\x4a\x54\xe6\xda\x0b\x7c\x41\xd3\xd8\x80\x39\x88\xe0\x28\x67\x53\x36\x8c\x8e\xe9\x05\xf7\x23\x2f\x4e\xee\x93\x2d\xcf\x1d\x4f\xf0\xb6\x64\xca\x83\x7d\xe1\x95\x04\x6f\x5e\xca\x3d\xe1\x8d\x50\x32\xa3\x8c\xec\x3f\xdb\x7d\x2d\xa6\x3e\x26\x3f\x7c\x4f\x46\xf9\x6c\xbe\x10\x79\x9c\x4e\x2e\xc8\x2c\x3f\x4d\xb2\x09\xca\x73\xf8\x90\x8c\xa6\x51\x01\x5b\x08\x3f\xb2\x8e\xb9\xb7\x9a\xbc\x62\x20\xa1\x53\xca\x2f\x9e\x54\x39\xb4\xc8\xf1\x56\x92\xce\x2e\xd9\x21\x9b\x1b\x3d\xf2\x8c\xfd\xbb\xd9\x23\xfd\x7e\xbf\x47\xfe\x97\xec\x90\xed\xef\xba\x4c\xd9\x22\xe5\x9c\x8e\x92\x71\xc2\x97\xd8\xfe\xbb\x83\xcd\xed\x47\x9b\x8f\x5c\x5f\xbe\xa4\xcc\xe1\x8b\x18\xca\x5d\x37\x6c\xf4\x25\xbf\x9c\xcd\x3a\xc3\x06\x69\x9d\x2b\xe2\x73\x77\x21\xa2\xc5\x0a\x4e\xc6\xff\x30\xdb\x30\x26\x98\xd5\x6d\xcc\x2b\x1b\x58\x7b\xb7\xdd\x67\xe8\xd9\xcb\x63\xba\x5b\x75\x36\xb0\x21\x9e\x8d\xb1\xfd\xbf\xee\x77\xc1\x28\xf9\x3d\x72\xa0\xe3\x2a\x3f\x9c\xcf\x69\xb1\x17\x95\xc8\x3e\x8f\xbe\xf3\x1b\xe9\x9d\x87\x5d\x79\x41\x5c\xbc\xd8\xe8\x3d\x74\xce\x0b\xf9\xf7\x79\x9a\x54\x9d\x76\xbb\x6b\xde\xd5\xcf\xba\x96\x0f\xdb\x28\x8f\xd9\x20\x33\xef\x18\xa4\x00\x0a\x40\x3f\xed\x90\x5d\x26\x71\xc2\xc3\x8f\x3b\xe4\x7f\xed\xb8\x4e\x83\x01\xf1\xcc\xb4\x98\x68\x13\x54\x05\x91\x8e\x29\x79\x40\x76\xc9\x3a\xd9\xdc\xc0\x3e\x5c\xde\x04\x1a\x32\xbd\xb2\xeb\x24\x76\xd9\xed\xff\x9e\x27\x19\x1b\xae\xcf\x57\x74\xb4\x80\x68\xc6\x30\xef\xaf\x0e\x9e\x33\x92\xdf\xdc\x90\x2c\x4c\xb8\x57\xc2\x9a\xf0\x90\xe2\xf7\x1b\x8f\x1e\xba\x94\x38\xcb\xe3\x1f\xbe\xdf\xdc\x08\x52\xa0\x45\x78\x28\x84\xb9\x20\x33\x51\x41\x3d\x79\x15\x74\x16\x25\x19\xb7\x79\xb1\x8f\xe8\x24\x56\x46\xb3\xb2\x38\x89\x80\xd7\x2e\xe6\x5b\x5d\x3b\x60\x17\x30\x37\x09\xa7\xbc\x91\x7f\x30\xdd\x13\x75\xbb\x20\xdd\xef\x67\x15\x0f\x28\xd5\x23\x9b\x1b\x5d\xf2\xff\x67\x18\x5c\x77\xaa\xe1\xf1\xc0\xc4\xcd\x81\xc0\xb5\x70\x55\x9d\x2a\xac\xab\x74\xa6\x6e\xf9\xa5\x33\x7e\x7d\x00\x16\x8a\xb8\xb8\x01\x8e\x07\xf0\x42\xdc\x5d\x11\x3c\x57\x4f\x61\x60\xba\x06\x46\x04\xfc\xc0\xac\x08\xef\x75\xbd\x30\xfd\x7d\x76\x12\x6c\x2f\xeb\x30\x85\x4c\x68\x8b\x99\xbc\x86\xe5\x10\x1c\x83\xda\xd5\xdf\x9c\x51\x44\xf8\x9b\x14\xda\xd9\x58\x2e\x15\x33\x34\x4d\x7b\xec\x5b\x1f\xd5\x5a\x1b\x59\x03\xac\x5b\xe5\x33\x19\xf5\x02\x5d\x3f\x11\x59\x8f\xc9\xe6\x23\xcc\xf7\x4e\xa2\x92\x6e\x3f\x22\x3b\x50\x48\x5b\xb6\xb6\x1f\x99\x4e\x13\x71\x4c\xb9\xad\x14\xf6\xd2\x0e\x2f\xd5\x23\x9b\xdf\x59\x32\xb7\xea\xeb\xb3\x93\x28\xeb\xf0\x72\x26\xc7\xf4\x2c\x7b\x11\xea\x07\x2d\xf1\x67\x0c\x09\x55\x6e\xec\x80\x6c\x42\x09\x84\x2c\x2e\x2e\xe4\xda\xe7\xb6\x30\xee\x55\xfd\x86\x67\x97\xc9\xf2\x4a\x88\x7c\x3f\x26\x3f\xb5\x26\x20\xea\xf0\xa0\x52\x63\x8d\xdf\x72\x1a\x71\x59\x10\x36\xc9\xf3\x51\xba\x28\x93\x53\x95\x96\x37\x39\x49\xd2\xa4\x52\x92\xd3\x49\x94\x7d\x1c\x9c\x14\x51\x36\x9a\x92\x92\x16\xa7\xc9\x48\xee\xa2\x11\x0f\xa1\xdc\xfa\x71\x90\xfc\xd4\x77\x68\x4a\xe5\xa5\x29\xe5\x36\x36\xa6\x05\xdb\xc7\xa2\x74\x92\x17\x49\x35\x9d\x91\x98\x96\xa3\x22\x39\xe1\x2c\x4c\x08\x56\x34\xeb\x9f\x25\x1f\x93\x39\x8d\x93\x08\xa4\x2b\xf6\x34\xd8\xcf\x2a\x5a\x64\x11\xbf\x0b\xf3\xe1\x59\x94\x7d\xfc\x20\x02\x38\x7f\xe0\x13\xfc\xff\xfb\x45\x0c\x35\x9b\x7c\x60\x63\xfc\x00\x97\xc6\x3e\xc4\xc9\x24\xf1\xdc\xcf\x91\x53\xe4\xa5\xd0\x13\xb9\x31\xcb\x69\x90\xc1\x98\xaa\xdc\xb7\x57\x37\xa2\xdd\x67\xf6\x62\x3d\xb1\x59\xa8\x98\xda\x3d\xbe\xcb\xb5\xff\xf1\xa2\xfd\x04\x3b\x55\x63\x4e\x27\x58\x72\xc7\x92\x00\x3a\xb8\x8a\x75\xd2\xde\x00\xf9\x0b\x1a\x32\x5c\x86\x18\x62\x9e\x33\xbc\x90\x1d\xd2\xe1\x42\x5a\xe7\x87\xc7\xe4\x81\x6e\xa3\x2b\x6f\x7f\x3c\xd8\x72\xf6\x6c\x15\x4c\xc6\x6c\x0d\xd5\x2a\xda\x6c\x60\x67\x13\x4c\x06\xe1\x0d\x48\x7d\x92\x30\x9d\x23\xc9\xca\x2a\xa9\x16\x95\x0c\x4f\x9e\xc4\x34\xab\xd8\x86\xe7\xa6\xeb\xe0\xf5\xec\x67\x71\x52\x50\xcb\xd9\xc3\xbc\x47\x55\xf6\xa4\xbc\xac\x2e\x52\xc1\x4d\xb9\x16\x6a\xac\x05\xad\xb5\x74\x73\xad\x15\x79\x95\xd9\x1b\x6f\xc8\x72\x4b\x0f\x37\xd9\x46\xfb\xc5\xfb\x97\x6c\x52\xe4\xe5\x25\x8c\x08\xf4\x56\xf5\xcf\xc5\xf4\xfb\x69\x5e\xc7\xda\xe5\x75\x4a\x8e\x67\xbe\xeb\x30\x0d\x92\x47\xc2\x41\x2c\xdf\x23\xd7\x42\xa0\xa0\xb0\x3c\xab\xb7\x30\x8f\x45\x46\x5a\x62\xf8\x95\x4a\xde\x1a\x12\x6a\xf7\x51\x28\xa2\x7a\x71\x23\xc1\x41\x8d\x12\x41\x6c\x58\xae\xd4\x11\x8d\x1a\x1d\x07\x28\x8c\xc0\x18\x6a\x6e\x93\x1a\xe3\xd7\x19\x5e\xbc\x03\xec\x91\xdc\x6b\x59\x82\x61\x62\x8b\x92\x3b\x60\x9b\x3e\x06\xff\xf7\x8f\x17\x47\x1b\x0f\x7e\x38\xfe\xb4\x75\xd9\x79\xf1\xfe\x25\xfb\xbd\xfb\xe0\x7f\x8f\x3f\x6d\x6e\x5f\x7e\x56\x0f\xdb\x1b\xbd\xed\xcd\xcb\xee\x7f\x0d\xfa\x15\xd8\x72\x95\x04\x60\xde\xd1\x0c\x71\x0f\x04\xcf\xaf\x6a\x6e\x5e\x01\x77\xe2\x76\x2e\x98\x23\x02\x18\x7c\x8e\x16\xe9\x4d\xa1\xf0\xb9\xbb\xd4\x6c\x1c\xea\xe1\xe1\x6b\x5c\xdb\x0f\xc9\xe7\xcf\xa1\x6f\xdf\x5d\x03\x01\x63\x92\x64\x41\x14\x98\x9c\xea\xa6\x90\xe0\xe5\x38\xcd\xd0\xb0\xb5\xd1\xd8\x79\x96\x4b\xac\x6c\xcc\xe5\x62\x06\x90\x87\xa5\xd0\x58\x66\x79\xfc\xe0\x87\xef\x1f\x6c\x6e\xa8\xef\xa0\x70\x43\x1f\x47\x79\x4a\x3a\xfb\xef\x0e\x06\xfb\x2f\xf6\x08\x53\x55\x86\x5b\x1b\x1b\xdb\x5d\x97\x95\xe3\x9a\x5d\x85\x18\x7f\x76\x71\x20\xbf\x36\xc5\x80\x50\x4d\xb7\x7a\x64\xab\xb9\xf7\x30\x66\xc7\xe6\x9e\x44\xe8\xa4\x4f\xfe\xf1\xf6\xc5\x2f\xee\x94\xeb\x32\x81\x81\x85\x6b\xf5\x4c\x35\x82\x5d\x3a\x52\x4d\x17\x1d\x08\x09\xe9\x8c\xfe\xfb\x1e\x79\xd8\x25\x43\xd2\x6e\x37\x46\xc1\x28\x4d\xe0\x3a\xa1\xea\x27\x58\xcc\x92\xcc\x19\x27\x43\xc8\x2f\xbb\x7f\x3f\xf8\xf9\x9f\x07\x6f\xff\xc7\x9d\x6b\xa8\x26\x34\xd3\x76\x1b\x81\x29\xe7\x60\xd7\x47\xc3\xe6\xe6\xd5\x90\x20\xd6\x5c\x48\x1d\xf2\xa8\x3b\xee\x20\xdd\x3a\xdc\x81\x46\x1e\xed\xc7\x38\x7b\x13\xc3\xf4\xc6\xed\x33\x54\x1d\x77\xec\x0f\xb1\x4e\x1d\x54\xa1\xa4\xd6\xa3\x95\x23\x43\x5d\xe6\xaa\x91\xa9\x47\x6d\x3e\xea\xf6\xc8\xd6\x86\x8e\x0d\x68\x09\x93\x08\xdd\xd6\x70\x65\x15\x0d\x97\x72\x38\x7c\xdb\x3e\xff\x2a\x4f\x2e\xb0\x95\xb4\x35\x34\x1f\x2f\x8f\x7b\xdb\x0f\x6f\xcf\x2a\x6e\xcf\x2a\xfe\x6a\x67\x15\xe2\x98\x62\x3e\x5a\xe6\x43\x79\x4d\x9f\xc7\x96\x4e\xbd\xda\x52\x07\x14\x37\x14\x52\x4a\x56\xb7\x3f\x1f\x79\x1d\xf0\xe6\x51\x35\xed\x91\x8c\x9a\xee\xfa\x1f\xc0\xac\xe2\x5e\x56\x96\xc7\xfa\x38\x11\xbe\x8a\x8f\x21\xfc\xa1\xc0\x87\x8a\xfd\x23\x5e\xa3\x8f\x23\x75\x04\x0e\x5c\xb4\x92\x2f\x3a\x9f\x18\xfc\x50\xd7\x80\xc2\xcb\x5a\x05\xfb\x79\xd6\x69\xc3\xf8\xda\x38\x19\x74\xd7\xf4\x77\x2f\x73\xc6\xec\xf8\x5d\xd3\xfd\x37\x7b\x44\x9f\xbd\xf3\x1b\xa8\xed\x1e\xa1\x98\x5b\x7f\xe0\x2c\x53\xf8\x06\x74\x3c\x51\x6e\xbd\xdd\xc8\x62\xdc\x09\xdc\x87\x70\x85\x44\x5f\x4e\x1f\x0c\xc8\xaf\xfb\xef\xde\xbf\x78\x0d\x8b\x6c\xef\xe0\xf5\xeb\x17\x7b\xef\xf7\x0f\x5e\x93\xb7\x2f\xde\xbd\x39\x78\xfd\xee\xc5\xbb\x70\xdb\x71\x54\x45\xb8\x71\xf6\x6c\xec\x6d\x83\xfb\xc2\xab\x73\x16\x9d\x8f\xf2\xd9\x3c\xa5\xe7\x49\x75\x31\x24\x8f\x04\xd1\x59\x3d\x05\xbb\xae\x72\xe3\x60\xb5\xe9\xed\xaa\xeb\xc9\x70\x25\xfc\x35\x3e\xe1\xaa\x94\x1e\x1a\xbb\x1e\x28\xa2\x53\x03\x90\x11\x80\x17\xc5\xe4\x6c\x9a\x8c\xa6\x64\x16\x55\xa3\xa9\x10\x95\xf9\x06\xc6\xb8\x5f\x6c\x16\xf4\x24\x8b\x81\xf6\xbd\x79\xb6\xc5\x81\x9c\xd3\x67\x70\xdd\x08\xe4\xe5\x4e\xc6\x9d\x0f\x7e\x12\x3f\x82\xab\x92\x49\x7c\xec\x49\x6f\xa1\x4a\xb3\x11\x0b\xb8\x27\x2e\x98\x91\x83\x9b\xd4\x26\x18\x87\x9a\xc4\x00\x9c\xba\x2e\x3d\xf8\x1c\x27\x05\x35\xe2\x4e\x38\x88\x0b\x8d\x8b\x0d\xc9\xd7\x85\x1a\x78\x9d\xf2\xdc\xf0\x15\xd2\x7f\x31\x4d\x69\x45\xeb\xaa\x70\x87\xe4\x60\xc9\xbe\xd4\xff\x1b\xdb\xf6\x80\x40\x05\x91\xf0\x6a\xc1\x20\xc5\x7d\xd2\x32\x1e\xd4\x89\xe4\x3c\xfe\x3a\x64\xa9\xbf\x7b\x47\x0a\x9b\x26\x71\xdf\xbd\x63\x9b\x68\xf8\xd5\x5d\x10\x2e\x35\x97\x44\x42\x97\x59\x1e\x07\x39\x36\x56\x9d\xcd\x38\x7b\xb6\x34\xf8\x77\x9e\x11\x01\xc5\xe9\x56\x7c\xe0\xf9\x8b\x07\x7b\x2f\x0f\x5f\xff\xcf\x8b\xb7\xba\xae\x98\x8e\xa6\x8b\xec\x23\x8d\xc5\xbd\x21\x71\xc3\x58\xfc\xf5\x0b\x3a\x4f\xa3\x11\xed\x0c\xfe\x75\x79\xf4\xaf\xec\x5f\xc5\xf1\xd3\x7f\x7d\x1a\x4c\x7a\xed\xcb\xcf\x0f\x1e\x7c\xfe\xd4\xee\x42\xa4\xf1\x4f\xfe\x02\xff\x3a\x96\x45\x8e\x44\xa1\x63\x56\xea\x48\x16\x3b\x3e\x0a\x14\xb4\x8b\x19\xa5\x42\x85\x74\x6b\xa8\x2d\xd5\x14\x2e\x24\x0e\x3d\xd9\xf7\xb6\xe6\xbd\x06\x22\xdc\x65\x0d\x93\x60\x30\xa2\xc1\x00\x8e\x87\xa9\x88\xc8\x02\xd1\x5e\xa0\x0a\x7c\x2a\x2a\xd6\x05\xfb\xb8\xc7\xbe\x59\xcb\x5b\xc4\x46\xb2\x80\xc8\x3a\x11\x97\xa6\x4d\xcd\x40\x9d\xee\x3b\x6c\xcf\x13\x48\xc3\xe7\x7e\x07\x83\x30\x0a\x0a\xff\x24\xe1\x9e\x64\xd6\x60\xf7\x6a\xc7\xed\x95\xc0\x03\x04\xc5\x56\x3e\xf0\x10\xe7\x31\x1b\xd1\x14\x32\x74\xc8\xcb\xbe\x66\xa1\x51\x4a\xa3\x42\xba\xcc\x59\x0d\x89\xd7\xf6\xca\xf7\x43\x41\x9c\x90\x4a\xd6\xe4\xdd\x26\xcd\x0a\x9c\xed\x12\xff\xd5\xba\xba\x4a\xec\xe1\x02\x97\x3d\xb2\xb9\xb1\xb1\x41\xee\x8b\xf3\x28\xdf\x59\x74\x28\xec\x08\xdc\xe4\x04\x3c\x49\xcc\x31\x5e\x53\x52\x41\x46\x3c\x59\x96\xbc\xe9\x79\x05\xa4\xb9\xf3\xe7\xd0\x0d\x24\x88\x93\xbe\xae\x4e\xc7\x39\x2b\xe9\xcf\x17\xe5\xd4\xf2\xdc\x74\x23\xf3\xe3\x12\x28\x64\x15\xb0\xd6\x5f\xc4\x6e\x1c\xc5\x31\xc4\x63\x52\x2e\xb8\xb9\xc1\x6a\xb5\xbc\xc7\x2d\xe0\xbd\xbb\x77\xf8\xe6\x2d\x35\x12\x61\x03\x48\x78\xee\x0b\xc1\x28\x61\x67\x97\xa7\x62\xea\xed\x7e\xcc\x4b\x45\x45\x91\x9c\x52\x93\x51\x47\xb1\x9a\xd3\x3d\xb5\x9d\xd5\x30\x66\x0f\xbc\x91\xf8\x22\xe0\xf1\x8b\xc4\x14\x19\x0a\x21\x81\xec\xca\xe2\xe9\x68\xe3\x58\x6f\xbe\x70\xda\xcf\xfb\xa7\xc1\xc5\x0b\xb3\x08\x7f\x69\x8a\x8c\xde\x3d\x90\xec\xa8\x1e\xd5\x4a\xd7\x0c\xb6\xaf\xda\x56\xd5\xa3\xad\x51\x2e\x35\xbc\x9c\xc9\xd9\x94\xca\x28\x17\x31\xd7\x05\x40\x05\x84\xe3\x05\x26\x2e\xc4\x06\xce\x05\x85\xd7\xe2\xd9\x75\xbc\xd5\x46\x87\x71\x5e\x74\x18\x8e\x3e\xd2\x0b\xae\xb4\xfa\x46\x62\x45\x2b\xea\xf8\xa1\xfa\xd3\xa8\x3c\x38\xcb\xde\x40\xce\xbc\xea\x02\xd2\xa8\xda\xec\x22\x80\xa9\x8f\xf4\xe2\x38\xec\x70\xdb\xce\x33\xb2\xff\x66\xaf\xdd\xb5\x99\x84\x90\x57\x6a\x2a\xf5\x38\xab\x58\x6b\x68\x0f\xc7\xe1\x14\x29\x04\x08\x52\x75\x92\x92\x94\x55\xc2\x33\x22\x25\xb1\x41\xf0\x86\xbb\x6e\x18\xff\x7e\xf7\xda\x4e\x9d\xca\xa6\x24\x0b\xb6\xff\x14\x54\x74\xa7\xc7\x69\xc3\xec\xdc\x24\xcf\xa8\xb4\x97\x75\xd6\x3e\xd8\xda\xc6\x59\x91\x54\x10\xd1\xc7\x66\x5f\x08\xc6\xd2\xe3\x3e\xf8\x14\x39\x19\x68\x73\x2d\xd4\x80\xb6\x79\x79\x91\x50\x7b\x41\x44\xf5\xdf\x57\x39\x7d\x87\x6f\x2c\x11\x63\xcb\x7e\x62\xb1\xfd\x55\xd0\x25\x51\xd6\x00\x63\xc4\xa3\xc6\x35\x50\x7e\x65\x5f\x63\x74\x73\xdc\x37\xb8\x3a\x3f\xf5\x2b\x8b\x22\x8a\xec\x0d\x41\xc4\x1c\xd1\xd2\x3d\x99\x58\x7f\x81\x0d\xd7\x76\x7d\x94\x86\x51\x5b\x4d\x72\x22\x49\xfd\x33\x5f\x80\x7f\xbc\xbe\x89\xd8\x6a\xaf\xdb\x6c\x7a\xbd\xdd\x22\x25\x76\xa9\xef\x63\x0f\x7b\xcd\x38\xe1\x0e\x5f\x5e\x91\x72\x31\x9f\xe7\x45\x05\x66\x41\x7e\xa4\xfd\x66\x8f\x28\x23\x50\xdb\x89\x8f\x1a\x26\xd8\xe6\xb7\x50\xae\xb4\x58\x1b\x50\xde\x8a\x54\xe7\xb7\x38\x00\xa1\xd5\x5f\x86\x40\x11\xa9\xed\x2d\xb9\x2e\x36\x93\x6b\x98\xd6\xb8\xf4\xa5\x45\x08\x5c\xfd\xbf\x3c\xee\x6d\x7f\x77\x6b\xa3\xbe\xb5\x51\xff\x35\x6d\xd4\xe2\xae\xcc\x75\xef\xf8\xef\x46\x45\x9e\x91\xff\x59\xcc\xa2\xd3\xa4\x24\x3f\x46\xec\xf1\xbf\x3f\xf2\xc7\xfe\x8c\x06\x0d\xd8\x83\x01\xd9\xcf\x92\x2a\x89\xd2\xe4\x0f\x4a\xfe\xc6\x3b\xc3\x68\x37\x22\x25\xf8\xbb\x49\x37\x26\x18\x31\x5b\xc2\x46\x42\x81\x3e\x37\x51\xcb\x72\x2a\xb7\x90\x48\x9b\xb7\x1f\x0f\xc9\x46\x93\xe3\x47\xee\x3a\xc3\x70\x61\xc7\xa5\x0e\xf8\xed\xf8\xe3\x51\xeb\x1b\x89\x32\x4d\xdf\x58\x22\x18\x1a\xd3\xce\x52\x77\x3d\x61\xac\xf9\xfd\xa3\x1e\xb2\x49\x8d\x65\x3d\xf2\x93\x0c\x5e\x7d\xd7\x1b\x35\x0b\x0d\x83\xb5\xe8\x0e\x61\x70\xf7\x8e\x40\x55\x20\x98\x35\x6f\xae\x27\xda\x33\x03\x0c\xf3\x6f\xdd\xa0\xb5\x5c\x36\xeb\xb8\x49\x29\xbf\xea\x35\x64\x99\x19\x0c\x48\x14\x9f\x32\x4d\x59\x4e\x16\xd9\x7f\xce\x3f\xc9\x2e\xaa\x49\x5c\x5f\xaf\x89\x8b\x15\xb8\xec\xc5\x2f\x87\x39\x55\xa1\xef\xf2\x3a\x98\x18\xb3\xfe\x20\xef\x81\xf1\x7f\x99\xa6\xa6\x6e\x84\xad\xe6\xbf\x22\x31\xa2\x14\x58\xe9\xa4\x15\x72\x83\xd2\x86\xc6\xa5\xa9\x1c\x3d\x57\xfe\xad\x46\x42\x6e\x2e\x12\x27\x56\x9b\x56\x76\x7b\xfe\xd2\x3e\x1f\xe6\xd1\xa7\x90\x25\x5d\x40\x3d\x55\xcd\xf7\xe9\x29\x2d\x2e\x3a\x32\xc2\xf8\xbb\x24\x9b\xa4\xf4\x15\x47\x7f\x97\x0c\x89\xf7\x83\xae\x49\x4d\xb4\xea\x8b\xbf\x80\x98\x50\xad\xe2\x29\x1d\x41\x52\x13\xf6\xd0\x92\x2f\x39\xa9\x9a\xce\x5b\xe2\x8b\x9c\xab\x9d\x9d\x1d\x4e\x49\x06\x94\x88\xf7\x21\x81\x99\xfe\xcf\xe0\xf8\x49\x77\xdb\x5b\xa1\x90\x8f\xad\x38\xab\x83\x01\xcf\x40\xaa\x5e\x89\x5c\x08\x98\x03\xa9\xf5\xda\x38\x9d\x03\x67\x59\x27\x70\x29\x71\x29\xe3\x7a\xc6\xc0\x6a\xa2\xe9\x8b\x01\x58\x8c\x88\x57\x57\x72\x3e\x2c\xea\x92\xb2\x52\xdc\x05\x23\x97\x58\x2f\x1d\xc9\xa4\xba\x64\x9c\xd0\x34\xb6\x5d\x35\x44\x33\x46\x6f\x1d\xe6\x84\x3b\x69\x71\x28\xde\x3b\x9b\x32\xe5\x7b\x2b\x23\x8b\xa4\x13\x4f\x28\x37\x87\x13\x4a\xe0\xbe\xe4\x82\xf2\x59\x70\x43\xf7\x8c\xc1\x11\x41\x45\x9d\x5a\xfc\x64\xd2\xe5\xa3\x5b\xe9\xf2\x56\xba\xfc\x8b\x49\x97\xe8\xb2\x26\x5f\x4d\x37\x7a\x5d\xf3\xc6\x3c\x1c\x18\xd0\x2b\x69\x25\x0d\x7b\x95\x83\x7e\x2a\x72\x2c\x49\x77\x71\xf6\x88\xd5\x57\x11\x47\x50\x7e\x66\x8f\xa6\x77\x03\x30\x47\x0d\xa0\xa5\x8b\x0d\x0c\x07\xe9\x31\x70\x5a\x54\xed\xb4\x8e\x3f\xe0\x22\x3c\x80\xba\xaf\x8c\xf5\xc5\xb4\x18\x83\xe5\xe2\x55\x94\x45\x13\x8a\xe2\x3e\x70\xc6\xc6\x71\x62\x58\x24\x64\x2c\x19\x5d\x02\x89\x0b\x33\x13\x55\x4e\xe5\xc5\xac\xc1\xe5\x85\x98\x32\x26\x94\x64\x66\xd0\x5b\x4b\xac\x3c\x89\x4a\x1e\xdd\x23\x9c\x2b\x66\x42\x21\x5c\xab\x6f\x6f\xb3\x92\x3c\xd8\x11\x77\x65\xbb\x66\x9b\x82\xf4\x1c\x9c\x88\x76\xc2\xd9\x60\x8c\x38\xbb\x28\x0f\x96\xa2\x17\xe5\x38\x29\xe3\x77\x96\x4c\x44\x52\x6f\x9a\x44\x0c\xe7\xe1\x69\xf5\xf1\x8b\xc8\xa3\x23\x76\x6d\x35\xde\x3e\x79\xc5\x38\x7f\x42\x4b\x91\x86\x1f\xf0\xe2\xa0\xce\x8a\x76\xbb\x02\x0a\xe5\xe0\x3e\xbf\x5e\xa4\xa9\x8e\xc8\xd2\x63\xa2\x29\x3d\x4f\xf8\x59\xa1\x17\x8d\xdf\x72\x4e\xb1\x1b\x4c\xa2\x45\x0c\x44\xdf\x78\x16\x2d\x07\xad\xcd\x72\x67\xd9\x99\x89\x54\x46\x28\x4b\x03\x24\x4b\xb2\x40\xbd\x7d\xb3\x27\x32\xc0\x34\x48\x01\xa5\x71\x28\x82\x22\x73\x92\x84\x69\x50\x3a\xaf\x8b\x33\x0e\xbc\xcf\x60\x3d\x28\x33\xc9\x51\xbf\xf3\xe1\x06\xd5\x54\x8f\x9a\x35\x0f\x4f\x0e\xd1\x56\xe0\xda\xab\xa7\x06\x4b\x46\x55\x81\x47\x7b\x24\xc9\x62\x7a\x5e\x9b\x2e\x8e\x3c\xd5\xbf\x39\xf1\x43\x99\x63\xc6\x38\xd0\x63\x93\x24\x17\xce\x34\xf0\xed\x42\xe5\xdf\x36\xa6\xc2\x33\x13\x3c\x7a\xf5\x32\x5d\xd5\x8e\xe9\x1d\x98\x0c\x4f\x96\x23\x2b\xe7\x37\xc6\xa7\xbd\xe5\x41\x34\x24\xd0\xb7\x9e\x7a\x01\x54\x5d\xc1\xbc\x42\x02\x2d\xbe\xac\x64\xf2\xf6\x9c\xa4\xd1\x86\xc6\x20\xbd\x92\xcb\x95\xf0\xd1\x30\xcd\x18\x8e\x5b\x2c\x76\x22\x27\xe6\xf8\xea\xc1\xcc\x85\x90\x02\xd0\x68\x95\x18\x90\xf0\xd1\x48\x21\xa6\x15\xa4\x90\x95\x46\x1a\x5b\xc0\x0a\x16\x32\xb5\xd4\xc6\x29\xb7\x2d\x30\x0e\xde\x64\x68\x69\x8e\x5e\x53\x9e\x3b\xf9\xdd\xc0\x1d\xfb\x22\x47\x79\xb2\x48\xd2\x18\xb0\x27\xc7\xc7\xbe\x3a\x61\xa1\x61\xcf\x78\x7f\xf0\xfc\x60\x6d\x6d\x0d\x74\x8a\x76\x49\x16\x93\xf4\xa2\x2f\x32\x09\x32\x2d\x64\x51\xb2\xed\xb5\xd2\xed\x64\x28\x0c\x33\xfb\x2d\xbd\x94\xf4\x41\x10\x63\x32\xf0\x45\x5d\xdb\xdf\x34\x73\xbb\x9d\xfc\x7e\xc4\xbe\x1f\x6d\x1c\x1f\x33\xc1\x0e\x3f\x7e\xfe\xac\x3d\x68\x6d\x58\xfe\x63\x13\x0a\xb1\xf1\x3c\x09\x1d\x8b\x59\x0d\x00\x2c\xb1\x38\xb8\x83\x6a\x85\xb3\xe0\x99\xb2\x72\x3d\x40\x7e\xc0\x3c\x95\x51\x16\xb8\x99\x47\x9c\x80\xfa\x42\x71\xd0\xfa\xf9\x4a\xb1\xd5\x89\x95\x71\xc6\x9b\x45\xc4\x30\x20\x40\x6b\xa6\xe8\xaa\x4f\xe2\xf4\x49\x94\x91\x55\x49\x79\x34\xfa\xdc\x21\xed\xa6\x79\x01\xd1\x10\x66\x7b\xca\x27\xd5\x76\x44\x0a\x64\x45\x32\xbb\x6c\xd4\x14\x1e\x86\x73\xea\x26\x69\x87\x7d\x6c\x1c\x36\x5d\x26\xb7\xa3\x59\xb3\x00\xa7\x92\xa1\x2e\x0a\x0a\x27\xc5\x6f\xdf\xec\xa9\xc0\x61\xdc\x11\x68\x14\x65\x4a\xa2\x4d\x32\x61\x17\x0a\x45\x29\x2b\x3c\xd1\x4f\xfb\xfd\xfe\xa5\x91\xf1\xd1\x0e\x22\xa9\xed\xb0\xaa\xb0\x8f\xf1\x2e\x4d\x29\x11\xcc\xf5\xb0\x12\x61\x4a\xaa\x30\x13\x42\xe0\x49\x0c\x62\x5d\x14\x0d\xdb\x9f\x5e\x69\x3f\xa2\xa6\x67\x9f\xdf\xdf\x5a\xa7\x6e\xad\x53\x7f\x31\xeb\x94\xb0\x4c\xc5\x27\xd7\x3b\xf6\x0c\x58\xa7\x94\x41\x09\x9b\xa7\x38\xff\x42\x66\xa7\xe7\xcf\x0c\x46\xc3\x06\x64\xc5\x9a\x71\xac\x28\x30\x68\xeb\xb5\x11\xd3\xc2\x4d\x14\x28\x8f\x43\x59\xe3\x65\xc7\x73\x1b\x43\x9c\xea\x91\x4f\xc4\x16\xd6\x2c\x81\xaa\xc3\x2a\xc7\xfb\x91\x80\x72\x2c\x43\x1d\x5f\x37\x3d\xc6\x73\x2d\x26\xd4\xa4\x23\x9b\x2f\x2a\x75\x6d\x31\xa3\x67\x02\xb7\x1d\xb4\xd9\x32\xe1\x65\x48\xda\x0a\xd0\xce\x76\x33\x24\xed\xf8\xe4\x83\xf7\xb3\x94\x3e\xb7\x51\xdf\x74\xd3\x13\xda\xb0\x69\x05\xe8\x6f\xda\xfb\x59\x36\xbd\xe5\x6d\x7a\xbe\xa8\x5e\xd2\xf3\x06\x43\x7e\x49\xcf\x83\xe3\xb5\xbe\x2d\x1d\x6c\x83\x16\x39\x54\x70\x98\x81\x16\xdd\x31\x8a\xed\xec\x08\xc1\xca\xf9\xe9\x69\xbc\xf7\x04\x1e\x7a\xa2\x77\x1c\xfa\x38\xbc\xfb\x3d\x7f\x86\x77\x3e\x4e\x5b\xad\xe1\x36\x6c\x73\x8f\x6f\xb7\xb9\xdb\x6d\xee\x2f\xb6\xcd\xa1\x43\x18\x5a\x4d\xaf\x78\x02\x23\xa0\xbf\xc4\x45\x55\x9d\x71\xc7\xda\x2c\xf5\x07\x75\x94\xe3\x3b\xf2\x09\x9c\xfa\x2c\xdb\x7f\x19\x8c\x74\x14\xb7\xa0\xe6\xe2\xb5\x82\x1b\x85\x9a\x1c\xe5\xd9\x38\x99\x28\x38\x94\xcf\x0a\x83\xcb\x9c\x48\x0a\xee\x4c\x5c\x59\x34\x8e\xa4\xc4\x4b\x05\xf4\x33\x58\x14\x6c\x9c\xc0\x4b\x05\xb3\x5f\xbe\xbb\xc8\x46\x7c\x77\xc2\x60\x25\x7f\xab\xe0\x18\xe7\x2e\xa8\x0d\x25\xde\xea\xda\x78\x34\x2d\x0c\x92\x9c\x44\x99\xfa\xce\xe3\x7d\x3a\x7d\x92\xaf\x91\x58\x03\x91\x00\x1b\x1d\x8b\x28\x5b\xbe\xb8\x2b\x0a\xd6\xcb\x8d\xe3\x2e\xb9\x77\x8f\x88\xdf\x7d\x30\x66\x1e\x8c\x3b\xed\x8d\xf3\x36\x8f\xa1\xb3\xd1\x25\x4f\x49\x8b\x56\x53\xb6\xe1\x40\x9e\xe3\x67\x17\x2f\xa3\x72\xda\x22\x43\xfb\x35\xb7\x4d\xb7\x0c\x81\x03\xba\xf7\x2e\x99\x64\xb4\x28\xeb\x7a\x79\xc3\x7d\x14\x2d\x06\xba\xaa\xbe\xfa\x7a\x5c\x56\xd1\x47\x5a\xbc\x3d\xd8\x6f\xd0\xdd\xab\xf5\x16\x75\xf6\x9d\x6c\xec\x55\x54\x56\xb4\xc8\xf2\x98\xe2\xde\xaa\xcf\x1e\xa4\xfe\x9c\x64\x51\x9a\x54\x17\x5f\x11\xab\xb2\xc9\x00\x5a\xf5\x67\x1f\x5e\x51\xa2\xbf\x9f\x8b\x7c\xf6\xec\x6b\xd0\x6d\x5b\x74\x0f\xa5\x8b\x7b\x76\x01\x2d\xb3\x01\xec\x66\xf1\x3e\x2b\xa7\xf2\x38\x7a\x21\xf9\x58\x14\xac\x31\xa6\x45\x36\x4a\xe9\xd7\x1a\xc4\x21\x6b\x6c\x49\xf7\x31\x4c\x5d\xc7\xe5\x94\xa1\xe1\xee\xe5\x8b\xac\xd9\xf9\xea\x0d\x8c\xc5\xdb\x38\x27\x2b\x3c\x9c\x00\x18\x1f\x99\x6f\x2a\xbe\xe6\x18\x0e\x55\x8b\x68\x52\x9c\xc9\xc0\x00\x76\xbf\x55\x17\x5f\x54\xd3\x2f\xa1\x90\x36\x57\x46\x6f\x4c\x17\x85\x74\xf3\x75\xba\xa8\xb0\xc9\xf1\x7d\x3f\xa1\xde\x6e\xcd\x8d\x1e\xcd\x97\x75\x66\x7e\xb5\x7e\x60\x27\x10\xbe\x1d\x8b\x48\x3b\x04\x27\x3f\xd8\x7f\xb6\xfb\xda\x4a\x42\x29\x36\x61\x6e\x35\xe4\xd7\xec\xa5\xed\x10\x0e\x23\x79\x37\xfb\xdc\xe1\x50\xdd\x90\x7b\x51\x4d\xb5\xc5\xb2\x47\xda\x31\x1d\x47\x8b\x94\x93\x78\xbb\x27\x07\x3c\xa1\xd5\x30\x64\xad\x97\x91\x9c\xfb\xb8\xa8\x1c\x53\x4f\xda\x96\x8d\xf2\xa7\x51\x6a\x26\x98\x34\xca\x92\x1d\x72\x1a\xa5\x6e\x28\x24\xfd\xf2\xf2\xee\x1d\x81\xad\x95\x06\x25\x22\x9b\x5e\x6d\x58\xa2\xf0\x15\x07\x26\x4a\xaf\x32\xb4\x46\x86\x11\xc6\x8d\xa2\x14\xfc\xa7\x97\x2b\xed\x02\xd2\xa3\xb8\x4b\xc6\xe6\x02\x28\xed\x1d\xbb\x54\x1b\xc7\xd8\x43\x72\xa4\x05\x75\x7e\xc4\x2d\x22\x0a\xff\xac\x4f\xb4\x6d\x88\xe7\x68\xbe\x39\xff\x51\xc0\x38\xdd\xb0\x75\x7e\x3b\xc4\xf5\xf0\x6f\x2a\x8c\x96\x02\x0a\x5b\x71\xf2\x22\x9a\xd0\xdd\xaa\x91\x21\x47\xc0\x86\x71\xe5\x05\x51\xd6\x95\x3a\x6c\xf1\xb5\xc9\x39\x7d\x95\x83\x65\x63\x15\xf4\x84\xc6\x27\x22\xdc\x2e\x1b\x1a\x03\x0b\x8f\xca\xfe\xfa\x27\x4c\x7f\x68\x7c\x92\x37\x2c\xa5\x72\xce\xba\xec\x11\x2a\x8d\xe4\xba\xa3\xf3\x75\xba\xe7\xf0\x00\xed\x89\xce\xd6\x36\xb9\x5c\x91\xaa\x41\x70\x5d\x46\xd1\x58\x6b\x08\x20\xc6\x42\x8b\x00\xd6\xd8\x41\xb8\x41\xea\x90\x93\x0b\x67\x53\xbd\xb9\x12\x7a\xf4\xe0\x1b\x0e\x5d\xf4\xa5\xc1\x9a\x16\x9a\x48\xa3\x35\x2d\x60\x5d\xda\x30\x94\x2b\x0f\x7d\x6c\xd6\xd2\x87\x94\x0f\x6c\xe6\x4f\x0c\xfe\x8e\x3d\x76\x02\xeb\x84\xd7\x30\xb4\x22\x43\x34\x26\x1d\x7c\x76\xf8\x96\x46\x69\x2d\xd9\x48\xad\xa8\x19\xdd\x48\x68\x2f\xe1\x60\x95\xef\xcf\xa1\x1c\x3c\xf2\xfd\xac\x0a\x0d\x1c\x24\xdf\x06\x94\x02\x70\x2e\x95\x28\xb5\xea\xcb\x70\x10\xb4\x21\x5c\x87\x59\xf4\xd4\xdd\x67\xcf\x0e\x31\x9b\x27\x69\x98\x59\x98\xdb\x84\x80\xad\xdb\x2b\x3c\x20\x12\x21\x1b\xb5\xd4\x67\x2b\x4f\x4d\xd9\xba\x5d\xce\xed\x5c\x9d\x0a\xb9\xf2\xca\x5e\x89\x40\x3d\x53\x25\xa7\xf4\x39\x1d\x25\xb3\x25\x0b\x52\xab\x65\x4d\x91\xa1\x4b\x84\x68\xf5\x5b\x1f\xb8\xa9\xc1\x2c\x1b\x34\x82\x0e\x13\xa5\x61\x29\x01\xd5\x77\xc9\xe0\x97\xaf\x2f\x54\xe5\xd2\x0d\xe9\xbd\xc7\x9c\xb4\xda\xd0\x54\x31\x77\x8c\x21\x5b\xd5\x37\xc6\x8f\xae\x88\xaf\xb7\x74\x44\x93\x79\x13\xea\x77\x0b\x35\xa2\x07\x0f\xec\xb5\x09\x42\xd4\xb9\xca\x38\x9b\xae\xf1\xe5\xbc\xce\x33\x46\x07\xb2\x11\x41\x70\x8d\xe4\xa6\x74\xb4\xf0\xe2\x27\xca\x15\x41\x3a\x01\xbe\x8d\xce\x56\x60\x02\x6e\x89\x00\x52\xea\x01\x1b\xf1\x40\x86\x13\xbf\x2e\xc2\x2a\x5f\xb1\xd3\xcd\x7a\x7c\x9d\xee\xda\x93\xe7\x5b\x84\x81\xe1\x24\x93\x6c\x95\xe1\x98\xe0\xa1\xe1\x84\xa1\xbe\xc2\x70\x9a\x8c\xa1\xa6\xe3\x5f\x40\x01\x0e\x53\x93\xf0\x30\xae\xed\x2f\x83\x09\xf4\xd7\xfe\x74\xa5\xfe\xb2\x4d\xe4\x26\xb5\x75\x5a\x56\xc9\x2c\xaa\xe8\x2f\xd1\x52\x51\x13\x81\x06\x46\x18\x80\xb8\x12\x19\x19\x03\xbd\xb6\x04\x33\xe2\x02\xf0\xbb\x3c\x4d\xe2\xb0\x2a\xa5\x67\x91\x83\xf7\x4b\x01\x1f\x9a\x51\xb3\x56\xef\x98\xeb\xba\xf3\xeb\xaf\xbf\x36\xed\x49\x1a\x26\x2b\x55\xd7\xca\xed\xbf\xa3\xc5\x9c\x2e\xdf\xe1\x14\x36\x38\xf8\x12\x64\xb8\x40\xf5\x7d\x29\x17\x27\xb3\xa4\xfa\x2d\x2f\x96\x4a\x5f\x1a\x32\xc4\x11\xbc\x00\x4b\xfd\xa8\x9a\xb4\x2d\xc0\xc2\x3b\x7b\xa8\xd5\xa0\x76\xb5\x17\x65\x31\x8f\x93\x50\x45\xd5\x62\xb9\x55\xc8\x82\xb7\xf5\x7b\xa5\xea\x85\xc0\x5c\x76\x73\x03\xd6\xc1\x17\xf3\x7c\x34\xad\x61\x34\xbe\xf1\x36\xd2\x69\x15\x70\x8d\x52\xeb\x85\xb9\x12\xb3\xa9\x19\xc6\xff\xc7\xde\xbb\x6e\xb7\x8d\x2b\x09\xa3\xbf\xfb\x5b\x6b\xde\x01\x9d\xef\xec\xb6\xd4\xa1\x65\xdd\xed\x28\x71\xcf\x38\xb2\x1d\x7b\xc7\x8e\xfd\xd9\x4e\x77\xef\xf1\x72\x67\x51\x22\x64\x31\x91\x48\x0d\x49\xf9\xd2\x3b\xfe\xde\xe7\x3c\xc7\x79\xb1\xb3\x50\xb8\x10\x00\x01\x92\x92\xed\x5c\xba\xed\x3d\xd3\x11\x49\xa0\x50\x00\x0a\x85\x42\xa1\x2e\xd9\xac\xd2\x92\x11\x5c\xaa\x88\x77\x94\x97\x42\xe3\xac\xbe\xee\x87\x9e\x56\x10\x18\xb5\xe1\x15\xd3\xaa\xe9\x50\x99\xee\xcb\x50\x81\x6b\x76\xb4\x06\xc5\x10\x59\xde\x53\x22\x51\x3f\xc2\x61\x55\x47\x9c\xe9\x0f\x0c\x2d\xeb\x22\xad\xa1\x48\x7a\xfc\x55\x3f\x4a\x55\xad\x1f\xc4\xf1\xc9\x5a\x82\x09\xf6\xd6\xef\x7a\xc3\x9a\x47\x93\xb4\x69\x49\x6f\xb3\x62\xa9\xfc\x51\x15\x99\xb4\x6a\xf6\x3a\x32\x12\xea\xd6\x91\xfd\x72\x70\x70\x60\x28\x4e\x99\xab\x0c\x56\xb0\x3c\xb5\xff\xe4\x0d\x7d\x71\x21\xc5\x81\x05\x53\x55\x71\x73\x9a\x9b\x58\x44\xa2\x72\xb2\x58\xc5\x85\x9d\xa6\x35\x15\x5b\x84\x1f\x0c\xdc\x58\x51\xc5\x31\x4c\x60\xc5\xb1\x1d\x82\x15\x4a\xcb\xdc\x55\x9d\x85\xda\x99\xfa\x81\x66\x97\x9b\x69\x85\x15\x59\xbe\x8d\xb1\x1b\x8f\x23\x37\xc9\xef\x8b\xad\x50\x39\xe9\x64\x19\xb4\xb8\x9d\x58\x1e\x56\x96\x32\xc5\xe7\x64\x66\x9a\xa6\x1d\x8e\x97\x41\xf3\xd2\x8d\x8f\x23\x7f\x98\x3f\x7a\xb6\x42\xcb\x5f\x22\x2e\x83\x2a\x4b\xde\x19\xe7\xa2\x2a\x0a\x2d\xdf\xce\x40\x32\xdd\xc8\x6b\x2a\xa7\xdc\xe3\x91\x15\x4f\x4d\xf6\x2b\xb5\x11\xce\x45\x50\x2f\x2b\xb7\xaa\x33\x1b\xe5\x62\xbf\x36\x4c\xad\x2d\x25\xb3\x9a\x81\xaf\x3a\x79\xba\xc3\x24\x8c\xb8\x70\xce\x0d\x34\xc1\xad\xca\x41\xa4\xb0\xba\x0f\xb3\xe2\x96\x16\x47\xdc\x24\x33\x13\x24\xc4\x91\x62\x1d\xd0\x52\xfd\x08\x83\xb5\x35\x38\xeb\xf7\x75\xb7\x43\x29\xeb\x27\xb5\xf3\x4c\x01\x91\x51\x59\x71\x8c\xc6\x36\x0e\xb7\x1c\xad\xe1\x64\x5c\xa9\x3a\x59\x52\x3e\x08\x2f\x25\xc9\xaa\x1c\x4e\x96\xce\xa6\x36\xa3\x05\x99\xa2\xf8\x3c\x54\x58\x8d\xda\xe5\x24\x1c\xb8\x93\x1a\x19\xdd\x9a\x9b\x7d\xcd\x72\x0b\x5b\x9a\xf5\x87\xee\xec\xdd\xd2\x4d\x93\xda\x99\x86\xe9\xcb\x82\x66\x25\x4b\xda\xb4\xd1\x8c\xbb\xa8\x9c\xad\x95\xd7\xa8\x98\xa7\xaa\x44\xac\xd2\x1d\x48\x72\x23\x7c\x15\x34\xb3\xe2\x67\xbd\xc6\x86\xf3\x2c\x63\xe1\xcc\x1c\xf8\x52\xb3\xe2\x67\xbd\x66\x07\x5e\xd0\x49\x7e\xd6\x6b\xbe\xa0\x8f\x82\x38\x9e\xf5\x5a\xb4\x8a\x3f\x70\x83\x67\xbd\x56\xcb\x51\x5d\x23\xe0\x91\x8d\xd6\xb3\x5e\xbb\x0d\xcf\xdc\x0a\xfa\x59\xaf\x4d\xc1\xb3\x8d\xe0\x59\xaf\x4d\xd1\xe2\x26\x47\xcf\x7a\x6d\xd2\x20\x37\x60\x7e\xd6\x6b\xb7\xee\x2e\x9c\xd6\x8b\x27\x5f\x8b\x27\x5f\x8b\xbf\x99\xaf\x85\xd5\xcf\xe2\x61\x7c\x0a\x17\x70\x7f\x28\xe3\xda\x40\x4b\xbe\xc3\xc9\x63\xfb\x20\xd2\xf7\xc5\xe6\x95\x92\xf7\xe1\x52\xf6\x95\x25\x7d\x0e\xd7\xd6\xd6\xd2\x48\x84\xa6\xf0\x86\x2c\x81\x3a\xd9\x0d\x00\x24\x4e\xc6\xc8\x9d\xf9\x52\x0f\x1e\xf1\xd8\x33\xf1\xe3\x04\xe7\x9e\x48\x02\x9c\x7c\x48\x4b\xdd\x43\x4c\xc3\x38\xca\xdc\x18\x65\x5a\xb2\x96\x5a\x44\x7e\xd4\x25\xb9\xcc\x56\xf8\x0e\x27\xc6\xad\x50\xdd\xf2\xe4\x3d\xe9\xee\xc2\x69\xd7\x9f\xf6\x98\xa7\x3d\xe6\x6f\xb6\xc7\x7c\xeb\xfe\x7c\x0f\xe9\x78\x57\xd6\x37\x50\xf2\x5a\x38\xc6\x51\x1c\x06\xee\xe4\xc9\x75\xe1\xcb\xba\x2e\xdc\x95\x36\x5a\x0f\xf0\x75\x6a\x0f\x9f\xab\xb4\x4f\x4b\x1a\x34\xf6\x33\x36\xd1\x1f\xcc\xa5\xee\x79\xcb\xef\x4f\xc9\xf6\x71\xe2\x5e\xbf\xc5\x85\x37\x7b\x72\x59\x82\xc2\x0f\x3f\xe8\x28\x66\x4b\xe4\xbb\xfe\x2f\x72\x8b\x9d\x6d\x2d\xfd\x22\x1b\xa4\xff\xf0\x43\x49\xc3\x8f\x45\xae\xaf\xf1\xf0\x04\x0f\xc3\x2b\x1a\x3b\x34\xf7\xa2\x97\x17\x34\xa3\xac\x7d\xce\x1f\x9d\x79\x30\x09\x87\x9f\x4a\xd2\x90\x52\x38\x8f\x8c\xac\x05\x4b\x59\xf5\x97\x1b\xc4\xbc\xa1\x7c\x70\xbb\x92\x94\x1e\x8a\x8d\x4b\x16\xb2\x17\x30\x59\x63\xe4\xf5\x6c\x81\xd9\x2a\x39\x57\x05\x33\xb5\xd0\x3d\x9d\x3e\x53\xd9\x3e\x18\xc5\x78\xd6\xbc\xdc\x92\xb4\xc8\xa5\xd7\x0a\x5d\xc9\x77\x44\x9c\xe4\xed\x17\x3a\xf6\x9b\x1f\x09\xa4\x2e\x5a\x3f\xea\xc1\x64\xab\x48\xbd\x9d\x4e\x91\x5c\x3a\xef\x28\x60\x38\x0c\xf0\x3d\x5c\x3e\x11\x18\xb4\x59\x9a\x02\x4b\x3f\x1c\x34\x9e\x0e\x07\x4f\x87\x83\xbf\xd9\xe1\x80\x1d\x0c\xe2\xb1\x55\x01\x55\x20\xf2\xe3\x08\xcf\xa7\x04\xfc\x2f\x45\x0a\xab\x61\x18\xe1\x9a\x1f\x6a\x87\x83\xf5\x85\x82\x60\x95\x8d\x73\x51\x18\x30\x83\x16\x3b\x1d\x8f\xbf\x8c\x2a\xeb\xdb\x3a\x02\x50\x3e\x7a\x3a\x56\x6e\x6f\xf0\x35\xcb\x92\xb2\xfb\x45\x2e\xad\xe2\x71\xf1\xa5\x55\x3c\x86\x4b\x2b\x2a\x08\x2d\x78\x37\x95\x7b\xb2\xc8\xdb\xd4\xb2\xa2\x86\xb4\xa5\x5d\x99\x2f\x28\x99\xb8\x11\x8f\xc7\x1f\x2c\x25\x34\x4b\x2c\x64\xd2\xbe\xe5\xb6\xec\x07\xa3\x30\xa7\x59\xd3\xe7\x7b\xb7\x19\xe3\xe4\xd0\xbd\x61\x64\x71\xea\xff\x99\xb9\x2a\x97\x10\x28\x2c\xab\x19\xe0\x2d\x87\x8d\x1f\x1c\x87\xbf\x15\x60\x61\x2c\x73\xef\xd6\xa7\x6e\xf4\xe9\x2c\x9a\xc7\x09\xf6\x8e\x71\xf6\x6e\x5c\xc2\xa1\xa0\xe4\xbd\x31\x09\x30\x11\x18\x8f\x5d\x3f\x0f\x09\x7b\xa1\x7b\x53\x85\xeb\x79\xc7\x91\x7f\xe5\x26\x98\x1d\x4e\x2d\x28\xe4\x96\xbb\xf7\x28\xd0\x44\xba\xc5\x03\x91\x5b\xee\xde\x58\x8c\xdd\xb8\x18\x05\x7b\xa1\x7b\xb7\x7f\x89\x13\x2a\x1e\xe4\x4f\x45\x5e\xb1\x07\xc1\xa1\x0c\x3d\xe4\x96\x7b\x88\x55\x71\x7a\x3b\xcd\xc7\xc0\x5a\xe6\x21\xd6\x44\x61\xeb\xd6\x32\x0f\x30\x03\x44\x52\x4c\x30\x05\xbf\x1b\x85\xd3\x63\x37\x8e\xaf\xc3\xc8\xcb\x9d\x8e\xb2\x95\x1e\x62\x95\x14\x8e\x8e\xb5\xcc\x43\xd0\x67\x61\xeb\xd6\x32\x0f\xc4\xa7\x0a\x11\xc8\x2b\x66\xc3\x21\x7d\x5c\x5b\x43\xf1\x7c\x00\x77\x90\x18\x92\xaa\xcd\x83\xf4\x79\xea\xc7\xb1\x1f\x5c\xca\xe5\x0b\xb1\x9e\x85\x71\xe6\xfa\x4e\xc2\xd6\xf4\xd9\xa4\x4b\x41\x05\x3a\x54\x54\xee\xae\xef\x74\x3c\x56\x53\xf3\x6a\x86\x2b\xca\xb9\x5e\x33\x2b\x69\x37\x9f\x4e\xf5\x4f\xa7\xfa\xbf\xd9\xa9\x5e\xba\xf2\x1b\xfc\xf9\xa7\x7e\xe5\xb7\x35\xc1\x37\xe8\x35\x8e\xf0\x65\xfc\xa7\x1b\xff\xe9\xa3\x57\xee\x04\xdf\xfc\x57\x94\x8c\xe2\xda\x78\xae\x9d\xcf\xbb\x22\x98\xfe\x09\x1e\xe1\x08\x07\x43\xdc\x43\x04\x8d\xb8\xb7\xb6\x76\xe9\x27\xe3\xf9\xa0\x36\x0c\xa7\x6b\xbf\xfb\xc1\xae\x1f\x1c\x45\x97\x6b\xbf\x6f\x1f\x87\xa7\xfd\xb1\xeb\x07\x6b\x83\x49\x38\x58\x8b\xaf\xdd\x68\xba\xe6\x07\x09\x8e\x02\x77\xb2\x46\x7a\x86\x6f\x12\xfe\x6f\xed\x32\xfc\xdf\x07\xad\xd6\x97\xb9\x22\x94\xae\xfd\x4e\x09\x56\x7f\x97\x03\x3f\xfd\xf9\x3d\xdd\xf9\x51\x33\x64\x9c\x5c\x87\xd1\xa7\x13\x0c\xd9\x13\x72\xef\x01\xf4\xf2\x86\xcb\x80\xc1\x9f\x7f\x7e\xc8\x2b\x76\x5f\x37\xdf\xdb\x60\xb8\x13\xb8\x83\x09\x2e\x44\x56\x2a\x6a\xc1\xd3\x52\xe2\xbe\x28\x5e\xbb\xb3\xb2\x28\xa6\x45\x6d\x28\x9a\x4b\xdc\x13\x45\x2f\xbc\x0e\x58\xb6\x8c\x5c\xfc\x78\x39\x0b\x72\xa6\xcf\x0b\xb8\xb6\xdb\xf1\x9b\xcf\xca\x60\x47\x4b\x59\x70\xcb\x7e\x7c\x10\xcc\x22\x9c\x44\x3e\xbe\x2a\x0c\x58\xc3\xcb\x59\xb0\x33\x7d\xbe\x2f\xd9\x25\x64\xeb\x2c\x22\x38\x52\xc8\x46\x6a\xfa\xb7\x07\x19\xb0\x4b\x5c\x26\xac\x82\x05\x25\xed\xcb\x3d\x47\x88\xe6\x30\x2b\x0a\xdb\x6f\x41\x45\xfb\xf2\x20\x63\xc3\xd2\x1c\x16\xe0\x44\x4b\x59\xd0\xca\x7e\xe4\x98\xb5\xcb\x61\x96\x7f\x03\x9e\x55\xde\xea\xbc\x5d\xbe\x17\x4d\xd9\xa9\xfc\x36\xe5\x60\xd2\x5b\xce\x3a\xe4\x1b\xd9\x99\xf6\x82\x2f\x12\x19\x18\xa1\x51\xe9\xf9\x12\xcb\x77\xb7\xb3\xb9\xfc\x24\x1f\x03\xbe\xc0\x3d\xec\xd8\xbf\xb2\x7b\x42\x91\xa9\x82\x02\x39\x07\xdc\x02\xf8\x26\xdd\xb3\x02\x1f\x0a\xe4\x9d\xf8\x4c\x67\x3e\x22\x9f\x99\x13\x33\x18\x2f\x6f\x5b\x4f\xc7\xbc\xa7\x63\xde\xdf\xec\x98\xc7\x8e\x78\xfc\xba\xec\xeb\x64\x25\x5a\xc6\x38\x9e\x3b\xc6\xb9\x33\x9f\x1f\x05\x58\xea\xed\x64\x9c\x6b\x07\x48\xaf\x11\xf3\x63\x63\xf3\xe2\xc9\xed\x8c\x48\x1d\x2c\x0e\xf6\x4b\x59\xff\x15\x5f\xfb\xc9\x70\x5c\x21\x25\x32\x21\x18\x87\x6e\x8c\xd1\x0a\x59\x09\x71\xb2\xd2\x53\xbf\xc1\xec\x45\x97\x71\x2d\x1e\xfb\xa3\xa4\xa2\x27\xde\x43\x99\xb4\xdd\x75\x43\x09\xc6\xc3\xc1\x99\x31\xc0\xd7\xcc\x73\x1e\xae\xaf\x5f\x9a\x50\x99\xe1\xc0\xf3\x83\xcb\x2f\x81\xcb\x31\x6d\x4a\xb6\xd7\x32\x22\xc6\xa2\x14\x1b\x30\xd2\x00\x66\xab\xb3\x7c\x84\x77\x8a\xb8\x21\x4a\x96\x30\xf0\x64\x20\x33\x42\x87\x42\x1d\x26\xd1\xcc\x2c\xcf\x07\x7e\x10\x27\xee\x64\x52\xae\x7d\xad\xb8\x25\x2e\x44\x4e\xa9\x7c\x6c\x2e\x71\x72\x10\x5e\x96\x89\x4d\x41\x8a\xd9\xa3\x52\xd0\x76\xf5\x32\xf9\x6d\xcf\xc2\xe2\xc0\x42\xa4\x4c\x51\xab\xfd\xb1\x1b\x5c\x5a\xc2\x61\x94\x90\xe2\xc4\x34\x2a\x16\x71\xca\x78\xaa\x52\x16\xe9\xa5\xdc\x56\xc8\x83\xa1\x5e\x2c\xef\xbf\x13\x8f\xc7\x35\xe0\xaa\x59\x0e\x15\x8f\x0d\x1c\x2a\x4f\x38\x2b\xba\xb5\xca\xd2\x08\xca\xdc\x5a\x29\x96\x19\x0f\x7e\x45\x91\x43\xae\xc8\x74\x4b\xf1\xb8\xd8\x18\x88\x1b\x65\x2e\x6b\x68\xdb\x0c\x91\x4c\xd9\x7b\xe3\xa0\xd3\xf9\x83\x20\xa0\x53\x65\x46\xe4\x65\xb8\xe0\x64\xdc\x23\xff\x61\x30\xe3\xf1\xb8\x47\xfe\xe3\xa4\xc2\xb2\x29\x55\x59\xbb\xfd\x24\x00\x3f\x09\xc0\x7f\x37\x01\x58\xba\xe8\xe0\xce\xfb\xcb\xf9\x37\x99\xa5\x5f\x1a\x81\xe0\x04\x5f\x92\x59\x77\xa3\xad\x81\x6f\xc9\xd4\x15\xaf\xbd\x51\x8b\xd6\x3e\xc6\x61\x9a\x08\xcb\x1f\xba\x33\x19\x8a\x0d\xc8\x7e\x7f\xeb\xd8\x00\x42\x46\x86\x85\x3a\x60\x46\xe8\x68\x13\xad\xd4\x6f\x86\x5d\xef\x85\xd7\x1c\x7a\xed\xf6\x0b\x77\xbd\xd3\x1e\xb6\x5f\xb4\x9b\xdd\x36\x6e\x6c\xd4\x5f\x0c\x3b\x75\xdc\x6a\x7b\xdd\x76\xa7\xdb\x1c\xac\x48\xe8\x98\xe0\xb8\x0d\xb7\xd1\x68\x0c\x86\xf5\xf5\xf6\xf0\xc5\x70\xe4\xae\x6f\x34\x46\xf5\x61\x6b\x03\x77\x5b\x03\xaf\xd3\x18\xbe\x68\x0c\x36\xdc\x51\xbd\xbe\x92\xcb\xbf\x28\x9e\x3d\x59\xae\x76\x07\x7e\xcf\x30\x98\x12\xd7\x64\xd1\x16\x7a\xc6\x5e\x32\xb1\x81\x15\x27\xd8\x67\xa1\xeb\x43\x6c\x82\x9d\xed\x37\x83\x9c\x61\xad\xf9\xf3\xfa\xac\xd7\x70\x9e\x15\x4c\xdc\xb3\x5e\x93\x70\xe5\xce\x13\x57\x7e\xe2\xca\x7f\x33\xae\x2c\x31\x65\xae\xa5\xd3\xb9\x72\x9e\x51\xf9\x28\x0a\xff\xc4\x53\x37\xa8\x79\xf8\x97\x87\x63\xe5\xa6\x50\x08\x7a\x1c\x84\xcc\x45\x72\xc6\x02\x5a\xbd\x2b\x26\x5b\x0e\xda\x64\xa4\x4a\x1f\xe5\xc4\x4b\x54\x07\x2a\x15\xa0\x2f\xd4\xdc\x4c\x5a\x91\x38\x53\x44\xf3\x9a\x97\xca\x6a\x5f\xe4\x4a\xaa\x5a\x5d\xaa\xa3\x7e\x90\xab\x64\xee\xbd\x83\xf9\x64\x22\x84\x55\x3e\x28\x72\xba\x7a\xfd\xfe\x57\x19\xb0\x68\xaa\x8e\x55\x06\x3c\x68\x77\xd9\xf9\x8c\xd1\xcc\x29\xa5\xe5\x01\x06\x61\x1b\x7b\x28\x09\x99\xb3\x21\xbd\x27\x00\x7d\x07\xa1\x6a\x2a\xf9\x66\xd2\xfc\xd3\xb2\xfb\xa4\xa8\x92\xea\x1f\x12\xed\xdf\xa9\x59\xfe\xd3\x77\x6b\xc6\xde\x49\xb0\x74\x55\x93\x31\xb2\x90\x36\xe2\xff\x69\x7a\x4b\x2b\xf7\x48\x37\x16\xe9\x3b\x9d\xe7\x4a\x84\xe3\xf9\x24\xa9\x16\xf6\x9f\xe6\xb5\x50\x06\x80\xde\xe1\x6b\x23\x20\xbd\xcc\x1b\x02\x0a\x4e\x9d\x5b\x86\x89\x61\x18\x74\x6a\xfd\xe9\x27\x44\x4b\xa3\x1f\x37\x29\x49\x69\xaf\xc8\x2e\x34\xf2\x03\xec\xf1\x21\xd3\x20\x88\xc6\x7a\xac\x56\xce\xc8\xcd\x63\x3a\x6e\xf8\x86\xc6\xf9\xe2\x2e\x03\x68\x14\x85\xd3\xf4\xd4\xef\x46\x97\xf3\x29\x0e\x92\xb8\x86\x0e\xc9\x96\xe8\xe3\x98\xd1\x17\x0c\x57\x66\x58\x19\x38\xee\x63\x60\x20\xad\x14\xa4\x3a\xc4\xbb\x6c\xc8\x3e\xbf\x9b\x4f\x26\x77\x92\x0b\x83\x3f\x42\xf8\xc6\x8f\x69\x79\xf3\xe8\x6b\xad\xda\xf5\x9d\xfe\x28\xcd\x03\xc8\x1b\xa4\x99\x00\x41\x3d\x38\xc1\xc1\x65\x32\x46\xab\xa8\x71\x51\x35\x65\x2c\x83\x42\xb3\x70\x56\xa9\xbe\x44\x6b\x6b\xfc\xe6\x8f\xec\x1b\xb0\xda\x60\xd4\x7e\xcc\xc8\x49\xda\xe0\x53\x63\x91\x14\xc3\x24\xb4\xd1\xa8\x6a\x56\x62\xa7\x52\xf6\x8e\x77\x28\x87\x4c\x55\x88\x2a\xd7\x1e\x7c\x54\xf3\xc2\x93\x4a\xa9\xa4\x8a\x78\x4e\x37\x20\xbc\xc1\xdc\x9f\x78\x6f\x70\x52\x91\x55\x05\x38\x98\x4f\x71\xe4\x0e\x26\xb8\x87\x92\x68\x8e\x8d\xda\x4b\x77\x0a\xf7\x75\x62\x4f\xa8\xc5\xb3\x89\x9f\x54\x56\x6a\x2b\x72\xf8\x59\xb6\x5b\x40\x69\xaa\x90\xe6\xb3\x07\xaf\xf8\x44\xfd\x82\x1a\xca\x34\x85\x83\x8f\xe7\xbc\xce\x05\xe1\xe4\xca\xf3\xe7\xcf\xe8\xdf\x77\x2f\x95\xd2\x7a\x99\x97\xaa\x1a\x4f\xa0\xd0\xb8\x48\x73\xc8\xd1\x1f\xe6\xec\x78\xe1\xe0\xa3\x03\x55\x1c\x3a\x7e\xbc\x4f\xa4\x11\x37\xbe\x0d\x86\x6f\x60\xcf\x22\x82\x35\xf4\xa4\x7a\xc1\xc7\x02\x46\x74\x8b\x15\xa9\xa8\xbe\x39\x5a\x4d\x65\xda\x00\x8a\xc6\x5d\xe0\x2e\x1e\x3d\x07\x44\x6a\xc3\xb1\x1b\x6d\x25\x95\x7a\xb5\x96\x84\xef\x67\x33\x1c\xf5\xdd\x18\x57\xaa\xfc\x73\x4c\xa4\x92\x4a\xa3\x9a\xb7\x7b\xf1\xd9\xb6\x5f\x37\xcc\x52\x39\x80\x99\x76\x49\xe8\x88\x3a\x97\xa4\x67\x86\x65\x25\x24\x1f\x99\x8b\x56\xc4\x5b\x75\x3b\x84\x1c\x8d\xba\x2e\x8a\x2e\x98\x5e\x0a\x89\x8a\x0f\xb2\x4a\x49\x18\x57\x15\xf6\x94\xcf\xc2\xa2\xdd\x4d\x0d\x25\x72\x82\xdc\xa1\xd4\xb8\xcc\xd8\x33\x68\x7c\xf1\xee\xc9\x59\xd2\x70\x14\x39\x48\xdb\x77\xf8\x1f\xc7\x87\x16\x32\x0f\x3c\xab\x2a\xdf\x92\xdc\xc9\xa3\xc7\x58\x01\xc7\x9e\x53\x30\x7b\xa4\x49\x32\x79\x7a\x4c\x69\x96\x2f\x71\xde\x7e\x94\xee\xe4\xc3\x08\x13\xa9\x74\x36\x8f\x30\xfa\xe7\xe9\xd1\xbb\x93\xe3\x3e\xe2\x4d\x5d\x8f\xfd\xe1\x18\xce\x6d\x7c\x0b\xf3\x03\x34\x00\xed\x33\x2b\x92\x61\xa2\xd2\x7b\xc1\x29\x6b\xb5\xda\x1d\x53\x3c\x1a\xf7\x79\x44\x4e\xa5\xd1\x6c\x28\x57\x36\x33\xd4\x74\x0c\x6c\xa4\xe2\xde\x32\x2b\xa8\x8c\x0d\x63\x4f\x16\x7d\x0d\x57\x00\xe7\x17\xda\xf5\x01\x99\x38\x56\x49\xdb\xf1\x2a\xb0\xb7\xca\x02\x27\x59\xd6\x35\x52\xa9\x22\xf6\xdb\x6a\x55\x9d\x43\x86\x1a\x9b\x7c\x3e\x8d\x32\x29\x58\xe7\x92\x55\xb5\xeb\x67\xf9\x50\xa9\xaa\x02\x2d\xec\x14\x39\xf4\x77\x9f\x0e\xfd\x4f\x87\xfe\xbf\xd9\xa1\x5f\x56\xc5\x32\x06\x32\x65\x5b\x80\x76\xf6\xff\x27\x1e\x8d\x22\x7c\x8b\x7e\xf3\x27\xc3\x4f\x18\xbd\xfa\x88\x47\x23\x6b\xc0\xa9\xc5\xc2\x53\x1d\xba\x91\xef\x06\xe8\xc8\x0d\x86\xd8\x85\xc2\xc6\xc0\x54\xcb\x04\xb3\x62\x75\xde\xb8\x57\xe8\xb7\x30\xf4\xd0\xab\x4b\xbb\xe6\xa1\xad\x68\x1e\xfe\xc9\xf8\xae\xe2\x8b\xce\x98\xb1\xd0\x10\x97\x51\x4f\x40\xd2\x0c\x63\x19\x1a\xff\x55\x14\xc2\x51\x14\x6a\x11\xb0\xd6\xe8\x3b\x6e\xb3\xc1\xb6\xaa\xfd\x64\x25\x26\xbb\xea\x2c\x0c\x62\x7f\x30\xa1\x54\x37\x73\xc1\x5f\x08\x4d\xd9\xe5\x16\xd9\xbf\x66\x51\x78\xe5\x7b\x38\x8a\xd3\x6a\xee\x24\x0e\xb3\x75\xc3\xc9\x84\xd4\x25\x14\xc8\x83\x03\xa0\x20\xf4\xe8\x57\x3f\x18\x86\x53\x19\x34\x40\x63\xe9\x62\xe8\x05\x74\xe2\x4f\x31\x59\x85\x7e\x8c\x1a\x28\xc6\xc3\x30\xf0\xe8\xa6\xea\x07\x97\x13\x9c\x84\x01\x1b\x5a\xd2\xcd\x1c\xed\x03\xc7\x57\xd5\x41\xf0\xb7\x68\x53\x74\x48\xd6\x80\x10\x04\x40\x8f\x7d\x27\xbf\xe5\x18\x69\x0a\x11\xfb\xe9\x93\x08\x3b\xe3\x28\x0c\xc2\x79\x3c\xb9\x85\x90\x2c\xd6\x7d\x9c\x7c\x34\x1d\x81\x90\xe7\x26\x6e\xde\x69\x5d\xed\xba\xa2\x94\x09\x3c\x65\x24\x08\x24\xe5\xa8\xf8\xa3\x32\x14\x6a\xfa\xe9\x30\x88\x43\xb2\xe5\x11\x5a\xa9\x50\x8a\xa9\xed\x07\x57\xee\xc4\xf7\x8e\x59\x85\x8a\x22\x43\x71\x0f\x7f\x3a\x32\xca\x61\x42\x15\x14\xd8\x22\xa8\x25\xe1\x31\x7d\x07\x88\xd5\xe8\x38\x38\xd0\x5f\x66\xa9\x22\x1f\x99\x98\x9e\x60\x53\x9d\x3e\x2a\x2d\x33\xd8\xa9\x2d\x01\x74\x8e\xb7\xe3\xc7\xbf\x12\xac\x4f\x28\x7d\x62\x21\xff\xc9\xdd\x4d\xc6\x51\x78\x8d\xd4\x6e\xea\x15\xf4\x5e\xb1\x0e\xd3\xaf\xb5\xd2\x1a\x09\x77\x41\xa2\x00\x89\xb9\x80\x32\xf4\x13\xb2\x10\xa7\xca\xd0\x08\x34\x90\x21\x14\x29\x08\x75\x49\x92\xe1\x69\xcf\x25\x11\x3c\x97\x68\x1e\x8c\x3c\xb2\x14\x41\x4f\x19\x0c\x66\x99\xb3\x03\xe9\x1a\x8e\x22\x5b\x12\x5e\xb9\x4f\xd5\xac\x05\x13\x12\xc9\xe9\x96\x22\xbe\xe2\xc1\xcb\x54\x57\x71\xc8\x8a\xd1\x2c\x8b\xbf\x42\x9b\xa6\x68\xb6\x39\xe7\x14\x13\x9d\xe6\x1f\x45\x48\x91\xd7\xa4\x84\x49\x2d\x46\xab\x3e\x10\xc9\x42\x2b\xdf\x22\xc9\x02\x62\x32\xdd\xa6\x3c\x69\x39\x2a\x8d\x1f\x88\x4c\x35\xf2\xe4\x4a\x42\x98\x9c\x0a\x6f\xea\x7e\x54\x19\x97\x20\x4b\xa5\x67\x29\x3d\xa2\x12\x5b\x29\x4e\xc4\x4e\x4d\x04\x5b\x7e\x32\x65\x92\xa5\x81\x18\x13\x3e\x7f\x36\xcd\x62\x3e\x95\x89\xea\xaa\x34\x61\x17\x23\xca\xc8\x03\x09\x39\xd3\x31\xc9\x28\x8b\x32\xf9\x7a\x9c\x7e\x2c\x66\xf8\x34\x39\xc7\x1d\x40\xdc\xf7\x4a\x2c\x2c\xc3\x67\x61\xf2\x95\xe2\x93\x84\x5e\x88\x86\x13\xec\x06\xf3\x19\x0a\xa0\x0d\x32\xe4\xa9\x46\x21\x77\xe4\xa4\x5e\x18\x96\x28\x45\x55\x8e\xe1\x23\x10\xd0\x86\x96\x88\x60\xe7\xb4\xf8\x05\x11\xc5\x48\xfd\x1e\xa2\x50\x7c\xaf\x97\x81\xd4\x33\xc1\xec\xa5\x3f\xb9\xbe\x1a\x31\x2f\x79\x6d\x2e\x14\x6e\xc1\x24\x3d\x4d\x46\x60\x58\x55\x24\x76\x50\x3c\xe3\xe1\x4c\x88\xc2\x44\xf0\x65\xe6\xce\x70\xcc\xba\xf4\xc9\x01\xd3\xcf\x6a\xc6\x49\x2d\x13\x21\x64\xe7\x3b\x7f\x26\x04\x14\x95\x86\xa1\xb6\xe8\x1b\xb5\xe4\x33\x0c\xfa\x4b\x65\xb4\xd2\x7e\xf0\xc1\xaa\x30\x25\xf1\x27\x7c\x1b\x57\xd2\xea\x55\xae\xbe\xde\xdc\xdc\x44\x75\xf4\xd3\x4f\xc8\x3a\xa4\x84\xc6\xa2\x33\xfa\xa1\xa2\x94\x7a\xa9\x8d\x7b\x46\xf4\x2e\x18\xff\x74\x1f\x8b\x30\x61\x1d\xe4\x14\xc2\xa7\x61\x8a\x87\x63\x37\xf0\xe3\x29\x3f\x20\x17\xf1\x12\x00\x51\x34\xda\xb4\x1d\x79\x9c\x3f\x61\x3c\x13\x99\x3e\x44\xbf\xd7\x7e\xfe\x18\x8f\xfd\x80\xb4\x76\x33\x0c\xa7\xb3\x09\xbe\xf1\x93\xdb\x5e\x87\x1d\x13\x49\x11\x42\x27\x15\xb2\xc5\x7c\xc2\xb7\x54\x9f\x21\xc6\x56\x1e\xbd\xb5\x35\x14\xe1\x69\x78\x85\x91\x3b\x99\x40\xef\x62\x07\xe1\x9b\x21\x9e\x25\x70\xf2\x60\xaf\x94\x0a\xc9\x18\xdf\xa2\x00\xd3\xa1\x19\x60\x06\xc0\x23\x5d\x9f\xbb\x93\xc9\x2d\x1a\xdc\xc2\xd8\x91\x71\x62\x49\x3b\x80\x8e\x7e\x23\x1b\x9b\x1f\x5c\x56\xaa\xf2\x4e\x52\xf9\x51\xe9\x23\xfa\xfc\x99\xa0\x5c\xf3\x03\x0f\xdf\x1c\x8d\x2a\xe0\xdd\x4a\x28\xf0\xc3\x4a\x15\xa8\x61\xb5\x91\xd9\x62\x24\xb2\xfb\x84\x6f\x2f\x6a\x62\xb9\x66\xcc\xd8\xb3\x74\x4a\x2a\x18\xec\xc9\xff\x12\x64\x0b\x47\x60\x42\x08\x43\x6a\x44\x8d\xc2\xa0\x1c\xef\x60\x56\xcf\xb9\xb4\xca\x0c\xbc\x0d\x3a\x5d\x0b\x75\xa2\x2e\x00\x34\xf4\x2b\xc6\x89\x32\x12\x04\xb4\xa4\x57\x75\xd0\xb0\xb6\x73\xb6\xf7\xe1\xf8\xe8\xe0\x60\xff\xdd\x9b\x0f\x67\xfb\x87\x3b\x47\xef\xcf\xd4\xa3\x5a\x99\x09\x31\xc8\x6d\xba\x50\xf6\x48\x47\x5a\xa3\xec\x47\x10\xdc\x76\x13\x17\x6d\xa2\xf3\x8b\x97\xda\x87\x7d\x70\x67\x17\xef\x4b\x2e\x67\x01\xb3\x36\x9b\xc7\xe3\x8a\xbe\x30\xb8\x34\xa9\x14\xdf\xf7\x62\x5a\xfa\x13\xbe\xcd\x08\xa9\x64\x3c\x52\xa0\x0b\x0e\x66\x29\x09\x57\x40\x57\x53\x74\xaf\xad\xa1\xa9\x3b\x53\x58\xab\x0f\x44\x0d\xdc\x07\x88\x0f\x08\x57\x1d\xb3\x43\x77\x26\x6b\x5c\x24\xf5\xbd\x1a\x9d\x80\x4a\xcb\xc0\x63\xaa\xfa\xf0\x01\x94\x73\xa8\xe7\x83\xd4\xc0\x47\xe9\x1c\xca\x5f\xa8\x91\x10\x52\x14\xd4\xb8\x0d\x68\x61\x71\x3d\xd4\x04\x76\x2d\x22\xcf\xd9\xd1\xf6\x51\x8f\x13\x20\x9a\x84\x97\xff\x99\x91\xe9\x43\x9b\x54\xff\x10\x72\x7c\x09\xf5\x46\x6c\x39\xd7\xb2\xaf\xb5\xa9\x3b\xab\x58\xcd\x3e\xf8\x1f\x58\x94\x7a\xe9\xb0\x93\xc9\x60\x67\x50\xdf\x53\xfd\xae\x04\x9d\x7c\xc2\x28\x9e\x47\xa0\x10\xe7\x0c\xce\x8f\x51\x9c\xf8\x84\x4a\xe8\x56\x80\x3d\xe4\x8e\xc0\x49\x2c\x8a\xfc\x2b\x77\xa2\xed\xdb\x2a\x50\x32\x2e\x10\x7d\x82\xae\x1d\xdf\xbb\xc8\xa0\x99\xf6\xab\x36\x4c\x6d\x2a\xd4\x4a\xe2\x8b\xdd\x55\x4a\xa8\x7c\xe4\x6f\x77\x08\x4f\xb8\x46\xdd\x50\x67\xe4\x4e\x62\xac\xdc\x3c\x32\x07\xb8\xe2\xc1\x65\x10\x7e\xfc\x91\xb5\x8b\x96\x82\x42\xa6\x08\xe6\x5f\x5a\xd5\x16\x25\xc5\xcb\xec\xc0\xfe\x08\x55\xcb\x0c\xe8\x02\x1a\x0c\xa4\x52\x9c\xd4\x57\xa8\xaa\x8d\x96\xc6\x0e\x72\x86\x4b\xc5\x27\x47\x23\x82\x94\x2b\xe0\x9c\xa4\x6b\x27\xd9\xc8\x2f\xda\xe5\x9f\x96\x7e\x2d\x9b\x88\x86\x69\xdf\x9f\xf5\x9a\x10\xa1\x8a\x29\xff\x9f\xf5\x5a\xe0\xba\xbc\x5e\xea\xba\x50\xc4\xac\xc5\x49\xe2\x07\x97\x16\x07\x71\xe0\x60\x9e\x94\x80\x1d\x6d\x0a\x67\xc6\x97\xd9\x22\x69\x94\x75\x61\x87\x95\x13\x86\x8b\xb5\x9c\x0e\x01\xc1\x7e\xe3\xe9\xb2\xf3\xe9\xb2\xf3\xef\x76\xd9\xc9\xa2\x66\xb3\xb3\xd2\x72\x91\xb3\xcb\x58\x2d\x5b\xf2\xd9\xe8\xe9\x6c\x16\x33\x70\xe6\x4b\xbe\x91\x9e\x47\xb6\x3c\x2f\x86\x91\x14\x5b\xa3\x1b\x80\x3a\x2d\x46\x73\x2a\xd3\x31\x27\x48\x87\x48\x74\x7e\x02\x91\x23\x11\xe4\xf1\xa0\x7b\x32\x95\x17\x08\x3c\xf9\x48\xc2\x8e\x88\xff\xf1\xbf\x74\xa5\x16\xd9\x76\xe9\x68\x72\x59\x30\x9b\x4d\x93\x86\x9c\x4a\xdd\x2b\x49\xc9\x30\x60\x2e\x77\x0a\xf7\x63\xb2\x18\x99\x0e\x93\xe6\xd4\x2a\x65\xd1\xdd\x9f\x77\x39\x36\x6c\x33\x46\x53\x27\xfe\xa7\xee\x7a\x99\xcd\x2d\x47\x19\x2b\xec\x35\x79\x70\x2d\xc0\xfc\xa7\x9f\xa0\x0b\x54\x99\xe6\x07\x97\xc0\xbf\xab\x2a\x54\x7e\x6d\x53\x94\x3b\x99\x82\x54\x9d\xde\x97\xee\xac\x90\xae\x26\x6e\x0c\x2d\x9d\x26\x64\xfa\x7f\xdc\xdc\xcc\x8e\x39\xff\xcb\xbe\x59\x5b\x83\x11\x53\xc9\x0c\x16\x63\x12\xcd\x89\x18\x18\xc5\x09\x8a\x43\x6a\x7a\x3a\x9b\x01\x9f\x87\xa3\xbc\x1b\xdc\x26\x63\x3f\xb8\x74\xd0\x00\x8f\x08\x97\xa0\x5c\x80\xdf\x33\xc3\x90\x30\x2d\xa9\xf6\xe7\x8f\x2a\x3f\x1a\x10\xff\xe9\x27\x64\x9a\x80\x6a\x16\x00\xca\x5e\xaf\x10\x64\x4d\xce\xf6\xf6\x0e\x87\x94\xc5\x06\xf8\x26\x41\xfd\xe3\xf7\x68\x78\x3b\x9c\x60\x47\x74\x15\x46\x5f\x6c\x4e\xd0\x1b\xe8\x36\xb3\x08\x9b\x45\xe1\x90\xb0\xb6\x98\x8e\x50\xb6\x19\xe9\x30\x2e\x96\x8e\x71\x4a\x0c\x9d\xe1\x54\xa2\x17\xbb\x73\x50\xbd\x5c\x27\x0d\xc3\x4b\xa9\xc2\x2e\xeb\x29\x86\x77\xf4\x17\x40\xd1\x2d\x07\x25\x9d\x72\xc5\x60\x68\x66\x4b\x36\x9e\x31\x35\xbb\x73\x52\x31\x7f\xdf\x73\x52\x26\xc2\xde\xcb\xaa\x2e\xaa\xc5\x00\xce\x43\x57\x4f\x6a\xb1\xba\x6f\xcc\xf8\x6b\xcd\xe2\x5b\xe0\xfd\xa0\x0b\x95\x48\x56\x8b\xed\x13\x41\x5d\x52\xa4\x3d\xa7\x3c\xfb\xf9\x73\xb9\xa0\x58\xca\xb2\xda\x01\xbe\xb8\x9e\x27\x8c\xe8\xe4\xac\xc2\xa2\x80\x3e\x5f\xf2\x01\x45\x62\xc6\xc2\x4a\x8e\x7e\x91\xec\xfc\x85\x90\x28\x06\x45\x36\xc8\x4e\x9b\xcf\xb7\x1b\xf5\x47\xe9\x3b\x4d\x87\x96\xf2\x29\xd0\x74\xe8\xbd\x28\x8b\x8a\x3c\xb5\x39\x02\x73\x86\xf2\x84\x0e\xbd\x22\xcd\x49\x35\x77\xf4\x2d\x42\xb3\xc0\x2a\xd7\x6a\x90\x9c\x0a\xd4\x84\x35\x44\xb4\x7e\xca\x88\xfc\x24\x5a\xff\xed\x44\x6b\xc9\x8e\x90\x27\x0c\x7f\x50\x9f\xee\xfd\x81\x1b\xa8\xc2\xb4\x3f\x70\x53\x57\x6d\x7c\x43\x75\xef\x79\xbe\xde\xa7\x53\x37\x4a\x76\x58\x41\xd9\x4d\xdb\x7e\x25\x08\x2a\x2f\x68\x9a\x77\x2a\xa3\xc3\x97\x3f\x88\xcb\xbf\xd3\x24\xf2\x83\xcb\x3b\xf0\x60\x32\x7e\x20\xe2\xf8\xc0\x0d\x94\x6f\xbf\xba\x93\x39\xbe\x43\x57\xe4\x1f\x76\xe5\x43\x80\x8f\x70\x84\x8b\xee\x8b\x1d\xdd\x24\x03\x22\x29\x31\xcc\x54\xa1\x3b\x19\x3b\x80\x16\x39\x12\x38\xb4\x31\xc3\xf6\x07\xda\x41\x3a\xe4\x90\x04\x7f\xe0\x06\x95\x24\xac\x72\x45\x16\xe8\x97\xc8\x77\xae\x8f\xaa\x98\x6c\xb4\x48\x4d\xc8\xf3\x52\x59\xf1\xa9\x6a\x89\xc2\x64\x9e\xdd\x2b\x46\x2d\x38\x83\xba\xed\x47\x44\xc2\x33\xfa\x3e\xf1\x8e\x9d\x85\xcc\x1f\x5c\xee\x15\xd4\x67\x2d\x54\xaa\xd9\x1e\xa6\x6d\xa6\x92\x11\x74\xc7\x28\x47\x83\xcf\x8b\x70\xb6\xc7\xc9\xb8\x26\x79\xa3\x57\xaa\xd0\x10\x43\x39\x88\x13\x3f\x99\x53\x39\xce\x60\x6c\xe7\xe1\x59\x18\xfb\x89\x8c\x2a\x03\x2c\x70\x04\x38\xc3\x89\x8f\x83\xc4\x60\xc7\x52\xba\xf1\x8c\x79\x0a\x6b\xc7\x34\x94\x8b\x62\x65\x18\xc8\xf4\x3e\xa1\xe8\x82\x5d\x10\xe4\x68\x1e\x78\x60\xa0\x3a\xc4\x51\xe2\xfa\x82\x22\xac\x8b\x4b\xcc\xf4\xa2\xab\xec\x8b\x2c\x30\x81\xdd\x32\x2b\x8d\x4d\x04\x99\x5d\x2d\x0f\xa0\x2c\x3d\x8b\x60\x08\x49\x28\xc9\xcc\x04\x7a\x8f\xb6\x21\x93\xec\x64\x8e\x7b\xf4\x1f\x21\x49\x0f\x33\x99\x96\xec\xd3\xc4\x68\x22\x9d\x25\xc8\x39\xe1\x0f\x11\xe7\x9d\x88\xf3\x54\x54\x99\xce\xe3\x04\xb6\x4a\x3c\xc5\x41\x22\xc8\x69\x70\x9b\xe0\xb8\xd5\xac\x32\xa9\xff\xc7\x6a\x66\x66\x59\xc9\xc7\x98\xcf\x38\x3b\xa1\x1c\x00\x25\x63\x34\x0f\xfc\xff\x99\x63\xe4\x7b\x38\x48\xfc\x91\xaf\x31\xef\x92\xb3\xcf\x87\xa9\xc4\x9c\x43\xab\x16\x2e\xeb\xc2\x8e\x25\xed\x5f\x2f\x33\x74\xc1\x87\xbb\xe2\x0e\xfc\x6a\xcd\x4d\x08\x27\xae\xf1\xa1\xe6\xc0\xff\xfd\x30\x64\x91\x91\x84\xf9\x88\xda\x22\x6d\x64\x77\xd5\x67\xbd\x16\x11\x8c\x09\xdf\x78\xd6\x6b\xb5\xee\x2e\x9c\x4e\xb9\x04\xee\x5c\x39\xdd\x29\x97\xd2\xf1\xa5\x7c\xb1\x10\x12\x89\x65\xe4\x0e\x93\x30\xba\x75\xa8\x5a\x1c\x86\xf9\x07\xc2\xdb\xc9\xa1\x22\x1c\x21\xd1\xa9\xcd\x4d\xf4\x8c\x06\x11\x7b\x46\x0b\xfd\xb0\xb6\x86\xfa\xe1\x74\x1a\x06\xff\x3c\x25\x8f\x99\x51\x48\x7f\xb1\x36\x38\x5e\x95\x67\x64\x30\x22\xfc\xac\xea\x20\xe9\x15\x0e\x86\xab\x03\x37\xc6\xdd\xb6\xf6\x61\xea\x75\xf4\xa2\x57\xb3\x4f\xde\x48\x7b\x39\xf4\x67\x63\x1c\xad\x52\xc8\x64\x76\x7e\xb8\xfb\x8f\xff\xf5\x03\x9e\xc4\x18\x49\x1d\xa2\xba\x7f\xda\x1f\x3e\x16\xcf\xd0\x4f\x3f\xb1\x0f\x35\x77\xea\xa5\xfd\xdb\x3a\xdc\x26\xbf\xe8\xa7\xca\x39\xc7\xdb\x41\x2a\xba\xf0\x4c\xb0\xa4\x1f\x28\x72\xf0\x5b\xc6\xe9\x42\x0c\xb6\x8a\x1c\x6f\x8c\xc6\x5f\x41\x95\x41\x14\x5e\xc7\x38\xaa\x92\xd7\x62\xe4\xc2\x30\xa9\xf5\xa3\xdb\x59\x12\xfe\xf3\x94\x57\xbf\x83\x23\x9b\xbc\x75\x89\x12\x54\x97\xf8\x43\x45\x3b\x06\xfe\x80\xa8\xb2\xe6\x74\x1c\x46\xc9\x70\x9e\xc4\xec\x15\x59\x54\x7d\xb4\x89\x78\xfd\x97\xf2\xfb\x0f\x13\x7f\x40\xbe\xd5\x26\xfe\x40\xfe\x00\x4a\xbb\x3e\x74\x90\x7c\x26\xc5\x6a\xd2\x3b\x15\x86\x3b\xb9\x0c\x01\x08\xf9\x01\xeb\x82\xe3\x72\x10\x86\x9f\xe6\x33\x94\xb8\x83\x09\x96\xf1\x39\x7d\x7d\xf4\x3b\x3f\x71\x8a\x97\xfb\xef\x7e\xfd\x60\xfc\x70\xfa\xfe\xf5\x87\xc3\xfd\xdf\x3f\xd4\xad\x5f\x1a\xd6\x2f\x4d\xeb\x97\x96\x19\x01\x6b\x5b\xf2\xd7\x6c\x7b\xf2\xd7\x6c\x9b\xf2\x57\xd1\x6e\x3a\x4c\xfd\x70\x3a\x23\xe7\xd4\x89\x61\xb8\x8c\xd3\xac\xd5\xf3\xc2\xf9\x80\x1c\x34\x48\x3d\xa9\x04\x70\x65\x05\x17\x24\x9b\x74\xf8\x10\x4d\x13\xf9\xe8\x15\x6a\x76\xba\x2f\x91\xff\xfc\xb9\xda\x82\x10\x41\xd1\x2b\xd4\x68\x6e\x64\x3f\x92\x3f\xef\xdc\xbf\x40\x9b\x04\xca\x2b\x50\xc5\x2b\x05\xe8\x8d\x72\x5e\xbd\x0a\xad\x58\x45\x7f\xa0\xfa\x4d\xa3\x31\xc8\x40\x90\x9e\xef\xc4\x98\xb1\xfe\xff\xe6\x4e\x3e\xa1\x37\xbb\x95\xe6\x1f\x1b\x55\xad\xdf\x37\x2c\x54\xa8\xfa\xd2\xd7\xdf\x2e\x36\x18\xd2\x90\xc7\x83\xf0\x46\xfb\x0a\xc6\x18\xa4\xdd\x1b\x1f\xfd\x81\x2a\x37\x69\xcf\xd8\xef\xa6\xf4\xbb\x25\xfd\x6e\x57\xf5\x5e\x03\x98\x4a\x7c\x83\x7e\xf9\xe5\x17\xb4\x01\x45\xe3\x1b\xf4\x13\xaa\xdf\x8c\x46\x74\xa8\xba\x2d\xbd\x0e\x59\x3a\xe7\x37\x64\x4c\xe3\x1b\xfd\x1b\x5f\x5a\xe7\x31\x14\xb8\x79\xa9\x8c\xa4\xd6\xb5\xe9\x7c\x92\xf8\xb3\x89\x3f\x04\xc5\x85\xa1\x93\x37\x84\xc0\xbd\xf3\x9b\x0b\xbd\x19\xf8\xd8\xa6\x1f\x9b\xe6\xaf\x1b\xf4\x6b\xfb\x22\x17\x85\x78\x3e\x40\x20\x33\x39\x68\xea\xdf\xa0\x61\x38\x99\x4f\x83\x58\x5d\x18\x32\x58\x22\x75\x54\x3c\xe8\xdd\xcf\x84\x8e\xea\x0d\x3e\x66\xec\xb1\xde\xa8\xd7\x33\xa3\x2c\xd6\x3a\x1d\xb6\x4a\x02\x93\xd4\xae\xa2\xcf\xe4\x37\x1d\x7a\x5b\x9d\x86\x5c\xa7\xd1\x95\xea\x34\xba\xd6\x4a\x4d\xb9\xd2\x46\x15\xa5\x95\x9a\x59\x1a\x10\xfc\x82\x56\x4a\x72\x07\xcc\x0f\xae\xe4\x41\x23\x8f\xe5\x07\xee\x66\x43\x1a\x26\x46\xb0\x6d\xf6\xaa\xce\x5f\x34\x95\x91\xcd\x1f\x58\x85\x91\x32\x9a\x2b\x35\xba\x0a\x8f\x55\x2a\x16\x0d\xb1\xc2\x7f\x95\x9a\x45\xe3\xac\xf0\x66\x56\x33\x7f\xb0\xe1\x0a\x04\x54\xd9\x44\x52\xce\xb0\xcb\x1f\x6f\xcc\x9c\x92\xb1\x86\xcd\x85\xd8\x24\x54\x6a\xa2\x3f\x90\x77\x4e\xfe\x77\xb3\x81\xfe\x40\x37\xcd\x8b\x8b\xcc\xea\x82\xc2\x3e\xfa\x63\x13\x4a\xde\xf8\xd9\x12\x1a\x2b\x85\xdf\x77\x15\x76\x41\xc0\xb7\xa2\xe3\x08\x0f\x69\x37\x3d\x74\x32\x0c\x03\xb6\x27\x49\x7b\xd9\x49\xff\xe8\x1d\xd9\x54\xea\x37\xf5\xba\x83\xea\x37\xf5\x06\xfc\xb7\x09\xff\x6d\xc3\x7f\x37\x1c\x20\x0e\xf2\xdf\x26\xfc\xb7\x0d\xff\xdd\x80\xff\x36\x06\xe4\xbf\xad\xae\xbc\x05\x92\xb3\x17\xc5\xed\x67\xb4\xb5\x73\x4a\x93\x20\x20\x2a\x60\x21\x22\x55\x44\x7e\x32\x9e\xd6\x44\xa1\x35\x09\x1f\x52\x7e\x93\x49\x21\x35\xfa\x20\x49\x2a\x35\x7c\x93\xb0\xa8\x14\xa2\xf3\x1f\xbc\xf0\x04\xc7\x38\xe9\xe9\x9a\x74\x7d\xc2\x4f\x3f\xf9\x33\x66\x84\x1d\x8e\x50\x70\x12\xc2\x09\x70\xec\xc6\x68\x80\x71\x00\x7e\x1d\xec\x2e\xcf\x0d\x3c\x30\x91\xf4\x7c\x0f\x05\x61\xc2\x2c\x5f\x0d\xc4\x41\xb3\x33\x71\x50\xdc\x52\xf7\xc3\x27\x7c\x7b\x1c\xf9\x61\x74\x42\x2d\xb1\x37\x37\xd3\xf7\x66\x62\x12\x06\x76\xfa\x14\x1b\x7a\xa1\x09\x84\xfc\x8f\x9b\x75\x6e\x9a\x71\x48\xdf\x9a\x18\xf9\x27\x7c\xfb\x5b\x18\x81\xb1\xe8\x27\x7c\x5b\xbb\x26\xbf\x2d\xe5\x4e\xfd\x3f\x31\x2b\x16\xfb\x97\xaf\x09\x87\x42\x6b\xa8\x9d\xbf\xc4\x84\xe7\x46\x04\x23\x65\x80\xcc\xc7\x90\x23\x9a\x3e\xf3\x36\x9f\xa3\x6e\xc9\x46\xc8\x30\xc4\xc3\x31\x26\xa7\x1c\x44\x44\x74\x53\x4f\xe2\x93\xf0\x9a\x80\xaf\xf0\x96\x9e\x93\xdd\xfd\xe7\x82\x9e\xc8\xa0\x2d\xe3\xc3\x1b\x96\x86\x5c\x7a\x77\x9e\x59\xc8\xa9\x51\x2e\x41\x89\x0a\x2e\xf4\xe7\x2b\x86\x25\x7b\x36\xc9\x30\x88\x11\xa2\xa8\x40\x07\xcb\x5c\x90\xfc\x49\xd8\x9c\x43\xa5\x0b\x3a\xc4\x30\xfd\xec\x8d\x89\x19\xe5\x30\x35\x24\xed\x3e\x19\xf0\x10\xe3\x29\x3b\xa4\x32\xee\x3f\x32\xec\xff\x21\xb0\xb7\xa3\xcf\xa6\xe3\x24\x4c\x10\x21\xd2\x9c\x52\x89\xbc\x65\x68\x3b\x46\x3e\xf0\xd3\xf9\xa0\x14\x70\x10\xc1\x38\xd8\x0b\x69\x3f\x84\x0f\xe9\xe6\xc6\x24\xbd\x0b\x69\xe3\x93\x4b\x6c\x28\x05\x00\x59\x06\x99\xbd\x2e\x44\xf8\xd0\xbf\x01\xee\x9e\x8b\xf0\x1f\x9b\xc0\xeb\xcf\xd9\x60\xaf\xa5\xa4\xf2\x19\xd5\x19\xf6\xa6\x89\x47\xe9\xe4\x03\xa1\xb1\xd5\xf8\x0b\xea\x12\x7e\xa7\xcd\x1c\xda\xdc\x44\xed\xc2\xd9\xfb\x06\x07\xd8\xdc\x6d\xeb\xc0\xdb\x56\x51\x86\xf6\xd9\xb8\x5c\xa0\x3f\x40\x0a\xc9\x2e\xab\x32\x2c\x5f\x16\x0b\x0b\x18\x90\x1f\x5c\xbd\x35\xf0\xa0\xcc\xeb\x1c\x36\x44\xca\xa6\x9c\x48\x3c\xa5\xcc\x88\xbf\xb2\xf1\x23\x99\x97\x31\x36\xbb\x2a\x2a\x99\x89\x19\xce\xa5\xbc\xa5\x7f\xe4\x91\x90\x95\xd1\x3c\x34\xd7\x6a\x9b\x01\x16\xa3\xff\x0a\xb5\xc1\xfd\x88\x3e\xe4\xae\x07\x75\x5a\xce\x39\x08\x2e\xb3\x2e\xda\x9d\x1c\x70\xaa\x0c\xaf\x2e\x2c\x42\x9c\xaa\xa8\x6e\x59\x5f\x17\xe8\x8f\x9c\x25\x6b\xf9\x53\x45\x79\xf3\xba\xd4\x31\x68\x9d\xab\x0b\xd4\x36\x15\x76\x81\xd8\x51\xe6\x09\x07\xc3\xe8\x76\x46\x6d\x8f\x65\x31\xf1\xd0\x41\xe1\x68\x14\xe3\x24\x3b\x45\x74\xdd\x78\x61\x5f\x54\x4c\x4b\x3b\xd9\x9d\xdd\x49\x8f\x9f\xe9\xcf\x46\xfa\xb3\x99\xfe\x6c\x39\xc0\x7e\x94\x93\x8b\x86\xaf\x87\x17\xc6\x97\xb0\xd5\x6b\x77\x86\x9a\x81\x07\xe2\x6b\x3b\x19\xdb\x44\x1f\x42\xf1\x87\xe7\x14\x10\x91\x7a\x32\xa3\xab\x7c\x54\x0b\xb7\xf2\x0a\xb7\x2c\x87\xad\x32\x63\xa9\xd2\xae\xa3\x12\xac\xfa\xd8\x50\x1f\x9b\xea\x63\xcb\x11\xfa\x11\xc3\x56\xbf\xb6\x86\xf6\xc9\xe1\xfa\x9b\x19\x2a\x1b\x09\x28\xc3\x65\xa4\x01\x07\xdd\x8f\xfe\x8c\x24\xc4\x0e\x17\xe5\x05\x74\xe3\x10\xbf\xc1\x2c\x38\x2e\xdc\xb7\x52\xa1\x9f\x60\x6b\x52\xb1\xd5\xa5\x51\xbb\x80\xd7\x7f\x28\xfc\xb8\x6e\xd4\x3c\xc5\x0d\x7d\x66\xb4\x6a\xd9\xa9\x82\x6a\x4d\xb5\x5a\x53\xaf\x66\xd6\x73\xc5\x2d\x7d\x6a\xb5\x6a\x2d\xb3\x02\xec\xad\x76\x10\xb1\xa8\x19\xe4\x0d\xd3\x7c\xfc\x38\x31\x1d\x9b\xc4\x8e\x4d\xc7\x77\x13\x35\x5e\xb2\x9f\xaf\xf8\x6c\xb1\x17\xb6\x9d\x1a\x66\xdc\x1f\x25\x40\xfe\x8e\x45\x4f\x97\x3f\x87\x1c\xff\x84\xcc\xa3\xa4\x25\xaa\x0b\xb1\xed\x0f\x49\xcb\x56\x89\x1b\x19\xa1\xed\x0f\x49\xa1\x56\x89\x9b\xba\xc8\xf6\x87\xa4\x3a\x8b\x5b\xd2\xeb\xcc\xa6\xfd\xfc\xb9\x71\x9f\x00\xec\x1a\x2a\x76\x0d\x0b\x76\xcd\x02\xec\x5a\xb9\xd8\xd5\x97\xc5\xae\xa9\x62\xd7\xb4\x60\xd7\x2a\xc0\xae\x9e\x8b\x5d\x63\x59\xec\x5a\x2a\x76\x2d\x0b\x76\xf5\x02\xec\x1a\xb9\xd8\x35\x8b\xb1\x33\x13\xf0\xfb\x19\x98\x54\xc5\x89\x9b\xe8\x02\x31\xf9\x03\xfe\x92\xd4\x4d\x9d\x03\x1e\x92\x64\xd4\x77\xf0\x89\xcc\x48\xd2\x34\x7e\x22\xc3\x91\x64\xf4\xf5\x16\x5d\x8d\x71\x71\x15\xf1\x44\x58\x4b\x15\x7a\x86\x91\x16\x92\x7e\xfe\x31\xac\x25\xfd\x00\x94\x5d\x4e\xca\x09\x28\x5d\x4f\xd5\x92\x44\x21\x16\x13\x47\xaf\x61\x47\x2f\xbb\x98\x32\xe8\x65\xd6\x93\x8a\x5e\x7d\x29\xf4\x9a\x12\x7a\x4d\x3b\x7a\xd9\xd5\x94\x41\x2f\xb3\xa0\x54\xf4\x1a\x4b\xa1\xd7\x92\xd0\x6b\xd9\xd1\xcb\x2e\xa7\x0c\x7a\x99\x15\xa5\xa2\xd7\x2c\x81\x9e\x81\x66\x31\x0f\xee\x6e\x91\x5e\xe8\x26\x6d\x5a\x54\xba\x30\x94\x5d\x5b\xea\xd6\x6b\x5a\x62\x19\x19\xa9\x95\x23\x24\xb1\xd3\x75\x0f\x35\x3b\xdd\xb5\x56\x93\x6b\xc1\xab\x16\x5d\x34\x97\x6e\x84\x34\x15\x33\x57\x70\xa6\x9b\x5e\x89\x59\xf2\x35\xe4\x93\x5d\x7a\xe4\x0e\x71\xaa\xa4\x4e\xc1\xfc\x17\xbe\x71\xa7\xb3\xf4\xf8\x2d\x7d\xe2\x93\x4c\xe1\x25\xf8\x26\x91\xae\xea\x6b\x5b\x3b\xa7\x35\x76\x14\xa9\x4c\xb9\xb5\xff\x27\x7c\xeb\xa0\xe1\xe8\x32\x3d\x0f\xa4\x60\x66\x13\x97\x60\x72\x93\x20\x1d\x0c\x3b\x21\x54\xd2\x86\x8c\x90\xb8\x66\xbd\x6f\x50\xa5\x7f\xa0\xf1\x7f\xf7\xf0\x64\x86\xa3\xca\xd6\x0e\x33\x56\xe0\x57\x08\xff\xf1\xbf\x7e\x60\x46\x3a\x72\xc3\xd4\xfd\x00\x8a\x80\xad\x8c\x62\x36\xd1\xeb\x34\x1d\x6e\x78\xd1\xeb\x80\x99\x8c\x64\x7a\xd1\xeb\xb4\x9d\xd4\xe6\xa2\xd7\x01\xaf\xd3\xa9\xd7\x79\xd6\xeb\x36\xee\x2e\x9c\x4e\xf3\x7e\x66\x31\x5f\xd8\x1e\xe6\x51\xad\x56\xbe\x82\xfd\x09\x5b\x28\x3f\x23\x66\x26\x42\xf0\x40\xc3\x70\x3a\x0b\x03\xc8\x4a\x00\x1f\x09\x39\x09\x6a\x98\xf8\x83\x1a\x2b\xfc\xf9\xb3\x6c\xd8\x20\xbc\x76\x1f\xc1\x90\xc5\x8d\x71\x6a\xc1\xe2\x82\x7f\x88\xf8\xf8\x5b\x18\x79\x10\x7e\x40\x94\x10\x6f\x14\x18\xf3\x11\x98\xd0\xc1\x5a\xd8\xe2\xb7\x51\x29\x54\xe3\x67\x15\x3b\x0c\xfe\x6e\x7d\xb2\x98\xe5\x0f\xef\x93\xd1\x06\xc0\xc1\xc1\xb0\x46\x1e\x74\xd4\xbb\x6d\xf1\x99\x3e\xe6\x5b\xde\x88\x4f\x3b\x57\xb3\xb7\xdb\xbb\xe9\xbd\x18\x7d\xb6\xdd\xb8\x0d\x62\x6a\xbe\x48\xd6\x1d\xbf\x75\x4b\xf0\x74\x36\x71\x13\x33\x3f\x13\x51\xd6\xff\x1d\xb0\xb0\x4e\x5c\x9d\x0b\xee\x1b\x82\x39\x82\xee\xd1\xff\x13\xd7\x78\x78\xd4\x1e\x6a\xa3\x4a\xa3\xb9\x81\x06\x7e\x12\x57\x73\x21\xfa\x57\x06\x80\xfb\xbf\x2e\x0d\xef\xc3\xce\xbb\xfe\x87\xdf\x77\x8f\x4e\x0e\x3f\x1c\x1e\x6d\xef\xa0\x2d\x08\x6a\x91\xb8\x41\x82\x22\x3c\x8b\x70\x8c\x83\xc4\x0f\x2e\xb9\xea\x87\x10\xe6\x34\xf4\xa4\xfe\x1b\x81\x6e\xef\x94\x02\xca\xb8\x6f\x16\xa8\x7c\x93\xa9\xd9\x5b\x89\x47\x33\x81\x99\x6e\x36\xa5\x69\xa5\x28\xf7\xc1\xa7\x7f\x1e\x81\x29\x87\x48\x9f\xa3\x94\x51\x2b\x48\x7d\x14\x6b\x81\xcc\x05\x3a\x1b\x63\x32\xfa\x49\x88\xe6\xcc\x1f\x83\x30\x08\x44\x0a\x03\x70\x15\xe8\x9a\xf4\x34\x1c\x5d\xf6\x80\x98\x39\xc6\x55\x75\x4f\xce\x22\x0d\xdb\x4c\x4c\x1b\x60\xe4\xe8\x07\xd6\x89\x31\xf6\x82\x9a\xae\x4a\x5d\x20\xa4\x48\xfa\xf0\x09\xdf\xd6\xcc\x85\xb9\x57\xef\x70\x74\x89\x2a\x47\xd0\x90\x3b\xa9\x42\xa5\xa1\x69\x18\xcb\x8e\x85\xd6\x1a\x0f\x85\x4b\xa7\xf7\x8e\x90\x0c\xef\x22\x21\x9c\x61\x7e\xc7\xc8\xa9\xc5\x1f\xe6\x95\xd0\x64\x0d\x43\x11\xa4\xc8\x1c\xb2\xa0\xc0\xef\xd0\x6b\x74\xa7\xdf\xa1\x23\x1e\x46\x15\x76\xdf\x07\x63\xe9\xa0\x7f\x23\xff\xaa\x87\xfc\xab\x94\x7f\xde\xa9\x66\x15\xea\xfc\xab\xb0\x7a\x4a\x98\x31\x26\x80\x64\x94\x0d\x72\x36\x1e\x0a\x80\x5d\x9d\xab\xab\xd8\x24\xc3\x64\xa5\xbe\xb2\x14\x66\x5b\xa5\x4f\x14\xf6\x58\x14\xb6\x8d\x1f\x8e\xc2\x04\xac\x7b\x52\x98\xca\xd2\x97\xa4\xb0\xfd\xc0\x4f\x7c\x77\xe2\xff\x89\x63\xe4\xa2\x00\x5f\x4f\x6e\x19\x9a\x1e\x1b\x95\x32\xd4\xc5\xb7\x99\x9b\x51\x18\x4d\x0f\x43\x0f\xa3\x1d\xea\x45\x08\x91\xc9\x53\x7e\x18\x46\x32\xed\x82\x89\x3a\xb8\x61\x72\x4a\x16\xbb\x92\x85\x30\xbf\x45\x2a\x7e\x40\x2a\xab\x64\x3f\x98\xf8\xc8\xd2\xf4\xe7\x07\xbe\x62\x4c\x24\xa6\x4b\x22\x1e\x93\xf2\x7c\x6b\x36\x23\x64\x01\x83\xc6\xb3\xd1\xeb\x3a\x5b\x4a\x9f\xa3\x4b\xae\x46\x1f\x8e\x2e\xf9\x3e\xca\x68\xd2\x70\x22\x4f\x88\x2c\x4e\x3d\x15\xc2\x68\x4a\x49\xc0\x35\x6a\x8f\x28\xc9\xa7\xf4\xb5\x99\xd2\x9a\x7e\xd0\x16\x57\x58\xf4\xfe\xd3\xaa\x0b\xf0\x29\xe9\x53\xd7\x0a\x63\x77\xc0\xa4\xaa\xb2\xd0\x7a\x02\xa3\x24\x95\x61\x43\x08\x8f\x58\x34\x07\xfa\xbc\x07\xa0\x28\xb6\x3a\x0d\x38\xaa\x93\x1e\x95\x32\x21\xa3\xc6\x54\x9e\x9b\xb8\x68\x00\x62\x9c\x56\xc4\x22\xdb\x01\x70\x9a\x24\x26\xf5\x5e\xd7\x61\x1f\xe3\x08\xa6\x77\x18\x06\xc3\x08\x27\x78\x95\x0d\xcc\x24\xbc\x54\x19\xb8\x74\xa3\x76\xb2\xf8\xd0\x43\x54\x15\xe8\x01\xf5\x29\x62\x7c\x07\x7b\x12\xdb\xc1\xde\x42\x9b\xe5\xe7\x98\x39\x20\x11\xb0\x4c\x1f\x4b\xf8\x07\x6f\x85\x35\x21\x35\x50\x6a\xc3\x93\xd8\x98\x80\x46\xa3\xaf\xb1\xf0\x13\x7e\x70\xf9\x40\x3c\x27\x1d\x84\x4d\x4e\x31\xac\x8d\xca\x0a\x69\x77\x45\xa3\x9c\x32\x15\xaf\x39\xfa\x39\x54\xc7\xca\xf6\xb4\xe0\xc4\x74\x0c\x6d\x4c\x06\xf2\x33\x18\xc8\xc1\x85\x4f\x32\x00\x33\x9d\xd1\x36\x91\x7b\xe5\xfa\x13\x77\x30\xc1\xd4\x3e\x53\x5f\xda\xf2\x86\xfa\x81\xf7\x69\x21\x4a\xdb\xf5\x03\xb6\x65\xe6\xee\x6f\x0c\xb6\xb6\x3d\xbd\x0b\x13\xe6\xed\x4e\xc3\xf1\x51\x50\xe9\x66\x83\xfc\x18\xe1\xd1\x08\x0f\x13\xff\x0a\x4f\x6e\x91\x8b\x3c\x1c\x27\xd1\x1c\x9e\x1d\x14\x61\xd7\x5b\x0d\x83\x21\x2e\xb9\x3d\x95\x25\x69\x40\xe4\xf1\x08\x9b\x82\xff\x12\xe4\xcd\x47\x54\xe7\x89\xa5\xea\x2c\xbc\x26\x44\xcd\x32\x8b\x82\x17\x5e\x60\x55\xec\xa6\xd3\x32\x87\x52\x5a\x11\x7f\x94\x0f\x02\xe5\x2f\x22\xa5\xac\xf1\xa6\x67\x11\xe6\x0d\x31\xb4\x08\xc2\x6c\x25\x62\x8f\xc5\x6f\xe5\x5c\x7d\x57\x9e\x1b\xf3\xb2\xcc\xd6\x2f\xa3\x26\x6f\x34\x37\xd6\x5a\x4d\xf5\x23\x55\xcc\x98\xbf\x69\x62\x55\x0f\x35\xb4\xef\xaa\x70\xdd\x43\xcd\x92\x27\xb5\xd8\xa8\x89\x77\x4b\xe8\xe1\x91\x7d\xf1\xf2\x03\x12\x1b\xfa\xb3\x31\x96\x64\x0b\x96\xec\xce\x45\x63\xd0\x77\x13\xf1\xb5\xd4\x5a\xe5\xe2\xf1\x56\xc0\x71\x82\x78\x12\x7c\xe5\x13\x31\x8c\x2d\x7d\x43\xa7\xbe\xd8\xc9\x8c\x59\xcd\x67\x55\xb3\x9a\x96\x3f\x23\x39\xe7\x2c\x43\xa5\x66\xcf\xee\xb9\x46\xfe\xc4\xb7\x18\x4f\xf0\x30\xa1\x6d\x9f\x26\x91\x9b\xe0\xcb\xdb\x8a\xd5\xec\x5d\x52\x9b\x83\x20\xba\x89\x56\x28\xdf\x5d\xb1\xdb\xcc\xb1\x89\x39\x76\xe3\x98\x30\x93\xd7\x6e\x8c\x3d\xd5\x8d\x51\xfe\x2b\xb0\x98\x63\xc0\x4e\x71\x04\xa7\x3b\xb2\x1b\xe6\xc0\x2a\x64\x04\x7a\x1e\x4e\x76\x3d\x93\x67\xf3\x6f\x45\x8d\x51\x98\xcc\x04\xb3\x77\x46\xb9\x96\xb6\x69\x3c\x39\xf3\x94\x88\xbb\x28\x8a\xa5\x83\x72\xee\xa4\xf4\xa1\x70\xac\xa6\xb1\x6c\x35\xf4\x32\xa3\xa0\x5d\x52\xdd\x0f\x75\xf5\xfe\xcb\x41\xf9\xf7\x60\x3a\xf6\xa6\xc9\xcd\xb0\x79\x85\xa1\x56\xaa\x5c\x1d\x6d\xbd\x5d\x54\xf5\xee\x71\x12\x61\x77\xba\xa4\xfa\x1d\x04\x32\xa6\x2f\x97\x1d\x1b\x5a\xcd\xd5\x81\x4f\x2d\xdf\xd5\xc3\x13\x15\x72\x20\x36\xbb\xa4\x4c\x6f\xa0\x4a\xab\xa9\xe9\xd2\x65\x0d\xf5\x29\xe0\xa8\xe9\xa9\xf5\x97\x79\x7e\x37\xbb\x86\x9d\xda\xb8\x3f\x73\x99\x73\xe6\x46\x70\xba\x33\x4a\x9c\xd9\x7d\x11\x8e\x51\xa9\xc9\x19\x97\x42\x7f\xfc\x71\x65\x34\x99\xc7\xe3\x95\xb2\xfb\x23\x85\x93\xb3\x43\x8a\x01\xef\xa1\x46\xd1\x3c\xc3\xc1\x1a\xb2\x15\xcf\x94\x0b\x62\x45\xf7\xff\x61\x4a\x8f\xdf\xfd\x1a\xfb\xf1\xef\xbb\x52\x64\xa3\xb8\x4a\x41\xd5\x2c\xe9\xc8\x0d\x49\x17\xba\xec\xc0\x9f\xf1\xee\x66\xef\x65\x95\x7d\xfe\x25\x83\xac\x4d\x9d\xf2\x34\x79\xa9\xf8\xbe\xc4\x56\xbc\xa5\xf6\xcb\xac\xb8\xd4\xf3\x34\xa5\xb7\x14\x40\xef\x5f\x6c\x2f\xe5\x33\xc7\xb7\x4a\xd0\x1d\xf7\x5f\xf7\x33\x5a\x74\xce\x7b\xfc\x2b\xea\x30\xb5\x9c\xd2\x3c\x85\x92\xaf\xd4\x14\x95\xb9\x16\x4c\xaa\xb8\xb4\xb2\x5c\x4c\x6f\x7a\x1e\xfb\x9b\x4f\x6f\xaa\xc2\x5e\x78\x7a\x8d\x1a\xeb\xb2\xd3\x2b\x2a\xdf\x73\x7a\xf3\x34\xd5\x65\x6f\x41\xbe\xf4\xf4\x3e\xc0\xe4\xe5\xac\x8e\xc2\xd9\xd3\xf5\xbd\x79\x53\x46\x37\x22\xa1\xa2\x1e\x1a\x85\x45\x66\xd1\x7e\x85\x36\x91\x7f\xa5\x4c\x5e\xd1\xde\xc2\xb6\x5d\x1a\x24\xbd\x3f\x76\xfd\x00\xd2\x04\xd9\xef\x98\x5f\x83\x09\xc5\x07\x3e\x0e\x68\x33\x27\xc2\x44\x46\x13\xa8\xec\x3c\xa4\x76\x96\x40\xe4\x71\x4a\x1b\xd4\x76\x17\x71\x13\xfc\xb2\x80\xf5\xbc\xee\xf3\x7d\x44\x3f\x7d\xc9\xed\x28\xf3\x49\xba\xf7\xba\x6f\xda\xb8\x0c\x4d\xd0\x66\x8e\x45\x70\xda\x84\x6b\x57\x28\x01\xbb\x09\x33\x9d\xaf\x65\x2a\x65\xa1\x68\xf4\x4c\x65\x2e\xa1\xae\x61\x22\x58\xc8\x25\x2f\xa4\x31\x4e\x64\xbc\xf8\x61\xa6\x6d\x04\x0a\xfb\x79\x3d\xc6\x2c\xe3\x04\x45\x11\xe2\xcb\xc6\xa5\xf0\x33\xac\x1a\x4b\x51\xf2\x07\x53\xcb\x04\x28\xea\x82\x01\xf9\x2b\xa1\x1f\xc2\xab\x24\x23\x30\x2b\xf3\x82\x52\x85\x65\xc6\x2b\x41\x85\x63\x37\x36\x37\xfb\x2e\x23\xfd\xea\x47\x5e\x66\x36\xbb\xe4\x54\x48\x16\x6a\x26\xf1\xca\x6a\x2d\xfc\xfb\xd1\x09\x9c\xd9\x19\x19\x1a\x0a\xdd\x84\x11\xf4\x2e\x55\xd7\x3b\x48\xe9\x9d\x93\xb6\x6c\x3c\x61\x30\x5c\x64\x9f\xa3\x4a\x66\x98\xcd\xd8\x9d\xe0\x29\x06\x59\x1f\x36\x67\x4a\x11\xec\xba\x0d\xb4\x0e\x10\xaa\x00\x5e\x1b\xea\x73\x19\x19\x5f\xf1\x1c\x0b\x94\xf3\x42\x86\xfa\x0a\xc7\x5d\x58\x57\xda\x3b\xa1\x38\x52\x95\x59\xd3\x1e\x2e\xb5\xa6\xc5\x16\xf7\xb4\xa6\x6d\xf8\x3d\xad\xe9\x25\xd6\xf4\xbd\x56\x0d\x98\x64\x8f\xfd\x78\xf1\x35\x63\x46\x86\x11\x39\x30\x99\xdf\x8f\x4e\xec\xfc\x41\xf6\xf1\xcb\xf2\x87\x7b\xb3\x25\x33\x76\x67\xe9\x08\x0d\xf0\x30\x9c\xb2\xf5\x44\x98\x86\x1f\xce\xe3\x05\x78\x8b\x18\xb3\x45\xb8\x87\xa0\x2d\xde\x9b\x8a\xb5\x0b\x0b\x7a\xa7\x81\xb0\xc5\xe5\x2e\x73\x04\x87\x71\x18\xc6\x18\x4d\xfd\x1b\x22\x52\x99\x3a\x0a\x5e\xbc\x06\x99\x0f\xc9\xc4\xc9\x65\x3a\x2b\x29\x86\x57\x20\xf5\x92\x43\x55\x3c\x1f\xc4\xf8\x7f\xe6\x38\x48\xcc\x0a\x0f\xa4\xca\x8a\x72\xb6\x1b\x75\x48\xed\x4a\x4c\x19\x2f\x6d\x92\x4a\xdd\x5b\x90\xfd\xd0\x88\x9b\x29\x94\x56\xba\x14\xcd\x01\xb5\xc8\x1f\x4c\x68\x6a\xc3\xef\x5f\xa0\x3f\x36\x69\xc5\x73\xbf\x28\x86\x8d\xf4\xc4\x4d\xcf\x5f\xf7\x79\x1d\x2d\xb6\x8d\x2c\x35\x1f\xbb\x9e\x47\x26\xb5\x50\x29\x33\x83\x14\x72\xfd\x1a\xfd\xd7\xaa\x92\x39\x7e\xdb\x3f\x45\xff\xbb\xb3\xb6\x8e\x66\x0c\x72\xcc\x94\x8f\x66\xc0\xc7\x9f\x86\xf1\x3a\xc8\xe1\x33\xd7\xab\xf1\xa7\x5c\xd9\xfb\xd8\xe5\xb7\xf0\xf3\x98\xe7\x8c\x10\x91\x71\x98\xa9\x38\x44\xfe\x16\xb8\x2c\x68\xbe\x06\xb0\xe5\x4b\x78\x82\x9a\xb9\x96\x59\xeb\xc8\xe2\x86\x49\x97\xb0\x00\x29\x16\x01\x55\xc9\xd8\x40\x48\xd5\x2f\x72\x74\x17\x47\x3e\x31\xc4\xe4\x57\x7a\x9f\xe8\xe8\x71\xd7\xd4\x7b\x76\xd7\xd3\x6f\x13\xef\xc1\x6c\x44\x45\x1a\xfd\x66\x53\x1a\x39\x7b\xfc\x98\x79\x90\x08\x72\x02\x3f\x30\x03\xe0\x80\x51\x72\x06\x2e\x7d\xb1\x4a\x73\xce\x8b\xb0\x3b\xff\xd0\x0a\x98\x5b\xa6\x17\x5f\xbc\x69\x43\xdc\x0d\x9a\x60\x11\x3e\x13\x02\x82\x98\x38\x0a\x22\xa9\x6f\x52\xe6\x3d\x73\x48\xca\xbc\x07\x37\x24\xe5\x6d\x09\xe4\xf2\xf1\x8a\x0b\xc2\x56\xa4\x7c\x4a\x6d\x17\xf9\xe8\xb9\x35\x0a\x83\x0c\x9f\x66\x75\x90\xde\xe4\x4a\xc6\x1a\x86\x68\x33\xf5\x3f\xe0\x3a\x08\x19\xb8\xa3\x62\x65\x36\xcd\xd8\xf2\x3c\xcb\x58\xc0\xc4\x0f\xc3\x60\xe8\x26\x1c\xec\x42\x6a\xa1\xf7\xc1\x4c\x70\x1c\x58\xd0\x63\xd7\xa3\x61\xaf\xd8\x32\xfe\x52\x6c\x68\x1e\x64\x18\xd1\x97\xe3\x18\xd0\x78\x29\x1b\x04\x28\xa9\xb3\x0c\x23\x9f\x78\x83\x13\x25\x33\xb9\xb4\xc2\x21\x48\x31\x9a\xb8\x71\x02\xcf\x25\x16\x7c\x2a\xbf\x9f\x57\xd4\xb5\xbe\x8a\x1a\x55\xea\x2c\x78\xc1\xdc\xfa\xcc\x8e\xe2\x54\x00\xc9\x21\xa2\x14\xe2\x66\x66\x81\xca\x9b\x31\xdd\x74\x17\xbf\xb4\xf8\x3a\x57\x5d\x46\xbf\x11\xcb\x45\x89\xe9\x92\x24\xf7\xa6\xeb\x41\xfd\x30\x0e\x43\x0f\xdf\x51\x45\xe6\x99\x38\x22\xd2\x9b\x1e\x38\xb3\x48\x9d\xea\xbf\xee\x5b\xc1\xb0\x99\xbb\x13\x14\x47\x80\xe9\xe2\x4a\x16\x24\xac\x03\x2b\xd5\x83\x6f\x07\x1b\x07\xc9\x32\x55\xa7\x7a\x82\x2d\x60\xe7\xe8\x27\x49\xda\x7e\xb6\x99\x3b\xcd\x49\x64\x11\x6b\x4b\x3a\xef\xda\xd7\xbe\x64\xd6\x59\x64\x58\x99\x17\x31\x4f\x35\xc5\x35\xf9\xeb\x82\x68\x4e\x06\x43\x55\xe5\x22\x55\x23\x4d\x0a\x4c\xa9\x95\xad\xad\x1f\xe9\x4c\x1b\xce\x1d\x19\xc3\x5d\x2e\xce\xab\x16\x38\xf6\xc3\x09\x81\x0b\xbb\x29\xa8\x57\x40\x33\xa0\x5d\x3a\x59\x4e\x15\x6b\x3f\xe7\x23\xa0\x9a\xf8\x54\xd1\xcf\x6b\x8b\xe3\x20\x34\x3f\xd6\x83\xd3\x5b\x8c\x67\xc8\x4d\xd0\x04\x13\x6e\x19\x06\x7c\x61\xb0\xdc\x37\xd4\xd8\x16\x36\x7b\xe0\xcc\x06\xe6\x86\xc4\x61\x6a\xea\x07\xd4\x0e\x97\x29\x12\xb2\x01\x3a\xb5\x67\x56\x8d\xce\xa4\xd4\x09\x4a\x58\x53\xb0\xfc\xa6\x27\x6e\xff\x0a\xfd\xf4\x93\xf9\x4e\x21\x1b\xbf\xe5\x78\x39\xbd\x4a\x8a\x8d\xaa\xdb\xb1\xeb\x08\xb2\x4d\x97\xbe\x98\xcf\x91\x72\x53\xc1\x46\x58\xaa\xb3\x57\x46\x22\xe7\x4d\x3e\x34\x71\xaf\xad\x91\xc3\x12\xcb\xa5\x67\x93\xdf\xe0\x2c\xc0\xcc\xe7\x40\xb6\x87\xdf\x25\x14\x22\xdc\x30\x81\x1a\x5e\x5a\x4f\xe9\xcb\x99\x26\x3c\xe2\x72\x7b\x6c\xd4\xcd\x4d\x82\x14\x59\x34\x15\x54\xc8\x32\x35\x59\xc2\x94\xf2\xfe\xe6\x1b\x60\xc6\xc8\xc5\x17\xab\xad\x0e\x1a\x86\x93\x09\xa6\x2b\x23\x1c\x71\xd9\x02\xe4\x57\x0c\x19\x2c\xf3\xa5\x17\x49\xc2\x95\x5c\xfd\xc9\x16\x1c\xb9\xd7\xd2\x2b\xb3\xbb\xa9\xd9\x3f\x87\xc6\x22\x10\x82\x4e\xa9\xea\xe9\x2d\x2b\xa4\x37\x61\xdc\x92\x02\x20\x6b\x37\x6b\xfc\x6c\x83\x14\xbb\x13\xda\x01\xf8\x01\xd0\x40\x79\xea\xd2\x40\xb8\x38\xf2\xaf\xa8\xb4\xc3\x19\x8a\x19\x22\xbf\x3a\x4e\x0f\x11\x92\x19\xa6\x21\xf4\x6f\x39\xc9\x68\xa9\xce\xe5\x4b\x48\xc3\x31\x9e\x2e\x09\xd8\x2c\xba\x32\x5d\x3f\x18\xa9\x8f\x24\x80\x66\x18\x34\x27\xea\x5d\x9a\x33\x95\x1e\x92\xa8\x98\xc6\xdf\xea\xa2\xdc\x30\x0c\xae\x70\x94\x28\xe2\x30\x4d\x2c\xc9\x6d\x53\xc1\x88\x96\x9a\x50\xe6\x39\x25\x1f\xd3\x4a\xaa\x6b\xb2\x78\x59\xda\x52\xa8\xd8\x2b\x4e\x45\xaf\xcc\xd9\x51\xb8\xa3\xc9\x38\x69\xc6\xb7\x6e\x20\x32\xc1\xcd\xc2\x38\xf6\x07\x13\x9c\xb3\x82\x4d\x8d\x2d\xea\x8d\x96\x0e\x58\xd6\xc4\x96\x7e\xe3\x67\xfe\x7f\x67\xc1\x20\xa1\xf4\x27\x6b\xba\x27\xfd\x4e\x5d\xd4\xcc\xb5\x3e\xe1\xdb\x9e\xea\xca\x66\x2e\xa7\x79\xb7\x59\x4a\x91\x95\xdd\x83\xff\x16\x95\x14\x0b\xb5\x97\x75\xc2\xb3\x54\x61\x67\x02\xdd\x30\xc3\x52\x5a\x1c\x14\xd4\x43\xfa\xdb\xfe\xe9\xba\xa5\x86\xc4\xe2\xdb\x96\x22\x62\x2d\x49\x60\xe9\xbb\xda\xd1\x0c\x07\xa7\xa7\x07\xd9\x7a\x8b\xf8\x01\xca\xa4\x60\x11\xdb\xa6\xfe\xcd\x7e\xa0\x16\x5c\xc8\x36\x8b\x2e\xf0\x78\xc1\x15\x8e\xec\xcb\x29\xcb\x67\x34\x1f\x4f\x0b\xab\x21\xa7\xc6\x3c\xf0\xdc\x78\x99\xbb\xc9\xc0\xce\x01\xbf\xfd\x91\xaf\x2f\xff\x5c\x48\x90\x4c\x2f\xa6\x99\xf4\x20\x39\x23\x4e\x7d\x62\x53\xac\x83\x90\xbe\xd1\x38\x24\x8e\x90\x1f\x23\xfd\xf6\x77\xf9\xd5\x4e\xbb\x20\x2e\x1f\xd9\xb2\x7f\x8e\x56\x56\x2c\xbe\x2e\xc6\x0a\xb5\x24\xa4\x29\xb9\xac\xce\x35\x05\xd5\x2c\xe4\x9b\x43\xab\xbc\xaa\x4c\xaf\x62\x8c\xac\x96\x67\x69\x11\xf4\xf9\x33\xa5\xe0\xb4\x52\x8d\xcf\xe7\xad\x38\x5b\x67\xf5\x43\x36\x01\x8b\xd2\x5d\xf1\x8d\x0c\x6d\x0e\x2e\x65\xc4\x4f\xeb\xbd\x0c\x1b\x06\x13\xcd\x9a\xe1\xb3\x0a\x22\x01\x39\xec\x78\xea\x98\x16\x5d\xd4\x88\x25\xe9\xda\xd7\x63\xc0\x1b\x5a\x1d\x86\xd3\x99\x9b\xc0\x86\x54\x7e\x8d\xca\xdb\x88\xb6\xf1\x49\xc2\x53\xf9\x9d\xd4\xb4\x36\x97\x43\xf0\x21\xed\x2e\x43\x8a\xc1\x29\xa7\x7c\x0b\x8d\x4b\x54\x67\x65\xa3\x2a\xe9\x8b\x0a\xe5\x79\x75\x91\x52\x48\x8e\xde\xa5\xac\xd0\xf4\x8b\x31\x4c\x28\x11\x9d\xb5\x1a\xe4\x9d\xf9\xbc\x0c\xdd\x36\x9c\x96\x49\x0d\xbb\x9e\xe7\x5a\x0a\x72\x94\xb9\x70\x38\xaf\xdf\x74\x5a\xdd\x46\x77\xb8\x0e\x99\x3b\xba\x9d\x6e\xbb\x33\xea\x8c\x2e\xaa\xfc\xea\x00\x60\xf3\x87\xb4\x33\xb6\xc3\x6a\x19\x24\xec\x43\x62\x3d\xdd\x89\xea\x29\xc7\xa3\xe1\x90\x96\xdb\x2c\xf3\xd6\x9f\xec\x56\xb6\xb8\x30\xca\x57\x50\x4a\xbb\xf7\x58\x4c\x6a\x1c\x0f\xbe\xdc\x97\x5a\xe1\x0f\x1f\xd4\x23\x2b\xe0\x6a\xcb\x72\xe6\x46\x31\xae\x28\x8b\x38\xf7\xbe\x35\x8a\x15\xe5\x53\x5a\xd1\xec\x1f\x42\xca\x23\x1a\x28\xae\x68\x41\x52\x52\xc9\x20\x94\xaf\xfb\xcd\x05\xca\x6f\x17\xa5\x83\x37\xcf\x80\x92\x85\x78\x86\xe3\x84\x5a\x77\xb8\x13\xd3\xf2\xd5\xc0\x9e\xd7\x2f\xd0\xe6\x26\x4a\x17\x26\xfa\xe9\x27\xbd\xe9\xf3\x06\x2b\xc3\x17\xac\x55\x13\xb6\x73\x43\xaf\x5d\x0c\x6d\x23\x95\x09\x65\x78\x83\xd6\x26\x33\x71\x6a\x3a\xa8\x5d\xcd\x35\x48\x0c\xaf\x98\x4e\x00\x2e\xb3\x52\x28\x86\x0a\x99\x26\x66\xd0\x46\x3d\x73\x37\x9f\x29\xaf\xdc\x4a\x35\xba\xa5\x39\x89\xf1\x04\x66\x39\x6c\x39\xd2\x01\x48\x93\xfb\x0b\xaf\xbb\xf8\x12\xbd\x8e\xdc\xd9\x0c\x84\x53\x37\x61\x38\xc8\xfa\x1a\xe4\x12\x39\x21\x96\xbc\x09\xf3\xd7\xb6\xea\x8d\x95\x71\x42\x4c\x7d\xb2\x4c\x9f\xca\x3b\xf4\xdc\xe3\xb6\x4a\x88\x4e\xfc\x08\x91\x77\x68\xe0\xfa\x09\xb9\xcf\xac\xcb\xd4\xbf\x37\xf0\x28\x15\x89\x13\x4c\x7a\x31\x65\x3a\xa1\xe5\x86\x1d\xcb\xb8\xa0\x02\x4e\xbd\x8c\xcc\x27\x4f\x73\x51\xa8\x32\x76\x57\x42\x26\x91\xf9\x42\xde\xcf\xef\x38\xd5\x82\x99\x8e\x54\x39\x51\x07\x58\xeb\xd4\x10\x87\xfd\x4e\xe3\x0d\x7c\x47\x61\x7f\xcc\x9b\xde\xd6\xb7\xb0\xe5\x91\x05\x6b\xd6\xeb\x64\x97\x9b\x70\x95\xcd\xaa\x43\x14\xaf\x59\xdb\x79\xef\xf1\x5a\x4c\x83\x1b\x65\x74\x19\x5f\xb4\x75\x47\x2c\x40\x8b\x04\x91\xab\x6a\x31\x38\x3b\xdb\x9d\x92\x97\x8d\xbd\xb4\x60\xd8\xa5\x1d\xa3\x8b\x80\x14\xe0\x22\x4c\x3d\x80\x4c\x11\xf6\xcc\x3e\xc8\x19\x71\x26\x75\x88\x11\x41\x32\x58\x97\x97\x94\x68\xfa\xd0\xcd\x14\x2c\xbd\xd7\xce\x02\x62\xb6\x57\x84\x29\x0b\x77\x6b\xdb\xc6\xb5\xc0\xee\x9b\xbb\xcf\x2b\xfb\xb1\xa1\x24\x57\x78\x9a\xbe\x11\x3a\x13\x3d\xac\xf9\x57\xa6\x32\x92\xe2\x92\xd1\x8f\xa1\x10\x55\x55\xa6\xa0\xe0\x82\xd7\x50\x4e\x28\x29\xd3\xa2\xec\x95\xa9\xb4\xa4\xa0\xd4\x2d\xd7\x4d\xc5\x25\x65\x25\x21\xc6\x91\xe9\x34\x78\xb7\xd0\x79\x88\x5d\xb2\xc7\x62\x1a\x85\x1a\x4e\xb9\x4a\x42\x8f\xb8\x91\xc9\x04\x21\xf6\x32\xed\x82\x4c\x7a\x84\x6c\xfc\xdf\xeb\x8e\xa6\x05\xf1\x11\xa1\xba\xbf\xd8\x2e\x96\x06\x07\x2f\x66\xe7\x3c\x5c\x82\x81\x9d\x73\x42\x64\x41\x34\xa4\x10\x0a\xcb\xb3\xf6\x87\xc6\x51\xdf\xc0\x1e\x74\xef\xb1\x06\xac\xb0\x44\x95\xf8\x42\xdb\x0f\x53\x6f\x48\x7a\x0c\x79\x75\xe9\xb0\xe5\x1d\x85\x5d\xeb\xc3\xf9\x58\xee\x41\xca\x67\xcc\x2d\x32\x06\x62\xd8\x58\xe4\x69\x54\x36\x3c\x25\xe0\x27\x1d\x9e\x74\x1b\x93\x98\x8f\xaa\x6a\x32\xef\x26\xa2\x91\xa5\x94\x40\x46\xa6\xa7\x8f\x9a\x76\x71\x04\x3a\x2e\x37\x8e\xe7\x53\xec\xa9\x37\xa3\xee\x24\xc2\xae\x77\x2b\x6d\x8e\xca\x31\x6f\x1e\xd0\x8c\xb0\xa5\xc2\xe4\x2d\xc6\x14\x2d\xcc\x6d\xa1\x73\x18\xe1\x6a\x60\xf1\x1f\xc5\x78\x89\xdd\xc0\xae\xa8\x9a\x07\x8b\x43\xfb\xca\x82\x7b\x66\x1d\x50\xdd\xd5\x11\xa7\x08\x94\xae\x08\x0b\x7f\xf8\x90\x51\x66\xc9\x8b\x8a\x55\x37\x66\xda\x67\xa1\x8d\xe4\xc5\x59\x14\xe1\x88\xdb\xbf\x50\xf6\x95\x5d\xc3\x99\x9b\x18\x94\xaf\xad\x65\xf0\x72\x95\xb4\x59\x35\x88\xed\x56\xe7\xad\xd9\x14\xa4\xf8\x9a\xe7\x93\x37\x82\x3b\x1e\xfa\x6f\xe1\x05\x4f\xa1\xc9\x89\xe1\x92\xe7\x2d\x6d\x82\x34\x55\xf6\x6e\x67\x9b\x34\x01\xb6\x0b\xa4\x41\xb2\xd6\xf7\x7f\xe5\x0a\x8a\x19\x8b\x2f\xb5\x88\x9a\x98\xd7\x61\x96\x26\xec\x01\xa4\x1c\xd2\x10\x80\x2e\xf0\xc1\x49\x03\xef\x63\x6a\x4b\xe2\x07\xcc\x06\x9a\x19\x3c\x30\x43\xa1\x4b\x1c\x80\x19\x74\x01\x38\x11\x75\xdf\x02\x8d\x86\x80\x2f\x00\x96\x55\x4f\x80\x0a\x4d\x92\xb1\xb6\x50\xb7\x0d\xe6\xda\xf0\x81\x1b\x1d\xef\x8f\x50\x38\xf5\x89\x68\xe1\x20\x97\x7e\xba\xf6\x27\x13\x34\xc0\xa2\x45\x0f\x45\x6e\xe0\x85\xd3\xc9\xed\x83\x69\x11\xa8\x89\x08\x1b\x2a\x07\xed\xff\xea\xc0\xcc\x92\xe6\xbf\x18\x9f\xa2\xf3\xed\x65\x99\x94\x44\x9c\x35\x7c\x83\x87\xf3\x04\x57\x56\x78\x28\xb3\x15\x87\xe5\xb1\x71\x98\x15\x9b\x4d\xaa\x7a\x20\xf0\x0e\x5a\x21\xa3\x42\xfe\x5f\x8f\xe5\xa8\x9c\xcd\x29\x20\x99\x01\x72\xda\x76\x38\xbd\x3a\x8c\xd2\xa8\x8e\xd5\xe2\x27\x41\xa7\x9c\xcd\xb8\x4d\x7d\xfe\xa3\xfd\xfa\x2b\xa3\xd9\xa6\x90\x2a\xdd\xf6\xda\x46\xb9\x28\x8d\x74\xc1\x4b\xab\xdd\x20\xeb\xd0\x88\xc8\x34\xc3\x46\xaa\x52\x16\x21\x14\xd3\x6c\xe4\x6c\x6d\xdd\x55\x6b\x2c\xc5\xbe\x34\x2c\xd0\x09\x4b\x48\x65\x42\xad\x49\x01\x12\x60\x74\x9e\x51\xe1\x8b\xd4\xec\x4c\x79\xcf\x33\x38\xf3\xd1\x47\x3f\x1b\x14\xed\x4a\xa2\xf6\x34\x9b\xba\xcd\x51\xed\x84\x09\x63\x8b\x1e\xfb\xd3\xa3\xbb\x10\xca\xef\xa1\x6e\x37\x69\x22\x14\xdd\xbb\xc7\x58\x37\x67\x89\x1a\xd7\x76\x52\x60\x16\x11\xee\x3e\x9a\x7a\x43\xec\x41\xa1\xaa\x37\x7f\x33\x69\xd8\x1e\x59\x73\xff\x76\x7b\xf7\x0e\x91\xfd\x96\x9b\x97\x9a\x36\xee\x54\x58\xe4\x1c\x39\x7f\x33\x5c\x50\x5f\x6f\xe8\x76\x8e\x5b\xc9\x27\x6f\xd4\x93\x76\x73\x99\x60\x16\x57\xdc\x33\x87\xb6\xc5\x36\xf2\x6f\x45\x93\x9f\x2b\x50\x7c\x1b\xea\x8f\xef\x4a\xa1\x6f\x58\x94\xa5\x34\xdc\x2b\x7c\xcc\xad\xb1\x8e\x1f\xbf\x65\x07\xfd\xfb\xd1\x55\xeb\xe9\xc6\xf5\x05\x15\x1c\xda\x66\x1c\x26\x56\x75\xb3\x49\xe6\x21\x2d\x10\x71\x87\x8b\x39\x52\x17\xe8\x28\x0b\xc9\x84\x3d\xd3\x2d\xd2\xee\x77\x4b\x45\x61\xda\xc3\x6c\xc7\x6a\xb0\x23\x2b\x48\xd4\x2c\x81\x26\xec\xf7\x06\x8a\x96\xc6\x7e\xe9\x22\x87\xf8\xc8\x4c\x95\x8a\x82\x7c\xcd\x90\xc5\xe4\xd0\xbf\xa1\x79\x70\xa0\x8a\x79\x6c\xa5\x53\x3c\x35\x5e\x55\x1a\xb0\x6b\x6b\xcc\x27\xca\xfb\xe9\xa8\xbf\x0e\xcf\x7e\x68\xa5\xf5\x77\xc0\xbc\xbf\x5d\xdd\xb5\x89\x5f\x2e\xaa\xbc\xbe\x1f\xef\x7c\x70\x1c\xb3\xca\xeb\x87\x63\xee\x25\x75\xd7\x5f\x85\xbf\x7f\x0d\x05\xf6\x57\xd8\x51\x1c\xc5\x8c\xc9\x7a\xee\x7b\xd0\x2d\xa6\x9c\xa6\xde\x7e\xc7\x62\xda\x61\xe4\x81\x2e\xbd\xc9\xe4\xaa\xee\x65\x6d\xa2\x9c\x57\x56\x49\x1f\xcb\x72\xc5\xde\x5d\x38\x9d\xd6\xb7\x9c\x00\xf6\x51\xf2\xbd\x2e\x93\xe7\x55\xc9\xef\x6a\x40\x30\x9b\xea\x35\x9b\xe2\x95\xd7\xb6\x26\x79\x05\xad\x6d\xda\x86\xf8\xa9\x26\x7a\x3d\x74\x93\xb1\x83\x4c\xe9\x5e\xa5\xc3\xfc\x41\x38\x74\x27\x68\x16\x4e\x6e\x47\xfe\x04\x85\x23\x44\xf7\x3a\xa6\x38\x30\x9e\xaf\x59\xae\x86\x4d\xb5\xa8\xd6\xb8\xca\xc6\xc4\xfb\x5d\xf2\xe1\xee\xa5\x29\x98\x94\x64\x8d\x3a\xf8\x98\xe5\x82\x60\x3c\x39\x1f\x90\x69\xcd\x12\xfa\x6e\x6d\x16\x85\x49\x48\x3e\xa2\x4d\x72\xbc\xc9\x16\x61\x75\xd1\x26\x0a\xf0\x35\xc1\xa3\x08\x4a\x30\x9f\x4c\xac\x4b\x2a\xc5\x24\x5d\x50\x72\x28\x2c\x4b\xfc\x58\x3e\x51\x45\x1a\xf9\x3c\x2d\xfc\x81\x3f\x88\xdc\xe8\xb6\x58\xab\x2f\x25\xe9\xcd\x83\x07\x49\x7b\x99\x72\x96\x08\x2c\x7c\x0c\xdc\x09\xf2\x83\x31\x8e\x7c\x35\x9c\xb0\x1a\xb6\x43\x4f\xf8\x6b\x88\x70\x6b\x9a\xeb\x52\x41\x25\x79\x28\x6c\xf0\x5d\x14\x0e\x1d\x63\x37\xe1\x78\xb1\x08\x2e\x54\xc2\xca\x1e\x69\x91\x2e\xe0\x20\xa3\x50\x17\x5e\xe1\x28\xf2\x3d\x1c\xa3\x63\xaa\x9d\xf1\x71\x4c\x37\x82\xd9\x2d\xf2\x03\x96\x82\x3c\x45\xa1\x54\x1b\x7a\x7e\x92\xb3\xc5\x41\x64\x05\x3a\x5b\xc9\xc5\xc2\x52\x92\x79\x3b\xbc\x3d\xa3\x44\xae\x48\x4e\x79\xf6\x9b\xb2\x23\x9f\x8f\x27\x5e\x0f\xad\x40\xca\xb9\x95\x8c\xf5\x8c\xa5\x59\xf2\x37\xc5\xc9\x38\xf4\xf2\xa3\x1e\x48\xc5\x33\x89\x20\x8c\x4e\x81\x48\x97\xba\x10\x68\xc5\x49\x2f\x14\x13\x77\x3e\xcd\xf6\x50\x99\x33\xf7\x3a\x30\x7c\x92\x38\x0f\x91\x43\xd2\xec\x95\x76\xc3\xec\xad\xf9\xe5\x14\x07\x26\x23\x6c\xb2\x35\x15\xa0\x82\x52\x6e\xc5\x0e\x7d\x69\x05\x4b\xe2\x13\x33\x16\xcc\x84\x8c\x3b\xe5\xf9\xc2\x1f\x58\x0f\xd7\x82\x84\x76\x9f\x35\x3b\x76\xe3\xa3\xeb\x80\xad\x87\xdb\xca\x0a\xa9\xba\x52\x15\x5e\x68\xe4\x11\xb6\x54\x5e\x9e\xbc\x28\xee\x0c\xad\x96\x3f\xfb\x86\x6a\xff\x4f\x3c\x9f\x11\x79\x2e\xf0\x93\x9a\x4b\x04\x61\xb6\x85\xba\xd1\xe5\x9c\x8c\xb2\x79\x54\x90\x29\x6b\x48\xee\x70\xa5\xfe\xd2\xd1\x4a\x8c\xd2\xad\xc0\xa7\x7a\x6c\x4e\x02\x74\x09\x1b\x40\xc8\xdd\x54\x76\x12\xeb\xb6\x85\xb8\x52\x7f\x84\x23\x1c\x0c\x49\x1b\x30\xe0\xb3\xcc\x5a\xce\x0c\x07\x93\xc3\xcd\x30\xed\x9b\x14\x32\x67\x87\x31\xf2\xdf\x1d\x58\x43\xb1\xcc\x5f\xa9\xba\x7e\x1e\xd0\x11\x81\xf9\xa4\x6b\xda\x10\x89\x77\x8b\x4f\x4f\x9a\xdf\xa9\x52\x15\x57\x8c\x44\x7c\x87\xf0\x84\x00\xa5\x52\xfd\x2b\x70\x55\x1e\x7a\x1f\x6d\x32\x06\xcb\xaf\x5f\x4a\x30\x2c\x5a\xb2\x80\x35\x66\xdb\x81\xe5\x28\xc5\x77\xcf\x2e\x6b\x9e\x0e\x40\x5a\x3e\xfc\x9d\xb6\x84\xec\x84\xc4\x2b\x2c\x4b\x49\x79\x91\x08\x6c\x73\x87\x8e\x18\xd3\x63\xa9\x30\x80\xcc\xc0\x4d\xc1\xf3\x50\x1c\x4e\x31\x4d\xde\x86\xae\xc7\x38\x40\xb7\xe1\x3c\x12\xae\x0c\x2e\x91\x9a\x29\xf4\x47\x88\xea\x7c\xef\xed\x53\xf7\x5b\xcf\xdd\x02\x11\xe5\x10\xb5\x9a\x61\x80\xc4\x2c\x2c\xbf\x4d\x16\xe3\x52\x76\x8a\xfb\xe1\x8c\xc8\x4d\xb3\x54\x84\x62\xa2\xd3\xbd\x64\x33\x09\x1c\x68\xc2\x14\x01\x6d\x0a\xfa\xd3\x47\x98\x62\xb6\x78\xe9\xde\x5b\x5a\x10\x5a\x7e\x16\xa0\x21\xe5\x02\x5f\xf4\xd3\xcc\x04\x44\x54\x4d\x7e\x9f\xf8\xce\x9d\x82\xf5\x48\x51\x45\xc4\x36\xfa\xb4\x9c\xbe\xd5\xcb\x10\xab\xf9\xfb\x33\x99\xdb\x73\xb9\xfc\x05\xda\x94\x30\x50\x3f\x2d\x94\xec\xcb\xba\x43\xef\xa0\xeb\x30\x58\x49\xa8\x6c\xce\xbd\x53\xa5\xe0\x98\x93\x30\x9c\x21\x77\x10\x5e\x99\x36\xd0\xfc\x8e\xaf\x70\x70\x2b\x39\xdd\x06\x76\x2b\xda\x95\x7b\x2b\xde\x96\x4a\x4d\x57\x76\x51\x89\x13\x10\x74\x18\xac\x82\x16\x5b\x4f\xa6\x1d\x73\x38\x09\x03\xfc\x48\x9c\x11\x60\xa3\xcd\x74\xdb\x81\x17\xa5\x36\x40\x52\xb0\x78\xff\x93\x93\xf2\xa8\x82\x16\x67\xbd\x66\x1b\x3c\xdb\x41\xdd\x66\xe3\x10\x20\x17\x3c\xa8\xb5\x58\x97\x05\x81\xa7\x32\x99\x0b\x0a\x80\x98\xe2\x16\x09\x6b\x10\x35\xe2\x66\xec\x5f\x06\xfe\xc8\x1f\xba\x41\xc2\xc2\x97\xfa\x74\x18\x00\x26\x6d\xc8\x7c\x48\xff\x4d\x72\x07\xa7\x27\x75\xf9\xcd\x83\x84\x13\x32\xa0\x90\x21\x14\x4b\x7e\x07\xd9\x4e\xad\x68\xd0\x91\xd1\x8a\x4e\x0c\x98\x76\x35\x53\x38\x76\xf8\x41\x93\x1f\xc9\x5e\xf7\x8a\x5c\x90\x31\x14\xb2\x5d\x69\x94\x87\x70\x5e\xbf\xa9\xd7\xeb\x8d\x7a\xb3\xde\x72\x50\xfd\xa6\xde\xae\x77\xea\xdd\xfa\xfa\xc5\xe3\x41\x76\x50\x77\x81\x58\x3c\x2c\x18\x22\x9f\x99\xec\x52\xbe\x66\x3e\xdd\xb0\x8e\xf9\x03\xfd\xf7\xf3\x67\x1a\x47\x5a\x17\x55\x46\xa8\x22\x66\xfa\xc7\x4d\x93\x5e\x53\xfe\x03\xc0\x92\x61\x15\xff\xb9\x80\x71\xae\x0e\x82\x12\xcb\x04\x07\x97\xc9\x98\x19\x68\xd9\x79\xcc\x42\xa1\x84\xd2\xe5\xb3\x68\x00\xa1\x9d\x60\x18\x7a\x64\x11\x60\xfa\x43\x5f\x03\xf0\x3a\x3f\xe6\xac\xa0\x07\x1c\x0c\x6b\x7b\xf8\x26\xaf\xd5\xa2\xb8\x42\x25\xf9\xc0\x12\x11\x7f\x52\x0a\x2e\x13\xee\xc7\x10\xc2\xa2\x30\xd6\x8f\xa1\x8e\x32\x34\xef\x93\xd1\xc6\x82\x21\x7e\xd8\xa4\xd8\x03\xfc\xf0\x59\xfb\xfc\x19\xed\xe1\x9b\xfc\x98\x3e\xc5\x14\x35\x74\x13\x1c\x30\x81\x41\x25\x29\xdb\x3e\x91\x43\x59\xd2\x25\x74\x3a\xf6\x67\x8c\x67\x4a\xc4\x0a\x09\xb9\x17\xbf\xd6\x2e\x8f\x4f\x39\x62\x11\x38\x36\x78\xfc\x14\xf1\x46\x37\xd4\x55\xec\xe0\xa0\xac\xce\xba\x68\xf8\xf1\x45\xe3\xd2\x90\x41\xfe\x2d\xc3\xd7\x4c\x1e\xa6\xc9\xd8\x15\x51\x2d\x52\xb2\xcb\x29\xee\xc7\xa7\x29\x1f\x52\xf8\x92\x0d\xfc\xa9\xca\xb7\x68\x0b\x52\xa5\x6c\xd7\xfa\x13\x77\x3a\x43\xf8\x06\xa2\x96\x0e\xfc\x4c\x17\xe9\xcd\x32\x29\x64\xba\x3b\xa1\x37\xca\x43\x63\xc8\x1c\x05\xff\x7f\xd8\x62\xfd\x03\x04\x22\xe5\x06\x18\x36\x69\xe4\x26\xc8\x45\x89\x3f\x35\xc9\xf2\xa6\xbc\x02\x72\xb7\x73\x52\xa0\xc8\xa3\x44\xca\xa2\x4d\x82\x21\x9b\x90\x73\x9f\x47\x71\x27\xff\x54\x9a\x6d\xb4\x8a\x2a\x3e\x45\xfa\x67\xb4\x51\xad\xa6\xd1\xdd\xad\x07\x04\x0a\x48\xed\xf5\x73\xe4\x8b\xf8\xf0\x9f\x37\xd3\xb6\x5f\xbd\xe2\x8d\x18\xca\x8b\x56\x4b\x9d\x29\xec\x1b\x99\x3c\xb2\x74\xd1\xdd\x6f\x64\x73\x12\x36\x94\x1d\x83\x4d\x94\x1d\xf2\x92\x49\xbd\xb3\x44\x29\xf6\xe8\xe7\x9b\x2a\xaa\xe6\x44\x43\xae\x1f\xb8\x83\xcc\xa9\x46\x3a\x58\x2c\xc2\x76\x69\x08\x16\x22\x50\x2a\x42\xa6\x9f\x3c\x84\x58\x99\xae\xdc\x74\xdd\xd9\x18\x19\x29\x50\x3a\x9e\xb4\x89\x7d\x65\x45\x32\x63\x10\x2d\x3b\x1f\xb2\xb0\x14\x93\xe4\x77\x2e\xc0\xf0\x9c\x09\x9b\xb0\xac\xe8\x1f\xac\x8a\x56\x93\xac\x8a\x58\x61\x1b\xa6\xb5\xa0\x48\x65\x9b\xe8\xd0\x4d\xc6\xb5\x21\xf6\x27\x69\xd5\x35\xb4\x60\xe4\x2a\xf3\xa9\xbb\xe4\x76\x65\x31\xe2\xca\x1e\xba\xef\x61\x4f\xcb\x0e\xd9\x32\x79\x64\x4f\xd9\x1a\x79\x14\x9e\xae\x65\xc8\x70\x28\xa4\x28\x2b\xd1\xfb\xb3\x27\xf6\x5a\x96\x6c\x98\xfb\x43\x3d\xc7\x3a\x91\xd4\x5c\x6e\x4a\x24\xe9\x63\xe4\x4f\x26\x3c\x0e\x32\xf3\x5a\x81\xc3\x5d\x19\xe9\x86\x9f\x1d\x03\xd3\x51\x5b\x06\x66\x77\xc0\x2a\x37\xef\x0c\x56\x49\xe2\x79\x48\x23\xbe\x12\x67\x3e\xe6\xa1\xd3\xc8\x3b\xda\xd1\x32\x32\xe9\x04\x96\x33\x9d\xcc\x44\x4c\x27\x38\xf2\x3d\x52\x0d\x04\xa6\x1f\xae\x73\x72\x26\x7c\xb8\x46\x9b\xe4\xbf\xb6\x74\x84\xd3\x0f\x7f\x92\x3d\xea\xa6\xe5\x7a\xb8\xbb\x31\xc8\x24\x12\x10\xe5\xdc\xf8\x13\x92\x19\x4c\xee\x65\x47\x99\xeb\x49\xda\x72\xa5\x7e\xf3\xa2\xde\x7d\x81\x7e\x26\x1d\xf9\x13\x24\x83\xdd\xdd\xdd\xdd\x2a\x7a\x4e\x5f\xfc\xf2\x0b\xaa\xdf\x34\xea\x20\x34\x10\x1c\x6c\x42\x03\xed\x68\xa5\x7e\xd3\xee\x76\xea\x14\xda\xb5\x0e\xed\xba\x34\x34\x18\x66\x1c\xcf\xc1\x1b\xab\x02\x88\xbc\x7a\x45\xab\xa2\xe7\x08\x46\x3c\x1f\x00\xab\xbc\xb6\x09\x95\xd8\x5f\x41\xe1\xe7\x9b\xa8\x5e\xeb\xd8\x0b\xc1\xc8\xb2\xb2\x3f\x53\xd3\x24\x4e\x7d\x55\xf4\x0b\xaa\x75\xd0\x7f\xa2\x06\xea\xa1\xd5\x46\x39\x61\xc7\xc0\x5b\x54\xc1\xc5\x41\xd1\xd0\x1d\x8e\x31\x4b\x39\x55\x42\x74\x21\x55\x3f\x10\xfa\x8c\x2a\x15\x5a\x97\x1c\xcb\x14\x4c\xc9\x0e\x24\x8d\x89\xed\xd2\x8c\x56\xde\x44\x1f\xa2\x0a\xad\x01\x04\xba\x3e\x58\x37\x75\xed\x3a\xcd\x6d\x55\x11\x15\xd2\x26\xd0\x67\x54\x2f\x1f\x98\x3f\xc0\xd7\x92\x5f\x1a\xdc\xac\x32\x55\x4c\x20\xf2\x5a\xfd\xa0\x0f\xaa\xd5\x9f\x98\x29\x17\x8a\x2d\x8d\x70\x30\x04\x4b\x23\xfa\xaf\xd5\xd2\x68\x0f\xdf\x64\x15\x12\x66\x98\xa4\xe8\x26\x85\x5c\xa3\xbf\xcb\x86\x81\xd5\x75\x29\x63\x7c\xb3\x80\x3e\xa5\xc4\xa9\x77\xe1\xe0\xae\x25\x31\x78\x48\xde\x3f\xc6\x37\xd9\x48\xae\x6c\x2c\x25\x25\x43\x99\x54\x5b\xc6\xf8\xad\xcb\x1f\x92\xaf\xcb\x1f\x7b\xe3\xc5\x8f\xb0\x94\x0c\x0c\xb0\xc6\xf8\xa6\x3f\x76\xa3\xf2\x49\xea\xe2\xe2\x83\x24\xe4\x1a\xf4\xe9\x01\xf2\xfa\xbe\x87\x47\x8e\x20\xe3\x04\x00\x97\x40\x69\x57\x53\x75\x54\xa3\x5b\x35\x72\x47\x53\x5d\xd2\x52\x7d\x54\x50\xd9\xca\x47\x04\xc4\x8f\xa1\x1f\x54\x56\x56\x96\x8c\xfc\x2a\x91\x3e\x5d\x8c\x8b\xa9\xa0\xf8\x22\xa2\xd4\xbc\xc8\x5a\xb2\x08\x63\xdf\x8a\x14\xc6\x57\x22\xb5\xa1\x17\x8b\x75\x91\x88\xad\xb4\xd2\xa2\x49\x83\x68\xad\x03\x7e\x58\xa2\x8f\xec\xf0\xb4\xe0\x8a\xba\x5e\x28\xe7\xa3\xdc\x30\xdb\x86\x9b\x79\x19\x6a\xe9\x4a\x6a\x81\xb2\x04\xfa\xbe\x1f\x24\xac\xcf\xb5\x78\x3e\x88\x93\xa8\xe2\x3b\xa8\x59\x75\x20\xc5\x65\xaa\x45\x21\xab\x6d\xa3\x6a\xf4\xb4\x5e\x62\xd3\x54\x86\x6b\x0d\x35\x17\x72\x93\x3e\x70\x13\x3f\x68\x94\xdd\xf0\x58\x69\xbe\xe7\x89\xc7\x65\xb7\x3d\x06\xe0\xeb\xee\x7c\xe5\x91\x78\xc8\x25\x37\x81\x56\xcd\xfb\x1f\xc5\xe8\x6f\xb9\x05\xd2\x61\xf9\xb6\x77\x41\x09\x47\xba\x99\xd1\x59\xac\x8d\xa2\x70\x4a\xde\xf6\x43\x0f\xc3\xfe\xb6\xc0\x5e\x26\xc3\xbc\xe7\x76\xa6\xd0\xf3\x7d\x76\x34\x41\xa2\x0b\x2e\x93\xef\x60\x5f\x63\x2b\x8c\x6e\x6d\xf2\x52\x5c\x64\x77\x13\xf5\x16\xdd\xe0\x44\x45\xb1\xc7\x89\x37\x5f\x62\x9b\xd3\x9a\x2f\x4c\xc4\xee\x4b\x77\x02\x69\xa7\x6b\x43\x46\xea\x5b\x49\xc5\xe7\xcb\x45\xdf\xe5\x2c\xea\xd0\x25\x76\x39\x0d\xe9\x85\x36\xb9\xf7\x67\xbb\xab\x1b\x65\xf7\xb8\xf7\xc9\x68\x43\xec\x70\xec\x61\xd9\xfd\x8d\x36\xfc\x75\xb7\xb7\xd2\x38\x3c\xe4\xc2\x9b\x27\xa3\x0d\xf3\xde\x46\x46\xf4\x91\x77\xb6\x24\xba\xcd\xb3\xca\xf2\xf0\x30\xf4\xf0\xfb\x93\xfd\x3e\x77\x5a\xab\xe0\x78\xe8\xce\x70\x25\x67\xdf\x35\xb0\x72\x34\x74\x93\xe1\x18\x55\x0c\xa9\xdf\x01\x8b\x71\x14\x5e\x03\x41\x43\x5a\xa2\xca\xca\xa1\x3b\x19\x85\xd1\x14\x7b\x6c\x4a\x3c\x37\x71\x0d\x29\x1e\x97\x63\xfa\xf2\x2c\xdf\x87\xe7\xb3\x89\x5b\x8c\x72\xbe\x03\x86\x0f\x64\x47\xd9\x7d\x4a\x9b\x8b\x30\x7b\x56\xcb\x6a\x25\xa1\xec\x28\xf3\x80\x51\x14\x35\x9d\x50\x68\x8d\x03\xaa\x2e\x16\xce\x48\x24\xcb\x86\xac\xb4\xd8\x63\xb9\x02\xa5\xf8\x04\x39\x39\xb3\x25\xb3\xe4\x5b\x29\xe5\xe0\x74\x1e\x27\x68\x80\x91\x4f\x46\x77\x8a\x83\x84\x26\x32\x74\xc1\xe0\x20\xc2\x89\x70\x27\x29\x99\x87\x5b\xcb\x9a\xab\xde\x57\xd0\xe4\xa2\xd4\x35\x2e\x1e\x87\xf3\x89\x47\x9a\xfe\x84\x67\x09\x9a\x07\x33\x9e\xa6\x53\x4d\xd6\x2b\x19\x00\xd5\x8d\xcc\xfa\x35\x1b\x0d\xc8\xee\xb9\x25\xc6\x42\x38\xfb\xd9\x3e\x97\xb6\x27\x84\xb4\xcb\xcc\x00\x4a\x1b\xf1\x15\x96\x0a\x9f\xe5\x15\x4e\x42\xe4\x27\x31\xf7\x5f\x42\x84\xaa\x1f\xe2\x2a\x6d\x60\xec\x02\x4d\x5a\x9d\x77\x97\x56\x2e\x3b\x36\x33\x97\x44\x60\x1c\x6e\xb4\xa5\x80\x5c\xb8\xcc\x1f\x55\xdb\x99\x33\xbc\x8b\x56\x08\xb6\xdd\xc4\xe5\x07\x82\xfa\x22\x42\xec\x96\xe7\xc5\xd0\x10\x4f\xf4\x6f\x19\x76\x46\x1c\x8b\x6c\xa8\x22\x28\x07\x80\x86\x3c\x99\xac\x0d\x66\x1b\x84\x28\x4b\x60\x8e\x19\x94\xb1\x52\xd7\x1f\x57\xb2\x4d\xa5\x46\xdc\xc0\x18\x1f\x6f\x6e\x3f\x50\x94\x2a\x2b\x86\x1d\xa2\x54\xc5\x32\x9b\x2a\x2b\x2b\x53\x08\x69\xce\x48\x25\xd9\x28\x0c\x69\xf2\x47\x39\x00\xae\x34\x50\x2c\xf8\xad\x06\x4b\x76\x79\x07\xb2\x2a\x0a\x65\xca\x88\x4f\xe2\xde\x80\x64\xa9\x40\x7d\x5b\xd0\x41\x2b\x4d\x73\x0b\x2c\x23\xc0\x0c\x25\x3f\xdf\x04\x5c\x8c\x16\x4d\x45\x64\xcd\x73\x10\xc7\xc8\xbd\x72\xfd\x09\x04\x8a\xa3\x9c\x03\x58\x62\x1e\x21\x9d\x49\x5e\x45\x7e\x70\x15\x7e\xc2\xb1\x9e\x15\xbc\xc2\x92\x79\x3b\xe8\x7a\xec\x0f\xc7\x46\xa6\x3e\xb8\xcd\x63\xea\x86\x76\xf9\xfa\x19\x84\xe1\x04\xbb\xc1\x1d\xf2\xc2\xdd\xc9\x3c\x1e\xa3\xdf\xc6\x38\xa1\x71\x71\x78\xba\x68\xf0\xb6\x9b\xb9\x11\xf0\x11\xf6\x2a\xe5\xef\x82\xb1\x2f\x15\x53\x46\xec\x0a\x30\xf6\x0f\x23\x22\x08\xa0\xdb\x94\xb6\x6c\x6b\x89\xa7\xb4\xb6\x86\x76\x59\x10\x8e\x25\xab\xb7\x16\x26\x98\x16\x56\x56\x25\x1d\xf9\x85\x15\x38\x6c\xe9\xa4\x04\x6f\x52\xdd\x90\xf7\xdc\xc6\x0f\xc6\xd8\xaa\xe4\x21\x5f\x25\x73\x3d\xeb\x62\xe0\xe5\x53\x29\x63\x53\x4b\xa4\x9e\x5b\x9a\xc3\x4f\xab\xdb\x82\x4c\xf6\xc3\x79\x90\x70\x82\x33\x31\x1b\x02\x37\xa0\x69\xbf\x4f\x20\x10\xf7\xa6\xda\x89\x35\xad\x55\x1d\x2f\xc2\xac\xac\x83\xcf\x90\x38\x09\xe7\x81\x87\xe6\x33\xea\x22\x3a\x9c\xcc\x3d\xac\xad\x05\x43\x3d\x0d\xa9\xd4\x18\x48\xfe\xb0\x48\x80\x66\x81\x88\x17\x5e\x07\x32\x2a\x61\x30\xb9\x45\xa3\xb9\x58\xab\xa6\x24\x12\x6b\x6b\x68\x82\x63\xea\x2b\x6b\x96\xd6\x80\xa3\x44\x78\xea\xfa\x81\x2a\x9e\x95\xec\xdb\xd4\xbd\xa9\x28\x7d\x83\xeb\x62\xb4\xca\x68\x53\x11\x1a\x9d\x52\x17\xc9\x62\xfa\xa9\xe2\xc3\x3a\xfb\x40\xda\x1c\x17\x05\x83\x9f\x91\x4c\x8f\x56\xea\x02\x42\xb1\x13\x17\xf9\xac\x76\xd5\x0f\x2a\x72\xab\x3f\xa3\xb6\xa3\x50\x9d\xd9\x28\x95\xa7\xe1\x37\x92\x0c\xa1\x43\x09\x66\x81\xb3\x1d\xdd\x0d\xa8\xb2\x87\xfd\x7e\x25\x0f\x84\x78\xfb\x5c\x5a\x64\x76\x1b\x12\x82\x1c\x8e\xc8\xb9\x55\xec\x1f\xab\xe9\x99\x03\x9c\x5b\x2d\x35\x19\xe3\x51\xf7\x2a\xc1\x6f\x1c\x86\xc6\x62\xb1\x02\x58\x2a\xb9\x74\x5f\x80\xf9\x37\x94\x55\x18\xb4\xcc\xe0\xf4\xa4\x72\xf2\xc0\x9a\x50\x51\xf8\x1c\x5a\xdd\x94\x27\xbd\x14\x9d\xf2\x58\xb8\xb9\x28\xdb\xb5\x5f\x6a\x27\x1c\xb9\xf9\x87\x30\x17\x5c\x20\x13\x6c\xbe\x73\xde\xfd\xed\x04\x2d\xfb\xe7\x57\x34\x1a\xfc\x90\xd9\x42\x25\x6c\xcc\x33\x58\x64\x33\xa8\x32\xbb\xf4\x54\x6b\xb5\x6e\x11\xe7\xfe\xb1\x1b\x43\x46\xeb\x9c\x53\xbe\xe1\x44\x9e\x6e\xa3\xea\x61\x5c\x76\x5c\xa3\x94\xc0\xe0\xd3\x18\x80\x38\x46\x61\x20\x1d\xbe\x1b\x5d\x54\xe9\x34\x9a\x60\x31\x5c\x35\x1e\xc4\xf7\x68\x75\x7e\xf0\x16\x8f\xe6\x13\xf8\x43\x05\x2e\xce\x4d\xee\x57\x14\xef\x37\xcf\x55\x90\x8e\x46\x19\x09\xf9\xde\x51\x17\x49\x53\x88\x46\xff\x2e\x0e\xbe\xb8\x80\x71\x8d\x98\x10\x25\x9a\xe0\xe9\xde\x56\xb3\xd3\xb5\xf8\xf8\xe5\x26\xae\xbf\x47\xd0\x3f\x1e\xee\x6f\x91\xc8\x7f\xa7\x58\xc4\x82\xc9\xd1\x4e\x18\xd4\x20\xc5\xb6\xf0\xa9\x46\x87\x2f\xaa\xc7\x51\xdd\x30\x22\x7a\x20\x55\x0d\xe0\x2d\x6b\x9c\xb4\x22\x96\x95\x06\xc0\x55\x56\x67\x90\x3f\xf4\x2d\x9e\x0d\x8c\x69\x7f\xe7\xfb\xfa\xc9\xe2\x43\xff\x7e\xe6\x01\x6f\x91\xc7\x1e\x0c\xa3\x17\x4a\x95\x69\x8d\x8f\x4d\xc1\xeb\x51\xb2\x17\xf0\xfd\xa2\x5c\x8b\x39\x7e\x95\x60\x01\x0b\x91\xc1\x1c\xb0\xab\xac\x30\xd4\x8c\x7a\x1d\xb5\x68\x19\x35\x0e\x2d\x2a\x13\x8f\x32\x18\xb6\x25\x6b\x53\x8c\x30\x05\x92\x0a\xc3\x48\x32\x6c\xb0\xc9\x61\x80\x60\x6d\x84\x26\x1f\xa1\x0d\x22\xf6\xc3\xfa\xb8\xec\xb2\x94\x51\xb1\xc0\xc9\xce\x55\xd1\xbb\x10\x70\x77\x13\x28\xcc\xb3\x4d\xa5\x11\x70\x91\x1f\x23\x3c\x1a\xe1\x61\xe2\x5f\xe1\xc9\x2d\x72\x91\x87\xe3\x24\x9a\xc3\xb3\x03\x27\x82\xd5\x30\x18\xe2\x92\x31\x73\x4b\x52\xae\x92\x0d\x05\x90\x4a\x23\xd1\x43\x89\x65\x94\x28\x64\x24\x1e\x70\x4f\x41\x9b\x9c\x4a\x45\x8e\x2e\x9b\x86\xc4\x52\x3c\x77\x05\xe4\xd4\x2b\xb3\x1c\x78\xe1\xc5\x16\xc4\xae\x61\xa8\x0d\x87\xb0\x02\x40\xa8\x70\x15\x15\x9f\x16\x16\x61\xc4\xd2\x50\x71\x9e\xbc\x2b\x4f\x89\x79\x59\x91\x1a\x39\xcb\x4a\xca\x40\xd9\x69\x34\xd7\x5a\xcd\xd2\xe7\x8a\x98\xe9\xa2\x94\xc4\x10\x2e\x9b\xc5\x15\x11\x9b\xcb\x0f\x12\x1c\x8d\x64\x33\x6d\x64\x5f\x30\x9c\x21\xb3\x51\xe0\xe4\x4c\xb7\x6c\x16\xd1\xd3\x45\x63\x3c\x99\xe1\x88\x48\x54\xa5\xd6\xc7\x2e\xc3\x8f\x39\x86\xeb\x68\x7f\xb1\xbb\x4a\x2a\x8a\xe9\x7e\x2f\xb4\xcb\xb5\x0f\xb4\x77\x7b\xd0\xb5\x8a\x49\x86\xcb\x53\x23\xca\x95\x15\x7b\x4c\x00\x6e\xbd\xc3\xcc\xac\x19\x4b\xac\x67\xa4\x1e\x59\xd9\x42\x85\xf3\xaa\x9a\xbd\x4f\x4a\x42\xab\xd2\xfe\x72\x47\x57\x23\x89\x11\x06\xbe\x77\xb8\xd5\x7f\x0c\x12\x23\x82\x3a\x0f\x60\x42\xda\x60\xa4\xf6\x5d\x91\xd9\xde\xd4\x1d\x96\x22\xb5\xa9\x3b\xbc\x1f\xb9\x09\x00\xf7\x23\xb9\x4f\xd8\xa2\xe3\x92\x48\xae\xff\x01\x50\x23\x73\x42\xe9\x8e\x36\x43\x2b\x2f\x4a\x7f\x85\x67\x70\xa1\xef\x2a\xf4\x31\x21\x58\x81\x93\x09\xfb\x21\x7b\x99\xf0\xcc\x47\x34\x92\xf5\xa1\x9b\x8c\x45\x34\xeb\x1f\xf8\x37\x36\xf0\x2f\x95\x10\xd7\x77\x17\x4e\xa7\xfd\x2d\xc7\xb5\x66\x08\x55\x78\x2c\xee\xea\xa3\x04\xba\xe6\xd0\x97\x09\x78\x2d\x30\x95\x03\x5f\xdb\xa3\x5d\x8b\x12\x2c\xea\xb5\x31\x64\xb4\xe1\xfe\x85\x87\x45\x96\xe6\x51\x22\x0e\x29\xd4\xb1\xfc\x21\x27\xf2\x91\x5a\x5f\x72\x60\xca\x89\x92\xdc\x6d\x97\xb5\x74\x63\xa5\xb9\xad\x9b\x78\x5c\xd6\xda\x8d\x01\xf8\xba\xe6\x6e\xe5\x91\x78\x48\x26\x3b\x80\x56\xcd\x16\x6f\x14\xa3\xbf\x8c\x35\x77\xa6\xc2\xd4\x9d\x09\x11\x74\xea\xce\x96\x0a\xdb\x61\x8a\x21\x60\x80\x62\x35\x80\xa5\xe3\xbf\xb4\xd9\x38\x7a\xbe\x89\x5a\x39\x96\xe3\xb7\x09\x6e\x18\x4c\xc7\xe9\x9f\xcd\x80\x9c\xfe\xd9\xcd\xc8\x39\xe4\x66\x0a\xb9\xe2\xa3\xe7\xa8\x51\x35\x98\xa6\xf3\x2f\xa5\x0c\xd4\x39\xe4\x96\x06\xb9\x69\x85\xdc\x34\x43\xb6\xc0\x4e\x22\x7f\x36\x81\x4b\xa6\x0a\x1d\x9a\x57\xaf\xc0\xc3\xe5\x33\x7d\x6e\x92\xe7\x0d\xf2\x08\x48\x98\xe1\x88\x19\xf9\x48\x67\xa4\xf2\x11\xbd\x22\x18\xfc\xf4\x13\x02\x8c\x3e\xa2\x9f\x51\xbd\xb6\xde\x91\x26\xaa\xfa\x12\x7d\xcc\x8b\x97\x22\x11\x01\xb5\xcb\x9f\xba\x33\xb0\x52\xde\x4a\x2a\x15\x8e\x33\xf4\xbc\x8b\x7e\x46\x95\x16\x5a\x45\x1f\xab\xac\xbb\xad\x91\xd9\x6b\xcd\x10\xda\xc3\xa0\x50\xf1\x3c\x9e\xe8\xdf\x40\x9b\xec\x0b\xc1\x0b\x6d\x22\x09\xa7\x6e\xd6\xfd\x07\xa2\x3f\xa6\xe5\x2d\x56\xd9\x63\x7f\x82\x51\x45\xee\x2e\x8b\x2c\x61\x0d\x5b\x63\x1c\x1e\xb9\xa1\xe5\xfa\xce\x18\xb0\x0c\xf9\x9e\xce\x0b\x0a\xfb\xbe\x8f\x21\xab\xe0\xc8\x0b\xee\x0a\xdf\x81\x2d\x2b\xdb\x50\xa8\x3d\x94\xbc\xf3\x2c\x62\xcf\x2a\xea\x2d\xbc\x97\x88\x9a\xc2\x7b\x41\xbc\x49\xbd\x17\x4a\xec\x12\x99\x22\x11\xbe\xc2\x51\x8c\x0f\xa5\x92\xe9\x2b\x73\xac\xbd\x1f\xd3\x02\x76\xc2\xcf\x85\x6b\xdc\x2e\xf8\x9f\xce\xa4\x08\x8f\x22\x0b\x98\x75\x33\x9f\x1d\xa9\x4d\x9f\xf3\x85\xcf\x5c\x26\x3e\x56\x2f\xd0\x26\xfa\x68\x6b\xb9\x14\xdf\xd9\xbf\x0c\xc2\x08\x7f\x49\xd6\x23\x01\xdd\x0f\x3c\x70\x79\x4f\x27\xdf\x27\x6f\x8e\x46\x85\x7c\x45\x6a\x89\x02\xf9\x71\x73\x13\xad\x36\x8a\x38\x97\x4c\x71\x72\xf5\xa5\xd9\xb6\x59\x9c\x88\x44\xf2\xda\x18\x1f\x84\xe1\x2c\x5d\x29\x8e\x8e\x88\x23\xcd\xaf\x26\xb1\x64\xee\x7d\xdd\x59\x0f\xad\x6c\xbd\xee\x6f\xef\xec\xbe\xd9\xdb\xff\xe7\xdb\x83\xc3\x77\x47\xc7\xff\xe7\xe4\xf4\xec\xfd\xaf\xbf\xfd\xfe\xaf\xff\x76\x07\x43\x0f\x8f\x2e\xc7\xfe\xc7\x4f\x93\x69\x10\xce\xfe\x27\x8a\x93\xf9\xd5\xf5\xcd\xed\x9f\xf5\x46\xb3\xd5\xee\x74\xd7\x37\x5e\x3c\x5f\xdb\xe4\xf1\x9b\xa5\x63\xa5\x58\xd2\x0b\x63\x2c\x8d\xb7\xcd\x89\x28\x35\x73\x51\x6d\x79\x4d\xf2\x94\xd6\x94\xd1\xad\x88\x4c\xbd\x6f\xdb\xa6\x98\x93\x5e\x4c\x44\x2d\x69\xe1\xa4\x04\x26\x7b\x1c\xa1\x55\xd4\xa8\x5e\x80\xbb\x51\x2a\x76\x35\x0d\xf4\xc6\xa1\x36\xcb\x40\xad\x5e\x70\x01\x41\x96\xe6\x4c\x60\xa9\x58\x15\x28\xf1\xa1\x3e\x13\x81\x08\x3a\xf0\x99\x36\x29\xbb\x43\x05\x05\x21\xa2\x10\x1b\xe8\xe7\xcf\xd5\x2f\x29\x29\xa7\xbf\x18\x8d\x66\xe2\xa2\x9a\xc3\x68\xdc\xa9\xa9\xb3\x74\x65\x83\xb4\xa7\xbc\xcc\x4b\xad\xd5\x79\x52\x41\x3c\xa9\x20\x0a\x55\x10\xef\xcf\x76\x57\x1b\x5d\xf4\x7a\x67\x01\x7f\xbb\x46\xf7\xf5\x8e\xec\x72\xd7\xe8\xaa\x4f\xf0\xf5\x3e\x3e\x78\x14\xa1\xaf\xef\x87\x57\x1a\x8f\x07\xf6\xc5\x6b\x74\xad\xce\x78\x8d\xee\x5f\x46\x33\xb1\x88\xc2\x00\x06\xe5\x5e\xfa\x02\x4b\x64\x08\xb0\x35\x0b\x3d\x7c\x1c\xfa\x41\x62\x73\x37\x6f\x74\x2d\xee\xe6\xe6\xf3\x7c\x8a\xac\xdd\xdf\x5c\xb4\xb9\x80\xd3\xb9\x04\xf7\x9e\xc7\x36\x9d\xb8\xef\xe9\x82\x08\xf4\xba\xf8\xaa\xf9\x0e\xce\x6e\x74\xc5\x09\x47\x44\xbe\x30\x17\xf4\x44\x84\x6a\x8b\x7a\x9d\xf3\x7a\x42\x88\xe6\x2f\xbe\x84\xcf\xb9\xda\x78\x49\x97\xf3\x06\x88\x54\x02\x4d\xd5\xe1\x9c\x48\x56\xe9\x3a\x6a\x92\x75\xa4\x87\x08\xcc\xa3\x7d\x9b\xec\xa4\x8d\x92\x2e\xfc\x95\x71\x35\x6f\x74\xd1\x41\xa9\xed\x4f\xda\xe2\x0e\x1e\x60\x8b\x3b\xf8\x46\xb6\xb8\x72\x78\x3c\xc6\x16\x67\x5c\x6d\x07\x3b\x4f\x3b\xdc\x63\xee\x70\xf1\xb5\x3b\xdb\x09\x3c\xdf\x0d\x2a\x8b\x6e\x76\x46\xf5\xc0\x77\xb3\xdb\x1d\x3c\xd6\x6e\x57\x6e\x01\x7d\x2f\xbb\xdd\xc1\x8e\xb6\xdf\x3d\x6d\x76\xfc\x2f\xbb\xd9\x49\x8b\x69\xa1\x7d\xef\x6b\x6c\x7c\x62\x96\x24\xa4\x09\x30\xb5\xaf\x3c\x8b\x04\x7c\x62\x37\x43\x74\xfd\xd7\xeb\xe4\xff\xe1\xda\x88\x7e\x24\xc3\xc0\xbe\xd2\x6f\x12\x87\x28\xa3\xc4\x00\x72\xcb\xd5\x61\x74\xef\xa7\xc3\x60\x89\xaa\xbf\xb0\x2a\xc3\x41\xd2\xab\x78\xec\x36\xb4\x57\xe3\xa9\x3b\x7c\x64\x85\x87\x83\x78\xd3\xf0\x0b\x5a\xfc\xab\x29\x41\x32\x69\xa2\x97\xd2\x90\x28\x16\x40\xf2\xa7\xc3\xed\x0e\xd4\x05\xc3\xa5\xc3\xed\x8e\x45\x80\x04\xdb\xf3\x4f\xf8\x96\xe6\xcf\xa7\xc6\xc8\xa2\xd7\xe0\x0c\xee\x06\x09\xcd\xfc\x1c\x80\xa9\x28\x18\xd0\xef\xfc\x7a\xfc\x01\xb6\xee\xb3\xf0\x2d\x96\x24\x4d\x74\x7d\x7d\x5d\x0b\x67\x38\x88\xe3\x49\x2d\x8c\x2e\xd7\xbc\x70\x18\xaf\x41\xfe\xfe\x70\x4d\xab\x34\x4e\xa6\x13\xa3\x86\x66\xe7\x6a\xf6\x76\x7b\x37\x45\x5e\x3c\x97\x8e\xa2\x51\xc2\x95\x47\xdf\x25\x33\xae\x4c\x9f\xf0\xad\x70\x64\x22\xe3\x13\x93\x07\x3f\xe0\x3e\x4c\x52\x00\xf4\xd4\x6f\xa9\x8d\x2a\x8d\xe6\x86\xea\xb6\x94\x69\xc0\x62\x01\x28\x87\x56\xd1\xb3\x11\x1d\x6e\x77\x0a\xf1\xf5\x13\x66\x19\xae\x07\x6e\x97\x3e\x24\x21\x9a\x51\x8b\x5f\xd9\xd9\xca\xba\x3b\x66\x5c\x9c\xf4\x3d\x85\x8d\x51\x0f\x35\x9a\x1b\xd4\x76\x57\xf9\x4c\x7b\x08\xe8\xeb\x9f\x52\xa4\x54\x04\xee\xee\xe3\x45\x65\x21\xe3\xc7\x77\xab\xc2\x52\xb3\x0f\x64\xfb\xfe\xc9\x1b\x65\x9c\xa9\xe8\x42\x28\x4a\x98\x56\x5c\xf3\xdf\xe9\xc4\x6d\xe8\xb9\x38\x97\x85\xe3\xa8\x53\x5a\xaf\xd7\x33\x90\x17\x76\xf7\x2a\xf6\xe3\x2a\x2d\x4d\x6f\x93\xf9\x01\x92\x21\x44\x02\x19\xf2\x5d\x48\xb7\x4c\x96\xf3\x72\xbe\x14\xbc\x36\x0d\x1d\x61\x04\x95\x53\x3b\x76\x27\x09\xda\x82\x7f\x96\x91\xba\x81\xde\x28\xc9\x3f\x14\xc1\x61\xb2\xd7\x7c\xf2\x46\x35\xea\xc6\x82\x2b\xbc\x4f\x0e\x60\x99\x9b\x2f\x0a\x2a\x28\xc9\x5a\xd5\xba\x0b\x4a\xd3\xea\x9c\x1b\x65\x67\xc2\x07\x18\x83\x31\x00\x10\xde\x88\x84\x64\x98\xbd\xb8\xb4\x6c\xcc\xe0\xac\xae\x7f\x10\x8f\x82\x0e\xf8\x5b\x18\x25\x63\xf2\xc2\xc5\x4e\xe9\x29\x3c\xe1\x2e\x2e\xde\xd8\x0f\xec\x7c\x53\xa2\x1d\x63\x4f\xa6\x82\x12\xd3\xa7\x65\xd3\x17\x46\x54\xdf\xb0\xcd\x8c\xb4\xa0\x7d\x65\xe6\x3f\x1a\xc2\xdc\x04\xe8\x15\xc7\xc9\x7c\xe2\x20\x72\x21\xf8\x78\xd8\x6f\xdb\x55\x27\x34\x5a\xb8\xcc\x1d\x3b\x92\x63\x79\xa4\xfe\x3b\x0c\x0e\x27\x40\xc9\x3a\x3b\x4b\xc5\x2a\x06\xa9\xe3\xa4\xa1\x0c\xa1\x11\x31\x84\x86\xef\xca\xb9\xac\x41\xcf\x65\xd2\x98\xe7\x67\xde\xd2\xba\x20\x30\xb6\x0f\x86\x11\x6d\xd3\x90\x19\xde\x4a\x84\xc6\x62\x12\x99\xdb\xd1\x07\x5c\xaa\x27\x29\x8e\x38\x49\x1a\xe3\xa6\x88\x10\x88\xbc\xe6\x42\x86\xf0\xe5\x98\xb6\xe2\x91\xbe\x1c\xb3\x5e\x94\x51\x3f\xa0\x3b\xb6\xc9\x67\x50\xee\xd1\x02\xfc\x5f\xae\xa6\xaa\x5b\xe4\x2f\xda\x8e\x20\x7d\x42\xca\x4e\x20\x36\x7e\xba\xe7\x5b\x77\x83\xc5\xea\x39\xc8\x26\x7c\xdc\x07\x4e\xbe\xf0\x91\xea\xbf\xd3\xa3\x84\x6d\xa7\x32\x78\x20\xb1\x19\x50\x45\x1f\xf0\x3b\x2a\xd8\x28\xef\x5e\x16\xe8\x10\x28\x48\xab\x02\xc1\xe1\x27\xdf\x5e\x67\xc3\xe1\xe7\xe1\xde\xfa\xfa\xdd\x85\xd3\x59\xff\xee\x15\x0b\x43\x7f\x36\xc6\xd1\xea\x17\xb0\x9e\x00\x15\x82\xdc\xdc\xd7\xd5\x24\x18\x72\xf4\x3e\x94\x4a\xa1\x0f\x9d\x3c\x26\xac\x29\x16\x8a\x03\xf9\x65\x9e\x75\x85\xf8\xa0\xa5\x99\x51\xeb\x90\xc3\xa3\x9b\x40\x35\xfa\x33\xe5\xdd\xac\xee\x2e\xbc\x4e\x58\x74\x0e\x5a\x68\xa1\x74\x35\xe4\x3c\x45\xa7\x2b\xc1\x37\x09\x39\xc2\xba\xec\x19\xcd\x68\xd7\x98\xe3\x1d\x4f\x65\xe3\x7a\x78\xe8\x4f\xdd\xc9\xe4\x96\x65\xfc\xf5\x16\xb8\x98\x92\x87\xe7\x8e\xb5\xc3\x46\xf0\x4c\x20\xa2\x36\xbc\x4c\xb2\x9b\xe5\x70\x7c\xf4\xf4\x37\xe9\xf4\x48\x97\x56\xf2\x20\x2c\x7a\x6f\xa5\xd4\xb5\x79\xe1\xc9\x85\x6a\xe9\x54\xa7\x79\x59\xf6\xf0\xcd\x3d\xb2\xab\x18\xc6\x5a\xa2\x27\xf9\x0e\x65\xe1\xd9\xd5\x6e\x53\xfc\x60\x36\x4f\xee\x37\xc5\x9c\x5e\x54\x3a\x5c\x8a\xf4\x1e\x92\x5a\x86\x1a\x2b\x31\x10\xcc\x3d\x12\xb5\xc0\xb8\x59\x02\x27\xa5\x33\xb5\x89\xd2\x66\x68\x0d\x5d\x44\xe5\x3b\xaa\x42\x4f\x5c\x39\x91\x42\xea\xc9\x50\xef\xac\xf7\x0c\xb9\x9b\x75\xda\xf1\xec\x86\x2d\xed\x2d\xbd\x4e\xd3\xd1\x2e\x01\x36\x9e\x0c\x19\xff\xaa\x86\x8c\xb9\x3a\x7c\xeb\x06\x9b\x09\xf9\x9f\xaf\xd2\x37\x1d\x8d\xc0\x3b\x5c\x68\x8c\x2d\xe9\xe2\x48\x99\x4d\xd9\x77\x79\x11\x1d\x7a\x9e\xa2\x15\xfc\xa0\x4b\xb0\xc9\xd2\xaa\xee\xb2\x5a\x33\x72\x34\x00\xf7\x76\x3c\x8c\x70\xf2\x80\xda\x2f\x22\x67\xef\x99\x43\x58\x41\x67\x19\x53\x31\x79\xaa\x53\x27\xf0\xf2\xaa\x4e\xd9\x75\xdc\x16\x23\xdb\xac\xd9\x12\x5a\x2d\xea\x54\x22\x1e\xf5\xa0\x08\xb9\xde\x8c\x0f\x1a\x55\x19\x8e\x6a\x45\x41\x95\xe9\x79\x4e\x8a\xa9\x9c\x19\x2f\x9b\xc7\x44\x9e\x02\x8d\x76\xf8\xb5\x14\xf6\x95\x0d\x41\x6e\xe0\x57\xad\x16\x57\x62\xe8\xc0\x6c\x41\x60\xb7\x26\x93\xf0\x1a\xb9\xd1\xc0\x4f\x22\x37\xba\x45\x4c\x09\xf6\x09\xdf\x9a\xa2\x68\x7e\x92\x35\x25\xbf\x18\xdb\xce\x1b\x31\x5d\x1b\x54\x7a\xd8\x8a\xbc\x5f\x09\x5e\xb9\x7e\xaf\x10\xbb\x10\x74\x2e\x61\x84\xfc\x20\xc0\x11\x44\x5d\x0e\xe7\x09\xc8\x23\x99\x78\x92\x10\x08\x94\xaa\x46\x29\x69\xb2\x07\xda\x50\x36\xa0\x22\x57\x52\xca\x55\x7c\x53\x95\xc5\x48\x22\x94\xb4\xa9\x61\xae\x1e\xd5\x97\x4a\xfa\x72\xc9\x6c\x83\xbf\x1f\x9d\xc0\xfc\xd2\x8b\xcf\x99\xeb\xa1\x61\x18\xc4\x89\x1b\x64\x50\x30\xa6\x78\x53\xe7\x3c\x47\x0f\x28\x90\x3f\xf7\x2f\xd0\x1f\x9b\xa8\x7e\xd3\x19\xd2\xff\x19\x7d\x9a\x32\xa5\x5b\x5d\xfa\xbf\x22\x2d\x5e\xa8\xe9\xef\x7c\xed\xd9\x44\xa5\x5f\x2f\x62\x1e\xec\x5a\x8f\x15\x2f\x4f\xf0\xfc\x87\x8a\x99\x97\x97\x64\xd0\xc4\xbb\x8d\xe3\x0a\xdd\x37\x72\x7e\x9b\xaa\x57\xd5\x7c\xa7\xcb\x69\xf9\x60\x79\x30\xec\xdf\x54\xa8\xbc\xc3\xad\x3e\x0b\x94\x07\xb8\xf9\xb0\x04\x0b\x42\xee\x2c\x4c\x06\xa5\x62\xe6\x65\x8a\x3f\x4a\xdc\x3c\x99\x4c\x78\x43\x25\xc2\xe4\x3d\x6a\x90\x3b\x18\xf9\xa7\x20\x77\x6c\x24\x1e\x50\xf2\x24\x6c\x37\x25\xab\xe2\x40\x77\xf6\x2a\xc5\xc1\xee\xec\x75\x1f\x2f\xe0\xdd\x83\xf0\xc5\x3e\xd5\xb6\xc3\xd8\x9b\xb6\x74\x22\xa6\xec\x99\x43\xf9\xe5\x47\xc6\xcb\x67\xae\xf2\xa0\x69\x60\x53\x59\x87\x8b\x2c\xfc\x42\x4d\x20\x53\xcd\x89\x8c\x37\x75\x87\xd6\xeb\x30\x59\x15\x61\x33\x2e\x7c\xf1\xdd\xdf\x01\xdc\x74\xdb\xab\x86\xd7\x13\x7f\xb0\x4a\x90\xf1\xc0\xac\x38\xd6\xbe\xe2\x60\xb8\x0a\xc6\xa3\x86\xf7\xd4\xcb\x56\xfb\x30\xf5\x3a\xc5\x46\x8d\xf1\xd8\x6d\x76\x74\x90\xe4\x65\x53\x07\x17\x8f\xdd\x4e\xa3\x99\x7d\xd9\xda\x30\x94\x6c\x69\xaf\x22\x7f\x86\xa7\x5e\xa3\x5b\x37\xda\x54\x2a\xaf\x66\x83\x4f\xde\x48\x6f\x07\x5f\xcd\x3e\x79\xa3\xbc\xab\x14\xb5\xeb\xa1\x87\x57\x87\xa3\x81\xf1\x75\x12\x59\x5e\xaf\x5e\x4e\x5c\x6f\xea\x06\xa6\xcf\xa1\x19\x18\x1e\xea\xaf\x67\xae\xb7\xea\x06\xb1\x7f\xf3\xa2\xa9\x0f\x02\xf9\xe4\xc7\x61\xa3\xde\x68\xea\x23\xce\x3e\xbd\x58\x7f\xb1\xae\xcf\x10\xf9\xf4\x27\x8e\x42\xe6\x8b\x6f\xf8\x1a\x58\xbe\x51\xd5\xdd\xea\x18\xdf\x68\x1f\x5c\xac\x13\x17\x0d\xdb\xe2\x65\xde\x47\x43\x7d\x72\x23\x77\x30\xf0\x13\xe3\xcb\xd5\x09\xbe\x74\x87\xb7\x5f\xe2\x5a\x4b\xac\x20\x78\xd2\x17\x0e\xbc\x4c\xd7\x8b\x78\x64\xcb\x04\x9e\xc9\xea\xd0\xcc\x6d\xd9\x5a\x10\xbf\x9b\x6d\xf1\x9b\x50\x3e\xff\x4d\x08\x5e\xfc\xa6\xbf\x52\xf2\x4e\xed\x76\xe1\x17\x23\x66\x8a\x01\xa5\xe1\xcc\xb5\x1c\x45\x87\x53\xac\xf4\x94\x44\xea\x93\xa0\xcf\xf4\x6d\xa8\xd4\x20\xd4\x48\x9b\x95\x89\x50\xbc\x11\xb4\x27\xbf\xa1\x24\x27\xde\xc8\x94\x26\x5e\x06\xea\x2b\x89\xae\xe0\x99\x90\x13\xfc\x48\xa9\x88\x8e\xca\x90\x0d\x14\xa3\x19\xe9\x37\x27\x95\x65\x14\xa3\x8a\x42\x54\xe6\xb9\xcb\x29\x4a\x73\x63\x02\xb2\xde\xf5\x3a\x0d\x27\x5f\xe1\xed\xa8\x24\xd6\xeb\xb4\x1d\x85\x06\x7b\x9d\x8e\x93\xd2\x40\xaf\xd3\x75\xd4\x81\xec\x75\xd6\xf5\x7b\x6f\x9d\xaa\x7b\xdd\xba\xc3\x08\xb7\xd7\x05\x7c\x04\xd1\xf4\xba\x4d\x47\x26\x9b\x5e\xb7\xed\x98\x08\xa7\xd7\x6d\x39\x32\xb1\xf4\xba\x1d\x47\x26\xa5\x5e\x17\xf0\x52\xc8\xa7\xd7\x5d\x77\x74\x02\xea\x75\x37\x1c\x9d\x84\x7a\xdd\x17\x4e\x86\x5e\x7a\xeb\x75\xc7\x40\x59\xbd\x75\xc0\x9f\xad\x8e\xde\x3a\x60\xcf\xa8\xa4\xb7\xde\x76\x32\x74\xd2\x5b\x07\xc4\x09\x45\xf5\xd6\x01\xe7\x74\xc9\xf5\xd6\xbb\xb2\x99\x80\x93\xae\xde\xde\x3a\x37\x20\x20\xeb\xba\xb7\xfe\xc2\xe1\xab\xb6\xb7\x51\x77\xd2\xd5\xdc\xdb\x68\x38\xe9\x3a\xef\x6d\x00\x3a\x29\x31\xf7\x36\xa0\x71\xc1\x73\x7a\x1b\xed\xbb\x0b\xa7\x5b\x7f\xba\xdf\xf8\x06\xef\x37\xfa\x63\x3c\xfc\x44\xfa\x07\x4b\x87\x7a\x68\xd1\x6c\x83\xf1\x7c\x46\x46\x09\xf3\x90\xec\xd2\x18\x80\xf8\x4f\x23\xfb\xa3\x1f\x37\xd1\x0a\x87\xbd\x62\x32\x89\x91\x5c\x65\x1e\xf8\x5a\x25\xdf\xfb\x21\x6d\xec\x04\x8f\x70\x84\xe1\xc8\x18\xf9\x97\x70\xb6\xf3\x03\x3f\x91\x20\xc5\xf3\x19\x8e\x40\xa3\xbe\xa9\xa5\xba\x51\x00\x6d\xcd\x2f\xa7\x38\x48\xb4\x22\x28\x09\xd1\xd8\x0d\xbc\x09\x56\x06\x51\x01\x3f\x30\x02\x57\x2c\x8c\xa0\xae\xc1\x97\x53\xd2\xc9\xd3\x0c\x0b\xd4\x3a\xcc\x0f\x92\x0d\xf9\xfa\x60\x24\x43\x10\x8a\x0f\x75\xb2\x0c\xfa\x83\xb4\x0a\xbd\x20\x78\x4f\xe0\xc2\x0b\x19\x21\xed\x00\x62\xc6\x2e\xa4\x29\xf8\x00\xd8\x95\x8f\xaf\xad\x78\xda\x71\x90\xd0\xde\xe7\x78\xa0\xcf\x9f\xb5\x0a\x9c\x0c\x01\x57\xd0\x62\xf3\xfa\x3f\x92\x55\x29\x2c\x67\x60\x59\x9a\xa1\x67\xaa\x56\xb3\xcd\x58\xf1\x6a\x74\x2d\x88\xd9\xdb\x5a\xb0\xca\x7e\x90\xb4\x9a\x0b\x37\xb2\x60\x95\xdd\x49\xe8\x2e\x55\xa7\xdb\x86\xf7\x52\x85\x65\x09\xab\x46\x29\xda\x41\xf2\xab\xdb\x04\x1f\x41\x16\xae\xcc\x6b\x73\x92\x75\x95\x1a\xf7\xe8\x4a\x4c\x9b\x2b\xb5\x48\xd2\xe2\x8b\x6a\x26\x52\x78\xaf\x05\x86\x68\xd3\x8c\xb9\x51\x61\xb1\x73\xc3\x52\x28\xdf\x26\x46\x93\xf2\xc5\x9c\x3c\x4d\xe8\x2c\x94\x4a\x3f\x05\x70\xee\x5f\x2c\x9b\x37\x3f\x35\x95\xf7\xff\xc4\x54\x57\x9c\x3a\x00\x6b\x65\x05\xef\x4d\xd3\xc1\x38\x88\x79\x7f\x9a\x7a\xa3\x4e\xbf\x39\xfd\x20\x19\x56\xf2\x9e\x40\x44\x01\x11\x1b\x15\x96\x9f\x6d\xda\x9d\xcd\x26\xb7\xac\x6d\x37\xba\x9c\x13\x36\x1f\x17\x79\x9a\x32\xb6\x5e\x9b\x45\x61\x12\x12\x54\x65\x06\x5f\x64\x28\x92\xdd\xae\x2c\x0a\x9c\x6e\xe3\x49\x70\xfa\x36\x04\x27\x08\x8e\xfe\xb5\xa2\x5c\x19\x53\x99\x95\xb3\x08\x81\x2d\x9a\xde\x45\xa2\x44\xd2\xfa\x93\x5a\x67\x9c\xb3\xc8\x85\xa9\x06\x55\xbf\xc0\x34\x8a\x90\x36\x3e\xd4\x6d\x5b\xb8\xce\x19\x61\x2b\x9b\x74\x30\x6b\xee\x20\xa6\x3f\x62\x3f\x60\xb1\x84\x09\x8b\xa9\xdf\x34\xea\xec\xaf\x8a\x3e\x6b\xd9\xba\xf9\x3a\xac\x54\x6d\x0e\x01\x87\xdb\x1d\xcd\x80\xc4\x6c\xf9\xa2\xfb\xbe\xa2\x4d\x36\xca\x26\xcb\x17\x9e\x5b\x2a\xff\x76\x2f\x55\x4f\x9b\x93\x93\x9f\x1b\x78\x70\xfd\xa6\xbb\xde\xee\x34\x5b\xf5\x86\x83\xea\x37\x78\x34\xf4\xdc\xc1\xc6\x0b\x53\x52\xd4\xfa\xcd\x8b\x8d\x81\xeb\x0d\x47\xd8\x81\x31\x6a\x35\x3b\xed\xf5\xae\x56\xf0\x22\xef\x3e\x4f\xcb\x7c\x29\x77\xe6\x50\x24\xbf\x34\xee\x80\xd7\xee\x0c\x61\xf0\xa6\x2f\xb1\x0b\x35\xba\x39\x7b\x4e\xce\xf5\x3c\x9f\x19\x8a\xc8\x07\x02\x91\xe7\x05\x45\xbe\xe9\x82\x1b\xa6\xf1\x83\x54\xfc\xf0\x9c\x3f\x5c\x98\x3d\x74\xa4\x02\x84\x0c\x0d\x25\xc8\x5f\xa5\x52\x91\xc0\xd2\xf0\x00\xe8\x33\x92\x5f\xc2\x96\xd9\xae\x6a\x81\x01\x90\x2e\x47\x59\x21\x36\xdb\x55\x03\x44\x08\xd1\xad\x04\x22\x30\xc0\xbb\xbf\x59\xcc\x9e\x72\x95\x62\xb3\x6b\x50\x46\xb7\x8e\xa4\xe1\x45\xcf\x51\x3d\x23\x8f\x28\xc5\x1b\x5a\xf1\x46\x7e\xf1\xa6\x56\xbc\x99\x5f\xbc\xa5\x15\x6f\xe5\x17\x6f\x6b\xc5\xdb\xf9\xc5\x3b\x5a\xf1\x4e\x7e\xf1\xae\x56\xbc\x9b\x5f\x7c\x5d\x2b\xbe\x9e\x5f\x7c\x43\x2b\xbe\x91\x5f\xfc\x85\x56\xfc\x45\xc1\x34\xd5\xb5\x69\x2a\x9a\xd6\x86\x56\xbe\x60\x5e\x1b\x4d\xad\x7c\xc1\xc4\x36\x5a\x5a\xf9\x82\x99\x6d\xb4\xb5\xf2\x05\x53\xdb\xe8\x68\xe5\x3b\x06\x3e\xb1\xb6\x46\xf8\xf6\x27\x3f\xb8\x24\x95\x7d\x77\x32\x30\x4a\xe6\x2e\xd9\x30\xce\xcd\x03\x36\x80\x6f\xe6\xc1\x19\xc2\x37\xf3\x40\x78\xf0\xad\x65\x46\xaa\x9f\x5e\xaa\x6b\x1f\x09\x2a\xbb\xbb\x15\xd7\x41\x03\x07\x0d\x1d\xe4\x39\xd2\xc2\x75\x10\x5a\x77\xc8\xce\x5b\xbf\xc8\x70\x0e\x8f\x56\xf4\x1c\x24\xea\xa6\x63\xe5\x20\xd4\x68\x3a\xe8\xec\xbc\x91\xad\x38\xa4\x15\x69\x5b\xb4\x6e\xba\x98\x49\xc5\x75\x52\xb1\x99\xad\x38\xa0\x15\x05\x9e\xae\x54\xb1\xe5\x20\xd4\x84\x16\x5b\xd9\x8a\x79\x7d\x6c\x8b\x3e\xb6\x17\xeb\x63\x47\xf4\xb1\xb3\x58\x1f\xbb\xa2\x8f\xdd\xc5\xfa\xb8\x2e\xfa\xb8\xbe\x58\x1f\x37\x44\x1f\x37\x16\xeb\xe3\x0b\xd1\xc7\x17\x8b\xf5\xb1\x51\x77\x58\x1f\x1b\x06\xd2\xc9\xeb\x64\xa3\xe1\xb0\x4e\x36\x0c\xb4\x93\xd7\x4b\x82\x28\xed\x65\xc3\x40\x3c\xb9\xe4\xda\x72\x38\xb9\x1a\xa8\x27\xb7\x9f\x6d\xd1\x4f\x03\xf9\xe4\xf6\xb3\x23\xfa\x49\xe9\xc7\xd0\xd3\x37\x6f\x2c\x3d\x75\x10\xea\xd0\x9e\x1a\x48\xc8\xa3\x35\x8d\x3d\x25\xb4\xf7\x82\xd6\x34\xd0\xd0\x90\xd6\x34\xf7\xb4\xe1\x20\xd2\xdb\xb3\xf3\x86\x81\x88\x06\xb4\xa6\xb1\xa7\x84\x8b\x34\xeb\x50\xd3\x40\x45\x79\xfd\xec\x88\x7e\x36\x2d\x0c\xc8\xd6\x4f\x42\x7f\xb4\x9f\x4d\x0b\x07\xb2\xf6\xb3\xc3\xfb\xd9\xb4\xb0\x20\x5b\x3f\xdb\xa2\x9f\x4d\x0b\x0f\xb2\xf5\xf3\x45\xda\x4f\x0b\x13\xb2\xf6\xb3\x2d\xfa\x69\xe1\x42\xb6\x7e\x12\x86\xc9\xfa\x69\x61\x43\xb6\x7e\x6e\xa4\xfd\xb4\xf0\x21\x2b\xdd\xb6\x1c\xde\x4f\x0b\x23\xb2\xf5\xb3\x29\xe8\xb6\x69\xe1\x44\xb6\x7e\xae\x8b\x7e\xb6\x2c\x9c\xc8\xd6\x4f\xc2\x11\x68\x3f\x5b\x0d\xdb\x0a\xdd\xdb\xb3\x53\x6e\x1b\xf0\x6d\x59\x78\xd1\xde\x9e\xb9\xa7\x64\x74\xc9\x5a\x3b\x3b\x6f\x59\x78\xd1\xde\x5e\xce\x0a\xed\x42\x4d\x0b\x2f\xda\xdb\xb3\xf4\xb4\xed\xa0\x66\x0b\x6a\x1a\xa8\x28\xaf\x9f\x8d\xb4\x9f\x16\x4e\x64\xeb\x67\x3b\xed\xa7\x85\x13\xd9\xfa\x09\x33\x4a\xfb\x69\xe1\x44\xd6\x7e\xd6\x45\x3f\x2d\x9c\xc8\xda\xcf\x96\xc3\xfa\xd9\xb6\x70\x22\x5b\x3f\xeb\xa2\x9f\x6d\x0b\x27\xb2\xf5\xb3\x25\xfa\xd9\xb6\x70\x22\x5b\x3f\x09\x97\xa7\xfd\x6c\x5b\x38\x91\xad\x9f\x2f\xc4\x7c\xb6\x2d\x9c\xc8\xd6\x4f\xb2\x5a\x58\x3f\x2d\x9c\xc8\x4a\xb7\x1d\x4e\xb7\x6d\x0b\x27\xb2\xf5\xb3\x99\xf6\x73\xdd\xb6\x42\xf7\xf7\xed\xb2\x6d\x97\xf6\xd4\xc2\x8b\xf6\xf7\xcd\x3d\x05\xfa\x03\xbe\xd0\xb6\xf0\xa2\xfd\xfd\x1c\x69\xa1\x03\x22\xa3\x85\x17\xed\xef\x9b\x7b\x4a\xf8\x49\x13\x46\xb7\x63\x91\x8a\x6c\xfd\x24\xf3\x42\xfb\xd9\xb1\x70\x22\x5b\x3f\x5b\xa2\x9f\x1d\x0b\x27\xb2\xf6\xb3\x2e\xfa\x69\xe1\x44\xb6\x7e\x36\xd2\x7e\x5a\x38\x91\xad\x9f\x1b\x62\x3e\x3b\x16\x4e\x64\xeb\x27\xd0\x1f\xed\xa7\x85\x13\xd9\xfa\x09\x92\x3c\xed\xa7\x85\x13\x59\xfb\xd9\x72\x78\x3f\x2d\x9c\xc8\xd6\xcf\xb6\xe8\x67\xd7\xc2\x89\xac\xfd\x6c\xf0\x7e\x76\x2d\x9c\xc8\xd6\xcf\xa6\xe8\x67\xd7\xc2\x89\x6c\xfd\x7c\x21\xe6\xb3\xdb\x32\xad\x50\xb8\xee\x49\x70\x34\xc5\x9e\xef\x26\xcc\x7b\x0f\x9c\x3d\xb4\x82\xe4\xb4\x8c\x36\x51\x05\xfe\x7d\x8e\xdc\x8c\x76\x97\x16\x6a\xb0\x42\x0d\x52\x68\x60\x29\xd4\x64\x85\x9a\xa4\xd0\xd0\x52\xa8\xc5\x0a\xb5\x48\x21\x2f\xab\x4c\xce\x68\x47\x77\x0d\x96\xcb\x0b\xc7\x56\xf6\xdc\xc4\x4d\xf3\x5f\xbb\x89\x6b\x3c\xe9\xbb\x89\x2b\x82\x3a\xb9\x89\x9b\xa7\x84\x0b\x5e\xfb\x49\x7c\x16\x26\xee\x44\x80\x0d\xb6\xdd\xc4\xa5\xde\x38\x3f\xa3\x0d\x53\x03\x50\xe9\x00\x8f\x12\xde\x80\x70\xdf\xa1\x15\xb2\x7d\xb2\x67\x8c\x13\xc8\x9e\xa7\x50\x7f\xf9\xe5\x17\xd4\x81\x3b\xc3\xfa\xcd\x46\x3d\xbd\x2a\x4c\x4b\xfc\x03\xb5\x9a\x06\x72\x51\x7b\xb4\x87\x36\x11\xdc\x01\x8c\x26\x61\x18\x55\xa4\xae\xae\x29\x17\x01\xd6\x2e\x42\xe1\x03\xb4\x29\x3d\x65\x16\x94\x40\xbf\x52\xa9\xa4\xf8\x3d\x47\xdd\x36\x4d\x3e\xf8\x02\x22\xd8\xb6\xab\x54\x23\x64\x51\x0c\xf3\xba\x0c\xed\x54\x2b\x2c\xbf\x5d\x40\x2d\x9c\x85\xc7\x74\xc2\x3a\xbc\x42\xa5\x70\x96\x83\x2c\xd2\xe1\x76\xa9\x0e\x1f\x18\x3b\x7c\xb0\x74\x87\x0f\x8c\x1d\x3e\x28\xdf\x61\x43\x97\x65\x0f\xb5\x8a\x18\x03\x1e\x84\x0c\x52\x55\xda\x7c\x36\xc1\x27\x80\x3a\x7e\x80\x6b\xa8\xd1\x4d\xed\xc3\x8c\x5e\x9e\x2c\xe1\x75\xa8\xe4\xc4\xd7\xd3\xdd\x23\x49\x2d\x9f\xa7\x90\x5f\xf8\x22\xc6\x76\x0b\x87\x72\xed\x1a\x04\x3a\x70\xa5\xb2\x77\x6e\xbb\x4b\xd9\x63\x77\x79\x95\xca\x9e\x72\x4b\xb2\xb7\xf8\xf5\x08\xa5\x8e\x3d\xe5\x6a\x64\xcf\x7a\x27\x52\xea\xfe\xe3\x84\xe5\xf2\x86\x39\x65\x41\x98\x3c\x18\x5e\xad\x2c\xf7\xb4\xd0\x26\x45\xdb\x1c\xc0\x77\x23\x7f\x5b\x00\xe5\x2e\x78\xc5\x8a\x9b\x44\x78\x4c\x2d\x1b\xb2\x1b\x36\x7c\xff\x90\xa1\x0e\xbb\x77\x2b\x0f\x8e\x42\xbe\x5b\x1d\x43\xd8\x6f\x81\xac\xa6\x6d\xbb\x71\x50\xec\x20\xed\xa6\x0f\x18\x2a\xda\x44\x2e\x7a\x8e\x2a\x95\x01\xfa\x89\xee\xaa\x95\xff\x4b\x7e\x7a\x55\xc2\x2a\x6e\xd0\x73\x94\xc8\x8d\x8a\x30\xda\x01\x99\xb7\x98\x2e\x66\x1a\x60\xbf\xd5\x44\xab\x28\xae\x42\xbd\x41\xd6\x08\x50\xa0\xa6\xa9\x19\x4a\xa2\x06\x7b\x79\x65\x88\x7e\x42\xff\xf7\xf1\x50\xd3\xce\x57\xc5\xa8\x0d\xd0\x1f\x68\x88\xfe\x20\xd8\x3d\x0e\x46\x9a\x3c\x59\x8c\x11\xc1\xa6\x32\x40\x9f\x1f\x61\x98\x94\x3b\x77\xce\x49\x52\x54\x93\x10\x1c\xfc\xa8\x37\xd4\x8a\x88\xc6\xe4\x13\x41\x71\xa4\x24\xab\x4f\xa1\x14\x7a\xeb\xe9\xbe\xa1\xb0\x54\x4c\x80\x2c\x1e\x79\xd6\xf2\xf7\x89\x84\xc7\x16\xaf\x30\xed\x39\xdc\xee\x98\x3c\xec\xf2\x2b\x18\xdc\xea\xa4\x88\x74\x8a\x75\xc2\x07\x1a\x66\x62\x0f\x4f\x66\x38\xaa\x1c\x6e\x77\x6c\x86\x10\xd6\x49\xd9\x3b\xdc\xea\x7f\x99\x29\x59\x2e\x4a\x47\x89\x99\x54\x7c\x2b\x1f\x6c\x26\xa9\x07\x9f\x98\x98\xbd\xa9\x3b\x24\x93\xc3\xba\xa7\xc5\xf0\x90\xe6\x87\x15\xcc\xce\xd1\xd4\x1d\xaa\xf3\xf4\xc3\x1d\xb5\x23\xb2\x1a\x86\xf1\x20\xec\x36\x73\xb0\xe6\x77\xef\xcf\xf7\xf7\x8a\xe9\xc7\x56\xe4\xcf\x2c\xfc\x14\xda\xc5\xd8\x1b\xb8\xc3\x4f\x2c\x9c\xeb\x34\xf4\xe8\xba\x03\x6a\x12\x54\x00\xaf\xfb\xbb\xaf\x89\x78\x65\x12\x39\xc0\xe2\x0b\x3e\x2b\x16\x85\x60\xd5\x43\x1b\x3a\x24\x10\x98\x21\x93\xc4\x20\xfa\xbb\xaf\x6b\x3b\x01\x8d\xb5\x0f\xe6\x64\xbb\xaf\x4d\xe6\x4e\x33\x8b\x95\x10\x33\xcc\xcc\xb3\x14\xca\x11\x82\x59\xac\x32\x2e\xe8\xd0\x47\xe3\xf5\xb9\x14\xb0\x85\x96\x52\x02\xb6\x68\x35\x78\x8c\xfd\xb7\xf8\x36\x4e\x22\xec\x4e\xb7\x02\x8f\xf5\xd1\x60\x54\x1a\x32\xe3\x62\x01\xd0\x61\x4d\x98\x85\xfa\x13\x3c\xc5\x10\x24\x1f\xcc\x58\xe9\xa4\xb1\xf0\xac\x10\xfa\x20\xc0\x37\x09\x7d\x6d\x39\x31\xe0\xab\xd7\x2c\x70\x2f\x20\x50\x8b\x27\xfe\x10\x57\x38\x16\xc2\x12\x41\xa0\x63\x36\x3b\xd5\xa6\x70\x1b\xff\xb5\xa6\xf0\x3e\x03\x0d\x66\xd8\x63\x3f\x5e\x7c\x98\xbf\x24\x1d\x9d\xa5\xbd\x1a\xe0\x61\x38\x65\xd1\x12\x08\x7d\xf8\xe1\x3c\x2e\x49\x42\xa2\x9f\xa5\x45\xff\x9c\x4e\x55\x0a\x7b\xa2\x7b\xa2\x18\x0e\x8c\x70\xe2\xbc\x4a\x03\xf4\x5c\xbd\xd4\x4d\xf2\xe5\xa8\xe1\x14\x05\xe9\x3b\xe4\x5e\xbe\x32\x9f\xa5\x44\x79\xb4\x89\xfc\x2b\x36\xa3\x75\xeb\x32\x0d\xaf\x30\xda\xff\x15\xce\xc1\xf1\x7c\x10\xe3\xff\x99\xe3\x20\xc9\x3b\xcd\x03\xda\xc2\x5d\xa4\x84\x5d\xb9\x8e\x94\x36\x3f\xa6\x39\x21\x7f\x8c\xfc\x31\x1d\x75\x28\x5a\x11\x60\x1c\xa4\xf7\x68\x6d\x0d\xb1\x09\x92\x5e\x1a\x73\x5b\x17\x04\x0c\xa2\xd6\xfd\xa9\x05\x25\xc4\x00\x12\x0d\xd3\x63\x7d\x96\x88\x04\x2e\x5c\x32\xd9\x7d\x5d\x64\xcc\xce\x77\xab\x05\x63\x1e\x76\x5b\x4f\xb2\xcc\xf7\x26\xcb\xa0\xff\x9a\x45\x38\xc6\xd1\x15\x66\x52\x4d\x38\x27\xc7\x07\x49\x9a\x01\x5d\x8b\x9b\xf8\x83\x09\x63\xdc\x68\x3b\x42\xaf\x23\xdf\x0d\xd0\x1b\xea\x58\x8b\x46\xfe\x04\xe3\x60\x58\x1b\x52\x18\x3c\x4c\x39\xc4\x6e\xd7\x88\xea\xec\x84\x96\xf9\xa7\x1b\xa0\xbd\x68\x3e\xb8\x45\x1f\xc7\xe4\x9f\xda\x35\x1e\xfc\xd7\xe5\xd4\xf5\x27\xb5\x61\x38\xb5\x09\x50\x67\x27\xbc\xc9\x3c\x39\x4a\x2e\xb5\x80\x38\xf5\x43\x9a\x01\x29\x18\x92\xe3\x09\xcd\x33\x46\xbe\xc0\x1c\x00\x49\x8a\x24\x62\xa0\xd5\xa2\x5a\xac\x2a\x50\x02\xfd\xf5\x6f\xb4\xb6\x16\x5e\xe1\x68\x34\x09\xaf\xa1\x12\xec\x9d\x0d\x9e\xa3\x97\x54\x6c\x74\xab\x3f\x91\xc2\x2f\xd3\xef\x4d\xf9\xfb\x46\xe6\x73\x8b\xed\x82\xac\x3d\x86\x2e\xe0\x43\x40\x8b\xc6\xd7\xd6\x10\x6f\x1b\x0d\x1a\x50\x86\x62\x0e\x08\xd4\x5f\xa6\xb5\x9a\x69\x2d\xa9\xd8\x0f\x80\x08\x2b\x47\x0b\xb6\xb4\x82\xbc\xe4\x0f\x80\x14\x2f\x7a\x47\xff\x21\xf4\xaa\x96\x7a\xfe\x7c\xd0\x52\xca\xd0\xff\x8a\x82\xac\xdc\xf3\xe7\x83\xe6\x4b\xe9\xbb\xb1\xd4\xf3\xe7\x83\x86\x28\x04\xff\xc2\x98\x08\x2c\xe0\xe9\xf9\x26\x8c\xc9\xab\x57\x3c\x4f\xab\xfc\xbe\x49\x95\x9a\xea\x6b\x8e\xa0\xb1\x4d\x51\xb7\x7e\x53\x6f\x30\x5d\xa6\x5c\x9c\x71\x4e\x52\x0c\x5e\xdf\x65\x29\x89\xad\xa8\xca\x90\xfe\xab\xd3\x13\x7b\x4d\x6f\xd2\x38\xe1\xa5\x2f\xab\x8c\xb8\x94\x69\x5a\x5b\x43\x64\xf3\x81\xbb\x28\xe4\x4b\xeb\x8f\x2e\xb9\xcc\x02\x5d\x89\x11\x40\x8c\x51\x18\x4c\x6e\xe9\x2a\xde\xfe\xed\xe8\x64\x1b\x7d\x44\xaf\xd0\x06\x05\xca\xdb\x6c\x98\x10\x61\x77\x93\x5a\xb7\xd9\x57\xa9\xe7\x7c\x0d\x2a\x47\x12\xb1\x1e\x6b\x96\xd7\x5f\x57\xda\x5d\x5c\xd8\xcd\x94\xd7\x05\xa6\x6c\xc3\x8c\xad\x8a\x96\xc5\xc8\x65\x3b\x90\x2b\x5f\xa1\x1c\x19\x0b\x64\x13\x73\x43\x45\x12\x17\x5a\x46\xea\x42\x25\x24\xaf\x54\x04\x21\x04\x9f\x5d\x0d\x9c\x97\xfd\xa0\xcb\x62\xac\x80\x8c\xb3\xaa\x69\x5f\x4c\x08\x43\x36\x41\x0c\x2d\x29\x8c\xa1\x45\x05\x32\xa4\x49\x91\xc6\xa3\x60\xba\x26\xe4\x13\xa1\x58\x36\x2f\x33\xc2\x9c\xa8\xa0\xc9\x74\x39\x72\x9d\x5c\x65\x21\xf1\xae\xfd\x24\xde\x7d\x6f\xe2\x9d\x4d\xa8\xb3\xaa\xa8\xce\x4e\x0a\x44\xab\xc5\x55\x54\x86\xfd\x40\xdf\x08\x9e\x76\x00\xa5\x03\x7f\xc5\x1d\x20\xf7\xe0\xfd\x38\xcc\x7e\x3f\x18\x46\x18\x22\x7c\x30\xf8\x3a\x54\x26\xdc\xa4\x73\xbd\x8a\xa8\xad\x92\xe5\x0b\x58\x1c\x7c\x46\xf5\xef\x73\x67\x29\xbf\xa5\x94\xd3\x0f\x40\xb9\x85\x36\x90\xce\xd3\x06\xf2\x7d\x6e\x20\x3b\x13\x3c\x4c\xa2\x30\xf0\x87\xa8\x1f\x7a\x78\x10\x86\x65\xee\x3b\x76\xfa\xb9\xf7\x1d\xf4\xf3\x82\x9b\xc9\x4e\x5f\xbd\xef\x20\xcf\x0f\xb7\x79\xc8\x9b\x82\xca\x6d\xd4\x8a\x45\xda\x5a\x82\x95\xb2\xda\x1e\x0f\x4b\x0f\x2f\x8d\x25\xcf\x71\xd6\x2f\xa7\x10\xa4\xe5\x16\x5a\xf0\xdf\x7f\x26\xf4\xbf\xe9\x82\x3f\x9a\x27\xb3\x79\xb2\xc8\xe5\xe6\x51\xfe\xe5\xe6\xd1\x32\x97\x9b\xba\xe4\x78\xa4\x5d\x76\x1e\x7d\xf5\x9b\xb2\x2f\x21\x39\x66\x6f\x28\xc4\x9b\x87\x97\x1e\x73\x1a\xfb\xa6\x24\xc8\xbf\xe4\xf1\xff\x48\xbb\x09\xb6\x0b\x69\x47\x25\x2f\x71\x8e\x16\xbf\xc4\x79\x4a\x32\xf9\x9d\xf2\xec\xad\x77\xa7\xfb\xe8\xf7\xda\x8b\x66\x8b\x5b\xfd\xa3\x38\x21\x8c\xe0\xf2\xd6\xc0\xb4\x67\xae\x57\xdb\x0a\x62\xff\x77\x52\x3e\x4d\xd2\x38\x73\x3d\x99\x65\x7a\x6e\xe2\x4a\x17\xc9\xd6\x0b\xe4\x58\xbb\x41\x26\xf5\x4e\x53\xe3\x6d\xc5\x98\xfb\xa5\x56\x76\xa0\xe7\xe5\x19\xd8\x33\xf2\x00\xa9\xcc\x83\x44\xf4\x50\x0f\xb3\x06\xd6\x92\xc7\xf4\x63\x06\x1e\x7d\xb1\xaa\x62\xf7\x0f\xed\xbb\xa1\x41\x1a\x40\x69\xe2\xc6\x34\xac\x1b\x9a\x85\xb1\xaf\x45\x6d\x20\xed\x92\x02\x04\xc4\x71\xc8\xfb\x2c\x1a\x79\xae\x21\xb5\x8a\x1a\x99\x76\x8e\x5d\x4f\x7a\x01\x43\x96\xe6\xeb\x51\xdf\x53\xce\x23\xb7\x97\x46\x7c\x53\x1b\x4a\x23\xbe\xc9\xa5\x8d\xb1\xdf\x54\x8b\xfb\xe7\x1a\x24\x61\x30\x9a\x9a\x51\xcf\x03\x03\xb5\x64\x48\xe4\x0d\x4e\x50\x30\x07\x4b\x90\x70\xa4\xce\x1b\xbd\xae\x10\xe3\x5a\x30\x8d\x52\xcf\x2b\x2a\xae\xab\xe4\x5c\xce\x46\x40\xbe\x22\x93\xb0\x60\xbb\x52\xd6\x1d\x46\x83\x64\xeb\x35\x59\x8d\x36\x4e\xcb\x97\xd2\xcd\x8b\x66\x6b\x51\x6e\x7b\xcf\x34\x81\x4f\xdc\xf6\x6b\x71\xdb\xfd\xd3\x23\x04\xe1\xa0\xcb\x32\xdb\x7d\x16\x3e\xfa\xfe\xcc\xf6\x9b\xe0\x9f\xe9\x9a\x29\x64\xa0\x26\xc6\x46\x33\x66\x98\xc3\x27\xd6\x22\x37\xf0\xc2\x69\x25\xc3\x32\xab\xd5\x9a\x2e\x86\xe5\x03\x62\x09\xfc\xce\x33\x3c\xb1\xd9\xbe\x70\x08\xbc\x27\xae\x96\xcb\xd5\x38\xcd\x2e\xca\xd5\xbe\xff\x24\x25\x7f\x5f\xae\xb6\xb6\xbf\xd3\x47\x2f\xd6\x5f\xac\xaf\x36\x10\x23\x1a\x74\x88\x93\x71\xe8\xa1\xa6\x9d\xb5\x41\x14\xfc\xe5\x59\xdb\x96\xe7\x51\xb7\x53\x6d\xc5\x94\x60\x16\x7c\x8d\x93\xea\xf4\x4f\x2c\x6d\xb5\x8d\xff\xc6\x51\x08\xa9\xfc\x92\x31\x46\x11\x8e\x65\x3e\xaa\x74\x87\x14\x64\x3d\x27\xcf\x19\xe4\x97\x66\x1a\x6c\xb9\xfe\xc9\x10\xd1\xd6\xac\x15\x07\x00\x4e\x21\xda\x38\x40\x18\x60\x34\x0d\x23\x4c\xe5\xd3\xd5\x55\xe8\xa3\x75\x40\x39\x63\x58\x5d\x5d\x84\x13\xc0\x14\x2f\xc8\x09\xd6\xef\x99\x26\xe0\x89\x13\x7c\xb5\xd3\x24\x0a\xc2\x70\x56\x56\xb8\x79\xc7\x89\xd5\xce\x02\xd2\xd5\x90\xb7\x6e\xa4\x52\x45\x24\x29\xda\x5c\x94\x26\xef\x19\x81\xf9\x89\x26\xbf\x16\x4d\xfe\xb7\xc4\x38\x8b\x28\x52\x62\xa0\x5f\x5b\xe2\x5e\xe0\x60\x2f\x1f\xbf\x33\x62\x77\xa5\x92\x2f\x78\x57\xd1\xe7\xcf\xfa\xab\xa5\xf7\x2a\x4b\xd7\xcb\x84\xb9\x58\x5b\x43\xef\x49\x1b\x5a\x55\x3f\x13\xb8\x82\x6a\x41\x44\xa1\xeb\xb1\x3f\xc1\xa8\xf2\x63\x25\xf5\xf5\x4f\x63\xd9\x83\x0b\x6b\x26\x76\xbd\x30\xc1\xcd\x6a\x68\xfd\x74\x77\x43\x9a\xee\x55\x8f\x2d\x00\xa1\xaa\x4b\x6f\x85\x12\x65\x2d\xca\x79\xbe\x7f\x67\x3f\x43\x12\x3d\x9a\xc5\xee\xf1\xb9\x50\x9a\xaa\x0c\x5a\xfc\x86\xb2\xee\x3c\x48\xe0\xf8\xd7\x6e\x8c\x45\x3c\x78\xf2\x20\x7f\x2c\x19\x55\x3e\x1b\x34\x5e\x7c\x3a\xdd\xdb\x6a\xa4\xe1\xd1\xc9\x93\xfc\x15\x92\xbc\x8a\xaf\xe4\xc9\xe2\x83\x7c\xec\xc6\x31\x59\xf2\xab\x04\x43\x0f\xbd\xc5\xb7\x68\x1b\x47\xfe\x15\xcd\xf5\xba\xcb\xc7\xa7\x59\x14\xac\xfd\xf8\xf5\xdb\xed\xdd\x66\xda\xa4\x78\x26\x70\x4d\x97\x7a\x99\x2c\xb5\xfd\x30\x18\xf9\x97\x73\x96\x65\x36\x84\x7c\xaf\x71\x7e\xee\xd8\x28\x9c\xe1\x28\xb9\x45\xff\xa6\x27\x77\xf0\x59\x06\xae\x7d\x36\xa6\x99\xcf\x63\xf2\xe0\x07\x2c\x49\x47\x12\x0a\x6f\xab\x1a\xda\xc6\x23\x77\x3e\x49\x7a\xa8\x8d\x2a\x8d\xe6\x06\x64\x58\xaf\x5a\x1b\xa0\x6e\xc3\x77\x3c\xd1\xe9\x99\xf0\x9c\x67\x2e\x70\x12\x3c\x32\x15\x85\x88\xfa\x09\x4b\x8e\x1b\x03\xac\x54\xf3\x20\x7d\x48\x42\x34\xc3\xd1\x28\x8c\xa6\x12\x74\x15\xb4\x9c\xd4\x75\x38\xba\xec\x59\x47\x1b\xd1\xab\xc0\x53\x08\x9d\xd4\x68\x6e\xac\xb5\x9a\x7a\x04\x7b\xda\x1f\x8a\xbf\xfe\x2d\xc5\x4a\xc5\xe0\xae\x5a\x90\x7a\x38\x4d\x33\x12\x23\x17\x05\xf8\x7a\x72\x8b\xe8\x01\xcf\x83\x09\xf2\x52\x5a\xe3\x6b\xb1\x4c\xba\xe0\x23\xe0\x89\x77\xa4\xcf\x72\x6a\x60\x32\x94\x43\x13\x19\x71\x47\xc5\x51\x18\xc1\x49\x2a\x6d\xf6\x81\xf2\xff\x7e\xf2\x46\xf2\x75\xb8\xb4\x04\xf8\x79\x56\xb5\x81\x5b\xa4\xe6\xbf\xd3\x99\xdb\x60\x79\x65\xef\x0d\xc7\x51\xa7\xb4\x5e\xaf\x67\x20\xcb\xb4\xe5\x07\xbe\x92\x59\x61\x38\xba\xb4\x98\xb1\x90\x19\xd9\x14\x3f\x39\x29\x92\xf2\x39\xb1\x5b\x0c\xbc\x00\xae\x68\xa8\x0b\x66\x59\x16\xb5\x5c\x9e\xe9\x19\x83\x0e\xc4\xc3\x1f\x6a\x65\x6b\xc7\xee\x24\x41\x5b\xf0\xcf\x32\x19\xa8\xb9\x67\x95\x1c\x5c\xe1\x9e\x84\x88\xc9\x96\xf2\xc9\x1b\xd5\x58\x48\x9d\x0a\xef\x93\x03\x58\xe6\x4c\x32\xab\x20\xcf\xb3\x56\x77\xc1\xdc\x4b\x2a\x2d\x58\x4c\x3a\xfd\xc4\x96\x0b\x9a\x45\x7b\x80\x48\x12\x8c\x84\x09\x49\x51\x3e\xe5\x88\xb9\xb2\xd9\x8a\x02\xe3\xa1\x61\xee\x8c\x41\xe0\xe8\xd0\xbf\x85\xf1\xca\x68\x9f\x8c\xe1\xcc\x40\x14\xdf\x0f\x3c\x7c\x63\xaa\x72\x5e\xbf\x61\xfa\x2a\x63\x20\xdb\xa2\x98\x74\x02\x1d\x21\x8d\x8b\x37\x42\x26\xcf\xc1\x88\xd7\x4a\xdf\xd8\x6b\xf1\x5d\x72\x93\xcc\x50\x8d\x3d\x19\x4d\x59\xd2\xcd\x88\x96\x4d\x5f\x14\x5a\xaa\x68\x5f\xd9\x59\x40\xeb\x26\x0f\xfd\xf5\x8a\xe3\x64\x36\xcc\x10\x5d\x65\x39\xcf\x79\x2a\x7d\x20\xca\x34\x93\x77\xda\xf7\xcc\xf4\x21\x96\xf3\x5f\xca\x0f\x6e\x28\x51\x22\xf5\x09\xb4\xa1\x0c\xb6\x79\x9c\xb3\xe5\x45\xee\xb1\xf4\x15\xeb\xbe\x15\x99\x7d\x31\xdc\x16\xe8\xbe\x1c\xd6\x91\x41\x36\x61\xa2\x58\xc4\x34\xa8\x45\x8c\x34\x97\x76\x93\x18\x04\xcc\x5f\x69\x04\x86\x51\x8c\xb9\xfc\xd1\x38\xea\xe5\x46\x1e\x15\x06\x3c\x33\x75\x99\xcf\x83\xfc\xce\x16\x9b\x4d\x6a\xe5\xf7\xa3\x13\xb5\x53\xe0\x40\x67\x72\xf0\xcf\x8c\xdf\x47\x6a\x51\xf4\x91\x5b\x14\x49\x33\xfb\x12\x7d\xcc\x1b\x45\xf2\x97\x56\x39\xff\x08\xc6\x45\x99\xce\x9c\x7f\xcc\x18\x19\xf1\x3f\xdd\x62\x0a\x19\x03\xab\x91\x3f\x89\x73\x30\x55\x3b\x34\x6c\x9c\x1e\x8d\x83\x9c\xd7\x2f\x9e\x3f\x2f\xb2\xd5\x92\xe0\x4b\x87\x6e\xce\x55\x8c\x11\xfc\xd8\xfe\x97\xd6\x2c\xb2\x65\x55\x0e\x29\xf7\x13\x07\x4a\x45\x4b\xca\x17\x03\x16\x15\x01\x1e\x4a\x52\xf5\x63\xb6\x2b\xab\xb2\x6a\x89\xf8\x4b\x26\xc9\xe2\xa1\xc2\x30\x51\x19\x43\x88\x9a\x54\xca\xb4\xca\x19\x8b\xd5\x73\x90\x4d\xdc\xbd\x0f\x9c\x7c\x71\x57\x0a\x14\x25\x8e\xad\x36\x19\xc8\x41\x19\xd9\x97\xcd\x80\x2a\x6c\x93\x52\x45\x22\xd8\x5d\x91\xc9\x1f\x05\x69\x0d\x37\xa5\xa7\xd8\xe6\x39\xa3\xef\x2e\x9c\xf5\xef\x3f\x74\x83\x94\x7f\x5c\xfd\x30\xf5\x3a\x7a\x51\x9a\x87\xfc\xab\xea\xd4\xad\x19\xf9\x6d\x89\xf2\xff\x6a\xfa\xae\x53\xb0\x92\xed\x73\xab\x6a\xaa\xd5\x92\x5f\xe6\x2b\xb6\x52\x6c\x4e\xf0\x3c\x76\x07\x13\xcc\xe2\xdf\xc9\x48\x9d\x22\x25\xd3\x2a\x85\x94\x79\xf5\x06\xe9\x59\x13\xe5\xcd\xe4\x04\x52\xb1\x23\x66\x03\xcd\xac\xc0\x0d\xda\xad\xb4\x06\x84\x06\xf2\x63\xe4\x22\x9a\xbf\x1d\x5d\xe1\x28\x86\x70\x7d\x63\x37\x41\x01\xbe\x9c\xe0\x61\x82\x3d\xc2\xba\x87\x2c\xd9\x72\xc2\x14\x50\x49\x88\x26\x7e\x92\x4c\xf0\x2a\x8d\x09\x5b\xd3\xa0\xe2\x28\x0a\x23\xe4\x85\x38\x0e\x56\x12\xe4\x8e\x46\x78\x48\x2b\x53\xbc\x56\x62\x14\xe3\xe1\x3c\xf2\x93\x5b\x27\xad\x39\x98\x27\xc8\x4f\xa0\x16\xaf\xe2\x27\xb1\x88\xeb\xe1\x4f\xfc\x84\x05\x05\xa0\x39\x9f\x7d\xc2\xcf\xa7\x38\xa0\xbb\x48\x6c\x56\xe0\xd1\x61\x39\xa0\x1d\x14\x6a\x3c\xed\xad\x3c\x9d\xcb\x67\x61\x2c\x38\x0a\xbd\x95\x4d\xd5\xed\xa7\x98\xd4\xce\x1e\x4e\x26\x57\xf9\x27\x12\x9f\x9d\x07\xc9\xbe\x87\xed\xa7\xc2\xdf\x45\xdb\xe4\x97\x29\x1d\xe4\xdb\xf3\xfa\x85\x83\x2a\x6f\xcf\x5b\x17\x2c\x2a\x05\xfa\x4c\x1e\xd9\x95\x46\xa3\x5b\x35\xa5\x86\x7c\x7b\xde\xa0\xb5\xea\x6a\xad\x56\x41\xad\x26\xad\xd5\x50\x6b\xd5\x0b\x6a\xb5\x68\xad\xa6\x5a\xab\x21\x6a\x69\x95\xcc\xd9\xcc\x32\x43\xc7\x1d\x4f\xad\x83\xd7\x17\x83\xd7\xb7\x0c\x5e\x16\x29\x69\xd8\x58\xcf\xe8\x05\xd0\x68\xc4\xd3\x8b\x52\xcc\x69\x98\xe2\x7a\x9d\x7c\x31\xf6\x3a\x3b\x23\x2d\x15\x74\xc3\x08\xba\x59\x0e\x74\xdd\x3a\x01\x12\x10\x0d\x74\xab\x1c\xe8\x86\x6d\x96\x1c\x09\x88\x06\xba\xae\x81\x2e\x35\xa1\x7d\x37\x8a\x6e\xd1\x20\x93\x66\x99\x4e\xd9\x80\x05\x5e\x31\xa8\x52\x12\x4a\x07\x84\x2d\xc5\xb7\x71\x82\xa7\x68\x14\xce\x23\x94\xf8\xd3\x0c\x19\x2c\x1a\xe4\x3a\xc0\x37\xc9\x29\x59\x92\x39\x31\x98\x8d\xd1\xa3\x0f\x43\xcf\x1f\xdd\x52\x56\x49\xe9\xb2\x0c\x2a\x1b\x39\xa8\xf4\xcf\xa9\xc3\xc7\xef\xe7\x90\xea\x16\xa2\x01\x65\x73\x3f\x9a\x93\x69\xff\x8a\x62\x9c\xcc\x67\xda\x97\x3c\xbf\x9c\x12\xaa\x86\xfd\x5f\xa9\x87\x4e\xae\x7e\x61\xff\xd7\x0f\x75\xb4\x89\xf6\x7f\x35\x24\x3a\x94\xca\x34\x68\x99\x86\x25\x52\xb8\xbc\xdc\x61\x6e\xe3\xf9\xe0\x0a\x13\x59\xc3\xaa\x79\xa8\xd3\xc8\xe2\xd0\x3e\x0d\x2d\xfe\x19\xd1\x27\x5b\x68\x71\xb9\x38\x0b\x21\x2e\xca\xa7\x37\xbf\x96\x10\xe2\xa2\xdd\xa6\x68\xb7\xa1\xb4\xdb\x28\x6a\xb7\xa1\xb6\xdb\x58\xb0\x5d\x08\xf9\xe4\xd7\xf9\xe2\x24\x50\xfc\xa6\xba\x36\xad\x75\x5b\x50\xb7\xc9\xd7\x39\xd4\xad\xab\x2b\xd8\x3a\x2f\x8c\xd0\x73\x99\x2f\x02\xf2\xad\x53\x95\x42\x26\xcd\x06\xfd\xda\xa0\x5f\x1b\xe6\xaf\x4d\xfa\xb5\x69\xfe\xda\xa2\x5f\x5b\xe6\xaf\xed\xdc\x76\x3b\xb9\xed\x76\x73\xdb\x5d\x4f\xdb\xcd\x53\x90\x95\x63\x4d\x68\x09\xf6\x84\x4a\xb2\x28\x64\xd0\x92\x28\xce\x61\x0f\x95\xe6\xd9\xae\x6c\x97\x24\x97\x92\x5c\x5c\x2b\x63\xe9\x67\x8e\x60\x00\x43\x9d\xba\x13\x02\x9f\xd2\x8a\x9f\xd2\x38\x58\xbf\x03\x71\xa2\xca\xef\x84\x1c\xf8\x0a\x82\x67\xb1\x67\xeb\x43\x7a\x4a\x03\x57\xfd\x0e\xa4\x49\x4a\xae\x6b\x35\x3b\xf6\x9a\x4d\x5a\xb3\xcd\x6a\x36\xb4\x9a\xeb\xf6\x9a\x2d\x5a\xb3\x7b\x21\xb0\x53\x6a\x36\xa4\x9a\xf7\xdc\xf9\x72\x73\x45\x50\x64\x78\xf6\x06\xf8\x95\xa6\x6f\x80\xc7\xa5\xf2\x37\x70\x40\x8c\x0b\x0a\x40\xc6\x0c\x0e\x66\x9c\xcd\x1e\x97\x48\xca\xdc\x2d\x3c\x27\x4f\x8b\x3c\x26\xd5\x45\x21\x0c\x9d\xa4\x0b\x6a\xe9\xb3\x7f\x45\xbf\x75\xdb\x6b\xad\xa6\x41\x61\x28\x96\x90\xa0\xe3\x4a\x69\xef\x36\x75\xed\x28\x9f\x24\x99\x36\x63\x14\x75\xea\x5e\x61\x14\x4e\x3c\x3b\x73\x5e\x44\x06\xe9\x7f\xa0\x13\xde\xcf\x06\xfe\x54\x9b\xed\xbb\x93\xe1\x7c\x42\x16\x60\x80\xaf\xed\x6d\xf7\x59\x32\xa7\x3e\x4d\xe6\x54\xbf\x69\x7b\x2d\xf8\x3f\xf4\x9c\x8b\x7c\x99\x84\x4b\x7d\x96\xdb\xa9\x4f\x73\x3b\xd5\x6f\x58\x95\x16\x24\x76\xe8\x73\xb9\xb7\x5e\x45\xaf\x50\xa5\xff\x41\x7a\xfe\x4f\xd4\x40\x3d\x54\xaf\x1a\x40\x36\x19\xc8\x26\x05\xc9\x20\xb6\x19\xc8\x86\x06\xb2\x51\x06\x64\x8b\x81\x6c\x65\x7a\x56\xa1\x0d\x29\x20\x9b\x65\x40\xb6\x19\xc8\xb6\xb1\xe3\x2d\x0d\x64\xab\x0c\xc8\x0e\x03\xd9\x31\x76\xbc\xad\x81\x6c\x97\x01\xd9\x65\x20\xbb\xc6\x8e\x77\x34\x90\x9d\x32\x20\xd7\x19\xc8\x75\x63\xc7\xbb\x1a\xc8\x6e\x31\xc8\xf4\x3c\x41\xa1\x2a\xf5\xd7\xf5\xfa\x59\x7f\x26\x41\xde\x64\xab\xba\x5c\xbd\xd7\xa2\x22\xc5\x2e\x6f\x80\xa7\xfb\xa4\x7f\x7d\x63\xb2\x1c\x50\x5d\x06\x71\x12\xcd\x87\x09\x1a\xfb\x97\x63\xe4\x06\x1e\x9a\x84\xd7\xc8\x8d\x2e\xe7\x10\x71\x08\x7c\xdf\xff\x67\xee\x46\xd9\xe4\x5b\xd0\x86\x8b\x36\x49\x43\x5c\x1e\x34\x29\x2c\x2e\x07\xb4\x0c\xdd\x51\x2c\x47\x34\xde\x77\x05\x8b\x08\xc7\xf3\x49\x82\xc2\x51\x2e\x0a\x63\xba\x5b\x54\x2e\x5d\xf4\x33\xba\x74\xa9\xaf\x51\x63\xbd\x8a\x9e\x23\xfa\x6a\xc0\x5e\x75\xe0\xd5\x00\x5e\x19\x11\x9d\x50\x48\x52\x7f\xe8\xd9\xf3\x67\x74\x79\x03\xd3\x5d\x05\xea\xe0\x05\x84\x10\x2b\x15\x30\x27\x71\x22\x9d\xfa\xfd\xe8\x04\xd1\x60\xaa\xf2\xd7\x37\x94\xf9\x5d\x8e\xd1\x1f\xe8\x72\xb2\x00\xff\xb3\x28\x74\x7e\x67\xdc\xef\x0d\xe5\x7e\x95\xca\x9b\x74\xdb\x27\x7b\xdf\x1b\x49\x9e\xa8\xb2\x02\x5d\xb5\x40\x37\x2d\x90\xa1\xf1\xdf\x19\xa3\x7c\x43\x19\x65\x85\xb6\x93\xee\xd1\x6f\x38\x6b\x84\x3d\xfa\x39\x22\xcd\x19\x80\x34\x19\x90\x26\x07\xd2\x50\x51\x68\x64\x70\xac\xab\x05\xea\xb9\x38\xb6\x18\xf8\x16\x07\xdf\x54\x71\x6c\x6a\x38\x36\x4c\x38\xb6\x19\x90\x36\x07\xd2\x52\x51\x68\x65\x70\x6c\xaa\x05\x9a\xb9\x38\x76\x18\xf8\x0e\x07\xdf\x56\x71\x6c\x6b\x38\xb6\x4c\x38\x76\x19\x90\x2e\x07\xd2\x51\x51\xe8\x64\x70\x6c\xab\x05\xda\xb9\x38\xae\x33\xf0\xeb\x17\x0a\xa5\x08\x1c\xbb\x1a\x8e\x1d\x15\xc7\xb2\x39\x79\x62\x9e\xff\x45\x28\x7f\x4b\x65\x80\x29\xbe\xb0\xa3\xf0\x12\x7c\x93\xc8\xf7\x66\xb2\x6e\x97\x07\xde\x50\x52\xa9\xd0\xbb\x2e\xc3\x05\xdc\x6c\xe2\x12\x94\x6e\x12\x64\x85\xc7\xc2\x18\x55\xd2\xa6\x8d\x20\xd3\x9b\xb7\x3c\x4d\xb3\x9a\x51\x47\x2e\x59\x2d\xba\x42\x93\x0b\x2f\x62\xdd\xed\xa8\x57\x3a\xbd\x4e\xdb\x49\xef\x72\x7a\x9d\xae\xc3\xae\x78\x7a\xdd\xc6\xdd\x85\xb3\xfe\xfd\x87\xd2\x7c\xba\x6e\x7b\xba\x6e\xfb\xf2\xd7\x6d\x19\x46\x90\x5e\x45\xe9\x97\x50\xdf\xe3\xf5\xd3\xc3\x65\x83\x7c\x2b\xb4\x01\x6f\x55\x6d\xc0\xdb\xa5\xb5\x01\x6f\x55\x6d\xc0\xdb\x5c\x6d\x40\xb1\x12\xfc\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\xed\xe9\xaa\x2d\x7d\xfd\x74\xd5\xa6\xd4\x79\xba\x6a\x7b\xba\x6a\x7b\xba\x6a\x7b\xba\x6a\x7b\xba\x6a\x7b\xba\x6a\x43\x4f\x57\x6d\xe8\x2f\x7f\xd5\xf6\x70\x97\x6c\xcb\x5e\xaf\x95\xb9\x58\x2b\x79\xa5\xf6\x88\x97\x69\xdf\x7f\x5a\xa1\xa7\xcb\xb4\xbf\xe5\x65\x9a\x72\xef\xd5\x6f\x17\xfb\x98\x29\xb7\x5e\xfd\xb6\x74\xe5\x05\x0f\x5f\xe4\xbe\x8b\x7a\xd3\x8a\x1b\x2f\x4b\xc0\x08\xee\x6a\x9f\x7b\x27\x06\x0e\xb7\xb2\x43\xb8\x9c\x23\xc0\xa0\x27\x09\xfc\x04\xc5\x83\xf0\xc6\x00\xea\x54\xe0\x74\xaa\x5c\x38\xf2\x3f\x93\x64\xda\xec\x74\x73\xb4\x00\xec\x90\xef\x97\x52\x33\xbf\xc5\xb7\x46\x3d\xb3\xda\xac\xc3\xe3\x01\x14\xb7\xce\x86\x87\x0c\x06\x8f\x20\xe2\xa3\x7f\xc8\x23\x66\x53\x69\xb2\x5a\x64\x5b\xe4\xf3\x70\xae\x40\xca\x06\xd4\x53\x3e\x67\x62\xeb\x99\x15\x0e\xa4\x27\x95\x8f\xe8\x39\x1d\xa7\xe7\xbc\xd9\x2a\xfa\x07\xf4\xcc\x1a\x2f\xe3\xda\xd5\xc7\x88\x23\x0e\xbb\x8d\x41\x31\x21\x4d\xc6\xa9\x25\xde\x01\x79\x4f\x08\xa0\xd4\x5c\xf5\xcd\x97\x12\x2c\x0b\x8d\xa0\xa3\x8f\x3c\xb3\xb4\x00\xf6\x10\x9a\x42\xae\x8a\x01\x35\x0c\x8f\x2e\xf6\x96\x2b\xea\xc8\x6c\x59\x74\x99\x5a\xeb\xc2\x57\xbd\xd9\xe9\x5a\x15\x32\xf5\x3c\x65\x8c\xb1\xf1\xf2\x8a\x19\x69\xc1\xe9\x8a\x99\x74\x0c\x7d\xfd\xd3\xc7\x74\x78\x33\xa7\xcb\x6c\xde\x22\xd0\x5b\x6a\x10\x3e\xc9\xe8\xea\x53\x24\x96\x5b\x40\xd7\x59\x40\x35\x7d\x81\x69\x95\xf9\xa0\xf9\xa7\x39\x1d\x39\xcd\x2a\x05\x14\x0a\xb7\xd2\xb5\x99\xa6\xf3\xe8\x39\x87\x96\x25\x3a\xd6\xbe\xa8\xdd\xfe\x4c\xaa\x57\xd8\xca\x23\x95\x18\x7a\x17\x69\xbe\x8f\x20\x93\xdf\x23\x73\x5a\x7b\x0f\x51\x71\x4c\x97\x74\xe9\x5a\xf0\xb3\xea\x03\x32\x2e\xda\xec\x31\x91\x4f\x41\xf2\x5b\x17\xb1\xfb\xed\x07\x91\xaf\xfb\xed\x25\x84\xeb\xec\x6e\xad\x49\xd6\xfd\xb6\x2d\xb6\x09\x5c\x3a\xf9\xd8\x5b\x4a\x60\xd8\x8e\xc2\x99\x22\x34\xb0\x17\x30\x18\x5f\x28\xe6\xa2\x47\x9a\x54\x83\x18\x6a\x17\x15\x84\x10\x48\x29\x11\xc6\x10\x35\x5e\x34\x15\xb8\x99\x38\x86\xa4\x03\x52\xfc\x38\x7d\xad\x13\x68\x3d\x0d\x8a\x1e\x8b\xb0\x9c\x70\x44\x1a\xe2\x25\x8b\x6e\x63\xc8\xe0\xe6\xc9\x03\xc2\x1a\x88\xa0\x47\x84\x82\x5f\x40\x36\x58\x5d\x35\x8b\x04\x8b\xec\x16\xa8\x44\xb6\xb1\x6f\x6d\x39\x92\xe1\x7a\xa0\x25\x09\xa0\x96\x59\x96\x6c\x3d\xe4\x2f\x4d\x52\xa8\xf8\xd4\xdb\x6f\x3f\xe2\x91\xf7\x9e\x89\x35\xbf\xf0\x59\xf7\x51\x4f\xa4\x5f\x27\x20\x39\xe1\x6c\x38\xc6\xd1\x15\x21\xf5\xca\xb0\x8a\x9a\xf5\x46\x13\x0d\x6e\x51\xff\xff\xfb\x7f\xbd\xc8\x1f\xa2\x43\x1c\x07\xfe\xa4\x86\xb6\x26\x13\x14\xf9\x97\xe3\x24\x46\xac\x82\x57\x03\x20\x27\xd8\xf3\xe3\x24\xf2\x07\x73\x68\xc4\x0d\x3c\x08\xe4\xe4\x07\x28\x0e\xe7\xd1\x10\xc3\x9b\x81\x1f\xb8\xd1\x2d\x61\x1b\xd3\xd8\x61\x31\x3a\x22\xf8\x37\x9c\x27\x68\x0a\x7b\xc1\x10\xb8\xb1\x83\xdc\x08\xa3\x19\x8e\xa6\x7e\x92\x60\x0f\xcd\xa2\xf0\xca\xf7\xb0\x47\x83\x8e\x90\x85\x3c\x0a\x27\x93\xf0\xda\x0f\x2e\xd1\x30\x0c\x3c\x9f\x2e\x72\x52\x69\x8a\x93\x9e\xe0\x0a\xab\x48\x45\x2c\x06\xdd\x36\xc5\x68\x18\x7a\x18\x4d\xe7\x71\x42\x36\x7c\xd7\x0f\x00\xac\x3b\x08\xaf\xc8\xa7\xd9\x2d\x74\x13\x05\x61\xe2\x0f\xb1\x43\xa3\x51\x4d\xfc\x18\x94\xe3\x72\x8b\x81\xa7\xa1\xe3\xf9\xf1\x70\xe2\xfa\x53\x1c\xd5\xac\x48\xf8\x81\x3c\x16\x1c\x89\x59\x14\x7a\xf3\x21\x7e\x70\x3c\x10\xeb\x9b\x17\x0e\xe7\x22\x10\x0a\xa9\xb1\x16\x46\x2c\x48\xca\xd4\x4d\x70\xe4\xbb\x93\x38\x1d\x69\x98\x1e\xa8\x26\xa1\x4e\x27\xfb\x6c\x6f\xff\x14\x9d\x1e\xed\x9e\xfd\xb6\x75\xb2\x83\xf6\x4f\xd1\xf1\xc9\xd1\xaf\xfb\xdb\x3b\xdb\xe8\xf5\xbf\xd0\xd9\xde\x0e\xea\x1f\x1d\xff\xeb\x64\xff\xcd\xde\x19\xda\x3b\x3a\xd8\xde\x39\x39\x45\x5b\xef\xb6\x51\xff\xe8\xdd\xd9\xc9\xfe\xeb\xf7\x67\x47\x27\xa7\xe8\xd9\xd6\x29\xda\x3f\x7d\x06\x1f\xb6\xde\xfd\x0b\xed\xfc\x7e\x7c\xb2\x73\x7a\x8a\x8e\x4e\xd0\xfe\xe1\xf1\xc1\xfe\xce\x36\xfa\x6d\xeb\xe4\x64\xeb\xdd\xd9\xfe\xce\xa9\x83\xf6\xdf\xf5\x0f\xde\x6f\xef\xbf\x7b\xe3\xa0\xd7\xef\xcf\xd0\xbb\xa3\x33\x74\xb0\x7f\xb8\x7f\xb6\xb3\x8d\xce\x8e\x1c\x68\x34\x5b\x0d\x1d\xed\xa2\xc3\x9d\x93\xfe\xde\xd6\xbb\xb3\xad\xd7\xfb\x07\xfb\x67\xff\x82\xf6\x76\xf7\xcf\xde\x91\xb6\x76\x8f\x4e\xd0\x16\x3a\xde\x3a\x39\xdb\xef\xbf\x3f\xd8\x3a\x41\xc7\xef\x4f\x8e\x8f\x4e\x77\x10\xe9\xd6\xf6\xfe\x69\xff\x60\x6b\xff\x70\x67\xbb\x86\xf6\xdf\xa1\x77\x47\x68\xe7\xd7\x9d\x77\x67\xe8\x74\x6f\xeb\xe0\xc0\xd8\x4b\x82\xbb\xd2\xc7\xd7\x3b\xe8\x60\x7f\xeb\xf5\xc1\x0e\x6d\xe9\xdd\xbf\xd0\xf6\xfe\xc9\x4e\xff\x8c\x74\x27\xfd\xd5\xdf\xdf\xde\x79\x77\xb6\x75\xe0\xa0\xd3\xe3\x9d\xfe\x3e\xf9\xb1\xf3\xfb\xce\xe1\xf1\xc1\xd6\xc9\xbf\x1c\x06\xf3\x74\xe7\xff\xbc\xdf\x79\x77\xb6\xbf\x75\x80\xb6\xb7\x0e\xb7\xde\xec\x9c\xa2\x4a\xc1\x90\x1c\x9f\x1c\xf5\xdf\x9f\xec\x1c\x12\x9c\x8f\x76\xd1\xe9\xfb\xd7\xa7\x67\xfb\x67\xef\xcf\x76\xd0\x9b\xa3\xa3\x6d\x18\xe8\xd3\x9d\x93\x5f\xf7\xfb\x3b\xa7\x2f\xd1\xc1\xd1\x29\x8c\xd6\xfb\xd3\x1d\x07\x6d\x6f\x9d\x6d\x41\xc3\xc7\x27\x47\xbb\xfb\x67\xa7\x2f\xc9\xef\xd7\xef\x4f\xf7\x61\xd0\xf6\xdf\x9d\xed\x9c\x9c\xbc\x3f\x3e\xdb\x3f\x7a\x57\x45\x7b\x47\xbf\xed\xfc\xba\x73\x82\xfa\x5b\xef\x4f\x77\xb6\x61\x74\x8f\xde\x41\x57\xcf\xf6\x76\x8e\x4e\xfe\x45\x80\x92\x31\x80\xc1\x77\xd0\x6f\x7b\x3b\x67\x7b\x3b\x27\x64\x40\x61\xa4\xb6\xc8\x10\x9c\x9e\x9d\xec\xf7\xcf\xe4\x62\x47\x27\xe8\xec\xe8\xe4\x4c\xea\x23\x7a\xb7\xf3\xe6\x60\xff\xcd\xce\xbb\xfe\x0e\xf9\x7a\x44\xa0\xfc\xb6\x7f\xba\x53\x45\x5b\x27\xfb\xa7\xa4\xc0\x3e\x6d\xf6\xb7\xad\x7f\xa1\xa3\xf7\xd0\x65\x32\x47\xef\x4f\x77\xe8\x4f\x89\x62\x1d\x98\x49\xb4\xbf\x8b\xb6\xb6\x7f\xdd\x27\x68\xb3\xc2\xc7\x47\xa7\xa7\xfb\x8c\x4e\x60\xc8\xfa\x7b\x6c\xb8\xc9\x52\x26\x7b\xab\xaa\x8a\x3b\x74\x93\xf1\xc3\xab\xe3\x4a\x46\x47\xa7\x41\xb9\x45\x19\xfa\x58\xd6\xec\x1d\x6e\x21\xdd\x20\x89\x51\xe2\x0e\x84\x80\x43\x6a\x7d\xf8\x73\x62\x8c\xef\x2a\x89\x5f\x75\x07\xa1\x86\x83\x50\xd3\x41\xa8\xe5\x20\xd4\x76\x10\xea\x38\x08\x75\x1d\x84\xd6\x1d\x84\x36\x1c\x84\x5e\x38\xa8\x51\x77\x50\xa3\xe1\xa0\x46\xd3\x41\x8d\x96\x83\x1a\x6d\x07\x35\x3a\xb2\x71\xea\x3a\xad\x4c\x3e\x12\x80\xa4\x02\x01\xd2\xe8\x50\xc0\xa4\x22\x34\xf6\x82\x35\xd0\x64\x40\x1a\xd0\x88\x04\xa8\xc5\x5a\x6b\x33\x6c\x5e\x30\x20\x1b\x12\xa6\xeb\x0c\x58\x97\x61\xd3\xa0\x40\x1b\x4a\x28\xf0\x06\xab\xcc\xb1\xa9\x53\x20\x80\x09\xc7\xb4\x45\x81\x91\x06\x1a\x72\xd7\x15\x40\x6d\x56\xb9\xc3\xd0\x5f\x67\x40\x9a\x12\xa6\x0d\x06\x6c\x83\x61\xc3\xba\xde\x68\x5d\x54\x5f\x2a\x33\x12\x15\xcd\x08\x47\x65\x5d\x1a\xb0\x26\x83\xca\xd1\xee\xaa\x63\x02\xdd\x6b\xe9\xfd\xef\xb2\x4a\xad\x14\x18\x54\xee\xa4\x68\x73\x20\x7c\x4c\xa0\xb1\x86\xde\x7f\x28\xd5\x91\x3a\xb9\xce\x50\xec\xa6\x23\x2c\xa0\x34\xa5\xd1\xa6\xe8\x4a\x90\x36\x58\x25\x69\xc4\x60\x7a\x3a\xe9\x08\x0b\x20\x2d\x69\xb4\x29\xba\x32\x4a\x4d\x36\xbe\x75\x09\x1a\x1f\x91\x75\x31\x89\x82\x56\x11\x1b\x21\x8a\xae\x36\x27\x71\xe1\x2a\xa1\x58\xb2\x01\x03\x0c\xe5\xb6\x38\x91\xb5\xa4\x41\xed\xa6\xdf\x54\xf2\x5e\x77\xe0\x1b\x8c\x17\x27\xdd\x17\x29\x15\x72\xe2\x6a\x74\xa4\xb1\x5d\x67\x65\xd5\x59\x69\xa4\xc4\x20\x66\xe4\x05\x2b\xc9\x89\x68\x43\x2a\xc3\x51\x5f\x87\xdf\xca\x91\x4c\x2c\xed\x76\x5a\x97\x63\x20\x58\x80\xbc\x3e\x36\x14\x98\x12\x2c\xbe\x5a\x3b\xe9\x3a\x10\x5d\x6d\xa6\x48\x88\xb1\x62\xa4\x43\x01\x23\x7d\x62\x0a\x17\x0b\xc3\x4d\x99\x82\x4e\x8a\x02\xf4\x75\x3d\x5d\x96\xd0\x64\x9b\xa1\xd2\xd5\xf1\x6e\xa9\x53\x20\x3a\xde\x48\x01\x89\x01\x14\xeb\x1b\xbe\xab\x80\x04\x47\x69\x48\x23\xd5\x4d\x5b\x16\xab\x90\x2d\xe7\x46\xcb\x34\x2b\xa2\x0f\x1a\xee\x1c\x92\x58\x7d\x4d\xe9\xdf\x8e\x58\xd3\xda\x20\x75\x0c\x05\xdb\xea\xfc\x88\x09\x4d\xfb\x85\x1a\x0d\x74\xa1\xa5\xbd\xff\x30\x26\xcb\xc5\x30\x2d\x48\x84\x0d\xaf\x3b\xa8\x7e\xd3\xd9\xda\x68\xae\xbf\x78\xf1\x82\xfc\xee\xee\x6c\xbf\xd8\x79\xbd\xd5\x20\xbf\x37\x76\x1b\xaf\x5f\xf7\xb7\xfb\xe4\xf7\xd6\x8b\x4e\x6b\x77\xbb\xbd\xa3\xcd\xfb\x38\xb2\xb6\xd0\xa9\x6f\x35\x37\x5e\xef\x74\xa1\x85\x7e\x7b\x7b\xbb\xd1\x6c\x43\x0b\xdb\xeb\xf5\xd6\xce\x6e\x8b\xfc\x5e\xdf\xea\x6e\xaf\x77\x77\xa0\x65\x8e\xd1\x85\x4d\xbd\x70\xb2\x7f\xbc\x73\xb8\xdd\xe8\xd6\x21\x6d\x44\xa1\xa6\x4a\x94\x4e\x75\x55\xd2\x2b\xba\x71\x2f\x7f\xc1\x45\xd5\x98\x80\x88\x25\x30\x7b\x77\xbd\xdd\x69\xfe\xff\xec\x7d\xeb\x72\xdc\xc6\xd5\xe0\x6f\xa7\xca\xef\xd0\xc9\x56\xa4\xa1\x39\x22\xd1\x8d\x5b\x43\x16\xfd\xad\x4c\x4b\x1f\xbd\x96\x6c\x97\xa4\xac\xfd\x95\x4a\x72\x70\x69\x70\x60\x0d\x67\xf8\xcd\x80\x22\xe9\x58\xa9\x7d\x8d\x7d\xbd\x7d\x92\xad\x3e\xdd\x00\x1a\x40\x5f\x30\x14\xe5\xc4\x89\x98\x8a\x3c\x33\x38\x7d\xce\xe9\x73\xeb\x83\xd3\x37\xdf\x03\x49\x3e\x7a\x7c\xfc\xd5\xc3\x2f\x29\xf4\x33\xa1\x5f\x3e\xfc\xea\xf8\xf1\x23\xfe\x19\x7b\x3e\x09\x83\x18\x64\x74\xec\x7f\x45\x1e\xe1\xc7\xde\x2b\x5b\xc9\x7e\xf2\x84\x81\xbe\xc2\x3c\x7d\x5f\x18\xb6\x4d\x2c\x4d\xd8\xdd\x20\x58\x81\xf2\x6f\xb7\x6e\xd4\x34\xdd\xf4\xf4\x27\x05\xbc\x99\xdd\xf8\x49\xb7\x94\x0b\x59\x67\x80\x94\xa6\xe8\x08\xcd\x34\x10\x48\xac\x94\x55\x08\x76\x0b\x3d\x94\x1f\x77\x5c\x7e\x3b\xc2\x28\x57\xe0\x0e\x30\x8e\xd7\xe1\x6a\xf0\x59\x4b\x70\xc8\xb9\x4e\xfc\x04\xb5\xb3\x23\xdc\x38\xcd\xf3\xa6\x10\x1b\x7e\x5a\x2c\x2d\x10\x1b\x80\xd8\x98\x21\x20\x69\xfd\xe9\x17\x0b\x0e\x48\xa2\x7e\xfa\xc5\x82\x03\x86\xf4\x9f\xb6\x16\x1c\x30\xb6\xfc\xb4\xdd\x98\x4e\x59\x3f\x3c\xe4\xfe\xf7\x86\xbf\x7d\xbf\x4d\x37\x15\xcf\xac\x75\x73\xce\xe9\x72\x8e\xb2\xe5\x1c\xe5\xcb\x39\x2a\x96\x73\xc4\x96\x3a\x62\xe9\x66\x8e\xb2\xcd\x1c\xe5\x9b\x39\x2a\x36\x73\x04\xc9\xfd\x00\x2e\xe5\x0c\xa5\x9c\xef\x13\xcd\xb6\x9c\x6c\x03\xa7\xe2\xc3\x53\x3c\x7a\x9a\xf3\xa7\xb9\x78\x4a\x46\x4f\x0b\xfe\xb4\x10\x4f\xfd\xd1\x53\x78\xef\x60\xe2\x69\x30\x7a\xda\xde\x32\x9f\x0e\xae\x95\x6f\xba\x36\x9a\xd9\xd4\xae\xb4\x84\xff\xee\x1f\x21\xac\x77\xfd\x9a\x3b\x56\xba\x44\xfb\x9d\xb7\xed\xff\xb2\x7c\x59\xbd\x7a\xb5\xf7\xab\x76\x8b\x08\xec\x92\x7a\x80\xa3\x3d\xa8\xa5\xf5\x51\xed\x1f\x21\x54\xe2\x59\xb6\x9c\xe7\xcb\x79\xb1\xdc\x43\xfb\x68\xb1\x34\xec\x74\x7a\x87\xda\xc2\x5f\xf5\xc0\x27\xb2\xa4\xa7\xc1\x47\x86\xf8\xc6\x4a\x18\xe1\x0b\xa8\x19\x9f\x3f\xc4\x37\x56\xdb\x08\x5f\x14\x98\xf1\x05\x43\x7c\x63\x45\x2b\xf8\xfe\x76\x78\x28\x71\x52\xcf\x8c\x33\x1c\xe2\x1c\x9b\x07\x32\x1c\xe7\xcf\x15\x5a\xeb\x55\xc7\x1f\xa1\xcd\xba\x5e\xce\xea\xf9\x96\xeb\x58\xbb\x31\x06\x2c\xa2\xde\x67\x4b\x83\x01\x80\xa3\x8c\x9d\x8d\xff\x81\x2d\x17\xda\x47\xe0\x04\x40\x9b\xfb\x2b\xd6\xef\xbe\x02\x3f\xca\xb4\xed\xc1\x01\x35\x73\xa0\x2d\xc7\xe9\x06\xed\x2b\x26\xbc\x79\x1f\x13\x0e\x67\xd9\x66\x9e\x6f\xe6\xc5\x06\xc4\xbf\x79\x5f\x13\x0e\x86\xf8\xde\xdf\x84\xfb\xf8\xde\xd3\x84\xc9\x10\xdf\x2d\x98\x30\x1e\xe2\xbc\x7d\x13\xde\xc0\x1c\xbc\xcd\x86\x37\x26\x1b\x86\xc8\xbb\xd1\xda\x30\x84\x6c\xed\x23\x88\xe6\xc2\x86\x37\x66\x1b\x86\xe1\x42\xdb\x1e\x46\x12\xdd\x7a\x94\x61\xdc\xff\x5a\xbd\x58\x04\x72\x52\x58\x30\x3d\x4c\x59\xf9\x3f\x47\x68\x76\x22\x16\x35\xe7\x3c\x88\x17\xba\x1e\x9f\xc8\xd5\xcf\x27\x62\xe1\x72\xc1\x01\xb5\xa2\x39\x91\x2b\x9c\x4f\xc4\x12\x64\xc6\x01\x53\x3d\xa0\x2f\x01\x61\x99\x31\x8c\x1f\x99\x1e\x30\x90\x80\xb0\xae\x3b\xe3\x80\xb9\x1e\x10\x16\x80\xf7\xc5\x33\x4e\x96\x1f\xcb\x3b\x63\xde\x6b\xb5\x5a\x91\xd6\x69\x9b\x55\xf1\x2f\xba\xc4\x61\xca\xa5\xa6\x0d\xec\xea\xcb\xaa\xde\xbe\x58\xd7\x10\x1a\x05\xda\xd5\x57\x69\x9d\x8a\x55\x6c\x9f\x21\xaa\x23\x00\x8d\x9e\xb0\xb2\x1e\x5d\x81\x2a\x1a\x8c\xfb\xf4\xb0\x28\x34\x57\x84\x23\x79\x79\xa9\x58\xd5\xd5\x61\xe5\x19\x6a\xf8\x0a\xfd\x7a\x24\xee\xfc\xee\x16\x81\xb4\x10\x7f\x46\x3e\x19\xd9\x70\x87\x6a\x36\x9b\x75\xb0\xfb\x88\x07\x10\x8e\x33\xd9\xe3\xb8\x02\xee\xd5\x38\x30\xe5\xe5\x4d\x5b\x21\x94\x2e\x27\x57\x7e\xdc\x21\x27\x1f\x61\x93\xf9\xf8\x00\x9b\x33\x1f\xd7\x76\x56\xbd\x7f\xa6\xbb\x64\xb6\xb9\x55\x0a\x96\x02\x69\xaf\xa3\x39\x3c\x84\x97\x4e\x04\xd7\x18\x89\xed\x70\xfa\xe5\x63\xe7\xe2\x05\x4f\x77\x6d\x91\xc3\x50\xc1\xf5\xd5\xf4\x5f\x67\x47\x27\xe8\x08\xf5\x5e\x0d\xde\xf7\x55\x31\x9c\xf6\xa6\x68\x78\xf7\x3b\x81\x97\xbe\x13\xed\xc6\x1d\x64\x7d\xdb\x3b\x69\x77\x50\x9e\xf4\xde\xe3\x4e\x76\x7f\x81\x13\x36\x73\xd2\x7b\x79\x3b\x31\xbe\xb5\x4d\x5a\x21\xf8\x4c\xcc\xe5\x0b\x6d\xcb\x4b\x59\x0a\x10\xfc\x00\x56\x4e\xfa\x0f\xd5\x35\x88\x65\xf9\x72\xbd\x72\x44\x31\x58\x18\xc1\xc1\xba\xf2\x06\x7c\xb5\x2c\xef\x10\xcf\x7f\x1a\xd9\x8d\x68\xa8\xb3\x40\xc9\x2d\x3c\x1f\x2c\x0c\x83\xcf\xef\xda\xc5\x0c\x48\x5d\x28\x58\xe2\xd9\xd5\x1c\x5d\xcf\xd1\x2f\xda\x7b\x6c\x66\xb3\x2b\xd8\x82\x7b\x0d\xff\xfe\xb2\xa7\x10\x7e\xa7\x41\x46\x1c\xc8\x66\x57\x7b\x77\x66\xd7\x7b\xe2\x70\x80\xbf\xf3\x2f\xbf\xec\xed\xed\x8d\x17\x93\x75\x18\x7d\x37\x46\x8e\xec\xef\x1c\xab\xc2\xa3\x11\x5f\x30\x01\xdf\x1d\xc0\x02\x3c\x5e\xef\xdd\x99\xfd\x1d\x98\xb4\x62\x0d\x27\x09\x91\x4b\xf1\x57\x05\x9d\x19\x21\xe4\x26\x57\xf3\x95\x1e\xdd\xd5\x83\x07\x2b\x60\xef\xea\x8b\x2f\xbe\x98\xf9\xe4\xde\x6a\xc0\x9d\xfc\x6c\x5f\x03\xd4\x2c\x01\x12\x57\x28\x4e\x5d\x02\x64\xbc\xf9\x4a\xae\xe9\x81\xc5\x5f\xcd\xe7\x7a\x2d\x02\x9a\x0e\x91\xe1\xaa\x2a\x23\xfc\xfb\xdc\x51\x25\xdd\xa8\x5b\xbe\xd3\xd4\x1b\x67\x77\x25\xab\x77\x75\x2b\x90\xcc\xcd\x2e\x1b\xa6\xf5\x4b\x8d\xc6\xe5\xcc\xc1\x32\xa3\x06\x60\xf2\x82\xad\x46\x59\x27\x4f\x1f\x1e\xff\x36\xaa\xb2\xb4\x7f\xc3\xae\xa1\xed\x96\xe5\x1b\x56\x1b\x6f\x15\x33\x68\x18\xae\xf0\xbc\x75\x0d\x8b\xeb\x41\x5b\x55\x9d\x9c\xa5\x79\xa7\x2e\x75\xbd\x99\x56\x63\x3d\xf0\xb1\xd6\xce\xd2\x5c\xa7\xb9\x4f\xde\x89\x29\x6f\xf3\x32\xb1\x06\xda\x78\x6b\xd7\xbb\x57\xf3\x38\xfe\xb8\xdc\xeb\x1f\xb8\xdc\xeb\x83\x6e\x25\xfa\x2d\xd6\x2e\x0c\x8e\xec\x53\xa9\xdb\x8e\xe2\x7b\x7e\xf2\xf0\x1e\x9e\x34\x61\x33\xbe\x5c\xfe\x76\xa7\x69\x8e\x60\x3f\x71\x37\x53\x53\xad\xaa\x7a\xa6\x3b\xc5\xac\x3f\x75\xc3\xca\xbc\x48\x33\x9a\xe8\x8e\xf7\xf2\xae\x12\x9a\xa5\x45\x5e\xb2\xde\x64\x8e\x16\x32\xf7\x0b\xc2\x70\xe9\x0d\x1e\xde\xce\x6c\x8f\xe9\x25\xc1\x90\xfe\x6b\xe6\x07\xc6\x38\x26\xd5\xd4\x0d\x35\x70\xfe\x2c\x33\x54\xc0\x21\x4d\x35\xd4\xbf\xe1\x45\xda\x50\xfd\xe6\xcf\x58\x57\xfb\x1e\x33\x6c\xae\x7e\x1b\x0b\xdd\xa6\xd7\x16\x28\x57\x21\xb1\x81\xd8\x74\x70\xd0\x0f\xe2\xf5\xa3\x7f\x2e\xca\x60\x6f\x71\xf3\xd7\x54\xc2\x0c\xa8\x9a\xdd\x26\x3f\xbc\xac\xd0\x3d\xe4\xbf\x42\xaf\xe5\x47\xda\x7d\xc4\x81\xf2\x39\x32\xde\xd8\x2a\xb9\x9a\xad\x60\xff\xb3\x78\xeb\x85\xd7\x18\x1f\x9b\x8e\x35\x32\xbc\x98\x41\x4d\x6c\x96\x72\x3c\x21\xe0\x49\xc5\x5b\x55\x0c\xbb\xa0\x19\xda\x07\x5a\xc6\x7a\x29\x7a\x80\x88\x67\x96\x1e\x54\xfd\x66\xb3\x0c\xdd\x41\xb9\x48\xad\xf9\xc7\x02\x70\x7b\x57\x61\x2a\x66\xa4\x5d\x55\x4a\xf4\x00\x05\x4e\x22\x19\x7a\x8d\x72\xf4\x1a\x15\x02\x77\xc4\x8a\x84\x65\xa9\xf6\xc4\xaa\x01\xee\x68\x97\x0e\x08\xfe\xf9\xa7\x5c\xf6\xe4\x1e\xf2\xae\x62\x8f\x05\x81\x4f\x02\x0b\xb5\xc3\xcf\x5a\x82\xd4\xdb\x43\x9f\x1d\x4e\xef\x0f\xa7\xe0\x87\x49\xe1\x33\x32\x2a\x4a\x21\xa3\x76\xb9\x17\x15\xda\x82\x25\x3a\x42\xb9\xb6\x48\x89\x80\xee\x83\x07\xc8\xf7\x64\x67\xc1\x16\xf4\xd7\xfb\xa2\x23\xa4\xe5\x26\x9d\xbc\xbd\x6e\x5a\x41\x53\xd6\x00\x9b\x62\x61\x3a\xda\xda\x8f\x7a\xc5\x4c\xa8\x7a\x8e\x0f\xc5\x41\xbd\x42\x26\x54\x3c\x73\x03\x90\xaf\x56\x3b\x0b\x03\x50\xa0\x56\x3a\xd9\x08\xe8\x63\x8d\xb2\xd7\xa7\x7f\xd2\x1a\x25\x4f\xb8\x0f\xca\xe5\x7a\xbd\x51\x8b\x86\x87\x30\xca\xcb\xbf\xf7\xa3\x02\xe7\x62\x74\xa8\x5d\x85\xc6\x51\x9d\xf1\x43\x96\x18\x77\x2d\x5d\xe9\xeb\x8d\xbf\xef\x02\xd6\xc7\xca\x86\xad\x44\xc1\xb3\xf3\xdd\x8a\x1a\xd0\xc2\x5e\xcf\xe8\xa7\xfc\xfd\x52\x06\x7f\xf6\xb1\x8a\xf1\x01\xab\x18\xa0\x9f\x49\x05\x0c\xbd\x9a\xba\xda\x45\xa3\x2a\xeb\xce\x36\x0e\x64\xad\x56\xd0\xdf\xfd\x79\x2c\xdb\x45\x4a\xc2\xe8\xb7\x38\x4a\x45\x52\xfa\x37\xad\x6a\x8c\x8b\x16\x6a\x49\x81\x84\x51\xaf\xa8\xd0\xdb\x7f\x3f\xaa\x54\x10\x12\x4c\xad\x55\x70\xd0\x1e\x62\xf8\x2e\x28\xfc\xd6\xf5\x8a\x1c\x7b\x61\xc2\x0a\x3a\xe7\xaf\x03\x51\x9c\x17\xa1\x17\xc3\x67\x2f\xf6\x8a\x02\xc3\xe7\x32\xf6\x58\x98\xf8\x86\x3a\x46\x59\xe6\x9e\x97\xf9\x50\xf1\x88\x68\x48\x71\x88\xc5\xe7\xa0\x4c\x68\x99\x02\x86\x8c\x95\x69\x50\xa6\xc1\x8e\x15\x8c\x69\xe9\xad\x32\x66\x48\x19\x2a\x4d\xad\x9b\xa4\x21\x12\xb7\xa9\xd2\xbd\x23\x5d\x62\x64\x9a\x63\xfb\x38\xe6\xef\x34\xe6\x13\x12\xec\x3c\xea\xf3\x36\xce\x71\xbf\xe7\x3c\xa3\x91\x9f\x10\xe3\x49\x06\x1f\xc7\xfe\xdb\x19\xfb\xb9\x96\xa6\x8e\xfe\x5a\x65\xf5\xc6\x7f\xa9\x30\x57\x06\x40\x88\x66\x7b\xbb\xb2\x97\x5d\x8e\x6b\xf7\xe3\x84\x67\x04\xc9\xc7\xf9\x8b\x7f\x8e\xf9\x8b\xdf\xef\xfe\xcb\xaf\xc5\x55\x27\xd5\x2f\xed\x5e\x6c\xb4\x59\x5f\xac\x0a\x94\xf7\x37\x66\xaa\x1d\x39\x19\xdd\x3d\xf4\xcd\x70\xbe\xa3\x29\x3d\xb3\x0e\x8f\x7c\xa4\xcd\x8f\x90\x3a\x05\x5f\x6d\xbf\xdf\x54\x67\x6c\xb6\xd2\x0f\x89\xdb\xff\xde\xd4\xdf\x36\xf5\x08\xfe\x65\xb6\x1a\xbd\x03\xb7\xd5\x6d\xa1\x62\x74\x84\xc8\xe7\xcd\xe7\x07\x47\x02\x45\xf3\x83\xad\xe0\xfd\xc7\xd9\x0a\xfd\x59\xc2\xed\x99\x0b\x9f\xd2\x91\xcb\x74\xb9\x65\x53\x56\x68\x8e\x0b\x7c\x4d\xd9\x60\x73\x31\x7c\x03\xd7\x49\xe8\x94\xd5\x8f\x37\x29\x7c\x4e\x97\x5f\x56\xf5\x56\x27\xab\x76\x09\xc4\x0a\xdd\x43\xb3\x15\x9c\x51\xbb\x87\x3e\xeb\xd5\x6b\x46\x95\xb8\x1e\xbd\xa6\x06\xdf\xbb\xab\x00\x7e\x04\x05\x0d\x4f\x89\xba\x5c\x54\x4b\x86\x66\xf2\xe1\x03\xd4\x2c\x97\x1d\x0a\xb5\xd3\xaf\x59\xf0\x2d\x12\x6a\x96\xfa\xc9\x4b\x01\x05\xa7\xe8\x8e\x24\x02\xe6\x71\xbe\xbe\x9c\xad\xe6\x08\xa3\x43\x44\xf6\x26\xdd\x61\x80\xe0\x3a\xa1\x5d\x10\xfb\x7b\x86\xb3\xe3\x05\x92\xfd\x7d\x77\x79\x77\xd5\x07\x6a\x73\xb0\x99\x8a\xfa\xfd\x26\x1c\x79\xd2\x3f\x35\x8d\x1f\xbf\x1f\xfc\x06\xd3\x8e\x27\x07\xdb\x65\x95\xb3\x99\xb7\xf7\x71\xfa\x6f\xf0\x6c\xe2\xf4\xdf\xe8\x59\x09\xcf\x42\xed\xb3\x53\x78\x36\x9e\x34\x83\x84\x08\x9e\xc5\xb7\x31\xa5\x18\xd9\x2e\x84\xf8\x07\x4c\x29\x9e\xa6\x67\x67\xa9\x77\xd5\x4e\x2c\xe2\xb1\x74\xc6\xe0\xb0\x44\x7c\xd6\x34\x7d\xf0\x00\x11\x31\xfb\xd7\xfc\xf2\xc5\x17\x5f\xa0\x78\x6f\x0f\xa1\xd7\x06\x54\xfd\xbf\x1e\x2a\x1c\x8c\x50\x61\xba\xb7\x37\x11\x55\xbf\xa1\x6f\x08\x44\xbd\xde\xe0\xae\xf3\xfa\x2d\x0f\x7d\x68\xa5\xef\x58\x30\xac\xf4\x1d\x5f\x35\x27\xae\x4f\x65\xb8\x8f\xca\x1f\xa3\x4a\x76\xed\x7b\xd3\xd0\x74\x83\x07\xea\x8c\x48\x6a\x73\x5f\x76\x1f\xce\xb6\x96\xbd\xdc\xb7\x4f\x23\x9b\xa7\x84\x73\xd8\xec\x3a\x63\xe8\x0e\x2a\x61\xa9\xe1\xdf\xf9\xc7\x53\xe3\xcd\x48\x67\x29\x9c\x7f\x98\xa2\x3b\x28\x03\xf8\x54\xcc\x96\xbe\x46\x72\xde\x54\xdf\x0b\x48\x7c\xaa\x53\xce\x7e\x3b\x05\x2d\xe7\x1d\xe5\x1c\xb4\x58\x83\x29\x9e\xe0\x44\x79\x82\xfd\xde\xa3\x5e\x23\xc3\xa0\xd8\x52\x83\x2b\xa0\x66\x0c\x6c\x5e\x1c\x1c\xce\xa0\x61\x24\x51\x8a\x27\x58\x79\x82\xb1\xfa\x28\x16\xcb\x8f\xc5\x23\x12\x9a\x46\x4a\x98\x5b\xe7\xb4\x16\x68\xbf\x21\xbc\xcf\x45\xbb\x2f\x2e\x5c\x34\xcf\xab\x43\x4b\x82\x8e\x1a\xe1\xec\x73\x01\xeb\x89\xf0\xa8\x76\xaa\xc3\xc1\x43\xe1\xe8\xfa\x02\xfe\xc7\xe3\xa7\x36\x9f\x83\x53\x60\xe1\x56\x11\xac\x9d\xf1\x44\xae\x89\xe3\xd1\x25\x04\xc8\x35\x49\x3c\xab\xb9\x48\x6a\xa2\xa5\xf7\xef\x36\x61\x2c\x80\x42\x09\x04\xe7\xe8\x97\x06\xa0\x48\x02\xc1\x39\xf9\xa7\x06\xa0\x58\x02\x41\x44\x58\x7c\x9c\x9f\xfe\x38\x3f\xfd\x71\x7e\xfa\xe3\xfc\x74\x5b\x42\xfc\x97\xa9\x55\x87\xd1\xee\xb5\xea\x30\x9a\x50\xab\x56\xdf\x10\xc7\xb5\xea\x30\xfa\x58\xab\xbe\x2d\xad\x1a\x6a\xd5\x61\x34\xbd\x56\xad\x53\x56\xbf\x56\x2d\x14\xe6\x5c\x64\xaf\xcc\x1d\x1a\xe6\xac\xa9\xf7\xbb\x9f\xb3\xbe\x8a\x82\xdf\xec\x02\x90\x96\xd6\xc7\x6a\xb6\xad\x9a\x7d\x15\xc1\x3c\xf3\xc1\x55\x14\xa8\x0f\x7e\x8c\x02\x79\x78\x3d\x80\x1c\xa8\xa7\xa5\xef\x78\x0c\xa1\xda\xd1\x67\x27\xdf\xfd\xf4\xdd\xe3\xc7\xcf\x1f\xbd\x78\x3e\xaa\x7b\x7f\xff\xf5\x4f\x5f\x7f\xfb\xd5\xa3\x1f\x1f\x69\xae\xe8\x7f\xf6\xdd\x5f\xbe\xfd\xea\xa7\xe3\xef\xbe\x7d\xfe\xe2\xe1\xb7\x5d\x5b\x95\xa6\xa8\x90\x1f\x4f\xad\x90\x2b\x6d\x36\x8b\x75\x73\x88\xd0\xb0\xc0\xde\xd0\xe7\xef\xf9\x78\x8e\xae\x8d\x87\xf9\xd7\xa2\x4c\x53\xa3\x07\x88\x04\x9f\xa3\x5a\x57\xa6\x51\x3a\xff\xf2\x0a\xed\xa3\x10\x7d\x86\xae\xc5\x16\xd3\xba\xd9\xd8\x0b\x9f\xc8\x1e\xd4\x58\xd1\x9f\x51\xa4\xc9\x72\x20\xd1\x64\x97\x3f\xa2\x23\x74\x8d\xfe\x8c\x42\x6d\x22\xca\x2e\xff\x8b\x23\x26\xe8\x33\xc4\x49\xf9\x9c\xd4\x9e\x0e\xfa\x4a\x54\x10\x7f\x1c\xfe\x7e\x2d\x7e\xff\x2f\x73\x45\x5b\x91\xe0\x79\x85\x2a\xb8\x98\x43\x27\xbf\x56\x46\x57\x42\x46\x57\x62\x4f\xef\x95\x4e\x44\x2d\xac\x90\x34\xba\x16\xb0\xd7\xa6\xaa\x57\x67\x33\x7d\x89\x5e\xc3\x4d\x5b\xe3\xde\x73\x11\x8f\x44\xf0\x6e\x4a\x17\x07\x13\x39\x03\xfb\x78\xf2\xf8\xf9\x33\xce\xf1\x95\x87\xb5\xe6\xa1\xde\xe8\x62\xaa\xe2\x71\x38\xa0\xd2\xd8\xf0\xd3\xed\xe5\xd0\xde\xb4\x70\x4f\x5a\x38\x93\x34\xe5\x95\x2e\x3f\xa3\x07\x28\xfe\x1c\xfd\x6c\xab\x21\x42\x4f\x60\x57\xb3\xe1\x84\x9e\x86\x85\xac\xaa\xbf\x5f\x6f\xe1\xa0\x62\x6e\x69\x70\x3f\xf6\xcf\x7b\xe8\x1e\xd2\xae\x7c\x6f\xd0\xab\xad\x1e\xa0\xe6\x90\x12\x1d\x34\xff\x1b\x75\xf3\xf5\x11\x02\x42\x0a\x1a\x13\xb5\xfe\xea\x77\x95\xee\x17\x47\x40\xd8\xb2\x10\x7e\x44\xfb\xa9\x42\xbb\x87\xeb\x9e\xee\x7d\xab\x65\x61\x72\xf5\x4b\x31\xb4\x15\xbb\xaa\xc1\x9e\x5c\x0a\xa2\x96\xdd\x03\x87\x87\xe8\xfb\x4d\x75\x56\xd5\xd5\x5b\x86\xce\xd7\xcb\xeb\xd5\xfa\xac\x4a\x97\x68\xfd\x96\x6d\xd0\x7f\x3e\x9e\x91\xbd\xfb\xe8\xea\x35\x45\xfb\xe8\xea\x75\x04\xff\x86\xf0\x6f\xc0\xe3\x90\x01\xa7\xb4\x71\xc1\x80\xd8\xfd\xf1\x1a\x79\x57\xb1\x6d\xa7\x83\x89\x3f\x89\xe3\x48\x6f\x2c\xee\x29\xbe\xc1\x78\x20\x4a\x92\x72\xcc\x6a\xce\xc8\x1b\x2a\x70\x3e\x32\xa7\xe1\xd5\x23\xe2\x05\xc8\x31\x51\xb4\x05\xb7\xaa\xd9\xd9\xf9\x7a\x93\x6e\xae\xfb\x77\x47\x72\xc7\x78\xd1\x1b\xbd\xcc\x53\xb4\xda\xdb\x9e\x0c\xb1\xe1\x85\xb6\x87\x53\xf8\x1f\xce\x5d\xf9\x53\x67\xae\xfc\xde\xbc\x95\x6f\x9d\xb5\xfa\x20\x97\x70\xac\x2f\xea\xf3\x8b\xfa\x09\xbc\xef\xf7\x81\x11\xbc\x13\x14\x6c\x5b\x6d\x58\xa1\xdc\xd1\x91\x55\xf5\xb6\x39\x16\x5d\xb4\xee\xbf\x9f\x34\xad\xbf\x5b\x2d\x1b\xbd\x29\xa7\xd1\xa7\x1b\x76\x1f\x11\x12\xcc\x11\x09\xa3\x39\xf2\x69\x30\x47\x21\x26\xa3\xd6\xf2\xc2\x8f\xfb\xfc\x61\xef\xd9\xe8\xc6\x8f\xe6\x25\xde\x7c\xe9\x87\xda\xc7\x21\xc2\x9b\x5d\xfe\x01\xe5\x66\xb8\xd4\xb4\xa9\x07\x34\xdf\x5e\xbe\x32\x0d\x0f\x53\x2c\x90\xff\x01\x26\x61\x89\x2b\x76\xd9\x5a\x23\x4c\x39\x4e\x38\xb5\x02\xd8\x69\xef\xe9\x86\x41\x23\xf2\x3c\x74\x0f\xf1\x71\xba\xbd\x68\x44\x15\x09\xcf\x83\x7c\xf2\x21\xa7\x30\x75\xb5\x44\x8d\xf8\xf4\xc5\xbe\xa6\x2b\x4f\xd2\x15\x54\xa9\x06\x1d\x3c\x84\xc9\xfe\x31\xed\x87\xd9\x76\xbd\xc9\x26\x28\x63\x40\xe1\xfd\x4e\xcc\x7c\x4a\x2a\xd4\x9f\xfc\xe3\x62\x37\xcf\x04\x3c\x25\x15\xd6\xc0\xf3\x01\xc2\x7e\x94\x8a\xf9\x4e\x7a\xce\x82\xfd\xdc\x4c\xd2\x3b\x30\x93\xdc\xe8\xa4\x4c\xd2\x3b\x22\x93\xbc\xcf\xd9\x98\x92\x69\xec\xe4\x1a\xf7\xd9\xc6\x37\xe3\x1b\xf7\x19\xc7\xbb\x71\xae\xd7\x88\x30\xb6\xb6\x64\x53\xad\xea\xb5\x30\x70\x83\xda\x97\x29\xd4\x1f\x1b\x57\xd7\x49\x84\x83\x1c\xc0\x0d\xd3\xaf\x8f\x40\x3c\x46\xa0\xe5\xfa\x12\x49\xa0\x49\xd3\x2c\xcf\xf8\x00\x3d\x34\xe0\xd6\x33\x44\x0a\x0e\xde\x21\x3e\x8a\x64\x1a\x3e\x5b\x1c\xe3\xc5\x82\xd5\xa9\xe6\xd1\x2e\xef\x25\x0a\xba\xa7\x15\x7f\xcd\x59\x5e\x9c\xad\xa0\x8f\x3a\x77\x6b\x64\xd9\x64\xf0\x73\xa4\xe4\xe8\x5a\xe8\x5d\xdf\x7b\x54\x2a\x3d\x8d\x75\x6f\x41\x26\x52\xfc\xaf\xc9\x67\x5b\x4d\x5a\x81\x9f\x28\xc0\xcb\xf5\xa5\x25\xdb\x35\x4b\xed\x85\x3e\x5f\xd2\xf5\xe7\x05\xd7\xc7\x8b\x97\x57\xc6\x1e\xbc\xb8\x12\xd6\x77\x04\xfd\xb0\x40\x81\xf9\x1d\x41\x07\xa6\x2e\x57\xba\xa1\x51\xd8\x82\x6f\xd7\xaf\x00\x3a\x36\xe3\x3a\x0a\xe0\x75\xd4\xba\x66\xe0\xc5\x15\xee\xe0\xf1\x24\x78\x61\x6f\x2f\xae\xb0\x55\xa9\x12\xf8\x49\x0b\x2c\x94\x6a\x37\xf9\xed\xc5\x06\x1c\x4d\xdc\xcd\xc3\xcd\x7f\x82\xe5\xbf\xb8\x0a\x64\xa0\x40\xb3\x99\xe4\xaf\xdd\x37\x2e\x59\x90\x9b\xc7\x8d\x2f\x51\x80\xee\x49\x8b\x4e\x84\x14\x81\xee\xc9\x00\xdd\xd3\x09\xe8\x7e\x63\x4f\xeb\xc5\x4a\x9b\xb9\xa2\x61\xcc\x34\x59\x2d\xda\xf5\xc5\xf2\xd9\x62\x8d\xbe\xaf\x6c\xb6\xce\xe9\x36\x37\xb8\xe2\xcf\x95\xaf\x22\x1f\x6c\xbf\xdf\x82\x13\xf4\x44\xd8\x22\xb6\xda\x35\x87\x12\xe6\xe4\x0c\x57\x0d\xf8\x93\x0e\xdc\x12\xb0\x60\x4c\x59\xac\xbf\x13\xf9\xcd\x51\xaf\x3e\xd7\x63\xcd\xdc\xe5\x67\x6b\xc8\x15\x6d\x03\x01\x7f\x67\xef\xa8\xb8\x6b\x1e\x8a\xfb\xcc\x9a\xae\x3f\x78\xd0\x31\x0a\xc6\xde\x74\x12\x2e\xc8\xf5\x09\xba\xa7\x3c\x37\x9a\x3e\xea\x7b\x53\x8b\x44\x8b\xfd\xe9\xae\xd8\xfb\xf5\x96\xae\xc7\xd3\xaa\x2d\xc3\x5e\x4b\xbe\x14\x3c\x50\x69\x19\xb3\x17\x05\x37\xef\xfc\x53\x07\x91\x27\xbb\x12\xb1\x0f\x81\x9b\x74\xb5\x3d\x5f\x6f\xed\xe6\x02\xc1\xf9\xfb\xea\x89\xf0\x93\x17\x2f\x95\x0a\x67\x67\x93\xe6\xa1\x51\xb4\x9c\x34\x3e\x4a\x50\xf7\x20\x69\x0e\x2b\xe7\x15\x4a\x6b\x18\x2a\x21\x9a\x1a\x52\xca\x17\x1e\xf4\x44\x7f\x68\x71\xfb\xc2\xe5\xb5\x61\x41\x0f\xf8\xc2\x6b\x7a\x25\xc0\x8d\x81\xe0\x85\xd7\xf4\x49\x02\x1a\x87\xb7\xc3\x43\x74\xbc\xb0\x46\xc6\x1d\xb2\x80\x9b\x0e\x2c\x13\x02\x27\x52\x42\x5b\x13\xa7\xdb\xe1\xc7\x65\xf0\x3b\x46\xdc\xa6\xd9\x8b\xd6\x02\x77\x68\x73\x85\xdb\x56\x33\x25\x6d\xd9\x9b\x34\x54\x0a\x0c\x64\x80\x81\x8c\x31\xd8\x85\xc9\x93\x95\xcd\xfa\xd2\x26\xcb\xa5\xe2\x22\x2f\x3a\x7f\x79\x8d\x66\x7f\x97\x5d\x10\x3f\xdc\x69\xf8\x81\xaf\xd6\xd0\xb2\x54\x5c\xe9\x45\xe7\x57\x2a\x4a\xf8\xa1\x43\xb9\x5c\x5f\xde\x4e\xe1\xf8\xeb\xb5\xf6\xf5\x66\xa4\x7b\xb3\xff\xf5\xea\xa2\x7c\x20\x1c\x54\x57\xe1\xb9\xfb\x55\xb0\x87\xc6\xe8\x9e\xbd\x24\xa7\xdf\x84\x3b\xaa\x75\x72\xe6\x9f\x71\xed\x98\xa6\x2e\xf4\x01\x56\x8e\x8d\x1a\xb4\x65\x26\xde\x70\x5c\x7b\xfa\x4c\xd4\xcd\x34\xc5\xa7\x1b\x2f\x38\xc3\x37\x5a\x6f\x06\x2b\xc9\x72\x56\x2d\xfb\x6b\xc2\xf0\x1e\x3a\xec\xf7\x61\x0f\x7d\x36\xfc\x01\xa8\xc3\x94\x52\xbb\xe6\xed\x9f\x6a\xa1\xd8\x2d\x14\x11\xd5\x6a\x67\xd3\x07\x6d\x29\x14\x1d\xea\xed\x40\x85\x69\xea\x90\x63\xa4\x87\x86\xe5\x87\xcf\xff\xfb\x82\xb1\x5f\x86\xb5\xa0\x66\xf9\x52\x63\xef\x2f\x47\xbe\xaf\xab\x56\x8e\x38\x79\xbf\x7a\xe5\x84\x42\xd4\x0e\x6f\x07\xc6\x37\x83\x9b\xd4\x31\x3b\x9a\x96\xaa\xa0\x92\x60\xca\xc2\xa0\x9a\xb7\xee\x56\x1b\x54\x70\xc9\xf2\xa0\x8a\xeb\xe6\xb5\xcd\x4e\x22\x8e\x8e\x3c\x19\x75\xe4\xc9\x8d\x3b\xf2\x64\xd4\x91\x27\xbb\x76\xc4\xa0\x34\x61\xcc\xd2\xf5\xea\x35\xda\xb0\x7a\x53\xb1\xb7\x4c\xb7\x76\x13\xc9\xad\xfd\x22\x58\x9c\x5f\x6c\x17\x0d\x2b\x5a\x49\x69\x40\x9f\x6a\x40\x6f\xe5\xa8\x6e\xcd\x86\xae\x96\xfc\x7c\xec\xdc\xb6\x2d\x5e\xb7\xb6\xea\xd4\x12\xe1\xe4\x1a\x54\x4d\xc0\x6b\x77\xa1\x4d\x09\x1f\x53\x67\x9e\x9a\x8f\xca\x12\x57\x87\x0a\x3e\x2e\x79\x1d\x3d\xb9\xd1\x92\x57\x7f\xe7\x05\xaf\xbe\x7b\xb9\xab\x6f\x59\xec\xea\x7f\x5c\xea\x7a\x5b\xda\xd4\x2f\x75\xf5\x27\x2f\x74\xd5\xa8\xa9\xb7\xcc\xd5\x9f\xba\xc8\xd5\xb7\x1e\xc9\xd0\x2e\xda\xbc\x4f\x83\x77\xaf\xe6\x14\xff\x0b\x2d\x79\x1d\x9e\xde\x14\x62\xf2\x9b\xae\x83\x6d\xce\x72\xe2\x74\x7f\xb7\x67\x39\xdd\x70\xb9\xaa\x7c\xde\x2d\x99\x6d\x80\x76\x3c\xee\x29\xc4\xa4\xb7\x2c\x26\xc4\xc4\xb6\xd6\x86\x4e\x3e\xee\x89\x83\xf6\xd6\xdb\x50\x79\x08\x4a\x88\xc9\x2d\xee\x13\x57\xe5\x60\x3e\xf1\x69\xb4\xb8\xc3\xbb\xca\xb3\x2c\x4b\x8a\xb0\x98\x2b\xc7\x41\xed\xcd\x75\x90\x11\x49\x52\x92\x90\x54\x3d\x2c\x6a\x4f\x77\x2a\x94\xa6\x6d\x82\xc3\xc4\xc3\x61\xaa\x1e\x2e\xa5\xa7\x82\x43\x52\xb2\x5c\x1c\x49\xd5\x1c\x3d\x35\x95\x4a\x14\xfb\x3e\x89\x22\x71\x6c\x95\x3c\x98\x4a\x4f\x85\xb2\x2c\x08\x52\x1a\xab\xc7\x56\x4d\xa5\x52\x64\x5e\x4e\x98\x57\xa8\xc7\x5c\xe9\xa9\x04\x71\x16\x06\x14\x17\xea\x21\x58\xc3\xcc\xf7\x43\x9c\x82\xc5\x4d\xeb\xc6\xa7\x60\xe1\xe8\xe3\x31\x58\x0d\xfc\x6d\xe7\x59\x74\xf7\x63\xb0\x78\x1b\x77\xae\xa5\x06\x95\x71\xb6\x45\x3f\x1e\x83\xf5\xa1\xf3\x2d\x3a\xfd\x18\x2c\xad\xb2\xfa\x39\x17\x9d\x74\x0c\x96\x4f\x9d\xc7\x60\xf1\x94\xe0\x3e\x25\xba\x0c\x8c\xfc\x0b\x65\x60\xff\x36\x9b\x8e\x6e\x7f\xc3\xd1\x87\xdb\x49\xf4\x3e\xa9\x99\x7c\xd8\x76\x5c\xe2\xfa\xa9\x59\x1f\xad\xbb\x77\xaa\xbf\x86\xfa\x20\x3d\x3f\x5f\x5e\xcf\xe4\x8f\x73\x94\x6e\x4e\x2f\xce\xd8\xaa\xde\x6a\x2e\xca\x52\xb7\x36\x29\x6c\xc1\x79\x5d\x0a\x9d\x01\x13\xde\x55\x40\x68\x4a\xca\x04\x72\x95\x22\x26\x34\x65\x84\xec\xcd\xc7\x70\x31\xf6\xe3\x20\x48\xe0\x60\x4c\xe2\xb3\x32\x0a\xf3\xa2\x97\x6d\x8c\x5a\x64\x61\xee\x95\x59\x5e\xc2\x45\x22\x79\x50\xf8\x19\x29\x75\x98\x59\x92\x85\x45\x96\x86\x70\xeb\x3e\xa6\x49\x91\x65\xb9\x1d\xb3\x9f\x84\x51\x4e\xc2\x0c\x72\x24\x3f\xa0\x59\xe8\x53\x1d\xe6\x30\x29\x31\xc6\x25\xf0\x9c\x45\x5e\x58\x78\x38\xb1\x63\x4e\x88\x5f\x52\x92\xc2\x5d\xfd\x69\x89\x93\xa0\x4c\x32\x1d\xe6\x34\xc3\x79\xc8\x0a\xe0\xb9\x48\xa3\x82\x62\x4c\xed\x98\x0b\xea\xc5\x69\x2a\xe4\x9c\xfa\x9e\xef\x91\x40\x2b\x67\x4c\xa8\x1f\x66\xe2\xfa\x95\x20\x8c\xbd\xa8\xcc\x98\x1d\x33\x09\x7c\x4c\xc3\x0c\xae\x61\x09\x18\x0b\x32\x42\x73\xad\x34\x42\x2f\x8f\x8b\xdc\x07\x9e\xc3\xb2\xcc\x02\x46\xec\x98\x63\x92\xb1\xb0\x88\x41\x1a\x25\x89\x33\x9a\x44\x5a\x0d\x52\xaf\x60\x19\x16\x17\xc1\xf8\x19\x8e\x92\x28\xc3\x0e\x39\x67\x45\xee\x45\xe2\x68\x55\x12\xe6\x31\x26\x7e\xa8\xc3\x9c\xe3\x24\x2b\xb1\xe0\x20\x2f\xa3\x84\x44\x49\x60\xc7\xcc\x82\x24\x8b\x92\x1c\xe4\x97\xb0\x12\x07\x69\xa1\x95\x33\x2b\x33\x16\xc4\x34\x02\x9e\x69\x50\x92\x90\xf9\x76\xcc\x5e\x99\xe3\xa4\xc8\xa1\x05\xcd\x68\x5e\x84\x99\x96\x67\x12\x78\x79\x8a\xf3\x9c\xc3\xc5\x71\x9a\x27\x79\x14\x3a\x34\x58\xb0\x84\xe4\x11\x78\x4a\x98\x90\xcc\x23\xb1\x16\x73\x90\xc6\x01\x0d\x52\x78\x03\x89\x58\x1a\xb1\x80\x3a\x78\x0e\xf3\xcc\x4b\x93\x02\x78\xc9\x8a\x00\x97\x59\x11\x68\xbd\x3b\x2a\x13\x4a\x0b\xc0\x4c\x7d\x8c\x43\x3f\x73\xf0\x9c\x50\x9f\x85\x38\x24\xe0\xdd\x2c\x8a\x8a\x32\xd5\x7b\x0a\xf5\x71\x1e\x45\xf0\xfe\x40\x8a\x2c\xf0\x09\xf6\x1c\x71\xc3\xf3\x7c\x12\xe7\xe0\x29\x09\x2d\x33\x82\x7d\xad\xd5\x65\x65\x98\xc4\x65\x2e\x8f\xe7\x65\xa5\xc7\x98\xc3\x36\xf2\x88\x79\x5e\x56\x82\x07\xf8\x45\x4a\x69\x99\x6b\x6d\xa3\x08\xd3\x38\xc1\x01\x60\x4e\x7c\x2f\x4d\x63\xe2\x90\x86\x17\xe5\x69\xe4\x87\xe2\xd2\x24\xcf\xf3\x29\xd1\x7b\x0a\x0e\x48\x42\x12\xf1\x76\xe7\xa5\x1e\x8b\x58\xec\x90\x06\x89\xb3\xd8\x4b\x29\x44\x9a\x20\x2a\x08\x29\x4b\xad\x77\x13\x86\xb9\xa4\x40\x6a\x61\x4e\xa2\x3c\x21\x91\x1d\x73\x50\x90\x3c\x2a\x4a\xb0\x8d\x30\xcd\x03\x92\xb2\x42\x1b\x37\x7c\x9f\x7a\x05\x06\xa9\x25\x45\x12\x66\x7e\x51\xda\x31\x47\xa1\x97\xc6\x7e\x18\x08\x4f\x49\xcb\xc8\x2f\x98\xde\xea\xa2\xd4\x4b\x33\x88\xe3\x7e\x1e\xc7\x19\x49\x1d\x51\x94\xe2\x9c\xe4\x09\x11\xb1\x2e\x66\x45\xca\x58\xa4\xc3\x9c\x90\x98\x90\x5c\x48\x0d\x07\x94\xf8\xa1\x9f\xd9\x31\xa7\x24\x2b\x19\x4d\x45\xdc\xcd\x4b\xec\xf9\x91\xd6\x53\x52\x8a\xd3\x28\x0a\x80\xe7\x2c\x0f\x88\xef\x79\x8e\x58\x97\x93\x20\xa3\x59\xec\x41\xdc\xf5\x4a\x9a\xc4\x09\xd6\xc6\xba\x38\xca\x43\x9c\x82\x9c\xbd\x28\x0c\x32\xe6\x3b\x6c\xa3\xc0\x09\x61\x14\x27\x80\x39\x62\x65\x48\xb0\x76\x1c\x2c\xa2\x24\xf1\x22\x02\xfa\x08\xc3\x28\x4c\x13\x97\x0f\x96\x81\xc7\xfc\x50\xc8\x2f\x8c\x63\x4c\x3c\x92\x6a\xed\xd9\x8b\xd2\xd4\x13\x7d\xf3\x49\x96\x15\x38\x73\x68\x10\x27\x69\x90\x63\x0c\x51\x34\xa3\x05\x29\xbc\x5c\xcb\x33\x66\x7e\x1c\xe5\x9e\xb0\x67\x1c\xe0\x34\x0b\x1d\xb1\x8e\xc4\x01\x8d\xe3\x00\xec\xb9\x28\x29\x63\x59\x92\xe8\x30\xfb\x41\xe6\x65\x79\x06\x7d\x63\x38\xc9\x02\xea\xb2\x3a\x3f\xc1\xb9\x97\x67\xa0\x99\x3c\xcc\x93\x30\x8d\x7c\x6d\x7c\x66\x05\x4d\xd3\x00\xa2\x28\xf3\x03\x4c\xd3\xdc\x61\x75\x61\x96\xe4\x79\x1a\x94\x62\xac\x88\x7c\xe6\xc7\x5a\xcc\x11\x25\x2c\x2a\x45\xe4\x2a\xa2\x8c\x64\x34\x75\x48\x23\x0e\x68\x49\x09\x03\x4f\x09\x0b\x56\x66\x44\x1f\x37\x62\x9a\x86\x91\x2f\xc6\x9e\xc0\xc7\x31\x29\x23\x87\x6d\xd0\x20\xa7\x31\xc5\x22\x47\xc2\xa5\x97\x66\xb1\x36\x8a\xd2\x3c\x8f\x3d\x22\x34\x88\xd3\x28\xf0\x13\xe6\xc8\xeb\x12\x2f\x63\x65\x59\xa6\x22\xc7\x8c\x7c\xcc\x88\xd6\x36\xd2\x20\xf4\xa2\x9c\x81\x0f\x16\x8c\x92\xac\x60\x8e\xbc\x2e\x63\x65\x92\xfa\xa5\x18\x2b\x48\x1e\xc5\x09\xd6\xe7\x1b\x51\x8c\x63\x5a\x8a\x51\xcd\x8f\x49\xe8\x13\x87\x06\xf3\x94\xc4\x3e\xcb\x41\xce\x2c\x25\x51\x84\x13\xad\x9c\x0b\x4c\xa3\x8c\x8a\xd1\x8a\x70\x73\x22\x83\xca\xe3\x38\x43\x49\x8b\x34\x2e\x0a\xf0\x94\xbc\x60\x1e\xcb\xb0\x36\x8a\x96\x61\x5c\x04\x65\x5c\xca\x91\x98\x15\x38\x76\xd8\xb3\x17\x95\x5e\x14\x8b\x3c\x22\x26\x38\x8e\xca\x4c\xeb\xdd\x5e\x1a\xf9\x71\x91\x83\xa7\xa4\x24\xa7\x09\x4d\x1d\x63\x0a\xc6\x7e\x99\x50\x2f\x90\xd5\xc2\xc4\x2b\x52\x2d\xcf\x38\x8b\xb1\x97\xf9\x22\x3e\xfb\x38\x0f\x62\xec\x90\x33\xa1\x45\x16\xc7\x65\x28\x6c\xc3\x0b\xe2\x82\x6a\xe3\xb3\x4f\xf2\x34\xcd\x62\xb0\x8d\xc0\xcb\x63\x12\x24\x0e\x4f\xf1\xf3\x84\x65\xcc\x03\x69\xe0\x30\x4f\x32\x96\x69\x35\x18\xf8\xb8\x88\xe2\x1c\xfa\x96\xe4\xd8\xf3\x8a\xc0\x61\xcf\x41\x9e\x87\x45\x20\x32\xf3\x3c\xf3\x59\x40\x32\xed\x68\xc5\xf3\x18\x92\x24\x10\xb9\xca\x3c\x0a\x63\xc6\xa3\xad\x35\x6e\x94\x79\x16\x95\xa9\x18\x39\xd3\x22\x2a\x53\xa6\xe5\x39\xca\x83\x00\x27\x14\x30\x07\x69\x10\x87\x14\xc7\x4d\xf5\xf6\x95\x75\x23\xb1\xf2\x0e\xf9\xc3\xcd\xf7\x0c\x1b\x2f\x1a\xfc\xa1\xb7\x67\xf8\xa7\xf7\xd8\x33\x1c\x62\x32\x75\x1e\x43\x33\x41\xf2\x21\xce\xbb\xbd\xf1\x3c\x46\x94\x7a\x09\x6b\x6a\xff\x7e\x96\xe7\x89\x67\x98\xc7\xc8\xb2\x28\x4e\x99\x18\x9f\x69\x90\xa7\x69\x3c\xc8\x6f\x2c\x54\xfc\x3c\x62\xa5\x1f\x43\x8c\x2b\x59\x12\x94\x94\xc7\x38\x1d\x64\x1a\x06\x65\x19\xfa\xe0\x19\x61\x89\x0b\x3f\x2a\x27\xcf\x30\x84\xd8\x63\x21\x11\x51\x29\x2d\x58\x44\x49\x61\x98\xc7\x48\x32\x2f\x8c\xa8\xb0\x51\x92\xf9\x2c\xca\x71\x39\x95\x0a\x2e\xa9\x5f\x24\xc2\x0f\xca\x2c\xc0\x59\x11\x19\xfa\x12\x66\xcc\xcb\x0b\x91\x2b\x61\x3f\x66\x04\xc7\xc9\xae\xf3\x18\xb7\xbf\x9b\x77\xda\x89\xc4\x00\xe9\x59\xce\x1b\x3e\xc1\x96\x03\x87\x4f\x88\xe5\xc4\xe1\x13\xdf\x72\xe4\xf0\x49\x60\x39\x73\xf8\x24\xb4\x1c\x3a\x7c\x12\x59\x4e\x1d\x3e\x89\x8d\xc7\x0e\x8b\x9e\xc2\xb1\xc4\xfa\x35\xf4\x02\x60\x29\x00\x34\xdb\x67\x84\x34\x00\x81\x7e\x9f\x99\x00\x58\x0a\x00\x13\x02\x02\x08\x88\x19\x01\x59\x0a\x00\x13\x02\x1f\x10\xf8\x66\x04\xfe\x52\x00\x98\x10\x04\x80\x20\x30\x23\x08\x96\x02\xc0\x84\x20\x04\x04\xa1\x19\x41\xb8\x14\x00\x26\x04\x11\x20\x88\xcc\x08\xa2\xa5\x00\x30\x21\x88\x01\x41\x6c\x46\x10\x2f\x05\x80\x76\xad\xe3\xd4\x53\xb8\x85\xad\x68\x09\xa4\xc2\x4c\x46\xe7\x37\xc2\x0a\x65\x61\x22\xda\x76\x99\xb0\x0e\x6d\xbb\x5c\x58\x86\xb6\x5d\x2e\x8c\x42\xdb\xae\x10\x06\xa1\x6d\x57\x08\x5b\xd0\xb6\x63\xc2\x0e\xb4\xed\x98\x30\x01\x6d\xbb\x52\xa8\x5f\xdb\xae\x14\x9a\xd7\xb6\x3b\x15\x5a\xd7\xb6\x3b\x15\x0a\xd7\xb6\x5b\x08\x65\x6b\xdb\x2d\x84\x9e\x97\xfa\xf3\x2c\xad\xbb\xaa\xa7\xde\x59\x6c\x3e\xf7\xbd\x61\xe2\x87\x4a\x9c\x86\x6d\x3e\x1e\xe0\x11\x24\x00\xcd\x24\x9f\x06\x66\xca\x29\xe6\x82\x14\x17\xc6\x0f\x55\xb3\x8b\x43\x3d\xd2\x1c\x7d\x86\xc8\x2b\x80\x34\x9c\x26\xdc\x21\x59\x0a\x24\x72\xdf\xc6\x10\x09\x1c\x75\x70\xc3\xf3\xd1\x0f\x0f\xd1\x7f\xc2\x09\xd9\x16\xfa\xcd\x71\xe3\xbb\x1d\xa0\x7e\xb5\x68\x4f\xdf\xbe\x72\x6e\x86\x94\x70\x4b\xa5\x89\x63\x43\xa4\x00\x5b\xf4\x8e\x69\x5f\x88\xd3\xa8\xd5\xc3\xd5\x97\x70\x68\x76\x73\x3e\x75\x0f\x8e\x8e\xe0\x60\x8d\xf0\x6b\xd4\x07\x8b\xad\x3b\x7e\x05\xe8\xb2\xc7\xc6\x72\xcc\xc6\x42\xc7\xc6\x72\xcc\xc6\x42\x65\xa3\x0f\x17\x8f\xe1\x8c\x67\x6b\xab\x9a\x35\x1d\x93\xf4\x56\x39\x1c\x7e\xa7\xd3\xe1\x3b\xc5\xe2\x89\x8a\xc5\x9d\x62\xf1\x34\xc5\xe2\x45\xef\x0c\xfa\x45\x73\x4e\xbc\x72\x74\xfc\x52\x9e\x26\xaf\x88\x0a\x4b\x39\xf7\xc1\x60\xf5\x77\xa2\x68\xb6\xc1\x17\xb9\x35\x8b\x97\x3d\x3e\x96\x1a\x3e\x16\x3a\x3e\x96\x23\x3e\x16\x3d\x3e\xfa\x08\xa3\x11\x3e\x12\x39\x54\xbb\xd3\xe9\xf6\xd6\xd8\x12\x77\xda\x8f\xad\xda\xff\xa1\x8a\x45\x30\xd3\x8f\xe3\x03\xd0\xa5\x04\xb5\xee\xd9\x17\xb0\x38\x52\x42\x8b\xf9\x4a\xf7\x06\x58\x30\x81\xf5\xe9\xc8\x10\x78\xd9\x00\x4f\xe0\xa3\x8b\x3e\x4b\x2e\xbd\x2a\x1e\x0d\x6f\x7d\xf8\x2e\xc0\x2d\x04\xfc\x02\x4e\xf3\xe3\x88\xb8\x56\xbd\x3d\xf4\xa0\x71\xd8\xf6\x97\xff\x40\x18\xdd\x47\xe3\x95\xe6\x63\x4e\xf8\xbf\x8d\x32\x27\x30\xc2\xff\xdd\x6f\x9d\xc7\xc0\x07\xbe\x31\x1f\x20\xcb\xa9\x5c\x08\x2d\x8d\x79\x10\x0a\x19\x73\x60\x40\xdb\x0d\x9b\x3f\x54\x46\x45\x77\xc3\xe2\x0f\x95\x96\x41\xdb\x35\x0e\xf2\x1e\x87\x05\xba\x83\xca\x85\xbc\xc9\x81\x7f\x31\x6c\xa2\x14\x8d\x44\x48\x60\x4b\xde\x68\x29\x1b\xf1\x2f\xa7\x4b\xdb\x05\x10\x0b\xb8\x01\x82\x23\xcf\x04\x25\xf8\x9c\x8b\xcf\x99\xfc\x6c\x69\xbf\x84\xf6\x9c\x4e\x26\x88\xc2\xe7\x5c\x7c\xce\xe4\x67\xd7\x3d\x12\x0b\x71\x91\x84\x8c\x45\x62\xe4\x49\x97\xe2\xb4\xf3\x3d\x71\x5c\x45\xba\x68\xae\x99\x90\x0f\x7b\x17\x4d\x2c\x94\x9b\x50\xd2\x66\x5c\xb2\x5f\x27\x01\x6f\x68\xb3\x16\x93\x24\xba\xe8\x13\x5d\xf6\x88\x2e\xfa\x44\x97\x2a\xd1\xc5\x24\xa2\x58\xf4\x94\xc9\x81\x43\x6c\xe1\x61\x62\xc8\xa0\xcd\x65\x15\x8b\xe6\xe6\x15\xe5\x61\xd0\x3d\xe4\x44\xfd\xe6\x99\x38\x17\xde\x41\x54\xf4\x54\x42\x37\x44\x17\x7d\xa2\xcb\x1e\xd1\x45\x9f\xe8\x52\x25\xba\x50\x88\xea\xd3\x54\xf7\xf5\x19\x06\x76\xbf\x81\x23\xb6\xbe\xb1\x6c\x57\xfb\x06\xdc\xf9\x9b\xca\xba\x51\xed\x1b\x08\x10\xdf\x54\xe6\xe0\xfa\x16\x2e\xf9\xe0\x50\x8b\x65\xcb\xa7\xd6\x4d\x05\x24\x27\xba\xe8\x7a\x24\x82\x48\x8d\xd5\x20\xb2\x98\x14\xc3\x3a\xc2\xfc\x5f\x2e\x18\x07\xd5\x1a\x88\xe5\x0b\x1d\xc9\xfc\x66\x34\xbf\xd1\x07\xa4\x21\xcd\x6f\x2a\x1d\xcd\x6f\xaa\x1b\xd1\x34\x04\xc1\x21\xcd\x1f\xb4\x34\x7f\xd0\xd2\x34\xd8\xde\xf0\x02\x16\x13\x55\xa8\x8f\x34\x91\x00\x20\xcd\x1c\x42\xb1\xa5\x09\x55\xfb\x22\x6c\x02\x9b\x44\x65\xb3\x41\x36\x95\xd5\xbf\x9c\x17\x69\xcd\xd0\xa5\xa3\x86\xc0\xff\xe0\xdd\x55\x6f\xf0\xf0\xea\x7a\xaa\xe5\x1d\xc6\xa8\x52\xdb\x0a\x5e\x94\x4b\x6d\x2b\x78\x2f\x67\xda\x56\xf0\x5a\xce\xb4\xad\xe0\x4d\x7f\x56\x2c\xe1\x22\x9a\xa5\xf1\x26\x1a\x28\x16\xcc\x8a\x05\x80\x09\x21\x32\x55\x86\xc5\x48\x7c\xe6\x4b\x6d\x38\xaa\x5c\xcb\x27\x94\x2b\x72\x2d\x9f\x50\x1d\xc9\xb4\xad\xa0\x38\x92\x69\x5b\x41\x2d\x26\xd5\xb6\x82\x52\xcc\xf8\x06\x0e\xfe\x07\xd5\x9d\x99\x70\x80\x9a\x98\x85\x02\x15\xa2\x99\x90\x07\xb7\xb5\xfd\x6e\x5c\x12\x52\xa9\xc7\x09\xd2\xad\xdf\xbd\xa3\x54\x2c\x21\x91\x38\x01\xb7\x48\xc7\xc9\xc3\x49\x7b\x90\xc8\xec\x04\xdc\x21\x15\x1c\x9f\x78\x2a\xcb\xe9\x98\xe3\x11\x22\xa5\xc6\x29\x48\x82\xa4\x32\x0d\x49\xdc\x91\x04\x29\x65\x92\x64\x2f\x4c\x64\x13\x48\x2a\x55\x51\x41\x92\x40\x14\xd6\x90\x24\x1d\x49\xb2\x68\x86\xb0\x19\x34\x50\x22\xf0\x04\x92\x4a\x1d\x55\x90\xf4\x39\xc9\x42\x43\xd2\xef\x48\xfa\x9c\x5a\x21\x49\xfa\x0e\x0f\x19\x21\x52\x2a\xaf\x82\x64\xc0\x49\x32\x0d\xc9\xa0\x23\x19\x70\x6a\x4c\x92\x0c\x54\x92\x6c\x02\x49\xa5\x56\x2b\x48\x86\x9c\x64\xa9\x21\x19\x76\x24\x43\x4e\xad\x94\x24\x43\x95\x64\x39\x81\xa4\x52\xdd\x15\x24\x23\x78\x33\xd1\x90\x8c\x3a\x92\xf0\x02\x70\x2a\x49\x46\xbd\x37\x91\x09\x24\x95\x7a\xb0\x20\x19\x73\x92\x0b\x0d\xc9\xb8\x23\x09\xef\x5f\x72\x00\xe7\x0d\x6c\x39\xc3\xad\x6c\x53\xf9\x78\xd7\xd3\x07\xb8\xeb\x09\xf3\x57\x04\x79\xbb\x1f\xc7\x06\x67\xea\xf8\xde\xad\xdf\xf6\xa4\xa7\x83\xff\x89\xef\x7b\x3a\x5e\xaf\xde\xb2\x8d\x38\x2b\x1a\xd5\x6b\xe4\x93\x7b\x59\x55\xf3\xbc\xa6\x40\x29\x2c\x4b\xcf\x58\xb9\xde\x30\xb9\x82\x7c\xac\x3e\x65\x4f\x8e\x32\xd3\x58\xaf\x7f\xf4\xc9\x2d\x5d\x31\xf5\x7b\xbf\x5c\xaa\xcf\x6e\x7b\xcc\xcb\x7d\x84\x3d\x12\x1c\xfa\xcd\xb1\xd7\x1f\x77\x88\x4d\xdb\x21\x16\x62\xb2\xf3\x0e\x31\xde\xc6\xb9\x43\xac\xb7\x5c\x63\xb4\x43\x2c\xc4\xe4\xe3\x0e\xb1\xdb\xd2\xaa\x7e\x87\x18\xd7\xd2\xd4\x1d\x62\x5a\x65\xf5\x76\x88\x49\x85\xb9\x76\x88\x35\xbb\x98\xa7\xee\xca\xf7\x7f\xf7\x7b\xc2\xd8\x2a\xbf\x97\xa5\x5b\x16\x05\x83\x07\x67\x45\x38\x04\x7d\x7b\xfe\xa6\x28\x07\x3f\xe6\xd5\xf9\x82\x6d\x7e\xb3\x6d\x65\x0a\xbb\xf0\x9d\x73\x29\x1e\x08\xe6\xe0\xb3\xca\xd3\xbf\xda\xf6\xb3\x1f\xa6\xdd\x77\x05\xcb\x86\x8e\x41\x0e\x2d\xa0\xf2\x5b\x9f\x94\xf9\x02\xab\xef\xd9\xe6\x0c\x06\xe4\xe3\xc5\xba\xca\x19\xc2\xa3\x7b\x7f\x38\x86\xef\x8f\xf1\x60\xe7\x57\x18\xcf\x51\x90\xcc\x51\x80\xe7\xc8\xf7\xe7\x88\x84\x73\x84\xe3\x39\x4a\xe6\x08\x61\x75\xb9\x55\x48\xe7\x28\xf4\xe6\x28\x20\x73\xe4\x07\x73\x44\xa2\x39\xc2\x74\x8e\xb0\x37\x47\xa4\x07\x98\xcc\x51\x88\xe7\x28\xf0\xe7\xc8\x0f\xe7\x88\xc4\x73\x84\x93\x39\xc2\x9c\x82\x0a\x18\x79\x73\x14\x92\x39\x0a\x82\x39\xf2\xa3\x39\x8a\xfc\x39\x0a\xc3\x39\x0a\xe2\x39\xf2\x13\x15\xd2\xc7\x73\x44\xfc\x39\xc2\xe1\x1c\xc5\x73\x84\x22\x32\x47\x61\x30\x47\x01\xdc\x79\xd1\x83\xe4\xdc\x90\x39\xc2\xc1\x1c\x45\x1c\x12\xcf\x51\xe8\xcf\x51\x10\xce\x91\x1f\xab\x90\x24\x99\x23\x82\xe7\x08\x73\xaa\x73\x84\x08\x9d\x23\xe2\xcd\x11\xe6\x1c\x49\xb8\x57\x56\x11\x13\x83\x88\xc9\x40\xc4\x9c\x17\x2e\x52\x2e\x00\xc2\x3f\xcf\x11\x0a\x7b\x4c\x4b\xf2\xbc\x7b\x9c\x69\x60\xcb\xeb\x31\xeb\x4b\x19\x72\xe6\x38\x44\x34\x47\xbd\x7e\xe3\x48\x48\x86\x0b\x1b\x7a\xe1\x0f\xb4\xc2\xf5\xcb\x85\xcd\x45\xe9\xc7\x42\xc8\x61\x38\x14\x5d\xe0\x49\xdd\x85\xc2\x1a\x82\x1e\x11\xae\x28\x6e\x2b\x3e\xd7\x70\x24\xcc\x20\xec\xa9\x94\x2b\x84\x1b\x08\x37\x14\xae\x52\x2e\xe4\x36\x53\x1a\xdc\x7e\x76\x71\x76\xb1\x4c\xe1\xb2\x1f\x9e\xb9\x6e\x17\x55\x39\xbe\xcb\x0c\x1c\xe4\xeb\x17\x3f\x3d\x3f\xf9\xfa\xb1\xb8\x42\x8d\x0b\x8f\xcc\x11\x48\x81\xcb\x8a\x72\x3b\x95\x6a\x03\x41\x4b\xfb\xc5\x52\xbd\x44\xda\x34\x08\x86\xf6\x59\x78\xfe\xe5\x77\x3f\xb2\x2d\x4a\x57\x85\x3c\x9c\xff\x1c\x34\x2c\x2e\x80\xd1\xb1\xc2\x1b\xfc\xf4\xfd\x40\xbd\xc3\xac\xd5\xbb\xf2\xee\xc3\xfb\x0f\x25\x9e\x37\x5c\xb0\xd8\xbd\x9e\x08\x18\x1d\x04\xe9\x41\x50\xcf\x23\x63\x18\x5f\x81\xd1\x3c\x0e\xd4\xc7\x3a\x1a\x61\x9f\x06\xd1\xd1\x88\xfa\x9c\x6a\x61\xe2\x41\x6f\x74\xb4\x68\x8f\x19\x0d\x92\x64\x48\x48\x83\x24\x55\x61\xb4\x10\xd9\x50\x6c\x1a\x98\x7c\x40\x69\x0c\x51\x0c\x3b\xa4\x81\x61\x0a\x8c\x86\x48\xd9\x67\x55\x83\x80\x5a\xdb\x63\xea\xd6\x0d\xa1\x2e\x1a\x3e\x75\xd9\x59\x30\xa4\xa3\xb3\x13\xea\x30\xa4\x88\xba\x8d\x35\xa6\x56\x63\xa5\xd4\xad\xfe\x84\xba\xd4\x9f\x0e\x19\xd1\x99\xc8\x90\x92\x86\x9b\x9c\xba\x0d\xa0\xa0\x2e\x33\x62\xd4\x61\xf3\xe5\x90\x8c\xce\x10\xcc\xba\x93\x51\x04\x1b\x44\x4a\x94\xc7\x26\xd5\xfa\x3d\x18\x3d\x07\x41\x1f\x8f\xb6\xab\xa1\x0a\xa3\xb7\x11\x95\x59\x1d\x40\xdc\x67\xc5\xe6\x33\xd8\xe6\x15\xc9\x90\x5d\x73\x20\xc1\x36\xfd\x66\xfd\x2e\xe9\xac\xa4\xd7\x25\x73\x1c\xc1\x36\xa3\x66\x03\x18\x63\x28\xc1\x86\x48\x41\xdd\x22\xc1\xd4\x2d\x12\x42\xdd\x96\xe0\x53\x87\x0e\x83\x01\x12\x63\x2c\xb1\x4a\x3e\xa2\x56\xbb\x8e\xa9\x4b\x31\x94\xba\x64\x9a\x50\xb7\xb1\xa5\xd4\xa1\xde\x6c\x28\x7a\xdd\x60\x33\x24\xa4\x81\x29\xa8\x55\xc1\x8c\xba\x7c\xab\x1c\xea\xb7\x77\x1d\xdb\xdc\x9d\xa7\x04\x9e\x47\x03\x0f\x9b\x63\x8c\x04\x32\x27\x2a\xad\x3e\x8d\x31\xa6\xa1\xe3\x69\xe9\x04\x7d\x3a\x7a\xa0\xb0\x8f\x49\xcf\x50\xd4\xc7\xa4\x07\x8a\x3b\x20\x1d\x21\x35\x2e\xeb\x11\x24\x43\x2a\x3a\x34\xe9\xb0\x53\x96\x94\x45\xd2\xd2\xa1\xc9\x7b\x22\xd6\x41\x14\x1d\x84\x39\xc4\x08\x36\x74\xcd\xcb\xa1\x86\xcc\x19\x9c\x5d\xac\x98\xba\xfa\x42\xa8\x55\xf0\xfe\x90\x8a\xd6\x56\xe8\xc0\x0c\xb4\xb6\x42\x27\xc8\x3e\xa2\x2e\xe3\x8d\xe9\x04\xe3\xa5\xd4\xa5\xa0\x84\xda\x14\x94\x52\x87\x93\x65\x43\x2e\x2c\xa1\xc6\xee\x42\x05\x75\x59\x36\x1b\x4a\xd7\x12\x71\xcc\x26\xa5\xbe\xe1\xe8\x1e\xe3\x29\x41\x01\x93\x29\x5e\x86\xfd\x29\x61\x01\x07\x53\x8c\x1c\x87\xf6\xc0\x80\x23\xa7\xb7\xe2\xd8\x15\x32\xd5\xdc\xde\x80\x23\x71\x46\x55\x9c\x3a\xa3\x02\xce\xa6\x04\x55\x9c\x3b\x83\x1d\x2e\xa6\xc4\x54\xcc\xa6\x84\x3b\x5c\x0e\xb5\xa5\x37\x1f\x67\x24\xc1\xd8\xe9\xbc\x98\x4c\xf1\x1b\xec\xbb\xdc\x0f\x07\x93\x82\x5f\x38\x25\x2e\xe1\xc8\x1e\x01\x71\x3c\x25\x70\x61\x3a\xc5\x4b\x71\x32\x25\x24\xe0\x74\x4a\xd0\xc5\x99\x33\xc8\xe1\xdc\x1a\xe5\x70\xe1\x0c\x1a\x6c\x4a\xb4\xc5\xe5\x20\x86\xed\x98\xec\x60\x2f\x30\xc5\x2b\x03\xe7\xa4\x27\x1f\x6c\x4e\x72\x04\x7a\x2d\x81\x40\x01\xf0\x74\x00\xe1\x40\x55\x1a\x90\xa8\x27\x3f\x2d\x99\xb8\x07\x32\x61\x20\xb7\x64\x37\x1d\x21\x63\x6e\xd3\x74\xd8\x98\xd7\x74\x9c\x68\x98\xcd\x07\x72\xd5\x80\x14\x3d\xb1\x19\x93\x1b\xc0\x61\x4a\x6c\x64\x6b\x83\x24\xac\xbd\xc4\xd4\xd9\x09\x42\x2d\x96\xe3\x53\xa7\xe5\x04\xd4\xa9\xf7\x90\x3a\x84\x10\x51\x87\x71\xc5\x0a\x80\xe6\x31\xa5\x16\x21\x26\xd4\x2a\xc4\x94\x3a\x2d\x2e\xa3\x0e\xe7\xc8\xa9\xc3\x98\x0a\xea\xb4\x14\x46\x9d\xce\x51\x52\xa7\xe5\xf7\xf2\x12\x93\x51\x60\x97\x2f\x63\xe2\x32\x5b\xec\xbb\x63\x0a\x0e\xec\xe6\x8b\x43\x77\x3c\xc0\x91\x3b\xac\xe0\xd8\x1a\xb6\xa9\xdb\x4b\x71\xe2\x8e\x29\x38\xb5\x79\x2a\xce\x5c\xf1\x04\xe7\xee\xd0\x86\xd5\x70\xa1\xa3\xc2\x5c\x61\x1a\x97\xee\xb0\x25\x93\x13\x7b\x6f\xb1\xdd\xe3\x30\x99\x10\x7c\x7c\x5b\x68\xc1\x81\xcb\xe9\x71\xe8\x8e\x3e\x38\xb2\x7b\x37\x8e\xdd\x11\x10\x53\x57\x7c\xc2\x89\xdb\x39\x71\xea\x8a\x12\x38\x73\x87\x4a\x9c\xbb\x23\x05\x2e\xdc\x21\x0b\x33\x5b\x48\xc4\x65\x3f\x60\xed\x98\x81\x50\x4f\xd0\x35\x84\x9f\x26\xa3\xc5\x5e\x60\x4a\x46\x1a\xde\x75\x00\x7e\x87\x23\x30\x58\x67\x60\xb1\xab\xb0\x2f\x1b\x43\x16\xd2\x66\xdd\x5a\x16\x62\xaf\x97\x4f\x5a\x46\xde\x66\x5e\xc8\x90\x83\x74\xba\x36\x64\x20\x02\xc0\x90\x7d\x74\x82\x34\xce\x03\x75\x72\xd2\x61\x29\x14\x1f\x36\xe5\x1e\x8d\xd9\x1b\xb2\x8f\x4e\xdf\x26\x39\xd8\xd5\x8d\xa9\xa5\x97\x84\x3a\xbb\xe0\x53\xa7\x20\x02\xea\xd0\x78\x48\x9d\x1d\x89\xa8\xd9\xa2\x62\xea\x34\x48\x4a\xad\x92\x4c\xfa\x0c\x18\xd3\x10\x9b\xb9\x64\xd4\xaa\xcb\x9c\x3a\x2d\xb2\xa0\x0e\xab\x66\xd4\xe1\x9a\x25\x75\xba\x0e\xf6\x5c\xbe\x83\xb1\xcb\x43\x31\x71\xbb\x28\xf6\xad\x63\x8b\xdd\xf0\x71\xe8\xf6\x1d\x1c\x79\x4e\xa5\xe1\xd8\x1d\xef\x30\x75\xbb\x11\x4e\xdc\xf1\x04\xa7\xee\xb8\x88\x33\x57\x70\xc5\xb9\x3b\xb0\xe0\xc2\x15\xba\x30\xb3\xc5\x2e\x5c\xda\xe3\x8a\xc8\x3f\x1c\x3d\xc1\x6e\x9f\xc5\xc4\xe2\xb4\xd8\x77\x45\x05\x1c\xb8\xfc\x01\x87\x6e\xa7\xc2\xd1\x84\x18\x18\xdb\x82\x20\xa6\x13\xbc\x2a\xb1\x07\x18\x9c\xba\xc3\x24\xce\xdc\xd1\x16\xe7\xf6\x28\x83\x0b\x77\x24\xc3\xcc\x15\xca\x70\xd9\x0f\x34\x3b\xa7\x1f\xfa\xb0\xd3\xb0\x6d\x9c\xe7\x69\x79\xd2\x27\x1d\xf7\x95\x75\x2b\xfa\x9c\x43\x42\x40\x6d\x47\x9f\x79\xb4\x49\xa4\x0e\x20\x6a\x50\x18\x21\xe2\x8e\x4b\xdd\x63\xd5\x08\x8c\x49\x47\xc7\xa4\x29\xeb\xe8\x3a\xaa\x23\x92\x75\x5c\x1a\xd8\xc8\x7b\x10\xda\xa1\xc6\xec\x98\x4c\xd5\x94\x0e\x7b\xd9\x93\x92\xa1\xee\x61\xc5\x80\xa9\x4b\xce\x84\x7a\x46\x53\xf2\xa9\xc3\x94\x02\x6a\x35\xa5\x90\xba\x0c\x25\xa2\x2e\xf9\xc5\xd4\x65\x8e\x94\xba\x34\x9d\x50\xa3\x0e\x52\xea\x52\x71\x46\x1d\xb6\x9c\x53\x97\x1d\x15\xd4\xa5\x47\x46\x1d\xe6\x5c\x52\xab\x3b\x60\xcf\xee\xd4\x18\x7b\x66\x35\x63\xe2\x74\x79\xec\x3b\x1d\x16\x07\x2e\xa7\xc7\xa1\xd3\x5b\x70\xe4\x8c\x2d\x38\x76\xb9\x7e\x3b\x60\x9a\x95\x8a\x13\xa7\x6b\xe1\xd4\x15\x48\x71\xe6\x8c\x31\x38\xb7\x87\x31\x5c\x38\x83\x10\x66\x96\xa1\xbd\x74\x85\x10\xc8\x30\x1c\x8a\xc3\x2e\xe3\xc3\xc4\x15\x08\xb0\xef\x74\x75\x1c\x38\x3d\x19\x87\xce\x78\x16\x59\xc2\x15\x8e\x9d\xd1\x04\x53\x87\x1f\x25\xce\x78\x80\x53\x73\x34\xc1\x99\xd3\xd3\x71\xee\x8a\x27\xb8\xb0\x47\x55\xcc\x9c\x01\x0f\x97\x83\x98\xb4\x63\x5e\x21\xb9\xa7\xda\x40\xd3\xe0\xd5\x66\x16\xa2\x35\x31\x74\xde\xef\x00\x88\x16\x7d\xd0\xc9\x46\x4f\x22\x54\xfb\xa5\xcd\x2b\xda\xc7\x1a\xf4\x71\xcf\xd0\xcd\xe3\xa9\x3e\x9f\x50\x38\xd3\xe0\x4e\x1b\xd2\x7a\xc6\x33\x69\xb7\xda\x1c\x42\x91\x9a\x06\xa0\x50\x30\x6b\x1e\xb3\xb6\xcf\x9a\x87\x65\x4f\xe2\xda\x1e\xdb\x55\x86\xa9\x43\x65\x84\x9a\x3a\xe6\x53\xab\xae\x02\x6a\xed\x56\x48\x1d\xa6\x18\x51\x87\xad\xc4\xd4\x22\x18\x4a\xad\x96\x92\x50\x8b\x9d\xa7\xd4\x61\x0b\x19\x75\xa8\x34\xa7\x26\x3b\x2b\xa8\x43\x61\x8c\x5a\xed\xac\xa4\x0e\x13\xc7\x9e\xcb\xc7\x30\x76\x59\x24\x26\x2e\x47\xc6\xbe\xcd\x2a\x71\x60\x77\x63\x1c\xba\x1c\x15\x47\x9e\x2b\x52\xc5\x76\x87\x6c\x53\x63\x53\x0f\x12\x73\x98\x4f\x8d\xce\x8c\x33\x57\x0c\xc4\xb9\x2d\x84\xe2\xc2\x15\x67\x30\x73\xb9\x34\x2e\xed\x51\x90\xe7\x04\x26\xf6\xb1\xdd\xba\x30\xb1\xfb\x34\xf6\x5d\x5e\x8b\x03\x97\xdb\xe2\xd0\xe6\xb7\x38\x72\x05\x24\x1c\xbb\x63\x9a\xcb\xc9\x70\xe2\xf2\x60\x9c\xda\x22\x04\xce\xec\xc1\x0d\xe7\xf6\xf0\x83\x0b\x63\x80\xc0\xcc\xe9\xe1\x65\x3f\x3e\xdd\x68\xf0\xd7\x99\x4d\xc3\x71\xe0\x61\xdd\xe0\x2f\x73\x16\xdd\xb0\x2f\xf1\x6a\x1b\x06\x6d\xc6\xa4\x7d\x1c\x9a\x04\x11\x09\xac\xba\x51\xbe\x4b\xc1\x34\x8f\xa9\xd2\x0f\xed\x40\xdf\x0a\x41\xd3\x38\x55\xcc\x5f\xf3\x38\x53\xfa\xa2\x2d\x17\x28\xc9\xa1\x6e\xa0\x17\x22\xd4\x20\x66\x9d\x08\xb5\x85\x02\x25\xb1\xd6\xf4\xd8\x2a\x0f\x4c\x0d\x02\x26\xd4\xaa\x70\x9f\x5a\xfb\x1a\x50\x9b\x31\x85\xd4\x2a\xc7\x88\x5a\x3b\x14\x53\xa3\xa0\x28\xb5\xd9\x5a\x42\xad\xba\x4f\xa9\x55\x3f\x19\xb5\x99\x46\x4e\x8d\x0e\x50\x50\xab\x89\x33\x6a\xb0\xe4\x92\xda\xb4\x8e\x3d\xbb\xda\x31\xb6\xfb\x33\xb1\x3b\x34\xf6\xed\x7e\x84\x03\xab\xa7\xe0\xd0\xee\x67\x38\xb2\xfb\x0a\x8e\xad\x51\x43\x0e\x54\xfa\x67\x89\x3d\xa4\xe0\xd4\xea\x4d\x38\x33\x45\x16\x9c\x1b\xa3\x72\x61\x77\x6d\xcc\xec\x81\x03\x97\xe6\xf0\x89\x3d\xbb\x19\x60\xbb\x9f\x62\xe2\xf0\x7f\xdf\x64\x7e\x38\xb0\xbb\x21\x0e\xad\x3e\x8e\x23\xb3\x9b\xe2\xd8\x1e\x3d\x30\xb5\x07\x08\x9c\xd8\x5d\x15\xa7\xa6\xa8\x86\x33\xbb\x33\xe2\xdc\x1a\x41\x70\x61\x76\x73\xcc\xec\xe1\x05\x97\x4a\x00\xd9\x71\x54\xa6\x3c\x51\x20\x3a\xa4\xad\x9c\x34\x11\xfc\x7e\x37\x63\xa3\x09\xe0\xa2\xa5\x26\x74\x4b\x94\xba\x67\xa1\x40\x49\xf4\xcc\x44\xed\x53\x6d\xd8\x96\xec\x18\x46\x28\xea\x19\xba\x91\xb4\x02\xd0\x06\x6d\xc1\xad\xf6\x59\xd6\xe2\xd5\x71\x9b\xdf\x17\x1b\x71\x34\x01\xdb\x60\x3c\xac\x15\xa8\xae\x55\x29\x39\xd1\x3d\x6b\xe6\xcd\xcc\x22\x10\xcf\xb1\x55\xbe\x12\x88\x58\x2d\x42\x02\xf9\x56\xe5\xcb\x07\x81\x55\xf0\x12\x28\xb4\x48\x58\x82\x44\xee\xae\xc7\x26\x73\x93\xcf\xa9\x55\xb6\x12\x28\x31\xaa\x4c\x02\xa4\x16\xdb\x95\x20\x99\xd5\x48\x25\x50\x6e\xb0\x00\xf9\xb8\xb0\x1a\x96\x04\x62\x56\xbb\x95\x40\xa5\xc5\x7f\x9b\x94\x5b\xef\xf8\xd8\xda\x0f\x4c\x4c\xf2\xc6\xbe\xd1\x08\x71\x60\x65\x19\x87\x56\x1d\xe1\xc8\x2a\x15\x1c\xdb\xba\x6a\x8c\xd7\x89\x45\xa3\x38\xb5\xda\x2f\xce\xec\xa1\x33\xb7\x3a\x1b\x2e\x2c\x76\x8f\x99\xd1\x12\x71\x39\xc1\xf3\xba\xb7\x29\x33\x08\x76\x04\x0b\x4c\x26\x58\x21\xf6\x9d\xae\x89\x03\xbb\x6b\xe2\x70\x42\x94\x68\x94\x6f\xef\x75\x3c\x21\x72\x61\x3a\x21\x06\xe2\x64\x42\xb8\x68\xcc\xc3\xea\x81\xc2\x48\xcc\x8f\x73\x67\xf4\x13\x86\x62\x63\x96\x39\xa3\x52\x63\x34\x40\x48\xcd\x0d\xe4\xe7\xfe\x59\x17\x4f\xd3\xed\x9b\x2d\xaa\x17\x69\x8d\xb6\x6c\xc9\xf2\x1a\x4e\xba\x7a\xfe\xe5\x77\x3f\xa2\x6a\x75\xde\xde\x8f\xd2\x9e\x72\xf1\xf4\xe1\xf3\xe1\x25\xe1\xdd\x66\xd3\x39\xea\xb6\x62\xc0\xbd\xa4\xf2\x0b\x7c\x96\x5f\xe6\xbd\x96\x9e\xfc\x59\x40\x88\x2f\xcd\x67\xfe\x65\xae\x74\x4b\xc3\xbf\x7a\x6c\xd7\x57\x8f\x9e\x8b\xd3\xd8\x90\x38\x3d\xc8\x75\xc3\x1b\x87\x6f\xaf\x77\x13\x5f\x94\xf3\x75\x6e\x7e\xc1\x9b\xe3\xc4\xc7\x37\xec\xba\x3d\x81\xee\x0d\xbb\xd6\x1d\xc7\xf8\x86\x5d\x37\xc7\x3d\xbe\x61\xd7\xa6\xd3\x1e\x39\x1d\xa1\xb1\x30\x42\x59\x55\x6f\x51\x9a\xe7\xeb\x4d\x51\xad\x4e\x51\xbd\x46\xdf\x1f\x0f\x6f\xf5\x90\xa8\xbf\xac\xe0\x70\xa9\x97\xa3\x73\xbd\x75\xd7\xe8\x84\x91\xe5\x1a\x9d\x0e\xe1\xf7\x6b\x8e\xf2\xfb\x63\xfc\xb2\x7a\x85\xee\x21\xac\x3b\x59\x57\x92\x16\x97\x52\xcc\x9a\x3e\xbe\xec\x10\xc8\x53\x22\xf9\x7f\x66\x3e\x46\xf7\x14\xdc\x70\x3c\xe4\x1e\xba\x33\xc6\xac\x3d\x66\xf7\xe1\x76\xcb\xce\xb2\x25\x43\x38\x42\xdb\x8b\xec\x0d\xbb\xd6\x69\x62\x7b\x91\x7d\xc3\xae\xb7\xad\x36\xba\xef\x16\xd9\xac\x9e\x03\x94\x90\x50\xf3\xe5\x01\xc2\x51\xfb\xcd\x72\xe9\xd0\x31\x9c\x6b\x26\x59\x32\x08\x74\xdb\xe0\x97\xec\xbc\x94\x68\x5f\x35\x7c\xe9\x51\x3b\xee\x33\xca\xaa\xfa\x39\x9c\xa4\x73\xa4\x9c\x9b\xd3\xa2\x36\x63\x15\x06\x16\x50\xad\x81\x11\x4d\x23\x9d\x11\x91\xc0\x62\x44\x7d\x4a\xe5\x66\x7d\x06\x11\x68\xc9\xca\x1a\x11\x0a\xee\xc2\x69\x1b\x5a\x0a\x21\xbd\x9c\x55\xe8\x50\x5c\x91\xe2\xc1\x31\xa3\x8d\xad\xcd\x66\xdf\x1f\x13\x69\x93\x7b\x68\xbf\x15\xc3\x1e\xfa\x33\x22\xf4\x15\x9c\x44\x0a\xa6\x56\xa1\x3f\x8b\xbb\x5e\xa6\x73\xb8\xa9\x4e\x17\x3b\xb0\x18\xc0\x99\xb3\x1d\x9f\x7b\x3d\x46\x09\x85\xc7\x82\x5d\xb4\x8f\x48\x60\xe0\x79\x4f\xc7\xf4\x88\xae\xfe\x42\x0b\xde\x89\x6a\x95\x33\xc4\xd2\x7c\x21\xad\x10\x55\x5b\x94\x9e\x9f\x2f\x2b\x56\x70\xa5\xa6\x2b\xc4\xae\xce\xd3\x55\xc1\x8a\xe6\xec\x50\x18\x06\x86\x83\x8d\x44\xc7\xe5\x20\xf1\xe4\xe9\x0a\x65\x0c\x65\x9b\xf5\x1b\xb6\x42\xd5\xaa\x5e\x23\x2a\x4e\xb7\xde\xa2\x6d\x9e\x2e\x05\x7e\x81\x73\x6b\x40\x77\xb9\xa8\xf2\x05\x4a\x97\xcb\xf5\xe5\x16\x70\x73\xc4\xf5\x9a\xe3\xbd\xd8\xb2\x02\x5d\x56\xf5\x62\x7d\x51\x0b\x16\xb7\xd5\x7a\xa5\x41\x23\xc5\x0d\x87\xc1\xce\xba\x2f\x0f\x1e\xc8\xdb\x96\xba\x9f\x78\xa0\xf1\xb1\x56\x7e\x3d\x2b\xc6\xc2\x8a\x63\x87\x11\x4b\xc4\x10\xde\xba\xcf\x10\xcd\x66\x95\x50\xe6\x67\x88\x5b\x81\x6f\x52\x99\xa9\x2f\xb1\xda\x97\xf8\x95\x3c\x89\xf6\x57\xf5\x27\xb8\x0c\x63\x7c\x0d\x95\x36\x3a\x1e\x8b\x33\x5a\x51\xb5\x7a\xcb\x36\x5b\x66\x89\x90\xd5\xea\xed\xf3\x41\x90\xec\xfd\x34\x6d\x0c\xc1\xb6\x31\xa4\xc3\xa7\x4a\x6e\xfb\x12\x87\xdc\xc0\x47\xf8\xdf\x0d\x8a\x1d\xca\x57\xb6\xca\x37\xd7\xe7\xf5\x2e\xd7\x6d\xca\x63\x97\xd7\xc7\x6d\xc3\x0e\x7a\xde\x1f\x15\x6c\x87\x41\x17\xec\x83\x50\xee\x44\xe3\x38\x89\xfa\xd8\x4e\x7d\xde\x08\x55\x9b\xab\xfc\x27\xab\x7b\x99\x5e\x9f\xc3\x25\xa0\x55\x2e\x94\x1b\x69\x44\xc0\x6d\x86\x70\x70\xe1\x9c\x36\x69\xf9\x7a\x55\xd5\x55\xba\x54\x0f\x55\x1b\x00\xb1\xab\x7c\x91\xae\x4e\xd9\x93\x67\xdd\x89\xbe\xe2\x7c\x3b\xef\xca\x2b\xc5\xff\x46\xa6\xae\x6f\x24\x6e\x8e\x87\xb7\xe3\xb2\x34\x37\x7a\xf6\x44\x6d\x44\x80\x92\x2f\xff\x26\x36\xa2\x82\x3d\xaf\x2c\xf9\xff\xa7\xb2\x07\x8d\x42\xf9\x67\x38\x5f\xd9\x7a\xe5\xa1\x38\xa0\x0e\x7c\x4d\x7c\x14\xfe\x06\x9f\x27\x5c\x7f\xa8\x1b\xb4\xb4\x59\x08\x20\x34\x5e\x05\xd3\x9a\x89\x6a\x35\x26\xe0\x4d\x1f\x78\xd3\x00\xeb\x39\x7d\xcc\xaa\x6d\xcd\x96\xad\x61\x1b\x90\x96\x20\x83\x89\x09\x09\x75\x84\xf2\x92\x0f\xcd\xe2\x50\xbf\x97\xd5\xab\x97\xb3\x99\x64\xf9\x75\x17\xd8\x79\x32\xda\xbe\x10\xc1\x77\x38\x3d\x5e\x2b\x21\x5d\x68\x1f\xb8\xd7\xc6\x28\xb1\x81\x7f\x2d\x1b\x4e\xca\x49\xb1\xfe\x2f\xab\x62\x8d\xb6\x97\xe9\xb9\xc8\x5b\x96\xe9\xb6\x16\xb6\xa1\x89\xf6\xb5\x43\x7f\x03\x96\x07\xda\xb3\x05\x85\x5a\x6b\xd8\x70\x80\xfe\xce\x61\x60\xec\x32\xb7\xe7\x9c\x37\x0a\x03\x37\x0a\x38\xae\xd0\xa6\x7b\xd7\xab\xd1\xfa\xa2\x1e\x07\xea\x36\x32\x3b\xd4\xd7\x8b\xcc\x16\xfd\x0d\xc6\x97\x37\xec\x5a\x1c\x6f\x1e\x05\x87\x3e\xe9\x3f\xab\xde\x1a\x1f\x29\xe7\xa2\x47\xa6\x53\xd1\x0f\xd1\x73\x6e\x99\xf2\xd5\x62\xb3\xde\x6e\xbb\xd4\x1f\x0e\xdf\x84\x0c\x1b\x5e\x7f\x65\x93\x76\x74\xeb\xe4\x38\x6b\x06\xb9\xb3\x74\xfb\xa6\xef\xd2\x8d\x51\xcf\x66\x3d\xd3\xe5\x8e\xda\x8c\xcb\xaf\x7b\x62\xe0\x4e\xcd\xd1\xa8\xe2\xe8\x99\xf2\x6b\x61\xcb\x9f\x68\x5d\x82\x3f\xe4\xb9\x99\xc0\xdd\x80\x75\x6e\x39\x62\xfe\xd9\x93\x1d\x98\xdf\x98\x99\x5f\x3a\x98\x5f\xda\x98\xdf\x4c\x63\xde\x7e\x42\xfa\xb6\x39\x22\x5d\x94\x5e\xa6\x1e\x92\xee\x3e\x5a\x5c\xe0\xab\xd9\x55\xad\x1e\x30\xfe\xd5\xa3\xe7\x07\x32\xdd\xeb\x9d\x30\x3e\x47\x79\x79\xaa\x3b\x43\xfe\x7c\x99\x72\x4e\xae\x6a\x34\x44\x23\x73\xb7\x59\x47\x48\x8b\xa9\x3b\xb0\x7c\x5c\x29\xea\x9f\x2d\xff\xd5\xa3\xe7\xa6\x83\xe5\x5f\x6c\xaa\xf3\x25\xbb\xb7\x6b\xa1\x4a\x34\xeb\x95\xab\xd4\x9f\x7e\x6f\x45\x2b\x59\x04\xe1\xcc\x57\x70\x94\x6e\x3e\xba\x66\x4b\x66\xc7\x6c\x8b\xd1\x11\x07\x3c\x10\x12\x7e\x24\x54\xbe\xde\xcc\xda\x13\xb3\xe5\x93\xb6\x9c\x74\xb0\x5d\x56\x39\x9b\x79\x73\x44\xf6\xc6\x77\xc6\xb4\x78\xc9\x0d\xf1\x92\x39\x0a\x6c\x78\xfd\x1b\xe2\x0d\xe6\x28\xda\xb3\x5e\x38\x73\xf3\xb7\x1b\xb6\xc5\x07\x6a\x6b\xa5\x89\x59\x3e\x07\xea\x3b\xcd\x94\x16\xfe\x14\x1a\xb7\xf6\xde\xc4\xe9\xed\xca\x21\xd9\x59\x0a\x78\x0a\x0d\xd3\x70\x89\x13\x72\xdb\xe3\xe5\x3f\x53\x08\x6e\x23\xd0\x6d\x04\xe2\x0e\xd9\xce\xe1\xd8\x14\x09\xfb\x41\xb9\x85\x72\x5e\x21\xd1\x42\x8e\x6f\x91\x50\xee\x24\xb8\x1f\x92\xf9\xe0\x62\x09\xe5\x5e\x83\xfb\x61\x30\xef\x2e\x34\xb8\x1f\x46\x73\x79\xcf\xc1\xfd\x08\xbf\x7b\x35\xa7\xc1\xfb\xdd\x39\xf1\x1b\x5f\x36\xf1\x41\xaf\x84\xf8\xc7\x5e\xee\x00\x77\x77\x54\x2b\x56\xdc\xfe\x2d\x0f\x5f\xa6\x5b\xd6\xdd\xdb\x90\x6e\x99\xfa\xf0\x47\x9f\xd8\x6f\x81\xd0\x79\xfc\x55\x14\xa0\x55\x7a\xc6\xb6\xe7\x3d\x5f\x3e\xec\x71\xc3\x81\x38\x37\xe2\xbf\x7f\x7b\x67\xc0\xf5\x10\x45\x41\x7b\x31\x94\x1e\xd7\x8f\x51\xc0\x39\x02\xf6\xae\xa2\xe0\x40\x7e\xe1\x5d\xd1\xa5\x19\x0a\x7a\x41\x42\x96\x79\xaa\x5f\xd8\x16\xa5\x68\xc5\x2e\x97\xd7\x48\xf8\x64\xa1\x25\xde\x8b\x3e\xa8\x77\x09\xce\xea\xe2\x2c\x63\x9b\x77\x08\x6e\x71\x83\xbb\x89\xf8\x07\x9f\xc0\x9b\xc3\x81\xbd\xcd\x72\x7d\x09\x4d\xf8\x7f\xb5\x2d\x06\xcd\x07\xf1\x50\x03\xd2\x08\xe8\xaa\x13\x50\x13\x3c\x1a\x39\x35\xa3\xbc\x98\xdf\xf4\x88\xe7\xc3\x4b\x61\xe0\x85\x5e\xe4\x0d\xaa\xb4\xad\xd0\x61\x80\x58\x55\xbd\x44\x8d\x77\x74\xce\x79\x37\x8c\x84\xf2\x5e\x3b\xdd\x05\xbc\xf0\x9c\xf7\xfa\x08\x0d\x6e\xd3\xef\x17\x0a\x46\x8a\xfb\xb2\xaa\x2f\xab\x2d\x43\xdf\x7e\xf7\x62\x0b\x58\xdc\x7a\x6a\x2e\x1b\x92\x36\xf3\x0e\x3d\xe4\x0a\xe7\x12\xba\x07\x22\x92\x23\x51\x5a\xd6\x6c\x83\x56\xec\x34\xad\xab\xd5\xe9\x2d\xa9\x01\xd0\x31\xae\x06\xa9\x90\x83\xd5\xba\x9e\x59\x64\x7c\x78\x88\x56\x6b\x77\x3a\x0c\x17\x1b\x09\xf1\xfe\xbd\x95\xf5\x50\xc8\x12\x4e\x88\xf9\xef\x8d\xc8\xb5\x69\xaf\x94\x91\x14\x51\x63\x21\x9d\x82\x3f\xef\xb3\x38\x48\x2b\x8c\x5a\x7a\xf8\xed\x57\x8a\x96\x60\x86\x04\xb2\x80\xf3\x74\x0b\x33\x26\x13\x5d\xac\xd5\x1c\x60\xe1\x0e\xd3\x2a\xaf\x5e\x73\x22\x0d\xe6\x5b\x37\x87\x87\xdf\x7e\x75\x7b\xc6\x20\x26\xae\x3a\x53\x48\x57\xc5\x2c\x5d\xad\xeb\x05\xdb\x48\x66\xec\x86\x91\xae\x0a\xd5\x30\x78\x4f\x5d\xc6\xd1\xf9\xe1\x1d\x21\x19\xa7\x9d\xb4\x9e\x29\x1b\xfc\xc6\x16\xf3\xdd\xb3\x0f\x6f\x30\xdf\x3d\xfb\x60\xf6\xf2\xdd\xb3\xdb\x33\x97\xf5\xa6\x67\x2d\xeb\xcd\x4e\xc6\xb2\xde\xdc\xdc\x56\x7e\xdd\xd5\x56\x7e\xfd\x87\xd8\xca\x8f\xbf\x85\xb1\xfc\xf8\x01\xad\xe5\xc7\xdb\x34\x97\xab\x81\xbd\x5c\xed\x68\x30\x57\xef\x63\x31\xaf\x77\xb5\x98\xd7\xbf\xa9\xc5\xc0\x12\x05\xd5\x56\x56\xa2\xae\x2b\x5f\x4a\x97\xac\xac\x77\x49\xf5\x56\x60\x25\xe2\x1b\x5a\x97\x2d\x2e\xb8\x0e\xea\xf6\xcc\x03\xd0\xdd\x9e\x81\x00\xba\x9e\x89\xc0\x2f\x4f\x66\x24\xb4\x5b\x86\x00\x53\x8d\x63\xa5\xb5\x0c\xfe\xf6\xb5\x42\x0f\x90\x4f\x8c\x33\x7b\x8a\xf1\xcc\x3a\xeb\x79\xf0\x00\xad\x60\xc9\x40\x6b\x1e\x62\x99\x15\x41\xf7\xd0\x6a\x5c\xd0\x32\x5b\x15\x47\xa4\xb1\xbf\x77\xa8\x7d\x6d\xb3\xf3\xa4\x22\x9a\xad\xd0\x3d\xdd\xbd\xbf\x23\xea\xa3\x89\x3d\x4e\xf1\x1f\x6f\xd4\x30\x3f\xf1\x6f\x6b\xd5\xcf\x66\xb6\x37\x99\xc6\xa8\x9f\xdd\x9a\x51\x0b\x53\xe8\x1b\xb0\x62\xd3\x8d\x99\x4f\xb1\xe9\x51\x70\x05\x5c\x37\x32\x6b\xc5\x3d\x5a\x4c\x13\xec\x5a\x72\xf0\x8f\x32\xec\x67\xeb\x3a\xad\xd9\x87\x0f\xd7\x1b\xa0\x73\x7b\x96\x0d\xf8\x6e\xcf\xb2\x05\x7b\xaa\x65\x6f\xd6\x13\xa2\x35\x07\x72\x9b\xb5\xec\x18\x98\x86\x1c\x06\x56\x7b\x3c\xc7\xec\x7e\x79\x36\x8b\x82\xb1\xb1\xde\x82\xfe\x6e\x2d\x32\xfd\x1e\x15\xe8\x0c\x4c\x1c\xe6\x06\xfa\x7b\x36\xd2\xdf\x93\x9b\xea\xef\x61\x51\x7c\xf8\xbc\x3a\x2d\x8a\x0f\x96\x57\x8b\xab\xff\x6f\xeb\xad\xbd\x18\xbc\xb5\x17\x3b\xbe\xb5\x17\xd3\xdf\xda\x87\xa3\xc8\x7e\x9b\x25\xc3\xaa\x5c\x43\x6a\x9d\xa7\x9b\xcd\x35\x6f\xd7\x0c\x3c\xde\x1e\x7a\x30\x18\x8b\xbc\x3d\xf4\x1f\x08\xa3\xfb\x46\x24\xe3\xac\x6c\xbf\xcb\xe9\xd1\xbe\x20\xd2\x70\xf1\xfe\x43\x80\xfc\x6a\x9c\x41\x7a\xb8\x42\x29\x14\xa0\xd7\xa5\x5a\x90\xdd\xea\xaf\x33\xdf\xac\xcf\xd9\xa6\xbe\x46\x7f\x93\x97\x89\x03\x28\x98\x5c\x8b\x64\x54\x06\x95\x26\xb3\x3d\xd0\x22\x6a\x42\xcf\xb6\x3a\xfd\xf2\x9a\x07\xb3\x7e\x04\xda\x56\xa7\xab\xaa\xac\xf2\x74\x55\xa3\x0c\x9e\x57\x2b\xc5\x65\x80\xaa\xb5\x72\xdd\x55\xd7\x1b\x7e\x9a\x5f\x6e\xa5\x86\xad\xe1\xc2\xe2\xa9\x3d\xa9\xcd\xbe\x3b\xe7\x96\x9a\x2e\xf7\x7a\x4a\x70\xcb\x0f\x69\x63\x77\x2b\x40\x05\xef\x24\x59\xb2\x81\xc2\xdf\xcf\x8b\x2f\x55\x99\x0f\xbb\xd2\x9b\xfc\x1e\x78\xf3\xfb\xa2\x7b\x39\x46\xc0\xff\x76\xad\xca\xcf\x77\x46\x83\x29\x4e\x70\x8a\x33\xd8\xf6\x94\xe3\x02\x33\x5c\xee\x8d\xb1\xbc\xfa\x77\xeb\xef\x1c\x61\x6f\x87\x49\x0e\x30\xc2\x79\x6b\xc6\xe3\xd0\x7d\x29\xd7\x95\x40\xe0\x6c\xbe\x88\xff\xfe\xfa\xab\x76\x53\x0c\x7f\xa5\x68\xdd\xe2\x8f\x47\x48\x33\xd1\xa7\xfe\x89\x11\xbd\x81\x3f\x6a\x59\x19\x2d\xb1\x34\xbf\x0e\x0c\x51\x08\xcf\x5a\xb2\xd5\x69\xbd\x40\x9f\x21\xba\xc3\x42\xf6\x51\x18\x3a\x5e\xaf\xde\xb2\x4d\xf3\x22\xaa\xc4\x6a\x19\x3b\xf8\x58\xdf\xec\xd6\x98\x18\x96\x9a\xc1\xbe\xd5\x76\x6f\x06\xf2\x1d\x7a\xd1\x0f\xb4\x77\xb7\xa8\x48\xeb\x14\xa5\xdb\x9d\x29\xed\x50\x5e\xeb\xcf\x8a\x5e\x29\x61\xfc\xa0\x5e\xff\xe8\x13\xdb\xac\x0e\x00\xbc\xd7\x1a\x27\x49\xaf\x6f\x68\xba\x95\x4e\x0d\xe0\x13\xa1\xdc\x96\xd3\x46\xdd\xfa\x55\x4f\x42\x87\x3a\x74\xa2\xdb\xd3\xf7\x53\xf4\xe9\x3b\xf6\xe7\x75\xb3\x94\x4d\xb3\x97\xe3\x5d\x15\xfc\xaf\x61\xe3\xe0\xfc\x62\xbb\x98\x35\xa9\x18\x4f\x2f\xb4\xef\xb1\x7a\xf0\x61\x1e\x82\xb4\xeb\x92\x9b\x4c\x46\xd1\x77\x13\x64\x1a\xb4\xf3\xbe\x43\xd9\x56\xdc\x8c\xdd\x05\x50\x71\x4b\xcd\xd7\xe7\x30\xb2\x9a\xd2\x06\xe4\x4e\x83\x5b\x7f\x60\x28\x5f\xae\x57\xf6\x57\xa1\xe9\xb6\x0e\xb8\x86\x46\x0e\x3f\xda\x8c\x1c\x00\xec\x46\xae\x22\x87\x3c\x47\x70\xdd\x2e\x36\xd6\x2f\x2e\x3e\x86\x16\x7f\x02\x93\xff\x93\x10\x92\x06\x6f\x13\x7a\x05\xca\x71\x54\x6e\x16\xdf\xd9\x68\xc0\xd6\xb3\x66\x6d\x81\xc8\x6f\x4c\x94\x5a\xff\xba\xec\x3b\x97\xd3\x41\x2e\x27\x79\xc7\xa5\x74\x86\x86\xc0\xcb\xea\x95\x56\x03\x36\x13\x06\xf8\xc1\xdc\x7a\x97\x75\xdb\x16\x1a\x8d\x97\x17\xc9\xb5\x44\xef\x5e\xcd\x69\x38\x69\x81\xd0\xe1\x67\x7f\x44\x8b\xba\x3e\xdf\xde\x3f\x3c\x3c\xab\x17\xdb\x83\x8c\x1d\x5e\xd4\x25\xfd\x79\x8b\xde\x92\x03\x7c\x40\x50\x76\x8d\xfe\xe7\x59\x5a\x2f\xaa\x74\x0b\x86\xd4\x2d\x29\x82\xc5\x33\xcd\x8a\x98\xc3\x43\xf4\x15\xab\xc5\xe6\x46\xc6\xb8\x02\xaa\x34\x5b\xb2\x2d\xfa\xab\xa4\xf6\xd7\x4f\xff\xf0\x09\x6c\xb2\xd8\x30\xf6\xa8\x5d\x31\x34\x5a\x7d\x84\xee\x0a\x85\xde\x45\x77\xee\x34\x3f\x7f\x6e\xa3\x80\xfe\x2a\x7a\xa5\xe2\x7f\x0a\xbf\x74\xe8\xcf\xe4\xf7\x3e\x76\xf9\xeb\x9d\x3b\xba\x55\x4d\x47\x3d\x46\x5b\x68\x07\x2b\xa7\xb0\xd4\xe8\xaf\x73\xb1\x53\xe2\xdb\x75\xc1\x0e\x7e\xde\xa2\xf5\x06\x7d\x29\xd6\x1e\x55\x65\xc5\x0a\x94\xaf\x0b\x36\x17\x68\xd2\x55\x81\x2e\xb6\x0c\x55\x35\x1f\x17\xff\xca\x25\xaa\x76\x44\x2e\x5d\x6a\x3b\x72\x2a\xbf\xf7\x3b\x22\x7e\xfd\x5c\x2e\xe8\xea\xda\x1d\xb4\xe0\x47\x2a\xb6\x5f\x7f\x55\xbe\x1d\x5c\x56\xab\x82\xbf\xcf\xf6\x60\xe4\x9a\x2b\xce\x0e\x52\x7f\x97\x0b\xa4\x38\xef\x9f\xdd\xbb\xb5\x3f\x6e\x56\xb2\xd3\xdb\x7a\x53\xad\x4e\x1f\x6f\xd6\x67\xc7\x8b\x74\x73\xbc\x2e\xb8\x16\x9f\xc3\x8f\x07\xa5\xf2\x6b\xab\x87\x17\xe9\x1b\xb6\x12\xe2\x1e\xda\xf1\xf9\xc5\xea\x9a\x8b\xfa\xd3\x3f\x7c\xd2\x46\xbb\x8b\x7c\x4b\x0a\xc6\x7f\x9d\x09\x52\xb2\xa7\x30\x93\x0b\x3b\x23\xda\x21\x14\x7e\xcb\xd7\x17\xab\x9a\x6d\x9a\x32\x2b\xfc\xb6\x6c\x62\x8a\xc0\xa0\x04\x15\x78\x0c\xfb\x55\xdb\x6f\xec\xaa\xde\xa4\xf0\xed\x72\x51\x2d\x19\x9a\x35\x18\x1f\x48\x3c\x92\x81\x4f\xa0\x59\x87\x34\x97\x1d\x7d\x58\x37\x2d\xf6\xf7\x21\x1e\x7c\x02\x4a\x16\xd0\x5f\x1c\x21\xef\xea\x2b\xea\x79\xdc\x0a\xc4\x4f\x0f\xe0\xa7\x2f\x1f\x3f\xe6\x3f\x99\x68\x71\xc1\x41\xc1\x60\x7b\xb1\xd9\xac\x4f\xd3\x9a\xcd\xc1\x12\xeb\x05\xdb\x30\xd8\xcd\x8b\x56\xec\xaa\x46\x9c\x89\x34\xaf\xd9\x46\xb4\x82\xbe\x4c\x62\x11\x78\x9c\x09\xf8\x3b\xc8\xbb\x7a\x7c\xec\x79\x7b\xdc\x6c\xbd\xab\xaf\xe0\xe3\xdf\x78\x34\x5f\xae\x2f\x3b\x0e\x44\xbb\x4f\x84\x12\x44\x46\x30\x93\xdd\xe4\x18\xfc\xc7\x8f\xf7\x60\x03\xae\xb7\x87\xf6\x91\x82\x1a\x1e\xec\x37\x07\x59\x35\xf4\x95\x2c\x5b\xf6\xf7\x62\x75\x96\xd6\xf9\x82\x15\x1d\xc9\xcf\xd1\x7a\xb5\xbc\x46\xe9\xf9\x39\x83\xce\x57\x5b\x70\x4d\x74\xb1\xaa\xea\x39\x7f\xbd\xcd\xd3\x2d\x83\x77\x5c\x2e\x8d\x0e\x55\x0b\xc4\x45\x55\x37\x6b\xc9\x5a\xb4\x3c\x5b\x48\x95\xaf\xe7\x69\xb5\xd1\xf4\x0e\xfa\xd6\xf0\xfb\x89\x94\xe0\xbd\x7b\x4d\x07\xe0\x3f\xfd\x6e\x98\x5a\x03\x2c\xfc\x23\x07\x08\x01\xa8\x38\xeb\x8d\xfc\x84\xad\xc0\x4f\x60\x24\x57\xdc\xa4\x35\x7f\x91\x07\x0d\xac\xbf\x5a\x15\xec\x0a\x1d\xa1\x7b\xd8\xe0\x10\xad\x97\xdd\xbd\xab\xba\xc5\xfe\xbe\x68\x69\x72\x0b\x20\xf6\x12\x60\x5e\x8d\xdc\x80\x5b\xd8\x63\x6e\x07\x52\x50\xe2\xe7\x7b\x47\x8d\x55\x7c\xae\xca\x0f\xed\x1f\x69\xc2\x4c\x83\xea\x8b\x2f\x10\xf6\x1a\xc3\x42\xbf\x4a\xff\x6a\xd4\xd4\x70\x23\xcc\x18\xfd\x8a\x7a\x06\xaa\x68\x63\x02\x2d\x81\xd3\xa6\xb6\x56\x1b\xf9\x82\xe5\x6f\x9e\xe7\xe9\x32\xdd\xfc\x6f\xde\x74\xc6\x15\xf3\xfd\xba\x5a\xc9\xd5\xed\x20\x8b\xf6\xb7\x7e\x58\xe8\x7e\x16\xa1\x41\x91\x53\xbd\xd8\xac\x2f\xd1\xa3\xcd\x66\xbd\x99\x89\xfe\xdd\x7d\xc2\xf3\xab\xce\x74\xff\xb2\x7f\x17\xed\x77\x28\x0e\xea\xb5\x88\xc5\x33\x1c\xed\x1d\xd4\xeb\xbf\x9c\x9f\xb3\xcd\x71\xba\x65\xb3\x3d\xb4\x2f\x31\x70\x9f\x58\xad\x6b\xee\x01\xc0\xb0\x10\xd1\x5d\x78\xda\x75\xf9\xdd\x87\x19\x42\x3a\x89\x41\xfe\xce\xf3\xfe\x4e\x2e\x73\x31\x9b\xd8\x8c\x6d\x42\xe6\x1a\xed\xcc\x54\x51\x7e\xd1\x34\x12\x3a\x86\xd2\xea\x15\xf5\xf6\x34\x5a\x12\xfe\x72\xdc\xb4\xd5\x2a\x49\x41\x7d\x47\x5a\xed\xe3\xc7\x54\xc6\x46\x19\x16\xf1\xbd\xec\xba\x66\x68\xcb\xfe\xfb\x82\xad\x72\x11\x18\xcd\xdc\x76\x54\x3a\x7b\x82\x91\xf4\xfa\x2c\x5b\x2f\x3b\x3f\x33\x51\xa7\x5e\x9f\x3a\xd1\x50\x6f\x71\xb9\xa5\x15\x09\x49\x61\x29\xa9\x63\x4f\x61\xab\x5d\xfc\xad\xe1\x03\x82\xb7\xca\x87\xaf\xe1\xc3\xe2\x07\x9f\xef\xca\x28\x26\x82\x53\x4f\x72\xfa\xc8\xeb\xe3\xd8\x3f\x32\x18\x51\x34\xa9\x47\x8f\xbc\x51\x8f\x82\xf7\x93\x2c\xa6\x92\xe1\x58\x30\xfc\x78\x2a\xc3\x98\xdc\xa0\x67\x1d\xac\x8e\xb3\x7e\x6f\x07\x6e\xd1\x1a\x2b\xa0\xd0\x38\x0a\x7f\xc1\x90\x83\xcb\x28\x09\x6b\x31\xf3\xb7\x83\x71\xb6\x36\x4e\xc2\xba\x06\x13\x86\xa2\x16\xb8\xfd\x85\xab\x44\xc4\xb4\xc9\x43\x52\xd7\x79\x95\x7a\x6f\x6c\x52\xb0\xee\x1f\x59\x02\xc3\x68\x08\xe8\x1a\x7e\xd0\x54\xbb\x55\xc5\x86\xa5\xc5\xf1\x7a\x55\x57\xab\x0b\xd8\x3e\x0d\x26\xa1\xc4\x2b\xce\xcf\xd7\x20\x85\x2f\x8e\x80\xb9\x63\x9e\xa7\xe8\x06\x90\xbb\x5f\xaf\xde\xa6\xcb\xaa\x00\x28\x21\xfb\xbb\x6d\xff\x3a\xf9\xf7\x49\x21\x81\x14\x4a\x17\x2f\x5b\x5a\xaf\xa4\x0f\x41\xeb\xf6\xd7\xfd\x7d\x91\xf4\x37\x91\x6c\x80\xe9\x8e\x88\x36\x22\xc9\xe4\x11\xf5\x6f\x6a\xe0\xd4\x82\xfb\x8f\x55\xfe\x0e\x0f\xd1\xd7\x25\xba\x64\x88\x27\x83\x17\xe7\x88\xe7\xc2\x73\x54\xd5\xff\xef\xff\xfc\xdf\x66\x44\x53\xb1\x00\xe3\xbc\x9d\x56\x08\x23\xc8\xbb\xba\x11\x43\xd8\xf6\x73\xf0\x93\x99\xe2\x04\xbc\x01\xee\x99\x28\xe9\x7d\xf3\x7b\xdf\x02\xad\x79\x6b\x34\xf8\x9e\x0a\xec\x63\x3b\xd2\xd8\x83\x14\x76\x99\x2e\xc5\x5e\x15\x45\xb4\xcf\x58\x5a\xa0\xb2\xda\x6c\xeb\x56\x70\xd0\xcb\x1b\x59\xc0\x78\x90\x44\xb3\xd5\x7a\x2c\xf4\xed\x5e\x6b\x2f\x82\xd8\x1d\x69\x1b\x32\x2a\xab\x4c\x77\x32\xef\x98\xd6\x8c\x85\x03\x64\x8f\x1a\x8b\x3b\x6e\xf1\x81\xba\xd0\x91\xc1\xb5\x3e\x1f\x85\x10\x15\x1d\x16\x2f\x39\x70\xba\x53\xa7\x76\x5d\x7a\xd7\x59\x78\x67\xe2\x6a\x6c\x1b\xbc\x3a\xec\x62\xa4\xdd\x0b\x85\x14\x83\x3f\x94\xf5\x59\x7a\x8d\xaa\x55\xbe\xbc\x80\xf7\x20\xfe\x7e\xa3\xbe\x56\x69\xa5\xfe\xb8\x11\xd4\xa3\x9d\x04\x05\xd6\x7e\x43\x61\x7a\xf2\x8d\x91\xc0\x02\x2f\x41\x4d\x15\xae\x6f\x14\xae\x07\x49\x91\x14\x9d\x33\xe9\xf8\xf0\x0a\xd0\x64\x0e\x43\xf1\x52\x29\xde\xc7\xb7\x2e\x5e\x08\x31\x37\x55\x41\x0c\x2a\xf0\xae\x86\x4a\xf0\xae\xbc\xe3\x3d\xf4\xab\x90\xcd\x4c\xb0\x21\x7e\x6e\xd5\x13\x98\xd5\x03\x2f\x75\x9a\x97\x1b\xec\xf5\x5e\x03\x0d\x7a\x51\x64\xab\xd5\xca\x5f\x5e\x3c\xbe\x47\x51\x01\x05\x3e\x56\xa8\x81\xbb\x89\xb8\xcd\x16\xbb\xf6\x07\x88\x82\xea\x0f\x10\xaf\x3e\x1f\x26\x3d\x32\x97\xe9\x06\x79\xc9\x6a\x8b\xb3\x9f\xf3\x28\x70\x6d\x20\x04\x4a\x6a\xd0\x54\xb3\x1e\x25\x3a\x2b\xf5\xaa\x5e\x4a\xa5\xd4\xb6\xea\xb3\x73\x35\xdd\x99\xd5\x67\xe7\xe8\x68\x30\x26\xed\xa1\x3f\x1e\x1d\x89\x80\x3e\x4a\x7f\xe4\xbc\x4d\x7d\x76\x3e\xce\x63\x94\xfa\x41\x07\xbf\xf7\xc1\xcb\x87\x5c\xc8\xe8\x48\x30\x7a\xf7\x2d\xdb\x6c\xab\xf5\xea\xee\x7d\x74\x17\x4a\xd9\x77\xe7\xf0\xb3\x60\xeb\xee\x7d\x25\x0d\x15\x0f\x44\xcf\xe5\x03\xf1\x85\xf3\xdb\x96\x1a\x9f\xaf\xcf\x18\x7a\xf8\xf4\x2b\x94\x5d\x54\xcb\x02\xad\xcf\xeb\xea\xac\xfa\x85\x6d\xb6\x73\xb4\xac\xde\x30\xb4\x39\xf8\x79\x3b\x17\xef\xea\x30\xa5\xb0\x3d\x67\x79\x55\x56\x39\x77\xf3\xa2\x02\x23\x38\x4f\xeb\x9a\x6d\x56\x5b\x81\x10\x5a\xd5\x0b\x86\xca\xf5\x72\xb9\xbe\xac\x56\xa7\xf7\x65\x0d\x17\x6c\x73\xb0\x43\x16\xdd\x6d\x6c\xe9\xae\xac\x59\xf7\x20\x0e\xd2\xb3\x62\x50\x18\xfe\xb4\xdd\x2c\xcb\x1f\x7e\xfa\x87\x4f\xa4\x0a\xe5\x06\xda\xb6\x8e\x3f\x18\x09\x79\xf7\x85\x42\x85\xc2\xba\xb7\x9c\x41\x49\xfc\x8f\xca\xf7\x83\xd5\xba\x60\x2f\xae\xcf\x99\x92\x3c\x76\xa5\x78\xf9\x06\x54\xad\xd4\x9a\xf8\xb3\x6a\x75\xba\xfe\x5f\xcf\xd1\x5b\xef\x80\x1e\x78\xa2\x7e\xd0\x35\x51\x36\x18\x77\x0c\xc9\x90\xda\xe0\x4a\x37\x97\x8b\x74\x39\xc0\x15\x1f\x78\xf7\x64\xe9\x68\xd3\x2c\x38\x93\xdb\x58\xe5\x8f\x8b\x74\xfb\xdd\xe5\xea\xfb\x66\x15\xd1\x91\x84\x3a\xe8\xff\x2e\xe0\xdb\xb9\x21\x38\xe7\x50\x08\xa7\x0d\x30\xfd\x06\x62\x82\x8c\x03\xc0\x7e\xf3\x3d\x2e\x22\x55\x64\x2f\xdf\x88\x13\x38\x39\x04\x7c\x1e\x96\xef\x06\xdd\x7b\xb6\xa8\x56\x6b\xde\xb9\x14\x5d\xb2\x0c\xc9\xed\xcb\x9f\xca\xba\xfc\x81\xb4\xf5\x46\x38\xe0\x57\x62\xe7\xb2\x9c\x30\x7a\x37\xff\xdb\xbb\x57\x73\x1a\x4d\x9a\x08\x1a\xed\xea\xfe\xf1\xe9\x93\x93\xba\x3e\x7f\xc6\xc7\x9c\x6d\xad\x20\xfc\x53\x56\x9d\x8a\x65\x41\x07\x3f\x6f\xff\x34\x09\xf9\xdd\x8b\x2d\x83\xf7\xc8\xbc\xbe\x0b\x98\x46\xd4\xbe\xac\x4e\xbf\x05\x9c\x9f\xf3\xce\xff\xbc\x5d\xf0\x98\x5e\x9d\xae\xd6\x1b\x76\x7f\x59\xad\x98\x98\x00\x93\x0c\x5c\xb2\xcc\x9f\x46\x98\x2b\xee\x07\x96\x89\x21\x4e\xec\x49\xbf\x7b\x70\xb8\xac\xb2\x43\x8e\xe3\xae\x90\xd3\xe1\x21\x2a\xd6\xab\x1a\xad\xdf\xb2\xcd\xa6\x2a\x58\x33\xcb\xd2\x4c\xeb\x7c\xfa\x07\x65\xc3\xba\x9c\x2e\xe1\x51\xf1\x6e\xbb\x22\x04\x66\x61\x7a\x00\x07\x82\x6a\x1f\x0a\xec\x06\xa6\x0d\x55\x18\x60\xf0\xf3\x4f\xff\xf0\x4e\x2b\x18\xf9\xb0\x99\xe1\x6b\x58\xff\xd3\x7d\x42\xde\xbd\xe2\xf2\x98\xbf\x14\xf2\x78\xb5\xc7\x7b\xf2\x3f\xd0\x76\x7d\xb1\xc9\xd9\xd3\xf4\xfc\xbc\x5a\x9d\xfe\xe5\xd9\x93\x23\xfe\xf4\xde\x12\x16\xf3\xfe\xbc\x3d\x38\x4b\xcf\x3f\xfd\xc3\xff\x0f\x00\x00\xff\xff\xf8\x06\xcd\x97\x2b\x5f\x06\x00") +var _web3Js = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x7b\xdb\x36\xd2\x38\x0e\xbf\xf7\xa7\x80\xf5\xdc\x4f\x24\xc5\x8a\x24\xdb\x69\x9a\xca\x75\xb3\x8e\x93\x36\xde\xbb\x89\x73\x25\xf1\x76\xf7\xf6\x7a\x73\xd1\x22\x24\xb1\xa1\x48\xfd\x48\xca\x87\xc6\xfe\xee\xff\x0b\x83\xd3\xe0\xc0\x83\x6c\xa7\x69\xbb\xf6\x8b\x44\x04\x06\xa7\xc1\x60\x30\x18\x0c\x66\x32\xfa\xff\x96\x51\x46\x77\x3b\x93\x65\x32\x2e\xa2\x34\x21\xb4\x53\xf4\x92\x5e\xd6\xfd\xac\x52\xf2\x4e\xda\x5b\x76\x3f\x47\x93\xce\x7a\x72\x9c\x9e\xf0\x5f\x05\xfc\x3a\x0b\x32\x12\xec\x16\x97\x0b\x9a\x4e\x88\xac\x6b\xb7\x25\x8b\xb6\x1e\x3c\x10\x89\x3b\xac\xcc\xf2\xc1\x83\xa0\x9b\xd1\x62\x99\x25\x24\xe8\xa4\xbd\xf5\x61\x97\xa5\x47\x32\x2d\x12\x69\xac\xd6\xc9\x6e\x42\xcf\xc9\xcb\x2c\x4b\xb3\x4e\x6b\x3f\x48\x92\xb4\x20\x93\x28\x09\xc9\x3c\x0d\x97\x31\x25\xed\xd6\x46\xba\xd1\x6a\xb7\xba\x3b\xc5\x2c\x4b\xcf\xc9\xa4\x3f\x4e\x43\xba\xdb\x7a\x7d\xf8\xe2\xe8\xe7\x97\x1f\xdf\x1c\x7e\xf8\xf8\xe3\xe1\xd1\x9b\x17\xad\xde\xe4\x9a\xd5\x17\xef\xb2\xbe\xef\x7e\xa6\x17\x8b\x34\x2b\xf2\xd1\xe7\xeb\xeb\x1d\x36\x86\xe3\xe1\x49\x7f\x1c\xc4\x71\x27\xee\x8b\xac\x9e\xec\x7d\x87\xf2\x01\x26\xbb\x00\xb8\x79\x72\x4c\x4f\x76\x44\x57\xf3\x4e\xf2\x2c\x19\xd1\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\x1d\xee\xa4\xdf\x67\xfd\x98\x26\xd3\x62\xb6\x93\x6e\x6c\x74\xf3\x4e\xc6\x10\xaf\xba\x71\xdd\xed\x7c\xde\x1c\x1d\xab\x2e\x8b\x2a\x7a\x1c\x4b\x3d\xd1\x76\xf7\xf3\x1a\x4f\x90\x9d\xd9\x3d\x5e\x23\xe4\xf3\x1a\x21\x84\xb4\xc6\x69\x92\x17\x41\x52\xb4\x46\xa4\xc8\x96\xb4\xc7\x53\xa3\x64\xb1\x2c\xf2\xd6\x88\x1c\xc3\xb7\x84\x86\xbc\x24\x98\xd3\xd6\x88\xb4\x3e\xa6\xe7\x09\xcd\x5a\x3d\x9d\xc3\x46\xc7\x72\x82\x30\xcc\x68\x9e\xb7\x44\xce\x35\xfc\x7f\x22\xaa\x96\xc5\xe1\x7f\x91\x96\x2e\x8b\xfa\xf6\xd2\x8f\xa8\x88\xd1\xde\xe9\x65\x41\xf3\xed\x2d\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\xef\x37\xf4\x8c\xe6\x34\x3b\xf3\xad\xfa\x3f\xfa\xa4\xe5\xcb\xd3\x77\x74\x1a\xe5\x45\x16\xfc\x17\x4c\x5e\xaf\xaa\x0e\x7a\x7e\x78\x2b\xbe\x5f\x64\x41\x92\x4f\xbc\xac\xef\xcf\x82\x83\xcc\x22\x85\xd5\x91\x90\xd3\xe2\x7d\x35\x49\xdd\x19\x2e\xec\xa6\x7f\x97\x46\xbf\xf0\x04\x04\x4d\x10\x5f\x55\xc1\x22\x8b\xe6\x41\x76\xe9\xed\x47\x9a\xc6\xb5\x93\xb7\x27\xda\xfa\xf3\xa2\xd0\xdc\x83\x2b\xab\x29\x43\xc2\x7e\xe9\x36\xfe\x47\x42\x82\xb7\xf7\x61\x94\xa7\xe7\xc9\x2d\x7a\x1e\x24\x69\x72\x39\x4f\x97\xf9\x0a\x5d\x8f\x92\x90\x5e\xd0\xd0\xd8\xbb\xee\x6c\x62\x75\xe5\xa8\x3b\x66\xed\xe7\x51\x72\x1b\xc6\xbd\xb7\x04\x4c\xbc\x4c\x42\x1a\xb6\x2c\x34\xd1\x33\x46\x08\x7f\x01\x1c\x9d\x46\x61\xd8\x0c\x47\x37\xab\xff\x2c\x88\x97\xde\xee\x2f\xa3\xa4\xd8\xfa\xe6\x49\xf5\x14\xbc\xa1\xe7\xcf\xa3\xaf\x88\xfc\x5b\xad\xb9\xfd\x59\x90\x4c\xbf\x26\xe9\xdc\x09\xe5\x94\xd4\x8d\xa4\xfa\x4a\xaa\xf1\x62\xe6\x2d\xdf\x8d\x6a\x11\xb4\x76\xb2\xb6\x76\xdd\xfb\x7c\x7d\xd2\xdb\xfa\x6a\x87\xfe\xbf\xd0\x99\xf7\x2b\xc9\x8e\x93\x65\x12\xde\x98\x54\x6e\xbd\x71\xdd\x1f\x7b\xff\xdc\xc7\xde\xfb\x43\xdf\x1f\xf9\xcc\xe1\x1d\xbc\x38\x2f\xfc\xd1\xa4\xcd\x2f\xbb\x99\xeb\xbd\x6a\xfb\xce\xf6\xaa\x55\xe7\x7d\x92\xa5\xf3\x5b\x4e\x7b\x91\xde\xf2\xa8\x79\x3b\x81\xef\xeb\xae\x9b\x3f\x02\xfe\xa2\x24\x8c\x32\x3a\x2e\x0e\xbc\x7b\xe6\x0a\x3d\xb9\xdd\x44\x44\xe3\x60\xf1\xe1\xab\x4e\x86\x1f\x93\xcd\x4e\xbb\x74\x91\xe6\x51\xd5\x41\x7d\x11\x5c\x06\xa7\x31\x35\x85\x82\xaf\xc2\x95\xca\x68\xee\x4e\x8e\x5f\xb7\xa3\x81\x3d\x39\xde\x17\x26\x3e\x7f\xff\x93\xcc\x9d\x20\xa9\xa4\xee\x66\x74\xf6\x15\xd0\xff\x87\xc5\xfa\x5d\x9c\x1f\x6f\xcc\x27\xbf\x34\xd6\x6d\xa6\x77\x8f\xf6\x86\x68\xbf\xf5\xc6\xf5\xa5\x67\xf6\xc0\xb3\xa5\x55\xc9\x71\x8f\x9b\xc8\x71\x60\xbc\x41\x76\xa5\x85\x43\xa7\xdd\x1f\x4c\xd2\x6c\x1e\x14\x05\xcd\xf2\x76\x77\x07\x00\xde\xa7\x71\x14\x46\xc5\xe5\x87\xcb\x05\x35\x61\x59\xfb\x0c\x6a\x6d\xf0\xf0\xe1\x1a\x79\x68\x40\x0a\x9d\x3b\x89\x72\x12\x90\x45\x96\xa6\x0c\x98\x14\xb3\xa0\x20\x19\x5d\xb0\x43\x56\x52\xe4\x44\xcc\x1d\x61\x99\xac\x86\x83\x82\xcc\x83\x62\x3c\xa3\xf9\x88\x7d\x8a\x6c\xf4\xf3\xf8\x04\x7f\x3c\x36\xbe\x4e\xcc\xcc\x6d\xeb\xfb\xe4\xf8\xc9\xc9\xf1\x49\x8f\xf4\xfb\xfd\x35\xf2\x70\xe0\x8c\x4d\xf6\x78\x97\x28\x6b\x9a\x4e\x57\x4c\x71\x31\x8b\xf2\xfe\x47\x58\x18\x3f\x4a\x04\x31\xc0\x3e\x47\xd7\x01\xcb\x38\x48\x8a\x1d\x04\xcc\xf7\x6d\x1f\xf4\x21\xe4\x88\xe6\x76\xd6\xae\x77\xd6\xd6\x3c\xfd\xe8\x2f\xb2\xb4\xe0\x58\xdb\x25\x09\x3d\x37\xfa\xda\xf9\x7c\xdd\xdd\xa9\x2e\xd5\x07\xe9\x25\x5b\x8e\x8b\x94\x35\xee\x81\xad\x6b\xb7\x1f\xe5\x62\xce\x35\x42\x18\x39\x4a\xa4\x08\xbb\x96\xf5\x75\x96\xd8\x87\x79\xeb\x0c\x04\xb6\x3b\xff\x3e\xee\x1c\x0f\x1f\x7d\x77\xf2\xb0\xfb\xef\x93\xee\xb3\x41\x97\x8f\xd3\x3c\x38\x94\x76\xeb\xba\xf7\xb9\x85\x49\xb1\x35\xfa\xae\xd7\xe2\xf4\xd6\x1a\x6d\x3e\xbe\x3e\xe9\x7d\xf3\x95\xc9\xfb\x79\x9a\xc6\x35\xb4\x7d\xca\x40\x4a\x08\x9b\xe5\xc9\xff\x39\x95\xc2\xaf\xc7\xfa\xe7\x09\x4a\xde\xc6\x1f\x75\x64\x0c\x3d\xbb\x29\x0d\xb3\xc2\xab\x10\x31\x87\xb7\x29\x98\xa5\xae\x48\xbe\x66\x91\x0a\xda\xe5\x2d\x56\x95\xbd\x09\xd5\xfe\x87\xa1\xd6\xa4\xd9\x87\xff\xd3\x88\x68\x45\x7f\xea\x29\xf6\xc9\xd7\xa6\x58\xb6\x87\x29\x92\x2d\xfc\x34\x5b\xcc\x28\x81\xcd\x0e\x08\xb7\xef\xa3\x5c\x96\xab\x7e\x08\xba\x84\x9f\x8f\xd1\xef\x13\x9c\xb1\x6d\x7c\x99\xf4\x4b\xc4\xd6\xaa\x7e\x3e\x35\xea\x11\x45\x3d\x54\x0e\x9d\xbc\x31\x99\xb3\xd2\x2b\xd1\x39\x2f\xe0\x10\x3a\x4b\x5e\x95\xd2\xcd\x32\x55\xa4\xce\x1b\xad\x2c\x7d\x33\x62\x67\x95\x70\x52\xff\xbc\xd9\xbb\xee\xde\x8c\xf0\x45\xef\xea\x29\xff\xdb\x26\x94\x3f\x78\x08\x1d\xfe\x30\x8b\x72\x32\x89\x62\xca\x28\x75\x11\x64\x05\x49\x27\xe4\x9c\x9e\x6e\xf7\x7f\xcd\xfb\x6b\x00\x22\xbe\x18\xc0\x24\xa3\x94\xe4\xe9\xa4\x38\x0f\x32\x3a\x22\x97\xe9\x92\x8c\x83\x84\x64\x34\x8c\xf2\x22\x8b\x4e\x97\x05\x25\x51\x41\x82\x24\x1c\xa4\x19\x99\xa7\x61\x34\xb9\x84\x3a\xa2\x82\x2c\x93\x90\x66\x40\xf0\x05\xcd\xe6\x39\x6b\x87\x7d\xfc\xf4\xe6\x88\xfc\x4c\xf3\x9c\x66\xe4\x27\x9a\xd0\x2c\x88\xc9\xdb\xe5\x69\x1c\x8d\xc9\xcf\xd1\x98\x26\x39\x25\x41\x4e\x16\x2c\x25\x9f\xd1\x90\x9c\x5e\x0a\x2a\xa2\xe4\x47\xd6\x99\xf7\xa2\x33\xe4\xc7\x74\x99\x84\x01\x1b\x73\x8f\xd0\xa8\x98\xd1\x8c\x9c\xd1\x2c\x67\x33\xb4\x2d\xdb\x12\x35\xf6\x48\x9a\x41\x2d\x9d\xa0\x60\x63\xc8\x48\xba\x60\x05\xbb\x24\x48\x2e\x49\x1c\x14\xba\xac\x8b\x02\x3d\xd2\x90\x44\x09\x54\x3b\x4b\xe5\xca\x8e\x0a\x72\x1e\xc5\x31\x39\xa5\x64\x99\xd3\xc9\x32\xe6\x82\xe3\xe9\xb2\x20\xbf\x1c\x7c\x78\x75\x78\xf4\x81\xec\xbd\xf9\x17\xf9\x65\xef\xdd\xbb\xbd\x37\x1f\xfe\xb5\x43\xce\xa3\x62\x96\x2e\x0b\xc2\x24\x4a\xa8\x2b\x9a\x2f\xe2\x88\x86\xe4\x3c\xc8\xb2\x20\x29\x2e\x49\x3a\x81\x2a\x5e\xbf\x7c\xb7\xff\x6a\xef\xcd\x87\xbd\xe7\x07\x3f\x1f\x7c\xf8\x17\x49\x33\xf2\xe3\xc1\x87\x37\x2f\xdf\xbf\x27\x3f\x1e\xbe\x23\x7b\xe4\xed\xde\xbb\x0f\x07\xfb\x47\x3f\xef\xbd\x23\x6f\x8f\xde\xbd\x3d\x7c\xff\xb2\x4f\xc8\x7b\xca\x3a\x46\xa1\x86\x7a\x44\x4f\x60\xce\x32\x4a\x42\x5a\x04\x51\x2c\xe7\xff\x5f\xe9\x92\xe4\xb3\x74\x19\x87\x64\x16\x9c\x51\x92\xd1\x31\x8d\xce\x68\x48\x02\x32\x4e\x17\x97\x8d\x27\x12\x2a\x0b\xe2\x34\x99\xc2\xb0\x15\x95\x11\x72\x30\x21\x49\x5a\xf4\x48\x4e\x29\xf9\x7e\x56\x14\x8b\xd1\x60\x70\x7e\x7e\xde\x9f\x26\xcb\x7e\x9a\x4d\x07\x31\xaf\x20\x1f\xfc\xd0\x5f\x7b\x38\x90\xcc\xf6\x6f\x40\xb6\xe3\x34\xa4\x59\xff\x57\x60\x91\x7f\x0b\x96\xc5\x2c\xcd\xc8\xeb\x20\xa3\x9f\xc8\xff\xa6\x05\x3d\x8f\xc6\xbf\x91\xef\xe7\xec\xfb\x6f\xb4\x98\x85\xf4\xac\x3f\x4e\xe7\x3f\x00\x70\x18\x14\x94\x6c\x0d\x37\xbf\x01\x86\x57\xbf\x15\x54\x08\xb0\xa8\x8c\x90\xc7\x7c\x7b\x87\x90\x14\x10\x30\xdb\x05\x7d\x90\x07\x49\x61\x02\x46\x49\xe1\x83\x3b\x72\x00\x97\x25\x90\x2f\x2e\x93\x60\x1e\x8d\x25\x1b\x47\x25\x42\x9e\x03\x3c\xca\x57\xf2\x7d\x91\x45\xc9\xd4\x2c\x93\x43\x9a\x0f\xfa\x1d\x0d\xac\x31\x66\x34\xf0\x8e\xf1\xc8\x05\x5d\x96\xc1\x7a\xba\xad\xfa\x0b\xc0\x51\x2e\x06\x68\x70\xe6\x1c\x55\xd1\x83\x1d\x56\xf0\x69\x69\x21\x8e\xf2\xfb\xaa\x0a\xd8\x46\x38\xf0\xd5\x95\x3a\x3d\x92\x12\xe8\xbd\x2c\x0b\x2e\x39\x38\x67\xe2\x96\x28\xb0\xcf\xe8\x13\x49\x00\x62\x25\x71\x0e\x11\x92\x22\x25\x34\x61\x34\x3c\x08\x29\xfb\x4f\xb5\xc2\x98\x71\xc0\xd9\x24\xe3\x4a\x42\xae\x35\x37\x66\x5e\x37\x1e\x31\x03\xcb\xcd\x9d\x19\x92\xc8\x2e\xd4\x90\x1b\x5d\x04\xde\x3f\xa7\xc5\x2c\x0d\x3d\xdd\xe2\xca\xf5\x34\x9b\x13\x2e\xb9\xa4\xc6\x8c\xac\x11\xbe\x06\x45\xf1\x8f\x62\x66\x44\x16\xf9\x1b\xf4\x9e\x7c\xe6\xc4\x73\xad\xc4\xf2\xbf\x71\xcc\xe7\xe4\x33\xae\xec\x1a\xb2\xe0\xad\x42\x4e\x3e\xc3\xbb\x86\x6b\x22\x3e\x23\xc6\x1b\xb8\x44\xc4\xc8\x10\xfa\xc2\x76\x22\xc6\xee\x01\x21\x06\x32\xd0\x4e\x8d\xbb\xe4\xe0\x48\xa2\x88\x61\x33\x37\xc5\x3b\x84\xb5\xfe\x24\x8a\x0b\x9a\x75\x50\xd9\x2e\xd2\x41\x08\x2a\x2a\x84\x50\x20\x89\x00\x74\x0a\xdd\xe3\xe1\xc9\x0e\xe7\x9f\xd1\x84\x74\xd6\x71\x23\xb8\x0e\xfe\x40\x83\x3f\xe5\x68\x47\xc9\x59\x10\x47\xa1\xa6\x01\x56\xe3\xfa\x88\xb4\xc9\x06\xc1\x95\xaf\x61\x59\x03\xd7\x6c\x52\x60\x09\xa5\x91\x45\x1c\x44\x09\xa7\x2f\x6b\x1a\x39\xc0\x5b\x91\x53\x3e\x8b\x22\xfd\xf0\xf4\x57\x3a\x2e\xae\xad\x0a\xe5\x24\xeb\x72\xbc\xda\xd0\x82\x2b\x9f\x3a\xd4\x0d\x67\xe6\x7a\xbc\xbc\x25\x70\xc1\xa4\xa1\x62\x79\xe7\x98\x01\x9f\xf4\xc8\x31\x80\x9f\x74\x9b\xa1\x26\x8e\x72\x90\x80\xf8\xe2\x2b\xc7\x4e\x8e\xd1\x00\x2c\x80\x63\xc7\x97\xbe\xd0\x05\xca\x10\xe3\x34\xdb\x08\x37\xb9\xbb\xf4\x05\x76\xf2\x32\xfa\xce\x25\x81\x4f\x69\x81\x57\x60\x2e\x38\x87\x20\x59\x56\x4c\xf4\x8d\x95\x30\x6a\xe8\xcf\x83\x45\xa7\x8c\xc7\x82\x56\xce\xb3\x46\x0c\xde\xc9\x6b\xee\xf0\x9e\x1e\x43\x91\x13\xce\x9e\xe5\x97\x5a\x45\xa8\x3f\x62\x9f\x3a\x9c\x4c\x72\x5a\x38\x9d\xca\x68\xb8\x1c\x53\xd4\xaf\x60\x3c\xee\x91\x9a\xce\x01\x76\x8a\xa0\x88\xc6\x6f\x83\xac\xf8\x19\x5e\x12\x59\x35\xf7\xed\xfc\x8e\xa7\x9f\xb2\xae\x8c\x31\x25\x1a\xbe\x77\xab\x7c\x1d\x14\xb3\xfe\x24\x4e\xd3\xac\xd3\x71\x5a\xdc\x20\xdb\x9b\x5d\x32\x20\xdb\x5b\x5d\xf2\x90\x6c\x6f\x89\x41\x23\xf4\x05\xe3\x31\xd9\x20\x1d\xb5\xe9\x18\x58\x2f\x41\x21\x79\x86\xf6\x2e\x42\xb6\xb7\xc8\xc8\x48\x28\xe9\xac\x44\x7d\x8f\x0c\x31\xf6\x33\x9a\x2f\xe3\x42\x52\x0f\x9f\xc1\xd7\xcb\xb8\x88\x7e\x89\x8a\x19\x9f\x13\x49\x81\x46\xdf\x7a\x8a\x8e\x7a\xe6\x0c\xca\xca\xc5\x08\x79\xfd\xe6\x89\xcf\x4f\xfa\x56\xab\xbe\x35\xd0\xb0\x07\x68\x8d\xa8\xe1\xb5\x5a\x3b\x7a\xe1\xd0\x78\x22\x46\x2c\x3a\x2b\x76\x85\x34\x7b\x19\x8c\x67\x1d\x9b\x31\x45\x98\xb6\x18\xd7\x2f\x9d\x2f\x3d\x57\x27\x5d\x5c\x88\x23\x04\xba\xb2\xe1\x6a\x3b\x3b\x66\xf7\xe5\x3a\x42\x44\xa8\xd6\x2e\xa3\x62\x1a\x4f\x04\x88\x3d\x47\xd0\x01\xb7\x4b\x12\x4f\xf0\x61\x4f\x16\x6e\xc2\x5c\x8a\x1b\xbb\x84\x8a\x67\x78\x64\x40\xb6\x34\xe8\x35\xa1\x71\x4e\xad\xe1\x0d\x06\x24\x4c\x93\x76\x41\x82\x30\x24\xa2\x54\x91\x9a\x55\xf6\x49\x54\xb4\x73\x12\xc4\x19\x0d\xc2\x4b\x32\x4e\x97\x49\x41\xc3\x12\x2c\x7d\xa1\x71\x5e\xeb\x45\x38\x18\x90\x0f\x87\x2f\x0e\x47\x64\x12\x4d\x97\x19\x25\xec\xc0\x96\xd0\x9c\x9d\x00\xd9\x29\xed\x32\x37\x99\xd5\xef\x41\x24\x7f\x9c\x49\x36\x27\x83\x62\x04\x4a\xac\x94\x2c\x73\x85\xd6\x8c\x4e\x02\x50\xc7\x9c\xcf\xd2\x98\xf2\x1e\x46\xc9\x74\xbd\x86\x11\x54\xf0\x00\x9b\xf3\x8b\x41\xf7\x48\xea\xac\x7c\x63\x91\xcb\x39\xa9\x15\xf5\x3d\x5b\x5c\xc7\x55\x8d\x21\x02\xe2\x0d\x93\xf3\x40\x93\x75\x4e\x0b\x67\x4e\x39\x59\xbd\x09\xe6\xd4\xde\x87\x74\x0e\x96\x33\xdd\xb2\x9e\xcd\xa7\x7a\x3f\xd3\x15\x7b\xea\x54\x7c\x51\x60\x50\x4b\xb5\xf2\xaf\x62\xd8\xb2\x92\x45\x46\xcf\xa2\x74\x99\xab\x0e\x6d\xed\x30\x94\x44\x09\x89\x92\xc2\x29\x51\x87\x7f\xd4\x5f\x5f\x83\xec\x6f\x92\x66\x04\x1e\x09\x47\x64\x97\x6c\xee\x90\x88\x7c\x2f\x07\x20\xdf\x0b\x93\x68\x63\xa3\xac\x38\xfb\xb3\xfa\xbc\xb1\x4b\x36\x3a\x12\x07\x11\x79\x44\x36\x4f\x98\x84\x4f\xae\xae\xc8\x70\xa7\xb4\x92\x0a\x56\x2e\xe8\x61\x83\x44\xe4\x61\xd9\xcc\x6d\xd8\xbd\x60\xc2\x41\x19\xdb\x97\x7f\xd7\x4e\xaa\x99\x72\xdd\xed\x74\xad\x29\x1c\x0c\xc8\x24\xca\xf2\x82\xd0\x98\xce\x69\x52\xb0\xf3\x15\x47\x53\x8f\xe4\x9f\xa2\x05\x89\x8a\x55\xa6\xdc\xc0\xfe\xd0\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\x38\x22\x1b\x64\xf3\x44\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\xb0\x8a\x21\x91\x46\x34\x5d\xcb\x51\x06\x03\x32\x0e\xe2\xf1\x32\x0e\x0a\x2a\x05\x1f\x76\xe4\x13\x7d\x21\x51\x41\xe7\xb7\x60\x47\x8c\x15\x1d\xff\x89\x98\x52\xd7\x86\xbd\x5e\x69\x5f\xb9\xe5\x84\x7c\x3d\x06\x83\x99\xcb\x17\xe7\x2d\xc4\xd1\x16\x89\x7e\xd4\x68\x43\x84\x2e\x52\xdc\x4c\xa6\x15\x1a\x23\x0e\xd9\x58\x63\x24\xd3\xd5\xad\xa6\x52\x89\xf8\x75\x49\xe5\x7a\x10\xd4\xb0\x47\xfc\x83\xfa\x7d\x3a\x22\x54\x4c\xeb\x88\x38\x34\xc8\x36\x4d\xd0\x52\xa9\x24\x2a\x41\x48\x99\x8e\xa8\x1c\x21\xa2\x04\x9c\x30\xa0\x35\x8d\x98\x6a\x0d\x11\x1e\xa2\xef\x74\x6c\xe0\x66\x75\x05\x91\x2c\xc5\xa9\x18\xc3\x73\x22\xce\xbd\xa7\x70\xeb\xb8\x7f\xc7\x1a\x25\x3e\xe4\x0e\x8c\x4c\xae\x2f\xad\x16\x31\xf4\x22\xb2\x46\xad\x61\xaa\x52\x39\xe8\x51\xd5\xea\x19\x30\x46\x39\x07\x62\x65\xee\x7a\xa4\x4d\xd4\x51\xea\x24\xea\x93\x83\x45\xd7\x4a\x99\xe4\x60\x40\xf2\xe5\x9c\xdf\xd0\x79\x76\x29\x21\x22\x2a\x78\x51\xdd\x71\x74\xc2\xb8\xa2\xfa\x82\x2d\xc9\xc7\x7f\x64\xf3\x26\x22\xa4\xb4\xe9\xa0\x60\x30\x20\x19\x9d\xa7\x67\x70\x8d\x49\xc6\xcb\x2c\x63\xf2\xa9\x12\x4e\x53\x48\x16\xdd\x8c\x72\xe8\xb9\xa7\xb7\xf9\x2a\x1a\x3f\x89\xcc\xc6\x9a\x3f\x63\x64\xe4\x91\x53\x7f\x63\x4a\x7b\x6f\xad\xc3\x92\x6b\x1d\xef\xa9\x55\xf2\x38\x0f\x95\x15\xd6\x95\x83\x24\x2b\xb6\x83\xe1\x4b\x12\xf3\xfe\x82\xf7\x96\xb5\x35\x16\xb7\x4c\xd8\xd4\x02\x7a\xdf\xe1\xf6\xaa\xb6\x09\x86\xb8\x16\xed\x74\x7b\xde\xec\xe7\x69\x1a\x97\xe5\x31\x21\xa4\x24\xeb\xa8\x22\x0f\x5f\x6e\x96\x36\x5b\x95\xc9\xb9\x70\x59\xee\x3b\x1a\x94\xf6\xf8\x88\x67\xae\x31\x82\x70\xed\x37\x00\x75\xca\x66\x43\x1a\xce\x8e\x1e\xf7\x5a\xfc\xee\xb7\x35\xfa\x06\x7e\xb2\xbe\xb5\x46\x4f\xd8\x6f\x7c\x1d\xdb\x1a\x3d\xed\xf9\x6c\x3d\xa2\xa4\x68\x8d\x36\x87\xec\x67\x46\x83\xb8\x35\xda\xdc\x62\xbf\xf9\xad\x6c\x6b\xb4\xb9\xcd\xbe\x96\x1c\x0a\x1a\x58\x0a\xb0\x27\xd7\x27\xbd\xa7\xbf\xa7\x5d\x54\xcd\x35\xf4\xcd\xac\x89\x70\x25\xab\x18\x15\x99\xe5\x6c\xdb\x22\x9c\xbb\xa2\x89\x91\xbf\x68\x85\xa5\x91\xd9\x93\x26\x75\xdd\xc2\xee\xa8\xc4\xd8\xa8\x51\xa3\xe8\x4a\xdc\x3b\x5d\x92\xed\x64\x4b\xda\xc0\x84\xc9\x1a\x76\xbd\x25\xd3\x77\xf7\x96\x4c\xf7\x96\x4c\xff\x2d\x96\x4c\x7a\x21\xdc\x95\x39\xd3\xf3\x68\xfa\x66\x39\x3f\x05\x56\xa8\xb8\xf3\x69\x34\x4d\x20\xb1\xff\xab\xe2\xe4\xcb\x22\x8a\x4d\xfb\x9a\xfe\x00\xd2\xf8\xbf\x12\x6c\xec\x05\x19\xa7\xc9\x24\x72\x8c\x81\xe4\xc9\x0c\xed\x0a\x70\x76\x81\x6d\x41\x0e\x9c\xf3\xea\x9c\x00\xbf\x27\xf0\x60\x83\x9d\xb3\x18\xdf\xd2\x56\xb2\xb0\x14\xd8\xdc\x80\x72\xe6\x21\xc3\x31\x87\x8c\x72\x92\xd0\x69\x50\x44\x67\xb4\x27\x39\x11\x5c\x1c\x15\xe7\x69\x3b\x27\xe3\x74\xbe\x90\xd2\x2a\x94\x62\x73\xab\x4a\x4e\xe2\x34\x28\xa2\x64\x4a\x16\x69\x94\x14\x3d\x7e\x1d\xca\xc8\x3e\x4c\xcf\x13\xeb\x4c\x67\xaa\x49\xdc\xe3\xdb\x15\xc7\xf2\x95\xc2\xf7\xb5\x1c\x0b\x5b\x4a\x09\xa5\x21\x9c\xa2\x4f\xf5\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\xf0\xea\xe3\xf3\x83\x9f\xde\x1c\xbd\x7e\xfe\xf2\xdd\xc7\x77\x87\x47\x6f\x5e\x1c\xbc\xf9\xe9\xe3\xeb\xc3\x17\x2f\xd1\x19\x4e\x69\xe2\x60\x26\xfb\x8b\x20\xfc\x99\x4e\x8a\x0e\xff\x2a\xd2\x0f\xe7\x69\xbe\xaf\xb0\x28\xda\xec\x17\xa9\x10\x97\x36\x9f\x74\x7b\xe4\xc9\x63\xf3\x86\x07\xef\x96\x30\x9c\x0e\x6f\xc4\x34\xc0\x30\x27\x5e\x1e\x7e\x4b\x70\xfe\x5c\x9d\x8d\xcd\x43\xf3\xaa\x38\x74\xa5\x0e\x03\x8b\x1e\x84\x14\xe9\x2b\x7a\x21\xc7\x9d\x2f\x4f\xf3\x22\xeb\x6c\x21\xfc\xc5\xd6\xd5\x3e\x2f\x2e\xb5\xdc\x1b\xe4\xc9\x76\x97\x0c\x30\x8a\x6c\x74\xbf\x8b\xa6\xb3\x42\x14\xeb\x91\x98\x3c\xfc\xc2\xf8\x14\x3b\xf0\x9d\xa2\xb5\x54\xa6\xbb\x35\x76\xe5\xf1\xcc\x44\xab\xd2\xce\x7d\xb5\x19\xb0\xd4\xa6\xbc\xb1\x6e\x9f\xaf\xf9\x0d\x52\x3f\x41\x75\x9c\x8e\x4b\xf2\xe5\x2b\xe2\xbd\xcc\xbf\xed\xdc\x29\xe3\xce\xe6\xb3\x36\xc9\xd2\xf9\x51\x31\x79\x7a\x3f\x71\x9e\x89\x13\xef\x8c\xca\x18\x99\x78\x85\x24\x27\x8d\x7d\xd3\x20\x59\x9d\x91\xd9\x4f\x8e\xca\xe7\xac\x3d\xbc\xdd\x5f\x9b\x6c\x88\xea\xc9\x33\x42\xda\x9b\x6d\x32\x22\xed\x61\xfb\xf6\x3c\xaa\x0e\x93\xec\xc4\xca\x4a\xfd\x83\xc1\xe5\x84\x09\xc6\xf3\x65\x5c\x44\x5c\xa8\x3c\xbd\x24\x5b\xff\x99\x33\xf1\x5c\xd9\xd0\x05\xac\xe6\x82\x4e\x69\x56\xb1\x95\xbc\x13\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\xba\xfd\x45\x7a\xde\xd9\xdc\x7a\xda\xed\x9a\x28\xdd\x9f\xd1\xf1\x27\x12\x4d\x0c\x9c\x22\xb1\xc8\x42\x44\x1e\x4d\x13\x1a\x1e\xe4\x6f\x74\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\x33\xec\x91\xcd\x6e\x8f\x6c\x3e\x41\xf2\xc8\x56\xd7\xc8\xed\x92\xdd\xdd\x5d\x46\xb2\x5e\x2a\xcc\x18\xfb\x78\x14\xc4\xd0\x29\xc2\x55\x07\xfa\xc2\x83\x8b\x9a\x2e\x11\x71\x45\x82\x2d\x04\x1a\xe4\xe1\xd8\xc1\x32\x9c\x69\xc1\xb0\xa2\x5d\x25\x1c\xc2\xb2\x88\xa6\x84\xcb\xe9\x16\xbd\xa9\x2e\x18\xf8\x33\x8c\x62\x19\x30\x9f\xc7\x5d\xde\x1b\xa4\xcb\xec\x74\xc9\xd5\x15\x69\x0d\x5b\x42\x47\x3c\x18\x90\xb1\xa2\x22\x26\x3c\xcb\x89\x54\xad\x73\xa0\xa8\xe0\x13\xad\x24\x6d\x57\xc8\x96\xf7\xb7\xd6\x3c\x8b\xb9\xf5\xa8\x20\x3d\xf3\xcb\xa7\x74\x1e\x25\x4b\x7b\x15\xb4\x27\xb7\xfc\x6b\x43\xdd\xb2\xf2\x4d\x75\x3d\xd6\xa0\x43\x37\xa0\xa0\x65\x35\x09\x1d\x55\xd2\x90\x8f\x7a\xe8\x4a\xe4\x23\x9a\x77\x09\xe7\xe8\x2e\x28\xe7\xcb\xa0\x4c\xb0\xfc\x32\x94\x39\xbc\xbb\x16\x65\x80\x31\x24\x12\x9b\x28\x12\xcd\xb9\x28\x72\x98\xb9\xcf\xe2\xdc\x5a\x8c\x02\xa6\x1f\x46\x67\x51\x48\xc3\xe7\x97\x15\x3c\xfc\x26\xd4\x54\x83\x9b\xa3\xbb\x46\xce\xb2\x14\x3b\x47\x2b\xa3\xe7\xe8\x36\xf8\x71\x6f\x61\x79\xd5\x0a\x45\x65\x12\x97\x7e\x30\xdd\x18\x2f\x72\x67\x33\xe7\xa2\x14\x47\xa2\x69\x17\x45\x8e\x7c\xe6\xc3\x90\x67\x79\xc1\x7e\x75\x4b\x81\x6d\xb3\x4d\x9e\xf1\xad\x59\x78\xc6\x58\x0d\x9b\xa5\x27\x47\xf4\x2e\xb7\x62\xef\x8b\xe9\x44\x23\x8e\x49\x10\x15\x67\x1b\x47\xf4\x48\x82\x39\xe5\x0f\x7c\xd8\x2f\x4b\x04\x13\x30\xac\x4e\x55\x83\x07\xf3\xce\x21\x14\xda\xe8\x11\xac\x2c\x67\x85\xc4\x13\x6b\xb2\x4b\xca\x5e\xea\x3e\xec\x0e\xd0\x91\x26\x8f\x7e\x13\x3c\x31\x87\x5b\x2a\x51\xfe\x78\xf3\xc4\x14\x85\xdb\xc3\x0b\x26\x32\xbb\x93\xdb\xcf\xe3\x68\x4c\x99\x64\xb2\x45\x1e\x42\x75\x2b\xd2\x79\xcd\xcc\xe0\x53\xf8\x9d\x4d\xd0\xaa\xe8\x2f\x55\x05\x38\x9b\x8c\x3a\x22\x5a\x7c\x80\x23\x4e\x5c\x82\xd9\x98\x7b\xf2\xb8\x2b\xf6\xf0\x22\x15\xf0\x5d\xf2\x50\x9e\x2a\x7d\x33\x60\x55\xc4\xa5\xc3\x27\x8f\x7b\xa2\xfd\xd5\xa6\xa0\xe2\x54\xce\x87\xef\x39\x96\xdf\x29\xf6\x83\x7c\x1c\x45\x55\xf8\xf7\x1c\xe7\x7f\x47\xcc\x4b\xad\x0e\x68\x07\x9a\xe1\x7f\xb5\x09\xd0\xee\x69\xca\x66\x60\x4f\x3b\xb0\x29\x99\x82\x52\xde\x5e\x82\x72\x55\xa1\x8b\x6d\x9f\x03\x9b\x15\xa4\x29\x03\x77\xad\xe1\x45\x8b\x6c\x10\x71\xc6\x01\xb4\xf3\xdf\xca\xac\xe0\xf1\xb0\x47\x70\x52\x99\xcf\x80\xcf\xd2\xf4\x03\x9d\x35\x47\xd6\x77\xcf\x86\x81\x15\x3b\x72\x52\x1c\x38\xbc\xc0\x47\x65\x19\x4e\x29\x8e\xcc\x91\x9b\xe4\xf6\x23\x4d\xe3\x91\x9d\xe0\x40\x31\x09\x64\x64\x27\x60\x28\x25\x96\x8d\xec\x04\x17\xea\xc8\x01\x3b\xf2\xc2\xe1\x46\x75\x8a\xa7\x3e\x17\xf0\xc8\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\x47\xde\x75\x77\x2d\xaf\x75\xcd\xcb\xa1\xd6\x68\xf3\x69\xaf\x65\x5e\x2a\xb5\x46\x5b\x60\xc1\x00\x0b\xa3\x35\xda\xdc\xec\xb5\xf0\xd5\x54\x6b\x64\x7e\x5e\x9f\xf4\x36\x87\x5f\xd9\xa5\xcb\x01\xb7\x8d\xaf\xf0\x41\x14\x25\x45\x99\x0b\x22\x71\x7b\x15\x25\x05\xf7\xce\xc2\x7e\x3c\x56\xbf\x4e\x74\xe2\x36\xfa\x6d\x39\x6f\x89\x92\x82\xbb\x6e\x89\x92\xe2\xc9\x63\x05\xf6\x54\x57\xb4\xf5\xcd\x93\x92\xba\x18\x7c\x8d\x2b\x23\xfb\x68\xf8\x05\xbd\x71\x01\xb8\x6d\x86\x70\x90\x14\x2b\x5a\x5e\x18\x25\x2a\x0c\x2e\xa0\xb9\x8a\x92\x37\x32\xaf\x88\x92\x42\x8a\x8a\xcf\x6e\xe4\xd2\x85\xf7\xaa\xde\x0c\x62\xb3\x51\x14\xbb\x7b\x3b\x88\x7b\x3b\x88\x3f\xaf\x1d\x04\xd1\x86\x10\x5c\x54\xba\x23\x1b\x88\x06\xa6\x0d\x36\xab\xe7\xa6\x0b\x29\x18\xa4\x6b\xcf\x1d\x7d\x8f\x84\x7a\x3e\xa3\x89\x7a\xaf\xd8\xe3\xb6\xdf\x4c\x00\x57\x0e\x1c\xa4\x64\x39\xf0\xda\x46\x58\xea\x6f\xfb\x79\x22\x70\x52\x29\x3f\xf2\xff\xaf\xae\x48\xbb\x8d\xf8\x6c\x2a\x5f\x2e\xf0\x1f\x3b\xe8\xa9\x61\x94\x88\xd6\x1b\x7b\xfc\x98\xd2\x02\x9b\xfc\x82\x01\x79\x3b\x97\x0f\x41\x81\x97\xb0\x4a\x0c\x6b\x77\x2d\xdf\x73\x63\x57\x53\x8a\x96\x6a\x26\x5d\x2b\xae\x8c\x74\x64\x1f\xbb\x86\x41\x3b\xa0\x07\x1b\xb4\xdb\x8d\x54\x9a\xa2\x81\x95\xbf\x71\xec\xc0\xd7\x8f\x8d\x91\x31\xce\x28\x23\x26\xb9\x1e\x4c\xb7\x2c\x9c\xdc\xc3\x68\x32\xa1\x60\x90\xcc\x51\x6e\x9d\x4b\xce\xd5\xbb\x10\x7c\x1c\x91\x28\x11\xb3\x24\x6d\x97\x13\xef\x21\xc4\x3c\xba\xb0\xed\xd0\xd7\x8f\x60\xc1\x39\x8c\xea\x45\x39\x2a\xcf\xfd\x6f\x66\x4d\xba\x2b\xbd\xd5\xd3\x04\xa9\x48\x75\x15\x8c\xa6\xf3\xd3\x28\x71\x3d\xdc\x14\xe9\x94\x32\xee\xce\x6a\xa0\xd3\x3e\x5f\x54\xc1\x62\x41\x13\x58\x4b\x41\xc2\xdf\x40\x58\xd8\x15\xb5\xd5\xdd\xc3\x08\xc6\x34\x8b\xc6\x8c\x3d\xc9\x5e\xd5\x17\x16\x17\xa8\xe9\x44\xc0\xc2\x3e\x54\x89\x5a\x39\xbc\x3a\xbd\x5f\x15\x5a\x95\xde\x82\x5f\x99\xec\x90\x7a\xec\x8e\x83\x38\x16\xf8\x95\xd7\x38\x7c\x44\xb3\x40\x2f\xdd\x3c\xfa\x4d\x38\x17\x84\xeb\xba\x59\x90\xf7\xd8\xff\x92\xd0\xc0\xfd\xaf\xe7\xde\x0e\xe3\x5b\xd9\x82\xfa\x75\xa6\x95\xa8\xf1\x7b\x67\xf2\x2d\x5c\xb1\x2a\xd6\x77\x77\x41\xba\x98\x44\x89\xf5\x56\xa9\x0e\x09\xda\x6b\x91\xa8\x4a\xdc\x30\xdb\x4a\x03\x9e\xbb\x97\x3f\x2f\x3f\xfa\x73\x8d\xaf\xab\xa1\x69\xb0\xcc\x8c\xda\xab\x06\xbd\x0e\xa3\xd6\x2e\x00\xba\xe4\x19\x69\xb7\xc9\xa8\x99\x41\x16\x42\x99\xd7\x2c\x6b\x05\xbc\x31\xde\xcf\x95\x13\x4a\x66\xf4\x3d\xf7\xd2\xfa\x0b\x3f\xce\xe4\xde\x23\x6f\x85\x03\xcc\xf0\x83\x39\x26\x32\x20\xf1\x4a\x2c\xea\xc6\xbc\x28\x04\xbf\x4a\x36\xfe\x7c\xfe\x99\xd4\xf2\xda\x21\xfc\xca\x8f\x94\xd0\x9d\x98\xb0\xce\xea\xa8\x33\xb6\xb5\x12\xdc\xa1\x4d\xc9\x8f\x3c\x99\x10\xc8\x4b\xf8\x06\x58\xa4\xf3\x45\x71\x89\x55\x82\x0d\x36\xd1\xda\x55\x68\xd2\x23\x62\x4f\x23\x90\x3e\x56\xc0\x8d\xf4\x38\x55\xea\x6b\xca\x8b\x89\xca\x81\x88\x2a\xeb\xc6\x60\x5c\xac\x6c\x78\xc4\x82\x9b\x8c\x43\x3f\xc6\x2b\xf7\x0f\xf5\x73\x94\x17\xce\xcb\xbf\x63\x63\x34\x27\x1e\xa7\x50\x95\xa3\xd7\x35\xbb\xdb\x8b\x7a\x17\x24\x6f\xea\x97\x8b\x90\x5b\xb6\x8a\x77\x70\x4a\x15\x59\xa4\x05\x7a\xeb\xca\x0b\x4b\xe1\x88\xfb\x1d\x22\xc6\xdb\x3e\xf5\x84\x50\x80\x9a\xcf\x8a\x8c\xbd\x4d\xad\x47\xbe\x7d\x95\x2c\x48\xfb\xf6\xcb\x76\x16\x62\x36\x4f\x76\x71\x8f\x35\x2c\x1e\xc6\xc6\xae\xab\xe8\x17\xaf\xb5\xdc\x17\x5a\x1c\x52\x8b\x40\x9d\x14\xbf\xba\x55\xaf\xe6\x06\x03\x39\xdd\xf4\x8c\x66\x97\xc5\x0c\x7c\x91\xa0\x7a\x30\x76\x5c\xc7\x53\xd2\x22\xcd\xc1\x8f\xf1\x52\xd7\x7f\x43\xa1\x7c\x2f\xdd\x69\x13\xae\xd2\xf9\xba\x47\xda\x6d\xa9\x7c\xaf\x50\x52\xbc\xe5\xb3\x64\xe9\xf4\x94\xfa\xee\xfa\xa4\xb7\xd9\x28\xd6\xde\x17\xd4\xc9\xc1\x6d\x74\xb5\x52\x2e\x63\x20\x25\x5a\x39\x69\x66\xc6\xfe\xe7\xaa\x32\xf8\xf5\x58\xff\x3c\x41\xc9\xdb\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\x51\xbe\xe8\x56\x03\x45\x5d\xa3\x68\x5e\x5f\xea\x71\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\x33\xe7\x69\xef\x6e\x5f\xcb\xa9\x51\x36\xa0\xbb\xbb\x8f\x3e\x52\xf9\x7e\xc7\xc3\x87\x91\x8b\xdb\x28\x6f\xee\xdb\x76\x4c\xb3\x22\x88\x12\xbf\x7f\x5b\x07\x91\xfc\x36\xa9\x86\xa8\x39\x50\xdf\x4c\xaf\x26\x6b\x51\xc4\xca\xa8\xf5\x06\x51\xd0\x6c\xce\x8e\xfc\xd1\x04\x6a\x36\xfb\x1d\x0a\xaf\xb5\x64\x1a\x9d\xd1\x44\x9a\xb4\x98\x47\xea\x32\x77\xb9\x96\xfd\x0b\x3f\x66\x6b\x8b\x5b\xc0\x32\xaf\xdc\x69\xd7\x6f\x7f\x8b\x21\x9a\x2f\x11\xee\x9c\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\x90\x1f\xac\x20\xf4\x51\x34\x4a\x04\x0a\x0b\xd7\xef\xb0\xfd\xd6\xbe\x11\x32\x5d\xad\xa4\xd5\x9c\xd6\xda\x96\xe0\xcd\xe3\x42\xc0\x8f\xc1\xc1\x00\x54\xe1\xc1\x9c\xad\x0a\xf0\x7a\x28\xb4\x59\x6c\xbc\x8c\x13\x50\x7e\xc7\x10\x47\x9f\x28\x09\x48\x1e\x25\xd3\x98\x2a\x3f\x5c\x00\xd9\x37\x4c\xa2\x81\x82\xb9\x9b\x19\xee\x96\x83\xb7\x76\x75\x45\x8e\xdb\xc7\x9b\x27\xed\x93\xae\x12\x06\x6b\xdc\x00\x88\xee\x99\x78\x67\x5f\xd8\xb5\x61\x89\xe8\xce\x6d\xa0\x38\x2a\xc0\x56\x61\xb3\x47\x1e\x81\x3d\xf6\x10\xfa\xb2\x89\x1d\xd1\xe8\x0e\x39\x82\xac\x74\xd4\xd0\x93\xae\x1d\xca\x4e\x0b\xd2\xa1\xc3\x43\x09\xa8\x1b\x18\x0c\x48\x10\xc7\xe4\x34\xc8\xa3\x31\xf7\x7f\x00\x8f\x05\xb6\xb7\x84\x02\x27\x4e\xd9\xc9\x58\xf6\xa6\x47\xb6\xb7\xea\x8c\x4e\xcc\x85\x2d\x38\x9a\x3c\x81\x4b\x5d\x24\xa1\x53\x10\x20\x21\x28\xd4\xf1\x49\x8b\xec\xfe\x00\xeb\x53\xa7\x3d\xe6\x89\x95\xca\xb4\x3d\x59\xdb\xaa\x1c\x60\x46\x4b\x7b\x56\xb1\xda\x71\xab\xa5\x34\xab\xdd\x7e\x19\x0e\x61\x1c\xa2\xdb\xb1\xb6\x51\x54\xe4\xc1\x03\x82\xbf\x8f\xd1\x6f\xe4\x02\xee\x44\xee\xba\x2a\x32\xc6\x60\x7a\xa3\xb9\x11\xcb\xb7\x6a\x6a\xe4\x2c\x98\x73\x23\x26\xcc\x9c\x1a\xe4\x71\xed\x96\x33\x63\xf5\xab\x62\x62\x50\x9b\x5f\x7a\x5e\xee\x72\x62\x4c\xd7\x27\x9a\x91\xa2\x99\x80\xb3\x51\x0b\x6c\x11\xb6\x38\xd2\xf9\x21\xa9\x25\x8c\x15\x36\xc5\x54\x6c\x3e\x56\x80\x5b\x27\xc7\xdb\x02\x54\xa6\x71\x10\x05\xb1\x79\x62\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\xac\x98\x72\xb1\x49\xc8\x53\xb5\x6f\x9e\x61\xde\x7c\x53\xdd\x52\xf1\xf7\x9c\x09\x17\x9f\x2d\x63\xde\x8d\x8a\x8e\xcd\xca\xf1\x74\x6b\xef\x6b\x8d\xe6\x59\x65\xf0\xa1\x88\xfc\xd2\xf9\x35\xbc\x28\x96\xee\xf6\xc2\x5b\x51\x1c\xe4\x05\x39\x3e\x61\xc2\x04\xaf\xf7\x46\xd3\xbe\xee\x9f\x77\x35\x07\x20\x67\x11\xc7\xc7\x12\x1c\x68\xf4\x4b\x28\xf8\x54\x34\xd0\x84\x48\x2a\x8c\x63\xd1\x11\x46\x71\x60\xfb\xa6\x89\x9c\x5e\x92\x90\x4e\x82\x65\x0c\x8a\xd0\x7c\xc9\xe4\x54\xb5\x31\xb7\x84\x9b\x9a\x9e\x08\xf3\x68\xcf\xa2\x71\x8c\xba\x01\x03\xd6\x3b\xe2\x8a\xa2\x70\xc3\xd3\x5b\xa9\x51\xbd\xf4\xd5\x2e\x75\xc4\x68\x89\xe4\xf6\x1a\x01\x8a\x17\xa4\x7c\xdc\x62\x14\xdf\x23\x2d\xb6\x08\xd8\x7f\x27\xad\x13\x4d\xed\x02\x02\xa5\x41\xa1\x64\x19\xdb\xcf\x1e\xd0\x6c\x36\x42\x9b\xed\x60\xce\xea\x6f\xcd\x42\x70\x9d\x54\x39\x2b\x81\xef\x0d\xc2\x59\x1e\x9f\xf5\x1c\x6e\x78\xd9\x70\x8c\xf1\xb2\x7f\x61\xd5\x5b\x44\x2c\xb8\x55\xe7\xdf\xc7\xfc\x34\xfe\xef\x93\x6e\xbd\x88\x20\x94\xb7\xca\xdb\x43\xf9\xbd\x83\x15\xc6\x42\x42\x37\x67\x1d\xf2\xed\xa9\x7b\x97\x65\xe1\xcc\x73\x69\x21\xee\xd1\xed\x8d\xc1\xeb\x8f\xda\xbc\x95\x11\xae\x50\xa5\x13\x54\x9b\x2d\xd4\x78\x83\x55\xf6\xdf\xd8\x98\x78\x87\x94\xfe\xf9\x1d\xa3\xba\x7e\x65\x69\x3c\xc1\xfe\x64\x05\x2b\x73\x0a\xa9\x97\xc9\xc7\x27\x3e\x27\xe2\xfd\xc5\x32\x9f\x75\x1c\xcf\xa4\xf2\xa5\xb6\x74\x33\xea\xd6\xcc\xc6\xe2\xfa\x5c\x3f\xf3\x39\x00\xc5\x2d\x21\x3f\x9e\x9d\xb3\x1e\xc1\xfe\x65\x2d\xf7\xa4\xb7\x72\xea\x2b\x26\x10\x3b\xf3\xbd\xf5\xfc\x41\xd7\x1d\xa9\x43\x20\xfe\xf7\x9f\x3f\x9f\x47\xd6\x1a\x4f\xac\xa5\x13\xc1\x66\x13\x5c\xa5\x56\xcc\xc7\xca\xb3\xb1\xe6\xdc\x11\x5a\xba\x23\x63\x49\x22\x8f\xb6\x4d\x7c\x82\xf2\xfb\xd1\x49\x96\xce\xbd\xe6\x06\x1c\xca\xc7\x5b\x4e\xed\x07\x3b\x96\x81\x90\x61\x19\xb4\xc2\x83\x29\xc9\xd4\x78\xcb\x0d\x58\x94\x18\x08\x66\x51\x86\x3f\xcd\x1a\x56\xf5\x45\x78\x15\xec\x4d\xf8\xc6\x92\x0b\xba\xe2\x89\x0f\x74\x4f\x0a\x3a\x02\x5d\x0f\xc9\x16\x18\x3f\x74\xa5\x47\x67\x81\xbc\xb2\x45\x54\x59\x27\x6e\xde\xa9\xd8\xb7\xa2\xa0\xc0\xfb\x82\xdf\xb1\xe3\xd2\x1b\x64\x9b\x3b\xbd\xe7\xbb\x6d\xce\x40\x72\x12\x4c\x0a\x9a\xa9\x45\x82\xfb\x7b\xa3\xb5\xea\x2f\xe3\xf3\xdd\xad\x39\x47\x89\xcf\x6e\x52\x89\x3d\x11\x3a\xe6\x4d\x59\xfd\xd8\xaf\x47\xa9\x1b\x69\x3b\xe6\x4d\x25\xa3\x69\xc8\x69\xc8\xc3\xea\xbe\x31\xd8\x8d\xdd\x6a\x98\x46\x8c\xca\x74\x38\x8b\xa6\x7d\x83\x44\x77\xcb\xb5\xfe\x10\x7b\x08\xfe\x6b\x48\xfd\xd2\x20\xb5\xe1\xdf\x1f\x8a\xf8\xef\x69\x1f\xfd\x7d\x15\xda\x27\x5e\xd2\xc7\x01\x1a\x6f\x4a\xfa\x76\x18\xb1\x15\x37\x15\x87\x58\xed\xfa\x9b\xed\x2c\x66\x2f\x56\xa9\x5f\xcc\x9f\x97\xde\x62\x87\xbe\xfc\xeb\xaf\x7c\x09\x2f\xc4\xad\x9f\x6b\xa4\x5a\xd7\xfd\x0e\xd9\x24\x1b\x66\xef\xba\xdc\x27\x13\x8f\x24\xe6\x99\x7a\xee\x81\xd8\xba\x74\x33\x1e\x6c\x57\xf8\xb3\x37\x70\x6d\x59\x7c\x19\x5c\x6c\x6d\xc5\xb1\xe1\x39\x57\x2b\x6b\xab\x6b\xaa\x55\xbd\x17\x89\x56\xd7\x6b\x2f\x78\xcb\xaf\x76\xd5\x9b\xb8\xeb\x93\xde\xe6\xd7\x0e\xbd\x7f\x54\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\xe0\x23\xb8\x23\xef\x2b\xb8\xa3\xd5\x9f\xc1\x1d\x35\x7d\x07\x77\xe4\x3e\x84\x3b\xba\x83\x97\x70\xcb\x5b\x3f\x85\x3b\x6a\xfc\x16\xee\x6b\xc7\xf5\x3f\x6a\x60\x71\xb6\xac\x32\x39\x93\xae\x55\xf8\x0f\x41\x9c\xc8\xea\x6c\x89\xcd\xce\x96\x86\x95\xd8\xd2\x67\x78\xb6\xd4\x96\x67\x4b\x6c\x7a\xb6\xc4\xb6\x67\x4b\xcb\xf8\xcc\x53\x6f\x93\xc5\xf1\xbb\xda\x9f\x1d\xf9\x0d\xd0\x8e\x6e\x60\x81\x76\xd4\xd8\x04\xed\xc8\x63\x83\x66\x97\xbe\xd9\x1a\xa9\x30\x43\x6b\xba\x48\x9a\x1b\xa2\x7d\xdb\x64\x95\xb4\x97\x39\x05\xc5\xec\xb8\x68\xf3\x80\x7c\xd3\x94\xd0\xe4\x8c\x84\x29\x05\x6b\x05\x78\x1d\x18\x24\x21\xf8\xb0\x25\xff\x7c\xfd\xf3\xab\xa2\x58\xbc\xa3\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\xbe\xde\x59\x33\x82\x45\x96\x42\x9a\x09\x20\xa9\xff\x9a\xcf\xd8\xee\x13\x4d\x93\x34\xa3\xa3\x38\x4a\xe8\xda\x35\xb7\x58\x65\x78\x68\xe4\xed\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\x47\x45\x14\x43\x9d\x5c\x9f\x09\x6b\x87\x3f\x4f\x72\xc0\xa2\xe2\x52\xb1\x44\x5d\x64\x1c\x07\x79\x4e\x8e\xa1\xc8\x89\xe8\x26\xcf\xd0\x4c\x98\x57\xb5\x36\x80\x7b\x23\x58\xa5\x42\xb9\xca\x38\x08\xa9\x70\x66\xdd\xdc\xcf\x39\x40\xb2\x9a\x8e\xde\x1c\x7c\x78\xcf\xce\xd6\x30\x09\xed\x73\x1a\xb5\x39\x69\xb6\x3f\xa1\xdf\xaf\xd1\xef\x9f\xd0\xef\xfc\xb7\xe0\x34\x95\x1f\x93\x28\x49\xe8\xa5\xfa\xa2\xf3\x22\x85\xa7\x8c\x32\x65\x11\x8d\xcd\x84\x24\x48\xcc\x84\x79\x34\xce\xec\x94\x38\x8e\x9c\x42\x06\xbc\x01\x2a\x3f\x8c\x22\xd3\x2c\x48\x42\x35\x14\x23\xeb\x27\xe3\xeb\x83\xf1\xf5\xd6\xf8\x7a\x69\x7c\xfd\x9f\xf1\xf5\x2f\xe3\xeb\x8d\xf1\xf5\xc2\xf8\xfa\x87\xf1\x75\xc4\xbf\xd6\x4e\xca\x5d\xd7\xb0\x39\x7a\xbb\xf7\x82\x4d\xf1\x88\x6c\x6f\xf5\x54\xe2\xfb\x83\x9f\xde\xec\x7d\x38\x7a\xf7\xf2\xe3\xcf\x2f\xdf\xfc\xf4\xe1\xd5\x88\x3c\xd6\x99\x30\xab\x23\xfd\x53\xe7\x94\x50\xce\x88\x7c\x26\x56\x82\xf6\xa3\x0e\x19\x1f\x5f\x1c\xfe\xf2\x86\x5c\xeb\x9a\xde\x1e\xfe\xfc\x33\x83\xfe\x70\xf0\xfa\xe5\xe1\xd1\x87\x11\xd9\x1c\x0e\x87\x03\xd1\x43\x71\xe3\xfd\x3c\x4e\xc7\x9f\x46\xa4\xcd\x58\x67\x5e\xb4\x8d\xbc\xbd\x31\x84\x32\x1e\xe9\xb7\x8d\xfc\x01\x06\xdb\xcf\xeb\x7c\x9f\xdc\x87\xc2\xb8\xdf\xc8\xfe\xea\x1b\xd9\x9a\x72\x01\x91\xcf\x82\xed\xbb\xf2\x00\xb1\x9f\x5d\x2e\x8a\xf4\xef\xef\xf1\xe6\x30\x86\xb4\x47\x3a\x02\x06\x6b\xd0\x0b\x30\x60\x39\x6d\x6f\x74\x27\xd7\x7d\x03\x50\x5c\x8e\x1f\xa8\x8a\x24\xf2\xe0\x81\xcc\xed\x4b\x7f\x11\x5c\x4c\x9e\xd1\x8b\xb6\xfd\x8a\xce\xf0\xfc\xf5\x03\xd9\x62\xa5\x6d\xef\xc7\x5b\xd2\x5d\xa4\x59\x9c\xc8\xcb\x70\x75\xc1\x6f\xf9\x67\x27\xd6\x6b\x3b\x0e\x2a\x71\xc4\x3a\xd7\x7f\x45\x2f\xfa\xa0\xbd\x14\x9e\x7b\x7d\x36\x46\x0c\x2b\x72\xd8\xba\x75\x7e\xa2\xe3\xea\xb7\x11\xd9\xfa\xe6\x09\x2f\x89\x1e\x27\xcb\x37\x67\x8c\xe5\x29\x1c\xb7\x46\xdf\x7c\xd7\x6b\x99\x28\x6f\x8d\x9e\x0e\xaf\x4f\x7a\x5b\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\x68\x43\x36\xaf\xed\x0f\x04\xbb\xd7\xe1\x88\x26\x4f\x31\x00\xfb\x56\x22\xfc\x32\x89\x8a\xd7\xc1\x42\x89\x8b\x6d\x29\x51\x8f\x38\x0f\x6a\x0f\xa5\xac\xc9\xa4\xf6\x91\x66\x8b\xed\x4d\x43\xce\x1f\xa1\x8c\xe1\x50\x15\xfa\xdf\x8a\xbc\xd3\xe0\xf4\x34\x98\x52\xd5\x12\xce\x43\xc2\xff\xc8\xce\x9b\x7b\xea\x44\xd9\xaf\xab\xb3\xe3\xf4\x8c\xc6\xc1\x58\x36\x6b\x67\xeb\x33\xc6\xc8\x97\x3d\xf5\x57\x8e\x20\x7e\xaa\x85\xc8\x67\x41\x92\xa4\x89\x31\x6e\x13\x42\x9f\x6b\x46\x15\x10\x35\xad\xc0\xc9\x6a\xe4\x81\xc0\xa8\xd4\xe7\xa5\x51\x35\x50\x5d\x4d\xe2\xec\x36\xf2\x02\x19\x95\xa9\xf3\x98\x3d\x36\x0f\xa0\x7f\x88\x26\xa0\x41\xae\x1e\x38\x04\xfa\xc9\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\x29\x65\x70\xa1\x88\xc8\x65\xd9\x60\x8d\x67\x41\x16\x8c\x0b\x9a\xe5\x52\xc5\x0f\xf7\xf2\xa2\x34\xda\x47\xbc\x6d\x44\xd3\xa4\x87\x6c\xa1\xc9\x70\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\x41\x69\xe1\xb5\xaa\xba\x21\xde\xec\xf6\x7f\x4d\xa3\x04\x82\x35\x90\x67\x50\x07\x19\x91\xd6\xb0\xd5\x25\x1b\x02\xb8\xc4\xf0\xed\xc6\x73\x01\x01\x7b\xfe\xec\x93\x01\x83\x58\x71\x36\x44\x0f\x37\xb8\xc7\xe5\x9b\xce\x4b\x99\x21\xa2\xe9\x88\x06\xb6\x4e\x30\x43\x84\x60\x1e\xae\x8f\x69\x6b\x5e\xb8\xb7\xe6\x8a\x59\x89\x12\x56\x89\x1f\x59\xd8\x1f\xb5\xc7\x51\x12\x6b\x5c\x9b\x1d\x72\x0f\x24\x47\x7c\x6b\x57\x22\xfd\x8c\xc7\x7b\x1e\x0c\xc8\x8f\x51\x12\x12\xfe\xb8\x4b\x74\x54\xc5\x6b\x66\x12\x45\xab\xa5\x6f\xf2\xc1\xf6\xa5\x07\x21\xa4\x66\xf4\x42\x9a\x30\xab\x33\x17\x4b\xe3\xa7\x1e\x76\xe2\x28\x3f\x2b\xb1\x6a\xb6\xf0\xbb\x17\x30\xae\x11\x36\x35\x3b\x24\xda\xd8\xdd\xc2\xe0\x32\x16\x32\xb6\xed\xd0\x4d\x75\x22\xd6\x8e\x08\x7d\xa1\x5a\x98\x90\x0e\x2f\xb2\xbb\x4b\x86\x5d\xe3\x94\x76\x9a\xd1\xe0\x93\x06\x65\xa3\xdc\xd8\x25\xe2\x55\x39\x9b\xc1\xfd\x59\x90\xed\xa7\x21\x85\x1a\xbc\x87\x30\x36\xd9\xd2\x1c\x27\x2f\xb2\x66\x14\xc2\x27\x6d\x25\x12\xd9\x63\x45\x7e\x3f\x1a\x81\xe6\xfe\x7b\x88\xe4\x26\x33\x9f\x17\x65\xaf\xd3\xcd\xc9\xf6\xf8\x98\xef\x2c\x32\x3a\x89\x2e\x78\x10\xad\xe1\x45\x97\xcd\x02\x70\x0d\xbf\x7b\x7b\x11\xed\xad\x7c\xf6\xbd\xb6\xcb\x70\x04\x0d\x62\xe0\xe6\x95\xc1\x04\x7c\x51\x3e\x0d\x5f\xfb\xc2\xed\xba\xe8\x06\xa6\x0a\x46\xf1\x02\xf3\x7c\xf6\x61\x39\x08\xb3\x6d\xbe\x1c\xe4\x8c\xb0\x96\x34\x75\x4c\xd2\xcc\x36\xa1\xcb\x8b\xac\x2c\x22\x3e\x9a\x51\x06\x35\x16\x73\xb3\x57\x74\xa2\x9b\xad\x74\xb0\x4e\x14\xc1\xc1\x0d\xaf\x6d\x1a\x84\xf5\x77\x63\x97\x24\x72\x5f\xf8\x9e\x6c\x91\x67\xec\x64\x43\x36\x08\xdb\x0f\x12\x1f\x4d\x08\x17\xf2\x33\x7a\x71\x97\xa4\x61\xc5\x1c\xb0\x69\xa3\x86\x35\xfc\x6e\xc4\xe1\xf0\x0c\x44\x1d\xbf\x0f\x05\x7c\xb5\x69\xb5\x3c\x96\x4e\x96\x71\xac\xd0\x30\xa0\x67\x34\x29\xf8\x43\x01\x60\xf9\xbf\xe6\x69\x42\x82\xd3\xc8\xe6\xf1\xd2\x6d\xe2\x87\xf4\xc7\x65\x1c\xdb\x6f\x28\xe5\x63\x02\x56\xfa\x11\x2f\xed\x3e\x86\xe2\x0d\x3b\xed\x6a\xc6\xee\xb6\x61\x08\x52\xac\x72\xac\x3a\x65\xdf\x7d\x30\xa1\x88\x92\x90\x5e\x1c\x4e\x3a\xed\x4e\xbb\x0b\xbe\x21\x1f\x6d\x7a\x9e\x43\x2a\x78\xc7\x4e\xb0\xb8\x5c\x50\xd1\x1c\x00\x01\x15\x99\xfe\xcc\x3a\x51\xf7\xb3\x0c\x21\xdc\x67\xf0\x3b\xe4\x5a\x88\x62\xa6\xe5\x9f\x6a\x85\x6c\x90\x76\x87\xcd\x9c\xaa\x7d\x83\xb4\xbb\xed\x46\x6b\x2f\x8c\xf2\x45\x1c\x5c\xf2\x79\x01\x1f\xa3\x49\xc1\x64\x5b\x85\x0d\xfb\xcd\xda\x05\x64\xbf\xe0\xc5\xaa\x5e\xb8\xb2\xda\xcc\xc9\xf7\x2f\x2f\xa3\x07\x6c\x4b\xb3\x28\x86\x4e\xfb\x32\xde\xe2\x65\x47\x98\xd5\x75\xc9\xa3\x1f\x54\xa2\x9a\x56\xb7\x6f\x95\x0f\x9f\x95\xcd\xa6\x33\xb3\x06\x9a\x05\x18\x9f\x6c\xf2\xcc\x7e\xd3\x2a\xde\x83\xb1\x35\xa3\x9d\x8d\x0c\x06\x7a\xa0\xe9\x19\xcd\xe2\x34\x08\x69\xa8\x14\xc1\x9e\x35\x81\x07\xf0\x41\x13\x49\xd9\x9b\xc6\x01\xf9\x70\xf8\xe2\x70\x44\xe6\xc1\x27\x50\x0d\x47\xc9\xd9\x32\x4e\x68\x16\x9c\xc6\xf4\x2e\x07\xa8\x4f\x03\xf6\xeb\xdd\x4d\xf2\x88\xa0\xec\x6e\xb7\x9f\xd1\x45\x1c\x8c\x69\xa7\x4d\xda\xe0\xd4\x8d\x9d\x16\x5a\x66\x90\xc8\x34\x39\xa3\x59\x91\xeb\x90\x9b\x20\xf7\x85\x74\x1c\xcd\x83\xd8\x66\xb2\x51\xe2\x67\xf6\x45\xfa\x82\x17\x70\x29\xaf\x32\x7c\xa6\xe9\xd6\x90\x0b\x78\xa2\xa6\xda\x00\x90\x45\xea\xc6\xc7\x54\xe1\x67\x9a\x8c\xb1\x56\xb6\x65\x3c\xf1\xae\xc6\x85\xea\xaa\x0e\xce\x9a\x48\x2d\xa9\x3b\x3e\x4f\x68\x6e\xa1\x3e\x35\x77\x14\xe3\xb0\xcf\x01\x62\x9a\xe7\x1f\x66\x41\xd2\x19\x82\x13\xd9\x47\xdc\xea\x5c\x58\xef\x0b\xc2\xda\xec\x42\xf8\x56\x94\x63\x60\x71\x6f\x09\x6e\x9a\x05\x2a\x83\xe4\x52\x38\xde\x11\xee\x48\x93\x72\xb4\xf6\x05\x5e\xf7\x92\x90\xab\xff\x39\x0d\x45\x93\xcb\x5c\x38\x52\xcf\xc9\x29\x9d\xa4\x19\xed\x3b\x74\xf5\x4a\x1c\x1d\xaa\x71\x7f\x25\xf6\xa0\x1a\xd2\x7a\x05\xfb\xbc\x81\x7c\xb5\x7e\x1f\x0a\x53\xb1\x79\x70\xc1\xc3\x56\x5e\x44\xc5\xe5\x88\x3c\x05\x15\xb6\xdc\x75\xa2\x5c\xb8\x34\x86\xa2\x5d\x7b\x93\x41\x93\xdc\xd9\x60\x10\x3b\x46\x51\x3c\x9d\xd5\x85\xad\xb2\xc2\x90\xee\x8c\xd1\x0e\x3b\x85\x70\xa4\xb5\xbd\x55\x40\x7c\xa5\xbf\xbf\x3f\x7c\xd3\x57\x58\xe6\xed\x69\x07\x96\xe0\x3a\x36\x27\x81\x1d\xcd\xb3\x47\x16\x41\x9e\x33\xde\x55\xcc\xb2\x74\x39\x9d\x99\x2b\x40\x0d\x44\xd0\x1a\xd4\xea\x5e\x4e\x6a\xae\xf6\x08\x4e\x4b\x1e\x99\xb7\x74\xc4\x12\x40\xbc\xed\x30\xab\xab\xa9\xed\x4c\xda\x8f\xa2\x0a\x48\x67\x3d\xca\x7f\x8c\x92\xa8\xa0\x16\xd2\xad\x6e\x80\x84\x88\x3a\x61\x4a\x59\x6e\x47\xd1\xba\x78\x27\x36\x15\xbe\x0e\xd8\x79\x29\x01\xee\x4f\x7e\xa1\xb6\x20\x35\xa5\x05\x44\x2c\x3e\x9c\x1c\x25\x91\x57\xdb\x05\x65\x8b\x19\x15\x3f\xd4\x82\x23\x45\xda\x53\xda\x29\xe5\x10\xdd\x1b\xb5\x51\xf5\x43\x55\xd3\xe1\x9d\xe9\x42\x11\x70\xdb\x95\x13\x9a\x65\x69\x26\x5d\xd2\xf0\x1e\xe7\x24\x49\x0b\x32\x4e\xb3\x8c\x8e\x8b\xd1\xb9\x5a\x37\x66\xaf\x8d\x05\xc4\x0a\x4a\x12\x58\xf2\x4c\xf8\xef\x19\xfc\xd7\x2f\xd2\x9f\xd3\x73\x9a\xed\x07\x39\xed\x00\x73\xe1\xfa\x5e\xcd\xc7\x18\xd4\x3f\xc4\x2d\xb3\xb8\xba\x39\x66\xff\x9f\xe8\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\x13\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\x6f\xd3\x3c\x8f\x4e\x63\x3e\x85\xe0\x42\x43\x18\xf5\xbd\x3f\x60\xf2\x65\x56\xf0\x9f\x4c\xa4\x96\xd8\x7a\x39\x99\x44\xd3\x4b\xf1\x71\x28\x49\xe9\x11\xf9\xc4\x9a\xe7\x7f\xfa\xba\x0a\x3e\xc5\xcd\x16\x07\x9b\x6b\x30\x75\xb9\xc4\x3f\xe5\x55\x14\x87\x9b\x6a\x38\x75\xff\xc3\x3f\xc5\x85\x91\xce\xe3\x05\x1e\x3d\x52\x0b\x53\xdf\xe3\xf0\x02\xbf\x05\xa7\xa9\x91\xe7\x29\x21\xef\x61\xf8\x00\xe0\xfa\x06\xe7\xf1\x12\xa8\x17\xa8\x30\xff\x14\x58\x40\x20\xc4\x82\x40\x1f\x70\x99\x22\x10\x42\x35\x0e\xa7\xe8\x77\x21\x7f\xdb\x22\x05\xe7\x0b\xd6\xc9\xf7\x4a\xc9\xe9\x9c\x1c\xc6\x41\xc2\x4e\x06\x81\x62\xcd\x22\x5d\xe8\xca\xd2\x8c\x04\xe4\xd5\xcb\x7f\xc2\x21\x5c\x4a\x6b\x77\xc6\x50\xd4\x3e\x2b\x8f\x76\xbf\xcc\xa8\xf4\xb3\x17\xa0\xab\x5c\x11\x05\x05\x05\x0b\x60\xeb\x29\xc8\xc9\x39\x65\x0b\x44\x3b\x58\x91\xc3\x58\x43\xd2\xd0\x2f\xd4\x38\x92\xcb\x71\x62\x96\xc2\x45\x1d\x56\xb3\x64\x12\x58\x28\xe2\x25\x70\xd4\x58\x93\x53\x71\xee\x64\xc9\x43\x78\x1b\x16\x15\x90\x67\x46\x23\x23\xfc\x85\x24\xab\xda\xe5\x1b\x70\x1c\x7b\x56\xf0\x39\x8d\xee\x17\xec\x7f\xcb\x12\x2f\xd2\xaa\x05\x8e\xce\x0b\xbf\xdb\x52\x67\xab\xed\x2b\x2e\x76\x40\xc8\xdd\x2c\xf5\x22\x9a\xd3\xfc\x6b\x2c\xf3\x44\x28\x17\xd9\xe2\x56\xaa\xaa\x9c\x1f\xf3\x61\x8b\x26\xca\x96\xc5\x21\x07\xd5\x93\x46\x44\xa1\xc9\x40\xde\x1d\xb2\xb9\xd7\xb4\x60\xd6\xa6\xbc\x5c\xe9\x0a\x34\x80\xc2\x3f\x36\xbe\xb1\x66\xa1\xe6\xfc\xf3\x0d\x13\x02\x61\xd9\xcb\xf2\xe2\xc7\xd5\x15\x19\xee\x78\x0f\x37\xa2\x5e\xe7\x70\xc2\xd3\x8d\x13\x91\xc0\xb9\xec\xc9\x83\x07\x44\xfc\xf6\x09\xfd\xac\x49\x3b\x17\x9f\x30\x7c\x3e\xd0\x0c\x59\x4c\x14\x56\x3a\x91\xe1\x45\xbb\xd7\x6e\xe3\x0b\x17\xcb\x53\x9a\xaf\x34\x26\x94\x52\x99\x2e\x91\xb1\x63\x3d\xa4\xa2\xe8\x84\x83\xc9\x28\x1e\xea\x28\x26\xcc\x26\x01\xb6\x38\x4f\xdb\x39\x19\xab\x98\x2e\x0e\x69\x99\x21\x5f\x9a\xd0\x57\x09\xd5\xa0\x43\xb2\x59\xa7\xa9\xf0\x32\x48\x86\x81\x9f\x22\xca\xf2\x2d\x58\x78\xf2\xdd\x41\x5e\xeb\x54\x01\xac\x92\xa8\x9d\xba\xd6\xe4\x96\x7f\x2d\x98\xe5\xfe\x22\x5e\xe6\xba\x0b\xe2\xdb\xeb\xde\x50\x01\x99\x9a\xa4\x19\x1d\x7f\xca\xe5\xb1\x89\xf3\x48\x79\xcd\x99\x8b\xc7\x72\xf1\x25\xf8\xf1\xf5\x46\x23\xe6\x24\x3f\xf6\x46\x22\x36\x63\x0a\xa3\x06\xd8\xfa\x0f\x34\x3c\x76\x6c\x07\xc1\x95\xc4\xcc\x59\x75\x1b\x13\x27\x2a\xb5\x34\x68\x83\xff\x0c\x2f\x8e\x87\x8f\xbe\x0b\x1e\x4d\x4e\x3e\x3f\x1e\x5e\xff\xcf\x20\xea\x17\x34\x2f\x14\xf8\x0a\x63\xaf\x18\xf2\x97\x19\x6c\x83\x61\xc2\xf9\x7f\xf0\x9f\xce\xf0\xa2\xfb\xac\x72\x9c\x98\xfe\x06\x03\x1d\x2b\x8b\x47\xc3\x82\xde\x71\x0f\xc2\xc2\xe8\x70\x0e\xef\x78\xd9\x7e\x8c\x46\x6d\xd2\xaf\x70\x04\x48\x4c\x57\x15\xde\xce\x98\x7d\x61\x6c\x0e\x81\xed\x3d\xfa\xd1\x0b\x66\x75\x19\x42\x77\xb5\x73\x70\x76\x9c\xcf\xd9\xbf\xe3\x60\x91\x83\xec\x10\xc7\x44\x7e\xf7\xb0\x87\x46\xbb\xc7\xdc\xf1\x3c\xea\xb0\xd1\xc0\xa1\xda\xde\x39\x76\x68\x30\x9e\x91\x71\x90\x3b\xd5\x44\x39\x27\x94\xe5\x5c\xcc\x10\xa2\x26\xbe\xca\x9a\xd3\x14\x6f\x2b\x5f\xce\xe7\x34\x2c\x25\x2f\xab\xb9\x3b\x26\x33\xab\xf6\x2a\x72\x1b\x0c\xf8\x78\x2c\xdc\x04\xaa\xa4\xf8\xe5\xec\x40\x5a\x1f\x22\x20\x5e\x05\x39\x38\xa3\x99\x05\xdb\xb2\x11\x53\x97\x22\xa5\x1d\x9f\xc3\x97\xc7\x43\xb8\xa3\x24\x16\x85\x80\xf3\xee\x62\x46\x62\x0a\xcf\xa9\x51\x04\xbe\xc5\x82\x66\xac\xb7\x72\x1a\x12\x88\x5e\x38\x8d\x78\x80\xbb\x20\xa7\xf3\x60\xc1\xa6\x63\xd3\xd0\xf4\x75\x94\x05\x03\xea\x34\xb8\x65\xdb\x7c\xd2\x25\x3f\x90\x6f\xd9\x76\x2e\xb2\x8e\xa3\x93\x7e\x91\x1e\xb1\x86\x84\x2e\x68\x7d\x77\x17\x65\x02\xd1\x57\x57\xf8\xfd\xae\xa7\x46\xac\x5d\xb2\x6a\x2c\xf1\x15\x8e\x96\xa5\x66\xf9\x06\xe3\xd7\xf1\x17\x14\x95\xbe\x16\x47\x3d\x49\x8d\x25\xa4\x58\xa4\x77\x49\x8a\x52\x7b\xad\xf6\xe5\x15\x28\x11\xe9\x8c\x15\xf5\xd9\xaf\xae\x45\x3b\xed\xb6\x20\x25\x97\x4c\x0d\xfc\xde\x88\x68\x11\xd0\xd8\xe9\x3d\xab\xa8\x82\x8c\x65\x2f\xd0\xb5\xbb\x4d\xd2\xc0\xf4\x66\xda\xf4\x8f\x11\xe9\x77\xec\xe0\x33\xe1\x0e\xf4\xe5\x4d\x9c\xa2\x70\x83\x80\xeb\xe8\xd7\xa4\x20\xbb\xff\x1b\xbb\xa5\xc4\x8d\xc8\xcb\x66\xa4\xb5\x35\x55\x92\xa6\x55\xd2\x94\x3c\xb5\xa4\x69\xb0\xd1\x22\x65\x12\x65\x14\x92\xad\x21\xf7\x19\xf4\x48\x5c\x10\xf2\x36\xf9\xfb\x84\xe1\x05\xe1\xc6\x1d\xae\x71\x57\x2d\x25\xfb\x6f\xfb\x85\xf7\x01\xcc\xb5\x95\x01\x57\x33\xfa\xb5\xc4\x19\xef\xc6\x27\x9d\xea\x4a\x7c\x20\x19\x9e\xef\xb6\x55\x1b\xad\xa7\x22\x71\xf9\xe5\xab\xcf\x84\x90\xa1\x17\xe1\x4a\x49\xd5\xa8\x5f\x53\xf5\xc8\xe3\xa1\xff\x96\x40\x3a\x22\x96\xa7\xe9\x5c\x4b\xb9\xf5\x41\x36\xbd\x27\x49\xdf\xd5\x97\x11\x78\x93\x6f\x64\xbe\x33\x20\xe9\xf0\x6e\x58\x72\xa1\xec\x5b\x92\x17\x41\x32\x66\x5c\x44\x17\xbe\xba\x52\x48\x13\x85\xe1\xf5\x1a\xfc\x32\x1c\x67\x78\x53\xb9\x6d\x04\xf0\x22\x55\x65\xbb\x29\xa2\xe4\x79\xb8\x0e\x4b\xef\x1d\xe3\xa2\x86\x28\xf2\x84\x48\xf2\xe2\x47\xb0\x56\xd1\x33\x18\x0d\xef\x5b\xfb\xee\xd0\xc3\xfb\xd2\x18\x37\xb2\xc7\xf5\xd8\xf9\x51\x1b\x91\xac\x8a\x1f\x59\xf4\x46\x18\x92\x25\xda\x0d\x47\xc4\xfa\x54\xd4\x0f\x87\x77\xfd\x06\x83\x39\x14\x7d\x6b\xb8\x18\x98\x78\x91\x2c\xe3\x18\xa2\x24\x74\xdc\x15\x02\x86\xdb\xa0\xc2\xf0\x8c\x5d\xdc\xd7\x36\x1c\xf9\x29\xef\x6c\x03\x76\xc0\x01\x6f\xc2\x0c\x78\xd2\x8d\x26\x52\x74\xaf\xe9\x68\xc0\x05\x60\xfd\x58\x9c\x88\x1a\x0d\x47\xe2\x46\xc5\x68\xc8\xd2\xa0\x60\xe5\x18\xec\xe3\x08\xdf\x47\xc1\x46\x2e\x95\x54\x67\x0e\xe2\xef\xb9\xb9\xae\xb4\x05\x42\xe5\x18\x58\x31\xfb\xd5\x80\x72\x9d\x94\x5d\xba\xfb\xd4\xfa\x3a\xdc\x4c\xf2\x67\xb8\xda\x98\xf5\x9a\x8c\x21\xec\x53\x87\x7a\xf6\x36\x7c\x20\x5d\x65\xd4\x81\x18\xf7\x4b\x36\x81\x74\x39\x27\xa7\x71\x3a\xfe\x44\x66\x34\x08\x69\xc6\x3e\xd2\xb9\x6d\xb5\x11\xe5\xcf\x59\xb2\x4f\x68\x98\xd1\x0b\xe5\x17\x1d\xca\x92\x49\x14\x17\xb6\x32\xd3\x43\xb0\x00\x6b\xb8\x1f\x66\x29\x95\x27\xfd\x6f\x36\xb7\xf4\x51\x9f\x83\xd7\xe0\xa5\xfc\xa0\xce\xeb\xc2\x55\xf9\xce\xe9\x2e\x94\x2f\xe2\xb0\x3e\x67\xaf\xb9\xfd\xb8\xc1\xcc\xc4\x29\x13\xf3\x16\xd1\xd8\x9d\x87\x0f\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\x1c\x8f\x08\x91\x6f\x24\x7f\xf4\x64\x2a\x3c\xfa\x19\xa9\x5f\x3c\x1d\x04\xc3\x11\xff\x4f\xa6\x08\x0b\x92\x91\xfe\xc9\x73\x90\x75\xc9\x08\x7f\xc8\x72\x47\xc5\xe4\xe9\x48\xfc\x2f\xd3\xc0\x5e\x65\x24\x7f\xe8\x7a\x38\xac\xfc\xa5\xd3\x05\xbc\xfa\x29\xea\x71\x8d\x6e\x47\xbe\x44\x0e\xed\xda\x72\x8e\x3c\x69\x06\xac\x34\x9b\x1c\xd9\x09\x72\x1c\xbf\x50\x18\xc5\x2f\x14\x8d\x01\xd2\xc4\x0f\x09\xa7\xa4\xc5\x11\xfe\x90\xb9\xa6\xca\x7a\xe4\xa4\x28\xac\x71\x41\x7d\xa4\x7f\xf2\x1c\x24\x1d\x8f\xf0\x87\xcc\x35\x4e\x22\x23\x3b\x41\x42\xa1\x7c\x2b\xc7\x3a\xba\x8f\xdc\x24\xd9\x43\x07\xd2\x49\x92\x75\x4a\x61\x6c\x84\x7e\xe3\xfe\x26\xd3\x91\xfa\x25\xd3\xf9\x9e\x3a\x52\xbf\xd4\xe8\xf9\x7a\x1f\xe9\x9f\x6a\x4c\x6c\x97\x1c\xc9\x1f\x32\x95\x6d\x58\x23\xf1\xbf\xaa\x83\xf1\xbb\x91\xfc\x21\x53\x81\x6d\x8c\xe4\x8f\x1e\x2c\x30\xee\xa0\x4e\xbc\xea\x6e\x8d\x36\xbf\xeb\x55\xfa\xb7\xe9\xb5\x96\xc5\xe4\x69\x6b\xf4\xf4\x9b\xeb\x93\xde\xd6\x66\x13\x8f\x0f\xe6\x12\xde\xe5\x0b\xb8\x25\x1c\x1d\xb4\x46\xa4\x35\xec\x6f\x0d\xfb\x9b\xad\xb5\x6b\xe9\x0a\x6e\xab\x51\xa4\xe2\x7b\x4f\x12\xf7\x9e\x24\xfe\x0a\x9e\x24\x44\x2d\x6b\xae\x2f\xb8\xbf\xd3\xc9\x24\xa3\x97\xe4\x97\x28\x1e\x7f\xa2\xe4\xfb\x5f\xe9\x64\x62\xbb\x93\x68\xe8\x31\x0e\xc0\xa2\x20\x21\x87\x4c\xe2\x0e\x00\x2a\x0a\x12\x17\xec\xc7\xe0\x94\x81\xfd\x23\x9d\xd2\x38\x2f\x68\x1c\xd3\x8c\x7c\x3f\x81\x44\x17\xf8\xa7\xe0\x8c\xfc\x92\xa6\x21\xf9\x7e\x5a\xea\xe6\xe2\xb1\x76\xef\x23\x7c\x41\xbe\x0e\x92\x60\x6a\xfa\x9e\xe8\x0f\x18\x16\x06\x19\x07\x98\x73\x00\xe9\x63\xe2\xe0\x14\x0e\x47\x36\x70\x74\x1a\x24\x12\xe4\x25\x98\xf1\xdb\x10\x5c\xf2\xca\x07\xb4\x98\x49\xc0\x17\xcf\x2b\xe0\xc2\x53\xe5\x6f\x76\x56\x55\x5f\x3e\x53\xf5\xbd\x01\xcf\xe4\x65\x80\x09\x2d\x24\xe0\x5b\x9a\xe5\xf0\x94\xaa\x1c\x7a\x21\x40\x54\x27\xce\x83\x6c\x5e\xd5\x0d\x96\xaf\x80\x69\x51\x40\xd4\x26\x17\x3e\x17\x59\x12\x54\x72\x15\x03\x52\xb2\x0b\x76\xa2\xd2\xce\x3d\xa2\xd8\xaa\x10\x85\x95\x2f\xf7\x11\xc2\x81\xa4\x37\x26\xf1\x70\x83\x26\xa1\xa7\x6f\x3c\x43\x82\x3d\x87\x13\x93\x0b\x75\xca\xd2\x15\x26\xb3\x74\x41\xb3\xe2\xd2\x03\xb7\x10\x59\x12\xf4\x55\x51\x2c\xde\x66\xe9\x59\x14\x7a\xc9\x8d\x2d\xd4\x85\xc8\x56\xc4\xb6\x18\x57\x94\x88\x16\x63\xbb\x40\x33\x8f\x86\x6b\x6b\x4a\x56\xff\x85\x9e\x6e\x93\x8e\xac\xc6\xf4\xca\x9b\xd9\x2b\x24\xa1\xe7\xd6\xb2\xd1\x25\x91\x83\x5e\x11\x6a\x15\xf5\x5c\x42\x21\x20\xca\xdf\xba\xd0\x73\xb6\x5c\xc0\x51\x3f\xae\x22\x3c\x15\x99\x2f\x9e\x3b\x79\xf9\x4c\x96\x7c\x3f\x73\x4b\x26\xb0\x06\x58\xee\x1b\x5a\x38\xb9\x0b\x4d\xf8\x0c\x44\xae\x03\x07\xee\xf4\xb7\xdf\x64\x1b\x8c\xae\xdd\x3e\x68\x02\x07\x20\xf1\xd9\xc1\x30\x9a\xb2\xf5\x51\x23\x58\x44\x23\xb5\x19\x8a\xff\xf9\x91\x03\x77\x52\x60\x2b\x37\x8a\x62\xf2\x19\x19\x5f\x3d\x05\x83\xe8\x65\x84\x3f\x9c\x26\x3e\xaa\x35\xc0\x7f\x38\x03\x14\x00\x1d\xdd\xbe\x20\xe7\x88\xe6\x23\xf4\xbb\xc3\x8d\x79\xae\xbb\x3b\x4c\x62\x1a\x0c\xc0\x05\x6f\x4e\x89\x1e\x43\xca\x77\x62\xf0\x09\xb4\xc6\xc8\xcd\x33\xbe\xba\xb1\x95\x8e\x8b\x09\x8d\xb2\x4e\x19\x4f\x93\x62\xca\xc3\x31\x83\xeb\x69\x1c\x17\x5e\x99\xb4\x3d\x7d\xc9\x28\x0f\x16\xa1\x7b\xf1\x89\xd2\xc5\x41\xfe\xfe\x32\x19\x47\xc9\xb4\xb2\x2b\x50\xd6\x82\x6f\x46\x81\x9e\x8e\x60\xbe\xf0\x5c\xdb\xaf\x58\x50\xf2\x19\x0c\x77\x27\x05\x5f\x1e\x18\xf9\x64\x56\x42\xc1\xb7\x07\x4e\xbc\xbb\x96\x60\xec\xd3\x81\xc2\x4f\x70\x39\xa0\x4a\xf1\xc2\x1a\x75\xca\x04\x4f\xdb\xfa\x3d\x95\x6c\x5e\xa4\x78\x6b\xb5\xa1\x51\x9a\xa7\x6e\x8c\x4b\x59\x7b\x15\x4e\xb9\x89\xa3\x84\xfc\x85\xfa\x47\x86\xa1\xc4\xb7\x03\x87\x4d\x5b\x38\xa4\x4a\xf1\xc0\xba\xb7\xc2\xb2\xcc\xbe\x7d\x5b\xe8\xf4\xb9\xac\xac\x93\xe3\x69\xf7\xe0\xf9\xde\x1b\xd4\x18\xfb\x74\xa0\xb4\x7b\x1a\x0e\x26\xbe\x7d\x70\xd2\x73\x8a\x02\x84\x04\xb6\x8b\xd9\x0b\x9f\x6f\xfd\xf8\x25\x37\xbf\x14\x32\xbd\x2b\x9a\xd7\x75\x70\x27\x6d\x43\x96\x5d\x9f\x86\x51\x06\xaa\xe2\x71\xb0\x80\xd7\x17\xe8\x02\xd3\x33\xa3\x07\xfb\x7b\x6f\x8d\xb5\xcf\xca\x61\x0b\xb9\x88\x8b\x92\x6c\xf9\x32\xa9\x92\xe7\x1b\x8f\x3d\x19\x44\x5f\x34\x23\x57\x36\x38\x94\x51\xfc\xb7\x2a\xe2\xe8\xb1\xe2\xdd\xb0\xd7\x09\x71\xa4\x63\xde\x39\x27\xa0\x83\x69\xcb\x3d\x29\x49\x43\xda\xee\x19\x10\x53\x30\x0b\x19\x91\x36\x13\x3a\x3e\x8e\xe3\x88\x26\xc5\x3f\x38\x78\x5b\xdf\x49\x77\x7b\x37\x69\x8d\x16\xe7\x69\xf6\xa9\xac\xc1\x84\x16\x1f\x05\xa8\x05\x62\x06\x0c\x18\xd9\xab\xfc\x96\xdd\xa2\x42\xa1\x5d\xd6\x2f\x5a\xcc\x3e\xc2\x5c\x8f\xd3\xf8\x1f\x5f\xa1\x7f\xe7\xb3\x28\x5f\x28\xdf\xc8\x4e\xf7\xf2\xd9\xec\xd6\x68\x83\x9f\x27\xde\xbd\x24\xca\xf7\xd3\x24\xe1\x3e\x9b\xd0\x72\xeb\x1a\xb4\xd7\xf1\x6e\x97\x0f\x1e\x78\xb7\x51\x5c\x65\xa7\xeb\xdf\xc1\xb8\x97\x02\x29\x93\x97\xd2\x3c\x18\x87\x42\xe4\x04\x21\xd1\x78\xf5\xb6\xac\x6e\xe9\x4d\x14\x9f\x10\xb8\xca\xc9\x38\x58\xb4\x46\x5b\x43\x96\x84\x8f\x24\xad\xd1\xd6\x26\x4b\xd3\xc7\x81\xd6\x68\xeb\xb1\x4a\xe1\xa2\x53\x6b\xb4\xf5\x54\x25\x61\xe1\xbe\x35\xda\xde\x52\x19\x6c\x85\xb7\x46\xdb\xdb\x3a\x41\x0b\xf5\xad\xd1\xb6\xae\x54\x1f\x0b\x5b\xa3\xed\x6f\x9d\x64\x5a\xcc\x5a\xa3\xed\xa7\x4e\x7a\x42\x8b\xd6\x68\xfb\x3b\x27\x5d\x0a\xc2\xad\xd1\xe3\xa1\x93\x99\xcf\x66\xad\xd1\xe3\x4d\x37\x9d\xc9\xc2\xad\xd1\x63\xdd\x7d\x79\xc6\x69\x8d\x1e\x7f\xa3\x12\xcd\x83\x73\x6b\xf4\xf8\x89\xca\x92\x52\x4b\x6b\xf4\xf8\xdb\x6a\xdd\xde\xf5\x49\x6f\x6b\xfb\x5e\xf3\x76\xaf\x79\xfb\x6f\xd1\xbc\x05\x71\x0c\x0e\x26\x6e\xe7\xc7\x15\x29\xb8\x1c\x55\x88\x4f\x17\x22\xc3\xc4\xbc\x3c\xe3\x16\xfd\x48\xc7\x00\xbd\x91\x70\x3a\x68\x4c\x5d\x74\x24\x57\x4f\xe3\x55\xd4\xfc\x08\x97\xbb\x56\x65\x90\x26\x21\xce\x79\xec\x23\x13\x44\xb2\x22\x91\xa9\xbc\xbb\xee\xc5\xb1\x31\x14\x53\x30\x32\x8f\x56\x3d\xb8\xa9\xef\x11\xcb\xb4\xac\x44\xe9\x61\x26\xe0\x23\xf2\xaf\xfc\x72\x9e\xfd\x87\x93\x1d\x73\x49\xbe\x09\x39\x3d\xac\x0e\xf3\x6d\x49\xad\xd2\x1f\xf8\xae\xfa\x75\x75\x05\xf1\x6f\x88\xed\xf7\x81\x25\x42\xea\x71\x9b\x49\xa1\x10\x57\xa0\xdd\x23\xed\x22\xe5\x3f\x4f\xfa\x1c\xcd\x28\xde\xe1\xc4\x73\x1b\x2a\x9a\x39\x9e\x9c\x80\x81\x8b\xb2\x0f\x15\x37\xa4\x5d\x4f\xd0\x6c\xab\x1a\xd6\x1f\x56\x7c\x17\x11\x0f\x77\xa1\x03\x1d\xe1\xe7\x25\x1d\x04\x4f\x37\x28\x6d\x16\xf4\xc3\x2d\xf0\x45\xa1\xf1\x6a\xe0\xd9\x7c\xdd\x85\xbd\x53\x54\x61\xdc\x13\xb5\x38\x0c\x8a\x40\x8e\x80\xfd\xee\xb3\x7f\xc8\x2e\xfa\x7d\x75\x05\x46\xb1\x0a\x00\xae\x92\x73\x09\x22\xbe\xae\xae\x74\xf4\x4d\xd0\x36\xb2\xa6\xe5\x1d\x39\x02\x3c\x1e\x9e\xf4\x73\xc6\x10\x94\x8b\x75\x06\x3d\x17\x02\x8e\xa6\x30\x77\xba\x7e\xf5\x4c\x17\x6e\x65\x57\x98\xda\x0a\xe9\xce\xbd\xb4\xed\xfc\xaa\xde\xa7\x77\x8f\x87\x27\xe8\xe1\xd5\x3a\xb4\xdf\x25\x9f\xe1\xb1\x43\x90\x24\x69\x41\x26\x51\x12\xf2\x7e\x45\xc9\x94\x37\xf4\x4c\x35\x3f\x4e\x93\x3c\x8d\x69\xff\x3c\xc8\x92\x4e\x1b\x97\xe0\xde\x72\x18\x2b\x8e\xd3\x69\x1b\x99\xbe\x8a\x1e\x33\x54\x38\x1e\x97\xa8\x60\x43\x38\x32\x17\xcc\x5d\xc7\xb7\x3a\x7b\xbc\x5b\x3d\x93\x20\xcc\x23\x14\xd4\x28\x9d\x1d\xc2\x14\x37\x58\x8e\x17\x74\xcc\x24\x00\xcf\x7a\xec\x81\x47\xa6\xd3\x60\xfc\x49\xc5\x10\x05\x57\x04\xe2\xb0\x2b\xaf\x5b\x3b\x41\x36\x5d\xc2\x5b\x90\x63\xf5\x0b\x79\xe3\x31\x8d\xd0\x65\x8d\x10\xfb\xb9\xb2\x18\xf6\x1b\xd7\x71\x20\xd8\xc4\x6f\x9a\x7e\x2c\x34\xdb\x48\x96\x71\xec\xa0\x3b\x95\x94\x26\xbc\xdf\xe9\x03\xb0\x84\x98\xa0\x28\x6b\x5c\x33\x0b\x98\xec\x9f\x46\xa6\xd2\x10\x89\xdf\x9c\xb3\x77\xd2\x1e\x1c\x94\xda\x3d\x2f\x63\xed\x49\xf6\xce\x0e\x5b\x9d\x6e\x4f\x37\x84\x30\x5c\x3f\x53\x41\x51\x04\xe3\xd9\x87\x74\x5f\x3a\xc2\xc2\x53\x26\xbd\x63\xe1\x33\xb7\x9e\x5a\x3e\x6e\xfe\xe9\x0c\x47\x16\xed\x07\x71\xac\xf6\x13\x01\x5c\x72\xa6\x70\xba\xa9\x0e\x18\x9e\x13\x86\xf7\x88\x01\xa4\xda\x1a\x6d\x81\x74\xcf\x57\x7d\x6b\xb4\x05\xb2\x3b\x8e\xd9\xb6\x0d\xc0\xd6\x46\xd8\x1a\x3d\xde\x66\x22\xf3\xe3\x7b\x91\xf9\x5e\x64\xfe\x6b\x8b\xcc\x28\xdc\x0b\x9c\xbd\xef\x2a\xde\xcb\xdf\xf3\x34\xc9\x16\x63\x53\xde\xfc\x95\x27\xaa\xab\xc3\x2c\x4b\x6d\x11\x98\xa7\x29\x49\xd4\x55\x51\xb0\xc1\x1a\x42\xa6\x23\x63\x02\x3a\x3e\x96\x4a\x9a\x22\x23\x17\x81\xbd\x6b\x1c\x05\x06\x61\x28\x7d\x3a\x32\x76\x2c\x0a\x83\x9b\x6c\xe8\x9a\x48\xb0\x2c\x02\x83\x30\xf4\xd8\xd8\x12\x31\x7e\x5e\xa8\xd0\xd6\xad\x83\x35\x18\x27\x66\xc5\x61\xe8\x93\xb9\x7d\x03\xcf\x79\x54\x70\x09\x51\x3b\x22\xc9\xb4\xab\xfa\x2f\x60\xbc\x5d\xf3\xed\xe7\xa6\x77\x01\x85\x5f\xa3\x9b\xee\x14\xe8\x7b\xa2\x24\xe4\x6a\x26\x09\xdb\x43\x75\xd3\x2c\xeb\x09\x49\x34\x77\x65\x62\x4e\x3e\xfc\x97\x10\x16\x35\x80\xc0\x0f\x76\x31\xa9\x50\xd9\x23\xf0\xba\xbd\xe4\xfd\x9a\xa8\xf2\x18\x60\x4e\xf0\xf1\xa0\x54\x60\xe7\x45\x4a\xaa\x65\x62\x8d\xec\x8f\xa8\xb4\xef\xc8\x3e\x76\x81\x75\xb1\x88\xfa\x51\xfe\x8f\x20\x8e\xc2\x77\x34\x5f\xa4\x49\x4e\x45\x53\xce\xdb\x3b\x67\x0c\xfe\xf6\x3a\x7c\x8d\xf5\x0f\x92\x33\x6f\xad\x3b\x4e\xa5\xd7\x6e\xff\x4a\x2b\xe7\x3e\x9b\x9c\xc1\xf2\x3d\x17\x7c\x43\xf8\x32\x44\xe3\x7d\xd1\x07\xf0\x1a\x81\x13\x9c\x28\xf6\x7a\x2a\xd4\xf9\x86\xf8\x45\x09\xa0\x2c\xad\x9f\xe4\x83\x6f\x8d\xb6\x40\x8f\x26\x56\x64\x6b\xb4\x0d\x56\x6f\x8d\xa2\x7c\xdf\x6f\xf8\xf7\x1b\xfe\x9f\x77\xc3\xd7\xfb\xbd\x12\xcb\xef\x48\x45\xd6\x50\x57\xc5\x4e\x3c\x99\x05\x96\x0b\x59\x7f\x00\x99\xab\xaa\xd3\x24\x1c\x7a\x37\x85\xf5\x60\xf2\x41\x94\x80\xde\x43\x87\x10\x04\xa6\x34\x86\x46\xc8\x71\xdf\xfe\xc9\xd5\x4b\xf8\x91\x19\x6c\xf3\xf6\x33\x65\x0e\xb7\xaf\xc1\xde\x4a\x28\x25\x17\x80\xb1\xef\x35\x91\xbe\x9c\xcd\x54\x6f\x03\xc2\xdb\xaf\xbf\x6a\xf3\xa9\xe7\x69\xd4\x13\xe5\xac\x5b\x9d\xe0\x34\xf2\xa8\x41\x90\xdf\x67\x62\x39\x5a\xe6\x01\xbe\x77\x77\x49\x1b\xf5\xa9\x4d\x1e\x3c\x30\x1c\x39\xa3\x73\x33\x6f\xd6\xf0\xf6\x7f\xdd\xb5\xb6\xe1\xaa\x06\x3d\xae\xa1\x49\x07\x12\x4b\xb6\x6b\xc8\xe3\x1e\xa3\x3d\x3b\x83\x55\x11\x03\xcb\x3d\x4d\x03\xed\x89\xc3\x3b\x47\x28\x07\x55\x68\x44\x5a\x1e\xa9\xbd\x6a\x20\x3d\xaa\x80\x5e\xc2\x55\x14\x3f\x5a\x7b\x5f\x36\x05\x61\x28\x69\x38\xd7\xc7\x70\x4c\x1b\x32\xed\x5a\xd5\x54\x4a\x4f\x9c\x54\xfc\x55\x56\x9e\xec\xf5\x71\xfd\xe6\x84\x82\x5e\x21\xae\x32\xfb\x58\x53\xa5\xb4\x3f\xaa\x3f\x1f\x69\x31\x93\xea\x66\xdd\x49\xd3\xeb\x45\xad\x2a\x75\xe2\xa8\x39\x34\x02\xb4\xaa\xb4\xc1\xbc\x72\x6e\xd1\x68\x52\x39\xbf\xb9\xbb\x19\xb5\xeb\xab\x57\xd4\x48\x86\x77\x17\x73\xcb\x79\xaf\xa5\x56\x16\x9c\x55\x68\x1b\x15\x8f\x35\x27\xcf\xd5\x5b\xf1\x8e\x95\x4e\xe7\x5e\x1c\x57\x4e\x17\x00\x89\x8b\x9e\x95\x09\x8c\xab\x42\x6b\x3a\xb8\x3a\xb5\x19\x8f\x02\x5d\xa5\x5a\x19\xb5\x55\x91\x9b\x72\x94\x03\xb6\x7f\x72\xd2\xa7\xb4\xc8\x85\xf1\x4a\x7c\x49\x42\xba\x88\xd3\x4b\x1a\x4a\x13\x41\x78\x3e\x38\x9e\x05\x51\x62\x3f\x57\x83\xda\x7e\x4c\x33\xd9\x23\x8f\xef\x01\x79\x60\xf5\x91\xa4\x5c\x97\xd7\x4a\xb5\xb8\x66\xb8\xc8\x3d\x92\x97\x1b\xfa\x59\x5b\x49\x8b\xd8\xe0\x41\xb6\x84\x14\x96\x9a\x7c\x21\x60\x33\x44\x92\x71\xd4\xbc\x3f\x42\x94\xf2\x5d\xf9\xb0\x0c\xf2\x07\x03\x72\x1e\x44\x5c\x5d\x0e\x22\xd7\xa2\xd0\x2a\x58\x79\x53\x66\xce\xbb\x58\x0a\x2a\x60\xb4\xee\x18\xed\x9a\x9e\x97\xd7\x29\x3c\x4d\x36\xda\xb7\x77\x25\xe8\xef\xc6\xc6\x8e\x79\x6c\x1a\x0c\x48\x5e\xa4\x0b\xae\xab\x8d\x92\x29\x09\x26\xac\x2b\xdf\x0c\xf9\x5c\xe5\xa4\x53\x44\x73\x9a\x2e\x8b\xae\x73\x74\xe4\x08\xf8\x81\x7c\x33\xf4\x1e\x16\x79\xef\xfb\xac\xf6\x5f\x44\xe5\x3a\xa6\x42\x97\x7c\xbe\xf6\x9c\xe9\x6c\x04\xf2\x07\x7b\xde\x73\xa8\x9a\x11\xef\x69\x53\x9f\xfc\xb4\x63\x60\xc5\x98\xe0\xbe\x24\xe0\x2b\x63\xcc\x08\x1b\x9c\x04\x9f\x32\x89\x79\x99\x84\x36\x06\xda\xbe\xc3\x27\x8d\x91\x43\x11\xfc\xe7\xb8\x23\xbe\x71\xab\x6c\xf9\xe1\x9a\x95\x3f\x11\x17\x6b\x06\xd5\x4c\x69\xf1\x41\x37\xf5\x8e\x93\x9a\xe6\x28\xa8\x1b\xaf\x82\x7c\x86\x89\xaa\x27\x09\xb3\xeb\x3f\xc2\x47\x93\x8e\x00\xf0\x53\x9b\xb7\x90\xb7\x83\x10\xc2\x48\xd4\xd5\x1f\x9b\x0b\xd0\xec\x11\xc4\x39\xf2\x77\x47\xfe\x95\x79\x6f\x7f\xa2\xbc\xb7\x97\xfd\x45\x93\x8e\x49\x71\x57\x57\x64\x1d\x5a\xac\x2c\x46\x14\xeb\xf6\xd0\x26\xfe\xbb\xc9\x12\xc0\x7f\x0d\x97\x83\x3d\xa4\x34\x44\x21\xa2\xb7\x2b\x67\x46\xfe\x0d\x06\xea\x9e\x2f\x4e\xa7\x88\x6a\xe1\x58\x21\xd9\xf8\x7a\xbb\x5b\xd3\x3c\x31\x44\x35\xc5\x51\x4b\xa6\xba\x41\x65\x83\x01\xe1\x9b\x95\x14\x17\x82\x24\x24\xe2\x66\x84\x04\xd3\x20\x4a\xc4\xca\x39\xa7\x22\xc2\x5f\xcd\x9f\x5f\xf6\xb4\x37\xc0\x9a\x1a\x6c\x59\xc7\xd9\xfe\x6b\x86\x34\xe6\x4e\xd9\xc4\xa5\x20\xdb\x12\xd8\xee\x98\xd3\x71\x9a\x84\x84\x31\xdc\xda\x4a\x10\xe9\xd6\x13\x2b\x31\x38\x22\xe8\xc2\x9a\x76\xd8\xeb\xc5\xe8\x8e\x3b\x84\x7d\xb7\x23\x51\x42\x9c\x68\x11\xa7\xcc\x8b\x34\xa3\xa1\xf2\xe3\xce\x25\x10\xd0\xf8\x4c\x83\x9c\x04\x73\xb6\x21\xf5\xbd\xfc\xda\xfe\x2b\xe5\xdf\xf6\x9f\xc7\xbd\xfc\x5d\x74\xb1\xba\x87\xd7\xa5\xb9\x65\x1c\xc3\x2d\x61\x43\x22\xed\x64\xd3\x03\x05\xba\x62\x90\x84\xfe\x63\xc0\x8e\xd9\x97\xca\x97\x86\x25\xc5\x59\x60\x35\x87\x06\xbb\x52\x7c\x60\x80\x53\x55\x70\x1a\x19\x97\x0b\xfc\x45\x11\x95\xc7\x77\x48\x0b\x4e\x23\xb2\xcb\x20\xa5\x9c\xf5\x90\x6b\x42\xeb\xc7\xa4\x4f\x48\x09\x09\x90\x68\x2a\x8a\xcb\x5a\xe4\xd8\x12\x7a\xae\x92\xe4\x98\x92\xcb\x6b\x4c\x0c\x96\x6e\x64\x53\xda\x14\x04\x71\x77\xc5\xa2\x5b\x15\x45\x6d\x39\xd8\x90\x2c\x84\xaf\x13\xa9\x28\x0e\x9d\xd2\x3e\x49\x59\x40\x28\x69\x59\x1f\xff\x64\x92\x6a\x4b\x4f\x3c\x14\x1a\xe8\x89\x60\x28\xf5\x5d\xbf\x90\x8a\x2d\xfa\x5b\x59\x03\xfb\x53\x3f\xb8\x74\xad\x4e\x91\x98\xfe\x3a\x92\x0e\x7a\x6a\xf6\x31\x07\x1b\x0c\x78\x6c\x45\x6d\x65\x61\x54\xaa\x6d\x25\x3e\x5f\xef\x30\x60\x89\xa5\x75\xb3\x6d\x81\x18\x54\x31\x9c\x71\x33\x78\x8b\x03\x84\x8c\x1f\x25\xc4\xd1\x98\xc2\x55\x83\xb6\xd7\xb0\xc2\xff\xf9\x6c\x47\xc0\xfe\xa3\xdc\x62\x84\x38\x56\x23\x79\x7f\x91\x2e\x0c\x07\x73\x66\xf7\xe2\x20\x2f\x04\xa4\x53\xb5\xbf\x3b\x9c\x90\x3a\xac\x20\x38\x2f\x5a\x57\x2f\x4e\x20\x10\x2d\xa4\xdb\x7d\xd2\x28\xac\xe9\x12\x6b\x48\x00\xf7\x79\x54\x92\x1f\xc8\xd0\xae\x4d\xcc\xb4\xa4\xfd\x3d\xb9\x96\xeb\xb5\x00\xf2\xef\x56\x2a\x41\x84\x26\x8b\x59\x4a\x75\x9a\x32\xb5\xc3\xc3\x5a\x37\xbb\xdc\x5f\x04\x97\xc1\x69\x4c\x7d\xdd\x73\x8f\x03\xdc\x7e\x2a\xa7\x49\xa8\x23\x52\x25\x69\xf2\x48\x54\x82\xd1\x61\x6f\x13\xd7\x65\x53\x0f\xbe\xfd\x18\x67\xf4\xab\x60\x3b\x72\xa9\xf4\x60\xc4\xa8\x56\x39\x41\x60\xfb\xb6\xb1\xcb\x2b\xda\x31\x27\xb1\xf4\x46\x10\x9f\x68\x0d\x1d\x80\x94\xfb\x82\x30\xb1\xb5\x04\x21\x25\xe7\x41\xae\x04\xca\x35\x13\x57\x7c\x69\xc3\xd5\x2b\x3a\xc2\x68\xc3\x2c\xeb\xfe\x75\x16\xe4\x33\x1f\xd2\x59\xaf\x69\x96\x95\xdd\x44\xe2\x2b\x47\xdf\xbd\x62\x95\xc4\xc3\xc4\xd1\x30\xe4\xd7\x5e\x88\xeb\xb2\x9e\xf8\xdb\x2a\x39\x76\x91\x5d\x28\x53\x22\x7c\x95\x4a\x88\x93\x28\xcb\x8b\x72\x01\x71\x45\x19\xaf\x44\x03\xe2\x53\x7b\xf8\xae\x5f\x8d\xaf\x3a\xc7\x97\x10\x69\x93\x0f\xbc\x6e\x9e\xad\xc6\x9a\xa2\xbc\x16\xd5\xab\x0c\xdd\xcf\xd3\x94\x4e\x9e\x03\x09\x5d\x99\xc0\xae\xdc\x04\xd9\xf9\xf6\x05\xb7\x2b\x85\x24\xf1\x69\x18\xa0\xdd\x58\xf0\xb2\xb5\x66\x75\xda\x59\xcf\xa6\x2e\x6a\xba\x36\x65\xa0\x89\xaa\x7f\xb0\x36\x18\x58\x3b\xb0\x71\x81\xa3\x3d\x1e\x23\xf5\xa5\x55\x79\x87\xef\xcb\x83\x81\xe1\x4a\xb7\x34\xee\xf4\x78\x0c\x5e\x71\x53\x1e\xa8\x29\x4a\xa6\x15\xb2\x99\xa9\xc6\x36\x47\xce\x27\xf1\xda\xe5\x44\x58\x1c\xaa\x12\x85\xc8\x67\x24\x75\x35\x95\x88\x26\x24\x49\x75\x0d\x8c\xbd\x2d\x82\x3c\xa7\x61\x8f\x55\xa1\x5d\xdf\x31\x88\x1c\x2d\x69\x93\x97\x29\xc2\x83\x19\xb0\xd0\x69\x98\x43\xfa\x7c\xa7\x9a\x36\xab\x64\x65\x19\x4a\x5b\xca\x6b\x6d\x65\x31\x43\xae\x25\x21\x58\x0d\x84\x08\x93\x46\x05\xaa\x4b\x3d\x59\xe0\x94\x8e\x83\x65\x4e\xd9\x49\x3c\x4c\x93\x82\x9c\x07\x09\xd8\x24\xe5\x8b\x34\x8a\xf9\x6d\x78\x52\xd0\x6c\x12\x8c\x95\x6f\xec\x06\x27\xf1\x26\xa7\x6d\x7b\x9b\xaa\xe7\x87\xc4\x71\xaf\xab\xd6\x34\x5a\x9b\x3f\xd1\x82\x3b\x6b\x66\xfb\x63\x8f\x9c\xcf\xa2\xf1\x0c\x8c\x06\xd8\xf2\x2e\x52\xb1\x8d\x91\x45\xbc\xcc\xeb\xaf\x5e\x05\x1f\xa8\x99\x5f\xcd\x3c\xfc\x86\x4c\x35\x22\xec\xea\x72\xaa\x2a\x56\x2f\x3f\xde\x46\x76\x2c\x97\x1b\x91\xb1\xf2\x8d\xe4\x98\x2a\x19\xc6\x7c\xe9\xd0\xe7\x06\xe9\xcd\x99\xaf\xe7\xd4\xe3\x3d\xee\x36\xb8\x3e\x2f\x63\x4d\xce\x61\xd8\x7b\x0a\x2e\x79\xc9\xe2\x3b\x0f\xbb\xbb\x9f\xb6\x0b\xe7\xf8\x73\x1f\xaf\x10\xcf\x61\xda\x6b\xb6\x64\xd1\xed\x8e\x32\x7f\x36\x6d\x25\x5a\xa3\x6f\xcb\x2c\xa0\x95\x45\x43\x6b\xb4\xb5\xed\x9a\x44\x8b\x91\xb7\x46\xdb\x9b\xd7\x27\xbd\xad\x27\xf7\xa6\x4f\xf7\xa6\x4f\x7f\x6d\xd3\x27\x64\xeb\x2c\x4c\x20\xef\xc0\xd8\xb9\xc4\x8d\xa5\x30\xae\xe4\xef\xb2\x0e\x27\xf2\xce\x79\x2f\x9b\xe6\xa3\x12\xcd\x0d\x92\xf1\xc4\x09\x56\x54\x82\x63\xdf\xc9\xed\x84\xb1\x4f\x59\x29\xc1\x26\x4e\xc0\xe7\x7b\xbe\x3e\xbc\x7b\xbb\xcf\x99\xfb\x6d\x3a\xc0\xe3\x2d\x01\xab\xa5\xf0\x80\xb1\x48\xc9\xbb\xb7\xfb\xe2\x9e\xc0\xdf\x01\xf1\x1c\x1d\x9c\x28\xea\x96\x67\x69\x8e\x6f\xbf\xdc\xc6\xf7\x0f\xdf\xbc\x79\xb9\xff\xe1\xe0\xf0\x0d\x79\xf9\xee\xdd\xe1\xbb\x11\xd9\x57\xea\xdf\x31\xaf\x92\x9f\xe8\x43\x4a\xda\x1b\x84\xd5\x47\x36\xda\x7d\x7f\x1f\xb4\xc7\x9b\xa6\x63\x57\xef\xec\xb9\x12\xa1\x60\xab\x27\xe2\x95\xf9\x9b\x90\x86\xb4\x23\x62\x1b\x05\xa3\x61\xc2\xb3\x34\x9a\xe7\xc1\x94\x92\x5d\xb2\xbe\x2e\x5e\x1a\xb2\x6d\x5d\xfc\xee\xf3\x90\xb1\x4e\x4a\x5f\x16\x7b\x46\xbc\xc9\x23\xa2\xa6\xeb\xef\xef\x0f\xdf\xc0\xac\x64\xaa\x4b\x9e\x30\xab\xa2\x6f\xce\x5b\x32\x8d\x03\x51\xb5\x39\x5a\x3d\x9b\x1f\xf8\x75\x35\x1e\xef\x3c\x6f\x3a\xa5\x1f\x0e\x5e\xbf\x3c\x3c\xfa\x30\x22\xe2\xd2\x9b\x11\x17\xeb\xe4\x3c\x27\x1b\xa4\xcd\xfe\x0b\xc6\x33\xc6\x31\xda\x46\x40\x1b\xe1\x46\xf2\xdb\xfb\xdd\xea\x7e\xb7\xfa\x6b\xef\x56\x68\xb3\x82\x57\x97\x7f\x54\x2b\xdd\xe6\x8f\xd9\x1b\xbd\xa1\xbf\xc3\xa7\xec\xd2\xe7\x10\x5b\xff\xea\x70\x86\x23\x32\xe5\xc6\x31\x44\xbc\xb1\x85\xb6\xf4\x61\xc1\x36\x42\xfe\xd2\xef\xe0\x17\xd2\x94\x17\x29\xd2\x71\x3e\x0f\x5d\x41\x2a\x9e\x23\xe7\x69\xd2\xad\x79\x42\x8f\x32\x93\x34\xb9\x9c\xa7\x4b\xd5\xa2\x4a\x28\x39\xbd\x49\xa4\x4d\xa9\xc4\x15\x0d\xb9\x3c\x00\x41\x0c\x9c\x60\x4d\x22\x4d\x1d\xcf\x9e\xa7\x69\x7c\x0d\xe1\x55\x43\x70\x41\xce\x37\x09\xca\x21\x43\x34\x3b\xf0\x3e\x84\x86\x86\xc3\x74\x79\xe2\x83\x60\x04\x6c\x51\x8a\xda\x07\x6b\xc6\x34\x61\xef\x5b\x0c\xc2\x74\x1c\xc5\xeb\xb5\x03\x30\x20\xe4\xbb\x57\x22\x91\x47\x54\x88\xfa\xa2\x26\xb8\xdf\x10\xbf\x4b\xcc\x5d\xfd\xe5\xb5\xbd\x72\xe9\x0d\x31\xc6\x36\xa7\xcf\x90\xbb\x00\x07\x2f\x46\x16\xae\x43\xed\x1d\xdc\x1b\x2d\xc8\x5b\x41\x39\xea\x50\x75\x55\x4e\x82\x38\x25\xba\x0e\xca\x3b\x9a\x5e\x9b\x8f\x0e\x56\xa8\x67\x68\x85\xf0\x67\x5e\x31\x2e\x5c\xb4\x9a\x1e\x56\x1a\x91\xf4\xa4\x7e\xa3\xe1\xe4\xd1\x34\x09\x8a\x65\x66\x0f\x07\xa7\x97\x8d\x07\xc3\x94\x8f\x47\x41\x55\x0d\x08\x1c\x18\x34\xef\xbf\x78\xe1\x20\xc9\x5b\x70\xa4\x20\x09\x95\x6a\xa9\x48\x21\x28\xf1\x24\x4a\x82\xd8\x6f\xf5\xcc\xeb\xf0\xd9\x94\xe2\x75\x6d\x65\x89\xea\x0d\xa4\xc8\x3c\x7a\x46\xb3\xcb\x62\xc6\x35\xd6\xf3\xd3\x08\x58\x46\xca\xa3\x44\x43\xdf\x44\x98\x85\x4a\x6c\x79\x5c\x83\x88\xee\x38\x9e\xed\xd4\xe2\x56\xbf\xd0\x23\xc0\x7b\x07\x22\xda\x5d\x87\xf2\xcf\x51\xe7\x59\x44\xea\x35\xd7\xad\x9d\xc7\xed\xa7\xa8\x9c\x3f\x6c\x15\xbe\x05\xb9\x9f\x4e\x49\xed\x9d\xae\xab\xd2\x14\xf3\xf4\x41\x76\xec\xb6\x2c\x1d\x85\xb0\xa8\xe4\xe7\xe0\x78\x59\x04\xd3\x16\xe5\x8f\x23\x08\x31\x65\x19\x03\x08\x20\x3c\x7f\x8c\x6e\x74\x72\xb2\x8c\xe3\x92\x17\x2e\x5a\xb3\x48\xdc\xcb\x7f\x53\x21\x0c\xf5\x95\x05\x66\x84\x4c\x6b\x34\x67\x15\xb7\xfd\x02\xfb\xce\xdb\x98\x0e\xdf\xbe\x7a\xe4\xcc\xbe\x39\xef\xda\xb1\xf5\x56\xaa\x0d\xfa\x5e\x43\x71\x26\x91\x8c\xd3\x64\x1c\x14\x1d\x63\xf6\xbb\xe5\x7e\x6c\x4a\xb9\x9e\x70\x62\x53\xce\xf5\xec\xdd\x96\x96\x71\xb8\x90\xdf\x3d\xb8\x3c\x4c\x70\x05\x61\x38\x04\x27\x04\x5e\x4b\xa8\x9a\x7d\xf0\x00\xf4\x0d\x66\x2f\xaa\xb7\xe9\x72\xe7\x3b\x80\x83\x3b\xf4\xbe\x13\x64\x53\x6b\x75\x69\xf1\xf1\x99\x51\x72\x84\xbf\x84\x67\x9e\x4d\xe4\x09\x45\x8c\x4f\xdc\xbf\xa8\x7a\xed\x97\x5a\x7c\x32\xc9\x67\x25\xa5\xe1\xfa\xb6\xba\x3b\x6c\x65\xfe\x9a\x46\x49\xa7\xd5\x72\x2b\x57\x8f\xe2\x38\xb9\x71\x3c\xe1\xeb\x0d\x90\x0d\x3b\x6c\x99\x77\x7b\xb8\x47\xf8\xaa\x26\x49\x8b\x03\xa3\xaf\x0a\x85\x1e\x7f\x43\x1a\xb8\x61\xdb\xf0\x6a\xa1\xdb\xb3\x5a\xc1\xed\xab\x8d\x04\x71\xed\x74\x59\x2c\x96\xc5\xcf\xe9\x54\xb3\x6b\xe1\x8b\x07\xad\x16\xe9\xfc\x87\xfb\x99\x41\x62\x99\x09\xa6\xb9\x35\x8c\xc9\x76\x03\xc5\x61\xf8\x2d\x97\xc1\x4f\x33\x1a\x2e\xc7\x14\xcd\x55\x30\x1e\xf7\x88\x70\x45\x89\xf9\x49\x30\x1e\x1f\x8b\x64\xce\x13\x19\x52\xc4\xb7\xa4\xf2\x67\xe6\x94\xf5\xf3\x59\x34\x29\x3a\x5d\x32\x72\x30\x2a\xb3\x1c\xa5\x55\x30\x1e\x4b\x2d\x15\x37\xf6\xe6\xa4\x4d\x63\x5a\x50\x39\x0e\xed\x24\xc9\x4c\xe7\x54\x75\x03\x96\x81\xee\xaf\xc4\xbb\x12\xb1\xb4\xd9\x56\xcf\xc5\xb8\x52\xc7\x0a\x77\x25\x17\x19\x0d\x57\x0b\x3f\x1e\xc7\x0d\xb6\xf4\xf3\x47\xf7\xc8\xb4\x55\xef\x91\xa9\xaa\xf8\x66\xb9\x8d\x9d\x59\x01\x31\x24\x40\xc3\xf7\x83\x2d\x76\xd8\x6e\x9f\x1c\x81\xf2\x0f\xe5\xff\xa9\x94\x96\xb1\xe9\x7f\x83\x47\x8d\xd6\xab\x36\xef\x8b\xc6\x4a\x6a\xfc\x52\xce\xa6\x18\xa8\x79\x72\x2d\xe3\x80\xd2\xbe\x10\x5a\x3a\x46\x00\x27\x06\xf5\xfa\x00\xb0\xff\x2a\x4d\x14\x5e\xd0\x63\xc5\xee\x79\xdb\x27\xa5\x03\x30\xac\x26\xbc\x77\xc2\x06\x2e\x91\x47\xac\xaa\x2b\xe1\x3a\x3f\x59\x37\x74\x8d\xf5\xb4\x89\x02\xfe\xb6\xbe\x2e\x07\x7e\xdd\xe4\x6b\x4e\x83\x1e\xfd\x5f\x75\x20\x11\x1c\x43\x64\x6d\x30\x20\x1f\x0e\x5f\x1c\x8e\x48\x46\xb9\x41\x56\x8f\xe4\xa9\x30\x9d\x51\x57\x5c\xda\x16\x27\xe0\x9a\xae\x3e\x2b\x17\x15\xed\x9c\x24\x74\x4c\xf3\x3c\xc8\x2e\xd9\x62\x81\x08\xd8\x39\x23\xb7\x36\xf8\x2b\x06\x6f\xd1\xe4\x3c\xcd\x3e\x71\x29\x6f\xbe\x8c\x8b\x68\x11\xa3\x48\x0e\x66\xec\x14\xbf\x7b\xa3\xc1\x43\xe2\xb5\xe5\xfe\x46\x9a\x72\xf3\x3a\x4c\x33\x06\xd9\xbc\x61\x43\xaa\x1b\xa3\x21\xdf\x38\xcc\x93\x89\x2a\xd5\x97\x38\xf2\x39\xb0\x59\x67\x9d\x3b\x76\x61\x4f\x7c\xe7\x87\x32\x58\x8b\x9d\x12\xc7\xbe\xd1\xec\xa7\xf0\xe7\xe4\xab\xa9\xc6\x0c\xd2\x5b\x4f\xe9\x11\x4a\xd7\x2f\x08\xde\x1e\x93\x03\xe0\x39\x72\xf3\x1c\x1f\x36\x78\x8e\x62\x7a\xc2\xa4\xc7\xec\xa2\xc7\xf2\x53\x14\xcb\x69\x61\x45\x8a\xf1\xf9\xb8\xaa\x3c\x88\x55\x4f\x77\x44\x2b\xc6\xab\x61\x3c\x43\x2e\xa3\x17\xa2\x83\x9c\x5c\xae\x3c\x6c\x55\xf0\x0e\x06\x4e\x90\xdd\x28\xbd\xe8\x1b\xec\x48\x7f\xec\x10\x09\x20\xb9\x10\xfc\xbf\x23\x53\x15\xcb\xe1\x3f\x54\x3a\x62\x34\xf2\xa7\x29\x47\xd2\x0b\xf1\xbc\xdb\xe5\xe6\x1c\x0d\xda\x33\x51\x09\x7f\x2e\xe1\xc8\xad\xd1\x36\x78\x30\xc2\x4e\xc3\x19\x63\xfe\xee\xfe\x66\xf4\xfe\x66\xf4\xaf\x7d\x33\x2a\xae\x45\xc5\x93\xdf\xff\x8a\xf8\x7a\x77\xea\x31\x1c\x0e\x01\x0f\xc9\x7e\x9a\x9c\x51\xc6\x8a\x02\x11\xf2\x18\xce\xc1\x70\x16\x80\xb8\xc5\x32\x90\x0b\x23\xe0\x20\xce\x53\x12\xc4\x71\x7a\x9e\xf3\xf0\xec\xa0\xa8\xcb\xfb\x6b\xac\x22\x29\xf8\xbf\x8e\x2e\x68\x78\xcd\xb3\xd6\xdc\x7b\x8d\x35\x71\xa3\x5a\xa4\x76\x90\x63\xa1\xb2\x54\x07\xce\x8e\xa9\x12\x25\x57\x57\x32\x40\xba\xce\x68\x2b\x1d\x6a\xbb\x6b\x2b\x03\xf8\x59\x4e\x88\x48\x5c\x31\xcb\xfb\xd0\x91\xfa\x45\xa3\x21\xae\x87\x38\x9c\x80\xaa\xb9\x0b\xb5\x0f\x9d\x3a\x01\x52\xf0\x7d\xfc\xa2\xd5\xb8\x33\x92\x41\x94\x54\x3b\x70\xe4\x62\xa2\x26\xe3\xb4\xf2\xf2\xc7\xb6\x84\x4d\x95\x7e\x5f\x1c\xb6\x7a\x6c\x12\xce\x68\x16\x4d\xc0\xaf\x47\x46\xc7\x01\xe3\x38\x28\x50\xcd\x83\x07\x24\x0e\x7e\xbb\x24\x71\x1a\x84\x24\xbc\x4c\x82\x79\x34\x26\x69\x42\x73\x68\x4d\x4c\x88\x6e\x48\x04\xb3\x4e\x95\x9e\x00\xa0\xa4\x7d\xbd\x6c\xdc\x81\x62\xb3\x35\xa5\xc5\xa1\x3a\x24\x7b\x3c\x38\xb3\x89\xd1\x02\x6b\x9d\x7b\x00\xac\x4c\x10\x53\x22\x8f\xc9\xe5\xb7\x1e\x86\xa6\xbf\xf4\xea\x85\x67\xe7\xe7\x11\xc4\x2b\x41\xbd\x22\xa0\x83\xc8\x29\x3f\x41\x8f\x9c\x97\x55\x5c\x78\x5f\x66\x54\xa8\x17\x7b\x70\x81\x37\xe6\xab\x83\x1f\x8e\x67\xf4\xc2\xa7\x36\xd0\x5a\x53\x2b\xc1\xf2\x44\xd9\xa0\x88\xa1\xf9\x14\x61\xb5\x4b\x95\xf2\x96\xc2\x5f\x06\xe1\x7e\x26\xc2\x93\xb3\xaa\xc4\x22\xeb\x92\x91\x5c\x6f\x02\xcc\x95\x95\x7c\xd7\x04\x9e\xe7\x75\xd0\xcd\x91\xd5\xed\x9e\x03\xc7\x96\x80\x86\x62\x5f\x2e\x4c\x91\xe2\x7a\xdc\xfc\x40\x46\x65\x96\x40\x01\x8e\xc9\x6c\xb7\x06\xf7\x57\xa3\x95\xae\xb5\xfa\xaa\x5c\xd7\xd7\xbb\x9b\xd4\x28\x4a\x99\xfa\x29\x74\xd0\xe1\x14\x98\xcf\x18\x05\x7a\x10\x6e\x91\xba\x54\xd5\xec\x85\x21\x7f\x16\xa1\x94\x68\x41\x12\x92\x9c\x16\x39\x59\x2e\x20\x43\x9c\x46\x80\x65\x44\x05\xcd\xd8\xde\x91\x9e\x09\x61\x4b\xb8\x31\xed\xaf\xad\xa1\xa7\x11\x3f\xa7\xd3\x7c\xaf\x78\x5f\x04\x59\xb1\x66\x6b\x1a\x73\x1a\x4f\x54\xe2\xc4\x7d\xbf\x2c\x58\xb8\x59\x8b\x11\x27\x8c\xc6\x13\xc7\x87\x8f\x7c\x64\x37\xa5\x05\xd7\x67\xb1\xc2\xd6\x4b\x3b\xd0\x2f\xe8\x61\xe6\xd0\x3d\x22\x4f\x9e\x16\xcf\x60\xad\xf4\x7d\x8c\x03\x32\xa6\xb4\xe8\x58\x6f\x7e\x84\x25\xa3\x73\xca\x19\x0c\x48\x98\x26\x6d\xf1\x4a\x94\xf5\x51\xa0\x0d\xcc\x26\xe1\xa2\x5b\x26\x4a\xb3\x23\xf0\x84\xd1\xef\xf7\xc9\xaf\x4b\xee\x08\x98\xb5\xc9\x78\xaf\x73\x5e\x2e\x79\x18\x59\xf1\x28\xf2\xda\x7e\x01\x6b\xad\x74\x35\x0c\xff\x19\x93\x67\x7a\x0f\xa6\xdc\x90\xb3\xee\x99\x26\x7f\xbc\x63\x9a\x7d\x1a\xfd\xab\xf7\xc3\xfa\xe5\x48\x77\x91\xc6\x31\x27\x1f\x3f\xd9\x0a\xda\xd4\x60\x36\x5d\x2a\x95\x08\xa8\x6d\x93\xd7\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\x48\x16\x72\x49\xe7\x56\xe8\xb9\x1d\x91\x96\xea\x03\xa0\x4f\xb6\x33\x6a\xc6\x78\xde\xa6\x71\xcc\xf8\x8c\xee\x09\xa7\xc1\x11\x2f\xc2\xce\x69\x74\x4e\x93\x02\x8e\x9c\x7d\x46\x71\x30\x34\xbd\x97\x2c\x84\xa1\xfd\x31\xc7\x14\x90\xe3\x41\x78\xd2\x93\x57\x54\x46\x72\x4f\x13\xa3\xc8\xc1\x6e\x8c\xb8\x82\x18\xe8\x97\x6d\xd6\x32\x6a\xa1\x43\xe2\x96\x4c\xd6\x23\x4e\x78\x0f\xb9\xdc\x3c\xb7\x03\x3d\x71\x9a\xda\xcf\x28\x8c\x09\xec\xb5\xf7\x3d\x0f\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\x1e\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\xdd\x2f\xcb\xd7\x6c\xcf\xc9\xc2\xd7\x4e\xea\x77\x69\xbf\xfb\x09\x3d\x17\xb7\x4e\x18\x07\xd8\x57\x18\x67\x92\x51\x68\xb8\xc6\xf3\x33\xc7\x9a\x65\xdf\x19\x9f\x7a\xc4\xdc\xf1\x69\x2d\x1f\x24\x82\x23\x8b\x73\x61\x05\xf5\x5a\x0e\x49\x5d\xf6\x52\x51\xd6\xdf\x8d\x6a\xbd\xb3\xb1\xb4\x19\x11\x84\xae\x1f\x40\xec\xaa\x21\xa3\x70\xc9\xc0\xce\x1c\x0b\x9a\x84\x60\xe0\xa6\x26\x39\xc8\x41\xd1\x92\xe4\x8c\x42\x95\x2f\x18\x5d\x51\x3a\x01\x60\x56\x88\x49\x3d\x5d\xae\x5c\x51\xad\x2f\x93\x20\xcf\xa3\x69\x42\xc3\xbe\xdb\x47\x9b\xa2\x7c\x3c\xd9\x37\x3b\x4a\xc6\x1a\x9f\xd6\x4c\x90\xb7\x19\x6c\x32\x86\x46\xa2\xed\x89\x49\x8c\xa5\xc3\x20\xce\x68\x10\x5e\xea\xf7\xea\x5a\x50\xcc\x6f\x4f\x69\xa6\x20\x2b\xa5\xd7\xba\x71\x45\x93\x8e\xd5\x9a\xf2\x01\x37\x74\x3d\x72\xe9\x95\xc9\xb9\xb8\xcf\x2d\x24\x93\xa2\x8b\x54\x8c\x2d\x9a\xcf\x69\x18\x05\x05\x8d\x2f\xed\x66\x05\xb9\x8f\x9b\xd2\xb6\x29\x9d\x40\xf5\x9d\x12\x4f\x13\x3e\xaf\x55\x58\x93\xcd\x59\x3e\xdb\x7e\xf8\x60\xd0\x5d\xee\xb9\x13\xa5\xc3\xde\xcc\x4d\xde\xc6\x0d\xfb\x50\x3f\xa4\x3a\xc6\x60\x8e\x78\x34\xd6\x3c\x89\xeb\x52\x77\x20\x08\xd7\xe8\x4e\xf8\xba\xe9\x40\xf0\xbe\x5b\x3f\x1e\x47\x72\x48\x17\x52\x70\x30\x07\x52\xc3\xdf\xe1\x69\xf9\x3c\x3d\x93\x2a\x4d\x12\xe4\x97\xc9\x58\x1d\x7e\x7c\x82\x91\x8f\x6f\x2f\x13\x78\x3b\x6d\x20\x00\xc9\x18\x16\xb6\x1c\xde\x85\x0d\xe1\x57\xa9\xd9\x10\xfc\x1d\x8c\x4e\xad\x90\xed\x3e\xe7\x09\x8e\x4c\xe1\x35\x39\x51\x25\x6d\xa1\xdc\xda\x51\x4b\xec\x28\x07\x03\x72\x30\xd1\x9c\x31\xca\xd5\xbb\xbe\x4b\x2a\xdc\xaf\x90\xa8\x20\xda\x4b\x97\x2e\x77\x3e\xa3\x60\x8c\x21\x46\xdf\x25\x9c\xa9\xe6\x24\x2a\x4c\xb6\xea\xdd\xa8\x1d\x62\x57\xcb\xcc\xb7\x7b\xf8\xd0\x2f\x6a\xb4\x27\x14\xef\xc7\x10\x21\xc5\xc3\xdf\xbe\xa0\x7f\x1e\x4b\x1e\xcf\xa8\x6d\xbd\x17\xa7\xd3\xb2\x76\x89\xc5\x98\x2a\xce\x16\x50\xcb\x88\xed\x09\x25\xee\xf8\xfc\x01\x4b\x4c\x10\xe7\x00\x60\x0f\xac\x39\x1d\x39\x6e\xa6\x84\x20\x7e\xf0\x82\x27\x8c\x04\x8d\x75\xba\x7d\xbe\x23\x8f\x03\xe9\xb0\x10\xdc\xaa\xd0\x90\xb0\xd5\x3d\xcb\xd2\x24\x5d\xe6\xca\x7b\xa1\x30\x0c\x60\xbb\xbd\xed\x89\x88\x57\x23\x84\xdd\xb6\xd7\xbc\x16\x9c\x4a\xa4\xda\x4a\xaf\x09\x01\xb9\x36\x74\xac\x86\xfa\x39\xbc\xc5\xbc\x5d\xd7\xf0\x63\xe7\x8a\x94\xe3\xd6\x89\xfd\x56\x71\x41\x7a\x7d\xd2\xdb\x1e\x36\xb9\x02\x6d\x2f\x73\xae\x17\x1f\x17\xed\xb5\xfb\x0b\xd1\xfb\x0b\xd1\x3f\xf1\x85\xa8\x7e\x2a\x8a\x54\xd6\x37\x79\x2f\x2a\x80\x57\xb8\xc9\xf4\xc5\x7e\x6b\xfc\xc4\x34\x99\x44\x53\x2f\x1c\xcf\x92\x80\x07\xa7\x81\x15\xd3\x25\x3a\x0d\x12\x4f\x9c\x16\xd0\x26\xf3\x40\x53\xdc\x46\x9a\x5f\x66\x9e\x46\x53\xe1\xc1\xc0\xb2\x62\xe4\x40\xcf\xa3\xa9\xa5\xd4\xc7\xd6\x8c\x5c\xe3\x7c\xc5\x21\xae\x14\xec\xb5\xe9\xb4\x4a\xa7\x63\x4b\x5c\xd0\x33\x96\xb4\x61\x48\x45\xbc\x77\xde\x67\x68\x45\xaa\xca\x4a\xb0\x1d\xa5\x04\x8a\xf2\xb7\x19\x15\xd7\xa0\xe8\x76\xc2\xa8\xfb\x54\xa7\x5b\x0d\x1c\x2b\x77\xf7\x6d\x71\xf2\x6c\xf7\xda\x34\xc8\xe2\x88\x27\x8e\xd3\xf9\x3c\x2a\x0a\x1a\xb6\x4f\xd4\x15\xa9\x51\xdb\x0f\xbb\x64\x88\x3a\x93\x2c\x96\xc5\x0b\x3a\x09\x96\xb1\xf7\xaa\xa4\xae\x57\x6c\x0f\x3e\xc5\x83\xc0\x0f\x65\xbc\xf1\x5a\x18\x91\xf4\x43\xd4\xa2\xc7\xdb\x54\xf9\xcd\x0d\xee\x82\x35\x8a\xdf\xa3\xfb\xf6\x1b\x2e\x2e\x92\xb0\x5a\x4a\x66\xd5\x68\xd4\x53\x21\xca\xf6\xe0\x41\x52\xd3\x2b\x7a\x51\x35\xf2\x97\x8b\x74\x3c\xab\x1a\x39\xd5\x00\xbc\x0f\x20\x62\xea\x44\xf7\x7d\x93\x9d\xd9\xe2\x54\xd7\xb2\xa8\x51\x26\xb3\xbe\xb3\x9e\x7b\xfa\x8d\xdb\x36\xcc\x99\x79\x57\x73\x64\xbe\x99\x4e\x48\x60\x38\x31\x0c\x92\x50\xde\xe9\xe6\x70\xa7\xc3\x2d\x18\x18\x87\x78\xf5\xf2\x9f\x16\x63\x80\x3a\x98\x04\xef\x65\x09\xf2\xd6\xc1\x70\x06\xec\x98\xe8\xcb\xcb\x7c\x79\x2f\xe1\xd6\xe9\x0d\x51\xfe\xd9\xb8\xe6\x86\x8b\x4a\x74\x59\x0c\x9f\x57\x57\x16\xed\xef\x8d\x21\x40\x04\x72\xd1\x86\xe1\x3d\xbe\xc1\x64\xb5\xd0\x27\xe1\x30\xcb\x7f\x49\x6a\x4a\x6c\xb8\xea\x22\x15\x91\xad\xa3\x82\xcc\xa3\xe9\x8c\x8b\xb8\xca\xcd\xb2\x50\xa7\x39\x2d\x17\x69\x6d\xbb\x45\x6a\xb6\x7a\xdc\x9e\x06\xf9\xdb\x2c\x1a\xd3\x76\x8f\xb0\xdf\xec\x3f\x98\x3e\xf6\x23\x49\x93\x31\xf5\xbd\xa3\xfc\x44\x2f\x2b\x5e\x52\x7e\xa2\x97\x4d\xdf\x52\x42\x4d\x0e\x0e\x79\x0d\xbb\xc8\xf2\xe3\x05\x1d\x47\xf3\x20\xee\x60\x00\xf7\x2d\x9b\x79\xdd\xfb\xa5\x89\x18\x39\xfd\xbc\x6b\x5a\xf6\x55\x7d\xf7\x24\x7d\x53\xaa\xbd\xa7\xd7\xdf\x93\x5e\x85\xb8\xe5\x10\x2c\xdc\xec\xca\x28\x45\x82\x5a\xbd\x42\x58\x63\x3a\xbd\x30\x05\x2f\x91\xbe\x66\x48\x5b\xb5\x94\x59\x5c\x74\x3f\x2b\x9d\xe3\x45\x1f\x6f\xdb\xeb\xf2\xdc\xaf\x75\x6d\x26\x80\xf2\xbd\x91\x4a\xfc\x99\x00\xea\x75\x09\x4b\x47\xb8\x80\x77\x6c\xfe\xea\x1d\x28\x6f\x1b\x36\x94\x54\x2b\x5e\xf4\x81\xa4\xfc\x85\x20\x4b\x43\x4e\x83\xdc\x0f\x37\x0d\x72\x03\x0a\xc8\x17\x81\x6a\x21\x14\xe5\xeb\x12\xd2\xcc\xce\x0b\x8e\x1f\xf5\xca\x33\xff\xc5\xca\xa4\x24\xe3\xe1\xdc\x84\xa4\x44\x68\x9e\x4a\xca\x52\x91\xa2\x56\x21\x2f\xbb\x62\xcb\x41\x0c\x0e\xf1\xa3\x43\xfa\xd4\xd0\x9b\x0f\xca\x9d\x33\x0f\x94\xa6\x3c\x99\xd9\x80\xfc\x4a\x41\xcb\x9b\x2c\x21\x44\x15\x79\x66\x39\x5f\xc6\x41\x11\x9d\xd1\x9f\x82\xfc\x28\x87\x17\x74\x65\x55\x39\xb0\x56\x5d\xd3\xda\x1a\xa6\xaa\x9c\x1c\xbc\x69\x14\x21\xe1\xe2\x74\x6a\xdb\x18\xea\x0c\x14\x37\xc7\x51\x82\x81\x26\xcb\xab\x02\xf3\xbc\xc3\x65\xb0\x75\xfa\x2e\xd1\x52\xa3\x05\x00\xb3\xdb\x9c\xe4\xe1\xb4\x50\x49\xe5\x50\x61\x03\x1a\x37\x6b\xc2\x96\x34\x50\x83\x32\xa5\x19\x0c\x88\x72\x42\x04\xde\xf8\xc4\x39\x9b\x10\xde\x14\x9b\x9f\x9f\xa3\x79\x54\x78\xa6\xd0\x04\x10\xb8\x52\x89\x25\xf3\x6e\xe4\x1b\x65\xf2\xe8\x37\x1f\x13\xd4\x99\x06\x74\x11\xcd\x69\x5e\x04\xf3\x45\x69\x11\x05\xa1\xd7\x15\xcf\x48\xca\x56\xae\x91\x5d\x56\xad\x3a\xc4\xa3\xce\x84\xd1\x64\x12\x8d\x97\x31\x3c\x24\x71\x79\xa8\x0d\x64\x0e\x24\x2d\x82\xf8\x45\x93\x0a\x2c\x48\x2c\x24\x99\x6b\x46\x80\xeb\x65\x6e\xae\x1c\x37\xdb\x15\x41\xa2\x82\xce\xbb\xf6\x13\x32\xc7\x8e\x0f\xa0\xdc\x1b\x53\x63\x7d\xf9\x36\x73\x5e\xb0\x6e\xa1\x9d\x72\x95\xc0\xf5\x4e\xa3\x55\xf6\x3e\x9a\x26\x34\x23\x71\xe4\x44\xc3\x5f\x69\x6d\xf1\x6a\x72\xff\x12\x23\xee\x1a\x13\xf0\xe5\x4b\x4d\x00\xe8\xc3\xb6\x67\xae\x24\x8c\x9c\x25\x9c\x58\x33\x37\xf5\xb3\x22\xb0\xc9\x15\x6b\x87\xd0\x73\xe9\xc3\x1f\x4d\x03\x9f\x02\x74\x70\xc7\x7d\x68\xc4\xeb\xe2\x74\xea\x45\x3c\x66\xb0\x3e\xb4\xc7\xe9\x54\x2b\xdd\x5c\xa4\x43\xbd\x06\xde\x71\x85\x18\xdd\xe8\xb2\x23\x9a\xb0\x2f\x63\x73\x55\xf8\xb0\x32\x3c\x0b\xdd\x2e\xba\x83\xeb\x74\x76\x4f\xa3\xe2\x06\xdb\xb0\xb7\x12\xa3\x89\x38\x9d\x7a\xaa\x96\xa9\x25\x55\xaa\x42\xa6\xe4\x0f\x17\x38\xf5\xa7\xd4\xf3\x59\x94\xb3\xcd\x69\x91\xe6\xc5\x0d\x8e\xa9\x6f\xd3\xbc\x5a\x3a\x73\x03\x2f\x55\x6e\x62\x6e\xa5\x78\xa2\x59\x27\xf1\x0e\xc6\xbe\xfb\x8b\xe0\x12\x5e\x53\xec\x1a\x2a\x27\x9c\x25\x90\x0c\x49\x45\x11\x7b\xcf\x52\x32\x13\xc3\x9e\xa7\xd9\xa7\x0f\xe9\xdb\x2c\x3d\xa3\xe5\x65\x10\x10\x2e\xbb\xc8\xa2\x34\x8b\x10\x5b\x77\x0a\x4a\x08\x14\x4f\x60\x82\xc3\x4d\x19\xf6\xd3\x9c\x67\xf0\x4e\x72\xe7\x2a\x98\xb1\xa3\x74\xb2\x6b\x7c\x3d\x23\xc7\xe8\xf3\x84\x8c\x94\xf1\xc2\xb5\x6e\x95\x6b\xde\xb9\x12\x3e\x8e\xd3\x73\x78\x4c\x22\x75\x09\x55\xd5\x57\x3f\x7e\xe0\x01\x13\x19\x31\x91\x34\x89\x2f\x79\x14\x88\xc2\x78\x93\x21\xdf\x45\xf0\xf7\x0f\xbe\xe7\x3c\xf2\x71\x04\x19\xd9\x4f\x75\xf0\xb3\x08\xfb\xd8\xcb\xfa\xd8\x88\x77\xa9\x5b\x20\xa0\x7f\x61\x9b\xea\xe5\x66\x75\x94\xde\x64\xe3\xa8\x26\x6c\x41\xd7\x80\x5f\x7a\xb1\x88\xb2\x4b\xcf\x8a\x47\xb9\x98\xdc\x72\xee\x34\xc6\x0b\xcd\xf2\xca\x96\x80\x05\xea\x59\x00\x40\xd9\x3e\x81\xce\x82\xe8\xee\xf8\x56\xe5\xbb\xe0\x5c\x92\x8c\x48\xf1\x82\xa1\xea\xf7\xf2\x71\x14\xd9\xcb\x57\x96\xc1\xdb\xe8\xdf\x73\x81\x38\x05\xa7\xc3\xae\xe8\x55\xa1\x1b\x00\x2f\xca\x10\xfa\xcc\xc7\x1c\x06\x83\x55\x56\x04\xac\x4d\xbc\x1a\x4b\x17\xa3\x5e\x6e\xb7\x58\x49\x96\x4a\x9d\xa3\xa8\x19\xfd\x2b\xa6\x6a\x6b\xc1\x7c\x31\x52\xf0\x95\x88\x48\xea\xe7\xcb\x53\xfe\xbe\xac\x33\xec\x6d\xf3\x55\xd9\xba\x08\xc7\x2d\xc3\x57\x90\x72\x46\xd4\x1a\x5e\xb4\xc8\x06\x71\x0b\x6f\x1b\x11\x45\xa0\x57\xfc\x76\x30\xa1\xe7\x70\x51\xd8\x31\x43\x74\xc3\x7d\xca\x69\x90\xf4\xa3\xfc\x1f\x41\x1c\x85\x1d\x08\xa1\x21\x52\x5e\x44\x19\x1d\x17\x1d\xdf\x65\x8a\xf0\x54\x06\x80\xa2\xc6\x4e\xd7\xb9\xa9\xc1\x82\x93\x8e\x6c\x24\x7b\xe0\xa9\xd6\x70\x86\xe7\xa9\xa8\x41\x15\xa2\x67\x66\x4d\x5c\x0f\x63\x9b\xa6\x08\x77\xe5\x12\xb6\x2d\x43\x8d\x6b\x4e\xf2\xfe\x32\x19\x47\x89\x5f\x1c\x12\xfe\xc1\xd1\x5c\xae\x9b\x49\xc4\x75\x97\x64\x08\xe1\xe0\x5c\x09\x6c\x1b\xa3\x64\x0a\xc2\xae\xf7\x1c\xef\x82\x99\x2e\xaa\x84\xb7\xa8\x9a\x0a\x30\x94\x59\x7e\x16\x4d\x67\x34\xaf\x2b\x8f\xa1\x10\xed\x88\xdc\x4f\x49\x7a\x9e\xbc\x2f\x82\x82\xfa\xdc\x15\xa2\xdc\xf2\x06\x70\x15\x3b\x76\x0d\x8b\x65\x1c\xd3\xb0\xae\x0a\x0c\x55\xa2\x5a\xd0\x5e\xab\x4a\x02\x13\xd4\xdd\xd2\x8e\x6a\x21\x7a\xba\x9e\x8a\x0a\x6a\x4a\xfa\xee\x19\x47\xe5\x59\xa8\xa4\x71\x85\x36\xf2\xa4\x21\x58\xdf\xd9\x71\x54\x9e\x85\x4a\xda\x6c\x6e\xe4\x4f\x46\x25\x8c\x4d\x79\xe4\x49\xe3\xb0\x65\xf6\x00\xa3\xd2\x1c\x5c\xce\x3f\xa0\xf2\xbc\x92\xb2\xb6\xda\xd2\x53\x85\x0d\x62\xf4\xde\x38\x0a\x8f\xbc\xa9\x0e\xbc\x7d\xd0\x1d\x55\x65\xe2\xd2\xf8\xb8\x36\xf2\xa4\x61\x58\x6b\x12\x3c\x89\x18\xda\xe6\x7e\xa3\x92\x74\xce\x35\x0d\x13\x34\x7e\x5b\xd5\x1a\x6d\x3e\x2d\x73\xac\xc4\xb6\x8e\xd6\x68\x7b\xfb\xfa\xa4\xb7\xbd\x79\xef\x94\xe3\xde\x06\xed\xbf\xc6\x06\x4d\x50\xfa\x5d\x44\xd7\x59\x2d\x14\x41\x43\xc3\x33\x1e\xfc\xc7\xb4\x28\xe3\x69\x5f\x20\xa6\x41\xf3\x28\x04\x41\x1c\x0f\xac\x38\x9d\xf0\xbc\xd8\x8e\xf2\xe3\xc6\x26\x90\x36\xf2\x6e\x40\xb3\x8a\x98\x04\xbe\x88\x66\x1f\xf9\xd6\x28\x7c\xe6\xe3\x50\xbe\xab\xfb\xb3\xd7\x95\x8a\xbd\x05\xd7\xca\x93\x6e\x57\x2d\x84\x01\x0c\xe0\xbc\x0a\x75\xca\x6f\x0c\x23\x43\xfd\x0a\x10\xf1\x89\x21\xee\x24\x9e\x02\xdb\x1f\xec\xc9\x30\x3c\x6f\x82\x91\x81\x7e\x91\x86\x8f\x4c\xd9\xd4\x38\x2f\xdd\x20\x80\xb5\x3c\x5b\xe8\x68\x7f\xe0\xd6\x02\x78\x3d\x7f\x43\x95\x4d\x73\x1e\x34\x61\x5d\x08\x8d\xcd\x3a\x8c\x85\xc0\xca\x4e\xe3\xee\xfd\xe0\x90\x92\xcc\xc1\xb1\x0b\xc5\x63\x4d\x77\x70\xfe\xb1\xd9\xae\x18\x2a\xc4\xd3\x8e\xc6\x43\x43\x44\x54\x45\x28\xc4\x31\x95\x7d\x61\xb8\xa2\x9c\x8c\xd3\x2c\x73\x3d\x64\xc2\xc9\x2b\x28\xe8\x5e\x36\xcd\x7d\x41\x0b\x75\xd4\xf4\x87\xe4\x6f\x70\x72\xcb\xc9\x67\x38\xb7\x5d\xb3\xf6\xa2\x42\x3c\x51\x31\x9c\x68\x7a\xa6\x0a\xb7\x53\x3a\x47\xfa\xf4\xce\xa1\x00\x45\x8e\x01\x4a\xa0\x11\x3f\x18\xc8\xb7\x48\xa0\xe9\x32\xbc\xd3\xc0\xe6\x09\x3e\x11\x75\x30\x32\xb6\xd5\x06\xf0\x92\x31\x0b\x2e\xe5\xbb\x3c\x31\x77\xeb\x1d\x27\x96\x65\xd0\x55\x1e\xd6\xd9\x79\xdc\xb9\x00\xb2\xee\x38\x04\x38\xf7\x96\x5c\x09\xaf\xaf\xbc\x8c\x32\x56\x01\xeb\x51\x30\xe8\x08\x24\x76\x24\x21\xae\xef\xee\x96\x11\xb2\xf9\x10\x8b\x9d\xb9\x45\x38\xb9\x8a\xa0\x6f\x1d\xc7\x3f\x42\x95\x47\x61\xa9\x6d\x02\x83\x27\x4c\x2a\x46\x4c\x8c\xf4\x2d\x07\xf3\x90\x97\xb3\x69\x68\x4f\xe2\x25\xde\x85\x83\x58\xb5\xaa\xed\xbf\x2a\x29\x4f\xb5\x5f\x49\x76\x46\x14\xd5\xd5\x19\xc6\xaa\xfc\xc2\x0c\x7e\x5a\x12\x5d\xf5\x5a\x73\x73\xbc\x7c\x3a\x9e\x50\xa7\x45\xea\x0f\x64\x60\x84\x42\xdd\x25\x25\x41\x0a\x7c\xbe\xee\xc5\x33\x1c\x34\x5c\x23\xc6\x6a\x85\xc1\x55\x49\x10\x1e\x89\xfa\x9b\x05\x1b\xf1\x16\xaf\x9c\xf7\x1b\x85\x1c\x11\xde\xd2\x87\x3d\xf2\x54\x6a\xa1\x2a\x9a\x58\x26\x8b\x60\xfc\x89\xdf\x35\x9a\x26\x85\x90\x64\xe8\xa4\xcc\x24\xdd\x05\xd3\x6b\x94\xac\x8a\xff\x50\xa4\xb7\x4b\xb6\xc8\x33\x99\x28\x1d\xba\x13\x79\x0e\xd4\x1e\x0e\x94\x1b\xf6\x32\x7f\xee\x58\xc8\xe9\x89\xe2\xe6\x8c\x0a\x1d\x0e\xf6\x46\xad\x42\xf9\x1d\x0f\x4f\xc8\xc8\xe7\x73\x7c\x1f\x22\x59\x07\x28\x78\xb8\x44\x96\x1d\x9e\x3c\x88\x63\xbc\xb8\xfb\xfd\xbe\x5c\xdf\xfb\x76\x59\x6b\xf3\x71\xbc\xfd\x1c\xf0\xed\x0e\xa2\x14\x4b\x50\xb6\x1b\x05\xaa\x86\x1e\x77\xec\x62\x57\xcc\x5d\xdb\xc1\x53\x4a\x79\xe8\x0a\x8c\xc7\x6e\x41\x12\x9a\x2e\x61\x24\x18\x0f\xe3\xcd\x4f\x46\xac\x0e\x1e\x03\x91\x81\x0b\xb4\x79\x69\x57\xcc\x2a\x84\x21\xae\xa3\x5a\xe8\x55\x59\xa8\xe7\x55\xe2\x38\xfb\xf7\x4d\x29\x83\x59\x26\x9a\x6a\x8f\x81\x83\x8c\x96\xff\x84\x07\x68\x43\x2c\xc4\xec\x07\xbc\x58\x9b\xd2\x17\x2e\x82\xc5\x1f\xbb\x98\xbe\xa9\xe0\x9e\xa7\x25\x97\x96\x70\xda\xe8\x63\xdd\xf7\xb2\x58\xeb\x86\x15\xe3\xa3\xc5\x8c\x23\x41\x54\xdd\x33\xba\xe6\xbe\x23\x84\x52\x78\x09\x77\x8c\xf5\x80\x7c\xa7\x3b\x2f\x7f\x9b\x34\xd8\x73\xfd\xf5\xb8\x3c\x00\x79\xeb\x91\xcf\x45\x0c\x9f\x0e\x3d\x6e\xba\xb3\x63\xfa\x48\xe6\x9d\xa6\xa1\xe3\x0f\xbe\xc8\x2e\xad\x67\x90\x08\x14\x5e\x3e\x96\x8f\x97\x18\x4f\x35\xc7\xf0\x56\xbe\xe3\x78\xdc\xe1\x14\xbf\x4b\xa8\xd7\xd7\x8f\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\xef\xfa\x03\x19\xc2\xa1\xc6\x38\x6b\xba\xd2\x21\x0e\x80\x1a\x24\xfc\xd9\x79\x12\x0a\xd7\x94\x10\xc1\x36\x79\x24\x0f\xaa\x4e\x28\xdf\x9a\xe5\x6a\x84\xaf\x63\xeb\xc6\x9a\x87\x8e\x79\x3d\x29\xaa\xab\x05\x6f\x1e\x37\x80\xe6\x45\x34\x0f\x0a\xfa\x53\x00\x0a\xc4\x3a\xaa\x42\xe0\x75\x14\x85\x6b\xbe\x0b\x6a\xfa\xf2\xd4\xd1\x6c\x86\xd0\xb8\xea\x66\xc7\x03\x5a\x36\x33\xef\x64\x33\x54\x46\x42\x83\x88\x2e\x52\x17\x28\xe4\x03\x3c\x15\x53\x5a\xbc\xb0\x23\x15\xc9\x9d\xd5\xae\xa6\x6e\xae\x44\x5d\x77\x3c\x4f\x8d\x10\x2f\xaf\xaa\xc5\xca\xe4\x41\x5e\x9a\x4b\xcd\xb7\x88\xa7\x88\x8b\x4a\x3c\x23\xb2\xaf\x44\xd8\xef\x1b\x5c\x51\xd5\x7f\xa3\xf8\x8a\xaa\xd0\xaa\x83\xfc\x92\xc1\x16\xb5\x8e\x86\x0d\x30\x5b\x8c\xa5\x17\xaf\x9c\x9f\x9a\xeb\x18\x91\x80\x2e\x37\xb7\xa9\x18\x97\x28\xfb\xc7\xe6\x4a\xc4\x08\x3a\x23\xc1\xb0\x98\x62\xc4\x4e\xc1\x73\xe2\xba\xbd\xb3\x34\xae\xcf\xc0\x97\xee\x47\xd6\xe3\x36\x19\xf1\x0f\x6b\x27\x69\xf7\x1c\xe1\x65\xa4\xdd\xcd\xa9\x3c\xe5\x28\x4f\x0c\xe7\x44\x67\xf1\x8e\x4b\x37\xac\x9c\x41\xd6\x12\x83\x8c\x12\x53\xb6\xfd\xa8\xf8\x4b\xd5\x5b\x8f\x27\x54\x12\x9e\xe0\xc2\x10\x74\xd6\x4d\xec\x68\x33\x23\xd8\xe6\x0b\x2c\x43\x49\x57\x23\x3a\xad\x6c\xab\xb0\xd0\xd9\x0f\x16\x8b\xf8\x52\x38\x3e\x6a\x44\x58\x5d\xdb\x3e\x8f\x6f\x01\x56\x33\x2c\xf1\x46\x75\xd7\xcc\x83\x08\x27\xa4\x19\x8f\x8e\x28\x74\xeb\x50\x42\x9e\x09\xfb\x52\xd1\x84\x64\xba\x5e\xf1\xd8\xf3\x53\x29\xb8\x38\x6c\x6a\x0c\x97\x01\xba\x52\xb3\x77\xf2\xcb\x8a\x9b\x22\x12\x1f\x89\x4e\x2a\x2d\xa6\x77\x6b\xe9\xb1\x88\x7d\xfe\x29\x43\x29\xc9\xb2\x40\xe0\x51\x36\x5e\xc6\x41\xb6\xbe\xbe\xbe\x5e\x1d\x40\x49\x52\xd0\xce\x9d\x84\x50\xe2\xda\xdf\xd6\x68\xeb\x89\xdf\x1f\xcd\xd6\xfd\xed\xff\xfd\xed\xff\x5f\xfb\xf6\x5f\x5c\xfd\x33\x58\x19\xe2\xca\x1f\x98\xe3\xab\x85\xdc\xf0\x59\x16\x54\x1b\x02\xac\x0d\x06\x10\xc2\x2b\xc8\x18\x29\xb3\x1d\x6c\x99\x9b\x43\x64\x04\x17\x46\x93\x09\xcd\x68\x52\x10\x9a\x9c\xe5\x50\xe8\x34\x4b\xcf\x73\x9a\xad\x21\xff\xa4\xe7\x51\x12\xa6\xe7\xa0\xb1\x40\x81\x2b\xc8\x83\x07\x22\xa7\xff\xcf\xd7\x3f\xbf\x2a\x8a\x85\x70\x7d\xcb\xb9\xa6\x99\x46\x76\xfd\xb0\xc0\xfa\x44\xdc\x85\x68\x9a\xa4\x8c\x11\xc4\x51\x42\x59\x4f\x92\x34\xa4\x6b\xc8\xd9\x99\x53\xa3\x1a\xf8\xc5\x3c\x66\x23\x13\x1b\x5b\xbb\xdb\xb4\x91\x6b\x8e\xc9\x7f\xbe\x7a\xb7\x65\x54\x37\xcb\xb6\xda\xdd\xd2\x52\x52\x72\x60\x2d\xbc\x95\xc8\x74\x4d\x22\x40\x7e\x62\xa2\x3d\x78\xfb\xe4\xbe\xc1\x59\x2f\x95\x01\x84\x51\x1e\x6f\xf9\xb3\x34\x2f\x7a\xa4\x88\xe6\x34\x5d\x16\x3d\x56\x61\xd6\x03\x25\xf3\x79\x9a\x09\x67\x2c\xb0\x99\x30\x38\xb2\x4b\xe0\xbf\xab\x2b\xd2\x16\xc4\x1e\xa7\xe3\x20\x66\x89\xa3\xa7\xdf\x3c\xfe\x06\xe2\xe4\xf2\xbd\x87\x57\xc8\x76\x42\xf1\xeb\xea\x8a\x0c\x55\x36\x6b\x86\xec\x42\x6b\x2a\x4d\x36\x4a\x76\x55\xfb\xb5\xc2\xd3\x22\xa3\x0b\x08\x3c\x47\xcf\xad\x29\xb3\x64\x27\x01\xf8\x0e\x9d\x65\x84\xe4\xf4\x3c\x4d\x63\x1a\x24\xd7\x70\xc7\xca\xf6\x67\x29\xc1\x68\x2c\x0b\x2f\x93\xe8\xc0\x67\xb6\x65\xb8\x32\xc2\x98\x46\x72\x97\xd9\x01\xf3\x22\x90\x55\xcf\x51\xcd\x6f\x50\x38\x21\xad\x89\x57\x6c\x28\x9b\x10\x2d\x5e\xc1\x90\x5f\xbd\xdb\xd2\x61\x6a\xb9\xa4\x85\x30\x8f\x26\x02\x9e\x9c\x61\x5f\x7e\x56\x45\xc6\x78\x3a\xe2\x85\xda\x9a\xae\x35\x5d\xd0\xa4\xd3\x7e\x7b\xf8\xfe\x83\x8c\xac\xc9\x09\x87\x77\x6e\x67\x0d\x39\x06\x84\xb9\x7d\xf0\xc0\x9c\x54\xe3\xd0\xb7\x04\x83\x9a\xf6\xf3\x20\x8f\xc6\xa4\x4d\x36\xa0\x0b\xcf\x97\x8c\x3d\xa0\x2a\x36\x48\x7b\xa4\xae\x0a\x55\x3d\xfd\x22\x15\x8f\xef\xda\xa7\x41\x4e\x9f\x3c\x6e\x5b\xe3\xd7\x6e\xb1\x5f\xd1\x20\xa4\x59\xa7\xbd\x07\x7c\x35\xfa\x2d\xe0\xa7\x2d\x68\x9f\x8f\xb0\xa2\x10\x93\x8f\x69\x52\x3c\x62\x07\xed\x76\x8f\xb4\x99\xe4\x1f\x8d\xa1\x8a\xc1\xaf\xb9\x54\x3b\xaa\x1b\x2b\x31\x65\x35\xe4\xca\x03\xa8\x5c\x26\x63\x74\xa8\xb6\x35\xc9\xbe\x8b\xe7\x05\xba\xbe\xf6\x87\xca\xae\x22\xbd\xdc\x0e\x9d\x28\x75\x69\x36\xc9\x49\x9a\x31\x69\x55\xc4\x5e\x06\x7a\xd4\xda\x7d\x8d\xb9\x24\xec\xc0\x4b\x0f\xfe\xee\x20\x9a\x5c\xaa\xfa\x05\x92\xa5\x22\x1f\x7b\xbd\xf6\x59\x03\xec\xa7\x49\x42\xc5\x7b\x0c\x49\x61\x9a\x12\x8d\xcb\x45\xd9\xba\x8c\x3f\xf1\x81\x5e\x14\x4e\x07\x05\x2c\x7a\x86\x22\xac\xf2\xcd\x6e\x55\x75\xe9\x9d\xa8\xbf\xe3\x6b\x10\xaf\x92\xe6\xa1\x90\x81\x06\x82\x1a\x22\xd8\x53\x1c\xa7\x82\x12\x44\xd6\x8f\x4e\xf0\x11\x52\x64\xd1\x74\x4a\x33\x1e\x31\x89\xcd\x3e\x88\x2d\xca\xfd\x29\xc3\x41\x1d\xc1\x40\x0f\x7c\x54\x63\x06\x3e\x6e\x42\x3f\x60\xbc\xb2\x63\x70\x93\x04\x5c\x55\xe7\x45\x50\xd0\xf1\x2c\x48\xa6\x7e\x05\x02\x7f\x56\x20\x11\x1f\x84\x97\x60\xd0\x0f\x37\xc2\x8f\x19\x87\xb1\x59\xde\xba\x19\xb8\xb8\x01\xc5\x68\x40\x79\xab\x84\x22\x62\xd9\x97\x59\x35\x14\x05\x67\x32\xef\xad\x95\xba\xb1\x5a\x91\xb6\x08\xbe\xda\xb2\x2f\xb6\x8c\x96\xd9\x59\xf0\xda\x42\xb1\xde\x08\x5c\xcc\x9a\x95\xe5\x7d\xbd\xf4\x3e\xf0\x52\x1d\xbc\x79\x88\x85\x7c\xb7\x1c\xc0\xee\x42\x15\x13\x10\x2b\x0d\xaf\x2b\x7d\x59\x1e\x5f\x32\x7a\xe7\x8f\x66\x61\x71\x31\xaa\x2e\x59\x5b\x51\x2e\xea\xa7\x26\x33\x55\x42\x80\x54\x70\xda\xc2\x00\x3b\x3f\x24\xed\x82\x4c\x82\x28\xa6\x61\x9f\x1c\xb2\x73\xda\x79\xc4\xce\x1e\x01\x04\x39\x2b\x5f\x4d\xa8\x4d\xcf\x5c\x68\x7c\x2a\x7d\x86\x0a\xa6\x11\x85\x23\xf2\x9d\xfa\x93\xfa\x3e\xb6\xfb\x64\x8b\xf1\x88\xb4\xb7\xfa\x43\xa5\x3c\x94\xfa\xc7\x76\x42\x8b\x8f\x71\x94\x17\x34\x01\x37\x85\x6b\x96\xf6\xf0\xc4\x30\xe8\x92\x0a\xae\x8c\x47\x6c\x73\xc9\x57\x5a\x15\xb2\x41\xea\x49\x70\xd4\x05\x78\xe8\x52\x55\x60\x9c\xf6\x99\x98\xdb\x1a\x3d\x65\xbf\x0c\xf9\xb9\x35\xda\xfc\x96\x9d\xfc\xb7\xef\x4f\xfe\xf7\x27\xff\xbf\xf8\xc9\x5f\x1b\xfe\xc3\x63\xc9\x3b\x32\xfa\x57\x86\x9c\xf8\x54\x79\x1a\x4d\xb9\x0d\x6e\xff\x57\x7e\x42\xe7\xf7\x20\xe1\xcf\x74\x62\x6e\x08\x2a\x74\xe5\x25\x7a\xb0\x67\x6c\x9c\x1c\x82\xb3\x8b\xf3\x19\xeb\x7d\xc7\x34\xd0\xfa\x9e\x17\x26\x0f\xc9\x96\xfb\xe2\x0f\x2c\xfe\x98\x14\x6f\xbe\x7b\x24\xfe\x97\x78\x82\xb9\xbf\x15\xa7\xba\x20\x21\x07\xcf\xf7\xde\x88\x49\x0e\xc9\x77\xdf\x92\x71\x3a\x5f\x2c\x45\xd8\x98\xd3\x4b\x32\x4f\xcf\xa2\x64\x8a\x82\xa3\x3d\x26\xe3\x59\x90\xc1\x5e\xc0\x6f\x66\x43\x6e\x4a\x25\xcd\xd5\x25\x74\x4c\xf9\xa3\x85\x22\x65\x0d\x72\x5c\xe5\xa4\xb3\x47\x76\xc9\xe6\xb0\x47\x9e\xb3\xff\x37\x7b\xa4\xdf\xef\xf7\xc8\xff\x91\x5d\xb2\xfd\x4d\x97\x1d\x76\x48\xbe\xa0\xe3\x68\x12\xf1\x85\x74\xf0\xfe\x70\x73\xfb\xc9\xe6\x13\xdb\xc4\x2c\xca\x53\x48\x17\xe3\x70\x9d\xe4\x5e\xf3\xb7\xb8\xac\x23\x6c\x80\xe6\xd5\x1a\xbe\x59\x16\x92\x54\x28\xc1\x84\xcf\x06\xb3\x7e\x63\x42\x59\xc5\x78\x1e\xd9\x88\xda\x7b\xed\x3e\x43\xcb\x7e\x1a\xd2\xbd\xa2\x33\x44\x5a\x6b\x36\xb6\xf6\xff\x39\xd9\x9c\x01\xf2\xf7\xc2\x40\xac\x45\x7a\xb4\x58\xd0\x6c\x3f\xc8\xb5\x2a\x1b\x65\xf3\x67\xc7\x9d\xc7\x5d\xf9\x12\x58\x24\x0c\x7b\x8f\xad\x1b\x33\x9e\xbb\x88\xa3\xa2\xd3\x6e\x77\xcd\x57\xd8\x49\xd7\xb4\xae\x1a\xa7\x21\x1b\x5c\xe2\xeb\xbc\x94\x0f\x01\xe6\x87\x5d\xb2\xc7\x04\x42\xf8\xf8\x7e\x97\xfc\x5f\xd7\x09\x69\xe0\x99\x59\x31\xb1\x06\xa4\xf2\x98\x1b\x52\xf2\x88\xec\x91\x0d\xb2\x39\x44\x76\x46\x3e\x37\xff\x32\x94\xaa\x6d\xc3\x74\xdd\xed\xff\x9a\x46\x09\x1b\xa6\x6d\xa9\x38\x5e\x82\x0b\x57\x98\xe2\xd7\x87\x2f\x18\x61\x6f\x0e\x25\x53\x12\x16\x7e\x40\xf9\x1e\x8a\xfb\x76\xf8\xe4\xb1\x4d\x70\xf3\x34\xfc\xee\xdb\xcd\x61\x19\xa1\x99\xf4\xa5\xdd\x32\x73\x6a\x12\x85\x2b\xa9\x28\xa3\xf3\x20\x4a\xb8\xee\x88\xe5\xe9\xbb\x47\xe1\x3a\xc8\x64\x0f\x02\x58\xdb\x2d\x6f\x75\x2d\xa7\x48\xc0\xac\x24\x98\xb2\x78\xfd\xce\x30\x91\xd3\x4d\x82\xac\x7d\x90\x14\xdc\x87\x4f\x8f\x6c\x0e\xbb\xe4\xff\xcf\xb0\xb6\xe1\xd4\xc2\x5d\x2e\x09\xf3\x73\xdf\xcb\x5f\x55\x97\x2a\xa9\xeb\x33\xe6\xa9\xfe\x1d\x12\x37\x41\x87\x75\x20\x0c\xfe\xe1\x42\x1d\x12\xc4\x5b\x07\xc1\x3e\xe5\x7c\xf9\x27\x67\x80\x9d\x77\xfb\x27\x41\x58\x42\xeb\x25\xe7\x76\xd5\x09\x9a\x5b\xd7\x4f\x0a\x31\x95\x96\x73\xf9\x3a\xc7\x22\x2a\x06\xb3\xa7\x72\x9c\xbe\x07\x28\x4b\x8a\xd1\x6c\x08\xd7\x8a\xad\x61\xad\x18\xcb\xe9\xa3\x1a\xab\x9c\x21\x80\x8e\x28\x7f\x2e\x7d\x15\xa0\x97\x0a\x22\xb8\x29\xd9\x7c\x82\x58\xd8\x69\x90\xd3\xed\x27\x64\x17\xca\x68\xf5\xd0\xf6\x13\xc3\x04\x20\x0c\x29\xd7\x2c\xc2\x1e\xd8\xe1\x85\x7a\x64\xf3\x1b\x53\x12\x56\xfd\x7c\x7e\x1a\x24\x1d\x5e\xcc\x64\x7e\xd6\x62\x16\xfe\x56\xd0\xc2\x7d\xce\x86\x5e\xa4\xc6\xee\xc5\xa6\x8f\x80\x9f\xd6\xec\x52\xae\x68\xae\x4c\x02\x7b\xdd\xb7\x3c\xb4\x45\x92\x16\x42\x28\xfb\x3e\xfa\xa1\x35\x05\x89\x84\xfb\xf1\x99\x68\xa4\xe6\xb3\x80\x4b\x6b\xb0\xbf\x5d\x8c\xe3\x65\x1e\x9d\xa9\x48\x9c\xd1\x69\x14\x47\x85\x12\x70\x4e\x83\xe4\xd3\xe0\x34\x0b\x92\xf1\x8c\xe4\x34\x3b\x8b\xc6\x72\x03\x0c\xb8\xdb\xd8\xd6\xf7\x83\xe8\x87\xbe\x4d\x43\x2a\x2a\x46\x2e\x77\xa1\x09\xcd\xd8\x36\x14\xc4\xd3\x34\x8b\x8a\xd9\x9c\x84\x34\x1f\x67\xd1\x29\x67\x4b\x42\xfe\xa1\x49\xff\x3c\xfa\x14\x2d\x68\x18\x05\x20\x04\xb1\xaf\xc1\x41\x52\xd0\x2c\x09\xf8\xd3\x89\x8f\xcf\x83\xe4\xd3\x47\xe1\xb3\xf6\x23\x9f\xd7\xff\xdf\x4f\x62\xa4\xc9\xf4\x23\x1b\xe2\x47\x78\x4b\xf4\x31\x8c\xa6\x91\xf3\x94\x43\x4e\x8d\x8f\x22\x4f\xe5\x9e\x2a\x67\x40\x3a\xc3\x29\x52\xcf\x36\xdb\x80\x56\x9f\xdb\x2b\xf2\xd4\x62\x8b\x62\x46\xf7\xf9\x3e\xd5\xfe\xe7\xcb\xf6\xce\x9a\x97\x67\x0a\x1e\xdb\xb1\x76\xee\x0e\xae\x60\x83\xb4\x87\x20\x2a\x41\x2b\xd8\xdc\x85\xa1\xe3\x05\xc3\x06\xd9\x25\x1d\x2e\x4e\x75\xbe\x7b\x4a\x1e\xe9\x26\xba\xf2\xd9\xc0\xa3\x2d\x6b\xbf\x55\xde\x3e\xcc\xa6\x50\x9d\xa2\xc1\x1a\xb5\x95\x60\x22\x08\x57\x40\xd8\x3c\x1e\x7a\x94\xe4\x45\x54\x2c\x0b\xe9\x79\x39\x0a\x69\x52\xb0\x4d\xcb\x8e\x23\xc0\x6b\x39\x48\xc2\x28\xa3\xa6\x01\x83\xf9\xc6\x26\xef\x49\x59\x56\x3d\xb2\x81\x57\x53\x2d\xd4\x52\x0b\x9a\x6a\xe9\xb6\x5a\xab\xf0\x22\xb3\x27\x5e\x6f\xcc\xe6\x11\xd8\xe4\x0c\xed\x97\x1f\x5e\xb1\x79\x90\xaf\x5b\x30\x06\x50\xaa\xea\x5b\xd7\xe2\xd7\x69\x15\xbf\x96\x4f\xe9\x38\x72\x45\xb0\xf1\x28\xe7\x2f\xe5\x30\x1f\x77\xe4\x4e\xf0\xdc\x52\x2a\x6f\xaa\xbd\xc8\xa3\xf8\x90\x0a\x0f\xfe\x9c\x8e\xb7\xa4\x84\xce\x03\xe4\x17\xa6\x52\x4e\x88\xb0\x7f\x99\x88\x93\x15\x16\xfe\xb4\x73\x99\x5a\x5d\xb9\xc2\x02\x74\xbd\xf4\xf5\x20\x1e\xb3\x0e\x32\xe1\x1d\x55\x8f\xa4\x1e\xad\x0d\x8c\x0d\x6b\x6b\xdc\x51\x5a\x94\x30\xf8\xcf\x3f\x5f\x1e\x0f\x1f\x7d\x77\xf2\x79\xeb\xba\xf3\xf2\xc3\x2b\xf6\x7b\xef\xd1\xff\x9d\x7c\xde\xdc\xbe\xbe\x52\x1f\xdb\xc3\xde\xf6\xe6\x75\xf7\x7f\x06\xfd\x02\x94\xa0\x6a\x03\x37\xde\xe5\x95\x31\x06\x04\xce\x9f\xe7\x6d\xae\x88\x30\xf1\x04\x13\x4e\xff\x5e\xb4\xbd\xd0\x4b\xf0\x6e\xf0\xf6\xc2\x5d\x49\x16\xe2\xf4\xa0\xf0\xe3\x9e\xed\xc7\xe4\xea\xaa\x2c\xef\x9b\x1b\x0e\x7b\x42\xa2\xa4\x64\xe0\x06\xf7\xb9\x9b\xa1\x7b\xd9\x48\xa3\xc1\x6f\x0d\x1b\x59\x6d\x72\x91\x92\x8d\x34\x5f\xce\x19\xe0\x51\x2e\x8e\x0f\xf3\x34\x7c\xf4\xdd\xb7\x8f\x36\x87\x2a\x1b\xce\xb8\xd0\xbb\x71\x1a\x93\xce\xc1\xfb\xc3\xc1\xc1\xcb\x7d\xc2\xce\x0d\xa3\xad\xe1\x70\xbb\x6b\xf3\x64\x54\xad\x7b\x0a\x45\xb9\xce\xc0\x65\x5e\xc3\x61\x8b\x33\xe1\x56\x8f\x6c\x35\xb3\x55\xc5\x4c\xd5\xd8\x52\x08\x9d\xf6\xc9\x3f\xdf\xbd\xfc\xc9\xf1\x90\xa8\x0a\xf8\x47\x53\x5a\xa3\x3b\xa9\x08\xb2\x6e\x78\x9a\x00\x3a\xe0\x3e\xcf\x19\xf2\xb7\x3d\xf2\xb8\x4b\x46\xa4\xdd\x6e\x34\xee\x71\x1c\xc1\x43\x32\xd5\x41\x50\x3e\x45\x89\x3d\x3e\x86\x85\x9f\xf6\xfe\x71\xf8\xe3\xbf\x0e\xdf\xfd\xaf\x3d\xab\x50\x47\xc9\x9c\xda\xf5\x7b\x27\x97\x03\xdd\x7a\xec\x9b\x9b\xab\x8f\x5c\xac\x26\xff\xb9\xc4\x3d\x78\xb8\x43\x73\x2a\x70\x86\x17\x78\xce\x21\xf8\xde\x49\x0c\xce\xe7\xf8\xcc\x38\x74\xb8\x03\x7e\x8c\x0e\xb1\xa5\x47\x19\x79\xfe\x50\xa7\x14\xe3\x84\xca\xcf\x28\xe6\x79\x66\xf3\x49\xb7\x47\xb6\x86\xca\xb5\x9a\x21\xe5\x49\xf4\x5a\x83\x94\x85\x9b\x2d\xd0\x12\x6f\x58\x07\x90\xc5\x95\xfa\x58\xaf\xd8\x1a\x99\x9f\xd7\x27\xbd\xed\xc7\xf7\x6a\xfc\x7b\x35\xfe\x5f\x5c\x8d\x2f\x54\xf8\x8b\x71\xb5\xfd\xde\x2d\x2c\xee\x5a\x3a\xe2\x62\x6b\x67\xa5\x48\x71\x35\x76\x7a\x5c\xcf\xb4\x18\x7b\x2d\xc1\x16\x41\x31\xeb\x91\x84\x1a\xd6\xdf\x1f\x41\x73\xe1\x3c\x3c\x95\x57\xd5\x38\x56\xb5\xf4\x5a\x20\xec\x75\xc0\xc6\x87\xfd\xc7\x53\x75\xd6\x58\xdd\xf0\x02\x57\x2c\x64\x42\xe7\x33\x83\x1e\xe9\xf2\xca\xc7\xa6\x55\xac\x9f\x26\x9d\x36\x8c\xaa\x8d\x63\xbb\x76\x0d\xfb\xe9\x3c\x65\x4c\x8c\xbf\x25\x3c\x78\xbb\x4f\xf4\xbd\x32\x7f\x61\xd8\xee\x11\x8a\x58\xef\x47\xce\x06\xc5\x85\x77\xc7\xf6\xf2\xe9\xed\x41\x12\xe2\xf6\x51\xf3\xa5\x95\x91\x35\xf5\xc6\xe0\xe7\x83\xf7\x1f\x5e\xbe\x81\x15\xb4\x7f\xf8\xe6\xcd\xcb\xfd\x0f\x07\x87\x6f\xc8\xbb\x97\xef\xdf\x1e\xbe\x79\xff\xf2\x7d\x69\xab\x61\x50\x04\xb8\x59\xf6\x8d\x37\xa7\xc1\x43\x61\x46\x38\x0f\x2e\xc6\xe9\x7c\x11\xd3\x8b\xa8\xb8\x1c\x91\x27\x40\x59\x56\x0f\x41\x17\xaa\xec\x10\x58\x55\x7a\xbf\xe9\x7a\xc2\xe5\x08\x9b\x83\xcf\x66\x5c\x6e\x38\xf8\x85\xb6\xed\x84\xe8\x0e\x8f\x57\x0e\xfc\x25\x24\xe7\xb3\x68\x3c\x23\xf3\xa0\x18\xcf\x84\xf8\xca\x37\x21\xc6\xd0\x42\xa3\x9c\x27\x3a\x05\x34\xed\x0f\xdc\x0d\xd7\x51\x4e\x6f\xc1\x02\xc1\x1f\x56\x37\x9a\x74\x3e\xfa\x09\xf9\x18\xde\xc6\x45\xe1\x89\xeb\x6c\x5f\x15\x66\x63\x15\x60\x3b\x0e\x94\x1d\x02\xbd\x34\x34\x30\x54\x23\xfa\x6e\x57\x74\xed\x60\x71\x12\x65\xd4\xf0\x08\x60\xa3\xab\x6c\x3c\x6c\x28\x9e\xd6\x2b\xc0\x75\x9c\x62\x6c\xda\xa2\xff\x42\x1a\xd3\x82\x56\xd5\x60\x0f\xc6\xc6\x0d\x7e\x85\xfd\x0b\xdb\xb5\x80\x10\x05\x41\xf0\xfa\x40\xb9\xc3\x6d\xa5\x12\xee\x2c\x87\xa4\xdc\x87\x74\x54\xf4\xd7\xd6\xa4\x30\x68\x92\xf0\x9a\xad\xf6\x80\x17\x99\x4c\xf8\xd3\x3c\x0f\x89\x47\x66\x61\xec\xd1\x15\xaf\x2a\x9b\x0d\xf6\x2c\x79\xed\x1f\xdc\x65\xbb\xf6\x3c\x2c\x97\xf8\x8b\x97\x8f\xf6\x5f\x1d\xbd\xf9\xdf\x97\xef\x54\x3d\x21\x1d\xcf\x96\xc9\x27\x1a\x8a\x57\x25\xfc\xc5\xa8\xf8\xeb\x67\x74\x11\x07\x63\xda\x19\xfc\xfb\xfa\xf8\xdf\xc9\xbf\xb3\x93\x67\xff\xfe\x3c\x98\xf6\xda\xd7\x57\x8f\x1e\x5d\x7d\x6e\x77\xc1\x67\xf2\x67\x2f\xfc\xbf\x4f\x64\x89\x63\x51\xe6\x84\x15\x3a\x96\xa5\x4e\x8e\xfd\xe5\xec\x52\x46\xa1\x92\x32\xba\x2d\xd4\x92\x6a\x08\x95\x11\xd7\x7c\x2c\xbb\x2d\x39\xa9\x81\x01\x77\xcd\x02\xe2\x11\x7f\x19\x0c\xe0\x0e\x94\x0a\x77\x18\xe0\x69\x03\x2a\x58\x73\x48\x9f\xe5\xed\xb3\x2c\x73\xe5\x0a\xbf\x33\x16\x0c\xd9\x20\xfc\xfd\xab\x21\xaa\xab\x3b\x6b\x8b\x93\xb9\x4e\x0d\x7c\xb6\x60\xd0\x77\x54\x4a\x58\xd3\x70\x63\x9a\x35\x77\xf1\xe9\xce\xec\xda\x9d\x11\x43\x07\x5f\xbf\xca\x82\x1a\x5c\xdf\x25\x63\x1a\x43\xa4\x00\xf9\x88\xd3\x28\x33\x8e\x69\x90\x49\x13\x2e\xab\x15\x91\x6c\x2d\x68\x3f\x10\xf8\x6a\x28\x64\x45\xbe\x3d\xce\x2c\x6f\xef\x75\xf8\xaf\xd2\xae\x52\xe0\x0c\xc3\x5f\xf7\xc8\xe6\x70\x38\x24\x0f\xf9\xe5\x8c\xe7\xae\xd5\xeb\xf8\x01\xde\xed\x01\x76\x24\xbe\x18\x07\xc9\xa9\xa0\x17\x1e\x72\x47\xbc\xeb\x5b\x1d\x55\xee\x8c\x59\x24\x02\xb1\xa4\x84\x65\xa5\xd3\x61\xce\x22\x78\x7c\x7b\xd3\x6e\xcf\xd2\xd6\x63\x70\xe1\xfc\x87\xf1\xc8\x9f\xc4\x16\x1a\x84\x61\x8e\x03\x9f\x0b\x2b\x07\x57\x1a\xe3\xea\xe1\xde\x1a\xdf\x70\xe5\xc1\x40\x9c\xb5\x23\xee\x87\x5f\x70\x3d\xd8\x8d\xe5\xad\x90\x4a\x3d\x08\x79\xa9\x20\xcb\xa2\x33\x8a\x19\x6e\x10\xaa\xd9\x93\xed\x55\x70\x58\x0f\xb4\xe1\x86\xdf\x6f\x53\x8a\x64\x0a\xf9\x5a\x3d\x82\x08\xa9\xe2\xeb\x78\x78\xa2\xb6\x4c\xb8\xc2\xe6\x7d\xd3\xd0\x22\xc1\x2c\xc1\x13\xb1\x44\xe7\xdd\xbc\xc8\xae\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\x89\x5e\xf2\x93\xa2\x6f\x00\xa6\x13\x98\x8e\x1f\xa8\x3f\x0b\xf2\xc3\xf3\xe4\x2d\x04\xd4\x2a\x2e\x21\x60\xa2\xc5\x05\x4a\xd0\xf3\x89\x5e\x9e\x94\xdb\x76\xb6\xd3\x84\x1c\xbc\xdd\x6f\x77\xad\xc5\x2f\x64\x8b\x8a\x3a\x1d\x33\x0b\xbd\x4c\xf6\xb1\x0f\x42\xe1\xe6\x9c\xa0\xe3\x46\x94\x93\xbc\x88\x78\x94\x95\x28\x44\x44\x8d\xcd\x42\x4b\x11\xee\xb7\xe3\xec\x94\x9f\x96\xa4\x1c\xc0\x76\x8f\x8c\x8a\x7e\xf4\x38\x15\x98\xbd\x9a\xa6\x09\x15\x9a\xa7\xce\xfa\x47\x5b\xec\x3f\xcf\xa2\x02\xfc\xa5\x58\xdc\x08\x81\x58\x47\xa8\x8f\xee\x19\x4a\xba\x18\x5c\x2f\xab\x5d\x28\x90\xbc\x43\xaf\x7a\x41\xb0\x86\xe9\xc7\xaa\x97\xbe\x47\x4f\x57\x88\xb1\xc9\xee\x18\x9c\x7b\x05\x14\x49\x34\xd5\x63\x89\x78\x8e\x50\xb5\x67\x4d\xd9\xcb\x10\x3d\xfb\xf5\x8d\xaa\xc2\xe2\xf9\x66\x62\x83\xa2\x6a\x2c\x35\x98\x43\xa9\xdd\x47\x89\xf5\xe7\xdb\x27\x2d\xb3\x3b\xa1\x4d\xb4\xce\x28\x8e\x3b\x9e\x7f\xa5\x4b\xb0\xb2\xd6\xaf\xcd\x5a\xed\x0d\x9b\xdd\x6e\xb4\x5b\x24\xc7\x86\xd9\x7d\x6c\xa7\xad\xf9\x20\xbc\xd8\x4a\x0b\x92\x2f\x17\x8b\x34\x2b\x40\xb7\xc6\x6f\x6a\xdf\xee\x13\xa5\x55\x69\x1b\x8e\x20\xcb\x09\xb3\xf1\x4b\x85\x9b\x2c\xc6\x7a\x2a\x5b\x89\xc2\xbc\xc7\x7a\xa0\xa9\x4a\x0b\x7a\xe4\x50\xd7\xde\x4d\x4b\xbd\xdd\xb8\x7a\x5c\x8d\x41\xc7\x49\x7b\xc9\x2b\xed\xeb\x93\xde\xf6\x37\xf7\x2a\xdd\x7b\x95\xee\x7f\x85\x4a\x57\x3c\xac\xb8\xd5\x73\xec\xbd\x20\x4b\x13\xf2\xbf\xcb\x79\x70\x16\xe5\xe4\xfb\x80\x7d\xfe\xed\x13\xff\xec\xcf\xa9\x57\xdd\x3b\x18\x90\x83\x24\x2a\xa2\x20\x8e\x7e\xa3\xe4\xef\xbc\x17\x8c\x50\x03\x92\x83\x25\x96\x34\xb8\x81\x81\xb2\xa5\x6a\x38\x39\xef\x83\x56\x57\x16\x93\xd1\x4b\x44\x64\xad\x83\x70\x44\x86\x75\x37\x6f\xdc\xda\x83\x0d\xdf\x76\xab\xeb\x35\x33\xf1\xba\xd3\xd5\xaf\xd0\x64\x10\xaf\x89\x44\x28\xb4\xa4\x0d\x7a\x3c\x4e\x78\xf9\xeb\x94\x1e\x52\xf5\x4c\x64\x35\x32\x4b\xfa\xde\xf5\xba\x21\x42\x23\x60\xed\x39\xbd\x1f\xac\x09\xf4\x94\xb8\xe2\xe5\x6d\xf5\x44\x63\x86\xd3\x54\x9e\xd5\x2d\x53\x2d\xcb\x26\x1d\x63\x1e\x65\xb6\xbb\xde\x46\xe1\xb4\x82\xf0\x8c\x9d\x51\xe5\xec\x90\x83\x17\x90\x23\x7b\xa7\x26\x6d\x63\xa3\xcc\xcf\x90\xff\xf5\x0f\x7f\x2b\xe4\x54\xa3\xb3\xe5\xf3\x20\x31\x52\x95\x2e\xdf\x05\xf1\xff\xd9\x81\x49\xbe\x10\x6a\x6e\x78\x21\x71\xa0\x0e\x8f\xd2\x80\xc8\x6f\xaa\xa3\x94\x75\x75\x21\xdd\x3c\x2f\xb3\xad\x06\xfc\xe6\x19\x12\x0d\x56\x7b\x56\xc4\x69\x9e\x68\x5d\x86\x72\x9f\x3e\x48\xe7\x2c\x80\x9e\xa9\xb6\xfb\xf4\x8c\x66\x97\x1d\xe9\x0d\xf9\x7d\x94\x4c\x63\xfa\x9a\x23\xbc\x4b\x46\xc4\x9b\xa1\x6b\x12\xd3\xaa\x3a\xe2\x07\x17\x13\xa8\x0e\x5a\x4a\x78\x97\x74\x83\x2c\x88\x64\x1a\xa7\x48\xc3\xb6\x48\x64\xc8\xf9\xd9\xdd\xdd\xe5\x54\x83\x81\x84\xdb\x05\x09\xcb\xce\xdc\x0c\x8c\x5f\xeb\xb6\x7d\xd5\x09\x19\xd6\xf2\x29\x39\x18\xf0\x98\x83\x2a\x49\x78\x65\xc7\xcc\x45\xae\xc7\x46\xfe\xe4\x39\x23\x3a\x85\xf7\x68\x35\xec\xe8\x39\x03\x2a\x77\xf1\x2d\x3a\x6e\xf1\x17\x5e\x57\xce\x99\xaa\xa8\x4a\x0a\x38\x61\x17\x94\x47\x62\x51\x74\x24\xef\xe9\x92\x49\x44\xe3\xd0\x32\x3d\x10\xad\x18\x3d\xb5\x78\x0e\xee\xa0\xc5\x78\x78\xd7\x2c\x32\x94\xc9\x56\xd4\x07\x49\x16\xae\x23\x2c\x87\xbd\x49\xd8\xbe\x64\x6d\xf2\x5b\xb0\x38\x53\x0f\xef\xc8\x8a\xa2\x3e\x21\x27\x32\x31\xf0\xc9\xbd\x18\x78\x2f\x06\xfe\xb5\xc5\x40\xfd\x3e\x8f\x2f\x9a\xbb\x7a\xa1\x77\x37\x77\xf7\x0c\xe4\xb5\x54\x37\x96\x1a\x2b\xc3\x39\x51\x44\x6a\x91\x56\xc8\xec\x13\x9d\x22\x85\xcb\x35\x99\xcb\x3e\x8d\x8b\x7b\xe0\x79\x3a\x5f\x4b\x06\x43\x04\x06\x3e\xf9\x71\x30\x44\x6d\x08\x8d\x33\x50\x09\xee\xe9\xd9\x57\xc4\xca\x31\x94\xae\xa0\x31\x78\x1d\x24\xc1\x94\xea\xd7\xf9\x8c\x65\x71\x54\x18\xaa\x00\xe9\xc2\x43\x83\xa3\xfd\x7e\x6e\x60\xc8\xa9\x38\x9b\xd7\xd8\xbf\x87\x94\x71\x98\x28\x31\xfd\x7b\x5a\xe2\xdf\x69\x90\x73\x9f\x0b\x65\x91\x28\xa6\x14\xbc\x54\x7a\x36\x29\xd3\xd3\xbc\xed\x58\x54\xb6\x69\xb6\x07\x24\xe6\x20\x42\xb4\x51\x1a\x6b\xc2\x70\x27\x8a\xc2\xe7\x28\xe2\x50\x76\x7c\xd2\x97\x61\xce\x04\x1b\x95\x52\xe7\xe6\x98\x3b\xe3\xd4\x97\x14\x22\x34\x87\xd8\x76\xd5\x38\xfb\xe4\x35\x63\xe5\x11\xcd\x45\x74\x6c\xc0\x87\xe3\x85\xd2\xf0\xec\xd9\x18\x6f\x72\x50\x57\x6f\x96\x71\xac\x1d\x63\xf4\x98\x14\x49\x2f\x22\xb8\x36\xf3\xe1\xee\x8f\x19\x7f\xe8\xce\xc2\xee\x90\xb5\x2f\x15\x77\xc7\xc1\x64\xa3\x68\x3b\x76\x80\x13\x15\x4a\xc6\x3c\x88\x91\x9a\xf0\x31\xef\xde\xee\x8b\x08\x13\xd5\xb1\x63\x34\xda\x84\xab\x57\x4e\x78\x80\x74\x75\xe2\xb4\xd1\xc4\x41\x0f\x18\xa4\x8b\x25\x83\xe8\x54\x92\x07\x1d\xa8\x96\x4a\x6c\xac\x7b\xb8\x6b\x09\x05\xf9\x1e\x37\x7a\x4a\x5b\x32\xa4\x72\xba\xd8\x23\x10\xfd\xbb\x2a\x84\x14\x79\xa6\x7f\x73\xea\x86\x22\x27\x8c\x1d\xa0\xcf\x1a\xcf\xfa\x0e\xd6\x39\xbf\x57\x51\x73\x31\xe6\x5d\xc4\x73\x07\xbc\xd5\x67\x45\xd3\x1d\x71\x09\xee\x3d\x31\x52\xcc\x20\xbd\x18\x85\xf6\x66\x05\xce\x66\xe0\xd8\xf3\xcc\x0b\xa0\xaa\xf2\xc6\x26\x11\xb8\xf0\x85\x2c\x92\xef\xa7\x24\x1d\xae\x10\xb9\x28\x90\xeb\xb6\x11\x12\x9a\xc5\x20\xc2\xee\x58\xc5\x3e\x62\x7b\x49\x5e\xd9\xf9\xb2\x90\x27\x00\x18\x2d\x03\x0c\x08\x79\x46\x80\x21\x75\x4c\xf1\x6b\x41\xa4\x3a\x03\x34\x4b\x25\xca\x8c\x2a\xb7\xca\x58\xc5\xe1\xa0\x4a\xba\xc8\xe5\xf8\x34\xa5\xad\xd3\x5f\x31\xba\x58\x86\x1c\xda\xe9\x32\x8a\x43\x40\x98\x18\x14\xcb\x74\xfc\xdb\x02\xc3\xff\x70\xf8\xe2\x70\x7d\x7d\x1d\xc4\xfb\x76\x4e\x96\xd3\xf8\xb2\x2f\xa2\x88\xb1\x03\xc1\x32\x67\x7b\x62\xa1\x5a\x49\x90\x4b\x59\xf6\x5b\xda\xd5\xa8\x1b\x12\xc6\x38\x20\x43\xbd\xb7\xde\x34\x22\x3d\x9d\xfe\x7a\xcc\xb2\x8f\x87\x27\x27\x4c\xec\xc2\x9f\x57\x57\xca\x6e\xd3\x06\xe5\x3f\x36\xa1\x0c\x1b\xcb\x8e\xff\xaa\xc8\xaa\x1d\x20\x09\xe2\xc2\x0e\x7a\x15\xa2\xca\x6e\x51\xd5\xa5\xba\x36\x3a\xe5\x21\x50\x12\xff\xb3\x2c\xe2\xf8\xf9\x16\xf2\xbb\x3e\x0d\xaf\xe2\x07\x9a\x58\x11\x2c\x7c\xa1\x0a\x8c\xb3\x3a\xb4\x65\x4a\x94\xfa\x62\x4a\xdf\xcf\x18\xb1\x58\x94\x79\x9d\xc7\x34\xcf\x6e\x98\xc3\x8b\x76\x30\x33\x53\x46\x91\x96\x01\x8d\x37\x9c\x8a\xd9\x5d\xa3\x9a\xf2\x21\xd8\xd7\x50\x82\x54\x58\x56\x53\x4f\xcf\x32\xcc\x15\x4d\xea\xdd\x39\x4a\x0e\xb9\xcc\x28\xdc\x90\xbe\x7b\xbb\xaf\x3c\x30\x71\x53\x96\x71\x90\x28\x61\x33\x4a\x84\xd2\xc5\xef\xeb\x29\x73\x7d\x3d\xf6\xfb\xfd\x6b\x1c\xdf\xcd\xf6\xa5\xa7\x35\x99\xb2\xa8\x87\x93\xd6\xf9\xb4\x2f\x75\x37\xbf\x0a\x11\x4a\x1a\x30\x7d\xd2\xe3\x59\x2b\x43\xb4\x28\x59\xa2\xd8\x79\x2d\x6d\x60\x9a\x5e\xff\x7d\x7b\xaf\xf7\xb9\xd7\xfb\xfc\xb5\xf5\x3e\x42\xe9\x13\x9e\xde\xe2\xe6\xcf\xa7\xf7\x51\xda\x1a\xac\xf8\xe1\xcc\x49\x69\x74\x5e\x3c\x37\xf8\x08\x1b\x86\xe9\xf2\xc3\xd1\x54\xc0\x48\xad\xe4\x9d\x8a\x40\x61\x6b\x5a\x5e\xca\x3b\x1e\x9b\x7e\x71\xc1\x45\x3e\x13\x4b\xba\xb2\xe4\xa0\x0e\xab\x19\xed\x2c\x02\xc8\x51\xbb\x74\x7c\x1d\xb4\xf4\xcd\x7a\x97\x2f\x0f\x58\xb4\x58\x16\xea\xf1\x5a\x42\xcf\x05\x36\x3b\x7a\xbb\x64\x42\xc7\x88\xb4\x15\x9c\x15\x47\x63\x44\xda\xe1\xe9\x47\x5f\xae\x14\x13\xb7\x55\x9f\x54\xa3\x53\xda\xac\x51\x05\xe7\x6d\xd4\x97\x2b\x1b\xdd\x72\x1b\x5d\x2c\x8b\x57\xf4\xa2\x7e\x98\xaf\xe8\x45\xd9\x18\xcd\xac\xea\x01\xd6\xb7\xc5\x81\xca\x86\xe6\x6f\xcb\x1a\x97\xd8\x8c\x8e\x35\x9c\x9c\x88\x9e\x46\x72\x4f\x0c\xbd\x27\xba\x05\xc0\x27\x25\x3b\xd7\x8b\xe7\x7a\xd7\xe2\xb4\xd3\x1a\x6d\xc3\x16\xf5\xf4\x7e\x8b\xba\xdf\xa2\xfe\xda\x5b\x94\xbe\x9a\xa0\xc5\xec\x46\xf7\x12\x02\xf8\x6e\x5f\x25\x96\x44\xff\xf7\x85\xff\xf7\x5d\x82\xf8\xef\x41\x6a\xb6\x4d\x06\x22\xcd\x91\x2d\xa0\x85\x48\x96\x60\xe3\xb2\xf6\xc6\x69\x32\x89\xa6\x12\x0c\x85\xc2\xc1\xd0\x32\xb2\x8a\x04\x3b\x17\xcf\xd6\x8c\x0b\x1a\x91\x28\x61\x7e\xe4\xa1\xc0\x2d\x64\x40\xa2\x04\x39\xc8\xdf\x5f\x26\x63\xbe\xc5\x60\xa8\x9c\xa7\x4a\x30\xc6\x8a\x33\x6a\x03\x89\x54\x55\x17\x77\x50\x84\x21\xa2\xd3\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\x0e\x4f\xba\xe4\xc1\x03\x22\x7e\xf7\x41\x27\x78\x38\xe9\xb4\x87\x17\x6d\xee\xba\x64\xd8\x25\xcf\x48\x8b\x16\x33\xb6\x7b\x40\x60\xd2\xe7\x97\xaf\x82\x7c\xd6\x22\x23\x3b\x99\x6b\x74\x5b\x5a\x4a\x80\xae\xbd\x8f\xa6\x09\xcd\xf2\x8a\x1e\xde\x71\xff\x44\x83\x25\xdd\x54\xb9\x4e\x6f\xf3\x22\xf8\x44\xb3\x77\x87\x07\xf5\x5d\xbd\x59\x4f\x51\x47\xdf\xcb\xb6\x5e\x07\x79\x41\xb3\x24\x0d\x29\xee\xa9\xca\xb6\x91\xf9\x63\x94\x04\x71\x54\x5c\xfe\x7e\xd8\x94\x2d\x96\xa0\x53\x67\x3b\xf8\x44\xd1\xbf\x7e\xcc\xd2\xf9\xf3\xdf\x81\x4e\xdb\xa2\x6b\x28\xa8\xd4\xf3\x4b\x68\x98\x75\x7e\x2f\x09\x0f\x58\x39\x15\xcb\xcd\x0b\xc9\xc7\xa1\x60\xf5\x78\x96\xc9\x38\xa6\xbf\xd3\x00\x8e\x58\x5b\x35\x5d\xc7\x30\xa5\x9d\x96\xf3\x84\xc6\xb9\x9f\x2e\x93\x46\x97\x8c\x77\x30\x0e\x6f\xdb\x9c\x94\xf0\x50\x4a\xc0\xf8\xa8\x9c\x29\xf8\x1d\xfb\x7f\xa4\x1a\x44\x93\xe1\x4c\x02\x06\x30\xfa\xac\xba\xf7\xb2\x98\xdd\xf5\xf1\xb0\xf1\xd1\xf0\x8e\x4e\x86\x10\xfe\xb9\xfc\x64\xc8\x15\x5f\x7c\x0f\x8f\xa8\xb7\x47\x0b\xdc\x99\x45\x4d\x3f\x16\x37\xe8\x02\xb2\x70\xe0\x7b\x2b\xf7\x7e\x42\xb0\x7f\xf6\x83\xe7\x7b\x6f\xac\x50\x74\x62\x47\xe5\x3a\x39\xfe\x7c\x5a\x68\xe6\xae\xd7\xd6\x78\xef\xfa\xdc\x2e\x4e\xbd\xa4\x7a\x59\xcc\xb4\x2e\xb0\x47\xda\x38\x70\x77\xbb\x27\x86\x39\xa5\xc5\xa8\x44\xe3\x2d\x3d\xd5\xf6\x71\x41\x31\x92\x9e\xd0\xd2\x1a\x85\xcf\x82\xd8\x88\x31\xd7\xb7\xc2\xa6\x9f\x05\xb1\xe3\x8a\x46\xa5\x5d\xaf\x01\x7a\x56\x1a\x8a\xf0\xf2\x78\x93\xc1\x88\xa2\x37\x19\x8e\x28\xda\x70\x40\x4d\x34\x11\x8c\xbb\x04\x31\xd8\xed\xd6\x9e\x9b\x05\xa0\x7b\x76\x96\x6c\xca\xc9\x57\x07\x68\x64\xcb\x6b\x5c\xe0\x8e\xc8\xb1\x16\xa7\xf9\xe5\xae\x70\xa2\xfa\xa3\xbe\xcb\xb5\x21\x70\xdc\x7b\xce\x4f\x14\x30\x0a\x1c\x6a\xdd\x62\x8e\x70\x35\x3c\x4f\x79\x2c\x52\x40\x25\x4a\x93\x34\x0b\xa6\x74\xaf\x68\xa2\x37\x11\xa0\xa5\x38\xf2\x41\x28\x95\x46\x05\x96\xf8\xba\xe3\x1c\xbb\x48\x41\xaf\xb0\x0a\x5a\xbc\x03\x13\xae\x3d\x6b\xc6\xc4\xa0\x4a\x87\x63\x65\xfe\xfe\xf3\xed\x1d\x98\x58\x26\x07\xc9\x24\xad\x1f\x1f\x02\x2e\x1d\xa6\x1f\xe6\x0f\x32\x5a\xc9\xe3\xea\x56\x2f\x67\xbe\xd6\x08\xd5\xf1\xe8\x76\xc3\xf2\xf5\xb6\xe7\x30\x34\x6d\xeb\xcd\x58\x15\xb9\x5e\x6d\xb5\x82\x3c\x5d\xb9\x52\xf1\x09\xc6\x8f\x10\x0b\x1d\x02\x56\x61\x05\xe1\x04\x9d\xcb\xec\x38\x23\x9b\x32\xe1\x46\x68\x51\x83\x6e\x38\x64\xd1\x91\x3a\x1e\x25\x4e\x44\x4d\x78\x94\x00\x75\x68\xc1\x38\xe1\xb9\xf4\xb0\x59\x45\x0f\x52\x88\xb1\x76\x2e\x62\xec\x4e\xd8\xe6\xa6\x64\x3d\xf0\x0a\x46\xa6\x3b\x83\xa6\x84\x82\xaf\x10\xdf\xd1\x20\x2e\x27\x12\x79\x2e\x6b\x44\x25\x12\xd8\x47\x26\xf8\xc4\xf9\x15\xe8\x04\x8f\xf8\x20\x29\xbc\x03\x06\x19\xbc\x9e\x2e\x00\xcc\xa1\x09\x75\xaa\xfb\x12\xfc\x01\x6d\x67\xb7\x60\x05\xbd\xb5\x92\xdd\x6d\xbe\x88\xe2\x52\x4e\x60\x6e\x71\x02\xb4\x62\x9f\x73\x21\x24\x1e\x86\xe5\x64\x66\x9f\xd9\x1a\x72\x69\xbb\x98\xd3\xad\xaa\x63\xeb\x8a\x0b\x77\x15\x4a\xf4\xcc\x8d\x9c\xc2\x17\x74\x1c\xcd\xab\x56\x9c\x3e\x09\x36\x44\x82\x2e\x50\x42\x94\x7f\xdc\x01\x9b\x07\xa8\x9a\xc1\x96\x47\xcb\x2f\x51\xc3\xc0\x19\xbb\x72\xd0\xf5\x2b\x08\x55\x58\xbd\xb1\x7c\xf0\x68\xa9\x56\x1a\x93\x2a\xe5\x0c\xae\x4c\x01\xf6\x47\xe2\x34\x37\xc1\xd3\x3b\x3a\xa6\xd1\xa2\x01\x99\xbb\x65\x9a\x10\x80\x0b\x7a\x5b\x0a\x10\x35\x36\x1e\x60\xc3\x55\x5c\xcb\xc5\x3c\x83\xb3\x01\x9b\x50\x00\x3f\x1a\xdd\xd1\x21\xb1\x6c\x79\x13\x69\x6d\x20\xad\xf5\xde\x05\xe7\xcd\x97\xb9\x5b\xc0\x8f\x8c\x4a\xb8\x26\xdc\x8d\xe1\xc2\x73\x4a\x60\xf5\xae\xd6\xdb\x46\x5d\xbd\x79\x3f\xed\xd9\xf2\xad\x33\xdf\x38\xa2\x69\xb2\xc2\x38\x4c\xe8\x92\x71\x94\x02\x7d\xe1\x71\x34\xe8\x7c\x79\x8f\xef\xfc\x14\x5a\x42\x38\xc2\xc4\xb7\xaa\xa3\x0c\xc4\xdf\x51\x2b\xe7\x26\x1d\x65\xfb\xc1\x9d\x9d\x95\x69\x5e\x44\xf3\xa0\xa0\x3f\x05\x75\x32\x21\x82\xf4\x0f\xcd\x0f\x70\x13\x8a\x31\x46\x78\x2b\xc1\x63\xcc\x65\xd4\xf7\x69\x1c\x85\xa5\x47\x1b\x3d\x6d\x1c\xba\x9f\x0b\xf0\x92\x29\x34\xeb\xf4\x8d\xb5\xb4\x23\x3f\xff\xfc\x73\xc3\x3e\xc4\xa5\x14\xa4\x6a\x5a\xa9\xe5\xf7\x34\x5b\xd0\xda\x2d\x4a\x61\x80\x43\x57\x23\xc0\x81\xa9\xe8\x45\xbe\x3c\x9d\x47\xc5\x2f\x69\x56\x27\x29\x69\xc0\x92\x95\xee\xcb\xaf\x36\x80\x6a\xd0\xaa\x80\x2a\xdd\x8e\x4b\xda\xf3\x1f\x73\xf6\x83\x24\xe4\x8f\xfc\x8b\xa0\x58\xd6\x6a\x5d\x2c\x70\xeb\x44\xad\x4e\x5b\x25\x50\x0e\x07\xb9\x03\x75\xdb\xcb\x45\x3a\x9e\x95\xf2\x0e\xdf\x48\x9b\x1c\x28\x15\x6c\xf9\x89\xd2\x07\x72\x13\x06\x52\x3e\x00\x27\x14\xae\xb6\x58\xd3\xda\xfa\x1e\x4e\x53\xda\x69\x23\x75\x3f\x0d\x4d\x30\xa4\x0e\x35\xd2\x81\x0f\xbb\x29\x42\x83\x65\xb5\x24\x74\x4d\x2e\xb8\x54\xa9\x98\x7d\x50\xe8\xf2\x27\x73\x4a\x31\xf2\xe0\x00\x69\x0d\x44\x9c\xe2\xdd\x46\x6d\x19\xd4\x85\xd0\xe7\x51\x23\x0f\x15\x2c\x4b\x57\xa7\x9b\x32\x00\x21\x80\x97\x65\x5b\x8d\x9a\xef\x82\xd0\x4e\xa4\x13\xff\x3f\xf6\xde\x7d\xad\x8d\x5c\x59\x1c\xfd\x3b\x79\x0a\x4d\x7e\x67\x0d\x76\xd2\x18\xdf\x21\x4e\x98\xbd\x89\x81\xc0\x0a\x04\x7e\x40\x66\x66\x6d\x3e\x86\xaf\x6d\xcb\xb8\x13\xbb\xdb\xab\xbb\xcd\x65\x26\xec\xf7\x39\xcf\x71\x5e\xec\x7c\x2a\x5d\x5a\xd7\x76\x9b\x4b\x26\x33\x0b\xd6\xde\x13\x77\xb7\x54\x2a\x49\xa5\x52\xa9\x54\x17\x53\x8e\x94\xbe\xa9\x02\x8f\x5a\xc9\x59\x43\x6a\x5e\xdd\x12\x8c\x0f\x7b\x7b\x7b\x66\x61\xca\x3e\x25\x90\x82\xb3\x29\x9d\x26\x2f\xe0\x99\x19\x4a\xd2\xd4\xae\xe2\xd6\x34\x2f\xd5\x43\x46\xdb\x64\x6d\x8a\xeb\x3b\x55\x15\x29\x38\x7f\x10\xf6\xfc\x44\xd6\x76\x31\x04\x60\x89\x31\xc6\xcf\xca\x88\x22\xb7\x65\x6f\x81\x36\x26\x41\xa8\x1a\xc9\x1a\x2d\xb0\x12\x77\x84\x3f\xf2\x93\x51\xec\xa7\xb9\x7d\x70\x94\x29\x24\x5a\x2c\x8e\x11\x37\xf2\xca\x41\xc8\x5e\x64\xfe\x61\x95\x59\x95\xa9\x27\xd4\xc5\x31\xbc\xf0\x93\xc3\x38\xe8\xe7\x8e\x99\xa3\xcc\x9d\x6f\x13\x17\xc7\x92\x65\x2f\x4c\xf2\xb0\x14\x65\xee\xd8\x46\x4f\xb2\xc5\xc8\x69\xc6\x5d\xec\x91\x68\x88\xa7\x76\xfa\x99\x9a\xec\xe6\xe1\xa6\x17\x95\x5a\x94\x59\x88\x72\x7f\x5f\xe9\x67\xe6\x90\x92\x6d\x4c\x2f\x50\x1c\x1f\xfd\x7e\x1a\xc5\x5c\x7e\xe6\x06\x94\xe0\x8d\xe4\x21\x52\x56\xd9\x53\x59\x69\x5b\x63\x43\x6e\x30\x69\x44\xb4\xf0\x24\xaf\x7d\x5a\xaa\x1b\x63\x30\x78\x06\x1f\xf4\xae\xe6\x95\x27\xa5\x3b\xa4\x46\x98\x19\x1c\x32\x14\x4b\x9e\xd5\x60\xc6\xe3\x56\x9d\x15\x9c\x8e\x4a\x65\xcf\x24\xd9\xbd\xe8\x42\x92\x8c\x8a\xa1\x64\xeb\x68\x66\xcf\x99\x9f\x89\x87\x8f\x7e\x89\x55\xa8\x5c\x8c\xa3\x9e\x3f\xae\x90\x41\xad\xf8\xe6\x6b\x96\x3a\xd5\xd6\x64\xd0\xf7\xa7\x1f\xef\xda\x2c\xa9\x6c\x34\x4a\x5f\xe6\x35\x29\x19\xb7\x66\x0d\xea\x1e\x94\x72\x6a\x4a\x5e\xa1\x64\x9f\x9e\x79\x41\x2d\xb7\xd2\x51\xe6\x16\xa0\xd9\xf7\xbe\xe8\xd4\xd6\xbc\x17\x86\x9d\x31\xf3\x73\xcb\x0c\x7c\x5f\x74\xea\x2d\x78\x41\xe7\xf4\x45\xa7\xfe\x9a\x3e\x0a\x5a\x78\xd1\x69\xd0\x2a\x41\xcf\x0f\x5f\x74\x1a\x0d\x4f\xf5\x42\x80\x47\x36\x48\x2f\x3a\xcd\x26\x3c\x73\x6b\xe4\x17\x9d\x26\x05\xcf\x38\xfb\x8b\x4e\x93\xa2\xc5\xad\x86\x5e\x74\x9a\xa4\x41\x6e\x4b\xfc\xa2\xd3\x6c\xdc\x9e\x79\x8d\xd7\x4f\x6e\x0d\x4f\x6e\x0d\x7f\x6f\xb7\x06\x97\x4f\xc3\xbd\x5d\xef\x8a\x7b\x1b\x14\x70\x25\x80\x72\x1f\x71\xfa\x98\x9e\x7a\xf0\x76\xbe\xed\x63\xe6\xa3\x77\x17\xe3\xc7\x02\x9e\x79\x2b\x2b\x2b\x59\x68\x3b\x5b\xb8\x3c\x96\xf7\x99\xb0\x78\x00\x87\xd3\x11\xf2\xa7\x81\x84\xfb\x23\x1d\x48\xc6\x41\x92\xe2\xbc\xf3\x42\x88\xd3\xf3\xac\xd0\x5d\x85\x2b\x8c\x63\xfd\x82\xc5\x68\xc5\x55\x68\x01\x81\x4f\x16\xbf\x8c\x4d\xed\x23\x4e\x2d\x9b\x9a\xba\x79\xc9\xbb\xcb\xed\x99\xd7\xac\x3e\xed\x16\x4f\xbb\xc5\xdf\x7b\xb7\xf8\x4e\x9d\xe0\x1e\xce\x5f\xad\xa0\x3b\x5d\xe6\x13\x70\x88\xe3\x24\x0a\xfd\xf1\x93\x63\xc0\x63\x3b\x06\xdc\x16\x33\x15\x0f\xf1\x55\x66\x7f\x9e\xa7\x00\xcf\x0a\x9a\xda\xef\x29\x9b\xd5\x73\x6b\xa1\x7b\x5c\x71\x07\x13\xb2\x11\x1c\xf9\x57\x1f\xf0\xbc\xab\x2f\xb9\xe8\x92\xf7\xfc\xd9\x33\x1d\x37\xa3\x40\x8e\x83\x7b\xf1\xab\x5c\xb3\x1d\xf1\x41\xb2\x00\x7f\xf6\xac\xa0\x81\x43\xe1\x3b\x5c\xdc\x3f\xc2\xfd\xe8\x92\xc6\x98\xcc\xbb\xf4\xe4\xe5\xac\xb8\xaa\x5f\x73\x06\x64\x16\x8e\xa3\xfe\x97\x62\x94\xa2\x94\xcd\x21\x16\x57\xb9\x22\x96\xf3\xc5\xc6\xcd\x39\x7a\x0f\x6c\x3a\x91\xcd\xfd\x5c\xfb\x89\x45\xee\xc9\x6d\x76\x07\xce\x2e\x15\x9f\x9f\x62\xb3\x93\x3f\x37\x8b\xdc\x65\xe9\x73\xa3\x21\x6f\x93\xac\x59\xc3\x52\x23\xd2\xe2\xcd\xde\x2a\x14\x24\xdd\x9e\x70\xaa\x76\xdd\x76\x38\x2f\x45\x24\x70\xb2\xbc\xfb\x78\xe7\x83\x8d\x39\x6a\xe1\x6c\x3a\xe4\xc2\x0e\xb1\xdc\x94\xcb\xf9\x76\x9b\x09\xe7\x16\x15\x91\xa6\x15\xd2\xe5\xf4\xda\x93\x9c\xfe\x24\xa7\xff\xbd\xe5\x74\x26\xa4\x27\x23\x87\x56\x67\x8e\xf8\x8d\x63\x3c\x9b\x10\xd0\x3f\xcd\x51\x02\xf5\xa3\x18\x57\x82\x48\x95\xd3\x57\x0b\xc7\x5f\x2a\x18\xaf\x61\x5e\xd8\x07\x28\x74\x3c\x1a\x3d\xba\x76\xe8\xfb\x91\xc7\x09\x77\x3c\x1e\x29\xb7\x1b\xf8\x8a\xe5\xae\xd8\xfe\x16\x17\x3a\xc9\x68\xfe\x85\x4e\x32\x82\x0b\x1d\x2a\xb8\x2c\x72\x6f\x93\x27\xe7\xbb\x37\x27\x43\x3c\x90\xb6\xa6\x4b\xeb\x4d\x1d\x13\x11\x92\xd1\xe8\xdc\x5e\x40\xb5\x2a\x42\x16\x5d\x56\x5e\xa3\x81\xea\x88\xa7\xb5\x68\xf9\x7a\xbf\xe6\x12\x9c\xee\xfb\xd7\x8c\x08\x8e\x83\xdf\xf5\xcb\x61\xa9\xed\x79\x45\x55\xb3\xb1\xbb\x20\x12\x84\x87\xd1\x2f\xf9\x08\xd8\x8a\xdc\xaf\xe1\x89\x1f\x7f\x39\x89\x67\x49\x8a\x07\x87\xd8\xb8\x0c\x96\x9a\xcf\x2f\x78\x3f\x24\x42\x4c\x64\xba\x43\x3f\xc8\x69\xdf\x59\xe6\x7e\x14\xe0\x0f\x06\x87\x71\x70\xe9\xa7\x98\x1e\x09\x1d\xad\xe7\x15\xbb\x5f\xdf\x69\xee\xd0\xb9\xdd\xcf\x2b\x76\x3f\x04\x46\x7e\x32\xb7\x75\x67\x99\xfb\x35\x7d\x81\x53\xba\xa1\xe7\x8e\x7d\x4e\xa9\xfb\x37\x5f\x60\xee\xf3\x8a\xdd\x9b\xee\x8f\x6f\x26\xb9\x8d\xbb\x8a\xdc\x9b\xea\xe7\x35\xec\x2a\x72\xdf\x21\x27\x72\x5c\x8a\x29\xe8\xed\x38\x9a\x1c\xfa\x49\x72\x15\xc5\x83\xbc\xf1\x2f\x58\xe7\xde\xeb\x60\xde\x98\xb8\x8a\xdc\x9b\x0c\xe7\x35\xec\x2a\xf2\x10\xac\x67\x5e\xdb\x39\xa5\xec\xcd\x8b\x87\x95\x15\x94\xcc\x7a\x70\xf3\x86\x21\x35\xd5\x2c\xcc\x9e\x27\x41\x92\x04\xe1\xc5\xf3\xc2\xd8\x4e\xa3\x44\xbf\xba\x92\xb0\xb4\x7c\xb5\xe8\x29\x50\xbe\xde\x11\xcd\xbf\xe5\x3a\x1e\x8d\xa4\x3c\xa4\x9a\xed\x85\x72\x8a\xd6\x2c\x23\x9a\xf5\xa7\x33\xf4\xd3\x19\xfa\xef\x7d\x86\xce\xee\xba\x7a\xbf\xff\xae\xdd\x75\x6d\x8c\xf1\x35\x7a\x87\x63\x7c\x91\xfc\xee\x27\xbf\x07\xe8\xad\x3f\xc6\xd7\xff\x1d\xa7\xc3\xa4\x32\x9a\xa9\xc7\xe1\x36\x0b\x8a\x7e\x84\x87\x38\xc6\x61\x1f\x77\x10\x69\x3f\xe9\xac\xac\x5c\x04\xe9\x68\xd6\xab\xf4\xa3\xc9\xca\xaf\x41\xb8\x1d\x84\x07\xf1\xc5\xca\xaf\x9b\xdd\xe5\xe3\x59\x2f\xc4\xe9\x4a\x6f\x1c\xf5\x56\x92\x2b\x3f\x9e\xac\x04\x61\x8a\xe3\xd0\x1f\xaf\x90\x2e\xe1\xeb\x94\xff\x5b\xb9\x88\xfe\xcf\x5e\xa3\xf1\xc8\x57\x63\xd9\x7d\xd7\x31\xc1\xe6\x6f\x7e\xb8\x86\x1f\x7f\x89\xcb\x2e\x6a\xf9\x8a\xd3\xab\x28\xfe\x72\x84\x21\xe2\x7d\x9e\xa2\x5c\x2f\x6e\x6a\xcb\x7b\xbf\xff\x7e\x9e\x53\xea\x3e\xce\x9d\x37\x61\x7f\x2b\xf4\x7b\x63\x3c\x0f\x4b\xa9\xa4\x1d\x41\x7b\x81\xfb\xe0\x76\xe5\x4f\x0b\xe2\x96\x95\x74\xe0\x66\x2d\x70\x0f\xdc\x06\xd1\x55\xc8\x92\x19\xe4\x21\xc6\x8b\xd9\xb1\xb2\x7c\x2d\xee\xb3\xec\x40\x6c\x36\x2d\x80\x16\x2d\x64\x47\xca\xf8\x76\x6f\x94\x62\x9c\xc6\x01\xbe\x9c\x17\x46\x84\x17\xb3\xa3\x65\xf9\x7a\x1f\xd2\x4a\xc9\x6e\x37\x87\xa8\x48\x19\x07\x39\x69\x9f\xee\x3d\x44\x17\xb8\x80\x4f\xbc\x1d\x17\xf5\xc3\x3d\xc6\x84\x26\x81\x9a\x13\x6a\xdd\x8e\x83\xfa\xe1\xde\xa3\xc1\xf2\xbe\xe5\x23\x43\x0b\xd9\xf1\x31\xbe\x71\x94\x9a\x85\x50\xca\xb9\xd5\x35\x54\x9c\x3a\x5b\x96\x6e\xff\x32\x7e\x28\xbd\xcc\x18\x51\xf6\x92\xf3\x01\xe9\xc6\x71\xaa\x3e\x73\xea\x97\x00\x11\x12\xcc\x1e\x2f\xb0\x74\x31\x39\x9d\x49\x0f\x92\x2c\xfe\xa8\xd7\x8c\xa3\xe0\xd2\xe9\x1b\x43\xe6\x04\xbe\x3b\xcf\x90\xf9\xb0\x2d\x4a\x59\x05\x36\x7c\x77\x1c\xaf\x2c\xe7\x2b\x22\x2c\xd9\x62\xe6\x5b\xef\x25\x1b\x4f\x67\xaa\xa7\x33\xd5\xdf\xfb\x4c\xc5\x0e\x54\xfc\x82\xe8\xdb\x26\x7b\xb9\x8b\x61\x35\xf7\x8e\xf2\xa7\x01\x17\xc6\x69\xa6\xe0\x74\x94\x67\x81\x46\xaf\xcb\x72\xc3\x1b\xf3\xd2\xe9\xcd\x94\xc8\x07\x2c\x94\xf1\x9b\xe7\x12\x03\x0f\xd2\xfe\xa8\x44\xbe\xeb\xb1\xea\xfa\x7e\x82\xd1\x12\xa1\xf8\x24\x5d\xea\x28\x9f\x60\xb2\xe2\x8b\xa4\x92\x8c\x82\x61\x5a\xd2\xf2\x92\x21\x23\xc7\x70\xd5\x2c\xc0\x58\x32\xb8\xaf\x85\xf8\x8a\x79\x3b\xc3\x85\xec\x1b\x0b\x1a\x53\x1c\x0e\x82\xf0\xe2\xd1\xf1\x38\xa4\xed\xc8\x36\x44\x36\xa4\x58\x0c\x5a\x13\x1b\x0d\x9c\x51\x99\xe6\x69\xbb\x95\xa4\x03\x51\x6a\xbe\x25\x21\x83\xa6\xcb\x08\x0a\x29\x58\x64\x27\x8b\x54\x1d\x06\x61\x92\xfa\xe3\x71\xa1\x96\xb5\xd2\x76\x37\x7e\x77\xa1\x1c\x3c\x2e\x70\xba\x17\x5d\x14\x08\x22\x40\x4a\x39\xc3\x07\xd0\x16\xb5\x22\x39\xad\x4e\xa3\xb9\x81\x5c\x48\x91\x39\xed\x75\x47\x7e\x78\x61\x8f\x58\x30\x47\xc6\x12\xf3\x25\x9b\x64\x29\xa3\xa7\x08\x42\xa4\x63\x52\x23\x11\x0b\x06\x79\x76\x47\x47\x8e\x64\x34\xaa\x00\x6b\x34\xd8\x4d\x32\x32\xd9\x8d\x5b\x7c\x9a\x73\x4b\x63\x90\x01\x32\x6e\x69\x14\x4b\x82\x07\x55\xd3\xbb\x89\x11\xd9\x34\xf5\x8f\x87\x88\x49\xba\xc8\xb8\xa6\xa0\xcd\x32\x1c\xf4\xa2\xf7\x6b\x5e\x23\xe3\x07\x68\x5b\x26\x3d\x43\x12\xa5\x38\xe0\x74\xd4\x21\xff\xa1\xc0\x92\xd1\xa8\x43\xfe\xe3\x51\xe9\xd5\x96\xd8\xa9\xd9\x7c\x92\x49\x9f\x64\xd2\xbf\xb9\x4c\x9a\x29\xfa\xb9\x93\xf5\x5d\x1c\x5b\x2c\x02\x29\x75\x10\x3f\xc2\x17\x64\x9e\xfd\x78\xa3\x17\x38\xf2\x1b\x25\x2b\xef\xd5\xa2\x95\xcf\x49\x24\x72\x08\x05\x7d\x7f\x2a\x03\x71\xc1\xd8\xed\x6e\x1c\x9a\x10\x24\x4c\x98\x27\x3a\x33\x5f\x46\xeb\x68\xa9\x7a\xdd\x6f\x0f\x5e\x0f\xea\xfd\x41\xb3\xf9\xda\x5f\x6d\x35\xfb\xcd\xd7\xcd\x7a\xbb\x89\x6b\x6b\xd5\xd7\xfd\x56\x15\x37\x9a\x83\x76\xb3\xd5\xae\xf7\x96\x32\x5c\x6c\x60\xfc\x9a\x5f\xab\xd5\x7a\xfd\xea\x6a\xb3\xff\xba\x3f\xf4\x57\xd7\x6a\xc3\x6a\xbf\xb1\x86\xdb\x8d\xde\xa0\x55\xeb\xbf\xae\xf5\xd6\xfc\x61\xb5\xba\xe4\x66\x4e\x14\xc7\x8e\x24\xea\xfa\xbd\xa0\x63\x19\xc4\x8c\x15\x32\x3f\xf8\x8e\xb5\x7f\x74\xab\xa7\x85\x09\xda\x06\x64\x7d\x5c\x2d\x70\xcd\xee\x52\xa8\x0a\xc7\xcc\x9f\xc5\x17\x9d\x9a\xf7\x62\xce\x3c\xbd\xe8\xd4\x09\xb3\x6d\x3d\x31\xdb\x27\x66\xfb\xf7\x66\xb6\x19\xaf\xe5\xda\x2f\x8d\xd9\xe6\x59\x26\x0f\xe3\xe8\x77\x3c\xf1\xc3\xca\x00\xff\xf4\x20\x0c\xda\xe6\xa3\xae\x39\xa8\xeb\x37\xa4\x86\x4d\xad\x72\x0d\xca\xf2\xc4\xb3\x4f\xf0\x28\x65\xae\xa1\x9a\x44\xe9\x3b\x7d\xa1\xe4\xb6\xd1\x4a\x24\x7a\x09\xcd\xc1\x59\x2a\xaa\x7d\x91\xea\xa8\x0a\x68\xa9\x8a\xfa\x41\xaa\x61\xdc\xe6\x86\xb3\xf1\x98\x8a\x96\x7c\x2c\xe4\x2c\xda\xfa\xed\xa6\x32\x4e\xf1\x44\x19\x22\x03\x74\x3c\x99\x9b\x94\x9c\xa5\xe0\x06\x74\x41\xab\x40\x68\x97\x0a\xaa\x5a\xc6\x71\x5a\x72\x97\x14\x94\xb3\x8e\x43\xde\xef\x5b\x25\xe1\xb8\x78\xb5\x62\xeb\x92\x04\x47\xd7\xe0\xd8\x62\xb7\x68\x23\xfc\x5f\xb6\xb7\xb4\x6e\x87\xe0\x5f\xb4\xc3\x91\x92\x63\x7e\x4e\xa7\x69\x78\x7d\xb9\xd7\x2c\xa7\xba\x2d\xcf\x7a\x7e\xbf\x29\x28\x75\x16\x95\x5c\xf9\x72\xdf\x75\x8a\xfc\xf1\x47\x96\x58\x1f\xfd\xb0\x4e\x09\x47\x7b\x45\x36\x94\x61\x10\xe2\x01\x1f\x27\x0d\x82\x68\xab\xc3\x6a\x39\x86\x0b\x32\xd0\xa7\x11\xc2\xd7\x34\x58\x12\xb7\x30\x47\xc3\x38\x9a\x64\xa7\x6d\x91\xd8\xbd\x82\xf6\xc9\xc6\x16\xe0\x84\x51\x12\x0c\x93\x36\x96\x0c\x18\x37\x48\x37\x89\x28\x83\xa7\x8c\xeb\x36\x1b\xa9\xaf\x1f\x67\xe3\xf1\xad\x64\xed\x1e\x0c\x11\xbe\x0e\x12\x28\x6e\x1d\x72\xad\x45\xa7\xc2\x30\x18\x66\xb9\xd0\x78\x6b\x34\x1b\x1a\xe8\xd9\xc6\x38\xbc\x48\x47\x68\x19\xd5\xce\xca\x96\xbc\x4e\x50\x66\x1a\x4d\x4b\xe5\x37\x68\x65\x85\x5f\x7c\x11\xfe\x0f\xeb\x09\x46\xeb\x07\x59\xb8\x51\x87\x9b\x1a\x38\x64\x98\xa5\x91\x9d\x14\x55\x43\x08\x17\x31\xb2\x57\xbc\x17\x4e\x6a\x54\xa1\xa9\xdc\xb7\xf7\x59\x49\x55\x4d\xea\x08\x51\x12\xf1\x54\x57\x40\x5e\xbd\x59\x30\x1e\xbc\xc7\x69\x49\x3a\x9e\xe3\x70\x36\xc1\xb1\xdf\x1b\xe3\x0e\x4a\xe3\x19\x36\x75\x7f\xfe\x04\x6e\xac\x04\x5b\xaf\x24\xd3\x71\x90\x96\x96\x2a\x4b\x52\xc0\x4d\xc6\xef\xa1\x30\x68\x6f\xf9\x44\xc1\x1b\x3e\x27\x3f\xa1\x9a\x3c\x23\x51\xef\xf3\x29\xaf\x71\x46\xb8\xb1\xf2\xfc\xf5\x2b\xfa\xe3\xf6\x8d\x5c\x58\x2f\xf2\x46\x51\x89\x89\xe6\x6b\x67\x3c\xad\x16\xfc\x63\xcf\x13\x16\xf5\x3e\x7b\x50\xde\xa3\x43\xc6\xfa\x42\xe0\xfb\xc9\x4d\xd8\x7f\x0f\xfb\x0d\x11\x79\xa1\x0b\xe5\x33\x3e\x04\x30\x88\x1b\xac\x48\x49\xf2\xd3\xd0\xaa\x29\x93\x04\x20\x54\x96\x01\xd7\xcb\xe8\x15\xe0\x50\xe9\x8f\xfc\x78\x23\x2d\x55\xcb\x95\x34\xfa\x34\x9d\xe2\xb8\xeb\x27\xb8\x54\xe6\x9f\x13\x22\x3f\x94\x6a\x65\xe7\xc6\xc3\x67\xd6\x9d\xc1\x3c\xdb\xb8\xb3\x74\xec\x3c\x24\x1a\xaf\x71\x41\x3a\x64\xae\x18\x21\xa0\xc8\x3c\xb1\x24\xde\xaa\xfb\x18\x64\xa5\xd3\x34\x3d\x74\x49\x74\x32\x40\x74\xbb\x97\x54\x36\xdc\xe0\x27\xbf\x83\x7c\xd4\x17\xeb\x65\x76\xd9\xef\x8e\x02\x86\x32\x3b\x27\x6b\x87\xa0\xe5\x45\x7b\x25\x27\x54\xc2\x71\xec\x21\x75\xeb\xe0\x7f\x1c\x17\x5a\xc6\x3e\xd8\xac\xa6\x74\x79\x70\x9b\x0d\x19\x5b\xe4\x1c\x6f\x4e\xa8\xec\x91\xe6\x01\x64\x19\x00\xa5\x59\xbd\xc0\xae\xed\x24\xdb\x7d\xfb\x31\x26\xb2\xe2\x74\x16\x63\xf4\xcf\xe3\x83\x8f\x47\x87\x5d\xc4\x5b\xb9\x1a\x05\xfd\x11\x1c\x9e\xf8\x0e\x14\x84\xa8\x07\x4a\x5b\x56\x44\xe3\x88\xd9\x5b\xc1\xf7\x2a\x95\xca\x2d\x53\xe1\xd9\xf6\x66\x44\x8e\x84\xf1\xb4\x2f\x55\xb5\x72\xc7\xac\xe3\x0e\xb2\xf0\x6f\x98\x85\x8e\x6e\x37\xd7\x91\xe5\x51\x53\x4b\x7e\x7a\xa6\xea\xd7\xc9\x34\xb1\x2a\xda\x66\x55\x82\x3d\x51\x16\x05\xc9\x92\xad\x90\x4a\x25\xb1\x4f\x96\xcb\xf2\x94\x31\xac\xd8\x44\xf3\x59\x93\xa7\xdd\x35\x75\xac\xa6\x43\xc3\xc9\x07\x48\x3a\x98\x6b\x41\x7b\xc8\x11\xbb\xfd\x74\xc4\x7e\x3a\x62\xff\xbd\x8f\xd8\x92\x3e\x93\x71\x88\x09\x63\xe9\xea\x49\xfb\x9f\x78\x38\x8c\xf1\x0d\xfa\x25\x18\xf7\xbf\x60\xf4\xf6\x33\x1e\x0e\x5d\xe1\x7a\x16\x8a\xed\xb3\xef\xc7\xe4\x08\x7f\xe0\x87\x7d\xec\x43\x59\x5b\x54\x9f\x3b\x04\x02\x62\x55\xde\xfb\x97\xe8\x97\x28\x1a\xa0\xb7\x17\xce\x43\x7e\x33\x3b\xe4\xff\x93\x71\x53\xc5\x7b\x98\xb1\xd8\xbc\xd4\xf8\x96\x48\x75\x7a\x36\x7b\x5b\x2a\x7b\x1c\xc7\x91\x16\x3d\x68\x85\xbe\xa3\x46\x08\x74\xdb\xd9\x4d\x97\x12\xb2\x31\x4e\xa3\x30\x09\x7a\x63\x4a\x60\x53\x1f\xbc\x48\xd0\x84\x5d\xfa\x90\xbd\x68\x1a\x47\x97\xc1\x00\xc7\x89\xa8\xe5\x8f\x93\xc8\xac\x1a\x8d\xc7\xa4\x2a\xa1\x36\xee\xc0\x8d\xc2\x68\x40\xbf\x06\x61\x3f\x9a\xc8\x90\x09\x30\x96\x95\x82\xde\xb9\xa6\xc1\x04\x93\xc5\x16\x24\xa8\x86\x12\xdc\x8f\xc2\x01\xec\x8e\x41\x78\x31\xc6\x69\x14\xc2\x70\x92\xee\xe5\x1c\xf4\x39\xaa\xca\x71\x9f\xbf\x44\xeb\xa2\x2b\x92\x9e\x81\xb4\x0d\x1a\xe0\x5b\xe9\x25\xc7\x45\xd6\x3a\x38\x0f\x7f\x44\x42\x19\xc5\x51\x18\xcd\x92\xf1\x0d\xc4\xc1\x70\xec\xc3\xe4\x93\xe5\x3c\x82\x06\x7e\xea\x3b\x4f\xc8\x6a\x6f\x15\x95\x47\x38\x50\x3a\x4f\xc0\xc8\x27\xb5\x1f\x94\xde\x2b\x69\x72\xa3\x30\x89\xc8\xd6\x45\x88\xa2\x44\x49\xa3\xb2\x1b\x5e\xfa\xe3\x60\x70\xc8\xca\x97\x64\x99\x87\xbb\x61\xc3\x60\x48\x12\xbe\xba\xc7\x33\x32\xaf\xa4\xd1\x21\x7d\x07\x28\x55\x68\xef\x3d\xe8\x26\xb3\xb6\x90\xce\x2f\xec\x54\xbe\xae\xce\x15\x15\x66\x19\x68\x7e\x57\x0e\x9d\xe2\x8d\x04\xc9\xcf\x04\xdd\x23\x4a\x85\x58\x08\x6a\x52\x37\xd3\x51\x1c\x5d\x21\xb5\x7b\x7a\x79\xa5\x3b\xac\x9b\xf4\x53\xa5\xd0\xc9\xdf\x5f\x68\xf6\x41\x9a\xcd\x25\x01\xfd\x5c\x2a\xa4\x9f\xf9\xc4\x00\xc0\x0d\x8a\x90\xa2\xe7\x16\xa2\x0d\x9e\x84\x59\x92\x8d\xf3\xa8\xe3\x61\x08\xc1\x9c\x7b\x2a\xf7\x33\x90\x05\xe4\x79\xd2\x29\x1c\xc7\x8e\x94\x9a\x72\x6f\xca\xba\xbd\x0d\xe2\x19\xab\xee\x42\x63\xf3\x87\xcc\xa8\x2d\xb7\x6f\x08\xb9\x2c\x6f\xb8\x42\x82\x7a\x74\x4e\xf7\xb1\xc1\x46\x8d\x79\x27\x03\x52\xe0\x1d\xf9\x6e\x51\x32\xd1\x7a\x0f\x41\x98\xd0\xc2\x77\x46\x98\x80\x93\x4c\x9d\x9c\xc9\xdc\x8d\x14\x93\x07\xa0\x45\x95\x06\xb9\x9e\x0d\x66\xa3\xc4\x5b\xb9\x17\xe9\x25\xf3\x68\x4f\xe9\x90\x20\x3a\x34\x67\xfb\xc3\xa9\xd8\x57\x89\xb4\xc9\xcf\x84\x4c\xe4\x33\x28\x2e\xe5\x53\x65\x57\xcd\xe5\xd2\x92\xa8\xab\xee\xfa\xce\xed\x7e\xde\xce\x9d\x92\x23\x15\x13\x5c\x74\x44\xc9\xb7\x43\xf1\x69\x2e\xc7\xa6\xc1\xff\x6f\x01\xda\xee\x60\xee\x92\xb1\x7c\x15\x76\x49\x1c\x93\x34\x1a\x44\xa8\x3f\xc6\x7e\x38\x9b\xa2\x10\xe0\x93\x01\x16\xc7\xf6\xbc\xa1\x92\xb0\xb7\xac\x3c\x8a\xa4\x1c\x11\x45\x34\xae\x8e\x25\x11\x8e\x4e\x69\xe9\x33\x22\x24\x91\xea\x1d\x44\x81\x04\x83\x8e\x01\xa8\x63\x03\xd9\xc9\x7e\x82\x5e\x17\x31\x5f\x66\x75\xf4\x15\x06\xc0\x04\x30\x75\x37\x67\x08\x95\xc4\x0a\x9f\x33\xb9\xd1\x54\x08\xa5\x44\x04\x65\x76\xb4\x70\xba\xb9\x08\xc8\x91\x2e\xd0\x75\xc7\xa4\x8e\x65\xce\x8d\xb9\xcd\x1d\x79\x01\x42\x25\x52\xa8\xcb\x3b\x44\x4d\xcb\x2c\x83\xfc\x46\x1a\x9e\x0c\x7f\x36\x3a\x25\xa6\x51\xfd\x82\x6f\x92\x52\x56\xb7\xcc\xb5\xbc\xeb\xeb\xeb\xa8\x8a\x7e\xfc\x11\xb9\xc6\x90\x10\x53\x7c\x42\xdf\x97\x94\x42\x6f\xd4\x71\xd6\x05\xe0\x9c\xf1\xce\x76\x9f\x18\x13\x5e\x40\xe4\x7f\x3e\xec\x13\xdc\x1f\xf9\x61\x90\x4c\xf8\x31\x34\x9f\x39\x00\x80\xfc\xe1\xa5\x6d\xc8\x03\xfb\x05\xe3\xa9\x48\x20\xc0\x3b\xbb\xf2\xf2\x73\x32\x0a\x42\xd2\xd0\x75\x3f\x9a\x4c\xc7\xf8\x3a\x48\x6f\x3a\x2d\x38\x92\x91\x02\x84\x20\x4a\x64\x73\xf8\x82\x6f\xa8\xa6\x40\x8c\xa6\x34\x5e\x2b\x2b\x28\xc6\x93\xe8\x12\x23\x7f\x3c\x86\x5e\x25\x1e\xc2\xd7\x7d\x3c\x4d\x41\xec\x67\xaf\xe4\xf2\xe9\x08\xdf\xa0\x10\xd3\x11\xe9\x61\x56\x7f\x40\x7a\x3c\xf3\xc7\xe3\x1b\xd4\xbb\x81\x21\x23\xc3\xc3\x72\x01\x00\xcd\xfc\x42\x36\xa4\x20\xbc\x28\x95\xa5\x7d\xa0\xf4\x83\xd2\x3b\xf4\xf5\x2b\xc1\xb7\x12\x84\x03\x7c\x7d\x30\x2c\x81\x9f\x22\x21\xb6\xf3\xa5\x32\x4c\xfe\x72\x4d\xdf\x20\x24\x0a\xfb\x82\x6f\xce\x2a\x62\x25\xea\xf6\xd0\x26\x45\x92\xf2\x86\x6d\xf2\x5f\x98\x3c\xe1\x94\x49\xe6\xbd\x4f\x8d\x73\x51\x14\x16\xe1\x09\xd4\xa6\x36\x8f\x26\x99\xc9\xb0\xa9\x02\x75\x50\x21\x6a\x13\x70\x96\xce\x24\x38\x55\x7a\x4f\x00\x4b\xaa\x48\x0f\xf5\x2b\x5b\x27\x3b\xe7\x87\x07\x7b\x7b\xbb\x1f\xdf\x9f\x9f\xec\xee\x6f\x1d\x7c\x3a\x91\x8f\x47\x45\x66\xc0\x14\xaa\x14\x89\xe9\x51\x8e\x8e\xa6\x4c\x46\xf0\xda\xf4\x53\x1f\xad\xa3\xd3\xb3\x37\xea\xfb\x5d\xf0\x37\xe6\xaf\x8b\x2d\x55\x01\xb0\x32\x9d\x25\xa3\x92\x4e\xf7\x4c\xc4\x53\x4a\xef\x0e\x12\x5a\xf8\x0b\xbe\x29\x1b\x63\x90\x01\x5c\x60\xf0\x0a\x89\x9b\x02\xb2\x9c\x2e\x77\x65\x05\x4d\xfc\xa9\xc2\x24\x03\x20\x5b\x60\x28\x40\x62\x84\x34\xd5\x61\xda\xf7\xa7\x92\xea\x42\xd2\x6b\xab\xae\xe2\x54\x70\x05\xae\x51\xfe\x43\x1f\x83\x7d\x7f\x7a\x0a\xd5\x02\xd8\xe2\xf9\xc8\x9c\x42\xf1\x33\xc9\x25\x5d\x34\xae\x38\xce\xa3\x85\x65\xe6\x48\x95\x9a\x95\xf8\x26\x27\x07\x9b\x07\x1d\x4e\x64\x68\x1c\x5d\xfc\x97\x2e\x55\x47\x0e\xb9\xfa\xbe\x92\x74\x01\x65\x41\x62\x3d\x3a\xb2\x6f\x95\x89\x3f\x2d\xb9\x8c\x15\xf8\x1f\xd8\x2f\x0e\xb2\x51\x26\x63\xcf\x8e\x7a\xc1\x40\xf6\xbc\x11\x14\xf1\x05\xa3\x64\x16\x83\x9e\x98\x33\xab\x20\x41\x49\x1a\x10\x7a\xa0\x9c\x1c\x0f\x90\x3f\x04\x0f\xa1\x38\x0e\x2e\xfd\xb1\xb6\xd7\x2a\x30\xc9\x80\x80\xdf\x3f\x5d\x1a\xc1\xe0\x4c\x47\x31\xeb\x52\xa5\x9f\xd9\x03\xa8\x75\xc4\x17\xa7\xc7\x0c\xd7\x9d\xc8\x9f\x6e\x11\x1e\x33\x3d\xb3\xa5\xc6\xd0\x1f\x27\x58\xbe\x65\x63\x7e\x4f\x73\xc7\x94\xd5\xff\xe1\x07\xd6\x26\xba\x03\x0c\x32\x2f\x30\xe3\xd2\xa2\x75\x1c\xfe\xdf\x18\xe3\xf9\x03\xd4\x2c\x30\x8e\xc5\x15\x03\x48\xa1\x30\xa9\x97\x50\x51\x1d\x25\x6d\xb1\xbb\x87\x49\xc5\xc5\xad\x67\x40\xf2\x25\xa7\x2b\xe5\xd2\x91\x1e\x55\x43\xbd\xf1\xd2\x72\x2f\x99\xb9\x2b\x98\x42\xfa\x45\xa7\x0e\xb1\x7d\x98\x32\xfc\x45\xa7\x01\x7e\xa8\xab\x45\xee\xc8\x58\xd0\x4d\x9c\xa6\x41\x78\x61\x77\xed\x05\xc6\x34\x90\x72\x1f\xa3\x75\xe1\xb4\xf6\xc6\x28\x91\x85\x7a\x16\xf6\x41\xae\xa8\x45\xac\x51\xd6\x6f\x82\xf2\xda\xd3\xb5\xde\xd3\xb5\xde\xdf\xfc\x5a\x8f\x85\xf4\x65\xa7\x96\xbb\x84\xf5\x9d\x67\x0e\xeb\x48\x7e\xa1\xe5\xbe\x58\xc4\x70\x96\x2f\xe9\x1a\x3b\x1c\x6c\x0c\x06\x09\x0c\x9d\xd8\xdd\xfc\x10\xd4\x52\x09\x9a\x51\xf1\x8b\x79\xbd\x79\x44\xf8\x0a\x52\x08\x95\x87\x20\x2b\x00\xdd\x54\xe9\x6e\xff\xfc\xb9\x7c\x3e\x60\xe7\xb3\xe7\xba\x92\x88\x6c\x9b\xcf\xd9\xb5\x95\x54\x4e\xe2\x55\x34\x50\x0f\xf7\xa5\x23\xe5\xa2\x90\x79\x5c\x29\x1c\x8d\xc9\x4d\x64\xec\x2d\xaa\x46\x97\x50\x44\xf7\x6d\xde\xd3\xc4\xb2\x59\xd8\xec\x71\xf8\x9f\xba\x6f\xe9\xdb\x93\x4b\x77\x29\x2c\x04\x79\x24\x22\x40\xf9\xc7\x1f\x01\x77\xaa\x98\x0a\xc2\x0b\xe0\xc6\x65\x05\x22\xbf\xbe\x98\x97\xd3\x94\x42\x94\xdd\x94\xef\xda\x49\x21\x0d\x8d\xfd\x04\x9a\x39\x4e\xc9\x64\xff\xb0\xbe\x6e\x0c\x34\xff\x33\x5e\xac\xac\xd0\xdc\xff\x0a\x49\xc1\x52\x4b\xe3\x19\x91\xd9\xe2\x24\x45\x49\x44\xed\x1c\xa7\x53\x60\xdd\x70\x76\xf6\xc3\x9b\x94\x1c\xf8\x3d\xd4\xc3\x43\xc2\x00\xe8\x12\xe7\x57\xa8\x30\x1a\x54\xc9\xa8\xfd\x05\xc3\xd2\x0f\x16\xac\x7f\xfc\x11\xd9\x46\xbe\x6c\xd4\x47\xe6\x75\x03\x41\xd5\xe2\x1f\xed\xec\x6c\x44\xf9\x66\x88\xaf\x53\xd4\x3d\xfc\x84\xfa\x37\xfd\x31\xf6\x44\x37\x61\xd8\xc5\x66\x03\x3d\x81\x2e\x33\x9b\xa5\x69\x1c\xf5\x09\xcf\x4a\xe8\xe8\x18\xad\x48\xc7\x60\xb1\x4c\x6c\x73\x61\xe9\x08\x23\x0d\xbd\xd4\xad\x87\xaa\x45\xfa\x67\x19\x56\x4a\x0a\x2e\xd1\x4c\x32\x06\x7b\x2e\x00\xe8\x66\x6c\x92\x2e\xb6\x64\xda\x41\x39\xf2\xfd\xea\x96\x50\xb7\x5e\x26\x84\xef\x0e\xbc\x8c\x4d\xb0\xf7\xb2\x0e\x89\xea\x0c\x80\xb3\x90\x75\xc2\xed\x24\x77\xad\x79\x39\x9d\xc9\x36\xf3\x4d\xe6\x35\xf9\x0f\xc9\xba\xa6\x5d\x22\x47\x4b\xca\xa9\x57\x94\x0b\xbf\x7a\x25\x95\x13\xeb\x55\x3a\xe9\xc3\x07\x7f\x30\x10\xb6\x5d\x52\xe2\x4f\xf1\x5d\x9f\x1e\xe9\xe0\x20\xb1\x58\x6e\xbc\x05\xef\x25\x5b\x71\x2a\xd0\x89\x91\x90\x2d\x7d\xb3\x76\x73\x2d\x16\x83\x61\xf6\x4a\xd5\x4a\x65\x2c\x08\xb4\x0a\x1a\xf2\x85\x90\x90\x67\xd1\x2d\xd1\x1a\x04\x26\x54\xce\x25\x69\x0e\xca\x39\xa3\x6d\x95\x6a\x05\x42\x6e\x03\x36\x22\xab\xab\xe9\x2e\x88\xec\xfb\x94\xa4\xf4\x49\xf6\xfd\xbb\xcb\xbe\x99\x49\x1b\xcf\xd8\xfb\x50\x3e\xba\xbb\x3d\x3f\x54\xa5\xdd\xa0\xe7\x0b\xd7\x5b\x7c\x4d\xd5\xd5\x79\xae\xbb\xc7\x13\x3f\x4e\xb7\x58\xc1\xcc\xed\xd6\x79\x35\x06\x6a\x25\x68\x96\xf7\x45\xd3\x79\x4b\xaf\xc5\x25\xd8\x71\x1a\x07\xe1\xc5\x2d\xb8\xb6\xd8\xde\x13\x69\xb9\xe7\x87\xf2\xa7\x9f\xfd\xf1\x0c\xdf\xa2\x4b\xf2\x0f\xbb\x0e\x21\x90\x87\x38\xc6\x73\x6e\x48\x3d\xd5\xbc\x00\xa2\xd4\x30\x9c\x54\xb1\x38\x1d\x79\x80\x11\x91\xd6\x3d\xda\x92\xb9\x85\x81\xda\x8d\x8e\x32\xa4\x9b\xee\xf9\x61\x29\x8d\xca\x4c\x55\x04\x3a\x1c\xf2\x99\xab\x7c\x4a\x16\x2b\x22\x52\x0f\xf2\x44\x94\x96\x02\xaa\xbe\xa1\x10\x99\x9f\xee\x92\xa9\x3f\x66\x10\x37\x83\x98\xc8\x62\x36\x87\x18\xde\xa3\x93\x88\x79\xf6\xca\xdd\x81\xea\x0c\x7a\xa9\x6c\x76\x8d\xb7\x27\xe4\x18\xe8\x86\x4d\xd2\x05\x17\x09\xe1\x29\x8d\xd3\x91\x9c\x13\xbc\x54\x86\x46\x18\xb6\x61\x92\x06\xe9\x8c\x0a\x5c\xa6\xf9\xd7\x00\x4f\xa3\x24\x48\x65\x2c\x19\x5c\x81\x1e\x80\xe9\x8f\x03\x1c\xa6\xba\x25\x46\xe1\x86\x0d\x13\x0b\x9e\x6b\xdc\x1c\xc1\x45\x31\x32\xc7\x8f\xab\xe0\x73\xaf\x92\x05\xe9\x0d\x67\xe1\x00\x6c\x22\xfb\x38\x4e\xfd\x40\x4c\xbf\x63\xf9\x88\x89\x5d\x6c\x1d\x3d\xfa\x12\x12\x78\xdd\x61\x2d\xb1\x91\x27\xb3\xa9\xa5\xfc\x92\x64\x5b\xe1\xbd\x9e\x46\x99\x44\x4b\x40\x77\x68\x03\x12\x6d\x8e\x67\xb8\x43\xff\xe1\x62\xae\x96\xed\xdd\x39\x2b\x6c\xf2\xb3\x49\x81\xc0\xf6\x41\x1f\x71\x4e\x88\x38\x87\x44\xa5\xc9\x2c\x49\x61\xab\xc3\x13\x1c\xa6\x82\x6e\x7a\x37\x29\x4e\x1a\xf5\x32\x13\xc6\x7f\x28\x6b\x13\xc9\xca\x3d\xf8\xf4\x25\xc6\xfc\xf1\xea\x94\x52\xd1\x2c\x0c\xfe\x3d\xc3\x28\x18\xe0\x30\x0d\x86\x81\xca\x89\x0b\xcd\x35\x1f\x9d\x02\x33\x0c\x4d\xda\xb9\xa6\x0f\xbb\x8e\xb4\x07\xbd\xd1\x89\x80\x8f\x71\xc9\xef\x05\xe5\x8a\x9f\x12\xc6\x5a\xe1\xe3\xcb\x41\xff\x71\x5f\x22\x30\x64\x55\x3e\x8a\xd6\x20\x08\xe6\x7e\xf8\xa2\xd3\x20\xa2\x2b\xcf\xdc\x7f\x7b\xe6\xb5\x0a\xe5\x4a\x66\xda\xdd\x56\xa1\x84\x6d\x6f\x64\x25\x7c\x44\xe4\x8b\xa1\xdf\x4f\xa3\xf8\xc6\xa3\x0a\x65\x32\xb0\xcf\x08\x9b\x26\xa2\x7e\x34\x44\xa2\x37\xeb\xeb\xe8\x05\x8d\xc8\xf4\x02\xca\x3c\x5b\x59\x41\xdd\x68\x32\x89\xc2\x7f\x1e\x3f\x7f\xf6\xcc\xe8\x7c\xf6\x8b\x35\xc0\x71\x2a\xbd\x20\xc3\x10\xe3\x17\x65\x0f\x49\xaf\x70\xd8\x5f\xee\xf9\x09\x6e\x37\xb5\x0f\x93\x41\x4b\x2f\x7a\x39\xfd\x32\x18\x6a\x2f\xfb\xc1\x74\x84\xe3\x65\x0a\xb9\xfc\xe6\xf9\xb3\xdb\xe7\xcf\xf0\x38\xc1\x48\xea\x0c\x55\x98\xd3\xbe\xf0\x61\x78\x81\x7e\xfc\x91\x7d\xa8\xf8\x93\x81\xe8\xdb\xc6\xfe\xe6\xf3\x67\xcf\xe8\x87\xd2\x29\xc7\xd9\x43\x2a\xaa\xf0\x4c\x30\xa4\x1f\x28\x62\xf0\x5b\xc6\xe7\x4c\x8c\xb2\x8c\x18\x6b\x88\x46\xc3\x40\xa5\x5e\x1c\x5d\x25\x38\x2e\x3f\x7f\xf6\x4c\x8c\x58\x14\xa5\x95\x6e\x7c\x33\x4d\xa3\x7f\x1e\xd3\xaa\xb7\x70\x7a\x92\xb7\x1f\xf1\x1d\xfd\xf1\xfc\xf9\xb3\x92\x7a\x1c\x7b\x86\xa8\x46\xe4\x78\x14\xc5\x69\x7f\x96\x26\xf4\x0d\x59\x36\x5d\xb4\x8e\x78\xdd\x37\xd2\xeb\xf3\x71\xd0\x23\x9f\x2a\xe3\xa0\x27\xbd\x07\x65\x58\x17\x3a\x45\xbe\x92\x52\x15\xe9\x9d\x02\xc1\x1f\x5f\x44\x00\x82\xfc\x78\xf3\x5c\x60\xb1\x17\x45\x5f\x66\x53\x94\xfa\xbd\x31\x96\x30\x39\x7e\x77\xf0\x2b\x3b\xf3\x89\x77\xbb\x1f\x7f\x3e\xb7\xbd\x3f\xfe\xf4\xee\x7c\x7f\xf7\xd7\xf3\xaa\xeb\x43\xcd\xf5\xa1\xee\xfa\xd0\xb0\xb6\xed\x6a\x47\xfe\x68\xb4\x25\x7f\x34\xda\x93\x3f\xf2\x36\xc5\xd0\x74\xa3\xc9\x94\x1c\x14\xc7\xe6\x10\xd9\xa6\x54\xab\x35\x88\x66\x3d\x22\xf5\x93\x5a\x59\x01\x60\xb1\x32\x16\x48\xb6\x54\x08\x20\x9c\x20\x0a\xd0\x5b\x54\x6f\xb5\xdf\xa0\xe0\xd5\x2b\x05\xbc\x90\x11\xd1\x5b\x54\xab\xaf\x19\xdf\xc8\xdf\xe0\x34\x38\x43\xeb\x04\xc6\x5b\x54\x7b\xa3\x7e\xa7\x57\xa9\x39\xb5\x4a\xb4\x5a\x19\xfd\x86\xaa\xd7\xb5\x5a\x4f\xaf\x9f\x3d\xde\x3e\x57\x7a\xfd\x8b\x3f\xfe\x82\xde\x6f\x97\xea\xbf\xad\x95\xd5\xde\x5e\xd3\x10\x89\xea\xbb\x40\x7b\xb9\xd0\x08\x48\x83\x9c\xf4\xa2\x6b\xf5\x23\x18\x1a\x90\x36\xaf\x03\xf4\x1b\x2a\x5d\x67\x1d\x62\xbf\xeb\xd2\xef\x86\xf4\xbb\x59\xd6\x3a\x0b\x50\x4a\xc9\x35\xfa\xe9\xa7\x9f\xd0\x1a\x94\x4c\xae\xd1\x8f\xa8\x7a\x3d\x1c\xd2\x01\x6a\x37\xb4\x2a\x64\x75\x9c\x5e\x93\x81\x4c\xae\xb5\x4f\x7c\xf1\x9c\x26\xf0\xfd\xfa\xcd\x73\x67\xa7\x26\xb3\x71\x1a\x4c\xc7\x41\x1f\xb4\x04\x66\xf7\xae\x09\x19\x0f\x4e\xaf\xcf\xde\x58\xbe\x35\xe9\xb7\xba\xf5\xe3\x1a\xfd\xd8\x3c\xcb\x69\x3d\x99\xf5\x10\xc8\x37\x1e\x9a\x04\xd7\xa8\x1f\x8d\x67\x93\x30\x51\xa8\x5f\x86\x49\x24\x85\xd2\x00\x7a\xf5\x92\xd0\x4c\xb5\xc6\x47\x8a\x3d\x56\x6b\xd5\xaa\x3e\xb4\x62\x25\xd3\xc1\x2a\xa5\x30\x31\xcd\x32\xfa\x4a\x7e\xd3\xf1\x76\x54\xa9\xc9\x55\x6a\x6d\xa9\x4a\xad\xed\xaa\x53\x97\xeb\xac\x95\x51\x56\xa7\x6e\xcc\xba\xe0\x06\xb4\x4e\x9a\x33\x52\x41\x78\x29\x8f\x16\x79\x2c\x3c\x62\xd7\x6b\xd2\xf8\x30\xf2\x6c\xb2\x57\x55\xfe\xa2\xae\x0c\x69\xee\x88\x2a\xfc\x91\xd1\x58\x91\x61\x55\x58\xa7\x52\x6f\xce\xd8\x2a\x6c\x55\xa9\x38\x67\x80\x15\x96\xcb\x2a\xe6\x8d\x32\x5c\x16\x80\x1e\x18\xc7\x26\x27\xfc\xe1\xda\xca\x04\x19\x03\x58\x5f\x80\x03\x42\x95\x3a\xfa\x0d\x0d\x4e\xc9\xff\xae\xd7\xd0\x6f\xe8\xba\x7e\x76\xa6\x2f\x24\x28\x1b\xa0\xdf\xd6\xa1\xe0\x75\x60\x14\x50\x98\x24\xfc\xbc\x85\x33\xad\xd8\x57\x0e\x63\xdc\xa7\x9d\x1b\xa0\xa3\x7e\x14\xb2\x0d\x26\xdb\x95\x8e\xba\x07\x1f\xc9\x1e\x51\xbd\xae\x56\x3d\x54\xbd\xae\xd6\xe0\xbf\x75\xf8\x6f\x13\xfe\xbb\xe6\x01\x2d\x90\xff\xd6\xe1\xbf\x4d\xf8\xef\x1a\xfc\xb7\xd6\x23\xff\x6d\xb4\xb3\xcd\xec\xe5\x4b\x86\xd4\x4b\xb4\xb1\x75\x4c\x03\xb2\x23\x2a\x0e\x21\x22\x10\xc4\x41\x3a\x9a\x54\x78\x99\x95\x0c\x15\x52\x7a\x9d\x89\x0f\x15\xfa\x20\x49\x18\x15\x7c\x9d\xd2\xe8\x01\xa2\xcb\xe7\x83\xe8\x08\x27\x38\xed\x20\xc7\x16\xc9\x06\xe1\xf8\x4b\x30\x65\x96\xbf\xd1\x10\x85\x47\x11\x9c\xc6\x46\x7e\x82\x7a\x18\x87\xe0\x1d\xc0\xee\xb7\xfc\x70\x00\x26\x7c\x83\x60\x80\xc2\x28\x65\x66\x98\x26\x29\xd0\x6c\x2e\x1c\x12\x37\x17\x3d\xff\x82\x6f\x0e\xe3\x20\x8a\x8f\xa8\x05\xf0\xfa\x7a\xf6\xde\x4a\x3a\xdc\x2c\x4c\x9b\x53\xb3\x03\xaa\xf8\xc6\xff\xb8\xc1\xe1\xba\xbd\xf9\xec\xad\x85\x3f\x7f\xc1\x37\xbf\x44\x31\x18\x31\x7e\xc1\x37\x95\x2b\xf2\xdb\x5e\xec\x38\xf8\x1d\xb3\x52\x49\x70\xf1\x8e\x30\x20\xb4\x82\x9a\x79\xcb\x48\xf8\x01\xc4\x30\x40\x26\x58\x3e\x72\x1c\xc7\xec\x99\x37\xf8\x0a\xb5\x0b\xb5\x40\xfa\x9f\xf4\x47\x98\x1c\x3f\x10\x11\xa1\x2d\x7d\x48\x8e\xa2\x2b\x02\xbb\xc4\x9b\x79\x45\x76\xe9\x97\xb9\x7d\x90\xe1\xda\x87\x85\x37\x2a\x8d\xb3\xf4\xee\x54\x5f\xaa\x99\x89\x28\x41\x87\x8a\x1e\xf4\xe7\x5b\x86\x21\x7b\xb6\x48\x21\x88\x91\x9d\x28\x4f\x07\xc9\x5a\x8e\xfc\x49\xa8\x9c\x42\x9d\x33\x3a\xb2\x30\xe3\xec\x8d\x85\xd5\xb8\x19\x16\x92\xf6\x13\x03\x38\x44\xd3\xd1\x87\x52\x46\xfb\x07\x86\xf8\x3f\x04\xe2\x4e\xcc\xd9\x2c\x1c\x45\x29\x22\x24\xe9\x2e\x94\xca\x7b\x80\xba\x05\xe4\x42\x3e\x9e\xf5\x8a\x40\x06\xf1\x89\xc3\x3c\x93\xf6\x36\xf8\x90\xed\x54\x4c\x46\x3b\x93\x76\x31\xb9\xc4\x9a\x52\x00\x30\x65\x90\xd9\xeb\x39\xd8\xee\x07\xd7\xc0\xb6\xf3\xb0\xfd\x6d\x1d\x98\xf8\x29\x1b\xe4\x95\x8c\x3a\xbe\xa2\x2a\x43\xdd\x32\xd9\x28\x9b\x70\x20\x2d\xb6\xee\x7e\x42\x6d\xc2\xcf\xb4\x09\x43\xeb\xeb\xa8\x39\x6f\xd2\xbe\xbb\xa1\xb5\xf7\xd9\x31\xe2\xae\x35\x63\xd0\x3a\x1b\x92\x33\xf4\x1b\x91\x25\xcc\x45\x34\x97\x9b\xcb\x32\x5d\x3e\x9b\x09\xc2\xcb\x0f\x16\x4e\x63\xbc\x76\x33\x1b\x52\x34\xe3\x37\xe2\x29\x63\x39\xfc\x95\x83\xeb\xc8\x0c\x8b\xf1\xd1\x65\x51\xc7\x46\xbc\x70\x64\xe4\xcd\xfc\x23\x87\x68\x9c\xec\xe4\x61\x39\x53\xd3\x0a\x6e\x1e\xe2\x6f\x51\x13\x1c\x59\xe8\x43\x1e\xed\xab\x73\x71\xca\x21\x30\x49\x73\xc1\x8e\xe4\x00\x53\x85\x6e\x75\x0d\x11\x52\x54\x85\x6b\xc7\x52\x3a\x43\xbf\xb9\x17\xa7\xe3\x4f\x15\xbe\xed\x2b\x50\x47\xa0\x71\xaa\x2e\x45\xfb\x1c\x38\x25\x59\x4f\x9a\x1e\x1c\xf6\xe3\x9b\x29\xb5\x8c\x95\xe5\xbc\x7d\x0f\x45\xc3\x61\x82\x53\x63\x66\xe8\x1a\x19\x44\x5d\x51\x2f\x2b\xec\x99\x7b\xb5\x97\x9d\x10\xb3\x9f\xb5\xec\x67\x3d\xfb\xd9\xf0\x80\xc5\xc8\xa7\x0c\x05\xd7\x01\x5e\x14\x57\xc2\x35\xaf\xfc\x29\xaa\x87\x03\x90\x3d\x9b\xe9\xc8\x21\xc4\x10\xfa\xde\x3f\xa5\x60\x88\xfc\xa2\x0f\xa9\xf2\x4d\x2d\xdb\xc8\x29\xdb\xb0\x1e\x89\x8a\x0c\xa1\x4a\xab\x9e\x4a\xa0\xea\x63\x4d\x7d\xac\xab\x8f\x0d\x4f\x28\x2c\x8c\xcd\x7b\x65\x05\xed\x92\x93\xef\x77\x31\x46\xf6\x49\x57\x86\xc9\x3a\xeb\x1e\xba\x1f\xb9\xd9\x88\x86\x1d\x08\x0a\x4b\xd6\x96\x81\x7d\x8f\x59\xac\x50\xb8\x90\xa4\xa2\x3a\xc1\xd4\xa2\xe3\xaa\x4a\x83\x75\x06\xaf\x7f\x53\x98\x6d\xd5\xa6\x01\x4a\x6a\xfa\x74\x68\xb5\x8c\xf9\x81\x5a\x75\xb5\x56\x5d\xaf\x65\xd5\x36\x25\x0d\x7d\x3a\xb5\x5a\x0d\x9b\x1a\xea\x83\x76\x76\xb0\x1f\xfd\xe5\x2d\xd0\x76\x62\x38\xb2\x9c\x71\xc4\xfe\x4b\x47\x75\x1d\xd5\xde\xb0\x9f\x6f\xf9\x0c\xb1\x17\x8e\x7d\x17\xe6\x38\x18\xa6\x40\xe9\x9e\x43\x51\x96\x3b\x71\x1c\xf5\x94\x4c\x9e\xa4\xae\xa9\x0a\xc9\xeb\x37\x49\xd1\x55\x4a\x6a\x86\xdc\xf5\x9b\xa4\xd4\x2a\x25\x75\x5d\xea\xfa\x4d\xd2\x5f\x25\x0d\xe9\xb5\xb1\x0d\xbf\x7a\x65\xdb\x00\x00\xb9\x9a\x8a\x5c\xcd\x81\x5c\x7d\x0e\x72\x8d\x5c\xe4\xaa\x77\x44\xae\xae\x22\x57\x77\x20\xd7\x98\x83\x5c\x35\x17\xb9\xda\x1d\x91\x6b\xa8\xc8\x35\x1c\xc8\x55\xe7\x20\x57\xcb\x45\xae\x3e\x17\x39\x2b\xe9\x7e\x9a\x82\x0d\x51\x92\xfa\x29\x36\x0b\x00\x3b\x49\xab\x96\x8e\x01\xcb\x48\x75\x3d\x1a\x7c\x21\x73\x91\xd6\x6d\x5f\xc8\x40\xa4\xba\x76\xdc\xaa\x44\xb1\xae\xa7\x39\xbc\x0f\x96\x4f\x89\x9e\x3c\xa4\xb5\xa3\x9f\x5a\x2c\xcb\x47\x3f\xb6\x98\x2b\x48\x39\xb7\x64\x4b\xa8\x5c\x8c\x12\xc4\xfa\xe1\xd8\xd5\xdc\xd8\x99\xeb\xc7\xc0\xce\x58\x42\x2a\x76\xd5\xbb\x60\x57\x97\xb0\xab\xbb\xb1\x33\x17\x90\x81\x9d\xb1\x86\x54\xec\x6a\x77\xc1\xae\x21\x61\xd7\x70\x63\x67\xae\x20\x03\x3b\x63\x11\xa9\xd8\xd5\xe7\x63\x67\x52\x2b\xe6\x81\xad\xed\x72\x09\xdd\x86\x2d\xeb\x48\x17\x72\x8c\xe5\xa4\x6e\xae\x96\x55\x65\x88\x3e\x0d\x97\xec\xc3\x8e\xc2\x1d\x54\x6f\xb5\x57\x1a\x75\xa6\x81\x2e\xdb\x54\xc1\x5c\x62\x11\x02\x52\xc2\x1c\x87\x99\x6a\x78\x29\x61\x09\x9f\x10\xe4\xf0\x1e\xfa\x7d\x2c\x74\xc4\x02\xc8\x7f\xe3\x6b\x7f\x32\x15\x27\xe5\xec\x03\x9f\x53\x0a\x2b\xc5\xd7\xa9\x74\xbb\x5d\xd9\xd8\x3a\xae\xb0\x73\x44\x69\xc2\x2d\xd2\xbf\xe0\x1b\x0f\xf5\x87\x17\x42\x9a\xcf\xa0\x4c\xc7\x3e\x41\xe2\x3a\x45\x3a\x14\x26\xe1\x97\xb2\x76\x6c\x80\x98\x4e\xbb\x6b\x51\x62\x9f\xd3\xa8\xa9\x3b\x78\x3c\xc5\x71\x69\x63\x8b\x5e\xeb\x53\x9d\xfd\xf3\x67\xcc\x66\x45\x6e\xf2\xcd\xf3\xe7\x10\x01\x17\x0c\x48\x14\xab\x82\x4e\xab\xee\x71\xbb\x84\x4e\x0b\x6c\x47\x24\xcb\x84\x4e\xab\xe9\x65\x26\x09\x9d\x16\xb8\x30\x4e\x06\xad\x17\x9d\x76\xed\xf6\xcc\x6b\xd5\xef\x65\x2d\xf2\x2d\xcd\x44\x1e\xcd\x98\xe3\x1b\x9a\x65\xd0\x95\xf0\x12\x31\x03\x0a\xd2\x3c\xea\x47\x93\x69\x14\x42\xc8\x75\xf2\x6d\xe5\xf9\x33\x31\xef\xe3\xa0\x57\x61\x45\xbf\x7e\x95\x0d\x00\x84\xd3\xe7\x03\x1b\x77\xf8\x09\xce\xac\x3a\xfc\x04\x4b\xdf\x7e\x89\xe2\x01\xb8\xa5\x8b\x02\xe2\x8d\x0c\x61\x36\x04\x7b\x31\xa0\xf5\x0d\x7e\xcb\x93\xc1\xb4\x7e\x56\x30\xc3\xe0\x59\xd5\x25\x0b\x55\x7a\xff\x29\x1d\xae\x01\x14\x1c\xf6\x2b\xe4\x41\xc3\xba\xdd\x14\x5f\xe9\x63\x9e\x21\x8a\xf8\xb2\x75\x39\xfd\xb0\xb9\x9d\x5d\x36\xd1\x67\xeb\x0d\x56\x2f\xa1\xe6\x79\x64\x59\xf1\x5b\xac\x14\x4f\xa6\x63\x3f\xb5\x31\x28\x11\x64\xfa\x8f\x90\x05\xe4\xe1\x1a\x54\x70\x2a\x10\xbc\x0e\xf4\x7e\xc1\xef\xb8\xc2\x03\x4c\x76\x50\x13\x95\x6a\xf5\x35\xd4\x0b\xd2\xa4\x9c\x07\x30\xb8\xb4\xc0\xdb\xfd\xf9\xae\xe0\xce\xb7\x3e\x76\xcf\x7f\xdd\x3e\x38\xda\x3f\xdf\x3f\xd8\xdc\x42\x1b\x10\xda\x20\xf5\xc3\x14\xc5\x78\x1a\xe3\x04\x87\x69\x10\x5e\x70\x45\x0c\x21\xc3\x49\x34\xc8\xfa\x6e\x85\xb9\xb9\x55\x08\x26\x63\xa7\x06\x4c\xe9\x52\x50\x33\x39\x12\x8f\x76\x8a\xb2\x5c\x12\x66\xb3\x49\xd1\xed\x82\xdb\xf7\x2c\x06\x83\x07\x91\xe3\x43\x2e\xa2\x14\x97\x7a\x27\xe8\x9e\xcc\x01\x3a\x19\x61\x32\xea\x69\x84\x66\xcc\x4d\x80\xb0\x00\x44\x0a\x03\x68\x05\xe4\x4a\xf6\xd0\x1f\x5e\x74\x80\x74\x39\xae\x65\x79\x47\x35\xb0\x85\xed\x22\xa1\xb0\x19\xf9\x05\xa1\x6b\x32\x6c\xe8\x53\x7b\x4c\x09\x77\x42\x7a\x04\xf9\x2f\xf8\xa6\x62\x2d\xcb\x3d\x43\xfb\xc3\x0b\x54\x3a\x80\x56\xfc\x71\x19\xea\xf4\x6d\x83\x57\x70\x0c\xd4\xb6\x78\x1c\x51\x3a\xa1\xb7\x84\x44\x78\xef\x08\xa1\xf4\xf3\xfa\x44\xce\x15\x41\xdf\xfd\x5d\x95\x12\xcc\x02\x48\x91\x16\xe4\x3d\x9e\x5f\x3d\x57\xe8\x36\xbd\x45\x87\x39\x8a\x4b\xec\xf2\x0c\x86\xd0\x43\x7f\xa0\xe0\xb2\x83\x82\xcb\x8c\x37\xde\x2a\xa6\x07\xca\x7c\xab\x90\x3a\x4a\x58\x28\x26\x39\xe8\x1a\x00\x39\x71\x08\xad\xcf\x6e\x9c\xd5\xb5\x6a\x91\x3d\x74\x09\xad\x20\x3d\x39\x16\xe2\x13\x3d\x3d\x2c\x3d\x6d\xe2\x87\xa2\x27\x01\xe9\x7e\xf4\xa4\xf2\xe9\x3b\xd0\xd3\x6e\x18\xa4\x81\x3f\x0e\x7e\xc7\x09\xf2\x51\x88\xaf\xc6\x37\x0c\xc3\x01\x1b\x8e\xf9\xb4\xc4\x77\x8d\xeb\x61\x14\x4f\xf6\xa3\x01\x46\x5b\xd4\x57\x0d\xc2\x34\x67\x9c\x2e\x8a\x65\x3a\x05\xeb\x6a\x70\xf3\xe3\x54\x2b\x36\x19\x3b\x19\x7e\x77\x24\xfb\x60\x64\x55\x32\x3f\xd8\x38\xc5\x1d\x09\x2e\x08\x03\xc5\xc2\x46\x4c\x93\x44\x2e\x16\x15\xf5\xc6\x74\x4a\x68\x01\x46\x8b\xa7\x9b\x4e\x2c\xd7\x0c\x64\x88\xd7\xc5\x4f\xbe\x29\x52\x1a\x34\x4f\xc5\x29\x91\x9c\xa9\x61\x7d\x14\x4f\xe8\xb4\xfb\x36\xdd\x0d\xa5\xef\x8c\xa4\xd6\x33\xf2\x7a\x63\x2b\x49\xed\x68\xc0\x56\xc6\x7a\x16\x0f\x28\xa1\x53\x0f\x00\x5b\x3f\xc0\xbe\xa8\x54\x78\xe1\x80\x8d\x8e\xca\x87\x21\x96\x43\x22\x5a\x02\xed\xd9\x3d\xc9\x87\x2d\x41\x13\x37\x65\x86\xe3\x22\x46\x54\xd4\xa8\x68\xe0\xa7\x3e\xea\x81\xec\xa5\x96\x70\xc8\x63\x00\x9a\x66\xba\xe0\xde\xce\x3a\xe0\x43\x1c\xc3\x5c\xf6\xa3\xb0\x1f\xe3\x14\x2f\xb3\xe1\x18\x47\x17\x0a\x53\x96\xee\xa5\x8e\x16\x1b\x6b\x88\xa7\x01\x98\x53\xf7\x16\xc6\x53\xf0\x40\x62\x29\x78\xb0\xc0\xa6\xf7\x35\x61\xae\x30\x04\x28\x53\x76\x12\xde\xc0\xdb\x60\x0d\x48\xe0\x0b\xec\x5c\x12\x7f\x12\xb0\x68\xd0\x2c\x16\x8c\x20\x08\x2f\x1e\x80\x9b\x64\x9d\x5f\xe7\xe4\xc1\xe0\x97\x96\x48\x9b\x4b\x2a\x99\x14\xa9\x77\xc5\x31\x77\x52\x18\x2b\xd9\xd1\xa2\xbc\xd2\xa1\x73\x70\x0f\x1c\x0e\x6c\xb3\xef\xc3\x17\xb9\xba\x8d\xa6\x68\x7b\xc8\xbf\xf4\x83\xb1\xdf\x1b\x63\x6a\x86\x98\xb8\xb7\xc5\x73\xde\x99\xc2\x54\xb5\x1d\x84\x6c\xe3\xcb\xdd\xa7\x18\x5c\x75\x9f\xf9\x18\xa5\xcc\x3b\x9a\x06\x4d\xa3\x90\xb2\x5d\x03\x05\x09\xc2\xc3\x21\xee\xa7\xc1\x25\x1e\xdf\x20\x1f\x0d\x70\x92\xc6\x33\x78\xf6\x50\x8c\xfd\xc1\x72\x14\xf6\x71\xa1\x7d\xa6\x28\xf5\x02\x1a\x8f\x45\xc3\x14\xf8\x63\x53\x32\x1f\xc9\x52\x71\x22\x16\x55\x16\xa5\x7e\x51\x71\x3e\xf9\xf3\xa2\xc5\xe9\x7f\x3b\x9b\x8b\x19\x14\x52\x4b\x04\xc3\x5c\x00\x28\x77\xb5\x28\x45\x2d\x17\x25\x0b\x30\x64\x88\x87\x44\x50\x65\x0b\x0e\x0f\x58\xbc\x4c\xce\xa9\xb7\xa5\x09\xb1\x2e\x3e\xb3\xf6\x5c\x65\x73\xad\xbe\xb6\xd2\xa8\xcb\x9f\xa8\x4a\xc4\xf6\x45\x93\x83\x3a\xa8\xa6\x7c\x55\xe5\xdf\x0e\xaa\x17\x39\x3b\x25\x56\x55\xb6\x3f\x5f\x91\x8d\x9c\x6b\x93\x9f\x5a\xd8\x48\x9f\x8c\xb0\x24\x14\xb0\x44\x5b\x3e\x1a\x81\xd6\x98\x08\x99\x05\x96\x22\x17\x61\x37\x42\x8e\x0f\x04\x18\xe0\xcb\x9a\x08\x4d\x6c\x5d\x5b\x3a\xf4\x0d\x0e\x4b\xcc\xda\xdb\x54\x79\x6a\x3a\x72\x43\xb6\x75\xae\x32\xa5\x5e\xc7\xe9\x37\x45\xfe\xc4\xa7\x04\x8f\x71\x3f\xa5\x0d\x1f\xa7\xb1\x9f\xe2\x8b\x9b\x92\xcb\x5c\x5b\xd2\x3e\x83\xb8\xb8\x8e\x96\x28\x2b\x5d\x72\x9a\x87\xb1\xd9\x38\xf4\x93\x84\xb0\x89\x77\x7e\x82\x07\x8a\xc7\x9c\xfc\x97\x6f\x1c\xc6\x40\x1d\xe3\x18\x0e\x5c\x64\x57\x73\x43\xca\x5f\xe4\x7a\x6e\x3f\x76\x9f\x91\x63\xa3\xee\x42\x8a\x91\x93\xcc\xd8\xcc\x1b\x96\x3c\xbb\xd1\x2c\x08\x98\x7d\x1e\xc4\xc5\x0d\x45\xd1\x43\xee\x0b\x1c\x7d\x0c\x3c\x87\xa5\x27\x23\xfb\x8e\xd1\x7f\xed\x3e\xe7\x5e\x68\xab\x37\x45\x1e\xca\xbd\x31\xd2\x31\xb7\x4c\xa8\xce\xb6\x65\x2e\x59\x2a\x33\x0d\xaf\xfd\xea\x4d\xd5\x61\x27\x69\x8c\xfd\xc9\x9d\x54\xd9\x20\x43\x31\xe5\xb3\x6c\x83\xdf\xa8\x2f\xf7\x02\x6a\xb0\xad\x9e\x68\xa8\x74\x02\x61\xac\x25\xcd\x74\x0d\x95\x1a\x75\x55\x31\x2d\x29\x7c\x8f\x01\x3f\x4d\xed\xab\xbf\xcc\xf1\x08\xd9\xb6\xec\xb5\xb6\x1d\x96\x8b\x88\x53\x3f\x86\xe3\x96\x4d\x40\x34\xb7\x37\x38\xde\x64\xd6\x55\x5c\x68\xfc\xe1\x87\xa5\xe1\x78\x96\x8c\x96\x8a\x6d\x73\x14\x8a\x6b\xa3\x13\xc3\xdc\x41\xb5\xbc\x79\x85\x73\x2d\x64\x35\x9d\xca\xb7\xa5\xb2\xf2\xfc\x7c\x42\xcf\xbe\xdd\x0a\xfb\xf1\xc7\xed\x7c\x0a\x51\x3c\x76\xa0\x9e\x41\x25\x52\x1b\xd2\xed\x26\x3b\x68\x1b\xce\xc1\xec\xbd\xac\xf4\xce\x53\xd0\xcb\x2a\xca\x09\x4f\xce\x95\xc9\xd7\x0b\xef\xa6\x1b\x6a\x8f\xac\x0a\x41\x3d\xb3\x4c\xa6\xe0\x07\xaa\xfe\x06\xfb\x21\x9f\x29\xbe\xdd\x81\x1e\xb6\xfb\xae\x6b\xa8\xa2\x39\x47\x09\x2e\xa9\xd7\xce\x5d\x34\xcf\x19\x8c\x5c\x5d\xa1\xa8\xcb\x15\x4d\x52\xbd\x3b\x69\x9c\xc5\x74\x66\x07\xa4\xff\xcc\xe9\xcc\x34\xc1\x0b\x4e\xa7\x55\xf1\x5b\x70\x3a\x45\xdd\x7b\x4c\x67\x9e\xc2\xb7\xd8\xd5\xc1\x37\x9d\xce\x7b\x4f\x57\xce\x12\x98\x33\x5f\xba\xde\x34\x67\x92\xe8\x66\x22\xf4\xbc\x7d\x9b\x58\xc7\xac\xae\x2f\xd1\x3a\x0a\x2e\xe5\xd9\xca\xdb\x22\xd8\x8e\x49\xe3\x4a\x77\x47\x7e\x10\x42\xca\x13\xd7\x5d\xeb\x3b\xb0\x1b\x38\xe7\x9d\x47\xeb\xee\xe0\x03\xba\x8a\x4d\xd9\x41\x48\x5d\x83\x18\xa4\xa1\xc9\x1a\xd3\x76\x09\x71\x27\xfa\x26\x8f\xa3\xbc\xeb\xf2\xed\x40\x3b\x09\x49\x4d\x28\x73\x47\x7a\xf5\xae\x6b\xd9\x7b\x4c\xf0\xb4\x89\x43\x11\xfe\x33\xe5\x6a\x0c\x4a\xa5\x7e\xca\x8c\xba\x2b\x7a\x1d\x03\x86\x46\xb3\x54\x3a\x12\x5a\x11\x26\x2c\x45\x5c\x46\x42\x2a\x27\x44\xd6\x1b\x12\x66\x97\x45\x80\xb0\x9f\x57\x23\xcc\x22\xef\x53\xfc\x20\x90\x67\x52\x00\x39\x73\x61\xd8\x0b\x92\x3f\x98\x4a\x26\xea\x50\x6f\x00\x48\x8f\x07\x5d\x10\xae\x0d\xba\x2c\x2b\x4f\x06\xca\x54\x80\x86\x99\xbc\x0a\xc5\x69\x0b\x6d\x75\x80\x45\xfa\x0d\x89\xbc\x90\x1c\x86\xb3\x99\x10\x2b\x34\x39\xe2\x95\xc3\x9c\xf5\xd7\x83\x23\x38\x2f\x33\xa2\x33\xcb\x5c\x47\x31\xf4\x2b\x53\x74\x7b\x48\xe9\x97\x97\x35\x6b\x13\xfa\x19\x1e\xb2\xaf\x4b\x49\x1f\x5d\x2b\x66\x47\x78\x82\x41\x0a\x87\xdd\x95\x92\x00\xbb\x8a\x82\xd3\x3e\x38\xb4\xc3\x6b\xb3\x3a\x97\x60\xf1\x25\x0f\x3b\x4f\x99\x29\xcd\x27\xcf\xf1\x16\xa6\x80\xce\x0e\xc8\x9e\x3b\x73\xd7\xed\x00\x17\x58\xb7\x62\x9f\x7a\x5a\xb7\x4f\xeb\x16\xdd\x7d\xdd\xde\x67\x75\x80\x85\xf0\x28\x48\x16\x5e\x1b\x56\x4c\x18\x45\x03\x17\xf9\xf5\xe0\xc8\xc9\x01\x64\x0f\x32\x83\x03\xdc\x97\xed\x58\x31\x3b\xc9\x86\xa6\x87\xfb\xd1\x84\x2d\x1d\xc2\x16\x82\x68\x96\x14\x67\x1e\x62\xb0\x8a\xb2\x07\x41\x4a\xbc\x1b\x25\x27\xee\x0b\x79\x40\x81\x88\xc4\xa5\x25\x9b\x87\xff\x28\x8a\x12\x8c\x26\xc1\x35\x91\x85\x2c\xfd\x03\x4f\x50\x53\x48\x43\x32\x21\x32\x29\xcc\x45\x76\xd1\x25\x48\xa7\xe4\xa4\x93\xcc\x7a\x09\xfe\xf7\x0c\x87\xa9\x55\xc5\x80\x54\xd1\x4e\xca\xea\xa1\x8e\xa2\x53\x35\x28\xa3\xa4\xcd\xca\x7c\x55\x3f\xd9\xd9\x6c\x58\xd9\x62\x24\x65\xab\xcd\x1a\x29\x89\xfc\xc1\x04\x66\xd6\xe3\xc1\x19\xfa\x6d\x9d\xd6\x3b\x0d\x72\x43\x97\x64\xbf\xb9\x09\xf4\xbb\x2e\x2b\xaf\x04\x34\x91\x44\xdb\x43\x7f\x30\x20\x13\x38\x47\x01\x32\x85\x2c\x57\xdd\x0a\xfd\xd7\xae\xfe\x38\xfc\xd0\x3d\x46\xff\xa7\xb5\xb2\x8a\xa6\x0c\x68\xc2\x74\x79\x36\x98\x87\x5f\xfa\xc9\x2a\xc8\xc9\x53\x7f\x50\xe1\x4f\x39\xb2\xf1\xa1\xcf\xaf\x9f\x67\x09\x0f\x9d\x2f\x02\xa1\x30\x73\x65\x88\x9b\x2c\xf0\x58\xc8\xfe\x0a\x20\xcb\xb7\xcf\x04\x2d\x6b\x25\xbb\x1e\x8f\x85\x80\x92\xee\x23\x01\x50\x22\x82\x59\x92\x41\x81\x70\x96\x8f\x7c\x6c\x16\x87\x2f\x31\xae\xe4\x57\x76\xbd\xe6\x69\x71\xb3\x94\x0b\x66\x7f\xa0\x5f\xae\xdd\x99\x81\x88\x6a\x34\xd6\xc9\xba\x34\x5e\xae\x98\x21\xb3\x30\x15\xb4\x03\x7e\x45\x26\xd4\x90\x11\xac\x01\x94\xbe\x58\xa6\x29\xa7\x45\x84\x95\x7f\x68\x05\x6c\xcd\xd2\x7b\x21\xde\xae\x19\x7a\x81\x66\x7a\x83\xaf\x84\x5e\x20\x02\x8a\x82\x45\xe6\xeb\x62\xbc\x67\x0e\x2e\xc6\x7b\x70\x6b\x51\xde\xce\xc5\x2c\x17\xa9\x24\x3f\x7c\x41\xc6\x7e\xd4\x36\x51\x80\x5e\xb9\xdc\xf2\x65\xe8\x34\xcc\xbd\xf4\x26\x47\x7a\xd5\xb0\x43\xeb\x99\xed\x3b\x3f\xfc\xcb\xa0\x3d\x15\x25\x9b\x19\xc2\xc6\x60\x60\x1f\x04\x98\xeb\x7e\x14\xf6\xfd\x94\xc3\x2c\xac\x81\xf9\x14\x4e\x05\x43\x81\x25\x3b\xf2\x07\x34\x90\x11\x5b\xa8\xdf\x86\xcb\xcc\x42\x9d\xcf\x7c\x13\x8e\x00\xcd\x16\xb8\x72\x87\x72\x3a\x4b\xb0\xf1\x81\xf7\x38\x55\x12\x17\x4b\x8b\x18\x62\xc0\xa2\xb1\x9f\xa4\xf0\x3c\x7f\x4d\x67\xe2\xf5\x69\x49\x5d\xce\xcb\xa8\x56\xa6\x2e\x66\x67\xcc\x19\xcc\xe6\x49\x4c\x05\x07\x37\xc5\x64\xe0\xd6\xf5\x35\x28\x6d\xa6\x74\xdb\x5c\x50\xcf\xff\x67\x5c\x04\xd9\x5c\x14\xec\x37\x0b\xb6\x5b\x85\xbc\x7b\xa0\x87\x33\xfa\xdf\x8f\x06\xf8\x96\xaa\x07\x4f\xc4\x69\x8d\x5e\x8a\xc0\x49\x42\xea\x4e\xf7\x5d\xd7\x05\x85\xcd\xd5\xad\xa0\x2f\x02\x4b\x17\x36\x4c\x88\x40\xf2\x0e\x02\x07\x3f\x02\x36\x00\x92\xe1\xa4\x46\xe0\x04\x53\xc0\xcc\xd3\x4e\x75\xb4\x6d\xa3\x89\x5b\xc5\x1b\x61\x01\xc3\x40\x3a\xd1\xea\xc7\xae\x64\x7d\x98\x6f\x03\x98\x13\xe0\x4c\xb5\x0f\xb5\xf8\x71\x82\xdc\x4c\x46\x40\x51\x8b\x22\x55\xb1\x4b\xbe\x4f\xc0\xf6\xd3\x81\x7f\x36\xb1\xe6\x61\xc0\xb0\x25\xe5\x92\xb6\x6a\x5c\xe2\x3c\x31\x10\xa8\xb0\x25\x82\x46\x03\x4e\xe5\xda\xdd\x8c\x5d\xda\x5f\x79\x99\xdf\xbc\x6a\xbd\x52\x46\x2f\x57\x16\xc6\x40\xa8\x5a\x1c\x67\x99\x0f\x18\x4f\x91\x9f\xa2\x31\x26\x5c\x30\x0a\xf9\x0a\x60\x59\x3e\xa8\x25\x28\xec\xd7\xc0\x70\x4d\xbe\x85\xc4\xf9\x66\x12\x84\xd4\x48\x94\x1d\xe2\x8d\x70\x89\xea\x23\xab\x44\xa7\x4f\xc2\x9f\x12\xd2\x04\xec\x8f\xe9\x91\x37\xb8\x44\x3f\xfe\x68\xd5\xc7\xeb\x81\x3a\x0e\xef\xa4\xcb\xc8\x30\x51\x95\x29\xce\xf3\xb9\xde\x6c\xd1\x2b\x69\xb7\x48\x9a\x89\x24\xc2\x50\x9a\xbd\xb2\x10\x34\x6f\xee\x61\x09\x79\x65\x85\x1c\x64\x68\xba\x2f\x97\xc8\x05\xf2\x3a\x33\xfd\x02\x09\x1c\x7e\xcf\xd5\x41\xf0\xab\x78\x6a\x23\xe8\x3a\x25\xdf\xe9\x32\xfe\xf1\x96\xd5\xe3\xe2\x6d\x6d\x0f\x24\xbf\x39\x33\x40\xe5\x23\x5b\x7b\xf3\x2c\xff\xee\x69\xa9\x00\xa6\x77\x4c\xf6\xb0\x9b\xa1\xa0\x7e\x34\x1e\x63\x4a\xff\xd1\x90\x8b\x06\x20\x6a\x62\xc8\xa5\x97\x27\x7a\x48\xa2\xa8\xe4\xe4\x4d\xb6\xd1\xd8\xbf\x92\x5e\x59\xfd\x12\xed\xae\x1f\xd4\x01\x5d\x08\x29\x45\x6a\x67\x17\x8f\x90\xe1\x81\x71\x41\x5a\x9f\xac\x4f\xc3\x1c\xd7\x05\x28\xf1\xc7\x14\x7b\xf8\x01\xc0\x40\x25\xe9\xd3\xf0\xa3\x38\x0e\x2e\xa9\xac\xc2\x39\x86\x15\x20\xbf\x4a\xcd\xe4\x7c\xc9\x72\xd0\x8c\xb5\x5a\x4c\xae\xb9\x4b\xcf\xf2\xe5\x9b\xfe\x08\x4f\xee\x06\xd7\x2e\x70\x32\x95\x39\x58\x4c\x0f\x25\x78\x56\x10\x34\x27\xe3\x6d\x96\xb3\x91\x9e\x62\xa8\x88\xc5\xdf\xea\x62\x58\x3f\x0a\x2f\x71\x9c\x2a\x32\x2c\xcd\x76\xc7\x8d\x29\xc1\xe2\x93\x5a\xff\xb9\xdd\x56\x0f\x69\x15\xd5\x79\x55\xbc\x2c\x68\x0f\x33\xdf\xc5\x4a\x45\x6d\xfe\xb1\x4e\x78\x37\xc9\xf8\x68\x76\xa2\x7e\x28\x92\x58\x4d\xa3\x24\x09\x7a\x63\xec\x5e\xb1\x96\xa6\x16\x73\x6e\xca\x06\xca\xb4\x07\xa5\xdf\xf8\x09\xfc\x0f\x03\x0a\x12\xea\x73\xb2\x82\x3b\xd2\xef\xcc\xe1\xc9\x5a\xe9\x0b\xbe\xe9\xa8\x7e\x51\xd6\x62\x9a\xa7\x94\xbd\x10\x59\xc6\x1d\xf8\xef\x9c\x82\x62\x55\x76\x4c\x77\x2e\x7b\x0d\x26\xc2\xeb\x96\x09\xf6\xc2\x42\xae\x57\x8f\xce\x1f\xba\xc7\xab\xf6\x0a\x12\x0b\x6f\xda\x4b\x88\x85\x23\x01\xa5\xef\x2a\x07\x53\x1c\x1e\x1f\xef\x19\xd5\x8a\x3b\x93\xc9\xd3\x6f\x17\xbc\x26\xc1\xf5\x6e\xa8\x96\x2b\x6c\x7a\x44\x57\x71\xb2\xd8\x32\x46\xce\x75\x63\xb2\x12\xcd\x37\xd0\xc1\x4d\xc8\xa1\xce\x0d\x9c\x1b\xd8\x72\xaf\x0c\xd8\x15\xe0\x77\x30\x0c\xf4\x35\x9e\x03\x07\x92\x80\x25\x34\x03\x18\x64\x8f\xc3\x99\x17\x65\x86\x71\x18\xd1\x37\x1a\x03\x64\x39\xfb\x71\x1e\xf7\x28\xba\xa4\x29\xf2\xe2\x9a\x8e\xad\xed\x57\x68\x69\xc9\xee\x5b\x61\x2d\x5f\x49\x23\x9a\x6f\xc8\xe5\xca\x31\xa7\x96\x83\x54\x9d\x84\xc9\x2b\xca\xc4\x29\xc6\xc6\x65\x55\x95\x95\x40\x5f\xbf\x52\x72\xcd\xea\x54\xf8\x24\xde\xf0\x63\xaf\xa1\xa3\xb1\xca\x49\x94\xca\xe6\xdd\x6b\xd0\x76\xe0\x6a\x43\xfc\xb4\xdf\x6e\xb0\x9e\xdb\x88\xd3\x06\x9a\x15\x17\xa9\x8c\x61\xf7\x52\x07\x31\xff\xba\x43\xac\x3a\xdf\xbd\xe4\x42\xde\xcc\x72\x3f\x9a\x4c\xfd\x14\xb6\x97\xa2\xcb\x50\xde\x16\xb4\x4d\x4c\x12\x7f\x8a\xee\x89\xb6\xe5\x77\x17\xe4\x1e\xca\x70\x30\xa2\x6d\x1f\x73\xf2\x76\x10\xb2\x44\x5d\x2e\xde\xa8\xd0\xb7\x28\x5e\x98\xfb\xce\x51\xcb\xc8\x91\x96\x94\x25\x98\x7d\xb1\x05\x6a\x24\xe2\xae\x56\x81\xbc\xb3\x1d\x63\xa1\xbf\xe6\x21\x96\x14\x77\xaa\x5a\xae\xa4\x68\x35\x86\xf6\xfe\xb4\x7a\xdd\x6a\xb4\x6b\xed\xfe\x2a\x24\x36\x68\xb7\xda\xcd\xd6\xb0\x35\x3c\x2b\x73\x55\x3c\x80\xe6\x0f\x59\x3f\x1c\xe7\xc8\x02\x28\x38\xc7\xc2\x71\xf8\x12\x75\x33\x46\x46\xc3\xda\x2c\xbe\xe7\xe5\xad\x31\xd9\x5f\x69\x51\xe1\x91\xaf\x93\x8c\x4e\xef\xbc\x64\xd4\x98\x0d\x7c\x41\xdf\x61\x0d\x3f\x6c\x00\x07\x53\x18\xd5\x96\xde\xd4\x8f\x13\x5c\x52\x16\x6a\xce\xc5\x64\x9c\x28\x8a\x9f\xac\x9a\xd5\x2b\x81\x14\x47\x34\x86\xd7\x9c\x45\x47\x09\xc3\x40\x26\x4f\xbd\x9a\x07\x91\x5f\xc6\x49\x87\x61\x96\x14\xc2\x00\x77\x82\x93\x94\xda\x36\xf8\x63\xcb\x02\xd5\x60\x9e\x56\xcf\xd0\xfa\x3a\xca\xd6\x1e\xfa\xf1\x47\xbd\xdd\xd3\x1a\x2b\xc3\xd7\xa4\x4b\x05\xb5\x75\x4d\x2f\x30\xcc\x96\x91\xca\x61\x8c\xc5\xaf\xb5\xc8\x4c\x79\xea\x1e\x6a\x96\x73\xac\xeb\xa2\x4b\x76\x44\x87\xab\xa0\x0c\x86\x59\xde\x80\x3f\x85\x06\xaa\xfa\xad\xb5\x51\x5c\xb9\xd5\xa9\xb5\x8b\x31\x0a\xeb\xd1\xc8\x71\x0c\xf2\xa4\xd3\x89\x2a\x9a\xe7\xde\x15\xf1\x45\x78\x15\xfb\xd3\x29\xc8\x91\x7e\xca\x9a\x97\x55\x26\xc8\x27\x3b\x7d\x22\x79\xa5\xe5\xae\x5e\xc5\xd5\xc7\x70\x65\xcb\x1c\x7e\x6c\x9f\x8a\x3a\x90\xdc\xf9\xb2\x47\x08\x3d\x5c\xc6\xcf\x93\xea\xb9\x8e\x40\xee\x2d\xeb\x2c\x75\x08\x0d\x07\x94\x6a\xc4\x01\x23\xbb\xd8\xb1\x1c\x9c\xf2\x42\x44\xe9\xde\x8b\x80\x50\xc7\x10\xd5\xa4\x89\xcd\x0d\x2a\xc5\xae\x1d\xc8\xbc\x31\x6f\xba\xfb\x78\xa8\x66\xca\x27\xcb\x51\x27\xc7\xfb\x9c\x35\x4d\x6d\x50\xd8\xef\xcc\xef\xfc\x2f\x12\xc3\xc5\xbe\x85\x6d\xfc\xb9\x1b\x18\x59\x96\x76\x8d\x8a\xb9\xac\x84\x7f\xa5\xa9\x8d\x50\x5c\x2d\x1d\xa7\xb0\xc7\x6b\x30\x0b\x52\xa3\xab\x13\xbe\x69\xe3\x9e\x58\x6d\x0e\x69\x20\x47\xd9\x61\x71\x8e\x75\x7b\xb1\xde\x2d\x84\xce\x42\xd1\x73\xb6\x6c\xf6\xeb\x52\x74\x83\x28\x73\x3e\xb1\x05\x40\xb3\xfa\xac\x1a\x62\x49\xe6\x99\x21\x02\x24\xb0\xce\xde\x45\x32\xe9\x42\xff\x32\x98\x70\x05\x6c\x40\x61\xf6\x46\x84\xe3\x0a\xc7\x5c\xd7\x7e\x54\x7c\x3b\xcd\xdb\xb4\x95\xfd\xd5\x2c\xc8\x55\x8b\x96\x4f\x84\xac\x44\xdf\x2a\xc1\xa5\xa5\x88\xa4\x23\x64\xf4\x62\x96\xa1\x5a\xc1\x0c\x10\x5c\x88\x9a\xc5\x84\x3e\x30\x2b\xc9\x5e\x59\x0a\x4b\xba\x40\xdd\xc2\xda\x52\x5a\xd2\x0b\x12\xd2\x1b\x5a\x8e\x6b\xb7\x85\x8f\x2d\xec\x1e\x3a\x11\x13\x27\x14\x5f\xf2\xb5\x0c\x7a\xb4\xed\x49\x26\x00\xb1\x43\x69\x17\x4d\xd2\x23\xa4\xf6\xfe\x2b\xee\x53\x5a\x80\x16\x11\xe9\xf8\x1b\xec\x4d\x59\x54\xe5\xf9\x6c\x9a\x7b\xcf\x5b\xd8\x34\x27\x3b\x16\x46\x41\xf2\xa8\xbf\x33\xcb\x7e\x68\x14\xf5\x7d\xe9\x01\xb7\x14\x67\xec\x02\x47\x84\x81\x6f\xb0\xab\x30\x8d\x83\xa4\x5a\x90\x17\x93\x06\x58\xde\x29\xd8\xed\x37\x9c\x5f\x65\xe4\x33\x6e\x62\x6b\x8e\x71\x0a\x73\xc3\x90\x27\x4f\xd9\xc4\x94\xa8\x8b\x74\x58\xb2\xbd\x49\x62\x32\x8a\xc2\xc7\xba\x4d\x88\x26\x16\xd6\xc6\x58\xd9\x9a\x3e\x56\xea\xfd\x0b\xe8\x98\xfc\x24\x99\x4d\xf0\x40\xbd\x4f\xf4\xc7\x31\xf6\x07\x37\xd2\x7e\xa7\x1c\xc8\x66\x21\x4d\x5b\x59\x20\xa2\xd9\x62\x6c\xcf\xce\xbf\x16\x3a\x34\x11\xc6\x05\x26\xea\x71\x82\x17\xe6\xf5\x6e\x7d\xd1\x2c\x5c\x14\xd6\x9f\x28\x71\x1b\x24\x4f\x55\x48\x07\x9c\x0a\x90\x20\x7e\x3b\x0f\x38\x37\x74\x4a\xf2\xea\x61\x95\x6d\xa9\xbc\x59\xec\x1a\x79\x11\xce\x09\x61\xc3\x6d\x42\x28\x7b\x32\x97\xaa\x7e\xb1\x81\x72\xb5\xa3\x0c\x5a\x8e\x52\xd4\xd0\x4c\x58\x6f\x48\x3e\xd8\x4d\x24\xe6\x5d\x99\x7c\x19\x0c\xe1\xbe\x84\xfe\x9b\x7f\x59\x32\xcf\x0a\xc3\xbc\x30\xf9\x40\xa1\x93\x56\x8a\xdd\x93\x6c\x12\xf0\x70\xa7\x4f\x1a\x23\x6b\x79\xf7\x67\xae\x30\x98\xb2\x78\x41\xc5\xd5\xb1\xbc\x06\xb3\xbc\x60\x0f\x20\xa7\x90\x66\x00\x70\xbe\x57\x48\x16\xa8\x1c\x53\xdb\x8a\x20\x64\x96\xbc\xcc\x0e\x80\x99\xcc\x5c\xe0\x10\x8c\x79\xf3\xa1\x89\x28\xe5\x0e\x60\x34\x74\x76\x3e\x2c\x53\x67\x00\x2a\x2c\x49\x48\xda\x40\xed\x26\x98\x1c\xc3\x07\x6e\x3f\xbb\x3b\x44\xd1\x24\x20\x32\x82\x87\x7c\xfa\xe9\x2a\x18\x8f\x51\x0f\x8b\x06\x07\x28\xf6\xc3\x41\x34\x19\xdf\x3c\xd0\xe1\x9e\x5a\x4d\xb0\x61\xf2\xd0\xee\xcf\x1e\x4c\x29\x69\xfc\x1b\x70\x21\x3a\xc9\x03\x93\x05\x49\xd4\x58\xc1\xd7\xb8\x3f\x4b\x71\x69\x89\x47\xa3\x5a\xf2\x58\xe2\x0e\x8f\x99\x6f\x39\xc4\xa2\x07\x82\xee\xa1\x25\x32\x1c\xe4\xff\x97\xdc\x67\x66\x0a\x46\xe6\x6e\x9c\x9a\x3d\x4e\xa2\x1e\xa3\x2e\xaa\xd8\xb4\x1b\xf5\xd3\x69\x66\xb3\xec\x50\x54\xff\xe0\xbc\x4a\x32\x94\xc8\x14\x4e\xa9\xdd\x5c\x31\xd2\x9a\x5b\xdc\xea\xe8\xd2\x96\xd6\xb5\x29\xad\xd0\x78\xb3\x34\xf1\x40\xa6\xc0\x15\x31\xee\xb2\x34\xc8\x6c\x21\xdd\x96\x2b\x2c\x91\xb7\x34\x1e\x80\xbf\x35\x60\x2d\xa1\xcd\x34\x1f\x03\xb0\x9b\x36\xd4\xe4\x22\x19\x34\x53\x90\xf3\x64\xb2\x7c\xcc\xd1\x4b\x53\x9f\xad\xa4\x86\xce\x52\x38\xdb\x9d\xa5\x8e\x98\x28\xb5\xe0\x61\x3c\x3b\x52\x0b\x29\xfa\x6e\x5a\x6d\x9b\x66\x40\x51\x71\x0f\x18\x5f\xe6\x2c\x4f\x63\xc9\x9e\x80\xe5\x10\xbf\xee\xae\x0f\xb7\x44\x89\x13\x0a\x71\xfb\x37\x9b\x86\xeb\x11\xf5\xe3\x1f\x36\xb7\x6f\x11\xd9\x3e\xb9\x05\xa5\x6d\x17\xce\xa4\x3c\xce\x6c\xf3\xb7\xb8\x85\xb4\xe2\x96\x0e\xbb\x9d\x1f\xbe\x0c\x86\x1d\x69\x7b\x96\x28\x64\x41\xf5\x38\x73\xa9\x5a\x64\x5f\xfe\x3e\xf4\xe5\xb9\xd2\xc1\x77\xa0\x8e\xf8\x8b\xa8\xcd\x2d\x8b\xaf\x90\x26\x79\x89\x0f\xb5\x2b\xac\xec\xe3\x37\xec\xa1\x3f\x1e\x59\x83\x9d\x6d\x47\xdf\x48\xe1\xa0\xed\xae\x51\xea\x52\xee\xda\x64\x17\x02\x9e\x88\x2d\x5c\x5c\x91\xb0\xa7\xc3\x2b\x64\x0c\xf6\x4c\xb7\x3d\x97\x77\x27\x15\x63\x69\xdf\x8c\x2e\x55\x60\x8b\x55\x30\xa8\x58\x43\x12\x38\x15\xf3\x8a\xbe\xc4\x7d\x9d\x21\x07\x80\x30\xe6\x47\x6d\x5f\xd2\xe3\x1b\x68\xec\x07\xd7\x34\x19\x08\x54\xb0\x0e\xa9\x74\xb6\xa6\x86\x99\x0a\x74\x97\xde\xc4\x7a\xe2\xbb\x87\x3e\xf8\x4f\xe0\xc7\x0f\xac\x20\xfe\xde\x19\xf3\xf7\xa8\x27\xb6\x31\xc3\x45\x15\xc5\xf7\x62\x8c\x0f\x8e\xa2\xa9\x28\x7e\x28\xc6\x5d\x50\x4f\xfc\xcd\x79\xf7\x37\x57\x16\x7f\xfb\xad\xc2\x53\x6c\x7b\x1c\x27\xb4\x87\xdb\x3b\x0a\xe9\xc3\xdd\xf7\x17\xb6\xad\x43\x1e\xdf\x82\xbb\x47\x9e\x82\x3c\x53\xe5\x89\x4c\x97\x72\x4a\x4b\x96\xbf\xf2\xf6\xcc\x6b\x35\xbe\xd7\xa4\x94\x0f\x9e\x83\x72\xd1\xdc\x93\x4a\xce\x49\x03\x31\x33\xfd\xa4\x96\x76\x92\x57\x74\x24\x9e\x04\xfd\x68\x06\x5c\xfc\x54\x93\x4f\xee\xfb\xe9\xc8\x43\x96\x14\x94\xd9\xf1\x7a\x2f\xea\xfb\x63\x34\x8d\xc6\x37\xc3\x60\x8c\xa2\x21\xa2\x9b\x16\x3b\xc5\x5b\x8e\xbc\x2c\xb6\xfd\xba\x5a\x50\x6b\x58\x61\x4c\xe2\xf5\x36\x79\x7f\xfb\xc6\x8c\x1d\x24\xd9\x5a\xf6\x3e\x1b\x4c\x0d\x6c\x04\x67\x3d\x32\x83\x3a\x11\x6f\x57\xa6\x71\x94\x46\xe4\x13\x5a\x27\xa7\x0f\xbd\x00\xab\x87\xd6\x51\x88\xaf\x08\x02\xf9\x10\xc2\xd9\x78\xec\x58\x28\x02\x83\x6c\x99\x48\xf1\x8e\x6c\x91\x3c\xf9\x9c\xe4\x2b\xb9\x9d\x8a\xed\xbd\xa0\x17\xfb\xf1\xcd\x3c\x1d\xb9\x94\x1f\xd4\x09\x0a\xb2\x85\x32\xad\x27\x11\x2e\x78\x97\xfd\x31\x0a\xc2\x11\x8e\x03\x25\x80\xab\x12\xd1\x41\xcf\x33\x6a\x46\x18\x35\xa7\xb3\x40\xd8\x3f\x1e\x63\x18\xdc\xe3\x84\x9f\xc1\xc8\x4f\x39\x42\x2c\x94\x07\x15\x83\x8c\x53\x25\x42\x79\x71\x00\xb9\xdc\x15\x5d\xe2\x38\x0e\x06\x38\x41\x87\x54\x21\x12\xe0\x84\x32\xf0\xe9\x0d\x0a\x42\x96\xcd\x38\x43\xa0\x40\x0b\x7a\xae\x86\x93\x45\x01\x18\x32\x97\xa3\xdc\x22\x51\x03\xc9\x44\xed\xdf\x9c\x50\x12\x56\xa4\x9b\x1c\x93\x44\xd9\x5f\x2c\xc0\xe3\x41\x07\x2d\x41\xa6\xac\x25\xdd\x70\xc4\xde\x26\xf9\x9b\xe0\x74\x14\x0d\x72\x7d\xe4\xa5\xd2\x7a\x8c\x7c\x9b\xe3\x19\x42\x66\x38\x43\x8a\xbe\x62\x90\xcd\xe7\xd5\x19\xc4\x70\xea\x5f\x85\xe6\x17\x89\x91\x10\x61\x21\x4b\xab\xe7\x32\x27\xde\x98\x5d\x4c\x70\x68\x31\x1d\x26\x3b\x4a\x3e\x16\x28\x63\x3e\xec\xdc\x95\x95\xb7\xa6\x7f\xb0\x22\xc0\xcc\xa4\xb8\xeb\x57\x20\x1c\x4b\x63\x3b\x4e\x3f\xf0\x26\x47\x7e\x72\x70\x15\x32\xb2\xbf\x29\x2d\x91\x9a\x4b\x65\xe1\xf3\x44\x1e\x61\x13\xe4\xe5\xc9\x8b\xb9\xfd\xa0\xb5\x72\xa7\xdb\x52\xeb\xff\x49\x66\x53\x22\x6a\x85\x41\x5a\xf1\x89\x70\xca\xb6\x3e\x3f\xbe\x98\x91\xd1\xb5\x8e\x07\xb2\x64\x50\xc8\x19\xa7\xcc\xe3\x36\x5e\x4a\x50\xc6\xd1\x03\xaa\x14\xe6\x93\x4e\x57\xa9\x09\x41\xee\xa0\xb2\x1f\x38\xb6\x1d\xc4\x15\xe3\x43\x1c\xe3\xb0\x4f\x1a\x80\x71\x9e\xea\xeb\xd5\x18\x06\x26\x17\xdb\x00\x3a\xf7\x19\x64\x4b\x8d\x61\x63\xaa\x5b\xb0\x52\x12\x99\x69\x52\x95\xf7\x2c\xa4\xe3\x00\x13\x48\x57\xad\x19\x02\x75\x83\xcf\x47\x96\xc1\xa6\x54\x16\xd7\x70\x44\x94\x86\x90\x72\x00\xa4\x54\xfe\x2b\xf3\x4a\x1e\xb1\x1c\xad\x33\xb6\xc9\xef\x2c\xe6\xf2\x22\x5a\x2e\x9f\xe3\x99\x8d\xc0\x92\xcb\xe2\x64\x9b\x2b\x97\x47\x50\x97\xd6\x08\x7f\xa7\xae\x13\x27\xd5\xf0\xe2\x77\x21\x9b\x3c\x77\x75\xc7\x5c\xa1\x03\xc6\xcc\x58\x92\x00\x20\x29\x30\xa1\x1f\x0c\x50\x12\x4d\x30\x4d\x3d\x85\xae\x46\x38\x44\x37\xd1\x2c\x16\x66\xf6\x3e\x11\x67\x29\xf0\x07\x8e\x9d\x7b\xdf\x5d\x50\x77\x74\xce\xdb\xcb\x10\x65\x00\x95\x8a\x39\x32\x62\xe8\xef\xb8\xdd\xcd\x45\xa3\xd0\x9c\x76\xa3\x29\x11\x76\xa6\x99\xdc\xc3\xe4\x9d\x7b\x88\x53\x12\x30\xd0\x30\x29\x32\xd5\x04\x34\x91\x0f\x3c\xa5\x6c\x75\xd2\xfd\xb3\xa8\xfc\x72\xc7\x71\x87\x46\x94\x4b\x6c\xd1\x3f\xeb\x1a\x17\x11\x0f\xf9\x65\xdb\x47\x7f\x02\x46\x13\x73\xea\x21\xb6\x55\x67\xc5\xf4\xcd\x5a\x06\x58\xce\xdd\x62\xc9\x74\x9e\xca\xc5\xcf\xd0\xba\xd4\xbe\xfa\x69\x81\xd4\x45\x8e\x4d\x76\x0b\x5d\x45\xe1\x52\x4a\xe5\x67\xee\xee\x28\x05\x2f\x1c\x47\xd1\x14\xf9\xbd\xe8\xd2\xb2\x0d\xe6\x77\x79\x89\x43\x5b\x72\x77\x18\xb8\xa8\x68\x55\xee\xa7\x78\x5b\x20\xaf\x56\xa1\xc5\x23\x0e\x27\xd0\x53\xb0\x7f\x59\x64\xdd\xd8\x36\xbe\xfe\x38\x0a\xf1\x23\x70\x3c\x80\x8b\xd6\xb3\x3d\x04\x5e\x14\xd8\xc9\x48\xb1\xb9\x1b\x99\x9c\x8b\x44\x15\x8e\x38\x3f\xb5\xda\x93\xd9\xcf\xc8\xd6\xdb\xfd\x10\xf9\xe0\x79\xab\xc5\x22\xcc\x8d\x2c\x64\xc4\x79\xcf\x07\x61\x0b\x4f\x23\x8c\x1f\xd4\x70\x88\x49\x70\x11\x06\xc3\xa0\xef\x87\x29\x0b\x28\x19\xd0\xde\x03\x48\xda\x8e\xed\x98\xfc\x8b\xe4\x41\x4c\xcf\xca\xf2\x9b\x07\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\x83\xa5\x7a\x91\xfd\xb3\x95\x8d\xdd\xb0\x85\x71\x68\xff\x8b\x03\x38\xad\x5e\x57\xab\xd5\x5a\xb5\x5e\x6d\x78\xa8\x7a\x5d\x6d\x56\x5b\xd5\x76\x75\xf5\xec\xd1\x00\x7b\xa8\x5d\x38\xf4\x0a\x0b\x5f\xc7\x67\xc4\x58\xb1\x57\xcc\x21\x18\x96\x2b\x7f\xa0\xff\x7e\xfd\x0a\x31\x7b\x35\x51\x63\x88\x4a\x62\x7a\x7f\x58\xb7\x28\x0a\xe5\x3f\x80\x2a\x19\x0d\xf1\x9f\x85\x8d\x49\x75\x00\x94\x3c\xc6\x38\xbc\x48\x47\xd4\xf4\xc8\xc9\x45\x8a\xc7\x8c\xc9\x16\xca\x62\x91\x62\xb6\xc2\x7e\x34\x20\xf4\x8e\xe9\x0f\x9d\xdc\xe1\x75\x7e\xec\x4f\x41\x00\x38\xec\x57\x76\xf0\xb5\xbb\xcd\x79\x01\x64\x0a\xad\xf6\x85\x83\xbb\x64\xc4\x5a\x20\xb2\x8b\x25\xae\xc1\xbc\xb0\x2e\x96\x2a\xca\x90\x7c\x4a\x87\x6b\x0b\x45\x73\x61\x53\xe1\x8c\xe5\xc2\xa7\xea\xeb\x57\xb4\x83\xaf\x73\xc3\xb7\xcc\x21\xa0\xbe\x9f\xe2\x90\xed\xf9\x2a\x05\x39\x98\xbf\x9b\x90\xa4\x7b\xd8\x6c\xc0\x4f\x18\x37\x94\x28\x13\xd2\xfc\x2e\x7a\xaf\x5b\x14\x97\x22\xb4\x21\xb0\xab\xf1\xf8\x19\xe2\x4d\xdd\x9d\xd2\x0c\x4a\xea\x4c\x89\x06\x76\x5e\x2c\x1c\x09\x19\xd8\x5f\x0c\x86\x65\xf1\x55\x4c\x47\xbe\x08\x75\x90\x91\x98\xbb\x74\x90\x1c\x67\x3c\x46\xe1\x39\x0e\xe0\xc7\x2a\x4b\xa2\xf0\xb3\x3a\x46\xa7\xba\x63\x7f\x32\x45\xf8\x1a\x22\x49\xf6\x02\xbd\x73\xf4\x5e\x95\x94\x31\x6f\x1b\xe8\x7d\x6a\xdf\x16\x24\x45\x41\xfc\x1f\x8e\x40\xe9\x50\x9f\x88\xa4\x21\x86\xad\x16\xf9\x29\xf2\x51\x1a\x4c\x2c\x12\xb7\x2d\x24\xbb\xdc\x5d\x77\x52\x08\x79\x70\x48\x51\xb4\x4e\xd0\x63\xb3\x70\x1a\xf0\xa8\xd8\xe4\x9f\x52\xbd\x89\x96\x51\x29\xa0\x18\xbf\x44\x6b\xe5\xb2\x88\x96\xed\x94\xe2\x29\x1c\xb5\xc7\xaf\x50\x20\xc2\x6d\x7f\x5d\xcf\x9a\x7e\xfb\x96\xb7\x61\x29\x2f\x1a\x2d\x20\xf8\x3b\xb7\x25\x79\x4c\xe9\xe2\xba\xd7\x98\xba\xa3\xdc\x17\xed\xfe\x3a\x32\x07\xbb\x48\xc6\x60\x93\x0a\xc5\x66\xfb\x6a\x5d\x45\xd3\x96\x63\xc5\x0f\x42\xbf\xa7\x9f\x3c\xa4\x03\x40\x51\x76\x4a\x63\x70\x10\x21\x50\x11\x0c\x83\xf4\xbe\xa2\x60\xb6\x38\xc5\xea\x72\x30\x29\xf2\xb9\x68\xe8\x5e\x0b\x6b\x32\xe5\x28\x5b\x5c\x24\x27\x93\xb1\x33\x0c\x8b\xa8\x76\x2a\x60\xf0\x38\xf3\xeb\xb0\x74\xe8\x1f\x90\x7e\xa3\x4e\x48\x3f\x51\xf8\x82\x85\xe0\x15\x51\x6a\x1d\xed\xfb\xe9\xa8\xd2\xc7\xc1\x38\xab\xb9\x82\x16\x88\x48\x64\x3f\xff\x16\xda\x79\x1c\xe6\x48\xc6\xf1\xf7\xae\x76\x9f\xec\xb8\x2b\xd3\x82\x71\xde\x55\x69\x61\xde\x39\x57\x06\x0b\x27\x35\x8a\xab\x1c\xfd\xdc\x3c\x39\x57\x4c\x1a\x61\xe6\xf7\x55\xa7\x49\x1d\xa9\xb7\xf8\x14\x48\x62\xc3\x30\x18\x8f\x79\xd8\x59\xe6\x26\x01\xe7\xad\xf9\x42\x09\x3f\xcc\x85\xb6\x43\xaf\x0c\xca\xe9\xe2\x53\x68\x96\x19\xa4\x42\x84\xf2\x50\xc6\x67\x05\x8e\x60\xcc\x15\xa4\xe6\x3e\x69\xd1\x12\x32\x99\x84\xf6\x23\x96\xcc\x1e\xcc\x03\x15\xf9\x1a\xab\x37\xe4\x93\xf3\x2b\x77\x94\xf9\xf3\x2b\xb4\x4e\xfe\xeb\x48\xa0\x36\x39\xff\x9d\x6c\x33\xd7\x0d\x7f\x80\xdb\x6b\x3d\x3d\xfc\xba\x28\xe6\x27\x5f\x90\xcc\x39\x72\xee\x09\x0a\xdc\xdd\xd1\x56\x4b\xd5\xeb\xd7\xd5\xf6\x6b\xf4\x92\x74\xe1\x77\xd8\xd3\xb7\xb7\xb7\xb7\xcb\xe8\x15\x7d\xf1\xd3\x4f\xa8\x7a\x5d\xab\xc2\x76\x4f\x10\x70\x6c\xf7\xb4\x8b\xa5\xea\x75\xb3\xdd\xaa\x52\x60\x57\x3a\xb0\xab\xa2\xc0\x60\x78\x71\x32\x03\x4f\x9f\x12\xa0\xf1\xf6\x2d\xad\x89\x5e\x21\x18\xe9\xdc\xfa\xac\xee\xca\x3a\xd4\x61\x7f\xf9\x65\x5f\xad\xa3\x6a\xa5\xe5\x2c\x03\x63\xca\x8a\xbe\xa4\xf6\x36\x9c\xda\xca\xe8\x27\x54\x69\xa1\xff\x42\x35\xd4\x41\xcb\xb5\x22\x22\x8a\xc1\x39\x54\x71\xc3\x43\x71\xdf\xef\x8f\x30\xcb\xae\x33\x5f\xe0\x20\x35\xcf\x09\x3d\xc6\xa5\x12\xad\x4a\x8e\x4a\x0a\x92\x64\x37\x91\x06\xc3\x7e\xc5\x44\xab\xae\xa3\xf3\xb8\x44\xcb\x03\x41\xae\xf6\x56\x2d\x7d\xba\xca\x72\xf8\x94\x44\xf9\x0c\x3e\xfa\x8a\xaa\x05\xc3\x9a\x87\xf8\x4a\x72\x76\x82\x5b\x47\xa6\x00\x09\x79\xfa\x9e\x67\xda\x48\xda\x9d\x4f\xd9\xd1\x7e\x9e\x21\x0d\x0e\xfb\x60\x48\x43\xff\xb5\x1b\xd2\xec\xe0\x6b\x53\x13\x60\x03\x47\x0a\xae\x53\xa0\x15\xfa\xbb\x58\xfc\x4d\x5d\x7d\x31\xc2\xd7\x85\x55\x18\x05\x4e\x9e\x0b\x46\xd5\x2c\xd4\xfa\x43\x31\xf2\x11\xbe\x36\x43\x68\xb2\xf1\x93\x8e\xf6\xf3\x13\x09\x59\x03\x67\xde\xf5\x98\x7a\x55\xf8\xe4\x99\x2c\x7a\x8c\xa4\xb3\x6e\x02\x1a\xe1\xeb\xee\xc8\x8f\x0b\xe7\xd9\x4a\xe6\x1e\xe8\x20\x47\x5a\x40\x0f\x72\x57\xf7\x3c\xc4\x71\xec\xd8\x1a\x07\xb0\x04\x48\xb3\x9c\xa9\x7d\x6a\xed\xb2\x8d\xdf\xd9\xaa\x92\x76\xaa\xc3\xfc\xba\x0e\x06\x21\xc0\x7d\x8e\x82\xb0\xb4\xb4\x74\x87\x88\x9b\x12\x85\xd3\xf5\xb6\x88\xa6\x87\xaf\x14\x4a\xb8\xc5\x17\x8c\x43\x78\xfa\xf3\xa5\x26\xbe\xd8\xa8\xcd\xb6\x58\x8f\xc5\x23\x65\xd2\x2a\x8b\x25\x4a\xa1\x75\xf6\xf8\xd1\x85\x3e\xb2\xa3\xcc\x22\xab\xe6\x6a\x91\xd4\x74\x72\xa3\x6c\x0b\xad\xe7\xe4\xc7\xa4\xab\xa5\x01\x9a\x09\xe8\xf4\x6e\x98\xb2\xce\x56\x92\x59\x2f\x49\xe3\x52\xe0\xa1\x7a\xd9\x83\x24\x7c\x99\xca\x82\xac\xa8\xb5\xb2\xcd\x01\x77\xe1\x3d\x4f\x19\xa6\x15\x54\x2f\xea\x3e\xbb\xe7\xa7\x41\x58\x2b\xb6\x69\xb1\xb2\x7c\xdf\x12\x8f\x77\xdb\xba\x58\xf5\x3f\x6f\xf7\x2a\x8a\xc0\x43\xad\xa9\x31\xb4\x67\xdf\xc3\x28\x2e\xff\x51\xdb\x18\x1d\x8e\xef\x78\x27\x93\x10\xa4\x3b\x12\x9d\xba\xca\x30\x8e\x26\xe4\x6d\x37\x1a\x60\xd8\xa4\x8a\x6e\x48\x32\xc0\x7b\xec\x49\x0a\xdd\xde\x7d\x5b\x12\xe4\xb8\xd0\x62\xf8\xae\x37\x27\xb6\x8a\xe8\xfe\x24\x2f\xb7\xe2\x5b\x94\xa8\xb5\xd8\x2e\x25\xaa\x89\x8d\x4a\xbc\x79\xec\xbd\x4a\x6b\x7a\x5e\x2e\xe7\x40\xd2\xa2\x67\xbd\xad\xf4\x19\x41\x6f\xa4\xa5\x80\xaf\x09\x7d\xab\xb2\xeb\x16\x17\xde\xaa\x34\x84\x8b\xee\x54\x9f\x4e\xb6\x97\xd7\x8a\x6d\x54\x9f\xd2\xe1\x9a\xd8\xa6\xd8\xc3\xdd\x36\x29\xda\xe8\x9f\xb7\x47\x15\x6c\xff\xa1\x56\xd6\x2c\x1d\xae\xd9\x37\x28\x32\x8a\x8f\xb9\x3d\xa5\xf1\x4d\x8e\x81\xd1\x00\x93\x23\xfa\xa7\xa3\xdd\x2e\xf7\x74\x2a\xe1\xa4\xef\x4f\x71\x29\x67\xe3\x34\xd9\x32\xea\xfb\x69\x7f\x84\x4a\x66\xfa\x68\x40\x61\x14\x47\x57\x40\xb7\x90\x71\xa5\xb4\xb4\xef\x8f\x87\x51\x3c\xc1\x03\x36\x0d\x03\x3f\xf5\xcd\x14\x74\x8b\x33\x70\x79\x52\xef\xce\xbf\xd9\x5c\x2d\x42\x26\xdf\x35\xf3\x06\x0a\xa3\xac\x3b\x23\xc3\xe2\x8c\x9b\xd5\x71\x19\x03\x28\x5b\xc3\x2c\x64\xd4\x43\x2d\x04\x14\xba\xe2\x70\xca\x85\x03\xd0\x88\x14\xbc\x90\x0b\x13\x0f\x58\x36\x33\xc9\x0b\xdd\x99\x89\x57\xb2\x93\xbd\x91\x52\xa2\x4d\x66\x49\x8a\x7a\x18\x05\x64\x44\x27\x38\x4c\x69\x9e\x35\x1f\xae\xd7\x63\x9c\x0a\x8f\x85\x42\xb9\x7d\xb5\x3c\x9d\xaa\x72\x9f\xe6\x38\xa4\xae\x55\x59\x82\xf8\x2f\x78\x9a\xa2\x59\x38\xe5\x49\x03\xd5\xec\xa0\x92\x4d\x4b\xd5\xc2\x7d\xdf\xb1\x71\x80\x4c\x83\x1b\x62\x14\x84\x97\x98\xeb\x73\x41\x33\x38\xc8\xee\xca\xac\x79\xb4\x91\x5e\x62\x49\xb4\x59\x12\xd3\x34\x42\x41\x9a\x70\xaf\x18\x44\x28\xf8\xbe\x77\x4c\x3d\x2b\xf2\x34\x21\xae\xfb\x92\xa9\x50\xd6\x5d\x66\xde\x87\xc0\x4a\xd9\x66\x33\x00\x19\x38\x99\xa7\xa2\xb6\xb3\xea\x4c\x89\x96\x0f\x37\xfd\xd4\xe7\xc2\x7a\xb5\xa8\xa4\xb9\x31\x18\x24\xd0\x06\xcf\x0b\xee\x18\x69\x46\x0b\xc5\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\xb4\x64\xf2\xfb\x42\xf5\xe6\xef\x8d\xac\x64\x91\x64\xe6\xa6\x7b\x7d\x96\x8e\x4e\x0e\x28\x2a\x0d\x10\x0b\x26\xaa\x82\x92\x7d\x9c\x81\x8c\xe6\xc4\x89\x64\xb4\x26\x31\x65\xc0\x70\x7e\xa4\xb4\x0d\xe8\x9a\x8b\x7c\xb9\x29\x91\x0d\x98\x41\xb4\xaf\xd6\xd5\x24\xe9\x45\x29\x98\xe7\x3a\x4d\x90\x7f\xe9\x07\x63\x88\xd8\x45\xf9\x02\x30\x3b\x37\xd5\x9c\x48\xce\x2a\x41\x78\x19\x7d\xc1\x89\x9e\x64\xb8\xc4\x92\x03\x7b\xe8\x6a\x14\xf4\x47\x56\x56\xdd\xbb\xc9\x61\xd5\x66\xab\x7c\xa1\xf4\xa2\x68\x8c\xfd\xf0\x16\x0d\xa2\xed\xf1\x2c\x19\xa1\x5f\x46\x38\xa5\xf1\x4c\x78\x2e\x5a\x70\xd7\x9a\xfa\x31\x30\x0a\xf6\x2a\xe3\xda\x82\x5d\xdf\x21\x1c\x88\xe0\xf4\x30\xe2\xf7\xdf\xe6\x05\xc0\x4d\x4a\x48\xae\x35\xc3\x53\xe5\xba\xe2\x72\x2c\x08\xc6\x9e\x29\x58\x8d\xb5\x4a\x8b\x2a\x8b\x8f\x0e\xf8\x82\x3a\x13\xb6\x44\x32\xe2\xb6\x68\x4b\xc8\x6b\x6e\x9c\x06\x23\xeb\x52\xab\x90\x8f\x92\xa1\x99\x8b\xee\x79\xf1\x4c\x56\x58\xd7\x52\x32\xe7\x15\xe6\xd0\xb3\xda\xf6\x88\x7e\xdd\x68\x16\xa6\x9c\xbe\x2c\xcc\x84\x00\x0d\x69\x22\xe1\x23\x88\x5b\xbc\xae\xe2\xbf\xa2\x35\xf9\xc6\xe4\x45\xae\x21\x67\x18\x1c\x45\xb3\x70\x80\x66\x53\xea\x50\xd8\x1f\xcf\x06\x58\xa3\x7b\xb3\x9a\x86\x51\x66\xe4\x22\x7f\x28\x1e\xdb\x56\x60\x31\x88\xae\x42\x19\x8f\x28\x1c\xdf\xa0\xe1\x4c\x2c\x4a\x4b\x24\xfd\x95\x15\x34\xc6\x09\x75\xaa\xb4\xcb\x5a\xc0\x37\x62\x3c\xf1\x83\x50\x15\xae\x8a\xf5\x6b\xe2\x5f\x97\x94\x7e\xc1\xc5\x29\x5a\xb6\x65\x66\xf7\xe6\x5f\xa9\x8a\x39\xa7\x9a\x07\xd7\x94\x03\x25\x73\x3c\x94\xd6\x5f\x22\x89\x00\x5d\xf4\x04\xb4\xe1\x24\x27\xf2\x55\xed\x63\x10\x96\xe4\x26\x5f\xa2\xa6\xa7\xd0\x99\xcd\x7c\x92\x67\xf0\xb6\x11\x09\xa1\x3b\x09\x60\xbe\xdb\x16\xe5\xf3\x54\xcd\xc2\x7e\xbf\x95\x47\x40\xbc\x7d\x25\xad\x27\xa7\xd1\x04\xc1\x0c\xc7\xe4\x34\x29\x36\x86\xe5\xec\x80\x00\xce\x90\xf6\x8a\x8c\xbb\xa8\x7b\x90\xe0\x2a\xb6\x5c\xf5\xae\x39\x46\x4a\x0a\xac\x8c\xe1\xc3\x94\x9b\x45\x15\xee\x2b\xb3\x30\x3d\x19\x96\x3c\xa2\x16\x34\x14\x4e\x86\x96\xd7\xe5\x99\x9e\x4f\x95\x3c\xb6\x68\x1e\xb6\x6e\x85\x93\x8a\xbf\x27\x37\x7d\x5f\x63\xb7\xc2\x59\x28\x73\x9d\xbc\xee\x69\xe5\xe6\xd8\x0d\xff\x24\x93\xb7\x73\x63\x43\xcc\x30\xb1\xce\x58\xae\xc5\x9b\xca\xc3\xc4\x49\xd3\x91\x89\x9e\x9f\xc1\x47\x7e\x02\x19\x72\x9d\x27\xee\xb9\xa9\xc8\x33\x76\x2d\xfb\x40\xd1\x49\x67\xd0\x69\xd8\x35\x9c\xa0\x28\x94\x8e\xc2\xb5\x36\x2a\xb5\x6a\x75\xb0\x64\x2d\x5b\x8e\xc5\x3b\xb4\x32\x3f\x06\x8b\x47\xfb\x79\xf8\x41\xa2\xbe\xe6\x65\x20\xcb\x0d\x98\x9a\xe7\x6a\x46\x07\x61\x81\x9c\xe4\x77\x8d\x6e\x47\x1a\x42\x34\x44\xf2\xbc\x20\x77\x85\x6d\x48\xc4\x1c\x28\xa1\xdb\x8e\x77\x36\xea\xad\xb6\xdd\x49\x2c\x2f\xd5\xf5\x9d\x23\xac\xf1\xd8\x6a\xc5\xc3\xac\x1d\x63\x11\xde\xc3\xad\x21\x30\xd5\x10\x73\x2c\xb1\x33\x4d\x0a\x5f\x38\x0f\xaf\x32\x61\xf4\xf2\x10\x2a\x12\x40\x58\x56\xf1\xa8\x25\x1c\x2b\x09\x40\x2b\xcc\xcb\x94\x1a\xf4\xbd\x99\x0d\x87\x65\x63\xe6\x1b\xf2\xd1\x62\x63\xfd\x69\x3a\x00\x96\x21\x0f\x36\x4d\xcb\x5f\x3c\x63\x9f\x33\x82\x30\x05\xae\xc7\x11\x2e\xec\x42\x44\x59\x11\xf3\x1f\x9a\xbb\xbc\x17\x98\xf3\x19\xe0\x55\x5a\x62\x48\xd9\x74\x29\x6a\xc9\xf9\xaa\x13\x5a\x50\x26\x14\x65\x0c\x1c\xeb\xd1\xa1\x91\x60\x0a\x1b\x15\x82\x85\x3c\xd8\xf8\x12\x21\x9d\xe0\x6b\x03\x25\x9d\x63\x4d\xf1\xf7\xc1\x7c\x27\xb6\x59\x92\x9b\x44\xe0\xe2\x64\x90\xe8\x63\x04\x28\xfb\x29\xcd\x17\xcf\x6a\x66\x31\x43\x51\x90\x20\x3c\x1c\xe2\x7e\x1a\x5c\xe2\xf1\x0d\xf2\xd1\x00\x27\x69\x3c\x83\x67\x0f\xe4\xf4\xe5\x28\xec\xe3\x42\x51\x46\x0b\x52\xa8\x92\xe8\x01\x50\xca\x02\x72\x43\x89\xc5\x35\x17\x64\x10\x1e\x68\x67\x40\xeb\x9c\x1c\x45\x32\x21\x87\x5a\xc2\x51\x3a\x8f\xd0\x73\xaa\xcd\xa7\x7a\x5e\x74\x21\xba\xdf\xb6\x8c\xaf\x79\x20\xca\x07\x83\xe6\xad\x95\x79\x02\xfc\x02\x9c\x55\x1a\x21\xce\x64\xb7\xa5\x79\xb0\x2e\x1e\x52\xde\xb5\x78\xa4\xe4\x77\xad\x5a\x7d\xa5\x51\x2f\x26\xe6\x27\x4c\xe3\xa3\xc4\xbf\xf7\xd9\xa4\x2d\x89\xc0\x49\x41\x98\xe2\x78\x28\x59\x0b\x23\xe7\xaa\xe0\xfc\x95\x75\x9d\x53\x2d\xdd\x6e\x59\x7c\x44\x1f\x8d\xf0\x78\x8a\x63\x22\xfe\x14\x58\x04\xdb\x0c\x37\xe6\x1b\xac\xa3\xfc\x0d\xee\xf1\xa8\xcc\xa4\x3b\x55\xd0\xae\x56\xce\x69\xaf\x76\xa0\x4b\x25\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\x65\xb8\x54\x29\x7c\xf1\x63\xa3\x95\x9e\x08\x4b\xde\xd9\xdf\xe8\x3e\x3c\x3d\x11\x11\x9a\x07\xa5\x20\x2d\x30\xba\xfa\x4b\xd0\xd4\xce\xc4\xef\x17\xa2\xab\x89\xdf\xbf\x0f\x6d\x89\xea\xf7\xa2\xaf\x2f\xd8\xae\x42\x92\xe8\xab\x7b\x0e\x68\x91\x79\xa0\x44\x46\x1b\xa1\x75\x17\x23\xb6\xdc\xe3\xaf\xd0\x24\xcd\xf1\x61\x20\xd8\x80\x13\x03\xfb\x91\x79\x31\xf0\x4c\x2d\x10\xd2\x77\xdf\x4f\x47\x34\xac\xef\x33\xfe\x9e\x0d\xf3\x9b\x2c\xd2\xef\xed\x99\xd7\x6a\x7e\xaf\xe1\x7d\x19\x32\x25\x1e\x8e\xb8\xfc\xe0\xf1\x7e\x39\xe4\x45\xe3\xfe\x0a\x0c\xe5\xf8\xbf\xae\xa0\xbf\xe2\x3b\x04\xff\xb5\x05\xd0\x35\xaf\x28\x78\xd4\xd8\x6c\xca\x24\x02\x90\xa2\xc1\x4a\xef\x73\xc2\xd3\x28\xb5\x25\x17\x18\x57\x18\xd9\x76\xb3\x98\x89\x16\x2b\xcb\x8d\xb4\xc4\xe3\xdd\xcc\xb4\x58\xf5\x3f\xcf\x4e\xab\x28\x02\x0f\xc5\x29\x7b\xd0\x9e\xdd\x54\x8b\xe2\xf2\x37\xb0\x25\x36\xca\x4f\xfc\xa9\x10\x0e\x27\xfe\x74\xf1\xd8\x0b\x16\x17\x71\x13\x84\xcb\x2a\x93\x8e\xf9\x5d\x0d\x96\xd1\xab\x75\xd4\x70\xdb\x2c\xdf\xa4\xb8\x66\x31\x5a\xa6\x7f\x2e\xd3\x65\xfa\xe7\x34\x60\xe6\x80\xeb\x19\xe0\x52\x80\x5e\xa1\x5a\xd9\x62\x13\xcd\xbf\x14\xb1\x8c\xe6\x80\x1b\x1a\xe0\xba\x13\x70\xdd\x0a\xd8\x0e\x39\x8d\x83\xe9\x18\xae\x5e\x4a\x74\x58\xde\xbe\x05\xbf\x89\xaf\xf4\xb9\x4e\x9e\xd7\xc8\x23\xa0\x60\x83\x22\xa6\xe2\x33\x9d\x8a\xd2\x67\xf4\x96\xb4\xfe\xe3\x8f\x08\xb0\xf9\x8c\x5e\xa2\x6a\x65\xb5\x25\xcd\x50\xf9\x0d\xfa\x9c\x13\xee\x42\x9a\x7b\x6a\x0b\x3e\xf1\xa7\x60\x33\xbb\x91\x96\x4a\x1c\x61\xe8\x74\x1b\xbd\x44\xa5\x06\x5a\x46\x9f\xcb\xac\xa7\x8d\xa1\xd5\xdb\xc9\x88\xcf\x60\x2a\x2e\x06\x03\x9e\xee\xdb\xa4\x46\xf6\x81\xa0\x84\xd6\x91\x84\x4e\xdb\x70\x26\x81\xd8\x7a\x59\x71\xbb\x71\xf0\x28\x18\x63\x54\x92\xfb\xc9\xc2\x05\xb8\x62\x8d\x58\x87\x45\x6e\x66\xf1\x3e\x33\xce\x2a\x43\xbd\x87\x9d\xbc\xc2\x93\xef\x6e\x67\x29\x58\xed\x42\x8c\xfe\xbb\x36\xb5\x64\x3b\x04\xb5\xeb\x91\xb7\x92\xe2\xe6\x96\xa2\xd6\x82\x9b\x83\xa8\x27\x0c\xe5\xc5\x1b\x61\x28\x3f\x9f\xef\x1b\x25\x62\x7c\x89\xe3\x04\xef\x4b\x05\xb3\x57\xb6\xb8\x66\x3f\x64\x9f\x9d\xd4\x9d\x0b\xd4\xb6\x05\xf0\x3f\x9d\xff\x10\xf6\x43\x56\x28\xeb\x60\x2e\xa7\x51\x1b\x3e\xe5\x0b\x9b\xd9\xe6\x7f\x2e\x9f\xa1\x75\xf4\xb9\x58\xac\x4e\x0b\x4b\xd9\xbd\x08\xa3\x18\x7f\x33\xae\x22\x81\xdc\x0d\x07\xe0\xe7\x9c\x4d\x77\x40\xde\x1c\x0c\xe7\xf1\x0c\xa9\x1d\x0a\xe3\x87\xf5\x75\xb4\x5c\x9b\xc3\x93\x64\x0a\x93\x6b\xdf\x89\x11\x5b\x45\x82\x58\xa4\xbd\x4c\xf0\x5e\x14\x4d\xb3\x25\xe1\xe9\x38\x78\xd2\x8c\x2a\x22\x87\x76\xe3\xe9\x4f\x3b\x68\x69\xe3\x5d\x77\x73\x6b\xfb\xfd\xce\xee\x3f\x3f\xec\xed\x7f\x3c\x38\xfc\xbf\x47\xc7\x27\x9f\x7e\xfe\xe5\xd7\x7f\xfd\x8f\xdf\xeb\x0f\xf0\xf0\x62\x14\x7c\xfe\x32\x9e\x84\xd1\xf4\xdf\x71\x92\xce\x2e\xaf\xae\x6f\x7e\xaf\xd6\xea\x8d\x66\xab\xbd\xba\xf6\xfa\xd5\xca\x3a\x8b\x70\x2b\x8e\x76\x62\xd1\x2e\x8c\x6a\x36\xc4\x0e\xaf\x94\xcc\x72\x43\xb1\x30\xb5\x89\x42\x5a\x3b\x36\x37\x15\x32\xd3\x81\x63\xbf\x61\x8e\x5d\x09\x11\x92\xa4\xe5\x91\x51\x93\xec\xc0\x82\x96\x51\xad\x7c\x06\xde\x2b\x99\xc0\x54\x37\x89\x8b\x03\xad\x17\x01\x5a\x3e\xe3\x1b\xbc\x2c\x86\x59\xa0\x52\x81\x28\x54\x22\xf7\x7c\x25\xc2\x0c\xa0\xff\x95\xb6\x28\xfb\xd6\x84\xf9\xc1\x7b\x10\x1b\xe2\x57\xaf\x94\x0f\x82\x6c\xc5\x0f\x46\x91\x46\x6c\x49\x6b\x58\x84\xdb\x2c\x77\x8f\x7e\xc8\x97\xf6\x88\x37\xce\xcc\x3e\xad\xa7\xa3\xff\xd3\xd1\x5f\x1c\xfd\x3f\x9d\x6c\x2f\xd7\xda\xe8\xdd\x56\x61\x07\xad\x5a\xfb\xdd\x96\xec\xa3\x55\x6b\xab\x4f\xf0\xf5\xee\x4e\x5b\x14\x99\x3f\xd7\x71\xab\x20\x0e\x0f\xe8\xbc\x55\x6b\x3b\xbd\xb7\x6a\xed\xbf\x81\x46\xa0\xf8\x61\x1d\x06\xe3\x3e\x67\x75\xbb\xbf\x3f\x58\x46\x45\x03\x7c\x18\x05\x61\xea\x72\x32\xae\xb5\x1d\x4e\xc6\xd6\xc3\x74\x86\xa9\xdb\xcb\x58\x34\x59\xd4\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\xcc\xd1\xb8\x06\xb2\x8f\xc0\x50\x75\x33\x26\x22\x50\xb6\x58\xea\x64\xb1\x68\x41\xd8\xdc\x14\xee\x92\x72\xb4\xd1\x79\x59\x3c\x14\x06\x23\xcb\xbd\x02\x7b\x98\xb4\x4f\xed\xdd\x7b\x9f\xda\xfb\x0e\xf6\xa9\x22\x38\x3c\xf4\x3e\x65\x5d\x4e\x7b\x5b\x4f\xdb\x94\xf8\x7b\xb0\x6d\x2a\xb9\xf2\xa7\x5b\xe1\x20\xf0\xc3\xd2\xa2\x3b\x96\xed\x48\xfe\xfd\x6f\x59\x7b\x8f\xb3\x65\x15\x59\x26\xdf\xff\x96\xb5\xb7\xa5\x6d\x5a\x4f\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\x57\xab\xe4\xff\xe1\x62\x85\x7e\x24\xdd\x67\x5f\xe9\xb7\x6c\xf9\xcf\x53\x17\x00\x61\xb9\xb5\x05\xed\x7b\x69\x0b\x58\x8e\xda\x6f\xa9\x34\xf0\x90\xf4\x2a\x19\xf9\x35\xed\xd5\x68\xe2\xf7\x1f\x51\xb5\xe0\x21\xde\x2c\xfc\x82\xd6\xfe\x0e\xea\x06\x23\x5f\xec\x1d\x54\x11\x8a\x11\x8b\xf4\x65\x7f\xb3\x05\x35\xc1\xe4\x66\x7f\xb3\x65\x93\xf1\xc0\xc4\xf9\x0b\xbe\xa1\x59\xb0\xa9\x1d\xac\xe8\x2b\x38\xff\xfa\x61\xca\x93\x78\x47\xf1\x84\xda\x68\x6f\xfd\x7c\x78\x0e\x9b\xee\x49\xf4\x01\x67\xc2\x20\xba\xba\xba\xaa\x44\x53\x1c\x26\xc9\xb8\x12\xc5\x17\x2b\x83\xa8\x9f\xac\x40\x12\xee\x68\x45\xab\x33\x4a\x27\x63\x8b\x22\x64\xeb\x72\xfa\x61\x73\x3b\x43\x5b\x3c\x17\x0c\x86\x30\xdf\x07\x44\xdb\xe3\x0c\xef\x17\x96\xf2\x1c\xf6\x28\x32\x30\x09\x79\x08\x42\xee\xf6\x22\x85\x7b\xce\x5c\x5d\x9a\xa8\x54\xab\xaf\x29\x9e\x2e\x06\x7c\x87\x91\x9a\x1c\x16\x43\x4f\x90\xb2\xbf\xd9\x9a\x87\x6d\x90\x32\x5b\x64\x3d\x48\xb5\xf4\x21\x8d\xd0\x94\x5a\x9d\xca\xde\x39\x8e\x1d\xce\xf0\x8b\xd1\x76\x07\x36\x3c\x1d\x54\xab\xaf\x81\x09\xa9\xf2\x95\x76\x0e\x30\xd7\xbe\x64\xf8\x28\x6d\xdf\xde\xd9\xed\xc6\x41\xb4\x8f\xed\x87\x83\xa5\x46\x1f\xc0\xcc\xfa\xcb\x60\x68\x78\xdf\x50\x9a\x9f\x93\xa2\x69\x7e\xc5\x3f\xb2\xb9\x5a\xd3\xf2\xf9\xdd\x15\x8c\xa7\x4e\x63\xb5\x5a\xd5\x01\x2f\xe8\x1d\x34\xd7\xef\xa7\x98\xbc\xbb\x09\x29\xfc\x09\x8d\x10\xaa\x80\x44\xd8\x3e\x64\x60\x25\x8b\xf6\x2e\x56\xfa\xbc\x2e\x8d\x05\x60\x03\x94\x53\x39\xf1\xc7\x29\xda\x80\x7f\x16\x17\x8b\x81\xba\x28\x79\x3f\x04\x79\x61\xb2\x79\x7c\x19\x0c\x2b\xd4\x2d\x02\x97\x78\x67\x3c\xc0\x2f\x27\x6f\x0d\x14\x57\xf2\x3b\xaa\x35\x17\x12\x78\xd5\x29\xb6\x88\xb7\x64\xa5\x33\xee\x61\xd6\x16\x5e\x6a\x84\x3c\x98\x89\x72\xb6\x3a\xac\xb0\x5c\x6e\x61\x10\x5a\x80\x0e\xf1\x07\x18\x1b\x5b\x4a\xb4\x45\xce\xc8\x19\x30\xe1\x13\x2c\xde\x38\x8f\xcb\x7c\x8f\xa1\x3d\x62\x4f\x96\x72\x12\x13\xa7\x45\xb3\x17\x16\x2c\xdf\xb3\x8d\x89\x80\x57\x3f\x32\x63\x16\x0d\x57\x6e\xd0\xf2\x96\xe3\x63\x3d\x0a\x10\x31\x0e\x3c\x07\x9c\x17\xcc\xaa\xcb\x12\x2d\x3b\xff\x5a\x19\xc9\xc1\x18\x32\x27\x10\x06\x85\x13\x9b\x64\x14\x6c\xd0\xab\xda\xbc\xf0\xa7\x33\x4b\x10\x9a\x10\x03\x67\x7e\x56\x0e\x4a\x35\x7a\x50\x92\x06\x3a\x37\xed\x8f\x86\xbd\x40\xd6\x39\x0a\x36\x8c\x2d\x43\x65\xbe\x93\xc8\x8a\xc5\x8c\xb1\xb6\xa1\x8d\xb2\x54\x4b\xd2\xd1\x70\xfa\xb3\x44\xbb\x10\x01\xe6\x78\xbd\xa2\x36\xd7\x85\x78\xb0\xec\x77\x7c\x27\xde\xbb\x20\xdf\x7d\x40\xef\x5b\x8b\x5f\x99\xd4\x9b\xe2\xdc\x5c\xaa\xa4\x68\x37\xa4\xf7\x2a\x77\xcf\x3e\x20\x85\xab\x8b\x4d\x9b\xee\xd7\x2e\xce\xbe\x58\x35\x0f\x39\xc4\x86\xfb\x80\xc9\x15\x1b\x84\x0a\x39\x93\xf5\x5d\x7b\x8e\xe9\xc2\xc2\x86\x5d\x95\x58\xc0\x71\x25\x7f\xbf\xbb\x7d\x93\x73\x7c\xa7\xd0\xec\x67\x77\x8f\x1f\x3e\x3b\xad\x35\x8f\x1f\x49\x3b\xab\xab\xe4\x4c\xbf\xfa\x97\x3e\xd3\xf7\x83\xe9\x08\xc7\xcb\x8f\x6c\x22\x00\xa7\x77\xb9\xa9\x3f\xe7\x10\x6f\x66\xee\x7c\x90\xd3\x7c\x17\x3a\x76\x48\x38\x4e\x22\x0e\xed\xf2\x4b\xb7\x09\x81\x78\xaf\x65\xc2\x50\x6a\x90\x33\x9c\x9f\x42\x25\xfa\x93\x33\x62\x56\x71\x1b\x5e\xa6\x2c\xaa\x02\x2d\xb2\x40\x3a\x0d\x72\xba\xa1\x73\x93\xe2\xeb\x94\x9c\x22\x7d\xf6\x8c\xa6\xb4\x4f\xcc\x37\x8b\xa7\xda\xf0\x07\xb8\x1f\x4c\xfc\xf1\xf8\x86\xa5\x01\x1d\x14\xbe\xb9\x91\x47\xe5\x96\xb5\xc2\x06\xee\x44\xa0\xa1\x36\xbb\x78\x32\x8e\xbb\xe0\xf7\xa8\xe9\x39\xb2\x29\x91\x6e\x75\xe4\xce\x2f\x76\xb1\xa3\xd4\x74\x38\x6a\xc9\x65\x2a\xd9\xec\x66\x09\x24\x76\xf0\xf5\x1d\x33\x41\x58\x86\x57\x22\x1f\xf9\xbe\x61\xc1\xe9\xd4\x6e\x1e\x82\x70\x3a\x4b\xef\x33\xa7\x9c\x3c\x54\xa2\xbb\x03\x9d\x3d\x14\x71\xf4\x35\x46\x61\xa1\x8f\x3b\x27\x95\x80\xd1\xb2\x87\xb0\xc9\x26\x67\x1d\x65\x6d\xd0\x0a\x6f\xac\xd4\xd3\x55\xa8\x87\x6b\x04\x32\x40\x1d\x19\xe8\xad\x5d\x37\xef\xde\x69\xb3\xee\x6a\xbb\xad\xb4\x41\x74\x5a\x75\x4f\x53\x9e\xaf\x3d\x99\xda\xfd\xdd\x75\xdf\xae\xdd\xd1\x88\x64\x9e\xa7\x09\x37\x0f\x29\xe0\x00\x2c\x34\xae\xd6\x44\x54\xa4\xc4\xba\xec\xa8\xfa\x30\x09\xe9\xc1\xe5\x75\x2e\xc7\x2b\xac\x24\x2e\xa8\x8a\x22\xb2\x3a\x38\x2f\xe3\x7e\x8c\xd3\x07\x52\x2a\x11\xf9\x77\xc7\x1e\x38\x08\x7a\xc9\xd8\x84\xcd\x13\x99\x3a\xfa\x16\xd5\x18\xca\xce\xc1\x8e\x00\xc1\x56\x9d\x91\xd0\x17\x51\x1f\x05\xf1\xa8\x7b\xb8\xe7\x78\xbb\x3d\x64\x7c\x59\x38\x30\xcd\x09\x2f\x4b\x0f\x55\x52\x74\x59\x7d\x9c\xec\x86\xf8\x39\x8a\x29\xda\xd1\x77\x52\x5c\x4c\xd6\xf5\xbc\xc8\x98\x5a\x25\xae\x2f\xd0\x61\xd9\xa3\x64\x6e\x8c\xc7\xd1\x15\xf2\xe3\x5e\x90\xc6\x7e\x7c\x83\x98\x7a\xe9\x0b\xbe\xb1\xc4\x1d\xfc\x22\x6b\x24\x7e\xb2\x36\x9c\x33\x50\xba\xba\xa5\xd8\x68\xcd\x71\x86\x24\x28\xe5\xb8\x41\x42\xfc\x37\xd0\x6d\x44\x31\x0a\xc2\x10\xc7\x10\x7d\x36\x9a\xa5\x20\x40\xe8\x51\xf8\x20\x66\x22\xd5\x31\x52\x32\x64\x0f\xb4\x15\x23\x20\x1d\xd7\xf8\xc9\x35\x02\x4b\x8d\x45\x48\x20\x92\xb4\x92\x51\x9e\x3e\x32\x90\x0a\x06\x52\x41\xa3\xb1\x5f\x0f\x8e\x60\x3e\xe9\x35\xe0\xd4\x1f\xa0\x7e\x14\x26\xa9\x1f\xea\xcd\x5b\x93\x48\xa9\x73\xec\x56\xac\x09\xbc\x4f\x83\x33\xf4\xdb\x3a\xaa\x5e\xb7\xfa\xf4\x7f\x36\x77\x18\xa3\x70\xa3\x4d\xff\x97\xaf\x19\x8b\x34\x9d\x58\xa0\x3d\xdb\x28\xf2\x4f\x88\x43\x06\x3b\xd0\x63\x44\x21\x13\x4c\xfc\x41\x22\x91\xe5\xe4\x2b\xb3\x31\x63\xcb\x40\x42\xa7\x6d\x7c\xdc\xa1\x27\x55\xf5\xc5\xd9\x82\xb9\x5b\x04\x32\x18\xe6\xef\x26\xfe\xd8\xfe\x46\x97\x45\x1f\x03\xbc\x02\x58\x62\xb9\x91\x50\x16\x9c\xf2\x22\x81\xc8\x8c\xd2\x0f\x1f\x8c\x4c\x26\x09\xde\xca\xdc\xe0\x63\x8f\x15\x3d\x0c\x86\xfa\x3f\x3d\x7a\xd8\x1c\x31\x75\x11\x11\x91\xf0\xd0\x8c\x86\xe6\x46\x10\x73\xd7\x98\x1b\x45\xcc\x5d\xf5\x91\x22\x89\xdd\x9f\xdb\x75\xa9\x7a\x1a\xc6\xdb\xb2\x1f\x13\xe9\x62\xc7\x1e\x1c\x2d\x37\xe0\x58\x2e\xc7\x94\xc7\x4a\x03\x9a\x49\x28\x5c\xd2\xe0\x97\x4c\x02\x95\xb2\x33\xe4\xd8\xc4\xef\xdb\x2f\x89\xc4\xc1\xdf\x61\x04\xf7\xfa\x2f\xad\x30\xbf\x6e\x37\x97\x2d\xaf\xc7\x41\x6f\x99\xa0\x32\x00\xdb\xd6\x44\xfb\x8a\xc3\xfe\x32\xd8\x34\x5a\xde\x53\x37\x4b\xed\xc3\x64\xd0\x9a\x6f\x7c\x97\x8c\xfc\x7a\x4b\x07\x49\x5e\xd6\x75\x70\xc9\xc8\x6f\xd5\xea\xe6\xcb\xc6\x9a\xa5\x64\x43\x7b\x15\x07\x53\x3c\x19\xd4\xda\x55\xab\xed\x9f\xf2\x6a\xda\xfb\x32\x18\xea\xed\xe0\xcb\xe9\x97\xc1\x30\xef\xde\x41\xed\x7a\x34\xc0\xcb\xfd\x61\xcf\xfa\x3a\x8d\x1d\xaf\x97\x2f\xc6\xfe\x60\xe2\x87\xb6\xcf\x91\x1d\x18\xee\xeb\xaf\xa7\xfe\x60\xd9\x0f\x93\xe0\xfa\x75\x5d\x1f\x04\xf2\x29\x48\xa2\x5a\xb5\x56\xd7\x47\x9c\x7d\x7a\xbd\xfa\x7a\x55\x9f\x21\xf2\xe9\x77\x1c\x47\xcc\xf5\xda\xf2\x35\x74\x7c\xa3\x3a\xb2\xe5\x11\xbe\xd6\x3e\xf8\x58\x27\x2e\x1a\x77\x63\x60\xbc\x8f\xfb\xfa\xe4\xc6\x7e\xaf\x17\xa4\xd6\x97\xcb\x63\x7c\xe1\xf7\x6f\x1e\xfb\x0e\x48\xac\x1e\x78\xd2\x17\x0d\xbc\xcc\xd6\x8a\x78\x64\x4b\x04\x9e\xc9\xca\xd0\xcc\x42\xd9\x3a\x10\xbf\xeb\x4d\xf1\x9b\x50\x3d\xff\x4d\x88\x5d\xfc\xa6\xbf\x32\xd2\xce\xec\x4b\xe1\x17\x23\x64\x8a\x01\xa5\x5f\xe3\x0e\x8b\xa2\xc3\xa9\x55\x7a\x4a\x63\xf5\x49\xd0\x66\xf6\x36\x52\x6a\x10\x4a\xa4\xcd\xca\x04\x28\xde\x08\xba\x93\xdf\x50\x72\x13\x6f\x64\x2a\x13\x2f\x43\xf5\x95\x44\x53\xf0\x4c\x48\x09\x7e\x64\x14\x44\x47\xa5\xcf\x06\x8a\xd1\x8b\xf4\x9b\x93\xc9\xa2\x8a\x48\x45\x01\x29\xf3\xda\xc5\x15\x93\xee\x50\x6c\xac\x4b\x9d\x56\xcd\xcb\xd7\x26\x7b\x2a\x5d\x75\x5a\x4d\x4f\x21\xbc\x4e\xab\xe5\x65\x13\xdf\x69\xb5\x3d\x75\xf4\x3a\xad\x55\xfd\x46\x58\x27\xe5\x4e\xbb\xea\x31\x6a\xed\xb4\x01\x1f\x41\x29\x9d\x76\xdd\x93\x69\xa5\xd3\x6e\x7a\x36\x6a\xe9\xb4\x1b\x9e\x4c\x21\x9d\x76\xcb\x93\xe9\xa7\xd3\x06\xbc\x14\x9a\xe9\xb4\x57\x3d\x9d\x6a\x3a\xed\x35\x4f\xa7\x9b\x4e\xfb\xb5\x67\x10\x49\x67\xb5\xea\x59\xc8\xa9\xb3\x0a\xf8\xb3\x25\xd1\x59\x05\xec\x19\x69\x74\x56\x9b\x9e\x41\x1c\x9d\x55\x40\x9c\x90\x51\x67\x15\x70\xce\xd6\x59\x67\xb5\x2d\x5f\xa0\x7b\xd9\x92\xed\xac\xf2\xab\x75\xb2\x98\x3b\xab\xaf\x3d\xbe\x54\x3b\x6b\x55\x2f\x5b\xc2\x9d\xb5\x9a\x97\x2d\xee\xce\x1a\xa0\x93\x51\x70\x67\x0d\x1a\x17\x8c\xa6\xb3\xd6\xbc\x3d\xf3\xda\xd5\xa7\xcb\x83\x3f\xff\xf2\xa0\x3b\xc2\xfd\x2f\xa4\x53\xb0\x52\xa8\x1b\x10\x4d\x73\x96\xcc\xa6\x64\x60\x30\x8b\x4f\x2d\xf5\x1b\xe4\x78\x1a\xd2\x1c\xfd\xb0\x8e\x96\x38\xe4\x25\x8b\x45\x88\x70\xd2\x78\xc0\xeb\x8a\x5c\x73\x7c\xd1\xce\x11\x1e\xe2\x18\xc3\x41\x2f\x0e\x2e\xe0\x4c\x16\x84\x41\x9a\x81\x49\x66\x53\x1c\x83\xea\x7a\x5d\x4b\xcf\x21\x41\xd9\x98\x5d\x4c\x70\x98\x6a\x05\x50\x1a\xa1\x91\x1f\x0e\xc6\x58\x19\x37\x19\x76\xcf\x0a\x59\xb1\xa9\x81\xaa\xa6\x3b\xa0\xa4\xfb\xa6\xb1\xe4\xa9\x09\x54\x10\xa6\x6b\x92\x86\x7e\x28\xd7\x17\x8a\x09\x75\x76\xcc\x63\x7e\x56\x83\x2a\xe1\x3f\x11\xa8\xf0\x42\xc6\x46\x39\x44\x58\x11\x8b\x68\xfa\x2f\x80\x74\x19\xe0\x2b\x17\x8a\xce\xe6\x25\x84\x77\x39\x0a\xe8\xeb\x57\xb5\x3c\x27\x38\xc0\x12\x74\xc6\xbc\xfa\x0f\x64\xcd\x09\xdb\x11\x58\x74\x76\xe0\x46\xd5\xb2\xd1\x8a\x13\xab\x5a\xdb\x8e\x96\xbb\xa5\xc5\x6a\xec\x86\x69\xa3\xbe\x68\x13\x8b\xd5\xd8\x1e\x47\xfe\x5d\xaa\xb4\x9b\xf0\x3e\x2b\x7f\x47\x52\xaa\x50\x0a\xf6\x90\xfc\xea\x26\xc5\x07\x90\x1c\xc8\x78\x6d\xcb\xbb\xac\xd0\xdf\x0e\x5d\x74\x59\x5b\x45\x56\x44\x56\x7a\x31\x15\x42\x06\xed\x9d\xc0\x0d\xad\xdb\x71\xb6\x68\x16\xb6\xae\x59\xf6\xd5\x9b\xd4\x66\xfc\xbc\x90\xbb\xa0\x0d\x95\x45\xf2\x69\x67\xf5\x4f\x83\xb3\x3b\x25\xcf\xce\xcc\xb9\x83\xdf\x31\x55\xd5\x66\x8e\xa3\x6a\x51\xc1\x58\xb3\xd4\x16\x1e\x62\x6e\x84\xb6\x8e\x28\xf3\x6d\xcd\x7a\x46\x46\x93\xbc\x26\xf0\x50\x48\xa4\x3e\x99\x99\x9b\xed\xfa\xd3\xe9\xf8\x86\x35\xec\xc7\x17\x33\xc2\xc2\x93\x3c\x7f\x45\xc6\xaf\x2b\xd3\x38\x4a\x23\x82\xa3\xcc\xb9\xf3\x0c\x27\xf4\xdd\xc7\xae\x60\x69\xd7\x9e\x64\x9d\x3f\x47\xd6\x81\x80\xd1\x7f\x42\x5c\x22\x6b\x4e\xa5\x02\x26\x12\xb0\xc5\xd2\x7b\x3c\x94\x66\xba\x75\x52\xe5\x84\x31\x0b\xa9\x24\x55\x5d\x6a\x37\x7f\x36\x49\xcf\xc5\x57\xda\x4d\x3b\x17\x39\x21\x6c\x62\x9d\x0e\x5f\xc5\xef\x25\xf4\x47\x12\x84\x2c\x18\x2b\x61\x19\xd5\xeb\x5a\x95\xfd\x95\xd1\x57\x35\x8d\x2f\x5b\x5e\xa5\xb2\xd5\x42\x7d\x7f\xb3\xa5\x59\x53\xd8\x0c\x40\x74\xaf\x49\xb4\xce\x46\xd5\x62\x00\xc2\xd3\xde\xe4\xde\x8e\x65\x9a\x60\x7b\xae\xe2\x53\x93\x93\x56\xaf\xdb\xab\xcd\x56\xbd\x51\xad\x79\xa8\x7a\x8d\x87\xfd\x81\xdf\x5b\x7b\x6d\xc9\xab\x58\xbd\x7e\xbd\xd6\xf3\x07\xfd\x21\xf6\x60\x60\x1a\xf5\x56\x73\xb5\xad\x96\x3b\x73\xde\x88\x69\x69\xf4\xe4\x5e\xec\x8b\x4c\x7a\xb6\xbd\xeb\xca\x9f\x22\x0c\xee\xd5\xf3\xf7\x90\x5a\xdb\xbd\x63\xb8\xaf\xaf\xf9\x6c\x50\x24\xce\x09\x3c\x9e\x5e\x10\x05\x8e\x08\xbc\xfb\xe7\x52\xe9\xfd\x53\xfe\x70\x66\x73\x09\x91\x3e\x13\x82\x33\x0b\x90\xbf\x52\xa9\x24\xc1\xa4\x9e\xe2\xe8\x2b\x92\x5f\xc2\x5e\xd7\x2c\x6b\x3e\xe2\xe8\x6b\x41\x80\xf5\x66\xd9\x02\x10\x42\x19\x2b\x2e\xe9\x26\xb8\xfb\x19\x87\xec\x28\x37\x14\xf6\xeb\x7e\x65\x48\xab\x48\x1a\x53\xf4\x0a\x55\x75\xf1\x41\x29\x5d\xd3\x4a\xd7\x72\x4b\xd7\xb5\xd2\xf5\xdc\xd2\x0d\xad\x74\x23\xb7\x74\x53\x2b\xdd\xcc\x2d\xdd\xd2\x4a\xb7\x72\x4b\xb7\xb5\xd2\xed\xdc\xd2\xab\x5a\xe9\xd5\xdc\xd2\x6b\x5a\xe9\xb5\xdc\xd2\xaf\xb5\xd2\xaf\xf3\x67\xa7\xaa\xcd\xce\x9c\xc9\xac\x69\xc5\xf3\x67\xb3\x56\xd7\x8a\xe7\x4f\x67\xad\xa1\x15\xcf\x9f\xcf\x5a\x53\x2b\x9e\x3f\xa1\xb5\x96\x56\xbc\x65\x70\x83\x95\x15\xc2\x90\xbf\x04\xe1\x05\xa9\x1a\xf8\xe3\x9e\x4d\x6c\xf6\xc9\x36\x70\x6a\x1d\xa8\x1e\x7c\xb2\x0e\x4a\x1f\x3e\x59\x07\x60\x00\x9f\x1a\x36\x74\xba\xd9\x1d\xb4\xfa\x8d\x20\xb1\xbd\x5d\xf2\x3d\xd4\xf3\x50\xdf\x43\x03\x4f\x5a\xa0\x1e\x42\xab\x1e\xd9\x42\xab\x67\x3a\x6f\x18\xd0\x7a\x03\x0f\x89\xaa\xd9\x08\x79\x08\xd5\xea\x1e\x3a\x39\xad\x19\xf5\xfa\xb4\x1e\x6d\x89\x56\xcd\x16\x2d\xa9\xb7\x4a\xea\xd5\x8d\x7a\x3d\x5a\x4f\x20\xe9\x4b\xf5\x1a\x1e\x42\x75\x68\xaf\x61\xd4\xcb\xeb\x5f\x53\xf4\xaf\xb9\x50\xff\x5a\xa2\x7f\xad\x85\xfa\xd7\x16\xfd\x6b\x2f\xd4\xbf\x55\xd1\xbf\xd5\x85\xfa\xb7\x26\xfa\xb7\xb6\x50\xff\x5e\x8b\xfe\xbd\x5e\xa8\x7f\xb5\xaa\xc7\xfa\x57\x33\x09\x26\xaf\x83\xb5\x9a\xc7\x3a\x58\x33\x29\x26\xaf\x87\x04\x4b\xda\xc3\x9a\x49\x32\xb9\x24\xda\xf0\x38\x89\x9a\x34\x93\xdb\xc7\xa6\xe8\xa3\x49\x34\xb9\x7d\x6c\x89\x3e\x02\xd5\x98\x9d\x7c\xff\xde\xd1\x49\x0f\xa1\x16\xed\xa4\x49\x37\x03\x5a\xd1\xda\x49\x42\x6f\xaf\x69\x45\x93\x70\xfa\xb4\xa2\xbd\x93\x35\x0f\x91\x8e\x9e\x9c\xd6\x4c\xca\xe9\xd1\x8a\xd6\x4e\x12\x8e\x51\xaf\x42\x45\x93\x74\xf2\xfa\xd8\x12\x7d\xac\xdb\x79\x8d\xab\x8f\x84\xe6\x68\x1f\xeb\x76\x66\xe3\xec\x63\x8b\xf7\xb1\x6e\xe7\x36\xae\x3e\x36\x45\x1f\xeb\x76\x76\xe3\xea\xe3\xeb\xac\x8f\x76\x7e\xe3\xec\x63\x53\xf4\xd1\xce\x70\x5c\x7d\x24\x8c\x91\xf5\xd1\xce\x71\x5c\x7d\x5c\xcb\xfa\x68\x67\x39\x4e\x5a\x6d\x78\xbc\x8f\x76\x9e\xe3\xea\x63\x5d\xd0\x6a\xdd\xce\x74\x5c\x7d\x5c\x15\x7d\x6c\xd8\x99\x8e\xab\x8f\x64\xf9\xd3\x3e\x36\x6a\xf6\x05\xb9\xb3\xe3\x26\xd6\x26\xe0\xda\xb0\x73\x9d\x9d\x1d\x7b\x27\xc9\xb0\x92\xb5\x75\x72\xda\xb0\x73\x9d\x9d\x9d\x9c\x05\xd9\x86\x8a\x76\xae\xb3\xb3\xe3\xe8\x64\xd3\x43\xf5\x06\x54\x34\x49\x27\xaf\x8f\xb5\xac\x8f\x76\xa6\xe3\xea\x63\x33\xeb\xa3\x9d\xe9\xb8\xfa\x08\x13\x49\xfb\x68\x67\x3a\xce\x3e\x56\x45\x1f\xed\x4c\xc7\xd9\xc7\x86\xc7\xfa\xd8\xb4\x33\x1d\x57\x1f\xab\xa2\x8f\x4d\x3b\xd3\x71\xf5\xb1\x21\xfa\xd8\xb4\x33\x1d\x57\x1f\x09\x2b\xa7\x7d\x6c\xda\x99\x8e\xab\x8f\xaf\xc5\x3c\x36\xed\x4c\xc7\xd5\x47\xb2\x3c\x58\x1f\xed\x4c\xc7\x49\xab\x2d\x4e\xab\x4d\x3b\xd3\x71\xf5\xb1\x9e\xf5\x71\xd5\xbe\x20\x77\x77\xdd\x82\x6a\x9b\x76\xd2\xce\x75\x76\x77\xed\x9d\x04\x9a\x03\x1e\xd0\xb4\x73\x9d\xdd\xdd\x1c\x31\xa0\x05\x22\xa0\x9d\xeb\xec\xee\xda\x3b\x49\x78\x47\x1d\x86\xb5\x65\x17\x75\x5c\x7d\x24\xf3\x41\xfb\xd8\xb2\x33\x1d\x57\x1f\x1b\xa2\x8f\x2d\x3b\xd3\x71\xf6\xb1\x2a\xfa\x68\x67\x3a\xae\x3e\xd6\xb2\x3e\xda\x99\x8e\xab\x8f\x6b\x62\x1e\x5b\x76\xa6\xe3\xea\x23\xd0\x1c\xed\xa3\x9d\xe9\xb8\xfa\x08\x22\x39\xed\xa3\x9d\xe9\x38\xfb\xd8\xf0\x78\x1f\xed\x4c\xc7\xd5\xc7\xa6\xe8\x63\xdb\xce\x74\x9c\x7d\xac\xf1\x3e\xb6\xed\x4c\xc7\xd5\xc7\xba\xe8\x63\xdb\xce\x74\x5c\x7d\x7c\x2d\xe6\xb1\xdd\x30\x17\x24\x5c\xa3\xa4\x38\x9e\xe0\x41\xe0\xa7\xcc\xa9\x0c\xdc\x15\xd4\x72\xe4\x88\x8b\xd6\x51\x09\xfe\x7d\x85\x7c\x5d\xc3\x4a\xcb\xd4\x58\x99\x1a\x29\xd3\xb3\x97\xa9\xb3\x32\x75\x52\xa6\x6f\x2f\xd3\x60\x65\x1a\xa4\xcc\xc0\xd0\xe6\x6a\xaa\xca\x6d\x8b\xa5\xee\x82\x01\x6d\x21\x53\xba\xc8\xa6\xeb\xa7\xbe\xed\x60\xee\xa7\xbe\x08\xe5\xe3\xa7\xbe\x5b\x39\x16\xbe\x0b\xd2\xe4\x24\x4a\xfd\xb1\x80\x19\x6e\xfa\xa9\x4f\x3d\x48\x5e\xa2\x35\x0b\x74\xa8\xb3\x87\x87\x29\x87\x2e\x3c\x4e\xa0\xbc\xd1\x19\x67\xca\x2b\x81\xe6\x69\x06\xf2\xa7\x9f\x7e\x42\x2d\xb8\x78\xab\x5e\xaf\x55\xb3\xfb\xb6\xac\xc4\x3f\x50\xa3\x6e\x10\x87\xda\x97\x1d\xb4\x8e\x40\xed\x3e\x1c\x47\x51\x5c\x92\x3a\xb9\xa2\xe8\xde\x5d\x9d\x83\xb2\x7b\x68\x5d\x7a\xd2\x17\x8e\x40\xbd\x54\x2a\x65\xb8\xbd\x42\xed\x26\xcd\x97\xf6\x1a\x82\x89\x36\xcb\x54\x61\x63\xd7\xcf\xf2\xaa\x0c\xe7\x4c\x39\x2b\xbf\x2d\xae\x9d\x35\xc1\x31\xd5\xac\x0e\x6e\x9e\x6e\xd6\xe0\x12\x8b\x74\xb6\x59\xa4\xb3\x7b\xd6\xce\xee\xdd\xb5\xb3\x7b\xd6\xce\xee\x15\xed\xac\xd9\x5b\xd9\x89\xaa\x24\xba\xcf\x83\x4d\x41\x4e\x3d\xbb\xff\x20\x18\xbc\x53\x37\x06\xf0\x51\xb4\x79\x52\xe5\xe6\x95\x9f\xe3\x0d\xa9\xe8\xbc\x2d\xe4\xbb\xc3\x0c\xe3\x9d\xde\x6f\x0b\xdd\x7b\x38\xae\xb8\x50\xde\xf5\xbf\xc0\x04\xae\x30\x76\x4e\xed\x77\x17\x3b\xec\x96\xac\x54\xda\x51\xae\x25\x76\x16\xbe\x8f\xa0\xb4\xb0\xa3\xdc\x45\xec\x38\x2f\x21\xe6\xdf\x38\x1c\xb1\xdc\xc0\x30\x87\x2c\x02\xcf\x00\xc6\x54\x2d\x5a\x20\x59\x39\xb8\x21\xe4\xb2\x7a\x50\xb0\x82\x53\xa6\xb8\xa1\x83\xc7\xec\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\xc4\x43\xea\x15\x1a\xf0\x49\xb4\x8e\x7c\xf4\x0a\x95\x4a\x3d\xf4\x23\xdd\x1c\x4b\xff\x4b\x7e\x0e\xca\x84\x0d\x5c\xa3\x57\x28\x95\xda\x13\x01\x8b\x43\x32\x4d\x09\x5d\xa9\x34\x4e\x79\xa3\x8e\x96\x51\x52\x86\x6a\x3d\xcd\xe8\x4d\x60\xa5\x9d\xff\x8b\x61\x05\xdb\x71\xa9\x8f\x7e\x44\xff\xfb\x38\x58\x69\x87\xa0\xb9\x58\xf5\xd0\x6f\xa8\x8f\x7e\x23\x88\x3d\x3c\x32\x9a\x00\x38\x17\x19\x82\x48\xa9\x87\xbe\x3e\xf0\xe0\xc8\xb7\xd5\xc7\xae\x34\xe9\x73\x13\xef\x17\x09\xb2\xc6\xfd\xc4\x34\x17\x45\x58\x0d\x26\x18\x87\xb3\x98\xa3\xf4\x5d\xc3\x9a\xb1\x75\x29\x8c\x5c\xf6\x37\x5b\x16\xdf\xaf\xfc\xf2\xa6\xc3\x57\x16\x5f\x4c\xb9\xcc\x57\x33\xf2\xef\x6f\xb6\xac\x26\x03\xce\x49\x98\x93\xab\xfe\xa1\xa6\xe0\x4e\xa1\x1d\xe6\x4f\x9c\xec\xe5\xf7\x10\x13\x47\x9d\xca\xc4\x44\xec\x4c\xfc\x3e\x99\x0c\x25\x33\xbc\x39\x1f\xac\x98\x39\x27\x59\x36\x7b\x3a\x2f\xb9\x19\xd8\x59\x64\x6b\x87\x05\x54\xfd\x2f\xed\x62\xf6\xf7\x8f\xc9\x46\x17\xdb\x4b\x16\x67\x08\x6d\x63\x3c\xe8\xf9\xfd\x2f\x2c\xae\xe6\x24\x1a\xc0\x92\x22\x34\x23\xe6\x1b\x5e\x76\xb7\xdf\x11\x11\xc8\x22\x1e\x80\x99\x13\x7c\x55\xac\xe5\xc0\xc2\x85\xb6\xb2\x4f\x00\x30\x63\x1e\xb1\xea\xbb\xdb\xef\x2a\x5b\x21\x8d\x55\x0e\x06\x54\xdb\xef\x2c\x06\x3f\x53\x87\xb9\x0c\x33\x33\xcc\x31\x99\x71\x8b\xa6\x2c\x04\x15\x17\x48\xe8\xa3\xed\x9e\x59\x0a\xe5\x41\x0b\xc9\xa1\x3c\xd4\xf2\x3c\x46\xf9\x07\x7c\x93\xa4\x31\xf6\x27\x1b\xe1\x80\xf5\xce\x62\x1d\x19\x31\xb3\x58\x01\xce\x63\x0d\xd8\x84\xec\x23\x3c\xc1\x10\x64\x1c\x8c\x31\xe9\x3c\xb1\x58\x99\xe0\x3f\x1f\xe2\xeb\x94\xbe\xb6\x8b\xef\xf8\xf2\x1d\x8b\x99\x0a\xad\x57\x92\x71\xd0\xc7\x25\x8e\x82\xb8\xa9\x17\xb8\xd8\xec\x27\x95\x59\xdb\xc4\x7f\x97\x59\xbb\xc7\xe8\x82\xe1\xf0\x28\x48\x16\x1e\xdb\x6f\x46\x37\x27\x59\x87\x7a\xb8\x1f\x4d\x98\xd7\x3d\x21\x88\x20\x9a\x25\xc5\x48\x46\x74\xb1\x90\x38\x9e\xd3\x9b\xd2\xdc\x2e\x68\xbe\x11\xe6\x81\x0d\xce\x7b\x97\x59\xb0\x96\xcb\x37\xaa\xd1\xb8\x1c\x8e\x99\x36\x9f\x7d\x86\xcc\xae\x97\xd6\x23\x8d\x28\x8d\xd6\x51\x70\xc9\xa6\xb0\xea\x58\x89\xd1\x25\x46\xbb\x3f\xc3\xf9\x33\x99\xf5\x12\xfc\xef\x19\x0e\xd3\x9c\xd3\x33\xe0\x2b\x1c\x18\xe6\x1a\x40\xeb\xf8\x68\x13\x62\x4e\x02\xf9\x63\x54\x8e\xe9\x40\x43\xc1\x92\x00\xe2\x21\xb5\x2b\x2b\x2b\x88\xcd\x48\xf6\xce\x9a\x2d\x37\x3f\x6a\x0c\x35\x3d\xcf\x2c\x04\x21\x12\x8c\x68\x14\xce\xd1\x06\xbd\x30\x2c\xb8\x38\xb1\xfd\x2e\xcf\xe0\x9a\x6f\x3a\x8b\xc4\xa9\x6b\x37\x9e\x84\x8f\xef\x5d\xf8\x40\xff\x3d\x8d\x71\x82\xe3\x4b\x4c\xc5\x90\x68\x46\x44\x79\x49\xfc\x00\x35\x86\x9f\x06\xbd\x31\xe3\xc0\x68\x33\x46\xef\xe2\xc0\x0f\xd1\x7b\xea\x9e\x89\x86\xc1\x18\xe3\xb0\x5f\xe9\x03\x08\x1e\xf2\x19\x22\x60\x6b\xf4\x73\x72\x04\x45\xfe\xe9\x87\x68\x27\x9e\xf5\x6e\xd0\xe7\x11\xf9\xa7\x72\x85\x7b\xff\x7d\x31\xf1\x83\x71\xa5\x1f\x4d\xec\xf2\xce\xc9\x11\x6f\x2e\x47\xec\x91\x0b\x15\x96\x7e\x9e\x65\xf9\x5e\xc2\x3e\x39\x28\xd0\x94\x49\xcf\x9f\x3d\x23\x83\x0e\xa4\x27\xd2\x21\x81\x92\x88\x2a\x85\xca\x30\xeb\xf4\xd7\x1f\x68\x65\x25\xba\xc4\xf1\x70\x1c\x5d\x91\x3a\xb0\xf1\xd5\x78\x3a\x50\x52\xaf\xd6\x2e\xff\x48\xca\xbe\x11\x9f\xeb\xf2\xe7\x35\xfd\x6b\x83\xed\x61\xac\x31\xc0\x13\x50\x21\x60\x45\xbb\x2b\x2b\x88\x37\x8b\x7a\x35\x52\x04\x50\x86\xa6\xab\x6f\x44\x95\x7a\x56\x45\x94\x79\x06\x08\xd0\x42\xb4\x54\x43\x2d\xc5\x8a\x3d\x03\x54\x58\xb9\x5b\xf8\x2f\x21\x48\xb9\xc4\xab\x57\xbd\x86\xf4\x1d\xfe\xc3\xcb\xd0\x22\xaf\x5e\xf5\xea\x6f\x9e\xbb\x0b\xbc\x7a\xd5\xab\xb1\xef\xe4\xbf\xd0\x71\xde\x28\x3c\xbc\x5a\x87\x9e\xbf\x7d\xcb\xf2\x41\xca\xaf\xeb\x54\x05\xa8\xbc\x65\x08\x99\x2d\x89\x6a\xd5\xeb\x6a\x8d\x69\xfd\xb2\xa2\x8c\xeb\x91\x42\xe4\xe5\xad\x4e\x1d\x6c\x79\x94\xfa\xf4\x5f\x95\x46\xd8\x4b\x7a\x83\xc4\x49\x29\x7b\x59\x66\x04\x23\x4d\xc1\xca\x0a\x22\xbb\x04\xdc\xc4\xa0\x40\x5a\x48\x74\xf1\x18\x2b\x6d\x29\x41\x00\x2f\x41\x51\x38\xbe\xa1\xcb\x71\xf3\x97\x83\xa3\x4d\xf4\x19\xbd\x45\x6b\x00\x93\x37\x58\xb3\x61\x41\xef\xe2\xd4\xce\xb2\x6f\xbc\xbf\x7c\x2d\x29\x67\x01\xb1\xae\x2a\x8e\xd7\x7f\xa2\xcc\xb9\xa8\xc8\x69\x14\xd7\x64\x18\xb3\x55\xc6\x13\x45\xb3\x7c\xc0\x0c\xd4\xf3\x24\x1e\xe4\x96\x7a\x40\x68\xb0\x37\x92\x2f\x03\xa1\x3b\xc8\x41\x68\xbe\x2c\xc4\xa5\x03\x42\xd8\x26\xcd\x53\x56\xf4\x4c\x17\x8d\xd8\x67\x09\x57\x55\xf5\xbc\x88\x50\x84\x1c\x82\x11\xba\x9b\x70\x84\x16\x14\x90\x90\x2a\xcf\x99\x87\xae\x8c\xee\xe5\xb3\x97\x58\x1a\x6f\x34\xc9\x4a\x14\x97\x04\x2c\xa7\x88\x25\x15\x5e\x40\xd2\x6a\x3e\x49\x5a\xdf\xbb\xa4\xe5\x90\xaf\x1c\xea\x9d\x93\xa3\x7c\x39\x67\x51\xf5\x8e\x85\xa5\xeb\xbc\xfc\x89\x89\xff\xfd\x98\x78\xee\x69\xf6\x11\x58\xf6\x6e\xd8\x8f\x31\x44\x6e\x60\xc0\x35\x90\x4c\x0e\xc9\x26\x77\x19\x51\x63\x1a\xc7\x17\xb8\x2d\xff\x8a\xaa\x7f\xa9\xcd\xa1\xe8\xae\x30\xff\xbc\x4d\xca\x2c\xb0\x0b\xb4\x9e\x76\x81\xbf\xc4\x2e\xb0\x35\xc6\xfd\x34\x8e\xc2\xa0\x8f\xba\xd1\x00\xf7\xa2\x68\xbe\xc2\x7f\xab\x9b\xa7\xf0\xa7\x5f\x17\xda\x11\xb6\xba\xaa\xc2\x9f\x3c\x3f\xd4\x0e\x20\xb3\x76\x95\x81\xa8\xf5\xf2\xb4\x98\x04\x1f\x65\x21\x3d\x16\x7e\x03\x7c\x27\xfc\x78\xea\xa5\xee\x7c\xbd\x19\x94\x59\x60\x1d\xff\xb5\x93\x23\xff\xe7\xac\xe3\x83\x59\x3a\x9d\xa5\xc5\x2f\xed\x0e\x72\x2f\xed\x0e\x16\xbf\xb4\xd3\xa5\xba\x03\xed\x12\xef\xe0\xcf\xbd\x0e\x7a\x74\xa9\xce\xd4\xcd\x8b\x37\x0f\x2b\xd9\xe5\x34\xf4\xbd\x48\x77\x7f\xa7\x13\xf6\x81\x76\xad\xe9\x12\xa2\x0e\x0a\x5c\x5a\x1c\x2c\x78\x69\xf1\x94\xc5\xee\xaf\xc1\x7c\x37\x3e\x1e\xef\xa2\x5f\x2b\xaf\xeb\x0d\x6e\x20\x8e\x92\x94\x2c\xef\x8b\x1b\x83\xfb\x4e\xfd\x41\x65\x23\x4c\x82\x5f\x49\x69\x91\x0b\x6e\xea\x0f\x64\xf6\x37\xf0\x53\x5f\xba\x08\x75\x5d\x80\x26\xea\x0d\x28\xa9\x75\x9c\x19\xfc\x2a\x06\xc0\x6f\xd4\xa2\x3d\x3d\xad\x48\xcf\x95\x50\x04\x88\x62\x16\xa6\xa2\x67\x5a\x30\x2b\xb0\xc5\x3b\xa4\xdf\x0c\x60\xf4\xc5\xb2\x8a\xd9\x3f\xb4\xef\x46\x6b\x34\xa6\xcd\xd8\x4f\x68\xe4\x2c\x34\x8d\x92\x40\xf5\xc0\x27\x8d\x92\xef\xa4\xfe\x61\xc4\x3b\x2b\x5a\x78\xa5\x61\xb4\x8c\x6a\x5a\x23\x87\xfe\x20\x7b\x86\x81\x12\xd9\x46\xd4\xd7\x94\x95\xc8\x6d\x65\x21\xb5\xd4\x46\xb2\x90\x5a\x72\x69\x5b\x70\x2d\xd5\x32\xfb\x95\x06\x88\xdb\x21\x72\x0b\xdc\x59\x68\x21\x0e\x9d\x22\xde\xe3\x54\x4a\x38\xaf\x4c\x15\x55\xe0\x8b\xd1\xcc\x9f\x39\xa9\xcf\x25\x15\xcd\x65\x72\xfc\x65\x7d\xcf\x2e\x82\x24\x14\xd8\xbe\x62\x78\x48\x68\x60\x1c\xbd\x7d\xfe\xec\xd6\xca\x37\xf9\x72\xb9\x7e\x5d\x6f\x2c\xc4\x3b\xef\x97\x98\xec\x89\x77\x7e\x2b\xde\xb9\x7b\x7c\x80\x20\x24\x6e\x31\xd6\xb9\xcb\x02\xe8\xde\x97\x75\xfe\xe9\xec\x30\x5b\x12\x73\xf8\xa1\x85\x55\xd1\x74\x00\xf6\x08\x74\x95\xd8\x0f\x07\xd1\xa4\x64\x70\xc0\x72\xb9\xa2\x49\x4a\xf9\x70\x58\xea\xb0\x53\x83\xcb\xd5\x9b\x67\x1e\x01\xf7\xc4\xa8\x74\x46\xc5\x89\x73\x21\x46\xf5\xd7\xce\xbc\xf0\x1f\xc5\xa8\x56\x76\xb7\xba\xe8\xf5\xea\xeb\xd5\xe5\x1a\x62\xb4\x81\xf6\x71\x3a\x8a\x06\xa8\xee\xe2\x56\x10\xda\xfb\xae\xdc\x6a\x63\x30\xa0\xfe\x83\xea\x82\x28\xc0\x05\xf8\xea\x25\xb5\xe9\x1f\x5f\xb4\x4a\x03\xff\x83\xe3\x08\x72\x87\xa5\x23\x8c\x62\x9c\x48\x7c\x51\xe9\x08\x29\xc7\x7a\x4c\x9e\x0d\xbc\xef\xc4\x0b\xd8\x42\xfc\x9d\xe1\xa0\xae\x46\x67\xf3\x00\x9a\xc2\xb3\x2f\xec\x28\xc4\x68\x12\xc5\x98\x0a\x8f\xcb\xcb\xd0\x37\xd7\x28\xf2\xf5\xbe\xbc\x5c\x70\x81\xc3\x7c\x2e\xb2\xc0\x57\xef\x17\xe5\xfc\x69\x81\x7f\xb3\x53\x1c\x0a\xa3\x68\x5a\x4c\x0c\xf9\xc8\xc9\xd1\xb9\xb2\x05\xb1\xbb\xd7\x44\x56\x24\x8f\xe6\x44\x53\x0b\x11\xdd\xfd\xc2\xcd\x3e\x11\xdd\xb7\x22\xba\xff\x91\x98\x5f\x3e\xc9\x49\x3c\xf0\x4f\x14\x7e\x0b\x1f\x9c\xe5\xf3\xad\x21\x00\x97\x4a\xf9\x22\x70\x19\x7d\xfd\xaa\xbf\xba\xd3\x16\x63\xef\xf1\xfc\xb8\x02\x2b\x2b\xe8\x13\x81\xaf\xd6\x0b\x8c\x48\x01\xa0\x59\x10\x65\xae\x46\xc1\x18\xa3\xd2\x0f\xa5\xcc\xd7\x3a\x8b\xc1\x0d\x1e\x87\x46\xcc\x6d\x61\xc2\x69\x28\x32\x03\xb1\x25\x21\x55\x45\xa9\x3b\x76\x43\x3c\xde\x22\xbb\x97\x44\x41\x0b\xf1\x92\xbf\xb6\xe3\x96\x25\x47\x17\x4d\x92\xf5\xb8\x7c\x25\xcb\x84\x04\xad\xfd\xf9\x79\x3e\x1e\x37\x49\x78\xb1\x98\xd8\x46\xcc\x6b\xf1\xe5\x78\x67\xa3\x96\xc5\x7a\x26\x4f\xd2\x47\x33\x11\xb8\xcd\x41\xf4\xd0\x4f\x12\xb2\x90\x97\x09\x6a\x03\xf4\x01\xdf\xa0\x4d\x1c\x07\x97\x34\x27\xe4\x36\x1f\x94\x7a\x7e\xcc\xe9\xc3\x77\x1f\x36\xb7\xeb\x59\x6b\xe2\xb9\x60\xe2\xf1\x6e\x14\x0e\x83\x8b\x19\xcb\x44\x19\x41\x56\xc8\x24\x2f\xbf\x64\x1c\x4d\x71\x9c\xde\xa0\x3f\xe8\xb1\x18\xbc\x49\x81\xf9\x9e\x8c\x68\x8e\xe3\x84\x3c\x04\x21\x4b\x17\x90\x46\xc2\x97\xa6\x82\x36\xf1\xd0\x9f\x8d\xd3\x0e\x6a\xa2\x52\xad\xbe\x06\x89\x94\xcb\x2e\xf8\x8e\x84\xe6\x38\xe6\x89\xcc\x33\x70\x64\xfc\xe7\xa1\x19\xa4\x2c\x79\x66\x02\xa0\xb2\x43\xbd\xf4\x21\x8d\xd0\x14\xc7\xc3\x28\x9e\x48\xc0\x15\xc8\x52\xfa\xc7\xfe\xf0\xa2\xe3\x1a\x65\x44\x2f\xbe\x8e\x21\xe6\x4c\xad\xbe\xb6\xd2\xa8\x6b\x21\xb8\x69\x57\x28\xea\xda\xa7\x0c\x21\xa5\xf1\xdb\x72\x5e\x42\xd2\xbc\x04\xf2\x64\x56\x06\x19\x69\xf1\xf5\x36\x3f\x8b\xe8\x01\xf0\xb9\x5b\xd2\x55\x39\x63\x28\x19\xbf\xbe\x8d\x6e\xb8\xbf\xd9\x30\x8a\xe1\x14\x93\x35\xfa\x00\x89\x41\xbf\x0c\x86\x46\xd2\x78\x4a\xed\xfc\xf4\xa8\x98\x61\x2d\x52\xf1\x8f\x6c\xb2\xd6\x68\xfa\xc9\x7b\x83\xf1\xd4\x69\xac\x56\xab\x3a\xe0\x9c\xec\xf5\xfd\xe1\x85\xdd\xf0\x82\x4c\xc4\xba\xf8\xc9\x09\x8f\x14\x77\x05\xc3\x30\xd7\x3b\x5c\x57\x50\x0f\xba\xa2\x2c\xe8\x2e\xf9\x66\xa7\x0c\x36\x50\x0b\x7f\xa8\x14\xac\x9c\xf8\xe3\x14\x6d\xc0\x3f\x8b\x27\xa2\xe5\x6e\x34\x92\x5f\xfb\x7d\xc8\x8e\x26\x52\x1f\x0c\x2b\x2c\x2a\x49\x89\x77\xc6\x03\xfc\x9c\x93\xca\x8a\xcb\xf3\xaa\xd5\x5c\x28\xb7\x8b\x3a\xf5\x56\x03\xc2\x20\x75\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\x6e\x38\xc0\xd7\xb6\x1a\xa7\xd5\x6b\xa6\x00\xb2\x44\xeb\x9c\x13\xa2\x4b\xa0\x22\x84\x65\xf1\xc6\x99\xbf\x3e\xc3\x86\x57\xca\xde\x38\x2b\xf1\x2d\x6f\x9d\xcc\x4a\x85\x3d\xd9\x8c\x30\xb2\xad\x85\x16\xcd\x5e\xcc\x31\xb2\x50\x3f\x32\x41\x5d\xeb\x20\x8f\x8b\xf4\x96\xe3\x63\x35\x2e\x10\x9d\x64\x79\x8e\x79\xb2\x6c\xa0\xc0\x2c\x8d\x6f\xd6\x6b\x7d\xce\x10\xcb\xe8\x9d\xa5\x06\x36\xbf\xcf\xcf\xc6\x00\xf0\x95\x21\xb6\x8e\xae\x59\x5c\x64\x31\xca\x5e\xb1\x8e\x3b\x10\xd9\x15\x63\x6c\x07\x1d\xc8\xd1\xec\x18\x58\x0b\x16\x8a\x2d\x47\x8d\xda\x72\x48\xd3\xe7\x34\xe6\x40\xc0\xcf\x95\x26\x60\xf4\xc4\x48\xcb\x1f\x6d\x63\x5d\x64\xbc\xd1\xbc\x50\x50\xb6\xce\xf2\xd1\x97\xdf\xd9\x03\x56\x49\x4d\xfc\x7a\x70\xa4\x76\x07\x5c\xa7\x2c\x1e\xd7\xc6\xb8\x7d\xa6\x36\x30\x9f\xb9\x0d\x8c\x34\x9b\x6f\xd0\xe7\x9c\xd1\x23\x7f\x59\x8d\xd3\xcf\x60\x0e\x63\x74\xe4\xf4\xb3\x6e\x16\xc3\xff\x6e\xcd\xd7\x7a\xc0\x29\xf2\x27\x31\x07\xa6\x9b\x86\x46\x6d\x53\xa2\x31\x89\xd3\xea\xd9\xab\x57\xf9\x26\x45\x12\x70\xe9\xe8\xcb\xf9\x86\x25\x88\x19\xdb\xcb\xb2\x7a\x79\x06\x94\xf2\x31\xe2\x5e\x1b\x7a\x91\x60\x33\xb9\x1b\xf9\x82\x9b\xf8\x43\x89\x96\x41\x62\x4b\xb7\x3f\x3f\x7a\x8d\x45\x34\x78\x80\x20\x36\x54\x44\x10\x92\x21\x15\x0a\x5d\x62\xc2\x62\xd5\x3c\xe4\x90\x4d\xef\x03\x26\x57\x36\xcd\x82\xec\x88\xa3\xa4\x4b\x80\xf1\x90\x2e\xa8\xb2\x61\x57\xc5\x62\x52\x68\x8e\xf0\x74\x9b\x67\x8b\x46\xa1\xd9\x03\xf5\xe8\x29\x74\x79\x4e\xd8\xdb\x33\x6f\xf5\xaf\xed\x43\xbf\x40\x5a\xf7\xf9\xc9\xd1\x1f\x57\x77\xe4\x4c\xaf\xed\xca\x7a\xfd\x77\xd0\x2e\x1d\x83\x71\x66\x97\x1b\xef\x52\x25\x92\xfc\x32\x4f\x8f\x24\xf0\x38\xc2\xb3\xc4\xef\x8d\x31\x0b\x07\x26\xa1\x73\x8c\xe4\x54\x8b\x14\x8a\xfe\xe6\x3d\x52\x33\xac\x49\xdb\xc2\x11\x64\x53\x46\xcc\xd0\x96\xd9\x18\x9b\x9a\x24\x51\x1e\x62\xac\x04\x09\xf2\x11\x4d\xc0\x8c\x2e\x71\x9c\x40\xd4\xb2\x91\x9f\xa2\x10\x5f\x8c\x71\x3f\xc5\x03\xc2\x86\xfb\x2c\xa5\x6a\xca\x14\x3e\x69\x84\xc6\x41\x9a\x8e\xf1\x32\x0d\x70\x59\x51\x81\xe2\x38\x8e\x62\x34\x88\x70\x12\x2e\xa5\xc8\x1f\x0e\x71\x9f\xd6\xa5\x48\x2d\x25\x28\xc1\xfd\x59\x1c\xa4\x37\x9e\xa8\xd8\x9b\xa5\x28\x48\xa1\x12\xaf\x11\xa4\x89\x08\xa8\x10\x8c\x83\x94\x39\x71\xd3\xbc\xae\x01\xe1\xcf\x13\x1c\xd2\xfd\x20\xb1\x29\xca\xe8\x80\xec\xd1\xce\x09\x75\x99\xf6\x56\x9e\xbf\xbb\x26\x6d\xcb\x3f\xa4\x7c\x90\xcd\xa0\x9d\x07\x8c\xcc\x7a\x1b\x4e\x0d\x97\x79\xa7\x85\x80\x9d\xd0\xc8\xee\x85\x9d\xe7\xb4\x5f\x45\xbb\xe4\x97\x25\x71\xdc\x87\xd3\xea\x99\x87\x4a\x1f\x4e\x1b\x67\x2c\x58\x00\xfa\x4a\x1e\xd9\x55\x40\xad\x5d\xb6\x24\x91\xfb\x70\x5a\xa3\x95\xaa\x6a\xa5\x46\x7e\xa5\x3a\xad\x54\x53\x2b\x55\xf3\x2b\x35\x68\xa5\xba\x5a\xa9\x26\x2a\xa9\x75\x6c\xd9\x91\x8c\x21\xe3\x5e\x86\xae\x41\xeb\x8a\x41\xeb\xda\x07\xcd\xc4\x47\x1a\x2e\xd6\x27\x7a\x61\x32\x1c\xf2\xb4\x83\x14\x69\x1a\x64\xb5\x5a\x25\x5f\x6c\xfd\x35\x27\xa2\xa1\x42\xae\x59\x21\xd7\x0b\x41\xae\x3a\x07\x5e\x82\xa1\x41\x6e\x14\x82\x5c\x73\xcd\x8e\x27\xc1\xd0\x20\x57\x35\xc8\xf3\x27\xb2\xeb\xc7\xf1\x0d\xea\xe9\xe9\x54\xe9\x54\xf5\x68\xfc\x0b\x53\x93\x91\xd2\xc9\x27\xac\x27\xb9\x49\x52\x3c\x41\xc3\x68\x16\xa3\x34\x98\xe8\x73\xbf\x60\x50\xde\x10\x5f\xa7\xc7\x64\xf5\xb9\xe3\xc7\x5a\x22\xde\xee\x47\x83\x60\x78\x43\x39\x21\xa5\xc3\x02\x58\xac\xb9\xb1\xe8\x9e\x52\xc7\x81\x5f\x4f\x21\xe5\x25\x44\x5b\x31\x32\xc5\xd9\x92\xe4\xfe\x8c\x12\x9c\xce\xa6\xea\x87\x1c\x8f\x8e\xf9\x87\xfd\xdd\x9f\xa9\x6b\x47\xde\x09\x7f\xf7\xe7\xf3\x2a\x5a\x47\xbb\x3f\x9b\xa9\xd1\xa4\x22\x35\x5a\xa4\x66\x8d\x66\x2c\x2f\x69\x98\xca\x64\xd6\xbb\xc4\x44\x54\x70\x1d\xfd\xab\x34\xf8\x31\xb4\x4d\xa3\x1f\x7f\x45\xf4\xc9\x15\xfd\x58\x2e\xce\xc2\x1c\x8b\xf2\xd9\x75\xa8\x3d\xcc\xb1\x68\xb6\x2e\x9a\xad\x29\xcd\xd6\xe6\x35\x5b\x53\x9b\xad\x2d\xd6\x2c\x84\xd1\x09\xaa\x7c\x09\x12\x20\x41\x5d\x5d\x81\xae\xaa\x0d\xa8\x5a\xe7\x8b\x19\xaa\x56\xd5\x65\xea\x98\x11\x46\xd6\x79\xac\x15\x01\xb5\x56\xe9\xb9\x5e\x8f\xed\x4f\x3f\xd6\xe8\xc7\x9a\xf5\x63\x9d\x7e\xac\x5b\x3f\x36\xe8\xc7\x86\xf5\x63\x33\xaf\xcd\x56\x5e\x9b\xed\xbc\x36\x57\x45\x9b\x39\x1a\xa9\x42\x9c\x07\x2d\xce\x7d\x50\x31\x0e\x84\x4c\x25\x85\xec\x47\xf4\x20\xc9\x5d\x9d\xca\x6b\x49\xfa\x28\xc4\x99\xd5\x22\xf6\xde\xb9\xb7\x77\x18\xdc\xcc\xcb\x0c\xb8\x90\x5a\xfa\x98\x86\x1a\xfa\x15\x88\x10\x95\x7e\x25\x73\xcf\x57\x09\x3c\x8b\xbd\xf7\x8d\x5e\xb1\x46\x2b\xd6\x59\xc5\x55\xad\x62\xcb\x59\xb1\x4e\x2b\x36\x59\xc5\x9a\x56\x71\xd5\x59\xb1\x41\x2b\xb6\xcf\x04\x6a\x4a\xc5\x5a\x56\xf1\x5e\xbb\x58\x5e\x94\x7a\x8a\x08\x8f\x1d\x7f\xcc\x52\xb2\xb3\xe0\xf1\xf0\x78\x97\xe8\xf1\x1c\x0e\x63\x70\x02\x8e\x2d\x7e\xbc\x15\x5f\xab\x13\x1e\x92\x72\xf4\x0a\x6f\xba\xe3\x7c\x2f\x3a\x99\xfa\x85\x1d\x4f\x76\x73\x9b\x7d\x0c\x2e\xe9\x97\x76\x73\xa5\x51\xd7\xd5\x72\x62\x99\x08\x82\x2d\x15\x74\x85\x52\xd6\x87\xf2\x45\x12\x41\x35\x83\x9f\x63\xff\x12\xa3\x68\x3c\x70\xb2\xda\x05\xe4\x87\xee\x39\x9d\xdc\xae\x1e\xef\x50\x69\xb1\xeb\x8f\xfb\xb3\x31\x59\x61\x21\xbe\x72\x36\xdb\x65\x89\x60\xba\x34\x11\x4c\xf5\xba\x39\x68\xc0\xff\xa1\x57\x5c\x42\xd3\xf3\xb5\x74\x59\x5e\x98\x2e\xcd\x0b\x53\xbd\x66\x35\x1a\x10\x53\xbe\xcb\x05\xd4\x6a\x19\xbd\x45\xa5\xee\xb9\xf4\xfc\x5f\xa8\x86\x3a\xa8\x5a\x36\x21\xd6\x19\xc4\x3a\x85\xc8\x00\x36\x19\xc4\x9a\x06\xb1\x56\x00\x62\x83\x41\x6c\x18\xdd\x2a\xd1\x76\x14\x88\xf5\x02\x10\x9b\x0c\x62\xd3\xda\xeb\x86\x06\xb1\x51\x00\x62\x8b\x41\x6c\x59\x7b\xdd\xd4\x20\x36\x0b\x40\x6c\x33\x88\x6d\x6b\xaf\x5b\x1a\xc4\x56\x01\x88\xab\x0c\xe2\xaa\xb5\xd7\x6d\x0d\x62\x7b\x2e\xc4\x4c\xec\xa7\x40\x95\xea\xab\x7a\x75\xdd\x3b\x46\xd0\x34\xd9\x7d\x2e\x96\xef\xb1\x88\x48\xa9\x8b\x6b\xe0\xd5\x01\xe9\x5a\xd7\x92\x84\x83\xa7\xcb\x8f\x67\xfd\x14\x8d\x82\x8b\x11\xf2\xc3\x01\x1a\x47\x57\xc8\x8f\x2f\x66\x10\xfe\x05\xdc\x9c\xff\x3d\xf3\x63\x23\x71\x0f\x34\xe0\xa3\x75\xd2\x0a\x97\xe2\x2c\xca\x83\x8b\x1e\x2d\x42\x77\x09\xeb\xf1\x89\xf7\x59\xc1\x20\xc6\xc9\x6c\x9c\xa2\x68\x98\xd7\xfc\x88\x6e\x01\xa5\x0b\x1f\xbd\x44\x17\x3e\x75\x5d\xa9\xad\x96\xd1\x2b\x44\x5f\xf5\xd8\xab\x16\xbc\xea\xc1\x2b\x1b\x92\x63\x0a\x48\xea\x0a\x3d\x12\xbe\x44\x17\xd7\x30\xc3\x65\x20\x08\x5e\x40\x88\x9d\x52\x01\x5b\x22\x18\xd2\xa1\x5f\x0f\x8e\x10\x84\x93\x94\x3f\xbe\xa7\x1c\xee\x62\x84\x7e\x43\x17\xe3\xa2\x4c\xce\xae\x54\xf9\x95\xb1\xb8\xf7\x94\xc5\x95\x4a\xef\xb3\xed\x9b\xec\x64\xef\x25\xb1\xa0\xcc\x0a\xb4\xd5\x02\xed\xac\x80\x4e\xcf\xbf\x32\x6e\xf8\x9e\x72\xc3\x12\x6d\x26\xdb\x6f\xdf\x73\xfe\x07\xfb\xed\x2b\x44\x5a\x33\x61\xd4\x19\x8c\x3a\x87\x51\x53\x11\xa8\x19\x18\x56\xd5\x02\xd5\x3c\x0c\x1b\x0c\x7a\x83\x43\xaf\xab\x18\xd6\x35\x0c\x6b\x16\x0c\x9b\x0c\x46\x93\xc3\x68\xa8\x08\x34\x0c\x0c\xeb\x6a\x81\x7a\x1e\x86\x2d\x06\xbd\xc5\xa1\x37\x55\x0c\x9b\x1a\x86\x0d\x0b\x86\x6d\x06\xa3\xcd\x61\xb4\x54\x04\x5a\x06\x86\x4d\xb5\x40\x33\x0f\xc3\x55\x06\x7d\xf5\x4c\x21\x11\x81\x61\x5b\xc3\xb0\xa5\x60\x58\x28\xf1\x47\xc2\x93\x4e\x08\x5d\x6b\x81\xb4\x13\xf3\xae\xbb\x28\xac\x14\x5f\xa7\xf2\xbd\x93\xac\x49\xe5\xa1\x14\x94\x34\x0e\xf4\xb6\xc8\xbc\xbf\x9a\x8e\x7d\x82\xcd\x75\x8a\x9c\xe0\x58\x9c\x99\x52\xd6\xb2\x0d\xa2\xb8\xb8\xca\x53\xea\xaa\xc9\x3b\xe4\x92\xe5\xbc\x3b\x28\xb9\x60\x61\x63\x64\x4f\xbd\x1b\xe9\xb4\x9a\x5e\x76\x29\xd2\x69\xb5\x3d\x76\x57\xd2\x69\xd7\x6e\xcf\xbc\xd5\xbf\x76\x24\xc2\xa7\xfb\xaa\xa7\xfb\xaa\x47\xbb\xaf\xd2\x96\x78\x76\x9f\xa3\xdf\xe4\xfc\xb5\xee\x70\x1e\x2a\x2b\xdc\x07\x71\x34\xff\xa0\x1e\xcd\x3f\xdc\xf5\x68\xfe\x41\x3d\x9a\x7f\xc8\x3b\x9a\xcf\x53\x30\x3f\xdd\x54\x3d\xdd\x54\x3d\xdd\x54\x29\x5f\x9e\x6e\xaa\x9e\x6e\xaa\x9e\x6e\xaa\xb2\x66\x9f\x6e\xaa\xf4\x8f\x4f\x37\x55\x8e\xc7\xa7\x9b\xaa\xa7\x9b\xaa\xa7\x9b\x2a\xf8\x7b\xba\xa9\x2a\xa6\xc4\x7d\xba\xa9\x7a\xba\xa9\x7a\xba\xa9\x92\xfe\x9e\x6e\xaa\x9e\x6e\xaa\x9e\x6e\xaa\x9e\x6e\xaa\xfe\x93\x6f\xaa\x1e\xec\x8e\xea\x6e\xb7\x53\x45\xee\xa5\x0a\xdc\x48\x3d\xd6\x5d\xd4\x5f\x3b\x1f\xca\xd3\x5d\xd4\xdf\xff\x2e\x4a\xbe\x3b\xea\x36\xe7\x3a\x3a\xc9\x37\x47\xdd\xa6\x74\x6d\x04\x0f\x8f\x7f\x67\x44\xbd\x34\xc5\xad\x91\x3d\xa8\x00\xf7\xd0\xce\xbb\x56\x02\x37\x4e\xd9\xa3\x58\x8a\x99\x6e\xea\x2b\xc2\x20\x45\x49\x2f\xba\x36\xe1\x1c\x0b\x74\x8e\xe5\x6b\x3a\xfe\x67\x93\x26\xeb\xad\xb6\xfb\x50\xce\x0e\xdd\xc1\x7c\x35\xee\x07\x7c\x63\xd3\xe3\xaa\x2d\x7a\xdc\x7f\x7c\x6e\xc3\x6c\x50\xc8\x10\xf0\xa8\x12\x01\xfa\x87\x3c\x4e\x0e\xd5\x21\xab\x44\xb6\x36\x3e\xf6\xa7\x0a\x20\x33\x12\x9a\xf2\xd9\x08\x8a\x66\x3b\xfb\x93\x5e\x94\x3e\xa3\x57\x74\x7c\x5e\xf1\x46\xcb\xe8\x1f\xd0\x2b\x47\x2c\x85\x2b\x7f\x6a\xc7\x19\xf6\x0d\x53\x43\x20\x4d\xc0\xb1\xdd\x31\x9e\xbc\x26\x33\x3e\x7f\x7a\xba\x56\x15\x3f\xcb\xaa\x21\x88\xe6\x33\xcb\x32\x2b\x00\xdd\x5b\x2d\xc7\x35\x21\xa0\x05\x31\xf2\xaf\x93\xe9\xb1\xab\x0c\x95\x96\x85\x93\x73\xbd\xd5\x76\x28\x44\xaa\x4e\x65\x88\xb5\xd1\xa2\x8a\x11\x69\x3d\x69\x8a\x91\x6c\xd0\x02\xed\xcb\xe7\x6c\x38\xe7\x66\x80\x07\xe5\xa0\x5a\xfd\x8b\x8c\xa7\x36\x1f\x62\x35\x85\x74\x19\x85\x54\xa5\x16\x5a\x16\x51\x00\x1a\x74\x9a\x30\x8e\x51\xa5\xf2\x5d\x21\x61\x07\xe1\x5a\x89\x36\x87\x60\xdd\xc4\x9a\x11\xaa\xfa\x5e\xed\xec\x57\x52\xb7\xc4\xd6\x14\xa9\xc2\xf0\x3a\xcb\xf2\x1a\x84\x7a\x1e\x03\xed\xf8\xf4\x09\xe2\xa0\x58\x6e\xb4\x32\x52\x0f\x8c\xb3\x3b\x19\x0b\x65\xae\x98\x58\xa6\x60\xf7\xbd\xca\xbd\xdd\xe6\x43\x08\xbd\xdd\xe6\xc2\x12\xaf\xb9\xc7\x6a\xe2\x6e\xb7\x69\x8d\x6d\x01\x37\x34\x01\x1e\xdc\x61\x87\xdf\x8c\xa3\xa9\xb2\xcb\xb3\x17\x30\x08\xdf\x20\x2a\xde\x80\x34\xa7\x06\x9a\xd3\xf4\xfc\x64\xe2\x49\x29\x11\x6a\x0e\xd5\x5e\xd7\x65\xb0\x7a\xac\x39\x82\xba\x14\xf5\x4b\x5b\xc5\x04\x54\x47\x05\xa1\x46\x8c\x2b\x24\xc4\x90\x36\x78\xc1\xfc\x3b\x0c\x32\x9e\x39\x1b\xb8\x30\x7c\x21\x78\x91\x5d\xfc\x27\xd8\xcc\x97\x97\xad\x7b\xf8\x02\xec\x1e\xcd\x49\x80\xf4\x1d\xad\x36\x32\x44\x0f\xb3\xe2\x00\xd2\xe2\xab\x8e\xd1\x7c\xfe\xca\x23\x85\xf2\x4f\x9a\xdd\xe6\x63\x1d\x33\xef\x97\xae\xef\x5b\x9e\x2f\x1f\xed\x14\xf8\x6d\x83\x38\x13\x56\x85\x13\x1c\x5f\xe2\xe7\xcf\x4a\xfd\x32\xaa\x57\x6b\x75\xd4\xbb\x41\xdd\xff\xef\xff\x1d\xc4\x41\x1f\xed\xe3\x24\x0c\xc6\x15\xb4\x31\x1e\xa3\x38\xb8\x18\xa5\x09\x62\xe5\x07\x95\xe7\xcf\x9f\x1d\xe1\x41\x90\xa4\x71\xd0\x9b\x01\x7c\x3f\x1c\x40\x50\x9e\x20\x44\x49\x34\x8b\xfb\x18\xde\xf4\x82\xd0\x8f\x6f\x08\x3b\x98\x24\x1e\x8b\xd2\x10\xc3\xbf\xd1\x2c\x45\x13\xe0\xe9\x7d\xe0\xac\x1e\xf2\x63\x8c\xa6\x38\x9e\x04\x69\x8a\x07\x68\x1a\x47\x97\xc1\x00\x0f\x68\xd0\x09\xb2\x4e\x87\xd1\x78\x1c\x5d\x05\xe1\x05\xea\x47\xe1\x20\xa0\x6b\x98\x54\x9a\xe0\xb4\xc3\x56\xfc\x32\x52\xd1\x4a\x40\x31\x4c\xf1\xe9\x47\x03\x8c\x26\xb3\x24\x25\x1b\xb5\x1f\x84\x00\xd4\xef\x45\x97\xe4\xd3\xf4\x06\xba\x88\xc2\x28\x0d\xfa\xd8\xa3\x71\x85\xc6\x41\x02\x9a\x65\xb9\xbd\x70\xa0\x21\x33\x08\x92\xfe\xd8\x0f\x26\x38\xae\xb8\x70\x08\x42\x79\x20\x38\x0e\xd3\x38\x1a\xcc\xfa\xf8\xc1\xd1\x40\xac\x6b\x83\xa8\x3f\x13\x71\x30\x48\x8d\x95\x28\x66\x31\x32\x26\x7e\x8a\xe3\xc0\x1f\x27\xd9\x30\xc3\xdc\x40\x35\x09\x75\x32\xcf\x27\x3b\xbb\xc7\xe8\xf8\x60\xfb\xe4\x97\x8d\xa3\x2d\xb4\x7b\x8c\x0e\x8f\x0e\x7e\xde\xdd\xdc\xda\x44\xef\xfe\x85\x4e\x76\xb6\x50\xf7\xe0\xf0\x5f\x47\xbb\xef\x77\x4e\xd0\xce\xc1\xde\xe6\xd6\xd1\x31\xda\xf8\xb8\x89\xba\x07\x1f\x4f\x8e\x76\xdf\x7d\x3a\x39\x38\x3a\x46\x2f\x36\x8e\xd1\xee\xf1\x0b\xf8\xb0\xf1\xf1\x5f\x68\xeb\xd7\xc3\xa3\xad\xe3\x63\x74\x70\x84\x76\xf7\x0f\xf7\x76\xb7\x36\xd1\x2f\x1b\x47\x47\x1b\x1f\x4f\x76\xb7\x8e\x3d\xb4\xfb\xb1\xbb\xf7\x69\x73\xf7\xe3\x7b\x0f\xbd\xfb\x74\x82\x3e\x1e\x9c\xa0\xbd\xdd\xfd\xdd\x93\xad\x4d\x74\x72\xe0\x41\xa3\x66\x35\x74\xb0\x8d\xf6\xb7\x8e\xba\x3b\x1b\x1f\x4f\x36\xde\xed\xee\xed\x9e\xfc\x0b\xda\xdb\xde\x3d\xf9\x48\xda\xda\x3e\x38\x42\x1b\xe8\x70\xe3\xe8\x64\xb7\xfb\x69\x6f\xe3\x08\x1d\x7e\x3a\x3a\x3c\x38\xde\x42\xa4\x5b\x9b\xbb\xc7\xdd\xbd\x8d\xdd\xfd\xad\xcd\x0a\xda\xfd\x88\x3e\x1e\xa0\xad\x9f\xb7\x3e\x9e\xa0\xe3\x9d\x8d\xbd\x3d\x6b\x2f\x09\xee\x4a\x1f\xdf\x6d\xa1\xbd\xdd\x8d\x77\x7b\x5b\xb4\xa5\x8f\xff\x42\x9b\xbb\x47\x5b\xdd\x13\xd2\x9d\xec\x57\x77\x77\x73\xeb\xe3\xc9\xc6\x9e\x87\x8e\x0f\xb7\xba\xbb\xe4\xc7\xd6\xaf\x5b\xfb\x87\x7b\x1b\x47\xff\xf2\x18\xcc\xe3\xad\xff\xfb\x69\xeb\xe3\xc9\xee\xc6\x1e\xda\xdc\xd8\xdf\x78\xbf\x75\x8c\x4a\x73\x86\xe4\xf0\xe8\xa0\xfb\xe9\x68\x6b\x9f\xe0\x7c\xb0\x8d\x8e\x3f\xbd\x3b\x3e\xd9\x3d\xf9\x74\xb2\x85\xde\x1f\x1c\x6c\xc2\x40\x1f\x6f\x1d\xfd\xbc\xdb\xdd\x3a\x7e\x83\xf6\x0e\x8e\x61\xb4\x3e\x1d\x6f\x79\x68\x73\xe3\x64\x03\x1a\x3e\x3c\x3a\xd8\xde\x3d\x39\x7e\x43\x7e\xbf\xfb\x74\xbc\x0b\x83\xb6\xfb\xf1\x64\xeb\xe8\xe8\xd3\xe1\xc9\xee\xc1\xc7\x32\xda\x39\xf8\x65\xeb\xe7\xad\x23\xd4\xdd\xf8\x74\xbc\xb5\x09\xa3\x7b\xf0\x11\xba\x7a\xb2\xb3\x75\x70\xf4\x2f\x02\x94\x8c\x01\x0c\xbe\x87\x7e\xd9\xd9\x3a\xd9\xd9\x3a\x22\x03\x0a\x23\xb5\x41\x86\xe0\xf8\xe4\x68\xb7\x7b\x22\x17\x3b\x38\x42\x27\x07\x47\x27\x52\x1f\xd1\xc7\xad\xf7\x7b\xbb\xef\xb7\x3e\x76\xb7\xc8\xd7\x03\x02\xe5\x97\xdd\xe3\xad\x32\xda\x38\xda\x3d\x26\x05\x76\x69\xb3\xbf\x6c\xfc\x0b\x1d\x7c\x82\x2e\x93\x39\xfa\x74\xbc\x45\x7f\x4a\x14\xeb\xc1\x4c\xa2\xdd\x6d\xb4\xb1\xf9\xf3\x2e\x41\x9b\x15\x3e\x3c\x38\x3e\xde\x65\x74\x02\x43\xd6\xdd\x61\xc3\x5d\x79\xfe\xec\xe5\x8a\xaa\xf3\xda\xf7\xd3\xd1\xc3\xea\xbd\x8a\x45\x9d\xa6\x81\x8f\x45\x11\xfa\x58\xc8\x3a\x1b\x2e\xec\xfc\x30\x4d\x50\xea\xf7\xb8\xc4\x42\xaa\x9c\xff\x3e\xb6\x06\xdb\xcc\xe4\xa8\xaa\x87\x50\xcd\x43\xa8\xee\x21\xd4\xf0\x10\x6a\x7a\x08\xb5\x3c\x84\xda\x1e\x42\xab\x1e\x42\x6b\x1e\x42\xaf\x3d\x54\xab\x7a\xa8\x56\xf3\x50\xad\xee\xa1\x5a\xc3\x43\xb5\xa6\x87\x6a\x2d\xc9\xc2\x72\x95\xd6\x25\xdf\x08\x3c\x52\x9e\xc0\xa8\xb5\x28\x5c\x52\x0f\xda\x7a\xcd\xe0\xd7\x19\x8c\x1a\xb4\x91\xc1\x69\xb0\xb6\x9a\x0c\x97\xd7\x0c\xc6\x9a\x84\xe7\x2a\x83\xd5\x66\xb8\xd4\x28\xcc\x9a\x1c\x6b\xb9\xc6\xea\x72\x5c\xaa\x14\x06\xe0\xc1\xf1\x6c\x50\x58\x04\x7e\x4d\xee\xb7\x0c\xa7\xc9\xea\xb6\x18\xee\xab\x0c\x46\x5d\xc2\xb3\xc6\x60\xad\x31\x5c\x58\xbf\x6b\x8d\xb3\xf2\x1b\x79\x2e\xe2\x39\x73\xc1\xf1\x58\x95\xc6\xaa\xce\x60\x72\x9c\xdb\xea\x78\x40\xdf\x1a\x5a\xdf\xdb\xac\x4e\x23\x83\x05\x75\x5b\x19\xce\x1c\x06\x1f\x0f\x68\xab\xa6\xf5\x1d\x0a\xb5\xa4\x0e\xae\x32\x04\xdb\xd9\xe0\x0a\x20\x75\x69\xa0\x29\xb2\x19\xa0\x35\x56\x47\x1a\x2c\x98\x98\x56\x36\xb8\x02\x46\x43\x1a\x68\x8a\xac\x84\x50\x9d\x8d\x6c\x55\x02\xc6\x47\x63\x55\xcc\x9e\xa0\x50\xc4\x46\x87\x22\xab\xce\x46\x32\x6f\x65\x50\x14\xd9\x58\x01\x7a\x72\x4b\x9c\xb6\x1a\xd2\x78\xb6\xb3\x6f\x0a\x4d\xaf\x7a\xf0\x09\x86\x8a\xd3\xeb\xeb\x8c\xf6\x38\x4d\xd5\x5a\xd2\xb0\xae\xb2\xb2\xca\x7c\xd4\x32\x22\x10\x73\xf1\x9a\x15\xe4\xc4\xb3\x26\x95\xe1\x88\xaf\xc2\x6f\xf9\x2c\x25\xd6\x72\x33\xab\xca\xdb\x17\x6b\x5e\x5e\x13\x6b\x0a\xc8\x0c\x14\x5f\x9f\xad\x8c\xf6\x45\x3f\xeb\x19\x0a\x62\x9c\x18\xc9\x50\xb8\x48\x9b\x92\x79\x0b\x84\x21\xa6\x0c\x7e\x2b\x43\x00\xfa\xb9\x9a\x2d\x44\x68\xb0\xc9\x10\x69\x6b\x48\x37\xd4\xc1\x17\x9d\xae\x65\x70\xc4\xd8\x89\x05\x0d\xdf\x15\x38\x82\x81\xd4\xa4\x41\x6a\x67\xed\x8a\x85\xc7\x16\x70\xad\x61\x99\x0f\xd1\x01\x0d\x71\x0e\x48\x2c\xb8\xba\xf4\x6f\x4b\xac\x62\x75\x80\x5a\x96\x72\x4d\x75\x66\xc4\x4c\x66\x9d\x42\xb5\x1a\x3a\x53\xb2\x64\x9f\x8f\xc8\x0a\xb1\xcc\x07\x12\xa1\x9a\xab\x1e\xaa\x5e\xb7\x36\xd6\xea\xab\xaf\x5f\xbf\x26\xbf\xdb\x5b\x9b\xaf\xb7\xde\x6d\xd4\xc8\xef\xb5\xed\xda\xbb\x77\xdd\xcd\x2e\xf9\xbd\xf1\xba\xd5\xd8\xde\x6c\x6e\xa9\xf3\x3d\x8a\x9d\x0d\xb4\xaa\x1b\xf5\xb5\x77\x5b\x6d\x68\xa0\xdb\xdc\xdc\xac\xd5\x9b\xd0\xc0\xe6\x6a\xb5\xb1\xb5\xdd\x20\xbf\x57\x37\xda\x9b\xab\xed\x2d\x68\x98\x23\x74\x66\xd5\x07\x1c\xed\x1e\x6e\xed\x6f\xd6\xda\x55\x08\xbf\x3f\x47\x87\x24\xca\x66\x5a\x24\xe9\x15\xdd\x95\xef\x7a\x57\x44\x95\x89\x80\x84\x23\x08\x76\x7b\xb5\xd9\xaa\x37\xaa\x30\x82\x5b\xdb\xdd\xcd\x8d\x77\x6b\xd0\xc1\xd7\x6b\xef\x36\x36\xbb\xdb\x5b\xe4\x77\xad\xda\xa8\xb7\x9a\xab\x30\x38\xdd\xc6\x66\x7d\xab\xb6\x5d\x3d\x73\xaa\xc6\x8b\x2a\xe5\xad\x8a\xdd\xc2\x5e\x4a\xb5\x9c\x9b\x9a\xf9\xe6\xf8\x14\x0b\xd0\xbd\x66\x66\x91\x8e\xeb\x9b\xfd\x73\xa9\x34\xbf\x3c\x38\x37\x0d\x99\x50\xde\x9d\x8a\x54\x0f\xad\xa3\x92\x59\x00\x51\x03\x50\xa9\xb1\xcc\xf0\x41\x7a\xb9\x98\x51\xa9\x01\x90\xd9\x95\x6a\x00\x4d\xeb\x52\x13\x5c\x8e\x6a\x0c\xcd\xb3\x75\xde\x41\xe2\xfe\x81\x90\xa2\xf3\xca\x11\x18\xc0\xf9\x68\xec\x2e\x10\x43\x81\xd8\x59\x00\xc4\xcf\xf3\xdf\xdd\x10\x40\x26\x3a\xff\xdd\x0d\x01\xb6\xe9\xf3\xc4\x0d\x01\x36\x8d\xf3\x24\xb6\x47\xb4\x5e\x59\x21\xab\xec\x0b\x39\x34\x5f\xfa\x71\x40\xa4\x63\xcb\x25\xad\x3f\xf6\x50\x6f\xec\xa1\xfe\xd8\x43\x83\xb1\x87\xf0\xd8\xd2\x90\x1f\x7b\xa8\x17\x7b\xa8\x1f\x7b\x68\x10\x7b\x08\xc7\x7a\x63\x3e\x41\xc5\x27\x08\xef\xfc\xff\xec\xbd\xfd\x96\xd4\x36\xb6\x28\xfe\x77\x78\x0a\xcd\xfc\xd6\x40\x35\x5d\x74\x5b\xf2\x97\x0c\x74\x7e\x97\x10\x38\x9d\x1b\x08\x2c\x60\x6e\x38\x8b\x05\x19\xd9\x96\xbb\x1c\xaa\xab\xfa\x54\xb9\xe9\xea\x24\x64\xdd\xd7\xb8\xaf\x77\x9f\xe4\x2e\x6d\xc9\xb6\x6c\x4b\x72\x55\xd3\xe4\x4c\x66\xe8\x59\x43\xaa\x4a\xd2\xde\x5b\xfb\x4b\x5b\x5f\x5b\xc3\x2b\x23\xe9\x0a\x92\x8e\x43\x21\xee\x17\x66\xa2\x30\x93\x85\xa4\x5f\x98\x8b\xc2\x5c\x16\xfa\xfd\x42\x98\x30\x70\x59\x18\xf4\x0b\x9b\x67\xaa\x59\xf7\x5d\xea\xba\x4b\xfd\x5d\x41\xe3\x51\x42\xf8\xef\xfe\x11\xc2\x46\xdb\xae\x84\xf9\xb0\x39\xda\x6f\x6d\x6a\xff\x97\xf9\x9b\xf2\xed\xdb\xbd\xdf\x4c\x97\x18\xe0\xd6\xce\x7d\x1c\xed\xfd\x7a\xe3\xab\xae\x6b\x14\x38\x50\x81\x27\xe9\x7c\x9a\xcd\xa7\xf9\x7c\x0f\xed\xa3\xd9\xdc\x7c\xf7\xe6\x23\x6a\x16\xe4\xca\xfb\x3e\x91\x4b\x6d\x06\x68\xa4\x0f\x6d\xc0\xf9\x01\xb4\x80\x5a\xa1\xf9\x7d\x68\x03\x51\x0d\xa0\x45\x81\x15\x5a\xd0\x87\x36\x90\xad\x06\xed\xd7\xc3\x43\x05\x91\x7a\x56\x88\x61\x1f\xe2\x40\x21\x90\x39\x4d\xba\x10\x62\x65\x14\x97\x28\x41\xab\x65\x35\x9f\x54\xd3\xb5\x10\xab\xe9\xd2\x06\xe8\x40\xb5\xcf\xe7\x66\x91\x83\x45\x0c\x4c\x4a\xfc\x81\xde\xe6\xa6\x12\x50\x77\xc0\x2b\x6c\x12\x1b\xaf\x01\x81\xbd\xa4\xa6\xd6\x60\x66\x83\x9d\xc4\x86\x54\xb6\x42\xfb\x9a\xb6\xae\xae\xae\xad\xe1\x24\x5d\x4d\xb3\xd5\x34\x5f\x01\xc7\x57\x9f\xa6\xad\x41\x1f\xda\xa7\x6a\x6b\x17\xda\x27\x69\x2b\xe9\x43\xfb\x64\x6d\xc5\x7d\x88\xd7\xac\xad\x2b\xd8\xb5\x76\xa8\xeb\xca\xa2\xae\xe0\x51\x57\x26\x75\x05\x47\x6c\x2a\x01\x17\x2d\xd5\x75\x65\x55\x57\x18\x00\x4c\xad\x61\x68\x18\x9e\xd0\xe8\xbb\xf2\xef\xf4\xe7\x18\x20\x86\x84\x53\xbf\xbd\x08\x53\xfc\x73\x84\x26\xc7\xf2\x68\x6e\x26\x3c\x73\x6e\xe8\xe9\xb1\x3a\xc2\x7b\x2c\x8f\xdf\xe6\xa2\x9e\x89\x23\xc7\xea\x98\xee\xb1\x3c\x48\xcb\x45\x3d\x66\xac\xe7\xab\x7a\x70\x58\x16\x46\x84\xd4\x58\x2f\x50\xf5\xe0\x60\x72\x2a\xea\x65\xc6\x7a\x70\x80\xb9\xc3\x96\x7e\x58\xfb\x58\x3d\xad\xf1\x09\xc7\xb3\x72\x56\xb1\x26\x18\x12\x5f\x0c\x03\xff\xf8\x33\x8c\x75\xcd\xc5\x37\x65\xb5\x7e\xb5\xac\xc0\xe3\x49\x98\x8b\x6f\x59\xc5\xe4\xa9\xad\xdb\x88\x1a\xa0\x43\x9b\x27\xbc\xa8\x06\x8f\x36\x42\xfd\x41\x67\x1e\xe4\xf9\xf0\x15\x62\xa4\xde\x5b\x94\x87\x99\x5a\x90\x22\x9a\x0c\xdf\xa2\xdf\x8e\xe4\xc3\xc2\xed\x19\x89\xa6\xc6\xdf\x90\x4f\xfa\xda\xda\x42\x9a\x4c\x26\x6d\xd5\x7d\x24\xfc\x83\x00\x99\xec\x09\x50\x81\xb0\x5b\x1c\x58\x02\xe8\xba\xa9\x64\x47\x1b\x3c\x6b\x3f\x6e\x1f\x3c\x0f\x80\xa9\xc0\xb9\x07\x6c\x2c\x70\x36\x75\x54\x7f\xa7\xa3\x7d\x0f\xb3\x7e\x63\x07\x0e\xc7\x18\x9e\xed\x38\x3c\x84\x99\x20\x82\xd7\x5d\xe4\x85\x2c\xe3\xc1\xa9\x33\x39\xf3\x1a\xbe\xe6\xe2\x56\x4b\xb0\x6e\x3d\x46\x37\x28\xce\x31\x3a\x42\x7a\xf8\xfe\x69\xf3\xb7\x70\xab\xe9\x9b\x79\x46\x76\x0c\x53\xb1\x63\xc3\x65\x12\xe4\x9a\x83\x1d\x37\xd7\xf5\x8e\x3b\xd3\xab\xe3\x9d\xe7\x55\x52\x43\x8e\x3b\x73\xaa\x63\xeb\x64\x6a\xfc\x28\xdc\x0b\xb9\x13\x2e\x85\xab\x5e\xb0\xc8\x81\xd9\xdd\xaa\x6a\xc7\xbc\x27\xa0\x8e\x9b\xca\xe6\xcb\x85\xdb\x41\xc1\x51\x02\x51\xab\x5d\x5d\x80\xaf\xf6\x63\x10\xb2\xf8\xa7\x81\x92\xc8\x76\x43\x5d\x53\x64\x42\x69\xe7\x5c\x14\x7c\xfc\x28\x77\xff\x91\x7e\x22\xae\xc0\x93\xcd\x14\x5d\x4e\xd1\x2f\xa6\x67\x3e\x26\x93\x0d\xdc\xec\xbc\x84\x7f\x7f\x69\x5f\x6b\xff\x38\x80\x43\xdc\x70\x26\x9b\xbd\x9b\x93\xcb\x3d\x79\x9d\xfc\x77\xf1\xe5\x97\xbd\xbd\xbd\x7b\x36\x68\xfe\x28\x34\x01\xe8\x77\x01\xb1\x25\xcd\x02\x2b\x18\x87\x75\x13\x20\x00\x6d\x97\x7b\x37\x27\xbf\x03\x71\x76\x88\xe1\x36\x3c\x13\x4c\xfb\xad\x05\x65\x81\x05\xa1\xc4\x66\xba\x30\x42\xda\xdc\xbf\xbf\x00\xaa\x36\x5f\x7f\xfd\xf5\xc4\x27\x77\x16\x3a\x51\xf2\x83\xf3\x34\x4c\x7d\x18\x46\xbe\x03\xb7\xdd\x61\x18\xeb\x6b\x3f\xea\x7c\x0b\x9c\x79\xaa\x3f\x57\x4b\xe9\x99\x86\x60\x2c\xef\xf3\x58\x6a\x5f\xf5\x61\x1e\x65\x19\xed\x49\x96\x7a\x01\x6f\x72\x4b\x91\x78\xcb\x70\x0a\xc7\xde\xea\xa2\xa6\xd6\x74\xdc\x66\xb8\x38\xd8\x3b\x6a\x53\x57\xd8\xee\xa8\x52\x2d\x9c\xe3\xa7\x0f\x1e\xfe\x01\xa2\x71\x34\x7f\xcf\x2f\xa1\xe9\x9a\x67\x2b\x5e\x59\xde\x4e\xb2\x08\x14\x9e\x1c\xbc\x46\x81\xca\x87\x0c\x1b\xd1\x1c\x9f\xb2\xac\x15\x8f\x7e\xc4\xca\x20\xa1\x4e\xe5\xa1\x94\x4e\x59\x66\x90\xd4\x57\x1f\xe5\x3e\xb0\xe5\x68\x54\x5d\xd3\xfc\x3a\xd1\xc7\xb7\xd3\x38\xfe\x72\xc4\xe9\x5f\xe1\xca\xca\xe7\xde\xba\xef\x25\x56\xd3\x10\x5b\x53\xa6\xbd\x3c\x7e\x70\x07\x6f\xb1\x93\x31\x7c\xab\xfa\x3a\xf7\x2f\x8e\xe0\xf6\x69\xbb\x85\x51\x2e\xca\x6a\x62\x48\x40\xd5\xdd\xd2\xe0\x45\x96\xb3\x94\x26\x86\xdc\x4c\xde\x26\xa1\x29\xcb\xb3\x82\x77\xf6\x38\x4c\x15\x33\x3f\x27\x1c\x17\x5e\xb7\xec\xd3\xb7\x40\x6c\x11\xba\x39\xf8\x1e\xae\xa0\x0f\x00\x6c\xb3\xf6\x6c\x5e\x2e\x16\x45\xa9\x79\xb1\x18\x02\x46\xf3\x52\x31\x4c\x57\xcd\x0b\xc5\xa2\x88\x37\xcb\xc4\x03\x4a\xad\xeb\xc4\xd6\x35\x61\xcb\x6c\x01\xd6\x7d\x90\xbc\x61\x6a\xc9\x05\xf3\xa3\x0c\xfc\xbb\x29\x30\xba\x77\x4f\xeb\xbf\x7a\x41\xc9\x0c\xa8\xbe\xe7\xf0\xe3\x9b\x12\xdd\x41\xfe\x5b\xf4\x4e\x7d\xa4\xed\x47\x1c\x68\x9f\x23\xdb\xdb\x91\x8a\xa4\xc9\x02\x2e\xc7\xca\xb9\x25\x4c\x1f\x7c\x6c\x4e\x53\x63\x9e\x09\xc1\xd2\xd2\x84\x09\x20\x21\x00\x61\x72\x26\x13\xc3\x05\x59\x8e\xf6\x01\x91\x6d\xa1\x11\xdd\x47\xc4\xb3\x72\x0d\x96\xcd\x26\x93\x14\xdd\x44\x99\x8c\x73\xc5\xc7\x1c\x20\x7b\x9b\x90\xc9\x5d\xd8\x91\x25\x3e\x74\x1f\x05\x63\x28\x52\xf4\x0e\x65\xe8\x1d\xca\x25\xe4\x88\xe7\x09\x4f\x99\x29\xe9\x50\x0f\x72\xb4\x03\xf1\x92\x76\xf1\x29\x53\xbd\xb8\x83\xbc\x4d\xec\xf1\x20\xf0\x49\x60\xc7\x75\x78\xbb\x41\x47\xbd\x3d\x74\xfb\x70\xeb\xbe\x08\xf8\x7e\x98\xe4\x3e\x27\xfd\x55\x1e\x64\x11\xa9\xb0\x97\xdc\xb4\xdc\x87\x8e\x50\x66\x5a\xe2\x43\x80\xf2\xfe\x7d\xe4\x7b\xaa\x97\x20\x7e\xe3\xdb\xa2\xe8\x08\x99\xe8\x60\xdb\xdd\xd6\xda\x6a\x31\x50\x2d\xa2\xd5\x8b\x6d\xac\x7f\xc3\x1b\x75\x16\x02\x61\xc1\x70\x90\xf9\x04\x75\x16\x01\x61\xb1\x30\x33\xd7\xf1\xf5\x85\xc2\xdc\x5c\x27\xd0\x17\x09\x79\xbf\xce\x97\x05\xbe\x7f\xd6\x05\x3e\x11\x0b\x1f\x14\xf3\xe5\x72\xa5\xaf\xb9\x1d\xc2\x40\xad\xfe\x3e\x09\x09\xe4\x42\x68\x21\x8f\xac\xd3\x0d\x96\xe9\x3e\xd3\x0a\xdd\x8e\xeb\x40\xc6\xe5\xba\x3f\xe3\x6a\xd0\x97\x25\x84\xc1\x62\x80\x08\x9f\x77\x5a\x3d\x80\x06\xae\x85\x83\x6e\x40\xde\x5d\x33\x10\x65\x5f\x96\x0b\xae\x75\xb9\x00\xe4\xb1\xc5\x4a\x81\x59\x2c\xed\x22\x81\x12\x8d\xfd\xda\x94\xa8\x60\x5f\x16\xa0\x7f\xea\x04\x1b\xeb\x19\x23\x61\xf4\xb9\x73\x63\x28\x2c\xff\x3e\xcb\x07\x83\xe5\x01\x7d\x0e\x4f\xc2\xa8\x33\x8b\xd7\x6e\x61\xf7\x57\x05\x08\x09\xb6\x5b\x17\x10\x15\x3b\x30\xe1\xbb\x04\xfe\x87\xae\x0d\x64\xd8\x0b\x13\x9e\x53\x31\xe5\xf7\xa3\x38\xcb\x43\x2f\x86\xcf\x5e\xec\xe5\x39\x86\xcf\x45\xec\xf1\x30\xf1\xcd\x6b\x06\x45\x91\x79\x5e\xea\xc3\xe2\x42\x44\x43\x8a\x43\x2c\x3f\x07\x45\x42\x0b\x06\x00\x52\x5e\xb0\xa0\x60\xc1\x0e\xcb\x05\x5b\x45\x9e\x9a\xdb\x57\xac\xd3\x5a\x3a\x6e\xd1\x82\x47\x6d\xc2\x99\x3b\x47\xc3\xe0\xc5\xb2\xb1\xf4\x65\x88\x1e\x19\x71\x09\x09\x76\x1d\xa4\x45\x93\x91\x61\xba\x63\x1d\x83\x81\x9a\x10\xf3\x25\xf6\x2f\x43\xf5\x27\x0c\xd5\x42\x2a\xdb\x0d\xd6\x46\xe1\x74\x86\x6b\x29\x20\xe7\x80\x4d\x48\xff\xaa\xb3\x76\xaf\x59\x0d\x47\x77\xe3\x44\x0c\xe0\xc9\x97\x75\xfd\xff\x9e\x81\xf9\xcf\x77\x2d\xef\x3b\xf9\x88\x43\xf9\x4b\x73\x2b\x17\xad\x96\xe7\x8b\x1c\x65\xdd\xfb\x7a\x5a\x0f\x8e\xfb\x4f\xa7\x7c\xdf\xdd\x06\xa8\x17\x6a\x79\x0b\x43\x96\x98\x22\x18\xa4\x6f\x29\x97\xeb\xe7\xab\xf2\x94\x4f\x16\xc6\x61\x6c\xfd\x5f\xab\xea\x87\x7a\x9e\x2f\xbe\x4c\x16\xfd\x79\x66\xb3\x10\x2c\xc5\x89\x8e\x10\xb9\x57\x7f\xbe\x7f\x24\x21\xd4\x3f\x38\xd6\x86\xff\x32\x59\xa0\xbf\xa9\x6a\x7b\xd6\xf5\x42\x65\xa3\x05\x9b\xaf\xf9\xf8\xa9\xc0\xfe\xfa\x58\x3d\x1f\x5f\x9d\x77\x67\xb8\x06\xb6\x9c\xf0\xea\xf1\x8a\xc1\x67\x36\xff\xa6\xac\xd6\x06\x06\x35\x5b\xf8\x0b\x74\x07\x4d\x16\x90\xd9\x73\x0f\xdd\xee\x2c\x7e\xf4\x57\xb2\x34\x5c\xf5\x2a\xb5\x9e\x99\x1d\x7e\x03\x81\xf4\xf2\xf7\x5c\xcc\xca\x39\x47\x13\x55\x76\x1f\xa9\x23\x99\x7d\x2e\xb6\xd2\xb4\x32\xba\x01\x41\xad\x5c\x3e\x7e\x23\x2b\x41\xda\xd1\x01\x23\x40\x17\xce\x96\x17\x93\xc5\x14\x61\x74\x88\xc8\xde\x16\x19\xdb\x11\xbc\x84\xb2\x0b\x58\x7f\xcf\x98\x3c\x5b\x82\xd8\xdf\x1f\x59\x0a\x5d\x74\x6a\xd4\x11\xd2\xa4\x85\x79\xf5\x3d\x36\x11\x78\x6f\x17\x4d\x0f\x23\xf4\xcf\xbe\xd3\x76\x7c\xb0\x9e\x97\x19\x9f\x78\x7b\x5f\x76\xbd\xb6\xde\xf5\x1a\x14\x15\x50\x14\x9a\x8a\x4e\xa0\x68\xb0\x61\x04\x31\x0b\x14\xc5\x9f\xbc\x8d\x16\x39\x72\xdd\xff\xd1\xdb\x68\x27\xec\xf4\x94\x79\x9b\x66\x33\x0d\x0f\x98\x32\xac\x0d\x07\x8d\x27\x75\xcb\xfb\xf7\x11\x91\x9b\x5e\xf5\x2f\x5f\x7f\xfd\x35\x8a\xf7\xf6\x10\x7a\x67\x86\xd4\xfd\xeb\x40\xc2\xc1\x00\x12\xa6\x7b\x7b\xdb\x41\xea\xb6\xf3\x8d\xee\xa5\xd3\x13\xdc\xf6\xdb\x78\x48\xbe\x5b\x59\xeb\x36\x96\xc4\x6a\xdd\xc6\x9b\x3a\xdf\xf4\x96\xc4\x76\x21\xf9\x43\x48\xc9\x8e\xdd\xae\xdb\x99\xdf\x24\x40\xad\xe2\x28\x21\xee\xab\x9e\x43\x92\x5f\xd5\xc3\x7d\xe7\x86\xa9\x6d\xf7\x33\x83\x5b\x8d\x13\x8e\x6e\xa2\x02\x0e\xbb\xfd\x2e\x3e\x9e\xd8\x9e\x70\x39\x65\x90\x61\x8e\xa1\x9b\x28\x85\xea\x4c\xee\x0e\xbe\x43\x6a\x9f\xd0\x44\x3f\x04\x2b\xe5\x89\x20\xbc\xd9\x6a\x55\x9b\x6d\x6a\xaf\x55\x1e\xfd\x93\x25\x38\xd1\x4a\xb0\xdf\x29\xea\x34\x32\x8f\x6d\x0d\x32\x78\xa7\x66\xc2\x41\xc7\x65\xe6\x64\x0e\xed\x22\x05\x51\x96\x60\xad\x04\x63\xbd\x28\x96\x27\x5b\x65\x11\x09\xcd\x23\x1e\x6c\x20\x0b\x4c\x33\xb4\x5f\xa3\xdd\x17\x4c\xdd\x97\x0f\xbd\x59\x37\x8f\xa1\x21\x41\x47\x35\x63\xf6\x05\x6b\x4d\x18\x84\xe3\x3a\x31\x00\x10\xbe\xae\x9f\xa7\x5d\xfc\x09\xf7\x68\x0a\xbf\x20\x77\x26\xbc\x96\x80\x4d\xdb\x7c\x68\x64\x8b\xb4\x9f\x6d\x1d\x8d\x6c\x87\x4e\x2a\xc1\x88\x8a\x98\x70\xfd\xbb\x6c\x8d\xca\x3a\xa1\xaa\x03\x29\xc3\x0b\x73\x9d\x48\xd5\x81\x94\xe0\x27\xe6\x3a\xb1\xaa\x03\x36\x3f\xfb\xb2\x0d\xfb\x65\x1b\xf6\xcb\x36\xec\x30\xda\xfc\xb2\x0d\xfb\x4f\xb9\xc6\x1b\x46\x3b\xaf\xf1\x86\xd1\xe8\x1a\xaf\x3e\x67\x1b\xae\xf1\x86\xd1\x97\x35\xde\x6b\x5f\xe3\x0d\xa3\x6d\xd7\x78\x4d\xc2\xe9\xae\xf1\x82\x80\xdc\x87\xb6\x9b\xbd\x33\xf3\xd6\x2c\xf5\xfe\xd4\x5b\xb3\x9b\x28\xf8\x43\x1e\x2e\x68\xf0\x7c\x59\x05\xee\xae\x02\x6f\x22\xd8\x53\x3d\xd8\x44\x81\xf6\xfb\xeb\x28\x50\x59\xba\xa1\xc6\x81\x96\x27\x7a\xa7\x9c\x6e\x5a\xff\x5e\x1c\x3f\xfb\xe9\xd9\xe3\xc7\x2f\x1f\xbd\x7a\xd9\x5f\x2d\x7e\xfe\xdd\x4f\xdf\xfd\xf0\xed\xa3\xd7\x8f\x86\xaf\x72\xbf\x78\xf6\xf7\x1f\xbe\xfd\xe9\xe1\xb3\x1f\x5e\xbe\x7a\xf0\x43\xd3\x52\x43\x27\x97\x95\x1f\x6e\xb7\xac\xac\xb5\x58\xcd\x96\x75\xd2\x96\xde\x9a\x74\x8d\x5a\xcc\xae\xf1\x14\x5d\xda\x52\x95\x57\x72\x49\xa4\x42\xf7\x11\x09\xee\xa1\xca\xb0\x24\xa2\xf5\xf9\xcd\x06\xed\xa3\x10\xdd\x46\x97\xf2\xf6\x60\x55\x5f\xd2\x84\x4f\x64\x0f\x56\x2a\xd1\xdf\x50\x34\x88\x45\x20\x0c\xe4\x17\xaf\xd1\x11\xba\x44\x7f\x43\xa1\x29\x4a\xe4\x17\xff\x29\xa0\x12\x74\x1b\x09\x3c\xbe\xc0\xb3\x67\xa8\xbc\x91\xcb\x72\xaf\x7b\x3f\x5f\xca\x9f\xff\xd3\xb2\x14\xac\xb1\xed\xac\x44\x25\x3c\x27\x60\x60\x5a\xc3\x99\x8d\xe4\xcc\x46\x5e\xd0\xdc\x18\x18\xd3\x54\x95\xdc\x45\x97\xb2\xea\xa5\x65\x59\xa9\x55\x90\x2e\x1b\x2f\xe1\x81\x9f\x61\xaf\x05\x5f\xfb\x5d\xff\x38\xda\xb7\xde\x2e\x47\x57\x1b\x9e\x3c\x7e\xf9\x42\xd0\xba\xf1\xb0\x49\x19\xf4\x77\x27\x2c\xeb\x63\xa2\x1a\xa0\xa8\x95\xf5\xe9\xfa\xa2\xa7\x5b\xc6\x6a\x4f\xea\x6a\x16\x16\xaa\x97\x27\x7e\x46\xf7\x51\x7c\x0f\xfd\xec\x58\x99\x83\x3e\xc0\xd5\x54\x73\x56\x94\x1a\x7d\x5a\x56\xcf\x97\x6b\xc8\xe3\x2a\xb4\x0a\x1e\xcb\xfd\x79\x0f\xdd\x41\xa6\xd3\xd4\x35\x70\xbd\xd1\x7d\xa4\xf2\x45\x98\x2a\x8b\xbf\x41\x07\xdf\x1d\x21\x40\xa3\x41\xb1\xe0\xea\x9e\xa8\xd6\xb1\x7e\x7d\x04\x68\xed\x87\xab\x07\x98\x9f\x6a\x98\x3b\xa0\xee\x18\xe6\x3d\x0d\x01\xdb\x2d\x2d\x69\x8a\xb5\xe0\x9b\x0a\x14\x68\x44\x2c\xd4\x7e\x12\xfd\xf0\x10\x3d\x5f\x95\xa7\x65\x55\x7e\xe0\xe8\x6c\x39\xbf\x5c\x2c\x4f\x4b\x36\x47\xcb\x0f\x7c\x85\xfe\xe3\xf1\x84\xec\xdd\x45\x9b\x77\x14\xed\xa3\xcd\xbb\x08\xfe\x0d\xe1\xdf\x40\xb8\x19\x33\x48\xa5\xd1\x12\xbd\xbc\x3f\xf0\x0e\x79\x9b\xd8\x71\x64\xde\x42\x9c\x82\x70\x64\xd4\x8f\x91\x4d\xaf\x9e\x83\x97\x6b\x7c\x6a\xf8\xa9\x13\x8c\xf5\x65\x36\x1d\xe8\xcf\xde\xae\xbb\x29\x6b\xb0\x9f\x8a\x9f\x9e\x2d\x57\x6c\x75\xd9\x79\x89\x4e\x98\xc0\x2b\x7d\x20\xb2\xee\x52\x1a\x5f\x9d\x31\x5b\xff\x2b\x63\xcf\xc6\xe8\xee\xed\xed\xf8\xdb\xed\xec\xf8\x9d\x7d\x1d\xdf\xb5\xab\x73\xfd\x4f\x09\x2c\xcf\xab\xb3\xf3\xea\x09\x4c\xad\x3b\x75\x11\x04\xe9\x39\x5f\x97\x2b\x9e\x6b\x0f\x0d\xa4\x65\xb5\xae\x13\x42\xcb\xc6\x9d\xd9\x42\xdd\xf8\xd9\x62\x5e\x8b\x49\xcb\xc1\xcd\x56\xfc\x2e\x22\x24\x98\x22\x12\x46\x53\xe4\xd3\x60\x8a\x42\x4c\xfa\x8d\xd5\x9b\x05\x77\x45\x99\x5e\xd4\x7f\xb4\xa0\x9e\x34\x5b\xdf\x2d\xd0\x7b\xd7\x83\x76\x85\xf7\x0b\x60\xa5\x16\x5e\x42\xac\xe7\xde\xf5\xb7\x37\x6f\x2d\xde\x7e\x0b\x55\x13\x7f\x00\x47\xaa\xdc\x82\x5f\x34\x6a\x07\x9b\x70\x63\xa9\x04\x80\x92\xe6\xb5\x5e\x18\x01\x22\xcf\x43\x77\x90\x18\x68\x9b\x97\x12\x74\x4e\x88\xe8\xc5\x27\x9f\x6b\x47\xcf\xb0\x30\x67\x60\x9a\x71\xf1\xac\xee\xc4\x13\xb6\x80\xb5\x9f\x5e\xd7\x0e\x11\x31\xad\xa1\xa5\xeb\xe5\x2a\x1d\xe7\x7f\x0f\xfc\xa7\x64\x12\x7c\x4a\x4a\xd4\xdd\x14\x13\xbc\xb6\x2e\x9b\x3f\x25\xf0\x06\x7d\xbf\xba\xf0\xf5\xae\x64\x16\xd6\x27\xa8\x05\x7a\x67\x3e\x41\xd2\x49\x24\x48\xae\x92\x41\x90\x74\x52\x07\x92\xab\xe7\x0c\x54\x04\xe3\x31\x8a\x71\x97\x64\x7c\x25\x9a\x71\x97\x68\xbc\x0b\xd5\x46\x39\x48\xe5\x6a\x96\x46\xca\x45\xb5\x94\xda\x6c\x96\xf4\x9c\xc1\x62\x5e\x6d\xce\x06\x56\x88\x1a\x07\xf0\xde\xec\xbb\x23\xe0\x8b\xad\xce\x7c\x79\x81\x54\x9d\xf1\xdd\x88\x17\x62\x80\x5d\x5b\x6c\x40\x06\xca\x60\x07\xf2\xa3\x0c\x7a\xe1\xb3\xdd\x04\x5e\xcd\x78\xc5\x86\x25\x3b\xcc\x1a\x34\x60\x4f\x4b\x31\x05\x99\x9f\x9f\x2e\xa0\x73\x06\xb3\xaa\x39\x58\x87\xd9\x53\xd4\x46\xd2\xc6\xca\x3b\xce\x49\x74\x1c\x1d\x29\xb5\x33\x14\x0b\x22\xf1\x57\x87\x9e\x8d\xf4\x5c\x75\x9f\x68\x75\xe7\xcb\x0b\x6b\x5c\x6a\xe5\xd6\x2b\x63\x9c\x63\xea\xc9\x2b\x21\x85\x57\x6f\x36\x36\xda\x5f\x6d\xa4\xae\x1d\x41\x0f\xec\x95\x40\xd9\x8e\x80\xf4\xed\x4e\xdf\x5c\x4d\x0d\x1c\x6e\xb5\xed\x51\x00\x5d\x9a\x08\xb9\x04\x30\x3d\x74\x6d\x96\xbf\xda\xe0\xb6\x3a\xde\xa6\xba\xd4\xaf\x57\x1b\xec\x92\xa3\xaa\xfb\xa4\xa9\x0b\x72\x74\xaa\xf7\xfa\x7c\x05\x16\x25\x9f\x13\x11\xaa\x3e\xae\xe5\xaf\x36\x81\xf2\x05\x68\x32\x51\xb4\x35\x57\x83\x15\x7e\x75\x3f\xd8\x36\xbd\x01\x68\x4f\x1a\x68\xd2\x6b\x48\x68\x4f\x7a\xd0\x9e\x8e\x43\xfb\x43\x8d\xaa\xe3\x0a\x1d\xfa\x89\xfa\x2e\xd1\xa2\xa6\x68\xa7\xd9\xde\x8b\xd9\x12\x3d\x2f\x1d\x9a\x2d\x50\xd6\x6f\x3e\xe2\x7b\xda\x57\x19\xca\x35\xdf\x3f\x59\xe5\x3b\x9c\x6b\xc0\xba\xd4\x58\x54\x92\x1a\x34\xe6\x90\xea\xda\x4f\xda\xda\x76\x97\x04\x83\xc5\x6c\xf9\x4c\x46\x29\x47\x9d\xf5\x30\x9d\x2e\x6b\x67\x5f\x2c\x21\xd0\x73\xb8\x78\x31\x81\x6e\x51\x8c\x2e\x3c\x68\xb6\x32\xa9\x3b\x7d\xff\x7e\x4b\x24\xa8\x76\xdd\x3f\x78\x4a\xd3\x27\xe8\x8e\x56\x6e\x53\x74\xd4\x35\x9d\x06\x86\x11\xf8\xd3\x1d\x81\x77\xd7\x3c\xda\xee\x6e\xb5\xe2\xd1\xef\xb2\xa2\x4a\x03\x03\xab\x1d\x43\xe2\xa2\xe0\xca\x3d\x7f\x3a\x82\xe3\xc9\x8e\x38\x5c\x63\xdb\x8a\x2d\xd6\x67\xcb\xb5\x53\x4b\xc0\xfd\x3e\x2f\x9f\x48\xc3\x78\xf5\x46\x5b\x50\x6c\xf5\xd0\x3a\xe6\xc9\x86\xdb\x0c\x7c\xaa\xe6\xd8\xe8\x67\xf5\x1f\x67\x25\x62\x15\x0c\x81\xe0\x2f\xcd\x31\xe1\x2b\x0f\xfa\x60\x4c\xda\xda\x4c\x8e\xbc\xc6\x01\x18\xeb\xbd\xf2\xea\xee\xc8\xda\x36\x93\x7f\xe5\xd5\x9d\x51\xf5\x2c\xe3\xd6\xe1\x21\x7a\x38\x73\x39\xbf\xed\x87\xf5\x2b\x0e\x19\xe3\xae\x11\x69\xee\xab\xf6\xc3\xcd\xb8\x32\xa2\xdc\xbb\xb9\xd4\xba\xd5\xab\x46\xe1\xb6\x6f\xb2\xc1\x4d\xa3\x89\x16\x84\xec\x6d\x33\x00\x4a\x00\xa4\x07\x80\x0c\x00\x38\xb9\x28\x62\x8f\xd5\xf2\xc2\xc1\xc4\xb9\x66\x0d\xaf\x5a\xd3\x78\x87\x26\xbf\x2b\xf2\xe5\x0f\x37\x6b\x62\xe0\xab\xcb\x7f\xcc\x35\xab\x79\xd5\x9a\x90\x0e\x11\x7e\x68\x21\xce\x97\x17\x9f\xbe\x40\xfb\xdd\xd2\x34\x23\x19\xc8\xdb\x6a\x69\x9d\x65\x48\x31\xbe\xf5\x16\x33\xa1\x7c\x74\xd2\xd6\x81\x62\x33\xc4\x4e\xbc\xd2\x6d\x21\x4c\xd2\xb1\xd9\xf1\xcf\x75\x2c\xca\xb0\x48\x73\xed\xa7\xa2\x06\xf5\x9b\x15\x1f\xd1\x6e\xb8\x0c\x74\x1b\x16\xaf\x86\xeb\x40\x57\x3d\x4b\x85\xaf\x72\x94\x0a\x0e\x49\x65\xbc\x9c\x77\xcf\x3b\xe1\x3d\x74\xd8\xa5\x7f\x0f\xdd\xee\xff\x00\xc8\x61\x83\xa6\x39\xcd\xf5\x4f\x72\x08\xea\x93\xd7\xf0\xf4\x65\xc6\x9a\x78\xe3\x1a\x24\x3a\x34\x8a\x5e\xaf\x52\xaf\x02\x0e\x61\x1e\x1a\x0f\xd3\xbd\xfc\xaf\x73\xce\x7f\xe1\x43\xa0\x33\xb6\x9e\xd5\xca\xbd\xd5\x5b\xf4\x03\x2a\x3e\x65\xb1\x70\x7c\x4d\x68\xfb\x90\xde\x16\xce\xef\xbe\x86\xd8\xe2\xb3\xaf\xca\x69\xa1\xa1\x5a\x98\xd3\x03\xce\x9d\xd6\xe6\x34\x50\x6a\x79\x4e\x07\x75\xd5\x75\xc5\x96\x15\xee\x4e\x3c\x19\x74\xe2\xc9\x55\x3b\xf1\x64\xd0\x89\x27\xbb\x75\xc2\x2c\x2a\xa9\xba\xca\xc8\xaa\x25\x5a\xf1\x6a\x55\xf2\x0f\xdc\x70\x00\x11\xa9\xcb\xdd\xd2\x1f\x9c\x9d\xaf\x67\x35\x19\x26\x16\x19\x6a\x3e\x1d\xd6\xfc\xf4\xf4\xc4\x86\xdb\x43\x0d\xea\xe9\xd0\x84\xad\xf7\x89\xae\xe9\xd4\xa4\xdd\x7f\xa9\x23\x94\x06\x77\xd6\x5c\x76\xda\xc2\x43\x6c\xb9\x99\x53\x7f\x6c\xcf\x67\x3a\xd9\xfe\xe5\xb8\xe6\x15\x8f\x6b\xfa\xbb\x1e\xd6\xf4\xc7\x8e\x6a\xfa\x8e\x83\x9a\xfe\x97\x63\x9a\xd7\x7d\x4c\xd3\xdf\xf2\x90\xa6\x41\x2c\x9d\x23\x9a\xfe\x36\x07\x34\x7d\xfb\x35\xfc\xe6\xe0\xe1\x5d\x1a\x7c\x7c\x3b\xa5\xf8\x5f\xe4\xb8\x66\x3f\xc1\x4e\x88\xc9\x1f\x76\x86\xb3\x4e\xb7\x23\x70\xfe\xb9\xd2\xed\x5c\xe9\xb4\xa5\x2a\x6e\x4f\x7b\xd6\x75\x76\x4a\xc8\x13\x62\xd2\x39\x16\x12\x62\x62\x3d\x66\x42\xb7\x4c\xc8\x23\x2a\x76\x8e\x9a\x50\x95\xd5\x22\xc4\xe4\xda\xae\x10\xeb\xdd\xb7\xe6\xe4\x19\x1c\x72\xf0\x36\x59\x9a\xa6\x49\x1e\xe6\x53\x2d\x61\xcf\xde\xd4\x54\x33\x22\x09\x23\x09\x61\x7a\x3a\x9f\x3d\x43\xde\x1e\x43\xd3\x04\x87\x89\x87\x43\xa6\x67\xff\x31\x23\xc1\x21\x29\x78\x26\x73\x06\xd5\xb9\x81\xb6\x44\x12\xc5\xbe\x4f\xa2\x48\xa6\x15\x52\x99\x83\xcc\x48\x28\x4f\x83\x80\xd1\x58\xcf\x2b\xb4\x25\x92\x3c\xf5\x32\xc2\xbd\x5c\x4f\x43\x64\x46\x12\xc4\x69\x18\x50\x9c\xeb\x49\x8a\x7a\xa1\xe9\x75\x67\x29\x12\xfa\x74\xc5\x2c\x45\x38\xfa\x92\xa6\xe8\x9a\x62\x22\xba\x73\x9a\x22\xd1\x64\x2c\x2e\xd2\x7d\xc6\x30\x32\xa2\x5f\xd2\x14\x5d\x7f\x6c\x44\xb7\x4d\x53\x64\x14\x4e\x37\x3e\xa2\xa3\x69\x8a\x7c\xea\x4e\x53\x24\x86\xf1\xbb\x94\x98\xa2\x25\xf2\x2f\x12\x2d\xfd\x4b\x5f\x6e\xb9\xde\x8b\x2d\x9f\xe9\xca\xca\xd5\x83\x28\x59\xd4\x74\x57\x01\xfa\xa9\x3e\xc1\x6b\x78\xeb\xa6\x7b\xc8\xf7\x80\x9d\x9d\xcd\x2f\x27\xea\xc7\x29\x62\xab\x93\xf3\x53\xbe\xa8\xd6\xfd\x37\x79\xf4\xeb\x33\x2d\x3d\x90\x4a\xa9\x45\xd1\x43\xef\x6d\x02\x42\x19\x29\x12\x88\x2b\xf2\x98\x50\xc6\x09\xd9\x9b\x0e\xeb\xc5\xd8\x8f\x83\x20\x81\x34\x83\xc4\xe7\x45\x14\x66\xb9\x1e\x1a\x0c\x1a\xa4\x61\xe6\x15\x69\x56\xc0\x03\x08\x59\x90\xfb\x29\x29\x4c\x80\x79\x92\x86\x79\xca\x42\x78\x3d\x1b\xd3\x24\x4f\xd3\xcc\x09\xd8\x4f\xc2\x28\x23\x61\x0a\xe1\x8c\x1f\xd0\x34\xf4\xa9\x09\x70\x98\x14\x18\xe3\x02\x28\x4e\x23\x2f\xcc\x3d\x9c\x38\x01\x27\xc4\x2f\x28\x61\xf0\xe4\x36\x2b\x70\x12\x14\x49\x6a\x02\xcc\x52\x9c\x85\x3c\x07\x8a\x73\x16\xe5\x14\x63\xea\x04\x9c\x53\x2f\x66\x4c\xf2\x98\xf9\x9e\xef\x91\xc0\xc8\x63\x4c\xa8\x1f\xa6\xf2\xcd\x88\x20\x8c\xbd\xa8\x48\xb9\x13\x30\x09\x7c\x4c\xc3\x14\xde\x8e\x08\x38\x0f\x52\x42\x33\x23\x2b\x42\x2f\x8b\xf3\x0c\x1e\x10\xcf\xc3\xa2\x48\x03\x4e\x9c\x80\x63\x92\xf2\x30\x8f\x81\x15\x05\x89\x53\x9a\x44\x46\xe1\x51\x2f\xe7\x29\x96\x8f\x57\xf8\x29\x8e\x92\x28\xc5\x6e\x1e\xa7\x79\xe6\x45\x32\x43\x25\x09\xb3\x18\x13\x3f\x34\x01\xce\x70\x92\x16\x58\x12\x90\x15\x51\x42\xa2\x24\x70\x02\xe6\x41\x92\x46\x49\x06\xbc\x4b\x78\x81\x03\x96\x1b\x79\xcc\x8b\x94\x07\x31\x85\x67\xc4\x7d\x1a\x14\x24\xe4\xbe\x13\xb0\x57\x64\x38\xc9\x33\x68\x40\x53\x9a\xe5\x61\x6a\xa4\x98\x04\x5e\xc6\x70\x96\xc1\x23\xed\x31\xcb\x92\x2c\x0a\xdd\xc2\xcb\x79\x42\xb2\x08\x0c\x24\x4c\x48\xea\x91\xd8\x08\x38\x60\x71\x40\x03\x06\x73\x84\x88\xb3\x88\x07\xd4\x4d\x71\x98\xa5\x1e\x4b\x72\xa0\x24\xcd\x03\x5c\xa4\x79\x60\x34\xe9\xa8\x48\x28\xcd\x01\x30\xf5\x31\x0e\xfd\xd4\x4d\x71\x42\x7d\x1e\xe2\x90\x80\x49\xf3\x28\xca\x0b\x66\x36\x10\xea\xe3\x2c\x8a\x20\xc2\x27\x79\x1a\xf8\x04\x7b\x6e\x5f\xe1\x79\x3e\x89\x33\x2a\xdf\x7c\x2f\x52\x82\x7d\xa3\xba\xa5\x45\x98\xc4\x45\xa6\xf2\x9b\xf2\xc2\xe3\xdc\xad\x15\x59\xc4\x3d\x2f\x2d\x40\xf1\xfd\x9c\x51\x5a\x64\x46\xad\xc8\x43\x16\x27\x38\x00\xc0\x89\xef\x31\x16\x13\x37\x2b\xbc\x28\x63\x91\x1f\xca\xe7\x5d\x3c\xcf\xa7\xc4\x6c\x20\x38\x20\x09\x49\xe4\xdc\xcb\x63\x1e\x8f\x78\xec\x66\x05\x89\xd3\xd8\x63\x14\x9c\x4b\x10\xe5\x84\x14\x85\xd1\xa4\x09\xc7\x82\x4d\xc0\xb2\x30\x23\x51\x96\x90\xc8\x09\x38\xc8\x49\x16\xe5\x05\x68\x45\xc8\xb2\x80\x30\x9e\x1b\x7d\x85\xef\x53\x2f\xc7\xc0\xb2\x24\x4f\xc2\xd4\xcf\x0b\x27\xe0\x28\xf4\x58\xec\x87\x81\x34\x10\x56\x44\x7e\xce\xcd\xea\x16\x31\x8f\xa5\xe0\xb7\xfd\x2c\x8e\x53\xc2\xdc\x6e\x93\xe2\x8c\x64\x09\x91\xde\x2d\xe6\x39\xe3\x3c\x32\x01\x4e\x48\x4c\x48\x26\x59\x86\x03\x4a\xfc\xd0\x4f\x9d\x80\x19\x49\x0b\x4e\x99\xf4\xb3\x59\x81\x3d\x3f\x32\x1a\x08\xa3\x98\x45\x51\x00\x14\xa7\x59\x40\x7c\xcf\x73\x7b\xb7\x8c\x04\x29\x4d\x63\x0f\xfc\xac\x57\xd0\x24\x4e\xb0\xd1\xbb\xc5\x51\x16\x62\x06\x3c\xf6\xa2\x30\x48\xb9\xef\xd6\x8a\x1c\x27\x84\x53\x9c\x00\xe0\x88\x17\x21\xc1\xc6\x31\x2f\x8f\x92\xc4\x8b\x08\xc8\x22\x0c\xa3\x90\x25\x23\x96\x57\x04\x1e\xf7\x43\xc9\xbb\x30\x8e\x31\xf1\x08\x33\xea\xb1\x17\x31\xe6\xc9\x9e\xf9\x24\x4d\x73\x9c\xba\x85\x87\x13\x16\x64\x18\x83\xdb\x4c\x69\x4e\x72\x2f\x33\x52\x8c\xb9\x1f\x47\x99\x27\xf5\x18\x07\x98\xa5\xa1\xdb\xbb\x91\x38\xa0\x71\x1c\x80\x1e\xe7\x05\xe5\x3c\x4d\x12\x13\x60\x3f\x48\xbd\x34\x4b\xa1\x67\x1c\x27\x69\x40\x47\xd4\xcd\x4f\x70\xe6\x65\x29\x08\x25\x0b\xb3\x24\x64\x91\x6f\xf4\xc7\x3c\xa7\x8c\x05\xe0\x36\xb9\x1f\x60\xca\x32\xb7\xba\x85\x69\x92\x65\x2c\x28\xe4\xc8\x10\xf9\xdc\x8f\x8d\x80\x23\x4a\x78\x54\x48\x67\x95\x47\x29\x49\x29\x73\xb3\x22\x0e\x68\x41\x09\x07\x03\x09\x73\x5e\xa4\xc4\xec\x2b\x62\xca\xc2\xc8\x97\x23\x4d\xe0\xe3\x98\x14\x91\x5b\x2b\x68\x90\xd1\x98\x62\x19\x09\xe1\xc2\x63\x69\x6c\x74\x9b\x34\xcb\x62\x8f\x48\xe1\x61\x16\x05\x7e\xc2\xdd\xb1\x5b\xe2\xa5\xbc\x28\x0a\x26\xa3\xc8\xc8\xc7\x9c\x18\xb5\x82\x05\xa1\x17\x65\x1c\x2c\x2f\xe7\x94\xa4\x39\x77\xc7\x6e\x29\x2f\x12\xe6\x17\x72\x64\x20\x59\x14\x27\xd8\x1c\x57\x44\x31\x8e\x69\x21\x87\x30\x3f\x26\xa1\x4f\xdc\xc2\xcb\x18\x89\x7d\x9e\x01\x8f\x39\x23\x51\x84\x13\x23\x8f\x73\x4c\xa3\x94\xca\xa1\x89\x08\x45\x22\xdd\x45\xc0\x61\x20\xc2\x72\x16\xe7\x39\x18\x48\x96\x73\x8f\xa7\xd8\xe8\x36\x8b\x30\xce\x83\x22\x2e\xd4\xa0\xcb\x73\x1c\xbb\xf5\xd8\x8b\x0a\x2f\x8a\x65\xbc\x10\x13\x1c\x47\x45\x6a\x34\x69\x8f\x45\x7e\x9c\x67\x60\x20\x8c\x64\x34\xa1\xcc\x3d\x82\x60\xec\x17\x09\xf5\x02\xb5\x70\x97\x78\x39\x33\x52\x8c\xd3\x18\x7b\xa9\x2f\xfd\xb1\x8f\xb3\x20\xc6\x6e\x1e\x13\x9a\xa7\x71\x5c\x84\x52\x2b\xbc\x20\xce\xa9\xd1\x1f\xfb\x24\x63\x2c\x8d\x41\x2b\x02\x2f\x8b\x49\x90\xb8\x0d\xc4\xcf\x12\x9e\x72\x0f\x58\x81\xc3\x2c\x49\x79\x6a\x14\x5e\xe0\xe3\x3c\x8a\x33\xe8\x59\x92\x61\xcf\xcb\x03\xb7\x1e\x07\x59\x16\xe6\x81\x0c\xbc\xb3\xd4\xe7\x01\x49\x8d\x43\x93\x08\x57\x48\x92\x80\xb3\x2a\xb2\x28\x8c\xb9\x70\xaf\x2e\x5f\x51\x64\x69\x54\x30\x39\x48\xb2\x3c\x2a\x18\x37\x52\x1c\x65\x41\x80\x13\x0a\x80\x03\x16\xc4\x21\xc5\xb1\x5a\x44\x7d\xeb\xb8\xb6\xda\xce\x0b\x7f\xbc\xea\x0d\x55\xdb\x33\x68\x3f\x76\x6e\xa8\xfe\x74\xb5\x1b\xaa\x21\x26\xdb\x6d\x1d\x18\xb6\x23\xae\x3f\xfb\xe8\x55\xb7\x0e\x22\xe6\x25\xbc\x5e\x70\xf7\xd3\x2c\x4b\x3c\xcb\xd6\x41\x9a\x46\x31\xe3\x72\xf8\xa5\x41\xc6\x58\xdc\x0d\x5d\x1c\x48\xfc\x2c\xe2\x85\x1f\x83\x27\x2b\x78\x12\x14\x54\x78\x32\x53\x4d\x16\x06\x45\x11\xfa\x60\x05\x61\x81\x73\x3f\x2a\xb6\x5d\xd5\x0f\xb1\xc7\x43\x22\x9d\x0f\xcb\x79\x44\x49\x6e\xd9\x3a\x48\x52\x2f\x8c\xa8\x54\x48\x92\xfa\x3c\xca\x70\xb1\x25\x12\x5c\x50\x3f\x4f\xa4\xce\x17\x69\x80\xd3\x3c\xb2\xf4\x24\x4c\xb9\x97\xe5\x32\x0c\xc2\x7e\xcc\x09\x8e\x93\x5d\xb6\x0e\xae\xfb\x1e\xe9\x36\xa9\x61\xa1\x9e\x67\xcf\xfc\x7a\x8c\xed\xa9\x5f\x8f\x89\x3d\xf7\xeb\xb1\x6f\x4f\xfe\x7a\x1c\xd8\xb3\xbf\x1e\x87\xf6\xf4\xaf\xc7\x91\x3d\xff\xeb\x71\x6c\x49\x00\x2b\x3b\x08\xe9\x61\x8d\xe7\xc0\x65\xf9\x5c\x96\x0f\x2f\x7b\x48\x1e\x40\x73\xe3\x15\x28\x59\x3e\x97\xe5\x96\xe6\x04\x9a\x13\x6b\x73\x32\x97\xe5\x96\xe6\x3e\x34\xf7\xad\xcd\xfd\xb9\x2c\xb7\x34\x0f\xa0\x79\x60\x6d\x1e\xcc\x65\xb9\xa5\x79\x08\xcd\x43\x6b\xf3\x70\x2e\xcb\x2d\xcd\x23\x68\x1e\x59\x9b\x47\x73\x59\x6e\x69\x1e\x43\xf3\xd8\xda\x3c\x9e\xcb\x72\xc3\xb1\xbe\x2d\x93\x1e\x4b\xcd\x30\x01\x67\x52\x29\xfa\x19\xf7\xe0\xc8\xad\x54\x08\x53\xab\x54\xea\x82\xa9\x55\x26\xf5\xc0\xd4\x2a\x93\x2a\x60\x6a\x95\x4b\xf1\x9b\x5a\xe5\x52\xf2\xa6\x56\x5c\x4a\xdd\xd4\x8a\x4b\x81\x9b\x5a\x15\x52\xd8\xa6\x56\x85\x94\xb3\xa9\xd5\x89\x94\xb1\xa9\xd5\x89\x14\xaf\xa9\xd5\x4c\x8a\xd6\xd4\x6a\x26\xa5\x3a\x37\xe5\x1d\x74\x5d\xdd\xdd\xf2\x39\x54\x6b\x3e\xed\x1a\xff\x8f\xa5\xcc\x3d\x6c\xbb\x6e\xfe\x08\x46\xf0\x7a\xfb\x6c\x58\x65\x8b\x44\xd1\x12\x8d\x60\xc1\x8f\x65\x7d\xdb\x40\xcf\x1a\x8d\x6e\x23\xf2\x16\x6a\x9a\x73\xb9\xb6\x30\xe6\x12\x86\xba\x5f\xd0\x87\x01\xb7\xe6\xaf\x94\x81\xfa\xf0\x10\xfd\x07\x64\x23\xb6\x23\xaf\x53\x3a\xef\x94\xa1\x7a\x33\x6b\xf2\x1c\x6f\xc6\xee\xe2\xa9\x6a\x73\xad\x85\xfb\x3e\x9e\xac\x35\xeb\x64\xc1\x9e\xc9\xe4\xbf\x7a\xf2\xea\x39\xa4\x28\xae\xd3\x01\x77\xea\xd1\x41\x3d\x38\xf4\xfa\x0e\x75\xab\xc5\xae\x1b\xa6\xb2\xe6\xbc\x43\xc5\x7c\x48\xc5\xcc\x44\xc5\x7c\x48\xc5\x4c\xa7\xa2\x5b\x2f\x1e\xd6\xb3\x64\x32\xd6\x45\x6a\xc9\x99\xf3\x41\xcb\xbd\xbd\x4b\xf2\xed\x56\xa2\x78\x3b\x89\xe2\x56\xa2\x78\x2b\x89\xe2\x59\x27\xc1\xf7\xac\xce\xc2\xad\x25\xe6\x9e\xab\x5c\xdd\x1a\x93\xb0\xe2\x70\xb7\x1a\x9c\x63\x4e\x34\x91\xd6\xf0\xa2\x51\x91\xe2\x79\x87\x8c\xb9\x81\x8c\x99\x89\x8c\xf9\x80\x8c\x59\x87\x8c\x2e\xc0\x68\x00\x8f\x44\x4e\x99\xee\x94\x3b\xdc\xe5\x4a\xe2\x56\xec\xb1\x4b\xec\x3f\x96\xb1\xf4\x5c\xc6\x81\xb9\x57\x73\xae\x6a\x3a\xee\x84\xcb\x9a\x38\xd2\x1c\x89\xf5\x55\xe8\xba\xae\x24\x00\x1b\x23\x8b\x7e\xdd\x79\x5d\x77\x94\x86\xd6\xd3\xcc\x05\xd3\xca\xb8\x3f\x72\x75\xab\xb7\xae\x6c\x26\xab\xcf\x20\x67\x9b\x80\x23\x24\xe9\xed\xa1\xfb\xb5\x75\x36\xbf\xfc\xff\x08\xa3\xbb\x68\x70\x6c\x7a\x48\x87\xf8\xb7\x96\xe0\x38\x19\xe2\xdf\xfd\xc6\x5a\x2c\x54\xe0\xab\x52\x01\x5c\xdc\x92\x06\x29\x9d\x21\x05\x52\x12\x03\xfc\x66\xa0\xed\xa8\xf8\x63\x69\x13\x6f\x3b\xea\xfd\x58\x9a\x88\xb3\xe7\xc4\x57\x49\xf1\x67\xe8\x26\x2a\x66\x2a\x2d\xbe\xf8\x62\xbe\xc7\x27\xdb\x48\xdb\xe7\x73\xd1\x66\xae\xda\x88\x2f\x27\x73\x47\x32\xfd\x19\x64\xd3\x17\xa0\x53\x89\x07\x3e\x67\xf2\x73\xaa\x3e\xdb\x9b\xcf\xa1\xb9\xc0\x92\x4a\x94\xf0\x39\x93\x9f\x53\xf5\xd9\x9d\x92\x7f\x26\x73\xf2\x2b\x87\x23\xc7\x15\x36\x97\xe9\xa5\xf7\x64\xf2\x03\x36\xab\x33\xf6\xab\xc2\x4e\xce\xfe\x99\xf6\x8a\x04\xab\x47\x1d\x67\x66\x7e\x98\x4d\x4d\x1a\x40\x0a\xe7\xac\x8b\x73\xde\xc1\x39\xeb\xe2\x9c\xeb\x38\x67\xdb\xe0\xc4\xb2\x9f\x5c\x0d\x0d\xf2\xbe\x09\x97\x83\x02\xad\xd3\xfe\xcf\xea\x47\x2b\xb4\xc2\xa0\x2d\x14\x38\xfd\xba\x4c\xa6\xe1\x76\xe3\x94\xfd\x54\x95\x6b\x9c\xb3\x2e\xce\x79\x07\xe7\xac\x8b\x73\xae\xe3\x9c\xb5\x38\x8d\x51\xe7\xf8\x3b\x04\x66\x5a\xbf\x87\xec\x4b\xdf\xdb\x2f\x53\x7d\x0f\xc6\xfb\x7d\xe9\xba\x46\xf5\x3d\x38\x83\xef\x4b\x9b\x0b\xfd\x00\x0f\x25\x88\x3a\xb3\x79\x43\xa2\xc9\x28\x65\x45\x81\x70\xd6\xf6\x45\xba\x8b\x0a\xeb\xee\x62\xb6\x8d\xaf\x6a\xd1\x8a\x7f\x05\x47\xdc\x38\x2b\x40\x95\xcd\x4c\x08\xb3\x2b\x61\xfc\xde\xe8\x7a\xfa\x18\xbf\x2f\x4d\x18\xbf\x2f\xaf\x82\xd1\xec\xec\xfa\x18\x7f\x34\x62\xfc\xd1\x84\xd1\xac\x6d\xfd\xc7\x2b\x2c\x28\x61\xf1\xa2\x36\x7b\xa8\x68\xa5\x0e\xd6\x41\x6a\xaf\xb4\x2f\xdd\x23\x90\x48\x74\x12\x6b\x58\xdb\x91\xf9\xf7\xb3\x9c\x55\x1c\x5d\xb8\x67\xfa\xe2\x0f\xe6\x9b\x46\xfd\x86\xe9\xe6\x89\x89\x6c\x18\x80\x0a\x53\x1b\x98\xd8\x16\xa6\x36\x30\x87\xe6\xa6\x36\x30\x85\xe6\xa6\x36\x30\x25\x9f\xe4\x73\x78\xbe\x63\x6e\x7b\xbf\x03\xe6\xf4\x93\x7c\x06\xb5\x24\xeb\xb8\xce\xb9\x7c\xc0\x34\xeb\x4b\x20\x02\x52\x66\xa2\x11\x96\x14\x32\x13\x8d\xb0\x7a\x91\x9a\xda\xc0\xe2\x45\x6a\x6a\x03\xeb\x24\xcc\xd4\x06\x96\x49\x06\xaf\x19\x88\x3f\x58\x76\x99\x48\x55\xaf\x88\x95\x19\xb0\x70\x33\x91\x7c\x10\x9a\xb5\xdf\x8e\x38\x92\x1b\xd5\x30\xd8\xb9\xd6\xc7\x4a\xb4\x35\x43\x88\x0c\x8e\x41\xff\xd9\x20\x1a\x38\x6e\x92\x51\x4c\x8e\x41\xef\x99\x24\xf6\xd8\xd3\xa9\x65\x43\x62\xfb\x70\xb4\x55\x46\x89\x10\x58\x94\x0e\x11\xe2\x16\x21\xb0\x27\x55\x08\x3b\x9e\x20\x1d\x47\xa8\xad\x4b\x4a\x84\x04\x5c\xec\x10\x21\x69\x11\x92\x59\x3d\x2e\x4d\xa0\xbe\xe6\x5e\xc7\x11\x6a\x2b\x99\x12\xa1\x2f\x10\xe6\x43\x84\x7e\x8b\xd0\x17\xb8\x72\x85\xd0\x1f\x31\x87\x3e\x1c\x6d\xed\x53\x22\x0c\x04\x42\x3e\x44\x18\xb4\x08\x03\x81\x8b\x2b\x84\x81\x8e\x90\x8f\x23\xd4\x56\x4b\x25\xc2\x50\x20\x2c\x86\x08\xc3\x16\x61\x28\x70\x15\x0a\x61\xa8\x23\x2c\xc6\x11\x6a\xeb\xab\x12\x61\x04\x93\x8a\x21\xc2\xa8\x45\x08\xd1\xfb\x89\x42\x18\x75\x26\x11\xe3\x08\xb5\x15\x59\x89\x30\x16\x08\x67\x43\x84\x71\x8b\x10\xa6\x4d\x6a\x4c\x16\xf5\x5d\x41\xc0\x27\xdf\xbd\xf8\xf2\x28\xce\xf5\x3d\x8a\x83\x45\x70\xaf\x5e\x36\x13\xc0\x20\x0f\x8b\xef\x5d\xf7\xb3\x38\x66\x34\xf8\x9f\xf2\x61\x9c\x87\xcb\xc5\x07\xbe\x92\x59\x7e\x51\xb5\x44\x3e\xb9\x93\x96\x95\x08\x50\x72\xc4\xe0\x7c\x76\xca\x8b\xe5\x8a\xab\xe3\xd4\x03\xa9\x69\x77\x4d\xb4\xbd\xbb\x6a\xf9\xda\x27\xd7\xf1\x10\xcf\x9f\xf5\x09\x1e\x9d\xce\x26\x3f\xc8\x5d\x84\x3d\x12\x1c\xfa\x2a\x4f\xf1\x97\xdb\x4d\xd6\xab\x4a\x21\x26\xbb\xde\x6e\x12\x4d\x46\x6e\x37\x75\x8e\x35\x0c\x6e\x37\x85\x98\x7c\xb9\xdd\x74\xdd\xb7\x9b\x84\x54\xb6\xbb\xdd\x64\x14\x4e\xe7\x76\x93\x14\x90\xf3\x76\x93\xbc\x47\xbb\xe5\xed\x6f\xff\x4f\x7d\x9f\x89\x2f\xb2\x3b\x29\x5b\xf3\x28\xe8\x15\x9c\xe6\x61\xbf\xea\x87\xb3\xf7\x79\xd1\xfb\x31\x2b\xcf\x66\x7c\xf5\x87\x5c\x89\xd2\x48\x85\xef\x82\x42\x59\x20\x09\x83\xcf\x3a\x3d\xff\x0a\x57\xa7\x7e\xdc\xea\x4d\x20\x38\x3c\xf3\x10\xba\xde\xd4\xd3\x7e\x1b\xbf\x0a\x75\x78\x88\x9e\xf3\xd5\x29\x8c\xa2\x0f\x67\xcb\x32\xe3\x08\xf7\x9f\x4d\x11\xcd\x9f\x3f\xc4\xdd\xbb\x4b\x61\x3c\x45\x41\x32\x45\x01\x9e\x22\xdf\x9f\x22\x12\x4e\x11\x8e\xa7\x28\x99\x22\x84\xb5\xa3\x46\x21\x9d\xa2\xd0\x9b\xa2\x80\x4c\x91\x1f\x4c\x11\x89\xa6\x08\xd3\x29\xc2\xde\x14\x11\xbd\x5e\x32\x45\x21\x9e\xa2\xc0\x9f\x22\x3f\x9c\x22\x12\x4f\x11\x4e\xa6\x08\x0b\xf8\x5a\xbd\xc8\x9b\xa2\x90\x4c\x51\x10\x4c\x91\x1f\x4d\x51\xe4\x4f\x51\x18\x4e\x51\x10\x4f\x91\x9f\x68\x15\x7d\x3c\x45\xc4\x9f\x22\x1c\x4e\x51\x3c\x45\x28\x22\x53\x14\x06\x53\x14\xc0\xd3\x02\x7a\x45\x41\x09\x99\x22\x1c\x4c\x51\x24\x2a\xe2\x29\x0a\xfd\x29\x0a\xc2\x29\xf2\x63\xad\x22\x49\xa6\x88\xe0\x29\xc2\x02\xe5\x14\x21\x42\xa7\x88\x78\x53\x84\x05\x39\xb2\xda\x5b\x07\x5f\x89\x99\xaf\xa4\xcb\x57\x41\x85\xe0\xa3\xe8\x37\x11\x9f\xa7\x08\x85\x3a\xb5\x0a\xb1\xe8\x96\xa0\x16\x08\xf2\x74\x2a\x7d\xc5\x38\x41\x95\xa8\x10\x4d\x91\xde\x5d\x1c\x49\x7e\x08\x06\x03\xf5\x7e\x57\x10\x42\xa0\x82\xc1\x82\x7f\x7e\x2c\x19\x1b\x86\x3d\x7e\x05\x9e\x92\x56\x28\xa5\x1f\xe8\x18\x84\x68\x84\x6a\xf8\x42\xa4\x91\x14\x7b\xa8\xcb\x50\x88\x40\xe8\x83\xd0\x0b\x21\x43\xc1\xd8\x3a\xaa\xe9\xbc\x08\x75\x7e\x7a\x3e\x67\xf0\x4c\x8a\x08\x2a\xd7\xb3\xb2\x18\xbc\xf0\x04\x56\xf0\xdd\xab\x9f\x5e\x1e\x7f\xf7\x58\xbe\x29\x25\x38\x46\xa6\x08\x3a\x2f\x38\x44\x85\x46\x2a\x31\x01\x77\x95\xa6\x62\x25\x4e\xa2\xb4\x17\x18\x42\x75\xfc\x2f\xbf\x79\xf6\x9a\xaf\x11\x5b\xe4\x2a\x37\xfa\x19\x88\x54\xbe\xa7\x61\xa0\x43\xd4\xff\xe9\x79\x57\x9e\xbd\x90\xd2\xdb\x78\x77\x61\x32\x42\x89\xe7\x4d\xfb\x65\xf5\x5c\x41\x56\x31\x54\x20\x9d\x0a\xd4\xf3\xc8\xa0\x8a\xaf\x55\x19\x96\x06\x7a\xa9\x01\x41\xd8\x45\x40\x0c\x08\xa2\x2e\x91\xa6\x2a\x71\xaf\x1f\x06\x44\xb4\x43\xc8\x10\x44\xd2\xc7\x32\x04\xc1\xf4\x2a\xa6\x0a\x69\x9f\x5b\xc3\x2a\x59\x0f\xcd\xa0\x42\xde\xef\xca\xb0\x0a\xd7\xaa\x0c\x31\x14\x5d\x2a\x87\xcd\xa9\xab\x35\xa6\xa3\xf2\x20\x74\x04\x81\x4f\x47\xb4\x2a\xe8\x23\x31\xe8\x05\x75\xeb\x4d\x44\x47\x15\x33\xa6\x2e\xc5\xa4\x74\x54\xde\x09\x1d\x91\x37\xeb\x13\x61\x50\x89\x3e\x9a\x21\x25\x19\x1d\x95\x78\x4e\x47\xb4\x86\x53\xb7\x76\x17\x7d\x1c\x06\xc9\x5b\xc5\xa5\xbc\x04\x36\x33\x92\x68\xa5\x16\x61\xfa\x9d\x2a\x46\xec\x41\x17\x8a\xa9\x8f\xa1\x5e\xc5\xa8\x13\x3a\x9d\x86\xf2\xb8\x4b\x86\xc3\x36\xb0\x43\xfd\x93\x3e\xa5\x56\x47\x81\x1d\x12\x4d\xbb\x9d\x31\x68\x45\xa7\x33\x56\x3f\x81\x1d\xfa\xcb\x7b\x55\x6c\xae\x02\x9b\x5d\x01\x1d\x65\x05\xa6\xa3\xac\x20\x74\x54\xf4\x3e\x75\x8b\x2d\xe8\x81\xb0\xf9\x0a\x17\xbb\x23\xea\x52\xe1\x98\x8e\x08\x83\xd2\x11\x4e\x26\x74\x54\xb5\x18\x75\x0b\x34\xed\xf3\xdb\x30\x78\xf4\xb1\x0c\xab\xe4\xd4\x25\x52\x4e\x47\x4c\xa8\xe8\x4b\x54\x7f\xa3\x6a\x3a\x16\x65\x04\x9e\x47\x03\x0f\x5b\x3d\x88\xaa\x63\x0d\x33\x1a\x01\xda\x3c\x48\x8d\xc4\x33\x21\x09\xba\x48\x8c\x75\xc2\x2e\x1c\x23\x31\x51\x17\x8e\xb1\x4e\xdc\xd6\x31\x60\xd1\x9d\xad\xb1\x79\xd2\x47\x61\x00\xc2\xfa\xdd\xb1\x07\x1c\x0a\x91\x01\x48\xd6\x61\xac\xa1\x42\xde\x56\xb0\x3a\x10\x49\x82\xa1\x71\xd1\x97\x8a\x35\xee\x72\x32\x13\xd3\x91\x5e\x10\xea\xe2\xb6\xdf\x47\x61\xd2\x0d\xda\x93\xbb\x49\x37\xe8\x38\xc3\x23\x3a\xa2\xa8\x31\x1d\x57\x54\x4a\x47\x84\x92\x50\x87\x50\x18\x75\xdb\x52\xda\xa7\xc0\xee\x48\x9c\xa6\x92\xd3\x11\x25\xe6\x7d\x9e\xda\xfd\x89\x55\x83\xf4\x09\x88\xa1\x14\x6f\x61\xf6\x98\x6c\x61\x4c\xd8\xdf\xc2\xf0\x71\xb0\x85\x3e\xe3\xd0\x69\xfa\x38\x1a\x33\x49\x1c\x8f\x38\x43\x3d\x04\x37\x43\x48\xc6\xdc\x25\x66\x63\x76\x8f\xd3\x2d\xbc\x25\xce\xc6\x1c\x19\xce\xb7\x70\x96\x98\x6f\xe1\xca\x70\xd1\x97\x90\x51\x5d\xc6\x5c\x05\xc6\x63\x16\x8a\xc9\x16\x06\x82\xfd\x11\x2b\xc3\xc1\x36\x8e\x2d\xdc\xc2\xed\xe0\xc8\xe9\xdd\x70\xbc\x85\x5b\xc2\x74\x0b\x5b\xc4\xc9\x16\x56\x8f\xd9\x16\xde\x14\xa7\x63\x1e\x0c\x67\x2e\x17\x86\xf3\x31\xb7\xc0\xb7\x70\xa3\xb8\xe8\x79\xa8\x5d\x42\x15\xec\x05\x16\x67\x64\x26\x99\x74\xb8\x82\xad\x21\x8a\x84\x6d\x82\x1e\x68\xe5\x9e\xa1\x3c\xec\x09\x67\x58\x23\xea\x30\xcd\x84\x23\xee\xd4\x18\x1f\x8e\xed\xb1\x49\x8b\xc5\x16\x99\xd4\x3d\xb5\x45\x25\x2d\x15\x43\x3a\xb3\x1e\x37\x87\x35\xf2\x0e\xb7\x6c\xa1\x09\x40\xb0\x84\x25\xaa\xad\x99\x03\xae\xee\x61\x3a\x46\x3e\xa1\x76\x45\xf1\xe9\x98\xa2\x04\x74\x4c\xd0\x21\x75\x77\x3e\xa2\x6e\x55\x8a\xb5\xf2\x61\x29\xa5\x76\xd6\x25\xd4\xc5\x3a\x46\xc7\xd4\x2b\xa5\x6e\x23\xc8\xa8\x5b\x75\x72\x3a\xa6\x18\x9c\x8e\x19\x41\x41\xc7\x54\xbc\x13\x56\x58\x94\x00\x8f\x98\x2b\x26\x23\x1a\x8a\xfd\x51\x97\x81\x03\xa7\xa6\xe2\x70\xd4\xe0\x71\x34\xea\x35\x70\xec\xf2\xc4\x74\xd4\x12\x71\x32\xea\x32\x30\x73\x58\x23\x4e\x47\xdc\x05\xce\x46\xbd\x16\xd6\xdd\x81\x01\x05\x1f\xf1\xbd\xb8\x18\x75\x49\x2a\xb4\x70\x76\x13\x3b\xed\x0a\x93\x71\xd7\xe2\x3b\x3c\x07\x0e\x46\xcc\x1a\x87\xa3\xbe\x05\x47\x4e\x03\xc6\xf1\xa8\x6f\xc3\x74\xc4\xf9\xe0\x64\xd4\x02\x31\x1b\x71\x03\x38\x1d\xf5\x81\x38\x1b\x75\x05\x38\x1f\xf5\x47\x98\x3b\x9c\x1d\x2e\xba\xde\x68\x97\xf8\x81\x7a\x12\xa5\xd9\xb7\xd4\xd1\x27\xf6\x02\x4b\x28\x51\x13\x6d\x28\xf7\x5b\x08\x81\x59\x11\x03\xbb\x12\x85\x5d\x8e\x98\x63\x88\x26\x38\x36\xa1\x8f\xbd\x4e\xf8\x67\x1f\x3f\xeb\x1d\x15\x73\x04\xd1\xca\xd6\x1c\x3f\xc8\x72\x73\xec\xd0\xb2\xcf\xb6\x83\xd2\xb2\xc7\x00\x23\xd7\xac\xd4\x12\x39\xd4\xea\x6d\x8e\x1d\x5a\x01\x5b\xfa\xef\x94\x2f\xa6\xf6\xee\x11\x3a\x46\xbc\x4f\xc7\x18\x10\x50\xb7\x88\x43\x3a\xd6\x85\x88\x5a\xf5\x27\xa6\x63\xca\x47\xa9\x8b\x7f\x49\x17\xb9\x2d\x88\x70\x68\x47\x4a\x5d\xd2\xcb\xe8\x98\xf6\xe5\xd4\xad\xbf\x9c\xba\xcd\xaf\xa0\x63\x16\x82\xbd\x11\x13\xc1\x78\xc4\x0a\x31\x19\x35\x43\xec\xbb\x46\x0a\xa7\x86\xe3\x70\xd4\x44\x70\xe4\x8d\xc9\x09\xc7\xa3\x9e\x0c\xd3\x51\x6b\xc1\xc9\xa8\xbb\xc0\x6c\xd4\xe1\xe1\x74\xc4\x67\xe2\x6c\xd4\x6f\xe0\x7c\xc4\x2d\x61\xee\xf0\x4b\xb8\x70\xba\x0d\x19\x3d\xb8\xfb\x80\x47\xed\x12\x13\xbb\x61\x62\x7f\xc4\xec\x71\x30\xa2\xf8\x38\x1c\xb5\x1d\x1c\x8d\x7b\xb7\xd8\xe1\xde\x30\x1d\x37\x9e\xc4\xe9\x3f\x30\x1b\xf5\x7f\x38\x1d\x75\xa2\x38\x73\x3a\x11\x9c\x8f\x7a\x29\xcc\x47\xdc\x14\x2e\xba\x7e\x64\xb7\xe0\xc1\xe8\x53\x6a\x7a\x6d\x3b\x24\x0d\x35\xc6\x90\xe1\xae\x76\x5c\xc3\x18\x31\xa8\x0a\xb0\x9e\x62\x8c\x1b\x9a\x98\xcf\x50\x1e\xd5\x00\x6c\x15\xe2\x96\x40\x43\xa9\x2e\x73\x5b\xc8\xd0\xd2\x67\x89\x19\xda\x1e\x1a\x30\xa4\x2d\x81\x66\x12\xb2\x4e\x05\xd3\xc0\x61\xb5\x3d\xae\x0b\xc7\x00\xba\xe8\x30\xc7\xbc\xe6\xe0\x6a\x8f\xe9\x08\x73\x09\xf5\x6c\x8a\xe3\x53\xb7\xe2\x04\xd4\xa5\x38\x21\x1d\xd1\x8b\x88\x8e\x70\x2d\xa6\x23\xaa\x47\xe9\x88\x68\x13\x6a\xe3\x3b\xa3\x23\x32\x4d\xa9\x5b\x6b\x33\x3a\xa2\x35\x39\x1d\x91\x1c\xa7\x6e\xc5\x2d\xa8\x4b\xed\xb1\xe7\x34\x5b\x8c\x3d\xab\x5c\x31\x19\xb3\x69\xec\x8f\xd9\x24\x0e\x46\xac\x1a\x87\x63\x46\x81\xa3\x31\xcf\x81\xe3\x11\xdb\x6e\xc6\x3d\xab\x18\x71\x32\x66\x40\x98\x8d\xf8\x47\x9c\x8e\x79\x10\x9c\x39\x3d\x14\xce\xc7\x3c\x0c\xe6\xf6\xc1\xb9\x18\xf1\x10\x10\x1f\xb8\x65\x85\x47\x34\x0d\x93\x11\x4b\xc7\xfe\x98\x31\xe3\x60\xcc\x58\x71\x38\xe6\xaa\x22\xbb\x2b\xc2\xf1\x98\xb3\xc0\xd4\x6d\x2e\xc9\x98\xc1\x63\x66\x75\x16\x38\x1d\xb3\x65\x9c\x8d\xb8\x0b\x9c\x3b\x9d\x25\xe6\x63\xae\x0c\x17\x3d\x87\xb3\x4b\x54\xa0\xc8\xa6\x26\x2f\x52\xc3\x34\xc5\x05\xb2\x2d\x31\xf7\xd9\x6f\xcb\x89\x09\x76\xd0\x72\xc4\x08\x3f\xd4\xfb\x63\x8a\x0a\x9a\xd2\x21\xec\xb8\xa3\xd0\xd6\x51\xd1\x18\x0d\x68\x44\x0d\x01\xb3\x1a\xad\x91\xe4\x54\x29\xa8\x29\x02\xd0\x78\x35\x2c\xcf\x35\xb0\xc3\x52\xde\xf4\x75\x58\x56\x74\xb8\x6c\xea\xa9\x53\x48\x98\xba\x85\x44\xa8\xa5\x47\x3e\x75\x49\x27\xa0\xae\xfe\x84\xd4\xad\x75\x11\x75\x6b\x46\x4c\xed\xfc\xa0\xd4\xa5\x17\x09\xb5\xeb\x33\xa3\x6e\xd1\xa7\xd4\x2d\xc3\x8c\x5a\x74\x2a\xa7\x6e\x11\x71\xea\xd2\xa9\x82\xba\x55\x19\x7b\x23\x76\x84\xf1\x88\xf2\x61\x32\x62\xa9\xd8\x77\x28\x20\x0e\x9c\x76\x8a\xc3\x11\x53\xc4\x91\x37\xe2\x83\x62\xa7\xcd\x35\x11\xac\x85\xf6\xc4\xea\xb5\x99\xcd\x5a\x71\x3a\xe2\xda\x70\xe6\xf0\x8b\x38\x1f\xf1\x21\x98\x8f\xd8\x2c\x2e\x9c\xce\x4d\x8c\xe8\x16\xc2\xb1\x53\x95\x30\x71\x1a\x2d\xf6\x47\xec\x12\x07\x23\x86\x89\x43\x87\x65\xe2\x68\xc4\xd7\xe0\x78\xd4\x59\x8d\x58\x12\x4e\x46\x6c\x14\x33\x87\x03\xc0\xa9\xd3\x6b\xe1\xcc\xe9\x5a\x70\x6e\xb3\x7f\xcc\xc7\x4c\xb8\xe8\xba\x9e\xdd\x87\x6e\x83\x8e\xd4\xa4\x06\x1e\x36\x0c\xdd\x2a\xd4\x30\x0c\xda\x0a\xa8\xa9\x59\xd0\x04\x39\xa6\xd2\xd0\xd2\xfd\x48\x82\x34\x8c\xd1\x6d\xc8\x34\x2c\xa5\x5a\x07\x4c\xc3\x74\xd3\xf7\x61\x53\xa6\x29\xf9\xb0\x34\xd5\x3a\x61\x9a\xaa\x6b\x71\x9c\x61\x98\x96\x7c\x1b\x42\xe5\x2d\xdf\x4c\x93\x74\x2d\xf2\x1d\xf6\xd4\xc5\x06\x4c\xcd\x4c\x25\xd4\x25\x5f\x9f\xba\xfa\x18\x50\x87\xe2\x84\xd4\xc5\xbc\x88\xba\x7a\x12\x53\x1b\x7b\x28\x75\xa8\x55\x42\x5d\xa2\x66\xd4\x25\x91\x94\x3a\x14\x21\xa3\x36\x35\xcf\xa9\x4b\x93\x39\x35\x6b\x6c\x41\x1d\x42\xc6\x9e\x53\xca\x18\x3b\xcd\x95\x38\xed\x15\xfb\x4e\x5b\xc1\x81\xcb\x1c\x70\xe8\x34\x25\x1c\x39\x0d\x02\xc7\x2e\x8f\xa0\xc6\x1b\x63\x51\xe2\xf4\x16\x98\xb9\x2c\x06\xa7\x16\xa7\x81\x33\x9b\x93\xcd\x9d\x96\x8b\xb9\xd3\x29\xe0\xc2\xea\x11\xb1\xe7\x94\x3a\x76\x1a\x22\x26\x6e\xeb\xf6\x2d\x9a\x86\x03\xa7\xa1\xe1\xd0\x65\xc2\x38\xb2\xda\x21\x8e\x9d\x9e\x01\x53\xa7\xf5\xe3\xc4\x69\x8b\x98\x59\x9c\x15\x4e\x9d\xe6\x86\x33\x97\x77\xc0\xb9\xd5\x8a\x31\x77\x7a\x0e\x5c\x68\xce\x61\x97\x31\x95\x8a\x01\x9e\x18\x00\x36\xcc\x19\xfa\xe3\xbb\xed\xe6\xc6\xd0\x1d\xcb\x76\x43\x47\xac\xe0\x19\x8a\x42\x09\x8f\x18\xe9\x88\x9a\x42\x93\x13\x56\x94\x98\xc7\x19\xea\x99\xe9\x4f\x9a\x7e\x9b\x5c\xb0\xa4\xd3\x54\x94\x36\x40\x0d\x74\x66\x77\xe5\x65\x8f\xa1\xfb\x35\xeb\x09\x6f\x98\x68\x68\x53\x28\x22\x0c\x45\xf5\xa6\x92\xb5\xe7\xb2\x18\xbb\x78\xaa\xea\x10\x97\xfc\x55\x1d\xdf\x25\x6b\xf5\x7b\xe0\x62\xb6\xaa\x13\xda\xd9\xaa\x6a\x44\xa3\x7d\x8e\x2d\xaa\xa5\x8a\xa9\x8b\xa3\xaa\x4e\x62\x93\x92\x2a\x67\x76\x2d\x55\x35\x52\x97\x3e\xaa\x3a\x99\x59\xe4\xaa\x34\x77\xa9\x91\xaa\xc3\x5d\x2a\xaa\xea\x14\x76\x0b\xad\x23\x62\xa3\x61\x63\x57\x0f\x30\xb1\x30\x19\xfb\x36\x8d\xc3\x81\x8b\x58\x1c\xba\xc4\x82\x23\x17\x33\x70\xec\xe8\xa2\xcd\xff\x26\x76\x11\x62\xe6\xd2\x54\x9c\x3a\xfd\x61\xe6\xb2\x28\x9c\xdb\xf5\x1b\x73\x9b\xd2\xe1\x62\xdc\xba\xda\xc9\x8d\xb5\x06\x76\xfb\x02\x4c\xc6\x15\x0e\xfb\x63\xd6\x87\x03\xa7\xf5\xe1\x70\xdc\x09\xd4\xc2\x76\x76\x37\x1e\x77\x4a\x98\x8e\x3b\x37\x9c\x8c\x7b\x83\x5a\x1d\x5c\x56\x26\x95\xc2\x5a\x9a\x8d\xb9\x35\xa9\x18\x0e\x3a\xf9\x98\xc7\xa9\x95\x04\xb0\x68\x23\xbb\xfc\xa8\xe7\x35\x78\xca\xd6\xef\xd7\xa8\x9a\xb1\x0a\xad\xf9\x9c\x67\x15\xe4\x23\x7a\xf9\xcd\xb3\xd7\xa8\x5c\x9c\xd5\xcf\x44\x34\x19\x0d\x9e\x3e\x78\xd9\x7b\xb8\xb8\xbd\x98\x38\x45\xed\xc1\x7f\x78\x40\x51\x7d\x81\xcf\xea\xcb\x54\x6f\xe8\xa9\x5f\x65\x05\xf9\xa5\xfe\x2c\xbe\x4c\xb5\xfe\xf4\x29\xd7\xb2\x2a\x7d\xfb\xe8\xa5\x4c\x8c\x85\x64\xe2\x17\xf7\x1b\x55\xa2\x76\xf3\x40\x95\xfc\xa2\x65\x49\xb9\xea\x13\x55\xee\xd4\x7a\xef\xf9\x65\x93\x02\xec\x3d\xbf\x34\xa4\xbe\x7b\xcf\x2f\xeb\xbc\x7a\xef\xf9\xa5\x39\xad\x9e\xc0\x21\x45\x14\x46\x28\x2d\xab\x35\x62\x59\xb6\x5c\xe5\xe5\xe2\x04\x55\x4b\xf4\xfc\x21\x36\xc2\xfd\xa6\x84\x54\x40\x6f\xfa\x39\x90\x4d\x6f\x87\x84\x91\xfd\xed\x90\x16\xdc\xf3\xa5\x00\xf8\xfc\x21\x7e\x53\xbe\x45\x77\x10\x36\xe4\x28\x55\x78\x65\x7a\xfe\x49\xdd\xbb\x37\x6d\x7b\x95\x8e\x4f\xfc\x67\xe2\x63\x74\x47\x03\x0d\x79\xf8\xf6\xd0\xcd\x01\x60\x43\xc2\xd2\x07\xeb\x35\x3f\x4d\xe7\x1c\xe1\x08\xad\xcf\xd3\xf7\xfc\xd2\xc0\xfe\xf5\x79\xfa\x3d\xbf\x5c\x37\x22\x68\xbf\xdb\x99\xb2\x78\x09\x95\x24\x6b\xea\x2f\xf7\x11\x8e\x9a\x6f\xf6\x27\x56\x1e\x42\xc6\x29\x45\x8f\x99\x91\xeb\x1a\xba\xa2\xe5\x8d\x02\xfa\x56\x11\x65\x84\xeb\x7e\xba\x25\x2d\xab\x97\x90\x15\xe5\x48\x4b\x82\xd2\xc0\xb5\x81\x94\x0a\x15\x50\xa3\x42\x91\x61\x1b\x93\xd6\x90\xc0\xae\x35\x5d\x3c\xc5\x6a\x79\x0a\x0e\x66\xce\x8b\x0a\x11\x0a\x96\x21\x30\x9b\x1b\x4a\xe6\xbc\x99\x94\xe8\x50\xbe\x0d\xe1\x41\x02\xc7\x5a\xb9\x26\x93\xe7\x0f\x89\xd2\xc1\x3d\xb4\xdf\x70\x60\x0f\xfd\x0d\x11\xfa\x16\x72\x3c\x82\x6e\x95\xe8\x6f\xf0\xc6\xc5\xd6\xe4\xad\xca\x93\xd9\xf6\xf4\x05\x90\xbe\xb3\x25\x72\xaf\x43\x25\xa1\x50\x2c\x69\x45\xfb\x88\x04\x16\x82\xf7\x0c\x14\x0f\xd0\x9a\x32\xfb\x8b\x0e\x94\x8b\x8c\x23\xce\xb2\x99\x52\x3b\x54\xae\x11\x3b\x3b\x9b\x97\x3c\x17\xb2\x64\x0b\xc4\x37\x67\x6c\x91\xf3\xbc\xce\xcb\x08\xee\x7d\x6a\x84\x26\x58\xa0\xc0\x64\x6c\x81\x52\x8e\xd2\xd5\xf2\x3d\x5f\xa0\x72\x51\x2d\x11\x95\x49\x81\xd7\x68\x9d\xb1\xb9\x04\x2f\x41\xae\xcd\xd0\x2e\x66\x65\x36\x43\x6c\x3e\x5f\x5e\xac\x01\xb4\x80\x5b\x2d\x05\xd8\xf3\x35\xcf\xd1\x45\x59\xcd\x96\xe7\x95\x24\x70\x5d\x2e\x17\x43\x28\x8a\xd1\x90\x5e\x73\xd2\x7e\xb9\x7f\x5f\x3d\x2b\xd3\xfe\x24\x1c\x8a\x8f\x4d\x9c\xeb\x68\x2e\x96\x9a\x1b\xbb\x15\x57\x81\x05\x27\xd6\x7e\x06\x9f\x35\x29\xa5\x10\x6f\x23\x21\x7d\xdf\x2c\x2a\x5b\x3f\x62\xbd\x1f\xf1\x5b\x95\xd8\xf3\x37\xfd\x27\x78\x14\x60\xf0\xd4\x8e\xc1\x03\x3e\x94\x89\x2f\x51\xb9\xf8\xc0\x57\x6b\x6e\xf7\x82\xe5\xe2\xc3\xcb\x9e\x23\xec\xfc\xb4\xd5\x00\x81\x1d\x03\x44\x0b\x4d\xe7\xd8\xfa\x0d\x0e\x85\x42\xf7\xa1\x7f\xec\x2c\x38\xb4\x5f\xf8\x22\x5b\x5d\x9e\x55\x3b\x3c\x05\xa8\x32\xd6\x2e\x1f\x36\xed\xda\xca\xd3\xae\xcb\xb7\xa6\xd0\xcd\xf9\xe7\xc0\xda\x72\xc4\x95\xbb\xf7\xa1\x1b\xf3\xb4\x66\xa4\x29\xe8\xf8\x0f\x5e\xe9\x71\x5a\x97\xb8\x39\x00\xd5\x9e\xc6\xea\xcb\x40\x56\x5b\xf5\xab\xc1\xcb\x59\x86\xe8\xe3\xbb\x45\x59\x95\x6c\xae\xa7\xbe\xea\xd6\xe1\x9b\x6c\xc6\x16\x27\xfc\xc9\x8b\x36\x2d\xaa\xcc\x3c\xe6\x6d\xbc\x42\xfe\xaf\xaf\xd2\xe6\x36\xf2\x7d\x6a\x98\xb1\x16\x85\xb5\xcd\x8b\x27\x7a\x1b\x02\x78\x7c\xf5\xb7\x5d\x1b\x2a\x69\xf3\x8a\x42\xfc\x7f\x4b\xda\xa0\x4d\xa8\xfe\x8c\x99\x69\x5d\x4f\xb5\xc9\xf4\x61\x60\x51\xf2\xa3\xb4\x2a\xf8\x3c\xfe\x6c\x9b\x61\x24\x32\xc6\x13\x00\xce\xf6\xec\x45\xa3\x18\xba\x9e\x58\xea\xae\xba\x75\x57\xaa\xae\x91\xc8\xc7\xbc\x5c\x57\x7c\xde\x68\xb1\x19\x62\x01\x9d\xdf\x2e\xb4\xa0\x6e\x07\x5d\x88\x81\x56\xa6\x5a\x7b\x53\xbe\x7d\x33\x99\x28\x6a\xdf\xb5\xee\x5a\x04\x92\xcd\xd4\x05\xbe\x43\x5a\x6d\x13\x6b\x0c\x0e\xbb\x67\x48\x2b\x1b\xa7\x7a\x96\x34\xaf\xc9\x28\xc6\x1d\xf8\xdf\x17\xf9\x12\xad\x2f\xd8\x99\x0c\x3f\xe6\x6c\x5d\x49\x65\x18\xba\xf0\xca\x2d\xb2\x1e\xb1\x5d\x81\xb9\x0c\xbf\x32\xe8\x30\x64\x14\xdf\xd5\xd4\x07\xa6\x71\x6d\x26\x78\x15\x53\xbf\x8a\x4b\x19\x71\x5d\x86\x19\x59\x85\x96\xe7\xd5\xc0\x03\x37\x2e\xd7\x2d\xb2\x8e\xcb\xb5\xcb\xac\x33\x64\xbc\xe7\x97\x32\x05\x74\x14\x1c\xfa\x44\x2f\x29\x3f\x58\x0a\xb4\xbc\xd1\x91\x31\x6b\xf4\x21\x7a\x29\x34\x50\x4d\x02\x56\xcb\xf5\xba\x0d\xd3\x21\xe7\x21\x04\xc4\x30\x2d\x95\x2d\x9a\x81\xaa\x65\xdc\xa4\x1e\xaf\x4e\xd9\xfa\x7d\xc7\x64\x6b\xdd\x9d\x4c\x3a\x2a\x2a\x0c\xb1\x1e\x5d\xdf\x75\xba\x2e\x8c\x56\x40\xd1\x58\xd0\x51\xd9\x77\xa0\xb3\x5f\x19\x15\x5f\x94\x89\x88\x4a\x42\x56\xb5\x6a\xbb\x1b\x90\xfd\xe2\xc9\xf6\x64\xaf\xec\x64\xcf\xdd\x64\xcf\x1d\x64\xaf\xb6\x20\xdb\x99\x44\x7a\x5d\x67\x91\x96\xcb\x1f\xdb\xe5\x91\x1e\x4b\xc2\x2c\x61\x55\x7c\x53\xe9\xa9\x98\xbf\x7d\xf4\xf2\x40\x05\x68\x9d\x5c\xcc\x53\x94\x15\x27\x86\xe4\xda\x67\x73\x26\x88\xd8\x54\xa8\x0f\x45\x05\x5c\x93\x16\x8f\x09\x50\x93\xd9\x79\xb8\x50\xd3\x4d\xba\xfd\xed\xa3\x97\xc6\x8c\xdb\xaf\x56\xe5\xd9\x9c\xdf\xd9\x6d\x89\x48\x36\xea\x2c\x14\xe9\x3f\xfd\x79\x96\x8b\xd4\x42\x84\x20\xbb\x84\x0c\xa5\x59\xff\x79\x20\x15\xc5\xf2\x35\x46\x47\xa2\xde\x81\xe4\xea\x23\x29\xe3\xe5\x6a\xd2\xbe\xb3\xae\x1e\x8e\xaf\x51\x1f\xac\xe7\x65\xc6\x27\xde\x14\x91\xbd\xc1\x5b\x18\x0d\x58\x72\x45\xb0\x64\x8a\x02\x07\x58\xff\x8a\x60\x83\x29\x8a\xf6\xec\x0f\x69\x5c\x79\xee\xc1\xd7\xf8\x40\x6f\xac\xb5\xb0\x72\xe6\x40\x9f\x73\x6c\xd1\xc0\xdf\x02\xc3\xf5\xcc\x69\x04\xae\x1d\x89\x23\xbb\x76\x1f\x6f\x81\xc1\x3c\xea\xe1\x84\x5c\xdb\xb0\xf7\x4f\xe2\x56\x1b\xef\x72\x0d\xce\xb5\x85\xb5\xa3\x8b\xb5\xb9\xb8\xae\xa3\x6d\x6a\x39\xf3\xe7\x37\xb5\x7a\x29\xf4\xb5\xc4\xec\x77\x43\x32\xed\x65\xd5\xd7\x92\xbb\xdf\x0d\x83\x69\x9b\xd5\xfd\x6e\x18\x4d\x55\xb2\xf7\xbb\x11\xfe\xf8\x76\x4a\x83\x4f\x4a\xb8\xff\x47\x66\xda\xff\x6c\xf9\xf0\xff\x7b\x32\xdb\xc3\x4b\x05\xe5\x82\xe7\xd7\x9b\xe2\xfe\x1b\xb6\xe6\x6d\xd6\x7a\xb6\xe6\x5a\xd9\x6b\x9f\x38\x33\xe0\x0f\x6d\x79\x13\x05\x68\xc1\x4e\xf9\xfa\x4c\xb7\xd2\x43\x9d\x0c\x51\x45\x90\x21\xff\xfb\xeb\x47\x13\x98\x07\x28\x0a\x9a\x27\x6c\x4c\x60\x5e\x47\x81\xa0\x03\x88\xda\x44\xc1\x81\xfa\x22\xe8\x37\x44\x06\x2d\x68\x09\x5e\x2d\xa7\x94\xbf\xf0\x35\x62\x68\xc1\x2f\xe6\x97\x48\xda\x5a\x6e\x42\xac\x3b\x14\xd4\x79\xcd\x63\x71\x7e\x9a\xf2\xd5\x47\x04\xaf\x4a\xc1\xab\x2a\xe2\x83\x4f\x20\x9c\x3f\x70\x36\x99\x2f\x2f\xa0\x85\xf8\xaf\xa9\x41\xb7\x71\xd7\xbb\x0d\x2b\xd4\x7c\xd9\xb4\x7c\xa9\x3d\x42\xcd\x9e\x7a\x60\x96\xbb\x7f\x1e\xf1\x7c\x98\x95\x05\x5e\xe8\x45\x5e\x77\xbd\xb3\xe6\x34\xb8\xf8\x45\xd9\x89\xa8\x44\x0f\xa7\x82\x6a\xf3\x18\xa6\xde\xd7\x32\xbc\xea\x09\xc5\xa2\xb7\x47\xa8\xfb\xfa\xb6\x3e\x33\xef\x4b\xea\x9b\xb2\xba\x28\xd7\x1c\xfd\xf0\xec\xd5\x1a\x20\x8c\x09\xa6\x7e\x28\x45\x29\xc8\x47\xf4\x40\xc8\x57\xf0\xe5\x0e\x30\x46\x8d\x24\xac\xa8\xf8\x0a\x2d\xf8\x09\xab\xca\xc5\xc9\x35\x30\x1e\x40\x71\xc1\x78\x25\x82\x83\xc5\xb2\x9a\x58\xb9\x7a\x78\x88\x16\xcb\xd1\x48\x15\xde\x64\x91\x0c\xfd\xbd\xe1\xee\x3d\x63\x35\xc9\xd8\xdf\x6b\x26\x1b\x42\x52\xc5\x19\xc5\x98\x5a\x1b\x5a\x71\xde\xeb\x50\xd7\x89\x00\x6c\x52\x79\xf0\xc3\xb7\x9a\x54\x60\x3b\x01\xc6\xed\x33\xb6\x86\xed\x85\xad\x6c\xa8\x91\x14\xc0\x10\x26\xd1\x08\xab\x5a\x0a\x14\x35\xdc\x6b\x16\xfe\x83\x1f\xbe\xbd\x1e\xd1\xcb\xbd\x9d\x56\xf0\x6c\x91\x4f\xd8\x62\x59\xcd\xf8\x4a\x11\xe2\x52\x03\xb6\xc8\x75\x35\x10\x3d\x1c\x51\x85\xd6\xce\x6e\x4a\x86\x8c\x69\x45\x63\x79\xaa\xfe\x1f\xa6\x1f\xcf\x5e\x7c\x6e\xf5\x78\xf6\xe2\x33\x69\xc7\xb3\x17\xd7\xa3\x1c\xcb\x55\x47\x37\x96\xab\x1d\x54\x63\xb9\xba\xb2\x66\xfc\xb6\xa3\x66\xfc\xf6\x07\x6b\xc6\xeb\xcf\xaf\x1a\xaf\x3f\x9b\x6e\xbc\xbe\x2e\xe5\xd8\xf4\xb4\x63\xb3\x93\x7a\x6c\x3e\x41\x3f\xde\xed\xa8\x1f\xef\xfe\x20\xfd\x80\x4d\x79\x5d\x33\x16\x72\x65\x54\x4d\x08\xe7\xbc\xa8\xb6\x8f\xca\x16\xa0\x13\xf2\x1b\x5a\x16\x0d\x24\x78\xc2\xe6\xba\x94\x01\x80\x5d\x8f\x3a\x00\xa8\x8e\x42\xc0\x2f\x4f\x26\x24\x74\xe9\x81\xac\xa4\xab\xc2\xc2\xa4\x07\x62\x0a\xb4\x40\xf7\x91\x4f\x6c\x3b\x5d\x9a\xa6\x4c\x5a\x55\xb9\x7f\x1f\x2d\x60\x8b\xbc\x51\x06\x79\x74\x88\xa0\x3b\x68\x61\x7c\xac\xde\xac\x42\x02\xce\x50\xd7\x3e\xa2\x7a\xf2\xe4\x26\x48\x07\x33\x59\xa0\x3b\x86\x17\x43\x07\xa8\xfb\x5b\x5d\x02\xdd\x7f\xa7\xf6\xc2\x52\xfe\xbf\x9d\xfa\xbe\x98\xd8\x27\x17\xb5\xf6\xbe\xb8\x26\xed\x95\x72\xef\x6a\xaa\xa6\xbc\xb5\x3e\x6f\xa1\xbc\x03\x8f\x09\xa0\xae\xa0\xbf\x9a\x15\x34\x70\xc6\x15\x58\xa1\xff\xc3\x35\xf8\xc5\xb2\x62\x15\xff\xdc\x0e\x78\x05\x58\xae\x4b\x85\x01\xda\xf5\xa8\xb0\x24\x4c\x57\xe1\xd5\x72\xd4\xff\x8a\x2a\xa3\xfa\xab\x7a\x04\x7a\xa0\xbc\xfa\x62\x4f\x84\x83\xed\x2f\x2f\x26\x51\x30\x50\xcb\x4f\x15\xd8\x35\xf9\x9c\x3f\x97\xc4\x46\x5c\x8e\xa8\xb1\xbb\xc0\x5e\x0c\x04\xf6\xe4\x2a\x02\x7b\x90\xe7\x9f\x3b\xf2\x65\x79\xfe\x99\x22\x5f\xf9\xe4\xf7\x75\xcc\x99\xf3\xde\x9c\x39\xdf\x69\xce\x9c\x6f\x3d\x67\xee\x8f\x08\xfb\x4d\x20\x0b\x07\x46\xcd\xc1\x6f\xc6\x56\xab\x4b\xd1\xac\x1e\x43\xe4\xc3\xf0\x9d\x61\xa5\x7d\x1e\xde\x0c\x63\x18\x48\xed\xb7\x31\x37\xda\x97\x38\x14\x0d\x9f\xea\xd1\xe5\x37\xf3\xee\xca\x83\x85\x7a\x02\x7c\x59\xe8\x6b\x9b\x6b\xd3\x0b\xc7\xab\xe5\x19\x5f\x55\x97\xe8\x57\xf5\xc4\x30\x54\x04\xf5\x6a\x40\x0c\x96\x15\x95\x82\xac\x0f\x4c\x70\x6a\xb7\xd2\xbc\x89\xde\xf5\x2e\xeb\xf2\x64\x51\x16\x65\xc6\x16\x15\x4a\xa1\xbc\x5c\x68\xb6\x01\x48\x1d\xab\xbf\xed\xba\x74\x4d\x4c\xfd\xcb\x35\xac\x03\x0f\x29\xb0\x9b\x63\x87\x5d\x93\x67\x67\x42\x2d\xd9\x7c\xaf\xc3\xfb\x51\xc6\x21\xa3\x43\x6e\x38\xa7\x81\xdd\x8a\x89\xbc\x2b\xe6\x4f\xb0\xd5\x0b\x9d\xd5\xfd\x5e\x74\xf6\x7c\xbb\x36\xfb\x89\xc0\xde\x0c\xda\x8b\xbf\x5d\x97\xb5\xa7\xbb\x42\xc1\x14\x27\x98\xe1\x14\xee\xd4\x64\x38\xc7\x1c\x17\x7b\x03\x20\x6f\xff\x8d\xba\x3a\x45\xd8\xdb\x7a\x7b\x00\x94\x6e\xda\xa8\xed\xc0\x2d\x5f\xa8\xc3\x13\xe0\x16\xeb\x2f\xf2\xbf\xbf\xfd\x66\xb8\x80\x21\xe2\xfe\xc6\x06\xfe\x72\x84\x86\xbb\x60\xfa\x9f\x1c\x9b\xeb\xea\x47\x0d\x19\xfd\xb3\x80\xd6\xa0\xbd\x0f\x40\xda\xd0\x9c\x2f\x4e\xaa\x19\xba\x8d\xe8\x96\x47\xa9\xfb\x8e\xe6\xe1\x72\xf1\x81\xaf\xea\xa9\xa1\xe6\x86\x95\x7f\x10\x83\x76\x7d\x3b\x60\x2b\xc7\x53\x8f\xda\x8d\x74\x3b\x3b\x73\x1f\xd1\xab\xae\x13\xbd\xb5\x46\x39\xab\x18\x62\xeb\x1d\xf1\x6c\xbd\x92\xd5\xdd\x29\xdc\x68\x0e\xfa\xa0\x5a\xbe\xf6\x89\x7d\x2b\x04\x8a\x3f\xe1\xcc\x8e\xc2\xd5\x55\x2a\xc3\xc9\x9d\xba\xde\x13\x29\xcc\x86\xc8\x5a\xbc\xa6\x53\x3c\x52\x6c\x06\x58\xb2\xbb\x5b\x1f\xde\xef\xe2\x76\xdf\xf4\x6a\xb7\xf0\xea\x56\x6f\x06\x47\xf8\xc5\x5f\x4d\xc3\xc1\xd9\xf9\x7a\x36\xa9\x03\x29\x11\x23\x98\xe6\x95\xe6\xda\xbd\x58\x02\x19\xce\xc9\xd6\xa1\x88\x26\xe0\xda\x83\xd4\x30\xa7\x5d\xb3\xb1\x1e\x24\x19\x58\x05\x80\x11\x2a\x99\x2d\xcf\x60\x90\xb4\x8c\xfd\x68\x34\x6c\x6d\xd4\x9e\xa3\x6c\xbe\x5c\xb8\x66\x2a\xdb\xaa\x34\xc0\xe9\xeb\x32\xfc\x68\xd7\x65\x28\x76\xea\xb2\x0e\x19\xa2\x14\x49\x6e\x73\xf2\xd5\x74\xd2\xf5\x21\xd4\xff\x2b\x28\xf6\x5f\x25\x67\x86\x40\x6b\x5f\x2a\xe1\x0d\xdd\x6c\x7d\x6a\xcc\x8e\x00\xee\x30\xd5\x1b\xeb\x32\x38\xb1\xa0\x69\x4c\xe8\xa2\x63\x3f\xa3\x66\x70\xb1\x8d\x0d\x5c\x28\x95\xaf\xc1\xbf\x29\xdf\x9a\xd8\x6e\x57\x55\xa8\xdc\xd9\x5f\x6e\xc2\x63\xeb\xb9\x99\xde\x69\x19\x75\x34\xe6\xe3\xdb\x29\x0d\xb7\x39\xef\x72\x78\xfb\x2f\x68\x56\x55\x67\xeb\xbb\x87\x87\xa7\xd5\x6c\x7d\x90\xf2\xc3\xf3\xaa\xa0\x3f\xaf\xd1\x07\x72\x80\x0f\x08\x4a\x2f\xd1\xff\x38\x65\xd5\xac\x64\x6b\xa1\x31\xed\x01\x19\x38\x15\x22\x0f\x7b\x1c\x1e\xa2\x6f\x79\x25\xaf\xc3\x71\x2e\xd8\x5d\xb2\x74\xce\xd7\xe8\x1f\x0a\xd3\x3f\x6e\x7c\x05\xc7\xf8\x57\x9c\x3f\x6a\xce\xbf\x0c\x4e\xd2\xa0\x5b\x52\x78\xb7\xd0\xcd\x9b\xf5\xcf\xf7\xec\xe0\xd1\x3f\x64\x77\x34\xe0\x4f\xe1\x87\x16\xf6\xa9\xfa\xde\x05\xad\x7e\xbd\x79\xd3\x70\x3e\xe7\xa8\x43\x64\x53\xd9\x49\xc6\x09\x9c\x9c\xf9\xc7\x54\x9e\xc6\xff\x61\x99\xf3\x83\x9f\xd7\x68\xb9\x42\xdf\xc8\xa3\x34\x65\x51\xf2\x1c\x65\xcb\x9c\x4f\x01\x0a\x5b\xe4\xe8\x7c\xcd\x51\x59\x89\x71\xed\x1f\x82\x8f\x5a\x1f\xd4\x39\x9c\xa6\x0f\x27\xea\x7b\xb7\x0f\xf2\xd7\x7b\xf2\x4c\x52\xdb\xec\xa0\xa9\x7d\xa4\x03\xfb\xed\x37\xed\xdb\xc1\x45\xb9\xc8\xc5\xec\xb2\x53\x47\x1e\x1d\x12\xb4\x20\xfd\x67\x38\xec\x73\xe3\xab\xc3\xdb\x77\xae\xed\xef\xf6\xe1\x0d\xd9\xdb\x75\xb5\x2a\x17\x27\x8f\x57\xcb\xd3\x87\x33\xb6\x7a\xb8\xcc\x85\xe4\x5e\xc2\x8f\x07\x85\xf6\xab\x62\xfe\x2b\xf6\x9e\x2f\x24\x8f\xfb\x2a\x7b\x76\xbe\xb8\x14\xfc\xbd\xf1\x55\xe3\xc1\xce\xb3\x35\xc9\xb9\xf8\x71\x22\xf1\xc8\x0e\xc2\xd6\x26\x1c\xbe\xaf\x87\x40\xf8\x29\x5b\x9e\x2f\x2a\xbe\x52\x2b\x97\xf0\xd3\xbc\xf6\x15\xb2\x79\xeb\x2c\xa0\x14\xee\x33\xd6\x5f\xf8\xa6\x5a\x31\xf1\xe5\x62\x56\xce\x39\x9a\xd4\xd0\xee\x2b\x20\x12\xf5\x57\xd0\xa6\x05\x98\xa9\xee\x3d\xa8\xea\x06\xfb\xfb\xc2\xd4\xbf\x02\x99\xca\xca\x5f\x1f\x21\x6f\xf3\x2d\xf5\x3c\x21\x73\xf9\xd3\x7d\xf8\xe9\x9b\xc7\x8f\xc5\x4f\x16\x4c\x82\x5d\x30\x5d\x5f\x9f\xaf\x56\xcb\x13\x56\xf1\x29\x68\x5d\x35\xe3\x2b\x0e\xf7\x3c\xd1\x82\x6f\x2a\x24\x48\x60\x59\xc5\x57\xd0\x08\xba\xb1\x0d\x7d\x40\xe0\x44\x56\xbf\x89\xbc\xcd\xe3\x87\x9e\xb7\x27\x34\xd4\xdb\x7c\x0b\x1f\x7f\x15\xce\x79\xbe\xbc\x68\xf1\x43\xb3\xaf\x24\xe7\xe5\x50\x3e\x51\x5d\x14\x00\xfc\xc7\x8f\xf7\xe0\x6a\xa6\xb7\x87\xf6\x91\x06\x19\x0a\xf6\xeb\x8c\x43\x0a\x7b\x1b\x05\xab\xae\x9e\x2f\x4e\x59\x95\xcd\x78\xde\xe2\xbb\x87\x96\x8b\xf9\x25\x62\x67\x67\x1c\xfa\x5d\xae\xc1\x00\xd1\xf9\xa2\xac\xa6\x62\xa2\x99\xb1\x35\x87\xd9\xa6\x60\x44\x03\xa9\xa9\x23\x98\x54\xd5\xe7\xa2\x1a\xa8\x62\xa8\x67\xda\xd7\x33\x56\xae\x86\x3d\x83\x7e\x29\x5a\xbf\x52\xac\xbb\x73\x47\xd1\x7e\xa3\xdf\x01\x4b\x4b\x51\x51\xfc\x5f\xf9\x7b\x59\xab\xb6\xc6\xab\x18\x03\x5f\x80\x31\xc0\x28\xdc\xda\x42\xa3\xe5\x32\x6e\xe9\x2a\x79\xb9\xc8\xf9\x06\x1d\xa1\x3b\xd8\xa8\xf6\x8d\x1d\xdd\xba\xa5\x29\xff\xfe\xbe\x6c\x66\x51\x7e\xc0\xf3\x06\xaa\xbc\xed\x2b\xbb\x50\xa5\xc7\x42\xe2\x92\x33\xf2\xd7\x3b\x47\xb5\xf8\xef\x69\xfc\x42\xfb\x47\x06\xff\x51\x03\xfa\xfa\x6b\x84\xbd\x5a\x81\xd0\x6f\xca\x86\x94\x48\x6a\x4a\xa4\xb2\xa2\xdf\x50\x47\x0f\x1b\xe6\x6f\x81\x08\x00\xda\x84\xd4\x30\x3f\x9b\xf1\xec\xfd\xcb\x8c\xcd\xd9\xea\x7f\x89\x56\x13\x21\x87\xe7\xcb\x72\x21\x4f\x53\x03\x03\x9a\x9f\xba\x16\xdf\xfe\x2c\xad\xbe\x65\x4e\x35\x5b\x2d\x2f\xd0\xa3\xd5\x6a\xb9\x9a\x40\xaf\x6e\x3d\x11\xa1\x50\xab\x9a\x7f\xdf\xbf\x85\xf6\x5b\x00\x07\xd5\x52\x7a\xd6\x09\x8e\xf6\x0e\xaa\xe5\xdf\xcf\xce\xf8\xea\x21\x5b\xf3\xc9\x1e\xda\x97\x00\x84\xca\x2f\x96\x95\x50\x70\x20\x56\xf2\xe5\x96\x28\xac\x3b\xfa\xf1\x33\x8c\x04\x2d\x9f\x20\xaa\x16\x91\x78\xcb\x8e\xa9\xdc\x66\x53\x83\x93\xe4\xb2\x41\x1a\x13\x9d\x81\x5f\xd7\x6d\xa4\x44\x61\xa9\x72\x43\xbd\xbd\xbe\x5c\xa4\x41\x3c\xac\x1b\x9a\xc4\xa2\x81\xbd\xa9\x94\xf3\xf1\x63\xaa\x7c\x9d\x72\x73\xf8\x4e\x7a\x59\x71\xb4\xe6\xff\x75\xce\x17\x19\x38\x3a\x3b\xa1\x2d\x8e\x5a\x75\x60\x20\xbc\x3c\x4d\x97\xf3\xc6\x90\x6c\x98\xa9\xd7\xc5\x4c\x86\x98\x1b\x48\xe3\x4c\x8a\x24\x83\xb0\x62\xd0\x43\xaf\x21\xa9\x39\x78\x6c\x20\x02\xdc\xb0\x4e\x84\x3f\x24\xc2\xa1\xf0\xf7\x76\x24\x12\x13\x49\xa5\xa7\xa8\x7c\xe4\x75\x40\xec\x1f\x59\xb4\x26\xda\xa2\x33\x8f\xbc\x41\x67\x82\x4f\xe2\x28\xa6\x8a\xd8\x58\x12\xfb\x78\x4b\x62\x31\xd9\xb5\x53\x6d\x4d\x13\x55\xdd\x8e\x76\x2d\xa0\xd1\x4d\x80\xd0\x37\x09\x11\xfa\xab\x71\xa2\x1f\x34\x35\x40\x45\xe8\x3e\x0c\xae\x06\x51\x53\x5b\x7f\x74\x50\x69\xaa\xd6\x3f\x08\x21\x48\x6f\xb5\xe5\xe0\xd2\xf6\x58\x47\xac\x8f\x32\x1a\xc8\xfd\x23\x87\xe9\xf7\x3c\x7a\xdb\xec\x73\x05\xc2\x0d\xef\x57\x9c\xe5\x0f\x97\x8b\xaa\x5c\x9c\xc3\xe5\x59\x90\x7e\xeb\x8a\x04\x25\xdf\x41\xdf\xbf\x3e\x02\xb2\x1e\x8a\xc0\xc2\x30\x1a\xdc\xfa\x6e\xf1\x81\xcd\xcb\x1c\x2a\x49\x6e\xdf\x52\xdd\x6a\xf8\xdd\xc5\x82\x24\x40\x58\x28\x78\xd3\xe0\x79\xab\xcc\x44\x34\x6d\x7e\xdc\xdf\x17\xc1\x78\xed\xa1\x7a\x60\x6e\x4a\x37\x22\x03\x41\xe1\x25\x7f\xd5\x9c\xa1\xb1\xb6\xff\xb8\x21\xec\xf0\x10\x7d\x57\xa0\x0b\x8e\x44\xbc\x76\x7e\x86\x44\xa4\x3a\x45\x65\xf5\x7f\xff\xf7\xff\xa9\x87\x25\x1d\x04\x50\x7c\xc3\xd2\xf3\x41\xc5\x5b\x03\xe7\x2f\xb5\xf7\x25\x58\xc1\xa4\xd5\x72\x51\x19\xeb\x6a\x48\xf4\x2f\xbe\xfe\x25\x30\xa8\xef\x50\x56\x9f\x20\xaa\x2e\xa4\xa3\xa1\xd4\x15\x67\x0b\x36\x87\xcb\x0f\x0d\x1f\x5f\x70\x96\xa3\xa2\x5c\xad\xab\x9a\x4b\xd0\xad\xdd\xc5\x3c\x1c\xdd\xd0\x64\xb1\x1c\xb2\x77\xbd\x57\xeb\x84\x44\x74\x53\xc9\x5f\x79\x56\x8d\xd6\x86\xbf\x35\xad\xc3\x31\xac\x07\xe7\x51\xad\x50\x0f\x6b\x50\x20\x16\x74\x64\x31\x98\x7b\x7d\x7f\xa0\x03\xc3\x72\x9a\x01\x39\x77\x1a\xe9\x9a\x02\xb0\x46\x7b\x5b\xf5\xd5\x7c\x54\x37\x80\xdf\x41\x05\xeb\xb0\x5e\xf6\xdd\xef\xf3\xf6\x94\x5d\xa2\x72\x91\xcd\xcf\x61\x12\x22\x26\x17\xfa\x94\xc6\xc4\xe5\xc7\x35\x77\x1e\xed\xc0\x1d\x50\xe5\xab\x31\xd0\x53\xf3\x34\x02\x67\x93\x24\x2e\x9d\xa1\xbe\x8d\xa1\x1e\x04\x2f\x92\x61\x63\xf1\xc1\xe7\xe4\xf9\x70\x84\xef\x73\x94\x2a\x8e\x3e\xbe\x5e\x8e\x82\xcb\xb8\x22\xd3\x63\x60\xba\xb7\xe9\xb3\xdd\xdb\x78\x0f\xf7\xd0\x6f\xc0\x91\x89\xa4\x41\xfe\xda\xc8\x23\xb0\xca\x03\x66\x54\x86\x39\x06\xf6\xf4\x29\x98\x59\x12\x35\x3f\x8d\x52\xf8\xfb\xab\xc7\x77\x28\xca\x61\xa5\x8c\xe7\x8d\xe7\xad\xdd\xa6\xba\x81\xd5\x7c\x07\x87\xa6\x7d\x07\xff\x73\xaf\x17\x93\xa8\x58\xa3\x1d\x8d\x25\x7d\x0d\xbc\x6e\x48\xa2\x55\xab\xbd\x1a\x60\xd1\x1d\xa0\x16\x94\x68\x3e\xb6\x5d\xfd\xe9\x84\x3b\xed\x3a\x51\x75\x7a\xa6\x45\x23\x93\xea\xf4\x0c\x1d\xf5\xc6\x92\x3d\xf4\x97\xa3\x23\xe9\x94\xfb\xd1\x89\xda\xc4\xa8\x4e\xcf\xfa\x71\x86\x36\x41\x6f\x6b\xef\x7d\xce\xc5\x37\xc1\x56\x74\x04\x04\xde\xfa\xc0\x57\xeb\x72\xb9\xb8\x75\x17\xdd\x82\x45\xdf\x5b\x53\xf1\xab\xa4\xe7\xd6\x5d\x2d\x2a\x84\xdf\x65\x77\xd5\xef\xf2\xcb\x8d\xaf\x3e\xaa\x45\xba\x97\xcb\x53\x8e\x1e\x3c\xfd\x16\xa5\xe7\xe5\x3c\x47\xcb\xb3\xaa\x3c\x2d\x7f\xe1\xab\xf5\x14\xcd\xcb\xf7\x1c\xad\x0e\x7e\x5e\x4f\xe5\x94\x18\x56\xda\xd7\x67\x3c\x2b\x8b\x32\x13\xc6\x9b\x97\x20\xf0\x33\x56\x55\x7c\xb5\x58\x03\x3c\x68\x54\xcd\x38\x2a\x96\xf3\xf9\xf2\xa2\x5c\x9c\xdc\x95\x6b\x9e\x42\xfd\x7a\xf7\x22\xd1\xad\x5a\x69\x6e\xc9\xc5\xdd\x4e\x85\x03\x76\x9a\xf7\x56\x51\x9b\x2b\x92\xa2\xec\xc6\x57\x52\x5c\xea\xd2\x64\xb3\xcc\xdd\x1d\xc0\x44\x9f\x41\x76\x20\x9c\x76\x76\xd1\x5b\x35\xfe\x8b\xf6\xfd\x60\xb1\xcc\xf9\xab\xcb\x33\xde\x06\x73\xed\x5a\xb5\x9a\x78\x94\x0b\x7d\xdd\xf8\x45\xb9\x38\x59\xfe\xcf\x97\xe8\x83\x77\x40\x0f\x3c\x98\x9e\xb7\x2d\xb4\xbb\xa4\x0d\x31\xca\x35\xd6\x90\xd8\xea\x62\xc6\xe6\x3d\x48\xf1\x81\x77\x47\x2e\xc4\xac\xea\xb3\x51\xf2\x16\xa3\xfa\x6d\xc6\xd6\xcf\x2e\x16\xcf\xeb\x23\x30\x47\xaa\xd2\x41\xf7\x77\xa8\xde\x6c\x91\x40\xd6\x38\xc9\x94\xda\x63\x74\xab\xcb\xfd\x21\x51\x0e\x17\x89\xf7\x04\x6f\x74\x5e\xbd\x79\x2f\x13\x18\x8a\x1a\xf0\xb9\xb3\xf8\xd5\xeb\xd7\x8b\x59\xb9\x58\x8a\x5e\x31\x74\xc1\x53\xa4\x2e\xaa\xaa\x55\xeb\x03\xa5\xd0\x8a\x27\x1f\x6f\xa8\x2b\xaa\xb0\x6d\xf2\x71\xfa\xeb\xc7\xb7\x53\x1a\x6d\xb3\x25\x32\xb8\xb1\xfb\xfa\xe9\x93\xe3\xaa\x3a\x7b\x21\x86\x8c\x75\xd5\x40\xfb\x6b\x5a\x9e\xc8\xc3\x2c\x07\x3f\xaf\xff\xba\x0d\xe4\x5b\xe7\x6b\x0e\x13\xb6\xac\xba\x75\xef\xc6\x10\xd1\x37\xe5\xc9\x0f\x00\xf0\x9e\xe8\xf0\xcf\xeb\x99\x70\xca\xe5\xc9\x62\xb9\xe2\x77\xe7\xe5\x82\xdf\x68\x50\x5f\xf0\xd4\xdf\x0a\xa5\x10\xd2\x8f\x3c\x95\x63\x93\xbc\x66\x7c\xeb\xe0\x70\x5e\xa6\x87\x02\x84\x70\xce\x37\x0e\x0f\x51\xbe\x5c\x54\x68\xf9\x81\xaf\x56\x65\xce\xeb\x0d\x87\x7a\x7f\xe3\x86\x76\x05\x59\xed\x1c\x08\x07\x77\xab\x39\xd0\x00\xfb\x11\x9d\x0a\x07\x12\x65\xb7\x96\x50\x10\xd8\x26\xd3\xab\x00\x71\xf7\x6e\x7c\x34\x70\x43\x96\xa8\x8d\xad\x9a\xe2\xbf\xde\x25\xe4\xe3\x5b\xc1\x85\xe9\x1b\xc9\x85\xb7\x7b\x37\x0e\x0f\xff\x3f\xb4\x5e\x9e\xaf\x32\xfe\x94\x9d\x9d\x95\x8b\x93\xbf\xbf\x78\x72\x24\x0a\xef\xcc\xe1\x10\xe9\xcf\xeb\x83\x53\x76\x76\xe3\xff\x05\x00\x00\xff\xff\xf8\x45\xa8\x9a\xa2\x2a\x06\x00") func web3JsBytes() ([]byte, error) { return bindataRead( @@ -114,7 +105,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{0x9b, 0xbb, 0xb1, 0x1f, 0xdd, 0xe5, 0x5a, 0xa8, 0xce, 0x52, 0x46, 0x21, 0xe7, 0xb4, 0x84, 0x30, 0xf9, 0xc, 0x83, 0xc8, 0xf2, 0x56, 0x37, 0x9a, 0xb4, 0x89, 0xbe, 0xc8, 0x40, 0x8a, 0x25, 0x5e}} return a, nil } @@ -122,8 +113,8 @@ func web3Js() (*asset, error) { // It returns an error if the asset could not be found or // could not be loaded. func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) @@ -133,6 +124,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,12 +141,18 @@ 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. func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) @@ -159,6 +162,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)) @@ -174,24 +204,29 @@ var _bindata = map[string]func() (*asset, error){ "web3.js": web3Js, } +// AssetDebug is true if the assets were built with the debug flag enabled. +const AssetDebug = false + // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// 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 +// +// data/ +// foo.txt +// 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, and // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") for _, p := range pathList { node = node.Children[p] if node == nil { @@ -219,7 +254,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 { @@ -233,18 +268,14 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + err = os.WriteFile(_filePath(dir, name), data, info.Mode()) 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 @@ -262,6 +293,6 @@ func RestoreAssets(dir, name string) error { } func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) } diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index abad5dbb8..2d536cfcf 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -5329,6 +5329,13 @@ var methods = function () { inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] }); + var getAccountInfo = new Method({ + name: 'getAccountInfo', + call: 'eth_getAccountInfo', + params: 2, + inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] + }); + var getBlock = new Method({ name: 'getBlock', call: blockCall, @@ -5513,6 +5520,7 @@ var methods = function () { getBalance, getStorageAt, getCode, + getAccountInfo, getBlock, getBlockSigners, getStakerROI, diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index 5e8845006..ddc54164c 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -22,8 +22,8 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" "math/rand" + "os" "time" "github.com/XinFinOrg/XDC-Subnet/common" @@ -245,7 +245,7 @@ func (re *JSRE) Stop(waitForCallbacks bool) { // Exec(file) loads and runs the contents of a file // if a relative path is given, the jsre's assetPath is used func (re *JSRE) Exec(file string) error { - code, err := ioutil.ReadFile(common.AbsolutePath(re.assetPath, file)) + code, err := os.ReadFile(common.AbsolutePath(re.assetPath, file)) if err != nil { return err } @@ -298,7 +298,7 @@ func (re *JSRE) Compile(filename string, src string) (err error) { func (re *JSRE) loadScript(call Call) (goja.Value, error) { file := call.Argument(0).ToString().String() file = common.AbsolutePath(re.assetPath, file) - source, err := ioutil.ReadFile(file) + source, err := os.ReadFile(file) if err != nil { return nil, fmt.Errorf("Could not read file %s: %v", file, err) } diff --git a/internal/jsre/jsre_test.go b/internal/jsre/jsre_test.go index bc38f7a44..9b58fb049 100644 --- a/internal/jsre/jsre_test.go +++ b/internal/jsre/jsre_test.go @@ -17,7 +17,6 @@ package jsre import ( - "io/ioutil" "os" "path" "reflect" @@ -41,12 +40,12 @@ func (no *testNativeObjectBinding) TestMethod(call goja.FunctionCall) goja.Value } func newWithTestJS(t *testing.T, testjs string) (*JSRE, string) { - dir, err := ioutil.TempDir("", "jsre-test") + dir, err := os.MkdirTemp("", "jsre-test") if err != nil { t.Fatal("cannot create temporary directory:", err) } if testjs != "" { - if err := ioutil.WriteFile(path.Join(dir, "test.js"), []byte(testjs), os.ModePerm); err != nil { + if err := os.WriteFile(path.Join(dir, "test.js"), []byte(testjs), os.ModePerm); err != nil { t.Fatal("cannot create test.js:", err) } } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 1f08ff05b..5113463dc 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -156,6 +156,12 @@ web3._extend({ name: 'getLatestPoolStatus', call: 'XDPoS_getLatestPoolStatus' }), + new web3._extend.Method({ + name: 'getMissedRoundsInEpochByBlockNum', + call: 'XDPoS_getMissedRoundsInEpochByBlockNum', + params: 1, + inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter] + }), ], properties: [ new web3._extend.Property({ diff --git a/les/api_backend.go b/les/api_backend.go index bfe5faf4b..db0a9adc7 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -20,8 +20,8 @@ import ( "context" "encoding/json" "errors" - "io/ioutil" "math/big" + "os" "path/filepath" "github.com/XinFinOrg/XDC-Subnet/XDCx/tradingstate" @@ -74,6 +74,30 @@ func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr)) } +func (b *LesApiBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.HeaderByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + header, err := b.HeaderByHash(ctx, hash) + if err != nil { + return nil, err + } + if header == nil { + return nil, errors.New("header for hash not found") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { + return nil, errors.New("hash is not currently canonical") + } + return header, nil + } + return nil, errors.New("invalid arguments; neither block nor hash specified") +} + +func (b *LesApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return b.eth.blockchain.GetHeaderByHash(hash), nil +} + func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { header, err := b.HeaderByNumber(ctx, blockNr) if header == nil || err != nil { @@ -82,6 +106,30 @@ func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb return b.GetBlock(ctx, header.Hash()) } +func (b *LesApiBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + return b.eth.blockchain.GetBlockByHash(ctx, hash) +} + +func (b *LesApiBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.BlockByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + block, err := b.BlockByHash(ctx, hash) + if err != nil { + return nil, err + } + if block == nil { + return nil, errors.New("header found, but block body is missing") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(block.NumberU64()) != hash { + return nil, errors.New("hash is not currently canonical") + } + return block, nil + } + return nil, errors.New("invalid arguments; neither block nor hash specified") +} + func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { header, err := b.HeaderByNumber(ctx, blockNr) if header == nil || err != nil { @@ -90,6 +138,23 @@ func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return light.NewState(ctx, header, b.eth.odr), header, nil } +func (b *LesApiBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { + if blockNr, ok := blockNrOrHash.Number(); ok { + return b.StateAndHeaderByNumber(ctx, blockNr) + } + if hash, ok := blockNrOrHash.Hash(); ok { + header := b.eth.blockchain.GetHeaderByHash(hash) + if header == nil { + return nil, nil, errors.New("header for hash not found") + } + if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { + return nil, nil, errors.New("hash is not currently canonical") + } + return light.NewState(ctx, header, b.eth.odr), header, nil + } + return nil, nil, errors.New("invalid arguments; neither block nor hash specified") +} + func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) { return b.eth.blockchain.GetBlockByHash(ctx, blockHash) } @@ -227,7 +292,7 @@ func (b *LesApiBackend) GetEngine() consensus.Engine { func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int { header := s.eth.blockchain.GetHeaderByHash(hash) if header != nil { - data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + data, err := os.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) if err == nil { rewards := make(map[string]map[string]map[string]*big.Int) err = json.Unmarshal(data, &rewards) @@ -235,7 +300,7 @@ func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]map[string] return rewards } } else { - data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) + data, err = os.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) if err == nil { rewards := make(map[string]map[string]map[string]*big.Int) err = json.Unmarshal(data, &rewards) diff --git a/les/odr_test.go b/les/odr_test.go index 4161bcce0..b8dff0d5f 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -133,7 +133,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai if value, ok := feeCapacity[testContractAddr]; ok { balanceTokenFee = value } - msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, balanceTokenFee)} + msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, balanceTokenFee, header.Number)} context := core.NewEVMContext(msg, header, bc, nil) vmenv := vm.NewEVM(context, statedb, nil, config, vm.Config{}) @@ -141,7 +141,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, ret...) } } else { @@ -153,12 +153,12 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai if value, ok := feeCapacity[testContractAddr]; ok { balanceTokenFee = value } - msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, balanceTokenFee)} + msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, balanceTokenFee, header.Number)} context := core.NewEVMContext(msg, header, lc, nil) vmenv := vm.NewEVM(context, statedb, nil, config, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) if statedb.Error() == nil { res = append(res, ret...) } diff --git a/light/lightchain.go b/light/lightchain.go index 5e6651902..1c3c11b14 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -420,6 +420,11 @@ func (bc *LightChain) HasHeader(hash common.Hash, number uint64) bool { return bc.hc.HasHeader(hash, number) } +// GetCanonicalHash returns the canonical hash for a given block number +func (bc *LightChain) GetCanonicalHash(number uint64) common.Hash { + return bc.hc.GetCanonicalHash(number) +} + // GetBlockHashesFromHash retrieves a number of block hashes starting at a given // hash, fetching towards the genesis block. func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { diff --git a/light/odr_test.go b/light/odr_test.go index 2ef2ea176..2a8d97e71 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -183,12 +183,12 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain if value, ok := feeCapacity[testContractAddr]; ok { balanceTokenFee = value } - msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false, balanceTokenFee)} + msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false, balanceTokenFee, header.Number)} context := core.NewEVMContext(msg, header, chain, nil) vmenv := vm.NewEVM(context, st, nil, config, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, ret...) if st.Error() != nil { return res, st.Error() diff --git a/metrics/librato/client.go b/metrics/librato/client.go index 8c0c850e3..b74fedfec 100644 --- a/metrics/librato/client.go +++ b/metrics/librato/client.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -93,7 +93,7 @@ func (self *LibratoClient) PostMetrics(batch Batch) (err error) { if resp.StatusCode != http.StatusOK { var body []byte - if body, err = ioutil.ReadAll(resp.Body); err != nil { + if body, err = io.ReadAll(resp.Body); err != nil { body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err)) } err = fmt.Errorf("Unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body)) diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go index df36da0ad..029c99870 100644 --- a/metrics/metrics_test.go +++ b/metrics/metrics_test.go @@ -2,7 +2,7 @@ package metrics import ( "fmt" - "io/ioutil" + "io" "log" "sync" "testing" @@ -13,7 +13,7 @@ const FANOUT = 128 // Stop the compiler from complaining during debugging. var ( - _ = ioutil.Discard + _ = io.Discard _ = log.LstdFlags ) @@ -78,7 +78,7 @@ func BenchmarkMetrics(b *testing.B) { //log.Println("done Write") return default: - WriteOnce(r, ioutil.Discard) + WriteOnce(r, io.Discard) } } }() diff --git a/miner/worker.go b/miner/worker.go index 9a125d011..7c1377e21 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -563,7 +563,7 @@ func (self *worker) commitNewWork() { tstamp = parent.Time().Int64() + 1 } // this will ensure we're not going off too far in the future - if now := time.Now().Unix(); tstamp > now+1 { + if now := time.Now().Unix(); tstamp > now { wait := time.Duration(tstamp-now) * time.Second log.Info("Mining too far in the future", "wait", common.PrettyDuration(wait)) time.Sleep(wait) @@ -652,7 +652,7 @@ func (self *worker) commitNewWork() { log.Warn("Can't find coinbase account wallet", "coinbase", self.coinbase, "err", err) return } - if self.config.XDPoS != nil && self.chain.Config().IsTIPXDCX(header.Number) { + if self.config.XDPoS != nil && self.chain.Config().IsTIPXDCXMiner(header.Number) { XDCX := self.eth.GetXDCX() XDCXLending := self.eth.GetXDCXLending() if XDCX != nil && header.Number.Uint64() > self.config.XDPoS.Epoch { @@ -710,8 +710,13 @@ func (self *worker) commitNewWork() { if XDCX.IsSDKNode() { self.chain.AddMatchingResult(tradingTransaction.Hash(), tradingMatchingResults) } + // force adding trading, lending transaction to this block + if tradingTransaction != nil { + specialTxs = append(specialTxs, tradingTransaction) + } } } + if len(lendingInput) > 0 { // lending transaction lendingBatch := &lendingstate.TxLendingBatch{ @@ -735,6 +740,9 @@ func (self *worker) commitNewWork() { if XDCX.IsSDKNode() { self.chain.AddLendingResult(lendingTransaction.Hash(), lendingMatchingResults) } + if lendingTransaction != nil { + specialTxs = append(specialTxs, lendingTransaction) + } } } @@ -756,32 +764,23 @@ func (self *worker) commitNewWork() { if XDCX.IsSDKNode() { self.chain.AddFinalizedTrades(lendingFinalizedTradeTransaction.Hash(), updatedTrades) } + if lendingFinalizedTradeTransaction != nil { + specialTxs = append(specialTxs, lendingFinalizedTradeTransaction) + } } } } + XDCxStateRoot := work.tradingState.IntermediateRoot() + LendingStateRoot := work.lendingState.IntermediateRoot() + txData := append(XDCxStateRoot.Bytes(), LendingStateRoot.Bytes()...) + tx := types.NewTransaction(work.state.GetNonce(self.coinbase), common.HexToAddress(common.TradingStateAddr), big.NewInt(0), txMatchGasLimit, big.NewInt(0), txData) + txStateRoot, err := wallet.SignTx(accounts.Account{Address: self.coinbase}, tx, self.config.ChainId) + if err != nil { + log.Error("Fail to create tx state root", "error", err) + return + } + specialTxs = append(specialTxs, txStateRoot) } - - // force adding trading, lending transaction to this block - if tradingTransaction != nil { - specialTxs = append(specialTxs, tradingTransaction) - } - if lendingTransaction != nil { - specialTxs = append(specialTxs, lendingTransaction) - } - if lendingFinalizedTradeTransaction != nil { - specialTxs = append(specialTxs, lendingFinalizedTradeTransaction) - } - - XDCxStateRoot := work.tradingState.IntermediateRoot() - LendingStateRoot := work.lendingState.IntermediateRoot() - txData := append(XDCxStateRoot.Bytes(), LendingStateRoot.Bytes()...) - tx := types.NewTransaction(work.state.GetNonce(self.coinbase), common.HexToAddress(common.TradingStateAddr), big.NewInt(0), txMatchGasLimit, big.NewInt(0), txData) - txStateRoot, err := wallet.SignTx(accounts.Account{Address: self.coinbase}, tx, self.config.ChainId) - if err != nil { - log.Error("Fail to create tx state root", "error", err) - return - } - specialTxs = append(specialTxs, txStateRoot) } work.commitTransactions(self.mux, feeCapacity, txs, specialTxs, self.chain, self.coinbase) // compute uncles for the new block. @@ -931,10 +930,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad log.Debug("Add Special Transaction failed, account skipped", "hash", tx.Hash(), "sender", from, "nonce", tx.Nonce(), "to", tx.To(), "err", err) } if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if env.header.Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(env.header.Number.Uint64(), gas) balanceFee[*tx.To()] = new(big.Int).Sub(balanceFee[*tx.To()], fee) balanceUpdated[*tx.To()] = balanceFee[*tx.To()] totalFeeUsed = totalFeeUsed.Add(totalFeeUsed, fee) @@ -1049,10 +1045,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad txs.Shift() } if tokenFeeUsed { - fee := new(big.Int).SetUint64(gas) - if env.header.Number.Cmp(common.TIPTRC21Fee) > 0 { - fee = fee.Mul(fee, common.TRC21GasPrice) - } + fee := common.GetGasFee(env.header.Number.Uint64(), gas) balanceFee[*tx.To()] = new(big.Int).Sub(balanceFee[*tx.To()], fee) balanceUpdated[*tx.To()] = balanceFee[*tx.To()] totalFeeUsed = totalFeeUsed.Add(totalFeeUsed, fee) diff --git a/node/config.go b/node/config.go index b89781874..94ea8ffbe 100644 --- a/node/config.go +++ b/node/config.go @@ -19,11 +19,11 @@ package node import ( "crypto/ecdsa" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" "strings" + "time" "github.com/XinFinOrg/XDC-Subnet/accounts" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" @@ -100,6 +100,9 @@ type Config struct { // for ephemeral nodes). HTTPPort int `toml:",omitempty"` + // HTTPWriteTimeout is the write timeout for the HTTP RPC server. + HTTPWriteTimeout time.Duration `toml:",omitempty"` + // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting // clients. Please be aware that CORS is a browser enforced security, it's fully // useless for custom HTTP clients. @@ -407,7 +410,7 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { var ephemeral string if keydir == "" { // There is no datadir. - keydir, err = ioutil.TempDir("", "go-ethereum-keystore") + keydir, err = os.MkdirTemp("", "go-ethereum-keystore") ephemeral = keydir } diff --git a/node/config_test.go b/node/config_test.go index 7711b3f7d..90b3642f3 100644 --- a/node/config_test.go +++ b/node/config_test.go @@ -18,7 +18,6 @@ package node import ( "bytes" - "io/ioutil" "os" "path/filepath" "runtime" @@ -32,7 +31,7 @@ import ( // ones or automatically generated temporary ones. func TestDatadirCreation(t *testing.T) { // Create a temporary data dir and check that it can be used by a node - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("failed to create manual data dir: %v", err) } @@ -50,7 +49,7 @@ func TestDatadirCreation(t *testing.T) { t.Fatalf("freshly created datadir not accessible: %v", err) } // Verify that an impossible datadir fails creation - file, err := ioutil.TempFile("", "") + file, err := os.CreateTemp("", "") if err != nil { t.Fatalf("failed to create temporary file: %v", err) } @@ -97,7 +96,7 @@ func TestIPCPathResolution(t *testing.T) { // ephemeral. func TestNodeKeyPersistency(t *testing.T) { // Create a temporary folder and make sure no key is present - dir, err := ioutil.TempDir("", "node-test") + dir, err := os.MkdirTemp("", "node-test") if err != nil { t.Fatalf("failed to create temporary data directory: %v", err) } @@ -125,7 +124,7 @@ func TestNodeKeyPersistency(t *testing.T) { if _, err = crypto.LoadECDSA(keyfile); err != nil { t.Fatalf("failed to load freshly persisted node key: %v", err) } - blob1, err := ioutil.ReadFile(keyfile) + blob1, err := os.ReadFile(keyfile) if err != nil { t.Fatalf("failed to read freshly persisted node key: %v", err) } @@ -133,7 +132,7 @@ func TestNodeKeyPersistency(t *testing.T) { // Configure a new node and ensure the previously persisted key is loaded config = &Config{Name: "unit-test", DataDir: dir} config.NodeKey() - blob2, err := ioutil.ReadFile(filepath.Join(keyfile)) + blob2, err := os.ReadFile(filepath.Join(keyfile)) if err != nil { t.Fatalf("failed to read previously persisted node key: %v", err) } diff --git a/node/defaults.go b/node/defaults.go index 7ab05fba8..fbf77bf59 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -21,22 +21,25 @@ import ( "os/user" "path/filepath" "runtime" + "time" "github.com/XinFinOrg/XDC-Subnet/p2p" "github.com/XinFinOrg/XDC-Subnet/p2p/nat" ) const ( - DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server - DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server - DefaultWSHost = "localhost" // Default host interface for the websocket RPC server - DefaultWSPort = 8546 // Default TCP port for the websocket RPC server + DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server + DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server + DefaultHTTPWriteTimeOut = 10 * time.Second // Default write timeout for the HTTP RPC server + DefaultWSHost = "localhost" // Default host interface for the websocket RPC server + DefaultWSPort = 8546 // Default TCP port for the websocket RPC server ) // DefaultConfig contains reasonable default settings. var DefaultConfig = Config{ DataDir: DefaultDataDir(), HTTPPort: DefaultHTTPPort, + HTTPWriteTimeout: DefaultHTTPWriteTimeOut, HTTPModules: []string{"net", "web3"}, HTTPVirtualHosts: []string{"localhost"}, WSPort: DefaultWSPort, diff --git a/node/node.go b/node/node.go index 7dd21dc96..f73025897 100644 --- a/node/node.go +++ b/node/node.go @@ -396,7 +396,7 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors if listener, err = net.Listen("tcp", endpoint); err != nil { return err } - go rpc.NewHTTPServer(cors, vhosts, handler).Serve(listener) + go rpc.NewHTTPServer(cors, vhosts, handler, n.config.HTTPWriteTimeout).Serve(listener) n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%s", endpoint), "cors", strings.Join(cors, ","), "vhosts", strings.Join(vhosts, ",")) // All listeners booted successfully n.httpEndpoint = endpoint diff --git a/node/node_test.go b/node/node_test.go index b418087ff..c3f793bd8 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -18,7 +18,6 @@ package node import ( "errors" - "io/ioutil" "os" "reflect" "testing" @@ -77,7 +76,7 @@ func TestNodeLifeCycle(t *testing.T) { // Tests that if the data dir is already in use, an appropriate error is returned. func TestNodeUsedDataDir(t *testing.T) { // Create a temporary folder to use as the data directory - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("failed to create temporary data directory: %v", err) } diff --git a/node/service_test.go b/node/service_test.go index a7ae439e0..86fb1a6fb 100644 --- a/node/service_test.go +++ b/node/service_test.go @@ -18,7 +18,6 @@ package node import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -28,7 +27,7 @@ import ( // the configured service context. func TestContextDatabases(t *testing.T) { // Create a temporary folder and ensure no database is contained within - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("failed to create temporary data directory: %v", err) } diff --git a/p2p/discover/database_test.go b/p2p/discover/database_test.go index c4fa44d09..6f452a060 100644 --- a/p2p/discover/database_test.go +++ b/p2p/discover/database_test.go @@ -18,7 +18,6 @@ package discover import ( "bytes" - "io/ioutil" "net" "os" "path/filepath" @@ -255,7 +254,7 @@ func TestNodeDBSeedQuery(t *testing.T) { } func TestNodeDBPersistency(t *testing.T) { - root, err := ioutil.TempDir("", "nodedb-") + root, err := os.MkdirTemp("", "nodedb-") if err != nil { t.Fatalf("failed to create temporary data folder: %v", err) } diff --git a/p2p/discv5/database_test.go b/p2p/discv5/database_test.go index a2ccb6467..ff0bc1a17 100644 --- a/p2p/discv5/database_test.go +++ b/p2p/discv5/database_test.go @@ -18,7 +18,6 @@ package discv5 import ( "bytes" - "io/ioutil" "net" "os" "path/filepath" @@ -255,7 +254,7 @@ func TestNodeDBSeedQuery(t *testing.T) { } func TestNodeDBPersistency(t *testing.T) { - root, err := ioutil.TempDir("", "nodedb-") + root, err := os.MkdirTemp("", "nodedb-") if err != nil { t.Fatalf("failed to create temporary data folder: %v", err) } diff --git a/p2p/message.go b/p2p/message.go index a9303d1c7..66493b4a4 100644 --- a/p2p/message.go +++ b/p2p/message.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "sync/atomic" "time" @@ -62,7 +61,7 @@ func (msg Msg) String() string { // Discard reads any remaining payload data into a black hole. func (msg Msg) Discard() error { - _, err := io.Copy(ioutil.Discard, msg.Payload) + _, err := io.Copy(io.Discard, msg.Payload) return err } @@ -236,7 +235,7 @@ func ExpectMsg(r MsgReader, code uint64, content interface{}) error { if int(msg.Size) != len(contentEnc) { return fmt.Errorf("message size mismatch: got %d, want %d", msg.Size, len(contentEnc)) } - actualContent, err := ioutil.ReadAll(msg.Payload) + actualContent, err := io.ReadAll(msg.Payload) if err != nil { return err } diff --git a/p2p/rlpx.go b/p2p/rlpx.go index c2947aba7..b2a053a88 100644 --- a/p2p/rlpx.go +++ b/p2p/rlpx.go @@ -29,7 +29,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" mrand "math/rand" "net" "sync" @@ -606,7 +605,7 @@ func (rw *rlpxFrameRW) WriteMsg(msg Msg) error { if msg.Size > maxUint24 { return errPlainMessageTooLarge } - payload, _ := ioutil.ReadAll(msg.Payload) + payload, _ := io.ReadAll(msg.Payload) payload = snappy.Encode(nil, payload) msg.Payload = bytes.NewReader(payload) @@ -700,7 +699,7 @@ func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) { // if snappy is enabled, verify and decompress message if rw.snappy { - payload, err := ioutil.ReadAll(msg.Payload) + payload, err := io.ReadAll(msg.Payload) if err != nil { return msg, err } diff --git a/p2p/rlpx_test.go b/p2p/rlpx_test.go index c291d9b6b..ce5b4a011 100644 --- a/p2p/rlpx_test.go +++ b/p2p/rlpx_test.go @@ -22,7 +22,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "reflect" "strings" @@ -305,7 +304,7 @@ ba628a4ba590cb43f7848f41c4382885 if msg.Code != 8 { t.Errorf("msg code mismatch: got %d, want %d", msg.Code, 8) } - payload, _ := ioutil.ReadAll(msg.Payload) + payload, _ := io.ReadAll(msg.Payload) wantPayload := unhex("C401020304") if !bytes.Equal(payload, wantPayload) { t.Errorf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) @@ -370,7 +369,7 @@ func TestRLPXFrameRW(t *testing.T) { if msg.Code != uint64(i) { t.Fatalf("msg code mismatch: got %d, want %d", msg.Code, i) } - payload, _ := ioutil.ReadAll(msg.Payload) + payload, _ := io.ReadAll(msg.Payload) wantPayload, _ := rlp.EncodeToBytes(wmsg) if !bytes.Equal(payload, wantPayload) { t.Fatalf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) diff --git a/p2p/simulations/adapters/docker.go b/p2p/simulations/adapters/docker.go index 7ae44e2c1..6faef40cc 100644 --- a/p2p/simulations/adapters/docker.go +++ b/p2p/simulations/adapters/docker.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -141,7 +140,7 @@ const dockerImage = "p2p-node" // when executed. func buildDockerImage() error { // create a directory to use as the build context - dir, err := ioutil.TempDir("", "p2p-docker") + dir, err := os.MkdirTemp("", "p2p-docker") if err != nil { return err } @@ -168,7 +167,7 @@ FROM ubuntu:16.04 RUN mkdir /data ADD self.bin /bin/p2p-node `) - if err := ioutil.WriteFile(filepath.Join(dir, "Dockerfile"), dockerfile, 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "Dockerfile"), dockerfile, 0644); err != nil { return err } diff --git a/p2p/simulations/examples/ping-pong.go b/p2p/simulations/examples/ping-pong.go index 8715dac36..0a40207fd 100644 --- a/p2p/simulations/examples/ping-pong.go +++ b/p2p/simulations/examples/ping-pong.go @@ -19,7 +19,7 @@ package main import ( "flag" "fmt" - "io/ioutil" + "io" "net/http" "os" "sync/atomic" @@ -62,7 +62,7 @@ func main() { adapter = adapters.NewSimAdapter(services) case "exec": - tmpdir, err := ioutil.TempDir("", "p2p-example") + tmpdir, err := os.MkdirTemp("", "p2p-example") if err != nil { log.Crit("error creating temp dir", "err", err) } @@ -170,7 +170,7 @@ func (p *pingPongService) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { errC <- err return } - payload, err := ioutil.ReadAll(msg.Payload) + payload, err := io.ReadAll(msg.Payload) if err != nil { errC <- err return diff --git a/p2p/simulations/http.go b/p2p/simulations/http.go index 429efc95e..a0b4bdd85 100644 --- a/p2p/simulations/http.go +++ b/p2p/simulations/http.go @@ -23,7 +23,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "strconv" "strings" @@ -111,7 +110,7 @@ func (c *Client) SubscribeNetwork(events chan *Event, opts SubscribeOpts) (event return nil, err } if res.StatusCode != http.StatusOK { - response, _ := ioutil.ReadAll(res.Body) + response, _ := io.ReadAll(res.Body) res.Body.Close() return nil, fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response) } @@ -251,7 +250,7 @@ func (c *Client) Send(method, path string, in, out interface{}) error { } defer res.Body.Close() if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated { - response, _ := ioutil.ReadAll(res.Body) + response, _ := io.ReadAll(res.Body) return fmt.Errorf("unexpected HTTP status: %s: %s", res.Status, response) } if out != nil { diff --git a/p2p/testing/protocoltester.go b/p2p/testing/protocoltester.go index bb8e0a55a..ced77dddd 100644 --- a/p2p/testing/protocoltester.go +++ b/p2p/testing/protocoltester.go @@ -27,7 +27,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "strings" "sync" "testing" @@ -220,7 +219,7 @@ func expectMsgs(rw p2p.MsgReadWriter, exps []Expect) error { } return err } - actualContent, err := ioutil.ReadAll(msg.Payload) + actualContent, err := io.ReadAll(msg.Payload) if err != nil { return err } diff --git a/params/config.go b/params/config.go index ebd9ea712..9687befc7 100644 --- a/params/config.go +++ b/params/config.go @@ -42,19 +42,19 @@ var ( MainnetV2Configs = map[uint64]*V2Config{ Default: { SwitchRound: 0, - CertThreshold: 5, // To be confirmed once mainnet is ready + CertThreshold: 0.667, TimeoutSyncThreshold: 3, TimeoutPeriod: 60, - MinePeriod: 10, + MinePeriod: 2, }, } TestnetV2Configs = map[uint64]*V2Config{ Default: { SwitchRound: 0, - CertThreshold: 3, - TimeoutSyncThreshold: 2, - TimeoutPeriod: 4, + CertThreshold: 0.667, + TimeoutSyncThreshold: 3, + TimeoutPeriod: 60, MinePeriod: 2, }, } @@ -62,10 +62,24 @@ var ( DevnetV2Configs = map[uint64]*V2Config{ Default: { SwitchRound: 0, - CertThreshold: 2, - TimeoutSyncThreshold: 5, - TimeoutPeriod: 25, - MinePeriod: 10, + CertThreshold: 0.667, + TimeoutSyncThreshold: 3, + TimeoutPeriod: 30, + MinePeriod: 2, + }, + 7956000: { // 2024.01.17 Devnet Deplyment Issue + SwitchRound: 7956000, + CertThreshold: 0.4, + TimeoutSyncThreshold: 3, + TimeoutPeriod: 30, + MinePeriod: 2, + }, + 7974000: { + SwitchRound: 7974000, + CertThreshold: 0.667, + TimeoutSyncThreshold: 3, + TimeoutPeriod: 30, + MinePeriod: 2, }, } @@ -96,28 +110,28 @@ var ( UnitTestV2Configs = map[uint64]*V2Config{ Default: { SwitchRound: 0, - CertThreshold: 3, + CertThreshold: 0.667, TimeoutSyncThreshold: 2, TimeoutPeriod: 10, MinePeriod: 2, }, 10: { SwitchRound: 10, - CertThreshold: 5, + CertThreshold: 0.667, TimeoutSyncThreshold: 2, TimeoutPeriod: 4, MinePeriod: 3, }, 899: { SwitchRound: 899, - CertThreshold: 3, + CertThreshold: 0.667, TimeoutSyncThreshold: 4, TimeoutPeriod: 5, MinePeriod: 2, }, 910: { SwitchRound: 915, - CertThreshold: 5, + CertThreshold: 0.667, TimeoutSyncThreshold: 4, TimeoutPeriod: 5, MinePeriod: 2, @@ -159,10 +173,9 @@ var ( Gap: 450, FoudationWalletAddr: common.HexToAddress("xdc746249c61f5832c5eed53172776b460491bdcd5c"), V2: &V2{ - SwitchBlock: common.TIPV2SwitchBlock, - CurrentConfig: TestnetV2Configs[0], - AllConfigs: TestnetV2Configs, - SkipV2Validation: true, + SwitchBlock: common.TIPV2SwitchBlock, + CurrentConfig: TestnetV2Configs[0], + AllConfigs: TestnetV2Configs, }, }, } @@ -196,31 +209,74 @@ var ( // // 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), nil, new(EthashConfig), nil, nil} + AllEthashProtocolChanges = &ChainConfig{ + ChainId: big.NewInt(1337), + 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(0), + ConstantinopleBlock: nil, + Ethash: new(EthashConfig), + Clique: nil, + XDPoS: nil, + } // AllXDPoSProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the XDPoS consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllXDPoSProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}} - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllXDPoSProtocolChanges = &ChainConfig{ + ChainId: big.NewInt(89), + 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(0), + ConstantinopleBlock: nil, + Ethash: nil, + Clique: nil, + XDPoS: &XDPoSConfig{Period: 0, Epoch: 900}, + } + + AllCliqueProtocolChanges = &ChainConfig{ + ChainId: big.NewInt(1337), + 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(0), + ConstantinopleBlock: nil, + Ethash: nil, + Clique: &CliqueConfig{Period: 0, Epoch: 900}, + XDPoS: nil, + } // XDPoS config with v2 engine after block 0 TestXDPoSMockChainConfig = &ChainConfig{ - big.NewInt(1337), - big.NewInt(0), - nil, - false, - big.NewInt(0), - common.Hash{}, - big.NewInt(0), - big.NewInt(0), - big.NewInt(0), - nil, - new(EthashConfig), - nil, - &XDPoSConfig{ + ChainId: big.NewInt(1337), + 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(0), + ConstantinopleBlock: nil, + Ethash: new(EthashConfig), + Clique: nil, + XDPoS: &XDPoSConfig{ Epoch: 900, Gap: 450, SkipV1Validation: true, @@ -237,8 +293,22 @@ var ( }, } - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil} - TestRules = TestChainConfig.Rules(new(big.Int)) + TestChainConfig = &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(0), + ConstantinopleBlock: nil, + Ethash: new(EthashConfig), + Clique: nil, + XDPoS: nil, + } + TestRules = TestChainConfig.Rules(new(big.Int)) ) // ChainConfig is the core config which determines the blockchain settings. @@ -315,11 +385,11 @@ type V2 struct { } type V2Config struct { - SwitchRound uint64 `json:"switchRound"` // v1 to v2 switch block number - MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block - TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout - TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms - CertThreshold int `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate + SwitchRound uint64 `json:"switchRound"` // v1 to v2 switch block number + MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block + TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout + TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms + CertThreshold float64 `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate } func (c *XDPoSConfig) String() string { @@ -340,7 +410,7 @@ func (v *V2) UpdateConfig(round uint64) { } } // update to current config - log.Info("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound) + log.Warn("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound) v.CurrentConfig = v.AllConfigs[index] } @@ -393,7 +463,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 Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Istanbul: %v BerlinBlock: %v LondonBlock: %v MergeBlock: %v ShanghaiBlock: %v Engine: %v}", c.ChainId, c.HomesteadBlock, c.DAOForkBlock, @@ -403,6 +473,11 @@ func (c *ChainConfig) String() string { c.EIP158Block, c.ByzantiumBlock, c.ConstantinopleBlock, + common.TIPXDCXCancellationFee, + common.BerlinBlock, + common.LondonBlock, + common.MergeBlock, + common.ShanghaiBlock, engine, ) } @@ -449,6 +524,27 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool { return isForked(common.TIPXDCXCancellationFee, num) } +// IsBerlin returns whether num is either equal to the Berlin fork block or greater. +func (c *ChainConfig) IsBerlin(num *big.Int) bool { + return isForked(common.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(common.LondonBlock, num) +} + +// IsMerge returns whether num is either equal to the Merge fork block or greater. +// Different from Geth which uses `block.difficulty != nil` +func (c *ChainConfig) IsMerge(num *big.Int) bool { + return isForked(common.MergeBlock, num) +} + +// IsShanghai returns whether num is either equal to the Shanghai fork block or greater. +func (c *ChainConfig) IsShanghai(num *big.Int) bool { + return isForked(common.ShanghaiBlock, num) +} + func (c *ChainConfig) IsTIP2019(num *big.Int) bool { return isForked(common.TIP2019Block, num) } @@ -465,11 +561,11 @@ func (c *ChainConfig) IsTIPNoHalvingMNReward(num *big.Int) bool { return isForked(common.TIPNoHalvingMNReward, num) } func (c *ChainConfig) IsTIPXDCX(num *big.Int) bool { - if common.IsTestnet { - return isForked(common.TIPXDCXTestnet, num) - } else { - return isForked(common.TIPXDCX, num) - } + return isForked(common.TIPXDCX, num) +} + +func (c *ChainConfig) IsTIPXDCXMiner(num *big.Int) bool { + return isForked(common.TIPXDCX, num) && !isForked(common.TIPXDCXDISABLE, num) } func (c *ChainConfig) IsTIPXDCXLending(num *big.Int) bool { @@ -610,6 +706,8 @@ type Rules struct { ChainId *big.Int IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool + IsBerlin, IsLondon bool + IsMerge, IsShanghai bool } func (c *ChainConfig) Rules(num *big.Int) Rules { @@ -627,5 +725,9 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsConstantinople: c.IsConstantinople(num), IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), + IsBerlin: c.IsBerlin(num), + IsLondon: c.IsLondon(num), + IsMerge: c.IsMerge(num), + IsShanghai: c.IsShanghai(num), } } diff --git a/params/config_test.go b/params/config_test.go index 12af7489f..5381a7a2d 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -85,11 +85,11 @@ func TestCheckCompatible(t *testing.T) { func TestUpdateV2Config(t *testing.T) { TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex() c := TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig - assert.Equal(t, 3, c.CertThreshold) + assert.Equal(t, 0.667, c.CertThreshold) TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(10) c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig - assert.Equal(t, 5, c.CertThreshold) + assert.Equal(t, float64(0.667), c.CertThreshold) TestXDPoSMockChainConfig.XDPoS.V2.UpdateConfig(899) c = TestXDPoSMockChainConfig.XDPoS.V2.CurrentConfig @@ -99,16 +99,16 @@ func TestUpdateV2Config(t *testing.T) { func TestV2Config(t *testing.T) { TestXDPoSMockChainConfig.XDPoS.V2.BuildConfigIndex() c := TestXDPoSMockChainConfig.XDPoS.V2.Config(1) - assert.Equal(t, 3, c.CertThreshold) + assert.Equal(t, 0.667, c.CertThreshold) c = TestXDPoSMockChainConfig.XDPoS.V2.Config(5) - assert.Equal(t, 3, c.CertThreshold) + assert.Equal(t, 0.667, c.CertThreshold) c = TestXDPoSMockChainConfig.XDPoS.V2.Config(10) - assert.Equal(t, 3, c.CertThreshold) + assert.Equal(t, 0.667, c.CertThreshold) c = TestXDPoSMockChainConfig.XDPoS.V2.Config(11) - assert.Equal(t, 5, c.CertThreshold) + assert.Equal(t, float64(0.667), c.CertThreshold) } func TestBuildConfigIndex(t *testing.T) { diff --git a/params/protocol_params.go b/params/protocol_params.go index 51b077992..2d2d402e9 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -41,8 +41,8 @@ const ( LogDataGas uint64 = 8 // Per byte in a LOG* operation's data. CallStipend uint64 = 2300 // Free gas given at beginning of call. - Sha3Gas uint64 = 30 // Once per SHA3 operation. - Sha3WordGas uint64 = 6 // Once per word of the SHA3 operation's data. + Keccak256Gas uint64 = 30 // Once per KECCAK256 operation. + Keccak256WordGas uint64 = 6 // Once per word of the KECCAK256 operation's data. 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. @@ -98,14 +98,10 @@ const ( NetSstoreResetRefund uint64 = 4800 // Once per SSTORE operation for resetting to the original non-zero value NetSstoreResetClearRefund uint64 = 19800 // Once per SSTORE operation for resetting to the original zero value - SstoreSentryGasEIP2200 uint64 = 2300 // Minimum gas required to be present for an SSTORE call, not consumed - SstoreNoopGasEIP2200 uint64 = 800 // Once per SSTORE operation if the value doesn't change. - SstoreDirtyGasEIP2200 uint64 = 800 // Once per SSTORE operation if a dirty value is changed. - SstoreInitGasEIP2200 uint64 = 20000 // Once per SSTORE operation from clean zero to non-zero - SstoreInitRefundEIP2200 uint64 = 19200 // Once per SSTORE operation for resetting to the original zero value - SstoreCleanGasEIP2200 uint64 = 5000 // Once per SSTORE operation from clean non-zero to something else - SstoreCleanRefundEIP2200 uint64 = 4200 // Once per SSTORE operation for resetting to the original non-zero value - SstoreClearRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot + SstoreSentryGasEIP2200 uint64 = 2300 // Minimum gas required to be present for an SSTORE call, not consumed + SstoreSetGasEIP2200 uint64 = 20000 // Once per SSTORE operation from clean zero to non-zero + 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 Create2Gas uint64 = 32000 // Once per CREATE2 operation SelfdestructRefundGas uint64 = 24000 // Refunded following a selfdestruct operation. diff --git a/rlp/encode_test.go b/rlp/encode_test.go index 827960f7c..12e8f2755 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/big" "sync" "testing" @@ -287,7 +286,7 @@ func TestEncodeToReader(t *testing.T) { if err != nil { return nil, err } - return ioutil.ReadAll(r) + return io.ReadAll(r) }) } @@ -328,7 +327,7 @@ func TestEncodeToReaderReturnToPool(t *testing.T) { go func() { for i := 0; i < 1000; i++ { _, r, _ := EncodeToReader("foo") - ioutil.ReadAll(r) + io.ReadAll(r) r.Read(buf) r.Read(buf) r.Read(buf) diff --git a/rpc/client.go b/rpc/client.go index c9122e6c2..7994364f2 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -32,6 +32,7 @@ import ( ) var ( + ErrBadResult = errors.New("bad result in JSON-RPC response") ErrClientQuit = errors.New("client is closed") ErrNoResult = errors.New("no result in JSON-RPC response") ErrSubscriptionQueueOverflow = errors.New("subscription queue overflow") @@ -316,7 +317,10 @@ func (c *Client) CallContext(ctx context.Context, result interface{}, method str case len(resp.Result) == 0: return ErrNoResult default: - return json.Unmarshal(resp.Result, &result) + if result == nil { + return nil + } + return json.Unmarshal(resp.Result, result) } } diff --git a/rpc/client_test.go b/rpc/client_test.go index 2be29d814..5ab61a2fe 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -18,6 +18,8 @@ package rpc import ( "context" + "encoding/json" + "errors" "fmt" "math/rand" "net" @@ -35,6 +37,73 @@ import ( "github.com/davecgh/go-spew/spew" ) +// This test checks calling a method that returns 'null'. +func TestClientNullResponse(t *testing.T) { + server := newTestServer() + defer server.Stop() + + client := DialInProc(server) + defer client.Close() + + var result json.RawMessage + if err := client.Call(&result, "test_null"); err != nil { + t.Fatal(err) + } + if result == nil { + t.Fatal("Expected non-nil result") + } + if !reflect.DeepEqual(result, json.RawMessage("null")) { + t.Errorf("Expected null, got %s", result) + } +} + +func TestClientBatchRequest_len(t *testing.T) { + b, err := json.Marshal([]jsonrpcMessage{ + {Version: "2.0", ID: json.RawMessage("1"), Method: "foo", Result: json.RawMessage(`"0x1"`)}, + {Version: "2.0", ID: json.RawMessage("2"), Method: "bar", Result: json.RawMessage(`"0x2"`)}, + }) + if err != nil { + t.Fatal("failed to encode jsonrpc message:", err) + } + s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + _, err := rw.Write(b) + if err != nil { + t.Error("failed to write response:", err) + } + })) + t.Cleanup(s.Close) + + client, err := Dial(s.URL) + if err != nil { + t.Fatal("failed to dial test server:", err) + } + defer client.Close() + + t.Run("too-few", func(t *testing.T) { + batch := []BatchElem{ + {Method: "foo"}, + {Method: "bar"}, + {Method: "baz"}, + } + ctx, cancelFn := context.WithTimeout(context.Background(), time.Second) + defer cancelFn() + if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) { + t.Errorf("expected %q but got: %v", ErrBadResult, err) + } + }) + + t.Run("too-many", func(t *testing.T) { + batch := []BatchElem{ + {Method: "foo"}, + } + ctx, cancelFn := context.WithTimeout(context.Background(), time.Second) + defer cancelFn() + if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) { + t.Errorf("expected %q but got: %v", ErrBadResult, err) + } + }) +} + func TestClientRequest(t *testing.T) { server := newTestServer() defer server.Stop() diff --git a/rpc/http.go b/rpc/http.go index a68b4dfe8..5f3fde11f 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -23,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "net" "net/http" @@ -32,6 +31,7 @@ import ( "sync" "time" + "github.com/XinFinOrg/XDC-Subnet/log" "github.com/rs/cors" ) @@ -170,6 +170,9 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil { return err } + if len(respmsgs) != len(msgs) { + return fmt.Errorf("batch has %d requests but response has %d: %w", len(msgs), len(respmsgs), ErrBadResult) + } for i := 0; i < len(respmsgs); i++ { op.resp <- &respmsgs[i] } @@ -181,7 +184,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos if err != nil { return nil, err } - req, err := http.NewRequestWithContext(ctx, "POST", hc.url, ioutil.NopCloser(bytes.NewReader(body))) + req, err := http.NewRequestWithContext(ctx, "POST", hc.url, io.NopCloser(bytes.NewReader(body))) if err != nil { return nil, err } @@ -230,14 +233,16 @@ func (t *httpServerConn) SetWriteDeadline(time.Time) error { return nil } // NewHTTPServer creates a new HTTP RPC server around an API provider. // // Deprecated: Server implements http.Handler -func NewHTTPServer(cors []string, vhosts []string, srv *Server) *http.Server { +func NewHTTPServer(cors []string, vhosts []string, srv *Server, writeTimeout time.Duration) *http.Server { // Wrap the CORS-handler within a host-handler handler := newCorsHandler(srv, cors) handler = newVHostHandler(vhosts, handler) + handler = http.TimeoutHandler(handler, writeTimeout, `{"error":"http server timeout"}`) + log.Info("NewHTTPServer", "writeTimeout", writeTimeout) return &http.Server{ Handler: handler, ReadTimeout: 5 * time.Second, - WriteTimeout: 10 * time.Second, + WriteTimeout: writeTimeout + time.Second, IdleTimeout: 120 * time.Second, } } diff --git a/rpc/server_test.go b/rpc/server_test.go index 6a2b09e44..1af285bc8 100644 --- a/rpc/server_test.go +++ b/rpc/server_test.go @@ -20,8 +20,8 @@ import ( "bufio" "bytes" "io" - "io/ioutil" "net" + "os" "path/filepath" "strings" "testing" @@ -45,14 +45,14 @@ func TestServerRegisterName(t *testing.T) { t.Fatalf("Expected service calc to be registered") } - wantCallbacks := 9 + wantCallbacks := 10 if len(svc.callbacks) != wantCallbacks { t.Errorf("Expected %d callbacks for service 'service', got %d", wantCallbacks, len(svc.callbacks)) } } func TestServer(t *testing.T) { - files, err := ioutil.ReadDir("testdata") + files, err := os.ReadDir("testdata") if err != nil { t.Fatal("where'd my testdata go?") } @@ -70,7 +70,7 @@ func TestServer(t *testing.T) { func runTestScript(t *testing.T, file string) { server := newTestServer() - content, err := ioutil.ReadFile(file) + content, err := os.ReadFile(file) if err != nil { t.Fatal(err) } diff --git a/rpc/testservice_test.go b/rpc/testservice_test.go index 62afc1df4..22bd64d2f 100644 --- a/rpc/testservice_test.go +++ b/rpc/testservice_test.go @@ -84,6 +84,10 @@ func (s *testService) Sleep(ctx context.Context, duration time.Duration) { time.Sleep(duration) } +func (s *testService) Null() any { + return nil +} + func (s *testService) Block(ctx context.Context) error { <-ctx.Done() return errors.New("context canceled in testservice_block") diff --git a/swarm/api/api_test.go b/swarm/api/api_test.go index 133918be4..08cecfe30 100644 --- a/swarm/api/api_test.go +++ b/swarm/api/api_test.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "testing" @@ -30,7 +29,7 @@ import ( ) func testApi(t *testing.T, f func(*Api)) { - datadir, err := ioutil.TempDir("", "bzz-test") + datadir, err := os.MkdirTemp("", "bzz-test") if err != nil { t.Fatalf("unable to create temp dir: %v", err) } diff --git a/swarm/api/client/client.go b/swarm/api/client/client.go index 58825a5d2..cc004f71f 100644 --- a/swarm/api/client/client.go +++ b/swarm/api/client/client.go @@ -23,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "mime/multipart" "net/http" @@ -70,7 +69,7 @@ func (c *Client) UploadRaw(r io.Reader, size int64) (string, error) { if res.StatusCode != http.StatusOK { return "", fmt.Errorf("unexpected HTTP status: %s", res.Status) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { return "", err } @@ -401,7 +400,7 @@ func (c *Client) TarUpload(hash string, uploader Uploader) (string, error) { if res.StatusCode != http.StatusOK { return "", fmt.Errorf("unexpected HTTP status: %s", res.Status) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { return "", err } @@ -457,7 +456,7 @@ func (c *Client) MultipartUpload(hash string, uploader Uploader) (string, error) if res.StatusCode != http.StatusOK { return "", fmt.Errorf("unexpected HTTP status: %s", res.Status) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { return "", err } diff --git a/swarm/api/client/client_test.go b/swarm/api/client/client_test.go index aaf5c6296..368267bc3 100644 --- a/swarm/api/client/client_test.go +++ b/swarm/api/client/client_test.go @@ -18,7 +18,7 @@ package client import ( "bytes" - "io/ioutil" + "io" "os" "path/filepath" "reflect" @@ -49,7 +49,7 @@ func TestClientUploadDownloadRaw(t *testing.T) { t.Fatal(err) } defer res.Close() - gotData, err := ioutil.ReadAll(res) + gotData, err := io.ReadAll(res) if err != nil { t.Fatal(err) } @@ -67,7 +67,7 @@ func TestClientUploadDownloadFiles(t *testing.T) { client := NewClient(srv.URL) upload := func(manifest, path string, data []byte) string { file := &File{ - ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), + ReadCloser: io.NopCloser(bytes.NewReader(data)), ManifestEntry: api.ManifestEntry{ Path: path, ContentType: "text/plain", @@ -92,7 +92,7 @@ func TestClientUploadDownloadFiles(t *testing.T) { if file.ContentType != "text/plain" { t.Fatalf("expected downloaded file to have type %q, got %q", "text/plain", file.ContentType) } - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { t.Fatal(err) } @@ -136,7 +136,7 @@ var testDirFiles = []string{ } func newTestDirectory(t *testing.T) string { - dir, err := ioutil.TempDir("", "swarm-client-test") + dir, err := os.MkdirTemp("", "swarm-client-test") if err != nil { t.Fatal(err) } @@ -147,7 +147,7 @@ func newTestDirectory(t *testing.T) string { os.RemoveAll(dir) t.Fatalf("error creating dir for %s: %s", path, err) } - if err := ioutil.WriteFile(path, []byte(file), 0644); err != nil { + if err := os.WriteFile(path, []byte(file), 0644); err != nil { os.RemoveAll(dir) t.Fatalf("error writing file %s: %s", path, err) } @@ -180,7 +180,7 @@ func TestClientUploadDownloadDirectory(t *testing.T) { t.Fatal(err) } defer file.Close() - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { t.Fatal(err) } @@ -196,7 +196,7 @@ func TestClientUploadDownloadDirectory(t *testing.T) { checkDownloadFile("", []byte(testDirFiles[0])) // check we can download the directory - tmp, err := ioutil.TempDir("", "swarm-client-test") + tmp, err := os.MkdirTemp("", "swarm-client-test") if err != nil { t.Fatal(err) } @@ -205,7 +205,7 @@ func TestClientUploadDownloadDirectory(t *testing.T) { t.Fatal(err) } for _, file := range testDirFiles { - data, err := ioutil.ReadFile(filepath.Join(tmp, file)) + data, err := os.ReadFile(filepath.Join(tmp, file)) if err != nil { t.Fatal(err) } @@ -283,7 +283,7 @@ func TestClientMultipartUpload(t *testing.T) { uploader := UploaderFunc(func(upload UploadFn) error { for _, name := range testDirFiles { file := &File{ - ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), + ReadCloser: io.NopCloser(bytes.NewReader(data)), ManifestEntry: api.ManifestEntry{ Path: name, ContentType: "text/plain", @@ -311,7 +311,7 @@ func TestClientMultipartUpload(t *testing.T) { t.Fatal(err) } defer file.Close() - gotData, err := ioutil.ReadAll(file) + gotData, err := io.ReadAll(file) if err != nil { t.Fatal(err) } diff --git a/swarm/api/filesystem_test.go b/swarm/api/filesystem_test.go index 4e028744c..7fc25e9fb 100644 --- a/swarm/api/filesystem_test.go +++ b/swarm/api/filesystem_test.go @@ -18,7 +18,6 @@ package api import ( "bytes" - "io/ioutil" "os" "path/filepath" "sync" @@ -28,7 +27,7 @@ import ( "github.com/XinFinOrg/XDC-Subnet/swarm/storage" ) -var testDownloadDir, _ = ioutil.TempDir(os.TempDir(), "bzz-test") +var testDownloadDir, _ = os.MkdirTemp(os.TempDir(), "bzz-test") func testFileSystem(t *testing.T, f func(*FileSystem)) { testApi(t, func(api *Api) { @@ -38,7 +37,7 @@ func testFileSystem(t *testing.T, f func(*FileSystem)) { func readPath(t *testing.T, parts ...string) string { file := filepath.Join(parts...) - content, err := ioutil.ReadFile(file) + content, err := os.ReadFile(file) if err != nil { t.Fatalf("unexpected error reading '%v': %v", file, err) @@ -100,7 +99,7 @@ func TestApiDirUploadModify(t *testing.T) { t.Errorf("unexpected error: %v", err) return } - index, err := ioutil.ReadFile(filepath.Join("testdata", "test0", "index.html")) + index, err := os.ReadFile(filepath.Join("testdata", "test0", "index.html")) if err != nil { t.Errorf("unexpected error: %v", err) return diff --git a/swarm/api/http/error_test.go b/swarm/api/http/error_test.go index 0b1b85cfa..8ee0c75c9 100644 --- a/swarm/api/http/error_test.go +++ b/swarm/api/http/error_test.go @@ -18,7 +18,7 @@ package http_test import ( "encoding/json" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -43,7 +43,7 @@ func TestError(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if resp.StatusCode != 400 && !strings.Contains(string(respbody), "Invalid URI "/this_should_fail_as_no_bzz_protocol_present": unknown scheme") { t.Fatalf("Response body does not match, expected: %v, to contain: %v; received code %d, expected code: %d", string(respbody), "Invalid bzz URI: unknown scheme", 400, resp.StatusCode) @@ -69,7 +69,7 @@ func Test404Page(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if resp.StatusCode != 404 || !strings.Contains(string(respbody), "404") { t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode) @@ -95,7 +95,7 @@ func Test500Page(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if resp.StatusCode != 404 { t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode) @@ -120,7 +120,7 @@ func Test500PageWith0xHashPrefix(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if resp.StatusCode != 404 { t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode) @@ -155,7 +155,7 @@ func TestJsonResponse(t *testing.T) { } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if resp.StatusCode != 404 { t.Fatalf("Invalid Status Code received, expected 404, got %d", resp.StatusCode) diff --git a/swarm/api/http/roundtripper_test.go b/swarm/api/http/roundtripper_test.go index f99c4f35e..fec282d86 100644 --- a/swarm/api/http/roundtripper_test.go +++ b/swarm/api/http/roundtripper_test.go @@ -17,7 +17,7 @@ package http import ( - "io/ioutil" + "io" "net" "net/http" "net/http/httptest" @@ -57,7 +57,7 @@ func TestRoundTripper(t *testing.T) { } }() - content, err := ioutil.ReadAll(resp.Body) + content, err := io.ReadAll(resp.Body) if err != nil { t.Errorf("expected no error, got %v", err) return diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index e844c9f15..c22ae7a4f 100644 --- a/swarm/api/http/server.go +++ b/swarm/api/http/server.go @@ -25,7 +25,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "mime/multipart" "net/http" @@ -247,7 +246,7 @@ func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.Ma reader = part } else { // copy the part to a tmp file to get its size - tmp, err := ioutil.TempFile("", "swarm-multipart") + tmp, err := os.CreateTemp("", "swarm-multipart") if err != nil { return err } diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index 3cda552b9..ffbd85ff6 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -20,7 +20,7 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "io" "net/http" "strings" "sync" @@ -88,7 +88,7 @@ func TestBzzGetPath(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if string(respbody) != testmanifest[v] { isexpectedfailrequest := false @@ -117,7 +117,7 @@ func TestBzzGetPath(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if err != nil { t.Fatalf("Read request body: %v", err) } @@ -174,7 +174,7 @@ func TestBzzGetPath(t *testing.T) { t.Fatalf("HTTP request: %v", err) } defer resp.Body.Close() - respbody, err := ioutil.ReadAll(resp.Body) + respbody, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("Read response body: %v", err) } @@ -204,7 +204,7 @@ func TestBzzGetPath(t *testing.T) { t.Fatalf("HTTP request: %v", err) } defer resp.Body.Close() - respbody, err := ioutil.ReadAll(resp.Body) + respbody, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("Read response body: %v", err) } @@ -250,7 +250,7 @@ func TestBzzGetPath(t *testing.T) { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() - respbody, err = ioutil.ReadAll(resp.Body) + respbody, err = io.ReadAll(resp.Body) if err != nil { t.Fatalf("ReadAll failed: %v", err) } @@ -272,7 +272,7 @@ func TestBzzRootRedirect(t *testing.T) { client := swarm.NewClient(srv.URL) data := []byte("data") file := &swarm.File{ - ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), + ReadCloser: io.NopCloser(bytes.NewReader(data)), ManifestEntry: api.ManifestEntry{ Path: "", ContentType: "text/plain", @@ -310,7 +310,7 @@ func TestBzzRootRedirect(t *testing.T) { if !redirected { t.Fatal("expected GET /bzz:/ to redirect to /bzz:// but it didn't") } - gotData, err := ioutil.ReadAll(res.Body) + gotData, err := io.ReadAll(res.Body) if err != nil { t.Fatal(err) } diff --git a/swarm/fuse/swarmfs_test.go b/swarm/fuse/swarmfs_test.go index a8ce82559..9c416e291 100644 --- a/swarm/fuse/swarmfs_test.go +++ b/swarm/fuse/swarmfs_test.go @@ -23,7 +23,6 @@ import ( "bytes" "crypto/rand" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -137,7 +136,7 @@ func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo t.Fatalf("file %v Permission mismatch source (-rwx------) vs destination(%v)", fname, dfinfo.Mode().Perm()) } - fileContents, err := ioutil.ReadFile(filepath.Join(mountDir, fname)) + fileContents, err := os.ReadFile(filepath.Join(mountDir, fname)) if err != nil { t.Fatalf("Could not readfile %v : %v", fname, err) } @@ -196,8 +195,8 @@ type testAPI struct { func (ta *testAPI) mountListAndUnmount(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "fuse-source") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "fuse-dest") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "fuse-source") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "fuse-dest") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["2.txt"] = fileInfo{0711, 333, 444, getRandomBtes(10)} @@ -234,44 +233,44 @@ func (ta *testAPI) mountListAndUnmount(t *testing.T) { func (ta *testAPI) maxMounts(t *testing.T) { files := make(map[string]fileInfo) files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir1, _ := ioutil.TempDir(os.TempDir(), "max-upload1") + uploadDir1, _ := os.MkdirTemp(os.TempDir(), "max-upload1") bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1) - mount1, _ := ioutil.TempDir(os.TempDir(), "max-mount1") + mount1, _ := os.MkdirTemp(os.TempDir(), "max-mount1") swarmfs1 := mountDir(t, ta.api, files, bzzHash1, mount1) defer swarmfs1.Stop() files["2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir2, _ := ioutil.TempDir(os.TempDir(), "max-upload2") + uploadDir2, _ := os.MkdirTemp(os.TempDir(), "max-upload2") bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2) - mount2, _ := ioutil.TempDir(os.TempDir(), "max-mount2") + mount2, _ := os.MkdirTemp(os.TempDir(), "max-mount2") swarmfs2 := mountDir(t, ta.api, files, bzzHash2, mount2) defer swarmfs2.Stop() files["3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir3, _ := ioutil.TempDir(os.TempDir(), "max-upload3") + uploadDir3, _ := os.MkdirTemp(os.TempDir(), "max-upload3") bzzHash3 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir3) - mount3, _ := ioutil.TempDir(os.TempDir(), "max-mount3") + mount3, _ := os.MkdirTemp(os.TempDir(), "max-mount3") swarmfs3 := mountDir(t, ta.api, files, bzzHash3, mount3) defer swarmfs3.Stop() files["4.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir4, _ := ioutil.TempDir(os.TempDir(), "max-upload4") + uploadDir4, _ := os.MkdirTemp(os.TempDir(), "max-upload4") bzzHash4 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir4) - mount4, _ := ioutil.TempDir(os.TempDir(), "max-mount4") + mount4, _ := os.MkdirTemp(os.TempDir(), "max-mount4") swarmfs4 := mountDir(t, ta.api, files, bzzHash4, mount4) defer swarmfs4.Stop() files["5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir5, _ := ioutil.TempDir(os.TempDir(), "max-upload5") + uploadDir5, _ := os.MkdirTemp(os.TempDir(), "max-upload5") bzzHash5 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir5) - mount5, _ := ioutil.TempDir(os.TempDir(), "max-mount5") + mount5, _ := os.MkdirTemp(os.TempDir(), "max-mount5") swarmfs5 := mountDir(t, ta.api, files, bzzHash5, mount5) defer swarmfs5.Stop() files["6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir6, _ := ioutil.TempDir(os.TempDir(), "max-upload6") + uploadDir6, _ := os.MkdirTemp(os.TempDir(), "max-upload6") bzzHash6 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir6) - mount6, _ := ioutil.TempDir(os.TempDir(), "max-mount6") + mount6, _ := os.MkdirTemp(os.TempDir(), "max-mount6") os.RemoveAll(mount6) os.MkdirAll(mount6, 0777) @@ -285,15 +284,15 @@ func (ta *testAPI) maxMounts(t *testing.T) { func (ta *testAPI) remount(t *testing.T) { files := make(map[string]fileInfo) files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir1, _ := ioutil.TempDir(os.TempDir(), "re-upload1") + uploadDir1, _ := os.MkdirTemp(os.TempDir(), "re-upload1") bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1) - testMountDir1, _ := ioutil.TempDir(os.TempDir(), "re-mount1") + testMountDir1, _ := os.MkdirTemp(os.TempDir(), "re-mount1") swarmfs := mountDir(t, ta.api, files, bzzHash1, testMountDir1) defer swarmfs.Stop() - uploadDir2, _ := ioutil.TempDir(os.TempDir(), "re-upload2") + uploadDir2, _ := os.MkdirTemp(os.TempDir(), "re-upload2") bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2) - testMountDir2, _ := ioutil.TempDir(os.TempDir(), "re-mount2") + testMountDir2, _ := os.MkdirTemp(os.TempDir(), "re-mount2") // try mounting the same hash second time os.RemoveAll(testMountDir2) @@ -318,8 +317,8 @@ func (ta *testAPI) remount(t *testing.T) { func (ta *testAPI) unmount(t *testing.T) { files := make(map[string]fileInfo) - uploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") + uploadDir, _ := os.MkdirTemp(os.TempDir(), "ex-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "ex-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir) @@ -339,8 +338,8 @@ func (ta *testAPI) unmount(t *testing.T) { func (ta *testAPI) unmountWhenResourceBusy(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "ex-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "ex-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) @@ -368,8 +367,8 @@ func (ta *testAPI) unmountWhenResourceBusy(t *testing.T) { func (ta *testAPI) seekInMultiChunkFile(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "seek-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "seek-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "seek-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "seek-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10240)} bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) @@ -395,8 +394,8 @@ func (ta *testAPI) seekInMultiChunkFile(t *testing.T) { func (ta *testAPI) createNewFile(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "create-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "create-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "create-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "create-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -432,8 +431,8 @@ func (ta *testAPI) createNewFile(t *testing.T) { func (ta *testAPI) createNewFileInsideDirectory(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "createinsidedir-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "createinsidedir-mount") files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) @@ -468,8 +467,8 @@ func (ta *testAPI) createNewFileInsideDirectory(t *testing.T) { func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "createinsidenewdir-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "createinsidenewdir-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) @@ -505,8 +504,8 @@ func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T) { func (ta *testAPI) removeExistingFile(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "remove-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "remove-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -533,8 +532,8 @@ func (ta *testAPI) removeExistingFile(t *testing.T) { func (ta *testAPI) removeExistingFileInsideDir(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "remove-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "remove-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["one/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -562,8 +561,8 @@ func (ta *testAPI) removeExistingFileInsideDir(t *testing.T) { func (ta *testAPI) removeNewlyAddedFile(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "removenew-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "removenew-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "removenew-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "removenew-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -606,8 +605,8 @@ func (ta *testAPI) removeNewlyAddedFile(t *testing.T) { func (ta *testAPI) addNewFileAndModifyContents(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "modifyfile-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "modifyfile-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -676,8 +675,8 @@ func (ta *testAPI) addNewFileAndModifyContents(t *testing.T) { func (ta *testAPI) removeEmptyDir(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "rmdir-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "rmdir-mount") files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -700,8 +699,8 @@ func (ta *testAPI) removeEmptyDir(t *testing.T) { func (ta *testAPI) removeDirWhichHasFiles(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "rmdir-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "rmdir-mount") files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["two/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -729,8 +728,8 @@ func (ta *testAPI) removeDirWhichHasFiles(t *testing.T) { func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "rmsubdir-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "rmsubdir-mount") files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} files["two/three/2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} @@ -765,8 +764,8 @@ func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T) { func (ta *testAPI) appendFileContentsToEnd(t *testing.T) { files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-mount") + testUploadDir, _ := os.MkdirTemp(os.TempDir(), "appendlargefile-upload") + testMountDir, _ := os.MkdirTemp(os.TempDir(), "appendlargefile-mount") line1 := make([]byte, 10) rand.Read(line1) @@ -803,7 +802,7 @@ func (ta *testAPI) appendFileContentsToEnd(t *testing.T) { } func TestFUSE(t *testing.T) { - datadir, err := ioutil.TempDir("", "fuse") + datadir, err := os.MkdirTemp("", "fuse") if err != nil { t.Fatalf("unable to create temp dir: %v", err) } diff --git a/swarm/network/kademlia/kaddb.go b/swarm/network/kademlia/kaddb.go index 5ff57149c..c4dadc2da 100644 --- a/swarm/network/kademlia/kaddb.go +++ b/swarm/network/kademlia/kaddb.go @@ -19,7 +19,6 @@ package kademlia import ( "encoding/json" "fmt" - "io/ioutil" "os" "sync" "time" @@ -291,7 +290,7 @@ func (self *KadDb) save(path string, cb func(*NodeRecord, Node)) error { if err != nil { return err } - err = ioutil.WriteFile(path, data, os.ModePerm) + err = os.WriteFile(path, data, os.ModePerm) if err != nil { log.Warn(fmt.Sprintf("unable to save kaddb with %v nodes to %v: %v", n, path, err)) } else { @@ -306,7 +305,7 @@ func (self *KadDb) load(path string, cb func(*NodeRecord, Node) error) (err erro self.lock.Lock() var data []byte - data, err = ioutil.ReadFile(path) + data, err = os.ReadFile(path) if err != nil { return } diff --git a/swarm/network/syncdb_test.go b/swarm/network/syncdb_test.go index 8b36158bd..ee7827bca 100644 --- a/swarm/network/syncdb_test.go +++ b/swarm/network/syncdb_test.go @@ -19,7 +19,6 @@ package network import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -47,7 +46,7 @@ type testSyncDb struct { func newTestSyncDb(priority, bufferSize, batchSize int, dbdir string, t *testing.T) *testSyncDb { if len(dbdir) == 0 { - tmp, err := ioutil.TempDir(os.TempDir(), "syncdb-test") + tmp, err := os.MkdirTemp(os.TempDir(), "syncdb-test") if err != nil { t.Fatalf("unable to create temporary direcory %v: %v", tmp, err) } diff --git a/swarm/storage/dbstore.go b/swarm/storage/dbstore.go index 6dbd301cc..b85108290 100644 --- a/swarm/storage/dbstore.go +++ b/swarm/storage/dbstore.go @@ -29,7 +29,6 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" "sync" "github.com/XinFinOrg/XDC-Subnet/log" @@ -39,7 +38,7 @@ import ( "github.com/syndtr/goleveldb/leveldb/iterator" ) -//metrics variables +// metrics variables var ( gcCounter = metrics.NewRegisteredCounter("storage.db.dbstore.gc.count", nil) dbStoreDeleteCounter = metrics.NewRegisteredCounter("storage.db.dbstore.rm.count", nil) @@ -338,7 +337,7 @@ func (s *DbStore) Import(in io.Reader) (int64, error) { continue } - data, err := ioutil.ReadAll(tr) + data, err := io.ReadAll(tr) if err != nil { return count, err } @@ -540,7 +539,8 @@ func (s *DbStore) Close() { s.db.Close() } -// describes a section of the DbStore representing the unsynced +// describes a section of the DbStore representing the unsynced +// // domain relevant to a peer // Start - Stop designate a continuous area Keys in an address space // typically the addresses closer to us than to the peer but not closer diff --git a/swarm/storage/dbstore_test.go b/swarm/storage/dbstore_test.go index 30fdcd895..5b9a96a8d 100644 --- a/swarm/storage/dbstore_test.go +++ b/swarm/storage/dbstore_test.go @@ -18,14 +18,14 @@ package storage import ( "bytes" - "io/ioutil" + "os" "testing" "github.com/XinFinOrg/XDC-Subnet/common" ) func initDbStore(t *testing.T) *DbStore { - dir, err := ioutil.TempDir("", "bzz-storage-test") + dir, err := os.MkdirTemp("", "bzz-storage-test") if err != nil { t.Fatal(err) } diff --git a/swarm/storage/dpa_test.go b/swarm/storage/dpa_test.go index a23b9efeb..c24488f46 100644 --- a/swarm/storage/dpa_test.go +++ b/swarm/storage/dpa_test.go @@ -19,7 +19,6 @@ package storage import ( "bytes" "io" - "io/ioutil" "os" "sync" "testing" @@ -63,8 +62,8 @@ func TestDPArandom(t *testing.T) { if !bytes.Equal(slice, resultSlice) { t.Errorf("Comparison error.") } - ioutil.WriteFile("/tmp/slice.bzz.16M", slice, 0666) - ioutil.WriteFile("/tmp/result.bzz.16M", resultSlice, 0666) + os.WriteFile("/tmp/slice.bzz.16M", slice, 0666) + os.WriteFile("/tmp/result.bzz.16M", resultSlice, 0666) localStore.memStore = NewMemStore(dbStore, defaultCacheCapacity) resultReader = dpa.Retrieve(key) for i := range resultSlice { diff --git a/swarm/testutil/http.go b/swarm/testutil/http.go index 5769eab2c..c883236bc 100644 --- a/swarm/testutil/http.go +++ b/swarm/testutil/http.go @@ -17,7 +17,6 @@ package testutil import ( - "io/ioutil" "net/http/httptest" "os" "testing" @@ -28,7 +27,7 @@ import ( ) func NewTestSwarmServer(t *testing.T) *TestSwarmServer { - dir, err := ioutil.TempDir("", "swarm-storage-test") + dir, err := os.MkdirTemp("", "swarm-storage-test") if err != nil { t.Fatal(err) } diff --git a/tests/init_test.go b/tests/init_test.go index 1a3aad9e7..444f52fb0 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -43,7 +42,7 @@ var ( ) func readJson(reader io.Reader, value interface{}) error { - data, err := ioutil.ReadAll(reader) + data, err := io.ReadAll(reader) if err != nil { return fmt.Errorf("error reading JSON file: %v", err) } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 02c87a03f..dbcb55ff1 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -131,7 +131,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD statedb := MakePreState(db, t.json.Pre) post := t.json.Post[subtest.Fork][subtest.Index] - msg, err := t.json.Tx.toMessage(post) + msg, err := t.json.Tx.toMessage(post, block.Number()) if err != nil { return nil, err } @@ -144,7 +144,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD snapshot := statedb.Snapshot() coinbase := &t.json.Env.Coinbase - if _, _, _, err := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { + if _, _, _, err, _ := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { statedb.RevertToSnapshot(snapshot) } if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) { @@ -190,7 +190,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, number *big.Int) (core.Message, error) { // Derive sender from private key if present. var from common.Address if len(tx.PrivateKey) > 0 { @@ -235,7 +235,7 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) { if err != nil { return nil, fmt.Errorf("invalid tx data %q", dataHex) } - msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, true, nil) + msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, true, nil, number) return msg, nil } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index d9b461696..0731c6d22 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -20,9 +20,10 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/XinFinOrg/XDC-Subnet/core/rawdb" "math/big" + "github.com/XinFinOrg/XDC-Subnet/core/rawdb" + "github.com/XinFinOrg/XDC-Subnet/common" "github.com/XinFinOrg/XDC-Subnet/common/hexutil" "github.com/XinFinOrg/XDC-Subnet/common/math" @@ -143,7 +144,6 @@ func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM { Difficulty: t.json.Env.Difficulty, GasPrice: t.json.Exec.GasPrice, } - vmconfig.NoRecursion = true return vm.NewEVM(context, statedb, nil, params.MainnetChainConfig, vmconfig) } diff --git a/trie/trie_test.go b/trie/trie_test.go index 8e2fcaad7..519d67c91 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -20,7 +20,6 @@ import ( "bytes" "encoding/binary" "fmt" - "io/ioutil" "math/big" "math/rand" "os" @@ -819,7 +818,7 @@ func benchmarkDerefRootFixedSize(b *testing.B, addresses [][20]byte, accounts [] } func tempDB() (string, *Database) { - dir, err := ioutil.TempDir("", "trie-bench") + dir, err := os.MkdirTemp("", "trie-bench") if err != nil { panic(fmt.Sprintf("can't create temporary directory: %v", err)) } diff --git a/whisper/mailserver/server_test.go b/whisper/mailserver/server_test.go index 41a5a0de7..b31427f89 100644 --- a/whisper/mailserver/server_test.go +++ b/whisper/mailserver/server_test.go @@ -20,8 +20,8 @@ import ( "bytes" "crypto/ecdsa" "encoding/binary" - "io/ioutil" "math/rand" + "os" "testing" "time" @@ -83,7 +83,7 @@ func TestMailServer(t *testing.T) { const password = "password_for_this_test" const dbPath = "whisper-server-test" - dir, err := ioutil.TempDir("", dbPath) + dir, err := os.MkdirTemp("", dbPath) if err != nil { t.Fatal(err) }